mmc: core: Attach PM domain prior probing of SDIO func driver
authorUlf Hansson <ulf.hansson@linaro.org>
Mon, 1 Jun 2015 10:18:25 +0000 (12:18 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Thu, 4 Jun 2015 08:03:51 +0000 (10:03 +0200)
Other subsystem buses attach PM domains during probe, but prior calling
the driver's ->probe() method. During the removal phase, detaching the PM
domain will be done after invoking the driver's ->remove() callback.

Convert the SDIO bus to follow this behavior and add error handling.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/sdio_bus.c

index bee02e6..7e327a6 100644 (file)
@@ -137,6 +137,10 @@ static int sdio_bus_probe(struct device *dev)
        if (!id)
                return -ENODEV;
 
+       ret = dev_pm_domain_attach(dev, false);
+       if (ret == -EPROBE_DEFER)
+               return ret;
+
        /* Unbound SDIO functions are always suspended.
         * During probe, the function is set active and the usage count
         * is incremented.  If the driver supports runtime PM,
@@ -166,6 +170,7 @@ static int sdio_bus_probe(struct device *dev)
 disable_runtimepm:
        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
                pm_runtime_put_noidle(dev);
+       dev_pm_domain_detach(dev, false);
        return ret;
 }
 
@@ -197,6 +202,8 @@ static int sdio_bus_remove(struct device *dev)
        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
                pm_runtime_put_sync(dev);
 
+       dev_pm_domain_detach(dev, false);
+
        return ret;
 }
 
@@ -316,10 +323,8 @@ int sdio_add_func(struct sdio_func *func)
        sdio_set_of_node(func);
        sdio_acpi_set_handle(func);
        ret = device_add(&func->dev);
-       if (ret == 0) {
+       if (ret == 0)
                sdio_func_set_present(func);
-               dev_pm_domain_attach(&func->dev, false);
-       }
 
        return ret;
 }
@@ -335,7 +340,6 @@ void sdio_remove_func(struct sdio_func *func)
        if (!sdio_func_present(func))
                return;
 
-       dev_pm_domain_detach(&func->dev, false);
        device_del(&func->dev);
        of_node_put(func->dev.of_node);
        put_device(&func->dev);