Re: [RFC/PATCH] mmc: core: Signal wakeup event at card insert/removal

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

 



On 09/23/2013 09:11 PM, Ulf Hansson wrote:
> On 23 September 2013 12:55, Jaehoon Chung <jh80.chung@xxxxxxxxxxx> wrote:
>> Hi Ulf,
>>
>> On 09/20/2013 06:48 PM, Ulf Hansson wrote:
>>> We want to give user space provision to fully consume a card
>>> insert/remove event, when the event was caused by a wakeup irq.
>>>
>>> By signaling the wakeup event for a time of 5 s for devices configured
>>> as wakeup capable, we likely will be prevent a sleep long enough to let
>>> user space consume the event.
>>>
>>> To enable this feature, host drivers must thus configure their devices
>>> as wakeup capable.
>>>
>>> This is a reworked implementation of the old wakelocks for the mmc
>>> subsystem, originally authored by Colin Cross and San Mehat for the
>>> Android kernel. Zoran Markovic shall also be given cred for recently
>>> re-trying to upstream this feature.
>>>
>>> Cc: San Mehat <san@xxxxxxxxxx>
>>> Cc: Colin Cross <ccross@xxxxxxxxxxx>
>>> Cc: John Stultz <john.stultz@xxxxxxxxxx>
>>> Cc: Zoran Markovic <zoran.markovic@xxxxxxxxxx>
>>> Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx>
>>> ---
>>>
>>> This patch has just been compile tested, since I at very moment did not
>>> have a good board to test it on. I am working on that.
>>>
>>> Any help in testing this patch is thus greatly appreciated. While
>>> testing also don't forget to enable the host device as wakeup capable.
>>> Use "device_init_wakeup" from the host probe function.
>>
> 
> Hi Jaehoon,
> 
> Thanks for helping out testing this patch!
> 
>> I used the device_init_wakeup(&pdev->dev, 1) into host controller. (Also enabled the irq for wakeup)
>> It didn't work when device is suspended.
>> Well, i might missed something.
> 
> Not sure what you mean by didn't work here. Did the card detect irq
> wake up the platform and thus triggered a resume? Or you mean that
> even that did not work?
> 
>> As my understanding, it's helpful that wakeup-event is used when device is suspended.
> 
> This feature is typically used for devices using "autosuspend", like
> Android devices. Otherwise you likely do not want to wakeup the
> platform when inserting/removing a card, but that is another story.
> :-)
Hi Ulf,

Then, my case should be another story. I will re-test with using "autosuspend".
I didn't use the autosuspend.
> 
>> How do you call mmc_detect_change() during suspended?

In my case,
1, entered suspended.
2. card is inserted..then didn't get the triggered irq.
If get the triggered irq, need to set irq_set_irq_wake(cd_irq, 1).

So i have asked to you how called mmc_detect_change().
In my-case, didn't call mmc_detect_change().

I will re-test and share the result.

Best Regards,
Jaehoon Chung
> 
> To try to clarify things a bit, the sequence is typically like this:
> 
> 1. We enter suspend.
> 2. A card is inserted and a card detect irq is triggered. The
> corresponding irq handler gets called which then issue
> mmc_detect_change.
> 3. mmc_detect_change recognize the device as a wakeup capable device
> and thus issue a pm_wakeup_event(5s) to prevent a new trigger of
> suspend.
> 4. A rescan work is scheduled.
> 5. System continues resuming.
> 6. After PM_POST_SUSPEND notification (mmc_pm_notify), rescan is
> enabled and a new work re-scheduled.
> 7. The rescan work detects the new card and user space soon gets
> notified about it.
> 8. User space gets the notification and can act on it.
> 9. The timeout of the pm_wakeup_event has elapsed, allowing a new
> suspend to be triggered.
> 
> 
> Kind regards
> Ulf Hansson
> 
>>
>> Best Regards,
>> Jaehoon Chung
>>>
>>> ---
>>>  drivers/mmc/core/core.c |   39 +++++++++++++++++++++++++++------------
>>>  1 file changed, 27 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index bf18b6b..3e8229e 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -23,6 +23,7 @@
>>>  #include <linux/log2.h>
>>>  #include <linux/regulator/consumer.h>
>>>  #include <linux/pm_runtime.h>
>>> +#include <linux/pm_wakeup.h>
>>>  #include <linux/suspend.h>
>>>  #include <linux/fault-inject.h>
>>>  #include <linux/random.h>
>>> @@ -1723,6 +1724,28 @@ void mmc_detach_bus(struct mmc_host *host)
>>>       mmc_bus_put(host);
>>>  }
>>>
>>> +static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
>>> +                             bool cd_irq)
>>> +{
>>> +#ifdef CONFIG_MMC_DEBUG
>>> +     unsigned long flags;
>>> +     spin_lock_irqsave(&host->lock, flags);
>>> +     WARN_ON(host->removed);
>>> +     spin_unlock_irqrestore(&host->lock, flags);
>>> +#endif
>>> +
>>> +     /*
>>> +      * If the device is configured as wakeup, we prevent a new sleep for
>>> +      * 5 s to give provision for user space to consume the event.
>>> +      */
>>> +     if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) &&
>>> +             device_can_wakeup(mmc_dev(host)))
>>> +             pm_wakeup_event(mmc_dev(host), 5000);
>>> +
>>> +     host->detect_change = 1;
>>> +     mmc_schedule_delayed_work(&host->detect, delay);
>>> +}
>>> +
>>>  /**
>>>   *   mmc_detect_change - process change of state on a MMC socket
>>>   *   @host: host which changed state.
>>> @@ -1735,16 +1758,8 @@ void mmc_detach_bus(struct mmc_host *host)
>>>   */
>>>  void mmc_detect_change(struct mmc_host *host, unsigned long delay)
>>>  {
>>> -#ifdef CONFIG_MMC_DEBUG
>>> -     unsigned long flags;
>>> -     spin_lock_irqsave(&host->lock, flags);
>>> -     WARN_ON(host->removed);
>>> -     spin_unlock_irqrestore(&host->lock, flags);
>>> -#endif
>>> -     host->detect_change = 1;
>>> -     mmc_schedule_delayed_work(&host->detect, delay);
>>> +     _mmc_detect_change(host, delay, true);
>>>  }
>>> -
>>>  EXPORT_SYMBOL(mmc_detect_change);
>>>
>>>  void mmc_init_erase(struct mmc_card *card)
>>> @@ -2423,7 +2438,7 @@ int mmc_detect_card_removed(struct mmc_host *host)
>>>                        * rescan handle the card removal.
>>>                        */
>>>                       cancel_delayed_work(&host->detect);
>>> -                     mmc_detect_change(host, 0);
>>> +                     _mmc_detect_change(host, 0, false);
>>>               }
>>>       }
>>>
>>> @@ -2505,7 +2520,7 @@ void mmc_start_host(struct mmc_host *host)
>>>               mmc_power_off(host);
>>>       else
>>>               mmc_power_up(host);
>>> -     mmc_detect_change(host, 0);
>>> +     _mmc_detect_change(host, 0, false);
>>>  }
>>>
>>>  void mmc_stop_host(struct mmc_host *host)
>>> @@ -2724,7 +2739,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
>>>               spin_lock_irqsave(&host->lock, flags);
>>>               host->rescan_disable = 0;
>>>               spin_unlock_irqrestore(&host->lock, flags);
>>> -             mmc_detect_change(host, 0);
>>> +             _mmc_detect_change(host, 0, false);
>>>
>>>       }
>>>
>>>
>>
> --
> 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
> 

--
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