|
@@ -43,7 +43,7 @@ static DEFINE_IDR(i2c_adapter_idr);
|
|
|
|
|
|
#define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect)
|
|
#define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect)
|
|
|
|
|
|
-static int i2c_attach_client(struct i2c_client *client);
|
|
|
|
|
|
+static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
|
|
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
|
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* ------------------------------------------------------------------------- */
|
|
@@ -237,15 +237,17 @@ EXPORT_SYMBOL(i2c_verify_client);
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
- * i2c_new_device - instantiate an i2c device for use with a new style driver
|
|
|
|
|
|
+ * i2c_new_device - instantiate an i2c device
|
|
* @adap: the adapter managing the device
|
|
* @adap: the adapter managing the device
|
|
* @info: describes one I2C device; bus_num is ignored
|
|
* @info: describes one I2C device; bus_num is ignored
|
|
* Context: can sleep
|
|
* Context: can sleep
|
|
*
|
|
*
|
|
- * Create a device to work with a new style i2c driver, where binding is
|
|
|
|
- * handled through driver model probe()/remove() methods. This call is not
|
|
|
|
- * appropriate for use by mainboad initialization logic, which usually runs
|
|
|
|
- * during an arch_initcall() long before any i2c_adapter could exist.
|
|
|
|
|
|
+ * Create an i2c device. Binding is handled through driver model
|
|
|
|
+ * probe()/remove() methods. A driver may be bound to this device when we
|
|
|
|
+ * return from this function, or any later moment (e.g. maybe hotplugging will
|
|
|
|
+ * load the driver module). This call is not appropriate for use by mainboard
|
|
|
|
+ * initialization logic, which usually runs during an arch_initcall() long
|
|
|
|
+ * before any i2c_adapter could exist.
|
|
*
|
|
*
|
|
* This returns the new i2c client, which may be saved for later use with
|
|
* This returns the new i2c client, which may be saved for later use with
|
|
* i2c_unregister_device(); or NULL to indicate an error.
|
|
* i2c_unregister_device(); or NULL to indicate an error.
|
|
@@ -273,17 +275,40 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
|
|
|
|
|
|
strlcpy(client->name, info->type, sizeof(client->name));
|
|
strlcpy(client->name, info->type, sizeof(client->name));
|
|
|
|
|
|
- /* a new style driver may be bound to this device when we
|
|
|
|
- * return from this function, or any later moment (e.g. maybe
|
|
|
|
- * hotplugging will load the driver module). and the device
|
|
|
|
- * refcount model is the standard driver model one.
|
|
|
|
- */
|
|
|
|
- status = i2c_attach_client(client);
|
|
|
|
- if (status < 0) {
|
|
|
|
- kfree(client);
|
|
|
|
- client = NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Check for address business */
|
|
|
|
+ status = i2c_check_addr(adap, client->addr);
|
|
|
|
+ if (status)
|
|
|
|
+ goto out_err;
|
|
|
|
+
|
|
|
|
+ client->dev.parent = &client->adapter->dev;
|
|
|
|
+ client->dev.bus = &i2c_bus_type;
|
|
|
|
+
|
|
|
|
+ if (client->driver && !is_newstyle_driver(client->driver)) {
|
|
|
|
+ client->dev.release = i2c_client_release;
|
|
|
|
+ dev_set_uevent_suppress(&client->dev, 1);
|
|
|
|
+ } else
|
|
|
|
+ client->dev.release = i2c_client_dev_release;
|
|
|
|
+
|
|
|
|
+ dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
|
|
|
|
+ client->addr);
|
|
|
|
+ status = device_register(&client->dev);
|
|
|
|
+ if (status)
|
|
|
|
+ goto out_err;
|
|
|
|
+
|
|
|
|
+ mutex_lock(&adap->clist_lock);
|
|
|
|
+ list_add_tail(&client->list, &adap->clients);
|
|
|
|
+ mutex_unlock(&adap->clist_lock);
|
|
|
|
+
|
|
|
|
+ dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
|
|
|
|
+ client->name, dev_name(&client->dev));
|
|
|
|
+
|
|
return client;
|
|
return client;
|
|
|
|
+
|
|
|
|
+out_err:
|
|
|
|
+ dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
|
|
|
|
+ "(%d)\n", client->name, client->addr, status);
|
|
|
|
+ kfree(client);
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(i2c_new_device);
|
|
EXPORT_SYMBOL_GPL(i2c_new_device);
|
|
|
|
|
|
@@ -760,49 +785,6 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
|
|
return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
|
|
return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
|
|
}
|
|
}
|
|
|
|
|
|
-static int i2c_attach_client(struct i2c_client *client)
|
|
|
|
-{
|
|
|
|
- struct i2c_adapter *adapter = client->adapter;
|
|
|
|
- int res;
|
|
|
|
-
|
|
|
|
- /* Check for address business */
|
|
|
|
- res = i2c_check_addr(adapter, client->addr);
|
|
|
|
- if (res)
|
|
|
|
- return res;
|
|
|
|
-
|
|
|
|
- client->dev.parent = &client->adapter->dev;
|
|
|
|
- client->dev.bus = &i2c_bus_type;
|
|
|
|
-
|
|
|
|
- if (client->driver)
|
|
|
|
- client->dev.driver = &client->driver->driver;
|
|
|
|
-
|
|
|
|
- if (client->driver && !is_newstyle_driver(client->driver)) {
|
|
|
|
- client->dev.release = i2c_client_release;
|
|
|
|
- dev_set_uevent_suppress(&client->dev, 1);
|
|
|
|
- } else
|
|
|
|
- client->dev.release = i2c_client_dev_release;
|
|
|
|
-
|
|
|
|
- dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adapter),
|
|
|
|
- client->addr);
|
|
|
|
- res = device_register(&client->dev);
|
|
|
|
- if (res)
|
|
|
|
- goto out_err;
|
|
|
|
-
|
|
|
|
- mutex_lock(&adapter->clist_lock);
|
|
|
|
- list_add_tail(&client->list, &adapter->clients);
|
|
|
|
- mutex_unlock(&adapter->clist_lock);
|
|
|
|
-
|
|
|
|
- dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
|
|
|
|
- client->name, dev_name(&client->dev));
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
-out_err:
|
|
|
|
- dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
|
|
|
|
- "(%d)\n", client->name, client->addr, res);
|
|
|
|
- return res;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* i2c_use_client - increments the reference count of the i2c client structure
|
|
* i2c_use_client - increments the reference count of the i2c client structure
|
|
* @client: the client being referenced
|
|
* @client: the client being referenced
|