]> Pileus Git - ~andy/linux/blob - drivers/staging/csr/sdio_mmc.c
Merge tag 'fbdev-updates-for-3.6' of git://github.com/schandinat/linux-2.6
[~andy/linux] / drivers / staging / csr / sdio_mmc.c
1 /*
2  * ---------------------------------------------------------------------------
3  *
4  * FILE: sdio_mmc.c
5  *
6  * PURPOSE: SDIO driver interface for generic MMC stack.
7  *
8  * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
9  *
10  * ---------------------------------------------------------------------------
11  */
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/mutex.h>
16 #include <linux/gfp.h>
17
18 #include <linux/mmc/core.h>
19 #include <linux/mmc/card.h>
20 #include <linux/mmc/host.h>
21 #include <linux/mmc/sdio_func.h>
22 #include <linux/mmc/sdio_ids.h>
23 #include <linux/mmc/sdio.h>
24 #include <linux/suspend.h>
25
26 #include "unifi_priv.h"
27
28 #ifdef ANDROID_BUILD
29 struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
30 #endif
31
32 static CsrSdioFunctionDriver *sdio_func_drv;
33
34 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
35 #ifdef CONFIG_PM
36 static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr);
37 #endif
38
39 /*
40  * We need to keep track of the power on/off because we can not call
41  * mmc_power_restore_host() when the card is already powered.
42  * Even then, we need to patch the MMC driver to add a power_restore handler
43  * in the mmc_sdio_ops structure. If the MMC driver before 2.6.37 is not patched,
44  * mmc_power_save_host() and mmc_power_restore_host() are no-ops in the kernel,
45  * returning immediately (at least on x86).
46  */
47 static int card_is_powered = 1;
48 #endif /* 2.6.32 */
49
50 /* MMC uses ENOMEDIUM to indicate card gone away */
51
52 static CsrResult
53 ConvertSdioToCsrSdioResult(int r)
54 {
55     CsrResult csrResult = CSR_RESULT_FAILURE;
56
57     switch (r) {
58     case 0:
59         csrResult = CSR_RESULT_SUCCESS;
60     break;
61     case -EIO:
62     case -EILSEQ:
63         csrResult = CSR_SDIO_RESULT_CRC_ERROR;
64     break;
65     /* Timeout errors */
66     case -ETIMEDOUT:
67     case -EBUSY:
68         csrResult = CSR_SDIO_RESULT_TIMEOUT;
69     break;
70     case -ENODEV:
71     case -ENOMEDIUM:
72         csrResult = CSR_SDIO_RESULT_NO_DEVICE;
73     break;
74     case -EINVAL:
75         csrResult = CSR_SDIO_RESULT_INVALID_VALUE;
76     break;
77     case -ENOMEM:
78     case -ENOSYS:
79     case -ERANGE:
80     case -ENXIO:
81         csrResult = CSR_RESULT_FAILURE;
82     break;
83     default:
84         unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r);
85     break;
86     }
87
88     return csrResult;
89 }
90
91
92 static int
93 csr_io_rw_direct(struct mmc_card *card, int write, uint8_t fn,
94                  uint32_t addr, uint8_t in, uint8_t* out)
95 {
96     struct mmc_command cmd;
97     int err;
98
99     BUG_ON(!card);
100     BUG_ON(fn > 7);
101
102     memset(&cmd, 0, sizeof(struct mmc_command));
103
104     cmd.opcode = SD_IO_RW_DIRECT;
105     cmd.arg = write ? 0x80000000 : 0x00000000;
106     cmd.arg |= fn << 28;
107     cmd.arg |= (write && out) ? 0x08000000 : 0x00000000;
108     cmd.arg |= addr << 9;
109     cmd.arg |= in;
110     cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
111
112     err = mmc_wait_for_cmd(card->host, &cmd, 0);
113     if (err)
114         return err;
115
116     /* this function is not exported, so we will need to sort it out here
117      * for now, lets hard code it to sdio */
118     if (0) {
119         /* old arg (mmc_host_is_spi(card->host)) { */
120         /* host driver already reported errors */
121     } else {
122         if (cmd.resp[0] & R5_ERROR) {
123             printk(KERN_ERR "%s: r5 error 0x%02x\n",
124                    __FUNCTION__, cmd.resp[0]);
125             return -EIO;
126         }
127         if (cmd.resp[0] & R5_FUNCTION_NUMBER)
128             return -EINVAL;
129         if (cmd.resp[0] & R5_OUT_OF_RANGE)
130             return -ERANGE;
131     }
132
133     if (out) {
134         if (0) {    /* old argument (mmc_host_is_spi(card->host)) */
135             *out = (cmd.resp[0] >> 8) & 0xFF;
136         }
137         else {
138             *out = cmd.resp[0] & 0xFF;
139         }
140     }
141
142     return CSR_RESULT_SUCCESS;
143 }
144
145
146 CsrResult
147 CsrSdioRead8(CsrSdioFunction *function, u32 address, u8 *data)
148 {
149     struct sdio_func *func = (struct sdio_func *)function->priv;
150     int err = 0;
151
152     _sdio_claim_host(func);
153     *data = sdio_readb(func, address, &err);
154     _sdio_release_host(func);
155
156     if (err) {
157         func_exit_r(err);
158         return ConvertSdioToCsrSdioResult(err);
159     }
160
161     return CSR_RESULT_SUCCESS;
162 } /* CsrSdioRead8() */
163
164 CsrResult
165 CsrSdioWrite8(CsrSdioFunction *function, u32 address, u8 data)
166 {
167     struct sdio_func *func = (struct sdio_func *)function->priv;
168     int err = 0;
169
170     _sdio_claim_host(func);
171     sdio_writeb(func, data, address, &err);
172     _sdio_release_host(func);
173
174     if (err) {
175         func_exit_r(err);
176         return ConvertSdioToCsrSdioResult(err);
177     }
178
179     return CSR_RESULT_SUCCESS;
180 } /* CsrSdioWrite8() */
181
182 CsrResult
183 CsrSdioRead16(CsrSdioFunction *function, u32 address, u16 *data)
184 {
185     struct sdio_func *func = (struct sdio_func *)function->priv;
186     int err;
187     uint8_t b0, b1;
188
189     _sdio_claim_host(func);
190     b0 = sdio_readb(func, address, &err);
191     if (err) {
192         _sdio_release_host(func);
193         return ConvertSdioToCsrSdioResult(err);
194     }
195
196     b1 = sdio_readb(func, address+1, &err);
197     if (err) {
198         _sdio_release_host(func);
199         return ConvertSdioToCsrSdioResult(err);
200     }
201     _sdio_release_host(func);
202
203     *data = ((uint16_t)b1 << 8) | b0;
204
205     return CSR_RESULT_SUCCESS;
206 } /* CsrSdioRead16() */
207
208
209 CsrResult
210 CsrSdioWrite16(CsrSdioFunction *function, u32 address, u16 data)
211 {
212     struct sdio_func *func = (struct sdio_func *)function->priv;
213     int err;
214     uint8_t b0, b1;
215
216     _sdio_claim_host(func);
217     b1 = (data >> 8) & 0xFF;
218     sdio_writeb(func, b1, address+1, &err);
219     if (err) {
220         _sdio_release_host(func);
221         return ConvertSdioToCsrSdioResult(err);
222     }
223
224     b0 = data & 0xFF;
225     sdio_writeb(func, b0, address, &err);
226     if (err) {
227         _sdio_release_host(func);
228         return ConvertSdioToCsrSdioResult(err);
229     }
230
231     _sdio_release_host(func);
232     return CSR_RESULT_SUCCESS;
233 } /* CsrSdioWrite16() */
234
235
236 CsrResult
237 CsrSdioF0Read8(CsrSdioFunction *function, u32 address, u8 *data)
238 {
239     struct sdio_func *func = (struct sdio_func *)function->priv;
240     int err = 0;
241
242     _sdio_claim_host(func);
243 #ifdef MMC_QUIRK_LENIENT_FN0
244     *data = sdio_f0_readb(func, address, &err);
245 #else
246     err = csr_io_rw_direct(func->card, 0, 0, address, 0, data);
247 #endif
248     _sdio_release_host(func);
249
250     if (err) {
251         func_exit_r(err);
252         return ConvertSdioToCsrSdioResult(err);
253     }
254
255     return CSR_RESULT_SUCCESS;
256 } /* CsrSdioF0Read8() */
257
258 CsrResult
259 CsrSdioF0Write8(CsrSdioFunction *function, u32 address, u8 data)
260 {
261     struct sdio_func *func = (struct sdio_func *)function->priv;
262     int err = 0;
263
264     _sdio_claim_host(func);
265 #ifdef MMC_QUIRK_LENIENT_FN0
266     sdio_f0_writeb(func, data, address, &err);
267 #else
268     err = csr_io_rw_direct(func->card, 1, 0, address, data, NULL);
269 #endif
270     _sdio_release_host(func);
271
272     if (err) {
273         func_exit_r(err);
274         return ConvertSdioToCsrSdioResult(err);
275     }
276
277     return CSR_RESULT_SUCCESS;
278 } /* CsrSdioF0Write8() */
279
280
281 CsrResult
282 CsrSdioRead(CsrSdioFunction *function, u32 address, void *data, u32 length)
283 {
284     struct sdio_func *func = (struct sdio_func *)function->priv;
285     int err;
286
287     _sdio_claim_host(func);
288     err = sdio_readsb(func, data, address, length);
289     _sdio_release_host(func);
290
291     if (err) {
292         func_exit_r(err);
293         return ConvertSdioToCsrSdioResult(err);
294     }
295
296     return CSR_RESULT_SUCCESS;
297 } /* CsrSdioRead() */
298
299 CsrResult
300 CsrSdioWrite(CsrSdioFunction *function, u32 address, const void *data, u32 length)
301 {
302     struct sdio_func *func = (struct sdio_func *)function->priv;
303     int err;
304
305     _sdio_claim_host(func);
306     err = sdio_writesb(func, address, (void*)data, length);
307     _sdio_release_host(func);
308
309     if (err) {
310         func_exit_r(err);
311         return ConvertSdioToCsrSdioResult(err);
312     }
313
314     return CSR_RESULT_SUCCESS;
315 } /* CsrSdioWrite() */
316
317
318 static int
319 csr_sdio_enable_hs(struct mmc_card *card)
320 {
321     int ret;
322     u8 speed;
323
324     if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) {
325         /* We've asked for HS clock rates, but controller doesn't
326          * claim to support it. We should limit the clock
327          * to 25MHz via module parameter.
328          */
329         printk(KERN_INFO "unifi: request HS but not MMC_CAP_SD_HIGHSPEED");
330         return 0;
331     }
332
333     if (!card->cccr.high_speed)
334         return 0;
335
336 #if 1
337     ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
338     if (ret)
339         return ret;
340
341     speed |= SDIO_SPEED_EHS;
342 #else
343     /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
344     speed = SDIO_SPEED_EHS | SDIO_SPEED_SHS;
345 #endif
346
347     ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
348     if (ret)
349         return ret;
350
351     mmc_card_set_highspeed(card);
352     card->host->ios.timing = MMC_TIMING_SD_HS;
353     card->host->ops->set_ios(card->host, &card->host->ios);
354
355     return 0;
356 }
357
358 static int
359 csr_sdio_disable_hs(struct mmc_card *card)
360 {
361     int ret;
362     u8 speed;
363
364     if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
365         return 0;
366
367     if (!card->cccr.high_speed)
368         return 0;
369 #if 1
370     ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
371     if (ret)
372         return ret;
373
374     speed &= ~SDIO_SPEED_EHS;
375 #else
376     /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
377     speed = SDIO_SPEED_SHS; /* clear SDIO_SPEED_EHS */
378 #endif
379
380     ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
381     if (ret)
382         return ret;
383
384     card->state &= ~MMC_STATE_HIGHSPEED;
385     card->host->ios.timing = MMC_TIMING_LEGACY;
386     card->host->ops->set_ios(card->host, &card->host->ios);
387
388     return 0;
389 }
390
391
392 /*
393  * ---------------------------------------------------------------------------
394  *  CsrSdioMaxBusClockFrequencySet
395  *
396  *      Set the maximum SDIO bus clock speed to use.
397  *
398  *  Arguments:
399  *      sdio            SDIO context pointer
400  *      maxFrequency         maximum clock speed in Hz
401  *
402  *  Returns:
403  *      an error code.
404  * ---------------------------------------------------------------------------
405  */
406 CsrResult
407 CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, u32 maxFrequency)
408 {
409     struct sdio_func *func = (struct sdio_func *)function->priv;
410     struct mmc_host *host = func->card->host;
411     struct mmc_ios *ios = &host->ios;
412     unsigned int max_hz;
413     int err;
414         u32 max_khz = maxFrequency/1000;
415
416     if (!max_khz || max_khz > sdio_clock) {
417         max_khz = sdio_clock;
418     }
419
420     _sdio_claim_host(func);
421     max_hz = 1000 * max_khz;
422     if (max_hz > host->f_max) {
423         max_hz = host->f_max;
424     }
425
426     if (max_hz > 25000000) {
427         err = csr_sdio_enable_hs(func->card);
428     } else {
429         err = csr_sdio_disable_hs(func->card);
430     }
431     if (err) {
432         printk(KERN_ERR "SDIO warning: Failed to configure SDIO clock mode\n");
433         _sdio_release_host(func);
434                 return CSR_RESULT_SUCCESS;
435     }
436
437     ios->clock = max_hz;
438     host->ops->set_ios(host, ios);
439
440     _sdio_release_host(func);
441
442         return CSR_RESULT_SUCCESS;
443 } /* CsrSdioMaxBusClockFrequencySet() */
444
445
446 /*
447  * ---------------------------------------------------------------------------
448  *  CsrSdioInterruptEnable
449  *  CsrSdioInterruptDisable
450  *
451  *      Enable or disable the SDIO interrupt.
452  *      The driver disables the SDIO interrupt until the i/o thread can
453  *      process it.
454  *      The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE
455  *      register in the Card Common Control Register block, but this requires
456  *      two CMD52 operations. A better solution is to mask the interrupt at
457  *      the host controller.
458  *
459  *  Arguments:
460  *      sdio            SDIO context pointer
461  *
462  *  Returns:
463  *      Zero on success or a UniFi driver error code.
464  *
465  * ---------------------------------------------------------------------------
466  */
467 CsrResult
468 CsrSdioInterruptEnable(CsrSdioFunction *function)
469 {
470     struct sdio_func *func = (struct sdio_func *)function->priv;
471     int err = 0;
472
473 #ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
474     sdio_unblock_card_irq(func);
475 #else
476     _sdio_claim_host(func);
477     /* Write the Int Enable in CCCR block */
478 #ifdef MMC_QUIRK_LENIENT_FN0
479     sdio_f0_writeb(func, 0x3, SDIO_CCCR_IENx, &err);
480 #else
481     err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x03, NULL);
482 #endif
483     _sdio_release_host(func);
484
485     func_exit();
486     if (err) {
487         printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
488         return ConvertSdioToCsrSdioResult(err);
489     }
490 #endif
491     return CSR_RESULT_SUCCESS;
492 } /* CsrSdioInterruptEnable() */
493
494 CsrResult
495 CsrSdioInterruptDisable(CsrSdioFunction *function)
496 {
497     struct sdio_func *func = (struct sdio_func *)function->priv;
498     int err = 0;
499
500 #ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
501     sdio_block_card_irq(func);
502 #else
503     _sdio_claim_host(func);
504     /* Write the Int Enable in CCCR block */
505 #ifdef MMC_QUIRK_LENIENT_FN0
506     sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &err);
507 #else
508     err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
509 #endif
510     _sdio_release_host(func);
511
512     func_exit();
513     if (err) {
514         printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
515         return ConvertSdioToCsrSdioResult(err);
516     }
517 #endif
518     return CSR_RESULT_SUCCESS;
519 } /* CsrSdioInterruptDisable() */
520
521
522 void CsrSdioInterruptAcknowledge(CsrSdioFunction *function)
523 {
524 }
525
526
527 /*
528  * ---------------------------------------------------------------------------
529  *  CsrSdioFunctionEnable
530  *
531  *      Enable i/o on function 1.
532  *
533  *  Arguments:
534  *      sdio            SDIO context pointer
535  *
536  * Returns:
537  *      UniFi driver error code.
538  * ---------------------------------------------------------------------------
539  */
540 CsrResult
541 CsrSdioFunctionEnable(CsrSdioFunction *function)
542 {
543     struct sdio_func *func = (struct sdio_func *)function->priv;
544     int err;
545
546     func_enter();
547
548     /* Enable UniFi function 1 (the 802.11 part). */
549     _sdio_claim_host(func);
550     err = sdio_enable_func(func);
551     _sdio_release_host(func);
552     if (err) {
553         unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num);
554     }
555
556     func_exit();
557     return ConvertSdioToCsrSdioResult(err);
558 } /* CsrSdioFunctionEnable() */
559
560
561 /*
562  * ---------------------------------------------------------------------------
563  *  CsrSdioFunctionDisable
564  *
565  *      Enable i/o on function 1.
566  *
567  *  Arguments:
568  *      sdio            SDIO context pointer
569  *
570  * Returns:
571  *      UniFi driver error code.
572  * ---------------------------------------------------------------------------
573  */
574 CsrResult
575 CsrSdioFunctionDisable(CsrSdioFunction *function)
576 {
577     struct sdio_func *func = (struct sdio_func *)function->priv;
578     int err;
579
580     func_enter();
581
582     /* Disable UniFi function 1 (the 802.11 part). */
583     _sdio_claim_host(func);
584     err = sdio_disable_func(func);
585     _sdio_release_host(func);
586     if (err) {
587         unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num);
588     }
589
590     func_exit();
591     return ConvertSdioToCsrSdioResult(err);
592 } /* CsrSdioFunctionDisable() */
593
594
595 /*
596  * ---------------------------------------------------------------------------
597  *  CsrSdioFunctionActive
598  *
599  *      No-op as the bus goes to an active state at the start of every
600  *      command.
601  *
602  *  Arguments:
603  *      sdio            SDIO context pointer
604  * ---------------------------------------------------------------------------
605  */
606 void
607 CsrSdioFunctionActive(CsrSdioFunction *function)
608 {
609 } /* CsrSdioFunctionActive() */
610
611 /*
612  * ---------------------------------------------------------------------------
613  *  CsrSdioFunctionIdle
614  *
615  *      Set the function as idle.
616  *
617  *  Arguments:
618  *      sdio            SDIO context pointer
619  * ---------------------------------------------------------------------------
620  */
621 void
622 CsrSdioFunctionIdle(CsrSdioFunction *function)
623 {
624 } /* CsrSdioFunctionIdle() */
625
626
627 /*
628  * ---------------------------------------------------------------------------
629  *  CsrSdioPowerOn
630  *
631  *      Power on UniFi.
632  *
633  *  Arguments:
634  *      sdio            SDIO context pointer
635  * ---------------------------------------------------------------------------
636  */
637 CsrResult
638 CsrSdioPowerOn(CsrSdioFunction *function)
639 {
640 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
641     struct sdio_func *func = (struct sdio_func *)function->priv;
642     struct mmc_host *host = func->card->host;
643
644     _sdio_claim_host(func);
645     if (!card_is_powered) {
646         mmc_power_restore_host(host);
647         card_is_powered = 1;
648     } else {
649         printk(KERN_INFO "SDIO: Skip power on; card is already powered.\n");
650     }
651     _sdio_release_host(func);
652 #endif /* 2.6.32 */
653
654     return CSR_RESULT_SUCCESS;
655 } /* CsrSdioPowerOn() */
656
657 /*
658  * ---------------------------------------------------------------------------
659  *  CsrSdioPowerOff
660  *
661  *      Power off UniFi.
662  *
663  *  Arguments:
664  *      sdio            SDIO context pointer
665  * ---------------------------------------------------------------------------
666  */
667 void
668 CsrSdioPowerOff(CsrSdioFunction *function)
669 {
670 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
671     struct sdio_func *func = (struct sdio_func *)function->priv;
672     struct mmc_host *host = func->card->host;
673
674     _sdio_claim_host(func);
675     if (card_is_powered) {
676         mmc_power_save_host(host);
677         card_is_powered = 0;
678     } else {
679         printk(KERN_INFO "SDIO: Skip power off; card is already powered off.\n");
680     }
681     _sdio_release_host(func);
682 #endif /* 2.6.32 */
683 } /* CsrSdioPowerOff() */
684
685
686 static int
687 sdio_set_block_size_ignore_first_error(struct sdio_func *func, unsigned blksz)
688 {
689     int ret;
690
691     if (blksz > func->card->host->max_blk_size)
692         return -EINVAL;
693
694     if (blksz == 0) {
695         blksz = min(func->max_blksize, func->card->host->max_blk_size);
696         blksz = min(blksz, 512u);
697     }
698
699     /*
700      * Ignore -ERANGE (OUT_OF_RANGE in R5) on the first byte as
701      * the block size may be invalid until both bytes are written.
702      */
703     ret = csr_io_rw_direct(func->card, 1, 0,
704                            SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
705                            blksz & 0xff, NULL);
706     if (ret && ret != -ERANGE)
707         return ret;
708     ret = csr_io_rw_direct(func->card, 1, 0,
709                            SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
710                            (blksz >> 8) & 0xff, NULL);
711     if (ret)
712         return ret;
713     func->cur_blksize = blksz;
714
715     return 0;
716 }
717
718 CsrResult
719 CsrSdioBlockSizeSet(CsrSdioFunction *function, u16 blockSize)
720 {
721     struct sdio_func *func = (struct sdio_func *)function->priv;
722     int r = 0;
723
724     /* Module parameter overrides */
725     if (sdio_block_size > -1) {
726         blockSize = sdio_block_size;
727     }
728
729     unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n",
730                 blockSize);
731
732     _sdio_claim_host(func);
733     r = sdio_set_block_size(func, blockSize);
734     _sdio_release_host(func);
735
736     /*
737      * The MMC driver for kernels prior to 2.6.32 may fail this request
738      * with -ERANGE. In this case use our workaround.
739      */
740     if (r == -ERANGE) {
741         _sdio_claim_host(func);
742         r = sdio_set_block_size_ignore_first_error(func, blockSize);
743         _sdio_release_host(func);
744     }
745     if (r) {
746         unifi_error(NULL, "Error %d setting block size\n", r);
747     }
748
749     /* Determine the achieved block size to pass to the core */
750     function->blockSize = func->cur_blksize;
751
752     return ConvertSdioToCsrSdioResult(r);
753 } /* CsrSdioBlockSizeSet() */
754
755
756 /*
757  * ---------------------------------------------------------------------------
758  *  CsrSdioHardReset
759  *
760  *      Hard Resets UniFi is possible.
761  *
762  *  Arguments:
763  *      sdio            SDIO context pointer
764  * ---------------------------------------------------------------------------
765  */
766 CsrResult
767 CsrSdioHardReset(CsrSdioFunction *function)
768 {
769     return CSR_RESULT_FAILURE;
770 } /* CsrSdioHardReset() */
771
772
773
774 /*
775  * ---------------------------------------------------------------------------
776  *  uf_glue_sdio_int_handler
777  *
778  *      Interrupt callback function for SDIO interrupts.
779  *      This is called in kernel context (i.e. not interrupt context).
780  *
781  *  Arguments:
782  *      func      SDIO context pointer
783  *
784  *  Returns:
785  *      None.
786  *
787  *  Note: Called with host already claimed.
788  * ---------------------------------------------------------------------------
789  */
790 static void
791 uf_glue_sdio_int_handler(struct sdio_func *func)
792 {
793     CsrSdioFunction *sdio_ctx;
794     CsrSdioInterruptDsrCallback func_dsr_callback;
795     int r;
796
797     sdio_ctx = sdio_get_drvdata(func);
798     if (!sdio_ctx) {
799         return;
800     }
801
802 #ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
803     /*
804      * Normally, we are not allowed to do any SDIO commands here.
805      * However, this is called in a thread context and with the SDIO lock
806      * so we disable the interrupts here instead of trying to do complicated
807      * things with the SDIO lock.
808      */
809 #ifdef MMC_QUIRK_LENIENT_FN0
810     sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &r);
811 #else
812     r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
813 #endif
814     if (r) {
815         printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r);
816     }
817 #endif
818
819     /* If the function driver has registered a handler, call it */
820     if (sdio_func_drv && sdio_func_drv->intr) {
821
822         func_dsr_callback = sdio_func_drv->intr(sdio_ctx);
823
824         /* If interrupt handle returns a DSR handle, call it */
825         if (func_dsr_callback) {
826             func_dsr_callback(sdio_ctx);
827         }
828     }
829
830 } /* uf_glue_sdio_int_handler() */
831
832
833
834 /*
835  * ---------------------------------------------------------------------------
836  *  csr_sdio_linux_remove_irq
837  *
838  *      Unregister the interrupt handler.
839  *      This means that the linux layer can not process interrupts any more.
840  *
841  *  Arguments:
842  *      sdio      SDIO context pointer
843  *
844  *  Returns:
845  *      Status of the removal.
846  * ---------------------------------------------------------------------------
847  */
848 int
849 csr_sdio_linux_remove_irq(CsrSdioFunction *function)
850 {
851     struct sdio_func *func = (struct sdio_func *)function->priv;
852     int r;
853
854     unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n");
855
856     sdio_claim_host(func);
857     r = sdio_release_irq(func);
858     sdio_release_host(func);
859
860     return r;
861
862 } /* csr_sdio_linux_remove_irq() */
863
864
865 /*
866  * ---------------------------------------------------------------------------
867  *  csr_sdio_linux_install_irq
868  *
869  *      Register the interrupt handler.
870  *      This means that the linux layer can process interrupts.
871  *
872  *  Arguments:
873  *      sdio      SDIO context pointer
874  *
875  *  Returns:
876  *      Status of the removal.
877  * ---------------------------------------------------------------------------
878  */
879 int
880 csr_sdio_linux_install_irq(CsrSdioFunction *function)
881 {
882     struct sdio_func *func = (struct sdio_func *)function->priv;
883     int r;
884
885     unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n");
886
887     /* Register our interrupt handle */
888     sdio_claim_host(func);
889     r = sdio_claim_irq(func, uf_glue_sdio_int_handler);
890     sdio_release_host(func);
891
892     /* If the interrupt was installed earlier, is fine */
893     if (r == -EBUSY) {
894         r = 0;
895     }
896
897     return r;
898 } /* csr_sdio_linux_install_irq() */
899
900 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
901 #ifdef CONFIG_PM
902
903 /*
904  * Power Management notifier
905  */
906 struct uf_sdio_mmc_pm_notifier
907 {
908     struct list_head list;
909
910     CsrSdioFunction *sdio_ctx;
911     struct notifier_block pm_notifier;
912 };
913
914 /* PM notifier list head */
915 static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = {
916     .sdio_ctx = NULL,
917 };
918
919 /*
920  * ---------------------------------------------------------------------------
921  * uf_sdio_mmc_register_pm_notifier
922  * uf_sdio_mmc_unregister_pm_notifier
923  *
924  *      Register/unregister for power management events. A list is used to
925  *      allow multiple card instances to be supported.
926  *
927  *  Arguments:
928  *      sdio_ctx - CSR SDIO context to associate PM notifier to
929  *
930  *  Returns:
931  *      Register function returns NULL on error
932  * ---------------------------------------------------------------------------
933  */
934 static struct uf_sdio_mmc_pm_notifier *
935 uf_sdio_mmc_register_pm_notifier(CsrSdioFunction *sdio_ctx)
936 {
937     /* Allocate notifier context for this card instance */
938     struct uf_sdio_mmc_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_mmc_pm_notifier), GFP_KERNEL);
939
940     if (notifier_ctx)
941     {
942         notifier_ctx->sdio_ctx = sdio_ctx;
943         notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event;
944
945         list_add(&notifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list);
946
947         if (register_pm_notifier(&notifier_ctx->pm_notifier)) {
948             printk(KERN_ERR "unifi: register_pm_notifier failed\n");
949         }
950     }
951
952     return notifier_ctx;
953 }
954
955 static void
956 uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
957 {
958     struct uf_sdio_mmc_pm_notifier *notifier_ctx;
959     struct list_head *node, *q;
960
961     list_for_each_safe(node, q, &uf_sdio_mmc_pm_notifiers.list) {
962         notifier_ctx = list_entry(node, struct uf_sdio_mmc_pm_notifier, list);
963
964         /* If it matches, unregister and free the notifier context */
965         if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
966         {
967             if (unregister_pm_notifier(&notifier_ctx->pm_notifier)) {
968                 printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
969             }
970
971             /* Remove from list */
972             notifier_ctx->sdio_ctx = NULL;
973             list_del(node);
974             kfree(notifier_ctx);
975         }
976     }
977 }
978
979 /*
980  * ---------------------------------------------------------------------------
981  * uf_sdio_mmc_power_event
982  *
983  *      Handler for power management events.
984  *
985  *      We need to handle suspend/resume events while the userspace is unsuspended
986  *      to allow the SME to run its suspend/resume state machines.
987  *
988  *  Arguments:
989  *      event   event ID
990  *
991  *  Returns:
992  *      Status of the event handling
993  * ---------------------------------------------------------------------------
994  */
995 static int
996 uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr)
997 {
998     struct uf_sdio_mmc_pm_notifier *notifier_ctx = container_of(this,
999                                                                 struct uf_sdio_mmc_pm_notifier,
1000                                                                 pm_notifier);
1001
1002     /* Call the CSR SDIO function driver's suspend/resume method
1003      * while the userspace is unsuspended.
1004      */
1005     switch (event) {
1006         case PM_POST_HIBERNATION:
1007         case PM_POST_SUSPEND:
1008             printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
1009             if (sdio_func_drv && sdio_func_drv->resume) {
1010                 sdio_func_drv->resume(notifier_ctx->sdio_ctx);
1011             }
1012             break;
1013
1014         case PM_HIBERNATION_PREPARE:
1015         case PM_SUSPEND_PREPARE:
1016             printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
1017             if (sdio_func_drv && sdio_func_drv->suspend) {
1018                 sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
1019             }
1020             break;
1021     }
1022     return NOTIFY_DONE;
1023 }
1024
1025 #endif /* CONFIG_PM */
1026 #endif /* 2.6.32 */
1027
1028 /*
1029  * ---------------------------------------------------------------------------
1030  *  uf_glue_sdio_probe
1031  *
1032  *      Card insert callback.
1033  *
1034  * Arguments:
1035  *      func            Our (glue layer) context pointer.
1036  *
1037  * Returns:
1038  *      UniFi driver error code.
1039  * ---------------------------------------------------------------------------
1040  */
1041 static int
1042 uf_glue_sdio_probe(struct sdio_func *func,
1043                    const struct sdio_device_id *id)
1044 {
1045     int instance;
1046     CsrSdioFunction *sdio_ctx;
1047
1048     func_enter();
1049
1050     /* First of all claim the SDIO driver */
1051     sdio_claim_host(func);
1052
1053 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1054     /* Assume that the card is already powered */
1055     card_is_powered = 1;
1056 #endif
1057
1058     /* Assumes one card per host, which is true for SDIO */
1059     instance = func->card->host->index;
1060     printk("sdio bus_id: %16s - UniFi card 0x%X inserted\n",
1061            sdio_func_id(func), instance);
1062
1063     /* Allocate context */
1064     sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction),
1065                                           GFP_KERNEL);
1066     if (sdio_ctx == NULL) {
1067         sdio_release_host(func);
1068         return -ENOMEM;
1069     }
1070
1071     /* Initialise the context */
1072     sdio_ctx->sdioId.manfId  = func->vendor;
1073     sdio_ctx->sdioId.cardId  = func->device;
1074     sdio_ctx->sdioId.sdioFunction  = func->num;
1075     sdio_ctx->sdioId.sdioInterface = func->class;
1076     sdio_ctx->blockSize = func->cur_blksize;
1077     sdio_ctx->priv = (void *)func;
1078     sdio_ctx->features = 0;
1079
1080     /* Module parameter enables byte mode */
1081     if (sdio_byte_mode) {
1082         sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
1083     }
1084
1085     if (func->card->host->caps & MMC_CAP_SD_HIGHSPEED) {
1086         unifi_trace(NULL, UDBG1, "MMC_CAP_SD_HIGHSPEED is available\n");
1087     }
1088
1089 #ifdef MMC_QUIRK_LENIENT_FN0
1090     func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
1091 #endif
1092
1093     /* Pass context to the SDIO driver */
1094     sdio_set_drvdata(func, sdio_ctx);
1095
1096 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1097 #ifdef CONFIG_PM
1098     /* Register to get PM events */
1099     if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) {
1100         unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
1101     }
1102 #endif
1103 #endif
1104
1105     /* Register this device with the SDIO function driver */
1106     /* Call the main UniFi driver inserted handler */
1107     if (sdio_func_drv && sdio_func_drv->inserted) {
1108         uf_add_os_device(instance, &func->dev);
1109         sdio_func_drv->inserted(sdio_ctx);
1110     }
1111
1112     /* We have finished, so release the SDIO driver */
1113     sdio_release_host(func);
1114
1115 #ifdef ANDROID_BUILD
1116     /* Take the wakelock */
1117     unifi_trace(NULL, UDBG1, "probe: take wake lock\n");
1118     wake_lock(&unifi_sdio_wake_lock);
1119 #endif
1120
1121     func_exit();
1122     return 0;
1123 } /* uf_glue_sdio_probe() */
1124
1125
1126 /*
1127  * ---------------------------------------------------------------------------
1128  *  uf_glue_sdio_remove
1129  *
1130  *      Card removal callback.
1131  *
1132  * Arguments:
1133  *      func            Our (glue layer) context pointer.
1134  *
1135  * Returns:
1136  *      UniFi driver error code.
1137  * ---------------------------------------------------------------------------
1138  */
1139 static void
1140 uf_glue_sdio_remove(struct sdio_func *func)
1141 {
1142     CsrSdioFunction *sdio_ctx;
1143
1144     sdio_ctx = sdio_get_drvdata(func);
1145     if (!sdio_ctx) {
1146         return;
1147     }
1148
1149     func_enter();
1150
1151     unifi_info(NULL, "UniFi card removed\n");
1152
1153     /* Clean up the SDIO function driver */
1154     if (sdio_func_drv && sdio_func_drv->removed) {
1155         uf_remove_os_device(func->card->host->index);
1156         sdio_func_drv->removed(sdio_ctx);
1157     }
1158
1159 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1160 #ifdef CONFIG_PM
1161     /* Unregister for PM events */
1162     uf_sdio_mmc_unregister_pm_notifier(sdio_ctx);
1163 #endif
1164 #endif
1165
1166     kfree(sdio_ctx);
1167
1168     func_exit();
1169
1170 } /* uf_glue_sdio_remove */
1171
1172
1173 /*
1174  * SDIO ids *must* be statically declared, so we can't take
1175  * them from the list passed in csr_sdio_register_driver().
1176  */
1177 static const struct sdio_device_id unifi_ids[] = {
1178     { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_3) },
1179     { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_4) },
1180     { /* end: all zeroes */                             },
1181 };
1182
1183 MODULE_DEVICE_TABLE(sdio, unifi_ids);
1184
1185 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1186 #ifdef CONFIG_PM
1187
1188 /*
1189  * ---------------------------------------------------------------------------
1190  *  uf_glue_sdio_suspend
1191  *
1192  *      Card suspend callback. The userspace will already be suspended.
1193  *
1194  * Arguments:
1195  *      dev            The struct device owned by the MMC driver
1196  *
1197  * Returns:
1198  *      None
1199  * ---------------------------------------------------------------------------
1200  */
1201 static int
1202 uf_glue_sdio_suspend(struct device *dev)
1203 {
1204     func_enter();
1205
1206     unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend");
1207
1208     func_exit();
1209     return 0;
1210 } /* uf_glue_sdio_suspend */
1211
1212
1213 /*
1214  * ---------------------------------------------------------------------------
1215  *  uf_glue_sdio_resume
1216  *
1217  *      Card resume callback. The userspace will still be suspended.
1218  *
1219  * Arguments:
1220  *      dev            The struct device owned by the MMC driver
1221  *
1222  * Returns:
1223  *      None
1224  * ---------------------------------------------------------------------------
1225  */
1226 static int
1227 uf_glue_sdio_resume(struct device *dev)
1228 {
1229     func_enter();
1230
1231     unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume");
1232
1233 #ifdef ANDROID_BUILD
1234     unifi_trace(NULL, UDBG1, "resume: take wakelock\n");
1235     wake_lock(&unifi_sdio_wake_lock);
1236 #endif
1237
1238     func_exit();
1239     return 0;
1240
1241 } /* uf_glue_sdio_resume */
1242
1243 static struct dev_pm_ops unifi_pm_ops = {
1244     .suspend = uf_glue_sdio_suspend,
1245     .resume  = uf_glue_sdio_resume,
1246 };
1247
1248 #define UNIFI_PM_OPS  (&unifi_pm_ops)
1249
1250 #else
1251
1252 #define UNIFI_PM_OPS  NULL
1253
1254 #endif /* CONFIG_PM */
1255 #endif /* 2.6.32 */
1256
1257 static struct sdio_driver unifi_driver = {
1258     .probe      = uf_glue_sdio_probe,
1259     .remove     = uf_glue_sdio_remove,
1260     .name       = "unifi",
1261     .id_table   = unifi_ids,
1262 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1263     .drv.pm     = UNIFI_PM_OPS,
1264 #endif /* 2.6.32 */
1265 };
1266
1267
1268 /*
1269  * ---------------------------------------------------------------------------
1270  *  CsrSdioFunctionDriverRegister
1271  *  CsrSdioFunctionDriverUnregister
1272  *
1273  *      These functions are called from the main module load and unload
1274  *      functions. They perform the appropriate operations for the
1275  *      linux MMC/SDIO driver.
1276  *
1277  *  Arguments:
1278  *      sdio_drv    Pointer to the function driver's SDIO structure.
1279  *
1280  *  Returns:
1281  *      None.
1282  * ---------------------------------------------------------------------------
1283  */
1284 CsrResult
1285 CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
1286 {
1287     int r;
1288
1289     printk("UniFi: Using native Linux MMC driver for SDIO.\n");
1290
1291     if (sdio_func_drv) {
1292         unifi_error(NULL, "sdio_mmc: UniFi driver already registered\n");
1293         return CSR_SDIO_RESULT_INVALID_VALUE;
1294     }
1295
1296 #ifdef ANDROID_BUILD
1297     wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
1298 #endif
1299
1300     /* Save the registered driver description */
1301     /*
1302      * FIXME:
1303      * Need a table here to handle a call to register for just one function.
1304      * mmc only allows us to register for the whole device
1305      */
1306     sdio_func_drv = sdio_drv;
1307
1308 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1309 #ifdef CONFIG_PM
1310     /* Initialise PM notifier list */
1311     INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list);
1312 #endif
1313 #endif
1314
1315     /* Register ourself with mmc_core */
1316     r = sdio_register_driver(&unifi_driver);
1317     if (r) {
1318         printk(KERN_ERR "unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r);
1319         return ConvertSdioToCsrSdioResult(r);
1320     }
1321
1322     return CSR_RESULT_SUCCESS;
1323 } /* CsrSdioFunctionDriverRegister() */
1324
1325
1326
1327 void
1328 CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
1329 {
1330     printk(KERN_INFO "UniFi: unregister from MMC sdio\n");
1331
1332 #ifdef ANDROID_BUILD
1333     wake_lock_destroy(&unifi_sdio_wake_lock);
1334 #endif
1335     sdio_unregister_driver(&unifi_driver);
1336
1337     sdio_func_drv = NULL;
1338
1339 } /* CsrSdioFunctionDriverUnregister() */
1340