OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [pcmcia/] [m32r_cfc.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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 DEBUG
42
static int m32r_cfc_debug;
43
module_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 */
53
static int poll_interval = 0;
54
 
55
typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
56
 
57
typedef struct pcc_socket {
58
        u_short                 type, flags;
59
        struct pcmcia_socket    socket;
60
        unsigned int            number;
61
        kio_addr_t              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
 
76
static int pcc_sockets = 0;
77
static pcc_socket_t socket[M32R_MAX_PCC] = {
78
        { 0, }, /* ... */
79
};
80
 
81
/*====================================================================*/
82
 
83
static unsigned int pcc_get(u_short, unsigned int);
84
static void pcc_set(u_short, unsigned int , unsigned int );
85
 
86
static DEFINE_SPINLOCK(pcc_lock);
87
 
88
#if !defined(CONFIG_PLAT_USRV)
89
static 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 */
103
static 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
 
119
void 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
 
144
void 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
 
175
void 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
 
200
void 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
 
242
typedef struct pcc_t {
243
        char                    *name;
244
        u_short                 flags;
245
} pcc_t;
246
 
247
static 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
 
256
static irqreturn_t pcc_interrupt(int, void *);
257
 
258
/*====================================================================*/
259
 
260
static struct timer_list poll_timer;
261
 
262
static 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
 
270
static 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
 
285
static 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
 
301
static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr)
302
{
303
        pcc_socket_t *t = &socket[pcc_sockets];
304
 
305
        debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
306
                 "mapaddr=%#lx, ioaddr=%08x\n",
307
                 base, irq, mapaddr, ioaddr);
308
 
309
        /* add sockets */
310
        t->ioaddr = ioaddr;
311
        t->mapaddr = mapaddr;
312
#if !defined(CONFIG_PLAT_USRV)
313
        t->base = 0;
314
        t->flags = 0;
315
        t->cs_irq1 = irq;               // insert irq
316
        t->cs_irq2 = irq + 1;           // eject irq
317
#else   /* CONFIG_PLAT_USRV */
318
        t->base = base;
319
        t->flags = 0;
320
        t->cs_irq1 = 0;                  // insert irq
321
        t->cs_irq2 = 0;                  // eject irq
322
#endif  /* CONFIG_PLAT_USRV */
323
 
324
        if (is_alive(pcc_sockets))
325
                t->flags |= IS_ALIVE;
326
 
327
        /* add pcc */
328
#if !defined(CONFIG_PLAT_USRV)
329
        request_region((unsigned int)PLD_CFRSTCR, 0x20, "m32r_cfc");
330
#else   /* CONFIG_PLAT_USRV */
331
        {
332
                unsigned int reg_base;
333
 
334
                reg_base = (unsigned int)PLD_CFRSTCR;
335
                reg_base |= pcc_sockets << 8;
336
                request_region(reg_base, 0x20, "m32r_cfc");
337
        }
338
#endif  /* CONFIG_PLAT_USRV */
339
        printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
340
        printk("pcc at 0x%08lx\n", t->base);
341
 
342
        /* Update socket interrupt information, capabilities */
343
        t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
344
        t->socket.map_size = M32R_PCC_MAPSIZE;
345
        t->socket.io_offset = ioaddr;   /* use for io access offset */
346
        t->socket.irq_mask = 0;
347
#if !defined(CONFIG_PLAT_USRV)
348
        t->socket.pci_irq = PLD_IRQ_CFIREQ ;    /* card interrupt */
349
#else   /* CONFIG_PLAT_USRV */
350
        t->socket.pci_irq = PLD_IRQ_CF0 + pcc_sockets;
351
#endif  /* CONFIG_PLAT_USRV */
352
 
353
#ifndef CONFIG_PLAT_USRV
354
        /* insert interrupt */
355
        request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
356
#ifndef CONFIG_PLAT_MAPPI3
357
        /* eject interrupt */
358
        request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
359
#endif
360
        debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
361
        pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
362
#endif  /* CONFIG_PLAT_USRV */
363
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
364
        pcc_set(pcc_sockets, (unsigned int)PLD_CFCR1, 0x0200);
365
#endif
366
        pcc_sockets++;
367
 
368
        return;
369
}
370
 
371
 
372
/*====================================================================*/
373
 
