From 436d42c61c3eef1d02256174c8615046c61a28ad Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 24 Aug 2012 15:22:12 +0200 Subject: ARM: samsung: move platform_data definitions Platform data for device drivers should be defined in include/linux/platform_data/*.h, not in the architecture and platform specific directories. This moves such data out of the samsung include directories Signed-off-by: Arnd Bergmann Acked-by: Mark Brown Acked-by: Greg Kroah-Hartman Acked-by: Nicolas Pitre Acked-by: Mauro Carvalho Chehab Cc: Kukjin Kim Cc: Kyungmin Park Cc: Ben Dooks Cc: Jeff Garzik Cc: Guenter Roeck Cc: "Wolfram Sang (embedded platforms)" Cc: Dmitry Torokhov Cc: Bryan Wu Cc: Richard Purdie Cc: Sylwester Nawrocki Cc: Chris Ball Cc: David Woodhouse Cc: Grant Likely Cc: Felipe Balbi Cc: Alan Stern Cc: Sangbeom Kim Cc: Liam Girdwood Cc: linux-samsung-soc@vger.kernel.org --- drivers/hwmon/s3c-hwmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index b7975f858cff..fe11b95670bd 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c @@ -34,7 +34,7 @@ #include #include -#include +#include struct s3c_hwmon_attr { struct sensor_device_attribute in; -- cgit v1.2.3 From 0038389add7388954d74985ce7e631076216cf02 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 4 Aug 2012 09:46:36 -0700 Subject: hwmon: (f71882fg) Fix build warning Fix: warning: 'address' may be used uninitialized in this function [-Wuninitialized] While this is a false warning, the patch reduces module size on x86_64 by approximately 175 bytes, so it is still worth the effort. Signed-off-by: Guenter Roeck Acked-by: Hans de Goede --- drivers/hwmon/f71882fg.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 6d1226365e30..dd5ae567bf92 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -2532,10 +2532,10 @@ static int f71882fg_remove(struct platform_device *pdev) return 0; } -static int __init f71882fg_find(int sioaddr, unsigned short *address, - struct f71882fg_sio_data *sio_data) +static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data) { u16 devid; + unsigned short address; int err = superio_enter(sioaddr); if (err) return err; @@ -2603,25 +2603,25 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, goto exit; } - *address = superio_inw(sioaddr, SIO_REG_ADDR); - if (*address == 0) { + address = superio_inw(sioaddr, SIO_REG_ADDR); + if (address == 0) { pr_warn("Base address not set\n"); err = -ENODEV; goto exit; } - *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ + address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ - err = 0; + err = address; pr_info("Found %s chip at %#x, revision %d\n", - f71882fg_names[sio_data->type], (unsigned int)*address, + f71882fg_names[sio_data->type], (unsigned int)address, (int)superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); return err; } -static int __init f71882fg_device_add(unsigned short address, - const struct f71882fg_sio_data *sio_data) +static int __init f71882fg_device_add(int address, + const struct f71882fg_sio_data *sio_data) { struct resource res = { .start = address, @@ -2668,19 +2668,21 @@ exit_device_put: static int __init f71882fg_init(void) { - int err = -ENODEV; - unsigned short address; + int err; + int address; struct f71882fg_sio_data sio_data; memset(&sio_data, 0, sizeof(sio_data)); - if (f71882fg_find(0x2e, &address, &sio_data) && - f71882fg_find(0x4e, &address, &sio_data)) - goto exit; + address = f71882fg_find(0x2e, &sio_data); + if (address < 0) + address = f71882fg_find(0x4e, &sio_data); + if (address < 0) + return address; err = platform_driver_register(&f71882fg_driver); if (err) - goto exit; + return err; err = f71882fg_device_add(address, &sio_data); if (err) @@ -2690,7 +2692,6 @@ static int __init f71882fg_init(void) exit_driver: platform_driver_unregister(&f71882fg_driver); -exit: return err; } -- cgit v1.2.3 From 313829ee3cccbc658409357f32a1508620b60142 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 4 Aug 2012 09:54:16 -0700 Subject: hwmon: (sch56xx-common) Fix build warnings Fix: warning: 'address' may be used uninitialized in this function warning: 'name' may be used uninitialized in this function While those are false warnings, the patch reduces module size on x86_64 by approximately 110 bytes, so it is still worth the effort. Signed-off-by: Guenter Roeck Acked-by: Hans de Goede --- drivers/hwmon/sch56xx-common.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c index 4380f5d07be2..d00b30adc34b 100644 --- a/drivers/hwmon/sch56xx-common.c +++ b/drivers/hwmon/sch56xx-common.c @@ -503,10 +503,10 @@ EXPORT_SYMBOL(sch56xx_watchdog_unregister); * platform dev find, add and remove functions */ -static int __init sch56xx_find(int sioaddr, unsigned short *address, - const char **name) +static int __init sch56xx_find(int sioaddr, const char **name) { u8 devid; + unsigned short address; int err; err = superio_enter(sioaddr); @@ -540,20 +540,21 @@ static int __init sch56xx_find(int sioaddr, unsigned short *address, * Warning the order of the low / high byte is the other way around * as on most other superio devices!! */ - *address = superio_inb(sioaddr, SIO_REG_ADDR) | + address = superio_inb(sioaddr, SIO_REG_ADDR) | superio_inb(sioaddr, SIO_REG_ADDR + 1) << 8; - if (*address == 0) { + if (address == 0) { pr_warn("Base address not set\n"); err = -ENODEV; goto exit; } + err = address; exit: superio_exit(sioaddr); return err; } -static int __init sch56xx_device_add(unsigned short address, const char *name) +static int __init sch56xx_device_add(int address, const char *name) { struct resource res = { .start = address, @@ -593,15 +594,14 @@ exit_device_put: static int __init sch56xx_init(void) { - int err; - unsigned short address; - const char *name; - - err = sch56xx_find(0x4e, &address, &name); - if (err) - err = sch56xx_find(0x2e, &address, &name); - if (err) - return err; + int address; + const char *name = NULL; + + address = sch56xx_find(0x4e, &name); + if (address < 0) + address = sch56xx_find(0x2e, &name); + if (address < 0) + return address; return sch56xx_device_add(address, name); } -- cgit v1.2.3 From d8f30ad8e556cad5ee23fdb63845914aec4a8172 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:56 -0700 Subject: hwmon: (abituguru) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Hans de Goede Signed-off-by: Guenter Roeck --- drivers/hwmon/abituguru.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index d4419b47f3d4..78b81793ddd9 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1278,7 +1278,8 @@ static int __devinit abituguru_probe(struct platform_device *pdev) 0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02, 0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C }; - data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct abituguru_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -1430,8 +1431,6 @@ abituguru_probe_error: for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) device_remove_file(&pdev->dev, &abituguru_sysfs_attr[i].dev_attr); - platform_set_drvdata(pdev, NULL); - kfree(data); return res; } @@ -1446,8 +1445,6 @@ static int __devexit abituguru_remove(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) device_remove_file(&pdev->dev, &abituguru_sysfs_attr[i].dev_attr); - platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } -- cgit v1.2.3 From a34c26d8e288d48e70c0e722da0c745e14d74e3a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:57 -0700 Subject: hwmon: (abituguru3) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Hans de Goede Cc: Alistair John Strachan Signed-off-by: Guenter Roeck --- drivers/hwmon/abituguru3.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 5d582aebff87..b174b8b2b4df 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -976,7 +976,8 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) u8 buf[2]; u16 id; - data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct abituguru3_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -1068,7 +1069,6 @@ abituguru3_probe_error: for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) device_remove_file(&pdev->dev, &abituguru3_sysfs_attr[i].dev_attr); - kfree(data); return res; } @@ -1084,8 +1084,6 @@ static int __devexit abituguru3_remove(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) device_remove_file(&pdev->dev, &abituguru3_sysfs_attr[i].dev_attr); - kfree(data); - return 0; } -- cgit v1.2.3 From be92304034220ee94a34df379101f14570db331b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:57 -0700 Subject: hwmon: (ad7314) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/ad7314.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index f915eb1c29f7..37c01e72d699 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -112,16 +112,16 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev) int ret; struct ad7314_data *chip; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - ret = -ENOMEM; - goto error_ret; - } + chip = devm_kzalloc(&spi_dev->dev, sizeof(*chip), GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + dev_set_drvdata(&spi_dev->dev, chip); ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group); if (ret < 0) - goto error_free_chip; + return ret; + chip->hwmon_dev = hwmon_device_register(&spi_dev->dev); if (IS_ERR(chip->hwmon_dev)) { ret = PTR_ERR(chip->hwmon_dev); @@ -132,9 +132,6 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev) return 0; error_remove_group: sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); -error_free_chip: - kfree(chip); -error_ret: return ret; } @@ -144,7 +141,6 @@ static int __devexit ad7314_remove(struct spi_device *spi_dev) hwmon_device_unregister(chip->hwmon_dev); sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); - kfree(chip); return 0; } -- cgit v1.2.3 From 0fee6591b7f82bb293de7949297fc8db59b31f0d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:57 -0700 Subject: hwmon: (ad7414) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/ad7414.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index 06d2d60d1fd0..b420fb3f3a71 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c @@ -185,16 +185,13 @@ static int ad7414_probe(struct i2c_client *client, int err; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_READ_WORD_DATA)) { - err = -EOPNOTSUPP; - goto exit; - } + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -EOPNOTSUPP; - data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct ad7414_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->lock); @@ -214,7 +211,7 @@ static int ad7414_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &ad7414_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -226,9 +223,6 @@ static int ad7414_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &ad7414_group); -exit_free: - kfree(data); -exit: return err; } @@ -238,7 +232,6 @@ static int __devexit ad7414_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ad7414_group); - kfree(data); return 0; } -- cgit v1.2.3 From d5282926aa89587d78bbfeb6655500b1a72de15c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:58 -0700 Subject: hwmon: (ad7418) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/ad7418.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index a50a6bef16c4..57d4a6295675 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c @@ -227,16 +227,13 @@ static int ad7418_probe(struct i2c_client *client, int err; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) { - err = -EOPNOTSUPP; - goto exit; - } + I2C_FUNC_SMBUS_WORD_DATA)) + return -EOPNOTSUPP; - data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct ad7418_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); @@ -268,7 +265,7 @@ static int ad7418_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &data->attrs); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -280,9 +277,6 @@ static int ad7418_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_free: - kfree(data); -exit: return err; } @@ -291,7 +285,6 @@ static int ad7418_remove(struct i2c_client *client) struct ad7418_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->attrs); - kfree(data); return 0; } -- cgit v1.2.3 From c60da82593b30d3b3b97e80f6f74b5f4afa9d0b5 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:58 -0700 Subject: hwmon: (adcxx) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/adcxx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c index a3d3183454ad..111af7c4a3d4 100644 --- a/drivers/hwmon/adcxx.c +++ b/drivers/hwmon/adcxx.c @@ -171,7 +171,7 @@ static int __devinit adcxx_probe(struct spi_device *spi) int status; int i; - adc = kzalloc(sizeof *adc, GFP_KERNEL); + adc = devm_kzalloc(&spi->dev, sizeof(*adc), GFP_KERNEL); if (!adc) return -ENOMEM; @@ -208,7 +208,6 @@ out_err: spi_set_drvdata(spi, NULL); mutex_unlock(&adc->lock); - kfree(adc); return status; } @@ -224,7 +223,6 @@ static int __devexit adcxx_remove(struct spi_device *spi) spi_set_drvdata(spi, NULL); mutex_unlock(&adc->lock); - kfree(adc); return 0; } -- cgit v1.2.3 From 08940b8aba8ded377e546c12c5b932364c0a03cc Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:57:59 -0700 Subject: hwmon: (adm1029) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Corentin Labbe Signed-off-by: Guenter Roeck --- drivers/hwmon/adm1029.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 80cc465d8ac7..97f4718382f6 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -342,11 +342,10 @@ static int adm1029_probe(struct i2c_client *client, struct adm1029_data *data; int err; - data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct adm1029_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -355,15 +354,13 @@ static int adm1029_probe(struct i2c_client *client, * Initialize the ADM1029 chip * Check config register */ - if (adm1029_init_client(client) == 0) { - err = -ENODEV; - goto exit_free; - } + if (adm1029_init_client(client) == 0) + return -ENODEV; /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &adm1029_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -375,9 +372,6 @@ static int adm1029_probe(struct i2c_client *client, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &adm1029_group); - exit_free: - kfree(data); - exit: return err; } @@ -405,7 +399,6 @@ static int adm1029_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1029_group); - kfree(data); return 0; } -- cgit v1.2.3 From 57457e314eefc7bce93854918a234e4ac9a52922 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:00 -0700 Subject: hwmon: (ads1015) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Dirk Eibach Signed-off-by: Guenter Roeck --- drivers/hwmon/ads1015.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index 1958f03efd7a..2798246ad814 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -156,7 +156,6 @@ static int ads1015_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); for (k = 0; k < ADS1015_CHANNELS; ++k) device_remove_file(&client->dev, &ads1015_in[k].dev_attr); - kfree(data); return 0; } @@ -254,11 +253,10 @@ static int ads1015_probe(struct i2c_client *client, int err; unsigned int k; - data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct ads1015_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -284,8 +282,6 @@ static int ads1015_probe(struct i2c_client *client, exit_remove: for (k = 0; k < ADS1015_CHANNELS; ++k) device_remove_file(&client->dev, &ads1015_in[k].dev_attr); - kfree(data); -exit: return err; } -- cgit v1.2.3 From 34e3f7f5a283c5520e0e1a409931a632f4d2662e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:00 -0700 Subject: hwmon: (ads7828) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/ads7828.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index bf3fdf495595..1f9e8af0f322 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -154,7 +154,6 @@ static int ads7828_remove(struct i2c_client *client) struct ads7828_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ads7828_group); - kfree(i2c_get_clientdata(client)); return 0; } @@ -217,11 +216,10 @@ static int ads7828_probe(struct i2c_client *client, struct ads7828_data *data; int err; - data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct ads7828_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -229,7 +227,7 @@ static int ads7828_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &ads7828_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -241,9 +239,6 @@ static int ads7828_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &ads7828_group); -exit_free: - kfree(data); -exit: return err; } -- cgit v1.2.3 From 33fd2b84c94f978e661c20267548b736d84f4645 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:00 -0700 Subject: hwmon: (ads7871) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/ads7871.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index 7bf4ce3d405e..1b53aa42b6db 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c @@ -198,20 +198,17 @@ static int __devinit ads7871_probe(struct spi_device *spi) * because there is no other error checking on an SPI bus * we need to make sure we really have a chip */ - if (val != ret) { - err = -ENODEV; - goto exit; - } + if (val != ret) + return -ENODEV; - pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); - if (!pdata) { - err = -ENOMEM; - goto exit; - } + pdata = devm_kzalloc(&spi->dev, sizeof(struct ads7871_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; err = sysfs_create_group(&spi->dev.kobj, &ads7871_group); if (err < 0) - goto error_free; + return err; spi_set_drvdata(spi, pdata); @@ -225,9 +222,6 @@ static int __devinit ads7871_probe(struct spi_device *spi) error_remove: sysfs_remove_group(&spi->dev.kobj, &ads7871_group); -error_free: - kfree(pdata); -exit: return err; } @@ -237,7 +231,6 @@ static int __devexit ads7871_remove(struct spi_device *spi) hwmon_device_unregister(pdata->hwmon_dev); sysfs_remove_group(&spi->dev.kobj, &ads7871_group); - kfree(pdata); return 0; } -- cgit v1.2.3 From 65ec17b0d5a5351846e3503d5599e1630e57ffc4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:01 -0700 Subject: hwmon: (adt7411) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Wolfram Sang Signed-off-by: Guenter Roeck --- drivers/hwmon/adt7411.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index 71bacc56e138..fe72c69a2d68 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -283,7 +283,7 @@ static int __devinit adt7411_probe(struct i2c_client *client, struct adt7411_data *data; int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -294,14 +294,14 @@ static int __devinit adt7411_probe(struct i2c_client *client, ret = adt7411_modify_bit(client, ADT7411_REG_CFG1, ADT7411_CFG1_START_MONITOR, 1); if (ret < 0) - goto exit_free; + return ret; /* force update on first occasion */ data->next_update = jiffies; ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp); if (ret) - goto exit_free; + return ret; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -315,8 +315,6 @@ static int __devinit adt7411_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); - exit_free: - kfree(data); return ret; } @@ -326,7 +324,6 @@ static int __devexit adt7411_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); - kfree(data); return 0; } -- cgit v1.2.3 From 0880830096ee314c953d4bd5d017e27589f0e830 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:01 -0700 Subject: hwmon: (adt7462) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/adt7462.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index 339269f76e57..baee482aedfc 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -1931,11 +1931,10 @@ static int adt7462_probe(struct i2c_client *client, struct adt7462_data *data; int err; - data = kzalloc(sizeof(struct adt7462_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->lock); @@ -1946,7 +1945,7 @@ static int adt7462_probe(struct i2c_client *client, data->attrs.attrs = adt7462_attr; err = sysfs_create_group(&client->dev.kobj, &data->attrs); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -1958,9 +1957,6 @@ static int adt7462_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_free: - kfree(data); -exit: return err; } @@ -1970,7 +1966,6 @@ static int adt7462_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->attrs); - kfree(data); return 0; } -- cgit v1.2.3 From 9cc7dcc5238308250eb3ca4314f6423bd6f54ef0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:01 -0700 Subject: hwmon: (adt7470) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/adt7470.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 54ec890521ff..39ecb1a3b9ef 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -1256,11 +1256,10 @@ static int adt7470_probe(struct i2c_client *client, struct adt7470_data *data; int err; - data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct adt7470_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; data->num_temp_sensors = -1; data->auto_update_interval = AUTO_UPDATE_INTERVAL; @@ -1277,7 +1276,7 @@ static int adt7470_probe(struct i2c_client *client, data->attrs.attrs = adt7470_attr; err = sysfs_create_group(&client->dev.kobj, &data->attrs); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -1299,9 +1298,6 @@ exit_unregister: hwmon_device_unregister(data->hwmon_dev); exit_remove: sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_free: - kfree(data); -exit: return err; } @@ -1313,7 +1309,6 @@ static int adt7470_remove(struct i2c_client *client) wait_for_completion(&data->auto_update_stop); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->attrs); - kfree(data); return 0; } -- cgit v1.2.3 From f9286434ea64803b673bb4ec0dd7084b13c2d90b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:02 -0700 Subject: hwmon: (amc6821) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/amc6821.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index f600fa1f92e3..ae482e3afdac 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -862,12 +862,10 @@ static int amc6821_probe( struct amc6821_data *data; int err; - data = kzalloc(sizeof(struct amc6821_data), GFP_KERNEL); - if (!data) { - dev_err(&client->dev, "out of memory.\n"); + data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data), + GFP_KERNEL); + if (!data) return -ENOMEM; - } - i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -877,11 +875,11 @@ static int amc6821_probe( */ err = amc6821_init_client(client); if (err) - goto err_free; + return err; err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp); if (err) - goto err_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (!IS_ERR(data->hwmon_dev)) @@ -890,8 +888,6 @@ static int amc6821_probe( err = PTR_ERR(data->hwmon_dev); dev_err(&client->dev, "error registering hwmon device.\n"); sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); -err_free: - kfree(data); return err; } @@ -902,8 +898,6 @@ static int amc6821_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); - kfree(data); - return 0; } -- cgit v1.2.3 From 64adf39837c7cf744161b18598577cbe2467a01d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:02 -0700 Subject: hwmon: (asb100) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Mark M. Hoffman Signed-off-by: Guenter Roeck --- drivers/hwmon/asb100.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 4b8814deabb1..a227be47149f 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -787,12 +787,10 @@ static int asb100_probe(struct i2c_client *client, int err; struct asb100_data *data; - data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL); - if (!data) { - pr_debug("probe failed, kzalloc failed!\n"); - err = -ENOMEM; - goto ERROR0; - } + data = devm_kzalloc(&client->dev, sizeof(struct asb100_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->lock); @@ -801,7 +799,7 @@ static int asb100_probe(struct i2c_client *client, /* Attach secondary lm75 clients */ err = asb100_detect_subclients(client); if (err) - goto ERROR1; + return err; /* Initialize the chip */ asb100_init_client(client); @@ -829,9 +827,6 @@ ERROR4: ERROR3: i2c_unregister_device(data->lm75[1]); i2c_unregister_device(data->lm75[0]); -ERROR1: - kfree(data); -ERROR0: return err; } @@ -845,8 +840,6 @@ static int asb100_remove(struct i2c_client *client) i2c_unregister_device(data->lm75[1]); i2c_unregister_device(data->lm75[0]); - kfree(data); - return 0; } -- cgit v1.2.3 From 805fd8c5b8868036e1e1298fcccf7499f6d6ede2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:03 -0700 Subject: hwmon: (dme1737) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Juerg Haefliger Signed-off-by: Guenter Roeck --- drivers/hwmon/dme1737.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index e7c6a19f3b25..fe0eeec0b750 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -2475,11 +2475,9 @@ static int dme1737_i2c_probe(struct i2c_client *client, struct device *dev = &client->dev; int err; - data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); data->type = id->driver_data; @@ -2491,14 +2489,14 @@ static int dme1737_i2c_probe(struct i2c_client *client, err = dme1737_init_device(dev); if (err) { dev_err(dev, "Failed to initialize device.\n"); - goto exit_kfree; + return err; } /* Create sysfs files */ err = dme1737_create_files(dev); if (err) { dev_err(dev, "Failed to create sysfs files.\n"); - goto exit_kfree; + return err; } /* Register device */ @@ -2513,9 +2511,6 @@ static int dme1737_i2c_probe(struct i2c_client *client, exit_remove: dme1737_remove_files(dev); -exit_kfree: - kfree(data); -exit: return err; } @@ -2526,7 +2521,6 @@ static int dme1737_i2c_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); dme1737_remove_files(&client->dev); - kfree(data); return 0; } @@ -2645,19 +2639,16 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) int err; res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, DME1737_EXTENT, "dme1737")) { + if (!devm_request_region(dev, res->start, DME1737_EXTENT, "dme1737")) { dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", (unsigned short)res->start, (unsigned short)res->start + DME1737_EXTENT - 1); - err = -EBUSY; - goto exit; + return -EBUSY; } - data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit_release_region; - } + data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL); + if (!data) + return -ENOMEM; data->addr = res->start; platform_set_drvdata(pdev, data); @@ -2683,8 +2674,7 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) (device == SCH5127_DEVICE)) { data->type = sch5127; } else { - err = -ENODEV; - goto exit_kfree; + return -ENODEV; } } @@ -2703,14 +2693,14 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) err = dme1737_init_device(dev); if (err) { dev_err(dev, "Failed to initialize device.\n"); - goto exit_kfree; + return err; } /* Create sysfs files */ err = dme1737_create_files(dev); if (err) { dev_err(dev, "Failed to create sysfs files.\n"); - goto exit_kfree; + return err; } /* Register device */ @@ -2725,12 +2715,6 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) exit_remove_files: dme1737_remove_files(dev); -exit_kfree: - platform_set_drvdata(pdev, NULL); - kfree(data); -exit_release_region: - release_region(res->start, DME1737_EXTENT); -exit: return err; } @@ -2740,9 +2724,6 @@ static int __devexit dme1737_isa_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); dme1737_remove_files(&pdev->dev); - release_region(data->addr, DME1737_EXTENT); - platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } -- cgit v1.2.3 From 3aa9d1df7e7abc91fb11bff41f389f3fc7b39eee Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:03 -0700 Subject: hwmon: (ds620) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/ds620.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c index 50663efad412..f1d6b422cf06 100644 --- a/drivers/hwmon/ds620.c +++ b/drivers/hwmon/ds620.c @@ -232,11 +232,10 @@ static int ds620_probe(struct i2c_client *client, struct ds620_data *data; int err; - data = kzalloc(sizeof(struct ds620_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct ds620_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -247,7 +246,7 @@ static int ds620_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &ds620_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -261,9 +260,6 @@ static int ds620_probe(struct i2c_client *client, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &ds620_group); -exit_free: - kfree(data); -exit: return err; } @@ -274,8 +270,6 @@ static int ds620_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ds620_group); - kfree(data); - return 0; } -- cgit v1.2.3 From 7b52eefe1637cffd449abdb5ce67e7dfbda8b2c1 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:04 -0700 Subject: hwmon: (emc1403) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/emc1403.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 149dcb0e148f..68ab94bde3f1 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c @@ -306,11 +306,10 @@ static int emc1403_probe(struct i2c_client *client, int res; struct thermal_data *data; - data = kzalloc(sizeof(struct thermal_data), GFP_KERNEL); - if (data == NULL) { - dev_warn(&client->dev, "out of memory"); + data = devm_kzalloc(&client->dev, sizeof(struct thermal_data), + GFP_KERNEL); + if (data == NULL) return -ENOMEM; - } i2c_set_clientdata(client, data); mutex_init(&data->mutex); @@ -319,21 +318,19 @@ static int emc1403_probe(struct i2c_client *client, res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); if (res) { dev_warn(&client->dev, "create group failed\n"); - goto thermal_error1; + return res; } data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { res = PTR_ERR(data->hwmon_dev); dev_warn(&client->dev, "register hwmon dev failed\n"); - goto thermal_error2; + goto thermal_error; } dev_info(&client->dev, "EMC1403 Thermal chip found\n"); - return res; + return 0; -thermal_error2: +thermal_error: sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); -thermal_error1: - kfree(data); return res; } @@ -343,7 +340,6 @@ static int emc1403_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); - kfree(data); return 0; } -- cgit v1.2.3 From 59da32d8dfd991fedc0bad197fb6f6a79bb9e712 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:04 -0700 Subject: hwmon: (emc2103) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Steve Glendinning Signed-off-by: Guenter Roeck --- drivers/hwmon/emc2103.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index 7bb8e888692c..77f434c58236 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -590,7 +590,8 @@ emc2103_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 emc2103_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct emc2103_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -608,7 +609,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id) if (status < 0) { dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_CONF1, status); - goto exit_free; + return status; } /* detect current state of hardware */ @@ -631,7 +632,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register sysfs hooks */ status = sysfs_create_group(&client->dev.kobj, &emc2103_group); if (status) - goto exit_free; + return status; if (data->temp_count >= 3) { status = sysfs_create_group(&client->dev.kobj, @@ -666,8 +667,6 @@ exit_remove_temp3: sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group); exit_remove: sysfs_remove_group(&client->dev.kobj, &emc2103_group); -exit_free: - kfree(data); return status; } @@ -685,7 +684,6 @@ static int emc2103_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &emc2103_group); - kfree(data); return 0; } -- cgit v1.2.3 From 33cd66e3c8048f03b9cc107b7a21c29cfd700ab7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:05 -0700 Subject: hwmon: (f71882fg) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/f71882fg.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index dd5ae567bf92..50e4ce2d22d8 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -2274,7 +2274,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) int err, i; u8 start_reg, reg; - data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -2288,13 +2289,11 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) start_reg = f71882fg_read8(data, F71882FG_REG_START); if (start_reg & 0x04) { dev_warn(&pdev->dev, "Hardware monitor is powered down\n"); - err = -ENODEV; - goto exit_free; + return -ENODEV; } if (!(start_reg & 0x03)) { dev_warn(&pdev->dev, "Hardware monitoring not activated\n"); - err = -ENODEV; - goto exit_free; + return -ENODEV; } /* Register sysfs interface files */ @@ -2422,8 +2421,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) exit_unregister_sysfs: f71882fg_remove(pdev); /* Will unregister the sysfs files for us */ return err; /* f71882fg_remove() also frees our data */ -exit_free: - kfree(data); return err; } @@ -2525,10 +2522,6 @@ static int f71882fg_remove(struct platform_device *pdev) ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); } } - - platform_set_drvdata(pdev, NULL); - kfree(data); - return 0; } -- cgit v1.2.3 From 05639bcb4b0d509090026e836addaa3b28a14d14 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:05 -0700 Subject: hwmon: (f75375s) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Riku Voipio Signed-off-by: Guenter Roeck --- drivers/hwmon/f75375s.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index ece4159bd453..f7dba229395f 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -838,7 +838,8 @@ static int f75375_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct f75375_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -848,7 +849,7 @@ static int f75375_probe(struct i2c_client *client, err = sysfs_create_group(&client->dev.kobj, &f75375_group); if (err) - goto exit_free; + return err; if (data->kind != f75373) { err = sysfs_chmod_file(&client->dev.kobj, @@ -875,8 +876,6 @@ static int f75375_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &f75375_group); -exit_free: - kfree(data); return err; } @@ -885,7 +884,6 @@ static int f75375_remove(struct i2c_client *client) struct f75375_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &f75375_group); - kfree(data); return 0; } -- cgit v1.2.3 From a81b0f73d10add406fca13c91c73e6a3cd505b46 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:06 -0700 Subject: hwmon: (g760a) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/g760a.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c index ebcd2698e4dc..8b2106f60eda 100644 --- a/drivers/hwmon/g760a.c +++ b/drivers/hwmon/g760a.c @@ -207,7 +207,8 @@ static int g760a_probe(struct i2c_client *client, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - data = kzalloc(sizeof(struct g760a_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct g760a_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -223,7 +224,7 @@ static int g760a_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &g760a_group); if (err) - goto error_sysfs_create_group; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -235,9 +236,6 @@ static int g760a_probe(struct i2c_client *client, error_hwmon_device_register: sysfs_remove_group(&client->dev.kobj, &g760a_group); -error_sysfs_create_group: - kfree(data); - return err; } @@ -246,8 +244,6 @@ static int g760a_remove(struct i2c_client *client) struct g760a_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &g760a_group); - kfree(data); - return 0; } -- cgit v1.2.3 From 33ed6d4a82b7422a0ab2f97f19fc841670da99d4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:08 -0700 Subject: hwmon: (lm70) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/lm70.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 472f79521a96..dd7f0cafd197 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -149,7 +149,7 @@ static int __devinit lm70_probe(struct spi_device *spi) /* NOTE: we assume 8-bit words, and convert to 16 bits manually */ - p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); + p_lm70 = devm_kzalloc(&spi->dev, sizeof(*p_lm70), GFP_KERNEL); if (!p_lm70) return -ENOMEM; @@ -181,7 +181,6 @@ out_dev_create_file_failed: device_remove_file(&spi->dev, &dev_attr_temp1_input); out_dev_create_temp_file_failed: spi_set_drvdata(spi, NULL); - kfree(p_lm70); return status; } @@ -193,7 +192,6 @@ static int __devexit lm70_remove(struct spi_device *spi) device_remove_file(&spi->dev, &dev_attr_temp1_input); device_remove_file(&spi->dev, &dev_attr_name); spi_set_drvdata(spi, NULL); - kfree(p_lm70); return 0; } -- cgit v1.2.3 From 1487bf70c1b123469893b5dc6d910ef21f59d2f7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:11 -0700 Subject: hwmon: (lm95241) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/lm95241.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index bd8cdb7b96ed..4b68fb2a31d7 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -391,11 +391,10 @@ static int lm95241_probe(struct i2c_client *new_client, struct lm95241_data *data; int err; - data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct lm95241_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); mutex_init(&data->update_lock); @@ -406,7 +405,7 @@ static int lm95241_probe(struct i2c_client *new_client, /* Register sysfs hooks */ err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -418,9 +417,6 @@ static int lm95241_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); -exit_free: - kfree(data); -exit: return err; } @@ -431,7 +427,6 @@ static int lm95241_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm95241_group); - kfree(data); return 0; } -- cgit v1.2.3 From a8dd946c420781fd7a70fec8b75e0daf67c4a681 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:12 -0700 Subject: hwmon: (lm95245) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Alexander Stein Signed-off-by: Guenter Roeck --- drivers/hwmon/lm95245.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/lm95245.c b/drivers/hwmon/lm95245.c index 9a46c106a240..2915fd908364 100644 --- a/drivers/hwmon/lm95245.c +++ b/drivers/hwmon/lm95245.c @@ -462,11 +462,10 @@ static int lm95245_probe(struct i2c_client *new_client, struct lm95245_data *data; int err; - data = kzalloc(sizeof(struct lm95245_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&new_client->dev, sizeof(struct lm95245_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(new_client, data); mutex_init(&data->update_lock); @@ -477,7 +476,7 @@ static int lm95245_probe(struct i2c_client *new_client, /* Register sysfs hooks */ err = sysfs_create_group(&new_client->dev.kobj, &lm95245_group); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -489,9 +488,6 @@ static int lm95245_probe(struct i2c_client *new_client, exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm95245_group); -exit_free: - kfree(data); -exit: return err; } @@ -502,7 +498,6 @@ static int lm95245_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm95245_group); - kfree(data); return 0; } -- cgit v1.2.3 From 7008b9704ada3d7483358da7a3c7c640e1e0be17 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:12 -0700 Subject: hwmon: (max1668) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/max1668.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c index 335b183d7c02..666d9f6263eb 100644 --- a/drivers/hwmon/max1668.c +++ b/drivers/hwmon/max1668.c @@ -411,7 +411,8 @@ static int max1668_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - data = kzalloc(sizeof(struct max1668_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct max1668_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -422,7 +423,7 @@ static int max1668_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &max1668_group_common); if (err) - goto error_free; + return err; if (data->type == max1668 || data->type == max1989) { err = sysfs_create_group(&client->dev.kobj, @@ -444,8 +445,6 @@ error_sysrem1: sysfs_remove_group(&client->dev.kobj, &max1668_group_unique); error_sysrem0: sysfs_remove_group(&client->dev.kobj, &max1668_group_common); -error_free: - kfree(data); return err; } @@ -459,7 +458,6 @@ static int max1668_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &max1668_group_common); - kfree(data); return 0; } -- cgit v1.2.3 From 78968642cc4b57c37d18b0242643026abc92717b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 10:35:52 -0700 Subject: hwmon: (ltc4151) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Per Dalen Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4151.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c index 4d005b219de2..8496baa08bc8 100644 --- a/drivers/hwmon/ltc4151.c +++ b/drivers/hwmon/ltc4151.c @@ -181,11 +181,9 @@ static int ltc4151_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto out_kzalloc; - } + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -193,7 +191,7 @@ static int ltc4151_probe(struct i2c_client *client, /* Register sysfs hooks */ ret = sysfs_create_group(&client->dev.kobj, <c4151_group); if (ret) - goto out_sysfs_create_group; + return ret; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -205,9 +203,6 @@ static int ltc4151_probe(struct i2c_client *client, out_hwmon_device_register: sysfs_remove_group(&client->dev.kobj, <c4151_group); -out_sysfs_create_group: - kfree(data); -out_kzalloc: return ret; } @@ -218,8 +213,6 @@ static int ltc4151_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, <c4151_group); - kfree(data); - return 0; } -- cgit v1.2.3 From d2b95e58ea28eedc126ce9b714e2c7620869fdf4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 10:35:52 -0700 Subject: hwmon: (ltc4215) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Ira W. Snyder Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4215.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 429c5b2b66fd..98b3d04f98b7 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c @@ -253,11 +253,9 @@ static int ltc4215_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto out_kzalloc; - } + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -268,7 +266,7 @@ static int ltc4215_probe(struct i2c_client *client, /* Register sysfs hooks */ ret = sysfs_create_group(&client->dev.kobj, <c4215_group); if (ret) - goto out_sysfs_create_group; + return ret; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -280,9 +278,6 @@ static int ltc4215_probe(struct i2c_client *client, out_hwmon_device_register: sysfs_remove_group(&client->dev.kobj, <c4215_group); -out_sysfs_create_group: - kfree(data); -out_kzalloc: return ret; } @@ -293,8 +288,6 @@ static int ltc4215_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, <c4215_group); - kfree(data); - return 0; } -- cgit v1.2.3 From effb8ab114f7ed574f3c033dac642cd2c4ae0021 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 10:35:52 -0700 Subject: hwmon: (ltc4245) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Ira W. Snyder Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4245.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index b99b45bafdad..52075914eb0b 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c @@ -519,11 +519,9 @@ static int ltc4245_probe(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto out_kzalloc; - } + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -536,7 +534,7 @@ static int ltc4245_probe(struct i2c_client *client, /* Register sysfs hooks */ ret = ltc4245_sysfs_create_groups(client); if (ret) - goto out_sysfs_create_groups; + return ret; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -548,9 +546,6 @@ static int ltc4245_probe(struct i2c_client *client, out_hwmon_device_register: ltc4245_sysfs_remove_groups(client); -out_sysfs_create_groups: - kfree(data); -out_kzalloc: return ret; } @@ -560,7 +555,6 @@ static int ltc4245_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); ltc4245_sysfs_remove_groups(client); - kfree(data); return 0; } -- cgit v1.2.3 From 79831fd4e0820bdc882d08707e4650ed4dfff3b8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:19 -0700 Subject: hwmon: (mcp3021) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Mingkai Hu Cc: Xie Xiaobo Signed-off-by: Guenter Roeck --- drivers/hwmon/mcp3021.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c index d0afc0cd3ff4..5162bb95bc61 100644 --- a/drivers/hwmon/mcp3021.c +++ b/drivers/hwmon/mcp3021.c @@ -103,7 +103,8 @@ static int mcp3021_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - data = kzalloc(sizeof(struct mcp3021_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct mcp3021_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -111,17 +112,14 @@ static int mcp3021_probe(struct i2c_client *client, if (client->dev.platform_data) { data->vdd = *(u32 *)client->dev.platform_data; - if (data->vdd > MCP3021_VDD_MAX || - data->vdd < MCP3021_VDD_MIN) { - err = -EINVAL; - goto exit_free; - } + if (data->vdd > MCP3021_VDD_MAX || data->vdd < MCP3021_VDD_MIN) + return -EINVAL; } else data->vdd = MCP3021_VDD_REF; err = sysfs_create_file(&client->dev.kobj, &dev_attr_in0_input.attr); if (err) - goto exit_free; + return err; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -133,8 +131,6 @@ static int mcp3021_probe(struct i2c_client *client, exit_remove: sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr); -exit_free: - kfree(data); return err; } @@ -144,7 +140,6 @@ static int mcp3021_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr); - kfree(data); return 0; } -- cgit v1.2.3 From bd8d8e088d4ec8738d47141c119013b5e63f591c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:21 -0700 Subject: hwmon: (sch5627) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Hans de Goede Signed-off-by: Guenter Roeck --- drivers/hwmon/sch5627.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c index 8342275378b8..49f6230bdcf1 100644 --- a/drivers/hwmon/sch5627.c +++ b/drivers/hwmon/sch5627.c @@ -461,8 +461,6 @@ static int sch5627_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &sch5627_group); - platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } @@ -472,7 +470,8 @@ static int __devinit sch5627_probe(struct platform_device *pdev) struct sch5627_data *data; int err, build_code, build_id, hwmon_rev, val; - data = kzalloc(sizeof(struct sch5627_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data), + GFP_KERNEL); if (!data) return -ENOMEM; -- cgit v1.2.3 From 9220f1e4a284667a813ca4428fbbd5a3cbc6295d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:21 -0700 Subject: hwmon: (sch5636) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/sch5636.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 96a7e68718ca..517118016192 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c @@ -402,9 +402,6 @@ static int sch5636_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &sch5636_fan_attr[i].dev_attr); - platform_set_drvdata(pdev, NULL); - kfree(data); - return 0; } @@ -414,7 +411,8 @@ static int __devinit sch5636_probe(struct platform_device *pdev) int i, err, val, revision[2]; char id[4]; - data = kzalloc(sizeof(struct sch5636_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct sch5636_data), + GFP_KERNEL); if (!data) return -ENOMEM; -- cgit v1.2.3 From 38fe7560a391cba81ec7fc5b169b764819632060 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:22 -0700 Subject: hwmon: (sht15) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jonathan Cameron Cc: Vivien Didelot Signed-off-by: Guenter Roeck Acked-by: Jonathan Cameron --- drivers/hwmon/sht15.c | 58 ++++++++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 38 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 8b011d016621..e4614644408b 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -884,14 +884,12 @@ static int sht15_invalidate_voltage(struct notifier_block *nb, static int __devinit sht15_probe(struct platform_device *pdev) { int ret; - struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); + struct sht15_data *data; u8 status = 0; - if (!data) { - ret = -ENOMEM; - dev_err(&pdev->dev, "kzalloc failed\n"); - goto error_ret; - } + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; INIT_WORK(&data->read_work, sht15_bh_read_data); INIT_WORK(&data->update_supply_work, sht15_update_voltage); @@ -901,9 +899,8 @@ static int __devinit sht15_probe(struct platform_device *pdev) init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { - ret = -EINVAL; dev_err(&pdev->dev, "no platform data supplied\n"); - goto err_free_data; + return -EINVAL; } data->pdata = pdev->dev.platform_data; data->supply_uV = data->pdata->supply_mv * 1000; @@ -918,7 +915,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) * If a regulator is available, * query what the supply voltage actually is! */ - data->reg = regulator_get(data->dev, "vcc"); + data->reg = devm_regulator_get(data->dev, "vcc"); if (!IS_ERR(data->reg)) { int voltage; @@ -937,51 +934,51 @@ static int __devinit sht15_probe(struct platform_device *pdev) dev_err(&pdev->dev, "regulator notifier request failed\n"); regulator_disable(data->reg); - regulator_put(data->reg); - goto err_free_data; + return ret; } } /* Try requesting the GPIOs */ - ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); + ret = devm_gpio_request(&pdev->dev, data->pdata->gpio_sck, "SHT15 sck"); if (ret) { dev_err(&pdev->dev, "gpio request failed\n"); goto err_release_reg; } gpio_direction_output(data->pdata->gpio_sck, 0); - ret = gpio_request(data->pdata->gpio_data, "SHT15 data"); + ret = devm_gpio_request(&pdev->dev, data->pdata->gpio_data, + "SHT15 data"); if (ret) { dev_err(&pdev->dev, "gpio request failed\n"); - goto err_release_gpio_sck; + goto err_release_reg; } - ret = request_irq(gpio_to_irq(data->pdata->gpio_data), - sht15_interrupt_fired, - IRQF_TRIGGER_FALLING, - "sht15 data", - data); + ret = devm_request_irq(&pdev->dev, gpio_to_irq(data->pdata->gpio_data), + sht15_interrupt_fired, + IRQF_TRIGGER_FALLING, + "sht15 data", + data); if (ret) { dev_err(&pdev->dev, "failed to get irq for data line\n"); - goto err_release_gpio_data; + goto err_release_reg; } disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); sht15_connection_reset(data); ret = sht15_soft_reset(data); if (ret) - goto err_release_irq; + goto err_release_reg; /* write status with platform data options */ if (status) { ret = sht15_send_status(data, status); if (ret) - goto err_release_irq; + goto err_release_reg; } ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); if (ret) { dev_err(&pdev->dev, "sysfs create failed\n"); - goto err_release_irq; + goto err_release_reg; } data->hwmon_dev = hwmon_device_register(data->dev); @@ -994,21 +991,11 @@ static int __devinit sht15_probe(struct platform_device *pdev) err_release_sysfs_group: sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); -err_release_irq: - free_irq(gpio_to_irq(data->pdata->gpio_data), data); -err_release_gpio_data: - gpio_free(data->pdata->gpio_data); -err_release_gpio_sck: - gpio_free(data->pdata->gpio_sck); err_release_reg: if (!IS_ERR(data->reg)) { regulator_unregister_notifier(data->reg, &data->nb); regulator_disable(data->reg); - regulator_put(data->reg); } -err_free_data: - kfree(data); -error_ret: return ret; } @@ -1030,14 +1017,9 @@ static int __devexit sht15_remove(struct platform_device *pdev) if (!IS_ERR(data->reg)) { regulator_unregister_notifier(data->reg, &data->nb); regulator_disable(data->reg); - regulator_put(data->reg); } - free_irq(gpio_to_irq(data->pdata->gpio_data), data); - gpio_free(data->pdata->gpio_data); - gpio_free(data->pdata->gpio_sck); mutex_unlock(&data->read_lock); - kfree(data); return 0; } -- cgit v1.2.3 From a844af19b9a8c3bcd1169f60916b0f7c40b6295f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:20:22 -0700 Subject: hwmon: (sht21) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Jonathan Cameron Cc: Urs Fleisch Signed-off-by: Guenter Roeck --- drivers/hwmon/sht21.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c index 6c2dede4b8e7..c2565d04cd4a 100644 --- a/drivers/hwmon/sht21.c +++ b/drivers/hwmon/sht21.c @@ -199,11 +199,10 @@ static int __devinit sht21_probe(struct i2c_client *client, return -ENODEV; } - sht21 = kzalloc(sizeof(*sht21), GFP_KERNEL); - if (!sht21) { - dev_dbg(&client->dev, "kzalloc failed\n"); + sht21 = devm_kzalloc(&client->dev, sizeof(*sht21), GFP_KERNEL); + if (!sht21) return -ENOMEM; - } + i2c_set_clientdata(client, sht21); mutex_init(&sht21->lock); @@ -211,7 +210,7 @@ static int __devinit sht21_probe(struct i2c_client *client, err = sysfs_create_group(&client->dev.kobj, &sht21_attr_group); if (err) { dev_dbg(&client->dev, "could not create sysfs files\n"); - goto fail_free; + return err; } sht21->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(sht21->hwmon_dev)) { @@ -226,9 +225,6 @@ static int __devinit sht21_probe(struct i2c_client *client, fail_remove_sysfs: sysfs_remove_group(&client->dev.kobj, &sht21_attr_group); -fail_free: - kfree(sht21); - return err; } @@ -242,7 +238,6 @@ static int __devexit sht21_remove(struct i2c_client *client) hwmon_device_unregister(sht21->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &sht21_attr_group); - kfree(sht21); return 0; } -- cgit v1.2.3 From 7711f1bd039233464dbde346f4a14a4bb874f77f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:35:55 -0700 Subject: hwmon: (vt8231) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Roger Lucas Signed-off-by: Guenter Roeck --- drivers/hwmon/vt8231.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 386a84538010..84e3dc5e3a83 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -789,18 +789,16 @@ static int vt8231_probe(struct platform_device *pdev) /* Reserve the ISA region */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, VT8231_EXTENT, - vt8231_driver.driver.name)) { + if (!devm_request_region(&pdev->dev, res->start, VT8231_EXTENT, + vt8231_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 vt8231_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit_release; - } + data = devm_kzalloc(&pdev->dev, sizeof(struct vt8231_data), GFP_KERNEL); + if (!data) + return -ENOMEM; platform_set_drvdata(pdev, data); data->addr = res->start; @@ -812,7 +810,7 @@ static int vt8231_probe(struct platform_device *pdev) /* Register sysfs hooks */ err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group); if (err) - goto exit_free; + return err; /* Must update device information to find out the config field */ data->uch_config = vt8231_read_value(data, VT8231_REG_UCH_CONFIG); @@ -850,13 +848,6 @@ exit_remove_files: sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]); sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); - -exit_free: - platform_set_drvdata(pdev, NULL); - kfree(data); - -exit_release: - release_region(res->start, VT8231_EXTENT); return err; } @@ -875,9 +866,6 @@ static int __devexit vt8231_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); - release_region(data->addr, VT8231_EXTENT); - platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } -- cgit v1.2.3 From 816864d9968814c23c12e6601ad7dd1dabb8f994 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 11:48:02 -0700 Subject: hwmon: (w83l786ng) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/w83l786ng.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 5850b7706088..c99c8a0473cf 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -668,11 +668,10 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) int i, err = 0; u8 reg_tmp; - data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct w83l786ng_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -708,8 +707,6 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) exit_remove: sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); - kfree(data); -exit: return err; } @@ -721,8 +718,6 @@ w83l786ng_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); - kfree(data); - return 0; } -- cgit v1.2.3 From b25df2bfbe2e7faddbb4f517e39de0323eef3ec7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 12:22:08 -0700 Subject: hwmon: (jz4740-hwmon) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Lars-Peter Clausen Signed-off-by: Guenter Roeck --- drivers/hwmon/jz4740-hwmon.c | 53 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 37 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index 5253d23361d9..dee9eec2036e 100644 --- a/drivers/hwmon/jz4740-hwmon.c +++ b/drivers/hwmon/jz4740-hwmon.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -106,42 +107,37 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev) int ret; struct jz4740_hwmon *hwmon; - hwmon = kmalloc(sizeof(*hwmon), GFP_KERNEL); - if (!hwmon) { - dev_err(&pdev->dev, "Failed to allocate driver structure\n"); + hwmon = devm_kzalloc(&pdev->dev, sizeof(*hwmon), GFP_KERNEL); + if (!hwmon) return -ENOMEM; - } hwmon->cell = mfd_get_cell(pdev); hwmon->irq = platform_get_irq(pdev, 0); if (hwmon->irq < 0) { - ret = hwmon->irq; - dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); - goto err_free; + dev_err(&pdev->dev, "Failed to get platform irq: %d\n", + hwmon->irq); + return hwmon->irq; } hwmon->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!hwmon->mem) { - ret = -ENOENT; dev_err(&pdev->dev, "Failed to get platform mmio resource\n"); - goto err_free; + return -ENOENT; } - hwmon->mem = request_mem_region(hwmon->mem->start, + hwmon->mem = devm_request_mem_region(&pdev->dev, hwmon->mem->start, resource_size(hwmon->mem), pdev->name); if (!hwmon->mem) { - ret = -EBUSY; dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - goto err_free; + return -EBUSY; } - hwmon->base = ioremap_nocache(hwmon->mem->start, - resource_size(hwmon->mem)); + hwmon->base = devm_ioremap_nocache(&pdev->dev, hwmon->mem->start, + resource_size(hwmon->mem)); if (!hwmon->base) { - ret = -EBUSY; dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - goto err_release_mem_region; + return -EBUSY; } init_completion(&hwmon->read_completion); @@ -149,17 +145,18 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hwmon); - ret = request_irq(hwmon->irq, jz4740_hwmon_irq, 0, pdev->name, hwmon); + ret = devm_request_irq(&pdev->dev, hwmon->irq, jz4740_hwmon_irq, 0, + pdev->name, hwmon); if (ret) { dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); - goto err_iounmap; + return ret; } disable_irq(hwmon->irq); ret = sysfs_create_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group); if (ret) { dev_err(&pdev->dev, "Failed to create sysfs group: %d\n", ret); - goto err_free_irq; + return ret; } hwmon->hwmon = hwmon_device_register(&pdev->dev); @@ -172,16 +169,6 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev) err_remove_file: sysfs_remove_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group); -err_free_irq: - free_irq(hwmon->irq, hwmon); -err_iounmap: - platform_set_drvdata(pdev, NULL); - iounmap(hwmon->base); -err_release_mem_region: - release_mem_region(hwmon->mem->start, resource_size(hwmon->mem)); -err_free: - kfree(hwmon); - return ret; } @@ -192,14 +179,6 @@ static int __devexit jz4740_hwmon_remove(struct platform_device *pdev) hwmon_device_unregister(hwmon->hwmon); sysfs_remove_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group); - free_irq(hwmon->irq, hwmon); - - iounmap(hwmon->base); - release_mem_region(hwmon->mem->start, resource_size(hwmon->mem)); - - platform_set_drvdata(pdev, NULL); - kfree(hwmon); - return 0; } -- cgit v1.2.3 From 505dc0cc7e99279d60f5c3508018682beee22d65 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 13:12:58 -0700 Subject: hwmon: (via-cputemp) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Signed-off-by: Guenter Roeck --- drivers/hwmon/via-cputemp.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 2e56c6ce9fb6..4cddee04f2e6 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -128,12 +128,10 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev) int err; u32 eax, edx; - data = kzalloc(sizeof(struct via_cputemp_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - dev_err(&pdev->dev, "Out of memory\n"); - goto exit; - } + data = devm_kzalloc(&pdev->dev, sizeof(struct via_cputemp_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; data->id = pdev->id; data->name = "via_cputemp"; @@ -151,8 +149,7 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev) data->msr_temp = 0x1423; break; default: - err = -ENODEV; - goto exit_free; + return -ENODEV; } /* test if we can access the TEMPERATURE MSR */ @@ -160,14 +157,14 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving up\n"); - goto exit_free; + return err; } platform_set_drvdata(pdev, data); err = sysfs_create_group(&pdev->dev.kobj, &via_cputemp_group); if (err) - goto exit_free; + return err; if (data->msr_vid) data->vrm = vid_which_vrm(); @@ -192,10 +189,6 @@ exit_remove: if (data->vrm) device_remove_file(&pdev->dev, &dev_attr_cpu0_vid); sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); -exit_free: - platform_set_drvdata(pdev, NULL); - kfree(data); -exit: return err; } @@ -207,8 +200,6 @@ static int __devexit via_cputemp_remove(struct platform_device *pdev) if (data->vrm) device_remove_file(&pdev->dev, &dev_attr_cpu0_vid); sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); - platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } -- cgit v1.2.3 From 87432a2e22d1ff63bb44ced0fb77e6f13e856354 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 2 Jun 2012 09:58:06 -0700 Subject: hwmon: (fam15h_power) Convert to use devm_ functions Convert to use devm_ functions to reduce code size and simplify the code. Cc: Andreas Herrmann Signed-off-by: Guenter Roeck --- drivers/hwmon/fam15h_power.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index af69073b3fe8..68ad7d255512 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -198,7 +198,7 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct fam15h_power_data *data; - struct device *dev; + struct device *dev = &pdev->dev; int err; /* @@ -208,23 +208,19 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, */ tweak_runavg_range(pdev); - if (!fam15h_power_is_internal_node0(pdev)) { - err = -ENODEV; - goto exit; - } + if (!fam15h_power_is_internal_node0(pdev)) + return -ENODEV; + + data = devm_kzalloc(dev, sizeof(struct fam15h_power_data), GFP_KERNEL); + if (!data) + return -ENOMEM; - data = kzalloc(sizeof(struct fam15h_power_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } fam15h_power_init_data(pdev, data); - dev = &pdev->dev; dev_set_drvdata(dev, data); err = sysfs_create_group(&dev->kobj, &fam15h_power_attr_group); if (err) - goto exit_free_data; + return err; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { @@ -236,9 +232,6 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, exit_remove_group: sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group); -exit_free_data: - kfree(data); -exit: return err; } @@ -251,8 +244,6 @@ static void __devexit fam15h_power_remove(struct pci_dev *pdev) data = dev_get_drvdata(dev); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group); - dev_set_drvdata(dev, NULL); - kfree(data); } static DEFINE_PCI_DEVICE_TABLE(fam15h_power_id_table) = { -- cgit v1.2.3 From 983b97bed21e392280e80f704e97170b76cb7f3e Mon Sep 17 00:00:00 2001 From: Hartmut Knaack Date: Sun, 12 Aug 2012 18:15:49 +0200 Subject: hwmon: Driver for ADT7410 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch brings basic support for the Analog Devices ADT7410 temperature sensor. The following functionality has been implemented: * get current temperature * get/set minimum, maximum and critical temperature * get/set hysteresis * get alarm events for minimum, maximum and critical temperature All implemented sysfs attributes have been sucessfully tested at temperatures of 15°C to 40°C. Signed-off-by: Hartmut Knaack Signed-off-by: Guenter Roeck --- Documentation/hwmon/adt7410 | 51 +++++ drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/adt7410.c | 459 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 521 insertions(+) create mode 100644 Documentation/hwmon/adt7410 create mode 100644 drivers/hwmon/adt7410.c (limited to 'drivers/hwmon') diff --git a/Documentation/hwmon/adt7410 b/Documentation/hwmon/adt7410 new file mode 100644 index 000000000000..96004000dc2a --- /dev/null +++ b/Documentation/hwmon/adt7410 @@ -0,0 +1,51 @@ +Kernel driver adt7410 +===================== + +Supported chips: + * Analog Devices ADT7410 + Prefix: 'adt7410' + Addresses scanned: I2C 0x48 - 0x4B + Datasheet: Publicly available at the Analog Devices website + http://www.analog.com/static/imported-files/data_sheets/ADT7410.pdf + +Author: Hartmut Knaack + +Description +----------- + +The ADT7410 is a temperature sensor with rated temperature range of -55°C to ++150°C. It has a high accuracy of +/-0.5°C and can be operated at a resolution +of 13 bits (0.0625°C) or 16 bits (0.0078°C). The sensor provides an INT pin to +indicate that a minimum or maximum temperature set point has been exceeded, as +well as a critical temperature (CT) pin to indicate that the critical +temperature set point has been exceeded. Both pins can be set up with a common +hysteresis of 0°C - 15°C and a fault queue, ranging from 1 to 4 events. Both +pins can individually set to be active-low or active-high, while the whole +device can either run in comparator mode or interrupt mode. The ADT7410 +supports continous temperature sampling, as well as sampling one temperature +value per second or even justget one sample on demand for power saving. +Besides, it can completely power down its ADC, if power management is +required. + +Configuration Notes +------------------- + +Since the device uses one hysteresis value, which is an offset to minimum, +maximum and critical temperature, it can only be set for temp#_max_hyst. +However, temp#_min_hyst and temp#_crit_hyst show their corresponding +hysteresis. +The device is set to 16 bit resolution and comparator mode. + +sysfs-Interface +--------------- + +temp#_input - temperature input +temp#_min - temperature minimum setpoint +temp#_max - temperature maximum setpoint +temp#_crit - critical temperature setpoint +temp#_min_hyst - hysteresis for temperature minimum (read-only) +temp#_max_hyst - hysteresis for temperature maximum (read/write) +temp#_crit_hyst - hysteresis for critical temperature (read-only) +temp#_min_alarm - temperature minimum alarm flag +temp#_max_alarm - temperature maximum alarm flag +temp#_crit_alarm - critical temperature alarm flag diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index b0a2e4c37e12..f50cb440575d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -179,6 +179,16 @@ config SENSORS_ADM9240 This driver can also be built as a module. If so, the module will be called adm9240. +config SENSORS_ADT7410 + tristate "Analog Devices ADT7410" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Analog Devices + ADT7410 temperature monitoring chip. + + This driver can also be built as a module. If so, the module + will be called adt7410. + config SENSORS_ADT7411 tristate "Analog Devices ADT7411" depends on I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 7aa98119c4ab..8b3d4382f61e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o +obj-$(CONFIG_SENSORS_ADT7410) += adt7410.o obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c new file mode 100644 index 000000000000..f8606dff3d1c --- /dev/null +++ b/drivers/hwmon/adt7410.c @@ -0,0 +1,459 @@ +/* + * adt7410.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * This driver handles the ADT7410 and compatible digital temperature sensors. + * Hartmut Knaack 2012-07-22 + * based on lm75.c by Frodo Looijaard + * and adt7410.c from iio-staging by Sonic Zhang + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * ADT7410 registers definition + */ + +#define ADT7410_TEMPERATURE 0 +#define ADT7410_STATUS 2 +#define ADT7410_CONFIG 3 +#define ADT7410_T_ALARM_HIGH 4 +#define ADT7410_T_ALARM_LOW 6 +#define ADT7410_T_CRIT 8 +#define ADT7410_T_HYST 0xA + +/* + * ADT7410 status + */ +#define ADT7410_STAT_T_LOW (1 << 4) +#define ADT7410_STAT_T_HIGH (1 << 5) +#define ADT7410_STAT_T_CRIT (1 << 6) +#define ADT7410_STAT_NOT_RDY (1 << 7) + +/* + * ADT7410 config + */ +#define ADT7410_FAULT_QUEUE_MASK (1 << 0 | 1 << 1) +#define ADT7410_CT_POLARITY (1 << 2) +#define ADT7410_INT_POLARITY (1 << 3) +#define ADT7410_EVENT_MODE (1 << 4) +#define ADT7410_MODE_MASK (1 << 5 | 1 << 6) +#define ADT7410_FULL (0 << 5 | 0 << 6) +#define ADT7410_PD (1 << 5 | 1 << 6) +#define ADT7410_RESOLUTION (1 << 7) + +/* + * ADT7410 masks + */ +#define ADT7410_T13_VALUE_MASK 0xFFF8 +#define ADT7410_T_HYST_MASK 0xF + +/* straight from the datasheet */ +#define ADT7410_TEMP_MIN (-55000) +#define ADT7410_TEMP_MAX 150000 + +enum adt7410_type { /* keep sorted in alphabetical order */ + adt7410, +}; + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + I2C_CLIENT_END }; + +static const u8 ADT7410_REG_TEMP[4] = { + ADT7410_TEMPERATURE, /* input */ + ADT7410_T_ALARM_HIGH, /* high */ + ADT7410_T_ALARM_LOW, /* low */ + ADT7410_T_CRIT, /* critical */ +}; + +/* Each client has this additional data */ +struct adt7410_data { + struct device *hwmon_dev; + struct mutex update_lock; + u8 config; + u8 oldconfig; + bool valid; /* true if registers valid */ + unsigned long last_updated; /* In jiffies */ + s16 temp[4]; /* Register values, + 0 = input + 1 = high + 2 = low + 3 = critical */ + u8 hyst; /* hysteresis offset */ +}; + +/* + * adt7410 register access by I2C + */ +static int adt7410_temp_ready(struct i2c_client *client) +{ + int i, status; + + for (i = 0; i < 6; i++) { + status = i2c_smbus_read_byte_data(client, ADT7410_STATUS); + if (status < 0) + return status; + if (!(status & ADT7410_STAT_NOT_RDY)) + return 0; + msleep(60); + } + return -ETIMEDOUT; +} + +static struct adt7410_data *adt7410_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + struct adt7410_data *ret = data; + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status; + + dev_dbg(&client->dev, "Starting update\n"); + + status = adt7410_temp_ready(client); /* check for new value */ + if (unlikely(status)) { + ret = ERR_PTR(status); + goto abort; + } + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + status = i2c_smbus_read_word_swapped(client, + ADT7410_REG_TEMP[i]); + if (unlikely(status < 0)) { + dev_dbg(dev, + "Failed to read value: reg %d, error %d\n", + ADT7410_REG_TEMP[i], status); + ret = ERR_PTR(status); + goto abort; + } + data->temp[i] = status; + } + status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); + if (unlikely(status < 0)) { + dev_dbg(dev, + "Failed to read value: reg %d, error %d\n", + ADT7410_T_HYST, status); + ret = ERR_PTR(status); + goto abort; + } + data->hyst = status; + data->last_updated = jiffies; + data->valid = true; + } + +abort: + mutex_unlock(&data->update_lock); + return ret; +} + +static s16 ADT7410_TEMP_TO_REG(long temp) +{ + return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, ADT7410_TEMP_MIN, + ADT7410_TEMP_MAX) * 128, 1000); +} + +static int ADT7410_REG_TO_TEMP(struct adt7410_data *data, s16 reg) +{ + /* in 13 bit mode, bits 0-2 are status flags - mask them out */ + if (!(data->config & ADT7410_RESOLUTION)) + reg &= ADT7410_T13_VALUE_MASK; + /* + * temperature is stored in twos complement format, in steps of + * 1/128°C + */ + return DIV_ROUND_CLOSEST(reg * 1000, 128); +} + +/*-----------------------------------------------------------------------*/ + +/* sysfs attributes for hwmon */ + +static ssize_t adt7410_show_temp(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct adt7410_data *data = adt7410_update_device(dev); + + if (IS_ERR(data)) + return PTR_ERR(data); + + return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, + data->temp[attr->index])); +} + +static ssize_t adt7410_set_temp(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + int nr = attr->index; + long temp; + int ret; + + ret = kstrtol(buf, 10, &temp); + if (ret) + return ret; + + mutex_lock(&data->update_lock); + data->temp[nr] = ADT7410_TEMP_TO_REG(temp); + ret = i2c_smbus_write_word_swapped(client, ADT7410_REG_TEMP[nr], + data->temp[nr]); + if (ret) + count = ret; + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t adt7410_show_t_hyst(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct adt7410_data *data = adt7410_update_device(dev); + int nr = attr->index; + int hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; + + /* + * hysteresis is stored as a 4 bit offset in the device, convert it + * to an absolute value + */ + if (nr == 2) /* min has positive offset, others have negative */ + hyst = -hyst; + return sprintf(buf, "%d\n", + ADT7410_REG_TO_TEMP(data, data->temp[nr]) - hyst); +} + +static ssize_t adt7410_set_t_hyst(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + int limit, ret; + long hyst; + + ret = kstrtol(buf, 10, &hyst); + if (ret) + return ret; + /* convert absolute hysteresis value to a 4 bit delta value */ + limit = ADT7410_REG_TO_TEMP(data, data->temp[1]); + hyst = SENSORS_LIMIT(hyst, ADT7410_TEMP_MIN, ADT7410_TEMP_MAX); + data->hyst = SENSORS_LIMIT(DIV_ROUND_CLOSEST(limit - hyst, 1000), + 0, ADT7410_T_HYST_MASK); + ret = i2c_smbus_write_byte_data(client, ADT7410_T_HYST, data->hyst); + if (ret) + return ret; + + return count; +} + +static ssize_t adt7410_show_alarm(struct device *dev, + struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int ret; + + ret = i2c_smbus_read_byte_data(client, ADT7410_STATUS); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", !!(ret & attr->index)); +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7410_show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, + adt7410_show_temp, adt7410_set_temp, 1); +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, + adt7410_show_temp, adt7410_set_temp, 2); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, + adt7410_show_temp, adt7410_set_temp, 3); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, + adt7410_show_t_hyst, adt7410_set_t_hyst, 1); +static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, + adt7410_show_t_hyst, NULL, 2); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, + adt7410_show_t_hyst, NULL, 3); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, adt7410_show_alarm, + NULL, ADT7410_STAT_T_LOW); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, adt7410_show_alarm, + NULL, ADT7410_STAT_T_HIGH); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, adt7410_show_alarm, + NULL, ADT7410_STAT_T_CRIT); + +static struct attribute *adt7410_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group adt7410_group = { + .attrs = adt7410_attributes, +}; + +/*-----------------------------------------------------------------------*/ + +/* device probe and removal */ + +static int adt7410_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt7410_data *data; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + data = devm_kzalloc(&client->dev, sizeof(struct adt7410_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + /* configure as specified */ + ret = i2c_smbus_read_byte_data(client, ADT7410_CONFIG); + if (ret < 0) { + dev_dbg(&client->dev, "Can't read config? %d\n", ret); + return ret; + } + data->oldconfig = ret; + /* + * Set to 16 bit resolution, continous conversion and comparator mode. + */ + data->config = ret | ADT7410_FULL | ADT7410_RESOLUTION | + ADT7410_EVENT_MODE; + if (data->config != data->oldconfig) { + ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, + data->config); + if (ret) + return ret; + } + dev_dbg(&client->dev, "Config %02x\n", data->config); + + /* Register sysfs hooks */ + ret = sysfs_create_group(&client->dev.kobj, &adt7410_group); + if (ret) + goto exit_restore; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "sensor '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &adt7410_group); +exit_restore: + i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->oldconfig); + return ret; +} + +static int adt7410_remove(struct i2c_client *client) +{ + struct adt7410_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &adt7410_group); + if (data->oldconfig != data->config) + i2c_smbus_write_byte_data(client, ADT7410_CONFIG, + data->oldconfig); + return 0; +} + +static const struct i2c_device_id adt7410_ids[] = { + { "adt7410", adt7410, }, + { /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, adt7410_ids); + +#ifdef CONFIG_PM +static int adt7410_suspend(struct device *dev) +{ + int ret; + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + + ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, + data->config | ADT7410_PD); + return ret; +} + +static int adt7410_resume(struct device *dev) +{ + int ret; + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); + + ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->config); + return ret; +} + +static const struct dev_pm_ops adt7410_dev_pm_ops = { + .suspend = adt7410_suspend, + .resume = adt7410_resume, +}; +#define ADT7410_DEV_PM_OPS (&adt7410_dev_pm_ops) +#else +#define ADT7410_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct i2c_driver adt7410_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "adt7410", + .pm = ADT7410_DEV_PM_OPS, + }, + .probe = adt7410_probe, + .remove = adt7410_remove, + .id_table = adt7410_ids, + .address_list = normal_i2c, +}; + +module_i2c_driver(adt7410_driver); + +MODULE_AUTHOR("Hartmut Knaack"); +MODULE_DESCRIPTION("ADT7410 driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 37f9648b2745fc3830f3715a601f7f94296de838 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Aug 2012 10:49:43 +0300 Subject: hwmon: (adt7410) handle errors from adt7410_update_device() Smatch complains that adt7410_update_device() can return error pointers. Signed-off-by: Dan Carpenter Signed-off-by: Guenter Roeck --- drivers/hwmon/adt7410.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c index f8606dff3d1c..030c8d7c33a5 100644 --- a/drivers/hwmon/adt7410.c +++ b/drivers/hwmon/adt7410.c @@ -236,9 +236,14 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7410_data *data = adt7410_update_device(dev); + struct adt7410_data *data; int nr = attr->index; - int hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; + int hyst; + + data = adt7410_update_device(dev); + if (IS_ERR(data)) + return PTR_ERR(data); + hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; /* * hysteresis is stored as a 4 bit offset in the device, convert it -- cgit v1.2.3 From 6c1fe725fd76f4328e22c146d3a36513963a01ea Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 30 Aug 2012 21:42:57 -0400 Subject: hwmon: add Maxim MAX197 support The MAX197 is an A/D converter, made by Maxim. This driver currently supports the MAX197, and MAX199. They are both 8-Channel, Multi-Range, 5V, 12-Bit DAS with 8+4 Bus Interface and Fault Protection. The available ranges for the MAX197 are {0,-5V} to 5V, and {0,-10V} to 10V, while they are {0,-2V} to 2V, and {0,-4V} to 4V on the MAX199. Signed-off-by: Vivien Didelot Signed-off-by: Guenter Roeck --- Documentation/hwmon/max197 | 60 ++++++ drivers/hwmon/Kconfig | 9 + drivers/hwmon/Makefile | 1 + drivers/hwmon/max197.c | 349 +++++++++++++++++++++++++++++++++++ include/linux/platform_data/max197.h | 21 +++ 5 files changed, 440 insertions(+) create mode 100644 Documentation/hwmon/max197 create mode 100644 drivers/hwmon/max197.c create mode 100644 include/linux/platform_data/max197.h (limited to 'drivers/hwmon') diff --git a/Documentation/hwmon/max197 b/Documentation/hwmon/max197 new file mode 100644 index 000000000000..8d89b9009df8 --- /dev/null +++ b/Documentation/hwmon/max197 @@ -0,0 +1,60 @@ +Maxim MAX197 driver +=================== + +Author: + * Vivien Didelot + +Supported chips: + * Maxim MAX197 + Prefix: 'max197' + Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX197.pdf + + * Maxim MAX199 + Prefix: 'max199' + Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX199.pdf + +Description +----------- + +The A/D converters MAX197, and MAX199 are both 8-Channel, Multi-Range, 5V, +12-Bit DAS with 8+4 Bus Interface and Fault Protection. + +The available ranges for the MAX197 are {0,-5V} to 5V, and {0,-10V} to 10V, +while they are {0,-2V} to 2V, and {0,-4V} to 4V on the MAX199. + +Platform data +------------- + +The MAX197 platform data (defined in linux/platform_data/max197.h) should be +filled with a pointer to a conversion function, defined like: + + int convert(u8 ctrl); + +ctrl is the control byte to write to start a new conversion. +On success, the function must return the 12-bit raw value read from the chip, +or a negative error code otherwise. + +Control byte format: + +Bit Name Description +7,6 PD1,PD0 Clock and Power-Down modes +5 ACQMOD Internal or External Controlled Acquisition +4 RNG Full-scale voltage magnitude at the input +3 BIP Unipolar or Bipolar conversion mode +2,1,0 A2,A1,A0 Channel + +Sysfs interface +--------------- + +* in[0-7]_input: The conversion value for the corresponding channel. + RO + +* in[0-7]_min: The lower limit (in mV) for the corresponding channel. + For the MAX197, it will be adjusted to -10000, -5000, or 0. + For the MAX199, it will be adjusted to -4000, -2000, or 0. + RW + +* in[0-7]_max: The higher limit (in mV) for the corresponding channel. + For the MAX197, it will be adjusted to 0, 5000, or 10000. + For the MAX199, it will be adjusted to 0, 2000, or 4000. + RW diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f50cb440575d..6566ed6db3b0 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -813,6 +813,15 @@ config SENSORS_MAX1668 This driver can also be built as a module. If so, the module will be called max1668. +config SENSORS_MAX197 + tristate "Maxim MAX197 and compatibles" + help + Support for the Maxim MAX197 A/D converter. + Support will include, but not be limited to, MAX197, and MAX199. + + This driver can also be built as a module. If so, the module + will be called max197. + config SENSORS_MAX6639 tristate "Maxim MAX6639 sensor chip" depends on I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8b3d4382f61e..a62ce17ddbfc 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -95,6 +95,7 @@ obj-$(CONFIG_SENSORS_MAX1111) += max1111.o obj-$(CONFIG_SENSORS_MAX16065) += max16065.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o obj-$(CONFIG_SENSORS_MAX1668) += max1668.o +obj-$(CONFIG_SENSORS_MAX197) += max197.o obj-$(CONFIG_SENSORS_MAX6639) += max6639.o obj-$(CONFIG_SENSORS_MAX6642) += max6642.o obj-$(CONFIG_SENSORS_MAX6650) += max6650.o diff --git a/drivers/hwmon/max197.c b/drivers/hwmon/max197.c new file mode 100644 index 000000000000..6304f2616fa7 --- /dev/null +++ b/drivers/hwmon/max197.c @@ -0,0 +1,349 @@ +/* + * Maxim MAX197 A/D Converter driver + * + * Copyright (c) 2012 Savoir-faire Linux Inc. + * Vivien Didelot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * For further information, see the Documentation/hwmon/max197 file. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX199_LIMIT 4000 /* 4V */ +#define MAX197_LIMIT 10000 /* 10V */ + +#define MAX197_NUM_CH 8 /* 8 Analog Input Channels */ + +/* Control byte format */ +#define MAX197_BIP (1 << 3) /* Bipolarity */ +#define MAX197_RNG (1 << 4) /* Full range */ + +#define MAX197_SCALE 12207 /* Scale coefficient for raw data */ + +/* List of supported chips */ +enum max197_chips { max197, max199 }; + +/** + * struct max197_data - device instance specific data + * @pdata: Platform data. + * @hwmon_dev: The hwmon device. + * @lock: Read/Write mutex. + * @limit: Max range value (10V for MAX197, 4V for MAX199). + * @scale: Need to scale. + * @ctrl_bytes: Channels control byte. + */ +struct max197_data { + struct max197_platform_data *pdata; + struct device *hwmon_dev; + struct mutex lock; + int limit; + bool scale; + u8 ctrl_bytes[MAX197_NUM_CH]; +}; + +static inline void max197_set_unipolarity(struct max197_data *data, int channel) +{ + data->ctrl_bytes[channel] &= ~MAX197_BIP; +} + +static inline void max197_set_bipolarity(struct max197_data *data, int channel) +{ + data->ctrl_bytes[channel] |= MAX197_BIP; +} + +static inline void max197_set_half_range(struct max197_data *data, int channel) +{ + data->ctrl_bytes[channel] &= ~MAX197_RNG; +} + +static inline void max197_set_full_range(struct max197_data *data, int channel) +{ + data->ctrl_bytes[channel] |= MAX197_RNG; +} + +static inline bool max197_is_bipolar(struct max197_data *data, int channel) +{ + return data->ctrl_bytes[channel] & MAX197_BIP; +} + +static inline bool max197_is_full_range(struct max197_data *data, int channel) +{ + return data->ctrl_bytes[channel] & MAX197_RNG; +} + +/* Function called on read access on in{0,1,2,3,4,5,6,7}_{min,max} */ +static ssize_t max197_show_range(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct max197_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); + int channel = attr->index; + bool is_min = attr->nr; + int range; + + if (mutex_lock_interruptible(&data->lock)) + return -ERESTARTSYS; + + range = max197_is_full_range(data, channel) ? + data->limit : data->limit / 2; + if (is_min) { + if (max197_is_bipolar(data, channel)) + range = -range; + else + range = 0; + } + + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", range); +} + +/* Function called on write access on in{0,1,2,3,4,5,6,7}_{min,max} */ +static ssize_t max197_store_range(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct max197_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); + int channel = attr->index; + bool is_min = attr->nr; + long value; + int half = data->limit / 2; + int full = data->limit; + + if (kstrtol(buf, 10, &value)) + return -EINVAL; + + if (is_min) { + if (value <= -full) + value = -full; + else if (value < 0) + value = -half; + else + value = 0; + } else { + if (value >= full) + value = full; + else + value = half; + } + + if (mutex_lock_interruptible(&data->lock)) + return -ERESTARTSYS; + + if (value == 0) { + /* We can deduce only the polarity */ + max197_set_unipolarity(data, channel); + } else if (value == -half) { + max197_set_bipolarity(data, channel); + max197_set_half_range(data, channel); + } else if (value == -full) { + max197_set_bipolarity(data, channel); + max197_set_full_range(data, channel); + } else if (value == half) { + /* We can deduce only the range */ + max197_set_half_range(data, channel); + } else if (value == full) { + /* We can deduce only the range */ + max197_set_full_range(data, channel); + } + + mutex_unlock(&data->lock); + + return count; +} + +/* Function called on read access on in{0,1,2,3,4,5,6,7}_input */ +static ssize_t max197_show_input(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct max197_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int channel = attr->index; + s32 value; + int ret; + + if (mutex_lock_interruptible(&data->lock)) + return -ERESTARTSYS; + + ret = data->pdata->convert(data->ctrl_bytes[channel]); + if (ret < 0) { + dev_err(dev, "conversion failed\n"); + goto unlock; + } + value = ret; + + /* + * Coefficient to apply on raw value. + * See Table 1. Full Scale and Zero Scale in the MAX197 datasheet. + */ + if (data->scale) { + value *= MAX197_SCALE; + if (max197_is_full_range(data, channel)) + value *= 2; + value /= 10000; + } + + ret = sprintf(buf, "%d\n", value); + +unlock: + mutex_unlock(&data->lock); + return ret; +} + +static ssize_t max197_show_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + return sprintf(buf, "%s\n", pdev->name); +} + +#define MAX197_SENSOR_DEVICE_ATTR_CH(chan) \ + static SENSOR_DEVICE_ATTR(in##chan##_input, S_IRUGO, \ + max197_show_input, NULL, chan); \ + static SENSOR_DEVICE_ATTR_2(in##chan##_min, S_IRUGO | S_IWUSR, \ + max197_show_range, \ + max197_store_range, \ + true, chan); \ + static SENSOR_DEVICE_ATTR_2(in##chan##_max, S_IRUGO | S_IWUSR, \ + max197_show_range, \ + max197_store_range, \ + false, chan) + +#define MAX197_SENSOR_DEV_ATTR_IN(chan) \ + &sensor_dev_attr_in##chan##_input.dev_attr.attr, \ + &sensor_dev_attr_in##chan##_max.dev_attr.attr, \ + &sensor_dev_attr_in##chan##_min.dev_attr.attr + +static DEVICE_ATTR(name, S_IRUGO, max197_show_name, NULL); + +MAX197_SENSOR_DEVICE_ATTR_CH(0); +MAX197_SENSOR_DEVICE_ATTR_CH(1); +MAX197_SENSOR_DEVICE_ATTR_CH(2); +MAX197_SENSOR_DEVICE_ATTR_CH(3); +MAX197_SENSOR_DEVICE_ATTR_CH(4); +MAX197_SENSOR_DEVICE_ATTR_CH(5); +MAX197_SENSOR_DEVICE_ATTR_CH(6); +MAX197_SENSOR_DEVICE_ATTR_CH(7); + +static const struct attribute_group max197_sysfs_group = { + .attrs = (struct attribute *[]) { + &dev_attr_name.attr, + MAX197_SENSOR_DEV_ATTR_IN(0), + MAX197_SENSOR_DEV_ATTR_IN(1), + MAX197_SENSOR_DEV_ATTR_IN(2), + MAX197_SENSOR_DEV_ATTR_IN(3), + MAX197_SENSOR_DEV_ATTR_IN(4), + MAX197_SENSOR_DEV_ATTR_IN(5), + MAX197_SENSOR_DEV_ATTR_IN(6), + MAX197_SENSOR_DEV_ATTR_IN(7), + NULL + }, +}; + +static int __devinit max197_probe(struct platform_device *pdev) +{ + int ch, ret; + struct max197_data *data; + struct max197_platform_data *pdata = pdev->dev.platform_data; + enum max197_chips chip = platform_get_device_id(pdev)->driver_data; + + if (pdata == NULL) { + dev_err(&pdev->dev, "no platform data supplied\n"); + return -EINVAL; + } + + if (pdata->convert == NULL) { + dev_err(&pdev->dev, "no convert function supplied\n"); + return -EINVAL; + } + + data = devm_kzalloc(&pdev->dev, sizeof(struct max197_data), GFP_KERNEL); + if (!data) { + dev_err(&pdev->dev, "devm_kzalloc failed\n"); + return -ENOMEM; + } + + data->pdata = pdata; + mutex_init(&data->lock); + + if (chip == max197) { + data->limit = MAX197_LIMIT; + data->scale = true; + } else { + data->limit = MAX199_LIMIT; + data->scale = false; + } + + for (ch = 0; ch < MAX197_NUM_CH; ch++) + data->ctrl_bytes[ch] = (u8) ch; + + platform_set_drvdata(pdev, data); + + ret = sysfs_create_group(&pdev->dev.kobj, &max197_sysfs_group); + if (ret) { + dev_err(&pdev->dev, "sysfs create group failed\n"); + return ret; + } + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + dev_err(&pdev->dev, "hwmon device register failed\n"); + goto error; + } + + return 0; + +error: + sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group); + return ret; +} + +static int __devexit max197_remove(struct platform_device *pdev) +{ + struct max197_data *data = platform_get_drvdata(pdev); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group); + + return 0; +} + +static struct platform_device_id max197_device_ids[] = { + { "max197", max197 }, + { "max199", max199 }, + { } +}; +MODULE_DEVICE_TABLE(platform, max197_device_ids); + +static struct platform_driver max197_driver = { + .driver = { + .name = "max197", + .owner = THIS_MODULE, + }, + .probe = max197_probe, + .remove = __devexit_p(max197_remove), + .id_table = max197_device_ids, +}; +module_platform_driver(max197_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Savoir-faire Linux Inc. "); +MODULE_DESCRIPTION("Maxim MAX197 A/D Converter driver"); diff --git a/include/linux/platform_data/max197.h b/include/linux/platform_data/max197.h new file mode 100644 index 000000000000..e2a41dd7690c --- /dev/null +++ b/include/linux/platform_data/max197.h @@ -0,0 +1,21 @@ +/* + * Maxim MAX197 A/D Converter Driver + * + * Copyright (c) 2012 Savoir-faire Linux Inc. + * Vivien Didelot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * For further information, see the Documentation/hwmon/max197 file. + */ + +/** + * struct max197_platform_data - MAX197 connectivity info + * @convert: Function used to start a conversion with control byte ctrl. + * It must return the raw data, or a negative error code. + */ +struct max197_platform_data { + int (*convert)(u8 ctrl); +}; -- cgit v1.2.3 From edec5af7c5cba4a8c00c0c52fbad3b83217122da Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 30 Aug 2012 21:46:19 -0400 Subject: hwmon: (sht15) remove multiple driver registration Declare an array of platform_device_id, instead of registering a driver for each supported chip. This makes the code cleaner. Also add a module description. Signed-off-by: Vivien Didelot Signed-off-by: Guenter Roeck --- drivers/hwmon/sht15.c | 94 +++++++++++++-------------------------------------- 1 file changed, 23 insertions(+), 71 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index e4614644408b..c8245c01fd53 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -1,7 +1,7 @@ /* * sht15.c - support for the SHT15 Temperature and Humidity Sensor * - * Portions Copyright (c) 2010-2011 Savoir-faire Linux Inc. + * Portions Copyright (c) 2010-2012 Savoir-faire Linux Inc. * Jerome Oufella * Vivien Didelot * @@ -53,6 +53,9 @@ #define SHT15_STATUS_HEATER 0x04 #define SHT15_STATUS_LOW_BATTERY 0x40 +/* List of supported chips */ +enum sht15_chips { sht10, sht11, sht15, sht71, sht75 }; + /* Actions the driver may be doing */ enum sht15_state { SHT15_READING_NOTHING, @@ -1024,77 +1027,26 @@ static int __devexit sht15_remove(struct platform_device *pdev) return 0; } -/* - * sht_drivers simultaneously refers to __devinit and __devexit function - * which causes spurious section mismatch warning. So use __refdata to - * get rid from this. - */ -static struct platform_driver __refdata sht_drivers[] = { - { - .driver = { - .name = "sht10", - .owner = THIS_MODULE, - }, - .probe = sht15_probe, - .remove = __devexit_p(sht15_remove), - }, { - .driver = { - .name = "sht11", - .owner = THIS_MODULE, - }, - .probe = sht15_probe, - .remove = __devexit_p(sht15_remove), - }, { - .driver = { - .name = "sht15", - .owner = THIS_MODULE, - }, - .probe = sht15_probe, - .remove = __devexit_p(sht15_remove), - }, { - .driver = { - .name = "sht71", - .owner = THIS_MODULE, - }, - .probe = sht15_probe, - .remove = __devexit_p(sht15_remove), - }, { - .driver = { - .name = "sht75", - .owner = THIS_MODULE, - }, - .probe = sht15_probe, - .remove = __devexit_p(sht15_remove), - }, +static struct platform_device_id sht15_device_ids[] = { + { "sht10", sht10 }, + { "sht11", sht11 }, + { "sht15", sht15 }, + { "sht71", sht71 }, + { "sht75", sht75 }, + { } }; +MODULE_DEVICE_TABLE(platform, sht15_device_ids); -static int __init sht15_init(void) -{ - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) { - ret = platform_driver_register(&sht_drivers[i]); - if (ret) - goto error_unreg; - } - - return 0; - -error_unreg: - while (--i >= 0) - platform_driver_unregister(&sht_drivers[i]); - - return ret; -} -module_init(sht15_init); - -static void __exit sht15_exit(void) -{ - int i; - for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--) - platform_driver_unregister(&sht_drivers[i]); -} -module_exit(sht15_exit); +static struct platform_driver sht15_driver = { + .driver = { + .name = "sht15", + .owner = THIS_MODULE, + }, + .probe = sht15_probe, + .remove = __devexit_p(sht15_remove), + .id_table = sht15_device_ids, +}; +module_platform_driver(sht15_driver); MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Sensirion SHT15 temperature and humidity sensor driver"); -- cgit v1.2.3 From 146ab288bbe037aa85a233221cd8d9a84bedcf85 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 4 Sep 2012 10:40:44 +0200 Subject: hwmon: (lm70) Allow 4wire SPI bus with LM70 Removing the 3wire limitation on LM70 as the component also allows operation on 4wire SPI bus Signed-off-by: Christophe Leroy Signed-off-by: Guenter Roeck --- Documentation/hwmon/lm70 | 5 ++--- drivers/hwmon/lm70.c | 4 ---- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/hwmon') diff --git a/Documentation/hwmon/lm70 b/Documentation/hwmon/lm70 index 0d240291e3cc..1bb1f20951ca 100644 --- a/Documentation/hwmon/lm70 +++ b/Documentation/hwmon/lm70 @@ -31,9 +31,8 @@ As a real (in-tree) example of this "SPI protocol driver" interfacing with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c and its associated documentation. -The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter- -face (read only) and 13-bit temperature data (0.0625 degrees celsius reso- -lution). +The TMP121/TMP123 are very similar; main difference is 13-bit temperature +data (0.0625 degrees celsius resolution). Thanks to --------- diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index dd7f0cafd197..1da62f616db5 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -143,10 +143,6 @@ static int __devinit lm70_probe(struct spi_device *spi) if (spi->mode & (SPI_CPOL | SPI_CPHA)) return -EINVAL; - /* 3-wire link (shared SI/SO) for LM70 */ - if (chip == LM70_CHIP_LM70 && !(spi->mode & SPI_3WIRE)) - return -EINVAL; - /* NOTE: we assume 8-bit words, and convert to 16 bits manually */ p_lm70 = devm_kzalloc(&spi->dev, sizeof(*p_lm70), GFP_KERNEL); -- cgit v1.2.3 From f4a41eeac90eaed4e21007e75d21fb74e3588f53 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 4 Sep 2012 18:57:08 -0700 Subject: hwmon: (adm9240) Remove legacy chassis intrusion detection sysfs attribute Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/adm9240.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 5a78d102a0fa..8b24d1a4a2b4 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -500,31 +500,6 @@ static ssize_t set_aout(struct device *dev, } static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); -/* chassis_clear */ -static ssize_t chassis_clear_legacy(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - long val; - int err; - - err = kstrtol(buf, 10, &val); - if (err) - return err; - - dev_warn(dev, "Attribute chassis_clear is deprecated, " - "use intrusion0_alarm instead\n"); - - if (val == 1) { - i2c_smbus_write_byte_data(client, - ADM9240_REG_CHASSIS_CLEAR, 0x80); - dev_dbg(&client->dev, "chassis intrusion latch cleared\n"); - } - return count; -} -static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear_legacy); - static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -586,7 +561,6 @@ static struct attribute *adm9240_attributes[] = { &sensor_dev_attr_fan2_alarm.dev_attr.attr, &dev_attr_alarms.attr, &dev_attr_aout_output.attr, - &dev_attr_chassis_clear.attr, &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, &dev_attr_cpu0_vid.attr, NULL -- cgit v1.2.3 From 1267ce9c332de174bae82e968e7f821380b2ccdf Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 4 Sep 2012 18:58:00 -0700 Subject: hwmon: (w83792d) Remove legacy chassis intrusion detection attributes Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83792d.c | 58 ++----------------------------------------------- 1 file changed, 2 insertions(+), 56 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 0ba5a2bd562e..06d6f56d4f69 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -296,7 +296,6 @@ struct w83792d_data { u8 pwmenable[3]; u32 alarms; /* realtime status register encoding,combined */ u8 chassis; /* Chassis status */ - u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */ u8 thermal_cruise[3]; /* Smart FanI: Fan1,2,3 target value */ u8 tolerance[3]; /* Fan1,2,3 tolerance(Smart Fan I/II) */ u8 sf2_points[3][4]; /* Smart FanII: Fan1,2,3 temperature points */ @@ -739,59 +738,13 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, } static ssize_t -show_chassis(struct device *dev, struct device_attribute *attr, +show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) { struct w83792d_data *data = w83792d_update_device(dev); return sprintf(buf, "%d\n", data->chassis); } -static ssize_t -show_regs_chassis(struct device *dev, struct device_attribute *attr, - char *buf) -{ - dev_warn(dev, - "Attribute %s is deprecated, use intrusion0_alarm instead\n", - "chassis"); - return show_chassis(dev, attr, buf); -} - -static ssize_t -show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct w83792d_data *data = w83792d_update_device(dev); - return sprintf(buf, "%d\n", data->chassis_clear); -} - -static ssize_t -store_chassis_clear_legacy(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83792d_data *data = i2c_get_clientdata(client); - unsigned long val; - int err; - u8 temp1 = 0, temp2 = 0; - - dev_warn(dev, - "Attribute %s is deprecated, use intrusion0_alarm instead\n", - "chassis_clear"); - - err = kstrtoul(buf, 10, &val); - if (err) - return err; - - mutex_lock(&data->update_lock); - data->chassis_clear = SENSORS_LIMIT(val, 0, 1); - temp1 = ((data->chassis_clear) << 7) & 0x80; - temp2 = w83792d_read_value(client, - W83792D_REG_CHASSIS_CLR) & 0x7f; - w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2); - mutex_unlock(&data->update_lock); - - return count; -} - static ssize_t store_chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1116,11 +1069,8 @@ static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20); static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21); static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22); static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23); -static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); -static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, - show_chassis_clear, store_chassis_clear_legacy); static DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, - show_chassis, store_chassis_clear); + show_chassis_clear, store_chassis_clear); static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2); @@ -1320,8 +1270,6 @@ static struct attribute *w83792d_attributes[] = { &sensor_dev_attr_pwm3_mode.dev_attr.attr, &sensor_dev_attr_pwm3_enable.dev_attr.attr, &dev_attr_alarms.attr, - &dev_attr_chassis.attr, - &dev_attr_chassis_clear.attr, &dev_attr_intrusion0_alarm.attr, &sensor_dev_attr_tolerance1.dev_attr.attr, &sensor_dev_attr_thermal_cruise1.dev_attr.attr, @@ -1627,8 +1575,6 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) /* Update CaseOpen status and it's CLR_CHS. */ data->chassis = (w83792d_read_value(client, W83792D_REG_CHASSIS) >> 5) & 0x01; - data->chassis_clear = (w83792d_read_value(client, - W83792D_REG_CHASSIS_CLR) >> 7) & 0x01; /* Update Thermal Cruise/Smart Fan I target value */ for (i = 0; i < 3; i++) { -- cgit v1.2.3 From 1a2a064eb8d74260edf23f9592675dd33519350f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 4 Sep 2012 18:58:29 -0700 Subject: hwmon: (w83793) Remove legacy chassis intrusion detection sysfs attributes Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83793.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index d6b0bdd48651..4fc47e062071 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -442,27 +442,6 @@ store_beep_enable(struct device *dev, struct device_attribute *attr, return count; } -/* Write any value to clear chassis alarm */ -static ssize_t -store_chassis_clear_legacy(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct w83793_data *data = i2c_get_clientdata(client); - u8 val; - - dev_warn(dev, "Attribute chassis is deprecated, " - "use intrusion0_alarm instead\n"); - - mutex_lock(&data->update_lock); - val = w83793_read_value(client, W83793_REG_CLR_CHASSIS); - val |= 0x80; - w83793_write_value(client, W83793_REG_CLR_CHASSIS, val); - mutex_unlock(&data->update_lock); - return count; -} - /* Write 0 to clear chassis alarm */ static ssize_t store_chassis_clear(struct device *dev, @@ -1189,8 +1168,6 @@ static struct sensor_device_attribute_2 w83793_vid[] = { static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm); static struct sensor_device_attribute_2 sda_single_files[] = { - SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, - store_chassis_clear_legacy, ALARM_STATUS, 30), SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, store_chassis_clear, ALARM_STATUS, 30), SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, -- cgit v1.2.3 From a86e94dc946d58fb5abb8e250a99720c9bdf8c2d Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Wed, 5 Sep 2012 11:49:14 +0200 Subject: hwmon: (lm70) Add support for LM71 and LM74 Add support for LM74 and LM71 to LM70 driver. Signed-off-by: Christophe Leroy Signed-off-by: Guenter Roeck --- Documentation/hwmon/lm70 | 11 +++++++++-- drivers/hwmon/Kconfig | 6 +++--- drivers/hwmon/lm70.c | 25 ++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers/hwmon') diff --git a/Documentation/hwmon/lm70 b/Documentation/hwmon/lm70 index 1bb1f20951ca..86d182942c51 100644 --- a/Documentation/hwmon/lm70 +++ b/Documentation/hwmon/lm70 @@ -6,6 +6,10 @@ Supported chips: Datasheet: http://www.national.com/pf/LM/LM70.html * Texas Instruments TMP121/TMP123 Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html + * National Semiconductor LM71 + Datasheet: http://www.ti.com/product/LM71 + * National Semiconductor LM74 + Datasheet: http://www.ti.com/product/LM74 Author: Kaiwan N Billimoria @@ -31,8 +35,11 @@ As a real (in-tree) example of this "SPI protocol driver" interfacing with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c and its associated documentation. -The TMP121/TMP123 are very similar; main difference is 13-bit temperature -data (0.0625 degrees celsius resolution). +The LM74 and TMP121/TMP123 are very similar; main difference is 13-bit +temperature data (0.0625 degrees celsius resolution). + +The LM71 is also very similar; main difference is 14-bit temperature +data (0.03125 degrees celsius resolution). Thanks to --------- diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6566ed6db3b0..8343cadd6632 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -560,12 +560,12 @@ config SENSORS_LM63 will be called lm63. config SENSORS_LM70 - tristate "National Semiconductor LM70 / Texas Instruments TMP121" + tristate "National Semiconductor LM70 and compatibles" depends on SPI_MASTER help If you say yes here you get support for the National Semiconductor - LM70 and Texas Instruments TMP121/TMP123 digital temperature - sensor chips. + LM70, LM71, LM74 and Texas Instruments TMP121/TMP123 digital tempera- + ture sensor chips. This driver can also be built as a module. If so, the module will be called lm70. diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 1da62f616db5..789753d0df79 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -43,6 +43,8 @@ #define LM70_CHIP_LM70 0 /* original NS LM70 */ #define LM70_CHIP_TMP121 1 /* TI TMP121/TMP123 */ +#define LM70_CHIP_LM71 2 /* NS LM71 */ +#define LM70_CHIP_LM74 3 /* NS LM74 */ struct lm70 { struct device *hwmon_dev; @@ -88,9 +90,13 @@ static ssize_t lm70_sense_temp(struct device *dev, * Celsius. * So it's equivalent to multiplying by 0.25 * 1000 = 250. * - * TMP121/TMP123: + * LM74 and TMP121/TMP123: * 13 bits of 2's complement data, discard LSB 3 bits, * resolution 0.0625 degrees celsius. + * + * LM71: + * 14 bits of 2's complement data, discard LSB 2 bits, + * resolution 0.0312 degrees celsius. */ switch (p_lm70->chip) { case LM70_CHIP_LM70: @@ -98,8 +104,13 @@ static ssize_t lm70_sense_temp(struct device *dev, break; case LM70_CHIP_TMP121: + case LM70_CHIP_LM74: val = ((int)raw / 8) * 625 / 10; break; + + case LM70_CHIP_LM71: + val = ((int)raw / 4) * 3125 / 100; + break; } status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ @@ -123,6 +134,12 @@ static ssize_t lm70_show_name(struct device *dev, struct device_attribute case LM70_CHIP_TMP121: ret = sprintf(buf, "tmp121\n"); break; + case LM70_CHIP_LM71: + ret = sprintf(buf, "lm71\n"); + break; + case LM70_CHIP_LM74: + ret = sprintf(buf, "lm74\n"); + break; default: ret = -EINVAL; } @@ -139,7 +156,7 @@ static int __devinit lm70_probe(struct spi_device *spi) struct lm70 *p_lm70; int status; - /* signaling is SPI_MODE_0 for both LM70 and TMP121 */ + /* signaling is SPI_MODE_0 */ if (spi->mode & (SPI_CPOL | SPI_CPHA)) return -EINVAL; @@ -196,6 +213,8 @@ static int __devexit lm70_remove(struct spi_device *spi) static const struct spi_device_id lm70_ids[] = { { "lm70", LM70_CHIP_LM70 }, { "tmp121", LM70_CHIP_TMP121 }, + { "lm71", LM70_CHIP_LM71 }, + { "lm74", LM70_CHIP_LM74 }, { }, }; MODULE_DEVICE_TABLE(spi, lm70_ids); @@ -213,5 +232,5 @@ static struct spi_driver lm70_driver = { module_spi_driver(lm70_driver); MODULE_AUTHOR("Kaiwan N Billimoria"); -MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver"); +MODULE_DESCRIPTION("NS LM70 and compatibles Linux driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 9224c38a312a339f1c9c2115a1f379c9f8f1731e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 20 Aug 2012 18:52:36 -0700 Subject: hwmon: (max1111) Add support for MAX1110, MAX1112, and MAX1113 MAX1110 is similar to MAX1111, with 8 instead of 4 channels. MAX1112 and MAX1113 are similar to MAX1110 and MAX1111, with 4.096V reference voltage instead of 2.048V. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/Kconfig | 5 ++-- drivers/hwmon/max1111.c | 74 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 9 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 8343cadd6632..41e311386e89 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -770,10 +770,11 @@ config SENSORS_LM95245 will be called lm95245. config SENSORS_MAX1111 - tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" + tristate "Maxim MAX1111 Serial 8-bit ADC chip and compatibles" depends on SPI_MASTER help - Say y here to support Maxim's MAX1111 ADC chips. + Say y here to support Maxim's MAX1110, MAX1111, MAX1112, and MAX1113 + ADC chips. This driver can also be built as a module. If so, the module will be called max1111. diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index f3978a46e844..b4eb0889c465 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -22,6 +22,8 @@ #include #include +enum chips { max1110, max1111, max1112, max1113 }; + #define MAX1111_TX_BUF_SIZE 1 #define MAX1111_RX_BUF_SIZE 2 @@ -30,6 +32,7 @@ #define MAX1111_CTRL_PD1 (1u << 1) #define MAX1111_CTRL_SGL (1u << 2) #define MAX1111_CTRL_UNI (1u << 3) +#define MAX1110_CTRL_SEL_SH (4) #define MAX1111_CTRL_SEL_SH (5) /* NOTE: bit 4 is ignored */ #define MAX1111_CTRL_STR (1u << 7) @@ -42,6 +45,8 @@ struct max1111_data { uint8_t rx_buf[MAX1111_RX_BUF_SIZE]; struct mutex drvdata_lock; /* protect msg, xfer and buffers from multiple access */ + int sel_sh; + int lsb; }; static int max1111_read(struct device *dev, int channel) @@ -53,7 +58,7 @@ static int max1111_read(struct device *dev, int channel) /* writing to drvdata struct is not thread safe, wait on mutex */ mutex_lock(&data->drvdata_lock); - data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | + data->tx_buf[0] = (channel << data->sel_sh) | MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; @@ -93,12 +98,13 @@ EXPORT_SYMBOL(max1111_read_channel); static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "max1111\n"); + return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); } static ssize_t show_adc(struct device *dev, struct device_attribute *attr, char *buf) { + struct max1111_data *data = dev_get_drvdata(dev); int channel = to_sensor_dev_attr(attr)->index; int ret; @@ -107,10 +113,10 @@ static ssize_t show_adc(struct device *dev, return ret; /* - * assume the reference voltage to be 2.048V, with an 8-bit sample, - * the LSB weight is 8mV + * Assume the reference voltage to be 2.048V or 4.096V, with an 8-bit + * sample. The LSB weight is 8mV or 16mV depending on the chip type. */ - return sprintf(buf, "%d\n", ret * 8); + return sprintf(buf, "%d\n", ret * data->lsb); } #define MAX1111_ADC_ATTR(_id) \ @@ -121,6 +127,10 @@ static MAX1111_ADC_ATTR(0); static MAX1111_ADC_ATTR(1); static MAX1111_ADC_ATTR(2); static MAX1111_ADC_ATTR(3); +static MAX1111_ADC_ATTR(4); +static MAX1111_ADC_ATTR(5); +static MAX1111_ADC_ATTR(6); +static MAX1111_ADC_ATTR(7); static struct attribute *max1111_attributes[] = { &dev_attr_name.attr, @@ -135,6 +145,18 @@ static const struct attribute_group max1111_attr_group = { .attrs = max1111_attributes, }; +static struct attribute *max1110_attributes[] = { + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + NULL, +}; + +static const struct attribute_group max1110_attr_group = { + .attrs = max1110_attributes, +}; + static int __devinit setup_transfer(struct max1111_data *data) { struct spi_message *m; @@ -159,6 +181,7 @@ static int __devinit setup_transfer(struct max1111_data *data) static int __devinit max1111_probe(struct spi_device *spi) { + enum chips chip = spi_get_device_id(spi)->driver_data; struct max1111_data *data; int err; @@ -174,6 +197,24 @@ static int __devinit max1111_probe(struct spi_device *spi) return -ENOMEM; } + switch (chip) { + case max1110: + data->lsb = 8; + data->sel_sh = MAX1110_CTRL_SEL_SH; + break; + case max1111: + data->lsb = 8; + data->sel_sh = MAX1111_CTRL_SEL_SH; + break; + case max1112: + data->lsb = 16; + data->sel_sh = MAX1110_CTRL_SEL_SH; + break; + case max1113: + data->lsb = 16; + data->sel_sh = MAX1111_CTRL_SEL_SH; + break; + } err = setup_transfer(data); if (err) return err; @@ -188,6 +229,14 @@ static int __devinit max1111_probe(struct spi_device *spi) dev_err(&spi->dev, "failed to create attribute group\n"); return err; } + if (chip == max1110 || chip == max1112) { + err = sysfs_create_group(&spi->dev.kobj, &max1110_attr_group); + if (err) { + dev_err(&spi->dev, + "failed to create extended attribute group\n"); + goto err_remove; + } + } data->hwmon_dev = hwmon_device_register(&spi->dev); if (IS_ERR(data->hwmon_dev)) { @@ -202,6 +251,7 @@ static int __devinit max1111_probe(struct spi_device *spi) return 0; err_remove: + sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group); sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); return err; } @@ -211,16 +261,27 @@ static int __devexit max1111_remove(struct spi_device *spi) struct max1111_data *data = spi_get_drvdata(spi); hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group); sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); mutex_destroy(&data->drvdata_lock); return 0; } +static const struct spi_device_id max1111_ids[] = { + { "max1110", max1110 }, + { "max1111", max1111 }, + { "max1112", max1112 }, + { "max1113", max1113 }, + { }, +}; +MODULE_DEVICE_TABLE(spi, max1111_ids); + static struct spi_driver max1111_driver = { .driver = { .name = "max1111", .owner = THIS_MODULE, }, + .id_table = max1111_ids, .probe = max1111_probe, .remove = __devexit_p(max1111_remove), }; @@ -228,6 +289,5 @@ static struct spi_driver max1111_driver = { module_spi_driver(max1111_driver); MODULE_AUTHOR("Eric Miao "); -MODULE_DESCRIPTION("MAX1111 ADC Driver"); +MODULE_DESCRIPTION("MAX1110/MAX1111/MAX1112/MAX1113 ADC Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:max1111"); -- cgit v1.2.3 From 6106db25c27550337a1d701631093cdfc645aa7b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 12 May 2012 11:21:01 -0700 Subject: hwmon: (ina2xx) Use structure array to distinguish chip types Replace per-device initialization and per-device calculation code with per-device configuration data, which is then used to configure the chip and perform calculations based on that data. This patch reduces code size by more than 400 bytes on x86_64. Cc: Lothar Felten Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/ina2xx.c | 159 +++++++++++++++++-------------------------------- 1 file changed, 56 insertions(+), 103 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 602148299f68..de8f2c6c6b66 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -57,18 +57,49 @@ enum ina2xx_ids { ina219, ina226 }; +struct ina2xx_config { + u16 config_default; + int calibration_factor; + int registers; + int shunt_div; + int bus_voltage_shift; + int bus_voltage_lsb; /* uV */ + int power_lsb; /* uW */ +}; + struct ina2xx_data { struct device *hwmon_dev; + const struct ina2xx_config *config; struct mutex update_lock; bool valid; unsigned long last_updated; int kind; - int registers; u16 regs[INA2XX_MAX_REGISTERS]; }; +static const struct ina2xx_config ina2xx_config[] = { + [ina219] = { + .config_default = INA219_CONFIG_DEFAULT, + .calibration_factor = 40960000, + .registers = INA219_REGISTERS, + .shunt_div = 100, + .bus_voltage_shift = 3, + .bus_voltage_lsb = 4000, + .power_lsb = 20000, + }, + [ina226] = { + .config_default = INA226_CONFIG_DEFAULT, + .calibration_factor = 5120000, + .registers = INA226_REGISTERS, + .shunt_div = 400, + .bus_voltage_shift = 0, + .bus_voltage_lsb = 1250, + .power_lsb = 25000, + }, +}; + static struct ina2xx_data *ina2xx_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -85,7 +116,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev) dev_dbg(&client->dev, "Starting ina2xx update\n"); /* Read all registers */ - for (i = 0; i < data->registers; i++) { + for (i = 0; i < data->config->registers; i++) { int rv = i2c_smbus_read_word_swapped(client, i); if (rv < 0) { ret = ERR_PTR(rv); @@ -101,73 +132,26 @@ abort: return ret; } -static int ina219_get_value(struct ina2xx_data *data, u8 reg) -{ - /* - * calculate exact value for the given register - * we assume default power-on reset settings: - * bus voltage range 32V - * gain = /8 - * adc 1 & 2 -> conversion time 532uS - * mode is continuous shunt and bus - * calibration value is INA219_CALIBRATION_VALUE - */ - int val = data->regs[reg]; - - switch (reg) { - case INA2XX_SHUNT_VOLTAGE: - /* LSB=10uV. Convert to mV. */ - val = DIV_ROUND_CLOSEST(val, 100); - break; - case INA2XX_BUS_VOLTAGE: - /* LSB=4mV. Register is not right aligned, convert to mV. */ - val = (val >> 3) * 4; - break; - case INA2XX_POWER: - /* LSB=20mW. Convert to uW */ - val = val * 20 * 1000; - break; - case INA2XX_CURRENT: - /* LSB=1mA (selected). Is in mA */ - break; - default: - /* programmer goofed */ - WARN_ON_ONCE(1); - val = 0; - break; - } - - return val; -} - -static int ina226_get_value(struct ina2xx_data *data, u8 reg) +static int ina2xx_get_value(struct ina2xx_data *data, u8 reg) { - /* - * calculate exact value for the given register - * we assume default power-on reset settings: - * bus voltage range 32V - * gain = /8 - * adc 1 & 2 -> conversion time 532uS - * mode is continuous shunt and bus - * calibration value is INA226_CALIBRATION_VALUE - */ - int val = data->regs[reg]; + int val; switch (reg) { case INA2XX_SHUNT_VOLTAGE: - /* LSB=2.5uV. Convert to mV. */ - val = DIV_ROUND_CLOSEST(val, 400); + val = DIV_ROUND_CLOSEST(data->regs[reg], + data->config->shunt_div); break; case INA2XX_BUS_VOLTAGE: - /* LSB=1.25mV. Convert to mV. */ - val = val + DIV_ROUND_CLOSEST(val, 4); + val = (data->regs[reg] >> data->config->bus_voltage_shift) + * data->config->bus_voltage_lsb; + val = DIV_ROUND_CLOSEST(val, 1000); break; case INA2XX_POWER: - /* LSB=25mW. Convert to uW */ - val = val * 25 * 1000; + val = data->regs[reg] * data->config->power_lsb; break; case INA2XX_CURRENT: /* LSB=1mA (selected). Is in mA */ + val = data->regs[reg]; break; default: /* programmer goofed */ @@ -184,23 +168,12 @@ static ssize_t ina2xx_show_value(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = ina2xx_update_device(dev); - int value = 0; if (IS_ERR(data)) return PTR_ERR(data); - switch (data->kind) { - case ina219: - value = ina219_get_value(data, attr->index); - break; - case ina226: - value = ina226_get_value(data, attr->index); - break; - default: - WARN_ON_ONCE(1); - break; - } - return snprintf(buf, PAGE_SIZE, "%d\n", value); + return snprintf(buf, PAGE_SIZE, "%d\n", + ina2xx_get_value(data, attr->index)); } /* shunt voltage */ @@ -238,7 +211,7 @@ static int ina2xx_probe(struct i2c_client *client, struct i2c_adapter *adapter = client->adapter; struct ina2xx_data *data; struct ina2xx_platform_data *pdata; - int ret = 0; + int ret; long shunt = 10000; /* default shunt value 10mOhms */ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) @@ -259,38 +232,15 @@ static int ina2xx_probe(struct i2c_client *client, /* set the device type */ data->kind = id->driver_data; + data->config = &ina2xx_config[data->kind]; - switch (data->kind) { - case ina219: - /* device configuration */ - i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, - INA219_CONFIG_DEFAULT); - - /* set current LSB to 1mA, shunt is in uOhms */ - /* (equation 13 in datasheet) */ - i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, - 40960000 / shunt); - dev_info(&client->dev, - "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); - data->registers = INA219_REGISTERS; - break; - case ina226: - /* device configuration */ - i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, - INA226_CONFIG_DEFAULT); - - /* set current LSB to 1mA, shunt is in uOhms */ - /* (equation 1 in datasheet)*/ - i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, - 5120000 / shunt); - dev_info(&client->dev, - "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); - data->registers = INA226_REGISTERS; - break; - default: - /* unknown device id */ - return -ENODEV; - } + /* device configuration */ + i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, + data->config->config_default); + /* set current LSB to 1mA, shunt is in uOhms */ + /* (equation 13 in datasheet) */ + i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, + data->config->calibration_factor / shunt); i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -305,6 +255,9 @@ static int ina2xx_probe(struct i2c_client *client, goto out_err_hwmon; } + dev_info(&client->dev, "power monitor %s (Rshunt = %li uOhm)\n", + id->name, shunt); + return 0; out_err_hwmon: -- cgit v1.2.3 From dc92cd0c13e0dbe2201fdececbb43c74af05da70 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 12 May 2012 11:33:11 -0700 Subject: hwmon: (ina2xx) Add support for INA220 and INA230 INA220 is register compatible to INA219, and INA230 is register compatible to INA226, so all we need to do is to add name aliases for those two chips. Cc: Lothar Felten Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- Documentation/hwmon/ina2xx | 18 ++++++++++++++++++ drivers/hwmon/Kconfig | 6 +++--- drivers/hwmon/ina2xx.c | 10 ++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) (limited to 'drivers/hwmon') diff --git a/Documentation/hwmon/ina2xx b/Documentation/hwmon/ina2xx index f50a6cc27616..03444f9d833f 100644 --- a/Documentation/hwmon/ina2xx +++ b/Documentation/hwmon/ina2xx @@ -8,12 +8,24 @@ Supported chips: Datasheet: Publicly available at the Texas Instruments website http://www.ti.com/ + * Texas Instruments INA220 + Prefix: 'ina220' + Addresses: I2C 0x40 - 0x4f + Datasheet: Publicly available at the Texas Instruments website + http://www.ti.com/ + * Texas Instruments INA226 Prefix: 'ina226' Addresses: I2C 0x40 - 0x4f Datasheet: Publicly available at the Texas Instruments website http://www.ti.com/ + * Texas Instruments INA230 + Prefix: 'ina230' + Addresses: I2C 0x40 - 0x4f + Datasheet: Publicly available at the Texas Instruments website + http://www.ti.com/ + Author: Lothar Felten Description @@ -23,7 +35,13 @@ The INA219 is a high-side current shunt and power monitor with an I2C interface. The INA219 monitors both shunt drop and supply voltage, with programmable conversion times and filtering. +The INA220 is a high or low side current shunt and power monitor with an I2C +interface. The INA220 monitors both shunt drop and supply voltage. + The INA226 is a current shunt and power monitor with an I2C interface. The INA226 monitors both a shunt voltage drop and bus supply voltage. +The INA230 is a high or low side current shunt and power monitor with an I2C +interface. The INA230 monitors both a shunt voltage drop and bus supply voltage. + The shunt value in micro-ohms can be set via platform data. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 41e311386e89..86adde90c1bb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1145,11 +1145,11 @@ config SENSORS_AMC6821 will be called amc6821. config SENSORS_INA2XX - tristate "Texas Instruments INA219, INA226" + tristate "Texas Instruments INA219 and compatibles" depends on I2C && EXPERIMENTAL help - If you say yes here you get support for INA219 and INA226 power - monitor chips. + If you say yes here you get support for INA219, INA220, INA226, and + INA230 power monitor chips. The INA2xx driver is configured for the default configuration of the part as described in the datasheet. diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index de8f2c6c6b66..70717d4a5e89 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -5,10 +5,18 @@ * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface * Datasheet: http://www.ti.com/product/ina219 * + * INA220: + * Bi-Directional Current/Power Monitor with I2C Interface + * Datasheet: http://www.ti.com/product/ina220 + * * INA226: * Bi-Directional Current/Power Monitor with I2C Interface * Datasheet: http://www.ti.com/product/ina226 * + * INA230: + * Bi-directional Current/Power Monitor with I2C Interface + * Datasheet: http://www.ti.com/product/ina230 + * * Copyright (C) 2012 Lothar Felten * Thanks to Jan Volkering * @@ -277,7 +285,9 @@ static int ina2xx_remove(struct i2c_client *client) static const struct i2c_device_id ina2xx_id[] = { { "ina219", ina219 }, + { "ina220", ina219 }, { "ina226", ina226 }, + { "ina230", ina226 }, { } }; MODULE_DEVICE_TABLE(i2c, ina2xx_id); -- cgit v1.2.3 From 8494df3aa65a110cfa756177fa6dc560322a7ab6 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Wed, 12 Sep 2012 17:06:42 +0200 Subject: hwmon: (asus_atk0110) Remove useless kfree The semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ position p1,p2; expression x; @@ if (x@p1 == NULL) { ... kfree@p2(x); ... return ...; } @unchanged exists@ position r.p1,r.p2; expression e <= r.x,x,e1; iterator I; statement S; @@ if (x@p1 == NULL) { ... when != I(x,...) S when != e = e1 when != e += e1 when != e -= e1 when != ++e when != --e when != e++ when != e-- when != &e kfree@p2(x); ... return ...; } @ok depends on unchanged exists@ position any r.p1; position r.p2; expression x; @@ ... when != true x@p1 == NULL kfree@p2(x); @depends on !ok && unchanged@ position r.p2; expression x; @@ *kfree@p2(x); // Signed-off-by: Peter Senna Tschudin Signed-off-by: Guenter Roeck --- drivers/hwmon/asus_atk0110.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 4ee578948723..cccb0e9d45b4 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -962,7 +962,6 @@ static int atk_add_sensor(struct atk_data *data, union acpi_object *obj) return 1; out: - kfree(sensor->acpi_name); kfree(sensor); return err; } -- cgit v1.2.3 From f9b693eb3db8b8cbcd34e0d3874e0252271f7204 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Wed, 12 Sep 2012 12:23:44 -0400 Subject: hwmon: (sht15) move header to linux/platform_data/ This patch moves the sht15.h header from include/linux to include/linux/platform_data, and update existing support (stargate2 platform) accordingly. Signed-off-by: Vivien Didelot Signed-off-by: Guenter Roeck --- arch/arm/mach-pxa/stargate2.c | 2 +- drivers/hwmon/sht15.c | 2 +- include/linux/platform_data/sht15.h | 33 +++++++++++++++++++++++++++++++++ include/linux/sht15.h | 34 ---------------------------------- 4 files changed, 35 insertions(+), 36 deletions(-) create mode 100644 include/linux/platform_data/sht15.h delete mode 100644 include/linux/sht15.h (limited to 'drivers/hwmon') diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 30b1b0b3c7f7..0701ca79e7d3 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include "devices.h" #include "generic.h" diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index c8245c01fd53..07a0c1a0b84d 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -24,12 +24,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/include/linux/platform_data/sht15.h b/include/linux/platform_data/sht15.h new file mode 100644 index 000000000000..33e0fd27225e --- /dev/null +++ b/include/linux/platform_data/sht15.h @@ -0,0 +1,33 @@ +/* + * sht15.h - support for the SHT15 Temperature and Humidity Sensor + * + * Copyright (c) 2009 Jonathan Cameron + * + * Copyright (c) 2007 Wouter Horre + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * For further information, see the Documentation/hwmon/sht15 file. + */ + +/** + * struct sht15_platform_data - sht15 connectivity info + * @gpio_data: no. of gpio to which bidirectional data line is + * connected. + * @gpio_sck: no. of gpio to which the data clock is connected. + * @supply_mv: supply voltage in mv. Overridden by regulator if + * available. + * @checksum: flag to indicate the checksum should be validated. + * @no_otp_reload: flag to indicate no reload from OTP. + * @low_resolution: flag to indicate the temp/humidity resolution to use. + */ +struct sht15_platform_data { + int gpio_data; + int gpio_sck; + int supply_mv; + bool checksum; + bool no_otp_reload; + bool low_resolution; +}; diff --git a/include/linux/sht15.h b/include/linux/sht15.h deleted file mode 100644 index f85c7c523da0..000000000000 --- a/include/linux/sht15.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * sht15.h - support for the SHT15 Temperature and Humidity Sensor - * - * Copyright (c) 2009 Jonathan Cameron - * - * Copyright (c) 2007 Wouter Horre - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * For further information, see the Documentation/hwmon/sht15 file. - */ - -/** - * struct sht15_platform_data - sht15 connectivity info - * @gpio_data: no. of gpio to which bidirectional data line is - * connected. - * @gpio_sck: no. of gpio to which the data clock is connected. - * @supply_mv: supply voltage in mv. Overridden by regulator if - * available. - * @checksum: flag to indicate the checksum should be validated. - * @no_otp_reload: flag to indicate no reload from OTP. - * @low_resolution: flag to indicate the temp/humidity resolution to use. - */ -struct sht15_platform_data { - int gpio_data; - int gpio_sck; - int supply_mv; - bool checksum; - bool no_otp_reload; - bool low_resolution; -}; - -- cgit v1.2.3 From ca2e24cbed1309d9c8ff50591294a0c82bd548d9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 12 Sep 2012 09:48:14 -0700 Subject: hwmon: (it87) Fix Kconfig for IT87 driver Add missing reference to IT8782F and IT8783E/F to it87 driver description in Kconfig. Replace wrong reference to Si960 with the correct Si950. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 86adde90c1bb..6cf51cbeca6f 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -505,8 +505,8 @@ config SENSORS_IT87 select HWMON_VID help If you say yes here you get support for ITE IT8705F, IT8712F, - IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F and IT8758E - sensor chips, and the SiS960 clone. + IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, + IT8782F, and IT8783E/F sensor chips, and the SiS950 clone. This driver can also be built as a module. If so, the module will be called it87. -- cgit v1.2.3 From e2d8c2b6de2db6d11afc661148b53691c2593f67 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 15 Sep 2012 07:59:15 -0700 Subject: hwmon: Drop dependencies on EXPERIMENTAL CONFIG_EXPERIMENTAL is expected to be removed, so drop dependencies on it. Signed-off-by: Guenter Roeck Acked-by: Greg Kroah-Hartman Acked-by: Jean Delvare --- drivers/hwmon/Kconfig | 81 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 41 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6cf51cbeca6f..6bc49cfb9f7b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -41,7 +41,7 @@ comment "Native drivers" config SENSORS_ABITUGURU tristate "Abit uGuru (rev 1 & 2)" - depends on X86 && DMI && EXPERIMENTAL + depends on X86 && DMI help If you say yes here you get support for the sensor part of the first and second revision of the Abit uGuru chip. The voltage and frequency @@ -56,7 +56,7 @@ config SENSORS_ABITUGURU config SENSORS_ABITUGURU3 tristate "Abit uGuru (rev 3)" - depends on X86 && DMI && EXPERIMENTAL + depends on X86 && DMI help If you say yes here you get support for the sensor part of the third revision of the Abit uGuru chip. Only reading the sensors @@ -70,7 +70,7 @@ config SENSORS_ABITUGURU3 config SENSORS_AD7314 tristate "Analog Devices AD7314 and compatibles" - depends on SPI && EXPERIMENTAL + depends on SPI help If you say yes here you get support for the Analog Devices AD7314, ADT7301 and ADT7302 temperature sensors. @@ -80,7 +80,7 @@ config SENSORS_AD7314 config SENSORS_AD7414 tristate "Analog Devices AD7414" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Analog Devices AD7414 temperature monitoring chip. @@ -90,7 +90,7 @@ config SENSORS_AD7414 config SENSORS_AD7418 tristate "Analog Devices AD7416, AD7417 and AD7418" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Analog Devices AD7416, AD7417 and AD7418 temperature monitoring chips. @@ -100,7 +100,7 @@ config SENSORS_AD7418 config SENSORS_ADCXX tristate "National Semiconductor ADCxxxSxxx" - depends on SPI_MASTER && EXPERIMENTAL + depends on SPI_MASTER help If you say yes here you get support for the National Semiconductor ADCS chip family, where @@ -181,7 +181,7 @@ config SENSORS_ADM9240 config SENSORS_ADT7410 tristate "Analog Devices ADT7410" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Analog Devices ADT7410 temperature monitoring chip. @@ -191,7 +191,7 @@ config SENSORS_ADT7410 config SENSORS_ADT7411 tristate "Analog Devices ADT7411" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Analog Devices ADT7411 voltage and temperature monitoring chip. @@ -201,7 +201,7 @@ config SENSORS_ADT7411 config SENSORS_ADT7462 tristate "Analog Devices ADT7462" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Analog Devices ADT7462 temperature monitoring chips. @@ -211,7 +211,7 @@ config SENSORS_ADT7462 config SENSORS_ADT7470 tristate "Analog Devices ADT7470" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Analog Devices ADT7470 temperature monitoring chips. @@ -246,7 +246,7 @@ config SENSORS_ASC7621 config SENSORS_K8TEMP tristate "AMD Athlon64/FX or Opteron temperature sensor" - depends on X86 && PCI && EXPERIMENTAL + depends on X86 && PCI help If you say yes here you get support for the temperature sensor(s) inside your CPU. Supported is whole AMD K8 @@ -281,7 +281,7 @@ config SENSORS_FAM15H_POWER config SENSORS_ASB100 tristate "Asus ASB100 Bach" - depends on X86 && I2C && EXPERIMENTAL + depends on X86 && I2C select HWMON_VID help If you say yes here you get support for the ASB100 Bach sensor @@ -292,7 +292,7 @@ config SENSORS_ASB100 config SENSORS_ATXP1 tristate "Attansic ATXP1 VID controller" - depends on I2C && EXPERIMENTAL + depends on I2C select HWMON_VID help If you say yes here you get support for the Attansic ATXP1 VID @@ -346,7 +346,7 @@ config SENSORS_EXYNOS4_TMU config SENSORS_I5K_AMB tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" - depends on PCI && EXPERIMENTAL + depends on PCI help If you say yes here you get support for FB-DIMM AMB temperature monitoring chips on systems with the Intel 5000 series chipset. @@ -455,7 +455,7 @@ config SENSORS_GPIO_FAN config SENSORS_HIH6130 tristate "Honeywell Humidicon HIH-6130 humidity/temperature sensor" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for Honeywell Humidicon HIH-6130 and HIH-6131 Humidicon humidity sensors. @@ -465,7 +465,7 @@ config SENSORS_HIH6130 config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" - depends on X86 && PCI && EXPERIMENTAL + depends on X86 && PCI help If you say yes here you get support for the temperature sensor inside your CPU. Most of the family 6 CPUs @@ -537,7 +537,7 @@ config SENSORS_JC42 config SENSORS_LINEAGE tristate "Lineage Compact Power Line Power Entry Module" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Lineage Compact Power Line series of DC/DC and AC/DC converters such as CP1800, CP2000AC, @@ -719,7 +719,7 @@ config SENSORS_LTC4151 config SENSORS_LTC4215 tristate "Linear Technology LTC4215" - depends on I2C && EXPERIMENTAL + depends on I2C default n help If you say yes here you get support for Linear Technology LTC4215 @@ -730,7 +730,7 @@ config SENSORS_LTC4215 config SENSORS_LTC4245 tristate "Linear Technology LTC4245" - depends on I2C && EXPERIMENTAL + depends on I2C default n help If you say yes here you get support for Linear Technology LTC4245 @@ -741,7 +741,7 @@ config SENSORS_LTC4245 config SENSORS_LTC4261 tristate "Linear Technology LTC4261" - depends on I2C && EXPERIMENTAL + depends on I2C default n help If you say yes here you get support for Linear Technology LTC4261 @@ -762,7 +762,7 @@ config SENSORS_LM95241 config SENSORS_LM95245 tristate "National Semiconductor LM95245 sensor chip" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for LM95245 sensor chip. @@ -806,7 +806,7 @@ config SENSORS_MAX1619 config SENSORS_MAX1668 tristate "Maxim MAX1668 and compatibles" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for MAX1668, MAX1989 and MAX1805 chips. @@ -825,7 +825,7 @@ config SENSORS_MAX197 config SENSORS_MAX6639 tristate "Maxim MAX6639 sensor chip" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the MAX6639 sensor chips. @@ -835,7 +835,7 @@ config SENSORS_MAX6639 config SENSORS_MAX6642 tristate "Maxim MAX6642 sensor chip" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for MAX6642 sensor chip. MAX6642 is a SMBus-Compatible Remote/Local Temperature Sensor @@ -846,7 +846,7 @@ config SENSORS_MAX6642 config SENSORS_MAX6650 tristate "Maxim MAX6650 sensor chip" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the MAX6650 / MAX6651 sensor chips. @@ -856,7 +856,7 @@ config SENSORS_MAX6650 config SENSORS_MCP3021 tristate "Microchip MCP3021" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the MCP3021 chip that is a A/D converter (ADC) with 10-bit resolution. @@ -866,7 +866,6 @@ config SENSORS_MCP3021 config SENSORS_NTC_THERMISTOR tristate "NTC thermistor support" - depends on EXPERIMENTAL help This driver supports NTC thermistors sensor reading and its interpretation. The driver can also monitor the temperature and @@ -971,7 +970,7 @@ config SENSORS_SIS5595 config SENSORS_SMM665 tristate "Summit Microelectronics SMM665" - depends on I2C && EXPERIMENTAL + depends on I2C default n help If you say yes here you get support for the hardware monitoring @@ -986,7 +985,7 @@ config SENSORS_SMM665 config SENSORS_DME1737 tristate "SMSC DME1737, SCH311x and compatibles" - depends on I2C && EXPERIMENTAL && !PPC + depends on I2C && !PPC select HWMON_VID help If you say yes here you get support for the hardware monitoring @@ -1062,7 +1061,7 @@ config SENSORS_SMSC47M192 config SENSORS_SMSC47B397 tristate "SMSC LPC47B397-NC" - depends on EXPERIMENTAL && !PPC + depends on !PPC help If you say yes here you get support for the SMSC LPC47B397-NC sensor chip. @@ -1136,7 +1135,7 @@ config SENSORS_ADS7871 config SENSORS_AMC6821 tristate "Texas Instruments AMC6821" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Texas Instruments AMC6821 hardware monitoring chips. @@ -1146,7 +1145,7 @@ config SENSORS_AMC6821 config SENSORS_INA2XX tristate "Texas Instruments INA219 and compatibles" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for INA219, INA220, INA226, and INA230 power monitor chips. @@ -1169,7 +1168,7 @@ config SENSORS_THMC50 config SENSORS_TMP102 tristate "Texas Instruments TMP102" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for Texas Instruments TMP102 sensor chips. @@ -1179,7 +1178,7 @@ config SENSORS_TMP102 config SENSORS_TMP401 tristate "Texas Instruments TMP401 and compatibles" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for Texas Instruments TMP401 and TMP411 temperature sensor chips. @@ -1189,7 +1188,7 @@ config SENSORS_TMP401 config SENSORS_TMP421 tristate "Texas Instruments TMP421 and compatible" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for Texas Instruments TMP421, TMP422 and TMP423 temperature sensor chips. @@ -1281,7 +1280,7 @@ config SENSORS_W83792D config SENSORS_W83793 tristate "Winbond W83793" - depends on I2C && EXPERIMENTAL + depends on I2C select HWMON_VID help If you say yes here you get support for the Winbond W83793 @@ -1293,7 +1292,7 @@ config SENSORS_W83793 config SENSORS_W83795 tristate "Winbond/Nuvoton W83795G/ADG" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Winbond W83795G and W83795ADG hardware monitoring chip, including manual fan speed @@ -1304,7 +1303,7 @@ config SENSORS_W83795 config SENSORS_W83795_FANCTRL boolean "Include automatic fan control support (DANGEROUS)" - depends on SENSORS_W83795 && EXPERIMENTAL + depends on SENSORS_W83795 default n help If you say yes here, support for automatic fan speed control @@ -1321,7 +1320,7 @@ config SENSORS_W83795_FANCTRL config SENSORS_W83L785TS tristate "Winbond W83L785TS-S" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Winbond W83L785TS-S sensor chip, which is used on the Asus A7N8X, among other @@ -1332,7 +1331,7 @@ config SENSORS_W83L785TS config SENSORS_W83L786NG tristate "Winbond W83L786NG, W83L786NR" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Winbond W83L786NG and W83L786NR sensor chips. @@ -1447,7 +1446,7 @@ config SENSORS_ACPI_POWER config SENSORS_ATK0110 tristate "ASUS ATK0110" - depends on X86 && EXPERIMENTAL + depends on X86 help If you say yes here you get support for the ACPI hardware monitoring interface found in many ASUS motherboards. This -- cgit v1.2.3 From cc00e4ddbf00d5ee6d8b7df6d4b04d98f3d99af5 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 11 Sep 2012 13:36:33 -0700 Subject: hwmon: (adcxx) Simplify show_name function Display device name using to_spi_device(dev)->modalias instead of computing it from the number of ADC channels. This is cleaner and reduces code size. Signed-off-by: Guenter Roeck --- drivers/hwmon/adcxx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c index 111af7c4a3d4..f4c5867170d6 100644 --- a/drivers/hwmon/adcxx.c +++ b/drivers/hwmon/adcxx.c @@ -141,10 +141,7 @@ static ssize_t adcxx_set_max(struct device *dev, static ssize_t adcxx_show_name(struct device *dev, struct device_attribute *devattr, char *buf) { - struct spi_device *spi = to_spi_device(dev); - struct adcxx *adc = spi_get_drvdata(spi); - - return sprintf(buf, "adcxx%ds\n", adc->channels); + return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); } static struct sensor_device_attribute ad_input[] = { -- cgit v1.2.3 From 860f37319e9a1141b041ca2e77ca121dccde4b93 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 11 Sep 2012 13:34:29 -0700 Subject: hwmon: (lm70) Simplify show_name function Instead of using a switch statement to determine the device name, use to_spi_device(dev)->modalias to simplify the code and reduce module size. Signed-off-by: Guenter Roeck --- drivers/hwmon/lm70.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 789753d0df79..2d1777a03edb 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -124,26 +124,7 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); static ssize_t lm70_show_name(struct device *dev, struct device_attribute *devattr, char *buf) { - struct lm70 *p_lm70 = dev_get_drvdata(dev); - int ret; - - switch (p_lm70->chip) { - case LM70_CHIP_LM70: - ret = sprintf(buf, "lm70\n"); - break; - case LM70_CHIP_TMP121: - ret = sprintf(buf, "tmp121\n"); - break; - case LM70_CHIP_LM71: - ret = sprintf(buf, "lm71\n"); - break; - case LM70_CHIP_LM74: - ret = sprintf(buf, "lm74\n"); - break; - default: - ret = -EINVAL; - } - return ret; + return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); } static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); -- cgit v1.2.3 From 3be8102fe30c09e9b264a2f08ae2f69da7e32eb4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 19 Sep 2012 11:21:51 -0700 Subject: hwmon: (lm93) Drop unnecessary compare statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following build warning is seen with -Wextra. lm93.c: In function ‘store_fan_smart_tach’: lm93.c:1833:2: warning: comparison of unsigned expression >= 0 is always true Drop the unnecessary comparison. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/lm93.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index bf946187bd37..c3d4255ed154 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -1830,7 +1830,7 @@ static ssize_t store_fan_smart_tach(struct device *dev, mutex_lock(&data->update_lock); /* sanity test, ignore the write otherwise */ - if (0 <= val && val <= 2) { + if (val <= 2) { /* can't enable if pwm freq is 22.5KHz */ if (val) { u8 ctl4 = lm93_read_byte(client, -- cgit v1.2.3 From a91698135bef4e945b0eee1b676d6ea5085177dc Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 19 Sep 2012 11:27:03 -0700 Subject: hwmon: (w83791d) Drop unnecessary compare statements The following build warnings are seen with -Wextra. w83791d.c: In function store_temp_target: w83791d.c:858:2: warning: comparison of unsigned expression < 0 is always false w83791d.c: In function store_temp_tolerance: w83791d.c:920:2: warning: comparison of unsigned expression < 0 is always false For store_temp_target, accept negative numbers and clamp to >= 0. For store_temp_tolerance, drop the unnecessary comparison. Signed-off-by: Guenter Roeck Acked-by: Jean Delvare --- drivers/hwmon/w83791d.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 9ade4d4e2185..93ea81a4bf35 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -259,8 +259,7 @@ static u8 fan_to_reg(long rpm, int div) ((val) + 500) / 1000) /* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */ -#define TOL_TEMP_TO_REG(val) ((val) < 0 ? 0 : \ - (val) >= 15000 ? 15 : \ +#define TOL_TEMP_TO_REG(val) ((val) >= 15000 ? 15 : \ ((val) + 500) / 1000) #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) @@ -848,10 +847,10 @@ static ssize_t store_temp_target(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct w83791d_data *data = i2c_get_clientdata(client); int nr = sensor_attr->index; - unsigned long val; + long val; u8 target_mask; - if (kstrtoul(buf, 10, &val)) + if (kstrtol(buf, 10, &val)) return -EINVAL; mutex_lock(&data->update_lock); -- cgit v1.2.3 From 8b662f38e066d8fc1b73a8655da547c348206904 Mon Sep 17 00:00:00 2001 From: Sven Schuchmann Date: Fri, 21 Sep 2012 13:04:21 +0200 Subject: hwmon: (mcp3021) Prepare MCP3021 driver to support other chips This Patch is to prepare the MCP3021 driver to support other chips like the MCP3221. The hard defined chip data is now stored within the data struct of each chip. Signed-off-by: Sven Schuchmann Signed-off-by: Guenter Roeck --- drivers/hwmon/mcp3021.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c index 5162bb95bc61..d700b9271174 100644 --- a/drivers/hwmon/mcp3021.c +++ b/drivers/hwmon/mcp3021.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc. * Author: Mingkai Hu + * Reworked by Sven Schuchmann * * This driver export the value of analog input voltage to sysfs, the * voltage unit is mV. Through the sysfs interface, lm-sensors tool @@ -34,16 +35,24 @@ #define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */ #define MCP3021_OUTPUT_SCALE 4 +enum chips { + mcp3021 +}; /* * Client data (each client gets its own) */ struct mcp3021_data { struct device *hwmon_dev; u32 vdd; /* device power supply */ + u16 sar_shift; + u16 sar_mask; + u8 output_res; + u8 output_scale; }; static int mcp3021_read16(struct i2c_client *client) { + struct mcp3021_data *data = i2c_get_clientdata(client); int ret; u16 reg; __be16 buf; @@ -61,20 +70,20 @@ static int mcp3021_read16(struct i2c_client *client) * The ten-bit output code is composed of the lower 4-bit of the * first byte and the upper 6-bit of the second byte. */ - reg = (reg >> MCP3021_SAR_SHIFT) & MCP3021_SAR_MASK; + reg = (reg >> data->sar_shift) & data->sar_mask; return reg; } -static inline u16 volts_from_reg(u16 vdd, u16 val) +static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val) { if (val == 0) return 0; - val = val * MCP3021_OUTPUT_SCALE - MCP3021_OUTPUT_SCALE / 2; + val = val * data->output_scale - data->output_scale / 2; - return val * DIV_ROUND_CLOSEST(vdd, - (1 << MCP3021_OUTPUT_RES) * MCP3021_OUTPUT_SCALE); + return val * DIV_ROUND_CLOSEST(data->vdd, + (1 << data->output_res) * data->output_scale); } static ssize_t show_in_input(struct device *dev, struct device_attribute *attr, @@ -88,7 +97,8 @@ static ssize_t show_in_input(struct device *dev, struct device_attribute *attr, if (reg < 0) return reg; - in_input = volts_from_reg(data->vdd, reg); + in_input = volts_from_reg(data, reg); + return sprintf(buf, "%d\n", in_input); } @@ -110,6 +120,15 @@ static int mcp3021_probe(struct i2c_client *client, i2c_set_clientdata(client, data); + switch (id->driver_data) { + case mcp3021: + data->sar_shift = MCP3021_SAR_SHIFT; + data->sar_mask = MCP3021_SAR_MASK; + data->output_res = MCP3021_OUTPUT_RES; + data->output_scale = MCP3021_OUTPUT_SCALE; + break; + } + if (client->dev.platform_data) { data->vdd = *(u32 *)client->dev.platform_data; if (data->vdd > MCP3021_VDD_MAX || data->vdd < MCP3021_VDD_MIN) @@ -145,7 +164,7 @@ static int mcp3021_remove(struct i2c_client *client) } static const struct i2c_device_id mcp3021_id[] = { - { "mcp3021", 0 }, + { "mcp3021", mcp3021 }, { } }; MODULE_DEVICE_TABLE(i2c, mcp3021_id); -- cgit v1.2.3 From 592758b12f2e327bb5902dabd3d36b2e86049871 Mon Sep 17 00:00:00 2001 From: Sven Schuchmann Date: Fri, 21 Sep 2012 13:04:22 +0200 Subject: hwmon: (mcp3021) Add MCP3221 support This Patch adds support for mcp3221 chip to the mcp3021 driver. Signed-off-by: Sven Schuchmann Signed-off-by: Guenter Roeck --- Documentation/hwmon/mcp3021 | 23 +++++++++++++++-------- drivers/hwmon/Kconfig | 7 ++++--- drivers/hwmon/mcp3021.c | 21 ++++++++++++++++++--- 3 files changed, 37 insertions(+), 14 deletions(-) (limited to 'drivers/hwmon') diff --git a/Documentation/hwmon/mcp3021 b/Documentation/hwmon/mcp3021 index 325fd87e81b2..74a6b72adf5f 100644 --- a/Documentation/hwmon/mcp3021 +++ b/Documentation/hwmon/mcp3021 @@ -5,18 +5,25 @@ Supported chips: * Microchip Technology MCP3021 Prefix: 'mcp3021' Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21805a.pdf + * Microchip Technology MCP3221 + Prefix: 'mcp3221' + Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21732c.pdf -Author: Mingkai Hu +Authors: + Mingkai Hu + Sven Schuchmann Description ----------- -This driver implements support for the Microchip Technology MCP3021 chip. +This driver implements support for the Microchip Technology MCP3021 and +MCP3221 chip. The Microchip Technology Inc. MCP3021 is a successive approximation A/D -converter (ADC) with 10-bit resolution. -This device provides one single-ended input with very low power consumption. -Communication to the MCP3021 is performed using a 2-wire I2C compatible -interface. Standard (100 kHz) and Fast (400 kHz) I2C modes are available. -The default I2C device address is 0x4d (contact the Microchip factory for -additional address options). +converter (ADC) with 10-bit resolution. The MCP3221 has 12-bit resolution. + +These devices provide one single-ended input with very low power consumption. +Communication to the MCP3021/MCP3221 is performed using a 2-wire I2C +compatible interface. Standard (100 kHz) and Fast (400 kHz) I2C modes are +available. The default I2C device address is 0x4d (contact the Microchip +factory for additional address options). diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6bc49cfb9f7b..c74e73b2069a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -855,11 +855,12 @@ config SENSORS_MAX6650 will be called max6650. config SENSORS_MCP3021 - tristate "Microchip MCP3021" + tristate "Microchip MCP3021 and compatibles" depends on I2C help - If you say yes here you get support for the MCP3021 chip - that is a A/D converter (ADC) with 10-bit resolution. + If you say yes here you get support for MCP3021 and MCP3221. + The MCP3021 is a A/D converter (ADC) with 10-bit and the MCP3221 + with 12-bit resolution. This driver can also be built as a module. If so, the module will be called mcp3021. diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c index d700b9271174..eedb32292d6d 100644 --- a/drivers/hwmon/mcp3021.c +++ b/drivers/hwmon/mcp3021.c @@ -1,5 +1,5 @@ /* - * mcp3021.c - driver for the Microchip MCP3021 chip + * mcp3021.c - driver for Microchip MCP3021 and MCP3221 * * Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc. * Author: Mingkai Hu @@ -35,9 +35,16 @@ #define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */ #define MCP3021_OUTPUT_SCALE 4 +#define MCP3221_SAR_SHIFT 0 +#define MCP3221_SAR_MASK 0xfff +#define MCP3221_OUTPUT_RES 12 /* 12-bit resolution */ +#define MCP3221_OUTPUT_SCALE 1 + enum chips { - mcp3021 + mcp3021, + mcp3221 }; + /* * Client data (each client gets its own) */ @@ -127,6 +134,13 @@ static int mcp3021_probe(struct i2c_client *client, data->output_res = MCP3021_OUTPUT_RES; data->output_scale = MCP3021_OUTPUT_SCALE; break; + + case mcp3221: + data->sar_shift = MCP3221_SAR_SHIFT; + data->sar_mask = MCP3221_SAR_MASK; + data->output_res = MCP3221_OUTPUT_RES; + data->output_scale = MCP3221_OUTPUT_SCALE; + break; } if (client->dev.platform_data) { @@ -165,6 +179,7 @@ static int mcp3021_remove(struct i2c_client *client) static const struct i2c_device_id mcp3021_id[] = { { "mcp3021", mcp3021 }, + { "mcp3221", mcp3221 }, { } }; MODULE_DEVICE_TABLE(i2c, mcp3021_id); @@ -181,5 +196,5 @@ static struct i2c_driver mcp3021_driver = { module_i2c_driver(mcp3021_driver); MODULE_AUTHOR("Mingkai Hu "); -MODULE_DESCRIPTION("Microchip MCP3021 driver"); +MODULE_DESCRIPTION("Microchip MCP3021/MCP3221 driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3