Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd6c26be authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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
parents c0ced86d 33cf00e5
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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),
+5 −0
Original line number Diff line number Diff line
@@ -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));
+16 −2
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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 {