374
static irqreturn_t pcc_interrupt(int irq, void *dev)
375
{
376
        int i;
377
        u_int events = 0;
378
        int handled = 0;
379
 
380
        debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
381
        for (i = 0; i < pcc_sockets; i++) {
382
                if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
383
                        continue;
384
 
385
                handled = 1;
386
                debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
387
                        i, irq);
388
                events |= SS_DETECT;    /* insert or eject */
389
                if (events)
390
                        pcmcia_parse_events(&socket[i].socket, events);
391
        }
392
        debug(3, "m32r_cfc: pcc_interrupt: done\n");
393
 
394
        return IRQ_RETVAL(handled);
395
} /* pcc_interrupt */
396
 
397
static void pcc_interrupt_wrapper(u_long data)
398
{
399
        debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
400
        pcc_interrupt(0, NULL);
401
        init_timer(&poll_timer);
402
        poll_timer.expires = jiffies + poll_interval;
403
        add_timer(&poll_timer);
404
}
405
 
406
/*====================================================================*/
407
 
408
static int _pcc_get_status(u_short sock, u_int *value)
409
{
410
        u_int status;
411
 
412
        debug(3, "m32r_cfc: _pcc_get_status:\n");
413
        status = pcc_get(sock, (unsigned int)PLD_CFSTS);
414
        *value = (status) ? SS_DETECT : 0;
415
        debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
416
 
417
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
418
        if ( status ) {
419
                /* enable CF power */
420
                status = inw((unsigned int)PLD_CPCR);
421
                if (!(status & PLD_CPCR_CF)) {
422
                        debug(3, "m32r_cfc: _pcc_get_status: "
423
                                 "power on (CPCR=0x%08x)\n", status);
424
                        status |= PLD_CPCR_CF;
425
                        outw(status, (unsigned int)PLD_CPCR);
426
                        udelay(100);
427
                }
428
                *value |= SS_POWERON;
429
 
430
                pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
431
                udelay(100);
432
 
433
                *value |= SS_READY;             /* always ready */
434
                *value |= SS_3VCARD;
435
        } else {
436
                /* disable CF power */
437
                status = inw((unsigned int)PLD_CPCR);
438
                status &= ~PLD_CPCR_CF;
439
                outw(status, (unsigned int)PLD_CPCR);
440
                udelay(100);
441
                debug(3, "m32r_cfc: _pcc_get_status: "
442
                         "power off (CPCR=0x%08x)\n", status);
443
        }
444
#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
445
        if ( status ) {
446
                status = pcc_get(sock, (unsigned int)PLD_CPCR);
447
                if (status == 0) { /* power off */
448
                        pcc_set(sock, (unsigned int)PLD_CPCR, 1);
449
                        pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
450
                        udelay(50);
451
                }
452
                *value |= SS_POWERON;
453
 
454
                pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
455
                udelay(50);
456
                pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
457
                udelay(25); /* for IDE reset */
458
                pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
459
                mdelay(2);  /* for IDE reset */
460
 
461
                *value |= SS_READY;
462
                *value |= SS_3VCARD;
463
        } else {
464
                /* disable CF power */
465
                pcc_set(sock, (unsigned int)PLD_CPCR, 0);
466
                udelay(100);
467
                debug(3, "m32r_cfc: _pcc_get_status: "
468
                         "power off (CPCR=0x%08x)\n", status);
469
        }
470
#else
471
#error no platform configuration
472
#endif
473
        debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
474
                 sock, *value);
475
        return 0;
476
} /* _get_status */
477
 
478
/*====================================================================*/
479
 
480
static int _pcc_set_socket(u_short sock, socket_state_t *state)
481
{
482
        debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
483
                  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
484
                  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
485
 
486
#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
487
        if (state->Vcc) {
488
                if ((state->Vcc != 50) && (state->Vcc != 33))
489
                        return -EINVAL;
490
                /* accept 5V and 3.3V */
491
        }
492
#endif
493
        if (state->flags & SS_RESET) {
494
                debug(3, ":RESET\n");
495
                pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
496
        }else{
497
                pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
498
        }
499
        if (state->flags & SS_OUTPUT_ENA){
500
                debug(3, ":OUTPUT_ENA\n");
501
                /* bit clear */
502
                pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
503
        } else {
504
                pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
505
        }
506
 
507
#ifdef DEBUG
508
        if(state->flags & SS_IOCARD){
509
                debug(3, ":IOCARD");
510
        }
511
        if (state->flags & SS_PWR_AUTO) {
512
                debug(3, ":PWR_AUTO");
513
        }
514
        if (state->csc_mask & SS_DETECT)
515
                debug(3, ":csc-SS_DETECT");
516
        if (state->flags & SS_IOCARD) {
517
                if (state->csc_mask & SS_STSCHG)
518
                        debug(3, ":STSCHG");
519
        } else {
520
                if (state->csc_mask & SS_BATDEAD)
521
                        debug(3, ":BATDEAD");
522
                if (state->csc_mask & SS_BATWARN)
523
                        debug(3, ":BATWARN");
524
                if (state->csc_mask & SS_READY)
525
                        debug(3, ":READY");
526
        }
527
        debug(3, "\n");
528
#endif
529
        return 0;
530
} /* _set_socket */
531
 
