summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/da905261
-rw-r--r--Documentation/hwmon/hih613037
-rw-r--r--Documentation/hwmon/submitting-patches3
-rw-r--r--drivers/hwmon/Kconfig20
-rw-r--r--drivers/hwmon/Makefile2
-rw-r--r--drivers/hwmon/abituguru.c19
-rw-r--r--drivers/hwmon/abituguru3.c19
-rw-r--r--drivers/hwmon/acpi_power_meter.c8
-rw-r--r--drivers/hwmon/adm1021.c18
-rw-r--r--drivers/hwmon/adm1025.c15
-rw-r--r--drivers/hwmon/adm1026.c15
-rw-r--r--drivers/hwmon/adm1031.c15
-rw-r--r--drivers/hwmon/adm9240.c14
-rw-r--r--drivers/hwmon/adt7475.c7
-rw-r--r--drivers/hwmon/applesmc.c133
-rw-r--r--drivers/hwmon/asc7621.c5
-rw-r--r--drivers/hwmon/atxp1.c16
-rw-r--r--drivers/hwmon/da9052-hwmon.c344
-rw-r--r--drivers/hwmon/ds1621.c16
-rw-r--r--drivers/hwmon/emc6w201.c15
-rw-r--r--drivers/hwmon/exynos4_tmu.c20
-rw-r--r--drivers/hwmon/f71805f.c26
-rw-r--r--drivers/hwmon/fam15h_power.c3
-rw-r--r--drivers/hwmon/gl518sm.c15
-rw-r--r--drivers/hwmon/gl520sm.c15
-rw-r--r--drivers/hwmon/gpio-fan.c77
-rw-r--r--drivers/hwmon/hih6130.c293
-rw-r--r--drivers/hwmon/k8temp.c25
-rw-r--r--drivers/hwmon/lm63.c14
-rw-r--r--drivers/hwmon/lm75.c9
-rw-r--r--drivers/hwmon/lm77.c73
-rw-r--r--drivers/hwmon/lm78.c36
-rw-r--r--drivers/hwmon/lm80.c14
-rw-r--r--drivers/hwmon/lm83.c15
-rw-r--r--drivers/hwmon/lm85.c7
-rw-r--r--drivers/hwmon/lm87.c15
-rw-r--r--drivers/hwmon/lm90.c12
-rw-r--r--drivers/hwmon/lm92.c15
-rw-r--r--drivers/hwmon/lm93.c14
-rw-r--r--drivers/hwmon/max1111.c9
-rw-r--r--drivers/hwmon/max1619.c15
-rw-r--r--drivers/hwmon/max6639.c17
-rw-r--r--drivers/hwmon/max6642.c15
-rw-r--r--drivers/hwmon/max6650.c10
-rw-r--r--drivers/hwmon/mc13783-adc.c12
-rw-r--r--drivers/hwmon/ntc_thermistor.c2
-rw-r--r--drivers/hwmon/pc87360.c41
-rw-r--r--drivers/hwmon/pc87427.c51
-rw-r--r--drivers/hwmon/pcf8591.c15
-rw-r--r--drivers/hwmon/s3c-hwmon.c7
-rw-r--r--drivers/hwmon/sis5595.c28
-rw-r--r--drivers/hwmon/smsc47b397.c22
-rw-r--r--drivers/hwmon/smsc47m1.c45
-rw-r--r--drivers/hwmon/smsc47m192.c16
-rw-r--r--drivers/hwmon/thmc50.c17
-rw-r--r--drivers/hwmon/tmp102.c14
-rw-r--r--drivers/hwmon/tmp401.c6
-rw-r--r--drivers/hwmon/tmp421.c13
-rw-r--r--drivers/hwmon/via686a.c23
-rw-r--r--drivers/hwmon/vt1211.c22
-rw-r--r--drivers/hwmon/w83627ehf.c1
-rw-r--r--drivers/hwmon/w83627hf.c46
-rw-r--r--drivers/hwmon/w83781d.c52
-rw-r--r--drivers/hwmon/w83791d.c15
-rw-r--r--drivers/hwmon/w83792d.c18
-rw-r--r--drivers/hwmon/w83795.c11
-rw-r--r--drivers/hwmon/w83l785ts.c34
-rw-r--r--drivers/hwmon/wm831x-hwmon.c9
68 files changed, 1220 insertions, 846 deletions
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 <dchen@diasemi.com>
+
+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/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 <ipaton0@gmail.com>
+
+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/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".
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6f1d167cb1ea..b0a2e4c37e12 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
@@ -433,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 e1eeac13b851..7aa98119c4ab 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
@@ -58,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/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 @@ LEAVE_UPDATE:
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)
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 @@ LEAVE_UPDATE:
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)
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index e3fcf8146834..563c02904ddf 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;
@@ -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,9 +307,7 @@ static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
if (res)
return res;
- temp /= 1000;
- if (temp < 0)
- return -EINVAL;
+ temp = DIV_ROUND_CLOSEST(temp, 1000);
mutex_lock(&resource->lock);
resource->trip[attr->index - 7] = temp;
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;
}
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;
}
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 @@ exitremove:
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;
}
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;
}
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;
}
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;
}
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 2cde9ecf7731..4d937a18fadb 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
@@ -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 */
@@ -96,10 +98,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)
@@ -135,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),
};
@@ -432,30 +432,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;
}
/*
@@ -482,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.
*/
@@ -517,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;
@@ -533,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);
@@ -542,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.
*
@@ -562,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)
{
@@ -624,8 +642,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 +652,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 +677,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;
@@ -718,44 +736,27 @@ out:
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;
- u8 buffer[2];
- unsigned int temp;
-
- entry = applesmc_get_entry_by_index(index);
- if (IS_ERR(entry))
- return PTR_ERR(entry);
- if (entry->len > 2)
- return -EINVAL;
+ s16 value;
+ int temp;
- ret = applesmc_read_entry(entry, buffer, entry->len);
+ ret = applesmc_read_s16(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,
@@ -1265,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;
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 @@ exit_remove:
&(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;
}
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;
};
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 <dchen@diasemi.com>
+ *
+ * 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 <linux/delay.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+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 <dchen@diasemi.com>");
+MODULE_DESCRIPTION("DA9052 HWMON driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-hwmon");
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;
}
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;
}
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);
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 @@ exit_remove_files:
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;
}
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;
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 @@ exit_remove_files:
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;
}
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 @@ exit_remove_files:
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;
}
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 2ce8c44a0e07..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;
@@ -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 @@ err_free_ctrl:
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,15 +472,14 @@ 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;
}
-#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;
@@ -515,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,
},
};
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 <ipaton0@gmail.com>
+ *
+ * heavily based on the sht21 driver
+ * Copyright (C) 2010 Urs Fleisch <urs.fleisch@sensirion.com>
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+
+/**
+ * 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 <ipaton0@gmail.com>");
+MODULE_DESCRIPTION("Honeywell HIH-6130 humidity and temperature sensor driver");
+MODULE_LICENSE("GPL");
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 @@ exit_remove:
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 = {
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 @@ exit_remove_files:
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;
}
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;
}
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 0fca8613e7d8..f82acf67acf5 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,31 +337,29 @@ 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;
- 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(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;
+ return err;
- 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,10 +368,7 @@ static int lm77_probe(struct i2c_client *new_client,
return 0;
exit_remove:
- sysfs_remove_group(&new_client->dev.kobj, &lm77_group);
-exit_free:
- kfree(data);
-exit:
+ sysfs_remove_group(&dev->kobj, &lm77_group);
return err;
}
@@ -383,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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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 @@ exit_remove_files:
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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 @@ out_err_create_ts:
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;
}
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:
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;
}
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)
-{
- 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;
+ int i;
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;
}
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;
}
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;
}
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 @@ exit_remove_files:
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;
}
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;
}
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;
}
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;
}
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 @@ exit_remove_sysfs:
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;
}
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 @@ fail_remove_sysfs:
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;
}
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;
}
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;
}
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;
}
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 @@ EXIT_DEV_REMOVE:
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;
}
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);
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;
}
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index b03d54a799e3..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;
@@ -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;
}
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 @@ error3:
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;
}
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 @@ exit_remove_files:
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;
}
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;
}
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index 5f14e3897058..39dbe990dc10 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -176,19 +176,18 @@ 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;
- int err = 0;
+ struct device *dev = &client->dev;
+ 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(new_client, data);
+ i2c_set_clientdata(client, data);
data->valid = 0;
mutex_init(&data->update_lock);
@@ -200,18 +199,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;
+ return err;
- 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,12 +217,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);
- kfree(data);
-exit:
+ device_remove_file(dev, &sensor_dev_attr_temp1_input.dev_attr);
+ device_remove_file(dev, &sensor_dev_attr_temp1_max.dev_attr);
return err;
}
@@ -239,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;
}
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;
}