2 * ---------------------------------------------------------------------------
6 * PURPOSE: SDIO driver interface for generic MMC stack.
8 * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
10 * ---------------------------------------------------------------------------
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>
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>
26 #include "unifi_priv.h"
29 struct wake_lock unifi_sdio_wake_lock
; /* wakelock to prevent suspend while resuming */
32 static CsrSdioFunctionDriver
*sdio_func_drv
;
34 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
36 static int uf_sdio_mmc_power_event(struct notifier_block
*this, unsigned long event
, void *ptr
);
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).
47 static int card_is_powered
= 1;
50 /* MMC uses ENOMEDIUM to indicate card gone away */
53 ConvertSdioToCsrSdioResult(int r
)
55 CsrResult csrResult
= CSR_RESULT_FAILURE
;
59 csrResult
= CSR_RESULT_SUCCESS
;
63 csrResult
= CSR_SDIO_RESULT_CRC_ERROR
;
68 csrResult
= CSR_SDIO_RESULT_TIMEOUT
;
72 csrResult
= CSR_SDIO_RESULT_NO_DEVICE
;
75 csrResult
= CSR_SDIO_RESULT_INVALID_VALUE
;
81 csrResult
= CSR_RESULT_FAILURE
;
84 unifi_warning(NULL
, "Unrecognised SDIO error code: %d\n", r
);
93 csr_io_rw_direct(struct mmc_card
*card
, int write
, uint8_t fn
,
94 uint32_t addr
, uint8_t in
, uint8_t* out
)
96 struct mmc_command cmd
;
102 memset(&cmd
, 0, sizeof(struct mmc_command
));
104 cmd
.opcode
= SD_IO_RW_DIRECT
;
105 cmd
.arg
= write
? 0x80000000 : 0x00000000;
107 cmd
.arg
|= (write
&& out
) ? 0x08000000 : 0x00000000;
108 cmd
.arg
|= addr
<< 9;
110 cmd
.flags
= MMC_RSP_SPI_R5
| MMC_RSP_R5
| MMC_CMD_AC
;
112 err
= mmc_wait_for_cmd(card
->host
, &cmd
, 0);
116 /* this function is not exported, so we will need to sort it out here
117 * for now, lets hard code it to sdio */
119 /* old arg (mmc_host_is_spi(card->host)) { */
120 /* host driver already reported errors */
122 if (cmd
.resp
[0] & R5_ERROR
) {
123 printk(KERN_ERR
"%s: r5 error 0x%02x\n",
124 __FUNCTION__
, cmd
.resp
[0]);
127 if (cmd
.resp
[0] & R5_FUNCTION_NUMBER
)
129 if (cmd
.resp
[0] & R5_OUT_OF_RANGE
)
134 if (0) { /* old argument (mmc_host_is_spi(card->host)) */
135 *out
= (cmd
.resp
[0] >> 8) & 0xFF;
138 *out
= cmd
.resp
[0] & 0xFF;
142 return CSR_RESULT_SUCCESS
;
147 CsrSdioRead8(CsrSdioFunction
*function
, u32 address
, u8
*data
)
149 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
152 _sdio_claim_host(func
);
153 *data
= sdio_readb(func
, address
, &err
);
154 _sdio_release_host(func
);
158 return ConvertSdioToCsrSdioResult(err
);
161 return CSR_RESULT_SUCCESS
;
162 } /* CsrSdioRead8() */
165 CsrSdioWrite8(CsrSdioFunction
*function
, u32 address
, u8 data
)
167 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
170 _sdio_claim_host(func
);
171 sdio_writeb(func
, data
, address
, &err
);
172 _sdio_release_host(func
);
176 return ConvertSdioToCsrSdioResult(err
);
179 return CSR_RESULT_SUCCESS
;
180 } /* CsrSdioWrite8() */
183 CsrSdioRead16(CsrSdioFunction
*function
, u32 address
, u16
*data
)
185 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
189 _sdio_claim_host(func
);
190 b0
= sdio_readb(func
, address
, &err
);
192 _sdio_release_host(func
);
193 return ConvertSdioToCsrSdioResult(err
);
196 b1
= sdio_readb(func
, address
+1, &err
);
198 _sdio_release_host(func
);
199 return ConvertSdioToCsrSdioResult(err
);
201 _sdio_release_host(func
);
203 *data
= ((uint16_t)b1
<< 8) | b0
;
205 return CSR_RESULT_SUCCESS
;
206 } /* CsrSdioRead16() */
210 CsrSdioWrite16(CsrSdioFunction
*function
, u32 address
, u16 data
)
212 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
216 _sdio_claim_host(func
);
217 b1
= (data
>> 8) & 0xFF;
218 sdio_writeb(func
, b1
, address
+1, &err
);
220 _sdio_release_host(func
);
221 return ConvertSdioToCsrSdioResult(err
);
225 sdio_writeb(func
, b0
, address
, &err
);
227 _sdio_release_host(func
);
228 return ConvertSdioToCsrSdioResult(err
);
231 _sdio_release_host(func
);
232 return CSR_RESULT_SUCCESS
;
233 } /* CsrSdioWrite16() */
237 CsrSdioF0Read8(CsrSdioFunction
*function
, u32 address
, u8
*data
)
239 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
242 _sdio_claim_host(func
);
243 #ifdef MMC_QUIRK_LENIENT_FN0
244 *data
= sdio_f0_readb(func
, address
, &err
);
246 err
= csr_io_rw_direct(func
->card
, 0, 0, address
, 0, data
);
248 _sdio_release_host(func
);
252 return ConvertSdioToCsrSdioResult(err
);
255 return CSR_RESULT_SUCCESS
;
256 } /* CsrSdioF0Read8() */
259 CsrSdioF0Write8(CsrSdioFunction
*function
, u32 address
, u8 data
)
261 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
264 _sdio_claim_host(func
);
265 #ifdef MMC_QUIRK_LENIENT_FN0
266 sdio_f0_writeb(func
, data
, address
, &err
);
268 err
= csr_io_rw_direct(func
->card
, 1, 0, address
, data
, NULL
);
270 _sdio_release_host(func
);
274 return ConvertSdioToCsrSdioResult(err
);
277 return CSR_RESULT_SUCCESS
;
278 } /* CsrSdioF0Write8() */
282 CsrSdioRead(CsrSdioFunction
*function
, u32 address
, void *data
, u32 length
)
284 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
287 _sdio_claim_host(func
);
288 err
= sdio_readsb(func
, data
, address
, length
);
289 _sdio_release_host(func
);
293 return ConvertSdioToCsrSdioResult(err
);
296 return CSR_RESULT_SUCCESS
;
297 } /* CsrSdioRead() */
300 CsrSdioWrite(CsrSdioFunction
*function
, u32 address
, const void *data
, u32 length
)
302 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
305 _sdio_claim_host(func
);
306 err
= sdio_writesb(func
, address
, (void*)data
, length
);
307 _sdio_release_host(func
);
311 return ConvertSdioToCsrSdioResult(err
);
314 return CSR_RESULT_SUCCESS
;
315 } /* CsrSdioWrite() */
319 csr_sdio_enable_hs(struct mmc_card
*card
)
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.
329 printk(KERN_INFO
"unifi: request HS but not MMC_CAP_SD_HIGHSPEED");
333 if (!card
->cccr
.high_speed
)
337 ret
= csr_io_rw_direct(card
, 0, 0, SDIO_CCCR_SPEED
, 0, &speed
);
341 speed
|= SDIO_SPEED_EHS
;
343 /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
344 speed
= SDIO_SPEED_EHS
| SDIO_SPEED_SHS
;
347 ret
= csr_io_rw_direct(card
, 1, 0, SDIO_CCCR_SPEED
, speed
, NULL
);
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
);
359 csr_sdio_disable_hs(struct mmc_card
*card
)
364 if (!(card
->host
->caps
& MMC_CAP_SD_HIGHSPEED
))
367 if (!card
->cccr
.high_speed
)
370 ret
= csr_io_rw_direct(card
, 0, 0, SDIO_CCCR_SPEED
, 0, &speed
);
374 speed
&= ~SDIO_SPEED_EHS
;
376 /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
377 speed
= SDIO_SPEED_SHS
; /* clear SDIO_SPEED_EHS */
380 ret
= csr_io_rw_direct(card
, 1, 0, SDIO_CCCR_SPEED
, speed
, NULL
);
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
);
393 * ---------------------------------------------------------------------------
394 * CsrSdioMaxBusClockFrequencySet
396 * Set the maximum SDIO bus clock speed to use.
399 * sdio SDIO context pointer
400 * maxFrequency maximum clock speed in Hz
404 * ---------------------------------------------------------------------------
407 CsrSdioMaxBusClockFrequencySet(CsrSdioFunction
*function
, u32 maxFrequency
)
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
;
414 u32 max_khz
= maxFrequency
/1000;
416 if (!max_khz
|| max_khz
> sdio_clock
) {
417 max_khz
= sdio_clock
;
420 _sdio_claim_host(func
);
421 max_hz
= 1000 * max_khz
;
422 if (max_hz
> host
->f_max
) {
423 max_hz
= host
->f_max
;
426 if (max_hz
> 25000000) {
427 err
= csr_sdio_enable_hs(func
->card
);
429 err
= csr_sdio_disable_hs(func
->card
);
432 printk(KERN_ERR
"SDIO warning: Failed to configure SDIO clock mode\n");
433 _sdio_release_host(func
);
434 return CSR_RESULT_SUCCESS
;
438 host
->ops
->set_ios(host
, ios
);
440 _sdio_release_host(func
);
442 return CSR_RESULT_SUCCESS
;
443 } /* CsrSdioMaxBusClockFrequencySet() */
447 * ---------------------------------------------------------------------------
448 * CsrSdioInterruptEnable
449 * CsrSdioInterruptDisable
451 * Enable or disable the SDIO interrupt.
452 * The driver disables the SDIO interrupt until the i/o thread can
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.
460 * sdio SDIO context pointer
463 * Zero on success or a UniFi driver error code.
465 * ---------------------------------------------------------------------------
468 CsrSdioInterruptEnable(CsrSdioFunction
*function
)
470 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
473 #ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
474 sdio_unblock_card_irq(func
);
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
);
481 err
= csr_io_rw_direct(func
->card
, 1, 0, SDIO_CCCR_IENx
, 0x03, NULL
);
483 _sdio_release_host(func
);
487 printk(KERN_ERR
"unifi: %s: error %d writing IENx\n", __FUNCTION__
, err
);
488 return ConvertSdioToCsrSdioResult(err
);
491 return CSR_RESULT_SUCCESS
;
492 } /* CsrSdioInterruptEnable() */
495 CsrSdioInterruptDisable(CsrSdioFunction
*function
)
497 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
500 #ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
501 sdio_block_card_irq(func
);
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
);
508 err
= csr_io_rw_direct(func
->card
, 1, 0, SDIO_CCCR_IENx
, 0x00, NULL
);
510 _sdio_release_host(func
);
514 printk(KERN_ERR
"unifi: %s: error %d writing IENx\n", __FUNCTION__
, err
);
515 return ConvertSdioToCsrSdioResult(err
);
518 return CSR_RESULT_SUCCESS
;
519 } /* CsrSdioInterruptDisable() */
522 void CsrSdioInterruptAcknowledge(CsrSdioFunction
*function
)
528 * ---------------------------------------------------------------------------
529 * CsrSdioFunctionEnable
531 * Enable i/o on function 1.
534 * sdio SDIO context pointer
537 * UniFi driver error code.
538 * ---------------------------------------------------------------------------
541 CsrSdioFunctionEnable(CsrSdioFunction
*function
)
543 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
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
);
553 unifi_error(NULL
, "Failed to enable SDIO function %d\n", func
->num
);
557 return ConvertSdioToCsrSdioResult(err
);
558 } /* CsrSdioFunctionEnable() */
562 * ---------------------------------------------------------------------------
563 * CsrSdioFunctionDisable
565 * Enable i/o on function 1.
568 * sdio SDIO context pointer
571 * UniFi driver error code.
572 * ---------------------------------------------------------------------------
575 CsrSdioFunctionDisable(CsrSdioFunction
*function
)
577 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
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
);
587 unifi_error(NULL
, "Failed to disable SDIO function %d\n", func
->num
);
591 return ConvertSdioToCsrSdioResult(err
);
592 } /* CsrSdioFunctionDisable() */
596 * ---------------------------------------------------------------------------
597 * CsrSdioFunctionActive
599 * No-op as the bus goes to an active state at the start of every
603 * sdio SDIO context pointer
604 * ---------------------------------------------------------------------------
607 CsrSdioFunctionActive(CsrSdioFunction
*function
)
609 } /* CsrSdioFunctionActive() */
612 * ---------------------------------------------------------------------------
613 * CsrSdioFunctionIdle
615 * Set the function as idle.
618 * sdio SDIO context pointer
619 * ---------------------------------------------------------------------------
622 CsrSdioFunctionIdle(CsrSdioFunction
*function
)
624 } /* CsrSdioFunctionIdle() */
628 * ---------------------------------------------------------------------------
634 * sdio SDIO context pointer
635 * ---------------------------------------------------------------------------
638 CsrSdioPowerOn(CsrSdioFunction
*function
)
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
;
644 _sdio_claim_host(func
);
645 if (!card_is_powered
) {
646 mmc_power_restore_host(host
);
649 printk(KERN_INFO
"SDIO: Skip power on; card is already powered.\n");
651 _sdio_release_host(func
);
654 return CSR_RESULT_SUCCESS
;
655 } /* CsrSdioPowerOn() */
658 * ---------------------------------------------------------------------------
664 * sdio SDIO context pointer
665 * ---------------------------------------------------------------------------
668 CsrSdioPowerOff(CsrSdioFunction
*function
)
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
;
674 _sdio_claim_host(func
);
675 if (card_is_powered
) {
676 mmc_power_save_host(host
);
679 printk(KERN_INFO
"SDIO: Skip power off; card is already powered off.\n");
681 _sdio_release_host(func
);
683 } /* CsrSdioPowerOff() */
687 sdio_set_block_size_ignore_first_error(struct sdio_func
*func
, unsigned blksz
)
691 if (blksz
> func
->card
->host
->max_blk_size
)
695 blksz
= min(func
->max_blksize
, func
->card
->host
->max_blk_size
);
696 blksz
= min(blksz
, 512u);
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.
703 ret
= csr_io_rw_direct(func
->card
, 1, 0,
704 SDIO_FBR_BASE(func
->num
) + SDIO_FBR_BLKSIZE
,
706 if (ret
&& ret
!= -ERANGE
)
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
);
713 func
->cur_blksize
= blksz
;
719 CsrSdioBlockSizeSet(CsrSdioFunction
*function
, u16 blockSize
)
721 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
724 /* Module parameter overrides */
725 if (sdio_block_size
> -1) {
726 blockSize
= sdio_block_size
;
729 unifi_trace(NULL
, UDBG1
, "Set SDIO function block size to %d\n",
732 _sdio_claim_host(func
);
733 r
= sdio_set_block_size(func
, blockSize
);
734 _sdio_release_host(func
);
737 * The MMC driver for kernels prior to 2.6.32 may fail this request
738 * with -ERANGE. In this case use our workaround.
741 _sdio_claim_host(func
);
742 r
= sdio_set_block_size_ignore_first_error(func
, blockSize
);
743 _sdio_release_host(func
);
746 unifi_error(NULL
, "Error %d setting block size\n", r
);
749 /* Determine the achieved block size to pass to the core */
750 function
->blockSize
= func
->cur_blksize
;
752 return ConvertSdioToCsrSdioResult(r
);
753 } /* CsrSdioBlockSizeSet() */
757 * ---------------------------------------------------------------------------
760 * Hard Resets UniFi is possible.
763 * sdio SDIO context pointer
764 * ---------------------------------------------------------------------------
767 CsrSdioHardReset(CsrSdioFunction
*function
)
769 return CSR_RESULT_FAILURE
;
770 } /* CsrSdioHardReset() */
775 * ---------------------------------------------------------------------------
776 * uf_glue_sdio_int_handler
778 * Interrupt callback function for SDIO interrupts.
779 * This is called in kernel context (i.e. not interrupt context).
782 * func SDIO context pointer
787 * Note: Called with host already claimed.
788 * ---------------------------------------------------------------------------
791 uf_glue_sdio_int_handler(struct sdio_func
*func
)
793 CsrSdioFunction
*sdio_ctx
;
794 CsrSdioInterruptDsrCallback func_dsr_callback
;
797 sdio_ctx
= sdio_get_drvdata(func
);
802 #ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
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.
809 #ifdef MMC_QUIRK_LENIENT_FN0
810 sdio_f0_writeb(func
, 0, SDIO_CCCR_IENx
, &r
);
812 r
= csr_io_rw_direct(func
->card
, 1, 0, SDIO_CCCR_IENx
, 0x00, NULL
);
815 printk(KERN_ERR
"UniFi MMC Int handler: Failed to disable interrupts %d\n", r
);
819 /* If the function driver has registered a handler, call it */
820 if (sdio_func_drv
&& sdio_func_drv
->intr
) {
822 func_dsr_callback
= sdio_func_drv
->intr(sdio_ctx
);
824 /* If interrupt handle returns a DSR handle, call it */
825 if (func_dsr_callback
) {
826 func_dsr_callback(sdio_ctx
);
830 } /* uf_glue_sdio_int_handler() */
835 * ---------------------------------------------------------------------------
836 * csr_sdio_linux_remove_irq
838 * Unregister the interrupt handler.
839 * This means that the linux layer can not process interrupts any more.
842 * sdio SDIO context pointer
845 * Status of the removal.
846 * ---------------------------------------------------------------------------
849 csr_sdio_linux_remove_irq(CsrSdioFunction
*function
)
851 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
854 unifi_trace(NULL
, UDBG1
, "csr_sdio_linux_remove_irq\n");
856 sdio_claim_host(func
);
857 r
= sdio_release_irq(func
);
858 sdio_release_host(func
);
862 } /* csr_sdio_linux_remove_irq() */
866 * ---------------------------------------------------------------------------
867 * csr_sdio_linux_install_irq
869 * Register the interrupt handler.
870 * This means that the linux layer can process interrupts.
873 * sdio SDIO context pointer
876 * Status of the removal.
877 * ---------------------------------------------------------------------------
880 csr_sdio_linux_install_irq(CsrSdioFunction
*function
)
882 struct sdio_func
*func
= (struct sdio_func
*)function
->priv
;
885 unifi_trace(NULL
, UDBG1
, "csr_sdio_linux_install_irq\n");
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
);
892 /* If the interrupt was installed earlier, is fine */
898 } /* csr_sdio_linux_install_irq() */
900 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
904 * Power Management notifier
906 struct uf_sdio_mmc_pm_notifier
908 struct list_head list
;
910 CsrSdioFunction
*sdio_ctx
;
911 struct notifier_block pm_notifier
;
914 /* PM notifier list head */
915 static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers
= {
920 * ---------------------------------------------------------------------------
921 * uf_sdio_mmc_register_pm_notifier
922 * uf_sdio_mmc_unregister_pm_notifier
924 * Register/unregister for power management events. A list is used to
925 * allow multiple card instances to be supported.
928 * sdio_ctx - CSR SDIO context to associate PM notifier to
931 * Register function returns NULL on error
932 * ---------------------------------------------------------------------------
934 static struct uf_sdio_mmc_pm_notifier
*
935 uf_sdio_mmc_register_pm_notifier(CsrSdioFunction
*sdio_ctx
)
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
);
942 notifier_ctx
->sdio_ctx
= sdio_ctx
;
943 notifier_ctx
->pm_notifier
.notifier_call
= uf_sdio_mmc_power_event
;
945 list_add(¬ifier_ctx
->list
, &uf_sdio_mmc_pm_notifiers
.list
);
947 if (register_pm_notifier(¬ifier_ctx
->pm_notifier
)) {
948 printk(KERN_ERR
"unifi: register_pm_notifier failed\n");
956 uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction
*sdio_ctx
)
958 struct uf_sdio_mmc_pm_notifier
*notifier_ctx
;
959 struct list_head
*node
, *q
;
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
);
964 /* If it matches, unregister and free the notifier context */
965 if (notifier_ctx
&& notifier_ctx
->sdio_ctx
== sdio_ctx
)
967 if (unregister_pm_notifier(¬ifier_ctx
->pm_notifier
)) {
968 printk(KERN_ERR
"unifi: unregister_pm_notifier failed\n");
971 /* Remove from list */
972 notifier_ctx
->sdio_ctx
= NULL
;
980 * ---------------------------------------------------------------------------
981 * uf_sdio_mmc_power_event
983 * Handler for power management events.
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.
992 * Status of the event handling
993 * ---------------------------------------------------------------------------
996 uf_sdio_mmc_power_event(struct notifier_block
*this, unsigned long event
, void *ptr
)
998 struct uf_sdio_mmc_pm_notifier
*notifier_ctx
= container_of(this,
999 struct uf_sdio_mmc_pm_notifier
,
1002 /* Call the CSR SDIO function driver's suspend/resume method
1003 * while the userspace is unsuspended.
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
);
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
);
1025 #endif /* CONFIG_PM */
1029 * ---------------------------------------------------------------------------
1030 * uf_glue_sdio_probe
1032 * Card insert callback.
1035 * func Our (glue layer) context pointer.
1038 * UniFi driver error code.
1039 * ---------------------------------------------------------------------------
1042 uf_glue_sdio_probe(struct sdio_func
*func
,
1043 const struct sdio_device_id
*id
)
1046 CsrSdioFunction
*sdio_ctx
;
1050 /* First of all claim the SDIO driver */
1051 sdio_claim_host(func
);
1053 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1054 /* Assume that the card is already powered */
1055 card_is_powered
= 1;
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
);
1063 /* Allocate context */
1064 sdio_ctx
= (CsrSdioFunction
*)kmalloc(sizeof(CsrSdioFunction
),
1066 if (sdio_ctx
== NULL
) {
1067 sdio_release_host(func
);
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;
1080 /* Module parameter enables byte mode */
1081 if (sdio_byte_mode
) {
1082 sdio_ctx
->features
|= CSR_SDIO_FEATURE_BYTE_MODE
;
1085 if (func
->card
->host
->caps
& MMC_CAP_SD_HIGHSPEED
) {
1086 unifi_trace(NULL
, UDBG1
, "MMC_CAP_SD_HIGHSPEED is available\n");
1089 #ifdef MMC_QUIRK_LENIENT_FN0
1090 func
->card
->quirks
|= MMC_QUIRK_LENIENT_FN0
;
1093 /* Pass context to the SDIO driver */
1094 sdio_set_drvdata(func
, sdio_ctx
);
1096 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
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__
);
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
);
1112 /* We have finished, so release the SDIO driver */
1113 sdio_release_host(func
);
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
);
1123 } /* uf_glue_sdio_probe() */
1127 * ---------------------------------------------------------------------------
1128 * uf_glue_sdio_remove
1130 * Card removal callback.
1133 * func Our (glue layer) context pointer.
1136 * UniFi driver error code.
1137 * ---------------------------------------------------------------------------
1140 uf_glue_sdio_remove(struct sdio_func
*func
)
1142 CsrSdioFunction
*sdio_ctx
;
1144 sdio_ctx
= sdio_get_drvdata(func
);
1151 unifi_info(NULL
, "UniFi card removed\n");
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
);
1159 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1161 /* Unregister for PM events */
1162 uf_sdio_mmc_unregister_pm_notifier(sdio_ctx
);
1170 } /* uf_glue_sdio_remove */
1174 * SDIO ids *must* be statically declared, so we can't take
1175 * them from the list passed in csr_sdio_register_driver().
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 */ },
1183 MODULE_DEVICE_TABLE(sdio
, unifi_ids
);
1185 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1189 * ---------------------------------------------------------------------------
1190 * uf_glue_sdio_suspend
1192 * Card suspend callback. The userspace will already be suspended.
1195 * dev The struct device owned by the MMC driver
1199 * ---------------------------------------------------------------------------
1202 uf_glue_sdio_suspend(struct device
*dev
)
1206 unifi_trace(NULL
, UDBG1
, "uf_glue_sdio_suspend");
1210 } /* uf_glue_sdio_suspend */
1214 * ---------------------------------------------------------------------------
1215 * uf_glue_sdio_resume
1217 * Card resume callback. The userspace will still be suspended.
1220 * dev The struct device owned by the MMC driver
1224 * ---------------------------------------------------------------------------
1227 uf_glue_sdio_resume(struct device
*dev
)
1231 unifi_trace(NULL
, UDBG1
, "uf_glue_sdio_resume");
1233 #ifdef ANDROID_BUILD
1234 unifi_trace(NULL
, UDBG1
, "resume: take wakelock\n");
1235 wake_lock(&unifi_sdio_wake_lock
);
1241 } /* uf_glue_sdio_resume */
1243 static struct dev_pm_ops unifi_pm_ops
= {
1244 .suspend
= uf_glue_sdio_suspend
,
1245 .resume
= uf_glue_sdio_resume
,
1248 #define UNIFI_PM_OPS (&unifi_pm_ops)
1252 #define UNIFI_PM_OPS NULL
1254 #endif /* CONFIG_PM */
1257 static struct sdio_driver unifi_driver
= {
1258 .probe
= uf_glue_sdio_probe
,
1259 .remove
= uf_glue_sdio_remove
,
1261 .id_table
= unifi_ids
,
1262 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1263 .drv
.pm
= UNIFI_PM_OPS
,
1269 * ---------------------------------------------------------------------------
1270 * CsrSdioFunctionDriverRegister
1271 * CsrSdioFunctionDriverUnregister
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.
1278 * sdio_drv Pointer to the function driver's SDIO structure.
1282 * ---------------------------------------------------------------------------
1285 CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver
*sdio_drv
)
1289 printk("UniFi: Using native Linux MMC driver for SDIO.\n");
1291 if (sdio_func_drv
) {
1292 unifi_error(NULL
, "sdio_mmc: UniFi driver already registered\n");
1293 return CSR_SDIO_RESULT_INVALID_VALUE
;
1296 #ifdef ANDROID_BUILD
1297 wake_lock_init(&unifi_sdio_wake_lock
, WAKE_LOCK_SUSPEND
, "unifi_sdio_work");
1300 /* Save the registered driver description */
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
1306 sdio_func_drv
= sdio_drv
;
1308 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1310 /* Initialise PM notifier list */
1311 INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers
.list
);
1315 /* Register ourself with mmc_core */
1316 r
= sdio_register_driver(&unifi_driver
);
1318 printk(KERN_ERR
"unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r
);
1319 return ConvertSdioToCsrSdioResult(r
);
1322 return CSR_RESULT_SUCCESS
;
1323 } /* CsrSdioFunctionDriverRegister() */
1328 CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver
*sdio_drv
)
1330 printk(KERN_INFO
"UniFi: unregister from MMC sdio\n");
1332 #ifdef ANDROID_BUILD
1333 wake_lock_destroy(&unifi_sdio_wake_lock
);
1335 sdio_unregister_driver(&unifi_driver
);
1337 sdio_func_drv
= NULL
;
1339 } /* CsrSdioFunctionDriverUnregister() */