The (libertas) wifi chip in my GTA04 is connected to an OMAP3 HS_MMC port as an SDIO card. When I configure it (via devicetree) to respond to the SD interrupt line (rather than polling for SD interrupts) it doesn't work well at all. After lots of experimenting and beating my head against a brick wall I have finally discovered why. According to section 7.1.2 of http://www.sandisk.com/media/File/OEM/Manuals/SD_SDIO_specsv1.pdf In the case where the interrupt mechanism is used to wake the host while the card is in a low power state (i.e. no clocks), Both the card and the host shall be placed into the 1-bit SD mode prior to stopping the clock. The omap_hsmmc driver doesn't appear to be aware of this requirement (and I cannot see that other host drivers are either). It will turn off the clocks for a 4-bit device without first switching to 1-bit. (The mmc core does switch to 1-bit mode for system suspend, but not for runtime suspend). This requirement exactly explains my observations. The chip is configured for 4-bit mode, and once pm_runtime turns the clocks off, interrupts stop being delivered. Note that the "reconfigure DAT1 as a GPIO" magic is properly configured. When something else wakes the chip, the GPIO interrupt handler will sometimes run in the small window between the clocks coming back and the DAT1 pin being configured back to the default setting. If I configure the chip as using a 1-bit wide interface, it works perfectly. In this configuration it is significantly faster than 4-bit polled mode, but somewhat slower than 4-bit interrupt mode with runtime_pm disabled. I'm open for suggestions on how best to fix this. I tried putting code into the pm_runtime_{suspend,resume} callbacks in omap_hsmmc.c to switch the bus width, but that doesn't work. The callbacks aren't allowed to sleep, and telling the card to use the new bus width is a sleeping operation. I imagine I could possibly do something similar to MMC_CLKGATE to switch to 1-bit mode after some idle time, and have the pm_runtime_suspend abort if it is still in 4-bit mode. Would that be a good idea? Would it make sense to get mmc_gate_clock to switch bus width (if it is an SDIO card with interrupts enabled) rather than having a separate timeout thing? Thoughts? Thanks, NeilBrown
Attachment:
pgpx1J1MI3Ivx.pgp
Description: OpenPGP digital signature