forked from Minki/linux
Merge branch 'pm-domains'
* pm-domains: PM / domains: Improve wording of dev_pm_domain_attach() comment PM / Domains: Don't return -EEXIST at attach when PM domain exists spi: Respect all error codes from dev_pm_domain_attach() soundwire: Respect all error codes from dev_pm_domain_attach() mmc: sdio: Respect all error codes from dev_pm_domain_attach() i2c: Respect all error codes from dev_pm_domain_attach() driver core: Respect all error codes from dev_pm_domain_attach() amba: Respect all error codes from dev_pm_domain_attach() PM / Domains: Allow a better error handling of dev_pm_domain_attach() PM / Domains: Check for existing PM domain in dev_pm_domain_attach() PM / Domains: Drop redundant code in genpd while attaching devices PM / Domains: Drop comment in genpd about legacy Samsung DT binding PM / Domains: Fix error path during attach in genpd
This commit is contained in:
commit
5b550c92d7
@ -1257,10 +1257,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
if (dev->pm_domain)
|
||||
return -EEXIST;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Only attach the power domain to the first device if the
|
||||
@ -1268,7 +1265,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
|
||||
* management twice.
|
||||
*/
|
||||
if (!acpi_device_is_first_physical_node(adev, dev))
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
|
||||
acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func);
|
||||
dev_pm_domain_set(dev, &acpi_general_pm_domain);
|
||||
@ -1278,7 +1275,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
|
||||
}
|
||||
|
||||
dev->pm_domain->detach = acpi_dev_pm_detach;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
|
||||
#endif /* CONFIG_PM */
|
||||
|
@ -248,7 +248,7 @@ static int amba_probe(struct device *dev)
|
||||
break;
|
||||
|
||||
ret = dev_pm_domain_attach(dev, true);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = amba_get_enable_pclk(pcdev);
|
||||
@ -375,7 +375,7 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
|
||||
}
|
||||
|
||||
ret = dev_pm_domain_attach(&dev->dev, true);
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
if (ret) {
|
||||
iounmap(tmp);
|
||||
goto err_release;
|
||||
}
|
||||
|
@ -572,17 +572,16 @@ static int platform_drv_probe(struct device *_dev)
|
||||
return ret;
|
||||
|
||||
ret = dev_pm_domain_attach(_dev, true);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(_dev, true);
|
||||
} else {
|
||||
/* don't fail if just dev_pm_domain_attach failed */
|
||||
ret = 0;
|
||||
}
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(_dev, true);
|
||||
}
|
||||
|
||||
out:
|
||||
if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
|
||||
dev_warn(_dev, "probe deferral not supported\n");
|
||||
ret = -ENXIO;
|
||||
|
@ -98,17 +98,21 @@ EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
|
||||
* Callers must ensure proper synchronization of this function with power
|
||||
* management callbacks.
|
||||
*
|
||||
* Returns 0 on successfully attached PM domain or negative error code.
|
||||
* Returns 0 on successfully attached PM domain, or when it is found that the
|
||||
* device doesn't need a PM domain, else a negative error code.
|
||||
*/
|
||||
int dev_pm_domain_attach(struct device *dev, bool power_on)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev->pm_domain)
|
||||
return 0;
|
||||
|
||||
ret = acpi_dev_pm_attach(dev, power_on);
|
||||
if (ret)
|
||||
if (!ret)
|
||||
ret = genpd_dev_pm_attach(dev);
|
||||
|
||||
return ret;
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_domain_attach);
|
||||
|
||||
|
@ -1377,7 +1377,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
|
||||
struct gpd_timing_data *td)
|
||||
{
|
||||
struct generic_pm_domain_data *gpd_data;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s()\n", __func__);
|
||||
|
||||
@ -1390,11 +1390,6 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
|
||||
|
||||
genpd_lock(genpd);
|
||||
|
||||
if (genpd->prepared_count > 0) {
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0;
|
||||
if (ret)
|
||||
goto out;
|
||||
@ -2185,31 +2180,25 @@ static void genpd_dev_pm_sync(struct device *dev)
|
||||
* Parse device's OF node to find a PM domain specifier. If such is found,
|
||||
* attaches the device to retrieved pm_domain ops.
|
||||
*
|
||||
* Both generic and legacy Samsung-specific DT bindings are supported to keep
|
||||
* backwards compatibility with existing DTBs.
|
||||
*
|
||||
* Returns 0 on successfully attached PM domain or negative error code. Note
|
||||
* that if a power-domain exists for the device, but it cannot be found or
|
||||
* turned on, then return -EPROBE_DEFER to ensure that the device is not
|
||||
* probed and to re-try again later.
|
||||
* Returns 1 on successfully attached PM domain, 0 when the device don't need a
|
||||
* PM domain or a negative error code in case of failures. Note that if a
|
||||
* power-domain exists for the device, but it cannot be found or turned on,
|
||||
* then return -EPROBE_DEFER to ensure that the device is not probed and to
|
||||
* re-try again later.
|
||||
*/
|
||||
int genpd_dev_pm_attach(struct device *dev)
|
||||
{
|
||||
struct of_phandle_args pd_args;
|
||||
struct generic_pm_domain *pd;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (!dev->of_node)
|
||||
return -ENODEV;
|
||||
|
||||
if (dev->pm_domain)
|
||||
return -EEXIST;
|
||||
return 0;
|
||||
|
||||
ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
|
||||
"#power-domain-cells", 0, &pd_args);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
mutex_lock(&gpd_list_lock);
|
||||
pd = genpd_get_from_provider(&pd_args);
|
||||
@ -2223,21 +2212,14 @@ int genpd_dev_pm_attach(struct device *dev)
|
||||
|
||||
dev_dbg(dev, "adding to PM domain %s\n", pd->name);
|
||||
|
||||
for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
|
||||
ret = genpd_add_device(pd, dev, NULL);
|
||||
if (ret != -EAGAIN)
|
||||
break;
|
||||
|
||||
mdelay(i);
|
||||
cond_resched();
|
||||
}
|
||||
ret = genpd_add_device(pd, dev, NULL);
|
||||
mutex_unlock(&gpd_list_lock);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to add to PM domain %s: %d",
|
||||
pd->name, ret);
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev->pm_domain->detach = genpd_dev_pm_detach;
|
||||
@ -2246,8 +2228,11 @@ int genpd_dev_pm_attach(struct device *dev)
|
||||
genpd_lock(pd);
|
||||
ret = genpd_power_on(pd, 0);
|
||||
genpd_unlock(pd);
|
||||
out:
|
||||
return ret ? -EPROBE_DEFER : 0;
|
||||
|
||||
if (ret)
|
||||
genpd_remove_device(pd, dev);
|
||||
|
||||
return ret ? -EPROBE_DEFER : 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
|
||||
|
||||
|
@ -363,7 +363,7 @@ static int i2c_device_probe(struct device *dev)
|
||||
goto err_clear_wakeup_irq;
|
||||
|
||||
status = dev_pm_domain_attach(&client->dev, true);
|
||||
if (status == -EPROBE_DEFER)
|
||||
if (status)
|
||||
goto err_clear_wakeup_irq;
|
||||
|
||||
/*
|
||||
|
@ -139,7 +139,7 @@ static int sdio_bus_probe(struct device *dev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = dev_pm_domain_attach(dev, false);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Unbound SDIO functions are always suspended.
|
||||
|
@ -83,17 +83,16 @@ static int sdw_drv_probe(struct device *dev)
|
||||
* attach to power domain but don't turn on (last arg)
|
||||
*/
|
||||
ret = dev_pm_domain_attach(dev, false);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
ret = drv->probe(slave, id);
|
||||
if (ret) {
|
||||
dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
|
||||
dev_pm_domain_detach(dev, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drv->probe(slave, id);
|
||||
if (ret) {
|
||||
dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
|
||||
dev_pm_domain_detach(dev, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* device is probed so let's read the properties now */
|
||||
if (slave->ops && slave->ops->read_prop)
|
||||
slave->ops->read_prop(slave);
|
||||
|
@ -356,11 +356,12 @@ static int spi_drv_probe(struct device *dev)
|
||||
}
|
||||
|
||||
ret = dev_pm_domain_attach(dev, true);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
ret = sdrv->probe(spi);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(dev, true);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sdrv->probe(spi);
|
||||
if (ret)
|
||||
dev_pm_domain_detach(dev, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -899,7 +899,7 @@ static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
|
||||
static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
|
||||
static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
|
||||
{
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -280,7 +280,7 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn,
|
||||
|
||||
static inline int genpd_dev_pm_attach(struct device *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -297,7 +297,7 @@ extern void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
|
||||
#else
|
||||
static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
|
||||
{
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
|
||||
static inline void dev_pm_domain_set(struct device *dev,
|
||||
|
Loading…
Reference in New Issue
Block a user