On Tue, 4 Sep 2018 21:41:17 +0200 Andreas Kemnade <andreas@xxxxxxxxxxxx> wrote: > Hi, > [...] > > [...] > &mmc2 { > pinctrl-names = "default", "idle"; > pinctrl-0 = <&mmc2_pins>; > pinctrl-1 = <&mmc2_idle_pins>; > > /* dat1 remuxed as gpio133 */ > interrupts-extended = <&intc 86>, <&gpio5 5 IRQ_TYPE_LEVEL_LOW>; > vmmc-supply = <&vaux4>; > bus-width = <4>; > ti,non-removable; /* remove ti, */ > mmc-pwrseq = <&wifi_pwrseq>; > cap-power-off-card; /* remove! */ > }; > > > Result: works with 4bit, Irq count is sane as long as the card > is powered on. On a wifi with low traffic I get around 2 irqs per second > But if as soon as I power off the card by doing ifconfig down, I get > around 10 irqs per second which could be explained by the fact that > autosuspend time is 100ms, and it is waking up just immediately. > Reason is probably that the other side of the level shifter powered > off and low, so > dat1 will be low permanently. And since wakeup is enabled regardless of > whether sdio irq or anything else is enabled, hsmmc will never get a > good sleep. > That behavior (I have to check that) was probably introduced by > 5b83b2234be6 ("mmc: omap_hsmmc: Change wake-up interrupt to use generic wakeirq"). > > I guess there is also a race somehow involved here. Ok, what fixes the problem: use above mentioned devicetree, reverting 5b83b2234be6 and applying this patch: --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2276,6 +2276,14 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) int ret = 0; host = platform_get_drvdata(to_platform_device(dev)); + spin_lock_irqsave(&host->irq_lock, flags); + if ((host->mmc->caps & MMC_CAP_SDIO_IRQ) && + (host->flags & HSMMC_SDIO_IRQ_ENABLED)) { + WARN_ON(host->flags & HSMMC_WAKE_IRQ_ENABLED); + enable_irq(host->wake_irq); + host->flags |= HSMMC_WAKE_IRQ_ENABLED; + } + spin_unlock_irqrestore(&host->irq_lock, flags); omap_hsmmc_context_save(host); dev_dbg(dev, "disabled\n"); @@ -2303,9 +2311,6 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) pinctrl_pm_select_idle_state(dev); - WARN_ON(host->flags & HSMMC_WAKE_IRQ_ENABLED); - enable_irq(host->wake_irq); - host->flags |= HSMMC_WAKE_IRQ_ENABLED; } else { pinctrl_pm_select_idle_state(dev); } This brings things in the same order as done with generic wakeirq. So I just have to convert this into a clean patch using the generic wakeirq api and add the devicetree entry. Regards, Andreas
Attachment:
pgpajAud1JyNV.pgp
Description: OpenPGP digital signature