diff options
Diffstat (limited to 'drivers/hwmon')
77 files changed, 1269 insertions, 1195 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 7cd9bf42108..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 @@ -1036,8 +1056,9 @@ config SENSORS_SCH56XX_COMMON  config SENSORS_SCH5627  	tristate "SMSC SCH5627" -	depends on !PPC +	depends on !PPC && WATCHDOG  	select SENSORS_SCH56XX_COMMON +	select WATCHDOG_CORE  	help  	  If you say yes here you get support for the hardware monitoring  	  features of the SMSC SCH5627 Super-I/O chip including support for @@ -1048,8 +1069,9 @@ config SENSORS_SCH5627  config SENSORS_SCH5636  	tristate "SMSC SCH5636" -	depends on !PPC +	depends on !PPC && WATCHDOG  	select SENSORS_SCH56XX_COMMON +	select WATCHDOG_CORE  	help  	  SMSC SCH5636 Super I/O chips include an embedded microcontroller for  	  hardware monitoring solutions, allowing motherboard manufacturers to 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..563c02904dd 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,25 @@ static int acpi_power_meter_remove(struct acpi_device *device, int type)  	return 0;  } -static int acpi_power_meter_resume(struct acpi_device *device) +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;  } +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 +953,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/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/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 f082e48ab11..4d937a18fad 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -8,7 +8,7 @@   *   * Based on hdaps.c driver:   * Copyright (C) 2005 Robert Love <rml@novell.com> - * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> + * Copyright (C) 2005 Jesper Juhl <jj@chaosbits.net>   *   * Fan control based on smcFanControl:   * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com> @@ -54,7 +54,7 @@  #define APPLESMC_MAX_DATA_LENGTH 32  /* wait up to 32 ms for a status change. */ -#define APPLESMC_MIN_WAIT	0x0040 +#define APPLESMC_MIN_WAIT	0x0010  #define APPLESMC_MAX_WAIT	0x8000  #define APPLESMC_STATUS_MASK	0x0f @@ -80,6 +80,8 @@  #define FANS_MANUAL		"FS! " /* r-w ui16 */  #define FAN_ID_FMT		"F%dID" /* r-o char[16] */ +#define TEMP_SENSOR_TYPE	"sp78" +  /* List of keys used to read/write fan speeds */  static const char *const fan_speed_fmt[] = {  	"F%dAc",		/* actual speed */ @@ -96,10 +98,6 @@ static const char *const fan_speed_fmt[] = {  #define APPLESMC_INPUT_FUZZ	4	/* input event threshold */  #define APPLESMC_INPUT_FLAT	4 -#define SENSOR_X 0 -#define SENSOR_Y 1 -#define SENSOR_Z 2 -  #define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff)  #define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16) @@ -135,11 +133,13 @@ static struct applesmc_registers {  	unsigned int temp_count;	/* number of temperature registers */  	unsigned int temp_begin;	/* temperature lower index bound */  	unsigned int temp_end;		/* temperature upper index bound */ +	unsigned int index_count;	/* size of temperature index array */  	int num_light_sensors;		/* number of light sensors */  	bool has_accelerometer;		/* has motion sensor */  	bool has_key_backlight;		/* has keyboard backlight */  	bool init_complete;		/* true when fully initialized */  	struct applesmc_entry *cache;	/* cached key entries */ +	const char **index;		/* temperature key index */  } smcreg = {  	.mutex = __MUTEX_INITIALIZER(smcreg.mutex),  }; @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)  	int i;  	if (send_command(cmd) || send_argument(key)) { -		pr_warn("%s: read arg fail\n", key); +		pr_warn("%.4s: read arg fail\n", key);  		return -EIO;  	} @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)  	for (i = 0; i < len; i++) {  		if (__wait_status(0x05)) { -			pr_warn("%s: read data fail\n", key); +			pr_warn("%.4s: read data fail\n", key);  			return -EIO;  		}  		buffer[i] = inb(APPLESMC_DATA_PORT); @@ -432,30 +432,19 @@ static int applesmc_has_key(const char *key, bool *value)  }  /* - * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). + * applesmc_read_s16 - Read 16-bit signed big endian register   */ -static int applesmc_read_motion_sensor(int index, s16 *value) +static int applesmc_read_s16(const char *key, s16 *value)  {  	u8 buffer[2];  	int ret; -	switch (index) { -	case SENSOR_X: -		ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2); -		break; -	case SENSOR_Y: -		ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2); -		break; -	case SENSOR_Z: -		ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2); -		break; -	default: -		ret = -EINVAL; -	} +	ret = applesmc_read_key(key, buffer, 2); +	if (ret) +		return ret;  	*value = ((s16)buffer[0] << 8) | buffer[1]; - -	return ret; +	return 0;  }  /* @@ -482,6 +471,30 @@ static void applesmc_device_init(void)  	pr_warn("failed to init the device\n");  } +static int applesmc_init_index(struct applesmc_registers *s) +{ +	const struct applesmc_entry *entry; +	unsigned int i; + +	if (s->index) +		return 0; + +	s->index = kcalloc(s->temp_count, sizeof(s->index[0]), GFP_KERNEL); +	if (!s->index) +		return -ENOMEM; + +	for (i = s->temp_begin; i < s->temp_end; i++) { +		entry = applesmc_get_entry_by_index(i); +		if (IS_ERR(entry)) +			continue; +		if (strcmp(entry->type, TEMP_SENSOR_TYPE)) +			continue; +		s->index[s->index_count++] = entry->key; +	} + +	return 0; +} +  /*   * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.   */ @@ -517,6 +530,10 @@ static int applesmc_init_smcreg_try(void)  		return ret;  	s->temp_count = s->temp_end - s->temp_begin; +	ret = applesmc_init_index(s); +	if (ret) +		return ret; +  	ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);  	if (ret)  		return ret; @@ -533,8 +550,8 @@ static int applesmc_init_smcreg_try(void)  	s->num_light_sensors = left_light_sensor + right_light_sensor;  	s->init_complete = true; -	pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n", -	       s->key_count, s->fan_count, s->temp_count, +	pr_info("key=%d fan=%d temp=%d index=%d acc=%d lux=%d kbd=%d\n", +	       s->key_count, s->fan_count, s->temp_count, s->index_count,  	       s->has_accelerometer,  	       s->num_light_sensors,  	       s->has_key_backlight); @@ -542,6 +559,15 @@ static int applesmc_init_smcreg_try(void)  	return 0;  } +static void applesmc_destroy_smcreg(void) +{ +	kfree(smcreg.index); +	smcreg.index = NULL; +	kfree(smcreg.cache); +	smcreg.cache = NULL; +	smcreg.init_complete = false; +} +  /*   * applesmc_init_smcreg - Initialize register cache.   * @@ -562,19 +588,11 @@ static int applesmc_init_smcreg(void)  		msleep(INIT_WAIT_MSECS);  	} -	kfree(smcreg.cache); -	smcreg.cache = NULL; +	applesmc_destroy_smcreg();  	return ret;  } -static void applesmc_destroy_smcreg(void) -{ -	kfree(smcreg.cache); -	smcreg.cache = NULL; -	smcreg.init_complete = false; -} -  /* Device model stuff */  static int applesmc_probe(struct platform_device *dev)  { @@ -624,8 +642,8 @@ static struct platform_driver applesmc_driver = {   */  static void applesmc_calibrate(void)  { -	applesmc_read_motion_sensor(SENSOR_X, &rest_x); -	applesmc_read_motion_sensor(SENSOR_Y, &rest_y); +	applesmc_read_s16(MOTION_SENSOR_X_KEY, &rest_x); +	applesmc_read_s16(MOTION_SENSOR_Y_KEY, &rest_y);  	rest_x = -rest_x;  } @@ -634,9 +652,9 @@ static void applesmc_idev_poll(struct input_polled_dev *dev)  	struct input_dev *idev = dev->input;  	s16 x, y; -	if (applesmc_read_motion_sensor(SENSOR_X, &x)) +	if (applesmc_read_s16(MOTION_SENSOR_X_KEY, &x))  		return; -	if (applesmc_read_motion_sensor(SENSOR_Y, &y)) +	if (applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y))  		return;  	x = -x; @@ -659,13 +677,13 @@ static ssize_t applesmc_position_show(struct device *dev,  	int ret;  	s16 x, y, z; -	ret = applesmc_read_motion_sensor(SENSOR_X, &x); +	ret = applesmc_read_s16(MOTION_SENSOR_X_KEY, &x);  	if (ret)  		goto out; -	ret = applesmc_read_motion_sensor(SENSOR_Y, &y); +	ret = applesmc_read_s16(MOTION_SENSOR_Y_KEY, &y);  	if (ret)  		goto out; -	ret = applesmc_read_motion_sensor(SENSOR_Z, &z); +	ret = applesmc_read_s16(MOTION_SENSOR_Z_KEY, &z);  	if (ret)  		goto out; @@ -718,44 +736,27 @@ out:  static ssize_t applesmc_show_sensor_label(struct device *dev,  			struct device_attribute *devattr, char *sysfsbuf)  { -	int index = smcreg.temp_begin + to_index(devattr); -	const struct applesmc_entry *entry; +	const char *key = smcreg.index[to_index(devattr)]; -	entry = applesmc_get_entry_by_index(index); -	if (IS_ERR(entry)) -		return PTR_ERR(entry); - -	return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key); +	return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);  }  /* Displays degree Celsius * 1000 */  static ssize_t applesmc_show_temperature(struct device *dev,  			struct device_attribute *devattr, char *sysfsbuf)  { -	int index = smcreg.temp_begin + to_index(devattr); -	const struct applesmc_entry *entry; +	const char *key = smcreg.index[to_index(devattr)];  	int ret; -	u8 buffer[2]; -	unsigned int temp; - -	entry = applesmc_get_entry_by_index(index); -	if (IS_ERR(entry)) -		return PTR_ERR(entry); -	if (entry->len > 2) -		return -EINVAL; +	s16 value; +	int temp; -	ret = applesmc_read_entry(entry, buffer, entry->len); +	ret = applesmc_read_s16(key, &value);  	if (ret)  		return ret; -	if (entry->len == 2) { -		temp = buffer[0] * 1000; -		temp += (buffer[1] >> 6) * 250; -	} else { -		temp = buffer[0] * 4000; -	} +	temp = 250 * (value >> 6); -	return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); +	return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", temp);  }  static ssize_t applesmc_show_fan_speed(struct device *dev, @@ -1265,7 +1266,7 @@ static int __init applesmc_init(void)  	if (ret)  		goto out_info; -	ret = applesmc_create_nodes(temp_group, smcreg.temp_count); +	ret = applesmc_create_nodes(temp_group, smcreg.index_count);  	if (ret)  		goto out_fans; diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index 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/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 b9d512331ed..637c51c11b4 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -191,6 +191,24 @@ static ssize_t show_temp(struct device *dev,  	return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN;  } +struct tjmax { +	char const *id; +	int tjmax; +}; + +static struct tjmax __cpuinitconst tjmax_table[] = { +	{ "CPU D410", 100000 }, +	{ "CPU D425", 100000 }, +	{ "CPU D510", 100000 }, +	{ "CPU D525", 100000 }, +	{ "CPU N450", 100000 }, +	{ "CPU N455", 100000 }, +	{ "CPU N470", 100000 }, +	{ "CPU N475", 100000 }, +	{ "CPU  230", 100000 }, +	{ "CPU  330", 125000 }, +}; +  static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,  				  struct device *dev)  { @@ -202,6 +220,13 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,  	int err;  	u32 eax, edx;  	struct pci_dev *host_bridge; +	int i; + +	/* explicit tjmax table entries override heuristics */ +	for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { +		if (strstr(c->x86_model_id, tjmax_table[i].id)) +			return tjmax_table[i].tjmax; +	}  	/* Early chips have no MSR for TjMax */ @@ -210,7 +235,8 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,  	/* Atom CPUs */ -	if (c->x86_model == 0x1c) { +	if (c->x86_model == 0x1c || c->x86_model == 0x26 +	    || c->x86_model == 0x27) {  		usemsr_ee = 0;  		host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); @@ -223,6 +249,9 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,  			tjmax = 90000;  		pci_dev_put(host_bridge); +	} else if (c->x86_model == 0x36) { +		usemsr_ee = 0; +		tjmax = 100000;  	}  	if (c->x86_model > 0xe && usemsr_ee) { @@ -664,7 +693,7 @@ static void __cpuinit get_core_online(unsigned int cpu)  	 * sensors. We check this bit only, all the early CPUs  	 * without thermal sensors will be filtered out.  	 */ -	if (!cpu_has(c, X86_FEATURE_DTS)) +	if (!cpu_has(c, X86_FEATURE_DTHERM))  		return;  	if (!pdev) { @@ -765,14 +794,14 @@ static struct notifier_block coretemp_cpu_notifier __refdata = {  };  static const struct x86_cpu_id coretemp_ids[] = { -	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, +	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM },  	{}  };  MODULE_DEVICE_TABLE(x86cpu, coretemp_ids);  static int __init coretemp_init(void)  { -	int i, err = -ENODEV; +	int i, err;  	/*  	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal 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 a73e68519cb..7bb8e888692 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -451,11 +451,15 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,  		data->fan_rpm_control = true;  		break;  	default: -		mutex_unlock(&data->update_lock); -		return -EINVAL; +		count = -EINVAL; +		goto err;  	} -	read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); +	result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); +	if (result) { +		count = result; +		goto err; +	}  	if (data->fan_rpm_control)  		conf_reg |= 0x80; @@ -463,7 +467,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,  		conf_reg &= ~0x80;  	i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); - +err:  	mutex_unlock(&data->update_lock);  	return count;  } 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..2764b78a784 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -67,7 +67,8 @@ static ssize_t show_power(struct device *dev,  				  REG_TDP_LIMIT3, &val);  	tdp_limit = val >> 16; -	curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range; +	curr_pwr_watts = ((u64)(tdp_limit + +				data->base_tdp)) << running_avg_range;  	curr_pwr_watts -= running_avg_capture;  	curr_pwr_watts *= data->tdp_to_watts; diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 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/it87.c b/drivers/hwmon/it87.c index e7701d99f8e..f1de3979181 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -2341,7 +2341,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)  	/* Start monitoring */  	it87_write_value(data, IT87_REG_CONFIG, -			 (it87_read_value(data, IT87_REG_CONFIG) & 0x36) +			 (it87_read_value(data, IT87_REG_CONFIG) & 0x3e)  			 | (update_vbat ? 0x41 : 0x01));  } diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index a9bfd6736d9..e72ba5d2a82 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -590,6 +590,6 @@ abort:  module_i2c_driver(jc42_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");  MODULE_DESCRIPTION("JC42 driver");  MODULE_LICENSE("GPL"); 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/lineage-pem.c b/drivers/hwmon/lineage-pem.c index d264937c7f5..bd75d241543 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -567,6 +567,6 @@ static struct i2c_driver pem_driver = {  module_i2c_driver(pem_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");  MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver");  MODULE_LICENSE("GPL"); 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/ltc4261.c b/drivers/hwmon/ltc4261.c index 069b7d34d8f..77476a575c4 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -292,6 +292,6 @@ static struct i2c_driver ltc4261_driver = {  module_i2c_driver(ltc4261_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");  MODULE_DESCRIPTION("LTC4261 driver");  MODULE_LICENSE("GPL"); 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/max16065.c b/drivers/hwmon/max16065.c index 822261be84d..019427d7a5f 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -692,6 +692,6 @@ static struct i2c_driver max16065_driver = {  module_i2c_driver(max16065_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");  MODULE_DESCRIPTION("MAX16065 driver");  MODULE_LICENSE("GPL"); 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/sch5627.c b/drivers/hwmon/sch5627.c index 8ec6dfbccb6..8342275378b 100644 --- a/drivers/hwmon/sch5627.c +++ b/drivers/hwmon/sch5627.c @@ -579,7 +579,7 @@ static int __devinit sch5627_probe(struct platform_device *pdev)  	}  	/* Note failing to register the watchdog is not a fatal error */ -	data->watchdog = sch56xx_watchdog_register(data->addr, +	data->watchdog = sch56xx_watchdog_register(&pdev->dev, data->addr,  			(build_code << 24) | (build_id << 8) | hwmon_rev,  			&data->update_lock, 1); diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 906d4ed32d8..96a7e68718c 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c @@ -510,7 +510,7 @@ static int __devinit sch5636_probe(struct platform_device *pdev)  	}  	/* Note failing to register the watchdog is not a fatal error */ -	data->watchdog = sch56xx_watchdog_register(data->addr, +	data->watchdog = sch56xx_watchdog_register(&pdev->dev, data->addr,  					(revision[0] << 8) | revision[1],  					&data->update_lock, 0); diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c index ce52fc57d41..4380f5d07be 100644 --- a/drivers/hwmon/sch56xx-common.c +++ b/drivers/hwmon/sch56xx-common.c @@ -66,15 +66,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="  struct sch56xx_watchdog_data {  	u16 addr; -	u32 revision;  	struct mutex *io_lock; -	struct mutex watchdog_lock; -	struct list_head list; /* member of the watchdog_data_list */  	struct kref kref; -	struct miscdevice watchdog_miscdev; -	unsigned long watchdog_is_open; -	char watchdog_name[10]; /* must be unique to avoid sysfs conflict */ -	char watchdog_expect_close; +	struct watchdog_info wdinfo; +	struct watchdog_device wddev;  	u8 watchdog_preset;  	u8 watchdog_control;  	u8 watchdog_output_enable; @@ -82,15 +77,6 @@ struct sch56xx_watchdog_data {  static struct platform_device *sch56xx_pdev; -/* - * Somewhat ugly :( global data pointer list with all sch56xx devices, so that - * we can find our device data as when using misc_register there is no other - * method to get to ones device data from the open fop. - */ -static LIST_HEAD(watchdog_data_list); -/* Note this lock not only protect list access, but also data.kref access */ -static DEFINE_MUTEX(watchdog_data_mutex); -  /* Super I/O functions */  static inline int superio_inb(int base, int reg)  { @@ -272,22 +258,22 @@ EXPORT_SYMBOL(sch56xx_read_virtual_reg12);   * Watchdog routines   */ -/* - * Release our data struct when the platform device has been released *and* - * all references to our watchdog device are released. - */ -static void sch56xx_watchdog_release_resources(struct kref *r) +/* Release our data struct when we're unregistered *and* +   all references to our watchdog device are released */ +static void watchdog_release_resources(struct kref *r)  {  	struct sch56xx_watchdog_data *data =  		container_of(r, struct sch56xx_watchdog_data, kref);  	kfree(data);  } -static int watchdog_set_timeout(struct sch56xx_watchdog_data *data, -				int timeout) +static int watchdog_set_timeout(struct watchdog_device *wddev, +				unsigned int timeout)  { -	int ret, resolution; +	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev); +	unsigned int resolution;  	u8 control; +	int ret;  	/* 1 second or 60 second resolution? */  	if (timeout <= 255) @@ -298,12 +284,6 @@ static int watchdog_set_timeout(struct sch56xx_watchdog_data *data,  	if (timeout < resolution || timeout > (resolution * 255))  		return -EINVAL; -	mutex_lock(&data->watchdog_lock); -	if (!data->addr) { -		ret = -ENODEV; -		goto leave; -	} -  	if (resolution == 1)  		control = data->watchdog_control | SCH56XX_WDOG_TIME_BASE_SEC;  	else @@ -316,7 +296,7 @@ static int watchdog_set_timeout(struct sch56xx_watchdog_data *data,  						control);  		mutex_unlock(data->io_lock);  		if (ret) -			goto leave; +			return ret;  		data->watchdog_control = control;  	} @@ -326,38 +306,17 @@ static int watchdog_set_timeout(struct sch56xx_watchdog_data *data,  	 * the watchdog countdown.  	 */  	data->watchdog_preset = DIV_ROUND_UP(timeout, resolution); +	wddev->timeout = data->watchdog_preset * resolution; -	ret = data->watchdog_preset * resolution; -leave: -	mutex_unlock(&data->watchdog_lock); -	return ret; -} - -static int watchdog_get_timeout(struct sch56xx_watchdog_data *data) -{ -	int timeout; - -	mutex_lock(&data->watchdog_lock); -	if (data->watchdog_control & SCH56XX_WDOG_TIME_BASE_SEC) -		timeout = data->watchdog_preset; -	else -		timeout = data->watchdog_preset * 60; -	mutex_unlock(&data->watchdog_lock); - -	return timeout; +	return 0;  } -static int watchdog_start(struct sch56xx_watchdog_data *data) +static int watchdog_start(struct watchdog_device *wddev)  { +	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);  	int ret;  	u8 val; -	mutex_lock(&data->watchdog_lock); -	if (!data->addr) { -		ret = -ENODEV; -		goto leave_unlock_watchdog; -	} -  	/*  	 * The sch56xx's watchdog cannot really be started / stopped  	 * it is always running, but we can avoid the timer expiring @@ -385,18 +344,14 @@ static int watchdog_start(struct sch56xx_watchdog_data *data)  	if (ret)  		goto leave; -	/* 2. Enable output (if not already enabled) */ -	if (!(data->watchdog_output_enable & SCH56XX_WDOG_OUTPUT_ENABLE)) { -		val = data->watchdog_output_enable | -		      SCH56XX_WDOG_OUTPUT_ENABLE; -		ret = sch56xx_write_virtual_reg(data->addr, -						SCH56XX_REG_WDOG_OUTPUT_ENABLE, -						val); -		if (ret) -			goto leave; +	/* 2. Enable output */ +	val = data->watchdog_output_enable | SCH56XX_WDOG_OUTPUT_ENABLE; +	ret = sch56xx_write_virtual_reg(data->addr, +					SCH56XX_REG_WDOG_OUTPUT_ENABLE, val); +	if (ret) +		goto leave; -		data->watchdog_output_enable = val; -	} +	data->watchdog_output_enable = val;  	/* 3. Clear the watchdog event bit if set */  	val = inb(data->addr + 9); @@ -405,234 +360,70 @@ static int watchdog_start(struct sch56xx_watchdog_data *data)  leave:  	mutex_unlock(data->io_lock); -leave_unlock_watchdog: -	mutex_unlock(&data->watchdog_lock);  	return ret;  } -static int watchdog_trigger(struct sch56xx_watchdog_data *data) +static int watchdog_trigger(struct watchdog_device *wddev)  { +	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);  	int ret; -	mutex_lock(&data->watchdog_lock); -	if (!data->addr) { -		ret = -ENODEV; -		goto leave; -	} -  	/* Reset the watchdog countdown counter */  	mutex_lock(data->io_lock);  	ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET,  					data->watchdog_preset);  	mutex_unlock(data->io_lock); -leave: -	mutex_unlock(&data->watchdog_lock); +  	return ret;  } -static int watchdog_stop_unlocked(struct sch56xx_watchdog_data *data) +static int watchdog_stop(struct watchdog_device *wddev)  { +	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);  	int ret = 0;  	u8 val; -	if (!data->addr) -		return -ENODEV; - -	if (data->watchdog_output_enable & SCH56XX_WDOG_OUTPUT_ENABLE) { -		val = data->watchdog_output_enable & -		      ~SCH56XX_WDOG_OUTPUT_ENABLE; -		mutex_lock(data->io_lock); -		ret = sch56xx_write_virtual_reg(data->addr, -						SCH56XX_REG_WDOG_OUTPUT_ENABLE, -						val); -		mutex_unlock(data->io_lock); -		if (ret) -			return ret; - -		data->watchdog_output_enable = val; -	} - -	return ret; -} - -static int watchdog_stop(struct sch56xx_watchdog_data *data) -{ -	int ret; - -	mutex_lock(&data->watchdog_lock); -	ret = watchdog_stop_unlocked(data); -	mutex_unlock(&data->watchdog_lock); - -	return ret; -} - -static int watchdog_release(struct inode *inode, struct file *filp) -{ -	struct sch56xx_watchdog_data *data = filp->private_data; - -	if (data->watchdog_expect_close) { -		watchdog_stop(data); -		data->watchdog_expect_close = 0; -	} else { -		watchdog_trigger(data); -		pr_crit("unexpected close, not stopping watchdog!\n"); -	} - -	clear_bit(0, &data->watchdog_is_open); - -	mutex_lock(&watchdog_data_mutex); -	kref_put(&data->kref, sch56xx_watchdog_release_resources); -	mutex_unlock(&watchdog_data_mutex); - -	return 0; -} - -static int watchdog_open(struct inode *inode, struct file *filp) -{ -	struct sch56xx_watchdog_data *pos, *data = NULL; -	int ret, watchdog_is_open; - -	/* -	 * We get called from drivers/char/misc.c with misc_mtx hold, and we -	 * call misc_register() from sch56xx_watchdog_probe() with -	 * watchdog_data_mutex hold, as misc_register() takes the misc_mtx -	 * lock, this is a possible deadlock, so we use mutex_trylock here. -	 */ -	if (!mutex_trylock(&watchdog_data_mutex)) -		return -ERESTARTSYS; -	list_for_each_entry(pos, &watchdog_data_list, list) { -		if (pos->watchdog_miscdev.minor == iminor(inode)) { -			data = pos; -			break; -		} -	} -	/* Note we can never not have found data, so we don't check for this */ -	watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open); -	if (!watchdog_is_open) -		kref_get(&data->kref); -	mutex_unlock(&watchdog_data_mutex); - -	if (watchdog_is_open) -		return -EBUSY; - -	filp->private_data = data; - -	/* Start the watchdog */ -	ret = watchdog_start(data); -	if (ret) { -		watchdog_release(inode, filp); +	val = data->watchdog_output_enable & ~SCH56XX_WDOG_OUTPUT_ENABLE; +	mutex_lock(data->io_lock); +	ret = sch56xx_write_virtual_reg(data->addr, +					SCH56XX_REG_WDOG_OUTPUT_ENABLE, val); +	mutex_unlock(data->io_lock); +	if (ret)  		return ret; -	} -	return nonseekable_open(inode, filp); +	data->watchdog_output_enable = val; +	return 0;  } -static ssize_t watchdog_write(struct file *filp, const char __user *buf, -	size_t count, loff_t *offset) +static void watchdog_ref(struct watchdog_device *wddev)  { -	int ret; -	struct sch56xx_watchdog_data *data = filp->private_data; - -	if (count) { -		if (!nowayout) { -			size_t i; +	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev); -			/* Clear it in case it was set with a previous write */ -			data->watchdog_expect_close = 0; - -			for (i = 0; i != count; i++) { -				char c; -				if (get_user(c, buf + i)) -					return -EFAULT; -				if (c == 'V') -					data->watchdog_expect_close = 1; -			} -		} -		ret = watchdog_trigger(data); -		if (ret) -			return ret; -	} -	return count; +	kref_get(&data->kref);  } -static long watchdog_ioctl(struct file *filp, unsigned int cmd, -			   unsigned long arg) +static void watchdog_unref(struct watchdog_device *wddev)  { -	struct watchdog_info ident = { -		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, -		.identity = "sch56xx watchdog" -	}; -	int i, ret = 0; -	struct sch56xx_watchdog_data *data = filp->private_data; - -	switch (cmd) { -	case WDIOC_GETSUPPORT: -		ident.firmware_version = data->revision; -		if (!nowayout) -			ident.options |= WDIOF_MAGICCLOSE; -		if (copy_to_user((void __user *)arg, &ident, sizeof(ident))) -			ret = -EFAULT; -		break; - -	case WDIOC_GETSTATUS: -	case WDIOC_GETBOOTSTATUS: -		ret = put_user(0, (int __user *)arg); -		break; - -	case WDIOC_KEEPALIVE: -		ret = watchdog_trigger(data); -		break; - -	case WDIOC_GETTIMEOUT: -		i = watchdog_get_timeout(data); -		ret = put_user(i, (int __user *)arg); -		break; - -	case WDIOC_SETTIMEOUT: -		if (get_user(i, (int __user *)arg)) { -			ret = -EFAULT; -			break; -		} -		ret = watchdog_set_timeout(data, i); -		if (ret >= 0) -			ret = put_user(ret, (int __user *)arg); -		break; - -	case WDIOC_SETOPTIONS: -		if (get_user(i, (int __user *)arg)) { -			ret = -EFAULT; -			break; -		} - -		if (i & WDIOS_DISABLECARD) -			ret = watchdog_stop(data); -		else if (i & WDIOS_ENABLECARD) -			ret = watchdog_trigger(data); -		else -			ret = -EINVAL; -		break; +	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev); -	default: -		ret = -ENOTTY; -	} -	return ret; +	kref_put(&data->kref, watchdog_release_resources);  } -static const struct file_operations watchdog_fops = { -	.owner = THIS_MODULE, -	.llseek = no_llseek, -	.open = watchdog_open, -	.release = watchdog_release, -	.write = watchdog_write, -	.unlocked_ioctl = watchdog_ioctl, +static const struct watchdog_ops watchdog_ops = { +	.owner		= THIS_MODULE, +	.start		= watchdog_start, +	.stop		= watchdog_stop, +	.ping		= watchdog_trigger, +	.set_timeout	= watchdog_set_timeout, +	.ref		= watchdog_ref, +	.unref		= watchdog_unref,  }; -struct sch56xx_watchdog_data *sch56xx_watchdog_register( +struct sch56xx_watchdog_data *sch56xx_watchdog_register(struct device *parent,  	u16 addr, u32 revision, struct mutex *io_lock, int check_enabled)  {  	struct sch56xx_watchdog_data *data; -	int i, err, control, output_enable; -	const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; +	int err, control, output_enable;  	/* Cache the watchdog registers */  	mutex_lock(io_lock); @@ -656,82 +447,55 @@ struct sch56xx_watchdog_data *sch56xx_watchdog_register(  		return NULL;  	data->addr = addr; -	data->revision = revision;  	data->io_lock = io_lock; -	data->watchdog_control = control; -	data->watchdog_output_enable = output_enable; -	mutex_init(&data->watchdog_lock); -	INIT_LIST_HEAD(&data->list);  	kref_init(&data->kref); -	err = watchdog_set_timeout(data, 60); -	if (err < 0) -		goto error; +	strlcpy(data->wdinfo.identity, "sch56xx watchdog", +		sizeof(data->wdinfo.identity)); +	data->wdinfo.firmware_version = revision; +	data->wdinfo.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT; +	if (!nowayout) +		data->wdinfo.options |= WDIOF_MAGICCLOSE; -	/* -	 * We take the data_mutex lock early so that watchdog_open() cannot -	 * run when misc_register() has completed, but we've not yet added -	 * our data to the watchdog_data_list. -	 */ -	mutex_lock(&watchdog_data_mutex); -	for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { -		/* Register our watchdog part */ -		snprintf(data->watchdog_name, sizeof(data->watchdog_name), -			"watchdog%c", (i == 0) ? '\0' : ('0' + i)); -		data->watchdog_miscdev.name = data->watchdog_name; -		data->watchdog_miscdev.fops = &watchdog_fops; -		data->watchdog_miscdev.minor = watchdog_minors[i]; -		err = misc_register(&data->watchdog_miscdev); -		if (err == -EBUSY) -			continue; -		if (err) -			break; +	data->wddev.info = &data->wdinfo; +	data->wddev.ops = &watchdog_ops; +	data->wddev.parent = parent; +	data->wddev.timeout = 60; +	data->wddev.min_timeout = 1; +	data->wddev.max_timeout = 255 * 60; +	if (nowayout) +		set_bit(WDOG_NO_WAY_OUT, &data->wddev.status); +	if (output_enable & SCH56XX_WDOG_OUTPUT_ENABLE) +		set_bit(WDOG_ACTIVE, &data->wddev.status); -		list_add(&data->list, &watchdog_data_list); -		pr_info("Registered /dev/%s chardev major 10, minor: %d\n", -			data->watchdog_name, watchdog_minors[i]); -		break; -	} -	mutex_unlock(&watchdog_data_mutex); +	/* Since the watchdog uses a downcounter there is no register to read +	   the BIOS set timeout from (if any was set at all) -> +	   Choose a preset which will give us a 1 minute timeout */ +	if (control & SCH56XX_WDOG_TIME_BASE_SEC) +		data->watchdog_preset = 60; /* seconds */ +	else +		data->watchdog_preset = 1; /* minute */ + +	data->watchdog_control = control; +	data->watchdog_output_enable = output_enable; +	watchdog_set_drvdata(&data->wddev, data); +	err = watchdog_register_device(&data->wddev);  	if (err) {  		pr_err("Registering watchdog chardev: %d\n", err); -		goto error; -	} -	if (i == ARRAY_SIZE(watchdog_minors)) { -		pr_warn("Couldn't register watchdog (no free minor)\n"); -		goto error; +		kfree(data); +		return NULL;  	}  	return data; - -error: -	kfree(data); -	return NULL;  }  EXPORT_SYMBOL(sch56xx_watchdog_register);  void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data)  { -	mutex_lock(&watchdog_data_mutex); -	misc_deregister(&data->watchdog_miscdev); -	list_del(&data->list); -	mutex_unlock(&watchdog_data_mutex); - -	mutex_lock(&data->watchdog_lock); -	if (data->watchdog_is_open) { -		pr_warn("platform device unregistered with watchdog " -			"open! Stopping watchdog.\n"); -		watchdog_stop_unlocked(data); -	} -	/* Tell the wdog start/stop/trigger functions our dev is gone */ -	data->addr = 0; -	data->io_lock = NULL; -	mutex_unlock(&data->watchdog_lock); - -	mutex_lock(&watchdog_data_mutex); -	kref_put(&data->kref, sch56xx_watchdog_release_resources); -	mutex_unlock(&watchdog_data_mutex); +	watchdog_unregister_device(&data->wddev); +	kref_put(&data->kref, watchdog_release_resources); +	/* Don't touch data after this it may have been free-ed! */  }  EXPORT_SYMBOL(sch56xx_watchdog_unregister); diff --git a/drivers/hwmon/sch56xx-common.h b/drivers/hwmon/sch56xx-common.h index 7475086eb97..704ea2c6d28 100644 --- a/drivers/hwmon/sch56xx-common.h +++ b/drivers/hwmon/sch56xx-common.h @@ -27,6 +27,6 @@ int sch56xx_read_virtual_reg16(u16 addr, u16 reg);  int sch56xx_read_virtual_reg12(u16 addr, u16 msb_reg, u16 lsn_reg,  			       int high_nibble); -struct sch56xx_watchdog_data *sch56xx_watchdog_register( +struct sch56xx_watchdog_data *sch56xx_watchdog_register(struct device *parent,  	u16 addr, u32 revision, struct mutex *io_lock, int check_enabled);  void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data); 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/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..ab4825205a9 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1359,19 +1359,17 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)  	};  	res = platform_get_resource(pdev, IORESOURCE_IO, 0); -	if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) { +	if (!devm_request_region(dev, res->start, WINB_REGION_SIZE, DRVNAME)) {  		dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",  			(unsigned long)res->start,  			(unsigned long)(res->start + WINB_REGION_SIZE - 1)); -		err = -EBUSY; -		goto ERROR0; +		return -EBUSY;  	} -	data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL); -	if (!data) { -		err = -ENOMEM; -		goto ERROR1; -	} +	data = devm_kzalloc(dev, sizeof(struct w83627hf_data), GFP_KERNEL); +	if (!data) +		return -ENOMEM; +  	data->addr = res->start;  	data->type = sio_data->type;  	data->name = names[sio_data->type]; @@ -1391,7 +1389,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)  	/* Register common device attributes */  	err = sysfs_create_group(&dev->kobj, &w83627hf_group);  	if (err) -		goto ERROR3; +		return err;  	/* Register chip-specific device attributes */  	if (data->type == w83627hf || data->type == w83697hf) @@ -1419,7 +1417,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)  				&sensor_dev_attr_pwm1_freq.dev_attr))  		 || (err = device_create_file(dev,  				&sensor_dev_attr_pwm2_freq.dev_attr))) -			goto ERROR4; +			goto error;  	if (data->type != w83697hf)  		if ((err = device_create_file(dev, @@ -1454,7 +1452,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)  				&sensor_dev_attr_temp3_beep.dev_attr))  		 || (err = device_create_file(dev,  				&sensor_dev_attr_temp3_type.dev_attr))) -			goto ERROR4; +			goto error;  	if (data->type != w83697hf && data->vid != 0xff) {  		/* Convert VID to voltage based on VRM */ @@ -1462,14 +1460,14 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)  		if ((err = device_create_file(dev, &dev_attr_cpu0_vid))  		 || (err = device_create_file(dev, &dev_attr_vrm))) -			goto ERROR4; +			goto error;  	}  	if (data->type == w83627thf || data->type == w83637hf  	    || data->type == w83687thf) {  		err = device_create_file(dev, &sensor_dev_attr_pwm3.dev_attr);  		if (err) -			goto ERROR4; +			goto error;  	}  	if (data->type == w83637hf || data->type == w83687thf) @@ -1479,57 +1477,45 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)  				&sensor_dev_attr_pwm2_freq.dev_attr))  		 || (err = device_create_file(dev,  				&sensor_dev_attr_pwm3_freq.dev_attr))) -			goto ERROR4; +			goto error;  	if (data->type != w83627hf)  		if ((err = device_create_file(dev,  				&sensor_dev_attr_pwm1_enable.dev_attr))  		 || (err = device_create_file(dev,  				&sensor_dev_attr_pwm2_enable.dev_attr))) -			goto ERROR4; +			goto error;  	if (data->type == w83627thf || data->type == w83637hf  	    || data->type == w83687thf) {  		err = device_create_file(dev,  					 &sensor_dev_attr_pwm3_enable.dev_attr);  		if (err) -			goto ERROR4; +			goto error;  	}  	data->hwmon_dev = hwmon_device_register(dev);  	if (IS_ERR(data->hwmon_dev)) {  		err = PTR_ERR(data->hwmon_dev); -		goto ERROR4; +		goto error;  	}  	return 0; -      ERROR4: + error:  	sysfs_remove_group(&dev->kobj, &w83627hf_group);  	sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); -      ERROR3: -	platform_set_drvdata(pdev, NULL); -	kfree(data); -      ERROR1: -	release_region(res->start, WINB_REGION_SIZE); -      ERROR0:  	return err;  }  static int __devexit w83627hf_remove(struct platform_device *pdev)  {  	struct w83627hf_data *data = platform_get_drvdata(pdev); -	struct resource *res;  	hwmon_device_unregister(data->hwmon_dev);  	sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);  	sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); -	platform_set_drvdata(pdev, NULL); -	kfree(data); - -	res = platform_get_resource(pdev, IORESOURCE_IO, 0); -	release_region(res->start, WINB_REGION_SIZE);  	return 0;  } diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 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;  }  |