]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/i2c/i2c-core.c
Merge branch 'master' into tk71
[mv-sheeva.git] / drivers / i2c / i2c-core.c
index bea4c5021d26cb5b4c92e9b58cabeda2b882023c..f0bd5bcdf56329294b5cab85a0fe41ce06600dd6 100644 (file)
@@ -196,88 +196,60 @@ static int i2c_device_pm_suspend(struct device *dev)
 {
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
-       if (pm) {
-               if (pm_runtime_suspended(dev))
-                       return 0;
-               else
-                       return pm->suspend ? pm->suspend(dev) : 0;
-       }
-
-       return i2c_legacy_suspend(dev, PMSG_SUSPEND);
+       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;
-       int ret;
 
        if (pm)
-               ret = pm->resume ? pm->resume(dev) : 0;
+               return pm_generic_resume(dev);
        else
-               ret = i2c_legacy_resume(dev);
-
-       return ret;
+               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) {
-               if (pm_runtime_suspended(dev))
-                       return 0;
-               else
-                       return pm->freeze ? pm->freeze(dev) : 0;
-       }
-
-       return i2c_legacy_suspend(dev, PMSG_FREEZE);
+       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) {
-               if (pm_runtime_suspended(dev))
-                       return 0;
-               else
-                       return pm->thaw ? pm->thaw(dev) : 0;
-       }
-
-       return i2c_legacy_resume(dev);
+       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) {
-               if (pm_runtime_suspended(dev))
-                       return 0;
-               else
-                       return pm->poweroff ? pm->poweroff(dev) : 0;
-       }
-
-       return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
+       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;
-       int ret;
 
        if (pm)
-               ret = pm->restore ? pm->restore(dev) : 0;
+               return pm_generic_restore(dev);
        else
-               ret = i2c_legacy_resume(dev);
-
-       if (!ret) {
-               pm_runtime_disable(dev);
-               pm_runtime_set_active(dev);
-               pm_runtime_enable(dev);
-       }
-
-       return ret;
+               return i2c_legacy_resume(dev);
 }
 #else /* !CONFIG_PM_SLEEP */
 #define i2c_device_pm_suspend  NULL
@@ -425,14 +397,14 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp)
 /* walk up mux tree */
 static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr)
 {
+       struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
        int result;
 
        result = device_for_each_child(&adapter->dev, &addr,
                                        __i2c_check_addr_busy);
 
-       if (!result && i2c_parent_is_i2c_adapter(adapter))
-               result = i2c_check_mux_parents(
-                                   to_i2c_adapter(adapter->dev.parent), addr);
+       if (!result && parent)
+               result = i2c_check_mux_parents(parent, addr);
 
        return result;
 }
