From 58c3667d83376c2f3016465f59f22c19c8f846e1 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 21 Jun 2012 06:32:40 -0700 Subject: [PATCH 01/72] hwmon: (w83627ehf) Add missing break statement A case statement in nct6775_write_fan_div() is missing a break. Fix it. This patch addresses Coverity #141439: Missing break in switch. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83627ehf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 54922ed12978..1821b7423d5b 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -599,6 +599,7 @@ static void nct6775_write_fan_div(struct w83627ehf_data *data, int nr) reg = (w83627ehf_read_value(data, NCT6775_REG_FANDIV1) & 0x7) | ((data->fan_div[1] << 4) & 0x70); w83627ehf_write_value(data, NCT6775_REG_FANDIV1, reg); + break; case 2: reg = (w83627ehf_read_value(data, NCT6775_REG_FANDIV2) & 0x70) | (data->fan_div[2] & 0x7); From 62867d491a27affee36194d4856564f2f4e12b3c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 21 Jun 2012 06:26:12 -0700 Subject: [PATCH 02/72] hwmon: (fam15h_power) Fix unintentional integer overflow Expression with two unsigned integer variables is calculated as unsigned integer before it is converted to u64. This may result in an integer overflow. Fix by typecasting the left operand to u64 before performing the left shift. This patch addresses Coverity #402320: Unintentional integer overflow. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare Acked-by: Andreas Herrmann --- drivers/hwmon/fam15h_power.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 6b13f1a4dc27..2764b78a784b 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -67,7 +67,8 @@ static ssize_t show_power(struct device *dev, REG_TDP_LIMIT3, &val); tdp_limit = val >> 16; - curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range; + curr_pwr_watts = ((u64)(tdp_limit + + data->base_tdp)) << running_avg_range; curr_pwr_watts -= running_avg_capture; curr_pwr_watts *= data->tdp_to_watts; From e41f6432d1ca757d8e4a2dccfd772e421d640e98 Mon Sep 17 00:00:00 2001 From: Ashish Jangam Date: Sat, 17 Mar 2012 15:34:41 +0530 Subject: [PATCH 03/72] hwmon: Driver for DA9052/53 PMIC The DA9052 PMIC provides an Analogue to Digital Converter with 10 bits resolution and 10 channels. This patch monitors the DA9052 PMIC's ADC channels mostly for battery parameters like battery temperature, junction temperature, battery current etc. This patch is functionally tested on Samsung SMDKV6410 Signed-off-by: David Dajun Chen Signed-off-by: Ashish Jangam [Guenter Roeck: __init --> __devinit for probe function] Signed-off-by: Guenter Roeck --- Documentation/hwmon/da9052 | 61 +++++++ drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/da9052-hwmon.c | 344 +++++++++++++++++++++++++++++++++++ 4 files changed, 416 insertions(+) create mode 100644 Documentation/hwmon/da9052 create mode 100644 drivers/hwmon/da9052-hwmon.c diff --git a/Documentation/hwmon/da9052 b/Documentation/hwmon/da9052 new file mode 100644 index 000000000000..ef898553638e --- /dev/null +++ b/Documentation/hwmon/da9052 @@ -0,0 +1,61 @@ +Supported chips: + * Dialog Semiconductors DA9052-BC and DA9053-AA/Bx PMICs + Prefix: 'da9052' + Datasheet: Datasheet is not publicly available. + +Authors: David Dajun Chen + +Description +----------- + +The DA9052/53 provides an Analogue to Digital Converter (ADC) with 10 bits +resolution and track and hold circuitry combined with an analogue input +multiplexer. The analogue input multiplexer will allow conversion of up to 10 +different inputs. The track and hold circuit ensures stable input voltages at +the input of the ADC during the conversion. + +The ADC is used to measure the following inputs: +Channel 0: VDDOUT - measurement of the system voltage +Channel 1: ICH - internal battery charger current measurement +Channel 2: TBAT - output from the battery NTC +Channel 3: VBAT - measurement of the battery voltage +Channel 4: ADC_IN4 - high impedance input (0 - 2.5V) +Channel 5: ADC_IN5 - high impedance input (0 - 2.5V) +Channel 6: ADC_IN6 - high impedance input (0 - 2.5V) +Channel 7: XY - TSI interface to measure the X and Y voltage of the touch + screen resistive potentiometers +Channel 8: Internal Tjunc. - sense (internal temp. sensor) +Channel 9: VBBAT - measurement of the backup battery voltage + +By using sysfs attributes we can measure the system voltage VDDOUT, the battery +charging current ICH, battery temperature TBAT, battery junction temperature +TJUNC, battery voltage VBAT and the back up battery voltage VBBAT. + +Voltage Monitoring +------------------ + +Voltages are sampled by a 10 bit ADC. + +The battery voltage is calculated as: + Milli volt = ((ADC value * 1000) / 512) + 2500 + +The backup battery voltage is calculated as: + Milli volt = (ADC value * 2500) / 512; + +The voltages on ADC channels 4, 5 and 6 are calculated as: + Milli volt = (ADC value * 2500) / 1023 + +Temperature Monitoring +---------------------- + +Temperatures are sampled by a 10 bit ADC. Junction and battery temperatures +are monitored by the ADC channels. + +The junction temperature is calculated: + Degrees celsius = 1.708 * (TJUNC_RES - T_OFFSET) - 108.8 +The junction temperature attribute is supported by the driver. + +The battery temperature is calculated: + Degree Celcius = 1 / (t1 + 1/298)- 273 +where t1 = (1/B)* ln(( ADCval * 2.5)/(R25*ITBAT*255)) +Default values of R25, B, ITBAT are 10e3, 3380 and 50e-6 respectively. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6f1d167cb1ea..40393535563d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -314,6 +314,16 @@ config SENSORS_DS1621 This driver can also be built as a module. If so, the module will be called ds1621. +config SENSORS_DA9052_ADC + tristate "Dialog DA9052/DA9053 ADC" + depends on PMIC_DA9052 + help + Say y here to support the ADC found on Dialog Semiconductor + DA9052-BC and DA9053-AA/Bx PMICs. + + This driver can also be built as module. If so, the module + will be called da9052-hwmon. + config SENSORS_EXYNOS4_TMU tristate "Temperature sensor on Samsung EXYNOS4" depends on ARCH_EXYNOS4 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index e1eeac13b851..2f4c00116f1e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o +obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o obj-$(CONFIG_SENSORS_DS620) += ds620.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c new file mode 100644 index 000000000000..fc65f2d3ec91 --- /dev/null +++ b/drivers/hwmon/da9052-hwmon.c @@ -0,0 +1,344 @@ +/* + * HWMON Driver for Dialog DA9052 + * + * Copyright(c) 2012 Dialog Semiconductor Ltd. + * + * Author: David Dajun Chen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct da9052_hwmon { + struct da9052 *da9052; + struct device *class_device; + struct mutex hwmon_lock; +}; + +static const char * const input_names[] = { + [DA9052_ADC_VDDOUT] = "VDDOUT", + [DA9052_ADC_ICH] = "CHARGING CURRENT", + [DA9052_ADC_TBAT] = "BATTERY TEMP", + [DA9052_ADC_VBAT] = "BATTERY VOLTAGE", + [DA9052_ADC_IN4] = "ADC IN4", + [DA9052_ADC_IN5] = "ADC IN5", + [DA9052_ADC_IN6] = "ADC IN6", + [DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP", + [DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE", +}; + +/* Conversion function for VDDOUT and VBAT */ +static inline int volt_reg_to_mV(int value) +{ + return DIV_ROUND_CLOSEST(value * 1000, 512) + 2500; +} + +/* Conversion function for ADC channels 4, 5 and 6 */ +static inline int input_reg_to_mV(int value) +{ + return DIV_ROUND_CLOSEST(value * 2500, 1023); +} + +/* Conversion function for VBBAT */ +static inline int vbbat_reg_to_mV(int value) +{ + return DIV_ROUND_CLOSEST(value * 2500, 512); +} + +static int da9052_enable_vddout_channel(struct da9052 *da9052) +{ + int ret; + + ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); + if (ret < 0) + return ret; + + ret |= DA9052_ADCCONT_AUTOVDDEN; + + return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); +} + +static int da9052_disable_vddout_channel(struct da9052 *da9052) +{ + int ret; + + ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); + if (ret < 0) + return ret; + + ret &= ~DA9052_ADCCONT_AUTOVDDEN; + + return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); +} + +static ssize_t da9052_read_vddout(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + int ret, vdd; + + mutex_lock(&hwmon->hwmon_lock); + + ret = da9052_enable_vddout_channel(hwmon->da9052); + if (ret < 0) + goto hwmon_err; + + vdd = da9052_reg_read(hwmon->da9052, DA9052_VDD_RES_REG); + if (vdd < 0) { + ret = vdd; + goto hwmon_err_release; + } + + ret = da9052_disable_vddout_channel(hwmon->da9052); + if (ret < 0) + goto hwmon_err; + + mutex_unlock(&hwmon->hwmon_lock); + return sprintf(buf, "%d\n", volt_reg_to_mV(vdd)); + +hwmon_err_release: + da9052_disable_vddout_channel(hwmon->da9052); +hwmon_err: + mutex_unlock(&hwmon->hwmon_lock); + return ret; +} + +static ssize_t da9052_read_ich(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + int ret; + + ret = da9052_reg_read(hwmon->da9052, DA9052_ICHG_AV_REG); + if (ret < 0) + return ret; + + /* Equivalent to 3.9mA/bit in register ICHG_AV */ + return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(ret * 39, 10)); +} + +static ssize_t da9052_read_tbat(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", da9052_adc_read_temp(hwmon->da9052)); +} + +static ssize_t da9052_read_vbat(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + int ret; + + ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBAT); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", volt_reg_to_mV(ret)); +} + +static ssize_t da9052_read_misc_channel(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + int channel = to_sensor_dev_attr(devattr)->index; + int ret; + + ret = da9052_adc_manual_read(hwmon->da9052, channel); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", input_reg_to_mV(ret)); +} + +static ssize_t da9052_read_tjunc(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + int tjunc; + int toffset; + + tjunc = da9052_reg_read(hwmon->da9052, DA9052_TJUNC_RES_REG); + if (tjunc < 0) + return tjunc; + + toffset = da9052_reg_read(hwmon->da9052, DA9052_T_OFFSET_REG); + if (toffset < 0) + return toffset; + + /* + * Degrees celsius = 1.708 * (TJUNC_RES - T_OFFSET) - 108.8 + * T_OFFSET is a trim value used to improve accuracy of the result + */ + return sprintf(buf, "%d\n", 1708 * (tjunc - toffset) - 108800); +} + +static ssize_t da9052_read_vbbat(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); + int ret; + + ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBBAT); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", vbbat_reg_to_mV(ret)); +} + +static ssize_t da9052_hwmon_show_name(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf, "da9052-hwmon\n"); +} + +static ssize_t show_label(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return sprintf(buf, "%s\n", + input_names[to_sensor_dev_attr(devattr)->index]); +} + +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9052_read_vddout, NULL, + DA9052_ADC_VDDOUT); +static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, + DA9052_ADC_VDDOUT); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9052_read_vbat, NULL, + DA9052_ADC_VBAT); +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, + DA9052_ADC_VBAT); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, da9052_read_misc_channel, NULL, + DA9052_ADC_IN4); +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, + DA9052_ADC_IN4); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, da9052_read_misc_channel, NULL, + DA9052_ADC_IN5); +static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, + DA9052_ADC_IN5); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, da9052_read_misc_channel, NULL, + DA9052_ADC_IN6); +static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, + DA9052_ADC_IN6); +static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, da9052_read_vbbat, NULL, + DA9052_ADC_VBBAT); +static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, + DA9052_ADC_VBBAT); + +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, da9052_read_ich, NULL, + DA9052_ADC_ICH); +static SENSOR_DEVICE_ATTR(curr1_label, S_IRUGO, show_label, NULL, + DA9052_ADC_ICH); + +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, da9052_read_tbat, NULL, + DA9052_ADC_TBAT); +static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, + DA9052_ADC_TBAT); +static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, da9052_read_tjunc, NULL, + DA9052_ADC_TJUNC); +static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_label, NULL, + DA9052_ADC_TJUNC); + +static DEVICE_ATTR(name, S_IRUGO, da9052_hwmon_show_name, NULL); + +static struct attribute *da9052_attr[] = { + &dev_attr_name.attr, + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_label.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_label.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_label.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_label.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in6_label.dev_attr.attr, + &sensor_dev_attr_in9_input.dev_attr.attr, + &sensor_dev_attr_in9_label.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr1_label.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_label.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp8_label.dev_attr.attr, + NULL +}; + +static const struct attribute_group da9052_attr_group = {.attrs = da9052_attr}; + +static int __devinit da9052_hwmon_probe(struct platform_device *pdev) +{ + struct da9052_hwmon *hwmon; + int ret; + + hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9052_hwmon), + GFP_KERNEL); + if (!hwmon) + return -ENOMEM; + + mutex_init(&hwmon->hwmon_lock); + hwmon->da9052 = dev_get_drvdata(pdev->dev.parent); + + platform_set_drvdata(pdev, hwmon); + + ret = sysfs_create_group(&pdev->dev.kobj, &da9052_attr_group); + if (ret) + goto err_mem; + + hwmon->class_device = hwmon_device_register(&pdev->dev); + if (IS_ERR(hwmon->class_device)) { + ret = PTR_ERR(hwmon->class_device); + goto err_sysfs; + } + + return 0; + +err_sysfs: + sysfs_remove_group(&pdev->dev.kobj, &da9052_attr_group); +err_mem: + return ret; +} + +static int __devexit da9052_hwmon_remove(struct platform_device *pdev) +{ + struct da9052_hwmon *hwmon = platform_get_drvdata(pdev); + + hwmon_device_unregister(hwmon->class_device); + sysfs_remove_group(&pdev->dev.kobj, &da9052_attr_group); + + return 0; +} + +static struct platform_driver da9052_hwmon_driver = { + .probe = da9052_hwmon_probe, + .remove = __devexit_p(da9052_hwmon_remove), + .driver = { + .name = "da9052-hwmon", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(da9052_hwmon_driver); + +MODULE_AUTHOR("David Dajun Chen "); +MODULE_DESCRIPTION("DA9052 HWMON driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:da9052-hwmon"); From e7d5bf7ed59ce26d3e6fc12ada497f42efd393ef Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:48:02 -0700 Subject: [PATCH 04/72] hwmon: (wm831x-hwmon) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Mark Brown Signed-off-by: Guenter Roeck Reviewed-by: Mark Brown --- drivers/hwmon/wm831x-hwmon.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c index 07cb25ae69be..d0db1f2738fb 100644 --- a/drivers/hwmon/wm831x-hwmon.c +++ b/drivers/hwmon/wm831x-hwmon.c @@ -163,7 +163,8 @@ static int __devinit wm831x_hwmon_probe(struct platform_device *pdev) struct wm831x_hwmon *hwmon; int ret; - hwmon = kzalloc(sizeof(struct wm831x_hwmon), GFP_KERNEL); + hwmon = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_hwmon), + GFP_KERNEL); if (!hwmon) return -ENOMEM; @@ -171,7 +172,7 @@ static int __devinit wm831x_hwmon_probe(struct platform_device *pdev) ret = sysfs_create_group(&pdev->dev.kobj, &wm831x_attr_group); if (ret) - goto err; + return ret; hwmon->classdev = hwmon_device_register(&pdev->dev); if (IS_ERR(hwmon->classdev)) { @@ -185,8 +186,6 @@ static int __devinit wm831x_hwmon_probe(struct platform_device *pdev) err_sysfs: sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group); -err: - kfree(hwmon); return ret; } @@ -196,8 +195,6 @@ static int __devexit wm831x_hwmon_remove(struct platform_device *pdev) hwmon_device_unregister(hwmon->classdev); sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group); - platform_set_drvdata(pdev, NULL); - kfree(hwmon); return 0; } From 94cd52027aa52780e56e11fd08703d955f0ff91e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:13 -0700 Subject: [PATCH 05/72] hwmon: (max6650) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Hans J. Koch Signed-off-by: Guenter Roeck Acked-by: Hans J. Koch --- drivers/hwmon/max6650.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 33a8a7f15e18..f739f83bafb9 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -545,7 +545,8 @@ static int max6650_probe(struct i2c_client *client, struct max6650_data *data; int err; - data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct max6650_data), + GFP_KERNEL); if (!data) { dev_err(&client->dev, "out of memory.\n"); return -ENOMEM; @@ -560,11 +561,11 @@ static int max6650_probe(struct i2c_client *client, */ err = max6650_init_client(client); if (err) - goto err_free; + return err; err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); if (err) - goto err_free; + return err; /* 3 additional fan inputs for the MAX6651 */ if (data->nr_fans == 4) { err = sysfs_create_group(&client->dev.kobj, &max6651_attr_grp); @@ -582,8 +583,6 @@ static int max6650_probe(struct i2c_client *client, sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp); err_remove: sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); -err_free: - kfree(data); return err; } @@ -595,7 +594,6 @@ static int max6650_remove(struct i2c_client *client) if (data->nr_fans == 4) sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp); sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); - kfree(data); return 0; } From b07405fbc38f2e7f2eef2f38fa724a7510ae14aa Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:13 -0700 Subject: [PATCH 06/72] hwmon: (max6639) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Roland Stigge Signed-off-by: Guenter Roeck Acked-by: Roland Stigge --- drivers/hwmon/max6639.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index de8f7adaccbd..6e60036abfa7 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -548,11 +548,10 @@ static int max6639_probe(struct i2c_client *client, struct max6639_data *data; int err; - data = kzalloc(sizeof(struct max6639_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct max6639_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -560,12 +559,12 @@ static int max6639_probe(struct i2c_client *client, /* Initialize the max6639 chip */ err = max6639_init_client(client); if (err < 0) - goto error_free; + return err; /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &max6639_group); if (err) - goto error_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -579,9 +578,6 @@ static int max6639_probe(struct i2c_client *client, error_remove: sysfs_remove_group(&client->dev.kobj, &max6639_group); -error_free: - kfree(data); -exit: return err; } @@ -592,7 +588,6 @@ static int max6639_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &max6639_group); - kfree(data); return 0; } From ed2e073b13c72de422afa75f7c9f4869ec3018cd Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:49:11 -0700 Subject: [PATCH 07/72] hwmon: (mc13783-adc.c) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Uwe Kleine-Koenig Signed-off-by: Guenter Roeck Acked-by: Uwe Kleine-Koenig --- drivers/hwmon/mc13783-adc.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index ce86c5e3c2c2..cf47a59657a9 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c @@ -179,7 +179,7 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) const struct platform_device_id *id = platform_get_device_id(pdev); char *dash; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -194,7 +194,7 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) /* Register sysfs hooks */ ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base); if (ret) - goto out_err_create_base; + return ret; if (id->driver_data & MC13783_ADC_16CHANS) { ret = sysfs_create_group(&pdev->dev.kobj, @@ -230,11 +230,6 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) out_err_create_16chans: sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); -out_err_create_base: - - platform_set_drvdata(pdev, NULL); - kfree(priv); - return ret; } @@ -253,9 +248,6 @@ static int __devexit mc13783_adc_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); - platform_set_drvdata(pdev, NULL); - kfree(priv); - return 0; } From 61d4d17ea9dc3624eeb2b235059c9c30578b81ae Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:19 -0700 Subject: [PATCH 08/72] hwmon: (pc87360) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jim Cromie Signed-off-by: Guenter Roeck Tested-by: Jim Cromie --- drivers/hwmon/pc87360.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 79ba48c8c116..91d5b2a21dd9 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -1230,7 +1230,7 @@ static int __devinit pc87360_probe(struct platform_device *pdev) int use_thermistors = 0; struct device *dev = &pdev->dev; - data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct pc87360_data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -1269,15 +1269,12 @@ static int __devinit pc87360_probe(struct platform_device *pdev) for (i = 0; i < LDNI_MAX; i++) { data->address[i] = extra_isa[i]; if (data->address[i] - && !request_region(extra_isa[i], PC87360_EXTENT, - pc87360_driver.driver.name)) { + && !devm_request_region(dev, extra_isa[i], PC87360_EXTENT, + pc87360_driver.driver.name)) { dev_err(dev, "Region 0x%x-0x%x already " "in use!\n", extra_isa[i], extra_isa[i]+PC87360_EXTENT-1); - for (i--; i >= 0; i--) - release_region(extra_isa[i], PC87360_EXTENT); - err = -EBUSY; - goto ERROR1; + return -EBUSY; } } @@ -1325,13 +1322,13 @@ static int __devinit pc87360_probe(struct platform_device *pdev) if (data->innr) { err = sysfs_create_group(&dev->kobj, &pc8736x_vin_group); if (err) - goto ERROR3; + goto error; } if (data->innr == 14) { err = sysfs_create_group(&dev->kobj, &pc8736x_therm_group); if (err) - goto ERROR3; + goto error; } /* create device attr-files for varying sysfs groups */ @@ -1341,11 +1338,11 @@ static int __devinit pc87360_probe(struct platform_device *pdev) err = sysfs_create_group(&dev->kobj, &pc8736x_temp_attr_group[i]); if (err) - goto ERROR3; + goto error; } err = device_create_file(dev, &dev_attr_alarms_temp); if (err) - goto ERROR3; + goto error; } for (i = 0; i < data->fannr; i++) { @@ -1353,49 +1350,37 @@ static int __devinit pc87360_probe(struct platform_device *pdev) err = sysfs_create_group(&dev->kobj, &pc8736x_fan_attr_group[i]); if (err) - goto ERROR3; + goto error; } if (FAN_CONFIG_CONTROL(data->fan_conf, i)) { err = device_create_file(dev, &pwm[i].dev_attr); if (err) - goto ERROR3; + goto error; } } err = device_create_file(dev, &dev_attr_name); if (err) - goto ERROR3; + goto error; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); - goto ERROR3; + goto error; } return 0; -ERROR3: +error: pc87360_remove_files(dev); - for (i = 0; i < 3; i++) { - if (data->address[i]) - release_region(data->address[i], PC87360_EXTENT); - } -ERROR1: - kfree(data); return err; } static int __devexit pc87360_remove(struct platform_device *pdev) { struct pc87360_data *data = platform_get_drvdata(pdev); - int i; hwmon_device_unregister(data->hwmon_dev); pc87360_remove_files(&pdev->dev); - for (i = 0; i < 3; i++) { - if (data->address[i]) - release_region(data->address[i], PC87360_EXTENT); - } - kfree(data); return 0; } From 6702c9981e92aeb5cbfc192d23c11ef0f26b6157 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:58 -0700 Subject: [PATCH 09/72] hwmon: (adm1025) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adm1025.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index b8557f9857d2..7e16e5d07bc6 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -477,11 +477,10 @@ static int adm1025_probe(struct i2c_client *client, int err; u8 config; - data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct adm1025_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -492,7 +491,7 @@ static int adm1025_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &adm1025_group); if (err) - goto exit_free; + return err; /* Pin 11 is either in4 (+12V) or VID4 */ config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG); @@ -513,9 +512,6 @@ static int adm1025_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &adm1025_group); sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4); -exit_free: - kfree(data); -exit: return err; } @@ -569,7 +565,6 @@ static int adm1025_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &adm1025_group); sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4); - kfree(data); return 0; } From e3ecb2eeedfc7b2c6b9f0d2db194eb43f34b688f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:01 -0700 Subject: [PATCH 10/72] hwmon: (adt7475) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adt7475.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index df29d13a5349..861c756e9536 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -1260,7 +1260,7 @@ static int adt7475_probe(struct i2c_client *client, int i, ret = 0, revision; u8 config2, config3; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -1344,7 +1344,7 @@ static int adt7475_probe(struct i2c_client *client, ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group); if (ret) - goto efree; + return ret; /* Features that can be disabled individually */ if (data->has_fan4) { @@ -1410,8 +1410,6 @@ static int adt7475_probe(struct i2c_client *client, eremove: adt7475_remove_files(client, data); -efree: - kfree(data); return ret; } @@ -1421,7 +1419,6 @@ static int adt7475_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); adt7475_remove_files(client, data); - kfree(data); return 0; } From 7b7bb90ca37914556c50947c4fcc09a9333cb9b6 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:09 -0700 Subject: [PATCH 11/72] hwmon: (lm78) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm78.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index f6bc414e1e91..c6ffafe600ad 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -660,7 +660,7 @@ static int lm78_i2c_probe(struct i2c_client *client, struct lm78_data *data; int err; - data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct lm78_data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -674,20 +674,18 @@ static int lm78_i2c_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &lm78_group); if (err) - goto ERROR3; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); - goto ERROR4; + goto error; } return 0; -ERROR4: +error: sysfs_remove_group(&client->dev.kobj, &lm78_group); -ERROR3: - kfree(data); return err; } @@ -697,7 +695,6 @@ static int lm78_i2c_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm78_group); - kfree(data); return 0; } @@ -844,16 +841,14 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) /* Reserve the ISA region */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) { - err = -EBUSY; - goto exit; - } + if (!devm_request_region(&pdev->dev, res->start + LM78_ADDR_REG_OFFSET, + 2, "lm78")) + return -EBUSY; + + data = devm_kzalloc(&pdev->dev, sizeof(struct lm78_data), GFP_KERNEL); + if (!data) + return -ENOMEM; - data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit_release_region; - } mutex_init(&data->lock); data->isa_addr = res->start; platform_set_drvdata(pdev, data); @@ -888,25 +883,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) exit_remove_files: sysfs_remove_group(&pdev->dev.kobj, &lm78_group); device_remove_file(&pdev->dev, &dev_attr_name); - kfree(data); - exit_release_region: - release_region(res->start + LM78_ADDR_REG_OFFSET, 2); - exit: return err; } static int __devexit lm78_isa_remove(struct platform_device *pdev) { struct lm78_data *data = platform_get_drvdata(pdev); - struct resource *res; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &lm78_group); device_remove_file(&pdev->dev, &dev_attr_name); - kfree(data); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start + LM78_ADDR_REG_OFFSET, 2); return 0; } From adc1413279d124e0940a314ccabebbbee159fd8f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:05 -0700 Subject: [PATCH 12/72] hwmon: (f71805f) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/f71805f.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 3e4da620e9c7..4dd7723d257f 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -1386,20 +1386,20 @@ static int __devinit f71805f_probe(struct platform_device *pdev) "f71872f", }; - data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct f71805f_data), + GFP_KERNEL); if (!data) { - err = -ENOMEM; pr_err("Out of memory\n"); - goto exit; + return -ENOMEM; } res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) { - err = -EBUSY; + if (!devm_request_region(&pdev->dev, res->start + ADDR_REG_OFFSET, 2, + DRVNAME)) { dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)(res->start + ADDR_REG_OFFSET), (unsigned long)(res->start + ADDR_REG_OFFSET + 1)); - goto exit_free; + return -EBUSY; } data->addr = res->start; data->name = names[sio_data->kind]; @@ -1427,7 +1427,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev) /* Register sysfs interface files */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group); if (err) - goto exit_release_region; + return err; if (data->has_in & (1 << 4)) { /* in4 */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[0]); @@ -1487,19 +1487,12 @@ static int __devinit f71805f_probe(struct platform_device *pdev) for (i = 0; i < 4; i++) sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); -exit_release_region: - release_region(res->start + ADDR_REG_OFFSET, 2); -exit_free: - platform_set_drvdata(pdev, NULL); - kfree(data); -exit: return err; } static int __devexit f71805f_remove(struct platform_device *pdev) { struct f71805f_data *data = platform_get_drvdata(pdev); - struct resource *res; int i; hwmon_device_unregister(data->hwmon_dev); @@ -1507,11 +1500,6 @@ static int __devexit f71805f_remove(struct platform_device *pdev) for (i = 0; i < 4; i++) sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); - platform_set_drvdata(pdev, NULL); - kfree(data); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start + ADDR_REG_OFFSET, 2); return 0; } From c087f73a249154ed83e451343d9eff0f299291a3 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:10 -0700 Subject: [PATCH 13/72] hwmon: (lm83) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm83.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index cd45b9d85584..e998034f1f11 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -343,11 +343,10 @@ static int lm83_probe(struct i2c_client *new_client, struct lm83_data *data; int err; - data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct lm83_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); data->valid = 0; @@ -362,7 +361,7 @@ static int lm83_probe(struct i2c_client *new_client, err = sysfs_create_group(&new_client->dev.kobj, &lm83_group); if (err) - goto exit_free; + return err; if (id->driver_data == lm83) { err = sysfs_create_group(&new_client->dev.kobj, @@ -382,9 +381,6 @@ static int lm83_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm83_group); sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt); -exit_free: - kfree(data); -exit: return err; } @@ -396,7 +392,6 @@ static int lm83_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &lm83_group); sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); - kfree(data); return 0; } From 20f426ff028202b2c0df947a3468ed4717f598d6 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:10 -0700 Subject: [PATCH 14/72] hwmon: (lm90) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm90.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 22b14a68e35e..863412a02bdd 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -1399,11 +1399,10 @@ static int lm90_probe(struct i2c_client *client, struct lm90_data *data; int err; - data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct lm90_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -1474,8 +1473,6 @@ static int lm90_probe(struct i2c_client *client, lm90_remove_files(client, data); exit_restore: lm90_restore_conf(client, data); - kfree(data); -exit: return err; } @@ -1487,7 +1484,6 @@ static int lm90_remove(struct i2c_client *client) lm90_remove_files(client, data); lm90_restore_conf(client, data); - kfree(data); return 0; } From 4cb14a3a6545bf4c51d6b61b95ccc1afe59510c9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:48:01 -0700 Subject: [PATCH 15/72] hwmon: (w83795) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83795.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index d887cb3b72e8..b813c646c7ca 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c @@ -2157,11 +2157,9 @@ static int w83795_probe(struct i2c_client *client, struct w83795_data *data; int err; - data = kzalloc(sizeof(struct w83795_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(dev, sizeof(struct w83795_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->chip_type = id->driver_data; @@ -2247,8 +2245,6 @@ static int w83795_probe(struct i2c_client *client, exit_remove: w83795_handle_files(dev, device_remove_file_wrapper); - kfree(data); -exit: return err; } @@ -2258,7 +2254,6 @@ static int w83795_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); w83795_handle_files(&client->dev, device_remove_file_wrapper); - kfree(data); return 0; } From 06ce97d608fb0599509c1c586662ba4778719fc4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:58 -0700 Subject: [PATCH 16/72] hwmon: (adm1021) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adm1021.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 4394e7e99c46..fd1d1b15854e 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -366,11 +366,11 @@ static int adm1021_probe(struct i2c_client *client, struct adm1021_data *data; int err; - data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct adm1021_data), + GFP_KERNEL); if (!data) { - pr_debug("adm1021: detect failed, kzalloc failed!\n"); - err = -ENOMEM; - goto error0; + pr_debug("adm1021: detect failed, devm_kzalloc failed!\n"); + return -ENOMEM; } i2c_set_clientdata(client, data); @@ -384,21 +384,18 @@ static int adm1021_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &adm1021_group); if (err) - goto error1; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); - goto error3; + goto error; } return 0; -error3: +error: sysfs_remove_group(&client->dev.kobj, &adm1021_group); -error1: - kfree(data); -error0: return err; } @@ -418,7 +415,6 @@ static int adm1021_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1021_group); - kfree(data); return 0; } From 3421e212e6dfa6792877ef0b9e7a147ee15a59c0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:59 -0700 Subject: [PATCH 17/72] hwmon: (adm1026) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adm1026.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 1003219b9f90..0f068e7297ee 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -1834,11 +1834,10 @@ static int adm1026_probe(struct i2c_client *client, struct adm1026_data *data; int err; - data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct adm1026_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -1852,7 +1851,7 @@ static int adm1026_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &adm1026_group); if (err) - goto exitfree; + return err; if (data->config1 & CFG1_AIN8_9) err = sysfs_create_group(&client->dev.kobj, &adm1026_group_in8_9); @@ -1877,9 +1876,6 @@ static int adm1026_probe(struct i2c_client *client, sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); else sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); -exitfree: - kfree(data); -exit: return err; } @@ -1892,7 +1888,6 @@ static int adm1026_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); else sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); - kfree(data); return 0; } From dc2fd6632788bcbe6243a50c6c819fc11b5da76b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:59 -0700 Subject: [PATCH 18/72] hwmon: (adm1031) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adm1031.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 44e1fd7f3d81..c6a4631e833f 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -954,11 +954,10 @@ static int adm1031_probe(struct i2c_client *client, struct adm1031_data *data; int err; - data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct adm1031_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->chip_type = id->driver_data; @@ -975,7 +974,7 @@ static int adm1031_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &adm1031_group); if (err) - goto exit_free; + return err; if (data->chip_type == adm1031) { err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt); @@ -994,9 +993,6 @@ static int adm1031_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &adm1031_group); sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); -exit_free: - kfree(data); -exit: return err; } @@ -1007,7 +1003,6 @@ static int adm1031_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1031_group); sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); - kfree(data); return 0; } From e5ebb772c697540f42a4b74f3d14fae6ecd4de24 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:00 -0700 Subject: [PATCH 19/72] hwmon: (adm9240) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adm9240.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index c3c2865a8967..5a78d102a0fa 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -650,11 +650,9 @@ static int adm9240_probe(struct i2c_client *new_client, struct adm9240_data *data; int err; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); mutex_init(&data->update_lock); @@ -664,7 +662,7 @@ static int adm9240_probe(struct i2c_client *new_client, /* populate sysfs filesystem */ err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -676,9 +674,6 @@ static int adm9240_probe(struct i2c_client *new_client, exit_remove: sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); -exit_free: - kfree(data); -exit: return err; } @@ -689,7 +684,6 @@ static int adm9240_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm9240_group); - kfree(data); return 0; } From d466a353052582ea784d9f5352c822d828d00244 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:03 -0700 Subject: [PATCH 20/72] hwmon: (atxp1) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/atxp1.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 58af6aa93530..aecb9ea7beb5 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -345,11 +345,10 @@ static int atxp1_probe(struct i2c_client *new_client, struct atxp1_data *data; int err; - data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct atxp1_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; /* Get VRM */ data->vrm = vid_which_vrm(); @@ -362,7 +361,7 @@ static int atxp1_probe(struct i2c_client *new_client, /* Register sysfs hooks */ err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -377,9 +376,6 @@ static int atxp1_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); -exit_free: - kfree(data); -exit: return err; }; @@ -390,8 +386,6 @@ static int atxp1_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &atxp1_group); - kfree(data); - return 0; }; From e20b4b38cdf1622d1577ae5e402ded2bd63bf616 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:03 -0700 Subject: [PATCH 21/72] hwmon: (ds1621) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/ds1621.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index f647a3307ebc..1c568736baff 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -249,11 +249,10 @@ static int ds1621_probe(struct i2c_client *client, struct ds1621_data *data; int err; - data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + 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); @@ -264,7 +263,7 @@ static int ds1621_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &ds1621_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -276,9 +275,6 @@ static int ds1621_probe(struct i2c_client *client, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &ds1621_group); - exit_free: - kfree(data); - exit: return err; } @@ -289,8 +285,6 @@ static int ds1621_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ds1621_group); - kfree(data); - return 0; } From 6ecffe16911dc79b079b6fb4491fd157c62d4371 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:04 -0700 Subject: [PATCH 22/72] hwmon: (emc6w201) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/emc6w201.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c index 840f5112e602..ada12a98a97c 100644 --- a/drivers/hwmon/emc6w201.c +++ b/drivers/hwmon/emc6w201.c @@ -492,11 +492,10 @@ static int emc6w201_probe(struct i2c_client *client, struct emc6w201_data *data; int err; - data = kzalloc(sizeof(struct emc6w201_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -504,7 +503,7 @@ static int emc6w201_probe(struct i2c_client *client, /* Create sysfs attribute */ err = sysfs_create_group(&client->dev.kobj, &emc6w201_group); if (err) - goto exit_free; + return err; /* Expose as a hwmon device */ data->hwmon_dev = hwmon_device_register(&client->dev); @@ -517,9 +516,6 @@ static int emc6w201_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &emc6w201_group); - exit_free: - kfree(data); - exit: return err; } @@ -529,7 +525,6 @@ static int emc6w201_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &emc6w201_group); - kfree(data); return 0; } From bba636d0592e5d33b960ba480459180ad5dc1fdd Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:06 -0700 Subject: [PATCH 23/72] hwmon: (gl518sm) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/gl518sm.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 764a083ac7a7..2c74673f48e5 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -544,11 +544,10 @@ static int gl518_probe(struct i2c_client *client, struct gl518_data *data; int err, revision; - data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct gl518_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); revision = gl518_read_value(client, GL518_REG_REVISION); @@ -562,7 +561,7 @@ static int gl518_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &gl518_group); if (err) - goto exit_free; + return err; if (data->type == gl518sm_r80) { err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80); if (err) @@ -581,9 +580,6 @@ static int gl518_probe(struct i2c_client *client, sysfs_remove_group(&client->dev.kobj, &gl518_group); if (data->type == gl518sm_r80) sysfs_remove_group(&client->dev.kobj, &gl518_group_r80); -exit_free: - kfree(data); -exit: return err; } @@ -617,7 +613,6 @@ static int gl518_remove(struct i2c_client *client) if (data->type == gl518sm_r80) sysfs_remove_group(&client->dev.kobj, &gl518_group_r80); - kfree(data); return 0; } From 647ff514d8a099fcce029283c1ecc38519b218d6 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:07 -0700 Subject: [PATCH 24/72] hwmon: (gl520sm) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/gl520sm.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 5ff452b6a4d0..a21ff252f2f1 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -779,11 +779,10 @@ static int gl520_probe(struct i2c_client *client, struct gl520_data *data; int err; - data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct gl520_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -794,7 +793,7 @@ static int gl520_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &gl520_group); if (err) - goto exit_free; + return err; if (data->two_temps) err = sysfs_create_group(&client->dev.kobj, &gl520_group_temp2); @@ -816,9 +815,6 @@ static int gl520_probe(struct i2c_client *client, sysfs_remove_group(&client->dev.kobj, &gl520_group); sysfs_remove_group(&client->dev.kobj, &gl520_group_in4); sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2); -exit_free: - kfree(data); -exit: return err; } @@ -870,7 +866,6 @@ static int gl520_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &gl520_group_in4); sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2); - kfree(data); return 0; } From c5a4a91d24e0d4af8630932081a4c9a15e7fb1f7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:08 -0700 Subject: [PATCH 25/72] hwmon: (lm63) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm63.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 602a0f0b0de8..eed4d9401788 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -1108,11 +1108,9 @@ static int lm63_probe(struct i2c_client *client, struct lm63_data *data; int err; - data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct lm63_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->valid = 0; @@ -1129,7 +1127,7 @@ static int lm63_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &lm63_group); if (err) - goto exit_free; + return err; if (data->config & 0x04) { /* tachometer enabled */ err = sysfs_create_group(&client->dev.kobj, &lm63_group_fan1); if (err) @@ -1161,9 +1159,6 @@ static int lm63_probe(struct i2c_client *client, device_remove_file(&client->dev, &dev_attr_temp2_type); sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); } -exit_free: - kfree(data); -exit: return err; } @@ -1179,7 +1174,6 @@ static int lm63_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); } - kfree(data); return 0; } From 13ac7a017678d9d7ee4dcc93a10947df0d3b5b12 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:08 -0700 Subject: [PATCH 26/72] hwmon: (lm75) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm75.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index a83f206af244..291edfff55bf 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -156,7 +156,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) return -EIO; - data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct lm75_data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -174,7 +174,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) status = lm75_read_value(client, LM75_REG_CONF); if (status < 0) { dev_dbg(&client->dev, "Can't read config? %d\n", status); - goto exit_free; + return status; } data->orig_conf = status; new = status & ~clr_mask; @@ -186,7 +186,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register sysfs hooks */ status = sysfs_create_group(&client->dev.kobj, &lm75_group); if (status) - goto exit_free; + return status; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -201,8 +201,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) exit_remove: sysfs_remove_group(&client->dev.kobj, &lm75_group); -exit_free: - kfree(data); return status; } @@ -213,7 +211,6 @@ static int lm75_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm75_group); lm75_write_value(client, LM75_REG_CONF, data->orig_conf); - kfree(data); return 0; } From efd2d117aeb5f01cc9c90e56fff29d4a5f535580 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:09 -0700 Subject: [PATCH 27/72] hwmon: (lm77) Improve code readability Rename new_client variable, and define new variable for client->dev. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm77.c | 59 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 0fca8613e7d8..3ccc23a0c7f5 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -267,10 +267,9 @@ static const struct attribute_group lm77_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm77_detect(struct i2c_client *new_client, - struct i2c_board_info *info) +static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info) { - struct i2c_adapter *adapter = new_client->adapter; + struct i2c_adapter *adapter = client->adapter; int i, cur, conf, hyst, crit, min, max; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | @@ -292,18 +291,18 @@ static int lm77_detect(struct i2c_client *new_client, */ /* addresses cycling */ - cur = i2c_smbus_read_word_data(new_client, 0); - conf = i2c_smbus_read_byte_data(new_client, 1); - hyst = i2c_smbus_read_word_data(new_client, 2); - crit = i2c_smbus_read_word_data(new_client, 3); - min = i2c_smbus_read_word_data(new_client, 4); - max = i2c_smbus_read_word_data(new_client, 5); + cur = i2c_smbus_read_word_data(client, 0); + conf = i2c_smbus_read_byte_data(client, 1); + hyst = i2c_smbus_read_word_data(client, 2); + crit = i2c_smbus_read_word_data(client, 3); + min = i2c_smbus_read_word_data(client, 4); + max = i2c_smbus_read_word_data(client, 5); for (i = 8; i <= 0xff; i += 8) { - if (i2c_smbus_read_byte_data(new_client, i + 1) != conf - || i2c_smbus_read_word_data(new_client, i + 2) != hyst - || i2c_smbus_read_word_data(new_client, i + 3) != crit - || i2c_smbus_read_word_data(new_client, i + 4) != min - || i2c_smbus_read_word_data(new_client, i + 5) != max) + if (i2c_smbus_read_byte_data(client, i + 1) != conf + || i2c_smbus_read_word_data(client, i + 2) != hyst + || i2c_smbus_read_word_data(client, i + 3) != crit + || i2c_smbus_read_word_data(client, i + 4) != min + || i2c_smbus_read_word_data(client, i + 5) != max) return -ENODEV; } @@ -320,17 +319,17 @@ static int lm77_detect(struct i2c_client *new_client, return -ENODEV; /* 0x06 and 0x07 return the last read value */ - cur = i2c_smbus_read_word_data(new_client, 0); - if (i2c_smbus_read_word_data(new_client, 6) != cur - || i2c_smbus_read_word_data(new_client, 7) != cur) + cur = i2c_smbus_read_word_data(client, 0); + if (i2c_smbus_read_word_data(client, 6) != cur + || i2c_smbus_read_word_data(client, 7) != cur) return -ENODEV; - hyst = i2c_smbus_read_word_data(new_client, 2); - if (i2c_smbus_read_word_data(new_client, 6) != hyst - || i2c_smbus_read_word_data(new_client, 7) != hyst) + hyst = i2c_smbus_read_word_data(client, 2); + if (i2c_smbus_read_word_data(client, 6) != hyst + || i2c_smbus_read_word_data(client, 7) != hyst) return -ENODEV; - min = i2c_smbus_read_word_data(new_client, 4); - if (i2c_smbus_read_word_data(new_client, 6) != min - || i2c_smbus_read_word_data(new_client, 7) != min) + min = i2c_smbus_read_word_data(client, 4); + if (i2c_smbus_read_word_data(client, 6) != min + || i2c_smbus_read_word_data(client, 7) != min) return -ENODEV; strlcpy(info->type, "lm77", I2C_NAME_SIZE); @@ -338,9 +337,9 @@ static int lm77_detect(struct i2c_client *new_client, return 0; } -static int lm77_probe(struct i2c_client *new_client, - const struct i2c_device_id *id) +static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct lm77_data *data; int err; @@ -350,19 +349,19 @@ static int lm77_probe(struct i2c_client *new_client, goto exit; } - i2c_set_clientdata(new_client, data); + i2c_set_clientdata(client, data); data->valid = 0; mutex_init(&data->update_lock); /* Initialize the LM77 chip */ - lm77_init_client(new_client); + lm77_init_client(client); /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &lm77_group); + err = sysfs_create_group(&dev->kobj, &lm77_group); if (err) goto exit_free; - data->hwmon_dev = hwmon_device_register(&new_client->dev); + data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exit_remove; @@ -371,7 +370,7 @@ static int lm77_probe(struct i2c_client *new_client, return 0; exit_remove: - sysfs_remove_group(&new_client->dev.kobj, &lm77_group); + sysfs_remove_group(&dev->kobj, &lm77_group); exit_free: kfree(data); exit: From 52714c04df4b12ca308a1d792d50681df43365c2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 16 Jun 2012 18:24:02 -0700 Subject: [PATCH 28/72] hwmon: (lm77) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm77.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 3ccc23a0c7f5..f82acf67acf5 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -343,11 +343,9 @@ static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id) struct lm77_data *data; int err; - data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(dev, sizeof(struct lm77_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->valid = 0; @@ -359,7 +357,7 @@ static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register sysfs hooks */ err = sysfs_create_group(&dev->kobj, &lm77_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { @@ -371,9 +369,6 @@ static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id) exit_remove: sysfs_remove_group(&dev->kobj, &lm77_group); -exit_free: - kfree(data); -exit: return err; } @@ -382,7 +377,6 @@ static int lm77_remove(struct i2c_client *client) struct lm77_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm77_group); - kfree(data); return 0; } From c38b2820cb4014b86b0bf45f334d3436c03b14be Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:09 -0700 Subject: [PATCH 29/72] hwmon: (lm80) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm80.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index e2c43e1774be..28a8b71f4571 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -543,11 +543,9 @@ static int lm80_probe(struct i2c_client *client, struct lm80_data *data; int err; - data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct lm80_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -562,7 +560,7 @@ static int lm80_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &lm80_group); if (err) - goto error_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -574,9 +572,6 @@ static int lm80_probe(struct i2c_client *client, error_remove: sysfs_remove_group(&client->dev.kobj, &lm80_group); -error_free: - kfree(data); -exit: return err; } @@ -587,7 +582,6 @@ static int lm80_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm80_group); - kfree(data); return 0; } From 747e5d62ac85b9706739d2e21b1722f68d797da0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:10 -0700 Subject: [PATCH 30/72] hwmon: (lm85) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm85.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 864c7d999e0c..9f2dd77e1e0e 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1387,7 +1387,7 @@ static int lm85_probe(struct i2c_client *client, struct lm85_data *data; int err; - data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct lm85_data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -1419,7 +1419,7 @@ static int lm85_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &lm85_group); if (err) - goto err_kfree; + return err; /* minctl and temp_off exist on all chips except emc6d103s */ if (data->type != emc6d103s) { @@ -1466,8 +1466,6 @@ static int lm85_probe(struct i2c_client *client, /* Error out and cleanup code */ err_remove_files: lm85_remove_files(client, data); - err_kfree: - kfree(data); return err; } @@ -1476,7 +1474,6 @@ static int lm85_remove(struct i2c_client *client) struct lm85_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); lm85_remove_files(client, data); - kfree(data); return 0; } From 5ff512b458ba7948d22dab0771233cf9b2da0793 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:10 -0700 Subject: [PATCH 31/72] hwmon: (lm87) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm87.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 314d147bf1ac..16e45d702152 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -898,11 +898,9 @@ static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id) struct lm87_data *data; int err; - data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct lm87_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->valid = 0; @@ -923,7 +921,7 @@ static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &lm87_group); if (err) - goto exit_free; + goto exit_stop; if (data->channel & CHAN_NO_FAN(0)) { err = sysfs_create_group(&client->dev.kobj, &lm87_group_in6); @@ -972,10 +970,8 @@ static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id) exit_remove: lm87_remove_files(client); -exit_free: +exit_stop: lm87_write_value(client, LM87_REG_CONFIG, data->config); - kfree(data); -exit: return err; } @@ -987,7 +983,6 @@ static int lm87_remove(struct i2c_client *client) lm87_remove_files(client); lm87_write_value(client, LM87_REG_CONFIG, data->config); - kfree(data); return 0; } From 35bb95a17a1c04ec9620553867f29a336e868707 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:02 -0700 Subject: [PATCH 32/72] hwmon: (asc7621) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: George Joseph Signed-off-by: Guenter Roeck Acked-by: George Joseph --- drivers/hwmon/asc7621.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index 7caa242915a6..b867aab78049 100644 --- a/drivers/hwmon/asc7621.c +++ b/drivers/hwmon/asc7621.c @@ -1109,7 +1109,8 @@ asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - data = kzalloc(sizeof(struct asc7621_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct asc7621_data), + GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -1143,7 +1144,6 @@ asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id) &(asc7621_params[i].sda.dev_attr)); } - kfree(data); return err; } @@ -1192,7 +1192,6 @@ static int asc7621_remove(struct i2c_client *client) &(asc7621_params[i].sda.dev_attr)); } - kfree(data); return 0; } From 705375cc41f2bd63dfffcf4830afff76c63e5681 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:11 -0700 Subject: [PATCH 33/72] hwmon: (lm92) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm92.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index fdc691a4028f..2282d77e83e8 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -373,11 +373,10 @@ static int lm92_probe(struct i2c_client *new_client, struct lm92_data *data; int err; - data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct lm92_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); data->valid = 0; @@ -389,7 +388,7 @@ static int lm92_probe(struct i2c_client *new_client, /* Register sysfs hooks */ err = sysfs_create_group(&new_client->dev.kobj, &lm92_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -401,9 +400,6 @@ static int lm92_probe(struct i2c_client *new_client, exit_remove: sysfs_remove_group(&new_client->dev.kobj, &lm92_group); -exit_free: - kfree(data); -exit: return err; } @@ -414,7 +410,6 @@ static int lm92_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm92_group); - kfree(data); return 0; } From 4a8ad25af56fa55746a97c4f48985154eb82a842 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:11 -0700 Subject: [PATCH 34/72] hwmon: (lm93) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm93.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 67e8fe256e02..bf946187bd37 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -2738,15 +2738,13 @@ static int lm93_probe(struct i2c_client *client, } else { dev_dbg(&client->dev, "detect failed, " "smbus byte and/or word data not supported!\n"); - err = -ENODEV; - goto err_out; + return -ENODEV; } - data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct lm93_data), GFP_KERNEL); if (!data) { dev_dbg(&client->dev, "out of memory!\n"); - err = -ENOMEM; - goto err_out; + return -ENOMEM; } i2c_set_clientdata(client, data); @@ -2760,7 +2758,7 @@ static int lm93_probe(struct i2c_client *client, err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp); if (err) - goto err_free; + return err; /* Register hwmon driver class */ data->hwmon_dev = hwmon_device_register(&client->dev); @@ -2770,9 +2768,6 @@ static int lm93_probe(struct i2c_client *client, err = PTR_ERR(data->hwmon_dev); dev_err(&client->dev, "error registering hwmon device.\n"); sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); -err_free: - kfree(data); -err_out: return err; } @@ -2783,7 +2778,6 @@ static int lm93_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); - kfree(data); return 0; } From 661f020f56c698be9cf40f0b3c8963c2d15be0dd Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:12 -0700 Subject: [PATCH 35/72] hwmon: (max1111) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/max1111.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index 362a40eb6129..f3978a46e844 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -168,7 +168,7 @@ static int __devinit max1111_probe(struct spi_device *spi) if (err < 0) return err; - data = kzalloc(sizeof(struct max1111_data), GFP_KERNEL); + data = devm_kzalloc(&spi->dev, sizeof(struct max1111_data), GFP_KERNEL); if (data == NULL) { dev_err(&spi->dev, "failed to allocate memory\n"); return -ENOMEM; @@ -176,7 +176,7 @@ static int __devinit max1111_probe(struct spi_device *spi) err = setup_transfer(data); if (err) - goto err_free_data; + return err; mutex_init(&data->drvdata_lock); @@ -186,7 +186,7 @@ static int __devinit max1111_probe(struct spi_device *spi) err = sysfs_create_group(&spi->dev.kobj, &max1111_attr_group); if (err) { dev_err(&spi->dev, "failed to create attribute group\n"); - goto err_free_data; + return err; } data->hwmon_dev = hwmon_device_register(&spi->dev); @@ -203,8 +203,6 @@ static int __devinit max1111_probe(struct spi_device *spi) err_remove: sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); -err_free_data: - kfree(data); return err; } @@ -215,7 +213,6 @@ static int __devexit max1111_remove(struct spi_device *spi) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); mutex_destroy(&data->drvdata_lock); - kfree(data); return 0; } From 215690a4f1050cdf3267e72e2d8c9c62d47b7b1f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:12 -0700 Subject: [PATCH 36/72] hwmon: (max1619) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/max1619.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index ecac04a7b7d6..6c11ec214071 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -267,11 +267,10 @@ static int max1619_probe(struct i2c_client *new_client, struct max1619_data *data; int err; - data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct max1619_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); data->valid = 0; @@ -283,7 +282,7 @@ static int max1619_probe(struct i2c_client *new_client, /* Register sysfs hooks */ err = sysfs_create_group(&new_client->dev.kobj, &max1619_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -295,9 +294,6 @@ static int max1619_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &max1619_group); -exit_free: - kfree(data); -exit: return err; } @@ -323,7 +319,6 @@ static int max1619_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &max1619_group); - kfree(data); return 0; } From 96f316c24c0aea2984c90170966d9a2cb93d1094 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:13 -0700 Subject: [PATCH 37/72] hwmon: (max6642) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Per Dalen Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/max6642.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c index 4298909a41fd..bf236c0782b7 100644 --- a/drivers/hwmon/max6642.c +++ b/drivers/hwmon/max6642.c @@ -286,11 +286,10 @@ static int max6642_probe(struct i2c_client *new_client, struct max6642_data *data; int err; - data = kzalloc(sizeof(struct max6642_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct max6642_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); mutex_init(&data->update_lock); @@ -301,7 +300,7 @@ static int max6642_probe(struct i2c_client *new_client, /* Register sysfs hooks */ err = sysfs_create_group(&new_client->dev.kobj, &max6642_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -313,9 +312,6 @@ static int max6642_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &max6642_group); -exit_free: - kfree(data); -exit: return err; } @@ -326,7 +322,6 @@ static int max6642_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &max6642_group); - kfree(data); return 0; } From 60c2b5697560b0216ddbebaabebd1aac7abe3012 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:20 -0700 Subject: [PATCH 38/72] hwmon: (pcf8591) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/pcf8591.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c index 4174c7463d70..825883d29002 100644 --- a/drivers/hwmon/pcf8591.c +++ b/drivers/hwmon/pcf8591.c @@ -200,11 +200,10 @@ static int pcf8591_probe(struct i2c_client *client, struct pcf8591_data *data; int err; - data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct pcf8591_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -215,7 +214,7 @@ static int pcf8591_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group); if (err) - goto exit_kfree; + return err; /* Register input2 if not in "two differential inputs" mode */ if (input_mode != 3) { @@ -242,9 +241,6 @@ static int pcf8591_probe(struct i2c_client *client, exit_sysfs_remove: sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); -exit_kfree: - kfree(data); -exit: return err; } @@ -255,7 +251,6 @@ static int pcf8591_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); - kfree(i2c_get_clientdata(client)); return 0; } From d00985f3dd5339eb3068e53f5704ae007ee62f90 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:07 -0700 Subject: [PATCH 39/72] hwmon: (gpio-fan) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Simon Guinot Signed-off-by: Guenter Roeck Acked-by: Simon Guinot --- drivers/hwmon/gpio-fan.c | 56 +++++++++++----------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 2ce8c44a0e07..b90b3e9617b0 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -95,17 +95,17 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, fan_data->alarm = alarm; - err = gpio_request(alarm->gpio, "GPIO fan alarm"); + err = devm_gpio_request(&pdev->dev, alarm->gpio, "GPIO fan alarm"); if (err) return err; err = gpio_direction_input(alarm->gpio); if (err) - goto err_free_gpio; + return err; err = device_create_file(&pdev->dev, &dev_attr_fan1_alarm); if (err) - goto err_free_gpio; + return err; /* * If the alarm GPIO don't support interrupts, just leave @@ -117,8 +117,8 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, INIT_WORK(&fan_data->alarm_work, fan_alarm_notify); irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); - err = request_irq(alarm_irq, fan_alarm_irq_handler, IRQF_SHARED, - "GPIO fan alarm", fan_data); + err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler, + IRQF_SHARED, "GPIO fan alarm", fan_data); if (err) goto err_free_sysfs; @@ -126,21 +126,14 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, err_free_sysfs: device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); -err_free_gpio: - gpio_free(alarm->gpio); - return err; } static void fan_alarm_free(struct gpio_fan_data *fan_data) { struct platform_device *pdev = fan_data->pdev; - int alarm_irq = gpio_to_irq(fan_data->alarm->gpio); - if (alarm_irq >= 0) - free_irq(alarm_irq, fan_data); device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); - gpio_free(fan_data->alarm->gpio); } /* @@ -365,15 +358,14 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, int i, err; for (i = 0; i < num_ctrl; i++) { - err = gpio_request(ctrl[i], "GPIO fan control"); + err = devm_gpio_request(&pdev->dev, ctrl[i], + "GPIO fan control"); if (err) - goto err_free_gpio; + return err; err = gpio_direction_output(ctrl[i], gpio_get_value(ctrl[i])); - if (err) { - gpio_free(ctrl[i]); - goto err_free_gpio; - } + if (err) + return err; } fan_data->num_ctrl = num_ctrl; @@ -382,32 +374,18 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, fan_data->speed = pdata->speed; 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) { - err = -ENODEV; - goto err_free_gpio; - } + if (fan_data->speed_index < 0) + return -ENODEV; err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); - if (err) - goto err_free_gpio; - - return 0; - -err_free_gpio: - for (i = i - 1; i >= 0; i--) - gpio_free(ctrl[i]); - return err; } static void fan_ctrl_free(struct gpio_fan_data *fan_data) { struct platform_device *pdev = fan_data->pdev; - int i; sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); - for (i = 0; i < fan_data->num_ctrl; i++) - gpio_free(fan_data->ctrl[i]); } /* @@ -431,7 +409,8 @@ static int __devinit gpio_fan_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - fan_data = kzalloc(sizeof(struct gpio_fan_data), GFP_KERNEL); + fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data), + GFP_KERNEL); if (!fan_data) return -ENOMEM; @@ -443,7 +422,7 @@ static int __devinit gpio_fan_probe(struct platform_device *pdev) if (pdata->alarm) { err = fan_alarm_init(fan_data, pdata->alarm); if (err) - goto err_free_data; + return err; } /* Configure control GPIOs if available. */ @@ -480,10 +459,6 @@ static int __devinit gpio_fan_probe(struct platform_device *pdev) err_free_alarm: if (fan_data->alarm) fan_alarm_free(fan_data); -err_free_data: - platform_set_drvdata(pdev, NULL); - kfree(fan_data); - return err; } @@ -497,7 +472,6 @@ static int __devexit gpio_fan_remove(struct platform_device *pdev) fan_alarm_free(fan_data); if (fan_data->ctrl) fan_ctrl_free(fan_data); - kfree(fan_data); return 0; } From 3fafb0ce92f13d14ba1c1340ac185e5c78fc7eae Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 16 Jun 2012 07:33:52 -0700 Subject: [PATCH 40/72] hwmon: Document the use of devres functions devres functions are the preferred means to allocate resources in hwmon drivers. Document it. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- Documentation/hwmon/submitting-patches | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/hwmon/submitting-patches b/Documentation/hwmon/submitting-patches index 86f42e8e9e49..790f774a3032 100644 --- a/Documentation/hwmon/submitting-patches +++ b/Documentation/hwmon/submitting-patches @@ -70,6 +70,9 @@ increase the chances of your change being accepted. review more difficult. It may also result in code which is more complicated than necessary. Use inline functions or just regular functions instead. +* Use devres functions whenever possible to allocate resources. For rationale + and supported functions, please see Documentation/driver-model/devres.txt. + * If the driver has a detect function, make sure it is silent. Debug messages and messages printed after a successful detection are acceptable, but it must not print messages such as "Chip XXX not found/supported". From 5e0c876920e6cc5cd074f1a5a8d4c30783f9baf9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:20 -0700 Subject: [PATCH 41/72] hwmon: (pc87427) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jean Delvare Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/pc87427.c | 53 ++++++++++------------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 37059a3755e9..f185b1fa53e5 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -956,44 +956,28 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); * Device detection, attach and detach */ -static void pc87427_release_regions(struct platform_device *pdev, int count) +static int __devinit pc87427_request_regions(struct platform_device *pdev, + int count) { struct resource *res; int i; - for (i = 0; i < count; i++) { - res = platform_get_resource(pdev, IORESOURCE_IO, i); - release_region(res->start, resource_size(res)); - } -} - -static int __devinit pc87427_request_regions(struct platform_device *pdev, - int count) -{ - struct resource *res; - int i, err = 0; - for (i = 0; i < count; i++) { res = platform_get_resource(pdev, IORESOURCE_IO, i); if (!res) { - err = -ENOENT; dev_err(&pdev->dev, "Missing resource #%d\n", i); - break; + return -ENOENT; } - if (!request_region(res->start, resource_size(res), DRVNAME)) { - err = -EBUSY; + if (!devm_request_region(&pdev->dev, res->start, + resource_size(res), DRVNAME)) { dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)res->end); - break; + return -EBUSY; } } - - if (err && i) - pc87427_release_regions(pdev, i); - - return err; + return 0; } static void __devinit pc87427_init_device(struct device *dev) @@ -1094,11 +1078,11 @@ static int __devinit pc87427_probe(struct platform_device *pdev) struct pc87427_data *data; int i, err, res_count; - data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct pc87427_data), + GFP_KERNEL); if (!data) { - err = -ENOMEM; pr_err("Out of memory\n"); - goto exit; + return -ENOMEM; } data->address[0] = sio_data->address[0]; @@ -1107,7 +1091,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev) err = pc87427_request_regions(pdev, res_count); if (err) - goto exit_kfree; + return err; mutex_init(&data->lock); data->name = "pc87427"; @@ -1117,7 +1101,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev) /* Register sysfs hooks */ err = device_create_file(&pdev->dev, &dev_attr_name); if (err) - goto exit_release_region; + return err; for (i = 0; i < 8; i++) { if (!(data->fan_enabled & (1 << i))) continue; @@ -1154,28 +1138,15 @@ static int __devinit pc87427_probe(struct platform_device *pdev) exit_remove_files: pc87427_remove_files(&pdev->dev); -exit_release_region: - pc87427_release_regions(pdev, res_count); -exit_kfree: - platform_set_drvdata(pdev, NULL); - kfree(data); -exit: return err; } static int __devexit pc87427_remove(struct platform_device *pdev) { struct pc87427_data *data = platform_get_drvdata(pdev); - int res_count; - - res_count = (data->address[0] != 0) + (data->address[1] != 0); hwmon_device_unregister(data->hwmon_dev); pc87427_remove_files(&pdev->dev); - platform_set_drvdata(pdev, NULL); - kfree(data); - - pc87427_release_regions(pdev, res_count); return 0; } From 5d224ade31f0a08c0a0eef9e74a6187c0b8747b4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:23 -0700 Subject: [PATCH 42/72] hwmon: (sis5595) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/sis5595.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 6c4d8eb9b7ca..8275f0e14eb7 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -593,17 +593,14 @@ static int __devinit sis5595_probe(struct platform_device *pdev) /* Reserve the ISA region */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, SIS5595_EXTENT, - sis5595_driver.driver.name)) { - err = -EBUSY; - goto exit; - } + if (!devm_request_region(&pdev->dev, res->start, SIS5595_EXTENT, + sis5595_driver.driver.name)) + return -EBUSY; - data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit_release; - } + data = devm_kzalloc(&pdev->dev, sizeof(struct sis5595_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; mutex_init(&data->lock); mutex_init(&data->update_lock); @@ -636,7 +633,7 @@ static int __devinit sis5595_probe(struct platform_device *pdev) /* Register sysfs hooks */ err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group); if (err) - goto exit_free; + return err; if (data->maxins == 4) { err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group_in4); if (err) @@ -659,11 +656,6 @@ static int __devinit sis5595_probe(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4); sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1); -exit_free: - kfree(data); -exit_release: - release_region(res->start, SIS5595_EXTENT); -exit: return err; } @@ -676,10 +668,6 @@ static int __devexit sis5595_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4); sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1); - release_region(data->addr, SIS5595_EXTENT); - platform_set_drvdata(pdev, NULL); - kfree(data); - return 0; } From bd91d3bab8787f53c1b937ac817b0c59f8146b97 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:23 -0700 Subject: [PATCH 43/72] hwmon: (thmc50) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/thmc50.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index add9f019b24f..080c26370480 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -361,12 +361,10 @@ static int thmc50_probe(struct i2c_client *client, struct thmc50_data *data; int err; - data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL); - if (!data) { - pr_debug("thmc50: detect failed, kzalloc failed!\n"); - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct thmc50_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->type = id->driver_data; @@ -377,7 +375,7 @@ static int thmc50_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &thmc50_group); if (err) - goto exit_free; + return err; /* Register ADM1022 sysfs hooks */ if (data->has_temp3) { @@ -400,9 +398,6 @@ static int thmc50_probe(struct i2c_client *client, sysfs_remove_group(&client->dev.kobj, &temp3_group); exit_remove_sysfs_thmc50: sysfs_remove_group(&client->dev.kobj, &thmc50_group); -exit_free: - kfree(data); -exit: return err; } @@ -415,8 +410,6 @@ static int thmc50_remove(struct i2c_client *client) if (data->has_temp3) sysfs_remove_group(&client->dev.kobj, &temp3_group); - kfree(data); - return 0; } From f511a21f4ea7d4410241e15db5cb05a287812582 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:35:52 -0700 Subject: [PATCH 44/72] hwmon: (tmp102) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/tmp102.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 0d466b9d8908..4e1ff82c63e0 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -159,17 +159,16 @@ static int __devinit tmp102_probe(struct i2c_client *client, return -ENODEV; } - tmp102 = kzalloc(sizeof(*tmp102), GFP_KERNEL); - if (!tmp102) { - dev_dbg(&client->dev, "kzalloc failed\n"); + tmp102 = devm_kzalloc(&client->dev, sizeof(*tmp102), GFP_KERNEL); + if (!tmp102) return -ENOMEM; - } + i2c_set_clientdata(client, tmp102); status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); if (status < 0) { dev_err(&client->dev, "error reading config register\n"); - goto fail_free; + return status; } tmp102->config_orig = status; status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, @@ -213,9 +212,6 @@ static int __devinit tmp102_probe(struct i2c_client *client, fail_restore_config: i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, tmp102->config_orig); -fail_free: - kfree(tmp102); - return status; } @@ -236,8 +232,6 @@ static int __devexit tmp102_remove(struct i2c_client *client) config | TMP102_CONF_SD); } - kfree(tmp102); - return 0; } From 0df9fc7bb8ced5e6fc16a0141d2ee8f6f0eea61c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:35:53 -0700 Subject: [PATCH 45/72] hwmon: (tmp401) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/tmp401.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ea54c3384671..e62054875164 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -594,7 +594,6 @@ static int tmp401_remove(struct i2c_client *client) &tmp411_attr[i].dev_attr); } - kfree(data); return 0; } @@ -605,7 +604,8 @@ static int tmp401_probe(struct i2c_client *client, struct tmp401_data *data; const char *names[] = { "TMP401", "TMP411" }; - data = kzalloc(sizeof(struct tmp401_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct tmp401_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -646,7 +646,7 @@ static int tmp401_probe(struct i2c_client *client, return 0; exit_remove: - tmp401_remove(client); /* will also free data for us */ + tmp401_remove(client); return err; } From f625e0fd513fa12cfabec9ed19f71a9bd7dd60e1 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:35:53 -0700 Subject: [PATCH 46/72] hwmon: (tmp421) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/tmp421.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 8fac87a38544..6a8ded29f1ed 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -267,7 +267,8 @@ static int tmp421_probe(struct i2c_client *client, struct tmp421_data *data; int err; - data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct tmp421_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -277,11 +278,11 @@ static int tmp421_probe(struct i2c_client *client, err = tmp421_init_client(client); if (err) - goto exit_free; + return err; err = sysfs_create_group(&client->dev.kobj, &tmp421_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -293,10 +294,6 @@ static int tmp421_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &tmp421_group); - -exit_free: - kfree(data); - return err; } @@ -307,8 +304,6 @@ static int tmp421_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &tmp421_group); - kfree(data); - return 0; } From fd55bc009aeed6265841d4c07d317ec2e557db03 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:35:54 -0700 Subject: [PATCH 47/72] hwmon: (via686a) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/via686a.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 288135d85e11..299399aa30fe 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -690,18 +690,17 @@ static int __devinit via686a_probe(struct platform_device *pdev) /* Reserve the ISA region */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, VIA686A_EXTENT, - via686a_driver.driver.name)) { + if (!devm_request_region(&pdev->dev, res->start, VIA686A_EXTENT, + via686a_driver.driver.name)) { dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", (unsigned long)res->start, (unsigned long)res->end); return -ENODEV; } - data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit_release; - } + data = devm_kzalloc(&pdev->dev, sizeof(struct via686a_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; platform_set_drvdata(pdev, data); data->addr = res->start; @@ -714,7 +713,7 @@ static int __devinit via686a_probe(struct platform_device *pdev) /* Register sysfs hooks */ err = sysfs_create_group(&pdev->dev.kobj, &via686a_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(data->hwmon_dev)) { @@ -726,10 +725,6 @@ static int __devinit via686a_probe(struct platform_device *pdev) exit_remove_files: sysfs_remove_group(&pdev->dev.kobj, &via686a_group); -exit_free: - kfree(data); -exit_release: - release_region(res->start, VIA686A_EXTENT); return err; } @@ -740,10 +735,6 @@ static int __devexit via686a_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &via686a_group); - release_region(data->addr, VIA686A_EXTENT); - platform_set_drvdata(pdev, NULL); - kfree(data); - return 0; } From 84269edce742e20a97b29619d3b9163a45a2a244 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:35:54 -0700 Subject: [PATCH 48/72] hwmon: (vt1211) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Juerg Haefliger Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/vt1211.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index c2c5c72fb8f0..f2c61153dba9 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -1148,19 +1148,18 @@ static int __devinit vt1211_probe(struct platform_device *pdev) struct resource *res; int i, err; - data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct vt1211_data), GFP_KERNEL); if (!data) { - err = -ENOMEM; dev_err(dev, "Out of memory\n"); - goto EXIT; + return -ENOMEM; } res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, resource_size(res), DRVNAME)) { - err = -EBUSY; + if (!devm_request_region(dev, res->start, resource_size(res), + DRVNAME)) { dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)res->end); - goto EXIT_KFREE; + return -EBUSY; } data->addr = res->start; data->name = DRVNAME; @@ -1215,26 +1214,15 @@ static int __devinit vt1211_probe(struct platform_device *pdev) dev_err(dev, "Sysfs interface creation failed (%d)\n", err); EXIT_DEV_REMOVE_SILENT: vt1211_remove_sysfs(pdev); - release_region(res->start, resource_size(res)); -EXIT_KFREE: - platform_set_drvdata(pdev, NULL); - kfree(data); -EXIT: return err; } static int __devexit vt1211_remove(struct platform_device *pdev) { struct vt1211_data *data = platform_get_drvdata(pdev); - struct resource *res; hwmon_device_unregister(data->hwmon_dev); vt1211_remove_sysfs(pdev); - platform_set_drvdata(pdev, NULL); - kfree(data); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, resource_size(res)); return 0; } From 0cf46997218344e6223a7874ff9433b09c12dd60 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:47:59 -0700 Subject: [PATCH 49/72] hwmon: (w83627hf) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83627hf.c | 46 ++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 5ce54a297249..ab4825205a9d 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1359,19 +1359,17 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) }; res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) { + if (!devm_request_region(dev, res->start, WINB_REGION_SIZE, DRVNAME)) { dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)(res->start + WINB_REGION_SIZE - 1)); - err = -EBUSY; - goto ERROR0; + return -EBUSY; } - data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto ERROR1; - } + data = devm_kzalloc(dev, sizeof(struct w83627hf_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + data->addr = res->start; data->type = sio_data->type; data->name = names[sio_data->type]; @@ -1391,7 +1389,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) /* Register common device attributes */ err = sysfs_create_group(&dev->kobj, &w83627hf_group); if (err) - goto ERROR3; + return err; /* Register chip-specific device attributes */ if (data->type == w83627hf || data->type == w83697hf) @@ -1419,7 +1417,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) &sensor_dev_attr_pwm1_freq.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm2_freq.dev_attr))) - goto ERROR4; + goto error; if (data->type != w83697hf) if ((err = device_create_file(dev, @@ -1454,7 +1452,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) &sensor_dev_attr_temp3_beep.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_temp3_type.dev_attr))) - goto ERROR4; + goto error; if (data->type != w83697hf && data->vid != 0xff) { /* Convert VID to voltage based on VRM */ @@ -1462,14 +1460,14 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) if ((err = device_create_file(dev, &dev_attr_cpu0_vid)) || (err = device_create_file(dev, &dev_attr_vrm))) - goto ERROR4; + goto error; } if (data->type == w83627thf || data->type == w83637hf || data->type == w83687thf) { err = device_create_file(dev, &sensor_dev_attr_pwm3.dev_attr); if (err) - goto ERROR4; + goto error; } if (data->type == w83637hf || data->type == w83687thf) @@ -1479,57 +1477,45 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) &sensor_dev_attr_pwm2_freq.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm3_freq.dev_attr))) - goto ERROR4; + goto error; if (data->type != w83627hf) if ((err = device_create_file(dev, &sensor_dev_attr_pwm1_enable.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm2_enable.dev_attr))) - goto ERROR4; + goto error; if (data->type == w83627thf || data->type == w83637hf || data->type == w83687thf) { err = device_create_file(dev, &sensor_dev_attr_pwm3_enable.dev_attr); if (err) - goto ERROR4; + goto error; } data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); - goto ERROR4; + goto error; } return 0; - ERROR4: + error: sysfs_remove_group(&dev->kobj, &w83627hf_group); sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); - ERROR3: - platform_set_drvdata(pdev, NULL); - kfree(data); - ERROR1: - release_region(res->start, WINB_REGION_SIZE); - ERROR0: return err; } static int __devexit w83627hf_remove(struct platform_device *pdev) { struct w83627hf_data *data = platform_get_drvdata(pdev); - struct resource *res; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); - platform_set_drvdata(pdev, NULL); - kfree(data); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, WINB_REGION_SIZE); return 0; } From 144d2b9985d363bd330788356b4ee8ffbf6b0363 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:48:00 -0700 Subject: [PATCH 50/72] hwmon: (w83781d) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83781d.c | 46 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index b03d54a799e3..c11452ebe18f 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1213,11 +1213,9 @@ w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id) struct w83781d_data *data; int err; - data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto ERROR1; - } + data = devm_kzalloc(dev, sizeof(struct w83781d_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->lock); @@ -1229,7 +1227,7 @@ w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id) /* attach secondary i2c lm75-like clients */ err = w83781d_detect_subclients(client); if (err) - goto ERROR3; + return err; /* Initialize the chip */ w83781d_init_device(dev); @@ -1237,25 +1235,22 @@ w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register sysfs hooks */ err = w83781d_create_files(dev, data->type, 0); if (err) - goto ERROR4; + goto exit_remove_files; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); - goto ERROR4; + goto exit_remove_files; } return 0; -ERROR4: + exit_remove_files: w83781d_remove_files(dev); if (data->lm75[0]) i2c_unregister_device(data->lm75[0]); if (data->lm75[1]) i2c_unregister_device(data->lm75[1]); -ERROR3: - kfree(data); -ERROR1: return err; } @@ -1273,8 +1268,6 @@ w83781d_remove(struct i2c_client *client) if (data->lm75[1]) i2c_unregister_device(data->lm75[1]); - kfree(data); - return 0; } @@ -1780,17 +1773,16 @@ w83781d_isa_probe(struct platform_device *pdev) /* Reserve the ISA region */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start + W83781D_ADDR_REG_OFFSET, 2, - "w83781d")) { - err = -EBUSY; - goto exit; - } + if (!devm_request_region(&pdev->dev, + res->start + W83781D_ADDR_REG_OFFSET, 2, + "w83781d")) + return -EBUSY; + + data = devm_kzalloc(&pdev->dev, sizeof(struct w83781d_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; - data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit_release_region; - } mutex_init(&data->lock); data->isa_addr = res->start; platform_set_drvdata(pdev, data); @@ -1829,10 +1821,6 @@ w83781d_isa_probe(struct platform_device *pdev) exit_remove_files: w83781d_remove_files(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_name); - kfree(data); - exit_release_region: - release_region(res->start + W83781D_ADDR_REG_OFFSET, 2); - exit: return err; } @@ -1844,8 +1832,6 @@ w83781d_isa_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); w83781d_remove_files(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_name); - release_region(data->isa_addr + W83781D_ADDR_REG_OFFSET, 2); - kfree(data); return 0; } From 140849e105fd0aadab035923f4cb454ce0518887 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:48:00 -0700 Subject: [PATCH 51/72] hwmon: (w83792d) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83792d.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index ffb5fdfecf0d..0ba5a2bd562e 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -1422,11 +1422,9 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) struct device *dev = &client->dev; int i, val1, err; - data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto ERROR0; - } + data = devm_kzalloc(dev, sizeof(struct w83792d_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->valid = 0; @@ -1434,7 +1432,7 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) err = w83792d_detect_subclients(client); if (err) - goto ERROR1; + return err; /* Initialize the chip */ w83792d_init_client(client); @@ -1448,7 +1446,7 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register sysfs hooks */ err = sysfs_create_group(&dev->kobj, &w83792d_group); if (err) - goto ERROR3; + goto exit_i2c_unregister; /* * Read GPIO enable register to check if pins for fan 4,5 are used as @@ -1493,14 +1491,11 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) sysfs_remove_group(&dev->kobj, &w83792d_group); for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]); -ERROR3: +exit_i2c_unregister: if (data->lm75[0] != NULL) i2c_unregister_device(data->lm75[0]); if (data->lm75[1] != NULL) i2c_unregister_device(data->lm75[1]); -ERROR1: - kfree(data); -ERROR0: return err; } @@ -1521,7 +1516,6 @@ w83792d_remove(struct i2c_client *client) if (data->lm75[1] != NULL) i2c_unregister_device(data->lm75[1]); - kfree(data); return 0; } From 6e13bb06f62f11797ceb5f28c392f703dc0aa548 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:52:24 -0700 Subject: [PATCH 52/72] hwmon: (w83791d) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Marc Hulsman Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83791d.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 2f446f92acf2..9ade4d4e2185 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -1384,18 +1384,17 @@ static int w83791d_probe(struct i2c_client *client, (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); #endif - data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto error0; - } + data = devm_kzalloc(&client->dev, sizeof(struct w83791d_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); err = w83791d_detect_subclients(client); if (err) - goto error1; + return err; /* Initialize the chip */ w83791d_init_client(client); @@ -1440,9 +1439,6 @@ static int w83791d_probe(struct i2c_client *client, i2c_unregister_device(data->lm75[0]); if (data->lm75[1] != NULL) i2c_unregister_device(data->lm75[1]); -error1: - kfree(data); -error0: return err; } @@ -1458,7 +1454,6 @@ static int w83791d_remove(struct i2c_client *client) if (data->lm75[1] != NULL) i2c_unregister_device(data->lm75[1]); - kfree(data); return 0; } From a0d44cbcc0b92d1dbec5dda3a5b7ea929c05d522 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 12:04:06 -0700 Subject: [PATCH 53/72] hwmon: (k8temp) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Rudolf Marek Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/k8temp.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 35aac82ee8eb..49a69c5b3b8d 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -183,21 +183,17 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, u8 model, stepping; struct k8temp_data *data; - data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&pdev->dev, sizeof(struct k8temp_data), GFP_KERNEL); + if (!data) + return -ENOMEM; model = boot_cpu_data.x86_model; stepping = boot_cpu_data.x86_mask; /* feature available since SH-C0, exclude older revisions */ - if (((model == 4) && (stepping == 0)) || - ((model == 5) && (stepping <= 1))) { - err = -ENODEV; - goto exit_free; - } + if ((model == 4 && stepping == 0) || + (model == 5 && stepping <= 1)) + return -ENODEV; /* * AMD NPT family 0fh, i.e. RevF and RevG: @@ -224,8 +220,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, if (scfg & (SEL_PLACE | SEL_CORE)) { dev_err(&pdev->dev, "Configuration bit(s) stuck at 1!\n"); - err = -ENODEV; - goto exit_free; + return -ENODEV; } scfg |= (SEL_PLACE | SEL_CORE); @@ -307,10 +302,6 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, device_remove_file(&pdev->dev, &sensor_dev_attr_temp4_input.dev_attr); device_remove_file(&pdev->dev, &dev_attr_name); -exit_free: - pci_set_drvdata(pdev, NULL); - kfree(data); -exit: return err; } @@ -328,8 +319,6 @@ static void __devexit k8temp_remove(struct pci_dev *pdev) device_remove_file(&pdev->dev, &sensor_dev_attr_temp4_input.dev_attr); device_remove_file(&pdev->dev, &dev_attr_name); - pci_set_drvdata(pdev, NULL); - kfree(data); } static struct pci_driver k8temp_driver = { From e43d5fefa7fe4e5d0999033753c15e1f30e06ff6 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 12:04:06 -0700 Subject: [PATCH 54/72] hwmon: (smsc47b397) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Mark M. Hoffman Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/smsc47b397.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index c5f6be478bad..65b07de11a0f 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -231,13 +231,9 @@ static const struct attribute_group smsc47b397_group = { static int __devexit smsc47b397_remove(struct platform_device *pdev) { struct smsc47b397_data *data = platform_get_drvdata(pdev); - struct resource *res; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, SMSC_EXTENT); - kfree(data); return 0; } @@ -261,19 +257,17 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) int err = 0; res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, SMSC_EXTENT, - smsc47b397_driver.driver.name)) { + if (!devm_request_region(dev, res->start, SMSC_EXTENT, + smsc47b397_driver.driver.name)) { dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", (unsigned long)res->start, (unsigned long)res->start + SMSC_EXTENT - 1); return -EBUSY; } - data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto error_release; - } + data = devm_kzalloc(dev, sizeof(struct smsc47b397_data), GFP_KERNEL); + if (!data) + return -ENOMEM; data->addr = res->start; data->name = "smsc47b397"; @@ -283,7 +277,7 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) err = sysfs_create_group(&dev->kobj, &smsc47b397_group); if (err) - goto error_free; + return err; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { @@ -295,10 +289,6 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) error_remove: sysfs_remove_group(&dev->kobj, &smsc47b397_group); -error_free: - kfree(data); -error_release: - release_region(res->start, SMSC_EXTENT); return err; } From 08ad7c9522c22eea1912d41ee9418154b8760ea9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 12:04:07 -0700 Subject: [PATCH 55/72] hwmon: (smsc47m1) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/smsc47m1.c | 45 ++++++++++------------------------------ 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index b5aa38dd7ab9..dba0c567e7a1 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -584,18 +584,17 @@ static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data) #define CHECK 1 #define REQUEST 2 -#define RELEASE 3 /* * This function can be used to: * - test for resource conflicts with ACPI * - request the resources - * - release the resources * We only allocate the I/O ports we really need, to minimize the risk of * conflicts with ACPI or with other drivers. */ -static int smsc47m1_handle_resources(unsigned short address, enum chips type, - int action, struct device *dev) +static int __init smsc47m1_handle_resources(unsigned short address, + enum chips type, int action, + struct device *dev) { static const u8 ports_m1[] = { /* register, region length */ @@ -642,21 +641,13 @@ static int smsc47m1_handle_resources(unsigned short address, enum chips type, break; case REQUEST: /* Request the resources */ - if (!request_region(start, len, DRVNAME)) { - dev_err(dev, "Region 0x%hx-0x%hx already in " - "use!\n", start, start + len); - - /* Undo all requests */ - for (i -= 2; i >= 0; i -= 2) - release_region(address + ports[i], - ports[i + 1]); + if (!devm_request_region(dev, start, len, DRVNAME)) { + dev_err(dev, + "Region 0x%hx-0x%hx already in use!\n", + start, start + len); return -EBUSY; } break; - case RELEASE: - /* Release the resources */ - release_region(start, len); - break; } } @@ -694,11 +685,9 @@ static int __init smsc47m1_probe(struct platform_device *pdev) if (err < 0) return err; - data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto error_release; - } + data = devm_kzalloc(dev, sizeof(struct smsc47m1_data), GFP_KERNEL); + if (!data) + return -ENOMEM; data->addr = res->start; data->type = sio_data->type; @@ -733,8 +722,7 @@ static int __init smsc47m1_probe(struct platform_device *pdev) } if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) { dev_warn(dev, "Device not configured, will not use\n"); - err = -ENODEV; - goto error_free; + return -ENODEV; } /* @@ -810,27 +798,16 @@ static int __init smsc47m1_probe(struct platform_device *pdev) error_remove_files: smsc47m1_remove_files(dev); -error_free: - platform_set_drvdata(pdev, NULL); - kfree(data); -error_release: - smsc47m1_handle_resources(res->start, sio_data->type, RELEASE, dev); return err; } static int __exit smsc47m1_remove(struct platform_device *pdev) { struct smsc47m1_data *data = platform_get_drvdata(pdev); - struct resource *res; hwmon_device_unregister(data->hwmon_dev); smsc47m1_remove_files(&pdev->dev); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - smsc47m1_handle_resources(res->start, data->type, RELEASE, &pdev->dev); - platform_set_drvdata(pdev, NULL); - kfree(data); - return 0; } From 2625996b7556f4b23ff73a8280e867372ab54bc4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 12:04:07 -0700 Subject: [PATCH 56/72] hwmon: (smsc47m192) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/smsc47m192.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 4705a8bf11c2..36a3478d0799 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -554,11 +554,10 @@ static int smsc47m192_probe(struct i2c_client *client, int config; int err; - data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct smsc47m192_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->vrm = vid_which_vrm(); @@ -570,7 +569,7 @@ static int smsc47m192_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group); if (err) - goto exit_free; + return err; /* Pin 110 is either in4 (+12V) or VID4 */ config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); @@ -592,9 +591,6 @@ static int smsc47m192_probe(struct i2c_client *client, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); -exit_free: - kfree(data); -exit: return err; } @@ -606,8 +602,6 @@ static int smsc47m192_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); - kfree(data); - return 0; } From f187fc040b31d9e7ff90be08d3140732a8450bc4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:48:01 -0700 Subject: [PATCH 57/72] hwmon: (w83l785ts) Simplify code and improve readability In probe function, rename new_client variable to client, and introduce local variable dev to point to client->dev, to simplify the code and improve readability. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83l785ts.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 5f14e3897058..6d45d23ef752 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -176,10 +176,11 @@ static int w83l785ts_detect(struct i2c_client *client, return 0; } -static int w83l785ts_probe(struct i2c_client *new_client, +static int w83l785ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct w83l785ts_data *data; + struct device *dev = &client->dev; int err = 0; data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL); @@ -188,7 +189,7 @@ static int w83l785ts_probe(struct i2c_client *new_client, goto exit; } - i2c_set_clientdata(new_client, data); + i2c_set_clientdata(client, data); data->valid = 0; mutex_init(&data->update_lock); @@ -200,18 +201,16 @@ static int w83l785ts_probe(struct i2c_client *new_client, * Nothing yet, assume it is already started. */ - err = device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); + err = device_create_file(dev, &sensor_dev_attr_temp1_input.dev_attr); if (err) goto exit_remove; - err = device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); + err = device_create_file(dev, &sensor_dev_attr_temp1_max.dev_attr); if (err) goto exit_remove; /* Register sysfs hooks */ - data->hwmon_dev = hwmon_device_register(&new_client->dev); + data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exit_remove; @@ -220,10 +219,8 @@ static int w83l785ts_probe(struct i2c_client *new_client, return 0; exit_remove: - device_remove_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); - device_remove_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); + device_remove_file(dev, &sensor_dev_attr_temp1_input.dev_attr); + device_remove_file(dev, &sensor_dev_attr_temp1_max.dev_attr); kfree(data); exit: return err; From e2730bea0b9951cb8ec0732045f59eea360f5e7c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 18 Jun 2012 08:26:05 -0700 Subject: [PATCH 58/72] hwmon: (w83l785ts) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83l785ts.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 6d45d23ef752..39dbe990dc10 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -181,13 +181,11 @@ static int w83l785ts_probe(struct i2c_client *client, { struct w83l785ts_data *data; struct device *dev = &client->dev; - int err = 0; + int err; - data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(dev, sizeof(struct w83l785ts_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->valid = 0; @@ -203,7 +201,7 @@ static int w83l785ts_probe(struct i2c_client *client, err = device_create_file(dev, &sensor_dev_attr_temp1_input.dev_attr); if (err) - goto exit_remove; + return err; err = device_create_file(dev, &sensor_dev_attr_temp1_max.dev_attr); if (err) @@ -221,8 +219,6 @@ static int w83l785ts_probe(struct i2c_client *client, exit_remove: device_remove_file(dev, &sensor_dev_attr_temp1_input.dev_attr); device_remove_file(dev, &sensor_dev_attr_temp1_max.dev_attr); - kfree(data); -exit: return err; } @@ -236,7 +232,6 @@ static int w83l785ts_remove(struct i2c_client *client) device_remove_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); - kfree(data); return 0; } From 0ef63e48f0247a9f9b9ffeef0f2641ac880728ab Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 18 Jun 2012 22:30:51 -0700 Subject: [PATCH 59/72] hwmon: (ntc_thermistor) Ensure that data->name string is terminated Fix Coverity warning: Calling strncpy with a maximum size argument of 20 bytes on destination array "data->name" of size 20 bytes might leave the destination string unterminated. Fix by replacing strncpy() with strlcpy() and by using sizeof() to determine the maximum string length. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/ntc_thermistor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 6da9696e1827..74a6c58d0218 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -351,7 +351,7 @@ static int __devinit ntc_thermistor_probe(struct platform_device *pdev) data->dev = &pdev->dev; data->pdata = pdata; - strncpy(data->name, pdev->id_entry->name, PLATFORM_NAME_SIZE); + strlcpy(data->name, pdev->id_entry->name, sizeof(data->name)); switch (pdev->id_entry->driver_data) { case TYPE_NCPXXWB473: From edf48f3a73b027a99c92edab2b07d78fe77523cc Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 20 Jun 2012 18:00:06 +0200 Subject: [PATCH 60/72] hwmon: (applesmc) Skip sensor mapping The special motion sensor mapping is unnecessary; remove it. Signed-off-by: Henrik Rydberg Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 41 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 2cde9ecf7731..0162f5527805 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -96,10 +96,6 @@ static const char *const fan_speed_fmt[] = { #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */ #define APPLESMC_INPUT_FLAT 4 -#define SENSOR_X 0 -#define SENSOR_Y 1 -#define SENSOR_Z 2 - #define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff) #define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16) @@ -432,30 +428,19 @@ static int applesmc_has_key(const char *key, bool *value) } /* - * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). + * applesmc_read_s16 - Read 16-bit signed big endian register */ -static int applesmc_read_motion_sensor(int index, s16 *value) +static int applesmc_read_s16(const char *key, s16 *value) { u8 buffer[2]; int ret; - switch (index) { - case SENSOR_X: - ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2); - break; - case SENSOR_Y: - ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2); - break; - case SENSOR_Z: - ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2); - break; - default: - ret = -EINVAL; - } + ret = applesmc_read_key(key, buffer, 2); + if (ret) + return ret; *value = ((s16)buffer[0] << 8) | buffer[1]; - - return ret; + return 0; } /* @@ -624,8 +609,8 @@ static struct platform_driver applesmc_driver = { */ static void applesmc_calibrate(void) { - applesmc_read_motion_sensor(SENSOR_X, &rest_x); - applesmc_read_motion_sensor(SENSOR_Y, &rest_y); + applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x); + applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y); rest_x = -rest_x; } @@ -634,9 +619,9 @@ static void applesmc_idev_poll(struct input_polled_dev *dev) struct input_dev *idev = dev->input; s16 x, y; - if (applesmc_read_motion_sensor(SENSOR_X, &x)) + if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x)) return; - if (applesmc_read_motion_sensor(SENSOR_Y, &y)) + if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y)) return; x = -x; @@ -659,13 +644,13 @@ static ssize_t applesmc_position_show(struct device *dev, int ret; s16 x, y, z; - ret = applesmc_read_motion_sensor(SENSOR_X, &x); + ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x); if (ret) goto out; - ret = applesmc_read_motion_sensor(SENSOR_Y, &y); + ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y); if (ret) goto out; - ret = applesmc_read_motion_sensor(SENSOR_Z, &z); + ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z); if (ret) goto out; From 27f8b1355504744e7cfbb5756f120734d58644a8 Mon Sep 17 00:00:00 2001 From: Iain Paton Date: Wed, 27 Jun 2012 08:55:11 +0000 Subject: [PATCH 61/72] hwmon: Honeywell Humidicon HIH-6130/HIH-6131 humidity and temperature sensor driver This is a new driver for the Honeywell Humidicon HIH-6130/HIH-6131 humidity sensor. The driver is based on the existing Sensiron sht21 driver with the necessary changes to the probe, update_measurements and conversion functions necessary to use the Honeywell sensors. There's no difference between the 6130 & 6131 other than the 6131 having an external condensation filter attached. Signed-off-by: Iain Paton Signed-off-by: Guenter Roeck --- Documentation/hwmon/hih6130 | 37 +++++ drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/hih6130.c | 293 ++++++++++++++++++++++++++++++++++++ 4 files changed, 341 insertions(+) create mode 100644 Documentation/hwmon/hih6130 create mode 100644 drivers/hwmon/hih6130.c diff --git a/Documentation/hwmon/hih6130 b/Documentation/hwmon/hih6130 new file mode 100644 index 000000000000..73dae918ea7b --- /dev/null +++ b/Documentation/hwmon/hih6130 @@ -0,0 +1,37 @@ +Kernel driver hih6130 +===================== + +Supported chips: + * Honeywell HIH-6130 / HIH-6131 + Prefix: 'hih6130' + Addresses scanned: none + Datasheet: Publicly available at the Honeywell website + http://sensing.honeywell.com/index.php?ci_id=3106&la_id=1&defId=44872 + +Author: + Iain Paton + +Description +----------- + +The HIH-6130 & HIH-6131 are humidity and temperature sensors in a SO8 package. +The difference between the two devices is that the HIH-6131 has a condensation +filter. + +The devices communicate with the I2C protocol. All sensors are set to the same +I2C address 0x27 by default, so an entry with I2C_BOARD_INFO("hih6130", 0x27) +can be used in the board setup code. + +Please see Documentation/i2c/instantiating-devices for details on how to +instantiate I2C devices. + +sysfs-Interface +--------------- + +temp1_input - temperature input +humidity1_input - humidity input + +Notes +----- + +Command mode and alarms are not currently supported. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 40393535563d..b0a2e4c37e12 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -443,6 +443,16 @@ config SENSORS_GPIO_FAN This driver can also be built as a module. If so, the module will be called gpio-fan. +config SENSORS_HIH6130 + tristate "Honeywell Humidicon HIH-6130 humidity/temperature sensor" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for Honeywell Humidicon + HIH-6130 and HIH-6131 Humidicon humidity sensors. + + This driver can also be built as a module. If so, the module + will be called hih6130. + config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" depends on X86 && PCI && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 2f4c00116f1e..7aa98119c4ab 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_SENSORS_G760A) += g760a.o obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o +obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c new file mode 100644 index 000000000000..e8ee75f55472 --- /dev/null +++ b/drivers/hwmon/hih6130.c @@ -0,0 +1,293 @@ +/* Honeywell HIH-6130/HIH-6131 humidity and temperature sensor driver + * + * Copyright (C) 2012 Iain Paton + * + * heavily based on the sht21 driver + * Copyright (C) 2010 Urs Fleisch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA + * + * Data sheets available (2012-06-22) at + * http://sensing.honeywell.com/index.php?ci_id=3106&la_id=1&defId=44872 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct hih6130 - HIH-6130 device specific data + * @hwmon_dev: device registered with hwmon + * @lock: mutex to protect measurement values + * @valid: only false before first measurement is taken + * @last_update: time of last update (jiffies) + * @temperature: cached temperature measurement value + * @humidity: cached humidity measurement value + */ +struct hih6130 { + struct device *hwmon_dev; + struct mutex lock; + bool valid; + unsigned long last_update; + int temperature; + int humidity; +}; + +/** + * hih6130_temp_ticks_to_millicelsius() - convert raw temperature ticks to + * milli celsius + * @ticks: temperature ticks value received from sensor + */ +static inline int hih6130_temp_ticks_to_millicelsius(int ticks) +{ + + ticks = ticks >> 2; + /* + * from data sheet section 5.0 + * Formula T = ( ticks / ( 2^14 - 2 ) ) * 165 -40 + */ + return (DIV_ROUND_CLOSEST(ticks * 1650, 16382) - 400) * 100; +} + +/** + * hih6130_rh_ticks_to_per_cent_mille() - convert raw humidity ticks to + * one-thousandths of a percent relative humidity + * @ticks: humidity ticks value received from sensor + */ +static inline int hih6130_rh_ticks_to_per_cent_mille(int ticks) +{ + + ticks &= ~0xC000; /* clear status bits */ + /* + * from data sheet section 4.0 + * Formula RH = ( ticks / ( 2^14 -2 ) ) * 100 + */ + return DIV_ROUND_CLOSEST(ticks * 1000, 16382) * 100; +} + +/** + * hih6130_update_measurements() - get updated measurements from device + * @client: I2C client device + * + * Returns 0 on success, else negative errno. + */ +static int hih6130_update_measurements(struct i2c_client *client) +{ + int ret = 0; + int t; + struct hih6130 *hih6130 = i2c_get_clientdata(client); + unsigned char tmp[4]; + struct i2c_msg msgs[1] = { + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 4, + .buf = tmp, + } + }; + + mutex_lock(&hih6130->lock); + + /* + * While the measurement can be completed in ~40ms the sensor takes + * much longer to react to a change in external conditions. How quickly + * it reacts depends on airflow and other factors outwith our control. + * The datasheet specifies maximum 'Response time' for humidity at 8s + * and temperature at 30s under specified conditions. + * We therefore choose to only read the sensor at most once per second. + * This trades off pointless activity polling the sensor much faster + * than it can react against better response times in conditions more + * favourable than specified in the datasheet. + */ + if (time_after(jiffies, hih6130->last_update + HZ) || !hih6130->valid) { + + /* write to slave address, no data, to request a measurement */ + ret = i2c_master_send(client, tmp, 0); + if (ret < 0) + goto out; + + /* measurement cycle time is ~36.65msec */ + msleep(40); + + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) + goto out; + + if ((tmp[0] & 0xC0) != 0) { + dev_err(&client->dev, "Error while reading measurement result\n"); + ret = -EIO; + goto out; + } + + t = (tmp[0] << 8) + tmp[1]; + hih6130->humidity = hih6130_rh_ticks_to_per_cent_mille(t); + + t = (tmp[2] << 8) + tmp[3]; + hih6130->temperature = hih6130_temp_ticks_to_millicelsius(t); + + hih6130->last_update = jiffies; + hih6130->valid = true; + } +out: + mutex_unlock(&hih6130->lock); + + return ret >= 0 ? 0 : ret; +} + +/** + * hih6130_show_temperature() - show temperature measurement value in sysfs + * @dev: device + * @attr: device attribute + * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to + * + * Will be called on read access to temp1_input sysfs attribute. + * Returns number of bytes written into buffer, negative errno on error. + */ +static ssize_t hih6130_show_temperature(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct hih6130 *hih6130 = i2c_get_clientdata(client); + int ret = hih6130_update_measurements(client); + if (ret < 0) + return ret; + return sprintf(buf, "%d\n", hih6130->temperature); +} + +/** + * hih6130_show_humidity() - show humidity measurement value in sysfs + * @dev: device + * @attr: device attribute + * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to + * + * Will be called on read access to humidity1_input sysfs attribute. + * Returns number of bytes written into buffer, negative errno on error. + */ +static ssize_t hih6130_show_humidity(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct hih6130 *hih6130 = i2c_get_clientdata(client); + int ret = hih6130_update_measurements(client); + if (ret < 0) + return ret; + return sprintf(buf, "%d\n", hih6130->humidity); +} + +/* sysfs attributes */ +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, hih6130_show_temperature, + NULL, 0); +static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, hih6130_show_humidity, + NULL, 0); + +static struct attribute *hih6130_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_humidity1_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group hih6130_attr_group = { + .attrs = hih6130_attributes, +}; + +/** + * hih6130_probe() - probe device + * @client: I2C client device + * @id: device ID + * + * Called by the I2C core when an entry in the ID table matches a + * device's name. + * Returns 0 on success. + */ +static int __devinit hih6130_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct hih6130 *hih6130; + int err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "adapter does not support true I2C\n"); + return -ENODEV; + } + + hih6130 = devm_kzalloc(&client->dev, sizeof(*hih6130), GFP_KERNEL); + if (!hih6130) + return -ENOMEM; + + i2c_set_clientdata(client, hih6130); + + mutex_init(&hih6130->lock); + + err = sysfs_create_group(&client->dev.kobj, &hih6130_attr_group); + if (err) { + dev_dbg(&client->dev, "could not create sysfs files\n"); + return err; + } + + hih6130->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(hih6130->hwmon_dev)) { + dev_dbg(&client->dev, "unable to register hwmon device\n"); + err = PTR_ERR(hih6130->hwmon_dev); + goto fail_remove_sysfs; + } + + return 0; + +fail_remove_sysfs: + sysfs_remove_group(&client->dev.kobj, &hih6130_attr_group); + return err; +} + +/** + * hih6130_remove() - remove device + * @client: I2C client device + */ +static int __devexit hih6130_remove(struct i2c_client *client) +{ + struct hih6130 *hih6130 = i2c_get_clientdata(client); + + hwmon_device_unregister(hih6130->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &hih6130_attr_group); + + return 0; +} + +/* Device ID table */ +static const struct i2c_device_id hih6130_id[] = { + { "hih6130", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, hih6130_id); + +static struct i2c_driver hih6130_driver = { + .driver.name = "hih6130", + .probe = hih6130_probe, + .remove = __devexit_p(hih6130_remove), + .id_table = hih6130_id, +}; + +module_i2c_driver(hih6130_driver); + +MODULE_AUTHOR("Iain Paton "); +MODULE_DESCRIPTION("Honeywell HIH-6130 humidity and temperature sensor driver"); +MODULE_LICENSE("GPL"); From 27c4db3996ef0d27fb25e6991ebf6e507a920937 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 18 Jun 2012 22:37:13 -0700 Subject: [PATCH 62/72] hwmon: (acpi_power_meter) Cleanup and optimizations An unsigned value can not be smaller than 0. Remove the check for it. Use DIV_ROUND_CLOSEST for divide operations converting milli-degrees C into degrees C. Limit maximum accepted trip point temperature to INT_MAX. This patch fixes Coverity #115214: Unsigned compared against 0 Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/acpi_power_meter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 34ad5a27a7e9..9a0821f1c914 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -237,7 +237,7 @@ static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, if (res) return res; - temp /= 1000; + temp = DIV_ROUND_CLOSEST(temp, 1000); if (temp > resource->caps.max_cap || temp < resource->caps.min_cap) return -EINVAL; arg0.integer.value = temp; @@ -307,8 +307,8 @@ static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, if (res) return res; - temp /= 1000; - if (temp < 0) + temp = DIV_ROUND_CLOSEST(temp, 1000); + if (temp > INT_MAX) return -EINVAL; mutex_lock(&resource->lock); From 75311bea569d7ea77a5a3c5395bae27bb8a2df96 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 21 Jun 2012 06:21:05 -0700 Subject: [PATCH 63/72] hwmon: (acpi_power_meter) Fix unintentional integer overflow Expression with two integer variables is calculated as integer before it is converted to u64. This may result in an integer overflow. Fix by declaring trip point variables as s64 instead of int. This patch addresses Coverity #200596: Unintentional integer overflow. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/acpi_power_meter.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 9a0821f1c914..5363da5f4d85 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -101,7 +101,7 @@ struct acpi_power_meter_resource { unsigned long sensors_last_updated; struct sensor_device_attribute sensors[NUM_SENSORS]; int num_sensors; - int trip[2]; + s64 trip[2]; int num_domain_devices; struct acpi_device **domain_devices; struct kobject *holders_dir; @@ -308,8 +308,6 @@ static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, return res; temp = DIV_ROUND_CLOSEST(temp, 1000); - if (temp > INT_MAX) - return -EINVAL; mutex_lock(&resource->lock); resource->trip[attr->index - 7] = temp; From 4f0928c6652d8b512f81002ebf66ef0b22cf1af4 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 7 Jul 2012 23:59:12 +0200 Subject: [PATCH 64/72] hwmon: (abituguru) Use struct dev_pm_ops for power management Make the Abit uGuru driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki [linux@roeck-us.net: CONFIG_PM->CONFIG_PM_SLEEP, and remove unnecessary ()] Signed-off-by: Guenter Roeck --- drivers/hwmon/abituguru.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index a72bf25601a4..d4419b47f3d4 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1513,10 +1513,10 @@ static struct abituguru_data *abituguru_update_device(struct device *dev) return NULL; } -#ifdef CONFIG_PM -static int abituguru_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int abituguru_suspend(struct device *dev) { - struct abituguru_data *data = platform_get_drvdata(pdev); + struct abituguru_data *data = dev_get_drvdata(dev); /* * make sure all communications with the uguru are done and no new * ones are started @@ -1525,29 +1525,30 @@ static int abituguru_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int abituguru_resume(struct platform_device *pdev) +static int abituguru_resume(struct device *dev) { - struct abituguru_data *data = platform_get_drvdata(pdev); + struct abituguru_data *data = dev_get_drvdata(dev); /* See if the uGuru is still ready */ if (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) data->uguru_ready = 0; mutex_unlock(&data->update_lock); return 0; } + +static SIMPLE_DEV_PM_OPS(abituguru_pm, abituguru_suspend, abituguru_resume); +#define ABIT_UGURU_PM &abituguru_pm #else -#define abituguru_suspend NULL -#define abituguru_resume NULL +#define ABIT_UGURU_PM NULL #endif /* CONFIG_PM */ static struct platform_driver abituguru_driver = { .driver = { .owner = THIS_MODULE, .name = ABIT_UGURU_NAME, + .pm = ABIT_UGURU_PM, }, .probe = abituguru_probe, .remove = __devexit_p(abituguru_remove), - .suspend = abituguru_suspend, - .resume = abituguru_resume, }; static int __init abituguru_detect(void) From c248f24cffc3d6692f428ccc9f2ba76cea1fa6ab Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 8 Jul 2012 00:00:01 +0200 Subject: [PATCH 65/72] hwmon: (abituguru3) Use struct dev_pm_ops for power management Make the Abit uGuru rev. 3 driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki [linux@roeck-us.net: CONFIG_PM->CONFIG_PM_SLEEP, and remove unnecessary ()] Signed-off-by: Guenter Roeck --- drivers/hwmon/abituguru3.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index a5bc4287daa6..5d582aebff87 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -1141,10 +1141,10 @@ static struct abituguru3_data *abituguru3_update_device(struct device *dev) return NULL; } -#ifdef CONFIG_PM -static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int abituguru3_suspend(struct device *dev) { - struct abituguru3_data *data = platform_get_drvdata(pdev); + struct abituguru3_data *data = dev_get_drvdata(dev); /* * make sure all communications with the uguru3 are done and no new * ones are started @@ -1153,26 +1153,27 @@ static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int abituguru3_resume(struct platform_device *pdev) +static int abituguru3_resume(struct device *dev) { - struct abituguru3_data *data = platform_get_drvdata(pdev); + struct abituguru3_data *data = dev_get_drvdata(dev); mutex_unlock(&data->update_lock); return 0; } + +static SIMPLE_DEV_PM_OPS(abituguru3_pm, abituguru3_suspend, abituguru3_resume); +#define ABIT_UGURU3_PM &abituguru3_pm #else -#define abituguru3_suspend NULL -#define abituguru3_resume NULL +#define ABIT_UGURU3_PM NULL #endif /* CONFIG_PM */ static struct platform_driver abituguru3_driver = { .driver = { .owner = THIS_MODULE, .name = ABIT_UGURU3_NAME, + .pm = ABIT_UGURU3_PM }, .probe = abituguru3_probe, .remove = __devexit_p(abituguru3_remove), - .suspend = abituguru3_suspend, - .resume = abituguru3_resume }; static int __init abituguru3_dmi_detect(void) From 6d20a6c060c41a7a9c8f5bd4b9d44b8f13b78694 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 8 Jul 2012 00:01:03 +0200 Subject: [PATCH 66/72] hwmon: (gpio-fan) Use struct dev_pm_ops for power management Make the gpio-fan driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki [linux@roeck-us.net: CONFIG_PM->CONFIG_PM_SLEEP, and remove unnecessary ()] Signed-off-by: Guenter Roeck --- drivers/hwmon/gpio-fan.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index b90b3e9617b0..2f4b01bda87c 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -41,7 +41,7 @@ struct gpio_fan_data { int num_speed; struct gpio_fan_speed *speed; int speed_index; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP int resume_speed; #endif bool pwm_enable; @@ -476,10 +476,10 @@ static int __devexit gpio_fan_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int gpio_fan_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int gpio_fan_suspend(struct device *dev) { - struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); + struct gpio_fan_data *fan_data = dev_get_drvdata(dev); if (fan_data->ctrl) { fan_data->resume_speed = fan_data->speed_index; @@ -489,27 +489,28 @@ static int gpio_fan_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int gpio_fan_resume(struct platform_device *pdev) +static int gpio_fan_resume(struct device *dev) { - struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); + struct gpio_fan_data *fan_data = dev_get_drvdata(dev); if (fan_data->ctrl) set_fan_speed(fan_data, fan_data->resume_speed); return 0; } + +static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); +#define GPIO_FAN_PM &gpio_fan_pm #else -#define gpio_fan_suspend NULL -#define gpio_fan_resume NULL +#define GPIO_FAN_PM NULL #endif static struct platform_driver gpio_fan_driver = { .probe = gpio_fan_probe, .remove = __devexit_p(gpio_fan_remove), - .suspend = gpio_fan_suspend, - .resume = gpio_fan_resume, .driver = { .name = "gpio-fan", + .pm = GPIO_FAN_PM, }, }; From 08cd6753d96aebcceebe10800fede1e4830e2a48 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 8 Jul 2012 21:48:15 +0200 Subject: [PATCH 67/72] hwmon: (exynos4_tmu) Use struct dev_pm_ops for power management Make the Exynos4 TMU driver define its PM callbacks through a struct dev_pm_ops object rather than by using legacy PM hooks in struct platform_driver. Signed-off-by: Rafael J. Wysocki [linux@roeck-us.net: CONFIG_PM->CONFIG_PM_SLEEP, and remove unnecessary ()] Signed-off-by: Guenter Roeck --- drivers/hwmon/exynos4_tmu.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/exynos4_tmu.c b/drivers/hwmon/exynos4_tmu.c index f2359a0093bd..e912059140cd 100644 --- a/drivers/hwmon/exynos4_tmu.c +++ b/drivers/hwmon/exynos4_tmu.c @@ -475,35 +475,39 @@ static int __devexit exynos4_tmu_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int exynos4_tmu_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int exynos4_tmu_suspend(struct device *dev) { - exynos4_tmu_control(pdev, false); + exynos4_tmu_control(to_platform_device(dev), false); return 0; } -static int exynos4_tmu_resume(struct platform_device *pdev) +static int exynos4_tmu_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); + exynos4_tmu_initialize(pdev); exynos4_tmu_control(pdev, true); return 0; } + +static SIMPLE_DEV_PM_OPS(exynos4_tmu_pm, + exynos4_tmu_suspend, exynos4_tmu_resume); +#define EXYNOS4_TMU_PM &exynos4_tmu_pm #else -#define exynos4_tmu_suspend NULL -#define exynos4_tmu_resume NULL +#define EXYNOS4_TMU_PM NULL #endif static struct platform_driver exynos4_tmu_driver = { .driver = { .name = "exynos4-tmu", .owner = THIS_MODULE, + .pm = EXYNOS4_TMU_PM, }, .probe = exynos4_tmu_probe, .remove = __devexit_p(exynos4_tmu_remove), - .suspend = exynos4_tmu_suspend, - .resume = exynos4_tmu_resume, }; module_platform_driver(exynos4_tmu_driver); From a332bf9a65ab34b01226ed177f6937af843c8465 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 9 Jul 2012 12:10:26 +0200 Subject: [PATCH 68/72] hwmon: (applesmc) Shorten minimum wait time The 2012 series of MacBooks have a faster SMC, and the current driver timings do not work at all. Tests show that decreasing the minimum wait time, from 64 us to 16 us, works well. Since this is still larger than the original minimum of 10 us used before 2008, there is nothing inherently problematic with changing it. The fail frequency on older machines seems to increase slightly, but not enough to be noticeable. Tested on MBA11, MBA31, MBA5,2, MBP9,2. The patch was originally written by adamski99 (ubuntuforums.org) and later tested by janhouse (bbs.archlinux.org). Signed-off-by: Henrik Rydberg Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 0162f5527805..f41585ecbe2b 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -54,7 +54,7 @@ #define APPLESMC_MAX_DATA_LENGTH 32 /* wait up to 32 ms for a status change. */ -#define APPLESMC_MIN_WAIT 0x0040 +#define APPLESMC_MIN_WAIT 0x0010 #define APPLESMC_MAX_WAIT 0x8000 #define APPLESMC_STATUS_MASK 0x0f From bbc8a569ae91e0951f4b7f8eb33ef1970bf2129c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 12 Jun 2012 08:27:49 -0700 Subject: [PATCH 69/72] hwmon: (w83781d) Fix compile warning The following compile warning may be seen if the driver is compiled with -Wuninitialized: drivers/hwmon/w83781d.c: warning: 'sc_addr[1]' may be used uninitialized in this function [-Wuninitialized] While this is a false positive, it is annoying in nightly builds, and may help to conceal real problems. The current code is quite tricky, and and it is easy to rearrage the code to make the warning disappear. So fix it. Cc: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/w83781d.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index c11452ebe18f..5a5046d94c3e 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -867,6 +867,7 @@ w83781d_detect_subclients(struct i2c_client *new_client) struct i2c_adapter *adapter = new_client->adapter; struct w83781d_data *data = i2c_get_clientdata(new_client); enum chips kind = data->type; + int num_sc = 1; id = i2c_adapter_id(adapter); @@ -891,6 +892,7 @@ w83781d_detect_subclients(struct i2c_client *new_client) } if (kind != w83783s) { + num_sc = 2; if (force_subclients[0] == id && force_subclients[1] == address) { sc_addr[1] = force_subclients[3]; @@ -906,7 +908,7 @@ w83781d_detect_subclients(struct i2c_client *new_client) } } - for (i = 0; i <= 1; i++) { + for (i = 0; i < num_sc; i++) { data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]); if (!data->lm75[i]) { dev_err(&new_client->dev, "Subclient %d " @@ -917,8 +919,6 @@ w83781d_detect_subclients(struct i2c_client *new_client) goto ERROR_SC_3; goto ERROR_SC_2; } - if (kind == w83783s) - break; } return 0; From 41bf870e6db130c6e467c70b6da96398066b8be7 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 13 Jul 2012 14:36:28 +0530 Subject: [PATCH 70/72] hwmon: (s3c-hwmon) Use devm_kzalloc instead of kzalloc This makes the code simpler as explicit freeing is not needed. Signed-off-by: Sachin Kamat Signed-off-by: Guenter Roeck --- drivers/hwmon/s3c-hwmon.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index f6c26d19f521..b7975f858cff 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c @@ -288,7 +288,7 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev) return -EINVAL; } - hwmon = kzalloc(sizeof(struct s3c_hwmon), GFP_KERNEL); + hwmon = devm_kzalloc(&dev->dev, sizeof(struct s3c_hwmon), GFP_KERNEL); if (hwmon == NULL) { dev_err(&dev->dev, "no memory\n"); return -ENOMEM; @@ -303,8 +303,7 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev) hwmon->client = s3c_adc_register(dev, NULL, NULL, 0); if (IS_ERR(hwmon->client)) { dev_err(&dev->dev, "cannot register adc\n"); - ret = PTR_ERR(hwmon->client); - goto err_mem; + return PTR_ERR(hwmon->client); } /* add attributes for our adc devices. */ @@ -363,8 +362,6 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev) err_registered: s3c_adc_release(hwmon->client); - err_mem: - kfree(hwmon); return ret; } From b6e5122f09272cb30c2e1fc1d80a40bfa6e87757 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 16 Jul 2012 09:18:10 +0200 Subject: [PATCH 71/72] hwmon: (applesmc) Allow negative temperature values There are many userland reports of sensors with unreasonably small and large temperatures. There seem to be several reasons for this: Firstly, the major sensor type (sp78) is actually a signed number. This explains why some sensors show very small or large values - they are in fact all small, but of different sign. Secondly, the other sensor type (1-hex) is not properly understood; it may be that it is not a temperature after all. Thirdly, some sensors are differential in nature, showing changes over time rather than absolute numbers. This explains why those values are small and of varying sign. This patch interprets the sp78 type as signed short, but keeps the original scaling. For other types, -EINVAL is returned, since the nature of those sensors is unknown. Signed-off-by: Henrik Rydberg Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f41585ecbe2b..75f87f125dac 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -80,6 +80,8 @@ #define FANS_MANUAL "FS! " /* r-w ui16 */ #define FAN_ID_FMT "F%dID" /* r-o char[16] */ +#define TEMP_SENSOR_TYPE "sp78" + /* List of keys used to read/write fan speeds */ static const char *const fan_speed_fmt[] = { "F%dAc", /* actual speed */ @@ -720,27 +722,22 @@ static ssize_t applesmc_show_temperature(struct device *dev, int index = smcreg.temp_begin + to_index(devattr); const struct applesmc_entry *entry; int ret; - u8 buffer[2]; - unsigned int temp; + s16 value; + int temp; entry = applesmc_get_entry_by_index(index); if (IS_ERR(entry)) return PTR_ERR(entry); - if (entry->len > 2) + if (strcmp(entry->type, TEMP_SENSOR_TYPE)) return -EINVAL; - ret = applesmc_read_entry(entry, buffer, entry->len); + ret = applesmc_read_s16(entry->key, &value); if (ret) return ret; - if (entry->len == 2) { - temp = buffer[0] * 1000; - temp += (buffer[1] >> 6) * 250; - } else { - temp = buffer[0] * 4000; - } + temp = 250 * (value >> 6); - return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", temp); } static ssize_t applesmc_show_fan_speed(struct device *dev, From e30bca12573fbf54e2470723aadc047549d147ce Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 16 Jul 2012 09:18:11 +0200 Subject: [PATCH 72/72] hwmon: (applesmc) Ignore some temperature registers Not all sensors in the T range are useful temperatures. This patch creates a subset of sensors to be exported to userland, excluding the unknown types. Signed-off-by: Henrik Rydberg Signed-off-by: Guenter Roeck --- drivers/hwmon/applesmc.c | 75 +++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 75f87f125dac..4d937a18fadb 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -133,11 +133,13 @@ static struct applesmc_registers { unsigned int temp_count; /* number of temperature registers */ unsigned int temp_begin; /* temperature lower index bound */ unsigned int temp_end; /* temperature upper index bound */ + unsigned int index_count; /* size of temperature index array */ int num_light_sensors; /* number of light sensors */ bool has_accelerometer; /* has motion sensor */ bool has_key_backlight; /* has keyboard backlight */ bool init_complete; /* true when fully initialized */ struct applesmc_entry *cache; /* cached key entries */ + const char **index; /* temperature key index */ } smcreg = { .mutex = __MUTEX_INITIALIZER(smcreg.mutex), }; @@ -469,6 +471,30 @@ static void applesmc_device_init(void) pr_warn("failed to init the device\n"); } +static int applesmc_init_index(struct applesmc_registers *s) +{ + const struct applesmc_entry *entry; + unsigned int i; + + if (s->index) + return 0; + + s->index = kcalloc(s->temp_count, sizeof(s->index[0]), GFP_KERNEL); + if (!s->index) + return -ENOMEM; + + for (i = s->temp_begin; i < s->temp_end; i++) { + entry = applesmc_get_entry_by_index(i); + if (IS_ERR(entry)) + continue; + if (strcmp(entry->type, TEMP_SENSOR_TYPE)) + continue; + s->index[s->index_count++] = entry->key; + } + + return 0; +} + /* * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. */ @@ -504,6 +530,10 @@ static int applesmc_init_smcreg_try(void) return ret; s->temp_count = s->temp_end - s->temp_begin; + ret = applesmc_init_index(s); + if (ret) + return ret; + ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); if (ret) return ret; @@ -520,8 +550,8 @@ static int applesmc_init_smcreg_try(void) s->num_light_sensors = left_light_sensor + right_light_sensor; s->init_complete = true; - pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n", - s->key_count, s->fan_count, s->temp_count, + pr_info("key=%d fan=%d temp=%d index=%d acc=%d lux=%d kbd=%d\n", + s->key_count, s->fan_count, s->temp_count, s->index_count, s->has_accelerometer, s->num_light_sensors, s->has_key_backlight); @@ -529,6 +559,15 @@ static int applesmc_init_smcreg_try(void) return 0; } +static void applesmc_destroy_smcreg(void) +{ + kfree(smcreg.index); + smcreg.index = NULL; + kfree(smcreg.cache); + smcreg.cache = NULL; + smcreg.init_complete = false; +} + /* * applesmc_init_smcreg - Initialize register cache. * @@ -549,19 +588,11 @@ static int applesmc_init_smcreg(void) msleep(INIT_WAIT_MSECS); } - kfree(smcreg.cache); - smcreg.cache = NULL; + applesmc_destroy_smcreg(); return ret; } -static void applesmc_destroy_smcreg(void) -{ - kfree(smcreg.cache); - smcreg.cache = NULL; - smcreg.init_complete = false; -} - /* Device model stuff */ static int applesmc_probe(struct platform_device *dev) { @@ -705,33 +736,21 @@ static ssize_t applesmc_light_show(struct device *dev, static ssize_t applesmc_show_sensor_label(struct device *dev, struct device_attribute *devattr, char *sysfsbuf) { - int index = smcreg.temp_begin + to_index(devattr); - const struct applesmc_entry *entry; + const char *key = smcreg.index[to_index(devattr)]; - entry = applesmc_get_entry_by_index(index); - if (IS_ERR(entry)) - return PTR_ERR(entry); - - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key); + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); } /* Displays degree Celsius * 1000 */ static ssize_t applesmc_show_temperature(struct device *dev, struct device_attribute *devattr, char *sysfsbuf) { - int index = smcreg.temp_begin + to_index(devattr); - const struct applesmc_entry *entry; + const char *key = smcreg.index[to_index(devattr)]; int ret; s16 value; int temp; - entry = applesmc_get_entry_by_index(index); - if (IS_ERR(entry)) - return PTR_ERR(entry); - if (strcmp(entry->type, TEMP_SENSOR_TYPE)) - return -EINVAL; - - ret = applesmc_read_s16(entry->key, &value); + ret = applesmc_read_s16(key, &value); if (ret) return ret; @@ -1247,7 +1266,7 @@ static int __init applesmc_init(void) if (ret) goto out_info; - ret = applesmc_create_nodes(temp_group, smcreg.temp_count); + ret = applesmc_create_nodes(temp_group, smcreg.index_count); if (ret) goto out_fans;