Merge branch 'acpi-pm'
* acpi-pm: spi: attach/detach SPI device to the ACPI power domain i2c: attach/detach I2C client device to the ACPI power domain ACPI / PM: allow child devices to ignore parent power state
This commit is contained in:
commit
dd6c26be3b
|
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
@ -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);
|
||||
|
|
|
@ -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…
Reference in a new issue