aboutsummaryrefslogtreecommitdiff
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.c165
1 files changed, 14 insertions, 151 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e9eae57a2b50..edf274cabe81 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -102,7 +102,7 @@ static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
struct acpi_resource_i2c_serialbus *sb;
sb = &ares->data.i2c_serial_bus;
- if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+ if (!info->addr && sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
info->addr = sb->slave_address;
if (sb->access_mode == ACPI_I2C_10BIT_MODE)
info->flags |= I2C_CLIENT_TEN;
@@ -679,9 +679,6 @@ static int i2c_device_remove(struct device *dev)
status = driver->remove(client);
}
- if (dev->of_node)
- irq_dispose_mapping(client->irq);
-
dev_pm_domain_detach(&client->dev, true);
return status;
}
@@ -698,101 +695,6 @@ static void i2c_device_shutdown(struct device *dev)
driver->shutdown(client);
}
-#ifdef CONFIG_PM_SLEEP
-static int i2c_legacy_suspend(struct device *dev, pm_message_t mesg)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
-
- if (!client || !dev->driver)
- return 0;
- driver = to_i2c_driver(dev->driver);
- if (!driver->suspend)
- return 0;
- return driver->suspend(client, mesg);
-}
-
-static int i2c_legacy_resume(struct device *dev)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_driver *driver;
-
- if (!client || !dev->driver)
- return 0;
- driver = to_i2c_driver(dev->driver);
- if (!driver->resume)
- return 0;
- return driver->resume(client);
-}
-
-static int i2c_device_pm_suspend(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_suspend(dev);
- else
- return i2c_legacy_suspend(dev, PMSG_SUSPEND);
-}
-
-static int i2c_device_pm_resume(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_resume(dev);
- else
- return i2c_legacy_resume(dev);
-}
-
-static int i2c_device_pm_freeze(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_freeze(dev);
- else
- return i2c_legacy_suspend(dev, PMSG_FREEZE);
-}
-
-static int i2c_device_pm_thaw(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_thaw(dev);
- else
- return i2c_legacy_resume(dev);
-}
-
-static int i2c_device_pm_poweroff(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_poweroff(dev);
- else
- return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
-}
-
-static int i2c_device_pm_restore(struct device *dev)
-{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- if (pm)
- return pm_generic_restore(dev);
- else
- return i2c_legacy_resume(dev);
-}
-#else /* !CONFIG_PM_SLEEP */
-#define i2c_device_pm_suspend NULL
-#define i2c_device_pm_resume NULL
-#define i2c_device_pm_freeze NULL
-#define i2c_device_pm_thaw NULL
-#define i2c_device_pm_poweroff NULL
-#define i2c_device_pm_restore NULL
-#endif /* !CONFIG_PM_SLEEP */
-
static void i2c_client_dev_release(struct device *dev)
{
kfree(to_i2c_client(dev));
@@ -804,6 +706,7 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%s\n", dev->type == &i2c_client_type ?
to_i2c_client(dev)->name : to_i2c_adapter(dev)->name);
}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static ssize_t
show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
@@ -817,8 +720,6 @@ show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
}
-
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
static struct attribute *i2c_dev_attrs[] = {
@@ -827,29 +728,7 @@ static struct attribute *i2c_dev_attrs[] = {
&dev_attr_modalias.attr,
NULL
};
-
-static struct attribute_group i2c_dev_attr_group = {
- .attrs = i2c_dev_attrs,
-};
-
-static const struct attribute_group *i2c_dev_attr_groups[] = {
- &i2c_dev_attr_group,
- NULL
-};
-
-static const struct dev_pm_ops i2c_device_pm_ops = {
- .suspend = i2c_device_pm_suspend,
- .resume = i2c_device_pm_resume,
- .freeze = i2c_device_pm_freeze,
- .thaw = i2c_device_pm_thaw,
- .poweroff = i2c_device_pm_poweroff,
- .restore = i2c_device_pm_restore,
- SET_RUNTIME_PM_OPS(
- pm_generic_runtime_suspend,
- pm_generic_runtime_resume,
- NULL
- )
-};
+ATTRIBUTE_GROUPS(i2c_dev);
struct bus_type i2c_bus_type = {
.name = "i2c",
@@ -857,12 +736,11 @@ struct bus_type i2c_bus_type = {
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
- .pm = &i2c_device_pm_ops,
};
EXPORT_SYMBOL_GPL(i2c_bus_type);
static struct device_type i2c_client_type = {
- .groups = i2c_dev_attr_groups,
+ .groups = i2c_dev_groups,
.uevent = i2c_device_uevent,
.release = i2c_client_dev_release,
};
@@ -1261,6 +1139,7 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
return count;
}
+static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);
/*
* And of course let the users delete the devices they instantiated, if
@@ -1315,8 +1194,6 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
"delete_device");
return res;
}
-
-static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);
static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, S_IWUSR, NULL,
i2c_sysfs_delete_device);
@@ -1326,18 +1203,10 @@ static struct attribute *i2c_adapter_attrs[] = {
&dev_attr_delete_device.attr,
NULL
};
-
-static struct attribute_group i2c_adapter_attr_group = {
- .attrs = i2c_adapter_attrs,
-};
-
-static const struct attribute_group *i2c_adapter_attr_groups[] = {
- &i2c_adapter_attr_group,
- NULL
-};
+ATTRIBUTE_GROUPS(i2c_adapter);
struct device_type i2c_adapter_type = {
- .groups = i2c_adapter_attr_groups,
+ .groups = i2c_adapter_groups,
.release = i2c_adapter_dev_release,
};
EXPORT_SYMBOL_GPL(i2c_adapter_type);
@@ -1419,8 +1288,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE;
- request_module("%s%s", I2C_MODULE_PREFIX, info.type);
-
result = i2c_new_device(adap, &info);
if (result == NULL) {
dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
@@ -1796,11 +1663,15 @@ void i2c_del_adapter(struct i2c_adapter *adap)
/* device name is gone after device_unregister */
dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
- /* clean up the sysfs representation */
+ /* wait until all references to the device are gone
+ *
+ * FIXME: This is old code and should ideally be replaced by an
+ * alternative which results in decoupling the lifetime of the struct
+ * device from the i2c_adapter, like spi or netdev do. Any solution
+ * should be throughly tested with DEBUG_KOBJECT_RELEASE enabled!
+ */
init_completion(&adap->dev_released);
device_unregister(&adap->dev);
-
- /* wait for sysfs to drop all references */
wait_for_completion(&adap->dev_released);
/* free bus id */
@@ -1859,14 +1730,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
if (res)
return res;
- /* Drivers should switch to dev_pm_ops instead. */
- if (driver->suspend)
- pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
- driver->driver.name);
- if (driver->resume)
- pr_warn("i2c-core: driver [%s] using legacy resume method\n",
- driver->driver.name);
-
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
INIT_LIST_HEAD(&driver->clients);