diff options
| -rw-r--r-- | drivers/hwmon/max1619.c | 101 |
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 7e7267a04544..1ab1cacad598 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
| @@ -79,23 +79,34 @@ I2C_CLIENT_INSMOD_1(max1619); | |||
| 79 | * Functions declaration | 79 | * Functions declaration |
| 80 | */ | 80 | */ |
| 81 | 81 | ||
| 82 | static int max1619_attach_adapter(struct i2c_adapter *adapter); | 82 | static int max1619_probe(struct i2c_client *client, |
| 83 | static int max1619_detect(struct i2c_adapter *adapter, int address, | 83 | const struct i2c_device_id *id); |
| 84 | int kind); | 84 | static int max1619_detect(struct i2c_client *client, int kind, |
| 85 | struct i2c_board_info *info); | ||
| 85 | static void max1619_init_client(struct i2c_client *client); | 86 | static void max1619_init_client(struct i2c_client *client); |
| 86 | static int max1619_detach_client(struct i2c_client *client); | 87 | static int max1619_remove(struct i2c_client *client); |
| 87 | static struct max1619_data *max1619_update_device(struct device *dev); | 88 | static struct max1619_data *max1619_update_device(struct device *dev); |
| 88 | 89 | ||
| 89 | /* | 90 | /* |
| 90 | * Driver data (common to all clients) | 91 | * Driver data (common to all clients) |
| 91 | */ | 92 | */ |
| 92 | 93 | ||
| 94 | static const struct i2c_device_id max1619_id[] = { | ||
| 95 | { "max1619", max1619 }, | ||
| 96 | { } | ||
| 97 | }; | ||
| 98 | MODULE_DEVICE_TABLE(i2c, max1619_id); | ||
| 99 | |||
| 93 | static struct i2c_driver max1619_driver = { | 100 | static struct i2c_driver max1619_driver = { |
| 101 | .class = I2C_CLASS_HWMON, | ||
| 94 | .driver = { | 102 | .driver = { |
| 95 | .name = "max1619", | 103 | .name = "max1619", |
| 96 | }, | 104 | }, |
| 97 | .attach_adapter = max1619_attach_adapter, | 105 | .probe = max1619_probe, |
| 98 | .detach_client = max1619_detach_client, | 106 | .remove = max1619_remove, |
| 107 | .id_table = max1619_id, | ||
| 108 | .detect = max1619_detect, | ||
| 109 | .address_data = &addr_data, | ||
| 99 | }; | 110 | }; |
| 100 | 111 | ||
| 101 | /* | 112 | /* |
| @@ -103,7 +114,6 @@ static struct i2c_driver max1619_driver = { | |||
| 103 | */ | 114 | */ |
| 104 | 115 | ||
| 105 | struct max1619_data { | 116 | struct max1619_data { |
| 106 | struct i2c_client client; | ||
| 107 | struct device *hwmon_dev; | 117 | struct device *hwmon_dev; |
| 108 | struct mutex update_lock; | 118 | struct mutex update_lock; |
| 109 | char valid; /* zero until following fields are valid */ | 119 | char valid; /* zero until following fields are valid */ |
| @@ -208,41 +218,15 @@ static const struct attribute_group max1619_group = { | |||
| 208 | * Real code | 218 | * Real code |
| 209 | */ | 219 | */ |
| 210 | 220 | ||
| 211 | static int max1619_attach_adapter(struct i2c_adapter *adapter) | 221 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 212 | { | 222 | static int max1619_detect(struct i2c_client *new_client, int kind, |
| 213 | if (!(adapter->class & I2C_CLASS_HWMON)) | 223 | struct i2c_board_info *info) |
| 214 | return 0; | ||
| 215 | return i2c_probe(adapter, &addr_data, max1619_detect); | ||
| 216 | } | ||
| 217 | |||
| 218 | /* | ||
| 219 | * The following function does more than just detection. If detection | ||
| 220 | * succeeds, it also registers the new chip. | ||
| 221 | */ | ||
| 222 | static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | ||
| 223 | { | 224 | { |
| 224 | struct i2c_client *new_client; | 225 | struct i2c_adapter *adapter = new_client->adapter; |
| 225 | struct max1619_data *data; | ||
| 226 | int err = 0; | ||
| 227 | const char *name = ""; | ||
| 228 | u8 reg_config=0, reg_convrate=0, reg_status=0; | 226 | u8 reg_config=0, reg_convrate=0, reg_status=0; |
| 229 | 227 | ||
| 230 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 228 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
| 231 | goto exit; | 229 | return -ENODEV; |
| 232 | |||
| 233 | if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) { | ||
| 234 | err = -ENOMEM; | ||
| 235 | goto exit; | ||
| 236 | } | ||
| 237 | |||
| 238 | /* The common I2C client data is placed right before the | ||
| 239 | MAX1619-specific data. */ | ||
| 240 | new_client = &data->client; | ||
| 241 | i2c_set_clientdata(new_client, data); | ||
| 242 | new_client->addr = address; | ||
| 243 | new_client->adapter = adapter; | ||
| 244 | new_client->driver = &max1619_driver; | ||
| 245 | new_client->flags = 0; | ||
| 246 | 230 | ||
| 247 | /* | 231 | /* |
| 248 | * Now we do the remaining detection. A negative kind means that | 232 | * Now we do the remaining detection. A negative kind means that |
| @@ -265,8 +249,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 265 | || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) { | 249 | || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) { |
| 266 | dev_dbg(&adapter->dev, | 250 | dev_dbg(&adapter->dev, |
| 267 | "MAX1619 detection failed at 0x%02x.\n", | 251 | "MAX1619 detection failed at 0x%02x.\n", |
| 268 | address); | 252 | new_client->addr); |
| 269 | goto exit_free; | 253 | return -ENODEV; |
| 270 | } | 254 | } |
| 271 | } | 255 | } |
| 272 | 256 | ||
| @@ -285,28 +269,37 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 285 | dev_info(&adapter->dev, | 269 | dev_info(&adapter->dev, |
| 286 | "Unsupported chip (man_id=0x%02X, " | 270 | "Unsupported chip (man_id=0x%02X, " |
| 287 | "chip_id=0x%02X).\n", man_id, chip_id); | 271 | "chip_id=0x%02X).\n", man_id, chip_id); |
| 288 | goto exit_free; | 272 | return -ENODEV; |
| 289 | } | 273 | } |
| 290 | } | 274 | } |
| 291 | 275 | ||
| 292 | if (kind == max1619) | 276 | strlcpy(info->type, "max1619", I2C_NAME_SIZE); |
| 293 | name = "max1619"; | 277 | |
| 278 | return 0; | ||
| 279 | } | ||
| 280 | |||
| 281 | static int max1619_probe(struct i2c_client *new_client, | ||
| 282 | const struct i2c_device_id *id) | ||
| 283 | { | ||
| 284 | struct max1619_data *data; | ||
| 285 | int err; | ||
| 286 | |||
| 287 | data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL); | ||
| 288 | if (!data) { | ||
| 289 | err = -ENOMEM; | ||
| 290 | goto exit; | ||
| 291 | } | ||
| 294 | 292 | ||
| 295 | /* We can fill in the remaining client fields */ | 293 | i2c_set_clientdata(new_client, data); |
| 296 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
| 297 | data->valid = 0; | 294 | data->valid = 0; |
| 298 | mutex_init(&data->update_lock); | 295 | mutex_init(&data->update_lock); |
| 299 | 296 | ||
| 300 | /* Tell the I2C layer a new client has arrived */ | ||
| 301 | if ((err = i2c_attach_client(new_client))) | ||
| 302 | goto exit_free; | ||
| 303 | |||
| 304 | /* Initialize the MAX1619 chip */ | 297 | /* Initialize the MAX1619 chip */ |
| 305 | max1619_init_client(new_client); | 298 | max1619_init_client(new_client); |
| 306 | 299 | ||
| 307 | /* Register sysfs hooks */ | 300 | /* Register sysfs hooks */ |
| 308 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) | 301 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) |
| 309 | goto exit_detach; | 302 | goto exit_free; |
| 310 | 303 | ||
| 311 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 304 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
| 312 | if (IS_ERR(data->hwmon_dev)) { | 305 | if (IS_ERR(data->hwmon_dev)) { |
| @@ -318,8 +311,6 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 318 | 311 | ||
| 319 | exit_remove_files: | 312 | exit_remove_files: |
| 320 | sysfs_remove_group(&new_client->dev.kobj, &max1619_group); | 313 | sysfs_remove_group(&new_client->dev.kobj, &max1619_group); |
| 321 | exit_detach: | ||
| 322 | i2c_detach_client(new_client); | ||
| 323 | exit_free: | 314 | exit_free: |
| 324 | kfree(data); | 315 | kfree(data); |
| 325 | exit: | 316 | exit: |
| @@ -341,17 +332,13 @@ static void max1619_init_client(struct i2c_client *client) | |||
| 341 | config & 0xBF); /* run */ | 332 | config & 0xBF); /* run */ |
| 342 | } | 333 | } |
| 343 | 334 | ||
| 344 | static int max1619_detach_client(struct i2c_client *client) | 335 | static int max1619_remove(struct i2c_client *client) |
| 345 | { | 336 | { |
| 346 | struct max1619_data *data = i2c_get_clientdata(client); | 337 | struct max1619_data *data = i2c_get_clientdata(client); |
| 347 | int err; | ||
| 348 | 338 | ||
| 349 | hwmon_device_unregister(data->hwmon_dev); | 339 | hwmon_device_unregister(data->hwmon_dev); |
| 350 | sysfs_remove_group(&client->dev.kobj, &max1619_group); | 340 | sysfs_remove_group(&client->dev.kobj, &max1619_group); |
| 351 | 341 | ||
| 352 | if ((err = i2c_detach_client(client))) | ||
| 353 | return err; | ||
| 354 | |||
| 355 | kfree(data); | 342 | kfree(data); |
| 356 | return 0; | 343 | return 0; |
| 357 | } | 344 | } |
