Loading drivers/acpi/device_pm.c +5 −3 Original line number Diff line number Diff line Loading @@ -118,9 +118,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state) /* * If we were unsure about the device parent's power state up to this * point, the fact that the device is in D0 implies that the parent has * to be in D0 too. * to be in D0 too, except if ignore_parent is set. */ if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN if (!device->power.flags.ignore_parent && device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN && result == ACPI_STATE_D0) device->parent->power.state = ACPI_STATE_D0; Loading Loading @@ -177,7 +178,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) acpi_power_state_string(state)); return -ENODEV; } if (device->parent && (state < device->parent->power.state)) { if (!device->power.flags.ignore_parent && device->parent && (state < device->parent->power.state)) { dev_warn(&device->dev, "Cannot transition to power state %s for parent in %s\n", acpi_power_state_string(state), Loading drivers/i2c/i2c-core.c +5 −0 Original line number Diff line number Diff line Loading @@ -254,10 +254,12 @@ static int i2c_device_probe(struct device *dev) client->flags & I2C_CLIENT_WAKE); dev_dbg(dev, "probe\n"); acpi_dev_pm_attach(&client->dev, true); status = driver->probe(client, i2c_match_id(driver->id_table, client)); if (status) { client->driver = NULL; i2c_set_clientdata(client, NULL); acpi_dev_pm_detach(&client->dev, true); } return status; } Loading @@ -283,6 +285,7 @@ static int i2c_device_remove(struct device *dev) client->driver = NULL; i2c_set_clientdata(client, NULL); } acpi_dev_pm_detach(&client->dev, true); return status; } Loading Loading @@ -1111,8 +1114,10 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, if (ret < 0 || !info.addr) return AE_OK; adev->power.flags.ignore_parent = true; strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); if (!i2c_new_device(adapter, &info)) { adev->power.flags.ignore_parent = false; dev_err(&adapter->dev, "failed to add I2C device %s from ACPI\n", dev_name(&adev->dev)); Loading drivers/spi/spi.c +16 −2 Original line number Diff line number Diff line Loading @@ -240,15 +240,27 @@ EXPORT_SYMBOL_GPL(spi_bus_type); static int spi_drv_probe(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); struct spi_device *spi = to_spi_device(dev); int ret; return sdrv->probe(to_spi_device(dev)); acpi_dev_pm_attach(&spi->dev, true); ret = sdrv->probe(spi); if (ret) acpi_dev_pm_detach(&spi->dev, true); return ret; } static int spi_drv_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); struct spi_device *spi = to_spi_device(dev); int ret; return sdrv->remove(to_spi_device(dev)); ret = sdrv->remove(spi); acpi_dev_pm_detach(&spi->dev, true); return ret; } static void spi_drv_shutdown(struct device *dev) Loading Loading @@ -1025,8 +1037,10 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, return AE_OK; } adev->power.flags.ignore_parent = true; strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias)); if (spi_add_device(spi)) { adev->power.flags.ignore_parent = false; dev_err(&master->dev, "failed to add SPI device %s from ACPI\n", dev_name(&adev->dev)); spi_dev_put(spi); Loading include/acpi/acpi_bus.h +2 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,8 @@ struct acpi_device_power_flags { u32 power_resources:1; /* Power resources */ u32 inrush_current:1; /* Serialize Dx->D0 */ u32 power_removed:1; /* Optimize Dx->D0 */ u32 reserved:28; u32 ignore_parent:1; /* Power is independent of parent power state */ u32 reserved:27; }; struct acpi_device_power_state { Loading Loading
drivers/acpi/device_pm.c +5 −3 Original line number Diff line number Diff line Loading @@ -118,9 +118,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state) /* * If we were unsure about the device parent's power state up to this * point, the fact that the device is in D0 implies that the parent has * to be in D0 too. * to be in D0 too, except if ignore_parent is set. */ if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN if (!device->power.flags.ignore_parent && device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN && result == ACPI_STATE_D0) device->parent->power.state = ACPI_STATE_D0; Loading Loading @@ -177,7 +178,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) acpi_power_state_string(state)); return -ENODEV; } if (device->parent && (state < device->parent->power.state)) { if (!device->power.flags.ignore_parent && device->parent && (state < device->parent->power.state)) { dev_warn(&device->dev, "Cannot transition to power state %s for parent in %s\n", acpi_power_state_string(state), Loading
drivers/i2c/i2c-core.c +5 −0 Original line number Diff line number Diff line Loading @@ -254,10 +254,12 @@ static int i2c_device_probe(struct device *dev) client->flags & I2C_CLIENT_WAKE); dev_dbg(dev, "probe\n"); acpi_dev_pm_attach(&client->dev, true); status = driver->probe(client, i2c_match_id(driver->id_table, client)); if (status) { client->driver = NULL; i2c_set_clientdata(client, NULL); acpi_dev_pm_detach(&client->dev, true); } return status; } Loading @@ -283,6 +285,7 @@ static int i2c_device_remove(struct device *dev) client->driver = NULL; i2c_set_clientdata(client, NULL); } acpi_dev_pm_detach(&client->dev, true); return status; } Loading Loading @@ -1111,8 +1114,10 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, if (ret < 0 || !info.addr) return AE_OK; adev->power.flags.ignore_parent = true; strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); if (!i2c_new_device(adapter, &info)) { adev->power.flags.ignore_parent = false; dev_err(&adapter->dev, "failed to add I2C device %s from ACPI\n", dev_name(&adev->dev)); Loading
drivers/spi/spi.c +16 −2 Original line number Diff line number Diff line Loading @@ -240,15 +240,27 @@ EXPORT_SYMBOL_GPL(spi_bus_type); static int spi_drv_probe(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); struct spi_device *spi = to_spi_device(dev); int ret; return sdrv->probe(to_spi_device(dev)); acpi_dev_pm_attach(&spi->dev, true); ret = sdrv->probe(spi); if (ret) acpi_dev_pm_detach(&spi->dev, true); return ret; } static int spi_drv_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); struct spi_device *spi = to_spi_device(dev); int ret; return sdrv->remove(to_spi_device(dev)); ret = sdrv->remove(spi); acpi_dev_pm_detach(&spi->dev, true); return ret; } static void spi_drv_shutdown(struct device *dev) Loading Loading @@ -1025,8 +1037,10 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level, return AE_OK; } adev->power.flags.ignore_parent = true; strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias)); if (spi_add_device(spi)) { adev->power.flags.ignore_parent = false; dev_err(&master->dev, "failed to add SPI device %s from ACPI\n", dev_name(&adev->dev)); spi_dev_put(spi); Loading
include/acpi/acpi_bus.h +2 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,8 @@ struct acpi_device_power_flags { u32 power_resources:1; /* Power resources */ u32 inrush_current:1; /* Serialize Dx->D0 */ u32 power_removed:1; /* Optimize Dx->D0 */ u32 reserved:28; u32 ignore_parent:1; /* Power is independent of parent power state */ u32 reserved:27; }; struct acpi_device_power_state { Loading