* How to manage SDIO interrupts with a runtime power managed host.
@ 2015-01-27 11:47 NeilBrown
2015-01-27 13:30 ` Ulf Hansson
0 siblings, 1 reply; 2+ messages in thread
From: NeilBrown @ 2015-01-27 11:47 UTC (permalink / raw)
To: linux-mmc, linux-omap; +Cc: GTA04 owners
[-- Attachment #1: Type: text/plain, Size: 2363 bytes --]
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 #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: How to manage SDIO interrupts with a runtime power managed host.
2015-01-27 11:47 How to manage SDIO interrupts with a runtime power managed host NeilBrown
@ 2015-01-27 13:30 ` Ulf Hansson
0 siblings, 0 replies; 2+ messages in thread
From: Ulf Hansson @ 2015-01-27 13:30 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-mmc, linux-omap, GTA04 owners
On 27 January 2015 at 12:47, NeilBrown <neilb@suse.de> wrote:
>
> 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.
I guess the reason to why this isn't implemented in host drivers is
either because such behaviour for SDIO cards hasn't been observed
(that's my case) or that it's kept as "hacks" in out of tree patches.
>
> (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.
Have you really investigated that it's not the GPIO IRQ that's not
been properly configured?
>
> 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.
Okay, so it seems like your assumption is correct. We need a way to
switch to 1-bit when host drivers is about to enter runtime PM suspend
state.
>
> 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.
They are allowed to sleep unless the have set pm_runtime_irq_safe(). I
don't think any of the mmc drivers are configured as such.
>
> 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?
I would prefer not.
I don't like the MMC_CLKGATE thing, since it just add complexity to
the mmc core for things that I think should be handled through runtime
PM instead.
> 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?
That will hit performance for each and every SDIO request. To me this
is not an option.
Kind regards
Uffe
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-01-27 13:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-27 11:47 How to manage SDIO interrupts with a runtime power managed host NeilBrown
2015-01-27 13:30 ` Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox