From a0393713530c49697e49ce0456c039228ab7facb Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 29 Mar 2013 13:54:50 -0700 Subject: [PATCH 01/49] hwmon: Remove unnecessary semicolons Semicolons after closing } of conditional blocks are not needed and can be removed. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- drivers/hwmon/adm1026.c | 6 +++--- drivers/hwmon/asc7621.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 3a6d9ef1c16c..b3498acb9ab4 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -616,7 +616,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) data->gpio = gpio; data->last_reading = jiffies; - }; /* last_reading */ + } /* last_reading */ if (!data->valid || time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) { @@ -700,7 +700,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) } data->last_config = jiffies; - }; /* last_config */ + } /* last_config */ data->valid = 1; mutex_unlock(&data->update_lock); @@ -1791,7 +1791,7 @@ static int adm1026_detect(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { /* We need to be able to do byte I/O */ return -ENODEV; - }; + } /* Now, we do the remaining detection. */ diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index 3ad9d849add2..8d9f2a0e8efe 100644 --- a/drivers/hwmon/asc7621.c +++ b/drivers/hwmon/asc7621.c @@ -138,7 +138,7 @@ static inline u8 read_byte(struct i2c_client *client, u8 reg) dev_err(&client->dev, "Unable to read from register 0x%02x.\n", reg); return 0; - }; + } return res & 0xff; } @@ -149,7 +149,7 @@ static inline int write_byte(struct i2c_client *client, u8 reg, u8 data) dev_err(&client->dev, "Unable to write value 0x%02x to register 0x%02x.\n", data, reg); - }; + } return res; } @@ -1030,7 +1030,7 @@ static struct asc7621_data *asc7621_update_device(struct device *dev) } } data->last_high_reading = jiffies; - }; /* last_reading */ + } /* last_reading */ /* Read all the low priority registers. */ @@ -1044,7 +1044,7 @@ static struct asc7621_data *asc7621_update_device(struct device *dev) } } data->last_low_reading = jiffies; - }; /* last_reading */ + } /* last_reading */ data->valid = 1; @@ -1084,11 +1084,11 @@ static void asc7621_init_client(struct i2c_client *client) dev_err(&client->dev, "Client (%d,0x%02x) config is locked.\n", i2c_adapter_id(client->adapter), client->addr); - }; + } if (!(value & 0x04)) { dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n", i2c_adapter_id(client->adapter), client->addr); - }; + } /* * Start monitoring From e8ab508c27be9868411b6578507e93e02bdb8cdb Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 11 Sep 2013 10:32:18 -0700 Subject: [PATCH 02/49] hwmon: (nct6775) Use return value from find_temp_source smatch complains that we don't use the return value from find_temp_source(). Valid point, only find_temp_source() doesn't return a valid error code. Have it return a valid error code and use it. Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 6eb03ce2cff4..de57e0d60d23 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -1545,7 +1545,7 @@ static int find_temp_source(struct nct6775_data *data, int index, int count) if (src == source) return nr; } - return -1; + return -ENODEV; } static ssize_t @@ -1644,7 +1644,7 @@ store_temp_beep(struct device *dev, struct device_attribute *attr, nr = find_temp_source(data, sattr->index, data->num_temp_beeps); if (nr < 0) - return -ENODEV; + return nr; bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; regindex = bit >> 3; From 45a5b3a183b43e07b7d1eaf1ef7c00fc87511b1b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 11 Sep 2013 10:35:47 -0700 Subject: [PATCH 03/49] hwmon: (nct6775) Check array index when accessing temp_offset smatch complains about a potential out-of-bounds access to the temp_offset array. That doesn't happen in practice, but it doesn't hurt to add an explicit check either. This prevents potential problems in the future (for example if the number of 'fixed' temperature sensors is increased to add support for another chip). Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index de57e0d60d23..b82fad487777 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -1457,7 +1457,8 @@ static struct nct6775_data *nct6775_update_device(struct device *dev) = nct6775_read_temp(data, data->reg_temp[j][i]); } - if (!(data->have_temp_fixed & (1 << i))) + if (i >= NUM_TEMP_FIXED || + !(data->have_temp_fixed & (1 << i))) continue; data->temp_offset[i] = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]); From ae02e7418ffa2ba5d927869ef9eab4c87549d8e9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:25:53 -0700 Subject: [PATCH 04/49] hwmon: (mc13783-adc) Increase size of name string smatch complains about mc13783_adc_probe() error: snprintf() chops off the last chars of 'id->name': 20 +vs 10 Use PLATFORM_NAME_SIZE instead of '10' as size when declaring the name variable. Signed-off-by: Guenter Roeck --- drivers/hwmon/mc13783-adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index 982d8622c09b..ae00e60d856c 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c @@ -37,7 +37,7 @@ struct mc13783_adc_priv { struct mc13xxx *mc13xxx; struct device *hwmon_dev; - char name[10]; + char name[PLATFORM_NAME_SIZE]; }; static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute From af78fdf4a61827bed7f0fcbba8cc9ae393a3ad82 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:31:38 -0700 Subject: [PATCH 05/49] hwmon: (pmbus) Don't unnecessarily crash the kernel pmbus code currently crashes the kernel if it detects an internal implementation error. While the detected condition suggests that there is a bug in the code, it is hardly fatal. Therefore, it should not trigger a crash. Replace BUG() with WARN(). Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 9319fcf142d9..871cf64d2996 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -686,7 +686,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, struct pmbus_boolean *b, if (!s1 && !s2) { ret = !!regval; } else if (!s1 || !s2) { - BUG(); + WARN(1, "Bad boolean descriptor %p: s1=%p, s2=%p\n", b, s1, s2); return 0; } else { long v1, v2; From bb34c0da646530425d9ae0e6e6229e641469da4c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:38:09 -0700 Subject: [PATCH 06/49] hwmon: (adt7462) Use error value returned from find_trange_value() find_trange_value() returns -ENODEV in case of errors, only to have it ignored and replaced with -EINVAL. Make it return -EINVAL and use it. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- drivers/hwmon/adt7462.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index addb5a4d5064..562cc3881d33 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -700,7 +700,7 @@ static int find_trange_value(int trange) if (trange_values[i] == trange) return i; - return -ENODEV; + return -EINVAL; } static struct adt7462_data *adt7462_update_device(struct device *dev) @@ -1294,9 +1294,8 @@ static ssize_t set_pwm_tmax(struct device *dev, /* trange = tmax - tmin */ tmin = (data->pwm_tmin[attr->index] - 64) * 1000; trange_value = find_trange_value(trange - tmin); - if (trange_value < 0) - return -EINVAL; + return trange_value; temp = trange_value << ADT7462_PWM_RANGE_SHIFT; temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK; From c52ae3d2794ee2a248245a9e5a26f717e1c401f5 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:42:39 -0700 Subject: [PATCH 07/49] hwmon: (gpio_fan) Use error value returned from get_fan_speed_index() get_fan_speed_index() returns -EINVAL in case of errors, only to have it ignored and replaced with -ENODEV. Make it return -ENODEV and use it. Signed-off-by: Guenter Roeck --- drivers/hwmon/gpio-fan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index b7d6a5704eb2..155c78f09d88 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -169,7 +169,7 @@ static int get_fan_speed_index(struct gpio_fan_data *fan_data) dev_warn(&fan_data->pdev->dev, "missing speed array entry for GPIO value 0x%x\n", ctrl_val); - return -EINVAL; + return -ENODEV; } static int rpm_to_speed_index(struct gpio_fan_data *fan_data, int rpm) @@ -384,7 +384,7 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, fan_data->pwm_enable = true; /* Enable manual fan speed control. */ fan_data->speed_index = get_fan_speed_index(fan_data); if (fan_data->speed_index < 0) - return -ENODEV; + return fan_data->speed_index; return 0; } From 83c97fe13e026a7795a07bfca76fe5d4b5cc5157 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:51:35 -0700 Subject: [PATCH 08/49] hwmon: (acpi_power_meter) Don't crash the kernel unnecessarily acpi_power_meter crashes the kernel if it detects an unexpected event or an internal implementation error. While the detected conditions suggest that there is a bug in the code, the condition is not fatal. Replace BUG() with WARN(). Signed-off-by: Guenter Roeck --- drivers/hwmon/acpi_power_meter.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index a9e3d0152c0b..51b045b20c1a 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -381,8 +381,10 @@ static ssize_t show_str(struct device *dev, val = resource->oem_info; break; default: - BUG(); + WARN(1, "Implementation error: unexpected attribute index %d\n", + attr->index); val = ""; + break; } return sprintf(buf, "%s\n", val); @@ -436,7 +438,9 @@ static ssize_t show_val(struct device *dev, val = resource->trip[attr->index - 7] * 1000; break; default: - BUG(); + WARN(1, "Implementation error: unexpected attribute index %d\n", + attr->index); + break; } return sprintf(buf, "%llu\n", val); @@ -855,7 +859,8 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event) dev_info(&device->dev, "Capping in progress.\n"); break; default: - BUG(); + WARN(1, "Unexpected event %d\n", event); + break; } mutex_unlock(&resource->lock); From 19f053c8406542eafb534b33d698677f076a3421 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:56:11 -0700 Subject: [PATCH 09/49] hwmon: (acpi_power_meter) Use return value from acpi_bus_register_driver acpi_bus_register_driver() returns a valid error code. Use it. Signed-off-by: Guenter Roeck --- drivers/hwmon/acpi_power_meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 51b045b20c1a..8d40da314a8e 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -996,7 +996,7 @@ static int __init acpi_power_meter_init(void) result = acpi_bus_register_driver(&acpi_power_meter_driver); if (result < 0) - return -ENODEV; + return result; return 0; } From 674d0ed8588c11ec9f70c8427ac83a73e0d156d5 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 13 Sep 2013 10:59:27 -0700 Subject: [PATCH 10/49] hwmon: (atxp1) Set and use error code from vid_to_reg() vid_to_reg() returns -1 if it encounters an error. Return -EINVAL instead. Its only caller, atxp1_storevcore(), doesn't use the return code but returns -1 instead, which is wrong anyway as it means -EPERM. Use the return value from vid_to_reg() instead to report the error. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- drivers/hwmon/atxp1.c | 3 +-- include/linux/hwmon-vid.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index aecb9ea7beb5..ddff02e3e66f 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -147,10 +147,9 @@ static ssize_t atxp1_storevcore(struct device *dev, /* Calculate VID */ vid = vid_to_reg(vcore, data->vrm); - if (vid < 0) { dev_err(dev, "VID calculation failed.\n"); - return -1; + return vid; } /* diff --git a/include/linux/hwmon-vid.h b/include/linux/hwmon-vid.h index f346e4d5381c..da0a680e2f6d 100644 --- a/include/linux/hwmon-vid.h +++ b/include/linux/hwmon-vid.h @@ -38,7 +38,7 @@ static inline int vid_to_reg(int val, u8 vrm) return ((val >= 1100) && (val <= 1850) ? ((18499 - val * 10) / 25 + 5) / 10 : -1); default: - return -1; + return -EINVAL; } } From 39b103b4d2e6f006dbd425cf71c46914bd31ce80 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 14 Sep 2013 00:43:12 -0700 Subject: [PATCH 11/49] hwmon: (f75375s) Don't crash the kernel unnecessarily The f75375s driver crashes the kernel if it detects an an internal implementation error. While the detected conditions suggest that there is a bug in the code, the condition is not fatal. Replace BUG() with WARN(). Cc: Riku Voipio Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index a837b94977f4..80c42bea90ed 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -275,7 +275,7 @@ static bool duty_mode_enabled(u8 pwm_enable) case 3: /* Manual, speed mode */ return false; default: - BUG(); + WARN(1, "Unexpected pwm_enable value %d\n", pwm_enable); return true; } } @@ -291,7 +291,7 @@ static bool auto_mode_enabled(u8 pwm_enable) case 4: /* Auto, duty mode */ return true; default: - BUG(); + WARN(1, "Unexpected pwm_enable value %d\n", pwm_enable); return false; } } From 522928a87fb98f0d6c99a5d66d2049768be6935b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 14 Sep 2013 00:47:24 -0700 Subject: [PATCH 12/49] hwmon: (f71882fg) Remove extra return statement Leftover from commit 33cd66e3 (hwmon: (f71882fg) Convert to use devm_ functions). Signed-off-by: Guenter Roeck --- drivers/hwmon/f71882fg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 31b221eeee6c..03d8592810bf 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -2420,7 +2420,6 @@ static int f71882fg_probe(struct platform_device *pdev) exit_unregister_sysfs: f71882fg_remove(pdev); /* Will unregister the sysfs files for us */ return err; /* f71882fg_remove() also frees our data */ - return err; } static int f71882fg_remove(struct platform_device *pdev) From bab2243ce1897865e31ea6d59b0478391f51812b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 6 Jul 2013 13:57:23 -0700 Subject: [PATCH 13/49] hwmon: Introduce hwmon_device_register_with_groups hwmon_device_register_with_groups() lets callers register a hwmon device together with all sysfs attributes in a single call. When using hwmon_device_register_with_groups(), hwmon attributes are attached to the hwmon device directly and no longer with its parent device. Signed-off-by: Guenter Roeck --- drivers/hwmon/hwmon.c | 130 +++++++++++++++++++++++++++++++++++------- include/linux/hwmon.h | 5 ++ 2 files changed, 115 insertions(+), 20 deletions(-) diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 646314f7c839..a982528293ea 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -25,10 +26,110 @@ #define HWMON_ID_PREFIX "hwmon" #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" -static struct class *hwmon_class; +struct hwmon_device { + const char *name; + struct device dev; +}; +#define to_hwmon_device(d) container_of(d, struct hwmon_device, dev) + +static ssize_t +show_name(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", to_hwmon_device(dev)->name); +} +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +static struct attribute *hwmon_dev_attrs[] = { + &dev_attr_name.attr, + NULL +}; + +static umode_t hwmon_dev_name_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + + if (to_hwmon_device(dev)->name == NULL) + return 0; + + return attr->mode; +} + +static struct attribute_group hwmon_dev_attr_group = { + .attrs = hwmon_dev_attrs, + .is_visible = hwmon_dev_name_is_visible, +}; + +static const struct attribute_group *hwmon_dev_attr_groups[] = { + &hwmon_dev_attr_group, + NULL +}; + +static void hwmon_dev_release(struct device *dev) +{ + kfree(to_hwmon_device(dev)); +} + +static struct class hwmon_class = { + .name = "hwmon", + .owner = THIS_MODULE, + .dev_groups = hwmon_dev_attr_groups, + .dev_release = hwmon_dev_release, +}; static DEFINE_IDA(hwmon_ida); +/** + * hwmon_device_register_with_groups - register w/ hwmon + * @dev: the parent device + * @name: hwmon name attribute + * @drvdata: driver data to attach to created device + * @groups: List of attribute groups to create + * + * hwmon_device_unregister() must be called when the device is no + * longer needed. + * + * Returns the pointer to the new device. + */ +struct device * +hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups) +{ + struct hwmon_device *hwdev; + int err, id; + + id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL); + if (id < 0) + return ERR_PTR(id); + + hwdev = kzalloc(sizeof(*hwdev), GFP_KERNEL); + if (hwdev == NULL) { + err = -ENOMEM; + goto ida_remove; + } + + hwdev->name = name; + hwdev->dev.class = &hwmon_class; + hwdev->dev.parent = dev; + hwdev->dev.groups = groups; + hwdev->dev.of_node = dev ? dev->of_node : NULL; + dev_set_drvdata(&hwdev->dev, drvdata); + dev_set_name(&hwdev->dev, HWMON_ID_FORMAT, id); + err = device_register(&hwdev->dev); + if (err) + goto free; + + return &hwdev->dev; + +free: + kfree(hwdev); +ida_remove: + ida_simple_remove(&hwmon_ida, id); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(hwmon_device_register_with_groups); + /** * hwmon_device_register - register w/ hwmon * @dev: the device to register @@ -40,20 +141,7 @@ static DEFINE_IDA(hwmon_ida); */ struct device *hwmon_device_register(struct device *dev) { - struct device *hwdev; - int id; - - id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL); - if (id < 0) - return ERR_PTR(id); - - hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, - HWMON_ID_FORMAT, id); - - if (IS_ERR(hwdev)) - ida_simple_remove(&hwmon_ida, id); - - return hwdev; + return hwmon_device_register_with_groups(dev, NULL, NULL, NULL); } EXPORT_SYMBOL_GPL(hwmon_device_register); @@ -105,19 +193,21 @@ static void __init hwmon_pci_quirks(void) static int __init hwmon_init(void) { + int err; + hwmon_pci_quirks(); - hwmon_class = class_create(THIS_MODULE, "hwmon"); - if (IS_ERR(hwmon_class)) { - pr_err("couldn't create sysfs class\n"); - return PTR_ERR(hwmon_class); + err = class_register(&hwmon_class); + if (err) { + pr_err("couldn't register hwmon sysfs class\n"); + return err; } return 0; } static void __exit hwmon_exit(void) { - class_destroy(hwmon_class); + class_unregister(&hwmon_class); } subsys_initcall(hwmon_init); diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index b2514f70d591..6d02ff77ae1a 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h @@ -15,8 +15,13 @@ #define _HWMON_H_ struct device; +struct attribute_group; struct device *hwmon_device_register(struct device *dev); +struct device * +hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups); void hwmon_device_unregister(struct device *dev); From 8269b75ae72c4501df7caf93d053526cef7e8a8a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 5 Jul 2013 22:30:39 -0700 Subject: [PATCH 14/49] hwmon: (ds1621) Convert to use hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/ds1621.c | 60 +++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index a26ba7a17c2b..595f4ef87100 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -120,7 +120,7 @@ static const u8 DS1621_REG_TEMP[3] = { /* Each client has this additional data */ struct ds1621_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ @@ -151,10 +151,10 @@ static inline u16 DS1621_TEMP_TO_REG(long temp, u8 zbits) return temp; } -static void ds1621_init_client(struct i2c_client *client) +static void ds1621_init_client(struct ds1621_data *data, + struct i2c_client *client) { u8 conf, new_conf, sreg, resol; - struct ds1621_data *data = i2c_get_clientdata(client); new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); /* switch to continuous conversion mode */ @@ -197,8 +197,8 @@ static void ds1621_init_client(struct i2c_client *client) static struct ds1621_data *ds1621_update_client(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); + struct ds1621_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 new_conf; mutex_lock(&data->update_lock); @@ -247,8 +247,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); + struct ds1621_data *data = dev_get_drvdata(dev); long val; int err; @@ -258,7 +257,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, mutex_lock(&data->update_lock); data->temp[attr->index] = DS1621_TEMP_TO_REG(val, data->zbits); - i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index], + i2c_smbus_write_word_swapped(data->client, DS1621_REG_TEMP[attr->index], data->temp[attr->index]); mutex_unlock(&data->update_lock); return count; @@ -282,16 +281,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da, static ssize_t show_convrate(struct device *dev, struct device_attribute *da, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); + struct ds1621_data *data = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%hu\n", data->update_interval); } static ssize_t set_convrate(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); + struct ds1621_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long convrate; s32 err; int resol = 0; @@ -343,8 +341,7 @@ static umode_t ds1621_attribute_visible(struct kobject *kobj, struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); - struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); + struct ds1621_data *data = dev_get_drvdata(dev); if (attr == &dev_attr_update_interval.attr) if (data->kind == ds1621 || data->kind == ds1625) @@ -358,49 +355,46 @@ static const struct attribute_group ds1621_group = { .is_visible = ds1621_attribute_visible }; +static const struct attribute_group *ds1621_groups[] = { + &ds1621_group, + NULL +}; + static int ds1621_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ds1621_data *data; - int err; + struct device *hwmon_dev; data = devm_kzalloc(&client->dev, sizeof(struct ds1621_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); mutex_init(&data->update_lock); data->kind = id->driver_data; + data->client = client; /* Initialize the DS1621 chip */ - ds1621_init_client(client); + ds1621_init_client(data, client); - /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &ds1621_group); - if (err) - return err; + hwmon_dev = hwmon_device_register_with_groups(&client->dev, + client->name, data, + ds1621_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } + i2c_set_clientdata(client, hwmon_dev); return 0; - - exit_remove_files: - sysfs_remove_group(&client->dev.kobj, &ds1621_group); - return err; } static int ds1621_remove(struct i2c_client *client) { - struct ds1621_data *data = i2c_get_clientdata(client); + struct device *hwmon_dev = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ds1621_group); + hwmon_device_unregister(hwmon_dev); return 0; } From 7258a12536da7f0db881b9ec9348f0d00a67e062 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 6 Jul 2013 09:46:14 -0700 Subject: [PATCH 15/49] hwmon: (gpio-fan) Convert to use hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/gpio-fan.c | 41 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 155c78f09d88..d5148c85ec5f 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -309,12 +309,6 @@ static ssize_t set_rpm(struct device *dev, struct device_attribute *attr, return ret; } -static ssize_t show_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "gpio-fan\n"); -} - static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm); static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, set_pwm_enable); @@ -324,26 +318,23 @@ static DEVICE_ATTR(fan1_max, S_IRUGO, show_rpm_max, NULL); static DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, NULL); static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_rpm, set_rpm); -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - static umode_t gpio_fan_is_visible(struct kobject *kobj, struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); struct gpio_fan_data *data = dev_get_drvdata(dev); - if (index == 1 && !data->alarm) + if (index == 0 && !data->alarm) return 0; - if (index > 1 && !data->ctrl) + if (index > 0 && !data->ctrl) return 0; return attr->mode; } static struct attribute *gpio_fan_attributes[] = { - &dev_attr_name.attr, - &dev_attr_fan1_alarm.attr, /* 1 */ - &dev_attr_pwm1.attr, /* 2 */ + &dev_attr_fan1_alarm.attr, /* 0 */ + &dev_attr_pwm1.attr, /* 1 */ &dev_attr_pwm1_enable.attr, &dev_attr_pwm1_mode.attr, &dev_attr_fan1_input.attr, @@ -358,6 +349,11 @@ static const struct attribute_group gpio_fan_group = { .is_visible = gpio_fan_is_visible, }; +static const struct attribute_group *gpio_fan_groups[] = { + &gpio_fan_group, + NULL +}; + static int fan_ctrl_init(struct gpio_fan_data *fan_data, struct gpio_fan_platform_data *pdata) { @@ -539,24 +535,16 @@ static int gpio_fan_probe(struct platform_device *pdev) return err; } - err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_group); - if (err) - return err; - /* Make this driver part of hwmon class. */ - fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(fan_data->hwmon_dev)) { - err = PTR_ERR(fan_data->hwmon_dev); - goto err_remove; - } + fan_data->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev, + "gpio-fan", fan_data, + gpio_fan_groups); + if (IS_ERR(fan_data->hwmon_dev)) + return PTR_ERR(fan_data->hwmon_dev); dev_info(&pdev->dev, "GPIO fan initialized\n"); return 0; - -err_remove: - sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group); - return err; } static int gpio_fan_remove(struct platform_device *pdev) @@ -564,7 +552,6 @@ static int gpio_fan_remove(struct platform_device *pdev) struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); hwmon_device_unregister(fan_data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group); return 0; } From 9a85d53cfcf1d65c08033aac067f79d2cfee5ad7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 6 Jul 2013 09:46:38 -0700 Subject: [PATCH 16/49] hwmon: (ltc4245) Convert to use hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4245.c | 78 +++++++++++++---------------------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index cdc1ecc6734d..d4172933ce4f 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c @@ -51,7 +51,9 @@ enum ltc4245_cmd { }; struct ltc4245_data { - struct device *hwmon_dev; + struct i2c_client *client; + + const struct attribute_group *groups[3]; struct mutex update_lock; bool valid; @@ -77,8 +79,8 @@ struct ltc4245_data { */ static void ltc4245_update_gpios(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ltc4245_data *data = i2c_get_clientdata(client); + struct ltc4245_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 gpio_curr, gpio_next, gpio_reg; int i; @@ -130,8 +132,8 @@ static void ltc4245_update_gpios(struct device *dev) static struct ltc4245_data *ltc4245_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ltc4245_data *data = i2c_get_clientdata(client); + struct ltc4245_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; s32 val; int i; @@ -455,41 +457,14 @@ static const struct attribute_group ltc4245_gpio_group = { .attrs = ltc4245_gpio_attributes, }; -static int ltc4245_sysfs_create_groups(struct i2c_client *client) +static void ltc4245_sysfs_add_groups(struct ltc4245_data *data) { - struct ltc4245_data *data = i2c_get_clientdata(client); - struct device *dev = &client->dev; - int ret; - - /* register the standard sysfs attributes */ - ret = sysfs_create_group(&dev->kobj, <c4245_std_group); - if (ret) { - dev_err(dev, "unable to register standard attributes\n"); - return ret; - } + /* standard sysfs attributes */ + data->groups[0] = <c4245_std_group; /* if we're using the extra gpio support, register it's attributes */ - if (data->use_extra_gpios) { - ret = sysfs_create_group(&dev->kobj, <c4245_gpio_group); - if (ret) { - dev_err(dev, "unable to register gpio attributes\n"); - sysfs_remove_group(&dev->kobj, <c4245_std_group); - return ret; - } - } - - return 0; -} - -static void ltc4245_sysfs_remove_groups(struct i2c_client *client) -{ - struct ltc4245_data *data = i2c_get_clientdata(client); - struct device *dev = &client->dev; - if (data->use_extra_gpios) - sysfs_remove_group(&dev->kobj, <c4245_gpio_group); - - sysfs_remove_group(&dev->kobj, <c4245_std_group); + data->groups[1] = <c4245_gpio_group; } static bool ltc4245_use_extra_gpios(struct i2c_client *client) @@ -517,7 +492,7 @@ static int ltc4245_probe(struct i2c_client *client, { struct i2c_adapter *adapter = client->adapter; struct ltc4245_data *data; - int ret; + struct device *hwmon_dev; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; @@ -526,7 +501,7 @@ static int ltc4245_probe(struct i2c_client *client, if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); data->use_extra_gpios = ltc4245_use_extra_gpios(client); @@ -534,30 +509,25 @@ static int ltc4245_probe(struct i2c_client *client, i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00); i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00); - /* Register sysfs hooks */ - ret = ltc4245_sysfs_create_groups(client); - if (ret) - return ret; + /* Add sysfs hooks */ + ltc4245_sysfs_add_groups(data); - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto out_hwmon_device_register; - } + hwmon_dev = hwmon_device_register_with_groups(&client->dev, + client->name, data, + data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + i2c_set_clientdata(client, hwmon_dev); return 0; - -out_hwmon_device_register: - ltc4245_sysfs_remove_groups(client); - return ret; } static int ltc4245_remove(struct i2c_client *client) { - struct ltc4245_data *data = i2c_get_clientdata(client); + struct device *hwmon_dev = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - ltc4245_sysfs_remove_groups(client); + hwmon_device_unregister(hwmon_dev); return 0; } From c3b7cddc70075d525db6b3068d8b2b9158eedc84 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 6 Jul 2013 09:47:08 -0700 Subject: [PATCH 17/49] hwmon: (pmbus) Convert to use hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 871cf64d2996..7f9ce3251063 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -97,6 +97,7 @@ struct pmbus_data { int max_attributes; int num_attributes; struct attribute_group group; + const struct attribute_group *groups[2]; struct pmbus_sensor *sensors; @@ -348,7 +349,7 @@ static struct _pmbus_status { static struct pmbus_data *pmbus_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); struct pmbus_data *data = i2c_get_clientdata(client); const struct pmbus_driver_info *info = data->info; struct pmbus_sensor *sensor; @@ -733,7 +734,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); struct pmbus_data *data = i2c_get_clientdata(client); struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); ssize_t rv = count; @@ -1768,22 +1769,16 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, goto out_kfree; } - /* Register sysfs hooks */ - ret = sysfs_create_group(&dev->kobj, &data->group); - if (ret) { - dev_err(dev, "Failed to create sysfs entries\n"); - goto out_kfree; - } - data->hwmon_dev = hwmon_device_register(dev); + data->groups[0] = &data->group; + data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, + data, data->groups); if (IS_ERR(data->hwmon_dev)) { ret = PTR_ERR(data->hwmon_dev); dev_err(dev, "Failed to register hwmon device\n"); - goto out_hwmon_device_register; + goto out_kfree; } return 0; -out_hwmon_device_register: - sysfs_remove_group(&dev->kobj, &data->group); out_kfree: kfree(data->group.attrs); return ret; @@ -1794,7 +1789,6 @@ int pmbus_do_remove(struct i2c_client *client) { struct pmbus_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &data->group); kfree(data->group.attrs); return 0; } From 615fc8cb0f900c91ee50f0da0a1821a7c6823671 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 6 Jul 2013 09:43:30 -0700 Subject: [PATCH 18/49] hwmon: (nct6775) Convert to use hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775.c | 122 ++++++++++++---------------------------- 1 file changed, 36 insertions(+), 86 deletions(-) diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index b82fad487777..58e9e11ef32a 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -725,10 +725,9 @@ struct nct6775_data { const char *name; struct device *hwmon_dev; - struct attribute_group *group_in; - struct attribute_group *group_fan; - struct attribute_group *group_temp; - struct attribute_group *group_pwm; + + int num_attr_groups; + const struct attribute_group *groups[6]; u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, * 3=temp_crit, 4=temp_lcrit @@ -942,7 +941,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg, struct sensor_device_attribute_2 *a2; struct attribute **attrs; struct sensor_device_template **t; - int err, i, j, count; + int i, j, count; if (repeat <= 0) return ERR_PTR(-EINVAL); @@ -1002,10 +1001,6 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg, } } - err = sysfs_create_group(&dev->kobj, group); - if (err) - return ERR_PTR(-ENOMEM); - return group; } @@ -2726,16 +2721,6 @@ store_fan_time(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t -show_name(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} - -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - static ssize_t show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf) { @@ -3062,16 +3047,16 @@ static umode_t nct6775_other_is_visible(struct kobject *kobj, struct device *dev = container_of(kobj, struct device, kobj); struct nct6775_data *data = dev_get_drvdata(dev); - if (index == 1 && !data->have_vid) + if (index == 0 && !data->have_vid) return 0; - if (index == 2 || index == 3) { - if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 2] < 0) + if (index == 1 || index == 2) { + if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0) return 0; } - if (index == 4 || index == 5) { - if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 4] < 0) + if (index == 3 || index == 4) { + if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0) return 0; } @@ -3084,13 +3069,12 @@ static umode_t nct6775_other_is_visible(struct kobject *kobj, * Any change in order or content must be matched. */ static struct attribute *nct6775_attributes_other[] = { - &dev_attr_name.attr, - &dev_attr_cpu0_vid.attr, /* 1 */ - &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 2 */ - &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 3 */ - &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 4 */ - &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 5 */ - &sensor_dev_attr_beep_enable.dev_attr.attr, /* 6 */ + &dev_attr_cpu0_vid.attr, /* 0 */ + &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 1 */ + &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 2 */ + &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 3 */ + &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 4 */ + &sensor_dev_attr_beep_enable.dev_attr.attr, /* 5 */ NULL }; @@ -3100,27 +3084,6 @@ static const struct attribute_group nct6775_group_other = { .is_visible = nct6775_other_is_visible, }; -/* - * Driver and device management - */ - -static void nct6775_device_remove_files(struct device *dev) -{ - struct nct6775_data *data = dev_get_drvdata(dev); - - if (data->group_pwm) - sysfs_remove_group(&dev->kobj, data->group_pwm); - if (data->group_in) - sysfs_remove_group(&dev->kobj, data->group_in); - if (data->group_fan) - sysfs_remove_group(&dev->kobj, data->group_fan); - if (data->group_temp) - sysfs_remove_group(&dev->kobj, data->group_temp); - - sysfs_remove_group(&dev->kobj, &nct6775_group_other); -} - -/* Get the monitoring functions started */ static inline void nct6775_init_device(struct nct6775_data *data) { int i; @@ -3871,51 +3834,39 @@ static int nct6775_probe(struct platform_device *pdev) /* Register sysfs hooks */ group = nct6775_create_attr_group(dev, &nct6775_pwm_template_group, data->pwm_num); - if (IS_ERR(group)) { - err = PTR_ERR(group); - goto exit_remove; - } - data->group_pwm = group; + if (IS_ERR(group)) + return PTR_ERR(group); + + data->groups[data->num_attr_groups++] = group; group = nct6775_create_attr_group(dev, &nct6775_in_template_group, fls(data->have_in)); - if (IS_ERR(group)) { - err = PTR_ERR(group); - goto exit_remove; - } - data->group_in = group; + if (IS_ERR(group)) + return PTR_ERR(group); + + data->groups[data->num_attr_groups++] = group; group = nct6775_create_attr_group(dev, &nct6775_fan_template_group, fls(data->has_fan)); - if (IS_ERR(group)) { - err = PTR_ERR(group); - goto exit_remove; - } - data->group_fan = group; + if (IS_ERR(group)) + return PTR_ERR(group); + + data->groups[data->num_attr_groups++] = group; group = nct6775_create_attr_group(dev, &nct6775_temp_template_group, fls(data->have_temp)); - if (IS_ERR(group)) { - err = PTR_ERR(group); - goto exit_remove; - } - data->group_temp = group; + if (IS_ERR(group)) + return PTR_ERR(group); - err = sysfs_create_group(&dev->kobj, &nct6775_group_other); - if (err) - goto exit_remove; + data->groups[data->num_attr_groups++] = group; + data->groups[data->num_attr_groups++] = &nct6775_group_other; - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } + data->hwmon_dev = hwmon_device_register_with_groups(dev, data->name, + data, data->groups); + if (IS_ERR(data->hwmon_dev)) + return PTR_ERR(data->hwmon_dev); return 0; - -exit_remove: - nct6775_device_remove_files(dev); - return err; } static int nct6775_remove(struct platform_device *pdev) @@ -3923,7 +3874,6 @@ static int nct6775_remove(struct platform_device *pdev) struct nct6775_data *data = platform_get_drvdata(pdev); hwmon_device_unregister(data->hwmon_dev); - nct6775_device_remove_files(&pdev->dev); return 0; } @@ -4102,7 +4052,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) /* * when Super-I/O functions move to a separate file, the Super-I/O * bus will manage the lifetime of the device and this module will only keep - * track of the nct6775 driver. But since we platform_device_alloc(), we + * track of the nct6775 driver. But since we use platform_device_alloc(), we * must keep track of the device */ static struct platform_device *pdev[2]; From 74188cba088192e14cd7fd5433876e8c947bcdd8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 11 Jul 2013 20:00:12 -0700 Subject: [PATCH 19/49] hwmon: Provide managed hwmon registration Drivers using the new hwmon_device_register_with_groups API often have a remove function which consists solely of a call hwmon_device_unregister(). Provide support for devm_hwmon_device_register_with_groups and devm_hwmon_device_unregister to allow this repeated code to be removed and help eliminate error handling code. Signed-off-by: Guenter Roeck --- drivers/hwmon/hwmon.c | 63 +++++++++++++++++++++++++++++++++++++++++++ include/linux/hwmon.h | 5 ++++ 2 files changed, 68 insertions(+) diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index a982528293ea..e176a43af63d 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -163,6 +163,69 @@ void hwmon_device_unregister(struct device *dev) } EXPORT_SYMBOL_GPL(hwmon_device_unregister); +static void devm_hwmon_release(struct device *dev, void *res) +{ + struct device *hwdev = *(struct device **)res; + + hwmon_device_unregister(hwdev); +} + +/** + * devm_hwmon_device_register_with_groups - register w/ hwmon + * @dev: the parent device + * @name: hwmon name attribute + * @drvdata: driver data to attach to created device + * @groups: List of attribute groups to create + * + * Returns the pointer to the new device. The new device is automatically + * unregistered with the parent device. + */ +struct device * +devm_hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups) +{ + struct device **ptr, *hwdev; + + if (!dev) + return ERR_PTR(-EINVAL); + + ptr = devres_alloc(devm_hwmon_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + hwdev = hwmon_device_register_with_groups(dev, name, drvdata, groups); + if (IS_ERR(hwdev)) + goto error; + + *ptr = hwdev; + devres_add(dev, ptr); + return hwdev; + +error: + devres_free(ptr); + return hwdev; +} +EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups); + +static int devm_hwmon_match(struct device *dev, void *res, void *data) +{ + struct device **hwdev = res; + + return *hwdev == data; +} + +/** + * devm_hwmon_device_unregister - removes a previously registered hwmon device + * + * @dev: the parent device of the device to unregister + */ +void devm_hwmon_device_unregister(struct device *dev) +{ + WARN_ON(devres_release(dev, devm_hwmon_release, devm_hwmon_match, dev)); +} +EXPORT_SYMBOL_GPL(devm_hwmon_device_unregister); + static void __init hwmon_pci_quirks(void) { #if defined CONFIG_X86 && defined CONFIG_PCI diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index 6d02ff77ae1a..09354f6c1d63 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h @@ -22,7 +22,12 @@ struct device * hwmon_device_register_with_groups(struct device *dev, const char *name, void *drvdata, const struct attribute_group **groups); +struct device * +devm_hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups); void hwmon_device_unregister(struct device *dev); +void devm_hwmon_device_unregister(struct device *dev); #endif From a150d95b7ce55fca87143f8ddce02f661e2fc6ec Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 11 Jul 2013 22:55:22 -0700 Subject: [PATCH 20/49] hwmon: (nct6775) Convert to use devm_hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 58e9e11ef32a..fdbd63282e29 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -724,8 +724,6 @@ struct nct6775_data { enum kinds kind; const char *name; - struct device *hwmon_dev; - int num_attr_groups; const struct attribute_group *groups[6]; @@ -3260,6 +3258,7 @@ static int nct6775_probe(struct platform_device *pdev) int num_reg_temp; u8 cr2a; struct attribute_group *group; + struct device *hwmon_dev; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, @@ -3861,19 +3860,10 @@ static int nct6775_probe(struct platform_device *pdev) data->groups[data->num_attr_groups++] = group; data->groups[data->num_attr_groups++] = &nct6775_group_other; - data->hwmon_dev = hwmon_device_register_with_groups(dev, data->name, - data, data->groups); - if (IS_ERR(data->hwmon_dev)) - return PTR_ERR(data->hwmon_dev); - - return 0; -} - -static int nct6775_remove(struct platform_device *pdev) -{ - struct nct6775_data *data = platform_get_drvdata(pdev); - - hwmon_device_unregister(data->hwmon_dev); + hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name, + data, data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); return 0; } @@ -3964,7 +3954,6 @@ static struct platform_driver nct6775_driver = { .pm = NCT6775_DEV_PM_OPS, }, .probe = nct6775_probe, - .remove = nct6775_remove, }; static const char * const nct6775_sio_names[] __initconst = { From 0d36dce0f1d15a9ca55f893b3aa5ce7c297e11c8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 11 Jul 2013 22:55:51 -0700 Subject: [PATCH 21/49] hwmon: (ds1621) Convert to use devm_hwmon_device_register_with_groups Also use new macro __ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/ds1621.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 595f4ef87100..5e398c98db2e 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -354,11 +354,7 @@ static const struct attribute_group ds1621_group = { .attrs = ds1621_attributes, .is_visible = ds1621_attribute_visible }; - -static const struct attribute_group *ds1621_groups[] = { - &ds1621_group, - NULL -}; +__ATTRIBUTE_GROUPS(ds1621); static int ds1621_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -379,23 +375,12 @@ static int ds1621_probe(struct i2c_client *client, /* Initialize the DS1621 chip */ ds1621_init_client(data, client); - hwmon_dev = hwmon_device_register_with_groups(&client->dev, - client->name, data, - ds1621_groups); + hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, + client->name, data, + ds1621_groups); if (IS_ERR(hwmon_dev)) return PTR_ERR(hwmon_dev); - i2c_set_clientdata(client, hwmon_dev); - - return 0; -} - -static int ds1621_remove(struct i2c_client *client) -{ - struct device *hwmon_dev = i2c_get_clientdata(client); - - hwmon_device_unregister(hwmon_dev); - return 0; } @@ -416,7 +401,6 @@ static struct i2c_driver ds1621_driver = { .name = "ds1621", }, .probe = ds1621_probe, - .remove = ds1621_remove, .id_table = ds1621_id, }; From 9bd024e9fd2bb82fdeb2a2bc8a4b687548f1467e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 1 Sep 2013 16:48:48 -0700 Subject: [PATCH 22/49] hwmon: (max6642) Convert to use devm_hwmon_device_register_with_groups Also rename new_client variable to client and introduce new variable dev pointing to client->dev in the probe function, and use new macro ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/max6642.c | 72 ++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c index 57d58cd32206..3d61f8d719d5 100644 --- a/drivers/hwmon/max6642.c +++ b/drivers/hwmon/max6642.c @@ -87,7 +87,7 @@ static int temp_to_reg(int val) */ struct max6642_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; bool valid; /* zero until following fields are valid */ unsigned long last_updated; /* in jiffies */ @@ -102,10 +102,10 @@ struct max6642_data { * Real code */ -static void max6642_init_client(struct i2c_client *client) +static void max6642_init_client(struct max6642_data *data, + struct i2c_client *client) { u8 config; - struct max6642_data *data = i2c_get_clientdata(client); /* * Start the conversions. @@ -168,14 +168,14 @@ static int max6642_detect(struct i2c_client *client, static struct max6642_data *max6642_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct max6642_data *data = i2c_get_clientdata(client); + struct max6642_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u16 val, tmp; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - dev_dbg(&client->dev, "Updating max6642 data.\n"); + dev_dbg(dev, "Updating max6642 data.\n"); val = i2c_smbus_read_byte_data(client, MAX6642_REG_R_LOCAL_TEMPL); tmp = (val >> 6) & 3; @@ -209,8 +209,8 @@ static struct max6642_data *max6642_update_device(struct device *dev) static ssize_t show_temp_max10(struct device *dev, struct device_attribute *dev_attr, char *buf) { - struct max6642_data *data = max6642_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct max6642_data *data = max6642_update_device(dev); return sprintf(buf, "%d\n", temp_from_reg10(data->temp_input[attr->index])); @@ -219,8 +219,8 @@ static ssize_t show_temp_max10(struct device *dev, static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, char *buf) { - struct max6642_data *data = max6642_update_device(dev); struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); + struct max6642_data *data = max6642_update_device(dev); return sprintf(buf, "%d\n", temp_from_reg(data->temp_high[attr2->nr])); } @@ -228,11 +228,10 @@ static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); + struct max6642_data *data = dev_get_drvdata(dev); unsigned long val; int err; - struct i2c_client *client = to_i2c_client(dev); - struct max6642_data *data = i2c_get_clientdata(client); - struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); err = kstrtoul(buf, 10, &val); if (err < 0) @@ -240,7 +239,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->temp_high[attr2->nr] = clamp_val(temp_to_reg(val), 0, 255); - i2c_smbus_write_byte_data(client, attr2->index, + i2c_smbus_write_byte_data(data->client, attr2->index, data->temp_high[attr2->nr]); mutex_unlock(&data->update_lock); return count; @@ -264,7 +263,7 @@ static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); -static struct attribute *max6642_attributes[] = { +static struct attribute *max6642_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, @@ -275,52 +274,30 @@ static struct attribute *max6642_attributes[] = { &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, NULL }; +ATTRIBUTE_GROUPS(max6642); -static const struct attribute_group max6642_group = { - .attrs = max6642_attributes, -}; - -static int max6642_probe(struct i2c_client *new_client, +static int max6642_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct max6642_data *data; - int err; + struct device *hwmon_dev; - data = devm_kzalloc(&new_client->dev, sizeof(struct max6642_data), - GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct max6642_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(new_client, data); + data->client = client; mutex_init(&data->update_lock); /* Initialize the MAX6642 chip */ - max6642_init_client(new_client); + max6642_init_client(data, client); - /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &max6642_group); - if (err) - return err; - - data->hwmon_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - return 0; - -exit_remove_files: - sysfs_remove_group(&new_client->dev.kobj, &max6642_group); - return err; -} - -static int max6642_remove(struct i2c_client *client) -{ - struct max6642_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &max6642_group); + hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, + client->name, data, + max6642_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); return 0; } @@ -341,7 +318,6 @@ static struct i2c_driver max6642_driver = { .name = "max6642", }, .probe = max6642_probe, - .remove = max6642_remove, .id_table = max6642_id, .detect = max6642_detect, .address_list = normal_i2c, From 3710263f136e629af1e4bae8df1c02b7fdec6260 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 1 Sep 2013 18:32:52 -0700 Subject: [PATCH 23/49] hwmon: (lm73) Convert to use devm_hwmon_device_register_with_groups Also introduce new variable dev pointing to client->dev in the probe function, and use new macro ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/lm73.c | 70 ++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 48 deletions(-) diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 9bde9644b102..9653bb870a47 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -55,7 +55,7 @@ static const unsigned short lm73_convrates[] = { }; struct lm73_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex lock; u8 ctrl; /* control register value */ }; @@ -66,7 +66,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); + struct lm73_data *data = dev_get_drvdata(dev); long temp; short value; s32 err; @@ -77,7 +77,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, /* Write value */ value = clamp_val(temp / 250, LM73_TEMP_MIN, LM73_TEMP_MAX) << 5; - err = i2c_smbus_write_word_swapped(client, attr->index, value); + err = i2c_smbus_write_word_swapped(data->client, attr->index, value); return (err < 0) ? err : count; } @@ -85,10 +85,10 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); + struct lm73_data *data = dev_get_drvdata(dev); int temp; - s32 err = i2c_smbus_read_word_swapped(client, attr->index); + s32 err = i2c_smbus_read_word_swapped(data->client, attr->index); if (err < 0) return err; @@ -101,8 +101,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, static ssize_t set_convrate(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm73_data *data = i2c_get_clientdata(client); + struct lm73_data *data = dev_get_drvdata(dev); unsigned long convrate; s32 err; int res = 0; @@ -124,7 +123,8 @@ static ssize_t set_convrate(struct device *dev, struct device_attribute *da, mutex_lock(&data->lock); data->ctrl &= LM73_CTRL_TO_MASK; data->ctrl |= res << LM73_CTRL_RES_SHIFT; - err = i2c_smbus_write_byte_data(client, LM73_REG_CTRL, data->ctrl); + err = i2c_smbus_write_byte_data(data->client, LM73_REG_CTRL, + data->ctrl); mutex_unlock(&data->lock); if (err < 0) @@ -136,8 +136,7 @@ static ssize_t set_convrate(struct device *dev, struct device_attribute *da, static ssize_t show_convrate(struct device *dev, struct device_attribute *da, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm73_data *data = i2c_get_clientdata(client); + struct lm73_data *data = dev_get_drvdata(dev); int res; res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT; @@ -147,13 +146,12 @@ static ssize_t show_convrate(struct device *dev, struct device_attribute *da, static ssize_t show_maxmin_alarm(struct device *dev, struct device_attribute *da, char *buf) { - struct i2c_client *client = to_i2c_client(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm73_data *data = i2c_get_clientdata(client); + struct lm73_data *data = dev_get_drvdata(dev); s32 ctrl; mutex_lock(&data->lock); - ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL); + ctrl = i2c_smbus_read_byte_data(data->client, LM73_REG_CTRL); if (ctrl < 0) goto abort; data->ctrl = ctrl; @@ -183,7 +181,7 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_maxmin_alarm, NULL, LM73_CTRL_LO_SHIFT); -static struct attribute *lm73_attributes[] = { +static struct attribute *lm73_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, @@ -192,10 +190,7 @@ static struct attribute *lm73_attributes[] = { &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, NULL }; - -static const struct attribute_group lm73_group = { - .attrs = lm73_attributes, -}; +ATTRIBUTE_GROUPS(lm73); /*-----------------------------------------------------------------------*/ @@ -204,16 +199,16 @@ static const struct attribute_group lm73_group = { static int lm73_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int status; + struct device *dev = &client->dev; + struct device *hwmon_dev; struct lm73_data *data; int ctrl; - data = devm_kzalloc(&client->dev, sizeof(struct lm73_data), - GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct lm73_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->lock); ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL); @@ -221,33 +216,13 @@ lm73_probe(struct i2c_client *client, const struct i2c_device_id *id) return ctrl; data->ctrl = ctrl; - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &lm73_group); - if (status) - return status; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, lm73_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } + dev_info(dev, "sensor '%s'\n", client->name); - dev_info(&client->dev, "%s: sensor '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &lm73_group); - return status; -} - -static int lm73_remove(struct i2c_client *client) -{ - struct lm73_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm73_group); return 0; } @@ -300,7 +275,6 @@ static struct i2c_driver lm73_driver = { .name = "lm73", }, .probe = lm73_probe, - .remove = lm73_remove, .id_table = lm73_ids, .detect = lm73_detect, .address_list = normal_i2c, From 8d3735522fb192738d7161865d41688f10983613 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 1 Sep 2013 22:49:25 -0700 Subject: [PATCH 24/49] hwmon: (max6697) Convert to use devm_hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/max6697.c | 54 +++++++++++++---------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c index a41b5f3fc506..0af910a479ab 100644 --- a/drivers/hwmon/max6697.c +++ b/drivers/hwmon/max6697.c @@ -77,7 +77,7 @@ struct max6697_chip_data { }; struct max6697_data { - struct device *hwmon_dev; + struct i2c_client *client; enum chips type; const struct max6697_chip_data *chip; @@ -181,8 +181,8 @@ static const struct max6697_chip_data max6697_chip_data[] = { static struct max6697_data *max6697_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct max6697_data *data = i2c_get_clientdata(client); + struct max6697_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; struct max6697_data *ret = data; int val; int i; @@ -303,8 +303,7 @@ static ssize_t set_temp(struct device *dev, { int nr = to_sensor_dev_attr_2(devattr)->nr; int index = to_sensor_dev_attr_2(devattr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct max6697_data *data = i2c_get_clientdata(client); + struct max6697_data *data = dev_get_drvdata(dev); long temp; int ret; @@ -316,7 +315,7 @@ static ssize_t set_temp(struct device *dev, temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset; temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127); data->temp[nr][index] = temp; - ret = i2c_smbus_write_byte_data(client, + ret = i2c_smbus_write_byte_data(data->client, index == 2 ? MAX6697_REG_MAX[nr] : MAX6697_REG_CRIT[nr], temp); @@ -405,8 +404,7 @@ static umode_t max6697_is_visible(struct kobject *kobj, struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); - struct i2c_client *client = to_i2c_client(dev); - struct max6697_data *data = i2c_get_clientdata(client); + struct max6697_data *data = dev_get_drvdata(dev); const struct max6697_chip_data *chip = data->chip; int channel = index / 6; /* channel number */ int nr = index % 6; /* attribute index within channel */ @@ -489,6 +487,7 @@ static struct attribute *max6697_attributes[] = { static const struct attribute_group max6697_group = { .attrs = max6697_attributes, .is_visible = max6697_is_visible, }; +__ATTRIBUTE_GROUPS(max6697); static void max6697_get_config_of(struct device_node *node, struct max6697_platform_data *pdata) @@ -525,9 +524,9 @@ static void max6697_get_config_of(struct device_node *node, } } -static int max6697_init_chip(struct i2c_client *client) +static int max6697_init_chip(struct max6697_data *data, + struct i2c_client *client) { - struct max6697_data *data = i2c_get_clientdata(client); struct max6697_platform_data *pdata = dev_get_platdata(&client->dev); struct max6697_platform_data p; const struct max6697_chip_data *chip = data->chip; @@ -625,6 +624,7 @@ static int max6697_probe(struct i2c_client *client, struct i2c_adapter *adapter = client->adapter; struct device *dev = &client->dev; struct max6697_data *data; + struct device *hwmon_dev; int err; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -636,37 +636,18 @@ static int max6697_probe(struct i2c_client *client, data->type = id->driver_data; data->chip = &max6697_chip_data[data->type]; - - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); - err = max6697_init_chip(client); + err = max6697_init_chip(data, client); if (err) return err; - err = sysfs_create_group(&client->dev.kobj, &max6697_group); - if (err) - return err; - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto error; - } - - return 0; - -error: - sysfs_remove_group(&client->dev.kobj, &max6697_group); - return err; -} - -static int max6697_remove(struct i2c_client *client) -{ - struct max6697_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &max6697_group); + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + max6697_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); return 0; } @@ -692,7 +673,6 @@ static struct i2c_driver max6697_driver = { .name = "max6697", }, .probe = max6697_probe, - .remove = max6697_remove, .id_table = max6697_id, }; From 38c75dc36dd368d10c4d0030665ec58565e4259b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 2 Sep 2013 11:31:28 -0700 Subject: [PATCH 25/49] 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 --- drivers/hwmon/max16065.c | 124 ++++++++++++++++----------------------- 1 file 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[] = { struct max16065_data { enum chips type; - struct device *hwmon_dev; + struct i2c_client *client; + const struct attribute_group *groups[4]; struct mutex update_lock; bool valid; unsigned long last_updated; /* in jiffies */ @@ -144,8 +145,8 @@ static int max16065_read_adc(struct i2c_client *client, int reg) static struct max16065_data *max16065_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct max16065_data *data = i2c_get_clientdata(client); + struct max16065_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { @@ -186,7 +187,7 @@ static ssize_t max16065_show_alarm(struct device *dev, val &= (1 << attr2->index); if (val) - i2c_smbus_write_byte_data(to_i2c_client(dev), + i2c_smbus_write_byte_data(data->client, MAX16065_FAULT(attr2->nr), val); return snprintf(buf, PAGE_SIZE, "%d\n", !!val); @@ -223,8 +224,7 @@ static ssize_t max16065_set_limit(struct device *dev, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); - struct i2c_client *client = to_i2c_client(dev); - struct max16065_data *data = i2c_get_clientdata(client); + struct max16065_data *data = dev_get_drvdata(dev); unsigned long val; int err; int limit; @@ -238,7 +238,7 @@ static ssize_t max16065_set_limit(struct device *dev, mutex_lock(&data->update_lock); data->limit[attr2->nr][attr2->index] = LIMIT_TO_MV(limit, data->range[attr2->index]); - i2c_smbus_write_byte_data(client, + i2c_smbus_write_byte_data(data->client, MAX16065_LIMIT(attr2->nr, attr2->index), limit); mutex_unlock(&data->update_lock); @@ -250,8 +250,7 @@ static ssize_t max16065_show_limit(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); - struct i2c_client *client = to_i2c_client(dev); - struct max16065_data *data = i2c_get_clientdata(client); + struct max16065_data *data = dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%d\n", data->limit[attr2->nr][attr2->index]); @@ -516,8 +515,32 @@ static struct attribute *max16065_max_attributes[] = { NULL }; +static umode_t max16065_basic_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct max16065_data *data = dev_get_drvdata(dev); + int index = n / 4; + + if (index >= data->num_adc || !data->range[index]) + return 0; + return a->mode; +} + +static umode_t max16065_secondary_is_visible(struct kobject *kobj, + struct attribute *a, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct max16065_data *data = dev_get_drvdata(dev); + + if (index >= data->num_adc) + return 0; + return a->mode; +} + static const struct attribute_group max16065_basic_group = { .attrs = max16065_basic_attributes, + .is_visible = max16065_basic_is_visible, }; static const struct attribute_group max16065_current_group = { @@ -526,38 +549,35 @@ static const struct attribute_group max16065_current_group = { static const struct attribute_group max16065_min_group = { .attrs = max16065_min_attributes, + .is_visible = max16065_secondary_is_visible, }; static const struct attribute_group max16065_max_group = { .attrs = max16065_max_attributes, + .is_visible = max16065_secondary_is_visible, }; -static void max16065_cleanup(struct i2c_client *client) -{ - sysfs_remove_group(&client->dev.kobj, &max16065_max_group); - sysfs_remove_group(&client->dev.kobj, &max16065_min_group); - sysfs_remove_group(&client->dev.kobj, &max16065_current_group); - sysfs_remove_group(&client->dev.kobj, &max16065_basic_group); -} - static int max16065_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = client->adapter; struct max16065_data *data; - int i, j, val, ret; + struct device *dev = &client->dev; + struct device *hwmon_dev; + int i, j, val; bool have_secondary; /* true if chip has secondary limits */ bool secondary_is_max = false; /* secondary limits reflect max */ + int groups = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_READ_WORD_DATA)) return -ENODEV; - data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (unlikely(!data)) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); data->num_adc = max16065_num_adc[id->driver_data]; @@ -596,38 +616,16 @@ static int max16065_probe(struct i2c_client *client, } } - /* Register sysfs hooks */ - for (i = 0; i < data->num_adc * 4; i++) { - /* Do not create sysfs entry if channel is disabled */ - if (!data->range[i / 4]) - continue; - - ret = sysfs_create_file(&client->dev.kobj, - max16065_basic_attributes[i]); - if (unlikely(ret)) - goto out; - } - - if (have_secondary) { - struct attribute **attr = secondary_is_max ? - max16065_max_attributes : max16065_min_attributes; - - for (i = 0; i < data->num_adc; i++) { - if (!data->range[i]) - continue; - - ret = sysfs_create_file(&client->dev.kobj, attr[i]); - if (unlikely(ret)) - goto out; - } - } + /* sysfs hooks */ + data->groups[groups++] = &max16065_basic_group; + if (have_secondary) + data->groups[groups++] = secondary_is_max ? + &max16065_max_group : &max16065_min_group; if (data->have_current) { val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL); - if (unlikely(val < 0)) { - ret = val; - goto out; - } + if (unlikely(val < 0)) + return val; if (val & MAX16065_CURR_ENABLE) { /* * Current gain is 6, 12, 24, 48 based on values in @@ -636,33 +634,16 @@ static int max16065_probe(struct i2c_client *client, data->curr_gain = 6 << ((val >> 2) & 0x03); data->range[MAX16065_NUM_ADC] = max16065_csp_adc_range[(val >> 1) & 0x01]; - ret = sysfs_create_group(&client->dev.kobj, - &max16065_current_group); - if (unlikely(ret)) - goto out; + data->groups[groups++] = &max16065_current_group; } else { data->have_current = false; } } - data->hwmon_dev = hwmon_device_register(&client->dev); - if (unlikely(IS_ERR(data->hwmon_dev))) { - ret = PTR_ERR(data->hwmon_dev); - goto out; - } - return 0; - -out: - max16065_cleanup(client); - return ret; -} - -static int max16065_remove(struct i2c_client *client) -{ - struct max16065_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - max16065_cleanup(client); + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (unlikely(IS_ERR(hwmon_dev))) + return PTR_ERR(hwmon_dev); return 0; } @@ -685,7 +666,6 @@ static struct i2c_driver max16065_driver = { .name = "max16065", }, .probe = max16065_probe, - .remove = max16065_remove, .id_table = max16065_id, }; From 468bf0e395363c12a41f508cc202b8d33f201807 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 2 Sep 2013 13:16:19 -0700 Subject: [PATCH 26/49] hwmon: (ina2xx) Convert to use devm_hwmon_device_register_with_groups Also introduce dev variable in probe function to simplify access to client->dev, and use new macro ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/ina2xx.c | 64 ++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 70a39a8ac016..93d26e8af3e2 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -78,7 +78,7 @@ struct ina2xx_config { }; struct ina2xx_data { - struct device *hwmon_dev; + struct i2c_client *client; const struct ina2xx_config *config; struct mutex update_lock; @@ -112,8 +112,8 @@ static const struct ina2xx_config ina2xx_config[] = { static struct ina2xx_data *ina2xx_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ina2xx_data *data = i2c_get_clientdata(client); + struct ina2xx_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; struct ina2xx_data *ret = data; mutex_lock(&data->update_lock); @@ -203,41 +203,39 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, INA2XX_POWER); /* pointers to created device attributes */ -static struct attribute *ina2xx_attributes[] = { +static struct attribute *ina2xx_attrs[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_curr1_input.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, NULL, }; - -static const struct attribute_group ina2xx_group = { - .attrs = ina2xx_attributes, -}; +ATTRIBUTE_GROUPS(ina2xx); static int ina2xx_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = client->adapter; - struct ina2xx_data *data; struct ina2xx_platform_data *pdata; - int ret; - u32 val; + struct device *dev = &client->dev; + struct ina2xx_data *data; + struct device *hwmon_dev; long shunt = 10000; /* default shunt value 10mOhms */ + u32 val; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; - data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - if (dev_get_platdata(&client->dev)) { - pdata = dev_get_platdata(&client->dev); + if (dev_get_platdata(dev)) { + pdata = dev_get_platdata(dev); shunt = pdata->shunt_uohms; - } else if (!of_property_read_u32(client->dev.of_node, - "shunt-resistor", &val)) { - shunt = val; + } else if (!of_property_read_u32(dev->of_node, + "shunt-resistor", &val)) { + shunt = val; } if (shunt <= 0) @@ -255,37 +253,18 @@ static int ina2xx_probe(struct i2c_client *client, i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, data->config->calibration_factor / shunt); - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); - ret = sysfs_create_group(&client->dev.kobj, &ina2xx_group); - if (ret) - return ret; + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, ina2xx_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto out_err_hwmon; - } - - dev_info(&client->dev, "power monitor %s (Rshunt = %li uOhm)\n", + dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n", id->name, shunt); return 0; - -out_err_hwmon: - sysfs_remove_group(&client->dev.kobj, &ina2xx_group); - return ret; -} - -static int ina2xx_remove(struct i2c_client *client) -{ - struct ina2xx_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ina2xx_group); - - return 0; } static const struct i2c_device_id ina2xx_id[] = { @@ -302,7 +281,6 @@ static struct i2c_driver ina2xx_driver = { .name = "ina2xx", }, .probe = ina2xx_probe, - .remove = ina2xx_remove, .id_table = ina2xx_id, }; From f3643ac7ffd8bf9a3b0bac8e207529d01bebf269 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 4 Sep 2013 16:24:09 -0700 Subject: [PATCH 27/49] hwmon: (tmp401) Convert to use devm_hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/tmp401.c | 94 +++++++++++++----------------------------- 1 file changed, 29 insertions(+), 65 deletions(-) diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index dfe6d9527efb..7fa6e7d0b9b6 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -155,7 +155,8 @@ MODULE_DEVICE_TABLE(i2c, tmp401_id); */ struct tmp401_data { - struct device *hwmon_dev; + struct i2c_client *client; + const struct attribute_group *groups[3]; struct mutex update_lock; char valid; /* zero until following fields are valid */ unsigned long last_updated; /* in jiffies */ @@ -231,8 +232,8 @@ static int tmp401_update_device_reg16(struct i2c_client *client, static struct tmp401_data *tmp401_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; struct tmp401_data *ret = data; int i, val; unsigned long next_update; @@ -350,15 +351,12 @@ static ssize_t store_temp(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr_2(devattr)->nr; int index = to_sensor_dev_attr_2(devattr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = tmp401_update_device(dev); + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; u16 reg; u8 regaddr; - if (IS_ERR(data)) - return PTR_ERR(data); - if (kstrtol(buf, 10, &val)) return -EINVAL; @@ -405,7 +403,7 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute val = clamp_val(val, temp - 255000, temp); reg = ((temp - val) + 500) / 1000; - i2c_smbus_write_byte_data(to_i2c_client(dev), TMP401_TEMP_CRIT_HYST, + i2c_smbus_write_byte_data(data->client, TMP401_TEMP_CRIT_HYST, reg); data->temp_crit_hyst = reg; @@ -423,8 +421,8 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute static ssize_t reset_temp_history(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; if (kstrtol(buf, 10, &val)) @@ -447,8 +445,7 @@ static ssize_t reset_temp_history(struct device *dev, static ssize_t show_update_interval(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); + struct tmp401_data *data = dev_get_drvdata(dev); return sprintf(buf, "%u\n", data->update_interval); } @@ -457,8 +454,8 @@ static ssize_t set_update_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); + struct tmp401_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err, rate; @@ -616,10 +613,10 @@ static const struct attribute_group tmp432_group = { * Begin non sysfs callback code (aka Real code) */ -static void tmp401_init_client(struct i2c_client *client) +static void tmp401_init_client(struct tmp401_data *data, + struct i2c_client *client) { int config, config_orig; - struct tmp401_data *data = i2c_get_clientdata(client); /* Set the conversion rate to 2 Hz */ i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5); @@ -705,77 +702,45 @@ static int tmp401_detect(struct i2c_client *client, return 0; } -static int tmp401_remove(struct i2c_client *client) -{ - struct device *dev = &client->dev; - struct tmp401_data *data = i2c_get_clientdata(client); - - if (data->hwmon_dev) - hwmon_device_unregister(data->hwmon_dev); - - sysfs_remove_group(&dev->kobj, &tmp401_group); - - if (data->kind == tmp411) - sysfs_remove_group(&dev->kobj, &tmp411_group); - - if (data->kind == tmp432) - sysfs_remove_group(&dev->kobj, &tmp432_group); - - return 0; -} - static int tmp401_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct device *dev = &client->dev; - int err; - struct tmp401_data *data; const char *names[] = { "TMP401", "TMP411", "TMP431", "TMP432" }; + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct tmp401_data *data; + int groups = 0; data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); data->kind = id->driver_data; /* Initialize the TMP401 chip */ - tmp401_init_client(client); + tmp401_init_client(data, client); /* Register sysfs hooks */ - err = sysfs_create_group(&dev->kobj, &tmp401_group); - if (err) - return err; + data->groups[groups++] = &tmp401_group; /* Register additional tmp411 sysfs hooks */ - if (data->kind == tmp411) { - err = sysfs_create_group(&dev->kobj, &tmp411_group); - if (err) - goto exit_remove; - } + if (data->kind == tmp411) + data->groups[groups++] = &tmp411_group; /* Register additional tmp432 sysfs hooks */ - if (data->kind == tmp432) { - err = sysfs_create_group(&dev->kobj, &tmp432_group); - if (err) - goto exit_remove; - } + if (data->kind == tmp432) + data->groups[groups++] = &tmp432_group; - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - data->hwmon_dev = NULL; - goto exit_remove; - } + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); dev_info(dev, "Detected TI %s chip\n", names[data->kind]); return 0; - -exit_remove: - tmp401_remove(client); - return err; } static struct i2c_driver tmp401_driver = { @@ -784,7 +749,6 @@ static struct i2c_driver tmp401_driver = { .name = "tmp401", }, .probe = tmp401_probe, - .remove = tmp401_remove, .id_table = tmp401_id, .detect = tmp401_detect, .address_list = normal_i2c, From 9d86bd6ba3ba2f254720e2916dfda64737974963 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 4 Sep 2013 16:39:12 -0700 Subject: [PATCH 28/49] hwmon: (lm95234) Convert to use devm_hwmon_device_register_with_groups Also use new macro ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/lm95234.c | 137 +++++++++++++++------------------------- 1 file changed, 50 insertions(+), 87 deletions(-) diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c index 307c9eaeeb9f..cf8750745c88 100644 --- a/drivers/hwmon/lm95234.c +++ b/drivers/hwmon/lm95234.c @@ -57,7 +57,7 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4d, 0x4e, I2C_CLIENT_END }; /* Client data (each client gets its own) */ struct lm95234_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; unsigned long last_updated, interval; /* in jiffies */ bool valid; /* false until following fields are valid */ @@ -114,9 +114,9 @@ static u16 update_intervals[] = { 143, 364, 1000, 2500 }; /* Fill value cache. Must be called with update lock held. */ -static int lm95234_fill_cache(struct i2c_client *client) +static int lm95234_fill_cache(struct lm95234_data *data, + struct i2c_client *client) { - struct lm95234_data *data = i2c_get_clientdata(client); int i, ret; ret = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE); @@ -157,9 +157,9 @@ static int lm95234_fill_cache(struct i2c_client *client) return 0; } -static int lm95234_update_device(struct i2c_client *client, - struct lm95234_data *data) +static int lm95234_update_device(struct lm95234_data *data) { + struct i2c_client *client = data->client; int ret; mutex_lock(&data->update_lock); @@ -169,7 +169,7 @@ static int lm95234_update_device(struct i2c_client *client, int i; if (!data->valid) { - ret = lm95234_fill_cache(client); + ret = lm95234_fill_cache(data, client); if (ret < 0) goto abort; } @@ -209,10 +209,9 @@ static int lm95234_update_device(struct i2c_client *client, static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -224,10 +223,9 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); u32 mask = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -238,10 +236,9 @@ static ssize_t show_alarm(struct device *dev, static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); u8 mask = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -252,11 +249,10 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, static ssize_t set_type(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); unsigned long val; u8 mask = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -274,7 +270,7 @@ static ssize_t set_type(struct device *dev, struct device_attribute *attr, else data->sensor_type &= ~mask; data->valid = false; - i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL, + i2c_smbus_write_byte_data(data->client, LM95234_REG_REM_MODEL, data->sensor_type); mutex_unlock(&data->update_lock); @@ -284,10 +280,9 @@ static ssize_t set_type(struct device *dev, struct device_attribute *attr, static ssize_t show_tcrit2(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -298,11 +293,10 @@ static ssize_t show_tcrit2(struct device *dev, struct device_attribute *attr, static ssize_t set_tcrit2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; long val; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -315,7 +309,7 @@ static ssize_t set_tcrit2(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->tcrit2[index] = val; - i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT2(index), val); + i2c_smbus_write_byte_data(data->client, LM95234_REG_TCRIT2(index), val); mutex_unlock(&data->update_lock); return count; @@ -324,10 +318,9 @@ static ssize_t set_tcrit2(struct device *dev, struct device_attribute *attr, static ssize_t show_tcrit2_hyst(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -340,8 +333,7 @@ static ssize_t show_tcrit2_hyst(struct device *dev, static ssize_t show_tcrit1(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; return sprintf(buf, "%u", data->tcrit1[index] * 1000); @@ -350,11 +342,10 @@ static ssize_t show_tcrit1(struct device *dev, struct device_attribute *attr, static ssize_t set_tcrit1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; + int ret = lm95234_update_device(data); long val; - int ret = lm95234_update_device(client, data); if (ret) return ret; @@ -367,7 +358,7 @@ static ssize_t set_tcrit1(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->tcrit1[index] = val; - i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT1(index), val); + i2c_smbus_write_byte_data(data->client, LM95234_REG_TCRIT1(index), val); mutex_unlock(&data->update_lock); return count; @@ -376,10 +367,9 @@ static ssize_t set_tcrit1(struct device *dev, struct device_attribute *attr, static ssize_t show_tcrit1_hyst(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -393,11 +383,10 @@ static ssize_t set_tcrit1_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; + int ret = lm95234_update_device(data); long val; - int ret = lm95234_update_device(client, data); if (ret) return ret; @@ -411,7 +400,7 @@ static ssize_t set_tcrit1_hyst(struct device *dev, mutex_lock(&data->update_lock); data->thyst = val; - i2c_smbus_write_byte_data(client, LM95234_REG_TCRIT_HYST, val); + i2c_smbus_write_byte_data(data->client, LM95234_REG_TCRIT_HYST, val); mutex_unlock(&data->update_lock); return count; @@ -420,10 +409,9 @@ static ssize_t set_tcrit1_hyst(struct device *dev, static ssize_t show_offset(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; - int ret = lm95234_update_device(client, data); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -434,11 +422,10 @@ static ssize_t show_offset(struct device *dev, struct device_attribute *attr, static ssize_t set_offset(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(attr)->index; + int ret = lm95234_update_device(data); long val; - int ret = lm95234_update_device(client, data); if (ret) return ret; @@ -452,7 +439,7 @@ static ssize_t set_offset(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->toffset[index] = val; - i2c_smbus_write_byte_data(client, LM95234_REG_OFFSET(index), val); + i2c_smbus_write_byte_data(data->client, LM95234_REG_OFFSET(index), val); mutex_unlock(&data->update_lock); return count; @@ -461,9 +448,8 @@ static ssize_t set_offset(struct device *dev, struct device_attribute *attr, static ssize_t show_interval(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); - int ret = lm95234_update_device(client, data); + struct lm95234_data *data = dev_get_drvdata(dev); + int ret = lm95234_update_device(data); if (ret) return ret; @@ -475,11 +461,10 @@ static ssize_t show_interval(struct device *dev, struct device_attribute *attr, static ssize_t set_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm95234_data *data = i2c_get_clientdata(client); + struct lm95234_data *data = dev_get_drvdata(dev); + int ret = lm95234_update_device(data); unsigned long val; u8 regval; - int ret = lm95234_update_device(client, data); if (ret) return ret; @@ -495,7 +480,7 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->interval = msecs_to_jiffies(update_intervals[regval]); - i2c_smbus_write_byte_data(client, LM95234_REG_CONVRATE, regval); + i2c_smbus_write_byte_data(data->client, LM95234_REG_CONVRATE, regval); mutex_unlock(&data->update_lock); return count; @@ -579,7 +564,7 @@ static SENSOR_DEVICE_ATTR(temp5_offset, S_IWUSR | S_IRUGO, show_offset, static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, set_interval); -static struct attribute *lm95234_attributes[] = { +static struct attribute *lm95234_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp3_input.dev_attr.attr, @@ -621,10 +606,7 @@ static struct attribute *lm95234_attributes[] = { &dev_attr_update_interval.attr, NULL }; - -static const struct attribute_group lm95234_group = { - .attrs = lm95234_attributes, -}; +ATTRIBUTE_GROUPS(lm95234); static int lm95234_detect(struct i2c_client *client, struct i2c_board_info *info) @@ -701,13 +683,14 @@ static int lm95234_probe(struct i2c_client *client, { struct device *dev = &client->dev; struct lm95234_data *data; + struct device *hwmon_dev; int err; data = devm_kzalloc(dev, sizeof(struct lm95234_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); /* Initialize the LM95234 chip */ @@ -715,30 +698,11 @@ static int lm95234_probe(struct i2c_client *client, if (err < 0) return err; - /* Register sysfs hooks */ - err = sysfs_create_group(&dev->kobj, &lm95234_group); - if (err) - return err; - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - return 0; - -exit_remove_files: - sysfs_remove_group(&dev->kobj, &lm95234_group); - return err; -} - -static int lm95234_remove(struct i2c_client *client) -{ - struct lm95234_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm95234_group); + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + lm95234_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); return 0; } @@ -756,7 +720,6 @@ static struct i2c_driver lm95234_driver = { .name = DRVNAME, }, .probe = lm95234_probe, - .remove = lm95234_remove, .id_table = lm95234_id, .detect = lm95234_detect, .address_list = normal_i2c, From 89de734471c5381558b1e749e0b1b88b5b497708 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 4 Sep 2013 16:55:59 -0700 Subject: [PATCH 29/49] hwmon: (ina209) Convert to use devm_hwmon_device_register_with_groups Also use new macro ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/ina209.c | 46 +++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/drivers/hwmon/ina209.c b/drivers/hwmon/ina209.c index c6fdd5bd395e..5378fdefc1f7 100644 --- a/drivers/hwmon/ina209.c +++ b/drivers/hwmon/ina209.c @@ -63,7 +63,7 @@ #define INA209_SHUNT_DEFAULT 10000 /* uOhm */ struct ina209_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; bool valid; @@ -78,8 +78,8 @@ struct ina209_data { static struct ina209_data *ina209_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ina209_data *data = i2c_get_clientdata(client); + struct ina209_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; struct ina209_data *ret = data; s32 val; int i; @@ -234,7 +234,6 @@ static ssize_t ina209_set_interval(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); struct ina209_data *data = ina209_update_device(dev); long val; u16 regval; @@ -250,7 +249,8 @@ static ssize_t ina209_set_interval(struct device *dev, mutex_lock(&data->update_lock); regval = ina209_reg_from_interval(data->regs[INA209_CONFIGURATION], val); - i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION, regval); + i2c_smbus_write_word_swapped(data->client, INA209_CONFIGURATION, + regval); data->regs[INA209_CONFIGURATION] = regval; data->update_interval = ina209_interval_from_reg(regval); mutex_unlock(&data->update_lock); @@ -260,8 +260,7 @@ static ssize_t ina209_set_interval(struct device *dev, static ssize_t ina209_show_interval(struct device *dev, struct device_attribute *da, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct ina209_data *data = i2c_get_clientdata(client); + struct ina209_data *data = dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%d\n", data->update_interval); } @@ -285,9 +284,9 @@ static ssize_t ina209_reset_history(struct device *dev, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct ina209_data *data = i2c_get_clientdata(client); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ina209_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u32 mask = attr->index; long val; int i, ret; @@ -312,7 +311,6 @@ static ssize_t ina209_set_value(struct device *dev, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); struct ina209_data *data = ina209_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int reg = attr->index; @@ -332,7 +330,7 @@ static ssize_t ina209_set_value(struct device *dev, count = ret; goto abort; } - i2c_smbus_write_word_swapped(client, reg, ret); + i2c_smbus_write_word_swapped(data->client, reg, ret); data->regs[reg] = ret; abort: mutex_unlock(&data->update_lock); @@ -457,7 +455,7 @@ static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, * Finally, construct an array of pointers to members of the above objects, * as required for sysfs_create_group() */ -static struct attribute *ina209_attributes[] = { +static struct attribute *ina209_attrs[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in0_input_highest.dev_attr.attr, &sensor_dev_attr_in0_input_lowest.dev_attr.attr, @@ -498,10 +496,7 @@ static struct attribute *ina209_attributes[] = { NULL, }; - -static const struct attribute_group ina209_group = { - .attrs = ina209_attributes, -}; +ATTRIBUTE_GROUPS(ina209); static void ina209_restore_conf(struct i2c_client *client, struct ina209_data *data) @@ -565,6 +560,7 @@ static int ina209_probe(struct i2c_client *client, { struct i2c_adapter *adapter = client->adapter; struct ina209_data *data; + struct device *hwmon_dev; int ret; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) @@ -575,27 +571,23 @@ static int ina209_probe(struct i2c_client *client, return -ENOMEM; i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); ret = ina209_init_client(client, data); if (ret) return ret; - /* Register sysfs hooks */ - ret = sysfs_create_group(&client->dev.kobj, &ina209_group); - if (ret) + hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, + client->name, + data, ina209_groups); + if (IS_ERR(hwmon_dev)) { + ret = PTR_ERR(hwmon_dev); goto out_restore_conf; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto out_hwmon_device_register; } return 0; -out_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, &ina209_group); out_restore_conf: ina209_restore_conf(client, data); return ret; @@ -605,8 +597,6 @@ static int ina209_remove(struct i2c_client *client) { struct ina209_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ina209_group); ina209_restore_conf(client, data); return 0; From 38f150fe382a42abeb333cc814becd57f5c01add Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 5 Sep 2013 08:52:41 -0700 Subject: [PATCH 30/49] hwmon: (ltc4261) Convert to use devm_hwmon_device_register_with_groups Also use new macro ATTRIBUTE_GROUPS to declare attribute groups. Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4261.c | 55 ++++++++++++----------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 487da58ec86c..6c50db9530db 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -55,7 +55,7 @@ #define FAULT_OC (1<<2) struct ltc4261_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; bool valid; @@ -67,8 +67,8 @@ struct ltc4261_data { static struct ltc4261_data *ltc4261_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ltc4261_data *data = i2c_get_clientdata(client); + struct ltc4261_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; struct ltc4261_data *ret = data; mutex_lock(&data->update_lock); @@ -150,7 +150,6 @@ static ssize_t ltc4261_show_bool(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); struct ltc4261_data *data = ltc4261_update_device(dev); u8 fault; @@ -159,7 +158,7 @@ static ssize_t ltc4261_show_bool(struct device *dev, fault = data->regs[LTC4261_FAULT] & attr->index; if (fault) /* Clear reported faults in chip register */ - i2c_smbus_write_byte_data(client, LTC4261_FAULT, ~fault); + i2c_smbus_write_byte_data(data->client, LTC4261_FAULT, ~fault); return snprintf(buf, PAGE_SIZE, "%d\n", fault ? 1 : 0); } @@ -197,7 +196,7 @@ static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4261_show_value, NULL, static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4261_show_bool, NULL, FAULT_OC); -static struct attribute *ltc4261_attributes[] = { +static struct attribute *ltc4261_attrs[] = { &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_min_alarm.dev_attr.attr, &sensor_dev_attr_in1_max_alarm.dev_attr.attr, @@ -210,60 +209,39 @@ static struct attribute *ltc4261_attributes[] = { NULL, }; - -static const struct attribute_group ltc4261_group = { - .attrs = ltc4261_attributes, -}; +ATTRIBUTE_GROUPS(ltc4261); static int ltc4261_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = client->adapter; + struct device *dev = &client->dev; struct ltc4261_data *data; - int ret; + struct device *hwmon_dev; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { - dev_err(&client->dev, "Failed to read status register\n"); + dev_err(dev, "Failed to read status register\n"); return -ENODEV; } - data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->update_lock); /* Clear faults */ i2c_smbus_write_byte_data(client, LTC4261_FAULT, 0x00); - /* Register sysfs hooks */ - ret = sysfs_create_group(&client->dev.kobj, <c4261_group); - if (ret) - return ret; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto out_hwmon_device_register; - } - - return 0; - -out_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, <c4261_group); - return ret; -} - -static int ltc4261_remove(struct i2c_client *client) -{ - struct ltc4261_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, <c4261_group); + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + ltc4261_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); return 0; } @@ -281,7 +259,6 @@ static struct i2c_driver ltc4261_driver = { .name = "ltc4261", }, .probe = ltc4261_probe, - .remove = ltc4261_remove, .id_table = ltc4261_id, }; From 62f9a57c0b48b6fd6c13e3b8d0c424737b1103c9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 5 Sep 2013 09:02:34 -0700 Subject: [PATCH 31/49] hwmon: (jc42) Convert to use devm_hwmon_device_register_with_groups Signed-off-by: Guenter Roeck --- drivers/hwmon/jc42.c | 61 ++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 4a58f130fd4e..f362cead837e 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -163,7 +163,7 @@ static struct jc42_chips jc42_chips[] = { /* Each client has this additional data */ struct jc42_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex update_lock; /* protect register access */ bool extended; /* true if extended range supported */ bool valid; @@ -193,21 +193,21 @@ MODULE_DEVICE_TABLE(i2c, jc42_id); static int jc42_suspend(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct jc42_data *data = i2c_get_clientdata(client); + struct jc42_data *data = dev_get_drvdata(dev); data->config |= JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config); + i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, + data->config); return 0; } static int jc42_resume(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct jc42_data *data = i2c_get_clientdata(client); + struct jc42_data *data = dev_get_drvdata(dev); data->config &= ~JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config); + i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, + data->config); return 0; } @@ -317,15 +317,14 @@ static ssize_t set_##value(struct device *dev, \ struct device_attribute *attr, \ const char *buf, size_t count) \ { \ - struct i2c_client *client = to_i2c_client(dev); \ - struct jc42_data *data = i2c_get_clientdata(client); \ + struct jc42_data *data = dev_get_drvdata(dev); \ int err, ret = count; \ long val; \ - if (kstrtol(buf, 10, &val) < 0) \ + if (kstrtol(buf, 10, &val) < 0) \ return -EINVAL; \ mutex_lock(&data->update_lock); \ data->value = jc42_temp_to_reg(val, data->extended); \ - err = i2c_smbus_write_word_swapped(client, reg, data->value); \ + err = i2c_smbus_write_word_swapped(data->client, reg, data->value); \ if (err < 0) \ ret = err; \ mutex_unlock(&data->update_lock); \ @@ -344,8 +343,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct jc42_data *data = i2c_get_clientdata(client); + struct jc42_data *data = dev_get_drvdata(dev); unsigned long val; int diff, hyst; int err; @@ -368,7 +366,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, mutex_lock(&data->update_lock); data->config = (data->config & ~JC42_CFG_HYST_MASK) | (hyst << JC42_CFG_HYST_SHIFT); - err = i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, + err = i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, data->config); if (err < 0) ret = err; @@ -430,8 +428,7 @@ static umode_t jc42_attribute_mode(struct kobject *kobj, struct attribute *attr, int index) { struct device *dev = container_of(kobj, struct device, kobj); - struct i2c_client *client = to_i2c_client(dev); - struct jc42_data *data = i2c_get_clientdata(client); + struct jc42_data *data = dev_get_drvdata(dev); unsigned int config = data->config; bool readonly; @@ -452,6 +449,7 @@ static const struct attribute_group jc42_group = { .attrs = jc42_attributes, .is_visible = jc42_attribute_mode, }; +__ATTRIBUTE_GROUPS(jc42); /* Return 0 if detection is successful, -ENODEV otherwise */ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) @@ -487,14 +485,16 @@ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct jc42_data *data; - int config, cap, err; struct device *dev = &client->dev; + struct device *hwmon_dev; + struct jc42_data *data; + int config, cap; data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); if (!data) return -ENOMEM; + data->client = client; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -515,29 +515,18 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) } data->config = config; - /* Register sysfs hooks */ - err = sysfs_create_group(&dev->kobj, &jc42_group); - if (err) - return err; - - data->hwmon_dev = hwmon_device_register(dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, + jc42_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); return 0; - -exit_remove: - sysfs_remove_group(&dev->kobj, &jc42_group); - return err; } static int jc42_remove(struct i2c_client *client) { struct jc42_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &jc42_group); /* Restore original configuration except hysteresis */ if ((data->config & ~JC42_CFG_HYST_MASK) != @@ -553,8 +542,8 @@ static int jc42_remove(struct i2c_client *client) static struct jc42_data *jc42_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct jc42_data *data = i2c_get_clientdata(client); + struct jc42_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; struct jc42_data *ret = data; int val; From 9c09bd8d896f8dcce14d0f032cb449a00a3e3141 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 06:43:42 -0700 Subject: [PATCH 32/49] hwmon: (nct6775) fix coccinelle warnings drivers/hwmon/nct6775.c:3866:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index fdbd63282e29..7a1b6a75ed54 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -3862,10 +3862,7 @@ static int nct6775_probe(struct platform_device *pdev) hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name, data, data->groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } #ifdef CONFIG_PM From 31ab1ad70b25f4e19f6442e8f6d68025ba43b942 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 20:54:09 -0700 Subject: [PATCH 33/49] hwmon: (ds1621) fix coccinelle warnings drivers/hwmon/ds1621.c:381:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/ds1621.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 5e398c98db2e..872d76744e30 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -378,10 +378,7 @@ static int ds1621_probe(struct i2c_client *client, hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, client->name, data, ds1621_groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } static const struct i2c_device_id ds1621_id[] = { From e5840c78f3c9e3d950363e4305b65183f2998a73 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 20:54:11 -0700 Subject: [PATCH 34/49] hwmon: (max6642 fix coccinelle warnings drivers/hwmon/max6642.c:299:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/max6642.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c index 3d61f8d719d5..8326fbd60150 100644 --- a/drivers/hwmon/max6642.c +++ b/drivers/hwmon/max6642.c @@ -296,10 +296,7 @@ static int max6642_probe(struct i2c_client *client, hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, client->name, data, max6642_groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } /* From 4109a7160849604395eda57d6f011c8db3866482 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 20:54:12 -0700 Subject: [PATCH 35/49] hwmon: (max6697) fix coccinelle warnings drivers/hwmon/max6697.c:649:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/max6697.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c index 0af910a479ab..7fd3eaf817f4 100644 --- a/drivers/hwmon/max6697.c +++ b/drivers/hwmon/max6697.c @@ -646,10 +646,7 @@ static int max6697_probe(struct i2c_client *client, hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, max6697_groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } static const struct i2c_device_id max6697_id[] = { From 3ea85ba7af58878889f438b1dfbe08e87befcb6d Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 20:54:14 -0700 Subject: [PATCH 36/49] hwmon: (lm95234) fix coccinelle warnings drivers/hwmon/lm95234.c:704:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/lm95234.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c index cf8750745c88..411202bdaf6b 100644 --- a/drivers/hwmon/lm95234.c +++ b/drivers/hwmon/lm95234.c @@ -701,10 +701,7 @@ static int lm95234_probe(struct i2c_client *client, hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, lm95234_groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } /* Driver data (common to all clients) */ From 2a253c4789db7ff46dbdba74d0f89ac08b077fda Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 20:54:16 -0700 Subject: [PATCH 37/49] hwmon: (ltc4261) fix coccinelle warnings drivers/hwmon/ltc4261.c:243:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4261.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 6c50db9530db..0becd69842bb 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -240,10 +240,7 @@ static int ltc4261_probe(struct i2c_client *client, hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, ltc4261_groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } static const struct i2c_device_id ltc4261_id[] = { From 650a2c02b5a0eaf46209bf505f95739366119bc8 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Tue, 17 Sep 2013 20:54:24 -0700 Subject: [PATCH 38/49] hwmon: (jc42) fix coccinelle warnings drivers/hwmon/jc42.c:521:1-3: WARNING: PTR_RET can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci CC: Guenter Roeck Signed-off-by: Fengguang Wu Signed-off-by: Guenter Roeck --- drivers/hwmon/jc42.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index f362cead837e..6013611e4f21 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -518,10 +518,7 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, jc42_groups); - if (IS_ERR(hwmon_dev)) - return PTR_ERR(hwmon_dev); - - return 0; + return PTR_ERR_OR_ZERO(hwmon_dev); } static int jc42_remove(struct i2c_client *client) From 20652ab8ca3854a1967baf8452c8bedceff7b92b Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 20 Sep 2013 09:36:41 +0530 Subject: [PATCH 39/49] hwmon: (adcxx) Remove redundant spi_set_drvdata Driver core sets driver data to NULL upon failure or remove. Signed-off-by: Sachin Kamat Cc: Marc Pignat Acked-by: Marc Pignat Signed-off-by: Guenter Roeck --- drivers/hwmon/adcxx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c index 751b1f0264a4..04c08c2f79b8 100644 --- a/drivers/hwmon/adcxx.c +++ b/drivers/hwmon/adcxx.c @@ -203,7 +203,6 @@ static int adcxx_probe(struct spi_device *spi) for (i--; i >= 0; i--) device_remove_file(&spi->dev, &ad_input[i].dev_attr); - spi_set_drvdata(spi, NULL); mutex_unlock(&adc->lock); return status; } @@ -218,7 +217,6 @@ static int adcxx_remove(struct spi_device *spi) for (i = 0; i < 3 + adc->channels; i++) device_remove_file(&spi->dev, &ad_input[i].dev_attr); - spi_set_drvdata(spi, NULL); mutex_unlock(&adc->lock); return 0; From 2825f033da13bc932aa470533da0f8cfb9a6e40d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 20 Sep 2013 09:36:42 +0530 Subject: [PATCH 40/49] hwmon: (lm70) Remove redundant spi_set_drvdata Driver core sets driver data to NULL upon failure or remove. Signed-off-by: Sachin Kamat Cc: Kaiwan N Billimoria Signed-off-by: Guenter Roeck --- drivers/hwmon/lm70.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 016efa26ba7c..505a59e100b0 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -174,7 +174,6 @@ static int lm70_probe(struct spi_device *spi) out_dev_create_file_failed: device_remove_file(&spi->dev, &dev_attr_temp1_input); out_dev_create_temp_file_failed: - spi_set_drvdata(spi, NULL); return status; } @@ -185,7 +184,6 @@ static int lm70_remove(struct spi_device *spi) hwmon_device_unregister(p_lm70->hwmon_dev); device_remove_file(&spi->dev, &dev_attr_temp1_input); device_remove_file(&spi->dev, &dev_attr_name); - spi_set_drvdata(spi, NULL); return 0; } From c50588ababd85e164a97f114d79af267a6aef42a Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 27 Sep 2013 16:56:00 +0530 Subject: [PATCH 41/49] hwmon: (gpio-fan) Include linux/of.h header 'of_match_ptr' is defined in linux/of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Guenter Roeck --- drivers/hwmon/gpio-fan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index d5148c85ec5f..73181be5b30b 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include From 84fb029faa05e1de229a68829cca5dcf85c79894 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Fri, 27 Sep 2013 14:36:04 +0200 Subject: [PATCH 42/49] hwmon: Correct some typos Signed-off-by: LABBE Corentin Signed-off-by: Guenter Roeck --- drivers/hwmon/abituguru.c | 6 +++--- drivers/hwmon/abituguru3.c | 2 +- drivers/hwmon/asus_atk0110.c | 2 +- drivers/hwmon/max6650.c | 2 +- drivers/hwmon/pmbus/pmbus_core.c | 2 +- drivers/hwmon/w83791d.c | 2 +- drivers/hwmon/w83792d.c | 2 +- drivers/hwmon/w83793.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 2ebd6ce46108..9c8a6bab8228 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -164,7 +164,7 @@ static const u8 abituguru_bank2_max_threshold = 50; static const int abituguru_pwm_settings_multiplier[5] = { 0, 1, 1, 1000, 1000 }; /* * Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a - * special case the minium allowed pwm% setting for this is 30% (77) on + * special case the minimum allowed pwm% setting for this is 30% (77) on * some MB's this special case is handled in the code! */ static const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 }; @@ -517,7 +517,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); /* - * Volt sensor test, enable volt low alarm, set min value ridicously + * Volt sensor test, enable volt low alarm, set min value ridiculously * high, or vica versa if the reading is very high. If its a volt * sensor this should always give us an alarm. */ @@ -564,7 +564,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, /* * Temp sensor test, enable sensor as a temp sensor, set beep value - * ridicously low (but not too low, otherwise uguru ignores it). + * ridiculously low (but not too low, otherwise uguru ignores it). * If its a temp sensor this should always give us an alarm. */ buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE; diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 0cac8c0b001a..4ae74aa8cdc1 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -176,7 +176,7 @@ struct abituguru3_data { /* * The abituguru3 supports up to 48 sensors, and thus has registers - * sets for 48 sensors, for convienence reasons / simplicity of the + * sets for 48 sensors, for convenience reasons / simplicity of the * code we always read and store all registers for all 48 sensors */ diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index b25c64302cbc..1d7ff46812c3 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -119,7 +119,7 @@ struct atk_data { acpi_handle rtmp_handle; acpi_handle rvlt_handle; acpi_handle rfan_handle; - /* new inteface */ + /* new interface */ acpi_handle enumerate_handle; acpi_handle read_handle; acpi_handle write_handle; diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 3c16cbd4c002..0cafc390db4d 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -660,7 +660,7 @@ static int max6650_init_client(struct i2c_client *client) /* * If mode is set to "full off", we change it to "open loop" and * set DAC to 255, which has the same effect. We do this because - * there's no "full off" mode defined in hwmon specifcations. + * there's no "full off" mode defined in hwmon specifications. */ if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) { diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 7f9ce3251063..3cbf66e9d861 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(pmbus_write_byte); /* * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if - * a device specific mapping funcion exists and calls it if necessary. + * a device specific mapping function exists and calls it if necessary. */ static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) { diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index a3feee332e20..bdcf2dce5ec4 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -1043,7 +1043,7 @@ static struct sensor_device_attribute sda_temp_alarm[] = { SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), }; -/* get reatime status of all sensors items: voltage, temp, fan */ +/* get realtime status of all sensors items: voltage, temp, fan */ static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 5febb43cb4c1..df585808adb6 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -579,7 +579,7 @@ static ssize_t store_temp23(struct device *dev, struct device_attribute *attr, return count; } -/* get reatime status of all sensors items: voltage, temp, fan */ +/* get realtime status of all sensors items: voltage, temp, fan */ static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index b0c30a546ff2..b6470ecda8fc 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -808,7 +808,7 @@ show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf) if (nr == TEMP_FAN_MAP) { val = data->temp_fan_map[index]; } else if (nr == TEMP_PWM_ENABLE) { - /* +2 to transfrom into 2 and 3 to conform with sysfs intf */ + /* +2 to transform into 2 and 3 to conform with sysfs intf */ val = ((data->pwm_enable >> index) & 0x01) + 2; } else if (nr == TEMP_CRUISE) { val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f); From c8ccab7ab5c71b4fab274bfd18425503a4dcc288 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 16 Mar 2013 10:25:04 -0700 Subject: [PATCH 43/49] hwmon: (pmbus/lm25066) Add support for LM25063 Signed-off-by: Guenter Roeck --- Documentation/hwmon/lm25066 | 20 +++++++- drivers/hwmon/pmbus/lm25066.c | 91 +++++++++++++++++++++++++++++++---- 2 files changed, 101 insertions(+), 10 deletions(-) diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066 index c1b57d72efc3..b34c3de5c1bc 100644 --- a/Documentation/hwmon/lm25066 +++ b/Documentation/hwmon/lm25066 @@ -8,6 +8,11 @@ Supported chips: Datasheets: http://www.ti.com/lit/gpn/lm25056 http://www.ti.com/lit/gpn/lm25056a + * TI LM25063 + Prefix: 'lm25063' + Addresses scanned: - + Datasheet: + To be announced * National Semiconductor LM25066 Prefix: 'lm25066' Addresses scanned: - @@ -32,7 +37,7 @@ Description ----------- This driver supports hardware montoring for National Semiconductor / TI LM25056, -LM25066, LM5064, and LM5064 Power Management, Monitoring, Control, and +LM25063, LM25066, LM5064, and LM5066 Power Management, Monitoring, Control, and Protection ICs. The driver is a client driver to the core PMBus driver. Please see @@ -64,8 +69,12 @@ in1_input Measured input voltage. in1_average Average measured input voltage. in1_min Minimum input voltage. in1_max Maximum input voltage. +in1_crit Critical high input voltage (LM25063 only). +in1_lcrit Critical low input voltage (LM25063 only). in1_min_alarm Input voltage low alarm. in1_max_alarm Input voltage high alarm. +in1_lcrit_alarm Input voltage critical low alarm (LM25063 only). +in1_crit_alarm Input voltage critical high alarm. (LM25063 only). in2_label "vmon" in2_input Measured voltage on VAUX pin @@ -80,12 +89,16 @@ in3_input Measured output voltage. in3_average Average measured output voltage. in3_min Minimum output voltage. in3_min_alarm Output voltage low alarm. +in3_highest Historical minimum output voltage (LM25063 only). +in3_lowest Historical maximum output voltage (LM25063 only). curr1_label "iin" curr1_input Measured input current. curr1_average Average measured input current. curr1_max Maximum input current. +curr1_crit Critical input current (LM25063 only). curr1_max_alarm Input current high alarm. +curr1_crit_alarm Input current critical high alarm (LM25063 only). power1_label "pin" power1_input Measured input power. @@ -95,6 +108,11 @@ power1_alarm Input power alarm power1_input_highest Historical maximum power. power1_reset_history Write any value to reset maximum power history. +power2_label "pout". LM25063 only. +power2_input Measured output power. +power2_max Maximum output power limit. +power2_crit Critical output power limit. + temp1_input Measured temperature. temp1_max Maximum temperature. temp1_crit Critical high temperature. diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 6a9d6edaacb3..a26b1d1d9514 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -1,5 +1,5 @@ /* - * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066 + * Hardware monitoring driver for LM25056 / LM25063 / LM25066 / LM5064 / LM5066 * * Copyright (c) 2011 Ericsson AB. * Copyright (c) 2013 Guenter Roeck @@ -27,7 +27,7 @@ #include #include "pmbus.h" -enum chips { lm25056, lm25066, lm5064, lm5066 }; +enum chips { lm25056, lm25063, lm25066, lm5064, lm5066 }; #define LM25066_READ_VAUX 0xd0 #define LM25066_MFR_READ_IIN 0xd1 @@ -52,6 +52,11 @@ enum chips { lm25056, lm25066, lm5064, lm5066 }; #define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1) #define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0) +/* LM25063 only */ + +#define LM25063_READ_VOUT_MAX 0xe5 +#define LM25063_READ_VOUT_MIN 0xe6 + struct __coeff { short m, b, R; }; @@ -59,7 +64,7 @@ struct __coeff { #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) #define PSC_POWER_L (PSC_NUM_CLASSES + 1) -static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { +static struct __coeff lm25066_coeff[5][PSC_NUM_CLASSES + 2] = { [lm25056] = { [PSC_VOLTAGE_IN] = { .m = 16296, @@ -116,6 +121,36 @@ static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { .m = 16, }, }, + [lm25063] = { + [PSC_VOLTAGE_IN] = { + .m = 16000, + .R = -2, + }, + [PSC_VOLTAGE_OUT] = { + .m = 16000, + .R = -2, + }, + [PSC_CURRENT_IN] = { + .m = 10000, + .R = -2, + }, + [PSC_CURRENT_IN_L] = { + .m = 10000, + .R = -2, + }, + [PSC_POWER] = { + .m = 5000, + .R = -3, + }, + [PSC_POWER_L] = { + .m = 5000, + .R = -3, + }, + [PSC_TEMPERATURE] = { + .m = 15596, + .R = -3, + }, + }, [lm5064] = { [PSC_VOLTAGE_IN] = { .m = 4611, @@ -178,6 +213,7 @@ static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = { struct lm25066_data { int id; + u16 rlimit; /* Maximum register value */ struct pmbus_driver_info info; }; @@ -200,6 +236,10 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) /* VIN: 6.14 mV VAUX: 293 uV LSB */ ret = DIV_ROUND_CLOSEST(ret * 293, 6140); break; + case lm25063: + /* VIN: 6.25 mV VAUX: 200.0 uV LSB */ + ret = DIV_ROUND_CLOSEST(ret * 20, 625); + break; case lm25066: /* VIN: 4.54 mV VAUX: 283.2 uV LSB */ ret = DIV_ROUND_CLOSEST(ret * 2832, 45400); @@ -253,6 +293,24 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) return ret; } +static int lm25063_read_word_data(struct i2c_client *client, int page, int reg) +{ + int ret; + + switch (reg) { + case PMBUS_VIRT_READ_VOUT_MAX: + ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MAX); + break; + case PMBUS_VIRT_READ_VOUT_MIN: + ret = pmbus_read_word_data(client, 0, LM25063_READ_VOUT_MIN); + break; + default: + ret = lm25066_read_word_data(client, page, reg); + break; + } + return ret; +} + static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) { int ret; @@ -308,27 +366,34 @@ static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg) static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, u16 word) { + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + const struct lm25066_data *data = to_lm25066_data(info); int ret; switch (reg) { + case PMBUS_POUT_OP_FAULT_LIMIT: + case PMBUS_POUT_OP_WARN_LIMIT: case PMBUS_VOUT_UV_WARN_LIMIT: case PMBUS_OT_FAULT_LIMIT: case PMBUS_OT_WARN_LIMIT: + case PMBUS_IIN_OC_FAULT_LIMIT: case PMBUS_VIN_UV_WARN_LIMIT: + case PMBUS_VIN_UV_FAULT_LIMIT: + case PMBUS_VIN_OV_FAULT_LIMIT: case PMBUS_VIN_OV_WARN_LIMIT: - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); + word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); ret = pmbus_write_word_data(client, 0, reg, word); pmbus_clear_cache(client); break; case PMBUS_IIN_OC_WARN_LIMIT: - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); + word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); ret = pmbus_write_word_data(client, 0, LM25066_MFR_IIN_OC_WARN_LIMIT, word); pmbus_clear_cache(client); break; case PMBUS_PIN_OP_WARN_LIMIT: - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); + word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); ret = pmbus_write_word_data(client, 0, LM25066_MFR_PIN_OP_WARN_LIMIT, word); @@ -337,7 +402,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, case PMBUS_VIRT_VMON_UV_WARN_LIMIT: /* Adjust from VIN coefficients (for LM25056) */ word = DIV_ROUND_CLOSEST((int)word * 6140, 293); - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); + word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); ret = pmbus_write_word_data(client, 0, LM25056_VAUX_UV_WARN_LIMIT, word); pmbus_clear_cache(client); @@ -345,7 +410,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, case PMBUS_VIRT_VMON_OV_WARN_LIMIT: /* Adjust from VIN coefficients (for LM25056) */ word = DIV_ROUND_CLOSEST((int)word * 6140, 293); - word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff); + word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit); ret = pmbus_write_word_data(client, 0, LM25056_VAUX_OV_WARN_LIMIT, word); pmbus_clear_cache(client); @@ -399,9 +464,16 @@ static int lm25066_probe(struct i2c_client *client, info->func[0] |= PMBUS_HAVE_STATUS_VMON; info->read_word_data = lm25056_read_word_data; info->read_byte_data = lm25056_read_byte_data; + data->rlimit = 0x0fff; + } else if (data->id == lm25063) { + info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_POUT; + info->read_word_data = lm25063_read_word_data; + data->rlimit = 0xffff; } else { info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; info->read_word_data = lm25066_read_word_data; + data->rlimit = 0x0fff; } info->write_word_data = lm25066_write_word_data; @@ -432,6 +504,7 @@ static int lm25066_probe(struct i2c_client *client, static const struct i2c_device_id lm25066_id[] = { {"lm25056", lm25056}, + {"lm25063", lm25063}, {"lm25066", lm25066}, {"lm5064", lm5064}, {"lm5066", lm5066}, @@ -453,5 +526,5 @@ static struct i2c_driver lm25066_driver = { module_i2c_driver(lm25066_driver); MODULE_AUTHOR("Guenter Roeck"); -MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066"); +MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips"); MODULE_LICENSE("GPL"); From c24c407e963e73d3ad18b9bc0af32cf23f37a7b0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 23 Sep 2013 10:56:48 -0700 Subject: [PATCH 44/49] hwmon: (pmbus/ltc2978): Add support for LTC2977 LTC2977 is a pin compatible replacement for LTC2978. Signed-off-by: Guenter Roeck --- Documentation/hwmon/ltc2978 | 41 +++++++++++++++++++++++------------ drivers/hwmon/pmbus/ltc2978.c | 12 +++++++--- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Documentation/hwmon/ltc2978 b/Documentation/hwmon/ltc2978 index dc0d08c61305..6934936de2c7 100644 --- a/Documentation/hwmon/ltc2978 +++ b/Documentation/hwmon/ltc2978 @@ -6,6 +6,10 @@ Supported chips: Prefix: 'ltc2974' Addresses scanned: - Datasheet: http://www.linear.com/product/ltc2974 + * Linear Technology LTC2977 + Prefix: 'ltc2977' + Addresses scanned: - + Datasheet: http://www.linear.com/product/ltc2977 * Linear Technology LTC2978 Prefix: 'ltc2978' Addresses scanned: - @@ -26,8 +30,9 @@ Description ----------- LTC2974 is a quad digital power supply manager. LTC2978 is an octal power supply -monitor. LTC3880 is a dual output poly-phase step-down DC/DC controller. LTC3883 -is a single phase step-down DC/DC controller. +monitor. LTC2977 is a pin compatible replacement for LTC2978. LTC3880 is a dual +output poly-phase step-down DC/DC controller. LTC3883 is a single phase +step-down DC/DC controller. Usage Notes @@ -49,21 +54,25 @@ Sysfs attributes in1_label "vin" in1_input Measured input voltage. in1_min Minimum input voltage. -in1_max Maximum input voltage. LTC2974 and LTC2978 only. -in1_lcrit Critical minimum input voltage. LTC2974 and LTC2978 - only. +in1_max Maximum input voltage. + LTC2974, LTC2977, and LTC2978 only. +in1_lcrit Critical minimum input voltage. + LTC2974, LTC2977, and LTC2978 only. in1_crit Critical maximum input voltage. in1_min_alarm Input voltage low alarm. -in1_max_alarm Input voltage high alarm. LTC2974 and LTC2978 only. -in1_lcrit_alarm Input voltage critical low alarm. LTC2974 and LTC2978 - only. +in1_max_alarm Input voltage high alarm. + LTC2974, LTC2977, and LTC2978 only. +in1_lcrit_alarm Input voltage critical low alarm. + LTC2974, LTC2977, and LTC2978 only. in1_crit_alarm Input voltage critical high alarm. -in1_lowest Lowest input voltage. LTC2974 and LTC2978 only. +in1_lowest Lowest input voltage. + LTC2974, LTC2977, and LTC2978 only. in1_highest Highest input voltage. in1_reset_history Reset input voltage history. in[N]_label "vout[1-8]". LTC2974: N=2-5 + LTC2977: N=2-9 LTC2978: N=2-9 LTC3880: N=2-3 LTC3883: N=2 @@ -83,21 +92,23 @@ in[N]_reset_history Reset output voltage history. temp[N]_input Measured temperature. On LTC2974, temp[1-4] report external temperatures, and temp5 reports the chip temperature. - On LTC2978, only one temperature measurement is - supported and reports the chip temperature. + On LTC2977 and LTC2978, only one temperature measurement + is supported and reports the chip temperature. On LTC3880, temp1 and temp2 report external temperatures, and temp3 reports the chip temperature. On LTC3883, temp1 reports an external temperature, and temp2 reports the chip temperature. -temp[N]_min Mimimum temperature. LTC2974 and LTC2978 only. +temp[N]_min Mimimum temperature. LTC2974, LCT2977, and LTC2978 only. temp[N]_max Maximum temperature. temp[N]_lcrit Critical low temperature. temp[N]_crit Critical high temperature. -temp[N]_min_alarm Temperature low alarm. LTC2974 and LTC2978 only. +temp[N]_min_alarm Temperature low alarm. + LTC2974, LTC2977, and LTC2978 only. temp[N]_max_alarm Temperature high alarm. temp[N]_lcrit_alarm Temperature critical low alarm. temp[N]_crit_alarm Temperature critical high alarm. -temp[N]_lowest Lowest measured temperature. LTC2974 and LTC2978 only. +temp[N]_lowest Lowest measured temperature. + LTC2974, LTC2977, and LTC2978 only. Not supported for chip temperature sensor on LTC2974. temp[N]_highest Highest measured temperature. Not supported for chip temperature sensor on LTC2974. @@ -109,6 +120,7 @@ power1_input Measured input power. power[N]_label "pout[1-4]". LTC2974: N=1-4 + LTC2977: Not supported LTC2978: Not supported LTC3880: N=1-2 LTC3883: N=2 @@ -123,6 +135,7 @@ curr1_reset_history Reset input current history. LTC3883 only. curr[N]_label "iout[1-4]". LTC2974: N=1-4 + LTC2977: not supported LTC2978: not supported LTC3880: N=2-3 LTC3883: N=2 diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index 586a89ef9e0f..e05ff565ef61 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -1,5 +1,6 @@ /* - * Hardware monitoring driver for LTC2974, LTC2978, LTC3880, and LTC3883 + * Hardware monitoring driver for LTC2974, LTC2977, LTC2978, LTC3880, + * and LTC3883 * * Copyright (c) 2011 Ericsson AB. * Copyright (c) 2013 Guenter Roeck @@ -27,7 +28,7 @@ #include #include "pmbus.h" -enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; +enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883 }; /* Common for all chips */ #define LTC2978_MFR_VOUT_PEAK 0xdd @@ -35,7 +36,7 @@ enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf #define LTC2978_MFR_SPECIAL_ID 0xe7 -/* LTC2974 and LTC2978 */ +/* LTC2974, LCT2977, and LTC2978 */ #define LTC2978_MFR_VOUT_MIN 0xfb #define LTC2978_MFR_VIN_MIN 0xfc #define LTC2978_MFR_TEMPERATURE_MIN 0xfd @@ -53,6 +54,7 @@ enum chips { ltc2974, ltc2978, ltc3880, ltc3883 }; #define LTC3883_MFR_IIN_PEAK 0xe1 #define LTC2974_ID 0x0212 +#define LTC2977_ID 0x0130 #define LTC2978_ID_REV1 0x0121 #define LTC2978_ID_REV2 0x0122 #define LTC3880_ID 0x4000 @@ -363,6 +365,7 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, static const struct i2c_device_id ltc2978_id[] = { {"ltc2974", ltc2974}, + {"ltc2977", ltc2977}, {"ltc2978", ltc2978}, {"ltc3880", ltc3880}, {"ltc3883", ltc3883}, @@ -392,6 +395,8 @@ static int ltc2978_probe(struct i2c_client *client, if (chip_id == LTC2974_ID) { data->id = ltc2974; + } else if (chip_id == LTC2977_ID) { + data->id = ltc2977; } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { data->id = ltc2978; } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { @@ -438,6 +443,7 @@ static int ltc2978_probe(struct i2c_client *client, | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; } break; + case ltc2977: case ltc2978: info->read_word_data = ltc2978_read_word_data; info->pages = LTC2978_NUM_PAGES; From 3f08d7f49f8365d5c9050522ee733951a503e955 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 23 Sep 2013 11:23:37 -0700 Subject: [PATCH 45/49] hwmon: (pmbus/ltc2978): Add support for LTC2978A Detect LTC2978A chip ID. Treat it as LC2978. Signed-off-by: Guenter Roeck --- Documentation/hwmon/ltc2978 | 3 ++- drivers/hwmon/pmbus/ltc2978.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/hwmon/ltc2978 b/Documentation/hwmon/ltc2978 index 6934936de2c7..a0546fc42273 100644 --- a/Documentation/hwmon/ltc2978 +++ b/Documentation/hwmon/ltc2978 @@ -10,10 +10,11 @@ Supported chips: Prefix: 'ltc2977' Addresses scanned: - Datasheet: http://www.linear.com/product/ltc2977 - * Linear Technology LTC2978 + * Linear Technology LTC2978, LTC2978A Prefix: 'ltc2978' Addresses scanned: - Datasheet: http://www.linear.com/product/ltc2978 + http://www.linear.com/product/ltc2978a * Linear Technology LTC3880 Prefix: 'ltc3880' Addresses scanned: - diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index e05ff565ef61..de3c152a1d9a 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -57,6 +57,7 @@ enum chips { ltc2974, ltc2977, ltc2978, ltc3880, ltc3883 }; #define LTC2977_ID 0x0130 #define LTC2978_ID_REV1 0x0121 #define LTC2978_ID_REV2 0x0122 +#define LTC2978A_ID 0x0124 #define LTC3880_ID 0x4000 #define LTC3880_ID_MASK 0xff00 #define LTC3883_ID 0x4300 @@ -397,7 +398,8 @@ static int ltc2978_probe(struct i2c_client *client, data->id = ltc2974; } else if (chip_id == LTC2977_ID) { data->id = ltc2977; - } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { + } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2 || + chip_id == LTC2978A_ID) { data->id = ltc2978; } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { data->id = ltc3880; From 454aee17fd441b8ee8e956196dd3ddc9c8ee96d6 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 29 Sep 2013 11:49:53 -0700 Subject: [PATCH 46/49] hwmon: (emc1403) Convert to use devm_hwmon_device_register_with_groups Simplify code and reduce its size. Signed-off-by: Guenter Roeck --- drivers/hwmon/emc1403.c | 73 +++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 142e1cb8dea7..dc2a917a87bb 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c @@ -40,7 +40,7 @@ #define THERMAL_REVISION_REG 0xff struct thermal_data { - struct device *hwmon_dev; + struct i2c_client *client; struct mutex mutex; /* * Cache the hyst value so we don't keep re-reading it. In theory @@ -53,10 +53,11 @@ struct thermal_data { static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); - int retval = i2c_smbus_read_byte_data(client, sda->index); + struct thermal_data *data = dev_get_drvdata(dev); + int retval; + retval = i2c_smbus_read_byte_data(data->client, sda->index); if (retval < 0) return retval; return sprintf(buf, "%d000\n", retval); @@ -65,27 +66,27 @@ static ssize_t show_temp(struct device *dev, static ssize_t show_bit(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); - int retval = i2c_smbus_read_byte_data(client, sda->nr); + struct thermal_data *data = dev_get_drvdata(dev); + int retval; + retval = i2c_smbus_read_byte_data(data->client, sda->nr); if (retval < 0) return retval; - retval &= sda->index; - return sprintf(buf, "%d\n", retval ? 1 : 0); + return sprintf(buf, "%d\n", !!(retval & sda->index)); } static ssize_t store_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); - struct i2c_client *client = to_i2c_client(dev); + struct thermal_data *data = dev_get_drvdata(dev); unsigned long val; int retval; if (kstrtoul(buf, 10, &val)) return -EINVAL; - retval = i2c_smbus_write_byte_data(client, sda->index, + retval = i2c_smbus_write_byte_data(data->client, sda->index, DIV_ROUND_CLOSEST(val, 1000)); if (retval < 0) return retval; @@ -95,9 +96,9 @@ static ssize_t store_temp(struct device *dev, static ssize_t store_bit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct thermal_data *data = i2c_get_clientdata(client); struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); + struct thermal_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int retval; @@ -124,9 +125,9 @@ static ssize_t store_bit(struct device *dev, static ssize_t show_hyst(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct thermal_data *data = i2c_get_clientdata(client); struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct thermal_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int retval; int hyst; @@ -147,9 +148,9 @@ static ssize_t show_hyst(struct device *dev, static ssize_t store_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct thermal_data *data = i2c_get_clientdata(client); struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct thermal_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int retval; int hyst; unsigned long val; @@ -235,7 +236,7 @@ static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR_2(power_state, S_IRUGO | S_IWUSR, show_bit, store_bit, 0x03, 0x40); -static struct attribute *mid_att_thermal[] = { +static struct attribute *emc1403_attrs[] = { &sensor_dev_attr_temp1_min.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, @@ -263,10 +264,7 @@ static struct attribute *mid_att_thermal[] = { &sensor_dev_attr_power_state.dev_attr.attr, NULL }; - -static const struct attribute_group m_thermal_gr = { - .attrs = mid_att_thermal -}; +ATTRIBUTE_GROUPS(emc1403); static int emc1403_detect(struct i2c_client *client, struct i2c_board_info *info) @@ -304,44 +302,26 @@ static int emc1403_detect(struct i2c_client *client, static int emc1403_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int res; struct thermal_data *data; + struct device *hwmon_dev; data = devm_kzalloc(&client->dev, sizeof(struct thermal_data), GFP_KERNEL); if (data == NULL) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; mutex_init(&data->mutex); data->hyst_valid = jiffies - 1; /* Expired */ - res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); - if (res) { - dev_warn(&client->dev, "create group failed\n"); - return res; - } - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - res = PTR_ERR(data->hwmon_dev); - dev_warn(&client->dev, "register hwmon dev failed\n"); - goto thermal_error; - } + hwmon_dev = hwmon_device_register_with_groups(&client->dev, + client->name, data, + emc1403_groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + dev_info(&client->dev, "EMC1403 Thermal chip found\n"); return 0; - -thermal_error: - sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); - return res; -} - -static int emc1403_remove(struct i2c_client *client) -{ - struct thermal_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); - return 0; } static const unsigned short emc1403_address_list[] = { @@ -362,7 +342,6 @@ static struct i2c_driver sensor_emc1403 = { }, .detect = emc1403_detect, .probe = emc1403_probe, - .remove = emc1403_remove, .id_table = emc1403_idtable, .address_list = emc1403_address_list, }; From 0011ddfe6a03279fae60d237f2f4d0d7f7678928 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 29 Sep 2013 13:20:53 -0700 Subject: [PATCH 47/49] hwmon: (emc1403) Add support for EMC1404 and EMC1424 EMC1404 and EMC1424 are similar to EMC1403 and EMC1423, but support an additional external temperature sensor. Signed-off-by: Guenter Roeck --- drivers/hwmon/emc1403.c | 59 +++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index dc2a917a87bb..90ec1173b8a1 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c @@ -21,7 +21,6 @@ * * TODO * - cache alarm and critical limit registers - * - add emc1404 support */ #include @@ -41,6 +40,7 @@ struct thermal_data { struct i2c_client *client; + const struct attribute_group *groups[3]; struct mutex mutex; /* * Cache the hyst value so we don't keep re-reading it. In theory @@ -233,6 +233,22 @@ static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR, show_hyst, store_hyst, 0x1A); +static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x2D); +static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x2C); +static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x30); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 0x2A); +static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, + show_bit, NULL, 0x36, 0x08); +static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, + show_bit, NULL, 0x35, 0x08); +static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, + show_bit, NULL, 0x37, 0x08); +static SENSOR_DEVICE_ATTR(temp4_crit_hyst, S_IRUGO | S_IWUSR, + show_hyst, store_hyst, 0x30); + static SENSOR_DEVICE_ATTR_2(power_state, S_IRUGO | S_IWUSR, show_bit, store_bit, 0x03, 0x40); @@ -264,7 +280,26 @@ static struct attribute *emc1403_attrs[] = { &sensor_dev_attr_power_state.dev_attr.attr, NULL }; -ATTRIBUTE_GROUPS(emc1403); + +static const struct attribute_group emc1403_group = { + .attrs = emc1403_attrs, +}; + +static struct attribute *emc1404_attrs[] = { + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_hyst.dev_attr.attr, + NULL +}; + +static const struct attribute_group emc1404_group = { + .attrs = emc1404_attrs, +}; static int emc1403_detect(struct i2c_client *client, struct i2c_board_info *info) @@ -284,10 +319,12 @@ static int emc1403_detect(struct i2c_client *client, case 0x23: strlcpy(info->type, "emc1423", I2C_NAME_SIZE); break; - /* - * Note: 0x25 is the 1404 which is very similar and this - * driver could be extended - */ + case 0x25: + strlcpy(info->type, "emc1404", I2C_NAME_SIZE); + break; + case 0x27: + strlcpy(info->type, "emc1424", I2C_NAME_SIZE); + break; default: return -ENODEV; } @@ -314,13 +351,17 @@ static int emc1403_probe(struct i2c_client *client, mutex_init(&data->mutex); data->hyst_valid = jiffies - 1; /* Expired */ + data->groups[0] = &emc1403_group; + if (id->driver_data) + data->groups[1] = &emc1404_group; + hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, - emc1403_groups); + data->groups); if (IS_ERR(hwmon_dev)) return PTR_ERR(hwmon_dev); - dev_info(&client->dev, "EMC1403 Thermal chip found\n"); + dev_info(&client->dev, "%s Thermal chip found\n", id->name); return 0; } @@ -330,7 +371,9 @@ static const unsigned short emc1403_address_list[] = { static const struct i2c_device_id emc1403_idtable[] = { { "emc1403", 0 }, + { "emc1404", 1 }, { "emc1423", 0 }, + { "emc1424", 1 }, { } }; MODULE_DEVICE_TABLE(i2c, emc1403_idtable); From 1e687e806b8ea1b1428e3e664afd4081e435f6d0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 19 Oct 2013 11:55:15 +0300 Subject: [PATCH 48/49] hwmon: (nct6775) Remove an unused variable We don't actually use "j" for anything. Signed-off-by: Dan Carpenter Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 7a1b6a75ed54..d17325db0ea3 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -939,7 +939,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg, struct sensor_device_attribute_2 *a2; struct attribute **attrs; struct sensor_device_template **t; - int i, j, count; + int i, count; if (repeat <= 0) return ERR_PTR(-EINVAL); @@ -970,7 +970,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg, for (i = 0; i < repeat; i++) { t = tg->templates; - for (j = 0; *t != NULL; j++) { + while (*t != NULL) { snprintf(su->name, sizeof(su->name), (*t)->dev_attr.attr.name, tg->base + i); if ((*t)->s2) { From 26336c8a36c0a6a28b9ecf6f1bb8c8f5605d6a21 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 19 Oct 2013 12:12:22 +0300 Subject: [PATCH 49/49] hwmon: (w83793) Clean up a signedness issue We cap the upper bound of "mtimeout" but since it's signed we should check for negative values as well. The mistake is harmless. But I have changed it to unsigned as a cleanup. Signed-off-by: Dan Carpenter Signed-off-by: Guenter Roeck --- drivers/hwmon/w83793.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index b6470ecda8fc..9d63d71214ca 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1199,7 +1199,8 @@ static void w83793_init_client(struct i2c_client *client) static int watchdog_set_timeout(struct w83793_data *data, int timeout) { - int ret, mtimeout; + unsigned int mtimeout; + int ret; mtimeout = DIV_ROUND_UP(timeout, 60);