How to manage SDIO interrupts with a runtime power managed host.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: pgpyooh3jt9d8.pgp
Description: OpenPGP digital signature


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux