diff options
Diffstat (limited to 'drivers/hwmon')
75 files changed, 1262 insertions, 922 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6f1d167cb1e..b0a2e4c37e1 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 e1eeac13b85..7aa98119c4a 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 a72bf25601a..d4419b47f3d 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 a5bc4287daa..5d582aebff8 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 34ad5a27a7e..23ab3c496b0 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; @@ -929,20 +927,29 @@ static int acpi_power_meter_remove(struct acpi_device *device, int type) return 0; } -static int acpi_power_meter_resume(struct acpi_device *device) +#ifdef CONFIG_PM_SLEEP + +static int acpi_power_meter_resume(struct device *dev) { struct acpi_power_meter_resource *resource; - if (!device || !acpi_driver_data(device)) + if (!dev) + return -EINVAL; + + resource = acpi_driver_data(to_acpi_device(dev)); + if (!resource) return -EINVAL; - resource = acpi_driver_data(device); free_capabilities(resource); read_capabilities(resource); return 0; } +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(acpi_power_meter_pm, NULL, acpi_power_meter_resume); + static struct acpi_driver acpi_power_meter_driver = { .name = "power_meter", .class = ACPI_POWER_METER_CLASS, @@ -950,9 +957,9 @@ static struct acpi_driver acpi_power_meter_driver = { .ops = { .add = acpi_power_meter_add, .remove = acpi_power_meter_remove, - .resume = acpi_power_meter_resume, .notify = acpi_power_meter_notify, }, + .drv.pm = &acpi_power_meter_pm, }; /* Module init/exit routines */ diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index cfec802cf9c..f915eb1c29f 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -87,10 +87,18 @@ static ssize_t ad7314_show_temperature(struct device *dev, } } +static ssize_t ad7314_show_name(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); +} + +static DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ad7314_show_temperature, NULL, 0); static struct attribute *ad7314_attributes[] = { + &dev_attr_name.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, NULL, }; diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 4394e7e99c4..fd1d1b15854 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 b8557f9857d..7e16e5d07bc 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 1003219b9f9..0f068e7297e 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 44e1fd7f3d8..c6a4631e833 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 c3c2865a896..5a78d102a0f 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/ads7871.c b/drivers/hwmon/ads7871.c index e65c6e45d36..7bf4ce3d405 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c @@ -139,6 +139,12 @@ static ssize_t show_voltage(struct device *dev, } } +static ssize_t ads7871_show_name(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); +} + static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0); static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1); static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2); @@ -148,6 +154,8 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5); static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6); static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7); +static DEVICE_ATTR(name, S_IRUGO, ads7871_show_name, NULL); + static struct attribute *ads7871_attributes[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, @@ -157,6 +165,7 @@ static struct attribute *ads7871_attributes[] = { &sensor_dev_attr_in5_input.dev_attr.attr, &sensor_dev_attr_in6_input.dev_attr.attr, &sensor_dev_attr_in7_input.dev_attr.attr, + &dev_attr_name.attr, NULL }; diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index df29d13a534..861c756e953 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 2cde9ecf773..8f3f6f2c45f 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -53,11 +53,11 @@ #define APPLESMC_MAX_DATA_LENGTH 32 -/* wait up to 32 ms for a status change. */ -#define APPLESMC_MIN_WAIT 0x0040 -#define APPLESMC_MAX_WAIT 0x8000 +/* wait up to 128 ms for a status change. */ +#define APPLESMC_MIN_WAIT 0x0010 +#define APPLESMC_RETRY_WAIT 0x0100 +#define APPLESMC_MAX_WAIT 0x20000 -#define APPLESMC_STATUS_MASK 0x0f #define APPLESMC_READ_CMD 0x10 #define APPLESMC_WRITE_CMD 0x11 #define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12 @@ -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), }; @@ -162,51 +162,68 @@ static unsigned int key_at_index; static struct workqueue_struct *applesmc_led_wq; /* - * __wait_status - Wait up to 32ms for the status port to get a certain value - * (masked with 0x0f), returning zero if the value is obtained. Callers must + * wait_read - Wait for a byte to appear on SMC port. Callers must * hold applesmc_lock. */ -static int __wait_status(u8 val) +static int wait_read(void) { + u8 status; int us; - - val = val & APPLESMC_STATUS_MASK; - for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { udelay(us); - if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) + status = inb(APPLESMC_CMD_PORT); + /* read: wait for smc to settle */ + if (status & 0x01) return 0; } + pr_warn("wait_read() fail: 0x%02x\n", status); return -EIO; } /* - * special treatment of command port - on newer macbooks, it seems necessary - * to resend the command byte before polling the status again. Callers must - * hold applesmc_lock. + * send_byte - Write to SMC port, retrying when necessary. Callers + * must hold applesmc_lock. */ -static int send_command(u8 cmd) +static int send_byte(u8 cmd, u16 port) { + u8 status; int us; + + outb(cmd, port); for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { - outb(cmd, APPLESMC_CMD_PORT); udelay(us); - if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) + status = inb(APPLESMC_CMD_PORT); + /* write: wait for smc to settle */ + if (status & 0x02) + continue; + /* ready: cmd accepted, return */ + if (status & 0x04) return 0; + /* timeout: give up */ + if (us << 1 == APPLESMC_MAX_WAIT) + break; + /* busy: long wait and resend */ + udelay(APPLESMC_RETRY_WAIT); + outb(cmd, port); } + + pr_warn("send_byte(0x%02x, 0x%04x) fail: 0x%02x\n", cmd, port, status); return -EIO; } +static int send_command(u8 cmd) +{ + return send_byte(cmd, APPLESMC_CMD_PORT); +} + static int send_argument(const char *key) { int i; - for (i = 0; i < 4; i++) { - outb(key[i], APPLESMC_DATA_PORT); - if (__wait_status(0x04)) + for (i = 0; i < 4; i++) + if (send_byte(key[i], APPLESMC_DATA_PORT)) return -EIO; - } return 0; } @@ -219,11 +236,14 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) return -EIO; } - outb(len, APPLESMC_DATA_PORT); + if (send_byte(len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: read len fail\n", key); + return -EIO; + } for (i = 0; i < len; i++) { - if (__wait_status(0x05)) { - pr_warn("%.4s: read data fail\n", key); + if (wait_read()) { + pr_warn("%.4s: read data[%d] fail\n", key, i); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); @@ -241,14 +261,16 @@ static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len) return -EIO; } - outb(len, APPLESMC_DATA_PORT); + if (send_byte(len, APPLESMC_DATA_PORT)) { + pr_warn("%.4s: write len fail\n", key); + return -EIO; + } for (i = 0; i < len; i++) { - if (__wait_status(0x04)) { + if (send_byte(buffer[i], APPLESMC_DATA_PORT)) { pr_warn("%s: write data fail\n", key); return -EIO; } - outb(buffer[i], APPLESMC_DATA_PORT); } return 0; @@ -432,30 +454,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 +493,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 +552,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 +572,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 +581,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 +610,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 +664,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 +674,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 +699,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 +758,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; - - entry = applesmc_get_entry_by_index(index); - if (IS_ERR(entry)) - return PTR_ERR(entry); + const char *key = smcreg.index[to_index(devattr)]; - 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 +1288,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 7caa242915a..b867aab7804 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/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 351d1f4593e..4ee57894872 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -34,6 +34,12 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = { .matches = { DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58") } + }, { + /* Old interface reads the same sensor for fan0 and fan1 */ + .ident = "Asus M5A78L", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "M5A78L") + } }, { } }; diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 58af6aa9353..aecb9ea7beb 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/coretemp.c b/drivers/hwmon/coretemp.c index 637c51c11b4..984a3f13923 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -196,7 +196,7 @@ struct tjmax { int tjmax; }; -static struct tjmax __cpuinitconst tjmax_table[] = { +static const struct tjmax __cpuinitconst tjmax_table[] = { { "CPU D410", 100000 }, { "CPU D425", 100000 }, { "CPU D510", 100000 }, @@ -793,7 +793,7 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; -static const struct x86_cpu_id coretemp_ids[] = { +static const struct x86_cpu_id __initconst coretemp_ids[] = { { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, {} }; @@ -815,17 +815,20 @@ static int __init coretemp_init(void) if (err) goto exit; + get_online_cpus(); for_each_online_cpu(i) get_core_online(i); #ifndef CONFIG_HOTPLUG_CPU if (list_empty(&pdev_list)) { + put_online_cpus(); err = -ENODEV; goto exit_driver_unreg; } #endif register_hotcpu_notifier(&coretemp_cpu_notifier); + put_online_cpus(); return 0; #ifndef CONFIG_HOTPLUG_CPU @@ -840,6 +843,7 @@ static void __exit coretemp_exit(void) { struct pdev_entry *p, *n; + get_online_cpus(); unregister_hotcpu_notifier(&coretemp_cpu_notifier); mutex_lock(&pdev_list_mutex); list_for_each_entry_safe(p, n, &pdev_list, list) { @@ -848,6 +852,7 @@ static void __exit coretemp_exit(void) kfree(p); } mutex_unlock(&pdev_list_mutex); + put_online_cpus(); platform_driver_unregister(&coretemp_driver); } diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c new file mode 100644 index 00000000000..fc65f2d3ec9 --- /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 f647a3307eb..1c568736baf 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/emc2103.c b/drivers/hwmon/emc2103.c index e7d234b5931..7bb8e888692 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -732,6 +732,6 @@ static struct i2c_driver emc2103_driver = { module_i2c_driver(emc2103_driver); -MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>"); +MODULE_AUTHOR("Steve Glendinning <steve.glendinning@shawell.net>"); MODULE_DESCRIPTION("SMSC EMC2103 hwmon driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c index 840f5112e60..ada12a98a97 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 f2359a0093b..e912059140c 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 3e4da620e9c..4dd7723d257 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 6b13f1a4dc2..af69073b3fe 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; @@ -128,12 +129,12 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) * counter saturations resulting in bogus power readings. * We correct this value ourselves to cope with older BIOSes. */ -static DEFINE_PCI_DEVICE_TABLE(affected_device) = { +static const struct pci_device_id affected_device[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, { 0 } }; -static void __devinit tweak_runavg_range(struct pci_dev *pdev) +static void tweak_runavg_range(struct pci_dev *pdev) { u32 val; @@ -157,6 +158,16 @@ static void __devinit tweak_runavg_range(struct pci_dev *pdev) REG_TDP_RUNNING_AVERAGE, val); } +#ifdef CONFIG_PM +static int fam15h_power_resume(struct pci_dev *pdev) +{ + tweak_runavg_range(pdev); + return 0; +} +#else +#define fam15h_power_resume NULL +#endif + static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -255,6 +266,7 @@ static struct pci_driver fam15h_power_driver = { .id_table = fam15h_power_id_table, .probe = fam15h_power_probe, .remove = __devexit_p(fam15h_power_remove), + .resume = fam15h_power_resume, }; module_pci_driver(fam15h_power_driver); diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 764a083ac7a..2c74673f48e 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 5ff452b6a4d..a21ff252f2f 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 2ce8c44a0e0..2f4b01bda87 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 00000000000..e8ee75f5547 --- /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/ina2xx.c b/drivers/hwmon/ina2xx.c index 7f3f4a38572..602148299f6 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -69,22 +69,6 @@ struct ina2xx_data { u16 regs[INA2XX_MAX_REGISTERS]; }; -int ina2xx_read_word(struct i2c_client *client, int reg) -{ - int val = i2c_smbus_read_word_data(client, reg); - if (unlikely(val < 0)) { - dev_dbg(&client->dev, - "Failed to read register: %d\n", reg); - return val; - } - return be16_to_cpu(val); -} - -void ina2xx_write_word(struct i2c_client *client, int reg, int data) -{ - i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); -} - static struct ina2xx_data *ina2xx_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev) /* Read all registers */ for (i = 0; i < data->registers; i++) { - int rv = ina2xx_read_word(client, i); + int rv = i2c_smbus_read_word_swapped(client, i); if (rv < 0) { ret = ERR_PTR(rv); goto abort; @@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_client *client, switch (data->kind) { case ina219: /* device configuration */ - ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); + i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, + INA219_CONFIG_DEFAULT); /* set current LSB to 1mA, shunt is in uOhms */ /* (equation 13 in datasheet) */ - ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); + i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, + 40960000 / shunt); dev_info(&client->dev, "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); data->registers = INA219_REGISTERS; break; case ina226: /* device configuration */ - ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); + i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, + INA226_CONFIG_DEFAULT); /* set current LSB to 1mA, shunt is in uOhms */ /* (equation 1 in datasheet)*/ - ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); + i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, + 5120000 / shunt); dev_info(&client->dev, "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); data->registers = INA226_REGISTERS; diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index e72ba5d2a82..e21e43c1315 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -57,7 +57,7 @@ static const unsigned short normal_i2c[] = { #define JC42_CFG_EVENT_LOCK (1 << 7) #define JC42_CFG_SHUTDOWN (1 << 8) #define JC42_CFG_HYST_SHIFT 9 -#define JC42_CFG_HYST_MASK 0x03 +#define JC42_CFG_HYST_MASK (0x03 << 9) /* Capabilities */ #define JC42_CAP_RANGE (1 << 2) @@ -287,8 +287,8 @@ static ssize_t show_temp_crit_hyst(struct device *dev, return PTR_ERR(data); temp = jc42_temp_from_reg(data->temp_crit); - hyst = jc42_hysteresis[(data->config >> JC42_CFG_HYST_SHIFT) - & JC42_CFG_HYST_MASK]; + hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) + >> JC42_CFG_HYST_SHIFT]; return sprintf(buf, "%d\n", temp - hyst); } @@ -302,8 +302,8 @@ static ssize_t show_temp_max_hyst(struct device *dev, return PTR_ERR(data); temp = jc42_temp_from_reg(data->temp_max); - hyst = jc42_hysteresis[(data->config >> JC42_CFG_HYST_SHIFT) - & JC42_CFG_HYST_MASK]; + hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) + >> JC42_CFG_HYST_SHIFT]; return sprintf(buf, "%d\n", temp - hyst); } @@ -362,8 +362,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, } mutex_lock(&data->update_lock); - data->config = (data->config - & ~(JC42_CFG_HYST_MASK << JC42_CFG_HYST_SHIFT)) + data->config = (data->config & ~JC42_CFG_HYST_MASK) | (hyst << JC42_CFG_HYST_SHIFT); err = i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config); @@ -535,9 +534,16 @@ static int jc42_remove(struct i2c_client *client) struct jc42_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &jc42_group); - if (data->config != data->orig_config) - i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, - data->orig_config); + + /* Restore original configuration except hysteresis */ + if ((data->config & ~JC42_CFG_HYST_MASK) != + (data->orig_config & ~JC42_CFG_HYST_MASK)) { + int config; + + config = (data->orig_config & ~JC42_CFG_HYST_MASK) + | (data->config & JC42_CFG_HYST_MASK); + i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); + } return 0; } diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 7356b5ec8f6..f2fe8078633 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -33,9 +33,6 @@ static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); -/* PCI-IDs for Northbridge devices not used anywhere else */ -#define PCI_DEVICE_ID_AMD_15H_M10H_NB_F3 0x1403 - /* CPUID function 0x80000001, ebx */ #define CPUID_PKGTYPE_MASK 0xf0000000 #define CPUID_PKGTYPE_F 0x00000000 @@ -213,7 +210,7 @@ static DEFINE_PCI_DEVICE_TABLE(k10temp_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_NB_F3) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 35aac82ee8e..49a69c5b3b8 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 602a0f0b0de..eed4d940178 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 a83f206af24..291edfff55b 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 0fca8613e7d..f82acf67acf 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 f6bc414e1e9..c6ffafe600a 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 e2c43e1774b..28a8b71f457 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 cd45b9d8558..e998034f1f1 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 864c7d999e0..9f2dd77e1e0 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 314d147bf1a..16e45d70215 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 22b14a68e35..863412a02bd 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 fdc691a4028..2282d77e83e 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 67e8fe256e0..bf946187bd3 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 362a40eb612..f3978a46e84 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 ecac04a7b7d..6c11ec21407 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 de8f7adaccb..6e60036abfa 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 4298909a41f..bf236c0782b 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 33a8a7f15e1..f739f83bafb 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 ce86c5e3c2c..cf47a59657a 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 6da9696e182..74a6c58d021 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 79ba48c8c11..91d5b2a21dd 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 37059a3755e..f185b1fa53e 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 4174c7463d7..825883d2900 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 f6c26d19f52..b7975f858cf 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 6c4d8eb9b7c..8275f0e14eb 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 c5f6be478ba..65b07de11a0 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 b5aa38dd7ab..dba0c567e7a 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 4705a8bf11c..36a3478d079 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 add9f019b24..080c2637048 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 0d466b9d890..4e1ff82c63e 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 ea54c338467..e6205487516 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 8fac87a3854..6a8ded29f1e 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/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 0018c7dd009..1a174f0a3cd 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -44,12 +44,13 @@ static ssize_t madc_read(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct twl4030_madc_request req; + struct twl4030_madc_request req = { + .channels = 1 << attr->index, + .method = TWL4030_MADC_SW2, + .type = TWL4030_MADC_WAIT, + }; long val; - req.channels = (1 << attr->index); - req.method = TWL4030_MADC_SW2; - req.func_cb = NULL; val = twl4030_madc_conversion(&req); if (val < 0) return val; diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 8689664ef03..2e56c6ce9fb 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -309,7 +309,7 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; -static const struct x86_cpu_id cputemp_ids[] = { +static const struct x86_cpu_id __initconst cputemp_ids[] = { { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */ @@ -328,6 +328,7 @@ static int __init via_cputemp_init(void) if (err) goto exit; + get_online_cpus(); for_each_online_cpu(i) { struct cpuinfo_x86 *c = &cpu_data(i); @@ -347,12 +348,14 @@ static int __init via_cputemp_init(void) #ifndef CONFIG_HOTPLUG_CPU if (list_empty(&pdev_list)) { + put_online_cpus(); err = -ENODEV; goto exit_driver_unreg; } #endif register_hotcpu_notifier(&via_cputemp_cpu_notifier); + put_online_cpus(); return 0; #ifndef CONFIG_HOTPLUG_CPU @@ -367,6 +370,7 @@ static void __exit via_cputemp_exit(void) { struct pdev_entry *p, *n; + get_online_cpus(); unregister_hotcpu_notifier(&via_cputemp_cpu_notifier); mutex_lock(&pdev_list_mutex); list_for_each_entry_safe(p, n, &pdev_list, list) { @@ -375,6 +379,7 @@ static void __exit via_cputemp_exit(void) kfree(p); } mutex_unlock(&pdev_list_mutex); + put_online_cpus(); platform_driver_unregister(&via_cputemp_driver); } diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 288135d85e1..299399aa30f 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 c2c5c72fb8f..f2c61153dba 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 54922ed1297..1821b7423d5 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 5ce54a29724..5b1a6a66644 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1206,7 +1206,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, int err = -ENODEV; u16 val; - static const __initdata char *names[] = { + static __initconst char *const names[] = { "W83627HF", "W83627THF", "W83697HF", @@ -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 b03d54a799e..5a5046d94c3 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 2f446f92acf..9ade4d4e218 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 ffb5fdfecf0..0ba5a2bd562 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 d887cb3b72e..b813c646c7c 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 5f14e389705..39dbe990dc1 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 07cb25ae69b..d0db1f2738f 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; } |