Commit c2df1591df3ea83b4a5890a1131dd821ca07e761

Authored by Jean Delvare
Committed by Jean Delvare
1 parent 935ada8c44

hwmon: (fscher) Convert to a new-style i2c driver

The new-style fscher driver implements the optional detect() callback
to cover the use cases of the legacy driver.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Reinhard Nissl <rnissl@gmx.de>

Showing 1 changed file with 42 additions and 51 deletions Side-by-side Diff

drivers/hwmon/fscher.c
... ... @@ -106,9 +106,11 @@
106 106 * Functions declaration
107 107 */
108 108  
109   -static int fscher_attach_adapter(struct i2c_adapter *adapter);
110   -static int fscher_detect(struct i2c_adapter *adapter, int address, int kind);
111   -static int fscher_detach_client(struct i2c_client *client);
  109 +static int fscher_probe(struct i2c_client *client,
  110 + const struct i2c_device_id *id);
  111 +static int fscher_detect(struct i2c_client *client, int kind,
  112 + struct i2c_board_info *info);
  113 +static int fscher_remove(struct i2c_client *client);
112 114 static struct fscher_data *fscher_update_device(struct device *dev);
113 115 static void fscher_init_client(struct i2c_client *client);
114 116  
115 117  
116 118  
... ... @@ -119,12 +121,21 @@
119 121 * Driver data (common to all clients)
120 122 */
121 123  
  124 +static const struct i2c_device_id fscher_id[] = {
  125 + { "fscher", fscher },
  126 + { }
  127 +};
  128 +
122 129 static struct i2c_driver fscher_driver = {
  130 + .class = I2C_CLASS_HWMON,
123 131 .driver = {
124 132 .name = "fscher",
125 133 },
126   - .attach_adapter = fscher_attach_adapter,
127   - .detach_client = fscher_detach_client,
  134 + .probe = fscher_probe,
  135 + .remove = fscher_remove,
  136 + .id_table = fscher_id,
  137 + .detect = fscher_detect,
  138 + .address_data = &addr_data,
128 139 };
129 140  
130 141 /*
... ... @@ -132,7 +143,6 @@
132 143 */
133 144  
134 145 struct fscher_data {
135   - struct i2c_client client;
136 146 struct device *hwmon_dev;
137 147 struct mutex update_lock;
138 148 char valid; /* zero until following fields are valid */
139 149  
140 150  
141 151  
142 152  
... ... @@ -283,39 +293,15 @@
283 293 * Real code
284 294 */
285 295  
286   -static int fscher_attach_adapter(struct i2c_adapter *adapter)
  296 +/* Return 0 if detection is successful, -ENODEV otherwise */
  297 +static int fscher_detect(struct i2c_client *new_client, int kind,
  298 + struct i2c_board_info *info)
287 299 {
288   - if (!(adapter->class & I2C_CLASS_HWMON))
289   - return 0;
290   - return i2c_probe(adapter, &addr_data, fscher_detect);
291   -}
  300 + struct i2c_adapter *adapter = new_client->adapter;
292 301  
293   -static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
294   -{
295   - struct i2c_client *new_client;
296   - struct fscher_data *data;
297   - int err = 0;
298   -
299 302 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
300   - goto exit;
  303 + return -ENODEV;
301 304  
302   - /* OK. For now, we presume we have a valid client. We now create the
303   - * client structure, even though we cannot fill it completely yet.
304   - * But it allows us to access i2c_smbus_read_byte_data. */
305   - if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
306   - err = -ENOMEM;
307   - goto exit;
308   - }
309   -
310   - /* The common I2C client data is placed right before the
311   - * Hermes-specific data. */
312   - new_client = &data->client;
313   - i2c_set_clientdata(new_client, data);
314   - new_client->addr = address;
315   - new_client->adapter = adapter;
316   - new_client->driver = &fscher_driver;
317   - new_client->flags = 0;
318   -
319 305 /* Do the remaining detection unless force or force_fscher parameter */
320 306 if (kind < 0) {
321 307 if ((i2c_smbus_read_byte_data(new_client,
322 308  
323 309  
324 310  
... ... @@ -324,24 +310,35 @@
324 310 FSCHER_REG_IDENT_1) != 0x45) /* 'E' */
325 311 || (i2c_smbus_read_byte_data(new_client,
326 312 FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */
327   - goto exit_free;
  313 + return -ENODEV;
328 314 }
329 315  
330   - /* Fill in the remaining client fields and put it into the
331   - * global list */
332   - strlcpy(new_client->name, "fscher", I2C_NAME_SIZE);
  316 + strlcpy(info->type, "fscher", I2C_NAME_SIZE);
  317 +
  318 + return 0;
  319 +}
  320 +
  321 +static int fscher_probe(struct i2c_client *new_client,
  322 + const struct i2c_device_id *id)
  323 +{
  324 + struct fscher_data *data;
  325 + int err;
  326 +
  327 + data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL);
  328 + if (!data) {
  329 + err = -ENOMEM;
  330 + goto exit;
  331 + }
  332 +
  333 + i2c_set_clientdata(new_client, data);
333 334 data->valid = 0;
334 335 mutex_init(&data->update_lock);
335 336  
336   - /* Tell the I2C layer a new client has arrived */
337   - if ((err = i2c_attach_client(new_client)))
338   - goto exit_free;
339   -
340 337 fscher_init_client(new_client);
341 338  
342 339 /* Register sysfs hooks */
343 340 if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group)))
344   - goto exit_detach;
  341 + goto exit_free;
345 342  
346 343 data->hwmon_dev = hwmon_device_register(&new_client->dev);
347 344 if (IS_ERR(data->hwmon_dev)) {
348 345  
349 346  
350 347  
... ... @@ -353,24 +350,18 @@
353 350  
354 351 exit_remove_files:
355 352 sysfs_remove_group(&new_client->dev.kobj, &fscher_group);
356   -exit_detach:
357   - i2c_detach_client(new_client);
358 353 exit_free:
359 354 kfree(data);
360 355 exit:
361 356 return err;
362 357 }
363 358  
364   -static int fscher_detach_client(struct i2c_client *client)
  359 +static int fscher_remove(struct i2c_client *client)
365 360 {
366 361 struct fscher_data *data = i2c_get_clientdata(client);
367   - int err;
368 362  
369 363 hwmon_device_unregister(data->hwmon_dev);
370 364 sysfs_remove_group(&client->dev.kobj, &fscher_group);
371   -
372   - if ((err = i2c_detach_client(client)))
373   - return err;
374 365  
375 366 kfree(data);
376 367 return 0;