Re: [PATCH V2 3/4] mmc: slot-gpio: Add a function to enable/disable card detect IRQ wakeup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 27/02/18 10:45, Ulf Hansson wrote:
> On 14 February 2018 at 13:56, Adrian Hunter <adrian.hunter@xxxxxxxxx> wrote:
>> Commit 03dbaa04a2e5 ("mmc: slot-gpio: Add support to enable irq wake on
>> cd_irq") enabled wakeup irrespective of the host controller's PM flags.
>> However, users also want to control it from sysfs power/wakeup attribute.
>> That means the driver needs to check the PM flags before enabling it in the
>> suspend callback. Add helper function mmc_gpio_set_cd_wake() to make it
>> easy for drivers to do that.
> 
> Depending on if device_may_wakeup() returns true to allow GPIO card
> detect IRQ to be configured as a wakeup IRQ is problematic.
> 
> The reason is related to PM domains (genpd) when it checks the
> dev->power.wakeup_path in system suspend. In case device_may_wakeup()
> returns true, it may lead to the PM domain is kept powered during
> system suspend, while in fact this may not be needed for the GPIO IRQ
> to be configured as wakeup (because the SoC have external HW logic to
> deal with wakeup IRQs).
> 
> So I can't apply this, until we have a solution of how to deal with
> the above situation and I have been working on that. According to the
> latest discussions [1], between me and Rafael, it seems like the
> solution must also take runtime PM wakeups into account.
> 
> Or perhaps you have some other ideas of how we can move forward?

What about removing device_may_wakeup() from mmc_gpio_set_cd_wake()
and leaving it to the driver (sdhci-pci) to decide whether to call
device_may_wakeup()?

> 
>>> Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
>> ---
>>  drivers/mmc/core/core.c       |  3 +--
>>  drivers/mmc/core/slot-gpio.c  | 23 +++++++++++++++++++++++
>>  include/linux/mmc/slot-gpio.h |  1 +
>>  3 files changed, 25 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index c0ba6d8823b7..7bed23c877de 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -2655,8 +2655,7 @@ void mmc_start_host(struct mmc_host *host)
>>  void mmc_stop_host(struct mmc_host *host)
>>  {
>>         if (host->slot.cd_irq >= 0) {
>> -               if (host->slot.cd_wake_enabled)
>> -                       disable_irq_wake(host->slot.cd_irq);
>> +               mmc_gpio_set_cd_wake(host, false);
>>                 disable_irq(host->slot.cd_irq);
>>         }
>>
>> diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
>> index 3698b0576009..817d668aae34 100644
>> --- a/drivers/mmc/core/slot-gpio.c
>> +++ b/drivers/mmc/core/slot-gpio.c
>> @@ -154,6 +154,29 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host)
>>  }
>>  EXPORT_SYMBOL(mmc_gpiod_request_cd_irq);
>>
>> +int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on)
>> +{
>> +       int ret = 0;
>> +
>> +       if (!(host->caps & MMC_CAP_CD_WAKE) ||
>> +           host->slot.cd_irq < 0 ||
>> +           on == host->slot.cd_wake_enabled)
>> +               return 0;
>> +
>> +       if (on) {
>> +               if (device_may_wakeup(mmc_dev(host))) {
>> +                       ret = enable_irq_wake(host->slot.cd_irq);
>> +                       host->slot.cd_wake_enabled = !ret;
>> +               }
>> +       } else {
>> +               disable_irq_wake(host->slot.cd_irq);
>> +               host->slot.cd_wake_enabled = false;
>> +       }
>> +
>> +       return ret;
>> +}
>> +EXPORT_SYMBOL(mmc_gpio_set_cd_wake);
>> +
>>  /* Register an alternate interrupt service routine for
>>   * the card-detect GPIO.
>>   */
>> diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
>> index 91f1ba0663c8..06607c59c4d0 100644
>> --- a/include/linux/mmc/slot-gpio.h
>> +++ b/include/linux/mmc/slot-gpio.h
>> @@ -31,6 +31,7 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
>>                          unsigned int debounce, bool *gpio_invert);
>>  void mmc_gpio_set_cd_isr(struct mmc_host *host,
>>                          irqreturn_t (*isr)(int irq, void *dev_id));
>> +int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on);
>>  void mmc_gpiod_request_cd_irq(struct mmc_host *host);
>>  bool mmc_can_gpio_cd(struct mmc_host *host);
>>  bool mmc_can_gpio_ro(struct mmc_host *host);
>> --
>> 1.9.1
>>
> 
> Kind regards
> Uffe
> 
> [1]
> https://marc.info/?l=linux-pm&m=151689653022118&w=2
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux