summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAndreas Fenkart <afenkart@gmail.com>2014-05-29 10:28:05 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2014-07-09 11:26:06 +0200
commit455e5cd6f736478d63a076086c732d287623e366 (patch)
tree6d1e4b37041d8d7a7f7ac983143663fa64fb1289 /drivers/mmc
parentmmc: omap_hsmmc: switch default/idle pinctrl states in runtime hooks (diff)
downloadlinux-455e5cd6f736478d63a076086c732d287623e366.tar.xz
linux-455e5cd6f736478d63a076086c732d287623e366.zip
mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x
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 <balajitk@ti.com> Signed-off-by: Andreas Fenkart <afenkart@gmail.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Acked-by: Balaji T K <balajitk@ti.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5167e55c0849..965672663ef0 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1754,15 +1754,33 @@ 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;
+ struct pinctrl *p = devm_pinctrl_get(host->dev);
+ if (!p) {
+ ret = -ENODEV;
+ goto err_free_irq;
+ }
+ if (IS_ERR(pinctrl_lookup_state(p, PINCTRL_STATE_DEFAULT))) {
+ dev_info(host->dev, "missing default pinctrl state\n");
+ devm_pinctrl_put(p);
+ ret = -EINVAL;
+ goto err_free_irq;
+ }
+
+ if (IS_ERR(pinctrl_lookup_state(p, PINCTRL_STATE_IDLE))) {
+ dev_info(host->dev, "missing idle pinctrl state\n");
+ devm_pinctrl_put(p);
+ ret = -EINVAL;
+ goto err_free_irq;
+ }
+ devm_pinctrl_put(p);
}
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;