diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/adm9240.c | 93 |
1 files changed, 46 insertions, 47 deletions
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 149ef25252e7..2444b15f2e9d 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -130,25 +130,37 @@ static inline unsigned int AOUT_FROM_REG(u8 reg) | |||
130 | return SCALE(reg, 1250, 255); | 130 | return SCALE(reg, 1250, 255); |
131 | } | 131 | } |
132 | 132 | ||
133 | static int adm9240_attach_adapter(struct i2c_adapter *adapter); | 133 | static int adm9240_probe(struct i2c_client *client, |
134 | static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind); | 134 | const struct i2c_device_id *id); |
135 | static int adm9240_detect(struct i2c_client *client, int kind, | ||
136 | struct i2c_board_info *info); | ||
135 | static void adm9240_init_client(struct i2c_client *client); | 137 | static void adm9240_init_client(struct i2c_client *client); |
136 | static int adm9240_detach_client(struct i2c_client *client); | 138 | static int adm9240_remove(struct i2c_client *client); |
137 | static struct adm9240_data *adm9240_update_device(struct device *dev); | 139 | static struct adm9240_data *adm9240_update_device(struct device *dev); |
138 | 140 | ||
139 | /* driver data */ | 141 | /* driver data */ |
142 | static const struct i2c_device_id adm9240_id[] = { | ||
143 | { "adm9240", adm9240 }, | ||
144 | { "ds1780", ds1780 }, | ||
145 | { "lm81", lm81 }, | ||
146 | { } | ||
147 | }; | ||
148 | MODULE_DEVICE_TABLE(i2c, adm9240_id); | ||
149 | |||
140 | static struct i2c_driver adm9240_driver = { | 150 | static struct i2c_driver adm9240_driver = { |
151 | .class = I2C_CLASS_HWMON, | ||
141 | .driver = { | 152 | .driver = { |
142 | .name = "adm9240", | 153 | .name = "adm9240", |
143 | }, | 154 | }, |
144 | .attach_adapter = adm9240_attach_adapter, | 155 | .probe = adm9240_probe, |
145 | .detach_client = adm9240_detach_client, | 156 | .remove = adm9240_remove, |
157 | .id_table = adm9240_id, | ||
158 | .detect = adm9240_detect, | ||
159 | .address_data = &addr_data, | ||
146 | }; | 160 | }; |
147 | 161 | ||
148 | /* per client data */ | 162 | /* per client data */ |
149 | struct adm9240_data { | 163 | struct adm9240_data { |
150 | enum chips type; | ||
151 | struct i2c_client client; | ||
152 | struct device *hwmon_dev; | 164 | struct device *hwmon_dev; |
153 | struct mutex update_lock; | 165 | struct mutex update_lock; |
154 | char valid; | 166 | char valid; |
@@ -532,28 +544,17 @@ static const struct attribute_group adm9240_group = { | |||
532 | 544 | ||
533 | /*** sensor chip detect and driver install ***/ | 545 | /*** sensor chip detect and driver install ***/ |
534 | 546 | ||
535 | static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | 547 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
548 | static int adm9240_detect(struct i2c_client *new_client, int kind, | ||
549 | struct i2c_board_info *info) | ||
536 | { | 550 | { |
537 | struct i2c_client *new_client; | 551 | struct i2c_adapter *adapter = new_client->adapter; |
538 | struct adm9240_data *data; | ||
539 | int err = 0; | ||
540 | const char *name = ""; | 552 | const char *name = ""; |
553 | int address = new_client->addr; | ||
541 | u8 man_id, die_rev; | 554 | u8 man_id, die_rev; |
542 | 555 | ||
543 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 556 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
544 | goto exit; | 557 | return -ENODEV; |
545 | |||
546 | if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { | ||
547 | err = -ENOMEM; | ||
548 | goto exit; | ||
549 | } | ||
550 | |||
551 | new_client = &data->client; | ||
552 | i2c_set_clientdata(new_client, data); | ||
553 | new_client->addr = address; | ||
554 | new_client->adapter = adapter; | ||
555 | new_client->driver = &adm9240_driver; | ||
556 | new_client->flags = 0; | ||
557 | 558 | ||
558 | if (kind == 0) { | 559 | if (kind == 0) { |
559 | kind = adm9240; | 560 | kind = adm9240; |
@@ -566,7 +567,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
566 | != address) { | 567 | != address) { |
567 | dev_err(&adapter->dev, "detect fail: address match, " | 568 | dev_err(&adapter->dev, "detect fail: address match, " |
568 | "0x%02x\n", address); | 569 | "0x%02x\n", address); |
569 | goto exit_free; | 570 | return -ENODEV; |
570 | } | 571 | } |
571 | 572 | ||
572 | /* check known chip manufacturer */ | 573 | /* check known chip manufacturer */ |
@@ -581,7 +582,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
581 | } else { | 582 | } else { |
582 | dev_err(&adapter->dev, "detect fail: unknown manuf, " | 583 | dev_err(&adapter->dev, "detect fail: unknown manuf, " |
583 | "0x%02x\n", man_id); | 584 | "0x%02x\n", man_id); |
584 | goto exit_free; | 585 | return -ENODEV; |
585 | } | 586 | } |
586 | 587 | ||
587 | /* successful detect, print chip info */ | 588 | /* successful detect, print chip info */ |
@@ -600,20 +601,31 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
600 | } else if (kind == lm81) { | 601 | } else if (kind == lm81) { |
601 | name = "lm81"; | 602 | name = "lm81"; |
602 | } | 603 | } |
604 | strlcpy(info->type, name, I2C_NAME_SIZE); | ||
603 | 605 | ||
604 | /* fill in the remaining client fields and attach */ | 606 | return 0; |
605 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | 607 | } |
606 | data->type = kind; | ||
607 | mutex_init(&data->update_lock); | ||
608 | 608 | ||
609 | if ((err = i2c_attach_client(new_client))) | 609 | static int adm9240_probe(struct i2c_client *new_client, |
610 | goto exit_free; | 610 | const struct i2c_device_id *id) |
611 | { | ||
612 | struct adm9240_data *data; | ||
613 | int err; | ||
614 | |||
615 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
616 | if (!data) { | ||
617 | err = -ENOMEM; | ||
618 | goto exit; | ||
619 | } | ||
620 | |||
621 | i2c_set_clientdata(new_client, data); | ||
622 | mutex_init(&data->update_lock); | ||
611 | 623 | ||
612 | adm9240_init_client(new_client); | 624 | adm9240_init_client(new_client); |
613 | 625 | ||
614 | /* populate sysfs filesystem */ | 626 | /* populate sysfs filesystem */ |
615 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) | 627 | if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) |
616 | goto exit_detach; | 628 | goto exit_free; |
617 | 629 | ||
618 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 630 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
619 | if (IS_ERR(data->hwmon_dev)) { | 631 | if (IS_ERR(data->hwmon_dev)) { |
@@ -625,32 +637,19 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
625 | 637 | ||
626 | exit_remove: | 638 | exit_remove: |
627 | sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); | 639 | sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); |
628 | exit_detach: | ||
629 | i2c_detach_client(new_client); | ||
630 | exit_free: | 640 | exit_free: |
631 | kfree(data); | 641 | kfree(data); |
632 | exit: | 642 | exit: |
633 | return err; | 643 | return err; |
634 | } | 644 | } |
635 | 645 | ||
636 | static int adm9240_attach_adapter(struct i2c_adapter *adapter) | 646 | static int adm9240_remove(struct i2c_client *client) |
637 | { | ||
638 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
639 | return 0; | ||
640 | return i2c_probe(adapter, &addr_data, adm9240_detect); | ||
641 | } | ||
642 | |||
643 | static int adm9240_detach_client(struct i2c_client *client) | ||
644 | { | 647 | { |
645 | struct adm9240_data *data = i2c_get_clientdata(client); | 648 | struct adm9240_data *data = i2c_get_clientdata(client); |
646 | int err; | ||
647 | 649 | ||
648 | hwmon_device_unregister(data->hwmon_dev); | 650 | hwmon_device_unregister(data->hwmon_dev); |
649 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); | 651 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); |
650 | 652 | ||
651 | if ((err = i2c_detach_client(client))) | ||
652 | return err; | ||
653 | |||
654 | kfree(data); | 653 | kfree(data); |
655 | return 0; | 654 | return 0; |
656 | } | 655 | } |