From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932995AbcBYJt3 (ORCPT ); Thu, 25 Feb 2016 04:49:29 -0500 Received: from eusmtp01.atmel.com ([212.144.249.242]:43847 "EHLO eusmtp01.atmel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932680AbcBYJtY (ORCPT ); Thu, 25 Feb 2016 04:49:24 -0500 Date: Thu, 25 Feb 2016 10:49:12 +0100 From: Ludovic Desroches To: CC: , , , , Ludovic Desroches Subject: Re: [PATCH] mmc: sdhci-of-at91: fix wakeup issue when using runtime pm Message-ID: <20160225094912.GC7249@odux.rfo.atmel.com> Mail-Followup-To: ulf.hansson@linaro.org, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, nicolas.ferre@atmel.com, adrian.hunter@intel.com References: <20160212120415.GJ14937@odux.rfo.atmel.com> <1455357400-32145-1-git-send-email-ludovic.desroches@atmel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <1455357400-32145-1-git-send-email-ludovic.desroches@atmel.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Feb 13, 2016 at 10:56:40AM +0100, Ludovic Desroches wrote: > When suspending the sdhci host, the only hardware event that could wake > up the host is a sdio irq if they are enabled. If we want to wakeup on > card detect events, a gpio as to be used. > If we don't want to use a gpio but the card detect pio of the controller > then we need to keep enabled the clock of the controller interface to > get the interrupt and to not set the host in a suspended state to have the > interrupt handled. > How can I move forward on this topic? I have several issues related to runtime PM (card detection, wifi module which doesn't like to get clocks disabled) but I am not in favour to get rid of it. Regards Ludovic > Signed-off-by: Ludovic Desroches > --- > drivers/mmc/host/sdhci-of-at91.c | 46 ++++++++++++++++++++++++++++++---------- > 1 file changed, 35 insertions(+), 11 deletions(-) > > diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c > index efec736..2159c6e 100644 > --- a/drivers/mmc/host/sdhci-of-at91.c > +++ b/drivers/mmc/host/sdhci-of-at91.c > @@ -18,6 +18,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -45,7 +46,6 @@ static const struct sdhci_ops sdhci_at91_sama5d2_ops = { > > static const struct sdhci_pltfm_data soc_data_sama5d2 = { > .ops = &sdhci_at91_sama5d2_ops, > - .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION, > .quirks2 = SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST, > }; > > @@ -55,17 +55,37 @@ static const struct of_device_id sdhci_at91_dt_match[] = { > }; > > #ifdef CONFIG_PM > +static bool sdhci_at91_use_sdhci_runtime(struct sdhci_host *host) > +{ > + u32 caps = host->mmc->caps; > + > + return (caps & MMC_CAP_NONREMOVABLE) || > + (!IS_ERR_VALUE(mmc_gpio_get_cd(host->mmc))); > +} > + > static int sdhci_at91_runtime_suspend(struct device *dev) > { > struct sdhci_host *host = dev_get_drvdata(dev); > struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > struct sdhci_at91_priv *priv = pltfm_host->priv; > - int ret; > + int ret = 0; > > - ret = sdhci_runtime_suspend_host(host); > + /* > + * If we call sdhci_runtime_suspend(), we could wakeup only if sdio > + * irqs are enabled. If we want to wakeup on a card detect event there > + * are two options: > + * - do not call sdhci_runtime_suspend() but save power by disabling > + * all clocks excepting the one for the controller interface. > + * - call sdhci_runtime_suspend(), save maximum power by disabling > + * all clocks but use a gpio for the card detect signal to have a way > + * to wakeup. > + */ > + if (sdhci_at91_use_sdhci_runtime(host)) { > + ret = sdhci_runtime_suspend_host(host); > + clk_disable_unprepare(priv->hclock); > + } > > clk_disable_unprepare(priv->gck); > - clk_disable_unprepare(priv->hclock); > clk_disable_unprepare(priv->mainck); > > return ret; > @@ -84,19 +104,23 @@ static int sdhci_at91_runtime_resume(struct device *dev) > return ret; > } > > - ret = clk_prepare_enable(priv->hclock); > - if (ret) { > - dev_err(dev, "can't enable hclock\n"); > - return ret; > - } > - > ret = clk_prepare_enable(priv->gck); > if (ret) { > dev_err(dev, "can't enable gck\n"); > return ret; > } > > - return sdhci_runtime_resume_host(host); > + if (sdhci_at91_use_sdhci_runtime(host)) { > + ret = clk_prepare_enable(priv->hclock); > + if (ret) { > + dev_err(dev, "can't enable hclock\n"); > + return ret; > + } > + > + ret = sdhci_runtime_resume_host(host); > + } > + > + return ret; > } > #endif /* CONFIG_PM */ > > -- > 2.7.0 >