Message ID | 20150303225355.GE3756@atomide.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, 3 Mar 2015 14:53:55 -0800 Tony Lindgren <tony@atomide.com> wrote: > * NeilBrown <neilb@suse.de> [150223 18:47]: > > 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. > > > > This is particularly important for the Marvell "libertas" wifi chip > > in the GTA04. While in 4-bit mode it will only signal an interrupt > > when the clock is running (which is why setting CLKEXTFREE is > > important). > > In 1-bit mode, the interrupt is asynchronous (explained in OMAP3 > > TRM description of the CIRQ flag to MMCHS_STAT: > > > > In 1-bit mode, interrupt source is asynchronous (can be a source of > > asynchronous wakeup). > > In 4-bit mode, interrupt source is sampled during the interrupt > > cycle. > > > > ) > > > > It is awkward to simply set 1-bit mode in ->runtime_suspend > > as that will call mmc_set_ios which calls ops->set_ios(), > > which will likely call pm_runtime_get_sync(), on the device that > > is currently suspending. This deadlocks. > > > > So: > > - create a work_struct to schedule setting of 1-bit mode > > - introduce an 'sdio_narrowed' state flag which transitions: > > 0 (normal) -> 1 (convert to 1-bit pending) -> > > 2 (have switch to 1-bit mode) -> 0 (normal) > > - create a function mmc_sdio_want_no_clocks() which can be called > > when the driver wants to turn off clocks (presumably after an > > idle timeout). This either succeeds (in 1-bit mode) or fails > > and schedules the work to switch to 1-bit mode. > > - when the host is claimed, if sdio_narrowed is 2, restore the > > 4-bit bus > > - When the host is released, if sdio_narrowed is 1, then some > > caller other than our worker claimed the host first, so > > clear sdio_narrowed. > > > > This all allows a graceful and race-free switch to 1-bit mode > > before switching off the clocks, if SDIO interrupts are enabled. > > > > A host should call mmc_sdio_want_no_clocks() when about to turn off > > clocks if sdio interrupts are enabled, and the ->disable() function > > should not use a timeout (pm_runtime_put_autosuspend) if > > ->sdio_narrowed is 2. > > Wow! A mystery finally solved for why libertas_sdio using devices > like overo won't work for the wakeirqs.. The interface has to be > in 1-bit mode for libertas to produce any SDIO interrupts.. > > Below is a patch enabling some more SDIO wakeirqs. Seems to work > on overo now too :) So tor the whole series, please feel free to > add: > > Tested-by: Tony Lindgren <tony@atomide.com> Thanks a lot! > > 8< ------------------- > From: Tony Lindgren <tony@atomide.com> > Date: Thu, 26 Feb 2015 16:16:03 -0800 > Subject: [PATCH] ARM: dts: Fix omap3 SDIO wakeirqs for devices using sdio_libertas > > Turns out the the MMC interface needs to be in 1-bit mode for the > libertas card to send any SDIO interrupts as pointed out by > NeilBrown <neilb@suse.de>. Now that the MMC framework is getting > fixed for setting 1-bit mode for idle, we can enable SDIO wakeirqs > for libertas using devices too. > > Cc: Andreas Fenkart <afenkart@gmail.com> > Cc: Ash Charles <ash@gumstix.com> > Cc: Florian Vaussard <florian.vaussard@epfl.ch> > Cc: NeilBrown <neil@brown.name> > Signed-off-by: Tony Lindgren <tony@atomide.com> > > --- a/arch/arm/boot/dts/omap3-gta04.dtsi > +++ b/arch/arm/boot/dts/omap3-gta04.dtsi > @@ -367,6 +367,7 @@ > }; > > &mmc2 { > + interrupts-extended = <&intc 86 &omap3_pmx_core 0x12e>; > vmmc-supply = <&vaux4>; > bus-width = <4>; > ti,non-removable; I had + interrupts-extended = <&intc 86 &gpio5 5 0>; /* GPIO_133 */ + pinctrl-names = "default", "idle"; + pinctrl-0 = <&mmc2_pins>; + pinctrl-1 = <&mmc2_cirq_pin>; together with + mmc2_cirq_pin: pinmux_cirq_pin { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE4) + >; + }; + and a longer definition for mmc2_pins. Is that one line reconfigure the pin on demand? How does that work? Thanks, NeilBrown
* NeilBrown <neilb@suse.de> [150303 21:29]: > On Tue, 3 Mar 2015 14:53:55 -0800 Tony Lindgren <tony@atomide.com> wrote: > > > > --- a/arch/arm/boot/dts/omap3-gta04.dtsi > > +++ b/arch/arm/boot/dts/omap3-gta04.dtsi > > @@ -367,6 +367,7 @@ > > }; > > > > &mmc2 { > > + interrupts-extended = <&intc 86 &omap3_pmx_core 0x12e>; > > vmmc-supply = <&vaux4>; > > bus-width = <4>; > > ti,non-removable; > > I had > > + interrupts-extended = <&intc 86 &gpio5 5 0>; /* GPIO_133 */ > + pinctrl-names = "default", "idle"; > + pinctrl-0 = <&mmc2_pins>; > + pinctrl-1 = <&mmc2_cirq_pin>; > > together with > > + mmc2_cirq_pin: pinmux_cirq_pin { > + pinctrl-single,pins = < > + OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE4) > + >; > + }; > + > > > and a longer definition for mmc2_pins. > > Is that one line reconfigure the pin on demand? How does that work? Well the remuxing of the mmc2 dat1 pin is not needed on omap3/4/5. These SoCs have the iochain wake-up events. Remuxing is needed on SoCs with no iochain wake-up events, such as am355x, am437x and dra7 variants. Not sure if we actually have the gpio5 bank wake-up the system properly currently from off-idle. It could be that only gpio1 bank is currently capable of wake-up from off-idle without needing to use the iochain wake-up also for GPIO lines. Regards, Tony -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
--- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -367,6 +367,7 @@ }; &mmc2 { + interrupts-extended = <&intc 86 &omap3_pmx_core 0x12e>; vmmc-supply = <&vaux4>; bus-width = <4>; ti,non-removable; --- a/arch/arm/boot/dts/omap3-overo-base.dtsi +++ b/arch/arm/boot/dts/omap3-overo-base.dtsi @@ -185,6 +185,7 @@ &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; + interrupts-extended = <&intc 86 &omap3_pmx_core 0x12e>; vmmc-supply = <&w3cbw003c_npoweron>; vqmmc-supply = <&w3cbw003c_bt_nreset>; vmmc_aux-supply = <&w3cbw003c_wifi_nreset>;