532
/*====================================================================*/
533
 
534
static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
535
{
536
        u_char map;
537
 
538
        debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
539
                  "%#lx-%#lx)\n", sock, io->map, io->flags,
540
                  io->speed, io->start, io->stop);
541
        map = io->map;
542
 
543
        return 0;
544
} /* _set_io_map */
545
 
546
/*====================================================================*/
547
 
548
static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
549
{
550
 
551
        u_char map = mem->map;
552
        u_long addr;
553
        pcc_socket_t *t = &socket[sock];
554
 
555
        debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
556
                 "%#lx, %#x)\n", sock, map, mem->flags,
557
                 mem->speed, mem->static_start, mem->card_start);
558
 
559
        /*
560
         * sanity check
561
         */
562
        if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
563
                return -EINVAL;
564
        }
565
 
566
        /*
567
         * de-activate
568
         */
569
        if ((mem->flags & MAP_ACTIVE) == 0) {
570
                t->current_space = as_none;
571
                return 0;
572
        }
573
 
574
        /*
575
         * Set mode
576
         */
577
        if (mem->flags & MAP_ATTRIB) {
578
                t->current_space = as_attr;
579
        } else {
580
                t->current_space = as_comm;
581
        }
582
 
583
        /*
584
         * Set address
585
         */
586
        addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
587
        mem->static_start = addr + mem->card_start;
588
 
589
        return 0;
590
 
591
} /* _set_mem_map */
592
 
593
#if 0 /* driver model ordering issue */
594
/*======================================================================
595
 
596
        Routines for accessing socket information and register dumps via
597
        /proc/bus/pccard/...
598
 
599
======================================================================*/
600
 
601
static ssize_t show_info(struct class_device *class_dev, char *buf)
602
{
603
        pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
604
                socket.dev);
605
 
606
        return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
607
                pcc[s->type].name, s->base);
608
}
609
 
610
static ssize_t show_exca(struct class_device *class_dev, char *buf)
611
{
612
        /* FIXME */
613
 
614
        return 0;
615
}
616
 
617
static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
618
static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
619
#endif
620
 
621
/*====================================================================*/
622
 
623
/* this is horribly ugly... proper locking needs to be done here at
624
 * some time... */
625
#define LOCKED(x) do {                                  \
626
        int retval;                                     \
627
        unsigned long flags;                            \
628
        spin_lock_irqsave(&pcc_lock, flags);            \
629
        retval = x;                                     \
630
        spin_unlock_irqrestore(&pcc_lock, flags);       \
631
        return retval;                                  \
632
} while (0)
633
 
634
 
635
static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
636
{
637
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
638
 
639
        if (socket[sock].flags & IS_ALIVE) {
640
                debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
641
                *value = 0;
642
                return -EINVAL;
643
        }
644
        debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
645
        LOCKED(_pcc_get_status(sock, value));
646
}
647
 
648
static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
649
{
650
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
651
 
652
        if (socket[sock].flags & IS_ALIVE) {
653
                debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
654
                return -EINVAL;
655
        }
656
        debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
657
        LOCKED(_pcc_set_socket(sock, state));
658
}
659
 
660
static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
661
{
662
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
663
 
664
        if (socket[sock].flags & IS_ALIVE) {
665
                debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
666
                return -EINVAL;
667
        }
668
        debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
669
        LOCKED(_pcc_set_io_map(sock, io));
670
}
671
 
672
static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
673
{
674
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
675
 
676
        if (socket[sock].flags & IS_ALIVE) {
677
                debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
678
                return -EINVAL;
679
        }
680
        debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
681
        LOCKED(_pcc_set_mem_map(sock, mem));
682
}
683
 
