diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-04-29 17:11:39 -0400 |
---|---|---|
committer | Jean Delvare <khali@hyperion.delvare> | 2008-04-29 17:11:39 -0400 |
commit | d2653e92732bd3911feff6bee5e23dbf959381db (patch) | |
tree | fd3a413bc150855a09de29b2d253b7dbeb2705ff /drivers/i2c/i2c-core.c | |
parent | ee56d977423a58b53fd0fc1ef0aca0c9cb564c53 (diff) |
i2c: Add support for device alias names
Based on earlier work by Jon Smirl and Jochen Friedrich.
This patch allows new-style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). At this
point, the old i2c driver binding scheme (driver_name/type) is still
supported.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Jochen Friedrich <jochen@scram.de>
Cc: Jon Smirl <jonsmirl@gmail.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6c7fa8d53c0e..26384daccb96 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -48,6 +48,17 @@ static DEFINE_IDR(i2c_adapter_idr); | |||
48 | 48 | ||
49 | /* ------------------------------------------------------------------------- */ | 49 | /* ------------------------------------------------------------------------- */ |
50 | 50 | ||
51 | static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, | ||
52 | const struct i2c_client *client) | ||
53 | { | ||
54 | while (id->name[0]) { | ||
55 | if (strcmp(client->name, id->name) == 0) | ||
56 | return id; | ||
57 | id++; | ||
58 | } | ||
59 | return NULL; | ||
60 | } | ||
61 | |||
51 | static int i2c_device_match(struct device *dev, struct device_driver *drv) | 62 | static int i2c_device_match(struct device *dev, struct device_driver *drv) |
52 | { | 63 | { |
53 | struct i2c_client *client = to_i2c_client(dev); | 64 | struct i2c_client *client = to_i2c_client(dev); |
@@ -59,6 +70,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) | |||
59 | if (!is_newstyle_driver(driver)) | 70 | if (!is_newstyle_driver(driver)) |
60 | return 0; | 71 | return 0; |
61 | 72 | ||
73 | /* match on an id table if there is one */ | ||
74 | if (driver->id_table) | ||
75 | return i2c_match_id(driver->id_table, client) != NULL; | ||
76 | |||
62 | /* new style drivers use the same kind of driver matching policy | 77 | /* new style drivers use the same kind of driver matching policy |
63 | * as platform devices or SPI: compare device and driver IDs. | 78 | * as platform devices or SPI: compare device and driver IDs. |
64 | */ | 79 | */ |
@@ -73,11 +88,17 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
73 | struct i2c_client *client = to_i2c_client(dev); | 88 | struct i2c_client *client = to_i2c_client(dev); |
74 | 89 | ||
75 | /* by definition, legacy drivers can't hotplug */ | 90 | /* by definition, legacy drivers can't hotplug */ |
76 | if (dev->driver || !client->driver_name) | 91 | if (dev->driver) |
77 | return 0; | 92 | return 0; |
78 | 93 | ||
79 | if (add_uevent_var(env, "MODALIAS=%s", client->driver_name)) | 94 | if (client->driver_name[0]) { |
80 | return -ENOMEM; | 95 | if (add_uevent_var(env, "MODALIAS=%s", client->driver_name)) |
96 | return -ENOMEM; | ||
97 | } else { | ||
98 | if (add_uevent_var(env, "MODALIAS=%s%s", | ||
99 | I2C_MODULE_PREFIX, client->name)) | ||
100 | return -ENOMEM; | ||
101 | } | ||
81 | dev_dbg(dev, "uevent\n"); | 102 | dev_dbg(dev, "uevent\n"); |
82 | return 0; | 103 | return 0; |
83 | } | 104 | } |
@@ -90,13 +111,19 @@ static int i2c_device_probe(struct device *dev) | |||
90 | { | 111 | { |
91 | struct i2c_client *client = to_i2c_client(dev); | 112 | struct i2c_client *client = to_i2c_client(dev); |
92 | struct i2c_driver *driver = to_i2c_driver(dev->driver); | 113 | struct i2c_driver *driver = to_i2c_driver(dev->driver); |
114 | const struct i2c_device_id *id; | ||
93 | int status; | 115 | int status; |
94 | 116 | ||
95 | if (!driver->probe) | 117 | if (!driver->probe) |
96 | return -ENODEV; | 118 | return -ENODEV; |
97 | client->driver = driver; | 119 | client->driver = driver; |
98 | dev_dbg(dev, "probe\n"); | 120 | dev_dbg(dev, "probe\n"); |
99 | status = driver->probe(client); | 121 | |
122 | if (driver->id_table) | ||
123 | id = i2c_match_id(driver->id_table, client); | ||
124 | else | ||
125 | id = NULL; | ||
126 | status = driver->probe(client, id); | ||
100 | if (status) | 127 | if (status) |
101 | client->driver = NULL; | 128 | client->driver = NULL; |
102 | return status; | 129 | return status; |
@@ -179,9 +206,9 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att | |||
179 | static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) | 206 | static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) |
180 | { | 207 | { |
181 | struct i2c_client *client = to_i2c_client(dev); | 208 | struct i2c_client *client = to_i2c_client(dev); |
182 | return client->driver_name | 209 | return client->driver_name[0] |
183 | ? sprintf(buf, "%s\n", client->driver_name) | 210 | ? sprintf(buf, "%s\n", client->driver_name) |
184 | : 0; | 211 | : sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); |
185 | } | 212 | } |
186 | 213 | ||
187 | static struct device_attribute i2c_dev_attrs[] = { | 214 | static struct device_attribute i2c_dev_attrs[] = { |
@@ -300,15 +327,21 @@ void i2c_unregister_device(struct i2c_client *client) | |||
300 | EXPORT_SYMBOL_GPL(i2c_unregister_device); | 327 | EXPORT_SYMBOL_GPL(i2c_unregister_device); |
301 | 328 | ||
302 | 329 | ||
303 | static int dummy_nop(struct i2c_client *client) | 330 | static int dummy_probe(struct i2c_client *client, |
331 | const struct i2c_device_id *id) | ||
332 | { | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int dummy_remove(struct i2c_client *client) | ||
304 | { | 337 | { |
305 | return 0; | 338 | return 0; |
306 | } | 339 | } |
307 | 340 | ||
308 | static struct i2c_driver dummy_driver = { | 341 | static struct i2c_driver dummy_driver = { |
309 | .driver.name = "dummy", | 342 | .driver.name = "dummy", |
310 | .probe = dummy_nop, | 343 | .probe = dummy_probe, |
311 | .remove = dummy_nop, | 344 | .remove = dummy_remove, |
312 | }; | 345 | }; |
313 | 346 | ||
314 | /** | 347 | /** |