linux/drivers/pcmcia/m32r_cfc.c
<<
>>
Prefs
   1/*
   2 *  drivers/pcmcia/m32r_cfc.c
   3 *
   4 *  Device driver for the CFC functionality of M32R.
   5 *
   6 *  Copyright (c) 2001, 2002, 2003, 2004
   7 *    Hiroyuki Kondo, Naoto Sugai, Hayato Fujiwara
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/moduleparam.h>
  12#include <linux/init.h>
  13#include <linux/types.h>
  14#include <linux/fcntl.h>
  15#include <linux/string.h>
  16#include <linux/kernel.h>
  17#include <linux/errno.h>
  18#include <linux/timer.h>
  19#include <linux/slab.h>
  20#include <linux/ioport.h>
  21#include <linux/delay.h>
  22#include <linux/workqueue.h>
  23#include <linux/interrupt.h>
  24#include <linux/platform_device.h>
  25#include <linux/bitops.h>
  26#include <asm/irq.h>
  27#include <asm/io.h>
  28#include <asm/system.h>
  29
  30#include <pcmcia/cs_types.h>
  31#include <pcmcia/ss.h>
  32#include <pcmcia/cs.h>
  33
  34#undef MAX_IO_WIN       /* FIXME */
  35#define MAX_IO_WIN 1
  36#undef MAX_WIN          /* FIXME */
  37#define MAX_WIN 1
  38
  39#include "m32r_cfc.h"
  40
  41#ifdef CONFIG_PCMCIA_DEBUG
  42static int m32r_cfc_debug;
  43module_param(m32r_cfc_debug, int, 0644);
  44#define debug(lvl, fmt, arg...) do {                            \
  45        if (m32r_cfc_debug > (lvl))                             \
  46                printk(KERN_DEBUG "m32r_cfc: " fmt , ## arg);   \
  47} while (0)
  48#else
  49#define debug(n, args...) do { } while (0)
  50#endif
  51
  52/* Poll status interval -- 0 means default to interrupt */
  53static int poll_interval = 0;
  54
  55typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
  56
  57typedef struct pcc_socket {
  58        u_short                 type, flags;
  59        struct pcmcia_socket    socket;
  60        unsigned int            number;
  61        unsigned int            ioaddr;
  62        u_long                  mapaddr;
  63        u_long                  base;   /* PCC register base */
  64        u_char                  cs_irq1, cs_irq2, intr;
  65        pccard_io_map           io_map[MAX_IO_WIN];
  66        pccard_mem_map          mem_map[MAX_WIN];
  67        u_char                  io_win;
  68        u_char                  mem_win;
  69        pcc_as_t                current_space;
  70        u_char                  last_iodbex;
  71#ifdef CONFIG_PROC_FS
  72        struct proc_dir_entry *proc;
  73#endif
  74} pcc_socket_t;
  75
  76static int pcc_sockets = 0;
  77static pcc_socket_t socket[M32R_MAX_PCC] = {
  78        { 0, }, /* ... */
  79};
  80
  81/*====================================================================*/
  82
  83static unsigned int pcc_get(u_short, unsigned int);
  84static void pcc_set(u_short, unsigned int , unsigned int );
  85
  86static DEFINE_SPINLOCK(pcc_lock);
  87
  88#if !defined(CONFIG_PLAT_USRV)
  89static inline u_long pcc_port2addr(unsigned long port, int size) {
  90        u_long addr = 0;
  91        u_long odd;
  92
  93        if (size == 1) {        /* byte access */
  94                odd = (port&1) << 11;
  95                port -= port & 1;
  96                addr = CFC_IO_MAPBASE_BYTE - CFC_IOPORT_BASE + odd + port;
  97        } else if (size == 2)
  98                addr = CFC_IO_MAPBASE_WORD - CFC_IOPORT_BASE + port;
  99
 100        return addr;
 101}
 102#else   /* CONFIG_PLAT_USRV */
 103static inline u_long pcc_port2addr(unsigned long port, int size) {
 104        u_long odd;
 105        u_long addr = ((port - CFC_IOPORT_BASE) & 0xf000) << 8;
 106
 107        if (size == 1) {        /* byte access */
 108                odd = port & 1;
 109                port -= odd;
 110                odd <<= 11;
 111                addr = (addr | CFC_IO_MAPBASE_BYTE) + odd + (port & 0xfff);
 112        } else if (size == 2)   /* word access */
 113                addr = (addr | CFC_IO_MAPBASE_WORD) + (port & 0xfff);
 114
 115        return addr;
 116}
 117#endif  /* CONFIG_PLAT_USRV */
 118
 119void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
 120        size_t nmemb, int flag)
 121{
 122        u_long addr;
 123        unsigned char *bp = (unsigned char *)buf;
 124        unsigned long flags;
 125
 126        debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
 127                 "size=%u, nmemb=%d, flag=%d\n",
 128                  sock, port, buf, size, nmemb, flag);
 129
 130        addr = pcc_port2addr(port, 1);
 131        if (!addr) {
 132                printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
 133                return;
 134        }
 135        debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
 136
 137        spin_lock_irqsave(&pcc_lock, flags);
 138        /* read Byte */
 139        while (nmemb--)
 140                *bp++ = readb(addr);
 141        spin_unlock_irqrestore(&pcc_lock, flags);
 142}
 143
 144void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
 145        size_t nmemb, int flag)
 146{
 147        u_long addr;
 148        unsigned short *bp = (unsigned short *)buf;
 149        unsigned long flags;
 150
 151        debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
 152                 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
 153                 sock, port, buf, size, nmemb, flag);
 154
 155        if (size != 2)
 156                printk("m32r_cfc: ioread_word :illigal size %u : %#lx\n", size,
 157                        port);
 158        if (size == 9)
 159                printk("m32r_cfc: ioread_word :insw \n");
 160
 161        addr = pcc_port2addr(port, 2);
 162        if (!addr) {
 163                printk("m32r_cfc:ioread_word null port :%#lx\n",port);
 164                return;
 165        }
 166        debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
 167
 168        spin_lock_irqsave(&pcc_lock, flags);
 169        /* read Word */
 170        while (nmemb--)
 171                *bp++ = readw(addr);
 172        spin_unlock_irqrestore(&pcc_lock, flags);
 173}
 174
 175void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
 176        size_t nmemb, int flag)
 177{
 178        u_long addr;
 179        unsigned char *bp = (unsigned char *)buf;
 180        unsigned long flags;
 181
 182        debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
 183                 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
 184                 sock, port, buf, size, nmemb, flag);
 185
 186        /* write Byte */
 187        addr = pcc_port2addr(port, 1);
 188        if (!addr) {
 189                printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
 190                return;
 191        }
 192        debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
 193
 194        spin_lock_irqsave(&pcc_lock, flags);
 195        while (nmemb--)
 196                writeb(*bp++, addr);
 197        spin_unlock_irqrestore(&pcc_lock, flags);
 198}
 199
 200void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
 201        size_t nmemb, int flag)
 202{
 203        u_long addr;
 204        unsigned short *bp = (unsigned short *)buf;
 205        unsigned long flags;
 206
 207        debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
 208                 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
 209                 sock, port, buf, size, nmemb, flag);
 210
 211        if(size != 2)
 212                printk("m32r_cfc: iowrite_word :illigal size %u : %#lx\n",
 213                        size, port);
 214        if(size == 9)
 215                printk("m32r_cfc: iowrite_word :outsw \n");
 216
 217        addr = pcc_port2addr(port, 2);
 218        if (!addr) {
 219                printk("m32r_cfc:iowrite_word null addr :%#lx\n",port);
 220                return;
 221        }
 222#if 1
 223        if (addr & 1) {
 224                printk("m32r_cfc:iowrite_word port addr (%#lx):%#lx\n", port,
 225                        addr);
 226                return;
 227        }
 228#endif
 229        debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
 230
 231        spin_lock_irqsave(&pcc_lock, flags);
 232        while (nmemb--)
 233                writew(*bp++, addr);
 234        spin_unlock_irqrestore(&pcc_lock, flags);
 235}
 236
 237/*====================================================================*/
 238
 239#define IS_REGISTERED           0x2000
 240#define IS_ALIVE                0x8000
 241
 242typedef struct pcc_t {
 243        char                    *name;
 244        u_short                 flags;
 245} pcc_t;
 246
 247static pcc_t pcc[] = {
 248#if !defined(CONFIG_PLAT_USRV)
 249        { "m32r_cfc", 0 }, { "", 0 },
 250#else   /* CONFIG_PLAT_USRV */
 251        { "m32r_cfc", 0 }, { "m32r_cfc", 0 }, { "m32r_cfc", 0 },
 252        { "m32r_cfc", 0 }, { "m32r_cfc", 0 }, { "", 0 },
 253#endif  /* CONFIG_PLAT_USRV */
 254};
 255
 256static irqreturn_t pcc_interrupt(int, void *);
 257
 258/*====================================================================*/
 259
 260static struct timer_list poll_timer;
 261
 262static unsigned int pcc_get(u_short sock, unsigned int reg)
 263{
 264        unsigned int val = inw(reg);
 265        debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
 266        return val;
 267}
 268
 269
 270static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
 271{
 272        outw(data, reg);
 273        debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
 274}
 275
 276/*======================================================================
 277
 278        See if a card is present, powered up, in IO mode, and already
 279        bound to a (non PC Card) Linux driver.  We leave these alone.
 280
 281        We make an exception for cards that seem to be serial devices.
 282
 283======================================================================*/
 284
 285static int __init is_alive(u_short sock)
 286{
 287        unsigned int stat;
 288
 289        debug(3, "m32r_cfc: is_alive:\n");
 290
 291        printk("CF: ");
 292        stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
 293        if (!stat)
 294                printk("No ");
 295        printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
 296        debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
 297
 298        return 0;
 299}
 300
 301static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
 302                           unsigned int ioaddr)
 303{
 304        pcc_socket_t *t = &socket[pcc_sockets];
 305
 306        debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
 307                 "mapaddr=%#lx, ioaddr=%08x\n",
 308                 base, irq, mapaddr, ioaddr);
 309
 310        /* add sockets */
 311        t->ioaddr = ioaddr;
 312        t->mapaddr = mapaddr;
 313#if !defined(CONFIG_PLAT_USRV)
 314        t->base = 0;
 315        t->flags = 0;
 316        t->cs_irq1 = irq;               // insert irq
 317        t->cs_irq2 = irq + 1;           // eject irq
 318#else   /* CONFIG_PLAT_USRV */
 319        t->base = base;
 320        t->flags = 0;
 321        t->cs_irq1 = 0;                 // insert irq
 322        t->cs_irq2 = 0;                 // eject irq
 323#endif  /* CONFIG_PLAT_USRV */
 324
 325        if (is_alive(pcc_sockets))
 326                t->flags |= IS_ALIVE;
 327
 328        /* add pcc */
 329#if !defined(CONFIG_PLAT_USRV)
 330        request_region((unsigned int)PLD_CFRSTCR, 0x20, "m32r_cfc");
 331#else   /* CONFIG_PLAT_USRV */
 332        {
 333                unsigned int reg_base;
 334
 335                reg_base = (unsigned int)PLD_CFRSTCR;
 336                reg_base |= pcc_sockets << 8;
 337                request_region(reg_base, 0x20, "m32r_cfc");
 338        }
 339#endif  /* CONFIG_PLAT_USRV */
 340        printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
 341        printk("pcc at 0x%08lx\n", t->base);
 342
 343        /* Update socket interrupt information, capabilities */
 344        t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
 345        t->socket.map_size = M32R_PCC_MAPSIZE;
 346        t->socket.io_offset = ioaddr;   /* use for io access offset */
 347        t->socket.irq_mask = 0;
 348#if !defined(CONFIG_PLAT_USRV)
 349        t->socket.pci_irq = PLD_IRQ_CFIREQ ;    /* card interrupt */
 350#else   /* CONFIG_PLAT_USRV */
 351        t->socket.pci_irq = PLD_IRQ_CF0 + pcc_sockets;
 352#endif  /* CONFIG_PLAT_USRV */
 353
 354#ifndef CONFIG_PLAT_USRV
 355        /* insert interrupt */
 356        request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
 357#ifndef CONFIG_PLAT_MAPPI3
 358        /* eject interrupt */
 359        request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
 360#endif
 361        debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
 362        pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
 363#endif  /* CONFIG_PLAT_USRV */
 364#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
 365        pcc_set(pcc_sockets, (unsigned int)PLD_CFCR1, 0x0200);
 366#endif
 367        pcc_sockets++;
 368
 369        return;
 370}
 371
 372
 373/*====================================================================*/
 374
 375static irqreturn_t pcc_interrupt(int irq, void *dev)
 376{
 377        int i;
 378        u_int events = 0;
 379        int handled = 0;
 380
 381        debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
 382        for (i = 0; i < pcc_sockets; i++) {
 383                if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
 384                        continue;
 385
 386                handled = 1;
 387                debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
 388                        i, irq);
 389                events |= SS_DETECT;    /* insert or eject */
 390                if (events)
 391                        pcmcia_parse_events(&socket[i].socket, events);
 392        }
 393        debug(3, "m32r_cfc: pcc_interrupt: done\n");
 394
 395        return IRQ_RETVAL(handled);
 396} /* pcc_interrupt */
 397
 398static void pcc_interrupt_wrapper(u_long data)
 399{
 400        debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
 401        pcc_interrupt(0, NULL);
 402        init_timer(&poll_timer);
 403        poll_timer.expires = jiffies + poll_interval;
 404        add_timer(&poll_timer);
 405}
 406
 407/*====================================================================*/
 408
 409static int _pcc_get_status(u_short sock, u_int *value)
 410{
 411        u_int status;
 412
 413        debug(3, "m32r_cfc: _pcc_get_status:\n");
 414        status = pcc_get(sock, (unsigned int)PLD_CFSTS);
 415        *value = (status) ? SS_DETECT : 0;
 416        debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
 417
 418#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
 419        if ( status ) {
 420                /* enable CF power */
 421                status = inw((unsigned int)PLD_CPCR);
 422                if (!(status & PLD_CPCR_CF)) {
 423                        debug(3, "m32r_cfc: _pcc_get_status: "
 424                                 "power on (CPCR=0x%08x)\n", status);
 425                        status |= PLD_CPCR_CF;
 426                        outw(status, (unsigned int)PLD_CPCR);
 427                        udelay(100);
 428                }
 429                *value |= SS_POWERON;
 430
 431                pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
 432                udelay(100);
 433
 434                *value |= SS_READY;             /* always ready */
 435                *value |= SS_3VCARD;
 436        } else {
 437                /* disable CF power */
 438                status = inw((unsigned int)PLD_CPCR);
 439                status &= ~PLD_CPCR_CF;
 440                outw(status, (unsigned int)PLD_CPCR);
 441                udelay(100);
 442                debug(3, "m32r_cfc: _pcc_get_status: "
 443                         "power off (CPCR=0x%08x)\n", status);
 444        }
 445#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 446        if ( status ) {
 447                status = pcc_get(sock, (unsigned int)PLD_CPCR);
 448                if (status == 0) { /* power off */
 449                        pcc_set(sock, (unsigned int)PLD_CPCR, 1);
 450                        pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
 451                        udelay(50);
 452                }
 453                *value |= SS_POWERON;
 454
 455                pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
 456                udelay(50);
 457                pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
 458                udelay(25); /* for IDE reset */
 459                pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
 460                mdelay(2);  /* for IDE reset */
 461
 462                *value |= SS_READY;
 463                *value |= SS_3VCARD;
 464        } else {
 465                /* disable CF power */
 466                pcc_set(sock, (unsigned int)PLD_CPCR, 0);
 467                udelay(100);
 468                debug(3, "m32r_cfc: _pcc_get_status: "
 469                         "power off (CPCR=0x%08x)\n", status);
 470        }
 471#else
 472#error no platform configuration
 473#endif
 474        debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
 475                 sock, *value);
 476        return 0;
 477} /* _get_status */
 478
 479/*====================================================================*/
 480
 481static int _pcc_set_socket(u_short sock, socket_state_t *state)
 482{
 483        debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 484                  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
 485                  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 486
 487#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 488        if (state->Vcc) {
 489                if ((state->Vcc != 50) && (state->Vcc != 33))
 490                        return -EINVAL;
 491                /* accept 5V and 3.3V */
 492        }
 493#endif
 494        if (state->flags & SS_RESET) {
 495                debug(3, ":RESET\n");
 496                pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
 497        }else{
 498                pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
 499        }
 500        if (state->flags & SS_OUTPUT_ENA){
 501                debug(3, ":OUTPUT_ENA\n");
 502                /* bit clear */
 503                pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
 504        } else {
 505                pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
 506        }
 507
 508#ifdef CONFIG_PCMCIA_DEBUG
 509        if(state->flags & SS_IOCARD){
 510                debug(3, ":IOCARD");
 511        }
 512        if (state->flags & SS_PWR_AUTO) {
 513                debug(3, ":PWR_AUTO");
 514        }
 515        if (state->csc_mask & SS_DETECT)
 516                debug(3, ":csc-SS_DETECT");
 517        if (state->flags & SS_IOCARD) {
 518                if (state->csc_mask & SS_STSCHG)
 519                        debug(3, ":STSCHG");
 520        } else {
 521                if (state->csc_mask & SS_BATDEAD)
 522                        debug(3, ":BATDEAD");
 523                if (state->csc_mask & SS_BATWARN)
 524                        debug(3, ":BATWARN");
 525                if (state->csc_mask & SS_READY)
 526                        debug(3, ":READY");
 527        }
 528        debug(3, "\n");
 529#endif
 530        return 0;
 531} /* _set_socket */
 532
 533/*====================================================================*/
 534
 535static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
 536{
 537        u_char map;
 538
 539        debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
 540                  "%#lx-%#lx)\n", sock, io->map, io->flags,
 541                  io->speed, io->start, io->stop);
 542        map = io->map;
 543
 544        return 0;
 545} /* _set_io_map */
 546
 547/*====================================================================*/
 548
 549static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 550{
 551
 552        u_char map = mem->map;
 553        u_long addr;
 554        pcc_socket_t *t = &socket[sock];
 555
 556        debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
 557                 "%#lx, %#x)\n", sock, map, mem->flags,
 558                 mem->speed, mem->static_start, mem->card_start);
 559
 560        /*
 561         * sanity check
 562         */
 563        if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
 564                return -EINVAL;
 565        }
 566
 567        /*
 568         * de-activate
 569         */
 570        if ((mem->flags & MAP_ACTIVE) == 0) {
 571                t->current_space = as_none;
 572                return 0;
 573        }
 574
 575        /*
 576         * Set mode
 577         */
 578        if (mem->flags & MAP_ATTRIB) {
 579                t->current_space = as_attr;
 580        } else {
 581                t->current_space = as_comm;
 582        }
 583
 584        /*
 585         * Set address
 586         */
 587        addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
 588        mem->static_start = addr + mem->card_start;
 589
 590        return 0;
 591
 592} /* _set_mem_map */
 593
 594#if 0 /* driver model ordering issue */
 595/*======================================================================
 596
 597        Routines for accessing socket information and register dumps via
 598        /proc/bus/pccard/...
 599
 600======================================================================*/
 601
 602static ssize_t show_info(struct class_device *class_dev, char *buf)
 603{
 604        pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
 605                socket.dev);
 606
 607        return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
 608                pcc[s->type].name, s->base);
 609}
 610
 611static ssize_t show_exca(struct class_device *class_dev, char *buf)
 612{
 613        /* FIXME */
 614
 615        return 0;
 616}
 617
 618static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
 619static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
 620#endif
 621
 622/*====================================================================*/
 623
 624/* this is horribly ugly... proper locking needs to be done here at
 625 * some time... */
 626#define LOCKED(x) do {                                  \
 627        int retval;                                     \
 628        unsigned long flags;                            \
 629        spin_lock_irqsave(&pcc_lock, flags);            \
 630        retval = x;                                     \
 631        spin_unlock_irqrestore(&pcc_lock, flags);       \
 632        return retval;                                  \
 633} while (0)
 634
 635
 636static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
 637{
 638        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 639
 640        if (socket[sock].flags & IS_ALIVE) {
 641                debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
 642                *value = 0;
 643                return -EINVAL;
 644        }
 645        debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
 646        LOCKED(_pcc_get_status(sock, value));
 647}
 648
 649static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 650{
 651        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 652
 653        if (socket[sock].flags & IS_ALIVE) {
 654                debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
 655                return -EINVAL;
 656        }
 657        debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
 658        LOCKED(_pcc_set_socket(sock, state));
 659}
 660
 661static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
 662{
 663        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 664
 665        if (socket[sock].flags & IS_ALIVE) {
 666                debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
 667                return -EINVAL;
 668        }
 669        debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
 670        LOCKED(_pcc_set_io_map(sock, io));
 671}
 672
 673static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
 674{
 675        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 676
 677        if (socket[sock].flags & IS_ALIVE) {
 678                debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
 679                return -EINVAL;
 680        }
 681        debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
 682        LOCKED(_pcc_set_mem_map(sock, mem));
 683}
 684
 685static int pcc_init(struct pcmcia_socket *s)
 686{
 687        debug(3, "m32r_cfc: pcc_init()\n");
 688        return 0;
 689}
 690
 691static struct pccard_operations pcc_operations = {
 692        .init                   = pcc_init,
 693        .get_status             = pcc_get_status,
 694        .set_socket             = pcc_set_socket,
 695        .set_io_map             = pcc_set_io_map,
 696        .set_mem_map            = pcc_set_mem_map,
 697};
 698
 699/*====================================================================*/
 700
 701static struct device_driver pcc_driver = {
 702        .name = "cfc",
 703        .bus = &platform_bus_type,
 704        .suspend = pcmcia_socket_dev_suspend,
 705        .resume = pcmcia_socket_dev_resume,
 706};
 707
 708static struct platform_device pcc_device = {
 709        .name = "cfc",
 710        .id = 0,
 711};
 712
 713/*====================================================================*/
 714
 715static int __init init_m32r_pcc(void)
 716{
 717        int i, ret;
 718
 719        ret = driver_register(&pcc_driver);
 720        if (ret)
 721                return ret;
 722
 723        ret = platform_device_register(&pcc_device);
 724        if (ret){
 725                driver_unregister(&pcc_driver);
 726                return ret;
 727        }
 728
 729#if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 730        pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
 731        pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
 732#endif
 733
 734        pcc_sockets = 0;
 735
 736#if !defined(CONFIG_PLAT_USRV)
 737        add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
 738                       CFC_IOPORT_BASE);
 739#else   /* CONFIG_PLAT_USRV */
 740        {
 741                ulong base, mapaddr;
 742                unsigned int ioaddr;
 743
 744                for (i = 0 ; i < M32R_MAX_PCC ; i++) {
 745                        base = (ulong)PLD_CFRSTCR;
 746                        base = base | (i << 8);
 747                        ioaddr = (i + 1) << 12;
 748                        mapaddr = CFC_ATTR_MAPBASE | (i << 20);
 749                        add_pcc_socket(base, 0, mapaddr, ioaddr);
 750                }
 751        }
 752#endif  /* CONFIG_PLAT_USRV */
 753
 754        if (pcc_sockets == 0) {
 755                printk("socket is not found.\n");
 756                platform_device_unregister(&pcc_device);
 757                driver_unregister(&pcc_driver);
 758                return -ENODEV;
 759        }
 760
 761        /* Set up interrupt handler(s) */
 762
 763        for (i = 0 ; i < pcc_sockets ; i++) {
 764                socket[i].socket.dev.parent = &pcc_device.dev;
 765                socket[i].socket.ops = &pcc_operations;
 766                socket[i].socket.resource_ops = &pccard_nonstatic_ops;
 767                socket[i].socket.owner = THIS_MODULE;
 768                socket[i].number = i;
 769                ret = pcmcia_register_socket(&socket[i].socket);
 770                if (!ret)
 771                        socket[i].flags |= IS_REGISTERED;
 772
 773#if 0   /* driver model ordering issue */
 774                class_device_create_file(&socket[i].socket.dev,
 775                                         &class_device_attr_info);
 776                class_device_create_file(&socket[i].socket.dev,
 777                                         &class_device_attr_exca);
 778#endif
 779        }
 780
 781        /* Finally, schedule a polling interrupt */
 782        if (poll_interval != 0) {
 783                poll_timer.function = pcc_interrupt_wrapper;
 784                poll_timer.data = 0;
 785                init_timer(&poll_timer);
 786                poll_timer.expires = jiffies + poll_interval;
 787                add_timer(&poll_timer);
 788        }
 789
 790        return 0;
 791} /* init_m32r_pcc */
 792
 793static void __exit exit_m32r_pcc(void)
 794{
 795        int i;
 796
 797        for (i = 0; i < pcc_sockets; i++)
 798                if (socket[i].flags & IS_REGISTERED)
 799                        pcmcia_unregister_socket(&socket[i].socket);
 800
 801        platform_device_unregister(&pcc_device);
 802        if (poll_interval != 0)
 803                del_timer_sync(&poll_timer);
 804
 805        driver_unregister(&pcc_driver);
 806} /* exit_m32r_pcc */
 807
 808module_init(init_m32r_pcc);
 809module_exit(exit_m32r_pcc);
 810MODULE_LICENSE("Dual MPL/GPL");
 811/*====================================================================*/
 812