Merge branch 'i2c/for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[platform/kernel/linux-exynos.git] / drivers / i2c / i2c-core.c
index e9eae57..210cf48 100644 (file)
@@ -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;
@@ -698,101 +698,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 +709,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 +723,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 +731,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 +739,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 +1142,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 +1197,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 +1206,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 +1291,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 +1666,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 +1733,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);