diff options
author | Guenter Roeck <linux@roeck-us.net> | 2013-09-02 14:31:28 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2013-10-13 19:16:29 -0400 |
commit | 38c75dc36dd368d10c4d0030665ec58565e4259b (patch) | |
tree | e2314857c44dc91b881ebedba852fd20c5dcce53 /drivers/hwmon/max16065.c | |
parent | 8d3735522fb192738d7161865d41688f10983613 (diff) |
hwmon: (max16065) Convert to use devm_hwmon_device_register_with_groups
Modify code to use is_visible to determine if an attribute should be created
or not, then use devm_hwmon_device_register_with_groups to create the hwmon
device and all attributes in one operation.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/max16065.c')
-rw-r--r-- | drivers/hwmon/max16065.c | 124 |
1 files changed, 52 insertions, 72 deletions
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index 2fa2c02f5569..d4efc79d7b93 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c | |||
@@ -83,7 +83,8 @@ static const bool max16065_have_current[] = { | |||
83 | 83 | ||
84 | struct max16065_data { | 84 | struct max16065_data { |
85 | enum chips type; | 85 | enum chips type; |
86 | struct device *hwmon_dev; | 86 | struct i2c_client *client; |
87 | const struct attribute_group *groups[4]; | ||
87 | struct mutex update_lock; | 88 | struct mutex update_lock; |
88 | bool valid; | 89 | bool valid; |
89 | unsigned long last_updated; /* in jiffies */ | 90 | unsigned long last_updated; /* in jiffies */ |
@@ -144,8 +145,8 @@ static int max16065_read_adc(struct i2c_client *client, int reg) | |||
144 | 145 | ||
145 | static struct max16065_data *max16065_update_device(struct device *dev) | 146 | static struct max16065_data *max16065_update_device(struct device *dev) |
146 | { | 147 | { |
147 | struct i2c_client *client = to_i2c_client(dev); | 148 | struct max16065_data *data = dev_get_drvdata(dev); |
148 | struct max16065_data *data = i2c_get_clientdata(client); | 149 | struct i2c_client *client = data->client; |
149 | 150 | ||
150 | mutex_lock(&data->update_lock); | 151 | mutex_lock(&data->update_lock); |
151 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 152 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
@@ -186,7 +187,7 @@ static ssize_t max16065_show_alarm(struct device *dev, | |||
186 | 187 | ||
187 | val &= (1 << attr2->index); | 188 | val &= (1 << attr2->index); |
188 | if (val) | 189 | if (val) |
189 | i2c_smbus_write_byte_data(to_i2c_client(dev), | 190 | i2c_smbus_write_byte_data(data->client, |
190 | MAX16065_FAULT(attr2->nr), val); | 191 | MAX16065_FAULT(attr2->nr), val); |
191 | 192 | ||
192 | return snprintf(buf, PAGE_SIZE, "%d\n", !!val); | 193 | return snprintf(buf, PAGE_SIZE, "%d\n", !!val); |
@@ -223,8 +224,7 @@ static ssize_t max16065_set_limit(struct device *dev, | |||
223 | const char *buf, size_t count) | 224 | const char *buf, size_t count) |
224 | { | 225 | { |
225 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | 226 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); |
226 | struct i2c_client *client = to_i2c_client(dev); | 227 | struct max16065_data *data = dev_get_drvdata(dev); |
227 | struct max16065_data *data = i2c_get_clientdata(client); | ||
228 | unsigned long val; | 228 | unsigned long val; |
229 | int err; | 229 | int err; |
230 | int limit; | 230 | int limit; |
@@ -238,7 +238,7 @@ static ssize_t max16065_set_limit(struct device *dev, | |||
238 | mutex_lock(&data->update_lock); | 238 | mutex_lock(&data->update_lock); |
239 | data->limit[attr2->nr][attr2->index] | 239 | data->limit[attr2->nr][attr2->index] |
240 | = LIMIT_TO_MV(limit, data->range[attr2->index]); | 240 | = LIMIT_TO_MV(limit, data->range[attr2->index]); |
241 | i2c_smbus_write_byte_data(client, | 241 | i2c_smbus_write_byte_data(data->client, |
242 | MAX16065_LIMIT(attr2->nr, attr2->index), | 242 | MAX16065_LIMIT(attr2->nr, attr2->index), |
243 | limit); | 243 | limit); |
244 | mutex_unlock(&data->update_lock); | 244 | mutex_unlock(&data->update_lock); |
@@ -250,8 +250,7 @@ static ssize_t max16065_show_limit(struct device *dev, | |||
250 | struct device_attribute *da, char *buf) | 250 | struct device_attribute *da, char *buf) |
251 | { | 251 | { |
252 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | 252 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); |
253 | struct i2c_client *client = to_i2c_client(dev); | 253 | struct max16065_data *data = dev_get_drvdata(dev); |
254 | struct max16065_data *data = i2c_get_clientdata(client); | ||
255 | 254 | ||
256 | return snprintf(buf, PAGE_SIZE, "%d\n", | 255 | return snprintf(buf, PAGE_SIZE, "%d\n", |
257 | data->limit[attr2->nr][attr2->index]); | 256 | data->limit[attr2->nr][attr2->index]); |
@@ -516,8 +515,32 @@ static struct attribute *max16065_max_attributes[] = { | |||
516 | NULL | 515 | NULL |
517 | }; | 516 | }; |
518 | 517 | ||
518 | static umode_t max16065_basic_is_visible(struct kobject *kobj, | ||
519 | struct attribute *a, int n) | ||
520 | { | ||
521 | struct device *dev = container_of(kobj, struct device, kobj); | ||
522 | struct max16065_data *data = dev_get_drvdata(dev); | ||
523 | int index = n / 4; | ||
524 | |||
525 | if (index >= data->num_adc || !data->range[index]) | ||
526 | return 0; | ||
527 | return a->mode; | ||
528 | } | ||
529 | |||
530 | static umode_t max16065_secondary_is_visible(struct kobject *kobj, | ||
531 | struct attribute *a, int index) | ||
532 | { | ||
533 | struct device *dev = container_of(kobj, struct device, kobj); | ||
534 | struct max16065_data *data = dev_get_drvdata(dev); | ||
535 | |||
536 | if (index >= data->num_adc) | ||
537 | return 0; | ||
538 | return a->mode; | ||
539 | } | ||
540 | |||
519 | static const struct attribute_group max16065_basic_group = { | 541 | static const struct attribute_group max16065_basic_group = { |
520 | .attrs = max16065_basic_attributes, | 542 | .attrs = max16065_basic_attributes, |
543 | .is_visible = max16065_basic_is_visible, | ||
521 | }; | 544 | }; |
522 | 545 | ||
523 | static const struct attribute_group max16065_current_group = { | 546 | static const struct attribute_group max16065_current_group = { |
@@ -526,38 +549,35 @@ static const struct attribute_group max16065_current_group = { | |||
526 | 549 | ||
527 | static const struct attribute_group max16065_min_group = { | 550 | static const struct attribute_group max16065_min_group = { |
528 | .attrs = max16065_min_attributes, | 551 | .attrs = max16065_min_attributes, |
552 | .is_visible = max16065_secondary_is_visible, | ||
529 | }; | 553 | }; |
530 | 554 | ||
531 | static const struct attribute_group max16065_max_group = { | 555 | static const struct attribute_group max16065_max_group = { |
532 | .attrs = max16065_max_attributes, | 556 | .attrs = max16065_max_attributes, |
557 | .is_visible = max16065_secondary_is_visible, | ||
533 | }; | 558 | }; |
534 | 559 | ||
535 | static void max16065_cleanup(struct i2c_client *client) | ||
536 | { | ||
537 | sysfs_remove_group(&client->dev.kobj, &max16065_max_group); | ||
538 | sysfs_remove_group(&client->dev.kobj, &max16065_min_group); | ||
539 | sysfs_remove_group(&client->dev.kobj, &max16065_current_group); | ||
540 | sysfs_remove_group(&client->dev.kobj, &max16065_basic_group); | ||
541 | } | ||
542 | |||
543 | static int max16065_probe(struct i2c_client *client, | 560 | static int max16065_probe(struct i2c_client *client, |
544 | const struct i2c_device_id *id) | 561 | const struct i2c_device_id *id) |
545 | { | 562 | { |
546 | struct i2c_adapter *adapter = client->adapter; | 563 | struct i2c_adapter *adapter = client->adapter; |
547 | struct max16065_data *data; | 564 | struct max16065_data *data; |
548 | int i, j, val, ret; | 565 | struct device *dev = &client->dev; |
566 | struct device *hwmon_dev; | ||
567 | int i, j, val; | ||
549 | bool have_secondary; /* true if chip has secondary limits */ | 568 | bool have_secondary; /* true if chip has secondary limits */ |
550 | bool secondary_is_max = false; /* secondary limits reflect max */ | 569 | bool secondary_is_max = false; /* secondary limits reflect max */ |
570 | int groups = 0; | ||
551 | 571 | ||
552 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 572 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
553 | | I2C_FUNC_SMBUS_READ_WORD_DATA)) | 573 | | I2C_FUNC_SMBUS_READ_WORD_DATA)) |
554 | return -ENODEV; | 574 | return -ENODEV; |
555 | 575 | ||
556 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | 576 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
557 | if (unlikely(!data)) | 577 | if (unlikely(!data)) |
558 | return -ENOMEM; | 578 | return -ENOMEM; |
559 | 579 | ||
560 | i2c_set_clientdata(client, data); | 580 | data->client = client; |
561 | mutex_init(&data->update_lock); | 581 | mutex_init(&data->update_lock); |
562 | 582 | ||
563 | data->num_adc = max16065_num_adc[id->driver_data]; | 583 | data->num_adc = max16065_num_adc[id->driver_data]; |
@@ -596,38 +616,16 @@ static int max16065_probe(struct i2c_client *client, | |||
596 | } | 616 | } |
597 | } | 617 | } |
598 | 618 | ||
599 | /* Register sysfs hooks */ | 619 | /* sysfs hooks */ |
600 | for (i = 0; i < data->num_adc * 4; i++) { | 620 | data->groups[groups++] = &max16065_basic_group; |
601 | /* Do not create sysfs entry if channel is disabled */ | 621 | if (have_secondary) |
602 | if (!data->range[i / 4]) | 622 | data->groups[groups++] = secondary_is_max ? |
603 | continue; | 623 | &max16065_max_group : &max16065_min_group; |
604 | |||
605 | ret = sysfs_create_file(&client->dev.kobj, | ||
606 | max16065_basic_attributes[i]); | ||
607 | if (unlikely(ret)) | ||
608 | goto out; | ||
609 | } | ||
610 | |||
611 | if (have_secondary) { | ||
612 | struct attribute **attr = secondary_is_max ? | ||
613 | max16065_max_attributes : max16065_min_attributes; | ||
614 | |||
615 | for (i = 0; i < data->num_adc; i++) { | ||
616 | if (!data->range[i]) | ||
617 | continue; | ||
618 | |||
619 | ret = sysfs_create_file(&client->dev.kobj, attr[i]); | ||
620 | if (unlikely(ret)) | ||
621 | goto out; | ||
622 | } | ||
623 | } | ||
624 | 624 | ||
625 | if (data->have_current) { | 625 | if (data->have_current) { |
626 | val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL); | 626 | val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL); |
627 | if (unlikely(val < 0)) { | 627 | if (unlikely(val < 0)) |
628 | ret = val; | 628 | return val; |
629 | goto out; | ||
630 | } | ||
631 | if (val & MAX16065_CURR_ENABLE) { | 629 | if (val & MAX16065_CURR_ENABLE) { |
632 | /* | 630 | /* |
633 | * Current gain is 6, 12, 24, 48 based on values in | 631 | * Current gain is 6, 12, 24, 48 based on values in |
@@ -636,33 +634,16 @@ static int max16065_probe(struct i2c_client *client, | |||
636 | data->curr_gain = 6 << ((val >> 2) & 0x03); | 634 | data->curr_gain = 6 << ((val >> 2) & 0x03); |
637 | data->range[MAX16065_NUM_ADC] | 635 | data->range[MAX16065_NUM_ADC] |
638 | = max16065_csp_adc_range[(val >> 1) & 0x01]; | 636 | = max16065_csp_adc_range[(val >> 1) & 0x01]; |
639 | ret = sysfs_create_group(&client->dev.kobj, | 637 | data->groups[groups++] = &max16065_current_group; |
640 | &max16065_current_group); | ||
641 | if (unlikely(ret)) | ||
642 | goto out; | ||
643 | } else { | 638 | } else { |
644 | data->have_current = false; | 639 | data->have_current = false; |
645 | } | 640 | } |
646 | } | 641 | } |
647 | 642 | ||
648 | data->hwmon_dev = hwmon_device_register(&client->dev); | 643 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
649 | if (unlikely(IS_ERR(data->hwmon_dev))) { | 644 | data, data->groups); |
650 | ret = PTR_ERR(data->hwmon_dev); | 645 | if (unlikely(IS_ERR(hwmon_dev))) |
651 | goto out; | 646 | return PTR_ERR(hwmon_dev); |
652 | } | ||
653 | return 0; | ||
654 | |||
655 | out: | ||
656 | max16065_cleanup(client); | ||
657 | return ret; | ||
658 | } | ||
659 | |||
660 | static int max16065_remove(struct i2c_client *client) | ||
661 | { | ||
662 | struct max16065_data *data = i2c_get_clientdata(client); | ||
663 | |||
664 | hwmon_device_unregister(data->hwmon_dev); | ||
665 | max16065_cleanup(client); | ||
666 | 647 | ||
667 | return 0; | 648 | return 0; |
668 | } | 649 | } |
@@ -685,7 +666,6 @@ static struct i2c_driver max16065_driver = { | |||
685 | .name = "max16065", | 666 | .name = "max16065", |
686 | }, | 667 | }, |
687 | .probe = max16065_probe, | 668 | .probe = max16065_probe, |
688 | .remove = max16065_remove, | ||
689 | .id_table = max16065_id, | 669 | .id_table = max16065_id, |
690 | }; | 670 | }; |
691 | 671 | ||