@@ -453,11 +425,11 @@ static int i2c_check_mux_children(struct device *dev, void *addrp)
 
 static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
 {
+       struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
        int result = 0;
 
-       if (i2c_parent_is_i2c_adapter(adapter))
-               result = i2c_check_mux_parents(
-                                   to_i2c_adapter(adapter->dev.parent), addr);
+       if (parent)
+               result = i2c_check_mux_parents(parent, addr);
 
        if (!result)
                result = device_for_each_child(&adapter->dev, &addr,
@@ -472,8 +444,10 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
  */
 void i2c_lock_adapter(struct i2c_adapter *adapter)
 {
-       if (i2c_parent_is_i2c_adapter(adapter))
-               i2c_lock_adapter(to_i2c_adapter(adapter->dev.parent));
+       struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+
+       if (parent)
+               i2c_lock_adapter(parent);
        else
                rt_mutex_lock(&adapter->bus_lock);
 }
@@ -485,8 +459,10 @@ EXPORT_SYMBOL_GPL(i2c_lock_adapter);
  */
 static int i2c_trylock_adapter(struct i2c_adapter *adapter)
 {
-       if (i2c_parent_is_i2c_adapter(adapter))
-               return i2c_trylock_adapter(to_i2c_adapter(adapter->dev.parent));
+       struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+
+       if (parent)
+               return i2c_trylock_adapter(parent);
        else
                return rt_mutex_trylock(&adapter->bus_lock);
 }
@@ -497,8 +473,10 @@ static int i2c_trylock_adapter(struct i2c_adapter *adapter)
  */
 void i2c_unlock_adapter(struct i2c_adapter *adapter)
 {
-       if (i2c_parent_is_i2c_adapter(adapter))
-               i2c_unlock_adapter(to_i2c_adapter(adapter->dev.parent));
+       struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+
+       if (parent)
+               i2c_unlock_adapter(parent);
        else
                rt_mutex_unlock(&adapter->bus_lock);
 }
@@ -677,8 +655,6 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
        char *blank, end;
        int res;
 
-       dev_warn(dev, "The new_device interface is still experimental "
-                "and may change in a near future\n");
        memset(&info, 0, sizeof(struct i2c_board_info));
 
        blank = strchr(buf, ' ');
@@ -844,6 +820,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
                goto out_list;
        }
 
+       /* Sanity checks */
+       if (unlikely(adap->name[0] == '\0')) {
+               pr_err("i2c-core: Attempt to register an adapter with "
+                      "no name!\n");
+               return -EINVAL;
+       }
+       if (unlikely(!adap->algo)) {
+               pr_err("i2c-core: Attempt to register adapter '%s' with "
+                      "no algo!\n", adap->name);
+               return -EINVAL;
+       }
+
        rt_mutex_init(&adap->bus_lock);
        mutex_init(&adap->userspace_clients_lock);
        INIT_LIST_HEAD(&adap->userspace_clients);
@@ -1003,6 +991,14 @@ static int i2c_do_del_adapter(struct i2c_driver *driver,
 }
 
 static int __unregister_client(struct device *dev, void *dummy)
+{
+       struct i2c_client *client = i2c_verify_client(dev);
+       if (client && strcmp(client->name, "dummy"))
+               i2c_unregister_device(client);
+       return 0;
+}
+
+static int __unregister_dummy(struct device *dev, void *dummy)
 {
        struct i2c_client *client = i2c_verify_client(dev);
        if (client)
@@ -1059,8 +1055,12 @@ int i2c_del_adapter(struct i2c_adapter *adap)
        mutex_unlock(&adap->userspace_clients_lock);
 
        /* Detach any active clients. This can't fail, thus we do not
-          checking the returned value. */
+        * check the returned value. This is a two-pass process, because
+        * we can't remove the dummy devices during the first pass: they
+        * could have been instantiated by real devices wishing to clean
+        * them up properly, so we give them a chance to do that first. */
        res = device_for_each_child(&adap->dev, NULL, __unregister_client);
+       res = device_for_each_child(&adap->dev, NULL, __unregister_dummy);
 
 #ifdef CONFIG_I2C_COMPAT
        class_compat_remove_link(i2c_adapter_compat_class, &adap->dev,
@@ -1124,6 +1124,14 @@ 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);
@@ -1346,7 +1354,7 @@ EXPORT_SYMBOL(i2c_transfer);
  *
  * Returns negative errno, or else the number of bytes written.
  */
-int i2c_master_send(struct i2c_client *client, const char *buf, int count)
+int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
 {
        int ret;
        struct i2c_adapter *adap = client->adapter;
@@ -1373,7 +1381,7 @@ EXPORT_SYMBOL(i2c_master_send);
  *
  * Returns negative errno, or else the number of bytes read.
  */
-int i2c_master_recv(struct i2c_client *client, char *buf, int count)
+int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
 {
        struct i2c_adapter *adap = client->adapter;
        struct i2c_msg msg;
@@ -1504,26 +1512,25 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
        if (!driver->detect || !address_list)
                return 0;
 
+       /* Stop here if the classes do not match */
+       if (!(adapter->class & driver->class))
+               return 0;
+
        /* Set up a temporary client to help detect callback */
        temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
        if (!temp_client)
                return -ENOMEM;
        temp_client->adapter = adapter;
 
-       /* Stop here if the classes do not match */
-       if (!(adapter->class & driver->class))
-               goto exit_free;
-
        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_list[i]);
                temp_client->addr = address_list[i];
                err = i2c_detect_address(temp_client, driver);
-               if (err)
-                       goto exit_free;
+               if (unlikely(err))
+                       break;
        }
 
- exit_free:
        kfree(temp_client);
        return err;
 }
@@ -1664,7 +1671,7 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
  * This executes the SMBus "receive byte" protocol, returning negative errno
  * else the byte received from the device.
  */
-s32 i2c_smbus_read_byte(struct i2c_client *client)
+s32 i2c_smbus_read_byte(const struct i2c_client *client)
 {
        union i2c_smbus_data data;
        int status;
@@ -1684,7 +1691,7 @@ EXPORT_SYMBOL(i2c_smbus_read_byte);
  * This executes the SMBus "send byte" protocol, returning negative errno
  * else zero on success.
  */
-s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
+s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value)
 {
        return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
                              I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
@@ -1699,7 +1706,7 @@ EXPORT_SYMBOL(i2c_smbus_write_byte);
  * This executes the SMBus "read byte" protocol, returning negative errno
  * else a data byte received from the device.
  */
-s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
+s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)
 {
        union i2c_smbus_data data;
        int status;
@@ -1720,7 +1727,8 @@ EXPORT_SYMBOL(i2c_smbus_read_byte_data);
  * This executes the SMBus "write byte" protocol, returning negative errno
  * else zero on success.
  */
-s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value)
+s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command,
+                             u8 value)
 {
        union i2c_smbus_data data;
        data.byte = value;
@@ -1738,7 +1746,7 @@ EXPORT_SYMBOL(i2c_smbus_write_byte_data);
  * This executes the SMBus "read word" protocol, returning negative errno
  * else a 16-bit unsigned "word" received from the device.
  */
-s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command)
+s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)
 {
        union i2c_smbus_data data;
        int status;
@@ -1759,7 +1767,8 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data);
  * This executes the SMBus "write word" protocol, returning negative errno
  * else zero on success.
  */
