aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2013-10-10 06:28:47 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-10-10 20:23:14 -0400
commita76e9bd89ae70fdfff5fd1ca47756a35d10c5f3f (patch)
treeb6bfe78690931cf6c105841d6d622d405653688d
parent644f17ad7fc12768cd619532383343e514eab2ac (diff)
i2c: attach/detach I2C client device to the ACPI power domain
If the I2C client device is enumerated from ACPI namespace it might have ACPI methods that needs to be called in order to transition the device to different power states (such as _PSx). Implement this for I2C client devices by checking if the device has an ACPI handle and if that's the case, attach it to the ACPI power domain. In addition we make sure that the device is fully powered when its ->probe() function gets called. For non-ACPI devices this patch is a no-op. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Wolfram Sang <wsa@the-dreams.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/i2c/i2c-core.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 29d3f045a2bf..03a8ae64d762 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -254,10 +254,12 @@ static int i2c_device_probe(struct device *dev)
254 client->flags & I2C_CLIENT_WAKE); 254 client->flags & I2C_CLIENT_WAKE);
255 dev_dbg(dev, "probe\n"); 255 dev_dbg(dev, "probe\n");
256 256
257 acpi_dev_pm_attach(&client->dev, true);
257 status = driver->probe(client, i2c_match_id(driver->id_table, client)); 258 status = driver->probe(client, i2c_match_id(driver->id_table, client));
258 if (status) { 259 if (status) {
259 client->driver = NULL; 260 client->driver = NULL;
260 i2c_set_clientdata(client, NULL); 261 i2c_set_clientdata(client, NULL);
262 acpi_dev_pm_detach(&client->dev, true);
261 } 263 }
262 return status; 264 return status;
263} 265}
@@ -283,6 +285,7 @@ static int i2c_device_remove(struct device *dev)
283 client->driver = NULL; 285 client->driver = NULL;
284 i2c_set_clientdata(client, NULL); 286 i2c_set_clientdata(client, NULL);
285 } 287 }
288 acpi_dev_pm_detach(&client->dev, true);
286 return status; 289 return status;
287} 290}
288 291
@@ -1111,8 +1114,10 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
1111 if (ret < 0 || !info.addr) 1114 if (ret < 0 || !info.addr)
1112 return AE_OK; 1115 return AE_OK;
1113 1116
1117 adev->power.flags.ignore_parent = true;
1114 strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); 1118 strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
1115 if (!i2c_new_device(adapter, &info)) { 1119 if (!i2c_new_device(adapter, &info)) {
1120 adev->power.flags.ignore_parent = false;
1116 dev_err(&adapter->dev, 1121 dev_err(&adapter->dev,
1117 "failed to add I2C device %s from ACPI\n", 1122 "failed to add I2C device %s from ACPI\n",
1118 dev_name(&adev->dev)); 1123 dev_name(&adev->dev));