From mboxrd@z Thu Jan 1 00:00:00 1970 From: Balaji T K Subject: Re: [PATCH v11 7/7] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x Date: Fri, 9 May 2014 22:41:59 +0530 Message-ID: <536D0C5F.5090209@ti.com> References: <1399591018-12930-1-git-send-email-afenkart@gmail.com> <1399591234-13089-1-git-send-email-afenkart@gmail.com> <1399591234-13089-7-git-send-email-afenkart@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Return-path: Received: from devils.ext.ti.com ([198.47.26.153]:36623 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757105AbaEIRMJ (ORCPT ); Fri, 9 May 2014 13:12:09 -0400 In-Reply-To: <1399591234-13089-7-git-send-email-afenkart@gmail.com> Sender: linux-mmc-owner@vger.kernel.org List-Id: linux-mmc@vger.kernel.org To: Andreas Fenkart Cc: Tony Lindgren , Chris Ball , Grant Likely , Felipe Balbi , Andreas Mueller , zonque@gmail.com, galak@codeaurora.org, linux-doc@vger.kernel.org, linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org On Friday 09 May 2014 04:50 AM, Andreas Fenkart wrote: > The am335x can't detect pending cirq in PM runtime suspend. > This patch reconfigures dat1 as a GPIO before going to suspend. > SDIO interrupts are detected with the GPIO, the GPIO will only wake > the module from suspend, SDIO irq detection will still happen through the > IP block. > > Idea of remuxing the pins by Tony Lindgren. Code contributions from > Tony Lindgren and Balaji T K > > Signed-off-by: Andreas Fenkart > Signed-off-by: Tony Lindgren > > Conflicts: > drivers/mmc/host/omap_hsmmc.c Remove above 2 lines Acked-by: Balaji T K > > diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt > index ce80561..946bc5f 100644 > --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt > +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt > @@ -56,3 +56,56 @@ Examples: > &edma 25>; > dma-names = "tx", "rx"; > }; > + > +[workaround for missing swakeup on am33xx] > + > +This SOC is missing the swakeup line, it will not detect SDIO irq > +while in suspend. > + > + ------ > + | PRCM | > + ------ > + ^ | > + swakeup | | fclk > + | v > + ------ ------- ----- > + | card | -- CIRQ --> | hsmmc | -- IRQ --> | CPU | > + ------ ------- ----- > + > +In suspend the fclk is off and the module is disfunctional. Even register reads > +will fail. A small logic in the host will request fclk restore, when an > +external event is detected. Once the clock is restored, the host detects the > +event normally. Since am33xx doesn't have this line it never wakes from > +suspend. > + > +The workaround is to reconfigure the dat1 line as a GPIO upon suspend. To make > +this work, we need to set the named pinctrl states "default" and "idle". > +Prepare idle to remux dat1 as a gpio, and default to remux it back as sdio > +dat1. The MMC driver will then toggle between idle and default state during > +runtime. > + > +In summary: > +1. select matching 'compatible' section, see example below. > +2. specify pinctrl states "default" and "idle", "sleep" is optional. > +3. specify the gpio irq used for detecting sdio irq in suspend > + > +If configuration is incomplete, a warning message is emitted "falling back to > +polling". Also check the "sdio irq mode" in /sys/kernel/debug/mmc0/regs. Mind > +not every application needs SDIO irq, e.g. MMC cards. > + > + mmc1: mmc@48060100 { > + compatible = "ti,am33xx-hsmmc"; > + ... > + pinctrl-names = "default", "idle", "sleep" > + pinctrl-0 = <&mmc1_pins>; > + pinctrl-1 = <&mmc1_idle>; > + pinctrl-2 = <&mmc1_sleep>; > + ... > + interrupts-extended = <&intc 64 &gpio2 28 0>; > + }; > + > + mmc1_idle : pinmux_cirq_pin { > + pinctrl-single,pins = < > + 0x0f8 0x3f /* GPIO2_28 */ > + >; > + }; > diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c > index 5a321f98..497b2fc 100644 > --- a/drivers/mmc/host/omap_hsmmc.c > +++ b/drivers/mmc/host/omap_hsmmc.c > @@ -1782,15 +1782,25 @@ static int omap_hsmmc_configure_wake_irq(struct omap_hsmmc_host *host) > * and need to remux SDIO DAT1 to GPIO for wake-up from idle. > */ > if (host->pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) { > - ret = -ENODEV; > - devm_free_irq(host->dev, host->wake_irq, host); > - goto err; > + if (IS_ERR(host->dev->pins->default_state)) { > + dev_info(host->dev, "missing default pinctrl state\n"); > + ret = -EINVAL; > + goto err_free_irq; > + } > + > + if (IS_ERR(host->dev->pins->idle_state)) { > + dev_info(host->dev, "missing idle pinctrl state\n"); > + ret = -EINVAL; > + goto err_free_irq; > + } > } > > OMAP_HSMMC_WRITE(host->base, HCTL, > OMAP_HSMMC_READ(host->base, HCTL) | IWE); > return 0; > > +err_free_irq: > + devm_free_irq(host->dev, host->wake_irq, host); > err: > dev_warn(host->dev, "no SDIO IRQ support, falling back to polling\n"); > host->wake_irq = 0; >