-s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
+s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command,
+                             u16 value)
 {
        union i2c_smbus_data data;
        data.word = value;
@@ -1778,7 +1787,8 @@ EXPORT_SYMBOL(i2c_smbus_write_word_data);
  * This executes the SMBus "process call" protocol, returning negative errno
  * else a 16-bit unsigned "word" received from the device.
  */
-s32 i2c_smbus_process_call(struct i2c_client *client, u8 command, u16 value)
+s32 i2c_smbus_process_call(const struct i2c_client *client, u8 command,
+                          u16 value)
 {
        union i2c_smbus_data data;
        int status;
@@ -1806,7 +1816,7 @@ EXPORT_SYMBOL(i2c_smbus_process_call);
  * support this; its emulation through I2C messaging relies on a specific
  * mechanism (I2C_M_RECV_LEN) which may not be implemented.
  */
-s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command,
+s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command,
                              u8 *values)
 {
        union i2c_smbus_data data;
@@ -1833,7 +1843,7 @@ EXPORT_SYMBOL(i2c_smbus_read_block_data);
  * This executes the SMBus "block write" protocol, returning negative errno
  * else zero on success.
  */
-s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
+s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command,
                               u8 length, const u8 *values)
 {
        union i2c_smbus_data data;
@@ -1849,7 +1859,7 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
 EXPORT_SYMBOL(i2c_smbus_write_block_data);
 
 /* Returns the number of read bytes */
-s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command,
+s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command,
                                  u8 length, u8 *values)
 {
        union i2c_smbus_data data;
@@ -1869,7 +1879,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command,
 }
 EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
 
-s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
+s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command,
                                   u8 length, const u8 *values)
 {
        union i2c_smbus_data data;