summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 4f34823e86b..10be7b5fbe9 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -155,6 +155,35 @@ static void i2c_device_shutdown(struct device *dev)
driver->shutdown(client);
}
+#ifdef CONFIG_SUSPEND
+static int i2c_device_pm_suspend(struct device *dev)
+{
+ const struct dev_pm_ops *pm;
+
+ if (!dev->driver)
+ return 0;
+ pm = dev->driver->pm;
+ if (!pm || !pm->suspend)
+ return 0;
+ return pm->suspend(dev);
+}
+
+static int i2c_device_pm_resume(struct device *dev)
+{
+ const struct dev_pm_ops *pm;
+
+ if (!dev->driver)
+ return 0;
+ pm = dev->driver->pm;
+ if (!pm || !pm->resume)
+ return 0;
+ return pm->resume(dev);
+}
+#else
+#define i2c_device_pm_suspend NULL
+#define i2c_device_pm_resume NULL
+#endif
+
static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
{
struct i2c_client *client = i2c_verify_client(dev);
@@ -219,6 +248,11 @@ static const struct attribute_group *i2c_dev_attr_groups[] = {
NULL
};
+static const struct dev_pm_ops i2c_device_pm_ops = {
+ .suspend = i2c_device_pm_suspend,
+ .resume = i2c_device_pm_resume,
+};
+
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
@@ -227,6 +261,7 @@ struct bus_type i2c_bus_type = {
.shutdown = i2c_device_shutdown,
.suspend = i2c_device_suspend,
.resume = i2c_device_resume,
+ .pm = &i2c_device_pm_ops,
};
EXPORT_SYMBOL_GPL(i2c_bus_type);
@@ -808,6 +843,9 @@ int i2c_del_adapter(struct i2c_adapter *adap)
adap->dev.parent);
#endif
+ /* device name is gone after device_unregister */
+ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
+
/* clean up the sysfs representation */
init_completion(&adap->dev_released);
device_unregister(&adap->dev);
@@ -820,8 +858,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
idr_remove(&i2c_adapter_idr, adap->nr);
mutex_unlock(&core_lock);
- dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
-
/* Clear the device structure in case this adapter is ever going to be
added again */
memset(&adap->dev, 0, sizeof(adap->dev));
@@ -1184,7 +1220,7 @@ static int i2c_detect_address(struct i2c_client *temp_client,
/* Finally call the custom detection function */
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = addr;
- err = driver->detect(temp_client, -1, &info);
+ err = driver->detect(temp_client, &info);
if (err) {
/* -ENODEV is returned if the detection fails. We catch it
here as this isn't an error. */
@@ -1214,13 +1250,13 @@ static int i2c_detect_address(struct i2c_client *temp_client,
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
{
- const struct i2c_client_address_data *address_data;
+ const unsigned short *address_list;
struct i2c_client *temp_client;
int i, err = 0;
int adap_id = i2c_adapter_id(adapter);
- address_data = driver->address_data;
- if (!driver->detect || !address_data)
+ address_list = driver->address_list;
+ if (!driver->detect || !address_list)
return 0;
/* Set up a temporary client to help detect callback */
@@ -1235,7 +1271,7 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
/* Stop here if we can't use SMBUS_QUICK */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
- if (address_data->normal_i2c[0] == I2C_CLIENT_END)
+ if (address_list[0] == I2C_CLIENT_END)
goto exit_free;
dev_warn(&adapter->dev, "SMBus Quick command not supported, "
@@ -1244,11 +1280,10 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
goto exit_free;
}
- for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) {
+ for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
- "addr 0x%02x\n", adap_id,
- address_data->normal_i2c[i]);
- temp_client->addr = address_data->normal_i2c[i];
+ "addr 0x%02x\n", adap_id, address_list[i]);
+ temp_client->addr = address_list[i];
err = i2c_detect_address(temp_client, driver);
if (err)
goto exit_free;