684
static int pcc_init(struct pcmcia_socket *s)
685
{
686
        debug(3, "m32r_cfc: pcc_init()\n");
687
        return 0;
688
}
689
 
690
static struct pccard_operations pcc_operations = {
691
        .init                   = pcc_init,
692
        .get_status             = pcc_get_status,
693
        .set_socket             = pcc_set_socket,
694
        .set_io_map             = pcc_set_io_map,
695
        .set_mem_map            = pcc_set_mem_map,
696
};
697
 
698
/*====================================================================*/
699
 
700
static struct device_driver pcc_driver = {
701
        .name = "cfc",
702
        .bus = &platform_bus_type,
703
        .suspend = pcmcia_socket_dev_suspend,
704
        .resume = pcmcia_socket_dev_resume,
705
};
706
 
707
static struct platform_device pcc_device = {
708
        .name = "cfc",
709
        .id = 0,
710
};
711
 
712
/*====================================================================*/
713
 
714
static int __init init_m32r_pcc(void)
715
{
716
        int i, ret;
717
 
718
        ret = driver_register(&pcc_driver);
719
        if (ret)
720
                return ret;
721
 
722
        ret = platform_device_register(&pcc_device);
723
        if (ret){
724
                driver_unregister(&pcc_driver);
725
                return ret;
726
        }
727
 
728
#if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
729
        pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
730
        pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
731
#endif
732
 
733
        pcc_sockets = 0;
734
 
735
#if !defined(CONFIG_PLAT_USRV)
736
        add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
737
                       CFC_IOPORT_BASE);
738
#else   /* CONFIG_PLAT_USRV */
739
        {
740
                ulong base, mapaddr;
741
                kio_addr_t ioaddr;
742
 
743
                for (i = 0 ; i < M32R_MAX_PCC ; i++) {
744
                        base = (ulong)PLD_CFRSTCR;
745
                        base = base | (i << 8);
746
                        ioaddr = (i + 1) << 12;
747
                        mapaddr = CFC_ATTR_MAPBASE | (i << 20);
748
                        add_pcc_socket(base, 0, mapaddr, ioaddr);
749
                }
750
        }
751
#endif  /* CONFIG_PLAT_USRV */
752
 
753
        if (pcc_sockets == 0) {
754
                printk("socket is not found.\n");
755
                platform_device_unregister(&pcc_device);
756
                driver_unregister(&pcc_driver);
757
                return -ENODEV;
758
        }
759
 
760
        /* Set up interrupt handler(s) */
761
 
762
        for (i = 0 ; i < pcc_sockets ; i++) {
763
                socket[i].socket.dev.parent = &pcc_device.dev;
764
                socket[i].socket.ops = &pcc_operations;
765
                socket[i].socket.resource_ops = &pccard_nonstatic_ops;
766
                socket[i].socket.owner = THIS_MODULE;
767
                socket[i].number = i;
768
                ret = pcmcia_register_socket(&socket[i].socket);
769
                if (!ret)
770
                        socket[i].flags |= IS_REGISTERED;
771
 
772
#if 0   /* driver model ordering issue */
773
                class_device_create_file(&socket[i].socket.dev,
774
                                         &class_device_attr_info);
775
                class_device_create_file(&socket[i].socket.dev,
776
                                         &class_device_attr_exca);
777
#endif
778
        }
779
 
780
        /* Finally, schedule a polling interrupt */
781
        if (poll_interval != 0) {
782
                poll_timer.function = pcc_interrupt_wrapper;
783
                poll_timer.data = 0;
784
                init_timer(&poll_timer);
785
                poll_timer.expires = jiffies + poll_interval;
786
                add_timer(&poll_timer);
787
        }
788
 
789
        return 0;
790
} /* init_m32r_pcc */
791
 
792
static void __exit exit_m32r_pcc(void)
793
{
794
        int i;
795
 
796
        for (i = 0; i < pcc_sockets; i++)
797
                if (socket[i].flags & IS_REGISTERED)
798
                        pcmcia_unregister_socket(&socket[i].socket);
799
 
800
        platform_device_unregister(&pcc_device);
801
        if (poll_interval != 0)
802
                del_timer_sync(&poll_timer);
803
 
804
        driver_unregister(&pcc_driver);
805
} /* exit_m32r_pcc */
806
 
807
module_init(init_m32r_pcc);
808
module_exit(exit_m32r_pcc);
809
MODULE_LICENSE("Dual MPL/GPL");
810
/*====================================================================*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.