mmc: core: Always allow the card detect uevent to be consumed
authorUlf Hansson <ulf.hansson@linaro.org>
Fri, 29 May 2020 10:23:41 +0000 (12:23 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 13 Jul 2020 10:18:22 +0000 (12:18 +0200)
The approach to allow userspace ~5s to consume the uevent, which is
triggered when a new card is inserted/initialized, currently requires the
mmc host to support system wakeup.

This is unnecessary limiting, especially for an mmc host that relies on a
GPIO IRQ for card detect. More precisely, the mmc host may not support
system wakeup for its corresponding struct device, while the GPIO IRQ still
could be configured as a wakeup IRQ via enable_irq_wake().

To support all various cases, let's simply drop the need for the wakeup
support. Instead let's always register a wakeup source and activate it for
all card detect IRQs by calling __pm_wakeup_event().

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Link: https://lore.kernel.org/r/20200529102341.12529-1-ulf.hansson@linaro.org
drivers/mmc/core/core.c
drivers/mmc/core/host.c
include/linux/mmc/host.h

index 8d2b808..aff3fa9 100644 (file)
@@ -1455,12 +1455,12 @@ void mmc_detach_bus(struct mmc_host *host)
 void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq)
 {
        /*
-        * 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.
+        * Prevent system sleep for 5s to allow user space to consume the
+        * corresponding uevent. This is especially useful, when CD irq is used
+        * as a system wakeup, but doesn't hurt in other cases.
         */
-       if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) &&
-               device_can_wakeup(mmc_dev(host)))
-               pm_wakeup_event(mmc_dev(host), 5000);
+       if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL))
+               __pm_wakeup_event(host->ws, 5000);
 
        host->detect_change = 1;
        mmc_schedule_delayed_work(&host->detect, delay);
index c876872..6141a85 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/pagemap.h>
+#include <linux/pm_wakeup.h>
 #include <linux/export.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
@@ -36,6 +37,7 @@ static DEFINE_IDA(mmc_host_ida);
 static void mmc_host_classdev_release(struct device *dev)
 {
        struct mmc_host *host = cls_dev_to_mmc_host(dev);
+       wakeup_source_unregister(host->ws);
        ida_simple_remove(&mmc_host_ida, host->index);
        kfree(host);
 }
@@ -400,6 +402,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        host->index = err;
 
        dev_set_name(&host->class_dev, "mmc%d", host->index);
+       host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev));
 
        host->parent = dev;
        host->class_dev.parent = dev;
index 7149bab..1fa4fa1 100644 (file)
@@ -287,6 +287,7 @@ struct mmc_host {
 #ifdef CONFIG_PM_SLEEP
        struct notifier_block   pm_notify;
 #endif
+       struct wakeup_source    *ws;            /* Enable consume of uevents */
        u32                     max_current_330;
        u32                     max_current_300;
        u32                     max_current_180;