diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-03-26 17:18:44 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-03-26 17:19:03 +0200 |
commit | 7fd52392c56361a40f0c630a82b36b95ca31eac6 (patch) | |
tree | 14091de24c6b28ea4cae9826f98aeedb7be091f5 /drivers/hwmon | |
parent | perf: Move mmap page data_head offset assertion out of header (diff) | |
parent | Merge tag 'stable/for-linus-3.4-tag-two' of git://git.kernel.org/pub/scm/linu... (diff) | |
download | linux-7fd52392c56361a40f0c630a82b36b95ca31eac6.tar.xz linux-7fd52392c56361a40f0c630a82b36b95ca31eac6.zip |
Merge branch 'linus' into perf/urgent
Merge reason: we need to fix a non-trivial merge conflict.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/hwmon')
126 files changed, 9278 insertions, 6553 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index dad895fec62a..5b32d56dbb4d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -598,11 +598,11 @@ config SENSORS_LM78 will be called lm78. config SENSORS_LM80 - tristate "National Semiconductor LM80" + tristate "National Semiconductor LM80 and LM96080" depends on I2C help If you say yes here you get support for National Semiconductor - LM80 sensor chips. + LM80 and LM96080 sensor chips. This driver can also be built as a module. If so, the module will be called lm80. @@ -648,7 +648,8 @@ config SENSORS_LM90 LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, - Winbond/Nuvoton W83L771W/G/AWG/ASG and Philips SA56004 sensor chips. + Winbond/Nuvoton W83L771W/G/AWG/ASG, Philips SA56004, and GMT G781 + sensor chips. This driver can also be built as a module. If so, the module will be called lm90. @@ -812,6 +813,16 @@ config SENSORS_MAX6650 This driver can also be built as a module. If so, the module will be called max6650. +config SENSORS_MCP3021 + tristate "Microchip MCP3021" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the MCP3021 chip + that is a A/D converter (ADC) with 10-bit resolution. + + This driver can also be built as a module. If so, the module + will be called mcp3021. + config SENSORS_NTC_THERMISTOR tristate "NTC thermistor support" depends on EXPERIMENTAL @@ -1028,7 +1039,8 @@ config SENSORS_SCH5627 select SENSORS_SCH56XX_COMMON help If you say yes here you get support for the hardware monitoring - features of the SMSC SCH5627 Super-I/O chip. + features of the SMSC SCH5627 Super-I/O chip including support for + the integrated watchdog. This driver can also be built as a module. If so, the module will be called sch5627. @@ -1044,7 +1056,8 @@ config SENSORS_SCH5636 Currently this driver only supports the Fujitsu Theseus SCH5636 based hwmon solution. Say yes here if you want support for the Fujitsu - Theseus' hardware monitoring features. + Theseus' hardware monitoring features including support for the + integrated watchdog. This driver can also be built as a module. If so, the module will be called sch5636. @@ -1227,18 +1240,19 @@ config SENSORS_W83795 depends on I2C && EXPERIMENTAL help If you say yes here you get support for the Winbond W83795G and - W83795ADG hardware monitoring chip. + W83795ADG hardware monitoring chip, including manual fan speed + control. This driver can also be built as a module. If so, the module will be called w83795. config SENSORS_W83795_FANCTRL - boolean "Include fan control support (DANGEROUS)" + boolean "Include automatic fan control support (DANGEROUS)" depends on SENSORS_W83795 && EXPERIMENTAL default n help - If you say yes here, support for the both manual and automatic - fan control features will be included in the driver. + If you say yes here, support for automatic fan speed control + will be included in the driver. This part of the code wasn't carefully reviewed and tested yet, so enabling this option is strongly discouraged on production @@ -1356,10 +1370,10 @@ config SENSORS_APPLESMC the awesome power of applesmc. config SENSORS_MC13783_ADC - tristate "Freescale MC13783 ADC" - depends on MFD_MC13783 + tristate "Freescale MC13783/MC13892 ADC" + depends on MFD_MC13XXX help - Support for the A/D converter on MC13783 PMIC. + Support for the A/D converter on MC13783 and MC13892 PMIC. if ACPI diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8251ce8cd035..6d3f11f71815 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -95,6 +95,7 @@ obj-$(CONFIG_SENSORS_MAX6639) += max6639.o obj-$(CONFIG_SENSORS_MAX6642) += max6642.o obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o +obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PC87427) += pc87427.o diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 3b728e8f169b..a72bf25601a4 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1,25 +1,25 @@ /* - abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* - This driver supports the sensor part of the first and second revision of - the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because - of lack of specs the CPU/RAM voltage & frequency control is not supported! -*/ + * This driver supports the sensor part of the first and second revision of + * the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because + * of lack of specs the CPU/RAM voltage & frequency control is not supported! + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -44,8 +44,10 @@ #define ABIT_UGURU_SENSOR_BANK2 0x26 /* fans */ /* max nr of sensors in bank1, a bank1 sensor can be in, temp or nc */ #define ABIT_UGURU_MAX_BANK1_SENSORS 16 -/* Warning if you increase one of the 2 MAX defines below to 10 or higher you - should adjust the belonging _NAMES_LENGTH macro for the 2 digit number! */ +/* + * Warning if you increase one of the 2 MAX defines below to 10 or higher you + * should adjust the belonging _NAMES_LENGTH macro for the 2 digit number! + */ /* max nr of sensors in bank2, currently mb's with max 6 fans are known */ #define ABIT_UGURU_MAX_BANK2_SENSORS 6 /* max nr of pwm outputs, currently mb's with max 5 pwm outputs are known */ @@ -70,16 +72,22 @@ #define ABIT_UGURU_IN_SENSOR 0 #define ABIT_UGURU_TEMP_SENSOR 1 #define ABIT_UGURU_NC 2 -/* In many cases we need to wait for the uGuru to reach a certain status, most - of the time it will reach this status within 30 - 90 ISA reads, and thus we - can best busy wait. This define gives the total amount of reads to try. */ +/* + * In many cases we need to wait for the uGuru to reach a certain status, most + * of the time it will reach this status within 30 - 90 ISA reads, and thus we + * can best busy wait. This define gives the total amount of reads to try. + */ #define ABIT_UGURU_WAIT_TIMEOUT 125 -/* However sometimes older versions of the uGuru seem to be distracted and they - do not respond for a long time. To handle this we sleep before each of the - last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. */ +/* + * However sometimes older versions of the uGuru seem to be distracted and they + * do not respond for a long time. To handle this we sleep before each of the + * last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. + */ #define ABIT_UGURU_WAIT_TIMEOUT_SLEEP 5 -/* Normally all expected status in abituguru_ready, are reported after the - first read, but sometimes not and we need to poll. */ +/* + * Normally all expected status in abituguru_ready, are reported after the + * first read, but sometimes not and we need to poll. + */ #define ABIT_UGURU_READY_TIMEOUT 5 /* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */ #define ABIT_UGURU_MAX_RETRIES 3 @@ -92,17 +100,25 @@ if (level <= verbose) \ printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) /* Macros to help calculate the sysfs_names array length */ -/* sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, - in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0 */ +/* + * sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, + * in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0 + */ #define ABITUGURU_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14) -/* sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0, - temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0 */ +/* + * sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0, + * temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0 + */ #define ABITUGURU_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16) -/* sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0, - fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0 */ +/* + * sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0, + * fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0 + */ #define ABITUGURU_FAN_NAMES_LENGTH (11 + 9 + 11 + 18 + 10 + 14) -/* sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0, - pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0 */ +/* + * sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0, + * pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0 + */ #define ABITUGURU_PWM_NAMES_LENGTH (12 + 24 + 2 * 21 + 2 * 22) /* IN_NAMES_LENGTH > TEMP_NAMES_LENGTH so assume all bank1 sensors are in */ #define ABITUGURU_SYSFS_NAMES_LENGTH ( \ @@ -110,10 +126,12 @@ ABIT_UGURU_MAX_BANK2_SENSORS * ABITUGURU_FAN_NAMES_LENGTH + \ ABIT_UGURU_MAX_PWMS * ABITUGURU_PWM_NAMES_LENGTH) -/* All the macros below are named identical to the oguru and oguru2 programs - reverse engineered by Olle Sandberg, hence the names might not be 100% - logical. I could come up with better names, but I prefer keeping the names - identical so that this driver can be compared with his work more easily. */ +/* + * All the macros below are named identical to the oguru and oguru2 programs + * reverse engineered by Olle Sandberg, hence the names might not be 100% + * logical. I could come up with better names, but I prefer keeping the names + * identical so that this driver can be compared with his work more easily. + */ /* Two i/o-ports are used by uGuru */ #define ABIT_UGURU_BASE 0x00E0 /* Used to tell uGuru what to read and to read the actual data */ @@ -130,16 +148,22 @@ /* Constants */ /* in (Volt) sensors go up to 3494 mV, temp to 255000 millidegrees Celsius */ static const int abituguru_bank1_max_value[2] = { 3494, 255000 }; -/* Min / Max allowed values for sensor2 (fan) alarm threshold, these values - correspond to 300-3000 RPM */ +/* + * Min / Max allowed values for sensor2 (fan) alarm threshold, these values + * correspond to 300-3000 RPM + */ static const u8 abituguru_bank2_min_threshold = 5; static const u8 abituguru_bank2_max_threshold = 50; -/* Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4 - are temperature trip points. */ +/* + * Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4 + * are temperature trip points. + */ static const int abituguru_pwm_settings_multiplier[5] = { 0, 1, 1, 1000, 1000 }; -/* Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a - special case the minium allowed pwm% setting for this is 30% (77) on - some MB's this special case is handled in the code! */ +/* + * Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a + * special case the minium allowed pwm% setting for this is 30% (77) on + * some MB's this special case is handled in the code! + */ static const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 }; static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 }; @@ -175,23 +199,29 @@ MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n" " 3 + retryable error reporting"); -/* For the Abit uGuru, we need to keep some data in memory. - The structure is dynamically allocated, at the same time when a new - abituguru device is allocated. */ +/* + * For the Abit uGuru, we need to keep some data in memory. + * The structure is dynamically allocated, at the same time when a new + * abituguru device is allocated. + */ struct abituguru_data { struct device *hwmon_dev; /* hwmon registered device */ struct mutex update_lock; /* protect access to data and uGuru */ unsigned long last_updated; /* In jiffies */ unsigned short addr; /* uguru base address */ char uguru_ready; /* is the uguru in ready state? */ - unsigned char update_timeouts; /* number of update timeouts since last - successful update */ - - /* The sysfs attr and their names are generated automatically, for bank1 - we cannot use a predefined array because we don't know beforehand - of a sensor is a volt or a temp sensor, for bank2 and the pwms its - easier todo things the same way. For in sensors we have 9 (temp 7) - sysfs entries per sensor, for bank2 and pwms 6. */ + unsigned char update_timeouts; /* + * number of update timeouts since last + * successful update + */ + + /* + * The sysfs attr and their names are generated automatically, for bank1 + * we cannot use a predefined array because we don't know beforehand + * of a sensor is a volt or a temp sensor, for bank2 and the pwms its + * easier todo things the same way. For in sensors we have 9 (temp 7) + * sysfs entries per sensor, for bank2 and pwms 6. + */ struct sensor_device_attribute_2 sysfs_attr[ ABIT_UGURU_MAX_BANK1_SENSORS * 9 + ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6]; @@ -203,11 +233,15 @@ struct abituguru_data { u8 bank1_sensors[2]; u8 bank1_address[2][ABIT_UGURU_MAX_BANK1_SENSORS]; u8 bank1_value[ABIT_UGURU_MAX_BANK1_SENSORS]; - /* This array holds 3 entries per sensor for the bank 1 sensor settings - (flags, min, max for voltage / flags, warn, shutdown for temp). */ + /* + * This array holds 3 entries per sensor for the bank 1 sensor settings + * (flags, min, max for voltage / flags, warn, shutdown for temp). + */ u8 bank1_settings[ABIT_UGURU_MAX_BANK1_SENSORS][3]; - /* Maximum value for each sensor used for scaling in mV/millidegrees - Celsius. */ + /* + * Maximum value for each sensor used for scaling in mV/millidegrees + * Celsius. + */ int bank1_max_value[ABIT_UGURU_MAX_BANK1_SENSORS]; /* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */ @@ -236,8 +270,10 @@ static int abituguru_wait(struct abituguru_data *data, u8 state) timeout--; if (timeout == 0) return -EBUSY; - /* sleep a bit before our last few tries, see the comment on - this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. */ + /* + * sleep a bit before our last few tries, see the comment on + * this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. + */ if (timeout <= ABIT_UGURU_WAIT_TIMEOUT_SLEEP) msleep(0); } @@ -273,8 +309,10 @@ static int abituguru_ready(struct abituguru_data *data) msleep(0); } - /* After this the ABIT_UGURU_DATA port should contain - ABIT_UGURU_STATUS_INPUT */ + /* + * After this the ABIT_UGURU_DATA port should contain + * ABIT_UGURU_STATUS_INPUT + */ timeout = ABIT_UGURU_READY_TIMEOUT; while (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) { timeout--; @@ -290,27 +328,35 @@ static int abituguru_ready(struct abituguru_data *data) return 0; } -/* Send the bank and then sensor address to the uGuru for the next read/write - cycle. This function gets called as the first part of a read/write by - abituguru_read and abituguru_write. This function should never be - called by any other function. */ +/* + * Send the bank and then sensor address to the uGuru for the next read/write + * cycle. This function gets called as the first part of a read/write by + * abituguru_read and abituguru_write. This function should never be + * called by any other function. + */ static int abituguru_send_address(struct abituguru_data *data, u8 bank_addr, u8 sensor_addr, int retries) { - /* assume the caller does error handling itself if it has not requested - any retries, and thus be quiet. */ + /* + * assume the caller does error handling itself if it has not requested + * any retries, and thus be quiet. + */ int report_errors = retries; for (;;) { - /* Make sure the uguru is ready and then send the bank address, - after this the uguru is no longer "ready". */ + /* + * Make sure the uguru is ready and then send the bank address, + * after this the uguru is no longer "ready". + */ if (abituguru_ready(data) != 0) return -EIO; outb(bank_addr, data->addr + ABIT_UGURU_DATA); data->uguru_ready = 0; - /* Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again - and send the sensor addr */ + /* + * Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again + * and send the sensor addr + */ if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) { if (retries) { ABIT_UGURU_DEBUG(3, "timeout exceeded " @@ -332,8 +378,10 @@ static int abituguru_send_address(struct abituguru_data *data, } } -/* Read count bytes from sensor sensor_addr in bank bank_addr and store the - result in buf, retry the send address part of the read retries times. */ +/* + * Read count bytes from sensor sensor_addr in bank bank_addr and store the + * result in buf, retry the send address part of the read retries times. + */ static int abituguru_read(struct abituguru_data *data, u8 bank_addr, u8 sensor_addr, u8 *buf, int count, int retries) { @@ -362,13 +410,17 @@ static int abituguru_read(struct abituguru_data *data, return i; } -/* Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send - address part of the write is always retried ABIT_UGURU_MAX_RETRIES times. */ +/* + * Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send + * address part of the write is always retried ABIT_UGURU_MAX_RETRIES times. + */ static int abituguru_write(struct abituguru_data *data, u8 bank_addr, u8 sensor_addr, u8 *buf, int count) { - /* We use the ready timeout as we have to wait for 0xAC just like the - ready function */ + /* + * We use the ready timeout as we have to wait for 0xAC just like the + * ready function + */ int i, timeout = ABIT_UGURU_READY_TIMEOUT; /* Send the address */ @@ -388,9 +440,11 @@ static int abituguru_write(struct abituguru_data *data, outb(buf[i], data->addr + ABIT_UGURU_CMD); } - /* Now we need to wait till the chip is ready to be read again, - so that we can read 0xAC as confirmation that our write has - succeeded. */ + /* + * Now we need to wait till the chip is ready to be read again, + * so that we can read 0xAC as confirmation that our write has + * succeeded. + */ if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state " "after write (bank: %d, sensor: %d)\n", (int)bank_addr, @@ -416,12 +470,14 @@ static int abituguru_write(struct abituguru_data *data, return i; } -/* Detect sensor type. Temp and Volt sensors are enabled with - different masks and will ignore enable masks not meant for them. - This enables us to test what kind of sensor we're dealing with. - By setting the alarm thresholds so that we will always get an - alarm for sensor type X and then enabling the sensor as sensor type - X, if we then get an alarm it is a sensor of type X. */ +/* + * Detect sensor type. Temp and Volt sensors are enabled with + * different masks and will ignore enable masks not meant for them. + * This enables us to test what kind of sensor we're dealing with. + * By setting the alarm thresholds so that we will always get an + * alarm for sensor type X and then enabling the sensor as sensor type + * X, if we then get an alarm it is a sensor of type X. + */ static int __devinit abituguru_detect_bank1_sensor_type(struct abituguru_data *data, u8 sensor_addr) @@ -448,16 +504,20 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, pr_warn("bank1-sensor: %d reading (%d) too close to limits, " "unable to determine sensor type, skipping sensor\n", (int)sensor_addr, (int)val); - /* assume no sensor is there for sensors for which we can't - determine the sensor type because their reading is too close - to their limits, this usually means no sensor is there. */ + /* + * assume no sensor is there for sensors for which we can't + * determine the sensor type because their reading is too close + * to their limits, this usually means no sensor is there. + */ return ABIT_UGURU_NC; } ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); - /* Volt sensor test, enable volt low alarm, set min value ridicously - high, or vica versa if the reading is very high. If its a volt - sensor this should always give us an alarm. */ + /* + * Volt sensor test, enable volt low alarm, set min value ridicously + * high, or vica versa if the reading is very high. If its a volt + * sensor this should always give us an alarm. + */ if (val <= 240u) { buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; buf[1] = 245; @@ -473,8 +533,10 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, buf, 3) != 3) goto abituguru_detect_bank1_sensor_type_exit; - /* Now we need 20 ms to give the uguru time to read the sensors - and raise a voltage alarm */ + /* + * Now we need 20 ms to give the uguru time to read the sensors + * and raise a voltage alarm + */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/50); /* Check for alarm and check the alarm is a volt low alarm. */ @@ -497,17 +559,21 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " "test\n"); - /* Temp sensor test, enable sensor as a temp sensor, set beep value - ridicously low (but not too low, otherwise uguru ignores it). - If its a temp sensor this should always give us an alarm. */ + /* + * Temp sensor test, enable sensor as a temp sensor, set beep value + * ridicously low (but not too low, otherwise uguru ignores it). + * If its a temp sensor this should always give us an alarm. + */ buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE; buf[1] = 5; buf[2] = 10; if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, buf, 3) != 3) goto abituguru_detect_bank1_sensor_type_exit; - /* Now we need 50 ms to give the uguru time to read the sensors - and raise a temp alarm */ + /* + * Now we need 50 ms to give the uguru time to read the sensors + * and raise a temp alarm + */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); /* Check for alarm and check the alarm is a temp high alarm. */ @@ -532,9 +598,11 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, ret = ABIT_UGURU_NC; abituguru_detect_bank1_sensor_type_exit: - /* Restore original settings, failing here is really BAD, it has been - reported that some BIOS-es hang when entering the uGuru menu with - invalid settings present in the uGuru, so we try this 3 times. */ + /* + * Restore original settings, failing here is really BAD, it has been + * reported that some BIOS-es hang when entering the uGuru menu with + * invalid settings present in the uGuru, so we try this 3 times. + */ for (i = 0; i < 3; i++) if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, data->bank1_settings[sensor_addr], @@ -548,23 +616,25 @@ abituguru_detect_bank1_sensor_type_exit: return ret; } -/* These functions try to find out how many sensors there are in bank2 and how - many pwms there are. The purpose of this is to make sure that we don't give - the user the possibility to change settings for non-existent sensors / pwm. - The uGuru will happily read / write whatever memory happens to be after the - memory storing the PWM settings when reading/writing to a PWM which is not - there. Notice even if we detect a PWM which doesn't exist we normally won't - write to it, unless the user tries to change the settings. - - Although the uGuru allows reading (settings) from non existing bank2 - sensors, my version of the uGuru does seem to stop writing to them, the - write function above aborts in this case with: - "CMD reg does not hold 0xAC after write" - - Notice these 2 tests are non destructive iow read-only tests, otherwise - they would defeat their purpose. Although for the bank2_sensors detection a - read/write test would be feasible because of the reaction above, I've - however opted to stay on the safe side. */ +/* + * These functions try to find out how many sensors there are in bank2 and how + * many pwms there are. The purpose of this is to make sure that we don't give + * the user the possibility to change settings for non-existent sensors / pwm. + * The uGuru will happily read / write whatever memory happens to be after the + * memory storing the PWM settings when reading/writing to a PWM which is not + * there. Notice even if we detect a PWM which doesn't exist we normally won't + * write to it, unless the user tries to change the settings. + * + * Although the uGuru allows reading (settings) from non existing bank2 + * sensors, my version of the uGuru does seem to stop writing to them, the + * write function above aborts in this case with: + * "CMD reg does not hold 0xAC after write" + * + * Notice these 2 tests are non destructive iow read-only tests, otherwise + * they would defeat their purpose. Although for the bank2_sensors detection a + * read/write test would be feasible because of the reaction above, I've + * however opted to stay on the safe side. + */ static void __devinit abituguru_detect_no_bank2_sensors(struct abituguru_data *data) { @@ -580,12 +650,14 @@ abituguru_detect_no_bank2_sensors(struct abituguru_data *data) ABIT_UGURU_DEBUG(2, "detecting number of fan sensors\n"); for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { - /* 0x89 are the known used bits: - -0x80 enable shutdown - -0x08 enable beep - -0x01 enable alarm - All other bits should be 0, but on some motherboards - 0x40 (bit 6) is also high for some of the fans?? */ + /* + * 0x89 are the known used bits: + * -0x80 enable shutdown + * -0x08 enable beep + * -0x01 enable alarm + * All other bits should be 0, but on some motherboards + * 0x40 (bit 6) is also high for some of the fans?? + */ if (data->bank2_settings[i][0] & ~0xC9) { ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " "to be a fan sensor: settings[0] = %02X\n", @@ -633,9 +705,11 @@ abituguru_detect_no_pwms(struct abituguru_data *data) ABIT_UGURU_DEBUG(2, "detecting number of PWM outputs\n"); for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { - /* 0x80 is the enable bit and the low - nibble is which temp sensor to use, - the other bits should be 0 */ + /* + * 0x80 is the enable bit and the low + * nibble is which temp sensor to use, + * the other bits should be 0 + */ if (data->pwm_settings[i][0] & ~0x8F) { ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " "to be a pwm channel: settings[0] = %02X\n", @@ -643,8 +717,10 @@ abituguru_detect_no_pwms(struct abituguru_data *data) break; } - /* the low nibble must correspond to one of the temp sensors - we've found */ + /* + * the low nibble must correspond to one of the temp sensors + * we've found + */ for (j = 0; j < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; j++) { if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][j] == @@ -711,9 +787,11 @@ abituguru_detect_no_pwms_exit: ABIT_UGURU_DEBUG(2, " found: %d PWM outputs\n", (int)data->pwms); } -/* Following are the sysfs callback functions. These functions expect: - sensor_device_attribute_2->index: sensor address/offset in the bank - sensor_device_attribute_2->nr: register offset, bitmask or NA. */ +/* + * Following are the sysfs callback functions. These functions expect: + * sensor_device_attribute_2->index: sensor address/offset in the bank + * sensor_device_attribute_2->nr: register offset, bitmask or NA. + */ static struct abituguru_data *abituguru_update_device(struct device *dev); static ssize_t show_bank1_value(struct device *dev, @@ -763,10 +841,18 @@ static ssize_t store_bank1_setting(struct device *dev, struct device_attribute { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - u8 val = (simple_strtoul(buf, NULL, 10) * 255 + - data->bank1_max_value[attr->index]/2) / + unsigned long val; + ssize_t ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + ret = count; + val = (val * 255 + data->bank1_max_value[attr->index] / 2) / data->bank1_max_value[attr->index]; - ssize_t ret = count; + if (val > 255) + return -EINVAL; mutex_lock(&data->update_lock); if (data->bank1_settings[attr->index][attr->nr] != val) { @@ -788,13 +874,19 @@ static ssize_t store_bank2_setting(struct device *dev, struct device_attribute { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - u8 val = (simple_strtoul(buf, NULL, 10)*255 + ABIT_UGURU_FAN_MAX/2) / - ABIT_UGURU_FAN_MAX; - ssize_t ret = count; + unsigned long val; + ssize_t ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + ret = count; + val = (val * 255 + ABIT_UGURU_FAN_MAX / 2) / ABIT_UGURU_FAN_MAX; /* this check can be done before taking the lock */ - if ((val < abituguru_bank2_min_threshold) || - (val > abituguru_bank2_max_threshold)) + if (val < abituguru_bank2_min_threshold || + val > abituguru_bank2_max_threshold) return -EINVAL; mutex_lock(&data->update_lock); @@ -819,11 +911,13 @@ static ssize_t show_bank1_alarm(struct device *dev, struct abituguru_data *data = abituguru_update_device(dev); if (!data) return -EIO; - /* See if the alarm bit for this sensor is set, and if the - alarm matches the type of alarm we're looking for (for volt - it can be either low or high). The type is stored in a few - readonly bits in the settings part of the relevant sensor. - The bitmask of the type is passed to us in attr->nr. */ + /* + * See if the alarm bit for this sensor is set, and if the + * alarm matches the type of alarm we're looking for (for volt + * it can be either low or high). The type is stored in a few + * readonly bits in the settings part of the relevant sensor. + * The bitmask of the type is passed to us in attr->nr. + */ if ((data->alarms[attr->index / 8] & (0x01 << (attr->index % 8))) && (data->bank1_settings[attr->index][0] & attr->nr)) return sprintf(buf, "1\n"); @@ -871,10 +965,15 @@ static ssize_t store_bank1_mask(struct device *dev, { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - int mask = simple_strtoul(buf, NULL, 10); - ssize_t ret = count; + ssize_t ret; u8 orig_val; + unsigned long mask; + + ret = kstrtoul(buf, 10, &mask); + if (ret) + return ret; + ret = count; mutex_lock(&data->update_lock); orig_val = data->bank1_settings[attr->index][0]; @@ -899,10 +998,15 @@ static ssize_t store_bank2_mask(struct device *dev, { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - int mask = simple_strtoul(buf, NULL, 10); - ssize_t ret = count; + ssize_t ret; u8 orig_val; + unsigned long mask; + ret = kstrtoul(buf, 10, &mask); + if (ret) + return ret; + + ret = count; mutex_lock(&data->update_lock); orig_val = data->bank2_settings[attr->index][0]; @@ -937,10 +1041,17 @@ static ssize_t store_pwm_setting(struct device *dev, struct device_attribute { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - u8 min, val = (simple_strtoul(buf, NULL, 10) + - abituguru_pwm_settings_multiplier[attr->nr]/2) / - abituguru_pwm_settings_multiplier[attr->nr]; - ssize_t ret = count; + u8 min; + unsigned long val; + ssize_t ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + ret = count; + val = (val + abituguru_pwm_settings_multiplier[attr->nr] / 2) / + abituguru_pwm_settings_multiplier[attr->nr]; /* special case pwm1 min pwm% */ if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2))) @@ -949,7 +1060,7 @@ static ssize_t store_pwm_setting(struct device *dev, struct device_attribute min = abituguru_pwm_min[attr->nr]; /* this check can be done before taking the lock */ - if ((val < min) || (val > abituguru_pwm_max[attr->nr])) + if (val < min || val > abituguru_pwm_max[attr->nr]) return -EINVAL; mutex_lock(&data->update_lock); @@ -981,8 +1092,10 @@ static ssize_t show_pwm_sensor(struct device *dev, struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); int i; - /* We need to walk to the temp sensor addresses to find what - the userspace id of the configured temp sensor is. */ + /* + * We need to walk to the temp sensor addresses to find what + * the userspace id of the configured temp sensor is. + */ for (i = 0; i < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; i++) if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][i] == (data->pwm_settings[attr->index][0] & 0x0F)) @@ -996,27 +1109,32 @@ static ssize_t store_pwm_sensor(struct device *dev, struct device_attribute { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10) - 1; - ssize_t ret = count; + ssize_t ret; + unsigned long val; + u8 orig_val; + u8 address; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + if (val == 0 || val > data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) + return -EINVAL; + + val -= 1; + ret = count; mutex_lock(&data->update_lock); - if (val < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) { - u8 orig_val = data->pwm_settings[attr->index][0]; - u8 address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val]; - data->pwm_settings[attr->index][0] &= 0xF0; - data->pwm_settings[attr->index][0] |= address; - if (data->pwm_settings[attr->index][0] != orig_val) { - if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, - attr->index, - data->pwm_settings[attr->index], - 5) < 1) { - data->pwm_settings[attr->index][0] = orig_val; - ret = -EIO; - } + orig_val = data->pwm_settings[attr->index][0]; + address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val]; + data->pwm_settings[attr->index][0] &= 0xF0; + data->pwm_settings[attr->index][0] |= address; + if (data->pwm_settings[attr->index][0] != orig_val) { + if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, attr->index, + data->pwm_settings[attr->index], 5) < 1) { + data->pwm_settings[attr->index][0] = orig_val; + ret = -EIO; } } - else - ret = -EINVAL; mutex_unlock(&data->update_lock); return ret; } @@ -1037,22 +1155,27 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); - u8 orig_val, user_val = simple_strtoul(buf, NULL, 10); - ssize_t ret = count; + u8 orig_val; + ssize_t ret; + unsigned long user_val; + + ret = kstrtoul(buf, 10, &user_val); + if (ret) + return ret; + ret = count; mutex_lock(&data->update_lock); orig_val = data->pwm_settings[attr->index][0]; switch (user_val) { - case 0: - data->pwm_settings[attr->index][0] &= - ~ABIT_UGURU_FAN_PWM_ENABLE; - break; - case 2: - data->pwm_settings[attr->index][0] |= - ABIT_UGURU_FAN_PWM_ENABLE; - break; - default: - ret = -EINVAL; + case 0: + data->pwm_settings[attr->index][0] &= + ~ABIT_UGURU_FAN_PWM_ENABLE; + break; + case 2: + data->pwm_settings[attr->index][0] |= ABIT_UGURU_FAN_PWM_ENABLE; + break; + default: + ret = -EINVAL; } if ((data->pwm_settings[attr->index][0] != orig_val) && (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, @@ -1147,13 +1270,16 @@ static int __devinit abituguru_probe(struct platform_device *pdev) int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV; char *sysfs_filename; - /* El weirdo probe order, to keep the sysfs order identical to the - BIOS and window-appliction listing order. */ + /* + * El weirdo probe order, to keep the sysfs order identical to the + * BIOS and window-appliction listing order. + */ const u8 probe_order[ABIT_UGURU_MAX_BANK1_SENSORS] = { 0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02, 0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C }; - if (!(data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL))) + data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL); + if (!data) return -ENOMEM; data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; @@ -1164,9 +1290,11 @@ static int __devinit abituguru_probe(struct platform_device *pdev) if (inb_p(data->addr + ABIT_UGURU_DATA) == ABIT_UGURU_STATUS_INPUT) data->uguru_ready = 1; - /* Completely read the uGuru this has 2 purposes: - - testread / see if one really is there. - - make an in memory copy of all the uguru settings for future use. */ + /* + * Completely read the uGuru this has 2 purposes: + * - testread / see if one really is there. + * - make an in memory copy of all the uguru settings for future use. + */ if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3) goto abituguru_probe_error; @@ -1181,11 +1309,13 @@ static int __devinit abituguru_probe(struct platform_device *pdev) ABIT_UGURU_MAX_RETRIES) != 3) goto abituguru_probe_error; } - /* Note: We don't know how many bank2 sensors / pwms there really are, - but in order to "detect" this we need to read the maximum amount - anyways. If we read sensors/pwms not there we'll just read crap - this can't hurt. We need the detection because we don't want - unwanted writes, which will hurt! */ + /* + * Note: We don't know how many bank2 sensors / pwms there really are, + * but in order to "detect" this we need to read the maximum amount + * anyways. If we read sensors/pwms not there we'll just read crap + * this can't hurt. We need the detection because we don't want + * unwanted writes, which will hurt! + */ for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i, &data->bank2_value[i], 1, @@ -1332,24 +1462,26 @@ static struct abituguru_data *abituguru_update_device(struct device *dev) mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ)) { success = 0; - if ((err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, - data->alarms, 3, 0)) != 3) + err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, + data->alarms, 3, 0); + if (err != 3) goto LEAVE_UPDATE; for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { - if ((err = abituguru_read(data, - ABIT_UGURU_SENSOR_BANK1, i, - &data->bank1_value[i], 1, 0)) != 1) + err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, + i, &data->bank1_value[i], 1, 0); + if (err != 1) goto LEAVE_UPDATE; - if ((err = abituguru_read(data, - ABIT_UGURU_SENSOR_BANK1 + 1, i, - data->bank1_settings[i], 3, 0)) != 3) + err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, + i, data->bank1_settings[i], 3, 0); + if (err != 3) goto LEAVE_UPDATE; } - for (i = 0; i < data->bank2_sensors; i++) - if ((err = abituguru_read(data, - ABIT_UGURU_SENSOR_BANK2, i, - &data->bank2_value[i], 1, 0)) != 1) + for (i = 0; i < data->bank2_sensors; i++) { + err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i, + &data->bank2_value[i], 1, 0); + if (err != 1) goto LEAVE_UPDATE; + } /* success! */ success = 1; data->update_timeouts = 0; @@ -1385,8 +1517,10 @@ LEAVE_UPDATE: static int abituguru_suspend(struct platform_device *pdev, pm_message_t state) { struct abituguru_data *data = platform_get_drvdata(pdev); - /* make sure all communications with the uguru are done and no new - ones are started */ + /* + * make sure all communications with the uguru are done and no new + * ones are started + */ mutex_lock(&data->update_lock); return 0; } @@ -1418,12 +1552,14 @@ static struct platform_driver abituguru_driver = { static int __init abituguru_detect(void) { - /* See if there is an uguru there. After a reboot uGuru will hold 0x00 - at DATA and 0xAC, when this driver has already been loaded once - DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either - scenario but some will hold 0x00. - Some uGuru's initially hold 0x09 at DATA and will only hold 0x08 - after reading CMD first, so CMD must be read first! */ + /* + * See if there is an uguru there. After a reboot uGuru will hold 0x00 + * at DATA and 0xAC, when this driver has already been loaded once + * DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either + * scenario but some will hold 0x00. + * Some uGuru's initially hold 0x09 at DATA and will only hold 0x08 + * after reading CMD first, so CMD must be read first! + */ u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD); u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA); if (((data_val == 0x00) || (data_val == 0x08)) && diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 34a14a77e008..a5bc4287daa6 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -1,28 +1,28 @@ /* - abituguru3.c - - Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com> - Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk> - - 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. -*/ + * abituguru3.c + * + * Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com> + * Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk> + * + * 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. + */ /* - This driver supports the sensor part of revision 3 of the custom Abit uGuru - chip found on newer Abit uGuru motherboards. Note: because of lack of specs - only reading the sensors and their settings is supported. -*/ + * This driver supports the sensor part of revision 3 of the custom Abit uGuru + * chip found on newer Abit uGuru motherboards. Note: because of lack of specs + * only reading the sensors and their settings is supported. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -62,13 +62,17 @@ #define ABIT_UGURU3_TEMP_SENSOR 1 #define ABIT_UGURU3_FAN_SENSOR 2 -/* Timeouts / Retries, if these turn out to need a lot of fiddling we could - convert them to params. Determined by trial and error. I assume this is - cpu-speed independent, since the ISA-bus and not the CPU should be the - bottleneck. */ +/* + * Timeouts / Retries, if these turn out to need a lot of fiddling we could + * convert them to params. Determined by trial and error. I assume this is + * cpu-speed independent, since the ISA-bus and not the CPU should be the + * bottleneck. + */ #define ABIT_UGURU3_WAIT_TIMEOUT 250 -/* Normally the 0xAC at the end of synchronize() is reported after the - first read, but sometimes not and we need to poll */ +/* + * Normally the 0xAC at the end of synchronize() is reported after the + * first read, but sometimes not and we need to poll + */ #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5 /* utility macros */ #define ABIT_UGURU3_NAME "abituguru3" @@ -78,32 +82,45 @@ /* Macros to help calculate the sysfs_names array length */ #define ABIT_UGURU3_MAX_NO_SENSORS 26 -/* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, - in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 */ -#define ABIT_UGURU3_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11) -/* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0, - temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0, - temp??_label\0 */ +/* + * sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, + * in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 + */ +#define ABIT_UGURU3_IN_NAMES_LENGTH \ + (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11) +/* + * sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0, + * temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0, + * temp??_label\0 + */ #define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13) -/* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0, - fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 */ +/* + * sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0, + * fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 + */ #define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12) -/* Worst case scenario 16 in sensors (longest names_length) and the rest - temp sensors (second longest names_length). */ +/* + * Worst case scenario 16 in sensors (longest names_length) and the rest + * temp sensors (second longest names_length). + */ #define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \ (ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH) -/* All the macros below are named identical to the openguru2 program - reverse engineered by Louis Kruger, hence the names might not be 100% - logical. I could come up with better names, but I prefer keeping the names - identical so that this driver can be compared with his work more easily. */ +/* + * All the macros below are named identical to the openguru2 program + * reverse engineered by Louis Kruger, hence the names might not be 100% + * logical. I could come up with better names, but I prefer keeping the names + * identical so that this driver can be compared with his work more easily. + */ /* Two i/o-ports are used by uGuru */ #define ABIT_UGURU3_BASE 0x00E0 #define ABIT_UGURU3_CMD 0x00 #define ABIT_UGURU3_DATA 0x04 #define ABIT_UGURU3_REGION_LENGTH 5 -/* The wait_xxx functions return this on success and the last contents - of the DATA register (0-255) on failure. */ +/* + * The wait_xxx functions return this on success and the last contents + * of the DATA register (0-255) on failure. + */ #define ABIT_UGURU3_SUCCESS -1 /* uGuru status flags */ #define ABIT_UGURU3_STATUS_READY_FOR_READ 0x01 @@ -112,7 +129,7 @@ /* Structures */ struct abituguru3_sensor_info { - const char* name; + const char *name; int port; int type; int multiplier; @@ -130,9 +147,11 @@ struct abituguru3_motherboard_info { struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; }; -/* For the Abit uGuru, we need to keep some data in memory. - The structure is dynamically allocated, at the same time when a new - abituguru3 device is allocated. */ +/* + * For the Abit uGuru, we need to keep some data in memory. + * The structure is dynamically allocated, at the same time when a new + * abituguru3 device is allocated. + */ struct abituguru3_data { struct device *hwmon_dev; /* hwmon registered device */ struct mutex update_lock; /* protect access to data and uGuru */ @@ -140,8 +159,10 @@ struct abituguru3_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ - /* For convenience the sysfs attr and their names are generated - automatically. We have max 10 entries per sensor (for in sensors) */ + /* + * For convenience the sysfs attr and their names are generated + * automatically. We have max 10 entries per sensor (for in sensors) + */ struct sensor_device_attribute_2 sysfs_attr[ABIT_UGURU3_MAX_NO_SENSORS * 10]; @@ -151,9 +172,11 @@ struct abituguru3_data { /* Pointer to the sensors info for the detected motherboard */ const struct abituguru3_sensor_info *sensors; - /* The abituguru3 supports up to 48 sensors, and thus has registers - sets for 48 sensors, for convienence reasons / simplicity of the - code we always read and store all registers for all 48 sensors */ + /* + * The abituguru3 supports up to 48 sensors, and thus has registers + * sets for 48 sensors, for convienence reasons / simplicity of the + * code we always read and store all registers for all 48 sensors + */ /* Alarms for all 48 sensors (1 bit per sensor) */ u8 alarms[48/8]; @@ -161,9 +184,11 @@ struct abituguru3_data { /* Value of all 48 sensors */ u8 value[48]; - /* Settings of all 48 sensors, note in and temp sensors (the first 32 - sensors) have 3 bytes of settings, while fans only have 2 bytes, - for convenience we use 3 bytes for all sensors */ + /* + * Settings of all 48 sensors, note in and temp sensors (the first 32 + * sensors) have 3 bytes of settings, while fans only have 2 bytes, + * for convenience we use 3 bytes for all sensors + */ u8 settings[48][3]; }; @@ -626,8 +651,10 @@ static int abituguru3_wait_while_busy(struct abituguru3_data *data) timeout--; if (timeout == 0) return x; - /* sleep a bit before our last try, to give the uGuru3 one - last chance to respond. */ + /* + * sleep a bit before our last try, to give the uGuru3 one + * last chance to respond. + */ if (timeout == 1) msleep(1); } @@ -645,48 +672,57 @@ static int abituguru3_wait_for_read(struct abituguru3_data *data) timeout--; if (timeout == 0) return x; - /* sleep a bit before our last try, to give the uGuru3 one - last chance to respond. */ + /* + * sleep a bit before our last try, to give the uGuru3 one + * last chance to respond. + */ if (timeout == 1) msleep(1); } return ABIT_UGURU3_SUCCESS; } -/* This synchronizes us with the uGuru3's protocol state machine, this - must be done before each command. */ +/* + * This synchronizes us with the uGuru3's protocol state machine, this + * must be done before each command. + */ static int abituguru3_synchronize(struct abituguru3_data *data) { int x, timeout = ABIT_UGURU3_SYNCHRONIZE_TIMEOUT; - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("synchronize timeout during initial busy " "wait, status: 0x%02x\n", x); return -EIO; } outb(0x20, data->addr + ABIT_UGURU3_DATA); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x20, " "status: 0x%02x\n", x); return -EIO; } outb(0x10, data->addr + ABIT_UGURU3_CMD); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x10, " "status: 0x%02x\n", x); return -EIO; } outb(0x00, data->addr + ABIT_UGURU3_CMD); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x00, " "status: 0x%02x\n", x); return -EIO; } - if ((x = abituguru3_wait_for_read(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_for_read(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("synchronize timeout waiting for read, " "status: 0x%02x\n", x); return -EIO; @@ -705,18 +741,22 @@ static int abituguru3_synchronize(struct abituguru3_data *data) return 0; } -/* Read count bytes from sensor sensor_addr in bank bank_addr and store the - result in buf */ +/* + * Read count bytes from sensor sensor_addr in bank bank_addr and store the + * result in buf + */ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, u8 count, u8 *buf) { int i, x; - if ((x = abituguru3_synchronize(data))) + x = abituguru3_synchronize(data); + if (x) return x; outb(0x1A, data->addr + ABIT_UGURU3_DATA); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " "sending 0x1A, status: 0x%02x\n", (unsigned int)bank, (unsigned int)offset, x); @@ -724,7 +764,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, } outb(bank, data->addr + ABIT_UGURU3_CMD); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " "sending the bank, status: 0x%02x\n", (unsigned int)bank, (unsigned int)offset, x); @@ -732,7 +773,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, } outb(offset, data->addr + ABIT_UGURU3_CMD); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " "sending the offset, status: 0x%02x\n", (unsigned int)bank, (unsigned int)offset, x); @@ -740,7 +782,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, } outb(count, data->addr + ABIT_UGURU3_CMD); - if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_while_busy(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " "sending the count, status: 0x%02x\n", (unsigned int)bank, (unsigned int)offset, x); @@ -748,8 +791,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, } for (i = 0; i < count; i++) { - if ((x = abituguru3_wait_for_read(data)) != - ABIT_UGURU3_SUCCESS) { + x = abituguru3_wait_for_read(data); + if (x != ABIT_UGURU3_SUCCESS) { ABIT_UGURU3_DEBUG("timeout reading byte %d from " "0x%02x:0x%02x, status: 0x%02x\n", i, (unsigned int)bank, (unsigned int)offset, x); @@ -760,28 +803,34 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, return i; } -/* Sensor settings are stored 1 byte per offset with the bytes - placed add consecutive offsets. */ +/* + * Sensor settings are stored 1 byte per offset with the bytes + * placed add consecutive offsets. + */ static int abituguru3_read_increment_offset(struct abituguru3_data *data, u8 bank, u8 offset, u8 count, u8 *buf, int offset_count) { int i, x; - for (i = 0; i < offset_count; i++) - if ((x = abituguru3_read(data, bank, offset + i, count, - buf + i * count)) != count) { + for (i = 0; i < offset_count; i++) { + x = abituguru3_read(data, bank, offset + i, count, + buf + i * count); + if (x != count) { if (x < 0) return x; return i * count + x; } + } return i * count; } -/* Following are the sysfs callback functions. These functions expect: - sensor_device_attribute_2->index: index into the data->sensors array - sensor_device_attribute_2->nr: register offset, bitmask or NA. */ +/* + * Following are the sysfs callback functions. These functions expect: + * sensor_device_attribute_2->index: index into the data->sensors array + * sensor_device_attribute_2->nr: register offset, bitmask or NA. + */ static struct abituguru3_data *abituguru3_update_device(struct device *dev); static ssize_t show_value(struct device *dev, @@ -807,8 +856,10 @@ static ssize_t show_value(struct device *dev, value = (value * sensor->multiplier) / sensor->divisor + sensor->offset; - /* alternatively we could update the sensors settings struct for this, - but then its contents would differ from the windows sw ini files */ + /* + * alternatively we could update the sensors settings struct for this, + * but then its contents would differ from the windows sw ini files + */ if (sensor->type == ABIT_UGURU3_TEMP_SENSOR) value *= 1000; @@ -827,10 +878,12 @@ static ssize_t show_alarm(struct device *dev, port = data->sensors[attr->index].port; - /* See if the alarm bit for this sensor is set and if a bitmask is - given in attr->nr also check if the alarm matches the type of alarm - we're looking for (for volt it can be either low or high). The type - is stored in a few readonly bits in the settings of the sensor. */ + /* + * See if the alarm bit for this sensor is set and if a bitmask is + * given in attr->nr also check if the alarm matches the type of alarm + * we're looking for (for volt it can be either low or high). The type + * is stored in a few readonly bits in the settings of the sensor. + */ if ((data->alarms[port / 8] & (0x01 << (port % 8))) && (!attr->nr || (data->settings[port][0] & attr->nr))) return sprintf(buf, "1\n"); @@ -923,7 +976,8 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) u8 buf[2]; u16 id; - if (!(data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL))) + data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL); + if (!data) return -ENOMEM; data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; @@ -931,10 +985,10 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); /* Read the motherboard ID */ - if ((i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK, - ABIT_UGURU3_BOARD_ID, 2, buf)) != 2) { + i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK, ABIT_UGURU3_BOARD_ID, + 2, buf); + if (i != 2) goto abituguru3_probe_error; - } /* Completely read the uGuru to see if one really is there */ if (!abituguru3_update_device(&pdev->dev)) @@ -1091,8 +1145,10 @@ LEAVE_UPDATE: static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state) { struct abituguru3_data *data = platform_get_drvdata(pdev); - /* make sure all communications with the uguru3 are done and no new - ones are started */ + /* + * make sure all communications with the uguru3 are done and no new + * ones are started + */ mutex_lock(&data->update_lock); return 0; } @@ -1134,7 +1190,8 @@ static int __init abituguru3_dmi_detect(void) if (!board_name) return err; - /* At the moment, we don't care about the part of the vendor + /* + * At the moment, we don't care about the part of the vendor * DMI string contained in brackets. Truncate the string at * the first occurrence of a bracket. Trim any trailing space * from the substring. @@ -1157,15 +1214,18 @@ static int __init abituguru3_dmi_detect(void) return 1; } -/* FIXME: Manual detection should die eventually; we need to collect stable +/* + * FIXME: Manual detection should die eventually; we need to collect stable * DMI model names first before we can rely entirely on CONFIG_DMI. */ static int __init abituguru3_detect(void) { - /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or - 0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05 - or 0x55 at CMD instead, why is unknown. */ + /* + * See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or + * 0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05 + * or 0x55 at CMD instead, why is unknown. + */ u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA); u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD); if (((data_val == 0x00) || (data_val == 0x08)) && @@ -1197,7 +1257,8 @@ static int __init abituguru3_init(void) if (err < 0) return err; - /* Fall back to manual detection if there was no exact + /* + * Fall back to manual detection if there was no exact * board name match, or force was specified. */ if (err > 0) { diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index 5d760f3d21c2..0e0cfcc36f8d 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -167,17 +167,7 @@ static struct spi_driver ad7314_driver = { .id_table = ad7314_id, }; -static __init int ad7314_init(void) -{ - return spi_register_driver(&ad7314_driver); -} -module_init(ad7314_init); - -static __exit void ad7314_exit(void) -{ - spi_unregister_driver(&ad7314_driver); -} -module_exit(ad7314_exit); +module_spi_driver(ad7314_driver); MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital" diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index df29a7fff9e7..06d2d60d1fd0 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c @@ -50,7 +50,8 @@ struct ad7414_data { /* REG: (0.25C/bit, two's complement) << 6 */ static inline int ad7414_temp_from_reg(s16 reg) { - /* use integer division instead of equivalent right shift to + /* + * use integer division instead of equivalent right shift to * guarantee arithmetic shift and preserve the sign */ return ((int)reg / 64) * 250; @@ -130,7 +131,11 @@ static ssize_t set_max_min(struct device *dev, struct ad7414_data *data = i2c_get_clientdata(client); int index = to_sensor_dev_attr(attr)->index; u8 reg = AD7414_REG_LIMIT[index]; - long temp = simple_strtol(buf, NULL, 10); + long temp; + int ret = kstrtol(buf, 10, &temp); + + if (ret < 0) + return ret; temp = SENSORS_LIMIT(temp, -40000, 85000); temp = (temp + (temp < 0 ? -500 : 500)) / 1000; @@ -252,17 +257,7 @@ static struct i2c_driver ad7414_driver = { .id_table = ad7414_id, }; -static int __init ad7414_init(void) -{ - return i2c_add_driver(&ad7414_driver); -} -module_init(ad7414_init); - -static void __exit ad7414_exit(void) -{ - i2c_del_driver(&ad7414_driver); -} -module_exit(ad7414_exit); +module_i2c_driver(ad7414_driver); MODULE_AUTHOR("Stefan Roese <sr at denx.de>, " "Frank Edelhaeuser <frank.edelhaeuser at spansion.com>"); diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index 8cb718ce8237..a50a6bef16c4 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c @@ -167,7 +167,11 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct ad7418_data *data = i2c_get_clientdata(client); - long temp = simple_strtol(buf, NULL, 10); + long temp; + int ret = kstrtol(buf, 10, &temp); + + if (ret < 0) + return ret; mutex_lock(&data->lock); data->temp[attr->index] = LM75_TEMP_TO_REG(temp); @@ -228,7 +232,8 @@ static int ad7418_probe(struct i2c_client *client, goto exit; } - if (!(data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto exit; } @@ -261,7 +266,8 @@ static int ad7418_probe(struct i2c_client *client, ad7418_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); @@ -289,20 +295,9 @@ static int ad7418_remove(struct i2c_client *client) return 0; } -static int __init ad7418_init(void) -{ - return i2c_add_driver(&ad7418_driver); -} - -static void __exit ad7418_exit(void) -{ - i2c_del_driver(&ad7418_driver); -} +module_i2c_driver(ad7418_driver); MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); MODULE_DESCRIPTION("AD7416/17/18 driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); - -module_init(ad7418_init); -module_exit(ad7418_exit); diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c index ceb24a365176..a3d3183454ad 100644 --- a/drivers/hwmon/adcxx.c +++ b/drivers/hwmon/adcxx.c @@ -248,18 +248,7 @@ static struct spi_driver adcxx_driver = { .remove = __devexit_p(adcxx_remove), }; -static int __init init_adcxx(void) -{ - return spi_register_driver(&adcxx_driver); -} - -static void __exit exit_adcxx(void) -{ - spi_unregister_driver(&adcxx_driver); -} - -module_init(init_adcxx); -module_exit(exit_adcxx); +module_spi_driver(adcxx_driver); MODULE_AUTHOR("Marc Pignat"); MODULE_DESCRIPTION("National Semiconductor adcxx8sxxx Linux driver"); diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 0158cc35cb2e..4394e7e99c46 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -1,23 +1,23 @@ /* - adm1021.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and - Philip Edelbrock <phil@netroedge.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * adm1021.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and + * Philip Edelbrock <phil@netroedge.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #include <linux/module.h> #include <linux/init.h> @@ -70,10 +70,12 @@ enum chips { /* Initial values */ -/* Note: Even though I left the low and high limits named os and hyst, -they don't quite work like a thermostat the way the LM75 does. I.e., -a lower temp than THYST actually triggers an alarm instead of -clearing it. Weird, ey? --Phil */ +/* + * Note: Even though I left the low and high limits named os and hyst, + * they don't quite work like a thermostat the way the LM75 does. I.e., + * a lower temp than THYST actually triggers an alarm instead of + * clearing it. Weird, ey? --Phil + */ /* Each client has this additional data */ struct adm1021_data { @@ -182,7 +184,13 @@ static ssize_t set_temp_max(struct device *dev, int index = to_sensor_dev_attr(devattr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); - long temp = simple_strtol(buf, NULL, 10) / 1000; + long temp; + int err; + + err = kstrtol(buf, 10, &temp); + if (err) + return err; + temp /= 1000; mutex_lock(&data->update_lock); data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127); @@ -201,7 +209,13 @@ static ssize_t set_temp_min(struct device *dev, int index = to_sensor_dev_attr(devattr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); - long temp = simple_strtol(buf, NULL, 10) / 1000; + long temp; + int err; + + err = kstrtol(buf, 10, &temp); + if (err) + return err; + temp /= 1000; mutex_lock(&data->update_lock); data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127); @@ -226,7 +240,14 @@ static ssize_t set_low_power(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); - int low_power = simple_strtol(buf, NULL, 10) != 0; + char low_power; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + low_power = val != 0; mutex_lock(&data->update_lock); if (low_power != data->low_power) { @@ -361,7 +382,8 @@ static int adm1021_probe(struct i2c_client *client, adm1021_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group))) + err = sysfs_create_group(&client->dev.kobj, &adm1021_group); + if (err) goto error1; data->hwmon_dev = hwmon_device_register(&client->dev); @@ -427,8 +449,10 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) data->alarms = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS) & 0x7c; if (data->type == adm1023) { - /* The ADM1023 provides 3 extra bits of precision for - * the remote sensor in extra registers. */ + /* + * The ADM1023 provides 3 extra bits of precision for + * the remote sensor in extra registers. + */ data->temp[1] += 125 * (i2c_smbus_read_byte_data( client, ADM1023_REG_REM_TEMP_PREC) >> 5); data->temp_max[1] += 125 * (i2c_smbus_read_byte_data( @@ -451,23 +475,12 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) return data; } -static int __init sensors_adm1021_init(void) -{ - return i2c_add_driver(&adm1021_driver); -} - -static void __exit sensors_adm1021_exit(void) -{ - i2c_del_driver(&adm1021_driver); -} +module_i2c_driver(adm1021_driver); -MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl> and " +MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " "Philip Edelbrock <phil@netroedge.com>"); MODULE_DESCRIPTION("adm1021 driver"); MODULE_LICENSE("GPL"); module_param(read_only, bool, 0); MODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); - -module_init(sensors_adm1021_init) -module_exit(sensors_adm1021_exit) diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 60befc0ee65f..b8557f9857d2 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -12,7 +12,7 @@ * resolution of about 0.5% of the nominal value). Temperature values are * reported with a 1 deg resolution and a 3 deg accuracy. Complete * datasheet can be obtained from Analog's website at: - * http://www.onsemi.com/PowerSolutions/product.do?id=ADM1025 + * http://www.onsemi.com/PowerSolutions/product.do?id=ADM1025 * * This driver also supports the ADM1025A, which differs from the ADM1025 * only in that it has "open-drain VID inputs while the ADM1025 has @@ -91,15 +91,16 @@ enum chips { adm1025, ne1619 }; static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 }; -#define IN_FROM_REG(reg,scale) (((reg) * (scale) + 96) / 192) -#define IN_TO_REG(val,scale) ((val) <= 0 ? 0 : \ +#define IN_FROM_REG(reg, scale) (((reg) * (scale) + 96) / 192) +#define IN_TO_REG(val, scale) ((val) <= 0 ? 0 : \ (val) * 192 >= (scale) * 255 ? 255 : \ - ((val) * 192 + (scale)/2) / (scale)) + ((val) * 192 + (scale) / 2) / (scale)) #define TEMP_FROM_REG(reg) ((reg) * 1000) #define TEMP_TO_REG(val) ((val) <= -127500 ? -128 : \ (val) >= 126500 ? 127 : \ - (((val) < 0 ? (val)-500 : (val)+500) / 1000)) + (((val) < 0 ? (val) - 500 : \ + (val) + 500) / 1000)) /* * Functions declaration @@ -218,7 +219,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, int index = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1025_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[index] = IN_TO_REG(val, in_scale[index]); @@ -234,7 +240,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, int index = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1025_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[index] = IN_TO_REG(val, in_scale[index]); @@ -264,7 +275,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, int index = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1025_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[index] = TEMP_TO_REG(val); @@ -280,7 +296,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, int index = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1025_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[index] = TEMP_TO_REG(val); @@ -343,7 +364,14 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct adm1025_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + data->vrm = val; return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); @@ -462,14 +490,15 @@ static int adm1025_probe(struct i2c_client *client, adm1025_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &adm1025_group))) + err = sysfs_create_group(&client->dev.kobj, &adm1025_group); + if (err) goto exit_free; /* Pin 11 is either in4 (+12V) or VID4 */ config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG); if (!(config & 0x20)) { - if ((err = sysfs_create_group(&client->dev.kobj, - &adm1025_group_in4))) + err = sysfs_create_group(&client->dev.kobj, &adm1025_group_in4); + if (err) goto exit_remove; } @@ -506,7 +535,7 @@ static void adm1025_init_client(struct i2c_client *client) * setting yet, we better set the high limits to the max so that * no alarm triggers. */ - for (i=0; i<6; i++) { + for (i = 0; i < 6; i++) { reg = i2c_smbus_read_byte_data(client, ADM1025_REG_IN_MAX(i)); if (reg == 0) @@ -514,7 +543,7 @@ static void adm1025_init_client(struct i2c_client *client) ADM1025_REG_IN_MAX(i), 0xFF); } - for (i=0; i<2; i++) { + for (i = 0; i < 2; i++) { reg = i2c_smbus_read_byte_data(client, ADM1025_REG_TEMP_HIGH(i)); if (reg == 0) @@ -555,7 +584,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev) int i; dev_dbg(&client->dev, "Updating data.\n"); - for (i=0; i<6; i++) { + for (i = 0; i < 6; i++) { data->in[i] = i2c_smbus_read_byte_data(client, ADM1025_REG_IN(i)); data->in_min[i] = i2c_smbus_read_byte_data(client, @@ -563,7 +592,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev) data->in_max[i] = i2c_smbus_read_byte_data(client, ADM1025_REG_IN_MAX(i)); } - for (i=0; i<2; i++) { + for (i = 0; i < 2; i++) { data->temp[i] = i2c_smbus_read_byte_data(client, ADM1025_REG_TEMP(i)); data->temp_min[i] = i2c_smbus_read_byte_data(client, @@ -589,19 +618,8 @@ static struct adm1025_data *adm1025_update_device(struct device *dev) return data; } -static int __init sensors_adm1025_init(void) -{ - return i2c_add_driver(&adm1025_driver); -} - -static void __exit sensors_adm1025_exit(void) -{ - i2c_del_driver(&adm1025_driver); -} +module_i2c_driver(adm1025_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("ADM1025 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_adm1025_init); -module_exit(sensors_adm1025_exit); diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 0531867484f4..1003219b9f90 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -1,27 +1,27 @@ /* - adm1026.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (C) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> - Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com> - - Chip details at: - - <http://www.onsemi.com/PowerSolutions/product.do?id=ADM1026> - - 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. -*/ + * adm1026.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> + * Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com> + * + * Chip details at: + * + * <http://www.onsemi.com/PowerSolutions/product.do?id=ADM1026> + * + * 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 <linux/module.h> #include <linux/init.h> @@ -90,7 +90,8 @@ MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs"); #define E2CFG_ROM 0x08 #define E2CFG_CLK_EXT 0x80 -/* There are 10 general analog inputs and 7 dedicated inputs +/* + * There are 10 general analog inputs and 7 dedicated inputs * They are: * 0 - 9 = AIN0 - AIN9 * 10 = Vbat @@ -117,7 +118,8 @@ static u16 ADM1026_REG_IN_MAX[] = { 0x43, 0x44, 0x45, 0x46, 0x47 }; -/* Temperatures are: +/* + * Temperatures are: * 0 - Internal * 1 - External 1 * 2 - External 2 @@ -170,12 +172,14 @@ static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f }; #define ADM1026_FAN_CONTROL_TEMP_RANGE 20 #define ADM1026_PWM_MAX 255 -/* Conversions. Rounding and limit checking is only done on the TO_REG +/* + * Conversions. Rounding and limit checking is only done on the TO_REG * variants. Note that you should be a bit careful with which arguments * these macros are called: arguments may be evaluated more than once. */ -/* IN are scaled according to built-in resistors. These are the +/* + * IN are scaled according to built-in resistors. These are the * voltages corresponding to 3/4 of full scale (192 or 0xc0) * NOTE: The -12V input needs an additional factor to account * for the Vref pullup resistor. @@ -197,23 +201,25 @@ static int adm1026_scaling[] = { /* .001 Volts */ 0, 255)) #define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n])) -/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses +/* + * FAN speed is measured using 22.5kHz clock and counts for 2 pulses * and we assume a 2 pulse-per-rev fan tach signal * 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000 */ #define FAN_TO_REG(val, div) ((val) <= 0 ? 0xff : \ - SENSORS_LIMIT(1350000/((val)*(div)), 1, 254)) -#define FAN_FROM_REG(val, div) ((val) == 0 ? -1:(val) == 0xff ? 0 : \ - 1350000/((val)*(div))) -#define DIV_FROM_REG(val) (1<<(val)) + SENSORS_LIMIT(1350000 / ((val) * (div)), \ + 1, 254)) +#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 0xff ? 0 : \ + 1350000 / ((val) * (div))) +#define DIV_FROM_REG(val) (1 << (val)) #define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0) /* Temperature is reported in 1 degC increments */ -#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\ - -127, 127)) +#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \ + / 1000, -127, 127)) #define TEMP_FROM_REG(val) ((val) * 1000) -#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\ - -127, 127)) +#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \ + / 1000, -127, 127)) #define OFFSET_FROM_REG(val) ((val) * 1000) #define PWM_TO_REG(val) (SENSORS_LIMIT(val, 0, 255)) @@ -222,14 +228,16 @@ static int adm1026_scaling[] = { /* .001 Volts */ #define PWM_MIN_TO_REG(val) ((val) & 0xf0) #define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4)) -/* Analog output is a voltage, and scaled to millivolts. The datasheet +/* + * Analog output is a voltage, and scaled to millivolts. The datasheet * indicates that the DAC could be used to drive the fans, but in our * example board (Arima HDAMA) it isn't connected to the fans at all. */ -#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500), 0, 255)) -#define DAC_FROM_REG(val) (((val)*2500)/255) +#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val) * 255) + 500) / 2500), 0, 255)) +#define DAC_FROM_REG(val) (((val) * 2500) / 255) -/* Chip sampling rates +/* + * Chip sampling rates * * Some sensors are not updated more frequently than once per second * so it doesn't make sense to read them more often than that. @@ -243,11 +251,13 @@ static int adm1026_scaling[] = { /* .001 Volts */ #define ADM1026_DATA_INTERVAL (1 * HZ) #define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ) -/* We allow for multiple chips in a single system. +/* + * We allow for multiple chips in a single system. * * For each registered ADM1026, we need to keep state information * at client->data. The adm1026_data structure is dynamically - * allocated, when a new client structure is allocated. */ + * allocated, when a new client structure is allocated. + */ struct pwm_data { u8 pwm; @@ -388,17 +398,16 @@ static void adm1026_init_client(struct i2c_client *client) dev_dbg(&client->dev, "THERM pin enabled. " "GPIO16 disabled.\n"); } - if (data->config3 & CFG3_VREF_250) { + if (data->config3 & CFG3_VREF_250) dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); - } else { + else dev_dbg(&client->dev, "Vref is 1.82 Volts.\n"); - } /* Read and pick apart the existing GPIO configuration */ value = 0; - for (i = 0;i <= 15;++i) { + for (i = 0; i <= 15; ++i) { if ((i & 0x03) == 0) { value = adm1026_read_value(client, - ADM1026_REG_GPIO_CFG_0_3 + i/4); + ADM1026_REG_GPIO_CFG_0_3 + i / 4); } data->gpio_config[i] = value & 0x03; value >>= 2; @@ -408,7 +417,8 @@ static void adm1026_init_client(struct i2c_client *client) /* ... and then print it */ adm1026_print_gpio(client); - /* If the user asks us to reprogram the GPIO config, then + /* + * If the user asks us to reprogram the GPIO config, then * do it now. */ if (gpio_input[0] != -1 || gpio_output[0] != -1 @@ -417,7 +427,8 @@ static void adm1026_init_client(struct i2c_client *client) adm1026_fixup_gpio(client); } - /* WE INTENTIONALLY make no changes to the limits, + /* + * WE INTENTIONALLY make no changes to the limits, * offsets, pwms, fans and zones. If they were * configured, we don't want to mess with them. * If they weren't, the default is 100% PWM, no @@ -428,7 +439,7 @@ static void adm1026_init_client(struct i2c_client *client) * without first setting a value for pwm1.auto_pwm_min * will not result in potentially dangerous fan speed decrease. */ - data->pwm1.auto_pwm_min=255; + data->pwm1.auto_pwm_min = 255; /* Start monitoring */ value = adm1026_read_value(client, ADM1026_REG_CONFIG1); /* Set MONITOR, clear interrupt acknowledge and s/w reset */ @@ -440,7 +451,7 @@ static void adm1026_init_client(struct i2c_client *client) /* initialize fan_div[] to hardware defaults */ value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); - for (i = 0;i <= 7;++i) { + for (i = 0; i <= 7; ++i) { data->fan_div[i] = DIV_FROM_REG(value & 0x03); value >>= 2; } @@ -452,7 +463,7 @@ static void adm1026_print_gpio(struct i2c_client *client) int i; dev_dbg(&client->dev, "GPIO config is:\n"); - for (i = 0;i <= 7;++i) { + for (i = 0; i <= 7; ++i) { if (data->config2 & (1 << i)) { dev_dbg(&client->dev, "\t%sGP%s%d\n", data->gpio_config[i] & 0x02 ? "" : "!", @@ -462,7 +473,7 @@ static void adm1026_print_gpio(struct i2c_client *client) dev_dbg(&client->dev, "\tFAN%d\n", i); } } - for (i = 8;i <= 15;++i) { + for (i = 8; i <= 15; ++i) { dev_dbg(&client->dev, "\t%sGP%s%d\n", data->gpio_config[i] & 0x02 ? "" : "!", data->gpio_config[i] & 0x01 ? "OUT" : "IN", @@ -485,52 +496,46 @@ static void adm1026_fixup_gpio(struct i2c_client *client) int value; /* Make the changes requested. */ - /* We may need to unlock/stop monitoring or soft-reset the + /* + * We may need to unlock/stop monitoring or soft-reset the * chip before we can make changes. This hasn't been * tested much. FIXME */ /* Make outputs */ - for (i = 0;i <= 16;++i) { - if (gpio_output[i] >= 0 && gpio_output[i] <= 16) { + for (i = 0; i <= 16; ++i) { + if (gpio_output[i] >= 0 && gpio_output[i] <= 16) data->gpio_config[gpio_output[i]] |= 0x01; - } /* if GPIO0-7 is output, it isn't a FAN tach */ - if (gpio_output[i] >= 0 && gpio_output[i] <= 7) { + if (gpio_output[i] >= 0 && gpio_output[i] <= 7) data->config2 |= 1 << gpio_output[i]; - } } /* Input overrides output */ - for (i = 0;i <= 16;++i) { - if (gpio_input[i] >= 0 && gpio_input[i] <= 16) { - data->gpio_config[gpio_input[i]] &= ~ 0x01; - } + for (i = 0; i <= 16; ++i) { + if (gpio_input[i] >= 0 && gpio_input[i] <= 16) + data->gpio_config[gpio_input[i]] &= ~0x01; /* if GPIO0-7 is input, it isn't a FAN tach */ - if (gpio_input[i] >= 0 && gpio_input[i] <= 7) { + if (gpio_input[i] >= 0 && gpio_input[i] <= 7) data->config2 |= 1 << gpio_input[i]; - } } /* Inverted */ - for (i = 0;i <= 16;++i) { - if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) { - data->gpio_config[gpio_inverted[i]] &= ~ 0x02; - } + for (i = 0; i <= 16; ++i) { + if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) + data->gpio_config[gpio_inverted[i]] &= ~0x02; } /* Normal overrides inverted */ - for (i = 0;i <= 16;++i) { - if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) { + for (i = 0; i <= 16; ++i) { + if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) data->gpio_config[gpio_normal[i]] |= 0x02; - } } /* Fan overrides input and output */ - for (i = 0;i <= 7;++i) { - if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) { + for (i = 0; i <= 7; ++i) { + if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) data->config2 &= ~(1 << gpio_fan[i]); - } } /* Write new configs to registers */ @@ -538,7 +543,7 @@ static void adm1026_fixup_gpio(struct i2c_client *client) data->config3 = (data->config3 & 0x3f) | ((data->gpio_config[16] & 0x03) << 6); adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3); - for (i = 15, value = 0;i >= 0;--i) { + for (i = 15, value = 0; i >= 0; --i) { value <<= 2; value |= data->gpio_config[i] & 0x03; if ((i & 0x03) == 0) { @@ -563,22 +568,25 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) mutex_lock(&data->update_lock); if (!data->valid - || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) { + || time_after(jiffies, + data->last_reading + ADM1026_DATA_INTERVAL)) { /* Things that change quickly */ dev_dbg(&client->dev, "Reading sensor values\n"); - for (i = 0;i <= 16;++i) { + for (i = 0; i <= 16; ++i) { data->in[i] = adm1026_read_value(client, ADM1026_REG_IN[i]); } - for (i = 0;i <= 7;++i) { + for (i = 0; i <= 7; ++i) { data->fan[i] = adm1026_read_value(client, ADM1026_REG_FAN(i)); } - for (i = 0;i <= 2;++i) { - /* NOTE: temp[] is s8 and we assume 2's complement - * "conversion" in the assignment */ + for (i = 0; i <= 2; ++i) { + /* + * NOTE: temp[] is s8 and we assume 2's complement + * "conversion" in the assignment + */ data->temp[i] = adm1026_read_value(client, ADM1026_REG_TEMP[i]); } @@ -614,7 +622,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) { /* Things that don't change often */ dev_dbg(&client->dev, "Reading config values\n"); - for (i = 0;i <= 16;++i) { + for (i = 0; i <= 16; ++i) { data->in_min[i] = adm1026_read_value(client, ADM1026_REG_IN_MIN[i]); data->in_max[i] = adm1026_read_value(client, @@ -624,7 +632,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); - for (i = 0;i <= 7;++i) { + for (i = 0; i <= 7; ++i) { data->fan_min[i] = adm1026_read_value(client, ADM1026_REG_FAN_MIN(i)); data->fan_div[i] = DIV_FROM_REG(value & 0x03); @@ -632,7 +640,8 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) } for (i = 0; i <= 2; ++i) { - /* NOTE: temp_xxx[] are s8 and we assume 2's + /* + * NOTE: temp_xxx[] are s8 and we assume 2's * complement "conversion" in the assignment */ data->temp_min[i] = adm1026_read_value(client, @@ -681,7 +690,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) data->gpio_config[16] = (data->config3 >> 6) & 0x03; value = 0; - for (i = 0;i <= 15;++i) { + for (i = 0; i <= 15; ++i) { if ((i & 0x03) == 0) { value = adm1026_read_value(client, ADM1026_REG_GPIO_CFG_0_3 + i/4); @@ -721,7 +730,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = INS_TO_REG(nr, val); @@ -744,7 +758,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = INS_TO_REG(nr, val); @@ -779,23 +798,31 @@ in_reg(13); in_reg(14); in_reg(15); -static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_in16(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in[16]) - NEG12_OFFSET); } -static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_min[16]) - NEG12_OFFSET); } -static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); @@ -803,17 +830,24 @@ static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, c mutex_unlock(&data->update_lock); return count; } -static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_max[16]) - NEG12_OFFSET); } -static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET); @@ -823,10 +857,10 @@ static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, c } static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16); -static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min, 16); -static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max, 16); - - +static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, + set_in16_min, 16); +static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, + set_in16_max, 16); /* Now add fan read/write functions */ @@ -856,7 +890,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]); @@ -890,9 +929,8 @@ static void fixup_fan_min(struct device *dev, int fan, int old_div) int new_div = data->fan_div[fan]; /* 0 and 0xff are special. Don't adjust them */ - if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) { + if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) return; - } new_min = data->fan_min[fan] * old_div / new_div; new_min = SENSORS_LIMIT(new_min, 1, 254); @@ -916,9 +954,14 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val, orig_div, new_div; + long val; + int orig_div, new_div; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; - val = simple_strtol(buf, NULL, 10); new_div = DIV_TO_REG(val); mutex_lock(&data->update_lock); @@ -939,9 +982,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, (DIV_TO_REG(data->fan_div[7]) << 6)); } - if (data->fan_div[nr] != orig_div) { + if (data->fan_div[nr] != orig_div) fixup_fan_min(dev, nr, orig_div); - } + mutex_unlock(&data->update_lock); return count; } @@ -983,7 +1026,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[nr] = TEMP_TO_REG(val); @@ -1007,7 +1055,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[nr] = TEMP_TO_REG(val); @@ -1046,7 +1099,12 @@ static ssize_t set_temp_offset(struct device *dev, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_offset[nr] = TEMP_TO_REG(val); @@ -1056,8 +1114,8 @@ static ssize_t set_temp_offset(struct device *dev, return count; } -#define temp_offset_reg(offset) \ -static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \ +#define temp_offset_reg(offset) \ +static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \ show_temp_offset, set_temp_offset, offset - 1); temp_offset_reg(1); @@ -1097,7 +1155,12 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_tmin[nr] = TEMP_TO_REG(val); @@ -1131,15 +1194,21 @@ static ssize_t set_temp_crit_enable(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + if (val > 1) + return -EINVAL; + + mutex_lock(&data->update_lock); + data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4); + adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1); + mutex_unlock(&data->update_lock); - if ((val == 1) || (val==0)) { - mutex_lock(&data->update_lock); - data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4); - adm1026_write_value(client, ADM1026_REG_CONFIG1, - data->config1); - mutex_unlock(&data->update_lock); - } return count; } @@ -1166,7 +1235,12 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_crit[nr] = TEMP_TO_REG(val); @@ -1184,17 +1258,24 @@ temp_crit_reg(1); temp_crit_reg(2); temp_crit_reg(3); -static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_analog_out_reg(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", DAC_FROM_REG(data->analog_out)); } -static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t set_analog_out_reg(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->analog_out = DAC_TO_REG(val); @@ -1206,7 +1287,8 @@ static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *a static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, set_analog_out_reg); -static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); int vid = (data->gpio >> 11) & 0x1f; @@ -1214,25 +1296,35 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, c dev_dbg(dev, "Setting VID from GPIO11-15.\n"); return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm)); } + static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); -static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", data->vrm); } -static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) + +static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct adm1026_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; - data->vrm = simple_strtol(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + data->vrm = val; return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); -static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms_reg(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%ld\n", data->alarms); @@ -1277,18 +1369,24 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 24); static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 25); static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 26); -static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarm_mask(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%ld\n", data->alarm_mask); } -static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); unsigned long mask; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->alarm_mask = val & 0x7fffffff; @@ -1313,18 +1411,24 @@ static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask, set_alarm_mask); -static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%ld\n", data->gpio); } -static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); long gpio; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->gpio = val & 0x1ffff; @@ -1340,19 +1444,24 @@ static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio); - -static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%ld\n", data->gpio_mask); } -static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); long mask; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->gpio_mask = val & 0x1ffff; @@ -1368,19 +1477,26 @@ static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask); -static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, + char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm1.pwm)); } -static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) + +static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); if (data->pwm1.enable == 1) { - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm1.pwm = PWM_TO_REG(val); @@ -1389,17 +1505,26 @@ static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, co } return count; } -static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf) + +static ssize_t show_auto_pwm_min(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", data->pwm1.auto_pwm_min); } -static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) + +static ssize_t set_auto_pwm_min(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm1.auto_pwm_min = SENSORS_LIMIT(val, 0, 255); @@ -1411,44 +1536,53 @@ static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *att mutex_unlock(&data->update_lock); return count; } -static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf) + +static ssize_t show_auto_pwm_max(struct device *dev, + struct device_attribute *attr, char *buf) { return sprintf(buf, "%d\n", ADM1026_PWM_MAX); } -static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf, "%d\n", data->pwm1.enable); } -static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) + +static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); int old_enable; + unsigned long val; + int err; - if ((val >= 0) && (val < 3)) { - mutex_lock(&data->update_lock); - old_enable = data->pwm1.enable; - data->pwm1.enable = val; - data->config1 = (data->config1 & ~CFG1_PWM_AFC) - | ((val == 2) ? CFG1_PWM_AFC : 0); - adm1026_write_value(client, ADM1026_REG_CONFIG1, - data->config1); - if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */ - data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | - PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); - adm1026_write_value(client, ADM1026_REG_PWM, - data->pwm1.pwm); - } else if (!((old_enable == 1) && (val == 1))) { - /* set pwm to safe value */ - data->pwm1.pwm = 255; - adm1026_write_value(client, ADM1026_REG_PWM, - data->pwm1.pwm); - } - mutex_unlock(&data->update_lock); + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + if (val >= 3) + return -EINVAL; + + mutex_lock(&data->update_lock); + old_enable = data->pwm1.enable; + data->pwm1.enable = val; + data->config1 = (data->config1 & ~CFG1_PWM_AFC) + | ((val == 2) ? CFG1_PWM_AFC : 0); + adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1); + if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */ + data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | + PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); + adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); + } else if (!((old_enable == 1) && (val == 1))) { + /* set pwm to safe value */ + data->pwm1.pwm = 255; + adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); } + mutex_unlock(&data->update_lock); + return count; } @@ -1716,7 +1850,8 @@ static int adm1026_probe(struct i2c_client *client, adm1026_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) + err = sysfs_create_group(&client->dev.kobj, &adm1026_group); + if (err) goto exitfree; if (data->config1 & CFG1_AIN8_9) err = sysfs_create_group(&client->dev.kobj, @@ -1761,20 +1896,9 @@ static int adm1026_remove(struct i2c_client *client) return 0; } -static int __init sm_adm1026_init(void) -{ - return i2c_add_driver(&adm1026_driver); -} - -static void __exit sm_adm1026_exit(void) -{ - i2c_del_driver(&adm1026_driver); -} +module_i2c_driver(adm1026_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " "Justin Thiessen <jthiessen@penguincomputing.com>"); MODULE_DESCRIPTION("ADM1026 driver"); - -module_init(sm_adm1026_init); -module_exit(sm_adm1026_exit); diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 0b8a3b145bd2..80cc465d8ac7 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -78,7 +78,7 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, #define TEMP_FROM_REG(val) ((val) * 1000) -#define DIV_FROM_REG(val) ( 1 << (((val) >> 6) - 1)) +#define DIV_FROM_REG(val) (1 << (((val) >> 6) - 1)) /* Registers to be checked by adm1029_update_device() */ static const u8 ADM1029_REG_TEMP[] = { @@ -200,8 +200,11 @@ static ssize_t set_fan_div(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct adm1029_data *data = i2c_get_clientdata(client); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - long val = simple_strtol(buf, NULL, 10); u8 reg; + long val; + int ret = kstrtol(buf, 10, &val); + if (ret < 0) + return ret; mutex_lock(&data->update_lock); @@ -237,9 +240,9 @@ static ssize_t set_fan_div(struct device *dev, } /* -Access rights on sysfs, S_IRUGO stand for Is Readable by User, Group and Others - S_IWUSR stand for Is Writable by User -*/ + * Access rights on sysfs. S_IRUGO: Is Readable by User, Group and Others + * S_IWUSR: Is Writable by User. + */ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); @@ -300,7 +303,8 @@ static int adm1029_detect(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - /* ADM1029 doesn't have CHIP ID, check just MAN ID + /* + * ADM1029 doesn't have CHIP ID, check just MAN ID * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED, * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values * documented @@ -318,8 +322,10 @@ static int adm1029_detect(struct i2c_client *client, return -ENODEV; if ((chip_id & 0xF0) != 0x00) { - /* There are no "official" CHIP ID, so actually - * we use Major/Minor revision for that */ + /* + * There are no "official" CHIP ID, so actually + * we use Major/Minor revision for that + */ pr_info("adm1029: Unknown major revision %x, " "please let us know\n", chip_id); return -ENODEV; @@ -355,7 +361,8 @@ static int adm1029_probe(struct i2c_client *client, } /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group))) + err = sysfs_create_group(&client->dev.kobj, &adm1029_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); @@ -403,8 +410,8 @@ static int adm1029_remove(struct i2c_client *client) } /* -function that update the status of the chips (temperature for example) -*/ + * function that update the status of the chips (temperature for example) + */ static struct adm1029_data *adm1029_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -446,24 +453,8 @@ static struct adm1029_data *adm1029_update_device(struct device *dev) return data; } -/* - Common module stuff -*/ -static int __init sensors_adm1029_init(void) -{ - - return i2c_add_driver(&adm1029_driver); -} - -static void __exit sensors_adm1029_exit(void) -{ - - i2c_del_driver(&adm1029_driver); -} +module_i2c_driver(adm1029_driver); MODULE_AUTHOR("Corentin LABBE <corentin.labbe@geomatys.fr>"); MODULE_DESCRIPTION("adm1029 driver"); MODULE_LICENSE("GPL v2"); - -module_init(sensors_adm1029_init); -module_exit(sensors_adm1029_exit); diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 97e2cfb0bc93..ff37363ea5bc 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -1,25 +1,25 @@ /* - adm1031.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Based on lm75.c and lm85.c - Supports adm1030 / adm1031 - Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org> - Reworked by Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * adm1031.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Based on lm75.c and lm85.c + * Supports adm1030 / adm1031 + * Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org> + * Reworked by Jean Delvare <khali@linux-fr.org> + * + * 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 <linux/module.h> #include <linux/init.h> @@ -80,7 +80,8 @@ struct adm1031_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ unsigned int update_interval; /* In milliseconds */ - /* The chan_select_table contains the possible configurations for + /* + * The chan_select_table contains the possible configurations for * auto fan control. */ const auto_chan_table_t *chan_select_table; @@ -205,7 +206,8 @@ static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm) #define GET_FAN_AUTO_BITFIELD(data, idx) \ (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2] -/* The tables below contains the possible values for the auto fan +/* + * The tables below contains the possible values for the auto fan * control bitfields. the index in the table is the register value. * MSb is the auto fan control enable bit, so the four first entries * in the table disables auto fan control when both bitfields are zero. @@ -226,7 +228,8 @@ static const auto_chan_table_t auto_channel_select_table_adm1030 = { { 3 /* 0b11 */ , 0 }, }; -/* That function checks if a bitfield is valid and returns the other bitfield +/* + * That function checks if a bitfield is valid and returns the other bitfield * nearest match if no exact match where found. */ static int @@ -252,7 +255,8 @@ get_fan_auto_nearest(struct adm1031_data *data, break; } else if (val == (*data->chan_select_table)[i][chan] && first_match == -1) { - /* Save the first match in case of an exact match has + /* + * Save the first match in case of an exact match has * not been found */ first_match = i; @@ -306,9 +310,11 @@ set_fan_auto_channel(struct device *dev, struct device_attribute *attr, if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^ (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) { if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { - /* Switch to Auto Fan Mode + /* + * Switch to Auto Fan Mode * Save PWM registers - * Set PWM registers to 33% Both */ + * Set PWM registers to 33% Both + */ data->old_pwm[0] = data->pwm[0]; data->old_pwm[1] = data->pwm[1]; adm1031_write_value(client, ADM1031_REG_PWM, 0x55); @@ -1131,19 +1137,8 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) return data; } -static int __init sensors_adm1031_init(void) -{ - return i2c_add_driver(&adm1031_driver); -} - -static void __exit sensors_adm1031_exit(void) -{ - i2c_del_driver(&adm1031_driver); -} +module_i2c_driver(adm1031_driver); MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>"); MODULE_DESCRIPTION("ADM1031/ADM1030 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_adm1031_init); -module_exit(sensors_adm1031_exit); diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 3f63f5f9741d..c3c2865a8967 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -1,12 +1,12 @@ /* * adm9240.c Part of lm_sensors, Linux kernel modules for hardware - * monitoring + * monitoring * * Copyright (C) 1999 Frodo Looijaard <frodol@dds.nl> * Philip Edelbrock <phil@netroedge.com> * Copyright (C) 2003 Michiel Rook <michiel@grendelproject.nl> * Copyright (C) 2005 Grant Coady <gcoady.lk@gmail.com> with valuable - * guidance from Jean Delvare + * guidance from Jean Delvare * * Driver supports Analog Devices ADM9240 * Dallas Semiconductor DS1780 @@ -204,7 +204,12 @@ static ssize_t set_max(struct device *dev, struct device_attribute *devattr, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[attr->index] = TEMP_TO_REG(val); @@ -255,7 +260,12 @@ static ssize_t set_in_min(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[attr->index] = IN_TO_REG(val, attr->index); @@ -272,7 +282,12 @@ static ssize_t set_in_max(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[attr->index] = IN_TO_REG(val, attr->index); @@ -283,7 +298,7 @@ static ssize_t set_in_max(struct device *dev, } #define vin(nr) \ -static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, \ +static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, \ show_in, NULL, nr); \ static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR, \ show_in_min, set_in_min, nr); \ @@ -357,9 +372,14 @@ static ssize_t set_fan_min(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); int nr = attr->index; u8 new_div; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -465,7 +485,12 @@ static ssize_t set_aout(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct adm9240_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->aout = AOUT_TO_REG(val); @@ -481,7 +506,12 @@ static ssize_t chassis_clear_legacy(struct device *dev, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); - unsigned long val = simple_strtol(buf, NULL, 10); + 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"); @@ -632,7 +662,8 @@ static int adm9240_probe(struct i2c_client *new_client, adm9240_init_client(new_client); /* populate sysfs filesystem */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) + err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); @@ -681,8 +712,7 @@ static void adm9240_init_client(struct i2c_client *client) } else { /* cold start: open limits before starting chip */ int i; - for (i = 0; i < 6; i++) - { + for (i = 0; i < 6; i++) { i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(i), 0); i2c_smbus_write_byte_data(client, @@ -717,8 +747,7 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4)) || !data->valid) { - for (i = 0; i < 6; i++) /* read voltages */ - { + for (i = 0; i < 6; i++) { /* read voltages */ data->in[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_IN(i)); } @@ -727,16 +756,17 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) i2c_smbus_read_byte_data(client, ADM9240_REG_INT(1)) << 8; - /* read temperature: assume temperature changes less than + /* + * read temperature: assume temperature changes less than * 0.5'C per two measurement cycles thus ignore possible - * but unlikely aliasing error on lsb reading. --Grant */ + * but unlikely aliasing error on lsb reading. --Grant + */ data->temp = ((i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP) << 8) | i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF)) / 128; - for (i = 0; i < 2; i++) /* read fans */ - { + for (i = 0; i < 2; i++) { /* read fans */ data->fan[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_FAN(i)); @@ -760,15 +790,13 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) if (time_after(jiffies, data->last_updated_config + (HZ * 300)) || !data->valid) { - for (i = 0; i < 6; i++) - { + for (i = 0; i < 6; i++) { data->in_min[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_IN_MIN(i)); data->in_max[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_IN_MAX(i)); } - for (i = 0; i < 2; i++) - { + for (i = 0; i < 2; i++) { data->fan_min[i] = i2c_smbus_read_byte_data(client, ADM9240_REG_FAN_MIN(i)); } @@ -795,21 +823,9 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) return data; } -static int __init sensors_adm9240_init(void) -{ - return i2c_add_driver(&adm9240_driver); -} - -static void __exit sensors_adm9240_exit(void) -{ - i2c_del_driver(&adm9240_driver); -} +module_i2c_driver(adm9240_driver); MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, " "Grant Coady <gcoady.lk@gmail.com> and others"); MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_adm9240_init); -module_exit(sensors_adm9240_exit); - diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index dd87ae96c262..7765e4f74ec5 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -305,19 +305,8 @@ static struct i2c_driver ads1015_driver = { .id_table = ads1015_id, }; -static int __init sensors_ads1015_init(void) -{ - return i2c_add_driver(&ads1015_driver); -} - -static void __exit sensors_ads1015_exit(void) -{ - i2c_del_driver(&ads1015_driver); -} +module_i2c_driver(ads1015_driver); MODULE_AUTHOR("Dirk Eibach <eibach@gdsys.de>"); MODULE_DESCRIPTION("ADS1015 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_ads1015_init); -module_exit(sensors_ads1015_exit); diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index ed60242d6a0a..bf3fdf495595 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -1,27 +1,27 @@ /* - ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC - (C) 2007 EADS Astrium - - This driver is based on the lm75 and other lm_sensors/hwmon drivers - - Written by Steve Hardy <shardy@redhat.com> - - Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf - - 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. -*/ + * ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC + * (C) 2007 EADS Astrium + * + * This driver is based on the lm75 and other lm_sensors/hwmon drivers + * + * Written by Steve Hardy <shardy@redhat.com> + * + * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf + * + * 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 <linux/module.h> #include <linux/init.h> @@ -188,12 +188,13 @@ static int ads7828_detect(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) return -ENODEV; - /* Now, we do the remaining detection. There is no identification - dedicated register so attempt to sanity check using knowledge of - the chip - - Read from the 8 channel addresses - - Check the top 4 bits of each result are not set (12 data bits) - */ + /* + * Now, we do the remaining detection. There is no identification + * dedicated register so attempt to sanity check using knowledge of + * the chip + * - Read from the 8 channel addresses + * - Check the top 4 bits of each result are not set (12 data bits) + */ for (ch = 0; ch < ADS7828_NCH; ch++) { u16 in_data; u8 cmd = channel_cmd_byte(ch); diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index 04450f8bf5da..e65c6e45d36b 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c @@ -34,9 +34,11 @@ #define REG_SER_CONTROL 24 /*Serial Interface Control Register*/ #define REG_ID 31 /*ID Register*/ -/*From figure 17 in the datasheet -* These bits get ORed with the address to form -* the instruction byte */ +/* + * From figure 17 in the datasheet + * These bits get ORed with the address to form + * the instruction byte + */ /*Instruction Bit masks*/ #define INST_MODE_bm (1<<7) #define INST_READ_bm (1<<6) @@ -105,8 +107,10 @@ static ssize_t show_voltage(struct device *dev, uint8_t channel, mux_cnv; channel = attr->index; - /*TODO: add support for conversions - *other than single ended with a gain of 1*/ + /* + * TODO: add support for conversions + * other than single ended with a gain of 1 + */ /*MUX_M3_bm forces single ended*/ /*This is also where the gain of the PGA would be set*/ ads7871_write_reg8(spi, REG_GAIN_MUX, @@ -114,8 +118,10 @@ static ssize_t show_voltage(struct device *dev, ret = ads7871_read_reg8(spi, REG_GAIN_MUX); mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); - /*on 400MHz arm9 platform the conversion - *is already done when we do this test*/ + /* + * on 400MHz arm9 platform the conversion + * is already done when we do this test + */ while ((i < 2) && mux_cnv) { i++; ret = ads7871_read_reg8(spi, REG_GAIN_MUX); @@ -179,8 +185,10 @@ static int __devinit ads7871_probe(struct spi_device *spi) ret = ads7871_read_reg8(spi, REG_OSC_CONTROL); dev_dbg(&spi->dev, "REG_OSC_CONTROL write:%x, read:%x\n", val, ret); - /*because there is no other error checking on an SPI bus - we need to make sure we really have a chip*/ + /* + * 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; @@ -234,18 +242,7 @@ static struct spi_driver ads7871_driver = { .remove = __devexit_p(ads7871_remove), }; -static int __init ads7871_init(void) -{ - return spi_register_driver(&ads7871_driver); -} - -static void __exit ads7871_exit(void) -{ - spi_unregister_driver(&ads7871_driver); -} - -module_init(ads7871_init); -module_exit(ads7871_exit); +module_spi_driver(ads7871_driver); MODULE_AUTHOR("Paul Thomas <pthomas8589@gmail.com>"); MODULE_DESCRIPTION("TI ADS7871 A/D driver"); diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index 5b02f7a91018..71bacc56e138 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -8,7 +8,7 @@ * published by the Free Software Foundation. * * TODO: SPI, support for external temperature sensor - * use power-down mode for suspend?, interrupt handling? + * use power-down mode for suspend?, interrupt handling? */ #include <linux/kernel.h> @@ -348,17 +348,7 @@ static struct i2c_driver adt7411_driver = { .class = I2C_CLASS_HWMON, }; -static int __init sensors_adt7411_init(void) -{ - return i2c_add_driver(&adt7411_driver); -} -module_init(sensors_adt7411_init) - -static void __exit sensors_adt7411_exit(void) -{ - i2c_del_driver(&adt7411_driver); -} -module_exit(sensors_adt7411_exit) +module_i2c_driver(adt7411_driver); MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and " "Wolfram Sang <w.sang@pengutronix.de>"); diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index 7a1494846cfd..339269f76e57 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -65,8 +65,8 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR 0x5F #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR 0x60 #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR 0x63 -#define ADT7462_PWM_HYST_MASK 0x0F -#define ADT7462_PWM_RANGE_MASK 0xF0 +#define ADT7462_PWM_HYST_MASK 0x0F +#define ADT7462_PWM_RANGE_MASK 0xF0 #define ADT7462_PWM_RANGE_SHIFT 4 #define ADT7462_REG_PWM_CFG_BASE_ADDR 0x21 #define ADT7462_REG_PWM_CFG_MAX_ADDR 0x24 @@ -85,7 +85,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; #define ADT7462_PIN15_INPUT 0x20 #define ADT7462_PIN13_INPUT 0x40 #define ADT7462_PIN8_INPUT 0x80 -#define ADT7462_PIN23_MASK 0x03 +#define ADT7462_PIN23_MASK 0x03 #define ADT7462_PIN23_SHIFT 0 #define ADT7462_PIN26_MASK 0x0C /* cfg2 */ #define ADT7462_PIN26_SHIFT 2 @@ -99,7 +99,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; #define ADT7462_PIN28_VOLT 0x5 #define ADT7462_REG_ALARM1 0xB8 -#define ADT7462_LT_ALARM 0x02 +#define ADT7462_LT_ALARM 0x02 #define ADT7462_R1T_ALARM 0x04 #define ADT7462_R2T_ALARM 0x08 #define ADT7462_R3T_ALARM 0x10 @@ -135,9 +135,9 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; #define ADT7462_ALARM_FLAG_MASK 0x0F #define ADT7462_TEMP_COUNT 4 -#define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + (x * 2)) -#define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) -#define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) +#define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + ((x) * 2)) +#define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) +#define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) #define TEMP_FRAC_OFFSET 6 #define ADT7462_FAN_COUNT 8 @@ -1727,8 +1727,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, show_pwm_auto_temp, set_pwm_auto_temp, 3); -static struct attribute *adt7462_attr[] = -{ +static struct attribute *adt7462_attr[] = { &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp3_max.dev_attr.attr, @@ -1975,19 +1974,8 @@ static int adt7462_remove(struct i2c_client *client) return 0; } -static int __init adt7462_init(void) -{ - return i2c_add_driver(&adt7462_driver); -} - -static void __exit adt7462_exit(void) -{ - i2c_del_driver(&adt7462_driver); -} +module_i2c_driver(adt7462_driver); MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); MODULE_DESCRIPTION("ADT7462 driver"); MODULE_LICENSE("GPL"); - -module_init(adt7462_init); -module_exit(adt7462_exit); diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 5e10c79f2dfd..54ec890521ff 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -1131,8 +1131,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, show_pwm_auto_temp, set_pwm_auto_temp, 3); -static struct attribute *adt7470_attr[] = -{ +static struct attribute *adt7470_attr[] = { &dev_attr_alarm_mask.attr, &dev_attr_num_temp_sensors.attr, &dev_attr_auto_update_interval.attr, @@ -1276,7 +1275,8 @@ static int adt7470_probe(struct i2c_client *client, /* Register sysfs hooks */ data->attrs.attrs = adt7470_attr; - if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); @@ -1317,19 +1317,8 @@ static int adt7470_remove(struct i2c_client *client) return 0; } -static int __init adt7470_init(void) -{ - return i2c_add_driver(&adt7470_driver); -} - -static void __exit adt7470_exit(void) -{ - i2c_del_driver(&adt7470_driver); -} +module_i2c_driver(adt7470_driver); MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); MODULE_DESCRIPTION("ADT7470 driver"); MODULE_LICENSE("GPL"); - -module_init(adt7470_init); -module_exit(adt7470_exit); diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 7dab3547fee5..df29d13a5349 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -32,9 +32,10 @@ #define THERM 5 #define HYSTERSIS 6 -/* These are unique identifiers for the sysfs functions - unlike the - numbers above, these are not also indexes into an array -*/ +/* + * These are unique identifiers for the sysfs functions - unlike the + * numbers above, these are not also indexes into an array + */ #define ALARM 9 #define FAULT 10 @@ -288,8 +289,10 @@ static void adt7475_write_word(struct i2c_client *client, int reg, u16 val) i2c_smbus_write_byte_data(client, reg, val & 0xFF); } -/* Find the nearest value in a table - used for pwm frequency and - auto temp range */ +/* + * Find the nearest value in a table - used for pwm frequency and + * auto temp range + */ static int find_nearest(long val, const int *array, int size) { int i; @@ -385,16 +388,20 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, out = (out >> 4) & 0xF; else out = (out & 0xF); - /* Show the value as an absolute number tied to - * THERM */ + /* + * Show the value as an absolute number tied to + * THERM + */ out = reg2temp(data, data->temp[THERM][sattr->index]) - out * 1000; mutex_unlock(&data->lock); break; case OFFSET: - /* Offset is always 2's complement, regardless of the - * setting in CONFIG5 */ + /* + * Offset is always 2's complement, regardless of the + * setting in CONFIG5 + */ mutex_lock(&data->lock); out = (s8)data->temp[sattr->nr][sattr->index]; if (data->config5 & CONFIG5_TEMPOFFSET) @@ -452,8 +459,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, break; case HYSTERSIS: - /* The value will be given as an absolute value, turn it - into an offset based on THERM */ + /* + * The value will be given as an absolute value, turn it + * into an offset based on THERM + */ /* Read fresh THERM and HYSTERSIS values from the chip */ data->temp[THERM][sattr->index] = @@ -478,8 +487,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, default: data->temp[sattr->nr][sattr->index] = temp2reg(data, val); - /* We maintain an extra 2 digits of precision for simplicity - * - shift those back off before writing the value */ + /* + * We maintain an extra 2 digits of precision for simplicity + * - shift those back off before writing the value + */ out = (u8) (data->temp[sattr->nr][sattr->index] >> 2); } @@ -514,8 +525,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, return count; } -/* Table of autorange values - the user will write the value in millidegrees, - and we'll convert it */ +/* + * Table of autorange values - the user will write the value in millidegrees, + * and we'll convert it + */ static const int autorange_table[] = { 2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000, 13330, 16000, 20000, 26670, 32000, 40000, @@ -558,8 +571,10 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr, data->range[sattr->index] = adt7475_read(TEMP_TRANGE_REG(sattr->index)); - /* The user will write an absolute value, so subtract the start point - to figure the range */ + /* + * The user will write an absolute value, so subtract the start point + * to figure the range + */ temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]); val = SENSORS_LIMIT(val, temp + autorange_table[0], temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]); @@ -664,8 +679,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm[CONTROL][sattr->index] = adt7475_read(PWM_CONFIG_REG(sattr->index)); - /* If we are not in manual mode, then we shouldn't allow - * the user to set the pwm speed */ + /* + * If we are not in manual mode, then we shouldn't allow + * the user to set the pwm speed + */ if (((data->pwm[CONTROL][sattr->index] >> 5) & 7) != 7) { mutex_unlock(&data->lock); return count; @@ -1232,7 +1249,7 @@ static void adt7475_remove_files(struct i2c_client *client, static int adt7475_probe(struct i2c_client *client, const struct i2c_device_id *id) { - static const char *names[] = { + static const char * const names[] = { [adt7473] = "ADT7473", [adt7475] = "ADT7475", [adt7476] = "ADT7476", @@ -1280,9 +1297,11 @@ static int adt7475_probe(struct i2c_client *client, if ((data->config4 & CONFIG4_PINFUNC) == 0x0) data->has_fan4 = 1; - /* THERM configuration is more complex on the ADT7476 and ADT7490, - because 2 different pins (TACH4 and +2.5 Vin) can be used for - this function */ + /* + * THERM configuration is more complex on the ADT7476 and ADT7490, + * because 2 different pins (TACH4 and +2.5 Vin) can be used for + * this function + */ if (id->driver_data == adt7490) { if ((data->config4 & CONFIG4_PINFUNC) == 0x1 && !(config3 & CONFIG3_THERM)) @@ -1294,8 +1313,10 @@ static int adt7475_probe(struct i2c_client *client, data->has_voltage |= (1 << 0); /* in0 */ } - /* On the ADT7476, the +12V input pin may instead be used as VID5, - and VID pins may alternatively be used as GPIO */ + /* + * On the ADT7476, the +12V input pin may instead be used as VID5, + * and VID pins may alternatively be used as GPIO + */ if (id->driver_data == adt7476) { u8 vid = adt7475_read(REG_VID); if (!(vid & VID_VIDSEL)) @@ -1314,8 +1335,10 @@ static int adt7475_probe(struct i2c_client *client, } data->bypass_attn &= data->has_voltage; - /* Call adt7475_read_pwm for all pwm's as this will reprogram any - pwm's which are disabled to manual mode with 0% duty cycle */ + /* + * Call adt7475_read_pwm for all pwm's as this will reprogram any + * pwm's which are disabled to manual mode with 0% duty cycle + */ for (i = 0; i < ADT7475_PWM_COUNT; i++) adt7475_read_pwm(client, i); @@ -1431,8 +1454,10 @@ static void adt7475_read_pwm(struct i2c_client *client, int index) data->pwm[CONTROL][index] = adt7475_read(PWM_CONFIG_REG(index)); - /* Figure out the internal value for pwmctrl and pwmchan - based on the current settings */ + /* + * Figure out the internal value for pwmctrl and pwmchan + * based on the current settings + */ v = (data->pwm[CONTROL][index] >> 5) & 7; if (v == 3) @@ -1440,10 +1465,11 @@ static void adt7475_read_pwm(struct i2c_client *client, int index) else if (v == 7) data->pwmctl[index] = 1; else if (v == 4) { - /* The fan is disabled - we don't want to - support that, so change to manual mode and - set the duty cycle to 0 instead - */ + /* + * The fan is disabled - we don't want to + * support that, so change to manual mode and + * set the duty cycle to 0 instead + */ data->pwm[INPUT][index] = 0; data->pwm[CONTROL][index] &= ~0xE0; data->pwm[CONTROL][index] |= (7 << 5); @@ -1600,19 +1626,8 @@ static struct adt7475_data *adt7475_update_device(struct device *dev) return data; } -static int __init sensors_adt7475_init(void) -{ - return i2c_add_driver(&adt7475_driver); -} - -static void __exit sensors_adt7475_exit(void) -{ - i2c_del_driver(&adt7475_driver); -} +module_i2c_driver(adt7475_driver); MODULE_AUTHOR("Advanced Micro Devices, Inc"); MODULE_DESCRIPTION("adt7475 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_adt7475_init); -module_exit(sensors_adt7475_exit); diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index 89a6b9da0ec3..f600fa1f92e3 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -1,25 +1,25 @@ /* - amc6821.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> - - Based on max6650.c: - Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de> - - 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. -*/ + * amc6821.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si> + * + * Based on max6650.c: + * Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de> + * + * 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 <linux/kernel.h> /* Needed for KERN_INFO */ @@ -47,7 +47,7 @@ static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, * Insmod parameters */ -static int pwminv = 0; /*Inverted PWM output. */ +static int pwminv; /*Inverted PWM output. */ module_param(pwminv, int, S_IRUGO); static int init = 1; /*Power-on initialization.*/ @@ -188,7 +188,7 @@ static struct i2c_driver amc6821_driver = { /* * Client data (each client gets its own) - */ + */ struct amc6821_data { struct device *hwmon_dev; @@ -836,8 +836,10 @@ static int amc6821_detect( return -ENODEV; } - /* Bit 7 of the address register is ignored, so we can check the - ID registers again */ + /* + * Bit 7 of the address register is ignored, so we can check the + * ID registers again + */ dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID); comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID); if (dev_id != 0x21 || comp_id != 0x49) { @@ -1080,9 +1082,10 @@ static struct amc6821_data *amc6821_update_device(struct device *dev) data->pwm1_auto_channels_temp = 3; data->pwm1_enable = 3; break; - case 1: /*semi-open loop: software sets rpm, chip controls pwm1, - *currently not implemented - */ + case 1: /* + * semi-open loop: software sets rpm, chip controls + * pwm1, currently not implemented + */ data->pwm1_auto_channels_temp = 0; data->pwm1_enable = 0; break; @@ -1095,20 +1098,7 @@ static struct amc6821_data *amc6821_update_device(struct device *dev) return data; } - -static int __init amc6821_init(void) -{ - return i2c_add_driver(&amc6821_driver); -} - -static void __exit amc6821_exit(void) -{ - i2c_del_driver(&amc6821_driver); -} - -module_init(amc6821_init); -module_exit(amc6821_exit); - +module_i2c_driver(amc6821_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("T. Mertelj <tomaz.mertelj@guest.arnes.si>"); diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index b9895531240d..f082e48ab113 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -344,8 +344,10 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key) while (begin != end) { int middle = begin + (end - begin) / 2; entry = applesmc_get_entry_by_index(middle); - if (IS_ERR(entry)) + if (IS_ERR(entry)) { + *lo = 0; return PTR_ERR(entry); + } if (strcmp(entry->key, key) < 0) begin = middle + 1; else @@ -364,8 +366,10 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key) while (begin != end) { int middle = begin + (end - begin) / 2; entry = applesmc_get_entry_by_index(middle); - if (IS_ERR(entry)) + if (IS_ERR(entry)) { + *hi = smcreg.key_count; return PTR_ERR(entry); + } if (strcmp(key, entry->key) < 0) end = middle; else @@ -1189,8 +1193,10 @@ static int applesmc_dmi_match(const struct dmi_system_id *id) return 1; } -/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". - * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ +/* + * Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". + * So we need to put "Apple MacBook Pro" before "Apple MacBook". + */ static __initdata struct dmi_system_id applesmc_whitelist[] = { { applesmc_dmi_match, "Apple MacBook Air", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index d7bd1f3f2a31..4b8814deabb1 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -1,40 +1,40 @@ /* - asb100.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - - Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com> - - (derived from w83781d.c) - - Copyright (C) 1998 - 2003 Frodo Looijaard <frodol@dds.nl>, - Philip Edelbrock <phil@netroedge.com>, and - Mark Studebaker <mdsxyz123@yahoo.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * asb100.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * + * Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com> + * + * (derived from w83781d.c) + * + * Copyright (C) 1998 - 2003 Frodo Looijaard <frodol@dds.nl>, + * Philip Edelbrock <phil@netroedge.com>, and + * Mark Studebaker <mdsxyz123@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* - This driver supports the hardware sensor chips: Asus ASB100 and - ASB100-A "BACH". - - ASB100-A supports pwm1, while plain ASB100 does not. There is no known - way for the driver to tell which one is there. - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - asb100 7 3 1 4 0x31 0x0694 yes no -*/ + * This driver supports the hardware sensor chips: Asus ASB100 and + * ASB100-A "BACH". + * + * ASB100-A supports pwm1, while plain ASB100 does not. There is no known + * way for the driver to tell which one is there. + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * asb100 7 3 1 4 0x31 0x0694 yes no + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -99,15 +99,19 @@ static const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19}; /* bit 7 -> enable, bits 0-3 -> duty cycle */ #define ASB100_REG_PWM1 0x59 -/* CONVERSIONS - Rounding and limit checking is only done on the TO_REG variants. */ +/* + * CONVERSIONS + * Rounding and limit checking is only done on the TO_REG variants. + */ /* These constants are a guess, consistent w/ w83781d */ -#define ASB100_IN_MIN ( 0) -#define ASB100_IN_MAX (4080) +#define ASB100_IN_MIN 0 +#define ASB100_IN_MAX 4080 -/* IN: 1/1000 V (0V to 4.08V) - REG: 16mV/bit */ +/* + * IN: 1/1000 V (0V to 4.08V) + * REG: 16mV/bit + */ static u8 IN_TO_REG(unsigned val) { unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX); @@ -131,19 +135,21 @@ static u8 FAN_TO_REG(long rpm, int div) static int FAN_FROM_REG(u8 val, int div) { - return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div); + return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div); } /* These constants are a guess, consistent w/ w83781d */ -#define ASB100_TEMP_MIN (-128000) -#define ASB100_TEMP_MAX ( 127000) +#define ASB100_TEMP_MIN -128000 +#define ASB100_TEMP_MAX 127000 -/* TEMP: 0.001C/bit (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: 0.001C/bit (-128C to +127C) + * REG: 1C/bit, two's complement + */ static u8 TEMP_TO_REG(long temp) { int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); - ntemp += (ntemp<0 ? -500 : 500); + ntemp += (ntemp < 0 ? -500 : 500); return (u8)(ntemp / 1000); } @@ -152,8 +158,10 @@ static int TEMP_FROM_REG(u8 reg) return (s8)reg * 1000; } -/* PWM: 0 - 255 per sensors documentation - REG: (6.25% duty cycle per bit) */ +/* + * PWM: 0 - 255 per sensors documentation + * REG: (6.25% duty cycle per bit) + */ static u8 ASB100_PWM_TO_REG(int pwm) { pwm = SENSORS_LIMIT(pwm, 0, 255); @@ -167,16 +175,20 @@ static int ASB100_PWM_FROM_REG(u8 reg) #define DIV_FROM_REG(val) (1 << (val)) -/* FAN DIV: 1, 2, 4, or 8 (defaults to 2) - REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */ +/* + * FAN DIV: 1, 2, 4, or 8 (defaults to 2) + * REG: 0, 1, 2, or 3 (respectively) (defaults to 1) + */ static u8 DIV_TO_REG(long val) { - return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1; + return val == 8 ? 3 : val == 4 ? 2 : val == 1 ? 0 : 1; } -/* For each registered client, we need to keep some data in memory. That - data is pointed to by client->data. The structure itself is - dynamically allocated, at the same time the client itself is allocated. */ +/* + * For each registered client, we need to keep some data in memory. That + * data is pointed to by client->data. The structure itself is + * dynamically allocated, at the same time the client itself is allocated. + */ struct asb100_data { struct device *hwmon_dev; struct mutex lock; @@ -253,8 +265,10 @@ static ssize_t set_in_##reg(struct device *dev, struct device_attribute *attr, \ int nr = to_sensor_dev_attr(attr)->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct asb100_data *data = i2c_get_clientdata(client); \ - unsigned long val = simple_strtoul(buf, NULL, 10); \ - \ + unsigned long val; \ + int err = kstrtoul(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ data->in_##reg[nr] = IN_TO_REG(val); \ asb100_write_value(client, ASB100_REG_IN_##REG(nr), \ @@ -315,7 +329,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct asb100_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -324,10 +343,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, return count; } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -335,8 +356,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct asb100_data *data = i2c_get_clientdata(client); unsigned long min; - unsigned long val = simple_strtoul(buf, NULL, 10); int reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -421,8 +447,10 @@ static ssize_t set_##reg(struct device *dev, struct device_attribute *attr, \ int nr = to_sensor_dev_attr(attr)->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct asb100_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ - \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ switch (nr) { \ case 1: case 2: \ @@ -476,7 +504,13 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct asb100_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + data->vrm = val; return count; } @@ -524,7 +558,12 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, { struct i2c_client *client = to_i2c_client(dev); struct asb100_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm &= 0x80; /* keep the enable bit */ @@ -546,7 +585,12 @@ static ssize_t set_pwm_enable1(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct asb100_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm &= 0x0f; /* keep the duty cycle bits */ @@ -768,7 +812,8 @@ static int asb100_probe(struct i2c_client *client, data->fan_min[2] = asb100_read_value(client, ASB100_REG_FAN_MIN(2)); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &asb100_group))) + err = sysfs_create_group(&client->dev.kobj, &asb100_group); + if (err) goto ERROR3; data->hwmon_dev = hwmon_device_register(&client->dev); @@ -805,8 +850,10 @@ static int asb100_remove(struct i2c_client *client) return 0; } -/* The SMBus locks itself, usually, but nothing may access the chip between - bank switches. */ +/* + * The SMBus locks itself, usually, but nothing may access the chip between + * bank switches. + */ static int asb100_read_value(struct i2c_client *client, u16 reg) { struct asb100_data *data = i2c_get_clientdata(client); @@ -971,19 +1018,8 @@ static struct asb100_data *asb100_update_device(struct device *dev) return data; } -static int __init asb100_init(void) -{ - return i2c_add_driver(&asb100_driver); -} - -static void __exit asb100_exit(void) -{ - i2c_del_driver(&asb100_driver); -} +module_i2c_driver(asb100_driver); MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); MODULE_DESCRIPTION("ASB100 Bach driver"); MODULE_LICENSE("GPL"); - -module_init(asb100_init); -module_exit(asb100_exit); diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index 3efd32449982..7caa242915a6 100644 --- a/drivers/hwmon/asc7621.c +++ b/drivers/hwmon/asc7621.c @@ -268,9 +268,11 @@ static ssize_t store_fan16(struct device *dev, if (kstrtol(buf, 10, &reqval)) return -EINVAL; - /* If a minimum RPM of zero is requested, then we set the register to - 0xffff. This value allows the fan to be stopped completely without - generating an alarm. */ + /* + * If a minimum RPM of zero is requested, then we set the register to + * 0xffff. This value allows the fan to be stopped completely without + * generating an alarm. + */ reqval = (reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe)); diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 00e98517f94c..351d1f4593e7 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -38,7 +38,8 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = { { } }; -/* Minimum time between readings, enforced in order to avoid +/* + * Minimum time between readings, enforced in order to avoid * hogging the CPU. */ #define CACHE_TIME HZ @@ -161,7 +162,8 @@ struct atk_sensor_data { char const *acpi_name; }; -/* Return buffer format: +/* + * Return buffer format: * [0-3] "value" is valid flag * [4-7] value * [8- ] unknown stuff on newer mobos @@ -310,7 +312,8 @@ static union acpi_object *atk_get_pack_member(struct atk_data *data, } -/* New package format is: +/* + * New package format is: * - flag (int) * class - used for de-muxing the request to the correct GITn * type (volt, temp, fan) @@ -613,7 +616,8 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value) buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer; if (buf->flags == 0) { - /* The reading is not valid, possible causes: + /* + * The reading is not valid, possible causes: * - sensor failure * - enumeration was FUBAR (and we didn't notice) */ @@ -1311,14 +1315,16 @@ static int atk_probe_if(struct atk_data *data) dev_dbg(dev, "method " METHOD_WRITE " not found: %s\n", acpi_format_exception(status)); - /* Check for hwmon methods: first check "old" style methods; note that + /* + * Check for hwmon methods: first check "old" style methods; note that * both may be present: in this case we stick to the old interface; * analysis of multiple DSDTs indicates that when both interfaces * are present the new one (GGRP/GITM) is not functional. */ if (new_if) dev_info(dev, "Overriding interface detection\n"); - if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle && !new_if) + if (data->rtmp_handle && + data->rvlt_handle && data->rfan_handle && !new_if) data->old_interface = true; else if (data->enumerate_handle && data->read_handle && data->write_handle) diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 33cc143b2069..58af6aa93530 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -1,22 +1,22 @@ /* - atxp1.c - kernel module for setting CPU VID and general purpose - I/Os using the Attansic ATXP1 chip. - - 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. - -*/ + * atxp1.c - kernel module for setting CPU VID and general purpose + * I/Os using the Attansic ATXP1 chip. + * + * 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 <linux/kernel.h> #include <linux/init.h> @@ -48,7 +48,7 @@ static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; static int atxp1_probe(struct i2c_client *client, const struct i2c_device_id *id); static int atxp1_remove(struct i2c_client *client); -static struct atxp1_data * atxp1_update_device(struct device *dev); +static struct atxp1_data *atxp1_update_device(struct device *dev); static int atxp1_detect(struct i2c_client *client, struct i2c_board_info *info); static const struct i2c_device_id atxp1_id[] = { @@ -83,7 +83,7 @@ struct atxp1_data { u8 vrm; /* Detected CPU VRM */ }; -static struct atxp1_data * atxp1_update_device(struct device *dev) +static struct atxp1_data *atxp1_update_device(struct device *dev) { struct i2c_client *client; struct atxp1_data *data; @@ -97,7 +97,8 @@ static struct atxp1_data * atxp1_update_device(struct device *dev) /* Update local register data */ data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID); - data->reg.cpu_vid = i2c_smbus_read_byte_data(client, ATXP1_CVID); + data->reg.cpu_vid = i2c_smbus_read_byte_data(client, + ATXP1_CVID); data->reg.gpio1 = i2c_smbus_read_byte_data(client, ATXP1_GPIO1); data->reg.gpio2 = i2c_smbus_read_byte_data(client, ATXP1_GPIO2); @@ -106,33 +107,41 @@ static struct atxp1_data * atxp1_update_device(struct device *dev) mutex_unlock(&data->update_lock); - return(data); + return data; } /* sys file functions for cpu0_vid */ -static ssize_t atxp1_showvcore(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t atxp1_showvcore(struct device *dev, + struct device_attribute *attr, char *buf) { int size; struct atxp1_data *data; data = atxp1_update_device(dev); - size = sprintf(buf, "%d\n", vid_from_reg(data->reg.vid & ATXP1_VIDMASK, data->vrm)); + size = sprintf(buf, "%d\n", vid_from_reg(data->reg.vid & ATXP1_VIDMASK, + data->vrm)); return size; } -static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t atxp1_storevcore(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct atxp1_data *data; struct i2c_client *client; int vid, cvid; - unsigned int vcore; + unsigned long vcore; + int err; client = to_i2c_client(dev); data = atxp1_update_device(dev); - vcore = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &vcore); + if (err) + return err; + vcore /= 25; vcore *= 25; @@ -144,7 +153,10 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att return -1; } - /* If output enabled, use control register value. Otherwise original CPU VID */ + /* + * If output enabled, use control register value. + * Otherwise original CPU VID + */ if (data->reg.vid & ATXP1_VIDENA) cvid = data->reg.vid & ATXP1_VIDMASK; else @@ -154,18 +166,17 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att if (vid == cvid) return count; - dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid); + dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", (int)vcore, vid); /* Write every 25 mV step to increase stability */ if (cvid > vid) { - for (; cvid >= vid; cvid--) { - i2c_smbus_write_byte_data(client, ATXP1_VID, cvid | ATXP1_VIDENA); - } - } - else { - for (; cvid <= vid; cvid++) { - i2c_smbus_write_byte_data(client, ATXP1_VID, cvid | ATXP1_VIDENA); - } + for (; cvid >= vid; cvid--) + i2c_smbus_write_byte_data(client, + ATXP1_VID, cvid | ATXP1_VIDENA); + } else { + for (; cvid <= vid; cvid++) + i2c_smbus_write_byte_data(client, + ATXP1_VID, cvid | ATXP1_VIDENA); } data->valid = 0; @@ -173,13 +184,16 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att return count; } -/* CPU core reference voltage - unit: millivolt -*/ -static DEVICE_ATTR(cpu0_vid, S_IRUGO | S_IWUSR, atxp1_showvcore, atxp1_storevcore); +/* + * CPU core reference voltage + * unit: millivolt + */ +static DEVICE_ATTR(cpu0_vid, S_IRUGO | S_IWUSR, atxp1_showvcore, + atxp1_storevcore); /* sys file functions for GPIO1 */ -static ssize_t atxp1_showgpio1(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t atxp1_showgpio1(struct device *dev, + struct device_attribute *attr, char *buf) { int size; struct atxp1_data *data; @@ -191,21 +205,26 @@ static ssize_t atxp1_showgpio1(struct device *dev, struct device_attribute *attr return size; } -static ssize_t atxp1_storegpio1(struct device *dev, struct device_attribute *attr, const char*buf, size_t count) +static ssize_t atxp1_storegpio1(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) { struct atxp1_data *data; struct i2c_client *client; - unsigned int value; + unsigned long value; + int err; client = to_i2c_client(dev); data = atxp1_update_device(dev); - value = simple_strtoul(buf, NULL, 16); + err = kstrtoul(buf, 16, &value); + if (err) + return err; value &= ATXP1_GPIO1MASK; if (value != (data->reg.gpio1 & ATXP1_GPIO1MASK)) { - dev_info(dev, "Writing 0x%x to GPIO1.\n", value); + dev_info(dev, "Writing 0x%x to GPIO1.\n", (unsigned int)value); i2c_smbus_write_byte_data(client, ATXP1_GPIO1, value); @@ -215,13 +234,15 @@ static ssize_t atxp1_storegpio1(struct device *dev, struct device_attribute *att return count; } -/* GPIO1 data register - unit: Four bit as hex (e.g. 0x0f) -*/ +/* + * GPIO1 data register + * unit: Four bit as hex (e.g. 0x0f) + */ static DEVICE_ATTR(gpio1, S_IRUGO | S_IWUSR, atxp1_showgpio1, atxp1_storegpio1); /* sys file functions for GPIO2 */ -static ssize_t atxp1_showgpio2(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t atxp1_showgpio2(struct device *dev, + struct device_attribute *attr, char *buf) { int size; struct atxp1_data *data; @@ -233,19 +254,22 @@ static ssize_t atxp1_showgpio2(struct device *dev, struct device_attribute *attr return size; } -static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t atxp1_storegpio2(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { - struct atxp1_data *data; - struct i2c_client *client; - unsigned int value; - - client = to_i2c_client(dev); - data = atxp1_update_device(dev); + struct atxp1_data *data = atxp1_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + unsigned long value; + int err; - value = simple_strtoul(buf, NULL, 16) & 0xff; + err = kstrtoul(buf, 16, &value); + if (err) + return err; + value &= 0xff; if (value != data->reg.gpio2) { - dev_info(dev, "Writing 0x%x to GPIO1.\n", value); + dev_info(dev, "Writing 0x%x to GPIO1.\n", (unsigned int)value); i2c_smbus_write_byte_data(client, ATXP1_GPIO2, value); @@ -255,9 +279,10 @@ static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *att return count; } -/* GPIO2 data register - unit: Eight bit as hex (e.g. 0xff) -*/ +/* + * GPIO2 data register + * unit: Eight bit as hex (e.g. 0xff) + */ static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2); static struct attribute *atxp1_attributes[] = { @@ -290,8 +315,10 @@ static int atxp1_detect(struct i2c_client *new_client, (i2c_smbus_read_byte_data(new_client, 0xff) == 0))) return -ENODEV; - /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) - * showing the same as register 0x00 */ + /* + * No vendor ID, now checking if registers 0x10,0x11 (non-existent) + * showing the same as register 0x00 + */ temp = i2c_smbus_read_byte_data(new_client, 0x00); if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && @@ -333,7 +360,8 @@ static int atxp1_probe(struct i2c_client *new_client, mutex_init(&data->update_lock); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) + err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); @@ -357,7 +385,7 @@ exit: static int atxp1_remove(struct i2c_client *client) { - struct atxp1_data * data = i2c_get_clientdata(client); + struct atxp1_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &atxp1_group); @@ -367,15 +395,4 @@ static int atxp1_remove(struct i2c_client *client) return 0; }; -static int __init atxp1_init(void) -{ - return i2c_add_driver(&atxp1_driver); -}; - -static void __exit atxp1_exit(void) -{ - i2c_del_driver(&atxp1_driver); -}; - -module_init(atxp1_init); -module_exit(atxp1_exit); +module_i2c_driver(atxp1_driver); diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index a6c6ec36615e..0d3141fbbc20 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -39,6 +39,7 @@ #include <linux/moduleparam.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> #define DRVNAME "coretemp" @@ -57,8 +58,8 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) -#define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id -#define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id +#define TO_PHYS_ID(cpu) (cpu_data(cpu).phys_proc_id) +#define TO_CORE_ID(cpu) (cpu_data(cpu).cpu_core_id) #define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) #ifdef CONFIG_SMP @@ -759,13 +760,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; +static const struct x86_cpu_id coretemp_ids[] = { + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); + static int __init coretemp_init(void) { int i, err = -ENODEV; - /* quick check if we run Intel */ - if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) - goto exit; + /* + * CPUID.06H.EAX[0] indicates whether the CPU has thermal + * sensors. We check this bit only, all the early CPUs + * without thermal sensors will be filtered out. + */ + if (!x86_match_cpu(coretemp_ids)) + return -ENODEV; err = platform_driver_register(&coretemp_driver); if (err) diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index ffb229af7861..e7c6a19f3b25 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -82,12 +82,12 @@ enum chips { dme1737, sch5027, sch311x, sch5127 }; * --------------------------------------------------------------------- */ /* Voltages (in) numbered 0-7 (ix) */ -#define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) : \ +#define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) : \ (ix) < 7 ? 0x94 + (ix) : \ 0x1f) -#define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \ +#define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \ : 0x91 + (ix) * 2) -#define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \ +#define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \ : 0x92 + (ix) * 2) /* Temperatures (temp) numbered 0-2 (ix) */ @@ -97,14 +97,16 @@ enum chips { dme1737, sch5027, sch311x, sch5127 }; #define DME1737_REG_TEMP_OFFSET(ix) ((ix) == 0 ? 0x1f \ : 0x1c + (ix)) -/* Voltage and temperature LSBs +/* + * Voltage and temperature LSBs * The LSBs (4 bits each) are stored in 5 registers with the following layouts: * IN_TEMP_LSB(0) = [in5, in6] * IN_TEMP_LSB(1) = [temp3, temp1] * IN_TEMP_LSB(2) = [in4, temp2] * IN_TEMP_LSB(3) = [in3, in0] * IN_TEMP_LSB(4) = [in2, in1] - * IN_TEMP_LSB(5) = [res, in7] */ + * IN_TEMP_LSB(5) = [res, in7] + */ #define DME1737_REG_IN_TEMP_LSB(ix) (0x84 + (ix)) static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5}; static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4}; @@ -127,24 +129,30 @@ static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0}; #define DME1737_REG_PWM_MIN(ix) (0x64 + (ix)) /* only for pwm[0-2] */ #define DME1737_REG_PWM_FREQ(ix) ((ix) < 3 ? 0x5f + (ix) \ : 0xa3 + (ix)) -/* The layout of the ramp rate registers is different from the other pwm +/* + * The layout of the ramp rate registers is different from the other pwm * registers. The bits for the 3 PWMs are stored in 2 registers: * PWM_RR(0) = [OFF3, OFF2, OFF1, RES, RR1E, RR1-2, RR1-1, RR1-0] - * PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0] */ + * PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0] + */ #define DME1737_REG_PWM_RR(ix) (0x62 + (ix)) /* only for pwm[0-2] */ /* Thermal zones 0-2 */ #define DME1737_REG_ZONE_LOW(ix) (0x67 + (ix)) #define DME1737_REG_ZONE_ABS(ix) (0x6a + (ix)) -/* The layout of the hysteresis registers is different from the other zone +/* + * The layout of the hysteresis registers is different from the other zone * registers. The bits for the 3 zones are stored in 2 registers: * ZONE_HYST(0) = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0] - * ZONE_HYST(1) = [H3-3, H3-2, H3-1, H3-0, RES, RES, RES, RES] */ + * ZONE_HYST(1) = [H3-3, H3-2, H3-1, H3-0, RES, RES, RES, RES] + */ #define DME1737_REG_ZONE_HYST(ix) (0x6d + (ix)) -/* Alarm registers and bit mapping +/* + * Alarm registers and bit mapping * The 3 8-bit alarm registers will be concatenated to a single 32-bit - * alarm value [0, ALARM3, ALARM2, ALARM1]. */ + * alarm value [0, ALARM3, ALARM2, ALARM1]. + */ #define DME1737_REG_ALARM1 0x41 #define DME1737_REG_ALARM2 0x42 #define DME1737_REG_ALARM3 0x83 @@ -257,9 +265,11 @@ static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ IN_NOMINAL_DME1737) -/* Voltage input +/* + * Voltage input * Voltage inputs have 16 bits resolution, limit values have 8 bits - * resolution. */ + * resolution. + */ static inline int IN_FROM_REG(int reg, int nominal, int res) { return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2)); @@ -270,10 +280,12 @@ static inline int IN_TO_REG(int val, int nominal) return SENSORS_LIMIT((val * 192 + nominal / 2) / nominal, 0, 255); } -/* Temperature input +/* + * Temperature input * The register values represent temperatures in 2's complement notation from * -127 degrees C to +127 degrees C. Temp inputs have 16 bits resolution, limit - * values have 8 bits resolution. */ + * values have 8 bits resolution. + */ static inline int TEMP_FROM_REG(int reg, int res) { return (reg * 1000) >> (res - 8); @@ -300,18 +312,19 @@ static int TEMP_RANGE_TO_REG(int val, int reg) int i; for (i = 15; i > 0; i--) { - if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2) { + if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2) break; - } } return (reg & 0x0f) | (i << 4); } -/* Temperature hysteresis +/* + * Temperature hysteresis * Register layout: * reg[0] = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0] - * reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx] */ + * reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx] + */ static inline int TEMP_HYST_FROM_REG(int reg, int ix) { return (((ix == 1) ? reg : reg >> 4) & 0x0f) * 1000; @@ -327,11 +340,10 @@ static inline int TEMP_HYST_TO_REG(int val, int ix, int reg) /* Fan input RPM */ static inline int FAN_FROM_REG(int reg, int tpc) { - if (tpc) { + if (tpc) return tpc * reg; - } else { + else return (reg == 0 || reg == 0xffff) ? 0 : 90000 * 60 / reg; - } } static inline int FAN_TO_REG(int val, int tpc) @@ -344,17 +356,21 @@ static inline int FAN_TO_REG(int val, int tpc) } } -/* Fan TPC (tach pulse count) +/* + * Fan TPC (tach pulse count) * Converts a register value to a TPC multiplier or returns 0 if the tachometer - * is configured in legacy (non-tpc) mode */ + * is configured in legacy (non-tpc) mode + */ static inline int FAN_TPC_FROM_REG(int reg) { return (reg & 0x20) ? 0 : 60 >> (reg & 0x03); } -/* Fan type +/* + * Fan type * The type of a fan is expressed in number of pulses-per-revolution that it - * emits */ + * emits + */ static inline int FAN_TYPE_FROM_REG(int reg) { int edge = (reg >> 1) & 0x03; @@ -378,9 +394,8 @@ static int FAN_MAX_FROM_REG(int reg) int i; for (i = 10; i > 0; i--) { - if (reg == FAN_MAX[i]) { + if (reg == FAN_MAX[i]) break; - } } return 1000 + i * 500; @@ -391,15 +406,15 @@ static int FAN_MAX_TO_REG(int val) int i; for (i = 10; i > 0; i--) { - if (val > (1000 + (i - 1) * 500)) { + if (val > (1000 + (i - 1) * 500)) break; - } } return FAN_MAX[i]; } -/* PWM enable +/* + * PWM enable * Register to enable mapping: * 000: 2 fan on zone 1 auto * 001: 2 fan on zone 2 auto @@ -408,7 +423,8 @@ static int FAN_MAX_TO_REG(int val) * 100: -1 fan disabled * 101: 2 fan on hottest of zones 2,3 auto * 110: 2 fan on hottest of zones 1,2,3 auto - * 111: 1 fan in manual mode */ + * 111: 1 fan in manual mode + */ static inline int PWM_EN_FROM_REG(int reg) { static const int en[] = {2, 2, 2, 0, -1, 2, 2, 1}; @@ -423,7 +439,8 @@ static inline int PWM_EN_TO_REG(int val, int reg) return (reg & 0x1f) | ((en & 0x07) << 5); } -/* PWM auto channels zone +/* + * PWM auto channels zone * Register to auto channels zone mapping (ACZ is a bitfield with bit x * corresponding to zone x+1): * 000: 001 fan on zone 1 auto @@ -433,7 +450,8 @@ static inline int PWM_EN_TO_REG(int val, int reg) * 100: 000 fan disabled * 101: 110 fan on hottest of zones 2,3 auto * 110: 111 fan on hottest of zones 1,2,3 auto - * 111: 000 fan in manual mode */ + * 111: 000 fan in manual mode + */ static inline int PWM_ACZ_FROM_REG(int reg) { static const int acz[] = {1, 2, 4, 0, 0, 6, 7, 0}; @@ -468,19 +486,20 @@ static int PWM_FREQ_TO_REG(int val, int reg) i = 11; } else { for (i = 9; i > 0; i--) { - if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2) { + if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2) break; - } } } return (reg & 0xf0) | i; } -/* PWM ramp rate +/* + * PWM ramp rate * Register layout: * reg[0] = [OFF3, OFF2, OFF1, RES, RR1-E, RR1-2, RR1-1, RR1-0] - * reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0] */ + * reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0] + */ static const u8 PWM_RR[] = {206, 104, 69, 41, 26, 18, 10, 5}; static inline int PWM_RR_FROM_REG(int reg, int ix) @@ -495,9 +514,8 @@ static int PWM_RR_TO_REG(int val, int ix, int reg) int i; for (i = 0; i < 7; i++) { - if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2) { + if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2) break; - } } return (ix == 1) ? (reg & 0x8f) | (i << 4) : (reg & 0xf8) | i; @@ -516,9 +534,11 @@ static inline int PWM_RR_EN_TO_REG(int val, int ix, int reg) return val ? reg | en : reg & ~en; } -/* PWM min/off +/* + * PWM min/off * The PWM min/off bits are part of the PMW ramp rate register 0 (see above for - * the register layout). */ + * the register layout). + */ static inline int PWM_OFF_FROM_REG(int reg, int ix) { return (reg >> (ix + 5)) & 0x01; @@ -604,12 +624,13 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* In (voltage) registers */ for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { - /* Voltage inputs are stored as 16 bit values even + /* + * Voltage inputs are stored as 16 bit values even * though they have only 12 bits resolution. This is - * to make it consistent with the temp inputs. */ - if (ix == 7 && !(data->has_features & HAS_IN7)) { + * to make it consistent with the temp inputs. + */ + if (ix == 7 && !(data->has_features & HAS_IN7)) continue; - } data->in[ix] = dme1737_read(data, DME1737_REG_IN(ix)) << 8; data->in_min[ix] = dme1737_read(data, @@ -620,11 +641,13 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Temp registers */ for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) { - /* Temp inputs are stored as 16 bit values even + /* + * Temp inputs are stored as 16 bit values even * though they have only 12 bits resolution. This is * to take advantage of implicit conversions between * register values (2's complement) and temp values - * (signed decimal). */ + * (signed decimal). + */ data->temp[ix] = dme1737_read(data, DME1737_REG_TEMP(ix)) << 8; data->temp_min[ix] = dme1737_read(data, @@ -637,21 +660,21 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) } } - /* In and temp LSB registers + /* + * In and temp LSB registers * The LSBs are latched when the MSBs are read, so the order in * which the registers are read (MSB first, then LSB) is - * important! */ + * important! + */ for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { - if (ix == 5 && !(data->has_features & HAS_IN7)) { + if (ix == 5 && !(data->has_features & HAS_IN7)) continue; - } lsb[ix] = dme1737_read(data, DME1737_REG_IN_TEMP_LSB(ix)); } for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { - if (ix == 7 && !(data->has_features & HAS_IN7)) { + if (ix == 7 && !(data->has_features & HAS_IN7)) continue; - } data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] << DME1737_REG_IN_LSB_SHL[ix]) & 0xf0; } @@ -662,11 +685,12 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Fan registers */ for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { - /* Skip reading registers if optional fans are not - * present */ - if (!(data->has_features & HAS_FAN(ix))) { + /* + * Skip reading registers if optional fans are not + * present + */ + if (!(data->has_features & HAS_FAN(ix))) continue; - } data->fan[ix] = dme1737_read(data, DME1737_REG_FAN(ix)); data->fan[ix] |= dme1737_read(data, @@ -686,11 +710,12 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* PWM registers */ for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { - /* Skip reading registers if optional PWMs are not - * present */ - if (!(data->has_features & HAS_PWM(ix))) { + /* + * Skip reading registers if optional PWMs are not + * present + */ + if (!(data->has_features & HAS_PWM(ix))) continue; - } data->pwm[ix] = dme1737_read(data, DME1737_REG_PWM(ix)); data->pwm_freq[ix] = dme1737_read(data, @@ -711,9 +736,8 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Thermal zone registers */ for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { /* Skip reading registers if zone3 is not present */ - if ((ix == 2) && !(data->has_features & HAS_ZONE3)) { + if ((ix == 2) && !(data->has_features & HAS_ZONE3)) continue; - } /* sch5127 zone2 registers are special */ if ((ix == 1) && (data->type == sch5127)) { data->zone_low[1] = dme1737_read(data, @@ -737,8 +761,10 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Alarm registers */ data->alarms = dme1737_read(data, DME1737_REG_ALARM1); - /* Bit 7 tells us if the other alarm registers are non-zero and - * therefore also need to be read */ + /* + * Bit 7 tells us if the other alarm registers are non-zero and + * therefore also need to be read + */ if (data->alarms & 0x80) { data->alarms |= dme1737_read(data, DME1737_REG_ALARM2) << 8; @@ -746,22 +772,18 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) DME1737_REG_ALARM3) << 16; } - /* The ISA chips require explicit clearing of alarm bits. + /* + * The ISA chips require explicit clearing of alarm bits. * Don't worry, an alarm will come back if the condition - * that causes it still exists */ + * that causes it still exists + */ if (!data->client) { - if (data->alarms & 0xff0000) { - dme1737_write(data, DME1737_REG_ALARM3, - 0xff); - } - if (data->alarms & 0xff00) { - dme1737_write(data, DME1737_REG_ALARM2, - 0xff); - } - if (data->alarms & 0xff) { - dme1737_write(data, DME1737_REG_ALARM1, - 0xff); - } + if (data->alarms & 0xff0000) + dme1737_write(data, DME1737_REG_ALARM3, 0xff); + if (data->alarms & 0xff00) + dme1737_write(data, DME1737_REG_ALARM2, 0xff); + if (data->alarms & 0xff) + dme1737_write(data, DME1737_REG_ALARM1, 0xff); } data->last_update = jiffies; @@ -822,7 +844,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -901,7 +928,12 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -952,11 +984,10 @@ static ssize_t show_zone(struct device *dev, struct device_attribute *attr, switch (fn) { case SYS_ZONE_AUTO_CHANNELS_TEMP: /* check config2 for non-standard temp-to-zone mapping */ - if ((ix == 1) && (data->config2 & 0x02)) { + if ((ix == 1) && (data->config2 & 0x02)) res = 4; - } else { + else res = 1 << ix; - } break; case SYS_ZONE_AUTO_POINT1_TEMP_HYST: res = TEMP_FROM_REG(data->zone_low[ix], 8) - @@ -989,7 +1020,12 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -1014,8 +1050,10 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr, /* Refresh the cache */ data->zone_low[ix] = dme1737_read(data, DME1737_REG_ZONE_LOW(ix)); - /* Modify the temp range value (which is stored in the upper - * nibble of the pwm_freq register) */ + /* + * Modify the temp range value (which is stored in the upper + * nibble of the pwm_freq register) + */ data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - TEMP_FROM_REG(data->zone_low[ix], 8), dme1737_read(data, @@ -1095,7 +1133,12 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -1170,21 +1213,19 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, switch (fn) { case SYS_PWM: - if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0) { + if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0) res = 255; - } else { + else res = data->pwm[ix]; - } break; case SYS_PWM_FREQ: res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]); break; case SYS_PWM_ENABLE: - if (ix >= 3) { + if (ix >= 3) res = 1; /* pwm[5-6] hard-wired to manual mode */ - } else { + else res = PWM_EN_FROM_REG(data->pwm_config[ix]); - } break; case SYS_PWM_RAMP_RATE: /* Only valid for pwm[1-3] */ @@ -1192,19 +1233,17 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, break; case SYS_PWM_AUTO_CHANNELS_ZONE: /* Only valid for pwm[1-3] */ - if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { + if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) res = PWM_ACZ_FROM_REG(data->pwm_config[ix]); - } else { + else res = data->pwm_acz[ix]; - } break; case SYS_PWM_AUTO_PWM_MIN: /* Only valid for pwm[1-3] */ - if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix)) { + if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix)) res = data->pwm_min[ix]; - } else { + else res = 0; - } break; case SYS_PWM_AUTO_POINT1_PWM: /* Only valid for pwm[1-3] */ @@ -1233,7 +1272,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -1307,8 +1351,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, /* Change permissions of pwm[ix] to read-only */ dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], S_IRUGO); - /* Turn on auto mode using the saved zone channel - * assignment */ + /* + * Turn on auto mode using the saved zone channel + * assignment + */ data->pwm_config[ix] = PWM_ACZ_TO_REG( data->pwm_acz[ix], data->pwm_config[ix]); @@ -1338,8 +1384,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix, data->pwm_rr[ix > 0]); } - /* Enable/disable the feature only if the associated PWM - * output is in automatic mode. */ + /* + * Enable/disable the feature only if the associated PWM + * output is in automatic mode. + */ if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, data->pwm_rr[ix > 0]); @@ -1361,15 +1409,19 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm_config[ix] = dme1737_read(data, DME1737_REG_PWM_CONFIG(ix)); if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { - /* PWM is already in auto mode so update the temp - * channel assignment */ + /* + * PWM is already in auto mode so update the temp + * channel assignment + */ data->pwm_config[ix] = PWM_ACZ_TO_REG(val, data->pwm_config[ix]); dme1737_write(data, DME1737_REG_PWM_CONFIG(ix), data->pwm_config[ix]); } else { - /* PWM is not in auto mode so we save the temp - * channel assignment for later use */ + /* + * PWM is not in auto mode so we save the temp + * channel assignment for later use + */ data->pwm_acz[ix] = val; } break; @@ -1378,10 +1430,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, /* Refresh the cache */ data->pwm_min[ix] = dme1737_read(data, DME1737_REG_PWM_MIN(ix)); - /* There are only 2 values supported for the auto_pwm_min + /* + * There are only 2 values supported for the auto_pwm_min * value: 0 or auto_point1_pwm. So if the temperature drops * below the auto_point1_temp_hyst value, the fan either turns - * off or runs at auto_point1_pwm duty-cycle. */ + * off or runs at auto_point1_pwm duty-cycle. + */ if (val > ((data->pwm_min[ix] + 1) / 2)) { data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, dme1737_read(data, @@ -1426,7 +1480,12 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dme1737_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; data->vrm = val; return count; @@ -1586,10 +1645,12 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* for ISA devices */ -/* This struct holds all the attributes that are always present and need to be +/* + * This struct holds all the attributes that are always present and need to be * created unconditionally. The attributes that need modification of their * permissions are created read-only and write permissions are added or removed - * on the fly when required */ + * on the fly when required + */ static struct attribute *dme1737_attr[] = { /* Voltages */ &sensor_dev_attr_in0_input.dev_attr.attr, @@ -1652,9 +1713,11 @@ static const struct attribute_group dme1737_group = { .attrs = dme1737_attr, }; -/* The following struct holds temp offset attributes, which are not available +/* + * The following struct holds temp offset attributes, which are not available * in all chips. The following chips support them: - * DME1737, SCH311x */ + * DME1737, SCH311x + */ static struct attribute *dme1737_temp_offset_attr[] = { &sensor_dev_attr_temp1_offset.dev_attr.attr, &sensor_dev_attr_temp2_offset.dev_attr.attr, @@ -1666,9 +1729,11 @@ static const struct attribute_group dme1737_temp_offset_group = { .attrs = dme1737_temp_offset_attr, }; -/* The following struct holds VID related attributes, which are not available +/* + * The following struct holds VID related attributes, which are not available * in all chips. The following chips support them: - * DME1737 */ + * DME1737 + */ static struct attribute *dme1737_vid_attr[] = { &dev_attr_vrm.attr, &dev_attr_cpu0_vid.attr, @@ -1679,9 +1744,11 @@ static const struct attribute_group dme1737_vid_group = { .attrs = dme1737_vid_attr, }; -/* The following struct holds temp zone 3 related attributes, which are not +/* + * The following struct holds temp zone 3 related attributes, which are not * available in all chips. The following chips support them: - * DME1737, SCH311x, SCH5027 */ + * DME1737, SCH311x, SCH5027 + */ static struct attribute *dme1737_zone3_attr[] = { &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, @@ -1695,9 +1762,11 @@ static const struct attribute_group dme1737_zone3_group = { }; -/* The following struct holds temp zone hysteresis related attributes, which +/* + * The following struct holds temp zone hysteresis related attributes, which * are not available in all chips. The following chips support them: - * DME1737, SCH311x */ + * DME1737, SCH311x + */ static struct attribute *dme1737_zone_hyst_attr[] = { &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, @@ -1709,9 +1778,11 @@ static const struct attribute_group dme1737_zone_hyst_group = { .attrs = dme1737_zone_hyst_attr, }; -/* The following struct holds voltage in7 related attributes, which +/* + * The following struct holds voltage in7 related attributes, which * are not available in all chips. The following chips support them: - * SCH5127 */ + * SCH5127 + */ static struct attribute *dme1737_in7_attr[] = { &sensor_dev_attr_in7_input.dev_attr.attr, &sensor_dev_attr_in7_min.dev_attr.attr, @@ -1724,9 +1795,11 @@ static const struct attribute_group dme1737_in7_group = { .attrs = dme1737_in7_attr, }; -/* The following structs hold the PWM attributes, some of which are optional. +/* + * The following structs hold the PWM attributes, some of which are optional. * Their creation depends on the chip configuration which is determined during - * module load. */ + * module load. + */ static struct attribute *dme1737_pwm1_attr[] = { &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm1_freq.dev_attr.attr, @@ -1779,18 +1852,22 @@ static const struct attribute_group dme1737_pwm_group[] = { { .attrs = dme1737_pwm6_attr }, }; -/* The following struct holds auto PWM min attributes, which are not available +/* + * The following struct holds auto PWM min attributes, which are not available * in all chips. Their creation depends on the chip type which is determined - * during module load. */ + * during module load. + */ static struct attribute *dme1737_auto_pwm_min_attr[] = { &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, }; -/* The following structs hold the fan attributes, some of which are optional. +/* + * The following structs hold the fan attributes, some of which are optional. * Their creation depends on the chip configuration which is determined during - * module load. */ + * module load. + */ static struct attribute *dme1737_fan1_attr[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_min.dev_attr.attr, @@ -1843,8 +1920,10 @@ static const struct attribute_group dme1737_fan_group[] = { { .attrs = dme1737_fan6_attr }, }; -/* The permissions of the following zone attributes are changed to read- - * writeable if the chip is *not* locked. Otherwise they stay read-only. */ +/* + * The permissions of the following zone attributes are changed to read- + * writeable if the chip is *not* locked. Otherwise they stay read-only. + */ static struct attribute *dme1737_zone_chmod_attr[] = { &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, @@ -1860,8 +1939,10 @@ static const struct attribute_group dme1737_zone_chmod_group = { }; -/* The permissions of the following zone 3 attributes are changed to read- - * writeable if the chip is *not* locked. Otherwise they stay read-only. */ +/* + * The permissions of the following zone 3 attributes are changed to read- + * writeable if the chip is *not* locked. Otherwise they stay read-only. + */ static struct attribute *dme1737_zone3_chmod_attr[] = { &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, @@ -1873,9 +1954,11 @@ static const struct attribute_group dme1737_zone3_chmod_group = { .attrs = dme1737_zone3_chmod_attr, }; -/* The permissions of the following PWM attributes are changed to read- +/* + * The permissions of the following PWM attributes are changed to read- * writeable if the chip is *not* locked and the respective PWM is available. - * Otherwise they stay read-only. */ + * Otherwise they stay read-only. + */ static struct attribute *dme1737_pwm1_chmod_attr[] = { &sensor_dev_attr_pwm1_freq.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr, @@ -1920,8 +2003,10 @@ static const struct attribute_group dme1737_pwm_chmod_group[] = { { .attrs = dme1737_pwm6_chmod_attr }, }; -/* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the - * chip is not locked. Otherwise they are read-only. */ +/* + * Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the + * chip is not locked. Otherwise they are read-only. + */ static struct attribute *dme1737_pwm_chmod_attr[] = { &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm2.dev_attr.attr, @@ -1975,9 +2060,8 @@ static void dme1737_chmod_group(struct device *dev, { struct attribute **attr; - for (attr = group->attrs; *attr; attr++) { + for (attr = group->attrs; *attr; attr++) dme1737_chmod_file(dev, *attr, mode); - } } static void dme1737_remove_files(struct device *dev) @@ -2003,26 +2087,20 @@ static void dme1737_remove_files(struct device *dev) } } - if (data->has_features & HAS_TEMP_OFFSET) { + if (data->has_features & HAS_TEMP_OFFSET) sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group); - } - if (data->has_features & HAS_VID) { + if (data->has_features & HAS_VID) sysfs_remove_group(&dev->kobj, &dme1737_vid_group); - } - if (data->has_features & HAS_ZONE3) { + if (data->has_features & HAS_ZONE3) sysfs_remove_group(&dev->kobj, &dme1737_zone3_group); - } - if (data->has_features & HAS_ZONE_HYST) { + if (data->has_features & HAS_ZONE_HYST) sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); - } - if (data->has_features & HAS_IN7) { + if (data->has_features & HAS_IN7) sysfs_remove_group(&dev->kobj, &dme1737_in7_group); - } sysfs_remove_group(&dev->kobj, &dme1737_group); - if (!data->client) { + if (!data->client) sysfs_remove_file(&dev->kobj, &dev_attr_name.attr); - } } static int dme1737_create_files(struct device *dev) @@ -2033,48 +2111,41 @@ static int dme1737_create_files(struct device *dev) /* Create a name attribute for ISA devices */ if (!data->client) { err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr); - if (err) { + if (err) goto exit; - } } /* Create standard sysfs attributes */ err = sysfs_create_group(&dev->kobj, &dme1737_group); - if (err) { + if (err) goto exit_remove; - } /* Create chip-dependent sysfs attributes */ if (data->has_features & HAS_TEMP_OFFSET) { err = sysfs_create_group(&dev->kobj, &dme1737_temp_offset_group); - if (err) { + if (err) goto exit_remove; - } } if (data->has_features & HAS_VID) { err = sysfs_create_group(&dev->kobj, &dme1737_vid_group); - if (err) { + if (err) goto exit_remove; - } } if (data->has_features & HAS_ZONE3) { err = sysfs_create_group(&dev->kobj, &dme1737_zone3_group); - if (err) { + if (err) goto exit_remove; - } } if (data->has_features & HAS_ZONE_HYST) { err = sysfs_create_group(&dev->kobj, &dme1737_zone_hyst_group); - if (err) { + if (err) goto exit_remove; - } } if (data->has_features & HAS_IN7) { err = sysfs_create_group(&dev->kobj, &dme1737_in7_group); - if (err) { + if (err) goto exit_remove; - } } /* Create fan sysfs attributes */ @@ -2082,9 +2153,8 @@ static int dme1737_create_files(struct device *dev) if (data->has_features & HAS_FAN(ix)) { err = sysfs_create_group(&dev->kobj, &dme1737_fan_group[ix]); - if (err) { + if (err) goto exit_remove; - } } } @@ -2093,21 +2163,21 @@ static int dme1737_create_files(struct device *dev) if (data->has_features & HAS_PWM(ix)) { err = sysfs_create_group(&dev->kobj, &dme1737_pwm_group[ix]); - if (err) { + if (err) goto exit_remove; - } if ((data->has_features & HAS_PWM_MIN) && (ix < 3)) { err = sysfs_create_file(&dev->kobj, dme1737_auto_pwm_min_attr[ix]); - if (err) { + if (err) goto exit_remove; - } } } } - /* Inform if the device is locked. Otherwise change the permissions of - * selected attributes from read-only to read-writeable. */ + /* + * Inform if the device is locked. Otherwise change the permissions of + * selected attributes from read-only to read-writeable. + */ if (data->config & 0x02) { dev_info(dev, "Device is locked. Some attributes " "will be read-only.\n"); @@ -2194,26 +2264,30 @@ static int dme1737_init_device(struct device *dev) return -EFAULT; } - /* Determine which optional fan and pwm features are enabled (only - * valid for I2C devices) */ + /* + * Determine which optional fan and pwm features are enabled (only + * valid for I2C devices) + */ if (client) { /* I2C chip */ data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); /* Check if optional fan3 input is enabled */ - if (data->config2 & 0x04) { + if (data->config2 & 0x04) data->has_features |= HAS_FAN(2); - } - /* Fan4 and pwm3 are only available if the client's I2C address + /* + * Fan4 and pwm3 are only available if the client's I2C address * is the default 0x2e. Otherwise the I/Os associated with - * these functions are used for addr enable/select. */ - if (client->addr == 0x2e) { + * these functions are used for addr enable/select. + */ + if (client->addr == 0x2e) data->has_features |= HAS_FAN(3) | HAS_PWM(2); - } - /* Determine which of the optional fan[5-6] and pwm[5-6] + /* + * Determine which of the optional fan[5-6] and pwm[5-6] * features are enabled. For this, we need to query the runtime * registers through the Super-IO LPC interface. Try both - * config ports 0x2e and 0x4e. */ + * config ports 0x2e and 0x4e. + */ if (dme1737_i2c_get_features(0x2e, data) && dme1737_i2c_get_features(0x4e, data)) { dev_warn(dev, "Failed to query Super-IO for optional " @@ -2271,9 +2345,11 @@ static int dme1737_init_device(struct device *dev) ((reg >> 4) & 0x03) + 1); } - /* Switch pwm[1-3] to manual mode if they are currently disabled and + /* + * Switch pwm[1-3] to manual mode if they are currently disabled and * set the duty-cycles to 0% (which is identical to the PWMs being - * disabled). */ + * disabled). + */ if (!(data->config & 0x02)) { for (ix = 0; ix < 3; ix++) { data->pwm_config[ix] = dme1737_read(data, @@ -2298,9 +2374,8 @@ static int dme1737_init_device(struct device *dev) data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ /* Set VRM */ - if (data->has_features & HAS_VID) { + if (data->has_features & HAS_VID) data->vrm = vid_which_vrm(); - } return 0; } @@ -2318,8 +2393,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) dme1737_sio_enter(sio_cip); - /* Check device ID - * We currently know about two kinds of DME1737 and SCH5027. */ + /* + * Check device ID + * We currently know about two kinds of DME1737 and SCH5027. + */ reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 || reg == SCH5027_ID)) { @@ -2338,21 +2415,19 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) goto exit; } - /* Read the runtime registers to determine which optional features + /* + * Read the runtime registers to determine which optional features * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set - * to '10' if the respective feature is enabled. */ - if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ + * to '10' if the respective feature is enabled. + */ + if ((inb(addr + 0x43) & 0x0c) == 0x08) /* fan6 */ data->has_features |= HAS_FAN(5); - } - if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ + if ((inb(addr + 0x44) & 0x0c) == 0x08) /* pwm6 */ data->has_features |= HAS_PWM(5); - } - if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ + if ((inb(addr + 0x45) & 0x0c) == 0x08) /* fan5 */ data->has_features |= HAS_FAN(4); - } - if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ + if ((inb(addr + 0x46) & 0x0c) == 0x08) /* pwm5 */ data->has_features |= HAS_PWM(4); - } exit: dme1737_sio_exit(sio_cip); @@ -2369,9 +2444,8 @@ static int dme1737_i2c_detect(struct i2c_client *client, u8 company, verstep = 0; const char *name; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - } company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY); verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP); @@ -2486,8 +2560,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) dme1737_sio_enter(sio_cip); - /* Check device ID - * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 */ + /* + * Check device ID + * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 + */ reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID || reg == SCH5127_ID)) { @@ -2507,8 +2583,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) goto exit; } - /* Access to the hwmon registers is through an index/data register - * pair located at offset 0x70/0x71. */ + /* + * Access to the hwmon registers is through an index/data register + * pair located at offset 0x70/0x71. + */ *addr = base_addr + 0x70; exit: @@ -2610,11 +2688,10 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) } } - if (data->type == sch5127) { + if (data->type == sch5127) data->name = "sch5127"; - } else { + else data->name = "sch311x"; - } /* Initialize the mutex */ mutex_init(&data->update_lock); @@ -2689,9 +2766,8 @@ static int __init dme1737_init(void) unsigned short addr; err = i2c_add_driver(&dme1737_i2c_driver); - if (err) { + if (err) goto exit; - } if (dme1737_isa_detect(0x2e, &addr) && dme1737_isa_detect(0x4e, &addr) && @@ -2703,15 +2779,13 @@ static int __init dme1737_init(void) } err = platform_driver_register(&dme1737_isa_driver); - if (err) { + if (err) goto exit_del_i2c_driver; - } /* Sets global pdev as a side effect */ err = dme1737_isa_device_add(addr); - if (err) { + if (err) goto exit_del_isa_driver; - } return 0; diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index ef1ac996752e..f647a3307ebc 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -1,25 +1,25 @@ /* - ds1621.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Christian W. Zuckschwerdt <zany@triq.net> 2000-11-23 - based on lm75.c by Frodo Looijaard <frodol@dds.nl> - Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with - the help of Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * ds1621.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Christian W. Zuckschwerdt <zany@triq.net> 2000-11-23 + * based on lm75.c by Frodo Looijaard <frodol@dds.nl> + * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with + * the help of Jean Delvare <khali@linux-fr.org> + * + * 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 <linux/module.h> #include <linux/init.h> @@ -67,7 +67,7 @@ static const u8 DS1621_REG_TEMP[3] = { /* Conversions */ #define ALARMS_FROM_REG(val) ((val) & \ - (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) + (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) /* Each client has this additional data */ struct ds1621_data { @@ -93,10 +93,10 @@ static void ds1621_init_client(struct i2c_client *client) new_conf &= ~DS1621_REG_CONFIG_POLARITY; else if (polarity == 1) new_conf |= DS1621_REG_CONFIG_POLARITY; - + if (conf != new_conf) i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf); - + /* start conversion */ i2c_smbus_write_byte(client, DS1621_COM_START); } @@ -155,10 +155,15 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); struct ds1621_data *data = i2c_get_clientdata(client); - u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10)); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - data->temp[attr->index] = val; + data->temp[attr->index] = LM75_TEMP_TO_REG(val); i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index], data->temp[attr->index]); mutex_unlock(&data->update_lock); @@ -212,14 +217,17 @@ static int ds1621_detect(struct i2c_client *client, int conf, temp; int i; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA - | I2C_FUNC_SMBUS_WORD_DATA + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_WRITE_BYTE)) return -ENODEV; - /* Now, we do the remaining detection. It is lousy. */ - /* The NVB bit should be low if no EEPROM write has been requested - during the latest 10ms, which is highly improbable in our case. */ + /* + * Now, we do the remaining detection. It is lousy. + * + * The NVB bit should be low if no EEPROM write has been requested + * during the latest 10ms, which is highly improbable in our case. + */ conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); if (conf < 0 || conf & DS1621_REG_CONFIG_NVB) return -ENODEV; @@ -254,7 +262,8 @@ static int ds1621_probe(struct i2c_client *client, ds1621_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) + err = sysfs_create_group(&client->dev.kobj, &ds1621_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); @@ -265,11 +274,11 @@ static int ds1621_probe(struct i2c_client *client, return 0; - exit_remove_files: + exit_remove_files: sysfs_remove_group(&client->dev.kobj, &ds1621_group); - exit_free: + exit_free: kfree(data); - exit: + exit: return err; } @@ -305,20 +314,8 @@ static struct i2c_driver ds1621_driver = { .address_list = normal_i2c, }; -static int __init ds1621_init(void) -{ - return i2c_add_driver(&ds1621_driver); -} - -static void __exit ds1621_exit(void) -{ - i2c_del_driver(&ds1621_driver); -} - +module_i2c_driver(ds1621_driver); MODULE_AUTHOR("Christian W. Zuckschwerdt <zany@triq.net>"); MODULE_DESCRIPTION("DS1621 driver"); MODULE_LICENSE("GPL"); - -module_init(ds1621_init); -module_exit(ds1621_exit); diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c index 300c3d4d67df..50663efad412 100644 --- a/drivers/hwmon/ds620.c +++ b/drivers/hwmon/ds620.c @@ -297,19 +297,8 @@ static struct i2c_driver ds620_driver = { .id_table = ds620_id, }; -static int __init ds620_init(void) -{ - return i2c_add_driver(&ds620_driver); -} - -static void __exit ds620_exit(void) -{ - i2c_del_driver(&ds620_driver); -} +module_i2c_driver(ds620_driver); MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); MODULE_DESCRIPTION("DS620 driver"); MODULE_LICENSE("GPL"); - -module_init(ds620_init); -module_exit(ds620_exit); diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 270ffab711cb..149dcb0e148f 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c @@ -41,8 +41,10 @@ struct thermal_data { struct device *hwmon_dev; struct mutex mutex; - /* Cache the hyst value so we don't keep re-reading it. In theory - we could cache it forever as nobody else should be writing it. */ + /* + * Cache the hyst value so we don't keep re-reading it. In theory + * we could cache it forever as nobody else should be writing it. + */ u8 cached_hyst; unsigned long hyst_valid; }; @@ -283,8 +285,10 @@ static int emc1403_detect(struct i2c_client *client, case 0x23: strlcpy(info->type, "emc1423", I2C_NAME_SIZE); break; - /* Note: 0x25 is the 1404 which is very similar and this - driver could be extended */ + /* + * Note: 0x25 is the 1404 which is very similar and this + * driver could be extended + */ default: return -ENODEV; } @@ -366,18 +370,7 @@ static struct i2c_driver sensor_emc1403 = { .address_list = emc1403_address_list, }; -static int __init sensor_emc1403_init(void) -{ - return i2c_add_driver(&sensor_emc1403); -} - -static void __exit sensor_emc1403_exit(void) -{ - i2c_del_driver(&sensor_emc1403); -} - -module_init(sensor_emc1403_init); -module_exit(sensor_emc1403_exit); +module_i2c_driver(sensor_emc1403); MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com"); MODULE_DESCRIPTION("emc1403 Thermal Driver"); diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index 865063914d76..9691f664c76e 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -1,21 +1,21 @@ /* - emc2103.c - Support for SMSC EMC2103 - Copyright (c) 2010 SMSC - - 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. -*/ + * emc2103.c - Support for SMSC EMC2103 + * Copyright (c) 2010 SMSC + * + * 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 <linux/module.h> #include <linux/init.h> @@ -48,12 +48,14 @@ static const u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 }; /* equation 4 from datasheet: rpm = (3932160 * multipler) / count */ #define FAN_RPM_FACTOR 3932160 -/* 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes +/* + * 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes * in anti-parallel mode, and in this configuration both can be read * independently (so we have 4 temperature inputs). The device can't * detect if it's connected in this mode, so we have to manually enable * it. Default is to leave the device in the state it's already in (-1). - * This parameter allows APD mode to be optionally forced on or off */ + * This parameter allows APD mode to be optionally forced on or off + */ static int apd = -1; module_param(apd, bint, 0); MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode"); @@ -302,10 +304,12 @@ show_fan_div(struct device *dev, struct device_attribute *da, char *buf) return sprintf(buf, "%d\n", fan_div); } -/* Note: we also update the fan target here, because its value is - determined in part by the fan clock divider. This follows the principle - of least surprise; the user doesn't expect the fan target to change just - because the divider changed. */ +/* + * Note: we also update the fan target here, because its value is + * determined in part by the fan clock divider. This follows the principle + * of least surprise; the user doesn't expect the fan target to change just + * because the divider changed. + */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -722,19 +726,8 @@ static struct i2c_driver emc2103_driver = { .address_list = normal_i2c, }; -static int __init sensors_emc2103_init(void) -{ - return i2c_add_driver(&emc2103_driver); -} - -static void __exit sensors_emc2103_exit(void) -{ - i2c_del_driver(&emc2103_driver); -} +module_i2c_driver(emc2103_driver); MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>"); MODULE_DESCRIPTION("SMSC EMC2103 hwmon driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_emc2103_init); -module_exit(sensors_emc2103_exit); diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c index 6ebb9b738c9c..840f5112e602 100644 --- a/drivers/hwmon/emc6w201.c +++ b/drivers/hwmon/emc6w201.c @@ -552,17 +552,7 @@ static struct i2c_driver emc6w201_driver = { .address_list = normal_i2c, }; -static int __init sensors_emc6w201_init(void) -{ - return i2c_add_driver(&emc6w201_driver); -} -module_init(sensors_emc6w201_init); - -static void __exit sensors_emc6w201_exit(void) -{ - i2c_del_driver(&emc6w201_driver); -} -module_exit(sensors_emc6w201_exit); +module_i2c_driver(emc6w201_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver"); diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 6dbfd3e516e4..3e4da620e9c7 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -202,7 +202,7 @@ struct f71805f_sio_data { static inline long in_from_reg(u8 reg) { - return (reg * 8); + return reg * 8; } /* The 2 least significant bits are not used */ @@ -212,13 +212,13 @@ static inline u8 in_to_reg(long val) return 0; if (val >= 2016) return 0xfc; - return (((val + 16) / 32) << 2); + return ((val + 16) / 32) << 2; } /* in0 is downscaled by a factor 2 internally */ static inline long in0_from_reg(u8 reg) { - return (reg * 16); + return reg * 16; } static inline u8 in0_to_reg(long val) @@ -227,7 +227,7 @@ static inline u8 in0_to_reg(long val) return 0; if (val >= 4032) return 0xfc; - return (((val + 32) / 64) << 2); + return ((val + 32) / 64) << 2; } /* The 4 most significant bits are not used */ @@ -236,17 +236,19 @@ static inline long fan_from_reg(u16 reg) reg &= 0xfff; if (!reg || reg == 0xfff) return 0; - return (1500000 / reg); + return 1500000 / reg; } static inline u16 fan_to_reg(long rpm) { - /* If the low limit is set below what the chip can measure, - store the largest possible 12-bit value in the registers, - so that no alarm will ever trigger. */ + /* + * If the low limit is set below what the chip can measure, + * store the largest possible 12-bit value in the registers, + * so that no alarm will ever trigger. + */ if (rpm < 367) return 0xfff; - return (1500000 / rpm); + return 1500000 / rpm; } static inline unsigned long pwm_freq_from_reg(u8 reg) @@ -278,7 +280,7 @@ static inline int pwm_mode_from_reg(u8 reg) static inline long temp_from_reg(u8 reg) { - return (reg * 1000); + return reg * 1000; } static inline u8 temp_to_reg(long val) @@ -308,9 +310,11 @@ static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) outb(val, data->addr + DATA_REG_OFFSET); } -/* It is important to read the MSB first, because doing so latches the - value of the LSB, so we are sure both bytes belong to the same value. - Must be called with data->update_lock held, except during initialization */ +/* + * It is important to read the MSB first, because doing so latches the + * value of the LSB, so we are sure both bytes belong to the same value. + * Must be called with data->update_lock held, except during initialization + */ static u16 f71805f_read16(struct f71805f_data *data, u8 reg) { u16 val; @@ -455,7 +459,12 @@ static ssize_t set_in0_max(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_high[nr] = in0_to_reg(val); @@ -471,7 +480,12 @@ static ssize_t set_in0_min(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_low[nr] = in0_to_reg(val); @@ -517,7 +531,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_high[nr] = in_to_reg(val); @@ -533,7 +552,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_low[nr] = in_to_reg(val); @@ -579,7 +603,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_low[nr] = fan_to_reg(val); @@ -595,7 +624,12 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_target[nr] = fan_to_reg(val); @@ -664,7 +698,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; if (val > 255) return -EINVAL; @@ -685,8 +724,13 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); u8 reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; if (val < 1 || val > 3) return -EINVAL; @@ -730,7 +774,12 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm_freq[nr] = pwm_freq_to_reg(val); @@ -742,7 +791,7 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute static ssize_t show_pwm_auto_point_temp(struct device *dev, struct device_attribute *devattr, - char* buf) + char *buf) { struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); @@ -755,13 +804,18 @@ static ssize_t show_pwm_auto_point_temp(struct device *dev, static ssize_t set_pwm_auto_point_temp(struct device *dev, struct device_attribute *devattr, - const char* buf, size_t count) + const char *buf, size_t count) { struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); int pwmnr = attr->nr; int apnr = attr->index; - unsigned long val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val); @@ -774,7 +828,7 @@ static ssize_t set_pwm_auto_point_temp(struct device *dev, static ssize_t show_pwm_auto_point_fan(struct device *dev, struct device_attribute *devattr, - char* buf) + char *buf) { struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); @@ -787,18 +841,23 @@ static ssize_t show_pwm_auto_point_fan(struct device *dev, static ssize_t set_pwm_auto_point_fan(struct device *dev, struct device_attribute *devattr, - const char* buf, size_t count) + const char *buf, size_t count) { struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); int pwmnr = attr->nr; int apnr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val); f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr), - data->auto_points[pwmnr].fan[apnr]); + data->auto_points[pwmnr].fan[apnr]); mutex_unlock(&data->update_lock); return count; @@ -851,7 +910,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_high[nr] = temp_to_reg(val); @@ -867,7 +931,12 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_hyst[nr] = temp_to_reg(val); @@ -920,9 +989,9 @@ static ssize_t show_name(struct device *dev, struct device_attribute } static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0); -static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, +static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, show_in0_max, set_in0_max, 0); -static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, +static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, show_in0_min, set_in0_min, 0); static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, @@ -1010,8 +1079,10 @@ static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_hyst, set_temp_hyst, 2); static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2); -/* pwm (value) files are created read-only, write permission is - then added or removed dynamically as needed */ +/* + * pwm (value) files are created read-only, write permission is + * then added or removed dynamically as needed + */ static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0); static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, set_pwm_enable, 0); @@ -1246,8 +1317,10 @@ static const struct attribute_group f71805f_group_optin[4] = { { .attrs = f71805f_attributes_optin[3] }, }; -/* We don't include pwm_freq files in the arrays above, because they must be - created conditionally (only if pwm_mode is 1 == PWM) */ +/* + * We don't include pwm_freq files in the arrays above, because they must be + * created conditionally (only if pwm_mode is 1 == PWM) + */ static struct attribute *f71805f_attributes_pwm_freq[] = { &sensor_dev_attr_pwm1_freq.dev_attr.attr, &sensor_dev_attr_pwm2_freq.dev_attr.attr, @@ -1282,13 +1355,17 @@ static void __devinit f71805f_init_device(struct f71805f_data *data) f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); } - /* Fan monitoring can be disabled. If it is, we won't be polling - the register values, and won't create the related sysfs files. */ + /* + * Fan monitoring can be disabled. If it is, we won't be polling + * the register values, and won't create the related sysfs files. + */ for (i = 0; i < 3; i++) { data->fan_ctrl[i] = f71805f_read8(data, F71805F_REG_FAN_CTRL(i)); - /* Clear latch full bit, else "speed mode" fan speed control - doesn't work */ + /* + * Clear latch full bit, else "speed mode" fan speed control + * doesn't work + */ if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) { data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL; f71805f_write8(data, F71805F_REG_FAN_CTRL(i), @@ -1304,12 +1381,13 @@ static int __devinit f71805f_probe(struct platform_device *pdev) struct resource *res; int i, err; - static const char *names[] = { + static const char * const names[] = { "f71805f", "f71872f", }; - if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; pr_err("Out of memory\n"); goto exit; @@ -1347,40 +1425,47 @@ static int __devinit f71805f_probe(struct platform_device *pdev) f71805f_init_device(data); /* Register sysfs interface files */ - if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) + err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group); + if (err) goto exit_release_region; if (data->has_in & (1 << 4)) { /* in4 */ - if ((err = sysfs_create_group(&pdev->dev.kobj, - &f71805f_group_optin[0]))) + err = sysfs_create_group(&pdev->dev.kobj, + &f71805f_group_optin[0]); + if (err) goto exit_remove_files; } if (data->has_in & (1 << 8)) { /* in8 */ - if ((err = sysfs_create_group(&pdev->dev.kobj, - &f71805f_group_optin[1]))) + err = sysfs_create_group(&pdev->dev.kobj, + &f71805f_group_optin[1]); + if (err) goto exit_remove_files; } if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */ - if ((err = sysfs_create_group(&pdev->dev.kobj, - &f71805f_group_optin[2]))) + err = sysfs_create_group(&pdev->dev.kobj, + &f71805f_group_optin[2]); + if (err) goto exit_remove_files; } if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */ - if ((err = sysfs_create_group(&pdev->dev.kobj, - &f71805f_group_optin[3]))) + err = sysfs_create_group(&pdev->dev.kobj, + &f71805f_group_optin[3]); + if (err) goto exit_remove_files; } for (i = 0; i < 3; i++) { /* If control mode is PWM, create pwm_freq file */ if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) { - if ((err = sysfs_create_file(&pdev->dev.kobj, - f71805f_attributes_pwm_freq[i]))) + err = sysfs_create_file(&pdev->dev.kobj, + f71805f_attributes_pwm_freq[i]); + if (err) goto exit_remove_files; } /* If PWM is in manual mode, add write permission */ if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) { - if ((err = sysfs_chmod_file(&pdev->dev.kobj, - f71805f_attr_pwm[i], - S_IRUGO | S_IWUSR))) { + err = sysfs_chmod_file(&pdev->dev.kobj, + f71805f_attr_pwm[i], + S_IRUGO | S_IWUSR); + if (err) { dev_err(&pdev->dev, "chmod +w pwm%d failed\n", i + 1); goto exit_remove_files; @@ -1495,7 +1580,7 @@ static int __init f71805f_find(int sioaddr, unsigned short *address, int err = -ENODEV; u16 devid; - static const char *names[] = { + static const char * const names[] = { "F71805F/FG", "F71872F/FG or F71806F/FG", }; diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index e50305819f01..6d1226365e30 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -112,7 +112,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg, f71889fg, f71889ed, f71889a, f8000, f81865f }; -static const char *f71882fg_names[] = { +static const char *const f71882fg_names[] = { "f71808e", "f71808a", "f71858fg", @@ -252,9 +252,11 @@ struct f71882fg_data { u16 fan_full_speed[4]; u8 fan_status; u8 fan_beep; - /* Note: all models have max 3 temperature channels, but on some - they are addressed as 0-2 and on others as 1-3, so for coding - convenience we reserve space for 4 channels */ + /* + * Note: all models have max 3 temperature channels, but on some + * they are addressed as 0-2 and on others as 1-3, so for coding + * convenience we reserve space for 4 channels + */ u16 temp[4]; u8 temp_ovt[4]; u8 temp_high[4]; @@ -362,7 +364,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf); -static int __devinit f71882fg_probe(struct platform_device * pdev); +static int __devinit f71882fg_probe(struct platform_device *pdev); static int f71882fg_remove(struct platform_device *pdev); static struct platform_driver f71882fg_driver = { @@ -376,8 +378,10 @@ static struct platform_driver f71882fg_driver = { static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -/* Temp attr for the f71858fg, the f71858fg is special as it has its - temperature indexes start at 0 (the others start at 1) */ +/* + * Temp attr for the f71858fg, the f71858fg is special as it has its + * temperature indexes start at 0 (the others start at 1) + */ static struct sensor_device_attribute_2 f71858fg_temp_attr[] = { SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, @@ -424,9 +428,11 @@ static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { { store_temp_max, 0, 1), SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, store_temp_max_hyst, 0, 1), - /* Should really be temp1_max_alarm, but older versions did not handle - the max and crit alarms separately and lm_sensors v2 depends on the - presence of temp#_alarm files. The same goes for temp2/3 _alarm. */ + /* + * Should really be temp1_max_alarm, but older versions did not handle + * the max and crit alarms separately and lm_sensors v2 depends on the + * presence of temp#_alarm files. The same goes for temp2/3 _alarm. + */ SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, store_temp_crit, 0, 1), @@ -485,10 +491,11 @@ static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { { store_temp_beep, 0, 7), } }; -/* Temp attr for the f8000 - Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) - is used as hysteresis value to clear alarms - Also like the f71858fg its temperature indexes start at 0 +/* + * Temp attr for the f8000 + * Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) + * is used as hysteresis value to clear alarms + * Also like the f71858fg its temperature indexes start at 0 */ static struct sensor_device_attribute_2 f8000_temp_attr[] = { SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), @@ -603,8 +610,10 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { store_fan_beep, 0, 3), }; -/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the - standard models */ +/* + * PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the + * standard models + */ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { { SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, show_pwm_auto_point_channel, @@ -673,9 +682,11 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { { show_pwm_auto_point_temp_hyst, NULL, 3, 2), } }; -/* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the - pwm setting when the temperature is above the pwmX_auto_point1_temp can be - programmed instead of being hardcoded to 0xff */ +/* + * PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the + * pwm setting when the temperature is above the pwmX_auto_point1_temp can be + * programmed instead of being hardcoded to 0xff + */ static struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { { SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, show_pwm_auto_point_channel, @@ -925,9 +936,11 @@ static struct sensor_device_attribute_2 f8000_fan_attr[] = { SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), }; -/* PWM attr for the f8000, zones mapped to temp instead of to pwm! - Also the register block at offset A0 maps to TEMP1 (so our temp2, as the - F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */ +/* + * PWM attr for the f8000, zones mapped to temp instead of to pwm! + * Also the register block at offset A0 maps to TEMP1 (so our temp2, as the + * F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 + */ static struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { { SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, show_pwm_auto_point_channel, @@ -2295,8 +2308,10 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) data->temp_config = f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG); if (data->temp_config & 0x10) - /* The f71858fg temperature alarms behave as - the f8000 alarms in this mode */ + /* + * The f71858fg temperature alarms behave as + * the f8000 alarms in this mode + */ err = f71882fg_create_sysfs_files(pdev, f8000_temp_attr, ARRAY_SIZE(f8000_temp_attr)); diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 6aa5a9fad879..729499e75210 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -917,19 +917,8 @@ static int f75375_detect(struct i2c_client *client, return 0; } -static int __init sensors_f75375_init(void) -{ - return i2c_add_driver(&f75375_driver); -} - -static void __exit sensors_f75375_exit(void) -{ - i2c_del_driver(&f75375_driver); -} +module_i2c_driver(f75375_driver); MODULE_AUTHOR("Riku Voipio"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("F75373/F75375/F75387 hardware monitoring driver"); - -module_init(sensors_f75375_init); -module_exit(sensors_f75375_exit); diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 523f8fb9e7d9..b7494af1e4a9 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -60,15 +60,15 @@ static ssize_t show_power(struct device *dev, pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), REG_TDP_RUNNING_AVERAGE, &val); running_avg_capture = (val >> 4) & 0x3fffff; - running_avg_capture = sign_extend32(running_avg_capture, 22); - running_avg_range = val & 0xf; + running_avg_capture = sign_extend32(running_avg_capture, 21); + running_avg_range = (val & 0xf) + 1; pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), REG_TDP_LIMIT3, &val); tdp_limit = val >> 16; - curr_pwr_watts = tdp_limit + data->base_tdp - - (s32)(running_avg_capture >> (running_avg_range + 1)); + curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range; + curr_pwr_watts -= running_avg_capture; curr_pwr_watts *= data->tdp_to_watts; /* @@ -78,7 +78,7 @@ static ssize_t show_power(struct device *dev, * scaling factor 1/(2^16). For conversion we use * (10^6)/(2^16) = 15625/(2^10) */ - curr_pwr_watts = (curr_pwr_watts * 15625) >> 10; + curr_pwr_watts = (curr_pwr_watts * 15625) >> (10 + running_avg_range); return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts); } static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL); diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index aa6d8b686f82..8305d29459bd 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -1,4 +1,5 @@ -/* fschmd.c +/* + * fschmd.c * * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com> * @@ -76,12 +77,12 @@ enum chips { fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl }; #define FSCHMD_CONTROL_ALERT_LED 0x01 /* watchdog */ -static const u8 FSCHMD_REG_WDOG_CONTROL[7] = - { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 }; -static const u8 FSCHMD_REG_WDOG_STATE[7] = - { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 }; -static const u8 FSCHMD_REG_WDOG_PRESET[7] = - { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a }; +static const u8 FSCHMD_REG_WDOG_CONTROL[7] = { + 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 }; +static const u8 FSCHMD_REG_WDOG_STATE[7] = { + 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 }; +static const u8 FSCHMD_REG_WDOG_PRESET[7] = { + 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a }; #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 #define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ @@ -103,10 +104,12 @@ static const u8 FSCHMD_REG_VOLT[7][6] = { static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 }; -/* minimum pwm at which the fan is driven (pwm can by increased depending on - the temp. Notice that for the scy some fans share there minimum speed. - Also notice that with the scy the sensor order is different than with the - other chips, this order was in the 2.4 driver and kept for consistency. */ +/* + * minimum pwm at which the fan is driven (pwm can by increased depending on + * the temp. Notice that for the scy some fans share there minimum speed. + * Also notice that with the scy the sensor order is different than with the + * other chips, this order was in the 2.4 driver and kept for consistency. + */ static const u8 FSCHMD_REG_FAN_MIN[7][7] = { { 0x55, 0x65 }, /* pos */ { 0x55, 0x65, 0xb5 }, /* her */ @@ -182,11 +185,13 @@ static const u8 FSCHMD_REG_TEMP_STATE[7][11] = { 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 }, }; -/* temperature high limit registers, FSC does not document these. Proven to be - there with field testing on the fscher and fschrc, already supported / used - in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers - at these addresses, but doesn't want to confirm they are the same as with - the fscher?? */ +/* + * temperature high limit registers, FSC does not document these. Proven to be + * there with field testing on the fscher and fschrc, already supported / used + * in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers + * at these addresses, but doesn't want to confirm they are the same as with + * the fscher?? + */ static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { { 0, 0, 0 }, /* pos */ { 0x76, 0x86, 0x96 }, /* her */ @@ -198,13 +203,15 @@ static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { 0xba, 0xca, 0xda, 0xea, 0xfa }, }; -/* These were found through experimenting with an fscher, currently they are - not used, but we keep them around for future reference. - On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc), - AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence - the fan speed. -static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; -static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ +/* + * These were found through experimenting with an fscher, currently they are + * not used, but we keep them around for future reference. + * On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc), + * AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence + * the fan speed. + * static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; + * static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; + */ static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; @@ -290,24 +297,30 @@ struct fschmd_data { u8 fan_ripple[7]; /* divider for rps */ }; -/* Global variables to hold information read from special DMI tables, which are - available on FSC machines with an fscher or later chip. There is no need to - protect these with a lock as they are only modified from our attach function - which always gets called with the i2c-core lock held and never accessed - before the attach function is done with them. */ +/* + * Global variables to hold information read from special DMI tables, which are + * available on FSC machines with an fscher or later chip. There is no need to + * protect these with a lock as they are only modified from our attach function + * which always gets called with the i2c-core lock held and never accessed + * before the attach function is done with them. + */ static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 }; static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 }; static int dmi_vref = -1; -/* Somewhat ugly :( global data pointer list with all fschmd devices, so that - we can find our device data as when using misc_register there is no other - method to get to ones device data from the open fop. */ +/* + * Somewhat ugly :( global data pointer list with all fschmd devices, so that + * we can find our device data as when using misc_register there is no other + * method to get to ones device data from the open fop. + */ static LIST_HEAD(watchdog_data_list); /* Note this lock not only protect list access, but also data.kref access */ static DEFINE_MUTEX(watchdog_data_mutex); -/* Release our data struct when we're detached from the i2c client *and* all - references to our watchdog device are released */ +/* + * Release our data struct when we're detached from the i2c client *and* all + * references to our watchdog device are released + */ static void fschmd_release_resources(struct kref *ref) { struct fschmd_data *data = container_of(ref, struct fschmd_data, kref); @@ -359,9 +372,14 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute { int index = to_sensor_dev_attr(devattr)->index; struct fschmd_data *data = dev_get_drvdata(dev); - long v = simple_strtol(buf, NULL, 10) / 1000; + long v; + int err; - v = SENSORS_LIMIT(v, -128, 127) + 128; + err = kstrtol(buf, 10, &v); + if (err) + return err; + + v = SENSORS_LIMIT(v / 1000, -128, 127) + 128; mutex_lock(&data->update_lock); i2c_smbus_write_byte_data(to_i2c_client(dev), @@ -427,12 +445,23 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute int index = to_sensor_dev_attr(devattr)->index; struct fschmd_data *data = dev_get_drvdata(dev); /* supported values: 2, 4, 8 */ - unsigned long v = simple_strtoul(buf, NULL, 10); + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; switch (v) { - case 2: v = 1; break; - case 4: v = 2; break; - case 8: v = 3; break; + case 2: + v = 1; + break; + case 4: + v = 2; + break; + case 8: + v = 3; + break; default: dev_err(dev, "fan_div value %lu not supported. " "Choose one of 2, 4 or 8!\n", v); @@ -502,7 +531,12 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, { int index = to_sensor_dev_attr(devattr)->index; struct fschmd_data *data = dev_get_drvdata(dev); - unsigned long v = simple_strtoul(buf, NULL, 10); + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */ if (v || data->kind == fscsyl) { @@ -522,8 +556,10 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, } -/* The FSC hwmon family has the ability to force an attached alert led to flash - from software, we export this as an alert_led sysfs attr */ +/* + * The FSC hwmon family has the ability to force an attached alert led to flash + * from software, we export this as an alert_led sysfs attr + */ static ssize_t show_alert_led(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -540,7 +576,12 @@ static ssize_t store_alert_led(struct device *dev, { u8 reg; struct fschmd_data *data = dev_get_drvdata(dev); - unsigned long v = simple_strtoul(buf, NULL, 10); + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; mutex_lock(&data->update_lock); @@ -754,8 +795,10 @@ static int watchdog_stop(struct fschmd_data *data) } data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED; - /* Don't store the stop flag in our watchdog control register copy, as - its a write only bit (read always returns 0) */ + /* + * Don't store the stop flag in our watchdog control register copy, as + * its a write only bit (read always returns 0) + */ i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL[data->kind], data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP); @@ -769,10 +812,12 @@ static int watchdog_open(struct inode *inode, struct file *filp) struct fschmd_data *pos, *data = NULL; int watchdog_is_open; - /* We get called from drivers/char/misc.c with misc_mtx hold, and we - call misc_register() from fschmd_probe() with watchdog_data_mutex - hold, as misc_register() takes the misc_mtx lock, this is a possible - deadlock, so we use mutex_trylock here. */ + /* + * We get called from drivers/char/misc.c with misc_mtx hold, and we + * call misc_register() from fschmd_probe() with watchdog_data_mutex + * hold, as misc_register() takes the misc_mtx lock, this is a possible + * deadlock, so we use mutex_trylock here. + */ if (!mutex_trylock(&watchdog_data_mutex)) return -ERESTARTSYS; list_for_each_entry(pos, &watchdog_data_list, list) { @@ -847,7 +892,8 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, return count; } -static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +static long watchdog_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) { struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | @@ -930,30 +976,38 @@ static const struct file_operations watchdog_fops = { * Detect, register, unregister and update device functions */ -/* DMI decode routine to read voltage scaling factors from special DMI tables, - which are available on FSC machines with an fscher or later chip. */ +/* + * DMI decode routine to read voltage scaling factors from special DMI tables, + * which are available on FSC machines with an fscher or later chip. + */ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) { int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0; - /* dmi code ugliness, we get passed the address of the contents of - a complete DMI record, but in the form of a dmi_header pointer, in - reality this address holds header->length bytes of which the header - are the first 4 bytes */ + /* + * dmi code ugliness, we get passed the address of the contents of + * a complete DMI record, but in the form of a dmi_header pointer, in + * reality this address holds header->length bytes of which the header + * are the first 4 bytes + */ u8 *dmi_data = (u8 *)header; /* We are looking for OEM-specific type 185 */ if (header->type != 185) return; - /* we are looking for what Siemens calls "subtype" 19, the subtype - is stored in byte 5 of the dmi block */ + /* + * we are looking for what Siemens calls "subtype" 19, the subtype + * is stored in byte 5 of the dmi block + */ if (header->length < 5 || dmi_data[4] != 19) return; - /* After the subtype comes 1 unknown byte and then blocks of 5 bytes, - consisting of what Siemens calls an "Entity" number, followed by - 2 16-bit words in LSB first order */ + /* + * After the subtype comes 1 unknown byte and then blocks of 5 bytes, + * consisting of what Siemens calls an "Entity" number, followed by + * 2 16-bit words in LSB first order + */ for (i = 6; (i + 4) < header->length; i += 5) { /* entity 1 - 3: voltage multiplier and offset */ if (dmi_data[i] >= 1 && dmi_data[i] <= 3) { @@ -988,9 +1042,11 @@ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) dmi_mult[i] = mult[i] * 10; dmi_offset[i] = offset[i] * 10; } - /* According to the docs there should be separate dmi entries - for the mult's and offsets of in3-5 of the syl, but on - my test machine these are not present */ + /* + * According to the docs there should be separate dmi entries + * for the mult's and offsets of in3-5 of the syl, but on + * my test machine these are not present + */ dmi_mult[3] = dmi_mult[2]; dmi_mult[4] = dmi_mult[1]; dmi_mult[5] = dmi_mult[2]; @@ -1058,15 +1114,19 @@ static int fschmd_probe(struct i2c_client *client, mutex_init(&data->watchdog_lock); INIT_LIST_HEAD(&data->list); kref_init(&data->kref); - /* Store client pointer in our data struct for watchdog usage - (where the client is found through a data ptr instead of the - otherway around) */ + /* + * Store client pointer in our data struct for watchdog usage + * (where the client is found through a data ptr instead of the + * otherway around) + */ data->client = client; data->kind = kind; if (kind == fscpos) { - /* The Poseidon has hardwired temp limits, fill these - in for the alarm resetting code */ + /* + * The Poseidon has hardwired temp limits, fill these + * in for the alarm resetting code + */ data->temp_max[0] = 70 + 128; data->temp_max[1] = 50 + 128; data->temp_max[2] = 50 + 128; @@ -1157,9 +1217,11 @@ static int fschmd_probe(struct i2c_client *client, goto exit_detach; } - /* We take the data_mutex lock early so that watchdog_open() cannot - run when misc_register() has completed, but we've not yet added - our data to the watchdog_data_list (and set the default timeout) */ + /* + * We take the data_mutex lock early so that watchdog_open() cannot + * run when misc_register() has completed, but we've not yet added + * our data to the watchdog_data_list (and set the default timeout) + */ mutex_lock(&watchdog_data_mutex); for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { /* Register our watchdog part */ @@ -1225,8 +1287,10 @@ static int fschmd_remove(struct i2c_client *client) mutex_unlock(&data->watchdog_lock); } - /* Check if registered in case we're called from fschmd_detect - to cleanup after an error */ + /* + * Check if registered in case we're called from fschmd_detect + * to cleanup after an error + */ if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); @@ -1269,8 +1333,10 @@ static struct fschmd_data *fschmd_update_device(struct device *dev) client, FSCHMD_REG_TEMP_LIMIT[data->kind][i]); - /* reset alarm if the alarm condition is gone, - the chip doesn't do this itself */ + /* + * reset alarm if the alarm condition is gone, + * the chip doesn't do this itself + */ if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) == FSCHMD_TEMP_ALARM_MASK && data->temp_act[i] < data->temp_max[i]) @@ -1314,20 +1380,9 @@ static struct fschmd_data *fschmd_update_device(struct device *dev) return data; } -static int __init fschmd_init(void) -{ - return i2c_add_driver(&fschmd_driver); -} - -static void __exit fschmd_exit(void) -{ - i2c_del_driver(&fschmd_driver); -} +module_i2c_driver(fschmd_driver); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades " "and Syleus driver"); MODULE_LICENSE("GPL"); - -module_init(fschmd_init); -module_exit(fschmd_exit); diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c index 781277ddbaa5..ebcd2698e4dc 100644 --- a/drivers/hwmon/g760a.c +++ b/drivers/hwmon/g760a.c @@ -1,17 +1,17 @@ /* - g760a - Driver for the Global Mixed-mode Technology Inc. G760A - fan speed PWM controller chip - - Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> - - Complete datasheet is available at GMT's website: - http://www.gmt.com.tw/product/datasheet/EDS-760A.pdf - - 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. -*/ + * g760a - Driver for the Global Mixed-mode Technology Inc. G760A + * fan speed PWM controller chip + * + * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> + * + * Complete datasheet is available at GMT's website: + * http://www.gmt.com.tw/product/datasheet/EDS-760A.pdf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ #include <linux/module.h> #include <linux/init.h> @@ -59,7 +59,8 @@ struct g760a_data { u8 act_cnt; /* formula: cnt = (CLK * 30)/(rpm * P) */ u8 fan_sta; /* bit 0: set when actual fan speed more than 20% * outside requested fan speed - * bit 1: set when fan speed below 1920 rpm */ + * bit 1: set when fan speed below 1920 rpm + */ }; #define G760A_DEFAULT_CLK 32768 @@ -99,7 +100,7 @@ static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg, return i2c_smbus_write_byte_data(client, reg, value); } -/**************************************************************************** +/* * sysfs attributes */ @@ -192,7 +193,7 @@ static const struct attribute_group g760a_group = { .attrs = g760a_attributes, }; -/**************************************************************************** +/* * new-style driver model code */ @@ -250,21 +251,8 @@ static int g760a_remove(struct i2c_client *client) return 0; } -/* module management */ - -static int __init g760a_init(void) -{ - return i2c_add_driver(&g760a_driver); -} - -static void __exit g760a_exit(void) -{ - i2c_del_driver(&g760a_driver); -} +module_i2c_driver(g760a_driver); MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>"); MODULE_DESCRIPTION("GMT G760A driver"); MODULE_LICENSE("GPL"); - -module_init(g760a_init); -module_exit(g760a_exit); diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index a13e2da97e30..764a083ac7a7 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -83,11 +83,12 @@ enum chips { gl518sm_r00, gl518sm_r80 }; #define RAW_FROM_REG(val) val -#define BOOL_FROM_REG(val) ((val)?0:1) -#define BOOL_TO_REG(val) ((val)?0:1) +#define BOOL_FROM_REG(val) ((val) ? 0 : 1) +#define BOOL_TO_REG(val) ((val) ? 0 : 1) -#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0? \ - (val)-500:(val)+500)/1000)+119),0,255)) +#define TEMP_TO_REG(val) SENSORS_LIMIT(((((val) < 0 ? \ + (val) - 500 : \ + (val) + 500) / 1000) + 119), 0, 255) #define TEMP_FROM_REG(val) (((val) - 119) * 1000) static inline u8 FAN_TO_REG(long rpm, int div) @@ -98,13 +99,13 @@ static inline u8 FAN_TO_REG(long rpm, int div) rpmdiv = SENSORS_LIMIT(rpm, 1, 960000) * div; return SENSORS_LIMIT((480000 + rpmdiv / 2) / rpmdiv, 1, 255); } -#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val)*(div)))) +#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) * (div)))) -#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) -#define IN_FROM_REG(val) ((val)*19) +#define IN_TO_REG(val) SENSORS_LIMIT((((val) + 9) / 19), 0, 255) +#define IN_FROM_REG(val) ((val) * 19) -#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) -#define VDD_FROM_REG(val) (((val)*95+2)/4) +#define VDD_TO_REG(val) SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255) +#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4) #define DIV_FROM_REG(val) (1 << (val)) @@ -169,7 +170,8 @@ static struct i2c_driver gl518_driver = { */ #define show(type, suffix, value) \ -static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##suffix(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct gl518_data *data = gl518_update_device(dev); \ return sprintf(buf, "%d\n", type##_FROM_REG(data->value)); \ @@ -222,12 +224,16 @@ static ssize_t show_fan_div(struct device *dev, } #define set(type, suffix, value, reg) \ -static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_##suffix(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct gl518_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ \ mutex_lock(&data->update_lock); \ data->value = type##_TO_REG(val); \ @@ -237,13 +243,17 @@ static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, c } #define set_bits(type, suffix, value, reg, mask, shift) \ -static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_##suffix(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct gl518_data *data = i2c_get_clientdata(client); \ int regvalue; \ - unsigned long val = simple_strtoul(buf, NULL, 10); \ + unsigned long val; \ + int err = kstrtoul(buf, 10, &val); \ + if (err) \ + return err; \ \ mutex_lock(&data->update_lock); \ regvalue = gl518_read_value(client, reg); \ @@ -280,7 +290,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, struct gl518_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; int regvalue; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT); @@ -308,13 +323,26 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, struct gl518_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; int regvalue; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; switch (val) { - case 1: val = 0; break; - case 2: val = 1; break; - case 4: val = 2; break; - case 8: val = 3; break; + case 1: + val = 0; + break; + case 2: + val = 1; + break; + case 4: + val = 2; + break; + case 8: + val = 3; + break; default: dev_err(dev, "Invalid fan clock divider %lu, choose one " "of 1, 2, 4 or 8\n", val); @@ -395,8 +423,12 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr, struct gl518_data *data = i2c_get_clientdata(client); int bitnr = to_sensor_dev_attr(attr)->index; unsigned long bit; + int err; + + err = kstrtoul(buf, 10, &bit); + if (err) + return err; - bit = simple_strtoul(buf, NULL, 10); if (bit & ~1) return -EINVAL; @@ -528,12 +560,14 @@ static int gl518_probe(struct i2c_client *client, gl518_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &gl518_group))) + err = sysfs_create_group(&client->dev.kobj, &gl518_group); + if (err) goto exit_free; - if (data->type == gl518sm_r80) - if ((err = sysfs_create_group(&client->dev.kobj, - &gl518_group_r80))) + if (data->type == gl518sm_r80) { + err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80); + if (err) goto exit_remove_files; + } data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -554,8 +588,10 @@ exit: } -/* Called when we have found a new GL518SM. - Note that we preserve D4:NoFan2 and D2:beep_enable. */ +/* + * Called when we have found a new GL518SM. + * Note that we preserve D4:NoFan2 and D2:beep_enable. + */ static void gl518_init_client(struct i2c_client *client) { /* Make sure we leave D7:Reset untouched */ @@ -585,9 +621,11 @@ static int gl518_remove(struct i2c_client *client) return 0; } -/* Registers 0x07 to 0x0c are word-sized, others are byte-sized - GL518 uses a high-byte first convention, which is exactly opposite to - the SMBus standard. */ +/* + * Registers 0x07 to 0x0c are word-sized, others are byte-sized + * GL518 uses a high-byte first convention, which is exactly opposite to + * the SMBus standard. + */ static int gl518_read_value(struct i2c_client *client, u8 reg) { if ((reg >= 0x07) && (reg <= 0x0c)) @@ -676,21 +714,10 @@ static struct gl518_data *gl518_update_device(struct device *dev) return data; } -static int __init sensors_gl518sm_init(void) -{ - return i2c_add_driver(&gl518_driver); -} - -static void __exit sensors_gl518sm_exit(void) -{ - i2c_del_driver(&gl518_driver); -} +module_i2c_driver(gl518_driver); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " "Kyosti Malkki <kmalkki@cc.hut.fi> and " "Hong-Gunn Chew <hglinux@gunnet.org>"); MODULE_DESCRIPTION("GL518SM driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_gl518sm_init); -module_exit(sensors_gl518sm_exit); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index cd6085bbfba7..5ff452b6a4d0 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -1,25 +1,25 @@ /* - gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>, - Kyösti Mälkki <kmalkki@cc.hut.fi> - Copyright (c) 2005 Maarten Deprez <maartendeprez@users.sourceforge.net> - - 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. - -*/ + * gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>, + * Kyösti Mälkki <kmalkki@cc.hut.fi> + * Copyright (c) 2005 Maarten Deprez <maartendeprez@users.sourceforge.net> + * + * 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 <linux/module.h> #include <linux/init.h> @@ -41,10 +41,11 @@ MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=tempe /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; -/* Many GL520 constants specified below -One of the inputs can be configured as either temp or voltage. -That's why _TEMP2 and _IN4 access the same register -*/ +/* + * Many GL520 constants specified below + * One of the inputs can be configured as either temp or voltage. + * That's why _TEMP2 and _IN4 access the same register + */ /* The GL520 registers */ #define GL520_REG_CHIP_ID 0x00 @@ -142,11 +143,11 @@ static ssize_t get_cpu_vid(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL); -#define VDD_FROM_REG(val) (((val)*95+2)/4) -#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) +#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4) +#define VDD_TO_REG(val) SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255) -#define IN_FROM_REG(val) ((val)*19) -#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) +#define IN_FROM_REG(val) ((val) * 19) +#define IN_TO_REG(val) SENSORS_LIMIT((((val) + 9) / 19), 0, 255) static ssize_t get_in_input(struct device *dev, struct device_attribute *attr, char *buf) @@ -193,8 +194,13 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); int n = to_sensor_dev_attr(attr)->index; - long v = simple_strtol(buf, NULL, 10); u8 r; + long v; + int err; + + err = kstrtol(buf, 10, &v); + if (err) + return err; mutex_lock(&data->update_lock); @@ -222,8 +228,13 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); int n = to_sensor_dev_attr(attr)->index; - long v = simple_strtol(buf, NULL, 10); u8 r; + long v; + int err; + + err = kstrtol(buf, 10, &v); + if (err) + return err; if (n == 0) r = VDD_TO_REG(v); @@ -272,8 +283,10 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR, get_in_max, set_in_max, 4); #define DIV_FROM_REG(val) (1 << (val)) -#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div)))) -#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)) +#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) << (div)))) +#define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \ + SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, \ + 255)) static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr, char *buf) @@ -317,8 +330,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); int n = to_sensor_dev_attr(attr)->index; - unsigned long v = simple_strtoul(buf, NULL, 10); u8 r; + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; mutex_lock(&data->update_lock); r = FAN_TO_REG(v, data->fan_div[n]); @@ -351,16 +369,30 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); int n = to_sensor_dev_attr(attr)->index; - unsigned long v = simple_strtoul(buf, NULL, 10); u8 r; + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; switch (v) { - case 1: r = 0; break; - case 2: r = 1; break; - case 4: r = 2; break; - case 8: r = 3; break; + case 1: + r = 0; + break; + case 2: + r = 1; + break; + case 4: + r = 2; + break; + case 8: + r = 3; + break; default: - dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v); + dev_err(&client->dev, + "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v); return -EINVAL; } @@ -385,7 +417,15 @@ static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr, { struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); - u8 r = simple_strtoul(buf, NULL, 10)?1:0; + u8 r; + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; + + r = (v ? 1 : 0); mutex_lock(&data->update_lock); data->fan_off = r; @@ -410,7 +450,8 @@ static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR, get_fan_off, set_fan_off); #define TEMP_FROM_REG(val) (((val) - 130) * 1000) -#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255)) +#define TEMP_TO_REG(val) SENSORS_LIMIT(((((val) < 0 ? \ + (val) - 500 : (val) + 500) / 1000) + 130), 0, 255) static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr, char *buf) @@ -430,8 +471,8 @@ static ssize_t get_temp_max(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n])); } -static ssize_t get_temp_max_hyst(struct device *dev, struct device_attribute - *attr, char *buf) +static ssize_t get_temp_max_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { int n = to_sensor_dev_attr(attr)->index; struct gl520_data *data = gl520_update_device(dev); @@ -445,7 +486,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); int n = to_sensor_dev_attr(attr)->index; - long v = simple_strtol(buf, NULL, 10); + long v; + int err; + + err = kstrtol(buf, 10, &v); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[n] = TEMP_TO_REG(v); @@ -460,7 +506,12 @@ static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); int n = to_sensor_dev_attr(attr)->index; - long v = simple_strtol(buf, NULL, 10); + long v; + int err; + + err = kstrtol(buf, 10, &v); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max_hyst[n] = TEMP_TO_REG(v); @@ -507,7 +558,15 @@ static ssize_t set_beep_enable(struct device *dev, struct device_attribute { struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); - u8 r = simple_strtoul(buf, NULL, 10)?0:1; + u8 r; + unsigned long v; + int err; + + err = kstrtoul(buf, 10, &v); + if (err) + return err; + + r = (v ? 0 : 1); mutex_lock(&data->update_lock); data->beep_enable = !r; @@ -523,7 +582,12 @@ static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr, { struct i2c_client *client = to_i2c_client(dev); struct gl520_data *data = i2c_get_clientdata(client); - u8 r = simple_strtoul(buf, NULL, 10); + unsigned long r; + int err; + + err = kstrtoul(buf, 10, &r); + if (err) + return err; mutex_lock(&data->update_lock); r &= data->alarm_mask; @@ -575,7 +639,11 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr, int bitnr = to_sensor_dev_attr(attr)->index; unsigned long bit; - bit = simple_strtoul(buf, NULL, 10); + int err; + + err = kstrtoul(buf, 10, &bit); + if (err) + return err; if (bit & ~1) return -EINVAL; @@ -652,13 +720,16 @@ static const struct attribute_group gl520_group = { .attrs = gl520_attributes, }; -static struct attribute *gl520_attributes_opt[] = { +static struct attribute *gl520_attributes_in4[] = { &sensor_dev_attr_in4_input.dev_attr.attr, &sensor_dev_attr_in4_min.dev_attr.attr, &sensor_dev_attr_in4_max.dev_attr.attr, &sensor_dev_attr_in4_alarm.dev_attr.attr, &sensor_dev_attr_in4_beep.dev_attr.attr, + NULL +}; +static struct attribute *gl520_attributes_temp2[] = { &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, @@ -667,8 +738,12 @@ static struct attribute *gl520_attributes_opt[] = { NULL }; -static const struct attribute_group gl520_group_opt = { - .attrs = gl520_attributes_opt, +static const struct attribute_group gl520_group_in4 = { + .attrs = gl520_attributes_in4, +}; + +static const struct attribute_group gl520_group_temp2 = { + .attrs = gl520_attributes_temp2, }; @@ -717,35 +792,17 @@ static int gl520_probe(struct i2c_client *client, gl520_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group))) + err = sysfs_create_group(&client->dev.kobj, &gl520_group); + if (err) goto exit_free; - if (data->two_temps) { - if ((err = device_create_file(&client->dev, - &sensor_dev_attr_temp2_input.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_temp2_max.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_temp2_max_hyst.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_temp2_alarm.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_temp2_beep.dev_attr))) - goto exit_remove_files; - } else { - if ((err = device_create_file(&client->dev, - &sensor_dev_attr_in4_input.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_in4_min.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_in4_max.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_in4_alarm.dev_attr)) - || (err = device_create_file(&client->dev, - &sensor_dev_attr_in4_beep.dev_attr))) - goto exit_remove_files; - } + if (data->two_temps) + err = sysfs_create_group(&client->dev.kobj, &gl520_group_temp2); + else + err = sysfs_create_group(&client->dev.kobj, &gl520_group_in4); + if (err) + goto exit_remove_files; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -757,7 +814,8 @@ static int gl520_probe(struct i2c_client *client, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &gl520_group); - sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); + sysfs_remove_group(&client->dev.kobj, &gl520_group_in4); + sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2); exit_free: kfree(data); exit: @@ -809,15 +867,18 @@ static int gl520_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &gl520_group); - sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); + sysfs_remove_group(&client->dev.kobj, &gl520_group_in4); + sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2); kfree(data); return 0; } -/* Registers 0x07 to 0x0c are word-sized, others are byte-sized - GL520 uses a high-byte first convention */ +/* + * Registers 0x07 to 0x0c are word-sized, others are byte-sized + * GL520 uses a high-byte first convention + */ static int gl520_read_value(struct i2c_client *client, u8 reg) { if ((reg >= 0x07) && (reg <= 0x0c)) @@ -849,7 +910,8 @@ static struct gl520_data *gl520_update_device(struct device *dev) data->alarms = gl520_read_value(client, GL520_REG_ALARMS); data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK); - data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f; + data->vid = gl520_read_value(client, + GL520_REG_VID_INPUT) & 0x1f; for (i = 0; i < 4; i++) { data->in_input[i] = gl520_read_value(client, @@ -910,23 +972,10 @@ static struct gl520_data *gl520_update_device(struct device *dev) return data; } - -static int __init sensors_gl520sm_init(void) -{ - return i2c_add_driver(&gl520_driver); -} - -static void __exit sensors_gl520sm_exit(void) -{ - i2c_del_driver(&gl520_driver); -} - +module_i2c_driver(gl520_driver); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " "Kyösti Mälkki <kmalkki@cc.hut.fi>, " "Maarten Deprez <maartendeprez@users.sourceforge.net>"); MODULE_DESCRIPTION("GL520SM driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_gl520sm_init); -module_exit(sensors_gl520sm_exit); diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 932da8a5aaf4..9f26400713f0 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c @@ -40,7 +40,7 @@ * available at http://developer.intel.com/. * * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094, - * http://support.amd.com/us/Processor_TechDocs/26094.PDF + * http://support.amd.com/us/Processor_TechDocs/26094.PDF * Table 74. VID Code Voltages * This corresponds to an arbitrary VRM code of 24 in the functions below. * These CPU models (K8 revision <= E) have 5 VID pins. See also: @@ -83,27 +83,27 @@ int vid_from_reg(int val, u8 vrm) { int vid; - switch(vrm) { + switch (vrm) { - case 100: /* VRD 10.0 */ + case 100: /* VRD 10.0 */ /* compute in uV, round to mV */ val &= 0x3f; - if((val & 0x1f) == 0x1f) + if ((val & 0x1f) == 0x1f) return 0; - if((val & 0x1f) <= 0x09 || val == 0x0a) + if ((val & 0x1f) <= 0x09 || val == 0x0a) vid = 1087500 - (val & 0x1f) * 25000; else vid = 1862500 - (val & 0x1f) * 25000; - if(val & 0x20) + if (val & 0x20) vid -= 12500; - return((vid + 500) / 1000); + return (vid + 500) / 1000; case 110: /* Intel Conroe */ /* compute in uV, round to mV */ val &= 0xff; if (val < 0x02 || val > 0xb2) return 0; - return((1600000 - (val - 2) * 6250 + 500) / 1000); + return (1600000 - (val - 2) * 6250 + 500) / 1000; case 24: /* Athlon64 & Opteron */ val &= 0x1f; @@ -118,38 +118,38 @@ int vid_from_reg(int val, u8 vrm) case 91: /* VRM 9.1 */ case 90: /* VRM 9.0 */ val &= 0x1f; - return(val == 0x1f ? 0 : - 1850 - val * 25); + return val == 0x1f ? 0 : + 1850 - val * 25; case 85: /* VRM 8.5 */ val &= 0x1f; - return((val & 0x10 ? 25 : 0) + + return (val & 0x10 ? 25 : 0) + ((val & 0x0f) > 0x04 ? 2050 : 1250) - - ((val & 0x0f) * 50)); + ((val & 0x0f) * 50); case 84: /* VRM 8.4 */ val &= 0x0f; /* fall through */ case 82: /* VRM 8.2 */ val &= 0x1f; - return(val == 0x1f ? 0 : + return val == 0x1f ? 0 : val & 0x10 ? 5100 - (val) * 100 : - 2050 - (val) * 50); + 2050 - (val) * 50; case 17: /* Intel IMVP-II */ val &= 0x1f; - return(val & 0x10 ? 975 - (val & 0xF) * 25 : - 1750 - val * 50); + return val & 0x10 ? 975 - (val & 0xF) * 25 : + 1750 - val * 50; case 13: case 131: val &= 0x3f; /* Exception for Eden ULV 500 MHz */ if (vrm == 131 && val == 0x3f) val++; - return(1708 - val * 16); + return 1708 - val * 16; case 14: /* Intel Core */ /* compute in uV, round to mV */ val &= 0x7f; - return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000); + return val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000; default: /* report 0 for unknown */ if (vrm) pr_warn("Requested unsupported VRM version (%u)\n", @@ -157,7 +157,7 @@ int vid_from_reg(int val, u8 vrm) return 0; } } - +EXPORT_SYMBOL(vid_from_reg); /* * After this point is the code to automatically determine which @@ -166,9 +166,10 @@ int vid_from_reg(int val, u8 vrm) struct vrm_model { u8 vendor; - u8 eff_family; - u8 eff_model; - u8 eff_stepping; + u8 family; + u8 model_from; + u8 model_to; + u8 stepping_to; u8 vrm_type; }; @@ -177,42 +178,52 @@ struct vrm_model { #ifdef CONFIG_X86 /* - * The stepping parameter is highest acceptable stepping for current line. + * The stepping_to parameter is highest acceptable stepping for current line. * The model match must be exact for 4-bit values. For model values 0x10 * and above (extended model), all models below the parameter will match. */ static struct vrm_model vrm_models[] = { - {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ - {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ - /* In theory, all NPT family 0Fh processors have 6 VID pins and should - thus use vrm 25, however in practice not all mainboards route the - 6th VID pin because it is never needed. So we use the 5 VID pin - variant (vrm 24) for the models which exist today. */ - {X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24}, /* NPT family 0Fh */ - {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* future fam. 0Fh */ - {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ - - {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ - {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ - {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ - {X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */ - {X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */ - {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ - {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ - {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ - {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ - {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ - - {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ - {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ - {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */ - {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ - {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ - {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7-M, C7, Eden (Esther) */ - {X86_VENDOR_CENTAUR, 0x6, 0xD, ANY, 134}, /* C7-D, C7-M, C7, Eden (Esther) */ - - {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ + {X86_VENDOR_AMD, 0x6, 0x0, ANY, ANY, 90}, /* Athlon Duron etc */ + {X86_VENDOR_AMD, 0xF, 0x0, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ + /* + * In theory, all NPT family 0Fh processors have 6 VID pins and should + * thus use vrm 25, however in practice not all mainboards route the + * 6th VID pin because it is never needed. So we use the 5 VID pin + * variant (vrm 24) for the models which exist today. + */ + {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24}, /* NPT family 0Fh */ + {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25}, /* future fam. 0Fh */ + {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25}, /* NPT family 10h */ + + {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82}, /* Pentium Pro, + * Pentium II, Xeon, + * Mobile Pentium, + * Celeron */ + {X86_VENDOR_INTEL, 0x6, 0x7, 0x7, ANY, 84}, /* Pentium III, Xeon */ + {X86_VENDOR_INTEL, 0x6, 0x8, 0x8, ANY, 82}, /* Pentium III, Xeon */ + {X86_VENDOR_INTEL, 0x6, 0x9, 0x9, ANY, 13}, /* Pentium M (130 nm) */ + {X86_VENDOR_INTEL, 0x6, 0xA, 0xA, ANY, 82}, /* Pentium III Xeon */ + {X86_VENDOR_INTEL, 0x6, 0xB, 0xB, ANY, 85}, /* Tualatin */ + {X86_VENDOR_INTEL, 0x6, 0xD, 0xD, ANY, 13}, /* Pentium M (90 nm) */ + {X86_VENDOR_INTEL, 0x6, 0xE, 0xE, ANY, 14}, /* Intel Core (65 nm) */ + {X86_VENDOR_INTEL, 0x6, 0xF, ANY, ANY, 110}, /* Intel Conroe and + * later */ + {X86_VENDOR_INTEL, 0xF, 0x0, 0x0, ANY, 90}, /* P4 */ + {X86_VENDOR_INTEL, 0xF, 0x1, 0x1, ANY, 90}, /* P4 Willamette */ + {X86_VENDOR_INTEL, 0xF, 0x2, 0x2, ANY, 90}, /* P4 Northwood */ + {X86_VENDOR_INTEL, 0xF, 0x3, ANY, ANY, 100}, /* Prescott and above + * assume VRD 10 */ + + {X86_VENDOR_CENTAUR, 0x6, 0x7, 0x7, ANY, 85}, /* Eden ESP/Ezra */ + {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x8, 0x7, 85}, /* Ezra T */ + {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, 0x7, 85}, /* Nehemiah */ + {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, ANY, 17}, /* C3-M, Eden-N */ + {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, 0x7, 0}, /* No information */ + {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, ANY, 13}, /* C7-M, C7, + * Eden (Esther) */ + {X86_VENDOR_CENTAUR, 0x6, 0xD, 0xD, ANY, 134}, /* C7-D, C7-M, C7, + * Eden (Esther) */ }; /* @@ -248,20 +259,17 @@ static u8 get_via_model_d_vrm(void) } } -static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) +static u8 find_vrm(u8 family, u8 model, u8 stepping, u8 vendor) { - int i = 0; - - while (vrm_models[i].vendor!=X86_VENDOR_UNKNOWN) { - if (vrm_models[i].vendor==vendor) - if ((vrm_models[i].eff_family==eff_family) - && ((vrm_models[i].eff_model==eff_model) || - (vrm_models[i].eff_model >= 0x10 && - eff_model <= vrm_models[i].eff_model) || - (vrm_models[i].eff_model==ANY)) && - (eff_stepping <= vrm_models[i].eff_stepping)) - return vrm_models[i].vrm_type; - i++; + int i; + + for (i = 0; i < ARRAY_SIZE(vrm_models); i++) { + if (vendor == vrm_models[i].vendor && + family == vrm_models[i].family && + model >= vrm_models[i].model_from && + model <= vrm_models[i].model_to && + stepping <= vrm_models[i].stepping_to) + return vrm_models[i].vrm_type; } return 0; @@ -270,21 +278,12 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) u8 vid_which_vrm(void) { struct cpuinfo_x86 *c = &cpu_data(0); - u32 eax; - u8 eff_family, eff_model, eff_stepping, vrm_ret; + u8 vrm_ret; if (c->x86 < 6) /* Any CPU with family lower than 6 */ - return 0; /* doesn't have VID and/or CPUID */ - - eax = cpuid_eax(1); - eff_family = ((eax & 0x00000F00)>>8); - eff_model = ((eax & 0x000000F0)>>4); - eff_stepping = eax & 0xF; - if (eff_family == 0xF) { /* use extended model & family */ - eff_family += ((eax & 0x00F00000)>>20); - eff_model += ((eax & 0x000F0000)>>16)<<4; - } - vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); + return 0; /* doesn't have VID */ + + vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_mask, c->x86_vendor); if (vrm_ret == 134) vrm_ret = get_via_model_d_vrm(); if (vrm_ret == 0) @@ -300,8 +299,6 @@ u8 vid_which_vrm(void) return 0; } #endif - -EXPORT_SYMBOL(vid_from_reg); EXPORT_SYMBOL(vid_which_vrm); MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 6460487e41b5..c3c471ca202f 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -1,14 +1,14 @@ /* - hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring - - This file defines the sysfs class "hwmon", for use by sensors drivers. - - Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. -*/ + * hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring + * + * This file defines the sysfs class "hwmon", for use by sensors drivers. + * + * Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -55,6 +55,7 @@ struct device *hwmon_device_register(struct device *dev) return hwdev; } +EXPORT_SYMBOL_GPL(hwmon_device_register); /** * hwmon_device_unregister - removes the previously registered class device @@ -72,6 +73,7 @@ void hwmon_device_unregister(struct device *dev) dev_dbg(dev->parent, "hwmon_device_unregister() failed: bad class ID!\n"); } +EXPORT_SYMBOL_GPL(hwmon_device_unregister); static void __init hwmon_pci_quirks(void) { @@ -119,9 +121,6 @@ static void __exit hwmon_exit(void) subsys_initcall(hwmon_init); module_exit(hwmon_exit); -EXPORT_SYMBOL_GPL(hwmon_device_register); -EXPORT_SYMBOL_GPL(hwmon_device_unregister); - MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); MODULE_DESCRIPTION("hardware monitoring sysfs/class support"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index d22f241b6a67..a18882cc073d 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -159,8 +159,12 @@ static ssize_t store_amb_min(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i5k_amb_data *data = dev_get_drvdata(dev); - unsigned long temp = simple_strtoul(buf, NULL, 10) / 500; + unsigned long temp; + int ret = kstrtoul(buf, 10, &temp); + if (ret < 0) + return ret; + temp = temp / 500; if (temp > 255) temp = 255; @@ -175,8 +179,12 @@ static ssize_t store_amb_mid(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i5k_amb_data *data = dev_get_drvdata(dev); - unsigned long temp = simple_strtoul(buf, NULL, 10) / 500; + unsigned long temp; + int ret = kstrtoul(buf, 10, &temp); + if (ret < 0) + return ret; + temp = temp / 500; if (temp > 255) temp = 255; @@ -191,8 +199,12 @@ static ssize_t store_amb_max(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i5k_amb_data *data = dev_get_drvdata(dev); - unsigned long temp = simple_strtoul(buf, NULL, 10) / 500; + unsigned long temp; + int ret = kstrtoul(buf, 10, &temp); + if (ret < 0) + return ret; + temp = temp / 500; if (temp > 255) temp = 255; diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index cc2981f749a6..37f17e0d9d5d 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -1045,7 +1045,7 @@ static struct aem_ro_sensor_template aem2_ro_sensors[] = { {"power6_average", aem2_show_pcap_value, POWER_CAP_MIN_WARNING}, {"power7_average", aem2_show_pcap_value, POWER_CAP_MIN}, -{"power3_average", aem2_show_pcap_value, POWER_AUX}, +{"power3_average", aem2_show_pcap_value, POWER_AUX}, {"power_cap", aem2_show_pcap_value, POWER_CAP}, {NULL, NULL, 0}, }; diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 0054d6f9cec9..0b204e4cf51c 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -176,12 +176,16 @@ static bool fix_pwm_polarity; #define IT87_REG_ALARM2 0x02 #define IT87_REG_ALARM3 0x03 -/* The IT8718F and IT8720F have the VID value in a different register, in - Super-I/O configuration space. */ +/* + * The IT8718F and IT8720F have the VID value in a different register, in + * Super-I/O configuration space. + */ #define IT87_REG_VID 0x0a -/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b - for fan divisors. Later IT8712F revisions must use 16-bit tachometer - mode. */ +/* + * The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b + * for fan divisors. Later IT8712F revisions must use 16-bit tachometer + * mode. + */ #define IT87_REG_FAN_DIV 0x0b #define IT87_REG_FAN_16BIT 0x0c @@ -227,8 +231,10 @@ struct it87_sio_data { u8 skip_pwm; }; -/* For each registered chip, we need to keep some data in memory. - The structure is dynamically allocated. */ +/* + * For each registered chip, we need to keep some data in memory. + * The structure is dynamically allocated. + */ struct it87_data { struct device *hwmon_dev; enum chips type; @@ -259,14 +265,16 @@ struct it87_data { u8 fan_main_ctrl; /* Register value */ u8 fan_ctl; /* Register value */ - /* The following 3 arrays correspond to the same registers up to + /* + * The following 3 arrays correspond to the same registers up to * the IT8720F. The meaning of bits 6-0 depends on the value of bit * 7, and we want to preserve settings on mode changes, so we have * to track all values separately. * Starting with the IT8721F, the manual PWM duty cycles are stored * in separate registers (8-bit values), so the separate tracking * is no longer needed, but it is still done to keep the driver - * simple. */ + * simple. + */ u8 pwm_ctrl[3]; /* Register value */ u8 pwm_duty[3]; /* Manual PWM value set by user */ u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ @@ -388,9 +396,11 @@ static const unsigned int pwm_freq[8] = { static inline int has_16bit_fans(const struct it87_data *data) { - /* IT8705F Datasheet 0.4.1, 3h == Version G. - IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. - These are the first revisions with 16bit tachometer support. */ + /* + * IT8705F Datasheet 0.4.1, 3h == Version G. + * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. + * These are the first revisions with 16-bit tachometer support. + */ return (data->type == it87 && data->revision >= 0x03) || (data->type == it8712 && data->revision >= 0x08) || data->type == it8716 @@ -402,9 +412,11 @@ static inline int has_16bit_fans(const struct it87_data *data) static inline int has_old_autopwm(const struct it87_data *data) { - /* The old automatic fan speed control interface is implemented - by IT8705F chips up to revision F and IT8712F chips up to - revision G. */ + /* + * The old automatic fan speed control interface is implemented + * by IT8705F chips up to revision F and IT8712F chips up to + * revision G. + */ return (data->type == it87 && data->revision < 0x03) || (data->type == it8712 && data->revision < 0x08); } @@ -606,10 +618,8 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, { struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; - struct it87_data *data = it87_update_device(dev); - u8 reg = data->sensor; /* In case the value is updated while - we use it */ + u8 reg = data->sensor; /* In case value is updated while used */ if (reg & (1 << nr)) return sprintf(buf, "3\n"); /* thermal diode */ @@ -894,8 +904,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); if (has_newer_autopwm(data)) { - /* If we are in automatic mode, the PWM duty cycle register - * is read-only so we can't write the value */ + /* + * If we are in automatic mode, the PWM duty cycle register + * is read-only so we can't write the value. + */ if (data->pwm_ctrl[nr] & 0x80) { mutex_unlock(&data->update_lock); return -EBUSY; @@ -905,8 +917,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, data->pwm_duty[nr]); } else { data->pwm_duty[nr] = pwm_to_reg(data, val); - /* If we are in manual mode, write the duty cycle immediately; - * otherwise, just store it for later use. */ + /* + * If we are in manual mode, write the duty cycle immediately; + * otherwise, just store it for later use. + */ if (!(data->pwm_ctrl[nr] & 0x80)) { data->pwm_ctrl[nr] = data->pwm_duty[nr]; it87_write_value(data, IT87_REG_PWM(nr), @@ -965,8 +979,10 @@ static ssize_t set_pwm_temp_map(struct device *dev, long val; u8 reg; - /* This check can go away if we ever support automatic fan speed - control on newer chips. */ + /* + * This check can go away if we ever support automatic fan speed + * control on newer chips. + */ if (!has_old_autopwm(data)) { dev_notice(dev, "Mapping change disabled for safety reasons\n"); return -EINVAL; @@ -991,8 +1007,10 @@ static ssize_t set_pwm_temp_map(struct device *dev, mutex_lock(&data->update_lock); data->pwm_temp_map[nr] = reg; - /* If we are in automatic mode, write the temp mapping immediately; - * otherwise, just store it for later use. */ + /* + * If we are in automatic mode, write the temp mapping immediately; + * otherwise, just store it for later use. + */ if (data->pwm_ctrl[nr] & 0x80) { data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); @@ -1162,9 +1180,11 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, return count; } -/* We want to use the same sysfs file names as 8-bit fans, but we need - different variable names, so we have to use SENSOR_ATTR instead of - SENSOR_DEVICE_ATTR. */ +/* + * We want to use the same sysfs file names as 8-bit fans, but we need + * different variable names, so we have to use SENSOR_ATTR instead of + * SENSOR_DEVICE_ATTR. + */ #define show_fan16_offset(offset) \ static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \ = SENSOR_ATTR(fan##offset##_input, S_IRUGO, \ @@ -1321,12 +1341,12 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); static ssize_t show_label(struct device *dev, struct device_attribute *attr, char *buf) { - static const char *labels[] = { + static const char * const labels[] = { "+5V", "5VSB", "Vbat", }; - static const char *labels_it8721[] = { + static const char * const labels_it8721[] = { "+3.3V", "3VSB", "Vbat", @@ -1736,12 +1756,14 @@ static int __init it87_find(unsigned short *address, if (board_vendor && board_name) { if (strcmp(board_vendor, "nVIDIA") == 0 && strcmp(board_name, "FN68PT") == 0) { - /* On the Shuttle SN68PT, FAN_CTL2 is apparently not - connected to a fan, but to something else. One user - has reported instant system power-off when changing - the PWM2 duty cycle, so we disable it. - I use the board name string as the trigger in case - the same board is ever used in other systems. */ + /* + * On the Shuttle SN68PT, FAN_CTL2 is apparently not + * connected to a fan, but to something else. One user + * has reported instant system power-off when changing + * the PWM2 duty cycle, so we disable it. + * I use the board name string as the trigger in case + * the same board is ever used in other systems. + */ pr_info("Disabling pwm2 due to hardware constraints\n"); sio_data->skip_pwm = (1 << 1); } @@ -1793,7 +1815,7 @@ static int __devinit it87_probe(struct platform_device *pdev) int err = 0, i; int enable_pwm_interface; int fan_beep_need_rw; - static const char *names[] = { + static const char * const names[] = { "it87", "it8712", "it8716", @@ -1879,9 +1901,11 @@ static int __devinit it87_probe(struct platform_device *pdev) if (!fan_beep_need_rw) continue; - /* As we have a single beep enable bit for all fans, + /* + * As we have a single beep enable bit for all fans, * only the first enabled fan has a writable attribute - * for it. */ + * for it. + */ if (sysfs_chmod_file(&dev->kobj, it87_attributes_fan_beep[i], S_IRUGO | S_IWUSR)) @@ -1961,18 +1985,22 @@ static int __devexit it87_remove(struct platform_device *pdev) return 0; } -/* Must be called with data->update_lock held, except during initialization. - We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, - would slow down the IT87 access and should not be necessary. */ +/* + * Must be called with data->update_lock held, except during initialization. + * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, + * would slow down the IT87 access and should not be necessary. + */ static int it87_read_value(struct it87_data *data, u8 reg) { outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); return inb_p(data->addr + IT87_DATA_REG_OFFSET); } -/* Must be called with data->update_lock held, except during initialization. - We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, - would slow down the IT87 access and should not be necessary. */ +/* + * Must be called with data->update_lock held, except during initialization. + * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, + * would slow down the IT87 access and should not be necessary. + */ static void it87_write_value(struct it87_data *data, u8 reg, u8 value) { outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); @@ -1983,15 +2011,19 @@ static void it87_write_value(struct it87_data *data, u8 reg, u8 value) static int __devinit it87_check_pwm(struct device *dev) { struct it87_data *data = dev_get_drvdata(dev); - /* Some BIOSes fail to correctly configure the IT87 fans. All fans off + /* + * Some BIOSes fail to correctly configure the IT87 fans. All fans off * and polarity set to active low is sign that this is the case so we - * disable pwm control to protect the user. */ + * disable pwm control to protect the user. + */ int tmp = it87_read_value(data, IT87_REG_FAN_CTL); if ((tmp & 0x87) == 0) { if (fix_pwm_polarity) { - /* The user asks us to attempt a chip reconfiguration. + /* + * The user asks us to attempt a chip reconfiguration. * This means switching to active high polarity and - * inverting all fan speed values. */ + * inverting all fan speed values. + */ int i; u8 pwm[3]; @@ -1999,10 +2031,12 @@ static int __devinit it87_check_pwm(struct device *dev) pwm[i] = it87_read_value(data, IT87_REG_PWM(i)); - /* If any fan is in automatic pwm mode, the polarity + /* + * If any fan is in automatic pwm mode, the polarity * might be correct, as suspicious as it seems, so we * better don't change anything (but still disable the - * PWM interface). */ + * PWM interface). + */ if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { dev_info(dev, "Reconfiguring PWM to " "active high polarity\n"); @@ -2038,7 +2072,8 @@ static void __devinit it87_init_device(struct platform_device *pdev) int tmp, i; u8 mask; - /* For each PWM channel: + /* + * For each PWM channel: * - If it is in automatic mode, setting to manual mode should set * the fan to full speed by default. * - If it is in manual mode, we need a mapping to temperature @@ -2048,18 +2083,21 @@ static void __devinit it87_init_device(struct platform_device *pdev) * prior to switching to a different mode. * Note that this is no longer needed for the IT8721F and later, as * these have separate registers for the temperature mapping and the - * manual duty cycle. */ + * manual duty cycle. + */ for (i = 0; i < 3; i++) { data->pwm_temp_map[i] = i; data->pwm_duty[i] = 0x7f; /* Full speed */ data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */ } - /* Some chips seem to have default value 0xff for all limit + /* + * Some chips seem to have default value 0xff for all limit * registers. For low voltage limits it makes no sense and triggers * alarms, so change to 0 instead. For high temperature limits, it * means -1 degree C, which surprisingly doesn't trigger an alarm, - * but is still confusing, so change to 127 degrees C. */ + * but is still confusing, so change to 127 degrees C. + */ for (i = 0; i < 8; i++) { tmp = it87_read_value(data, IT87_REG_VIN_MIN(i)); if (tmp == 0xff) @@ -2071,10 +2109,12 @@ static void __devinit it87_init_device(struct platform_device *pdev) it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); } - /* Temperature channels are not forcibly enabled, as they can be + /* + * Temperature channels are not forcibly enabled, as they can be * set to two different sensor types and we can't guess which one * is correct for a given system. These channels can be enabled at - * run-time through the temp{1-3}_type sysfs accessors if needed. */ + * run-time through the temp{1-3}_type sysfs accessors if needed. + */ /* Check if voltage monitors are reset manually or by some reason */ tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); @@ -2157,8 +2197,10 @@ static struct it87_data *it87_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { if (update_vbat) { - /* Cleared after each update, so reenable. Value - returned by this read will be previous value */ + /* + * Cleared after each update, so reenable. Value + * returned by this read will be previous value + */ it87_write_value(data, IT87_REG_CONFIG, it87_read_value(data, IT87_REG_CONFIG) | 0x40); } @@ -2220,13 +2262,17 @@ static struct it87_data *it87_update_device(struct device *dev) it87_update_pwm_ctrl(data, i); data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); - /* The 8705 does not have VID capability. - The 8718 and later don't use IT87_REG_VID for the - same purpose. */ + /* + * The IT8705F does not have VID capability. + * The IT8718F and later don't use IT87_REG_VID for the + * same purpose. + */ if (data->type == it8712 || data->type == it8716) { data->vid = it87_read_value(data, IT87_REG_VID); - /* The older IT8712F revisions had only 5 VID pins, - but we assume it is always safe to read 6 bits. */ + /* + * The older IT8712F revisions had only 5 VID pins, + * but we assume it is always safe to read 6 bits. + */ data->vid &= 0x3f; } data->last_updated = jiffies; diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index b927ee5ccdd7..a9bfd6736d9a 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -180,25 +180,7 @@ static int jc42_remove(struct i2c_client *client); static struct jc42_data *jc42_update_device(struct device *dev); static const struct i2c_device_id jc42_id[] = { - { "adt7408", 0 }, - { "at30ts00", 0 }, - { "cat94ts02", 0 }, - { "cat6095", 0 }, { "jc42", 0 }, - { "max6604", 0 }, - { "mcp9804", 0 }, - { "mcp9805", 0 }, - { "mcp98242", 0 }, - { "mcp98243", 0 }, - { "mcp9843", 0 }, - { "se97", 0 }, - { "se97b", 0 }, - { "se98", 0 }, - { "stts424", 0 }, - { "stts2002", 0 }, - { "stts3000", 0 }, - { "tse2002", 0 }, - { "ts3000", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, jc42_id); @@ -350,8 +332,10 @@ set(temp_min, JC42_REG_TEMP_LOWER); set(temp_max, JC42_REG_TEMP_UPPER); set(temp_crit, JC42_REG_TEMP_CRITICAL); -/* JC42.4 compliant chips only support four hysteresis values. - * Pick best choice and go from there. */ +/* + * JC42.4 compliant chips only support four hysteresis values. + * Pick best choice and go from there. + */ static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -467,20 +451,19 @@ static const struct attribute_group jc42_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int jc42_detect(struct i2c_client *new_client, - struct i2c_board_info *info) +static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) { - struct i2c_adapter *adapter = new_client->adapter; + struct i2c_adapter *adapter = client->adapter; int i, config, cap, manid, devid; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; - cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP); - config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG); - manid = i2c_smbus_read_word_swapped(new_client, JC42_REG_MANID); - devid = i2c_smbus_read_word_swapped(new_client, JC42_REG_DEVICEID); + cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); + config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); + manid = i2c_smbus_read_word_swapped(client, JC42_REG_MANID); + devid = i2c_smbus_read_word_swapped(client, JC42_REG_DEVICEID); if (cap < 0 || config < 0 || manid < 0 || devid < 0) return -ENODEV; @@ -499,47 +482,42 @@ static int jc42_detect(struct i2c_client *new_client, return -ENODEV; } -static int jc42_probe(struct i2c_client *new_client, - const struct i2c_device_id *id) +static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct jc42_data *data; int config, cap, err; + struct device *dev = &client->dev; - data = kzalloc(sizeof(struct jc42_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); + if (!data) + return -ENOMEM; - i2c_set_clientdata(new_client, data); + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP); - if (cap < 0) { - err = -EINVAL; - goto exit_free; - } + cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); + if (cap < 0) + return cap; + data->extended = !!(cap & JC42_CAP_RANGE); - config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG); - if (config < 0) { - err = -EINVAL; - goto exit_free; - } + config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); + if (config < 0) + return config; + data->orig_config = config; if (config & JC42_CFG_SHUTDOWN) { config &= ~JC42_CFG_SHUTDOWN; - i2c_smbus_write_word_swapped(new_client, JC42_REG_CONFIG, - config); + i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); } data->config = config; /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &jc42_group); + err = sysfs_create_group(&dev->kobj, &jc42_group); if (err) - goto exit_free; + return err; - data->hwmon_dev = hwmon_device_register(&new_client->dev); + data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exit_remove; @@ -548,10 +526,7 @@ static int jc42_probe(struct i2c_client *new_client, return 0; exit_remove: - sysfs_remove_group(&new_client->dev.kobj, &jc42_group); -exit_free: - kfree(data); -exit: + sysfs_remove_group(&dev->kobj, &jc42_group); return err; } @@ -563,7 +538,6 @@ static int jc42_remove(struct i2c_client *client) if (data->config != data->orig_config) i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->orig_config); - kfree(data); return 0; } @@ -614,19 +588,8 @@ abort: return ret; } -static int __init sensors_jc42_init(void) -{ - return i2c_add_driver(&jc42_driver); -} - -static void __exit sensors_jc42_exit(void) -{ - i2c_del_driver(&jc42_driver); -} +module_i2c_driver(jc42_driver); MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); MODULE_DESCRIPTION("JC42 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_jc42_init); -module_exit(sensors_jc42_exit); diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 41aa6a319870..aba29d63f195 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -205,7 +205,7 @@ static void __devexit k10temp_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static const struct pci_device_id k10temp_id_table[] = { +static DEFINE_PCI_DEVICE_TABLE(k10temp_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index b923bc2307ad..575101988751 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -46,7 +46,7 @@ struct k8temp_data { unsigned long last_updated; /* in jiffies */ /* registers values */ - u8 sensorsp; /* sensor presence bits - SEL_CORE & SEL_PLACE */ + u8 sensorsp; /* sensor presence bits - SEL_CORE, SEL_PLACE */ u32 temp[2][2]; /* core, place */ u8 swap_core_select; /* meaning of SEL_CORE is inverted */ u32 temp_offset; @@ -63,7 +63,7 @@ static struct k8temp_data *k8temp_update_device(struct device *dev) if (!data->valid || time_after(jiffies, data->last_updated + HZ)) { pci_read_config_byte(pdev, REG_TEMP, &tmp); - tmp &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ + tmp &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ pci_write_config_byte(pdev, REG_TEMP, tmp); pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]); @@ -82,7 +82,7 @@ static struct k8temp_data *k8temp_update_device(struct device *dev) &data->temp[1][0]); if (data->sensorsp & SEL_PLACE) { - tmp |= SEL_PLACE; /* Select sensor 1, core1 */ + tmp |= SEL_PLACE; /* Select sensor 1, core1 */ pci_write_config_byte(pdev, REG_TEMP, tmp); pci_read_config_dword(pdev, REG_TEMP, &data->temp[1][1]); @@ -136,7 +136,7 @@ static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0); static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -static const struct pci_device_id k8temp_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(k8temp_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, { 0 }, }; @@ -183,7 +183,8 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, u8 model, stepping; struct k8temp_data *data; - if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto exit; } @@ -217,7 +218,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, data->temp_offset = 21000; pci_read_config_byte(pdev, REG_TEMP, &scfg); - scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ + scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ pci_write_config_byte(pdev, REG_TEMP, scfg); pci_read_config_byte(pdev, REG_TEMP, &scfg); @@ -238,7 +239,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, pci_write_config_byte(pdev, REG_TEMP, scfg); pci_read_config_dword(pdev, REG_TEMP, &temp); scfg |= SEL_CORE; /* prepare for next selection */ - if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is not likely */ + if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */ data->sensorsp &= ~SEL_PLACE; } @@ -246,7 +247,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, scfg &= ~SEL_PLACE; /* Select sensor 0, core1 */ pci_write_config_byte(pdev, REG_TEMP, scfg); pci_read_config_dword(pdev, REG_TEMP, &temp); - if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is not likely */ + if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */ data->sensorsp &= ~SEL_CORE; } diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c index 58eded27f385..d264937c7f5e 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -448,7 +448,7 @@ static int pem_probe(struct i2c_client *client, | I2C_FUNC_SMBUS_WRITE_BYTE)) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -462,11 +462,11 @@ static int pem_probe(struct i2c_client *client, ret = pem_read_block(client, PEM_READ_FIRMWARE_REV, data->firmware_rev, sizeof(data->firmware_rev)); if (ret < 0) - goto out_kfree; + return ret; ret = i2c_smbus_write_byte(client, PEM_CLEAR_INFO_FLAGS); if (ret < 0) - goto out_kfree; + return ret; dev_info(&client->dev, "Firmware revision %d.%d.%d\n", data->firmware_rev[0], data->firmware_rev[1], @@ -475,7 +475,7 @@ static int pem_probe(struct i2c_client *client, /* Register sysfs hooks */ ret = sysfs_create_group(&client->dev.kobj, &pem_group); if (ret) - goto out_kfree; + return ret; /* * Check if input readings are supported. @@ -534,8 +534,6 @@ out_remove_groups: sysfs_remove_group(&client->dev.kobj, &pem_input_group); sysfs_remove_group(&client->dev.kobj, &pem_fan_group); sysfs_remove_group(&client->dev.kobj, &pem_group); -out_kfree: - kfree(data); return ret; } @@ -549,7 +547,6 @@ static int pem_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &pem_fan_group); sysfs_remove_group(&client->dev.kobj, &pem_group); - kfree(data); return 0; } @@ -568,19 +565,8 @@ static struct i2c_driver pem_driver = { .id_table = pem_id, }; -static int __init pem_init(void) -{ - return i2c_add_driver(&pem_driver); -} - -static void __exit pem_exit(void) -{ - i2c_del_driver(&pem_driver); -} +module_i2c_driver(pem_driver); MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver"); MODULE_LICENSE("GPL"); - -module_init(pem_init); -module_exit(pem_exit); diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 5e6457a6644d..602a0f0b0de8 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -148,46 +148,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; #define UPDATE_INTERVAL(max, rate) \ ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) -/* - * Functions declaration - */ - -static int lm63_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int lm63_remove(struct i2c_client *client); - -static struct lm63_data *lm63_update_device(struct device *dev); - -static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); -static void lm63_init_client(struct i2c_client *client); - enum chips { lm63, lm64, lm96163 }; /* - * Driver data (common to all clients) - */ - -static const struct i2c_device_id lm63_id[] = { - { "lm63", lm63 }, - { "lm64", lm64 }, - { "lm96163", lm96163 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, lm63_id); - -static struct i2c_driver lm63_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "lm63", - }, - .probe = lm63_probe, - .remove = lm63_remove, - .id_table = lm63_id, - .detect = lm63_detect, - .address_list = normal_i2c, -}; - -/* * Client data (each client gets its own) */ @@ -242,6 +205,145 @@ static inline int lut_temp_from_reg(struct lm63_data *data, int nr) return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); } +static inline int lut_temp_to_reg(struct lm63_data *data, long val) +{ + val -= data->temp2_offset; + if (data->lut_temp_highres) + return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127500), 500); + else + return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127000), 1000); +} + +/* + * Update the lookup table register cache. + * client->update_lock must be held when calling this function. + */ +static void lm63_update_lut(struct i2c_client *client) +{ + struct lm63_data *data = i2c_get_clientdata(client); + int i; + + if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || + !data->lut_valid) { + for (i = 0; i < data->lut_size; i++) { + data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, + LM63_REG_LUT_PWM(i)); + data->temp8[3 + i] = i2c_smbus_read_byte_data(client, + LM63_REG_LUT_TEMP(i)); + } + data->lut_temp_hyst = i2c_smbus_read_byte_data(client, + LM63_REG_LUT_TEMP_HYST); + + data->lut_last_updated = jiffies; + data->lut_valid = 1; + } +} + +static struct lm63_data *lm63_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct lm63_data *data = i2c_get_clientdata(client); + unsigned long next_update; + + mutex_lock(&data->update_lock); + + next_update = data->last_updated + + msecs_to_jiffies(data->update_interval) + 1; + + if (time_after(jiffies, next_update) || !data->valid) { + if (data->config & 0x04) { /* tachometer enabled */ + /* order matters for fan1_input */ + data->fan[0] = i2c_smbus_read_byte_data(client, + LM63_REG_TACH_COUNT_LSB) & 0xFC; + data->fan[0] |= i2c_smbus_read_byte_data(client, + LM63_REG_TACH_COUNT_MSB) << 8; + data->fan[1] = (i2c_smbus_read_byte_data(client, + LM63_REG_TACH_LIMIT_LSB) & 0xFC) + | (i2c_smbus_read_byte_data(client, + LM63_REG_TACH_LIMIT_MSB) << 8); + } + + data->pwm1_freq = i2c_smbus_read_byte_data(client, + LM63_REG_PWM_FREQ); + if (data->pwm1_freq == 0) + data->pwm1_freq = 1; + data->pwm1[0] = i2c_smbus_read_byte_data(client, + LM63_REG_PWM_VALUE); + + data->temp8[0] = i2c_smbus_read_byte_data(client, + LM63_REG_LOCAL_TEMP); + data->temp8[1] = i2c_smbus_read_byte_data(client, + LM63_REG_LOCAL_HIGH); + + /* order matters for temp2_input */ + data->temp11[0] = i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_TEMP_MSB) << 8; + data->temp11[0] |= i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_TEMP_LSB); + data->temp11[1] = (i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_LOW_MSB) << 8) + | i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_LOW_LSB); + data->temp11[2] = (i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_HIGH_MSB) << 8) + | i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_HIGH_LSB); + data->temp11[3] = (i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_OFFSET_MSB) << 8) + | i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_OFFSET_LSB); + + if (data->kind == lm96163) + data->temp11u = (i2c_smbus_read_byte_data(client, + LM96163_REG_REMOTE_TEMP_U_MSB) << 8) + | i2c_smbus_read_byte_data(client, + LM96163_REG_REMOTE_TEMP_U_LSB); + + data->temp8[2] = i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_TCRIT); + data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, + LM63_REG_REMOTE_TCRIT_HYST); + + data->alarms = i2c_smbus_read_byte_data(client, + LM63_REG_ALERT_STATUS) & 0x7F; + + data->last_updated = jiffies; + data->valid = 1; + } + + lm63_update_lut(client); + + mutex_unlock(&data->update_lock); + + return data; +} + +/* + * Trip points in the lookup table should be in ascending order for both + * temperatures and PWM output values. + */ +static int lm63_lut_looks_bad(struct i2c_client *client) +{ + struct lm63_data *data = i2c_get_clientdata(client); + int i; + + mutex_lock(&data->update_lock); + lm63_update_lut(client); + + for (i = 1; i < data->lut_size; i++) { + if (data->pwm1[1 + i - 1] > data->pwm1[1 + i] + || data->temp8[3 + i - 1] > data->temp8[3 + i]) { + dev_warn(&client->dev, + "Lookup table doesn't look sane (check entries %d and %d)\n", + i, i + 1); + break; + } + } + mutex_unlock(&data->update_lock); + + return i == data->lut_size ? 0 : 1; +} + /* * Sysfs callback functions and files */ @@ -294,13 +396,16 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr, return sprintf(buf, "%d\n", pwm); } -static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, +static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct lm63_data *data = i2c_get_clientdata(client); + int nr = attr->index; unsigned long val; int err; + u8 reg; if (!(data->config_fan & 0x20)) /* register is read-only */ return -EPERM; @@ -309,11 +414,13 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, if (err) return err; + reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE; val = SENSORS_LIMIT(val, 0, 255); + mutex_lock(&data->update_lock); - data->pwm1[0] = data->pwm_highres ? val : + data->pwm1[nr] = data->pwm_highres ? val : (val * data->pwm1_freq * 2 + 127) / 255; - i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]); + i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]); mutex_unlock(&data->update_lock); return count; } @@ -325,6 +432,41 @@ static ssize_t show_pwm1_enable(struct device *dev, return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); } +static ssize_t set_pwm1_enable(struct device *dev, + struct device_attribute *dummy, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct lm63_data *data = i2c_get_clientdata(client); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + if (val < 1 || val > 2) + return -EINVAL; + + /* + * Only let the user switch to automatic mode if the lookup table + * looks sane. + */ + if (val == 2 && lm63_lut_looks_bad(client)) + return -EPERM; + + mutex_lock(&data->update_lock); + data->config_fan = i2c_smbus_read_byte_data(client, + LM63_REG_CONFIG_FAN); + if (val == 1) + data->config_fan |= 0x20; + else + data->config_fan &= ~0x20; + i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, + data->config_fan); + mutex_unlock(&data->update_lock); + return count; +} + /* * There are 8bit registers for both local(temp1) and remote(temp2) sensor. * For remote sensor registers temp2_offset has to be considered, @@ -367,23 +509,31 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, struct i2c_client *client = to_i2c_client(dev); struct lm63_data *data = i2c_get_clientdata(client); int nr = attr->index; - int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH; long val; int err; int temp; + u8 reg; err = kstrtol(buf, 10, &val); if (err) return err; mutex_lock(&data->update_lock); - if (nr == 2) { + switch (nr) { + case 2: + reg = LM63_REG_REMOTE_TCRIT; if (data->remote_unsigned) temp = TEMP8U_TO_REG(val - data->temp2_offset); else temp = TEMP8_TO_REG(val - data->temp2_offset); - } else { + break; + case 1: + reg = LM63_REG_LOCAL_HIGH; temp = TEMP8_TO_REG(val); + break; + default: /* lookup table */ + reg = LM63_REG_LUT_TEMP(nr - 3); + temp = lut_temp_to_reg(data, val); } data->temp8[nr] = temp; i2c_smbus_write_byte_data(client, reg, temp); @@ -613,65 +763,78 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0); -static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); -static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1); -static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO, - show_lut_temp, NULL, 3); +static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, + show_pwm1_enable, set_pwm1_enable); +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 1); +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 3); static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 3); -static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2); -static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, - show_lut_temp, NULL, 4); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 2); +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 4); static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 4); -static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3); -static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO, - show_lut_temp, NULL, 5); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 3); +static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 5); static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 5); -static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4); -static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO, - show_lut_temp, NULL, 6); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 4); +static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 6); static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 6); -static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5); -static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO, - show_lut_temp, NULL, 7); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 5); +static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 7); static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 7); -static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6); -static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO, - show_lut_temp, NULL, 8); +static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 6); +static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 8); static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 8); -static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7); -static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO, - show_lut_temp, NULL, 9); +static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 7); +static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 9); static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 9); -static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8); -static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, - show_lut_temp, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 8); +static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 10); static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 10); -static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); -static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, - show_lut_temp, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 9); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 11); static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 11); -static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); -static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, - show_lut_temp, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 12); static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 12); -static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); -static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, - show_lut_temp, NULL, 13); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 13); static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 13); -static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); -static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, - show_lut_temp, NULL, 14); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IWUSR | S_IRUGO, + show_pwm1, set_pwm1, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IWUSR | S_IRUGO, + show_lut_temp, set_temp8, 14); static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 14); @@ -817,28 +980,25 @@ static const struct attribute_group lm63_group_fan1 = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm63_detect(struct i2c_client *new_client, +static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info) { - struct i2c_adapter *adapter = new_client->adapter; + struct i2c_adapter *adapter = client->adapter; u8 man_id, chip_id, reg_config1, reg_config2; u8 reg_alert_status, reg_alert_mask; - int address = new_client->addr; + int address = client->addr; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - man_id = i2c_smbus_read_byte_data(new_client, LM63_REG_MAN_ID); - chip_id = i2c_smbus_read_byte_data(new_client, LM63_REG_CHIP_ID); + man_id = i2c_smbus_read_byte_data(client, LM63_REG_MAN_ID); + chip_id = i2c_smbus_read_byte_data(client, LM63_REG_CHIP_ID); - reg_config1 = i2c_smbus_read_byte_data(new_client, - LM63_REG_CONFIG1); - reg_config2 = i2c_smbus_read_byte_data(new_client, - LM63_REG_CONFIG2); - reg_alert_status = i2c_smbus_read_byte_data(new_client, + reg_config1 = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); + reg_config2 = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG2); + reg_alert_status = i2c_smbus_read_byte_data(client, LM63_REG_ALERT_STATUS); - reg_alert_mask = i2c_smbus_read_byte_data(new_client, - LM63_REG_ALERT_MASK); + reg_alert_mask = i2c_smbus_read_byte_data(client, LM63_REG_ALERT_MASK); if (man_id != 0x01 /* National Semiconductor */ || (reg_config1 & 0x18) != 0x00 @@ -863,74 +1023,6 @@ static int lm63_detect(struct i2c_client *new_client, return 0; } -static int lm63_probe(struct i2c_client *new_client, - const struct i2c_device_id *id) -{ - struct lm63_data *data; - int err; - - data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(new_client, data); - data->valid = 0; - mutex_init(&data->update_lock); - - /* Set the device type */ - data->kind = id->driver_data; - if (data->kind == lm64) - data->temp2_offset = 16000; - - /* Initialize chip */ - lm63_init_client(new_client); - - /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &lm63_group); - if (err) - goto exit_free; - if (data->config & 0x04) { /* tachometer enabled */ - err = sysfs_create_group(&new_client->dev.kobj, - &lm63_group_fan1); - if (err) - goto exit_remove_files; - } - if (data->kind == lm96163) { - err = device_create_file(&new_client->dev, - &dev_attr_temp2_type); - if (err) - goto exit_remove_files; - - err = sysfs_create_group(&new_client->dev.kobj, - &lm63_group_extra_lut); - if (err) - goto exit_remove_files; - } - - data->hwmon_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - return 0; - -exit_remove_files: - sysfs_remove_group(&new_client->dev.kobj, &lm63_group); - sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); - if (data->kind == lm96163) { - device_remove_file(&new_client->dev, &dev_attr_temp2_type); - sysfs_remove_group(&new_client->dev.kobj, - &lm63_group_extra_lut); - } -exit_free: - kfree(data); -exit: - return err; -} - /* * Ideally we shouldn't have to initialize anything, since the BIOS * should have taken care of everything @@ -1010,128 +1102,113 @@ static void lm63_init_client(struct i2c_client *client) (data->config_fan & 0x20) ? "manual" : "auto"); } -static int lm63_remove(struct i2c_client *client) +static int lm63_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct lm63_data *data = i2c_get_clientdata(client); + struct lm63_data *data; + int err; - hwmon_device_unregister(data->hwmon_dev); + data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Set the device type */ + data->kind = id->driver_data; + if (data->kind == lm64) + data->temp2_offset = 16000; + + /* Initialize chip */ + lm63_init_client(client); + + /* Register sysfs hooks */ + err = sysfs_create_group(&client->dev.kobj, &lm63_group); + if (err) + goto exit_free; + if (data->config & 0x04) { /* tachometer enabled */ + err = sysfs_create_group(&client->dev.kobj, &lm63_group_fan1); + if (err) + goto exit_remove_files; + } + if (data->kind == lm96163) { + err = device_create_file(&client->dev, &dev_attr_temp2_type); + if (err) + goto exit_remove_files; + + err = sysfs_create_group(&client->dev.kobj, + &lm63_group_extra_lut); + if (err) + goto exit_remove_files; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove_files; + } + + return 0; + +exit_remove_files: sysfs_remove_group(&client->dev.kobj, &lm63_group); sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); if (data->kind == lm96163) { device_remove_file(&client->dev, &dev_attr_temp2_type); sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); } - +exit_free: kfree(data); - return 0; +exit: + return err; } -static struct lm63_data *lm63_update_device(struct device *dev) +static int lm63_remove(struct i2c_client *client) { - struct i2c_client *client = to_i2c_client(dev); struct lm63_data *data = i2c_get_clientdata(client); - unsigned long next_update; - int i; - mutex_lock(&data->update_lock); - - next_update = data->last_updated - + msecs_to_jiffies(data->update_interval) + 1; - - if (time_after(jiffies, next_update) || !data->valid) { - if (data->config & 0x04) { /* tachometer enabled */ - /* order matters for fan1_input */ - data->fan[0] = i2c_smbus_read_byte_data(client, - LM63_REG_TACH_COUNT_LSB) & 0xFC; - data->fan[0] |= i2c_smbus_read_byte_data(client, - LM63_REG_TACH_COUNT_MSB) << 8; - data->fan[1] = (i2c_smbus_read_byte_data(client, - LM63_REG_TACH_LIMIT_LSB) & 0xFC) - | (i2c_smbus_read_byte_data(client, - LM63_REG_TACH_LIMIT_MSB) << 8); - } - - data->pwm1_freq = i2c_smbus_read_byte_data(client, - LM63_REG_PWM_FREQ); - if (data->pwm1_freq == 0) - data->pwm1_freq = 1; - data->pwm1[0] = i2c_smbus_read_byte_data(client, - LM63_REG_PWM_VALUE); - - data->temp8[0] = i2c_smbus_read_byte_data(client, - LM63_REG_LOCAL_TEMP); - data->temp8[1] = i2c_smbus_read_byte_data(client, - LM63_REG_LOCAL_HIGH); - - /* order matters for temp2_input */ - data->temp11[0] = i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_TEMP_MSB) << 8; - data->temp11[0] |= i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_TEMP_LSB); - data->temp11[1] = (i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_LOW_MSB) << 8) - | i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_LOW_LSB); - data->temp11[2] = (i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_HIGH_MSB) << 8) - | i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_HIGH_LSB); - data->temp11[3] = (i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_OFFSET_MSB) << 8) - | i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_OFFSET_LSB); - - if (data->kind == lm96163) - data->temp11u = (i2c_smbus_read_byte_data(client, - LM96163_REG_REMOTE_TEMP_U_MSB) << 8) - | i2c_smbus_read_byte_data(client, - LM96163_REG_REMOTE_TEMP_U_LSB); - - data->temp8[2] = i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_TCRIT); - data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, - LM63_REG_REMOTE_TCRIT_HYST); - - data->alarms = i2c_smbus_read_byte_data(client, - LM63_REG_ALERT_STATUS) & 0x7F; - - data->last_updated = jiffies; - data->valid = 1; + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &lm63_group); + sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); + if (data->kind == lm96163) { + device_remove_file(&client->dev, &dev_attr_temp2_type); + sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); } - if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || - !data->lut_valid) { - for (i = 0; i < data->lut_size; i++) { - data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, - LM63_REG_LUT_PWM(i)); - data->temp8[3 + i] = i2c_smbus_read_byte_data(client, - LM63_REG_LUT_TEMP(i)); - } - data->lut_temp_hyst = i2c_smbus_read_byte_data(client, - LM63_REG_LUT_TEMP_HYST); - - data->lut_last_updated = jiffies; - data->lut_valid = 1; - } + kfree(data); + return 0; +} - mutex_unlock(&data->update_lock); +/* + * Driver data (common to all clients) + */ - return data; -} +static const struct i2c_device_id lm63_id[] = { + { "lm63", lm63 }, + { "lm64", lm64 }, + { "lm96163", lm96163 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm63_id); -static int __init sensors_lm63_init(void) -{ - return i2c_add_driver(&lm63_driver); -} +static struct i2c_driver lm63_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "lm63", + }, + .probe = lm63_probe, + .remove = lm63_remove, + .id_table = lm63_id, + .detect = lm63_detect, + .address_list = normal_i2c, +}; -static void __exit sensors_lm63_exit(void) -{ - i2c_del_driver(&lm63_driver); -} +module_i2c_driver(lm63_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("LM63 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm63_init); -module_exit(sensors_lm63_exit); diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index c274ea25d899..472f79521a96 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -57,7 +57,7 @@ static ssize_t lm70_sense_temp(struct device *dev, struct spi_device *spi = to_spi_device(dev); int status, val = 0; u8 rxbuf[2]; - s16 raw=0; + s16 raw = 0; struct lm70 *p_lm70 = spi_get_drvdata(spi); if (mutex_lock_interruptible(&p_lm70->lock)) @@ -156,6 +156,15 @@ static int __devinit lm70_probe(struct spi_device *spi) mutex_init(&p_lm70->lock); p_lm70->chip = chip; + spi_set_drvdata(spi, p_lm70); + + status = device_create_file(&spi->dev, &dev_attr_temp1_input); + if (status) + goto out_dev_create_temp_file_failed; + status = device_create_file(&spi->dev, &dev_attr_name); + if (status) + goto out_dev_create_file_failed; + /* sysfs hook */ p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); if (IS_ERR(p_lm70->hwmon_dev)) { @@ -163,20 +172,14 @@ static int __devinit lm70_probe(struct spi_device *spi) status = PTR_ERR(p_lm70->hwmon_dev); goto out_dev_reg_failed; } - spi_set_drvdata(spi, p_lm70); - - if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input)) - || (status = device_create_file(&spi->dev, &dev_attr_name))) { - dev_dbg(&spi->dev, "device_create_file failure.\n"); - goto out_dev_create_file_failed; - } return 0; +out_dev_reg_failed: + device_remove_file(&spi->dev, &dev_attr_name); out_dev_create_file_failed: device_remove_file(&spi->dev, &dev_attr_temp1_input); - hwmon_device_unregister(p_lm70->hwmon_dev); -out_dev_reg_failed: +out_dev_create_temp_file_failed: spi_set_drvdata(spi, NULL); kfree(p_lm70); return status; @@ -186,9 +189,9 @@ static int __devexit lm70_remove(struct spi_device *spi) { struct lm70 *p_lm70 = spi_get_drvdata(spi); + hwmon_device_unregister(p_lm70->hwmon_dev); device_remove_file(&spi->dev, &dev_attr_temp1_input); device_remove_file(&spi->dev, &dev_attr_name); - hwmon_device_unregister(p_lm70->hwmon_dev); spi_set_drvdata(spi, NULL); kfree(p_lm70); @@ -213,18 +216,7 @@ static struct spi_driver lm70_driver = { .remove = __devexit_p(lm70_remove), }; -static int __init init_lm70(void) -{ - return spi_register_driver(&lm70_driver); -} - -static void __exit cleanup_lm70(void) -{ - spi_unregister_driver(&lm70_driver); -} - -module_init(init_lm70); -module_exit(cleanup_lm70); +module_spi_driver(lm70_driver); MODULE_AUTHOR("Kaiwan N Billimoria"); MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver"); diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 9c8093c4b307..8fa2632cbbaf 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -194,21 +194,8 @@ static struct i2c_driver lm73_driver = { .address_list = normal_i2c, }; -/* module glue */ - -static int __init sensors_lm73_init(void) -{ - return i2c_add_driver(&lm73_driver); -} - -static void __exit sensors_lm73_exit(void) -{ - i2c_del_driver(&lm73_driver); -} +module_i2c_driver(lm73_driver); MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@gmail.com>"); MODULE_DESCRIPTION("LM73 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm73_init); -module_exit(sensors_lm73_exit); diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index b3311b1d3d92..a83f206af244 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -438,23 +438,8 @@ abort: return ret; } -/*-----------------------------------------------------------------------*/ - -/* module glue */ - -static int __init sensors_lm75_init(void) -{ - return i2c_add_driver(&lm75_driver); -} - -static void __exit sensors_lm75_exit(void) -{ - i2c_del_driver(&lm75_driver); -} +module_i2c_driver(lm75_driver); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); MODULE_DESCRIPTION("LM75 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm75_init); -module_exit(sensors_lm75_exit); diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 8dfc6782d596..0fca8613e7d8 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -1,29 +1,29 @@ /* - lm77.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - - Copyright (c) 2004 Andras BALI <drewie@freemail.hu> - - Heavily based on lm75.c by Frodo Looijaard <frodol@dds.nl>. The LM77 - is a temperature sensor and thermal window comparator with 0.5 deg - resolution made by National Semiconductor. Complete datasheet can be - obtained at their site: - http://www.national.com/pf/LM/LM77.html - - 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. -*/ + * lm77.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * + * Copyright (c) 2004 Andras BALI <drewie@freemail.hu> + * + * Heavily based on lm75.c by Frodo Looijaard <frodol@dds.nl>. The LM77 + * is a temperature sensor and thermal window comparator with 0.5 deg + * resolution made by National Semiconductor. Complete datasheet can be + * obtained at their site: + * http://www.national.com/pf/LM/LM77.html + * + * 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 <linux/module.h> #include <linux/init.h> @@ -49,7 +49,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, /* Each client has this additional data */ struct lm77_data { - struct device *hwmon_dev; + struct device *hwmon_dev; struct mutex update_lock; char valid; unsigned long last_updated; /* In jiffies */ @@ -95,8 +95,10 @@ static struct i2c_driver lm77_driver = { #define LM77_TEMP_MIN (-55000) #define LM77_TEMP_MAX 125000 -/* In the temperature registers, the low 3 bits are not part of the - temperature values; they are the status bits. */ +/* + * In the temperature registers, the low 3 bits are not part of the + * temperature values; they are the status bits. + */ static inline s16 LM77_TEMP_TO_REG(int temp) { int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); @@ -112,7 +114,9 @@ static inline int LM77_TEMP_FROM_REG(s16 reg) /* read routines for temperature limits */ #define show(value) \ -static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##value(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ { \ struct lm77_data *data = lm77_update_device(dev); \ return sprintf(buf, "%d\n", data->value); \ @@ -124,17 +128,20 @@ show(temp_min); show(temp_max); /* read routines for hysteresis values */ -static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_crit_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm77_data *data = lm77_update_device(dev); return sprintf(buf, "%d\n", data->temp_crit - data->temp_hyst); } -static ssize_t show_temp_min_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_min_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm77_data *data = lm77_update_device(dev); return sprintf(buf, "%d\n", data->temp_min + data->temp_hyst); } -static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_max_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm77_data *data = lm77_update_device(dev); return sprintf(buf, "%d\n", data->temp_max - data->temp_hyst); @@ -142,29 +149,42 @@ static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute *a /* write routines */ #define set(value, reg) \ -static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm77_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ - \ - mutex_lock(&data->update_lock); \ - data->value = val; \ - lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value)); \ - mutex_unlock(&data->update_lock); \ - return count; \ +static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm77_data *data = i2c_get_clientdata(client); \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ + \ + mutex_lock(&data->update_lock); \ + data->value = val; \ + lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value)); \ + mutex_unlock(&data->update_lock); \ + return count; \ } set(temp_min, LM77_REG_TEMP_MIN); set(temp_max, LM77_REG_TEMP_MAX); -/* hysteresis is stored as a relative value on the chip, so it has to be - converted first */ -static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +/* + * hysteresis is stored as a relative value on the chip, so it has to be + * converted first + */ +static ssize_t set_temp_crit_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm77_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_hyst = data->temp_crit - val; @@ -175,13 +195,19 @@ static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *a } /* preserve hysteresis when setting T_crit */ -static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm77_data *data = i2c_get_clientdata(client); - long val = simple_strtoul(buf, NULL, 10); int oldcrithyst; - + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); oldcrithyst = data->temp_crit - data->temp_hyst; data->temp_crit = val; @@ -251,17 +277,19 @@ static int lm77_detect(struct i2c_client *new_client, I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; - /* Here comes the remaining detection. Since the LM77 has no - register dedicated to identification, we have to rely on the - following tricks: - - 1. the high 4 bits represent the sign and thus they should - always be the same - 2. the high 3 bits are unused in the configuration register - 3. addresses 0x06 and 0x07 return the last read value - 4. registers cycling over 8-address boundaries - - Word-sized registers are high-byte first. */ + /* + * Here comes the remaining detection. Since the LM77 has no + * register dedicated to identification, we have to rely on the + * following tricks: + * + * 1. the high 4 bits represent the sign and thus they should + * always be the same + * 2. the high 3 bits are unused in the configuration register + * 3. addresses 0x06 and 0x07 return the last read value + * 4. registers cycling over 8-address boundaries + * + * Word-sized registers are high-byte first. + */ /* addresses cycling */ cur = i2c_smbus_read_word_data(new_client, 0); @@ -330,7 +358,8 @@ static int lm77_probe(struct i2c_client *new_client, lm77_init_client(new_client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) + err = sysfs_create_group(&new_client->dev.kobj, &lm77_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); @@ -358,8 +387,10 @@ static int lm77_remove(struct i2c_client *client) return 0; } -/* All registers are word-sized, except for the configuration register. - The LM77 uses the high-byte first convention. */ +/* + * All registers are word-sized, except for the configuration register. + * The LM77 uses the high-byte first convention. + */ static u16 lm77_read_value(struct i2c_client *client, u8 reg) { if (reg == LM77_REG_CONF) @@ -420,19 +451,8 @@ static struct lm77_data *lm77_update_device(struct device *dev) return data; } -static int __init sensors_lm77_init(void) -{ - return i2c_add_driver(&lm77_driver); -} - -static void __exit sensors_lm77_exit(void) -{ - i2c_del_driver(&lm77_driver); -} +module_i2c_driver(lm77_driver); MODULE_AUTHOR("Andras BALI <drewie@freemail.hu>"); MODULE_DESCRIPTION("LM77 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm77_init); -module_exit(sensors_lm77_exit); diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 6df0b4681710..f6bc414e1e91 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -1,23 +1,23 @@ /* - lm78.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> - Copyright (c) 2007, 2011 Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * lm78.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> + * Copyright (c) 2007, 2011 Jean Delvare <khali@linux-fr.org> + * + * 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. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -74,11 +74,15 @@ enum chips { lm78, lm79 }; #define LM78_REG_I2C_ADDR 0x48 -/* Conversions. Rounding and limit checking is only done on the TO_REG - variants. */ +/* + * Conversions. Rounding and limit checking is only done on the TO_REG + * variants. + */ -/* IN: mV, (0V to 4.08V) - REG: 16mV/bit */ +/* + * IN: mV (0V to 4.08V) + * REG: 16mV/bit + */ static inline u8 IN_TO_REG(unsigned long val) { unsigned long nval = SENSORS_LIMIT(val, 0, 4080); @@ -95,15 +99,17 @@ static inline u8 FAN_TO_REG(long rpm, int div) static inline int FAN_FROM_REG(u8 val, int div) { - return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div); + return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div); } -/* TEMP: mC (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: mC (-128C to +127C) + * REG: 1C/bit, two's complement + */ static inline s8 TEMP_TO_REG(int val) { int nval = SENSORS_LIMIT(val, -128000, 127000) ; - return nval<0 ? (nval-500)/1000 : (nval+500)/1000; + return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000; } static inline int TEMP_FROM_REG(s8 val) @@ -177,8 +183,13 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); int nr = attr->index; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val); @@ -192,8 +203,13 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); int nr = attr->index; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val); @@ -201,7 +217,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da, mutex_unlock(&data->update_lock); return count; } - + #define show_in_offset(offset) \ static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ show_in, NULL, offset); \ @@ -237,7 +253,12 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct lm78_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_over = TEMP_TO_REG(val); @@ -257,7 +278,12 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct lm78_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_hyst = TEMP_TO_REG(val); @@ -280,7 +306,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da, struct lm78_data *data = lm78_update_device(dev); int nr = attr->index; return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], - DIV_FROM_REG(data->fan_div[nr])) ); + DIV_FROM_REG(data->fan_div[nr]))); } static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, @@ -289,8 +315,8 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); int nr = attr->index; - return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], - DIV_FROM_REG(data->fan_div[nr])) ); + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr]))); } static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, @@ -299,7 +325,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -316,29 +347,44 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); unsigned long min; u8 reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); switch (val) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; + case 1: + data->fan_div[nr] = 0; + break; + case 2: + data->fan_div[nr] = 1; + break; + case 4: + data->fan_div[nr] = 2; + break; + case 8: + data->fan_div[nr] = 3; + break; default: dev_err(dev, "fan_div value %ld not " "supported. Choose one of 1, 2, 4 or 8!\n", val); @@ -484,8 +530,10 @@ static struct platform_device *pdev; static unsigned short isa_address = 0x290; -/* I2C devices get this name attribute automatically, but for ISA devices - we must create it by ourselves. */ +/* + * I2C devices get this name attribute automatically, but for ISA devices + * we must create it by ourselves. + */ static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -515,8 +563,10 @@ static int lm78_alias_detect(struct i2c_client *client, u8 chipid) if ((lm78_read_value(isa, LM78_REG_CHIPID) & 0xfe) != (chipid & 0xfe)) return 0; /* Chip type doesn't match */ - /* We compare all the limit registers, the config register and the - * interrupt mask registers */ + /* + * We compare all the limit registers, the config register and the + * interrupt mask registers + */ for (i = 0x2b; i <= 0x3d; i++) { if (lm78_read_value(isa, i) != i2c_smbus_read_byte_data(client, i)) @@ -558,9 +608,11 @@ static int lm78_i2c_detect(struct i2c_client *client, if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - /* We block updates of the ISA device to minimize the risk of - concurrent access to the same LM78 chip through different - interfaces. */ + /* + * We block updates of the ISA device to minimize the risk of + * concurrent access to the same LM78 chip through different + * interfaces. + */ if (isa) mutex_lock(&isa->update_lock); @@ -669,11 +721,13 @@ static struct i2c_driver lm78_driver = { .address_list = normal_i2c, }; -/* The SMBus locks itself, but ISA access must be locked explicitly! - We don't want to lock the whole ISA bus, so we lock each client - separately. - We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, - would slow down the LM78 access and should not be necessary. */ +/* + * The SMBus locks itself, but ISA access must be locked explicitly! + * We don't want to lock the whole ISA bus, so we lock each client + * separately. + * We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, + * would slow down the LM78 access and should not be necessary. + */ static int lm78_read_value(struct lm78_data *data, u8 reg) { struct i2c_client *client = data->client; @@ -691,13 +745,6 @@ static int lm78_read_value(struct lm78_data *data, u8 reg) return i2c_smbus_read_byte_data(client, reg); } -/* The SMBus locks itself, but ISA access muse be locked explicitly! - We don't want to lock the whole ISA bus, so we lock each client - separately. - We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, - would slow down the LM78 access and should not be necessary. - There are some ugly typecasts here, but the good new is - they should - nowhere else be necessary! */ static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) { struct i2c_client *client = data->client; @@ -823,8 +870,11 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) lm78_init_device(data); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group)) - || (err = device_create_file(&pdev->dev, &dev_attr_name))) + err = sysfs_create_group(&pdev->dev.kobj, &lm78_group); + if (err) + goto exit_remove_files; + err = device_create_file(&pdev->dev, &dev_attr_name); + if (err) goto exit_remove_files; data->hwmon_dev = hwmon_device_register(&pdev->dev); @@ -876,9 +926,11 @@ static int __init lm78_isa_found(unsigned short address) int val, save, found = 0; int port; - /* Some boards declare base+0 to base+7 as a PNP device, some base+4 + /* + * Some boards declare base+0 to base+7 as a PNP device, some base+4 * to base+7 and some base+5 to base+6. So we better request each port - * individually for the probing phase. */ + * individually for the probing phase. + */ for (port = address; port < address + LM78_EXTENT; port++) { if (!request_region(port, 1, "lm78")) { pr_debug("Failed to request port 0x%x\n", port); @@ -887,8 +939,10 @@ static int __init lm78_isa_found(unsigned short address) } #define REALLY_SLOW_IO - /* We need the timeouts for at least some LM78-like - chips. But only if we read 'undefined' registers. */ + /* + * We need the timeouts for at least some LM78-like + * chips. But only if we read 'undefined' registers. + */ val = inb_p(address + 1); if (inb_p(address + 2) != val || inb_p(address + 3) != val @@ -896,8 +950,10 @@ static int __init lm78_isa_found(unsigned short address) goto release; #undef REALLY_SLOW_IO - /* We should be able to change the 7 LSB of the address port. The - MSB (busy flag) should be clear initially, set after the write. */ + /* + * We should be able to change the 7 LSB of the address port. The + * MSB (busy flag) should be clear initially, set after the write. + */ save = inb_p(address + LM78_ADDR_REG_OFFSET); if (save & 0x80) goto release; @@ -1036,8 +1092,10 @@ static int __init sm_lm78_init(void) { int res; - /* We register the ISA device first, so that we can skip the - * registration of an I2C interface to the same device. */ + /* + * We register the ISA device first, so that we can skip the + * registration of an I2C interface to the same device. + */ res = lm78_isa_register(); if (res) goto exit; diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 0891b38ffec0..e2c43e1774be 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -1,8 +1,8 @@ /* * lm80.c - From lm_sensors, Linux kernel modules for hardware - * monitoring + * monitoring * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> - * and Philip Edelbrock <phil@netroedge.com> + * and Philip Edelbrock <phil@netroedge.com> * * Ported to Linux 2.6 by Tiago Sousa <mirage@kaotik.org> * @@ -60,11 +60,17 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, #define LM80_REG_FANDIV 0x05 #define LM80_REG_RES 0x06 +#define LM96080_REG_CONV_RATE 0x07 +#define LM96080_REG_MAN_ID 0x3e +#define LM96080_REG_DEV_ID 0x3f -/* Conversions. Rounding and limit checking is only done on the TO_REG - variants. Note that you should be a bit careful with which arguments - these macros are called: arguments may be evaluated more than once. - Fixing this is just not worth it. */ + +/* + * Conversions. Rounding and limit checking is only done on the TO_REG + * variants. Note that you should be a bit careful with which arguments + * these macros are called: arguments may be evaluated more than once. + * Fixing this is just not worth it. + */ #define IN_TO_REG(val) (SENSORS_LIMIT(((val) + 5) / 10, 0, 255)) #define IN_FROM_REG(val) ((val) * 10) @@ -108,6 +114,7 @@ static inline long TEMP_FROM_REG(u16 temp) struct lm80_data { struct device *hwmon_dev; struct mutex update_lock; + char error; /* !=0 if error occurred during last update */ char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ @@ -144,6 +151,7 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); static const struct i2c_device_id lm80_id[] = { { "lm80", 0 }, + { "lm96080", 1 }, { } }; MODULE_DEVICE_TABLE(i2c, lm80_id); @@ -170,6 +178,8 @@ static ssize_t show_in_##suffix(struct device *dev, \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct lm80_data *data = lm80_update_device(dev); \ + if (IS_ERR(data)) \ + return PTR_ERR(data); \ return sprintf(buf, "%d\n", IN_FROM_REG(data->value[nr])); \ } show_in(min, in_min) @@ -183,7 +193,10 @@ static ssize_t set_in_##suffix(struct device *dev, \ int nr = to_sensor_dev_attr(attr)->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err < 0) \ + return err; \ \ mutex_lock(&data->update_lock);\ data->value[nr] = IN_TO_REG(val); \ @@ -200,6 +213,8 @@ static ssize_t show_fan_##suffix(struct device *dev, \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct lm80_data *data = lm80_update_device(dev); \ + if (IS_ERR(data)) \ + return PTR_ERR(data); \ return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[nr], \ DIV_FROM_REG(data->fan_div[nr]))); \ } @@ -211,6 +226,8 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, { int nr = to_sensor_dev_attr(attr)->index; struct lm80_data *data = lm80_update_device(dev); + if (IS_ERR(data)) + return PTR_ERR(data); return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); } @@ -220,7 +237,10 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm80_data *data = i2c_get_clientdata(client); - long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -229,18 +249,23 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, return count; } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm80_data *data = i2c_get_clientdata(client); - unsigned long min, val = simple_strtoul(buf, NULL, 10); + unsigned long min, val; u8 reg; + int err = kstrtoul(buf, 10, &val); + if (err < 0) + return err; /* Save fan_min */ mutex_lock(&data->update_lock); @@ -283,6 +308,8 @@ static ssize_t show_temp_input1(struct device *dev, struct device_attribute *attr, char *buf) { struct lm80_data *data = lm80_update_device(dev); + if (IS_ERR(data)) + return PTR_ERR(data); return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp)); } @@ -291,6 +318,8 @@ static ssize_t show_temp_##suffix(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct lm80_data *data = lm80_update_device(dev); \ + if (IS_ERR(data)) \ + return PTR_ERR(data); \ return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \ } show_temp(hot_max, temp_hot_max); @@ -304,7 +333,10 @@ static ssize_t set_temp_##suffix(struct device *dev, \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ - long val = simple_strtoul(buf, NULL, 10); \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err < 0) \ + return err; \ \ mutex_lock(&data->update_lock); \ data->value = TEMP_LIMIT_TO_REG(val); \ @@ -321,6 +353,8 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) { struct lm80_data *data = lm80_update_device(dev); + if (IS_ERR(data)) + return PTR_ERR(data); return sprintf(buf, "%u\n", data->alarms); } @@ -329,6 +363,8 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, { int bitnr = to_sensor_dev_attr(attr)->index; struct lm80_data *data = lm80_update_device(dev); + if (IS_ERR(data)) + return PTR_ERR(data); return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); } @@ -459,23 +495,44 @@ static const struct attribute_group lm80_group = { static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; - int i, cur; + int i, cur, man_id, dev_id; + const char *name = NULL; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - /* Now, we do the remaining detection. It is lousy. */ - if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0) + /* First check for unused bits, common to both chip types */ + if ((lm80_read_value(client, LM80_REG_ALARM2) & 0xc0) + || (lm80_read_value(client, LM80_REG_CONFIG) & 0x80)) return -ENODEV; - for (i = 0x2a; i <= 0x3d; i++) { - cur = i2c_smbus_read_byte_data(client, i); - if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur) - || (i2c_smbus_read_byte_data(client, i + 0x80) != cur) - || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur)) + + /* + * The LM96080 has manufacturer and stepping/die rev registers so we + * can just check that. The LM80 does not have such registers so we + * have to use a more expensive trick. + */ + man_id = lm80_read_value(client, LM96080_REG_MAN_ID); + dev_id = lm80_read_value(client, LM96080_REG_DEV_ID); + if (man_id == 0x01 && dev_id == 0x08) { + /* Check more unused bits for confirmation */ + if (lm80_read_value(client, LM96080_REG_CONV_RATE) & 0xfe) return -ENODEV; + + name = "lm96080"; + } else { + /* Check 6-bit addressing */ + for (i = 0x2a; i <= 0x3d; i++) { + cur = i2c_smbus_read_byte_data(client, i); + if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur) + || (i2c_smbus_read_byte_data(client, i + 0x80) != cur) + || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur)) + return -ENODEV; + } + + name = "lm80"; } - strlcpy(info->type, "lm80", I2C_NAME_SIZE); + strlcpy(info->type, name, I2C_NAME_SIZE); return 0; } @@ -547,9 +604,11 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value) /* Called when we have found a new LM80. */ static void lm80_init_client(struct i2c_client *client) { - /* Reset all except Watchdog values and last conversion values - This sets fan-divs to 2, among others. This makes most other - initializations unnecessary */ + /* + * Reset all except Watchdog values and last conversion values + * This sets fan-divs to 2, among others. This makes most other + * initializations unnecessary + */ lm80_write_value(client, LM80_REG_CONFIG, 0x80); /* Set 11-bit temperature resolution */ lm80_write_value(client, LM80_REG_RES, 0x08); @@ -563,66 +622,116 @@ static struct lm80_data *lm80_update_device(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct lm80_data *data = i2c_get_clientdata(client); int i; + int rv; + int prev_rv; + struct lm80_data *ret = data; mutex_lock(&data->update_lock); + if (data->error) + lm80_init_client(client); + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { dev_dbg(&client->dev, "Starting lm80 update\n"); for (i = 0; i <= 6; i++) { - data->in[i] = - lm80_read_value(client, LM80_REG_IN(i)); - data->in_min[i] = - lm80_read_value(client, LM80_REG_IN_MIN(i)); - data->in_max[i] = - lm80_read_value(client, LM80_REG_IN_MAX(i)); + rv = lm80_read_value(client, LM80_REG_IN(i)); + if (rv < 0) + goto abort; + data->in[i] = rv; + + rv = lm80_read_value(client, LM80_REG_IN_MIN(i)); + if (rv < 0) + goto abort; + data->in_min[i] = rv; + + rv = lm80_read_value(client, LM80_REG_IN_MAX(i)); + if (rv < 0) + goto abort; + data->in_max[i] = rv; } - data->fan[0] = lm80_read_value(client, LM80_REG_FAN1); - data->fan_min[0] = - lm80_read_value(client, LM80_REG_FAN_MIN(1)); - data->fan[1] = lm80_read_value(client, LM80_REG_FAN2); - data->fan_min[1] = - lm80_read_value(client, LM80_REG_FAN_MIN(2)); - - data->temp = - (lm80_read_value(client, LM80_REG_TEMP) << 8) | - (lm80_read_value(client, LM80_REG_RES) & 0xf0); - data->temp_os_max = - lm80_read_value(client, LM80_REG_TEMP_OS_MAX); - data->temp_os_hyst = - lm80_read_value(client, LM80_REG_TEMP_OS_HYST); - data->temp_hot_max = - lm80_read_value(client, LM80_REG_TEMP_HOT_MAX); - data->temp_hot_hyst = - lm80_read_value(client, LM80_REG_TEMP_HOT_HYST); - - i = lm80_read_value(client, LM80_REG_FANDIV); - data->fan_div[0] = (i >> 2) & 0x03; - data->fan_div[1] = (i >> 4) & 0x03; - data->alarms = lm80_read_value(client, LM80_REG_ALARM1) + - (lm80_read_value(client, LM80_REG_ALARM2) << 8); + + rv = lm80_read_value(client, LM80_REG_FAN1); + if (rv < 0) + goto abort; + data->fan[0] = rv; + + rv = lm80_read_value(client, LM80_REG_FAN_MIN(1)); + if (rv < 0) + goto abort; + data->fan_min[0] = rv; + + rv = lm80_read_value(client, LM80_REG_FAN2); + if (rv < 0) + goto abort; + data->fan[1] = rv; + + rv = lm80_read_value(client, LM80_REG_FAN_MIN(2)); + if (rv < 0) + goto abort; + data->fan_min[1] = rv; + + prev_rv = rv = lm80_read_value(client, LM80_REG_TEMP); + if (rv < 0) + goto abort; + rv = lm80_read_value(client, LM80_REG_RES); + if (rv < 0) + goto abort; + data->temp = (prev_rv << 8) | (rv & 0xf0); + + rv = lm80_read_value(client, LM80_REG_TEMP_OS_MAX); + if (rv < 0) + goto abort; + data->temp_os_max = rv; + + rv = lm80_read_value(client, LM80_REG_TEMP_OS_HYST); + if (rv < 0) + goto abort; + data->temp_os_hyst = rv; + + rv = lm80_read_value(client, LM80_REG_TEMP_HOT_MAX); + if (rv < 0) + goto abort; + data->temp_hot_max = rv; + + rv = lm80_read_value(client, LM80_REG_TEMP_HOT_HYST); + if (rv < 0) + goto abort; + data->temp_hot_hyst = rv; + + rv = lm80_read_value(client, LM80_REG_FANDIV); + if (rv < 0) + goto abort; + data->fan_div[0] = (rv >> 2) & 0x03; + data->fan_div[1] = (rv >> 4) & 0x03; + + prev_rv = rv = lm80_read_value(client, LM80_REG_ALARM1); + if (rv < 0) + goto abort; + rv = lm80_read_value(client, LM80_REG_ALARM2); + if (rv < 0) + goto abort; + data->alarms = prev_rv + (rv << 8); + data->last_updated = jiffies; data->valid = 1; + data->error = 0; } + goto done; + +abort: + ret = ERR_PTR(rv); + data->valid = 0; + data->error = 1; +done: mutex_unlock(&data->update_lock); - return data; + return ret; } -static int __init sensors_lm80_init(void) -{ - return i2c_add_driver(&lm80_driver); -} - -static void __exit sensors_lm80_exit(void) -{ - i2c_del_driver(&lm80_driver); -} +module_i2c_driver(lm80_driver); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " "Philip Edelbrock <phil@netroedge.com>"); MODULE_DESCRIPTION("LM80 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm80_init); -module_exit(sensors_lm80_exit); diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 8290476aee4a..cd45b9d85584 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -124,7 +124,7 @@ static struct lm83_data *lm83_update_device(struct device *dev); /* * Driver data (common to all clients) */ - + static const struct i2c_device_id lm83_id[] = { { "lm83", lm83 }, { "lm82", lm82 }, @@ -179,8 +179,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct lm83_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; int nr = attr->index; + int err; + + err = kstrtol(buf, 10, &val); + if (err < 0) + return err; mutex_lock(&data->update_lock); data->temp[nr] = TEMP_TO_REG(val); @@ -355,12 +360,14 @@ static int lm83_probe(struct i2c_client *new_client, * declare 1 and 3 common, and then 2 and 4 only for the LM83. */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group))) + err = sysfs_create_group(&new_client->dev.kobj, &lm83_group); + if (err) goto exit_free; if (id->driver_data == lm83) { - if ((err = sysfs_create_group(&new_client->dev.kobj, - &lm83_group_opt))) + err = sysfs_create_group(&new_client->dev.kobj, + &lm83_group_opt); + if (err) goto exit_remove_files; } @@ -423,19 +430,8 @@ static struct lm83_data *lm83_update_device(struct device *dev) return data; } -static int __init sensors_lm83_init(void) -{ - return i2c_add_driver(&lm83_driver); -} - -static void __exit sensors_lm83_exit(void) -{ - i2c_del_driver(&lm83_driver); -} +module_i2c_driver(lm83_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("LM83 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm83_init); -module_exit(sensors_lm83_exit); diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index da72dc12068c..864c7d999e0c 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1,28 +1,28 @@ /* - lm85.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> - Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> - Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> - Copyright (c) 2004 Justin Thiessen <jthiessen@penguincomputing.com> - Copyright (C) 2007--2009 Jean Delvare <khali@linux-fr.org> - - Chip details at <http://www.national.com/ds/LM/LM85.pdf> - - 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. -*/ + * lm85.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> + * Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> + * Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> + * Copyright (c) 2004 Justin Thiessen <jthiessen@penguincomputing.com> + * Copyright (C) 2007--2009 Jean Delvare <khali@linux-fr.org> + * + * Chip details at <http://www.national.com/ds/LM/LM85.pdf> + * + * 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 <linux/module.h> #include <linux/init.h> @@ -46,88 +46,89 @@ enum chips { /* The LM85 registers */ -#define LM85_REG_IN(nr) (0x20 + (nr)) -#define LM85_REG_IN_MIN(nr) (0x44 + (nr) * 2) -#define LM85_REG_IN_MAX(nr) (0x45 + (nr) * 2) +#define LM85_REG_IN(nr) (0x20 + (nr)) +#define LM85_REG_IN_MIN(nr) (0x44 + (nr) * 2) +#define LM85_REG_IN_MAX(nr) (0x45 + (nr) * 2) -#define LM85_REG_TEMP(nr) (0x25 + (nr)) -#define LM85_REG_TEMP_MIN(nr) (0x4e + (nr) * 2) -#define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) +#define LM85_REG_TEMP(nr) (0x25 + (nr)) +#define LM85_REG_TEMP_MIN(nr) (0x4e + (nr) * 2) +#define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) /* Fan speeds are LSB, MSB (2 bytes) */ -#define LM85_REG_FAN(nr) (0x28 + (nr) * 2) -#define LM85_REG_FAN_MIN(nr) (0x54 + (nr) * 2) +#define LM85_REG_FAN(nr) (0x28 + (nr) * 2) +#define LM85_REG_FAN_MIN(nr) (0x54 + (nr) * 2) -#define LM85_REG_PWM(nr) (0x30 + (nr)) +#define LM85_REG_PWM(nr) (0x30 + (nr)) -#define LM85_REG_COMPANY 0x3e -#define LM85_REG_VERSTEP 0x3f +#define LM85_REG_COMPANY 0x3e +#define LM85_REG_VERSTEP 0x3f -#define ADT7468_REG_CFG5 0x7c -#define ADT7468_OFF64 (1 << 0) -#define ADT7468_HFPWM (1 << 1) -#define IS_ADT7468_OFF64(data) \ +#define ADT7468_REG_CFG5 0x7c +#define ADT7468_OFF64 (1 << 0) +#define ADT7468_HFPWM (1 << 1) +#define IS_ADT7468_OFF64(data) \ ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64)) -#define IS_ADT7468_HFPWM(data) \ +#define IS_ADT7468_HFPWM(data) \ ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_HFPWM)) /* These are the recognized values for the above regs */ -#define LM85_COMPANY_NATIONAL 0x01 -#define LM85_COMPANY_ANALOG_DEV 0x41 -#define LM85_COMPANY_SMSC 0x5c -#define LM85_VERSTEP_VMASK 0xf0 -#define LM85_VERSTEP_GENERIC 0x60 -#define LM85_VERSTEP_GENERIC2 0x70 -#define LM85_VERSTEP_LM85C 0x60 -#define LM85_VERSTEP_LM85B 0x62 -#define LM85_VERSTEP_LM96000_1 0x68 -#define LM85_VERSTEP_LM96000_2 0x69 -#define LM85_VERSTEP_ADM1027 0x60 -#define LM85_VERSTEP_ADT7463 0x62 -#define LM85_VERSTEP_ADT7463C 0x6A -#define LM85_VERSTEP_ADT7468_1 0x71 -#define LM85_VERSTEP_ADT7468_2 0x72 -#define LM85_VERSTEP_EMC6D100_A0 0x60 -#define LM85_VERSTEP_EMC6D100_A1 0x61 -#define LM85_VERSTEP_EMC6D102 0x65 -#define LM85_VERSTEP_EMC6D103_A0 0x68 -#define LM85_VERSTEP_EMC6D103_A1 0x69 -#define LM85_VERSTEP_EMC6D103S 0x6A /* Also known as EMC6D103:A2 */ - -#define LM85_REG_CONFIG 0x40 - -#define LM85_REG_ALARM1 0x41 -#define LM85_REG_ALARM2 0x42 - -#define LM85_REG_VID 0x43 +#define LM85_COMPANY_NATIONAL 0x01 +#define LM85_COMPANY_ANALOG_DEV 0x41 +#define LM85_COMPANY_SMSC 0x5c +#define LM85_VERSTEP_VMASK 0xf0 +#define LM85_VERSTEP_GENERIC 0x60 +#define LM85_VERSTEP_GENERIC2 0x70 +#define LM85_VERSTEP_LM85C 0x60 +#define LM85_VERSTEP_LM85B 0x62 +#define LM85_VERSTEP_LM96000_1 0x68 +#define LM85_VERSTEP_LM96000_2 0x69 +#define LM85_VERSTEP_ADM1027 0x60 +#define LM85_VERSTEP_ADT7463 0x62 +#define LM85_VERSTEP_ADT7463C 0x6A +#define LM85_VERSTEP_ADT7468_1 0x71 +#define LM85_VERSTEP_ADT7468_2 0x72 +#define LM85_VERSTEP_EMC6D100_A0 0x60 +#define LM85_VERSTEP_EMC6D100_A1 0x61 +#define LM85_VERSTEP_EMC6D102 0x65 +#define LM85_VERSTEP_EMC6D103_A0 0x68 +#define LM85_VERSTEP_EMC6D103_A1 0x69 +#define LM85_VERSTEP_EMC6D103S 0x6A /* Also known as EMC6D103:A2 */ + +#define LM85_REG_CONFIG 0x40 + +#define LM85_REG_ALARM1 0x41 +#define LM85_REG_ALARM2 0x42 + +#define LM85_REG_VID 0x43 /* Automated FAN control */ -#define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) -#define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) -#define LM85_REG_AFAN_SPIKE1 0x62 -#define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) -#define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) -#define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) -#define LM85_REG_AFAN_HYST1 0x6d -#define LM85_REG_AFAN_HYST2 0x6e - -#define ADM1027_REG_EXTEND_ADC1 0x76 -#define ADM1027_REG_EXTEND_ADC2 0x77 +#define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) +#define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) +#define LM85_REG_AFAN_SPIKE1 0x62 +#define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) +#define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) +#define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) +#define LM85_REG_AFAN_HYST1 0x6d +#define LM85_REG_AFAN_HYST2 0x6e + +#define ADM1027_REG_EXTEND_ADC1 0x76 +#define ADM1027_REG_EXTEND_ADC2 0x77 #define EMC6D100_REG_ALARM3 0x7d /* IN5, IN6 and IN7 */ -#define EMC6D100_REG_IN(nr) (0x70 + ((nr) - 5)) -#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr) - 5) * 2) -#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr) - 5) * 2) -#define EMC6D102_REG_EXTEND_ADC1 0x85 -#define EMC6D102_REG_EXTEND_ADC2 0x86 -#define EMC6D102_REG_EXTEND_ADC3 0x87 -#define EMC6D102_REG_EXTEND_ADC4 0x88 - - -/* Conversions. Rounding and limit checking is only done on the TO_REG - variants. Note that you should be a bit careful with which arguments - these macros are called: arguments may be evaluated more than once. +#define EMC6D100_REG_IN(nr) (0x70 + ((nr) - 5)) +#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr) - 5) * 2) +#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr) - 5) * 2) +#define EMC6D102_REG_EXTEND_ADC1 0x85 +#define EMC6D102_REG_EXTEND_ADC2 0x86 +#define EMC6D102_REG_EXTEND_ADC3 0x87 +#define EMC6D102_REG_EXTEND_ADC4 0x88 + + +/* + * Conversions. Rounding and limit checking is only done on the TO_REG + * variants. Note that you should be a bit careful with which arguments + * these macros are called: arguments may be evaluated more than once. */ /* IN are scaled according to built-in resistors */ @@ -166,7 +167,8 @@ static inline u16 FAN_TO_REG(unsigned long val) #define PWM_FROM_REG(val) (val) -/* ZONEs have the following parameters: +/* + * ZONEs have the following parameters: * Limit (low) temp, 1. degC * Hysteresis (below limit), 1. degC (0-15) * Range of speed control, .1 degC (2-80) @@ -228,7 +230,8 @@ static int FREQ_FROM_REG(const int *map, u8 reg) return map[reg & 0x07]; } -/* Since we can't use strings, I'm abusing these numbers +/* + * Since we can't use strings, I'm abusing these numbers * to stand in for the following meanings: * 1 -- PWM responds to Zone 1 * 2 -- PWM responds to Zone 2 @@ -258,7 +261,8 @@ static int ZONE_TO_REG(int zone) #define HYST_TO_REG(val) SENSORS_LIMIT(((val) + 500) / 1000, 0, 15) #define HYST_FROM_REG(val) ((val) * 1000) -/* Chip sampling rates +/* + * Chip sampling rates * * Some sensors are not updated more frequently than once per second * so it doesn't make sense to read them more often than that. @@ -274,7 +278,8 @@ static int ZONE_TO_REG(int zone) #define LM85_DATA_INTERVAL (HZ + HZ / 2) #define LM85_CONFIG_INTERVAL (1 * 60 * HZ) -/* LM85 can automatically adjust fan speeds based on temperature +/* + * LM85 can automatically adjust fan speeds based on temperature * This structure encapsulates an entire Zone config. There are * three zones (one for each temperature input) on the lm85 */ @@ -283,7 +288,8 @@ struct lm85_zone { u8 hyst; /* Low limit hysteresis. (0-15) */ u8 range; /* Temp range, encoded */ s8 critical; /* "All fans ON" temp limit */ - u8 max_desired; /* Actual "max" temperature specified. Preserved + u8 max_desired; /* + * Actual "max" temperature specified. Preserved * to prevent "drift" as other autofan control * values change. */ @@ -295,8 +301,10 @@ struct lm85_autofan { u8 min_off; /* Min PWM or OFF below "limit", flag */ }; -/* For each registered chip, we need to keep some data in memory. - The structure is dynamically allocated. */ +/* + * For each registered chip, we need to keep some data in memory. + * The structure is dynamically allocated. + */ struct lm85_data { struct device *hwmon_dev; const int *freq_map; @@ -391,7 +399,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val); @@ -443,7 +456,14 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lm85_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + data->vrm = val; return count; } @@ -500,7 +520,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm[nr] = PWM_TO_REG(val); @@ -537,8 +562,13 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); u8 config; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; switch (val) { case 0: @@ -548,8 +578,10 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute config = 7; break; case 2: - /* Here we have to choose arbitrarily one of the 5 possible - configurations; I go for the safest */ + /* + * Here we have to choose arbitrarily one of the 5 possible + * configurations; I go for the safest + */ config = 6; break; default: @@ -588,12 +620,19 @@ static ssize_t set_pwm_freq(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - /* The ADT7468 has a special high-frequency PWM output mode, + /* + * The ADT7468 has a special high-frequency PWM output mode, * where all PWM outputs are driven by a 22.5 kHz clock. - * This might confuse the user, but there's not much we can do. */ + * This might confuse the user, but there's not much we can do. + */ if (data->type == adt7468 && val >= 11300) { /* High freq. mode */ data->cfg5 &= ~ADT7468_HFPWM; lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5); @@ -648,7 +687,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = INS_TO_REG(nr, val); @@ -671,7 +715,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = INS_TO_REG(nr, val); @@ -722,7 +771,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; if (IS_ADT7468_OFF64(data)) val += 64; @@ -748,7 +802,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; if (IS_ADT7468_OFF64(data)) val += 64; @@ -789,7 +848,12 @@ static ssize_t set_pwm_auto_channels(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->autofan[nr].config = (data->autofan[nr].config & (~0xe0)) @@ -814,7 +878,12 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->autofan[nr].min_pwm = PWM_TO_REG(val); @@ -838,8 +907,13 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); u8 tmp; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->autofan[nr].min_off = val; @@ -885,7 +959,12 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int min; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); min = TEMP_FROM_REG(data->zone[nr].limit); @@ -916,7 +995,12 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->zone[nr].limit = TEMP_TO_REG(val); @@ -951,7 +1035,12 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int min; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); min = TEMP_FROM_REG(data->zone[nr].limit); @@ -979,7 +1068,12 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->zone[nr].critical = TEMP_TO_REG(val); @@ -1338,24 +1432,28 @@ static int lm85_probe(struct i2c_client *client, goto err_remove_files; } - /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used - as a sixth digital VID input rather than an analog input. */ + /* + * The ADT7463/68 have an optional VRM 10 mode where pin 21 is used + * as a sixth digital VID input rather than an analog input. + */ if (data->type == adt7463 || data->type == adt7468) { u8 vid = lm85_read_value(client, LM85_REG_VID); if (vid & 0x80) data->has_vid5 = true; } - if (!data->has_vid5) - if ((err = sysfs_create_group(&client->dev.kobj, - &lm85_group_in4))) + if (!data->has_vid5) { + err = sysfs_create_group(&client->dev.kobj, &lm85_group_in4); + if (err) goto err_remove_files; + } /* The EMC6D100 has 3 additional voltage inputs */ - if (data->type == emc6d100) - if ((err = sysfs_create_group(&client->dev.kobj, - &lm85_group_in567))) + if (data->type == emc6d100) { + err = sysfs_create_group(&client->dev.kobj, &lm85_group_in567); + if (err) goto err_remove_files; + } data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -1443,7 +1541,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) /* Things that change quickly */ dev_dbg(&client->dev, "Reading sensor values\n"); - /* Have to read extended bits first to "freeze" the + /* + * Have to read extended bits first to "freeze" the * more significant bits that are read later. * There are 2 additional resolution bits per channel and we * have room for 4, so we shift them to the left. @@ -1503,9 +1602,10 @@ static struct lm85_data *lm85_update_device(struct device *dev) EMC6D100_REG_ALARM3) << 16; } else if (data->type == emc6d102 || data->type == emc6d103 || data->type == emc6d103s) { - /* Have to read LSB bits after the MSB ones because - the reading of the MSB bits has frozen the - LSBs (backward from the ADM1027). + /* + * Have to read LSB bits after the MSB ones because + * the reading of the MSB bits has frozen the + * LSBs (backward from the ADM1027). */ int ext1 = lm85_read_value(client, EMC6D102_REG_EXTEND_ADC1); @@ -1611,22 +1711,10 @@ static struct lm85_data *lm85_update_device(struct device *dev) return data; } - -static int __init sm_lm85_init(void) -{ - return i2c_add_driver(&lm85_driver); -} - -static void __exit sm_lm85_exit(void) -{ - i2c_del_driver(&lm85_driver); -} +module_i2c_driver(lm85_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " "Margit Schubert-While <margitsw@t-online.de>, " "Justin Thiessen <jthiessen@penguincomputing.com>"); MODULE_DESCRIPTION("LM85-B, LM85-C driver"); - -module_init(sm_lm85_init); -module_exit(sm_lm85_exit); diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index f1e6e7512ffa..314d147bf1ac 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -119,20 +119,21 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; * The LM87 uses signed 8-bit values for temperatures. */ -#define IN_FROM_REG(reg,scale) (((reg) * (scale) + 96) / 192) -#define IN_TO_REG(val,scale) ((val) <= 0 ? 0 : \ +#define IN_FROM_REG(reg, scale) (((reg) * (scale) + 96) / 192) +#define IN_TO_REG(val, scale) ((val) <= 0 ? 0 : \ (val) * 192 >= (scale) * 255 ? 255 : \ - ((val) * 192 + (scale)/2) / (scale)) + ((val) * 192 + (scale) / 2) / (scale)) #define TEMP_FROM_REG(reg) ((reg) * 1000) #define TEMP_TO_REG(val) ((val) <= -127500 ? -128 : \ (val) >= 126500 ? 127 : \ - (((val) < 0 ? (val)-500 : (val)+500) / 1000)) + (((val) < 0 ? (val) - 500 : \ + (val) + 500) / 1000)) -#define FAN_FROM_REG(reg,div) ((reg) == 255 || (reg) == 0 ? 0 : \ - (1350000 + (reg)*(div) / 2) / ((reg)*(div))) -#define FAN_TO_REG(val,div) ((val)*(div) * 255 <= 1350000 ? 255 : \ - (1350000 + (val)*(div) / 2) / ((val)*(div))) +#define FAN_FROM_REG(reg, div) ((reg) == 255 || (reg) == 0 ? 0 : \ + (1350000 + (reg)*(div) / 2) / ((reg) * (div))) +#define FAN_TO_REG(val, div) ((val) * (div) * 255 <= 1350000 ? 255 : \ + (1350000 + (val)*(div) / 2) / ((val) * (div))) #define FAN_DIV_FROM_REG(reg) (1 << (reg)) @@ -149,41 +150,6 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; #define CHAN_NO_VID (1 << 7) /* - * Functions declaration - */ - -static int lm87_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int lm87_detect(struct i2c_client *new_client, - struct i2c_board_info *info); -static void lm87_init_client(struct i2c_client *client); -static int lm87_remove(struct i2c_client *client); -static struct lm87_data *lm87_update_device(struct device *dev); - -/* - * Driver data (common to all clients) - */ - -static const struct i2c_device_id lm87_id[] = { - { "lm87", lm87 }, - { "adm1024", adm1024 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, lm87_id); - -static struct i2c_driver lm87_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "lm87", - }, - .probe = lm87_probe, - .remove = lm87_remove, - .id_table = lm87_id, - .detect = lm87_detect, - .address_list = normal_i2c, -}; - -/* * Client data (each client gets its own) */ @@ -217,10 +183,6 @@ struct lm87_data { u8 vrm; }; -/* - * Sysfs stuff - */ - static inline int lm87_read_value(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); @@ -231,79 +193,168 @@ static inline int lm87_write_value(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -#define show_in(offset) \ -static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \ - data->in_scale[offset])); \ -} \ -static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \ - data->in_scale[offset])); \ -} \ -static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \ - data->in_scale[offset])); \ -} \ -static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ - show_in##offset##_input, NULL); -show_in(0); -show_in(1); -show_in(2); -show_in(3); -show_in(4); -show_in(5); -show_in(6); -show_in(7); - -static void set_in_min(struct device *dev, const char *buf, int nr) +static struct lm87_data *lm87_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + int i, j; + + dev_dbg(&client->dev, "Updating data.\n"); + + i = (data->channel & CHAN_TEMP3) ? 1 : 0; + j = (data->channel & CHAN_TEMP3) ? 5 : 6; + for (; i < j; i++) { + data->in[i] = lm87_read_value(client, + LM87_REG_IN(i)); + data->in_min[i] = lm87_read_value(client, + LM87_REG_IN_MIN(i)); + data->in_max[i] = lm87_read_value(client, + LM87_REG_IN_MAX(i)); + } + + for (i = 0; i < 2; i++) { + if (data->channel & CHAN_NO_FAN(i)) { + data->in[6+i] = lm87_read_value(client, + LM87_REG_AIN(i)); + data->in_max[6+i] = lm87_read_value(client, + LM87_REG_AIN_MAX(i)); + data->in_min[6+i] = lm87_read_value(client, + LM87_REG_AIN_MIN(i)); + + } else { + data->fan[i] = lm87_read_value(client, + LM87_REG_FAN(i)); + data->fan_min[i] = lm87_read_value(client, + LM87_REG_FAN_MIN(i)); + } + } + + j = (data->channel & CHAN_TEMP3) ? 3 : 2; + for (i = 0 ; i < j; i++) { + data->temp[i] = lm87_read_value(client, + LM87_REG_TEMP[i]); + data->temp_high[i] = lm87_read_value(client, + LM87_REG_TEMP_HIGH[i]); + data->temp_low[i] = lm87_read_value(client, + LM87_REG_TEMP_LOW[i]); + } + + i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK); + j = lm87_read_value(client, LM87_REG_TEMP_HW_INT); + data->temp_crit_int = min(i, j); + + i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK); + j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT); + data->temp_crit_ext = min(i, j); + + i = lm87_read_value(client, LM87_REG_VID_FAN_DIV); + data->fan_div[0] = (i >> 4) & 0x03; + data->fan_div[1] = (i >> 6) & 0x03; + data->vid = (i & 0x0F) + | (lm87_read_value(client, LM87_REG_VID4) & 0x01) + << 4; + + data->alarms = lm87_read_value(client, LM87_REG_ALARMS1) + | (lm87_read_value(client, LM87_REG_ALARMS2) + << 8); + data->aout = lm87_read_value(client, LM87_REG_AOUT); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +/* + * Sysfs stuff + */ + +static ssize_t show_in_input(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%u\n", IN_FROM_REG(data->in[nr], + data->in_scale[nr])); +} + +static ssize_t show_in_min(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[nr], + data->in_scale[nr])); +} + +static ssize_t show_in_max(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[nr], + data->in_scale[nr])); +} + +static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct lm87_data *data = i2c_get_clientdata(client); + int nr = to_sensor_dev_attr(attr)->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]); - lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) : - LM87_REG_AIN_MIN(nr-6), data->in_min[nr]); + lm87_write_value(client, nr < 6 ? LM87_REG_IN_MIN(nr) : + LM87_REG_AIN_MIN(nr - 6), data->in_min[nr]); mutex_unlock(&data->update_lock); + return count; } -static void set_in_max(struct device *dev, const char *buf, int nr) +static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + int nr = to_sensor_dev_attr(attr)->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]); - lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) : - LM87_REG_AIN_MAX(nr-6), data->in_max[nr]); + lm87_write_value(client, nr < 6 ? LM87_REG_IN_MAX(nr) : + LM87_REG_AIN_MAX(nr - 6), data->in_max[nr]); mutex_unlock(&data->update_lock); + return count; } #define set_in(offset) \ -static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - set_in_min(dev, buf, offset); \ - return count; \ -} \ -static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - set_in_max(dev, buf, offset); \ - return count; \ -} \ -static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in##offset##_min, set_in##offset##_min); \ -static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in##offset##_max, set_in##offset##_max); +static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ + show_in_input, NULL, offset); \ +static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ + show_in_min, set_in_min, offset); \ +static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ + show_in_max, set_in_max, offset) set_in(0); set_in(1); set_in(2); @@ -313,80 +364,95 @@ set_in(5); set_in(6); set_in(7); -#define show_temp(offset) \ -static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \ -} \ -static ssize_t show_temp##offset##_low(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[offset-1])); \ -} \ -static ssize_t show_temp##offset##_high(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[offset-1])); \ -}\ -static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ - show_temp##offset##_input, NULL); -show_temp(1); -show_temp(2); -show_temp(3); - -static void set_temp_low(struct device *dev, const char *buf, int nr) +static ssize_t show_temp_input(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); +} + +static ssize_t show_temp_low(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%d\n", + TEMP_FROM_REG(data->temp_low[nr])); +} + +static ssize_t show_temp_high(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%d\n", + TEMP_FROM_REG(data->temp_high[nr])); +} + +static ssize_t set_temp_low(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + int nr = to_sensor_dev_attr(attr)->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_low[nr] = TEMP_TO_REG(val); lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]); mutex_unlock(&data->update_lock); + return count; } -static void set_temp_high(struct device *dev, const char *buf, int nr) +static ssize_t set_temp_high(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + int nr = to_sensor_dev_attr(attr)->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_high[nr] = TEMP_TO_REG(val); lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]); mutex_unlock(&data->update_lock); + return count; } #define set_temp(offset) \ -static ssize_t set_temp##offset##_low(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - set_temp_low(dev, buf, offset-1); \ - return count; \ -} \ -static ssize_t set_temp##offset##_high(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - set_temp_high(dev, buf, offset-1); \ - return count; \ -} \ -static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ - show_temp##offset##_high, set_temp##offset##_high); \ -static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ - show_temp##offset##_low, set_temp##offset##_low); +static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ + show_temp_input, NULL, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ + show_temp_high, set_temp_high, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ + show_temp_low, set_temp_low, offset - 1) set_temp(1); set_temp(2); set_temp(3); -static ssize_t show_temp_crit_int(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_crit_int(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm87_data *data = lm87_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int)); } -static ssize_t show_temp_crit_ext(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_crit_ext(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm87_data *data = lm87_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext)); @@ -396,64 +462,95 @@ static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit_int, NULL); static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit_ext, NULL); static DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit_ext, NULL); -#define show_fan(offset) \ -static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[offset-1], \ - FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \ -} \ -static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[offset-1], \ - FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \ -} \ -static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct lm87_data *data = lm87_update_device(dev); \ - return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[offset-1])); \ -} \ -static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ - show_fan##offset##_input, NULL); -show_fan(1); -show_fan(2); - -static void set_fan_min(struct device *dev, const char *buf, int nr) +static ssize_t show_fan_input(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], + FAN_DIV_FROM_REG(data->fan_div[nr]))); +} + +static ssize_t show_fan_min(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], + FAN_DIV_FROM_REG(data->fan_div[nr]))); +} + +static ssize_t show_fan_div(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lm87_data *data = lm87_update_device(dev); + int nr = to_sensor_dev_attr(attr)->index; + + return sprintf(buf, "%d\n", + FAN_DIV_FROM_REG(data->fan_div[nr])); +} + +static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + int nr = to_sensor_dev_attr(attr)->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr])); lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]); mutex_unlock(&data->update_lock); + return count; } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan clock divider. This follows the principle - of least surprise; the user doesn't expect the fan minimum to change just - because the divider changed. */ -static ssize_t set_fan_div(struct device *dev, const char *buf, - size_t count, int nr) +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan clock divider. This follows the principle + * of least surprise; the user doesn't expect the fan minimum to change just + * because the divider changed. + */ +static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + int nr = to_sensor_dev_attr(attr)->index; + long val; + int err; unsigned long min; u8 reg; + err = kstrtol(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], FAN_DIV_FROM_REG(data->fan_div[nr])); switch (val) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; + case 1: + data->fan_div[nr] = 0; + break; + case 2: + data->fan_div[nr] = 1; + break; + case 4: + data->fan_div[nr] = 2; + break; + case 8: + data->fan_div[nr] = 3; + break; default: mutex_unlock(&data->update_lock); return -EINVAL; @@ -479,61 +576,69 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, } #define set_fan(offset) \ -static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ -{ \ - set_fan_min(dev, buf, offset-1); \ - return count; \ -} \ -static ssize_t set_fan##offset##_div(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ -{ \ - return set_fan_div(dev, buf, count, offset-1); \ -} \ -static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan##offset##_min, set_fan##offset##_min); \ -static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ - show_fan##offset##_div, set_fan##offset##_div); +static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ + show_fan_input, NULL, offset - 1); \ +static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + show_fan_min, set_fan_min, offset - 1); \ +static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ + show_fan_div, set_fan_div, offset - 1) set_fan(1); set_fan(2); -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm87_data *data = lm87_update_device(dev); return sprintf(buf, "%d\n", data->alarms); } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); -static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vid(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm87_data *data = lm87_update_device(dev); return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); } static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); -static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm87_data *data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", data->vrm); } -static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct lm87_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + data->vrm = val; return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); -static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_aout(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm87_data *data = lm87_update_device(dev); return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout)); } -static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_aout(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm87_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->aout = AOUT_TO_REG(val); @@ -571,31 +676,31 @@ static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); */ static struct attribute *lm87_attributes[] = { - &dev_attr_in1_input.attr, - &dev_attr_in1_min.attr, - &dev_attr_in1_max.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, &sensor_dev_attr_in1_alarm.dev_attr.attr, - &dev_attr_in2_input.attr, - &dev_attr_in2_min.attr, - &dev_attr_in2_max.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, &sensor_dev_attr_in2_alarm.dev_attr.attr, - &dev_attr_in3_input.attr, - &dev_attr_in3_min.attr, - &dev_attr_in3_max.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, &sensor_dev_attr_in3_alarm.dev_attr.attr, - &dev_attr_in4_input.attr, - &dev_attr_in4_min.attr, - &dev_attr_in4_max.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, &sensor_dev_attr_in4_alarm.dev_attr.attr, - &dev_attr_temp1_input.attr, - &dev_attr_temp1_max.attr, - &dev_attr_temp1_min.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, &dev_attr_temp1_crit.attr, &sensor_dev_attr_temp1_alarm.dev_attr.attr, - &dev_attr_temp2_input.attr, - &dev_attr_temp2_max.attr, - &dev_attr_temp2_min.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, &dev_attr_temp2_crit.attr, &sensor_dev_attr_temp2_alarm.dev_attr.attr, &sensor_dev_attr_temp2_fault.dev_attr.attr, @@ -610,70 +715,110 @@ static const struct attribute_group lm87_group = { .attrs = lm87_attributes, }; -static struct attribute *lm87_attributes_opt[] = { - &dev_attr_in6_input.attr, - &dev_attr_in6_min.attr, - &dev_attr_in6_max.attr, +static struct attribute *lm87_attributes_in6[] = { + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in6_max.dev_attr.attr, &sensor_dev_attr_in6_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm87_group_in6 = { + .attrs = lm87_attributes_in6, +}; - &dev_attr_fan1_input.attr, - &dev_attr_fan1_min.attr, - &dev_attr_fan1_div.attr, +static struct attribute *lm87_attributes_fan1[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan1_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm87_group_fan1 = { + .attrs = lm87_attributes_fan1, +}; - &dev_attr_in7_input.attr, - &dev_attr_in7_min.attr, - &dev_attr_in7_max.attr, +static struct attribute *lm87_attributes_in7[] = { + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, &sensor_dev_attr_in7_alarm.dev_attr.attr, + NULL +}; - &dev_attr_fan2_input.attr, - &dev_attr_fan2_min.attr, - &dev_attr_fan2_div.attr, +static const struct attribute_group lm87_group_in7 = { + .attrs = lm87_attributes_in7, +}; + +static struct attribute *lm87_attributes_fan2[] = { + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan2_div.dev_attr.attr, &sensor_dev_attr_fan2_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm87_group_fan2 = { + .attrs = lm87_attributes_fan2, +}; - &dev_attr_temp3_input.attr, - &dev_attr_temp3_max.attr, - &dev_attr_temp3_min.attr, +static struct attribute *lm87_attributes_temp3[] = { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, &dev_attr_temp3_crit.attr, &sensor_dev_attr_temp3_alarm.dev_attr.attr, &sensor_dev_attr_temp3_fault.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm87_group_temp3 = { + .attrs = lm87_attributes_temp3, +}; - &dev_attr_in0_input.attr, - &dev_attr_in0_min.attr, - &dev_attr_in0_max.attr, +static struct attribute *lm87_attributes_in0_5[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, &sensor_dev_attr_in0_alarm.dev_attr.attr, - &dev_attr_in5_input.attr, - &dev_attr_in5_min.attr, - &dev_attr_in5_max.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, &sensor_dev_attr_in5_alarm.dev_attr.attr, + NULL +}; +static const struct attribute_group lm87_group_in0_5 = { + .attrs = lm87_attributes_in0_5, +}; + +static struct attribute *lm87_attributes_vid[] = { &dev_attr_cpu0_vid.attr, &dev_attr_vrm.attr, - NULL }; -static const struct attribute_group lm87_group_opt = { - .attrs = lm87_attributes_opt, +static const struct attribute_group lm87_group_vid = { + .attrs = lm87_attributes_vid, }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm87_detect(struct i2c_client *new_client, - struct i2c_board_info *info) +static int lm87_detect(struct i2c_client *client, struct i2c_board_info *info) { - struct i2c_adapter *adapter = new_client->adapter; + struct i2c_adapter *adapter = client->adapter; const char *name; u8 cid, rev; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - if (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80) + if (lm87_read_value(client, LM87_REG_CONFIG) & 0x80) return -ENODEV; /* Now, we do the remaining detection. */ - cid = lm87_read_value(new_client, LM87_REG_COMPANY_ID); - rev = lm87_read_value(new_client, LM87_REG_REVISION); + cid = lm87_read_value(client, LM87_REG_COMPANY_ID); + rev = lm87_read_value(client, LM87_REG_REVISION); if (cid == 0x02 /* National Semiconductor */ && (rev >= 0x01 && rev <= 0x08)) @@ -683,7 +828,7 @@ static int lm87_detect(struct i2c_client *new_client, name = "adm1024"; else { dev_dbg(&adapter->dev, "LM87 detection failed at 0x%02x\n", - new_client->addr); + client->addr); return -ENODEV; } @@ -692,8 +837,63 @@ static int lm87_detect(struct i2c_client *new_client, return 0; } -static int lm87_probe(struct i2c_client *new_client, - const struct i2c_device_id *id) +static void lm87_remove_files(struct i2c_client *client) +{ + struct device *dev = &client->dev; + + sysfs_remove_group(&dev->kobj, &lm87_group); + sysfs_remove_group(&dev->kobj, &lm87_group_in6); + sysfs_remove_group(&dev->kobj, &lm87_group_fan1); + sysfs_remove_group(&dev->kobj, &lm87_group_in7); + sysfs_remove_group(&dev->kobj, &lm87_group_fan2); + sysfs_remove_group(&dev->kobj, &lm87_group_temp3); + sysfs_remove_group(&dev->kobj, &lm87_group_in0_5); + sysfs_remove_group(&dev->kobj, &lm87_group_vid); +} + +static void lm87_init_client(struct i2c_client *client) +{ + struct lm87_data *data = i2c_get_clientdata(client); + + if (client->dev.platform_data) { + data->channel = *(u8 *)client->dev.platform_data; + lm87_write_value(client, + LM87_REG_CHANNEL_MODE, data->channel); + } else { + data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); + } + data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F; + + if (!(data->config & 0x01)) { + int i; + + /* Limits are left uninitialized after power-up */ + for (i = 1; i < 6; i++) { + lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00); + lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF); + } + for (i = 0; i < 2; i++) { + lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F); + lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00); + lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00); + lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF); + } + if (data->channel & CHAN_TEMP3) { + lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F); + lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00); + } else { + lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00); + lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF); + } + } + + /* Make sure Start is set and INT#_Clear is clear */ + if ((data->config & 0x09) != 0x01) + lm87_write_value(client, LM87_REG_CONFIG, + (data->config & 0x77) | 0x01); +} + +static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct lm87_data *data; int err; @@ -704,12 +904,12 @@ static int lm87_probe(struct i2c_client *new_client, goto exit; } - i2c_set_clientdata(new_client, data); + i2c_set_clientdata(client, data); data->valid = 0; mutex_init(&data->update_lock); /* Initialize the LM87 chip */ - lm87_init_client(new_client); + lm87_init_client(client); data->in_scale[0] = 2500; data->in_scale[1] = 2700; @@ -721,97 +921,48 @@ static int lm87_probe(struct i2c_client *new_client, data->in_scale[7] = 1875; /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group); + if (err) goto exit_free; if (data->channel & CHAN_NO_FAN(0)) { - if ((err = device_create_file(&new_client->dev, - &dev_attr_in6_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in6_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in6_max)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_in6_alarm.dev_attr))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_in6); + if (err) goto exit_remove; } else { - if ((err = device_create_file(&new_client->dev, - &dev_attr_fan1_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_fan1_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_fan1_div)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_fan1_alarm.dev_attr))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_fan1); + if (err) goto exit_remove; } if (data->channel & CHAN_NO_FAN(1)) { - if ((err = device_create_file(&new_client->dev, - &dev_attr_in7_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in7_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in7_max)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_in7_alarm.dev_attr))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_in7); + if (err) goto exit_remove; } else { - if ((err = device_create_file(&new_client->dev, - &dev_attr_fan2_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_fan2_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_fan2_div)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_fan2_alarm.dev_attr))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_fan2); + if (err) goto exit_remove; } if (data->channel & CHAN_TEMP3) { - if ((err = device_create_file(&new_client->dev, - &dev_attr_temp3_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_temp3_max)) - || (err = device_create_file(&new_client->dev, - &dev_attr_temp3_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_temp3_crit)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_alarm.dev_attr)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_fault.dev_attr))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_temp3); + if (err) goto exit_remove; } else { - if ((err = device_create_file(&new_client->dev, - &dev_attr_in0_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in0_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in0_max)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_in0_alarm.dev_attr)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in5_input)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in5_min)) - || (err = device_create_file(&new_client->dev, - &dev_attr_in5_max)) - || (err = device_create_file(&new_client->dev, - &sensor_dev_attr_in5_alarm.dev_attr))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_in0_5); + if (err) goto exit_remove; } if (!(data->channel & CHAN_NO_VID)) { data->vrm = vid_which_vrm(); - if ((err = device_create_file(&new_client->dev, - &dev_attr_cpu0_vid)) - || (err = device_create_file(&new_client->dev, - &dev_attr_vrm))) + err = sysfs_create_group(&client->dev.kobj, &lm87_group_vid); + if (err) goto exit_remove; } - data->hwmon_dev = hwmon_device_register(&new_client->dev); + data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exit_remove; @@ -820,162 +971,51 @@ static int lm87_probe(struct i2c_client *new_client, return 0; exit_remove: - sysfs_remove_group(&new_client->dev.kobj, &lm87_group); - sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); + lm87_remove_files(client); exit_free: - lm87_write_value(new_client, LM87_REG_CONFIG, data->config); + lm87_write_value(client, LM87_REG_CONFIG, data->config); kfree(data); exit: return err; } -static void lm87_init_client(struct i2c_client *client) -{ - struct lm87_data *data = i2c_get_clientdata(client); - - if (client->dev.platform_data) { - data->channel = *(u8 *)client->dev.platform_data; - lm87_write_value(client, - LM87_REG_CHANNEL_MODE, data->channel); - } else { - data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); - } - data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F; - - if (!(data->config & 0x01)) { - int i; - - /* Limits are left uninitialized after power-up */ - for (i = 1; i < 6; i++) { - lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00); - lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF); - } - for (i = 0; i < 2; i++) { - lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F); - lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00); - lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00); - lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF); - } - if (data->channel & CHAN_TEMP3) { - lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F); - lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00); - } else { - lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00); - lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF); - } - } - - /* Make sure Start is set and INT#_Clear is clear */ - if ((data->config & 0x09) != 0x01) - lm87_write_value(client, LM87_REG_CONFIG, - (data->config & 0x77) | 0x01); -} - static int lm87_remove(struct i2c_client *client) { struct lm87_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm87_group); - sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); + lm87_remove_files(client); lm87_write_value(client, LM87_REG_CONFIG, data->config); kfree(data); return 0; } -static struct lm87_data *lm87_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm87_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - int i, j; - - dev_dbg(&client->dev, "Updating data.\n"); - - i = (data->channel & CHAN_TEMP3) ? 1 : 0; - j = (data->channel & CHAN_TEMP3) ? 5 : 6; - for (; i < j; i++) { - data->in[i] = lm87_read_value(client, - LM87_REG_IN(i)); - data->in_min[i] = lm87_read_value(client, - LM87_REG_IN_MIN(i)); - data->in_max[i] = lm87_read_value(client, - LM87_REG_IN_MAX(i)); - } - - for (i = 0; i < 2; i++) { - if (data->channel & CHAN_NO_FAN(i)) { - data->in[6+i] = lm87_read_value(client, - LM87_REG_AIN(i)); - data->in_max[6+i] = lm87_read_value(client, - LM87_REG_AIN_MAX(i)); - data->in_min[6+i] = lm87_read_value(client, - LM87_REG_AIN_MIN(i)); - - } else { - data->fan[i] = lm87_read_value(client, - LM87_REG_FAN(i)); - data->fan_min[i] = lm87_read_value(client, - LM87_REG_FAN_MIN(i)); - } - } - - j = (data->channel & CHAN_TEMP3) ? 3 : 2; - for (i = 0 ; i < j; i++) { - data->temp[i] = lm87_read_value(client, - LM87_REG_TEMP[i]); - data->temp_high[i] = lm87_read_value(client, - LM87_REG_TEMP_HIGH[i]); - data->temp_low[i] = lm87_read_value(client, - LM87_REG_TEMP_LOW[i]); - } - - i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK); - j = lm87_read_value(client, LM87_REG_TEMP_HW_INT); - data->temp_crit_int = min(i, j); - - i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK); - j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT); - data->temp_crit_ext = min(i, j); - - i = lm87_read_value(client, LM87_REG_VID_FAN_DIV); - data->fan_div[0] = (i >> 4) & 0x03; - data->fan_div[1] = (i >> 6) & 0x03; - data->vid = (i & 0x0F) - | (lm87_read_value(client, LM87_REG_VID4) & 0x01) - << 4; - - data->alarms = lm87_read_value(client, LM87_REG_ALARMS1) - | (lm87_read_value(client, LM87_REG_ALARMS2) - << 8); - data->aout = lm87_read_value(client, LM87_REG_AOUT); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); +/* + * Driver data (common to all clients) + */ - return data; -} +static const struct i2c_device_id lm87_id[] = { + { "lm87", lm87 }, + { "adm1024", adm1024 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm87_id); -static int __init sensors_lm87_init(void) -{ - return i2c_add_driver(&lm87_driver); -} +static struct i2c_driver lm87_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "lm87", + }, + .probe = lm87_probe, + .remove = lm87_remove, + .id_table = lm87_id, + .detect = lm87_detect, + .address_list = normal_i2c, +}; -static void __exit sensors_lm87_exit(void) -{ - i2c_del_driver(&lm87_driver); -} +module_i2c_driver(lm87_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org> and others"); MODULE_DESCRIPTION("LM87 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm87_init); -module_exit(sensors_lm87_exit); diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index d2dd5f90496d..22b14a68e35e 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -57,6 +57,9 @@ * This driver also supports the SA56004 from Philips. This device is * pin-compatible with the LM86, the ED/EDP parts are also address-compatible. * + * This driver also supports the G781 from GMT. This device is compatible + * with the ADM1032. + * * Since the LM90 was the first chipset supported by this driver, most * comments will refer to this chipset, but are actually general and * concern all supported chipsets, unless mentioned otherwise. @@ -107,7 +110,7 @@ static const unsigned short normal_i2c[] = { 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, - max6646, w83l771, max6696, sa56004 }; + max6646, w83l771, max6696, sa56004, g781 }; /* * The LM90 registers @@ -184,6 +187,7 @@ static const struct i2c_device_id lm90_id[] = { { "adm1032", adm1032 }, { "adt7461", adt7461 }, { "adt7461a", adt7461 }, + { "g781", g781 }, { "lm90", lm90 }, { "lm86", lm86 }, { "lm89", lm86 }, @@ -229,6 +233,12 @@ static const struct lm90_params lm90_params[] = { .alert_alarms = 0x7c, .max_convrate = 10, }, + [g781] = { + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT + | LM90_HAVE_BROKEN_ALERT, + .alert_alarms = 0x7c, + .max_convrate = 8, + }, [lm86] = { .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, .alert_alarms = 0x7b, @@ -308,22 +318,24 @@ struct lm90_data { /* registers values */ s8 temp8[8]; /* 0: local low limit - 1: local high limit - 2: local critical limit - 3: remote critical limit - 4: local emergency limit (max6659 and max6695/96) - 5: remote emergency limit (max6659 and max6695/96) - 6: remote 2 critical limit (max6695/96 only) - 7: remote 2 emergency limit (max6695/96 only) */ + * 1: local high limit + * 2: local critical limit + * 3: remote critical limit + * 4: local emergency limit (max6659 and max6695/96) + * 5: remote emergency limit (max6659 and max6695/96) + * 6: remote 2 critical limit (max6695/96 only) + * 7: remote 2 emergency limit (max6695/96 only) + */ s16 temp11[8]; /* 0: remote input - 1: remote low limit - 2: remote high limit - 3: remote offset (except max6646, max6657/58/59, - and max6695/96) - 4: local input - 5: remote 2 input (max6695/96 only) - 6: remote 2 low limit (max6695/96 only) - 7: remote 2 high limit (ma6695/96 only) */ + * 1: remote low limit + * 2: remote high limit + * 3: remote offset (except max6646, max6657/58/59, + * and max6695/96) + * 4: local input + * 5: remote 2 input (max6695/96 only) + * 6: remote 2 low limit (max6695/96 only) + * 7: remote 2 high limit (max6695/96 only) + */ u8 temp_hyst; u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ }; @@ -533,8 +545,10 @@ static struct lm90_data *lm90_update_device(struct device *dev) data->alarms |= alarms << 8; } - /* Re-enable ALERT# output if it was originally enabled and - * relevant alarms are all clear */ + /* + * Re-enable ALERT# output if it was originally enabled and + * relevant alarms are all clear + */ if ((data->config_orig & 0x80) == 0 && (data->alarms & data->alert_alarms) == 0) { u8 config; @@ -1162,8 +1176,10 @@ static int lm90_detect(struct i2c_client *client, && (config1 & 0x3F) == 0x00 && convrate <= 0x0A) { name = "adm1032"; - /* The ADM1032 supports PEC, but only if combined - transactions are not used. */ + /* + * The ADM1032 supports PEC, but only if combined + * transactions are not used. + */ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) info->flags |= I2C_CLIENT_PEC; @@ -1283,6 +1299,13 @@ static int lm90_detect(struct i2c_client *client, && convrate <= 0x09) { name = "sa56004"; } + } else + if ((address == 0x4C || address == 0x4D) + && man_id == 0x47) { /* GMT */ + if (chip_id == 0x01 /* G781 */ + && (config1 & 0x3F) == 0x00 + && convrate <= 0x08) + name = "g781"; } if (!name) { /* identification failed */ @@ -1313,6 +1336,15 @@ static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) sysfs_remove_group(&dev->kobj, &lm90_group); } +static void lm90_restore_conf(struct i2c_client *client, struct lm90_data *data) +{ + /* Restore initial configuration */ + i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, + data->convrate_orig); + i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, + data->config_orig); +} + static void lm90_init_client(struct i2c_client *client) { u8 config, convrate; @@ -1382,8 +1414,10 @@ static int lm90_probe(struct i2c_client *client, client->flags &= ~I2C_CLIENT_PEC; } - /* Different devices have different alarm bits triggering the - * ALERT# output */ + /* + * Different devices have different alarm bits triggering the + * ALERT# output + */ data->alert_alarms = lm90_params[data->kind].alert_alarms; /* Set chip capabilities */ @@ -1399,7 +1433,7 @@ static int lm90_probe(struct i2c_client *client, /* Register sysfs hooks */ err = sysfs_create_group(&dev->kobj, &lm90_group); if (err) - goto exit_free; + goto exit_restore; if (client->flags & I2C_CLIENT_PEC) { err = device_create_file(dev, &dev_attr_pec); if (err) @@ -1438,7 +1472,8 @@ static int lm90_probe(struct i2c_client *client, exit_remove_files: lm90_remove_files(client, data); -exit_free: +exit_restore: + lm90_restore_conf(client, data); kfree(data); exit: return err; @@ -1450,12 +1485,7 @@ static int lm90_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); lm90_remove_files(client, data); - - /* Restore initial configuration */ - i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, - data->convrate_orig); - i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, - data->config_orig); + lm90_restore_conf(client, data); kfree(data); return 0; @@ -1488,9 +1518,11 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag) dev_warn(&client->dev, "temp%d out of range, please check!\n", 3); - /* Disable ALERT# output, because these chips don't implement - SMBus alert correctly; they should only hold the alert line - low briefly. */ + /* + * Disable ALERT# output, because these chips don't implement + * SMBus alert correctly; they should only hold the alert line + * low briefly. + */ if ((data->flags & LM90_HAVE_BROKEN_ALERT) && (alarms & data->alert_alarms)) { dev_dbg(&client->dev, "Disabling ALERT#\n"); @@ -1514,19 +1546,8 @@ static struct i2c_driver lm90_driver = { .address_list = normal_i2c, }; -static int __init sensors_lm90_init(void) -{ - return i2c_add_driver(&lm90_driver); -} - -static void __exit sensors_lm90_exit(void) -{ - i2c_del_driver(&lm90_driver); -} +module_i2c_driver(lm90_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("LM90/ADM1032 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm90_init); -module_exit(sensors_lm90_exit); diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 8fcbd4d422c5..fdc691a4028f 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -49,8 +49,10 @@ #include <linux/err.h> #include <linux/mutex.h> -/* The LM92 and MAX6635 have 2 two-state pins for address selection, - resulting in 4 possible addresses. */ +/* + * The LM92 and MAX6635 have 2 two-state pins for address selection, + * resulting in 4 possible addresses. + */ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; @@ -63,11 +65,13 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, #define LM92_REG_TEMP_HIGH 0x05 /* 16-bit, RW */ #define LM92_REG_MAN_ID 0x07 /* 16-bit, RO, LM92 only */ -/* The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius, - left-justified in 16-bit registers. No rounding is done, with such - a resolution it's just not worth it. Note that the MAX6635 doesn't - make use of the 4 lower bits for limits (i.e. effective resolution - for limits is 1 degree Celsius). */ +/* + * The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius, + * left-justified in 16-bit registers. No rounding is done, with such + * a resolution it's just not worth it. Note that the MAX6635 doesn't + * make use of the 4 lower bits for limits (i.e. effective resolution + * for limits is 1 degree Celsius). + */ static inline int TEMP_FROM_REG(s16 reg) { return reg / 8 * 625 / 10; @@ -138,7 +142,8 @@ static struct lm92_data *lm92_update_device(struct device *dev) } #define show_temp(value) \ -static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##value(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct lm92_data *data = lm92_update_device(dev); \ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ @@ -149,13 +154,17 @@ show_temp(temp1_min); show_temp(temp1_max); #define set_temp(value, reg) \ -static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \ +static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \ + const char *buf, \ size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct lm92_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ - \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ +\ mutex_lock(&data->update_lock); \ data->value = TEMP_TO_REG(val); \ i2c_smbus_write_word_swapped(client, reg, data->value); \ @@ -166,31 +175,40 @@ set_temp(temp1_crit, LM92_REG_TEMP_CRIT); set_temp(temp1_min, LM92_REG_TEMP_LOW); set_temp(temp1_max, LM92_REG_TEMP_HIGH); -static ssize_t show_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp1_crit_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm92_data *data = lm92_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit) - TEMP_FROM_REG(data->temp1_hyst)); } -static ssize_t show_temp1_max_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp1_max_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm92_data *data = lm92_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max) - TEMP_FROM_REG(data->temp1_hyst)); } -static ssize_t show_temp1_min_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp1_min_hyst(struct device *dev, + struct device_attribute *attr, char *buf) { struct lm92_data *data = lm92_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min) + TEMP_FROM_REG(data->temp1_hyst)); } -static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t set_temp1_crit_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct lm92_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val; @@ -200,7 +218,8 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute * return count; } -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm92_data *data = lm92_update_device(dev); return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input)); @@ -246,26 +265,30 @@ static void lm92_init_client(struct i2c_client *client) config & 0xFE); } -/* The MAX6635 has no identification register, so we have to use tricks - to identify it reliably. This is somewhat slow. - Note that we do NOT rely on the 2 MSB of the configuration register - always reading 0, as suggested by the datasheet, because it was once - reported not to be true. */ +/* + * The MAX6635 has no identification register, so we have to use tricks + * to identify it reliably. This is somewhat slow. + * Note that we do NOT rely on the 2 MSB of the configuration register + * always reading 0, as suggested by the datasheet, because it was once + * reported not to be true. + */ static int max6635_check(struct i2c_client *client) { u16 temp_low, temp_high, temp_hyst, temp_crit; u8 conf; int i; - /* No manufacturer ID register, so a read from this address will - always return the last read value. */ + /* + * No manufacturer ID register, so a read from this address will + * always return the last read value. + */ temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW); if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low) return 0; temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH); if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high) return 0; - + /* Limits are stored as integer values (signed, 9-bit). */ if ((temp_low & 0x7f00) || (temp_high & 0x7f00)) return 0; @@ -274,22 +297,24 @@ static int max6635_check(struct i2c_client *client) if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00)) return 0; - /* Registers addresses were found to cycle over 16-byte boundaries. - We don't test all registers with all offsets so as to save some - reads and time, but this should still be sufficient to dismiss - non-MAX6635 chips. */ + /* + * Registers addresses were found to cycle over 16-byte boundaries. + * We don't test all registers with all offsets so as to save some + * reads and time, but this should still be sufficient to dismiss + * non-MAX6635 chips. + */ conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG); - for (i=16; i<96; i*=2) { + for (i = 16; i < 96; i *= 2) { if (temp_hyst != i2c_smbus_read_word_data(client, - LM92_REG_TEMP_HYST + i - 16) + LM92_REG_TEMP_HYST + i - 16) || temp_crit != i2c_smbus_read_word_data(client, - LM92_REG_TEMP_CRIT + i) + LM92_REG_TEMP_CRIT + i) || temp_low != i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW + i + 16) || temp_high != i2c_smbus_read_word_data(client, - LM92_REG_TEMP_HIGH + i + 32) + LM92_REG_TEMP_HIGH + i + 32) || conf != i2c_smbus_read_byte_data(client, - LM92_REG_CONFIG + i)) + LM92_REG_CONFIG + i)) return 0; } @@ -362,7 +387,8 @@ static int lm92_probe(struct i2c_client *new_client, lm92_init_client(new_client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) + err = sysfs_create_group(&new_client->dev.kobj, &lm92_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); @@ -416,19 +442,8 @@ static struct i2c_driver lm92_driver = { .address_list = normal_i2c, }; -static int __init sensors_lm92_init(void) -{ - return i2c_add_driver(&lm92_driver); -} - -static void __exit sensors_lm92_exit(void) -{ - i2c_del_driver(&lm92_driver); -} +module_i2c_driver(lm92_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("LM92/MAX6635 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm92_init); -module_exit(sensors_lm92_exit); diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 8bd6c5c9e05b..67e8fe256e02 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -1,42 +1,42 @@ /* - lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring - - Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> - Copyright (c) 2004 Utilitek Systems, Inc. - - derived in part from lm78.c: - Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> - - derived in part from lm85.c: - Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> - Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> - - derived in part from w83l785ts.c: - Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org> - - Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com> - Copyright (c) 2005 Aspen Systems, Inc. - - Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> - Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab - - Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de> - Copyright (c) 2007 Hans J. Koch, Linutronix GmbH - - 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. -*/ + * lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring + * + * Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> + * Copyright (c) 2004 Utilitek Systems, Inc. + * + * derived in part from lm78.c: + * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> + * + * derived in part from lm85.c: + * Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> + * Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> + * + * derived in part from w83l785ts.c: + * Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org> + * + * Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com> + * Copyright (c) 2005 Aspen Systems, Inc. + * + * Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> + * Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab + * + * Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de> + * Copyright (c) 2007 Hans J. Koch, Linutronix GmbH + * + * 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 <linux/module.h> #include <linux/init.h> @@ -83,7 +83,7 @@ #define LM93_REG_FAN_MIN(nr) (0xb4 + (nr) * 2) /* pwm outputs: pwm1-pwm2 (nr => 0-1, reg => 0-3) */ -#define LM93_REG_PWM_CTL(nr,reg) (0xc8 + (reg) + (nr) * 4) +#define LM93_REG_PWM_CTL(nr, reg) (0xc8 + (reg) + (nr) * 4) #define LM93_PWM_CTL1 0x0 #define LM93_PWM_CTL2 0x1 #define LM93_PWM_CTL3 0x2 @@ -160,7 +160,7 @@ static bool init; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization."); -static int vccp_limit_type[2] = {0,0}; +static int vccp_limit_type[2] = {0, 0}; module_param_array(vccp_limit_type, int, NULL, 0); MODULE_PARM_DESC(vccp_limit_type, "Configures in7 and in8 limit modes."); @@ -187,8 +187,10 @@ static const struct { u8 cmd; u8 len; } lm93_block_read_cmds[12] = { { 0xfd, 9 }, }; -/* ALARMS: SYSCTL format described further below - REG: 64 bits in 8 registers, as immediately below */ +/* + * ALARMS: SYSCTL format described further below + * REG: 64 bits in 8 registers, as immediately below + */ struct block1_t { u8 host_status_1; u8 host_status_2; @@ -217,8 +219,10 @@ struct lm93_data { /* register values, arranged by block read groups */ struct block1_t block1; - /* temp1 - temp4: unfiltered readings - temp1 - temp2: filtered readings */ + /* + * temp1 - temp4: unfiltered readings + * temp1 - temp2: filtered readings + */ u8 block2[6]; /* vin1 - vin16: readings */ @@ -295,14 +299,18 @@ struct lm93_data { u8 sfc2; u8 sf_tach_to_pwm; - /* The two PWM CTL2 registers can read something other than what was - last written for the OVR_DC field (duty cycle override). So, we - save the user-commanded value here. */ + /* + * The two PWM CTL2 registers can read something other than what was + * last written for the OVR_DC field (duty cycle override). So, we + * save the user-commanded value here. + */ u8 pwm_override[2]; }; -/* VID: mV - REG: 6-bits, right justified, *always* using Intel VRM/VRD 10 */ +/* + * VID: mV + * REG: 6-bits, right justified, *always* using Intel VRM/VRD 10 + */ static int LM93_VID_FROM_REG(u8 reg) { return vid_from_reg((reg & 0x3f), 100); @@ -317,12 +325,13 @@ static const u8 lm93_vin_reg_max[16] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, }; -/* Values from the datasheet. They're here for documentation only. -static const u8 lm93_vin_reg_nom[16] = { - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0, -}; -*/ +/* + * Values from the datasheet. They're here for documentation only. + * static const u8 lm93_vin_reg_nom[16] = { + * 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + * 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0, + * }; + */ /* min, max, and nominal voltage readings, per channel (mV)*/ static const unsigned long lm93_vin_val_min[16] = { @@ -334,12 +343,13 @@ static const unsigned long lm93_vin_val_max[16] = { 1236, 1236, 1236, 1600, 2000, 2000, 1600, 1600, 4400, 6500, 3333, 2625, 1312, 1312, 1236, 3600, }; -/* Values from the datasheet. They're here for documentation only. -static const unsigned long lm93_vin_val_nom[16] = { - 927, 927, 927, 1200, 1500, 1500, 1200, 1200, - 3300, 5000, 2500, 1969, 984, 984, 309, 3300, -}; -*/ +/* + * Values from the datasheet. They're here for documentation only. + * static const unsigned long lm93_vin_val_nom[16] = { + * 927, 927, 927, 1200, 1500, 1500, 1200, 1200, + * 3300, 5000, 2500, 1969, 984, 984, 309, 3300, + * }; + */ static unsigned LM93_IN_FROM_REG(int nr, u8 reg) { @@ -353,8 +363,10 @@ static unsigned LM93_IN_FROM_REG(int nr, u8 reg) return (slope * reg + intercept + 500) / 1000; } -/* IN: mV, limits determined by channel nr - REG: scaling determined by channel nr */ +/* + * IN: mV, limits determined by channel nr + * REG: scaling determined by channel nr + */ static u8 LM93_IN_TO_REG(int nr, unsigned val) { /* range limit */ @@ -386,12 +398,14 @@ static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) return (uV_vid + uV_offset + 5000) / 10000; } -#define LM93_IN_MIN_FROM_REG(reg,vid) LM93_IN_REL_FROM_REG(reg,0,vid) -#define LM93_IN_MAX_FROM_REG(reg,vid) LM93_IN_REL_FROM_REG(reg,1,vid) +#define LM93_IN_MIN_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 0, (vid)) +#define LM93_IN_MAX_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 1, (vid)) -/* vid in mV , upper == 0 indicates low limit, otherwise upper limit - upper also determines which nibble of the register is returned - (the other nibble will be 0x0) */ +/* + * vid in mV , upper == 0 indicates low limit, otherwise upper limit + * upper also determines which nibble of the register is returned + * (the other nibble will be 0x0) + */ static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) { long uV_offset = vid * 1000 - val * 10000; @@ -404,22 +418,26 @@ static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) } } -/* TEMP: 1/1000 degrees C (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: 1/1000 degrees C (-128C to +127C) + * REG: 1C/bit, two's complement + */ static int LM93_TEMP_FROM_REG(u8 reg) { return (s8)reg * 1000; } #define LM93_TEMP_MIN (-128000) -#define LM93_TEMP_MAX ( 127000) +#define LM93_TEMP_MAX (127000) -/* TEMP: 1/1000 degrees C (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: 1/1000 degrees C (-128C to +127C) + * REG: 1C/bit, two's complement + */ static u8 LM93_TEMP_TO_REG(long temp) { int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); - ntemp += (ntemp<0 ? -500 : 500); + ntemp += (ntemp < 0 ? -500 : 500); return (u8)(ntemp / 1000); } @@ -430,21 +448,25 @@ static int LM93_TEMP_OFFSET_MODE_FROM_REG(u8 sfc2, int nr) return sfc2 & (nr < 2 ? 0x10 : 0x20); } -/* This function is common to all 4-bit temperature offsets - reg is 4 bits right justified - mode 0 => 1C/bit, mode !0 => 0.5C/bit */ +/* + * This function is common to all 4-bit temperature offsets + * reg is 4 bits right justified + * mode 0 => 1C/bit, mode !0 => 0.5C/bit + */ static int LM93_TEMP_OFFSET_FROM_REG(u8 reg, int mode) { return (reg & 0x0f) * (mode ? 5 : 10); } -#define LM93_TEMP_OFFSET_MIN ( 0) +#define LM93_TEMP_OFFSET_MIN (0) #define LM93_TEMP_OFFSET_MAX0 (150) -#define LM93_TEMP_OFFSET_MAX1 ( 75) +#define LM93_TEMP_OFFSET_MAX1 (75) -/* This function is common to all 4-bit temperature offsets - returns 4 bits right justified - mode 0 => 1C/bit, mode !0 => 0.5C/bit */ +/* + * This function is common to all 4-bit temperature offsets + * returns 4 bits right justified + * mode 0 => 1C/bit, mode !0 => 0.5C/bit + */ static u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode) { int factor = mode ? 5 : 10; @@ -466,9 +488,11 @@ static int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode) return LM93_TEMP_OFFSET_FROM_REG(reg >> 4 & 0x0f, mode); } -/* TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero)) - REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) - 0 <= nr <= 3 */ +/* + * TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero)) + * REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) + * 0 <= nr <= 3 + */ static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode) { u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode); @@ -532,9 +556,12 @@ static u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, long hyst, return reg; } -/* PWM: 0-255 per sensors documentation - REG: 0-13 as mapped below... right justified */ -typedef enum { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ } pwm_freq_t; +/* + * PWM: 0-255 per sensors documentation + * REG: 0-13 as mapped below... right justified + */ +enum pwm_freq { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ }; + static int lm93_pwm_map[2][16] = { { 0x00, /* 0.00% */ 0x40, /* 25.00% */ @@ -558,13 +585,13 @@ static int lm93_pwm_map[2][16] = { }, }; -static int LM93_PWM_FROM_REG(u8 reg, pwm_freq_t freq) +static int LM93_PWM_FROM_REG(u8 reg, enum pwm_freq freq) { return lm93_pwm_map[freq][reg & 0x0f]; } /* round up to nearest match */ -static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq) +static u8 LM93_PWM_TO_REG(int pwm, enum pwm_freq freq) { int i; for (i = 0; i < 13; i++) @@ -578,7 +605,7 @@ static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq) static int LM93_FAN_FROM_REG(u16 regs) { const u16 count = le16_to_cpu(regs) >> 2; - return count==0 ? -1 : count==0x3fff ? 0: 1350000 / count; + return count == 0 ? -1 : count == 0x3fff ? 0 : 1350000 / count; } /* @@ -600,8 +627,10 @@ static u16 LM93_FAN_TO_REG(long rpm) return cpu_to_le16(regs); } -/* PWM FREQ: HZ - REG: 0-7 as mapped below */ +/* + * PWM FREQ: HZ + * REG: 0-7 as mapped below + */ static int lm93_pwm_freq_map[8] = { 22500, 96, 84, 72, 60, 48, 36, 12 }; @@ -623,8 +652,10 @@ static u8 LM93_PWM_FREQ_TO_REG(int freq) return (u8)i; } -/* TIME: 1/100 seconds - * REG: 0-7 as mapped below */ +/* + * TIME: 1/100 seconds + * REG: 0-7 as mapped below + */ static int lm93_spinup_time_map[8] = { 0, 10, 25, 40, 70, 100, 200, 400, }; @@ -654,24 +685,30 @@ static int LM93_RAMP_FROM_REG(u8 reg) return (reg & 0x0f) * 5; } -/* RAMP: 1/100 seconds - REG: 50mS/bit 4-bits right justified */ +/* + * RAMP: 1/100 seconds + * REG: 50mS/bit 4-bits right justified + */ static u8 LM93_RAMP_TO_REG(int ramp) { ramp = SENSORS_LIMIT(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX); return (u8)((ramp + 2) / 5); } -/* PROCHOT: 0-255, 0 => 0%, 255 => > 96.6% - * REG: (same) */ +/* + * PROCHOT: 0-255, 0 => 0%, 255 => > 96.6% + * REG: (same) + */ static u8 LM93_PROCHOT_TO_REG(long prochot) { prochot = SENSORS_LIMIT(prochot, 0, 255); return (u8)prochot; } -/* PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds) - * REG: 0-9 as mapped below */ +/* + * PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds) + * REG: 0-9 as mapped below + */ static int lm93_interval_map[10] = { 73, 146, 290, 580, 1170, 2330, 4660, 9320, 18600, 37200, }; @@ -693,22 +730,25 @@ static u8 LM93_INTERVAL_TO_REG(long interval) return (u8)i; } -/* GPIO: 0-255, GPIO0 is LSB - * REG: inverted */ +/* + * GPIO: 0-255, GPIO0 is LSB + * REG: inverted + */ static unsigned LM93_GPI_FROM_REG(u8 reg) { return ~reg & 0xff; } -/* alarm bitmask definitions - The LM93 has nearly 64 bits of error status... I've pared that down to - what I think is a useful subset in order to fit it into 32 bits. - - Especially note that the #VRD_HOT alarms are missing because we provide - that information as values in another sysfs file. - - If libsensors is extended to support 64 bit values, this could be revisited. -*/ +/* + * alarm bitmask definitions + * The LM93 has nearly 64 bits of error status... I've pared that down to + * what I think is a useful subset in order to fit it into 32 bits. + * + * Especially note that the #VRD_HOT alarms are missing because we provide + * that information as values in another sysfs file. + * + * If libsensors is extended to support 64 bit values, this could be revisited. + */ #define LM93_ALARM_IN1 0x00000001 #define LM93_ALARM_IN2 0x00000002 #define LM93_ALARM_IN3 0x00000004 @@ -772,11 +812,12 @@ static u8 lm93_read_byte(struct i2c_client *client, u8 reg) int value, i; /* retry in case of read errors */ - for (i=1; i<=MAX_RETRIES; i++) { - if ((value = i2c_smbus_read_byte_data(client, reg)) >= 0) { + for (i = 1; i <= MAX_RETRIES; i++) { + value = i2c_smbus_read_byte_data(client, reg); + if (value >= 0) { return value; } else { - dev_warn(&client->dev,"lm93: read byte data failed, " + dev_warn(&client->dev, "lm93: read byte data failed, " "address 0x%02x.\n", reg); mdelay(i + 3); } @@ -784,7 +825,7 @@ static u8 lm93_read_byte(struct i2c_client *client, u8 reg) } /* <TODO> what to return in case of error? */ - dev_err(&client->dev,"lm93: All read byte retries failed!!\n"); + dev_err(&client->dev, "lm93: All read byte retries failed!!\n"); return 0; } @@ -796,7 +837,7 @@ static int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value) result = i2c_smbus_write_byte_data(client, reg, value); if (result < 0) - dev_warn(&client->dev,"lm93: write byte data failed, " + dev_warn(&client->dev, "lm93: write byte data failed, " "0x%02x at address 0x%02x.\n", value, reg); return result; @@ -807,11 +848,12 @@ static u16 lm93_read_word(struct i2c_client *client, u8 reg) int value, i; /* retry in case of read errors */ - for (i=1; i<=MAX_RETRIES; i++) { - if ((value = i2c_smbus_read_word_data(client, reg)) >= 0) { + for (i = 1; i <= MAX_RETRIES; i++) { + value = i2c_smbus_read_word_data(client, reg); + if (value >= 0) { return value; } else { - dev_warn(&client->dev,"lm93: read word data failed, " + dev_warn(&client->dev, "lm93: read word data failed, " "address 0x%02x.\n", reg); mdelay(i + 3); } @@ -819,7 +861,7 @@ static u16 lm93_read_word(struct i2c_client *client, u8 reg) } /* <TODO> what to return in case of error? */ - dev_err(&client->dev,"lm93: All read word retries failed!!\n"); + dev_err(&client->dev, "lm93: All read word retries failed!!\n"); return 0; } @@ -831,7 +873,7 @@ static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) result = i2c_smbus_write_word_data(client, reg, value); if (result < 0) - dev_warn(&client->dev,"lm93: write word data failed, " + dev_warn(&client->dev, "lm93: write word data failed, " "0x%04x at address 0x%02x.\n", value, reg); return result; @@ -840,13 +882,13 @@ static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) static u8 lm93_block_buffer[I2C_SMBUS_BLOCK_MAX]; /* - read block data into values, retry if not expected length - fbn => index to lm93_block_read_cmds table - (Fixed Block Number - section 14.5.2 of LM93 datasheet) -*/ + * read block data into values, retry if not expected length + * fbn => index to lm93_block_read_cmds table + * (Fixed Block Number - section 14.5.2 of LM93 datasheet) + */ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) { - int i, result=0; + int i, result = 0; for (i = 1; i <= MAX_RETRIES; i++) { result = i2c_smbus_read_block_data(client, @@ -855,7 +897,7 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) if (result == lm93_block_read_cmds[fbn].len) { break; } else { - dev_warn(&client->dev,"lm93: block read data failed, " + dev_warn(&client->dev, "lm93: block read data failed, " "command 0x%02x.\n", lm93_block_read_cmds[fbn].cmd); mdelay(i + 3); @@ -863,7 +905,8 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) } if (result == lm93_block_read_cmds[fbn].len) { - memcpy(values,lm93_block_buffer,lm93_block_read_cmds[fbn].len); + memcpy(values, lm93_block_buffer, + lm93_block_read_cmds[fbn].len); } else { /* <TODO> what to do in case of error? */ } @@ -964,7 +1007,7 @@ static void lm93_update_client_common(struct lm93_data *data, static void lm93_update_client_full(struct lm93_data *data, struct i2c_client *client) { - dev_dbg(&client->dev,"starting device update (block data enabled)\n"); + dev_dbg(&client->dev, "starting device update (block data enabled)\n"); /* in1 - in16: values & limits */ lm93_read_block(client, 3, (u8 *)(data->block3)); @@ -996,10 +1039,10 @@ static void lm93_update_client_full(struct lm93_data *data, static void lm93_update_client_min(struct lm93_data *data, struct i2c_client *client) { - int i,j; + int i, j; u8 *ptr; - dev_dbg(&client->dev,"starting device update (block data disabled)\n"); + dev_dbg(&client->dev, "starting device update (block data disabled)\n"); /* in1 - in16: values & limits */ for (i = 0; i < 16; i++) { @@ -1037,7 +1080,7 @@ static void lm93_update_client_min(struct lm93_data *data, for (i = 0; i < 2; i++) { for (j = 0; j < 4; j++) { data->block9[i][j] = - lm93_read_byte(client, LM93_REG_PWM_CTL(i,j)); + lm93_read_byte(client, LM93_REG_PWM_CTL(i, j)); } } @@ -1097,14 +1140,13 @@ static ssize_t show_in_min(struct device *dev, int vccp = nr - 6; long rc, vid; - if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { + if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { vid = LM93_VID_FROM_REG(data->vid[vccp]); rc = LM93_IN_MIN_FROM_REG(data->vccp_limits[vccp], vid); + } else { + rc = LM93_IN_FROM_REG(nr, data->block7[nr].min); } - else { - rc = LM93_IN_FROM_REG(nr, data->block7[nr].min); \ - } - return sprintf(buf, "%ld\n", rc); \ + return sprintf(buf, "%ld\n", rc); } static ssize_t store_in_min(struct device *dev, struct device_attribute *attr, @@ -1113,20 +1155,24 @@ static ssize_t store_in_min(struct device *dev, struct device_attribute *attr, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); int vccp = nr - 6; long vid; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { + if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { vid = LM93_VID_FROM_REG(data->vid[vccp]); data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0xf0) | LM93_IN_REL_TO_REG(val, 0, vid); lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), data->vccp_limits[vccp]); - } - else { - data->block7[nr].min = LM93_IN_TO_REG(nr,val); + } else { + data->block7[nr].min = LM93_IN_TO_REG(nr, val); lm93_write_byte(client, LM93_REG_IN_MIN(nr), data->block7[nr].min); } @@ -1175,14 +1221,13 @@ static ssize_t show_in_max(struct device *dev, int vccp = nr - 6; long rc, vid; - if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { + if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { vid = LM93_VID_FROM_REG(data->vid[vccp]); - rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp],vid); - } - else { - rc = LM93_IN_FROM_REG(nr,data->block7[nr].max); \ + rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp], vid); + } else { + rc = LM93_IN_FROM_REG(nr, data->block7[nr].max); } - return sprintf(buf,"%ld\n",rc); \ + return sprintf(buf, "%ld\n", rc); } static ssize_t store_in_max(struct device *dev, struct device_attribute *attr, @@ -1191,20 +1236,24 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute *attr, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); int vccp = nr - 6; long vid; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { + if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { vid = LM93_VID_FROM_REG(data->vid[vccp]); data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0x0f) | LM93_IN_REL_TO_REG(val, 1, vid); lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), data->vccp_limits[vccp]); - } - else { - data->block7[nr].max = LM93_IN_TO_REG(nr,val); + } else { + data->block7[nr].max = LM93_IN_TO_REG(nr, val); lm93_write_byte(client, LM93_REG_IN_MAX(nr), data->block7[nr].max); } @@ -1250,7 +1299,7 @@ static ssize_t show_temp(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block2[nr])); + return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->block2[nr])); } static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); @@ -1262,7 +1311,7 @@ static ssize_t show_temp_min(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].min)); + return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->temp_lim[nr].min)); } static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, @@ -1271,7 +1320,12 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); @@ -1292,7 +1346,7 @@ static ssize_t show_temp_max(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].max)); + return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->temp_lim[nr].max)); } static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, @@ -1301,7 +1355,12 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); @@ -1322,7 +1381,7 @@ static ssize_t show_temp_auto_base(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block10.base[nr])); + return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->block10.base[nr])); } static ssize_t store_temp_auto_base(struct device *dev, @@ -1332,7 +1391,12 @@ static ssize_t store_temp_auto_base(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->block10.base[nr] = LM93_TEMP_TO_REG(val); @@ -1349,11 +1413,11 @@ static SENSOR_DEVICE_ATTR(temp3_auto_base, S_IWUSR | S_IRUGO, show_temp_auto_base, store_temp_auto_base, 2); static ssize_t show_temp_auto_boost(struct device *dev, - struct device_attribute *attr,char *buf) + struct device_attribute *attr, char *buf) { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->boost[nr])); + return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->boost[nr])); } static ssize_t store_temp_auto_boost(struct device *dev, @@ -1363,7 +1427,12 @@ static ssize_t store_temp_auto_boost(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->boost[nr] = LM93_TEMP_TO_REG(val); @@ -1386,7 +1455,7 @@ static ssize_t show_temp_auto_boost_hyst(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); - return sprintf(buf,"%d\n", + return sprintf(buf, "%d\n", LM93_AUTO_BOOST_HYST_FROM_REGS(data, nr, mode)); } @@ -1397,7 +1466,12 @@ static ssize_t store_temp_auto_boost_hyst(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); /* force 0.5C/bit mode */ @@ -1429,9 +1503,9 @@ static ssize_t show_temp_auto_offset(struct device *dev, int ofs = s_attr->nr; struct lm93_data *data = lm93_update_device(dev); int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); - return sprintf(buf,"%d\n", + return sprintf(buf, "%d\n", LM93_TEMP_AUTO_OFFSET_FROM_REG(data->block10.offset[ofs], - nr,mode)); + nr, mode)); } static ssize_t store_temp_auto_offset(struct device *dev, @@ -1443,7 +1517,12 @@ static ssize_t store_temp_auto_offset(struct device *dev, int ofs = s_attr->nr; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); /* force 0.5C/bit mode */ @@ -1539,7 +1618,7 @@ static ssize_t show_temp_auto_pwm_min(struct device *dev, struct lm93_data *data = lm93_update_device(dev); reg = data->auto_pwm_min_hyst[nr/2] >> 4 & 0x0f; ctl4 = data->block9[nr][LM93_PWM_CTL4]; - return sprintf(buf,"%d\n",LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ? + return sprintf(buf, "%d\n", LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); } @@ -1550,12 +1629,17 @@ static ssize_t store_temp_auto_pwm_min(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 reg, ctl4; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); reg = lm93_read_byte(client, LM93_REG_PWM_MIN_HYST(nr)); - ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); + ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); reg = (reg & 0x0f) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : @@ -1582,8 +1666,8 @@ static ssize_t show_temp_auto_offset_hyst(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); - return sprintf(buf,"%d\n",LM93_TEMP_OFFSET_FROM_REG( - data->auto_pwm_min_hyst[nr/2], mode)); + return sprintf(buf, "%d\n", LM93_TEMP_OFFSET_FROM_REG( + data->auto_pwm_min_hyst[nr / 2], mode)); } static ssize_t store_temp_auto_offset_hyst(struct device *dev, @@ -1593,8 +1677,13 @@ static ssize_t store_temp_auto_offset_hyst(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); /* force 0.5C/bit mode */ @@ -1626,7 +1715,7 @@ static ssize_t show_fan_input(struct device *dev, int nr = s_attr->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block5[nr])); + return sprintf(buf, "%d\n", LM93_FAN_FROM_REG(data->block5[nr])); } static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); @@ -1640,7 +1729,7 @@ static ssize_t show_fan_min(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block8[nr])); + return sprintf(buf, "%d\n", LM93_FAN_FROM_REG(data->block8[nr])); } static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, @@ -1649,11 +1738,16 @@ static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->block8[nr] = LM93_FAN_TO_REG(val); - lm93_write_word(client,LM93_REG_FAN_MIN(nr),data->block8[nr]); + lm93_write_word(client, LM93_REG_FAN_MIN(nr), data->block8[nr]); mutex_unlock(&data->update_lock); return count; } @@ -1667,18 +1761,19 @@ static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 3); -/* some tedious bit-twiddling here to deal with the register format: - - data->sf_tach_to_pwm: (tach to pwm mapping bits) - - bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 - T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1 - - data->sfc2: (enable bits) - - bit | 3 | 2 | 1 | 0 - T4 T3 T2 T1 -*/ +/* + * some tedious bit-twiddling here to deal with the register format: + * + * data->sf_tach_to_pwm: (tach to pwm mapping bits) + * + * bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 + * T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1 + * + * data->sfc2: (enable bits) + * + * bit | 3 | 2 | 1 | 0 + * T4 T3 T2 T1 + */ static ssize_t show_fan_smart_tach(struct device *dev, struct device_attribute *attr, char *buf) @@ -1694,11 +1789,13 @@ static ssize_t show_fan_smart_tach(struct device *dev, /* if there's a mapping and it's enabled */ if (mapping && ((data->sfc2 >> nr) & 0x01)) rc = mapping; - return sprintf(buf,"%ld\n",rc); + return sprintf(buf, "%ld\n", rc); } -/* helper function - must grab data->update_lock before calling - fan is 0-3, indicating fan1-fan4 */ +/* + * helper function - must grab data->update_lock before calling + * fan is 0-3, indicating fan1-fan4 + */ static void lm93_write_fan_smart_tach(struct i2c_client *client, struct lm93_data *data, int fan, long value) { @@ -1724,7 +1821,12 @@ static ssize_t store_fan_smart_tach(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); /* sanity test, ignore the write otherwise */ @@ -1732,7 +1834,7 @@ static ssize_t store_fan_smart_tach(struct device *dev, /* can't enable if pwm freq is 22.5KHz */ if (val) { u8 ctl4 = lm93_read_byte(client, - LM93_REG_PWM_CTL(val-1,LM93_PWM_CTL4)); + LM93_REG_PWM_CTL(val - 1, LM93_PWM_CTL4)); if ((ctl4 & 0x07) == 0) val = 0; } @@ -1766,7 +1868,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, else /* show present h/w value if manual pwm disabled */ rc = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); - return sprintf(buf,"%ld\n",rc); + return sprintf(buf, "%ld\n", rc); } static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, @@ -1775,19 +1877,24 @@ static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ctl2, ctl4; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); - ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); - ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val,(ctl4 & 0x07) ? + ctl2 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2)); + ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); + ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ) << 4; /* save user commanded value */ data->pwm_override[nr] = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); - lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); + lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2), ctl2); mutex_unlock(&data->update_lock); return count; } @@ -1808,7 +1915,7 @@ static ssize_t show_pwm_enable(struct device *dev, rc = ((ctl2 & 0xF0) == 0xF0) ? 0 : 1; else rc = 2; - return sprintf(buf,"%ld\n",rc); + return sprintf(buf, "%ld\n", rc); } static ssize_t store_pwm_enable(struct device *dev, @@ -1818,26 +1925,33 @@ static ssize_t store_pwm_enable(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ctl2; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); + ctl2 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2)); switch (val) { case 0: ctl2 |= 0xF1; /* enable manual override, set PWM to max */ break; - case 1: ctl2 |= 0x01; /* enable manual override */ + case 1: + ctl2 |= 0x01; /* enable manual override */ break; - case 2: ctl2 &= ~0x01; /* disable manual override */ + case 2: + ctl2 &= ~0x01; /* disable manual override */ break; default: mutex_unlock(&data->update_lock); return -EINVAL; } - lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); + lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2), ctl2); mutex_unlock(&data->update_lock); return count; } @@ -1855,12 +1969,14 @@ static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, u8 ctl4; ctl4 = data->block9[nr][LM93_PWM_CTL4]; - return sprintf(buf,"%d\n",LM93_PWM_FREQ_FROM_REG(ctl4)); + return sprintf(buf, "%d\n", LM93_PWM_FREQ_FROM_REG(ctl4)); } -/* helper function - must grab data->update_lock before calling - pwm is 0-1, indicating pwm1-pwm2 - this disables smart tach for all tach channels bound to the given pwm */ +/* + * helper function - must grab data->update_lock before calling + * pwm is 0-1, indicating pwm1-pwm2 + * this disables smart tach for all tach channels bound to the given pwm + */ static void lm93_disable_fan_smart_tach(struct i2c_client *client, struct lm93_data *data, int pwm) { @@ -1887,17 +2003,22 @@ static ssize_t store_pwm_freq(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ctl4; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); + ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(val); data->block9[nr][LM93_PWM_CTL4] = ctl4; /* ctl4 == 0 -> 22.5KHz -> disable smart tach */ if (!ctl4) lm93_disable_fan_smart_tach(client, data, nr); - lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4), ctl4); + lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4), ctl4); mutex_unlock(&data->update_lock); return count; } @@ -1912,7 +2033,7 @@ static ssize_t show_pwm_auto_channels(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",data->block9[nr][LM93_PWM_CTL1]); + return sprintf(buf, "%d\n", data->block9[nr][LM93_PWM_CTL1]); } static ssize_t store_pwm_auto_channels(struct device *dev, @@ -1922,11 +2043,16 @@ static ssize_t store_pwm_auto_channels(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255); - lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL1), + lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL1), data->block9[nr][LM93_PWM_CTL1]); mutex_unlock(&data->update_lock); return count; @@ -1938,7 +2064,7 @@ static SENSOR_DEVICE_ATTR(pwm2_auto_channels, S_IWUSR | S_IRUGO, show_pwm_auto_channels, store_pwm_auto_channels, 1); static ssize_t show_pwm_auto_spinup_min(struct device *dev, - struct device_attribute *attr,char *buf) + struct device_attribute *attr, char *buf) { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); @@ -1946,7 +2072,7 @@ static ssize_t show_pwm_auto_spinup_min(struct device *dev, ctl3 = data->block9[nr][LM93_PWM_CTL3]; ctl4 = data->block9[nr][LM93_PWM_CTL4]; - return sprintf(buf,"%d\n", + return sprintf(buf, "%d\n", LM93_PWM_FROM_REG(ctl3 & 0x0f, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); } @@ -1958,17 +2084,22 @@ static ssize_t store_pwm_auto_spinup_min(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ctl3, ctl4; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); - ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); - ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? + ctl3 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); + ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); + ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); data->block9[nr][LM93_PWM_CTL3] = ctl3; - lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); + lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); mutex_unlock(&data->update_lock); return count; } @@ -1985,7 +2116,7 @@ static ssize_t show_pwm_auto_spinup_time(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_SPINUP_TIME_FROM_REG( + return sprintf(buf, "%d\n", LM93_SPINUP_TIME_FROM_REG( data->block9[nr][LM93_PWM_CTL3])); } @@ -1996,14 +2127,19 @@ static ssize_t store_pwm_auto_spinup_time(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ctl3; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); + ctl3 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); ctl3 = (ctl3 & 0x1f) | (LM93_SPINUP_TIME_TO_REG(val) << 5 & 0xe0); data->block9[nr][LM93_PWM_CTL3] = ctl3; - lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); + lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); mutex_unlock(&data->update_lock); return count; } @@ -2019,7 +2155,7 @@ static ssize_t show_pwm_auto_prochot_ramp(struct device *dev, struct device_attribute *attr, char *buf) { struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n", + return sprintf(buf, "%d\n", LM93_RAMP_FROM_REG(data->pwm_ramp_ctl >> 4 & 0x0f)); } @@ -2029,8 +2165,13 @@ static ssize_t store_pwm_auto_prochot_ramp(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ramp; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); @@ -2048,7 +2189,7 @@ static ssize_t show_pwm_auto_vrdhot_ramp(struct device *dev, struct device_attribute *attr, char *buf) { struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n", + return sprintf(buf, "%d\n", LM93_RAMP_FROM_REG(data->pwm_ramp_ctl & 0x0f)); } @@ -2058,8 +2199,13 @@ static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 ramp; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); @@ -2078,7 +2224,7 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); + return sprintf(buf, "%d\n", LM93_VID_FROM_REG(data->vid[nr])); } static SENSOR_DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL, 0); @@ -2089,7 +2235,7 @@ static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",data->block4[nr].cur); + return sprintf(buf, "%d\n", data->block4[nr].cur); } static SENSOR_DEVICE_ATTR(prochot1, S_IRUGO, show_prochot, NULL, 0); @@ -2100,7 +2246,7 @@ static ssize_t show_prochot_avg(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",data->block4[nr].avg); + return sprintf(buf, "%d\n", data->block4[nr].avg); } static SENSOR_DEVICE_ATTR(prochot1_avg, S_IRUGO, show_prochot_avg, NULL, 0); @@ -2111,7 +2257,7 @@ static ssize_t show_prochot_max(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",data->prochot_max[nr]); + return sprintf(buf, "%d\n", data->prochot_max[nr]); } static ssize_t store_prochot_max(struct device *dev, @@ -2121,7 +2267,12 @@ static ssize_t store_prochot_max(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->prochot_max[nr] = LM93_PROCHOT_TO_REG(val); @@ -2143,7 +2294,7 @@ static ssize_t show_prochot_override(struct device *dev, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n", + return sprintf(buf, "%d\n", (data->prochot_override & prochot_override_mask[nr]) ? 1 : 0); } @@ -2154,7 +2305,12 @@ static ssize_t store_prochot_override(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); if (val) @@ -2178,11 +2334,11 @@ static ssize_t show_prochot_interval(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); u8 tmp; - if (nr==1) + if (nr == 1) tmp = (data->prochot_interval & 0xf0) >> 4; else tmp = data->prochot_interval & 0x0f; - return sprintf(buf,"%d\n",LM93_INTERVAL_FROM_REG(tmp)); + return sprintf(buf, "%d\n", LM93_INTERVAL_FROM_REG(tmp)); } static ssize_t store_prochot_interval(struct device *dev, @@ -2192,12 +2348,17 @@ static ssize_t store_prochot_interval(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 tmp; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); tmp = lm93_read_byte(client, LM93_REG_PROCHOT_INTERVAL); - if (nr==1) + if (nr == 1) tmp = (tmp & 0x0f) | (LM93_INTERVAL_TO_REG(val) << 4); else tmp = (tmp & 0xf0) | LM93_INTERVAL_TO_REG(val); @@ -2217,7 +2378,7 @@ static ssize_t show_prochot_override_duty_cycle(struct device *dev, char *buf) { struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",data->prochot_override & 0x0f); + return sprintf(buf, "%d\n", data->prochot_override & 0x0f); } static ssize_t store_prochot_override_duty_cycle(struct device *dev, @@ -2226,7 +2387,12 @@ static ssize_t store_prochot_override_duty_cycle(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->prochot_override = (data->prochot_override & 0xf0) | @@ -2245,7 +2411,7 @@ static ssize_t show_prochot_short(struct device *dev, struct device_attribute *attr, char *buf) { struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",(data->config & 0x10) ? 1 : 0); + return sprintf(buf, "%d\n", (data->config & 0x10) ? 1 : 0); } static ssize_t store_prochot_short(struct device *dev, @@ -2254,7 +2420,12 @@ static ssize_t store_prochot_short(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); if (val) @@ -2274,8 +2445,8 @@ static ssize_t show_vrdhot(struct device *dev, struct device_attribute *attr, { int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n", - data->block1.host_status_1 & (1 << (nr+4)) ? 1 : 0); + return sprintf(buf, "%d\n", + data->block1.host_status_1 & (1 << (nr + 4)) ? 1 : 0); } static SENSOR_DEVICE_ATTR(vrdhot1, S_IRUGO, show_vrdhot, NULL, 0); @@ -2285,7 +2456,7 @@ static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf) { struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_GPI_FROM_REG(data->gpi)); + return sprintf(buf, "%d\n", LM93_GPI_FROM_REG(data->gpi)); } static DEVICE_ATTR(gpio, S_IRUGO, show_gpio, NULL); @@ -2294,7 +2465,7 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) { struct lm93_data *data = lm93_update_device(dev); - return sprintf(buf,"%d\n",LM93_ALARMS_FROM_REG(data->block1)); + return sprintf(buf, "%d\n", LM93_ALARMS_FROM_REG(data->block1)); } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); @@ -2494,13 +2665,13 @@ static void lm93_init_client(struct i2c_client *client) lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x01); /* spin until ready */ - for (i=0; i<20; i++) { + for (i = 0; i < 20; i++) { msleep(10); if ((lm93_read_byte(client, LM93_REG_CONFIG) & 0x80) == 0x80) return; } - dev_warn(&client->dev,"timed out waiting for sensor " + dev_warn(&client->dev, "timed out waiting for sensor " "chip to signal ready!\n"); } @@ -2540,7 +2711,7 @@ static int lm93_detect(struct i2c_client *client, struct i2c_board_info *info) } strlcpy(info->type, name, I2C_NAME_SIZE); - dev_dbg(&adapter->dev,"loading %s at %d,0x%02x\n", + dev_dbg(&adapter->dev, "loading %s at %d, 0x%02x\n", client->name, i2c_adapter_id(client->adapter), client->addr); @@ -2593,7 +2764,7 @@ static int lm93_probe(struct i2c_client *client, /* Register hwmon driver class */ data->hwmon_dev = hwmon_device_register(&client->dev); - if ( !IS_ERR(data->hwmon_dev)) + if (!IS_ERR(data->hwmon_dev)) return 0; err = PTR_ERR(data->hwmon_dev); @@ -2635,20 +2806,9 @@ static struct i2c_driver lm93_driver = { .address_list = normal_i2c, }; -static int __init lm93_init(void) -{ - return i2c_add_driver(&lm93_driver); -} - -static void __exit lm93_exit(void) -{ - i2c_del_driver(&lm93_driver); -} +module_i2c_driver(lm93_driver); MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " "Hans J. Koch <hjk@hansjkoch.de>"); MODULE_DESCRIPTION("LM93 driver"); MODULE_LICENSE("GPL"); - -module_init(lm93_init); -module_exit(lm93_exit); diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 70bca671e083..bd8cdb7b96ed 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -455,19 +455,8 @@ static struct i2c_driver lm95241_driver = { .address_list = normal_i2c, }; -static int __init sensors_lm95241_init(void) -{ - return i2c_add_driver(&lm95241_driver); -} - -static void __exit sensors_lm95241_exit(void) -{ - i2c_del_driver(&lm95241_driver); -} +module_i2c_driver(lm95241_driver); MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>"); MODULE_DESCRIPTION("LM95241 sensor driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm95241_init); -module_exit(sensors_lm95241_exit); diff --git a/drivers/hwmon/lm95245.c b/drivers/hwmon/lm95245.c index 5e5fc1b0ace1..9a46c106a240 100644 --- a/drivers/hwmon/lm95245.c +++ b/drivers/hwmon/lm95245.c @@ -525,19 +525,8 @@ static struct i2c_driver lm95245_driver = { .address_list = normal_i2c, }; -static int __init sensors_lm95245_init(void) -{ - return i2c_add_driver(&lm95245_driver); -} - -static void __exit sensors_lm95245_exit(void) -{ - i2c_del_driver(&lm95245_driver); -} +module_i2c_driver(lm95245_driver); MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>"); MODULE_DESCRIPTION("LM95245 sensor driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_lm95245_init); -module_exit(sensors_lm95245_exit); diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c index 4ac06b75aa60..4d005b219de2 100644 --- a/drivers/hwmon/ltc4151.c +++ b/drivers/hwmon/ltc4151.c @@ -154,7 +154,8 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, \ static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \ ltc4151_show_value, NULL, LTC4151_SENSE_H); -/* Finally, construct an array of pointers to members of the above objects, +/* + * Finally, construct an array of pointers to members of the above objects, * as required for sysfs_create_group() */ static struct attribute *ltc4151_attributes[] = { @@ -238,19 +239,8 @@ static struct i2c_driver ltc4151_driver = { .id_table = ltc4151_id, }; -static int __init ltc4151_init(void) -{ - return i2c_add_driver(<c4151_driver); -} - -static void __exit ltc4151_exit(void) -{ - i2c_del_driver(<c4151_driver); -} +module_i2c_driver(ltc4151_driver); MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>"); MODULE_DESCRIPTION("LTC4151 driver"); MODULE_LICENSE("GPL"); - -module_init(ltc4151_init); -module_exit(ltc4151_exit); diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index c7e6d8e81656..429c5b2b66fd 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c @@ -91,8 +91,10 @@ static int ltc4215_get_voltage(struct device *dev, u8 reg) voltage = regval * 605 / 10; break; case LTC4215_ADIN: - /* The ADIN input is divided by 12.5, and has 4.82 mV - * per increment, so we have the additional multiply */ + /* + * The ADIN input is divided by 12.5, and has 4.82 mV + * per increment, so we have the additional multiply + */ voltage = regval * 482 * 125 / 1000; break; default: @@ -109,7 +111,8 @@ static unsigned int ltc4215_get_current(struct device *dev) { struct ltc4215_data *data = ltc4215_update_device(dev); - /* The strange looking conversions that follow are fixed-point + /* + * The strange looking conversions that follow are fixed-point * math, since we cannot do floating point in the kernel. * * Step 1: convert sense register to microVolts @@ -176,7 +179,8 @@ static ssize_t ltc4215_show_alarm(struct device *dev, return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); } -/* These macros are used below in constructing device attribute objects +/* + * These macros are used below in constructing device attribute objects * for use with sysfs_create_group() to make a sysfs device file * for each register. */ @@ -215,7 +219,8 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); -/* Finally, construct an array of pointers to members of the above objects, +/* + * Finally, construct an array of pointers to members of the above objects, * as required for sysfs_create_group() */ static struct attribute *ltc4215_attributes[] = { @@ -309,19 +314,8 @@ static struct i2c_driver ltc4215_driver = { .id_table = ltc4215_id, }; -static int __init ltc4215_init(void) -{ - return i2c_add_driver(<c4215_driver); -} - -static void __exit ltc4215_exit(void) -{ - i2c_del_driver(<c4215_driver); -} +module_i2c_driver(ltc4215_driver); MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); MODULE_DESCRIPTION("LTC4215 driver"); MODULE_LICENSE("GPL"); - -module_init(ltc4215_init); -module_exit(ltc4215_exit); diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 659308329308..b99b45bafdad 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c @@ -214,7 +214,8 @@ static unsigned int ltc4245_get_current(struct device *dev, u8 reg) unsigned int voltage; unsigned int curr; - /* The strange looking conversions that follow are fixed-point + /* + * The strange looking conversions that follow are fixed-point * math, since we cannot do floating point in the kernel. * * Step 1: convert sense register to microVolts @@ -317,7 +318,8 @@ static ssize_t ltc4245_show_gpio(struct device *dev, return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); } -/* These macros are used below in constructing device attribute objects +/* + * These macros are used below in constructing device attribute objects * for use with sysfs_create_group() to make a sysfs device file * for each register. */ @@ -391,7 +393,8 @@ LTC4245_POWER(power2_input, LTC4245_5VSENSE); LTC4245_POWER(power3_input, LTC4245_3VSENSE); LTC4245_POWER(power4_input, LTC4245_VEESENSE); -/* Finally, construct an array of pointers to members of the above objects, +/* + * Finally, construct an array of pointers to members of the above objects, * as required for sysfs_create_group() */ static struct attribute *ltc4245_std_attributes[] = { @@ -578,19 +581,8 @@ static struct i2c_driver ltc4245_driver = { .id_table = ltc4245_id, }; -static int __init ltc4245_init(void) -{ - return i2c_add_driver(<c4245_driver); -} - -static void __exit ltc4245_exit(void) -{ - i2c_del_driver(<c4245_driver); -} +module_i2c_driver(ltc4245_driver); MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); MODULE_DESCRIPTION("LTC4245 driver"); MODULE_LICENSE("GPL"); - -module_init(ltc4245_init); -module_exit(ltc4245_exit); diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index ce5235560f01..069b7d34d8f9 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -235,11 +235,9 @@ static int ltc4261_probe(struct i2c_client *client, 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); @@ -250,7 +248,7 @@ static int ltc4261_probe(struct i2c_client *client, /* Register sysfs hooks */ ret = sysfs_create_group(&client->dev.kobj, <c4261_group); if (ret) - goto out_sysfs_create_group; + return ret; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -262,9 +260,6 @@ static int ltc4261_probe(struct i2c_client *client, out_hwmon_device_register: sysfs_remove_group(&client->dev.kobj, <c4261_group); -out_sysfs_create_group: - kfree(data); -out_kzalloc: return ret; } @@ -275,8 +270,6 @@ static int ltc4261_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, <c4261_group); - kfree(data); - return 0; } @@ -297,19 +290,8 @@ static struct i2c_driver ltc4261_driver = { .id_table = ltc4261_id, }; -static int __init ltc4261_init(void) -{ - return i2c_add_driver(<c4261_driver); -} - -static void __exit ltc4261_exit(void) -{ - i2c_del_driver(<c4261_driver); -} +module_i2c_driver(ltc4261_driver); MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); MODULE_DESCRIPTION("LTC4261 driver"); MODULE_LICENSE("GPL"); - -module_init(ltc4261_init); -module_exit(ltc4261_exit); diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index 482ca901db30..362a40eb6129 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -106,7 +106,8 @@ static ssize_t show_adc(struct device *dev, if (ret < 0) return ret; - /* assume the reference voltage to be 2.048V, with an 8-bit sample, + /* + * assume the reference voltage to be 2.048V, with an 8-bit sample, * the LSB weight is 8mV */ return sprintf(buf, "%d\n", ret * 8); @@ -227,17 +228,7 @@ static struct spi_driver max1111_driver = { .remove = __devexit_p(max1111_remove), }; -static int __init max1111_init(void) -{ - return spi_register_driver(&max1111_driver); -} -module_init(max1111_init); - -static void __exit max1111_exit(void) -{ - spi_unregister_driver(&max1111_driver); -} -module_exit(max1111_exit); +module_spi_driver(max1111_driver); MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); MODULE_DESCRIPTION("MAX1111 ADC Driver"); diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index f8e323ac6cb3..822261be84dd 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -554,7 +554,7 @@ static int max16065_probe(struct i2c_client *client, | I2C_FUNC_SMBUS_READ_WORD_DATA)) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (unlikely(!data)) return -ENOMEM; @@ -567,20 +567,16 @@ static int max16065_probe(struct i2c_client *client, if (have_secondary) { val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE); - if (unlikely(val < 0)) { - ret = val; - goto out_free; - } + if (unlikely(val < 0)) + return val; secondary_is_max = val & MAX16065_WARNING_OV; } /* Read scale registers, convert to range */ for (i = 0; i < DIV_ROUND_UP(data->num_adc, 4); i++) { val = i2c_smbus_read_byte_data(client, MAX16065_SCALE(i)); - if (unlikely(val < 0)) { - ret = val; - goto out_free; - } + if (unlikely(val < 0)) + return val; for (j = 0; j < 4 && i * 4 + j < data->num_adc; j++) { data->range[i * 4 + j] = max16065_adc_range[(val >> (j * 2)) & 0x3]; @@ -595,10 +591,8 @@ static int max16065_probe(struct i2c_client *client, for (j = 0; j < data->num_adc; j++) { val = i2c_smbus_read_byte_data(client, MAX16065_LIMIT(i, j)); - if (unlikely(val < 0)) { - ret = val; - goto out_free; - } + if (unlikely(val < 0)) + return val; data->limit[i][j] = LIMIT_TO_MV(val, data->range[j]); } } @@ -661,8 +655,6 @@ static int max16065_probe(struct i2c_client *client, out: max16065_cleanup(client); -out_free: - kfree(data); return ret; } @@ -672,7 +664,6 @@ static int max16065_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); max16065_cleanup(client); - kfree(data); return 0; } @@ -699,19 +690,8 @@ static struct i2c_driver max16065_driver = { .id_table = max16065_id, }; -static int __init max16065_init(void) -{ - return i2c_add_driver(&max16065_driver); -} - -static void __exit max16065_exit(void) -{ - i2c_del_driver(&max16065_driver); -} +module_i2c_driver(max16065_driver); MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); MODULE_DESCRIPTION("MAX16065 driver"); MODULE_LICENSE("GPL"); - -module_init(max16065_init); -module_exit(max16065_exit); diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 022ded098100..ecac04a7b7d6 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -125,7 +125,7 @@ struct max1619_data { u8 temp_input2, temp_low2, temp_high2; /* remote */ u8 temp_crit2; u8 temp_hyst2; - u8 alarms; + u8 alarms; }; /* @@ -133,7 +133,8 @@ struct max1619_data { */ #define show_temp(value) \ -static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##value(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct max1619_data *data = max1619_update_device(dev); \ return sprintf(buf, "%d\n", temp_from_reg(data->value)); \ @@ -146,13 +147,17 @@ show_temp(temp_crit2); show_temp(temp_hyst2); #define set_temp2(value, reg) \ -static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \ +static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \ + const char *buf, \ size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct max1619_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ - \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ +\ mutex_lock(&data->update_lock); \ data->value = temp_to_reg(val); \ i2c_smbus_write_byte_data(client, reg, data->value); \ @@ -165,7 +170,8 @@ set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH); set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT); set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST); -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, + char *buf) { struct max1619_data *data = max1619_update_device(dev); return sprintf(buf, "%d\n", data->alarms); @@ -275,7 +281,8 @@ static int max1619_probe(struct i2c_client *new_client, max1619_init_client(new_client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) + err = sysfs_create_group(&new_client->dev.kobj, &max1619_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); @@ -353,20 +360,9 @@ static struct max1619_data *max1619_update_device(struct device *dev) return data; } -static int __init sensors_max1619_init(void) -{ - return i2c_add_driver(&max1619_driver); -} - -static void __exit sensors_max1619_exit(void) -{ - i2c_del_driver(&max1619_driver); -} +module_i2c_driver(max1619_driver); MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and " "Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("MAX1619 sensor driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_max1619_init); -module_exit(sensors_max1619_exit); diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c index 88953f99e914..335b183d7c02 100644 --- a/drivers/hwmon/max1668.c +++ b/drivers/hwmon/max1668.c @@ -1,23 +1,23 @@ /* - Copyright (c) 2011 David George <david.george@ska.ac.za> - - based on adm1021.c - some credit to Christoph Scheurer, but largely a rewrite - - 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. -*/ + * Copyright (c) 2011 David George <david.george@ska.ac.za> + * + * based on adm1021.c + * some credit to Christoph Scheurer, but largely a rewrite + * + * 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 <linux/module.h> #include <linux/init.h> @@ -484,19 +484,8 @@ static struct i2c_driver max1668_driver = { .address_list = max1668_addr_list, }; -static int __init sensors_max1668_init(void) -{ - return i2c_add_driver(&max1668_driver); -} - -static void __exit sensors_max1668_exit(void) -{ - i2c_del_driver(&max1668_driver); -} +module_i2c_driver(max1668_driver); MODULE_AUTHOR("David George <david.george@ska.ac.za>"); MODULE_DESCRIPTION("MAX1668 remote temperature sensor driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_max1668_init) -module_exit(sensors_max1668_exit) diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index a6760bacd915..193067e27b6f 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -637,19 +637,8 @@ static struct i2c_driver max6639_driver = { .address_list = normal_i2c, }; -static int __init max6639_init(void) -{ - return i2c_add_driver(&max6639_driver); -} - -static void __exit max6639_exit(void) -{ - i2c_del_driver(&max6639_driver); -} +module_i2c_driver(max6639_driver); MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); MODULE_DESCRIPTION("max6639 driver"); MODULE_LICENSE("GPL"); - -module_init(max6639_init); -module_exit(max6639_exit); diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c index 209e8a526eb1..4298909a41fd 100644 --- a/drivers/hwmon/max6642.c +++ b/drivers/hwmon/max6642.c @@ -352,19 +352,8 @@ static struct i2c_driver max6642_driver = { .address_list = normal_i2c, }; -static int __init max6642_init(void) -{ - return i2c_add_driver(&max6642_driver); -} - -static void __exit max6642_exit(void) -{ - i2c_del_driver(&max6642_driver); -} +module_i2c_driver(max6642_driver); MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>"); MODULE_DESCRIPTION("MAX6642 sensor driver"); MODULE_LICENSE("GPL"); - -module_init(max6642_init); -module_exit(max6642_exit); diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 2fc034aeca09..33a8a7f15e18 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -135,8 +135,7 @@ static struct i2c_driver max6650_driver = { * Client data (each client gets its own) */ -struct max6650_data -{ +struct max6650_data { struct device *hwmon_dev; struct mutex update_lock; int nr_fans; @@ -160,13 +159,13 @@ static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, int rpm; /* - * Calculation details: - * - * Each tachometer counts over an interval given by the "count" - * register (0.25, 0.5, 1 or 2 seconds). This module assumes - * that the fans produce two pulses per revolution (this seems - * to be the most common). - */ + * Calculation details: + * + * Each tachometer counts over an interval given by the "count" + * register (0.25, 0.5, 1 or 2 seconds). This module assumes + * that the fans produce two pulses per revolution (this seems + * to be the most common). + */ rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count)); return sprintf(buf, "%d\n", rpm); @@ -220,12 +219,12 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr, int kscale, ktach, rpm; /* - * Use the datasheet equation: - * - * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] - * - * then multiply by 60 to give rpm. - */ + * Use the datasheet equation: + * + * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] + * + * then multiply by 60 to give rpm. + */ kscale = DIV_FROM_REG(data->config); ktach = data->speed; @@ -238,17 +237,22 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr, { struct i2c_client *client = to_i2c_client(dev); struct max6650_data *data = i2c_get_clientdata(client); - int rpm = simple_strtoul(buf, NULL, 10); int kscale, ktach; + unsigned long rpm; + int err; + + err = kstrtoul(buf, 10, &rpm); + if (err) + return err; rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); /* - * Divide the required speed by 60 to get from rpm to rps, then - * use the datasheet equation: - * - * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 - */ + * Divide the required speed by 60 to get from rpm to rps, then + * use the datasheet equation: + * + * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 + */ mutex_lock(&data->update_lock); @@ -282,8 +286,10 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, int pwm; struct max6650_data *data = max6650_update_device(dev); - /* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. - Lower DAC values mean higher speeds. */ + /* + * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. + * Lower DAC values mean higher speeds. + */ if (data->config & MAX6650_CFG_V12) pwm = 255 - (255 * (int)data->dac)/180; else @@ -300,7 +306,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, { struct i2c_client *client = to_i2c_client(dev); struct max6650_data *data = i2c_get_clientdata(client); - int pwm = simple_strtoul(buf, NULL, 10); + unsigned long pwm; + int err; + + err = kstrtoul(buf, 10, &pwm); + if (err) + return err; pwm = SENSORS_LIMIT(pwm, 0, 255); @@ -341,14 +352,16 @@ static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, { struct i2c_client *client = to_i2c_client(dev); struct max6650_data *data = i2c_get_clientdata(client); - int mode = simple_strtoul(buf, NULL, 10); int max6650_modes[3] = {0, 3, 2}; + unsigned long mode; + int err; - if ((mode < 0)||(mode > 2)) { - dev_err(&client->dev, - "illegal value for pwm1_enable (%d)\n", mode); + err = kstrtoul(buf, 10, &mode); + if (err) + return err; + + if (mode > 2) return -EINVAL; - } mutex_lock(&data->update_lock); @@ -389,7 +402,12 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, { struct i2c_client *client = to_i2c_client(dev); struct max6650_data *data = i2c_get_clientdata(client); - int div = simple_strtoul(buf, NULL, 10); + unsigned long div; + int err; + + err = kstrtoul(buf, 10, &div); + if (err) + return err; mutex_lock(&data->update_lock); switch (div) { @@ -407,8 +425,6 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, break; default: mutex_unlock(&data->update_lock); - dev_err(&client->dev, - "illegal value for fan divider (%d)\n", div); return -EINVAL; } @@ -529,7 +545,8 @@ static int max6650_probe(struct i2c_client *client, struct max6650_data *data; int err; - if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL); + if (!data) { dev_err(&client->dev, "out of memory.\n"); return -ENOMEM; } @@ -596,55 +613,54 @@ static int max6650_init_client(struct i2c_client *client) } switch (fan_voltage) { - case 0: - break; - case 5: - config &= ~MAX6650_CFG_V12; - break; - case 12: - config |= MAX6650_CFG_V12; - break; - default: - dev_err(&client->dev, - "illegal value for fan_voltage (%d)\n", - fan_voltage); + case 0: + break; + case 5: + config &= ~MAX6650_CFG_V12; + break; + case 12: + config |= MAX6650_CFG_V12; + break; + default: + dev_err(&client->dev, "illegal value for fan_voltage (%d)\n", + fan_voltage); } dev_info(&client->dev, "Fan voltage is set to %dV.\n", (config & MAX6650_CFG_V12) ? 12 : 5); switch (prescaler) { - case 0: - break; - case 1: - config &= ~MAX6650_CFG_PRESCALER_MASK; - break; - case 2: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_2; - break; - case 4: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_4; - break; - case 8: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_8; - break; - case 16: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_16; - break; - default: - dev_err(&client->dev, - "illegal value for prescaler (%d)\n", - prescaler); + case 0: + break; + case 1: + config &= ~MAX6650_CFG_PRESCALER_MASK; + break; + case 2: + config = (config & ~MAX6650_CFG_PRESCALER_MASK) + | MAX6650_CFG_PRESCALER_2; + break; + case 4: + config = (config & ~MAX6650_CFG_PRESCALER_MASK) + | MAX6650_CFG_PRESCALER_4; + break; + case 8: + config = (config & ~MAX6650_CFG_PRESCALER_MASK) + | MAX6650_CFG_PRESCALER_8; + break; + case 16: + config = (config & ~MAX6650_CFG_PRESCALER_MASK) + | MAX6650_CFG_PRESCALER_16; + break; + default: + dev_err(&client->dev, "illegal value for prescaler (%d)\n", + prescaler); } dev_info(&client->dev, "Prescaler is set to %d.\n", 1 << (config & MAX6650_CFG_PRESCALER_MASK)); - /* If mode is set to "full off", we change it to "open loop" and + /* + * If mode is set to "full off", we change it to "open loop" and * set DAC to 255, which has the same effect. We do this because * there's no "full off" mode defined in hwmon specifcations. */ @@ -698,9 +714,11 @@ static struct max6650_data *max6650_update_device(struct device *dev) MAX6650_REG_COUNT); data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); - /* Alarms are cleared on read in case the condition that + /* + * Alarms are cleared on read in case the condition that * caused the alarm is removed. Keep the value latched here - * for providing the register through different alarm files. */ + * for providing the register through different alarm files. + */ data->alarm |= i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM); @@ -713,19 +731,8 @@ static struct max6650_data *max6650_update_device(struct device *dev) return data; } -static int __init sensors_max6650_init(void) -{ - return i2c_add_driver(&max6650_driver); -} - -static void __exit sensors_max6650_exit(void) -{ - i2c_del_driver(&max6650_driver); -} +module_i2c_driver(max6650_driver); MODULE_AUTHOR("Hans J. Koch"); MODULE_DESCRIPTION("MAX6650 sensor driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_max6650_init); -module_exit(sensors_max6650_exit); diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index ef65ab56b094..6c6b240a782e 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c @@ -1,5 +1,5 @@ /* - * Driver for the Freescale Semiconductor MC13783 adc. + * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs. * * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2009 Sascha Hauer, Pengutronix @@ -18,7 +18,7 @@ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <linux/mfd/mc13783.h> +#include <linux/mfd/mc13xxx.h> #include <linux/platform_device.h> #include <linux/hwmon-sysfs.h> #include <linux/kernel.h> @@ -28,24 +28,30 @@ #include <linux/init.h> #include <linux/err.h> -#define MC13783_ADC_NAME "mc13783-adc" +#define DRIVER_NAME "mc13783-adc" + +/* platform device id driver data */ +#define MC13783_ADC_16CHANS 1 +#define MC13783_ADC_BPDIV2 2 struct mc13783_adc_priv { struct mc13xxx *mc13xxx; struct device *hwmon_dev; + char name[10]; }; static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute *devattr, char *buf) { - return sprintf(buf, "mc13783_adc\n"); + struct mc13783_adc_priv *priv = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", priv->name); } static int mc13783_adc_read(struct device *dev, struct device_attribute *devattr, unsigned int *val) { - struct platform_device *pdev = to_platform_device(dev); - struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); + struct mc13783_adc_priv *priv = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); unsigned int channel = attr->index; unsigned int sample[4]; @@ -68,16 +74,21 @@ static ssize_t mc13783_adc_read_bp(struct device *dev, struct device_attribute *devattr, char *buf) { unsigned val; + struct platform_device *pdev = to_platform_device(dev); + kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; int ret = mc13783_adc_read(dev, devattr, &val); if (ret) return ret; - /* - * BP (channel 2) reports with offset 2.4V to the actual value to fit - * the input range of the ADC. unit = 2.25mV = 9/4 mV. - */ - val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400; + if (driver_data & MC13783_ADC_BPDIV2) + val = DIV_ROUND_CLOSEST(val * 9, 2); + else + /* + * BP (channel 2) reports with offset 2.4V to the actual value + * to fit the input range of the ADC. unit = 2.25mV = 9/4 mV. + */ + val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400; return sprintf(buf, "%u\n", val); } @@ -114,12 +125,21 @@ static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13); static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14); static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15); -static struct attribute *mc13783_attr[] = { +static struct attribute *mc13783_attr_base[] = { &dev_attr_name.attr, &sensor_dev_attr_in2_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 mc13783_group_base = { + .attrs = mc13783_attr_base, +}; + +/* these are only used if MC13783_ADC_16CHANS is provided in driver data */ +static struct attribute *mc13783_attr_16chans[] = { &sensor_dev_attr_in8_input.dev_attr.attr, &sensor_dev_attr_in9_input.dev_attr.attr, &sensor_dev_attr_in10_input.dev_attr.attr, @@ -127,8 +147,8 @@ static struct attribute *mc13783_attr[] = { NULL }; -static const struct attribute_group mc13783_group = { - .attrs = mc13783_attr, +static const struct attribute_group mc13783_group_16chans = { + .attrs = mc13783_attr_16chans, }; /* last four channels may be occupied by the touchscreen */ @@ -156,24 +176,37 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) { struct mc13783_adc_priv *priv; int ret; + const struct platform_device_id *id = platform_get_device_id(pdev); + char *dash; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); + snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name); + dash = strchr(priv->name, '-'); + if (dash) + *dash = '\0'; platform_set_drvdata(pdev, priv); /* Register sysfs hooks */ - ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group); + ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base); if (ret) - goto out_err_create1; + goto out_err_create_base; + + if (id->driver_data & MC13783_ADC_16CHANS) { + ret = sysfs_create_group(&pdev->dev.kobj, + &mc13783_group_16chans); + if (ret) + goto out_err_create_16chans; + } if (!mc13783_adc_use_touchscreen(pdev)) { ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts); if (ret) - goto out_err_create2; + goto out_err_create_ts; } priv->hwmon_dev = hwmon_device_register(&pdev->dev); @@ -184,17 +217,20 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) goto out_err_register; } - return 0; out_err_register: if (!mc13783_adc_use_touchscreen(pdev)) sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); -out_err_create2: +out_err_create_ts: - sysfs_remove_group(&pdev->dev.kobj, &mc13783_group); -out_err_create1: + if (id->driver_data & MC13783_ADC_16CHANS) + sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); +out_err_create_16chans: + + sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); +out_err_create_base: platform_set_drvdata(pdev, NULL); kfree(priv); @@ -205,13 +241,17 @@ out_err_create1: static int __devexit mc13783_adc_remove(struct platform_device *pdev) { struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); + kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; hwmon_device_unregister(priv->hwmon_dev); if (!mc13783_adc_use_touchscreen(pdev)) sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); - sysfs_remove_group(&pdev->dev.kobj, &mc13783_group); + if (driver_data & MC13783_ADC_16CHANS) + sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); + + sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); platform_set_drvdata(pdev, NULL); kfree(priv); @@ -219,12 +259,26 @@ static int __devexit mc13783_adc_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id mc13783_adc_idtable[] = { + { + .name = "mc13783-adc", + .driver_data = MC13783_ADC_16CHANS, + }, { + .name = "mc13892-adc", + .driver_data = MC13783_ADC_BPDIV2, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable); + static struct platform_driver mc13783_adc_driver = { - .remove = __devexit_p(mc13783_adc_remove), + .remove = __devexit_p(mc13783_adc_remove), .driver = { .owner = THIS_MODULE, - .name = MC13783_ADC_NAME, + .name = DRIVER_NAME, }, + .id_table = mc13783_adc_idtable, }; static int __init mc13783_adc_init(void) @@ -243,4 +297,3 @@ module_exit(mc13783_adc_exit); MODULE_DESCRIPTION("MC13783 ADC driver"); MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" MC13783_ADC_NAME); diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c new file mode 100644 index 000000000000..d0afc0cd3ff4 --- /dev/null +++ b/drivers/hwmon/mcp3021.c @@ -0,0 +1,171 @@ +/* + * mcp3021.c - driver for the Microchip MCP3021 chip + * + * Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc. + * Author: Mingkai Hu <Mingkai.hu@freescale.com> + * + * This driver export the value of analog input voltage to sysfs, the + * voltage unit is mV. Through the sysfs interface, lm-sensors tool + * can also display the input voltage. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/hwmon.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/err.h> +#include <linux/device.h> + +/* Vdd info */ +#define MCP3021_VDD_MAX 5500 +#define MCP3021_VDD_MIN 2700 +#define MCP3021_VDD_REF 3300 + +/* output format */ +#define MCP3021_SAR_SHIFT 2 +#define MCP3021_SAR_MASK 0x3ff + +#define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */ +#define MCP3021_OUTPUT_SCALE 4 + +/* + * Client data (each client gets its own) + */ +struct mcp3021_data { + struct device *hwmon_dev; + u32 vdd; /* device power supply */ +}; + +static int mcp3021_read16(struct i2c_client *client) +{ + int ret; + u16 reg; + __be16 buf; + + ret = i2c_master_recv(client, (char *)&buf, 2); + if (ret < 0) + return ret; + if (ret != 2) + return -EIO; + + /* The output code of the MCP3021 is transmitted with MSB first. */ + reg = be16_to_cpu(buf); + + /* + * 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; + + return reg; +} + +static inline u16 volts_from_reg(u16 vdd, u16 val) +{ + if (val == 0) + return 0; + + val = val * MCP3021_OUTPUT_SCALE - MCP3021_OUTPUT_SCALE / 2; + + return val * DIV_ROUND_CLOSEST(vdd, + (1 << MCP3021_OUTPUT_RES) * MCP3021_OUTPUT_SCALE); +} + +static ssize_t show_in_input(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct mcp3021_data *data = i2c_get_clientdata(client); + int reg, in_input; + + reg = mcp3021_read16(client); + if (reg < 0) + return reg; + + in_input = volts_from_reg(data->vdd, reg); + return sprintf(buf, "%d\n", in_input); +} + +static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input, NULL); + +static int mcp3021_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + struct mcp3021_data *data = NULL; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + data = kzalloc(sizeof(struct mcp3021_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + + 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; + } + } else + data->vdd = MCP3021_VDD_REF; + + err = sysfs_create_file(&client->dev.kobj, &dev_attr_in0_input.attr); + if (err) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + return 0; + +exit_remove: + sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr); +exit_free: + kfree(data); + return err; +} + +static int mcp3021_remove(struct i2c_client *client) +{ + struct mcp3021_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr); + kfree(data); + + return 0; +} + +static const struct i2c_device_id mcp3021_id[] = { + { "mcp3021", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp3021_id); + +static struct i2c_driver mcp3021_driver = { + .driver = { + .name = "mcp3021", + }, + .probe = mcp3021_probe, + .remove = mcp3021_remove, + .id_table = mcp3021_id, +}; + +module_i2c_driver(mcp3021_driver); + +MODULE_AUTHOR("Mingkai Hu <Mingkai.hu@freescale.com>"); +MODULE_DESCRIPTION("Microchip MCP3021 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 3d99b8854d7c..79ba48c8c116 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -56,11 +56,11 @@ static u8 confreg[4]; static int init = 1; module_param(init, int, 0); MODULE_PARM_DESC(init, - "Chip initialization level:\n" - " 0: None\n" - "*1: Forcibly enable internal voltage and temperature channels, except in9\n" - " 2: Forcibly enable all voltage and temperature channels, except in9\n" - " 3: Forcibly enable all voltage and temperature channels, including in9"); +"Chip initialization level:\n" +" 0: None\n" +"*1: Forcibly enable internal voltage and temperature channels, except in9\n" +" 2: Forcibly enable all voltage and temperature channels, except in9\n" +" 3: Forcibly enable all voltage and temperature channels, including in9"); static unsigned short force_id; module_param(force_id, ushort, 0); @@ -88,19 +88,19 @@ static const u8 logdev[LDNI_MAX] = { FSCM, VLM, TMS }; static inline void superio_outb(int sioaddr, int reg, int val) { outb(reg, sioaddr); - outb(val, sioaddr+1); + outb(val, sioaddr + 1); } static inline int superio_inb(int sioaddr, int reg) { outb(reg, sioaddr); - return inb(sioaddr+1); + return inb(sioaddr + 1); } static inline void superio_exit(int sioaddr) { outb(0x02, sioaddr); - outb(0x02, sioaddr+1); + outb(0x02, sioaddr + 1); } /* @@ -122,18 +122,18 @@ static inline void superio_exit(int sioaddr) #define PC87360_REG_FAN(nr) (0x07 + 3 * (nr)) #define PC87360_REG_FAN_STATUS(nr) (0x08 + 3 * (nr)) -#define FAN_FROM_REG(val,div) ((val) == 0 ? 0: \ - 480000 / ((val)*(div))) -#define FAN_TO_REG(val,div) ((val) <= 100 ? 0 : \ - 480000 / ((val)*(div))) -#define FAN_DIV_FROM_REG(val) (1 << ((val >> 5) & 0x03)) +#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : \ + 480000 / ((val) * (div))) +#define FAN_TO_REG(val, div) ((val) <= 100 ? 0 : \ + 480000 / ((val) * (div))) +#define FAN_DIV_FROM_REG(val) (1 << (((val) >> 5) & 0x03)) #define FAN_STATUS_FROM_REG(val) ((val) & 0x07) -#define FAN_CONFIG_MONITOR(val,nr) (((val) >> (2 + nr * 3)) & 1) -#define FAN_CONFIG_CONTROL(val,nr) (((val) >> (3 + nr * 3)) & 1) -#define FAN_CONFIG_INVERT(val,nr) (((val) >> (4 + nr * 3)) & 1) +#define FAN_CONFIG_MONITOR(val, nr) (((val) >> (2 + (nr) * 3)) & 1) +#define FAN_CONFIG_CONTROL(val, nr) (((val) >> (3 + (nr) * 3)) & 1) +#define FAN_CONFIG_INVERT(val, nr) (((val) >> (4 + (nr) * 3)) & 1) -#define PWM_FROM_REG(val,inv) ((inv) ? 255 - (val) : (val)) +#define PWM_FROM_REG(val, inv) ((inv) ? 255 - (val) : (val)) static inline u8 PWM_TO_REG(int val, int inv) { if (inv) @@ -159,10 +159,10 @@ static inline u8 PWM_TO_REG(int val, int inv) #define PC87365_REG_IN_ALARMS2 0x01 #define PC87365_REG_VID 0x06 -#define IN_FROM_REG(val,ref) (((val) * (ref) + 128) / 256) -#define IN_TO_REG(val,ref) ((val) < 0 ? 0 : \ - (val)*256 >= (ref)*255 ? 255: \ - ((val) * 256 + (ref)/2) / (ref)) +#define IN_FROM_REG(val, ref) (((val) * (ref) + 128) / 256) +#define IN_TO_REG(val, ref) ((val) < 0 ? 0 : \ + (val) * 256 >= (ref) * 255 ? 255 : \ + ((val) * 256 + (ref) / 2) / (ref)) /* * Temperature registers and conversions @@ -255,43 +255,54 @@ static struct platform_driver pc87360_driver = { * Sysfs stuff */ -static ssize_t show_fan_input(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_fan_input(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[attr->index], FAN_DIV_FROM_REG(data->fan_status[attr->index]))); } -static ssize_t show_fan_min(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_fan_min(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[attr->index], FAN_DIV_FROM_REG(data->fan_status[attr->index]))); } -static ssize_t show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_fan_div(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", FAN_DIV_FROM_REG(data->fan_status[attr->index])); } -static ssize_t show_fan_status(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_fan_status(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", FAN_STATUS_FROM_REG(data->fan_status[attr->index])); } -static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, const char *buf, +static ssize_t set_fan_min(struct device *dev, + struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long fan_min = simple_strtol(buf, NULL, 10); + long fan_min; + int err; + + err = kstrtol(buf, 10, &fan_min); + if (err) + return err; mutex_lock(&data->update_lock); - fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index])); + fan_min = FAN_TO_REG(fan_min, + FAN_DIV_FROM_REG(data->fan_status[attr->index])); /* If it wouldn't fit, change clock divisor */ while (fan_min > 255 @@ -301,11 +312,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, data->fan_status[attr->index] += 0x20; } data->fan_min[attr->index] = fan_min > 255 ? 255 : fan_min; - pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(attr->index), + pc87360_write_value(data, LD_FAN, NO_BANK, + PC87360_REG_FAN_MIN(attr->index), data->fan_min[attr->index]); /* Write new divider, preserve alarm bits */ - pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index), + pc87360_write_value(data, LD_FAN, NO_BANK, + PC87360_REG_FAN_STATUS(attr->index), data->fan_status[attr->index] & 0xF9); mutex_unlock(&data->update_lock); @@ -333,13 +346,16 @@ static struct sensor_device_attribute fan_min[] = { SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2), }; -#define FAN_UNIT_ATTRS(X) \ - &fan_input[X].dev_attr.attr, \ +#define FAN_UNIT_ATTRS(X) \ +{ &fan_input[X].dev_attr.attr, \ &fan_status[X].dev_attr.attr, \ &fan_div[X].dev_attr.attr, \ - &fan_min[X].dev_attr.attr + &fan_min[X].dev_attr.attr, \ + NULL \ +} -static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); @@ -348,12 +364,17 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, ch FAN_CONFIG_INVERT(data->fan_conf, attr->index))); } -static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm[attr->index] = PWM_TO_REG(val, @@ -370,52 +391,60 @@ static struct sensor_device_attribute pwm[] = { SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2), }; -static struct attribute * pc8736x_fan_attr_array[] = { +static struct attribute *pc8736x_fan_attr[][5] = { FAN_UNIT_ATTRS(0), FAN_UNIT_ATTRS(1), - FAN_UNIT_ATTRS(2), - &pwm[0].dev_attr.attr, - &pwm[1].dev_attr.attr, - &pwm[2].dev_attr.attr, - NULL + FAN_UNIT_ATTRS(2) }; -static const struct attribute_group pc8736x_fan_group = { - .attrs = pc8736x_fan_attr_array, + +static const struct attribute_group pc8736x_fan_attr_group[] = { + { .attrs = pc8736x_fan_attr[0], }, + { .attrs = pc8736x_fan_attr[1], }, + { .attrs = pc8736x_fan_attr[2], }, }; -static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_in_input(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index], data->in_vref)); } -static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_in_min(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index], data->in_vref)); } -static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_in_max(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index], data->in_vref)); } -static ssize_t show_in_status(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_in_status(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", data->in_status[attr->index]); } -static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) +static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); @@ -424,12 +453,17 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, mutex_unlock(&data->update_lock); return count; } -static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) +static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[attr->index] = IN_TO_REG(val, @@ -498,9 +532,11 @@ static struct sensor_device_attribute in_max[] = { #define CHAN_ALM_MAX 0x04 /* max limit exceeded */ #define TEMP_ALM_CRIT 0x08 /* temp crit exceeded (temp only) */ -/* show_in_min/max_alarm() reads data from the per-channel status - register (sec 11.5.12), not the vin event status registers (sec - 11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) */ +/* + * show_in_min/max_alarm() reads data from the per-channel status + * register (sec 11.5.12), not the vin event status registers (sec + * 11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) + */ static ssize_t show_in_min_alarm(struct device *dev, struct device_attribute *devattr, char *buf) @@ -554,27 +590,38 @@ static struct sensor_device_attribute in_max_alarm[] = { &in_min_alarm[X].dev_attr.attr, \ &in_max_alarm[X].dev_attr.attr -static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vid(struct device *dev, struct device_attribute *attr, + char *buf) { struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); } static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); -static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, + char *buf) { struct pc87360_data *data = dev_get_drvdata(dev); return sprintf(buf, "%u\n", data->vrm); } -static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct pc87360_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + data->vrm = val; return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); -static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_in_alarms(struct device *dev, + struct device_attribute *attr, char *buf) { struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", data->in_alarms); @@ -602,46 +649,58 @@ static const struct attribute_group pc8736x_vin_group = { .attrs = pc8736x_vin_attr_array, }; -static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_therm_input(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index], data->in_vref)); } -static ssize_t show_therm_min(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_therm_min(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index], data->in_vref)); } -static ssize_t show_therm_max(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_therm_max(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index], data->in_vref)); } -static ssize_t show_therm_crit(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_therm_crit(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[attr->index-11], data->in_vref)); } -static ssize_t show_therm_status(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_therm_status(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", data->in_status[attr->index]); } -static ssize_t set_therm_min(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) + +static ssize_t set_therm_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); @@ -650,12 +709,19 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt mutex_unlock(&data->update_lock); return count; } -static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) + +static ssize_t set_therm_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[attr->index] = IN_TO_REG(val, data->in_vref); @@ -664,12 +730,18 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt mutex_unlock(&data->update_lock); return count; } -static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) +static ssize_t set_therm_crit(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref); @@ -679,46 +751,49 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat return count; } -/* the +11 term below reflects the fact that VLM units 11,12,13 are - used in the chip to measure voltage across the thermistors -*/ +/* + * the +11 term below reflects the fact that VLM units 11,12,13 are + * used in the chip to measure voltage across the thermistors + */ static struct sensor_device_attribute therm_input[] = { - SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0+11), - SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1+11), - SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2+11), + SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0 + 11), + SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1 + 11), + SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2 + 11), }; static struct sensor_device_attribute therm_status[] = { - SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0+11), - SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1+11), - SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2+11), + SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0 + 11), + SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1 + 11), + SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2 + 11), }; static struct sensor_device_attribute therm_min[] = { SENSOR_ATTR(temp4_min, S_IRUGO | S_IWUSR, - show_therm_min, set_therm_min, 0+11), + show_therm_min, set_therm_min, 0 + 11), SENSOR_ATTR(temp5_min, S_IRUGO | S_IWUSR, - show_therm_min, set_therm_min, 1+11), + show_therm_min, set_therm_min, 1 + 11), SENSOR_ATTR(temp6_min, S_IRUGO | S_IWUSR, - show_therm_min, set_therm_min, 2+11), + show_therm_min, set_therm_min, 2 + 11), }; static struct sensor_device_attribute therm_max[] = { SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR, - show_therm_max, set_therm_max, 0+11), + show_therm_max, set_therm_max, 0 + 11), SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR, - show_therm_max, set_therm_max, 1+11), + show_therm_max, set_therm_max, 1 + 11), SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR, - show_therm_max, set_therm_max, 2+11), + show_therm_max, set_therm_max, 2 + 11), }; static struct sensor_device_attribute therm_crit[] = { SENSOR_ATTR(temp4_crit, S_IRUGO | S_IWUSR, - show_therm_crit, set_therm_crit, 0+11), + show_therm_crit, set_therm_crit, 0 + 11), SENSOR_ATTR(temp5_crit, S_IRUGO | S_IWUSR, - show_therm_crit, set_therm_crit, 1+11), + show_therm_crit, set_therm_crit, 1 + 11), SENSOR_ATTR(temp6_crit, S_IRUGO | S_IWUSR, - show_therm_crit, set_therm_crit, 2+11), + show_therm_crit, set_therm_crit, 2 + 11), }; -/* show_therm_min/max_alarm() reads data from the per-channel voltage - status register (sec 11.5.12) */ +/* + * show_therm_min/max_alarm() reads data from the per-channel voltage + * status register (sec 11.5.12) + */ static ssize_t show_therm_min_alarm(struct device *dev, struct device_attribute *devattr, char *buf) @@ -747,27 +822,27 @@ static ssize_t show_therm_crit_alarm(struct device *dev, static struct sensor_device_attribute therm_min_alarm[] = { SENSOR_ATTR(temp4_min_alarm, S_IRUGO, - show_therm_min_alarm, NULL, 0+11), + show_therm_min_alarm, NULL, 0 + 11), SENSOR_ATTR(temp5_min_alarm, S_IRUGO, - show_therm_min_alarm, NULL, 1+11), + show_therm_min_alarm, NULL, 1 + 11), SENSOR_ATTR(temp6_min_alarm, S_IRUGO, - show_therm_min_alarm, NULL, 2+11), + show_therm_min_alarm, NULL, 2 + 11), }; static struct sensor_device_attribute therm_max_alarm[] = { SENSOR_ATTR(temp4_max_alarm, S_IRUGO, - show_therm_max_alarm, NULL, 0+11), + show_therm_max_alarm, NULL, 0 + 11), SENSOR_ATTR(temp5_max_alarm, S_IRUGO, - show_therm_max_alarm, NULL, 1+11), + show_therm_max_alarm, NULL, 1 + 11), SENSOR_ATTR(temp6_max_alarm, S_IRUGO, - show_therm_max_alarm, NULL, 2+11), + show_therm_max_alarm, NULL, 2 + 11), }; static struct sensor_device_attribute therm_crit_alarm[] = { SENSOR_ATTR(temp4_crit_alarm, S_IRUGO, - show_therm_crit_alarm, NULL, 0+11), + show_therm_crit_alarm, NULL, 0 + 11), SENSOR_ATTR(temp5_crit_alarm, S_IRUGO, - show_therm_crit_alarm, NULL, 1+11), + show_therm_crit_alarm, NULL, 1 + 11), SENSOR_ATTR(temp6_crit_alarm, S_IRUGO, - show_therm_crit_alarm, NULL, 2+11), + show_therm_crit_alarm, NULL, 2 + 11), }; #define THERM_UNIT_ATTRS(X) \ @@ -780,7 +855,7 @@ static struct sensor_device_attribute therm_crit_alarm[] = { &therm_max_alarm[X].dev_attr.attr, \ &therm_crit_alarm[X].dev_attr.attr -static struct attribute * pc8736x_therm_attr_array[] = { +static struct attribute *pc8736x_therm_attr_array[] = { THERM_UNIT_ATTRS(0), THERM_UNIT_ATTRS(1), THERM_UNIT_ATTRS(2), @@ -790,42 +865,59 @@ static const struct attribute_group pc8736x_therm_group = { .attrs = pc8736x_therm_attr_array, }; -static ssize_t show_temp_input(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_temp_input(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])); } -static ssize_t show_temp_min(struct device *dev, struct device_attribute *devattr, char *buf) + +static ssize_t show_temp_min(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[attr->index])); } -static ssize_t show_temp_max(struct device *dev, struct device_attribute *devattr, char *buf) + +static ssize_t show_temp_max(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[attr->index])); } -static ssize_t show_temp_crit(struct device *dev, struct device_attribute *devattr, char *buf) + +static ssize_t show_temp_crit(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[attr->index])); + return sprintf(buf, "%d\n", + TEMP_FROM_REG(data->temp_crit[attr->index])); } -static ssize_t show_temp_status(struct device *dev, struct device_attribute *devattr, char *buf) + +static ssize_t show_temp_status(struct device *dev, + struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%d\n", data->temp_status[attr->index]); } -static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) + +static ssize_t set_temp_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[attr->index] = TEMP_TO_REG(val); @@ -834,12 +926,19 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr mutex_unlock(&data->update_lock); return count; } -static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) + +static ssize_t set_temp_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[attr->index] = TEMP_TO_REG(val); @@ -848,12 +947,19 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr mutex_unlock(&data->update_lock); return count; } -static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, - size_t count) + +static ssize_t set_temp_crit(struct device *dev, + struct device_attribute *devattr, const char *buf, + size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct pc87360_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_crit[attr->index] = TEMP_TO_REG(val); @@ -898,16 +1004,20 @@ static struct sensor_device_attribute temp_crit[] = { show_temp_crit, set_temp_crit, 2), }; -static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_alarms(struct device *dev, + struct device_attribute *attr, char *buf) { struct pc87360_data *data = pc87360_update_device(dev); return sprintf(buf, "%u\n", data->temp_alarms); } + static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); -/* show_temp_min/max_alarm() reads data from the per-channel status - register (sec 12.3.7), not the temp event status registers (sec - 12.3.2) that show_temp_alarm() reads (via data->temp_alarms) */ +/* + * show_temp_min/max_alarm() reads data from the per-channel status + * register (sec 12.3.7), not the temp event status registers (sec + * 12.3.2) that show_temp_alarm() reads (via data->temp_alarms) + */ static ssize_t show_temp_min_alarm(struct device *dev, struct device_attribute *devattr, char *buf) @@ -917,6 +1027,7 @@ static ssize_t show_temp_min_alarm(struct device *dev, return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MIN)); } + static ssize_t show_temp_max_alarm(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -925,6 +1036,7 @@ static ssize_t show_temp_max_alarm(struct device *dev, return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MAX)); } + static ssize_t show_temp_crit_alarm(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -939,11 +1051,13 @@ static struct sensor_device_attribute temp_min_alarm[] = { SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 1), SENSOR_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 2), }; + static struct sensor_device_attribute temp_max_alarm[] = { SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 0), SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 1), SENSOR_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 2), }; + static struct sensor_device_attribute temp_crit_alarm[] = { SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 0), SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 1), @@ -965,27 +1079,29 @@ static struct sensor_device_attribute temp_fault[] = { SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2), }; -#define TEMP_UNIT_ATTRS(X) \ - &temp_input[X].dev_attr.attr, \ - &temp_status[X].dev_attr.attr, \ - &temp_min[X].dev_attr.attr, \ - &temp_max[X].dev_attr.attr, \ - &temp_crit[X].dev_attr.attr, \ - &temp_min_alarm[X].dev_attr.attr, \ - &temp_max_alarm[X].dev_attr.attr, \ - &temp_crit_alarm[X].dev_attr.attr, \ - &temp_fault[X].dev_attr.attr - -static struct attribute * pc8736x_temp_attr_array[] = { +#define TEMP_UNIT_ATTRS(X) \ +{ &temp_input[X].dev_attr.attr, \ + &temp_status[X].dev_attr.attr, \ + &temp_min[X].dev_attr.attr, \ + &temp_max[X].dev_attr.attr, \ + &temp_crit[X].dev_attr.attr, \ + &temp_min_alarm[X].dev_attr.attr, \ + &temp_max_alarm[X].dev_attr.attr, \ + &temp_crit_alarm[X].dev_attr.attr, \ + &temp_fault[X].dev_attr.attr, \ + NULL \ +} + +static struct attribute *pc8736x_temp_attr[][10] = { TEMP_UNIT_ATTRS(0), TEMP_UNIT_ATTRS(1), - TEMP_UNIT_ATTRS(2), - /* include the few miscellaneous atts here */ - &dev_attr_alarms_temp.attr, - NULL + TEMP_UNIT_ATTRS(2) }; -static const struct attribute_group pc8736x_temp_group = { - .attrs = pc8736x_temp_attr_array, + +static const struct attribute_group pc8736x_temp_attr_group[] = { + { .attrs = pc8736x_temp_attr[0] }, + { .attrs = pc8736x_temp_attr[1] }, + { .attrs = pc8736x_temp_attr[2] } }; static ssize_t show_name(struct device *dev, @@ -994,13 +1110,15 @@ static ssize_t show_name(struct device *dev, struct pc87360_data *data = dev_get_drvdata(dev); return sprintf(buf, "%s\n", data->name); } + static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); /* * Device detection, registration and update */ -static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses) +static int __init pc87360_find(int sioaddr, u8 *devid, + unsigned short *addresses) { u16 val; int i; @@ -1047,7 +1165,7 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses addresses[i] = val; - if (i==0) { /* Fans */ + if (i == 0) { /* Fans */ confreg[0] = superio_inb(sioaddr, 0xF0); confreg[1] = superio_inb(sioaddr, 0xF1); @@ -1060,12 +1178,14 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 3, confreg[1] & 1, (confreg[1] >> 1) & 1, (confreg[1] >> 2) & 1); - } else if (i==1) { /* Voltages */ + } else if (i == 1) { /* Voltages */ /* Are we using thermistors? */ if (*devid == 0xE9) { /* PC87366 */ - /* These registers are not logical-device - specific, just that we won't need them if - we don't use the VLM device */ + /* + * These registers are not logical-device + * specific, just that we won't need them if + * we don't use the VLM device + */ confreg[2] = superio_inb(sioaddr, 0x2B); confreg[3] = superio_inb(sioaddr, 0x25); @@ -1085,6 +1205,22 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses return 0; } +static void pc87360_remove_files(struct device *dev) +{ + int i; + + device_remove_file(dev, &dev_attr_name); + device_remove_file(dev, &dev_attr_alarms_temp); + for (i = 0; i < ARRAY_SIZE(pc8736x_temp_attr_group); i++) + sysfs_remove_group(&dev->kobj, &pc8736x_temp_attr_group[i]); + for (i = 0; i < ARRAY_SIZE(pc8736x_fan_attr_group); i++) { + sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_attr_group[i]); + device_remove_file(dev, &pwm[i].dev_attr); + } + sysfs_remove_group(&dev->kobj, &pc8736x_therm_group); + sysfs_remove_group(&dev->kobj, &pc8736x_vin_group); +} + static int __devinit pc87360_probe(struct platform_device *pdev) { int i; @@ -1094,7 +1230,8 @@ static int __devinit pc87360_probe(struct platform_device *pdev) int use_thermistors = 0; struct device *dev = &pdev->dev; - if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) + data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL); + if (!data) return -ENOMEM; data->fannr = 2; @@ -1130,9 +1267,10 @@ static int __devinit pc87360_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); for (i = 0; i < LDNI_MAX; i++) { - if (((data->address[i] = extra_isa[i])) + data->address[i] = extra_isa[i]; + if (data->address[i] && !request_region(extra_isa[i], PC87360_EXTENT, - pc87360_driver.driver.name)) { + pc87360_driver.driver.name)) { dev_err(dev, "Region 0x%x-0x%x already " "in use!\n", extra_isa[i], extra_isa[i]+PC87360_EXTENT-1); @@ -1147,9 +1285,11 @@ static int __devinit pc87360_probe(struct platform_device *pdev) if (data->fannr) data->fan_conf = confreg[0] | (confreg[1] << 8); - /* Use the correct reference voltage - Unless both the VLM and the TMS logical devices agree to - use an external Vref, the internal one is used. */ + /* + * Use the correct reference voltage + * Unless both the VLM and the TMS logical devices agree to + * use an external Vref, the internal one is used. + */ if (data->innr) { i = pc87360_read_value(data, LD_IN, NO_BANK, PC87365_REG_IN_CONFIG); @@ -1182,62 +1322,48 @@ static int __devinit pc87360_probe(struct platform_device *pdev) /* Register all-or-nothing sysfs groups */ - if (data->innr && - (err = sysfs_create_group(&dev->kobj, - &pc8736x_vin_group))) - goto ERROR3; + if (data->innr) { + err = sysfs_create_group(&dev->kobj, &pc8736x_vin_group); + if (err) + goto ERROR3; + } - if (data->innr == 14 && - (err = sysfs_create_group(&dev->kobj, - &pc8736x_therm_group))) - goto ERROR3; + if (data->innr == 14) { + err = sysfs_create_group(&dev->kobj, &pc8736x_therm_group); + if (err) + goto ERROR3; + } /* create device attr-files for varying sysfs groups */ if (data->tempnr) { for (i = 0; i < data->tempnr; i++) { - if ((err = device_create_file(dev, - &temp_input[i].dev_attr)) - || (err = device_create_file(dev, - &temp_min[i].dev_attr)) - || (err = device_create_file(dev, - &temp_max[i].dev_attr)) - || (err = device_create_file(dev, - &temp_crit[i].dev_attr)) - || (err = device_create_file(dev, - &temp_status[i].dev_attr)) - || (err = device_create_file(dev, - &temp_min_alarm[i].dev_attr)) - || (err = device_create_file(dev, - &temp_max_alarm[i].dev_attr)) - || (err = device_create_file(dev, - &temp_crit_alarm[i].dev_attr)) - || (err = device_create_file(dev, - &temp_fault[i].dev_attr))) + err = sysfs_create_group(&dev->kobj, + &pc8736x_temp_attr_group[i]); + if (err) goto ERROR3; } - if ((err = device_create_file(dev, &dev_attr_alarms_temp))) + err = device_create_file(dev, &dev_attr_alarms_temp); + if (err) goto ERROR3; } for (i = 0; i < data->fannr; i++) { - if (FAN_CONFIG_MONITOR(data->fan_conf, i) - && ((err = device_create_file(dev, - &fan_input[i].dev_attr)) - || (err = device_create_file(dev, - &fan_min[i].dev_attr)) - || (err = device_create_file(dev, - &fan_div[i].dev_attr)) - || (err = device_create_file(dev, - &fan_status[i].dev_attr)))) - goto ERROR3; - - if (FAN_CONFIG_CONTROL(data->fan_conf, i) - && (err = device_create_file(dev, &pwm[i].dev_attr))) - goto ERROR3; + if (FAN_CONFIG_MONITOR(data->fan_conf, i)) { + err = sysfs_create_group(&dev->kobj, + &pc8736x_fan_attr_group[i]); + if (err) + goto ERROR3; + } + if (FAN_CONFIG_CONTROL(data->fan_conf, i)) { + err = device_create_file(dev, &pwm[i].dev_attr); + if (err) + goto ERROR3; + } } - if ((err = device_create_file(dev, &dev_attr_name))) + err = device_create_file(dev, &dev_attr_name); + if (err) goto ERROR3; data->hwmon_dev = hwmon_device_register(dev); @@ -1248,16 +1374,10 @@ static int __devinit pc87360_probe(struct platform_device *pdev) return 0; ERROR3: - device_remove_file(dev, &dev_attr_name); - /* can still remove groups whose members were added individually */ - sysfs_remove_group(&dev->kobj, &pc8736x_temp_group); - sysfs_remove_group(&dev->kobj, &pc8736x_fan_group); - sysfs_remove_group(&dev->kobj, &pc8736x_therm_group); - sysfs_remove_group(&dev->kobj, &pc8736x_vin_group); + pc87360_remove_files(dev); for (i = 0; i < 3; i++) { - if (data->address[i]) { + if (data->address[i]) release_region(data->address[i], PC87360_EXTENT); - } } ERROR1: kfree(data); @@ -1270,25 +1390,20 @@ static int __devexit pc87360_remove(struct platform_device *pdev) int i; hwmon_device_unregister(data->hwmon_dev); - - device_remove_file(&pdev->dev, &dev_attr_name); - sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); - sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_group); - sysfs_remove_group(&pdev->dev.kobj, &pc8736x_therm_group); - sysfs_remove_group(&pdev->dev.kobj, &pc8736x_vin_group); - + pc87360_remove_files(&pdev->dev); for (i = 0; i < 3; i++) { - if (data->address[i]) { + if (data->address[i]) release_region(data->address[i], PC87360_EXTENT); - } } kfree(data); return 0; } -/* ldi is the logical device index - bank is for voltages and temperatures only */ +/* + * ldi is the logical device index + * bank is for voltages and temperatures only + */ static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, u8 reg) { @@ -1359,8 +1474,10 @@ static void pc87360_init_device(struct platform_device *pdev, } } - /* We can't blindly trust the Super-I/O space configuration bit, - most BIOS won't set it properly */ + /* + * We can't blindly trust the Super-I/O space configuration bit, + * most BIOS won't set it properly + */ dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors); for (i = 11; i < data->innr; i++) { reg = pc87360_read_value(data, LD_IN, i, @@ -1375,12 +1492,12 @@ static void pc87360_init_device(struct platform_device *pdev, for (; i < data->tempnr; i++) { reg = pc87360_read_value(data, LD_TEMP, i, PC87365_REG_TEMP_STATUS); - dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg); + dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i + 1, reg); if (init >= init_temp[i]) { /* Forcibly enable temperature channel */ if (!(reg & CHAN_ENA)) { - dev_dbg(&pdev->dev, "Forcibly " - "enabling temp%d\n", i+1); + dev_dbg(&pdev->dev, + "Forcibly enabling temp%d\n", i + 1); pc87360_write_value(data, LD_TEMP, i, PC87365_REG_TEMP_STATUS, 0xCF); @@ -1391,14 +1508,16 @@ static void pc87360_init_device(struct platform_device *pdev, if (use_thermistors) { for (i = 11; i < data->innr; i++) { if (init >= init_in[i]) { - /* The pin may already be used by thermal - diodes */ + /* + * The pin may already be used by thermal + * diodes + */ reg = pc87360_read_value(data, LD_TEMP, - (i-11)/2, PC87365_REG_TEMP_STATUS); + (i - 11) / 2, PC87365_REG_TEMP_STATUS); if (reg & CHAN_ENA) { - dev_dbg(&pdev->dev, "Skipping " - "temp%d, pin already in use " - "by temp%d\n", i-7, (i-11)/2); + dev_dbg(&pdev->dev, + "Skipping temp%d, pin already in use by temp%d\n", + i - 7, (i - 11) / 2); continue; } @@ -1406,8 +1525,9 @@ static void pc87360_init_device(struct platform_device *pdev, reg = pc87360_read_value(data, LD_IN, i, PC87365_REG_IN_STATUS); if (!(reg & CHAN_ENA)) { - dev_dbg(&pdev->dev, "Forcibly " - "enabling temp%d\n", i-7); + dev_dbg(&pdev->dev, + "Forcibly enabling temp%d\n", + i - 7); pc87360_write_value(data, LD_IN, i, PC87365_REG_TEMP_STATUS, (reg & 0x60) | 0x8F); @@ -1421,8 +1541,8 @@ static void pc87360_init_device(struct platform_device *pdev, PC87365_REG_IN_CONFIG); dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg); if (reg & CHAN_ENA) { - dev_dbg(&pdev->dev, "Forcibly " - "enabling monitoring (VLM)\n"); + dev_dbg(&pdev->dev, + "Forcibly enabling monitoring (VLM)\n"); pc87360_write_value(data, LD_IN, NO_BANK, PC87365_REG_IN_CONFIG, reg & 0xFE); @@ -1434,8 +1554,8 @@ static void pc87360_init_device(struct platform_device *pdev, PC87365_REG_TEMP_CONFIG); dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg); if (reg & CHAN_ENA) { - dev_dbg(&pdev->dev, "Forcibly enabling " - "monitoring (TMS)\n"); + dev_dbg(&pdev->dev, + "Forcibly enabling monitoring (TMS)\n"); pc87360_write_value(data, LD_TEMP, NO_BANK, PC87365_REG_TEMP_CONFIG, reg & 0xFE); @@ -1444,10 +1564,12 @@ static void pc87360_init_device(struct platform_device *pdev, if (init >= 2) { /* Chip config as documented by National Semi. */ pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08); - /* We voluntarily omit the bank here, in case the - sequence itself matters. It shouldn't be a problem, - since nobody else is supposed to access the - device at that point. */ + /* + * We voluntarily omit the bank here, in case the + * sequence itself matters. It shouldn't be a problem, + * since nobody else is supposed to access the + * device at that point. + */ pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04); pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35); pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05); @@ -1470,7 +1592,7 @@ static void pc87360_autodiv(struct device *dev, int nr) data->fan[nr] >>= 1; dev_dbg(dev, "Increasing " "clock divider to %d for fan %d\n", - FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1); + FAN_DIV_FROM_REG(data->fan_status[nr]), nr + 1); } } else { /* Decrease clock divider if possible */ @@ -1483,7 +1605,7 @@ static void pc87360_autodiv(struct device *dev, int nr) dev_dbg(dev, "Decreasing " "clock divider to %d for fan %d\n", FAN_DIV_FROM_REG(data->fan_status[nr]), - nr+1); + nr + 1); } } diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index cb35461d52d9..37059a3755e9 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -46,9 +46,11 @@ static struct platform_device *pdev; #define DRVNAME "pc87427" -/* The lock mutex protects both the I/O accesses (needed because the - device is using banked registers) and the register cache (needed to keep - the data in the registers and the cache in sync at any time). */ +/* + * The lock mutex protects both the I/O accesses (needed because the + * device is using banked registers) and the register cache (needed to keep + * the data in the registers and the cache in sync at any time). + */ struct pc87427_data { struct device *hwmon_dev; struct mutex lock; @@ -173,10 +175,12 @@ static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi, #define FAN_STATUS_LOSPD (1 << 1) #define FAN_STATUS_MONEN (1 << 0) -/* Dedicated function to read all registers related to a given fan input. - This saves us quite a few locks and bank selections. - Must be called with data->lock held. - nr is from 0 to 7 */ +/* + * Dedicated function to read all registers related to a given fan input. + * This saves us quite a few locks and bank selections. + * Must be called with data->lock held. + * nr is from 0 to 7 + */ static void pc87427_readall_fan(struct pc87427_data *data, u8 nr) { int iobase = data->address[LD_FAN]; @@ -189,8 +193,10 @@ static void pc87427_readall_fan(struct pc87427_data *data, u8 nr) outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS); } -/* The 2 LSB of fan speed registers are used for something different. - The actual 2 LSB of the measurements are not available. */ +/* + * The 2 LSB of fan speed registers are used for something different. + * The actual 2 LSB of the measurements are not available. + */ static inline unsigned long fan_from_reg(u16 reg) { reg &= 0xfffc; @@ -224,10 +230,12 @@ static inline u16 fan_to_reg(unsigned long val) #define PWM_MODE_OFF (2 << 4) #define PWM_MODE_ON (7 << 4) -/* Dedicated function to read all registers related to a given PWM output. - This saves us quite a few locks and bank selections. - Must be called with data->lock held. - nr is from 0 to 3 */ +/* + * Dedicated function to read all registers related to a given PWM output. + * This saves us quite a few locks and bank selections. + * Must be called with data->lock held. + * nr is from 0 to 3 + */ static void pc87427_readall_pwm(struct pc87427_data *data, u8 nr) { int iobase = data->address[LD_FAN]; @@ -286,10 +294,12 @@ static inline u8 pwm_enable_to_reg(unsigned long val, u8 pwmval) #define TEMP_TYPE_REMOTE_DIODE (2 << 5) #define TEMP_TYPE_LOCAL_DIODE (3 << 5) -/* Dedicated function to read all registers related to a given temperature - input. This saves us quite a few locks and bank selections. - Must be called with data->lock held. - nr is from 0 to 5 */ +/* + * Dedicated function to read all registers related to a given temperature + * input. This saves us quite a few locks and bank selections. + * Must be called with data->lock held. + * nr is from 0 to 5 + */ static void pc87427_readall_temp(struct pc87427_data *data, u8 nr) { int iobase = data->address[LD_TEMP]; @@ -318,8 +328,10 @@ static inline unsigned int temp_type_from_reg(u8 reg) } } -/* We assume 8-bit thermal sensors; 9-bit thermal sensors are possible - too, but I have no idea how to figure out when they are used. */ +/* + * We assume 8-bit thermal sensors; 9-bit thermal sensors are possible + * too, but I have no idea how to figure out when they are used. + */ static inline long temp_from_reg(s16 reg) { return reg * 1000 / 256; @@ -423,9 +435,11 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute mutex_lock(&data->lock); outb(BANK_FM(nr), iobase + PC87427_REG_BANK); - /* The low speed limit registers are read-only while monitoring - is enabled, so we have to disable monitoring, then change the - limit, and finally enable monitoring again. */ + /* + * The low speed limit registers are read-only while monitoring + * is enabled, so we have to disable monitoring, then change the + * limit, and finally enable monitoring again. + */ outb(0, iobase + PC87427_REG_FAN_STATUS); data->fan_min[nr] = fan_to_reg(val); outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN); @@ -542,8 +556,10 @@ static const struct attribute_group pc87427_group_fan[8] = { { .attrs = pc87427_attributes_fan[7] }, }; -/* Must be called with data->lock held and pc87427_readall_pwm() freshly - called */ +/* + * Must be called with data->lock held and pc87427_readall_pwm() freshly + * called + */ static void update_pwm_enable(struct pc87427_data *data, int nr, u8 mode) { int iobase = data->address[LD_FAN]; @@ -1023,9 +1039,11 @@ static void __devinit pc87427_init_device(struct device *dev) if (reg & PWM_ENABLE_CTLEN) data->pwm_enabled |= (1 << i); - /* We don't expose an interface to reconfigure the automatic - fan control mode, so only allow to return to this mode if - it was originally set. */ + /* + * We don't expose an interface to reconfigure the automatic + * fan control mode, so only allow to return to this mode if + * it was originally set. + */ if ((reg & PWM_ENABLE_MODE_MASK) == PWM_MODE_AUTO) { dev_dbg(dev, "PWM%d is in automatic control mode\n", i + 1); diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c index 731b09af76b9..4174c7463d70 100644 --- a/drivers/hwmon/pcf8591.c +++ b/drivers/hwmon/pcf8591.c @@ -1,22 +1,22 @@ /* - Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net> - Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with - the help of Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net> + * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with + * the help of Jean Delvare <khali@linux-fr.org> + * + * 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. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -39,28 +39,34 @@ MODULE_PARM_DESC(input_mode, " 2 = single ended and differential mixed\n" " 3 = two differential inputs\n"); -/* The PCF8591 control byte - 7 6 5 4 3 2 1 0 - | 0 |AOEF| AIP | 0 |AINC| AICH | */ +/* + * The PCF8591 control byte + * 7 6 5 4 3 2 1 0 + * | 0 |AOEF| AIP | 0 |AINC| AICH | + */ /* Analog Output Enable Flag (analog output active if 1) */ #define PCF8591_CONTROL_AOEF 0x40 -/* Analog Input Programming - 0x00 = four single ended inputs - 0x10 = three differential inputs - 0x20 = single ended and differential mixed - 0x30 = two differential inputs */ +/* + * Analog Input Programming + * 0x00 = four single ended inputs + * 0x10 = three differential inputs + * 0x20 = single ended and differential mixed + * 0x30 = two differential inputs + */ #define PCF8591_CONTROL_AIP_MASK 0x30 /* Autoincrement Flag (switch on if 1) */ #define PCF8591_CONTROL_AINC 0x04 -/* Channel selection - 0x00 = channel 0 - 0x01 = channel 1 - 0x02 = channel 2 - 0x03 = channel 3 */ +/* + * Channel selection + * 0x00 = channel 0 + * 0x01 = channel 1 + * 0x02 = channel 2 + * 0x03 = channel 3 + */ #define PCF8591_CONTROL_AICH_MASK 0x03 /* Initial values */ @@ -68,7 +74,7 @@ MODULE_PARM_DESC(input_mode, #define PCF8591_INIT_AOUT 0 /* DAC out = 0 */ /* Conversions */ -#define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg)) +#define REG_TO_SIGNED(reg) (((reg) & 0x80) ? ((reg) - 256) : (reg)) struct pcf8591_data { struct device *hwmon_dev; @@ -83,7 +89,9 @@ static int pcf8591_read_channel(struct device *dev, int channel); /* following are the sysfs callback functions */ #define show_in_channel(channel) \ -static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_in##channel##_input(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ { \ return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\ } \ @@ -95,39 +103,57 @@ show_in_channel(1); show_in_channel(2); show_in_channel(3); -static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_out0_ouput(struct device *dev, + struct device_attribute *attr, char *buf) { struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev)); return sprintf(buf, "%d\n", data->aout * 10); } -static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_out0_output(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { - unsigned int value; + unsigned long val; struct i2c_client *client = to_i2c_client(dev); struct pcf8591_data *data = i2c_get_clientdata(client); - if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) { - data->aout = value; - i2c_smbus_write_byte_data(client, data->control, data->aout); - return count; - } - return -EINVAL; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + val /= 10; + if (val > 255) + return -EINVAL; + + data->aout = val; + i2c_smbus_write_byte_data(client, data->control, data->aout); + return count; } static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO, show_out0_ouput, set_out0_output); -static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_out0_enable(struct device *dev, + struct device_attribute *attr, char *buf) { struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev)); return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF))); } -static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_out0_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct pcf8591_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); if (val) @@ -174,7 +200,8 @@ static int pcf8591_probe(struct i2c_client *client, struct pcf8591_data *data; int err; - if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto exit; } @@ -192,15 +219,15 @@ static int pcf8591_probe(struct i2c_client *client, /* Register input2 if not in "two differential inputs" mode */ if (input_mode != 3) { - if ((err = device_create_file(&client->dev, - &dev_attr_in2_input))) + err = device_create_file(&client->dev, &dev_attr_in2_input); + if (err) goto exit_sysfs_remove; } /* Register input3 only in "four single ended inputs" mode */ if (input_mode == 0) { - if ((err = device_create_file(&client->dev, - &dev_attr_in3_input))) + err = device_create_file(&client->dev, &dev_attr_in3_input); + if (err) goto exit_sysfs_remove; } @@ -241,8 +268,10 @@ static void pcf8591_init_client(struct i2c_client *client) i2c_smbus_write_byte_data(client, data->control, data->aout); - /* The first byte transmitted contains the conversion code of the - previous read cycle. FLUSH IT! */ + /* + * The first byte transmitted contains the conversion code of the + * previous read cycle. FLUSH IT! + */ i2c_smbus_read_byte(client); } @@ -259,8 +288,10 @@ static int pcf8591_read_channel(struct device *dev, int channel) | channel; i2c_smbus_write_byte(client, data->control); - /* The first byte transmitted contains the conversion code of - the previous read cycle. FLUSH IT! */ + /* + * The first byte transmitted contains the conversion code of + * the previous read cycle. FLUSH IT! + */ i2c_smbus_read_byte(client); } value = i2c_smbus_read_byte(client); @@ -269,9 +300,9 @@ static int pcf8591_read_channel(struct device *dev, int channel) if ((channel == 2 && input_mode == 2) || (channel != 3 && (input_mode == 1 || input_mode == 3))) - return (10 * REG_TO_SIGNED(value)); + return 10 * REG_TO_SIGNED(value); else - return (10 * value); + return 10 * value; } static const struct i2c_device_id pcf8591_id[] = { diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index cfec923f42b7..2ca6a5a4f5a7 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -20,7 +20,8 @@ config SENSORS_PMBUS help If you say yes here you get hardware monitoring support for generic PMBus devices, including but not limited to ADP4000, BMR453, BMR454, - NCP4200, and NCP4208. + MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, TPS40400, + and TPS40422. This driver can also be built as a module. If so, the module will be called pmbus. @@ -30,8 +31,8 @@ config SENSORS_ADM1275 default n help If you say yes here you get hardware monitoring support for Analog - Devices ADM1275 and ADM1276 Hot-Swap Controller and Digital Power - Monitor. + Devices ADM1075, ADM1275, and ADM1276 Hot-Swap Controller and Digital + Power Monitors. This driver can also be built as a module. If so, the module will be called adm1275. @@ -67,11 +68,11 @@ config SENSORS_MAX16064 be called max16064. config SENSORS_MAX34440 - tristate "Maxim MAX34440/MAX34441" + tristate "Maxim MAX34440 and compatibles" default n help If you say yes here you get hardware monitoring support for Maxim - MAX34440 and MAX34441. + MAX34440, MAX34441, and MAX34446. This driver can also be built as a module. If so, the module will be called max34440. @@ -113,9 +114,9 @@ config SENSORS_ZL6100 default n help If you say yes here you get hardware monitoring support for Intersil - ZL2004, ZL2005, ZL2006, ZL2008, ZL2105, ZL2106, ZL6100, and ZL6105 - Digital DC/DC Controllers, as well as for Ericsson BMR450, BMR451, - BMR462, BMR463, and BMR464. + ZL2004, ZL2005, ZL2006, ZL2008, ZL2105, ZL2106, ZL6100, ZL6105, + ZL9101M, and ZL9117M Digital DC/DC Controllers, as well as for + Ericsson BMR450, BMR451, BMR462, BMR463, and BMR464. This driver can also be built as a module. If so, the module will be called zl6100. diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 81c7c2ead6f3..60aad9570f01 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -23,7 +23,7 @@ #include <linux/i2c.h> #include "pmbus.h" -enum chips { adm1275, adm1276 }; +enum chips { adm1075, adm1275, adm1276 }; #define ADM1275_PEAK_IOUT 0xd0 #define ADM1275_PEAK_VIN 0xd1 @@ -32,6 +32,9 @@ enum chips { adm1275, adm1276 }; #define ADM1275_VIN_VOUT_SELECT (1 << 6) #define ADM1275_VRANGE (1 << 5) +#define ADM1075_IRANGE_50 (1 << 4) +#define ADM1075_IRANGE_25 (1 << 3) +#define ADM1075_IRANGE_MASK ((1 << 3) | (1 << 4)) #define ADM1275_IOUT_WARN2_LIMIT 0xd7 #define ADM1275_DEVICE_CONFIG 0xd8 @@ -42,6 +45,14 @@ enum chips { adm1275, adm1276 }; #define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0) +#define ADM1075_READ_VAUX 0xdd +#define ADM1075_VAUX_OV_WARN_LIMIT 0xde +#define ADM1075_VAUX_UV_WARN_LIMIT 0xdf +#define ADM1075_VAUX_STATUS 0xf6 + +#define ADM1075_VAUX_OV_WARN (1<<7) +#define ADM1075_VAUX_UV_WARN (1<<6) + struct adm1275_data { int id; bool have_oc_fault; @@ -74,6 +85,29 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) } ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT); break; + case PMBUS_VOUT_OV_WARN_LIMIT: + if (data->id != adm1075) { + ret = -ENODATA; + break; + } + ret = pmbus_read_word_data(client, 0, + ADM1075_VAUX_OV_WARN_LIMIT); + break; + case PMBUS_VOUT_UV_WARN_LIMIT: + if (data->id != adm1075) { + ret = -ENODATA; + break; + } + ret = pmbus_read_word_data(client, 0, + ADM1075_VAUX_UV_WARN_LIMIT); + break; + case PMBUS_READ_VOUT: + if (data->id != adm1075) { + ret = -ENODATA; + break; + } + ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX); + break; case PMBUS_VIRT_READ_IOUT_MAX: ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT); break; @@ -84,7 +118,7 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); break; case PMBUS_VIRT_READ_PIN_MAX: - if (data->id != adm1276) { + if (data->id == adm1275) { ret = -ENXIO; break; } @@ -95,7 +129,7 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) case PMBUS_VIRT_RESET_VIN_HISTORY: break; case PMBUS_VIRT_RESET_PIN_HISTORY: - if (data->id != adm1276) + if (data->id == adm1275) ret = -ENXIO; break; default: @@ -163,6 +197,19 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg) PB_IOUT_OC_FAULT : PB_IOUT_UC_FAULT; } break; + case PMBUS_STATUS_VOUT: + if (data->id != adm1075) { + ret = -ENODATA; + break; + } + ret = 0; + mfr_status = pmbus_read_byte_data(client, 0, + ADM1075_VAUX_STATUS); + if (mfr_status & ADM1075_VAUX_OV_WARN) + ret |= PB_VOLTAGE_OV_WARNING; + if (mfr_status & ADM1075_VAUX_UV_WARN) + ret |= PB_VOLTAGE_UV_WARNING; + break; default: ret = -ENODATA; break; @@ -171,6 +218,7 @@ static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg) } static const struct i2c_device_id adm1275_id[] = { + { "adm1075", adm1075 }, { "adm1275", adm1275 }, { "adm1276", adm1276 }, { } @@ -229,7 +277,8 @@ static int adm1275_probe(struct i2c_client *client, if (device_config < 0) return device_config; - data = kzalloc(sizeof(struct adm1275_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct adm1275_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -250,7 +299,14 @@ static int adm1275_probe(struct i2c_client *client, info->read_byte_data = adm1275_read_byte_data; info->write_word_data = adm1275_write_word_data; - if (config & ADM1275_VRANGE) { + if (data->id == adm1075) { + info->m[PSC_VOLTAGE_IN] = 27169; + info->b[PSC_VOLTAGE_IN] = 0; + info->R[PSC_VOLTAGE_IN] = -1; + info->m[PSC_VOLTAGE_OUT] = 27169; + info->b[PSC_VOLTAGE_OUT] = 0; + info->R[PSC_VOLTAGE_OUT] = -1; + } else if (config & ADM1275_VRANGE) { info->m[PSC_VOLTAGE_IN] = 19199; info->b[PSC_VOLTAGE_IN] = 0; info->R[PSC_VOLTAGE_IN] = -2; @@ -270,6 +326,31 @@ static int adm1275_probe(struct i2c_client *client, data->have_oc_fault = true; switch (data->id) { + case adm1075: + info->format[PSC_POWER] = direct; + info->b[PSC_POWER] = 0; + info->R[PSC_POWER] = -1; + switch (config & ADM1075_IRANGE_MASK) { + case ADM1075_IRANGE_25: + info->m[PSC_POWER] = 8549; + info->m[PSC_CURRENT_OUT] = 806; + break; + case ADM1075_IRANGE_50: + info->m[PSC_POWER] = 4279; + info->m[PSC_CURRENT_OUT] = 404; + break; + default: + dev_err(&client->dev, "Invalid input current range"); + info->m[PSC_POWER] = 0; + info->m[PSC_CURRENT_OUT] = 0; + break; + } + info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN + | PMBUS_HAVE_STATUS_INPUT; + if (config & ADM1275_VIN_VOUT_SELECT) + info->func[0] |= + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; + break; case adm1275: if (config & ADM1275_VIN_VOUT_SELECT) info->func[0] |= @@ -297,24 +378,7 @@ static int adm1275_probe(struct i2c_client *client, break; } - ret = pmbus_do_probe(client, id, info); - if (ret) - goto err_mem; - return 0; - -err_mem: - kfree(data); - return ret; -} - -static int adm1275_remove(struct i2c_client *client) -{ - const struct pmbus_driver_info *info = pmbus_get_driver_info(client); - const struct adm1275_data *data = to_adm1275_data(info); - - pmbus_do_remove(client); - kfree(data); - return 0; + return pmbus_do_probe(client, id, info); } static struct i2c_driver adm1275_driver = { @@ -322,22 +386,12 @@ static struct i2c_driver adm1275_driver = { .name = "adm1275", }, .probe = adm1275_probe, - .remove = adm1275_remove, + .remove = pmbus_do_remove, .id_table = adm1275_id, }; -static int __init adm1275_init(void) -{ - return i2c_add_driver(&adm1275_driver); -} - -static void __exit adm1275_exit(void) -{ - i2c_del_driver(&adm1275_driver); -} +module_i2c_driver(adm1275_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles"); MODULE_LICENSE("GPL"); -module_init(adm1275_init); -module_exit(adm1275_exit); diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 84a37f0c8db6..c299392716af 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -176,7 +176,6 @@ static int lm25066_probe(struct i2c_client *client, const struct i2c_device_id *id) { int config; - int ret; struct lm25066_data *data; struct pmbus_driver_info *info; @@ -184,15 +183,14 @@ static int lm25066_probe(struct i2c_client *client, I2C_FUNC_SMBUS_READ_BYTE_DATA)) return -ENODEV; - data = kzalloc(sizeof(struct lm25066_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct lm25066_data), + GFP_KERNEL); if (!data) return -ENOMEM; config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP); - if (config < 0) { - ret = config; - goto err_mem; - } + if (config < 0) + return config; data->id = id->driver_data; info = &data->info; @@ -291,28 +289,10 @@ static int lm25066_probe(struct i2c_client *client, } break; default: - ret = -ENODEV; - goto err_mem; + return -ENODEV; } - ret = pmbus_do_probe(client, id, info); - if (ret) - goto err_mem; - return 0; - -err_mem: - kfree(data); - return ret; -} - -static int lm25066_remove(struct i2c_client *client) -{ - const struct pmbus_driver_info *info = pmbus_get_driver_info(client); - const struct lm25066_data *data = to_lm25066_data(info); - - pmbus_do_remove(client); - kfree(data); - return 0; + return pmbus_do_probe(client, id, info); } static const struct i2c_device_id lm25066_id[] = { @@ -330,22 +310,12 @@ static struct i2c_driver lm25066_driver = { .name = "lm25066", }, .probe = lm25066_probe, - .remove = lm25066_remove, + .remove = pmbus_do_remove, .id_table = lm25066_id, }; -static int __init lm25066_init(void) -{ - return i2c_add_driver(&lm25066_driver); -} - -static void __exit lm25066_exit(void) -{ - i2c_del_driver(&lm25066_driver); -} +module_i2c_driver(lm25066_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066"); MODULE_LICENSE("GPL"); -module_init(lm25066_init); -module_exit(lm25066_exit); diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index 820fff48910b..9652a2c92a24 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -287,7 +287,7 @@ MODULE_DEVICE_TABLE(i2c, ltc2978_id); static int ltc2978_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int chip_id, ret, i; + int chip_id, i; struct ltc2978_data *data; struct pmbus_driver_info *info; @@ -295,15 +295,14 @@ static int ltc2978_probe(struct i2c_client *client, I2C_FUNC_SMBUS_READ_WORD_DATA)) return -ENODEV; - data = kzalloc(sizeof(struct ltc2978_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data), + GFP_KERNEL); if (!data) return -ENOMEM; chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID); - if (chip_id < 0) { - ret = chip_id; - goto err_mem; - } + if (chip_id < 0) + return chip_id; if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { data->id = ltc2978; @@ -311,8 +310,7 @@ static int ltc2978_probe(struct i2c_client *client, data->id = ltc3880; } else { dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id); - ret = -ENODEV; - goto err_mem; + return -ENODEV; } if (data->id != id->driver_data) dev_warn(&client->dev, @@ -357,28 +355,10 @@ static int ltc2978_probe(struct i2c_client *client, data->vout_min[1] = 0xffff; break; default: - ret = -ENODEV; - goto err_mem; + return -ENODEV; } - ret = pmbus_do_probe(client, id, info); - if (ret) - goto err_mem; - return 0; - -err_mem: - kfree(data); - return ret; -} - -static int ltc2978_remove(struct i2c_client *client) -{ - const struct pmbus_driver_info *info = pmbus_get_driver_info(client); - const struct ltc2978_data *data = to_ltc2978_data(info); - - pmbus_do_remove(client); - kfree(data); - return 0; + return pmbus_do_probe(client, id, info); } /* This is the driver that will be inserted */ @@ -387,22 +367,12 @@ static struct i2c_driver ltc2978_driver = { .name = "ltc2978", }, .probe = ltc2978_probe, - .remove = ltc2978_remove, + .remove = pmbus_do_remove, .id_table = ltc2978_id, }; -static int __init ltc2978_init(void) -{ - return i2c_add_driver(<c2978_driver); -} - -static void __exit ltc2978_exit(void) -{ - i2c_del_driver(<c2978_driver); -} +module_i2c_driver(ltc2978_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880"); MODULE_LICENSE("GPL"); -module_init(ltc2978_init); -module_exit(ltc2978_exit); diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c index 1d77cf4d2d44..fa237a3c3291 100644 --- a/drivers/hwmon/pmbus/max16064.c +++ b/drivers/hwmon/pmbus/max16064.c @@ -103,12 +103,6 @@ static int max16064_probe(struct i2c_client *client, return pmbus_do_probe(client, id, &max16064_info); } -static int max16064_remove(struct i2c_client *client) -{ - pmbus_do_remove(client); - return 0; -} - static const struct i2c_device_id max16064_id[] = { {"max16064", 0}, {} @@ -122,22 +116,12 @@ static struct i2c_driver max16064_driver = { .name = "max16064", }, .probe = max16064_probe, - .remove = max16064_remove, + .remove = pmbus_do_remove, .id_table = max16064_id, }; -static int __init max16064_init(void) -{ - return i2c_add_driver(&max16064_driver); -} - -static void __exit max16064_exit(void) -{ - i2c_del_driver(&max16064_driver); -} +module_i2c_driver(max16064_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064"); MODULE_LICENSE("GPL"); -module_init(max16064_init); -module_exit(max16064_exit); diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index 9b97a5b3cf3d..2ada7b021fbe 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c @@ -25,34 +25,82 @@ #include <linux/i2c.h> #include "pmbus.h" -enum chips { max34440, max34441 }; +enum chips { max34440, max34441, max34446 }; #define MAX34440_MFR_VOUT_PEAK 0xd4 #define MAX34440_MFR_IOUT_PEAK 0xd5 #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 +#define MAX34440_MFR_VOUT_MIN 0xd7 + +#define MAX34446_MFR_POUT_PEAK 0xe0 +#define MAX34446_MFR_POUT_AVG 0xe1 +#define MAX34446_MFR_IOUT_AVG 0xe2 +#define MAX34446_MFR_TEMPERATURE_AVG 0xe3 #define MAX34440_STATUS_OC_WARN (1 << 0) #define MAX34440_STATUS_OC_FAULT (1 << 1) #define MAX34440_STATUS_OT_FAULT (1 << 5) #define MAX34440_STATUS_OT_WARN (1 << 6) +struct max34440_data { + int id; + struct pmbus_driver_info info; +}; + +#define to_max34440_data(x) container_of(x, struct max34440_data, info) + static int max34440_read_word_data(struct i2c_client *client, int page, int reg) { int ret; + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + const struct max34440_data *data = to_max34440_data(info); switch (reg) { + case PMBUS_VIRT_READ_VOUT_MIN: + ret = pmbus_read_word_data(client, page, + MAX34440_MFR_VOUT_MIN); + break; case PMBUS_VIRT_READ_VOUT_MAX: ret = pmbus_read_word_data(client, page, MAX34440_MFR_VOUT_PEAK); break; + case PMBUS_VIRT_READ_IOUT_AVG: + if (data->id != max34446) + return -ENXIO; + ret = pmbus_read_word_data(client, page, + MAX34446_MFR_IOUT_AVG); + break; case PMBUS_VIRT_READ_IOUT_MAX: ret = pmbus_read_word_data(client, page, MAX34440_MFR_IOUT_PEAK); break; + case PMBUS_VIRT_READ_POUT_AVG: + if (data->id != max34446) + return -ENXIO; + ret = pmbus_read_word_data(client, page, + MAX34446_MFR_POUT_AVG); + break; + case PMBUS_VIRT_READ_POUT_MAX: + if (data->id != max34446) + return -ENXIO; + ret = pmbus_read_word_data(client, page, + MAX34446_MFR_POUT_PEAK); + break; + case PMBUS_VIRT_READ_TEMP_AVG: + if (data->id != max34446) + return -ENXIO; + ret = pmbus_read_word_data(client, page, + MAX34446_MFR_TEMPERATURE_AVG); + break; case PMBUS_VIRT_READ_TEMP_MAX: ret = pmbus_read_word_data(client, page, MAX34440_MFR_TEMPERATURE_PEAK); break; + case PMBUS_VIRT_RESET_POUT_HISTORY: + if (data->id != max34446) + return -ENXIO; + ret = 0; + break; case PMBUS_VIRT_RESET_VOUT_HISTORY: case PMBUS_VIRT_RESET_IOUT_HISTORY: case PMBUS_VIRT_RESET_TEMP_HISTORY: @@ -68,21 +116,42 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg) static int max34440_write_word_data(struct i2c_client *client, int page, int reg, u16 word) { + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + const struct max34440_data *data = to_max34440_data(info); int ret; switch (reg) { + case PMBUS_VIRT_RESET_POUT_HISTORY: + ret = pmbus_write_word_data(client, page, + MAX34446_MFR_POUT_PEAK, 0); + if (ret) + break; + ret = pmbus_write_word_data(client, page, + MAX34446_MFR_POUT_AVG, 0); + break; case PMBUS_VIRT_RESET_VOUT_HISTORY: ret = pmbus_write_word_data(client, page, + MAX34440_MFR_VOUT_MIN, 0x7fff); + if (ret) + break; + ret = pmbus_write_word_data(client, page, MAX34440_MFR_VOUT_PEAK, 0); break; case PMBUS_VIRT_RESET_IOUT_HISTORY: ret = pmbus_write_word_data(client, page, MAX34440_MFR_IOUT_PEAK, 0); + if (!ret && data->id == max34446) + ret = pmbus_write_word_data(client, page, + MAX34446_MFR_IOUT_AVG, 0); + break; case PMBUS_VIRT_RESET_TEMP_HISTORY: ret = pmbus_write_word_data(client, page, MAX34440_MFR_TEMPERATURE_PEAK, 0x8000); + if (!ret && data->id == max34446) + ret = pmbus_write_word_data(client, page, + MAX34446_MFR_TEMPERATURE_AVG, 0); break; default: ret = -ENODATA; @@ -216,26 +285,66 @@ static struct pmbus_driver_info max34440_info[] = { .read_word_data = max34440_read_word_data, .write_word_data = max34440_write_word_data, }, + [max34446] = { + .pages = 7, + .format[PSC_VOLTAGE_IN] = direct, + .format[PSC_VOLTAGE_OUT] = direct, + .format[PSC_TEMPERATURE] = direct, + .format[PSC_CURRENT_OUT] = direct, + .format[PSC_POWER] = direct, + .m[PSC_VOLTAGE_IN] = 1, + .b[PSC_VOLTAGE_IN] = 0, + .R[PSC_VOLTAGE_IN] = 3, + .m[PSC_VOLTAGE_OUT] = 1, + .b[PSC_VOLTAGE_OUT] = 0, + .R[PSC_VOLTAGE_OUT] = 3, + .m[PSC_CURRENT_OUT] = 1, + .b[PSC_CURRENT_OUT] = 0, + .R[PSC_CURRENT_OUT] = 3, + .m[PSC_POWER] = 1, + .b[PSC_POWER] = 0, + .R[PSC_POWER] = 3, + .m[PSC_TEMPERATURE] = 1, + .b[PSC_TEMPERATURE] = 0, + .R[PSC_TEMPERATURE] = 2, + .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, + .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, + .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, + .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, + .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, + .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, + .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, + .read_byte_data = max34440_read_byte_data, + .read_word_data = max34440_read_word_data, + .write_word_data = max34440_write_word_data, + }, }; static int max34440_probe(struct i2c_client *client, const struct i2c_device_id *id) { - return pmbus_do_probe(client, id, &max34440_info[id->driver_data]); -} + struct max34440_data *data; -static int max34440_remove(struct i2c_client *client) -{ - pmbus_do_remove(client); - return 0; + data = devm_kzalloc(&client->dev, sizeof(struct max34440_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + data->id = id->driver_data; + data->info = max34440_info[id->driver_data]; + + return pmbus_do_probe(client, id, &data->info); } static const struct i2c_device_id max34440_id[] = { {"max34440", max34440}, {"max34441", max34441}, + {"max34446", max34446}, {} }; - MODULE_DEVICE_TABLE(i2c, max34440_id); /* This is the driver that will be inserted */ @@ -244,22 +353,12 @@ static struct i2c_driver max34440_driver = { .name = "max34440", }, .probe = max34440_probe, - .remove = max34440_remove, + .remove = pmbus_do_remove, .id_table = max34440_id, }; -static int __init max34440_init(void) -{ - return i2c_add_driver(&max34440_driver); -} - -static void __exit max34440_exit(void) -{ - i2c_del_driver(&max34440_driver); -} +module_i2c_driver(max34440_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441"); MODULE_LICENSE("GPL"); -module_init(max34440_init); -module_exit(max34440_exit); diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c index e2b74bb399ba..f04454a42fdd 100644 --- a/drivers/hwmon/pmbus/max8688.c +++ b/drivers/hwmon/pmbus/max8688.c @@ -180,12 +180,6 @@ static int max8688_probe(struct i2c_client *client, return pmbus_do_probe(client, id, &max8688_info); } -static int max8688_remove(struct i2c_client *client) -{ - pmbus_do_remove(client); - return 0; -} - static const struct i2c_device_id max8688_id[] = { {"max8688", 0}, { } @@ -199,22 +193,12 @@ static struct i2c_driver max8688_driver = { .name = "max8688", }, .probe = max8688_probe, - .remove = max8688_remove, + .remove = pmbus_do_remove, .id_table = max8688_id, }; -static int __init max8688_init(void) -{ - return i2c_add_driver(&max8688_driver); -} - -static void __exit max8688_exit(void) -{ - i2c_del_driver(&max8688_driver); -} +module_i2c_driver(max8688_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688"); MODULE_LICENSE("GPL"); -module_init(max8688_init); -module_exit(max8688_exit); diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c index 18a385e753d7..7e91700131a7 100644 --- a/drivers/hwmon/pmbus/pmbus.c +++ b/drivers/hwmon/pmbus/pmbus.c @@ -166,33 +166,16 @@ static int pmbus_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pmbus_driver_info *info; - int ret; - info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); + info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), + GFP_KERNEL); if (!info) return -ENOMEM; info->pages = id->driver_data; info->identify = pmbus_identify; - ret = pmbus_do_probe(client, id, info); - if (ret < 0) - goto out; - return 0; - -out: - kfree(info); - return ret; -} - -static int pmbus_remove(struct i2c_client *client) -{ - const struct pmbus_driver_info *info; - - info = pmbus_get_driver_info(client); - pmbus_do_remove(client); - kfree(info); - return 0; + return pmbus_do_probe(client, id, info); } /* @@ -202,12 +185,15 @@ static const struct i2c_device_id pmbus_id[] = { {"adp4000", 1}, {"bmr453", 1}, {"bmr454", 1}, + {"mdt040", 1}, {"ncp4200", 1}, {"ncp4208", 1}, {"pdt003", 1}, {"pdt006", 1}, {"pdt012", 1}, {"pmbus", 0}, + {"tps40400", 1}, + {"tps40422", 2}, {"udt020", 1}, {} }; @@ -220,22 +206,12 @@ static struct i2c_driver pmbus_driver = { .name = "pmbus", }, .probe = pmbus_probe, - .remove = pmbus_remove, + .remove = pmbus_do_remove, .id_table = pmbus_id, }; -static int __init pmbus_init(void) -{ - return i2c_add_driver(&pmbus_driver); -} - -static void __exit pmbus_exit(void) -{ - i2c_del_driver(&pmbus_driver); -} +module_i2c_driver(pmbus_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("Generic PMBus driver"); MODULE_LICENSE("GPL"); -module_init(pmbus_init); -module_exit(pmbus_exit); diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index 5d31d1c2c0f5..3fe03dc47eb7 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h @@ -146,31 +146,36 @@ * code when reading or writing virtual registers. */ #define PMBUS_VIRT_BASE 0x100 -#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 0) -#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 1) -#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 2) -#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 3) -#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 4) -#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 5) -#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 6) -#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 7) -#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 8) -#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 9) -#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 10) -#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 11) -#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 12) -#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 13) -#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 14) -#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 15) -#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 16) -#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 17) -#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 18) -#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 19) -#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 20) -#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 21) -#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 22) -#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 23) -#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 24) +#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0) +#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1) +#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2) +#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3) +#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4) +#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5) +#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6) +#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7) +#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8) +#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9) +#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10) +#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11) +#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12) +#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13) +#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14) +#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15) +#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16) +#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17) +#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18) +#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19) +#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20) +#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21) +#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22) +#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23) +#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24) +#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25) +#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26) +#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27) +#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28) +#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29) /* * CAPABILITY @@ -364,7 +369,7 @@ bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, struct pmbus_driver_info *info); -void pmbus_do_remove(struct i2c_client *client); +int pmbus_do_remove(struct i2c_client *client); const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client); diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index d89b33967a85..be51037363c8 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -40,11 +40,14 @@ #define PMBUS_IOUT_SENSORS_PER_PAGE 8 /* input, min, max, crit, lowest, highest, avg, reset */ -#define PMBUS_POUT_SENSORS_PER_PAGE 4 /* input, cap, max, crit */ +#define PMBUS_POUT_SENSORS_PER_PAGE 7 /* input, cap, max, crit, + * highest, avg, reset + */ #define PMBUS_MAX_SENSORS_PER_FAN 1 /* input */ -#define PMBUS_MAX_SENSORS_PER_TEMP 8 /* input, min, max, lcrit, - crit, lowest, highest, - reset */ +#define PMBUS_MAX_SENSORS_PER_TEMP 9 /* input, min, max, lcrit, + * crit, lowest, highest, avg, + * reset + */ #define PMBUS_MAX_INPUT_BOOLEANS 7 /* v: min_alarm, max_alarm, lcrit_alarm, crit_alarm; @@ -782,7 +785,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, int ret; u16 regval; - if (strict_strtol(buf, 10, &val) < 0) + if (kstrtol(buf, 10, &val) < 0) return -EINVAL; mutex_lock(&data->update_lock); @@ -1334,6 +1337,17 @@ static const struct pmbus_limit_attr pout_limit_attrs[] = { .attr = "crit", .alarm = "crit_alarm", .sbit = PB_POUT_OP_FAULT, + }, { + .reg = PMBUS_VIRT_READ_POUT_AVG, + .update = true, + .attr = "average", + }, { + .reg = PMBUS_VIRT_READ_POUT_MAX, + .update = true, + .attr = "input_highest", + }, { + .reg = PMBUS_VIRT_RESET_POUT_HISTORY, + .attr = "reset_history", } }; @@ -1389,6 +1403,9 @@ static const struct pmbus_limit_attr temp_limit_attrs[] = { .reg = PMBUS_VIRT_READ_TEMP_MIN, .attr = "lowest", }, { + .reg = PMBUS_VIRT_READ_TEMP_AVG, + .attr = "average", + }, { .reg = PMBUS_VIRT_READ_TEMP_MAX, .attr = "highest", }, { @@ -1424,6 +1441,9 @@ static const struct pmbus_limit_attr temp_limit_attrs2[] = { .reg = PMBUS_VIRT_READ_TEMP2_MIN, .attr = "lowest", }, { + .reg = PMBUS_VIRT_READ_TEMP2_AVG, + .attr = "average", + }, { .reg = PMBUS_VIRT_READ_TEMP2_MAX, .attr = "highest", }, { @@ -1676,7 +1696,7 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (!data) { dev_err(&client->dev, "No memory to allocate driver data\n"); return -ENOMEM; @@ -1688,8 +1708,7 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, /* Bail out if PMBus status register does not exist. */ if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) { dev_err(&client->dev, "PMBus status register not found\n"); - ret = -ENODEV; - goto out_data; + return -ENODEV; } if (pdata) @@ -1702,50 +1721,49 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, ret = (*info->identify)(client, info); if (ret < 0) { dev_err(&client->dev, "Chip identification failed\n"); - goto out_data; + return ret; } } if (info->pages <= 0 || info->pages > PMBUS_PAGES) { dev_err(&client->dev, "Bad number of PMBus pages: %d\n", info->pages); - ret = -ENODEV; - goto out_data; + return -ENODEV; } ret = pmbus_identify_common(client, data); if (ret < 0) { dev_err(&client->dev, "Failed to identify chip capabilities\n"); - goto out_data; + return ret; } ret = -ENOMEM; - data->sensors = kzalloc(sizeof(struct pmbus_sensor) * data->max_sensors, - GFP_KERNEL); + data->sensors = devm_kzalloc(&client->dev, sizeof(struct pmbus_sensor) + * data->max_sensors, GFP_KERNEL); if (!data->sensors) { dev_err(&client->dev, "No memory to allocate sensor data\n"); - goto out_data; + return -ENOMEM; } - data->booleans = kzalloc(sizeof(struct pmbus_boolean) + data->booleans = devm_kzalloc(&client->dev, sizeof(struct pmbus_boolean) * data->max_booleans, GFP_KERNEL); if (!data->booleans) { dev_err(&client->dev, "No memory to allocate boolean data\n"); - goto out_sensors; + return -ENOMEM; } - data->labels = kzalloc(sizeof(struct pmbus_label) * data->max_labels, - GFP_KERNEL); + data->labels = devm_kzalloc(&client->dev, sizeof(struct pmbus_label) + * data->max_labels, GFP_KERNEL); if (!data->labels) { dev_err(&client->dev, "No memory to allocate label data\n"); - goto out_booleans; + return -ENOMEM; } - data->attributes = kzalloc(sizeof(struct attribute *) - * data->max_attributes, GFP_KERNEL); + data->attributes = devm_kzalloc(&client->dev, sizeof(struct attribute *) + * data->max_attributes, GFP_KERNEL); if (!data->attributes) { dev_err(&client->dev, "No memory to allocate attribute data\n"); - goto out_labels; + return -ENOMEM; } pmbus_find_attributes(client, data); @@ -1756,8 +1774,7 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, */ if (!data->num_attributes) { dev_err(&client->dev, "No attributes found\n"); - ret = -ENODEV; - goto out_attributes; + return -ENODEV; } /* Register sysfs hooks */ @@ -1765,7 +1782,7 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, ret = sysfs_create_group(&client->dev.kobj, &data->group); if (ret) { dev_err(&client->dev, "Failed to create sysfs entries\n"); - goto out_attributes; + return ret; } data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -1777,30 +1794,16 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, out_hwmon_device_register: sysfs_remove_group(&client->dev.kobj, &data->group); -out_attributes: - kfree(data->attributes); -out_labels: - kfree(data->labels); -out_booleans: - kfree(data->booleans); -out_sensors: - kfree(data->sensors); -out_data: - kfree(data); return ret; } EXPORT_SYMBOL_GPL(pmbus_do_probe); -void pmbus_do_remove(struct i2c_client *client) +int pmbus_do_remove(struct i2c_client *client) { struct pmbus_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->group); - kfree(data->attributes); - kfree(data->labels); - kfree(data->booleans); - kfree(data->sensors); - kfree(data); + return 0; } EXPORT_SYMBOL_GPL(pmbus_do_remove); diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c index 4ff6cf289f85..fbb1479d3ad4 100644 --- a/drivers/hwmon/pmbus/ucd9000.c +++ b/drivers/hwmon/pmbus/ucd9000.c @@ -155,7 +155,8 @@ static int ucd9000_probe(struct i2c_client *client, "Device mismatch: Configured %s, detected %s\n", id->name, mid->name); - data = kzalloc(sizeof(struct ucd9000_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data), + GFP_KERNEL); if (!data) return -ENOMEM; info = &data->info; @@ -164,13 +165,12 @@ static int ucd9000_probe(struct i2c_client *client, if (ret < 0) { dev_err(&client->dev, "Failed to read number of active pages\n"); - goto out; + return ret; } info->pages = ret; if (!info->pages) { dev_err(&client->dev, "No pages configured\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } /* The internal temperature sensor is always active */ @@ -181,8 +181,7 @@ static int ucd9000_probe(struct i2c_client *client, block_buffer); if (ret <= 0) { dev_err(&client->dev, "Failed to read configuration data\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } for (i = 0; i < ret; i++) { int page = UCD9000_MON_PAGE(block_buffer[i]); @@ -218,7 +217,7 @@ static int ucd9000_probe(struct i2c_client *client, UCD9000_FAN_CONFIG, data->fan_data[i]); if (ret < 0) - goto out; + return ret; } i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0); @@ -227,49 +226,21 @@ static int ucd9000_probe(struct i2c_client *client, | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; } - ret = pmbus_do_probe(client, mid, info); - if (ret < 0) - goto out; - return 0; - -out: - kfree(data); - return ret; -} - -static int ucd9000_remove(struct i2c_client *client) -{ - struct ucd9000_data *data; - - data = to_ucd9000_data(pmbus_get_driver_info(client)); - pmbus_do_remove(client); - kfree(data); - return 0; + return pmbus_do_probe(client, mid, info); } - /* This is the driver that will be inserted */ static struct i2c_driver ucd9000_driver = { .driver = { .name = "ucd9000", }, .probe = ucd9000_probe, - .remove = ucd9000_remove, + .remove = pmbus_do_remove, .id_table = ucd9000_id, }; -static int __init ucd9000_init(void) -{ - return i2c_add_driver(&ucd9000_driver); -} - -static void __exit ucd9000_exit(void) -{ - i2c_del_driver(&ucd9000_driver); -} +module_i2c_driver(ucd9000_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx"); MODULE_LICENSE("GPL"); -module_init(ucd9000_init); -module_exit(ucd9000_exit); diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c index 6e1c1a80ab85..033d6aca47d3 100644 --- a/drivers/hwmon/pmbus/ucd9200.c +++ b/drivers/hwmon/pmbus/ucd9200.c @@ -81,7 +81,8 @@ static int ucd9200_probe(struct i2c_client *client, "Device mismatch: Configured %s, detected %s\n", id->name, mid->name); - info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); + info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), + GFP_KERNEL); if (!info) return -ENOMEM; @@ -89,7 +90,7 @@ static int ucd9200_probe(struct i2c_client *client, block_buffer); if (ret < 0) { dev_err(&client->dev, "Failed to read phase information\n"); - goto out; + return ret; } /* @@ -106,8 +107,7 @@ static int ucd9200_probe(struct i2c_client *client, } if (!info->pages) { dev_err(&client->dev, "No rails configured\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } dev_info(&client->dev, "%d rails configured\n", info->pages); @@ -137,7 +137,7 @@ static int ucd9200_probe(struct i2c_client *client, if (ret < 0) { dev_err(&client->dev, "Failed to initialize PHASE registers\n"); - goto out; + return ret; } } if (info->pages > 1) @@ -160,48 +160,21 @@ static int ucd9200_probe(struct i2c_client *client, if (mid->driver_data == ucd9240) info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12; - ret = pmbus_do_probe(client, mid, info); - if (ret < 0) - goto out; - return 0; -out: - kfree(info); - return ret; -} - -static int ucd9200_remove(struct i2c_client *client) -{ - const struct pmbus_driver_info *info; - - info = pmbus_get_driver_info(client); - pmbus_do_remove(client); - kfree(info); - return 0; + return pmbus_do_probe(client, mid, info); } - /* This is the driver that will be inserted */ static struct i2c_driver ucd9200_driver = { .driver = { .name = "ucd9200", }, .probe = ucd9200_probe, - .remove = ucd9200_remove, + .remove = pmbus_do_remove, .id_table = ucd9200_id, }; -static int __init ucd9200_init(void) -{ - return i2c_add_driver(&ucd9200_driver); -} - -static void __exit ucd9200_exit(void) -{ - i2c_del_driver(&ucd9200_driver); -} +module_i2c_driver(ucd9200_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x"); MODULE_LICENSE("GPL"); -module_init(ucd9200_init); -module_exit(ucd9200_exit); diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index e3e8420b7b81..fc5eed8e85bb 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -28,7 +28,8 @@ #include <linux/delay.h> #include "pmbus.h" -enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105 }; +enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105, + zl9101, zl9117 }; struct zl6100_data { int id; @@ -152,6 +153,8 @@ static const struct i2c_device_id zl6100_id[] = { {"zl2106", zl2106}, {"zl6100", zl6100}, {"zl6105", zl6105}, + {"zl9101", zl9101}, + {"zl9117", zl9117}, { } }; MODULE_DEVICE_TABLE(i2c, zl6100_id); @@ -193,7 +196,8 @@ static int zl6100_probe(struct i2c_client *client, "Device mismatch: Configured %s, detected %s\n", id->name, mid->name); - data = kzalloc(sizeof(struct zl6100_data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct zl6100_data), + GFP_KERNEL); if (!data) return -ENOMEM; @@ -223,7 +227,8 @@ static int zl6100_probe(struct i2c_client *client, ret = i2c_smbus_read_word_data(client, ZL6100_MFR_CONFIG); if (ret < 0) - goto err_mem; + return ret; + if (ret & ZL6100_MFR_XTEMP_ENABLE) info->func[0] |= PMBUS_HAVE_TEMP2; @@ -235,24 +240,7 @@ static int zl6100_probe(struct i2c_client *client, info->write_word_data = zl6100_write_word_data; info->write_byte = zl6100_write_byte; - ret = pmbus_do_probe(client, mid, info); - if (ret) - goto err_mem; - return 0; - -err_mem: - kfree(data); - return ret; -} - -static int zl6100_remove(struct i2c_client *client) -{ - const struct pmbus_driver_info *info = pmbus_get_driver_info(client); - const struct zl6100_data *data = to_zl6100_data(info); - - pmbus_do_remove(client); - kfree(data); - return 0; + return pmbus_do_probe(client, mid, info); } static struct i2c_driver zl6100_driver = { @@ -260,22 +248,12 @@ static struct i2c_driver zl6100_driver = { .name = "zl6100", }, .probe = zl6100_probe, - .remove = zl6100_remove, + .remove = pmbus_do_remove, .id_table = zl6100_id, }; -static int __init zl6100_init(void) -{ - return i2c_add_driver(&zl6100_driver); -} - -static void __exit zl6100_exit(void) -{ - i2c_del_driver(&zl6100_driver); -} +module_i2c_driver(zl6100_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles"); MODULE_LICENSE("GPL"); -module_init(zl6100_init); -module_exit(zl6100_exit); diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c index 79b6dabe3161..8ec6dfbccb64 100644 --- a/drivers/hwmon/sch5627.c +++ b/drivers/hwmon/sch5627.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> * + * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -79,6 +79,7 @@ static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = { struct sch5627_data { unsigned short addr; struct device *hwmon_dev; + struct sch56xx_watchdog_data *watchdog; u8 control; u8 temp_max[SCH5627_NO_TEMPS]; u8 temp_crit[SCH5627_NO_TEMPS]; @@ -453,6 +454,9 @@ static int sch5627_remove(struct platform_device *pdev) { struct sch5627_data *data = platform_get_drvdata(pdev); + if (data->watchdog) + sch56xx_watchdog_unregister(data->watchdog); + if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); @@ -574,6 +578,11 @@ static int __devinit sch5627_probe(struct platform_device *pdev) goto error; } + /* Note failing to register the watchdog is not a fatal error */ + data->watchdog = sch56xx_watchdog_register(data->addr, + (build_code << 24) | (build_id << 8) | hwmon_rev, + &data->update_lock, 1); + return 0; error: diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 9d5236fb09b4..906d4ed32d81 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com> * + * Copyright (C) 2011-2012 Hans de Goede <hdegoede@redhat.com> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -67,6 +67,7 @@ static const u16 SCH5636_REG_FAN_VAL[SCH5636_NO_FANS] = { struct sch5636_data { unsigned short addr; struct device *hwmon_dev; + struct sch56xx_watchdog_data *watchdog; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -384,6 +385,9 @@ static int sch5636_remove(struct platform_device *pdev) struct sch5636_data *data = platform_get_drvdata(pdev); int i; + if (data->watchdog) + sch56xx_watchdog_unregister(data->watchdog); + if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); @@ -505,6 +509,11 @@ static int __devinit sch5636_probe(struct platform_device *pdev) goto error; } + /* Note failing to register the watchdog is not a fatal error */ + data->watchdog = sch56xx_watchdog_register(data->addr, + (revision[0] << 8) | revision[1], + &data->update_lock, 0); + return 0; error: diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c index fac32ee0b10e..ce52fc57d41d 100644 --- a/drivers/hwmon/sch56xx-common.c +++ b/drivers/hwmon/sch56xx-common.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> * + * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -26,8 +26,20 @@ #include <linux/io.h> #include <linux/acpi.h> #include <linux/delay.h> +#include <linux/fs.h> +#include <linux/watchdog.h> +#include <linux/miscdevice.h> +#include <linux/uaccess.h> +#include <linux/kref.h> +#include <linux/slab.h> #include "sch56xx-common.h" +/* Insmod parameters */ +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + #define SIO_SCH56XX_LD_EM 0x0C /* Embedded uController Logical Dev */ #define SIO_UNLOCK_KEY 0x55 /* Key to enable Super-I/O */ #define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */ @@ -40,13 +52,45 @@ #define SIO_SCH5627_ID 0xC6 /* Chipset ID */ #define SIO_SCH5636_ID 0xC7 /* Chipset ID */ -#define REGION_LENGTH 9 +#define REGION_LENGTH 10 #define SCH56XX_CMD_READ 0x02 #define SCH56XX_CMD_WRITE 0x03 +/* Watchdog registers */ +#define SCH56XX_REG_WDOG_PRESET 0x58B +#define SCH56XX_REG_WDOG_CONTROL 0x58C +#define SCH56XX_WDOG_TIME_BASE_SEC 0x01 +#define SCH56XX_REG_WDOG_OUTPUT_ENABLE 0x58E +#define SCH56XX_WDOG_OUTPUT_ENABLE 0x02 + +struct sch56xx_watchdog_data { + u16 addr; + u32 revision; + struct mutex *io_lock; + struct mutex watchdog_lock; + struct list_head list; /* member of the watchdog_data_list */ + struct kref kref; + struct miscdevice watchdog_miscdev; + unsigned long watchdog_is_open; + char watchdog_name[10]; /* must be unique to avoid sysfs conflict */ + char watchdog_expect_close; + u8 watchdog_preset; + u8 watchdog_control; + u8 watchdog_output_enable; +}; + static struct platform_device *sch56xx_pdev; +/* + * Somewhat ugly :( global data pointer list with all sch56xx devices, so that + * we can find our device data as when using misc_register there is no other + * method to get to ones device data from the open fop. + */ +static LIST_HEAD(watchdog_data_list); +/* Note this lock not only protect list access, but also data.kref access */ +static DEFINE_MUTEX(watchdog_data_mutex); + /* Super I/O functions */ static inline int superio_inb(int base, int reg) { @@ -224,6 +268,477 @@ int sch56xx_read_virtual_reg12(u16 addr, u16 msb_reg, u16 lsn_reg, } EXPORT_SYMBOL(sch56xx_read_virtual_reg12); +/* + * Watchdog routines + */ + +/* + * Release our data struct when the platform device has been released *and* + * all references to our watchdog device are released. + */ +static void sch56xx_watchdog_release_resources(struct kref *r) +{ + struct sch56xx_watchdog_data *data = + container_of(r, struct sch56xx_watchdog_data, kref); + kfree(data); +} + +static int watchdog_set_timeout(struct sch56xx_watchdog_data *data, + int timeout) +{ + int ret, resolution; + u8 control; + + /* 1 second or 60 second resolution? */ + if (timeout <= 255) + resolution = 1; + else + resolution = 60; + + if (timeout < resolution || timeout > (resolution * 255)) + return -EINVAL; + + mutex_lock(&data->watchdog_lock); + if (!data->addr) { + ret = -ENODEV; + goto leave; + } + + if (resolution == 1) + control = data->watchdog_control | SCH56XX_WDOG_TIME_BASE_SEC; + else + control = data->watchdog_control & ~SCH56XX_WDOG_TIME_BASE_SEC; + + if (data->watchdog_control != control) { + mutex_lock(data->io_lock); + ret = sch56xx_write_virtual_reg(data->addr, + SCH56XX_REG_WDOG_CONTROL, + control); + mutex_unlock(data->io_lock); + if (ret) + goto leave; + + data->watchdog_control = control; + } + + /* + * Remember new timeout value, but do not write as that (re)starts + * the watchdog countdown. + */ + data->watchdog_preset = DIV_ROUND_UP(timeout, resolution); + + ret = data->watchdog_preset * resolution; +leave: + mutex_unlock(&data->watchdog_lock); + return ret; +} + +static int watchdog_get_timeout(struct sch56xx_watchdog_data *data) +{ + int timeout; + + mutex_lock(&data->watchdog_lock); + if (data->watchdog_control & SCH56XX_WDOG_TIME_BASE_SEC) + timeout = data->watchdog_preset; + else + timeout = data->watchdog_preset * 60; + mutex_unlock(&data->watchdog_lock); + + return timeout; +} + +static int watchdog_start(struct sch56xx_watchdog_data *data) +{ + int ret; + u8 val; + + mutex_lock(&data->watchdog_lock); + if (!data->addr) { + ret = -ENODEV; + goto leave_unlock_watchdog; + } + + /* + * The sch56xx's watchdog cannot really be started / stopped + * it is always running, but we can avoid the timer expiring + * from causing a system reset by clearing the output enable bit. + * + * The sch56xx's watchdog will set the watchdog event bit, bit 0 + * of the second interrupt source register (at base-address + 9), + * when the timer expires. + * + * This will only cause a system reset if the 0-1 flank happens when + * output enable is true. Setting output enable after the flank will + * not cause a reset, nor will the timer expiring a second time. + * This means we must clear the watchdog event bit in case it is set. + * + * The timer may still be running (after a recent watchdog_stop) and + * mere milliseconds away from expiring, so the timer must be reset + * first! + */ + + mutex_lock(data->io_lock); + + /* 1. Reset the watchdog countdown counter */ + ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET, + data->watchdog_preset); + if (ret) + goto leave; + + /* 2. Enable output (if not already enabled) */ + if (!(data->watchdog_output_enable & SCH56XX_WDOG_OUTPUT_ENABLE)) { + val = data->watchdog_output_enable | + SCH56XX_WDOG_OUTPUT_ENABLE; + ret = sch56xx_write_virtual_reg(data->addr, + SCH56XX_REG_WDOG_OUTPUT_ENABLE, + val); + if (ret) + goto leave; + + data->watchdog_output_enable = val; + } + + /* 3. Clear the watchdog event bit if set */ + val = inb(data->addr + 9); + if (val & 0x01) + outb(0x01, data->addr + 9); + +leave: + mutex_unlock(data->io_lock); +leave_unlock_watchdog: + mutex_unlock(&data->watchdog_lock); + return ret; +} + +static int watchdog_trigger(struct sch56xx_watchdog_data *data) +{ + int ret; + + mutex_lock(&data->watchdog_lock); + if (!data->addr) { + ret = -ENODEV; + goto leave; + } + + /* Reset the watchdog countdown counter */ + mutex_lock(data->io_lock); + ret = sch56xx_write_virtual_reg(data->addr, SCH56XX_REG_WDOG_PRESET, + data->watchdog_preset); + mutex_unlock(data->io_lock); +leave: + mutex_unlock(&data->watchdog_lock); + return ret; +} + +static int watchdog_stop_unlocked(struct sch56xx_watchdog_data *data) +{ + int ret = 0; + u8 val; + + if (!data->addr) + return -ENODEV; + + if (data->watchdog_output_enable & SCH56XX_WDOG_OUTPUT_ENABLE) { + val = data->watchdog_output_enable & + ~SCH56XX_WDOG_OUTPUT_ENABLE; + mutex_lock(data->io_lock); + ret = sch56xx_write_virtual_reg(data->addr, + SCH56XX_REG_WDOG_OUTPUT_ENABLE, + val); + mutex_unlock(data->io_lock); + if (ret) + return ret; + + data->watchdog_output_enable = val; + } + + return ret; +} + +static int watchdog_stop(struct sch56xx_watchdog_data *data) +{ + int ret; + + mutex_lock(&data->watchdog_lock); + ret = watchdog_stop_unlocked(data); + mutex_unlock(&data->watchdog_lock); + + return ret; +} + +static int watchdog_release(struct inode *inode, struct file *filp) +{ + struct sch56xx_watchdog_data *data = filp->private_data; + + if (data->watchdog_expect_close) { + watchdog_stop(data); + data->watchdog_expect_close = 0; + } else { + watchdog_trigger(data); + pr_crit("unexpected close, not stopping watchdog!\n"); + } + + clear_bit(0, &data->watchdog_is_open); + + mutex_lock(&watchdog_data_mutex); + kref_put(&data->kref, sch56xx_watchdog_release_resources); + mutex_unlock(&watchdog_data_mutex); + + return 0; +} + +static int watchdog_open(struct inode *inode, struct file *filp) +{ + struct sch56xx_watchdog_data *pos, *data = NULL; + int ret, watchdog_is_open; + + /* + * We get called from drivers/char/misc.c with misc_mtx hold, and we + * call misc_register() from sch56xx_watchdog_probe() with + * watchdog_data_mutex hold, as misc_register() takes the misc_mtx + * lock, this is a possible deadlock, so we use mutex_trylock here. + */ + if (!mutex_trylock(&watchdog_data_mutex)) + return -ERESTARTSYS; + list_for_each_entry(pos, &watchdog_data_list, list) { + if (pos->watchdog_miscdev.minor == iminor(inode)) { + data = pos; + break; + } + } + /* Note we can never not have found data, so we don't check for this */ + watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open); + if (!watchdog_is_open) + kref_get(&data->kref); + mutex_unlock(&watchdog_data_mutex); + + if (watchdog_is_open) + return -EBUSY; + + filp->private_data = data; + + /* Start the watchdog */ + ret = watchdog_start(data); + if (ret) { + watchdog_release(inode, filp); + return ret; + } + + return nonseekable_open(inode, filp); +} + +static ssize_t watchdog_write(struct file *filp, const char __user *buf, + size_t count, loff_t *offset) +{ + int ret; + struct sch56xx_watchdog_data *data = filp->private_data; + + if (count) { + if (!nowayout) { + size_t i; + + /* Clear it in case it was set with a previous write */ + data->watchdog_expect_close = 0; + + for (i = 0; i != count; i++) { + char c; + if (get_user(c, buf + i)) + return -EFAULT; + if (c == 'V') + data->watchdog_expect_close = 1; + } + } + ret = watchdog_trigger(data); + if (ret) + return ret; + } + return count; +} + +static long watchdog_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, + .identity = "sch56xx watchdog" + }; + int i, ret = 0; + struct sch56xx_watchdog_data *data = filp->private_data; + + switch (cmd) { + case WDIOC_GETSUPPORT: + ident.firmware_version = data->revision; + if (!nowayout) + ident.options |= WDIOF_MAGICCLOSE; + if (copy_to_user((void __user *)arg, &ident, sizeof(ident))) + ret = -EFAULT; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + ret = put_user(0, (int __user *)arg); + break; + + case WDIOC_KEEPALIVE: + ret = watchdog_trigger(data); + break; + + case WDIOC_GETTIMEOUT: + i = watchdog_get_timeout(data); + ret = put_user(i, (int __user *)arg); + break; + + case WDIOC_SETTIMEOUT: + if (get_user(i, (int __user *)arg)) { + ret = -EFAULT; + break; + } + ret = watchdog_set_timeout(data, i); + if (ret >= 0) + ret = put_user(ret, (int __user *)arg); + break; + + case WDIOC_SETOPTIONS: + if (get_user(i, (int __user *)arg)) { + ret = -EFAULT; + break; + } + + if (i & WDIOS_DISABLECARD) + ret = watchdog_stop(data); + else if (i & WDIOS_ENABLECARD) + ret = watchdog_trigger(data); + else + ret = -EINVAL; + break; + + default: + ret = -ENOTTY; + } + return ret; +} + +static const struct file_operations watchdog_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = watchdog_open, + .release = watchdog_release, + .write = watchdog_write, + .unlocked_ioctl = watchdog_ioctl, +}; + +struct sch56xx_watchdog_data *sch56xx_watchdog_register( + u16 addr, u32 revision, struct mutex *io_lock, int check_enabled) +{ + struct sch56xx_watchdog_data *data; + int i, err, control, output_enable; + const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; + + /* Cache the watchdog registers */ + mutex_lock(io_lock); + control = + sch56xx_read_virtual_reg(addr, SCH56XX_REG_WDOG_CONTROL); + output_enable = + sch56xx_read_virtual_reg(addr, SCH56XX_REG_WDOG_OUTPUT_ENABLE); + mutex_unlock(io_lock); + + if (control < 0) + return NULL; + if (output_enable < 0) + return NULL; + if (check_enabled && !(output_enable & SCH56XX_WDOG_OUTPUT_ENABLE)) { + pr_warn("Watchdog not enabled by BIOS, not registering\n"); + return NULL; + } + + data = kzalloc(sizeof(struct sch56xx_watchdog_data), GFP_KERNEL); + if (!data) + return NULL; + + data->addr = addr; + data->revision = revision; + data->io_lock = io_lock; + data->watchdog_control = control; + data->watchdog_output_enable = output_enable; + mutex_init(&data->watchdog_lock); + INIT_LIST_HEAD(&data->list); + kref_init(&data->kref); + + err = watchdog_set_timeout(data, 60); + if (err < 0) + goto error; + + /* + * We take the data_mutex lock early so that watchdog_open() cannot + * run when misc_register() has completed, but we've not yet added + * our data to the watchdog_data_list. + */ + mutex_lock(&watchdog_data_mutex); + for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { + /* Register our watchdog part */ + snprintf(data->watchdog_name, sizeof(data->watchdog_name), + "watchdog%c", (i == 0) ? '\0' : ('0' + i)); + data->watchdog_miscdev.name = data->watchdog_name; + data->watchdog_miscdev.fops = &watchdog_fops; + data->watchdog_miscdev.minor = watchdog_minors[i]; + err = misc_register(&data->watchdog_miscdev); + if (err == -EBUSY) + continue; + if (err) + break; + + list_add(&data->list, &watchdog_data_list); + pr_info("Registered /dev/%s chardev major 10, minor: %d\n", + data->watchdog_name, watchdog_minors[i]); + break; + } + mutex_unlock(&watchdog_data_mutex); + + if (err) { + pr_err("Registering watchdog chardev: %d\n", err); + goto error; + } + if (i == ARRAY_SIZE(watchdog_minors)) { + pr_warn("Couldn't register watchdog (no free minor)\n"); + goto error; + } + + return data; + +error: + kfree(data); + return NULL; +} +EXPORT_SYMBOL(sch56xx_watchdog_register); + +void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data) +{ + mutex_lock(&watchdog_data_mutex); + misc_deregister(&data->watchdog_miscdev); + list_del(&data->list); + mutex_unlock(&watchdog_data_mutex); + + mutex_lock(&data->watchdog_lock); + if (data->watchdog_is_open) { + pr_warn("platform device unregistered with watchdog " + "open! Stopping watchdog.\n"); + watchdog_stop_unlocked(data); + } + /* Tell the wdog start/stop/trigger functions our dev is gone */ + data->addr = 0; + data->io_lock = NULL; + mutex_unlock(&data->watchdog_lock); + + mutex_lock(&watchdog_data_mutex); + kref_put(&data->kref, sch56xx_watchdog_release_resources); + mutex_unlock(&watchdog_data_mutex); +} +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) { diff --git a/drivers/hwmon/sch56xx-common.h b/drivers/hwmon/sch56xx-common.h index d5eaf3b9ebf5..7475086eb978 100644 --- a/drivers/hwmon/sch56xx-common.h +++ b/drivers/hwmon/sch56xx-common.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> * + * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -17,8 +17,16 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include <linux/mutex.h> + +struct sch56xx_watchdog_data; + int sch56xx_read_virtual_reg(u16 addr, u16 reg); int sch56xx_write_virtual_reg(u16 addr, u16 reg, u8 val); int sch56xx_read_virtual_reg16(u16 addr, u16 reg); int sch56xx_read_virtual_reg12(u16 addr, u16 msb_reg, u16 lsn_reg, int high_nibble); + +struct sch56xx_watchdog_data *sch56xx_watchdog_register( + u16 addr, u32 revision, struct mutex *io_lock, int check_enabled); +void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data); diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 91fdd1fe18b0..8b011d016621 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -806,7 +806,7 @@ static void sht15_bh_read_data(struct work_struct *work_s) */ atomic_set(&data->interrupt_handled, 0); enable_irq(gpio_to_irq(data->pdata->gpio_data)); - /* If still not occurred or another handler has been scheduled */ + /* If still not occurred or another handler was scheduled */ if (gpio_get_value(data->pdata->gpio_data) || atomic_read(&data->interrupt_handled)) return; diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c index 15398780cc00..6c2dede4b8e7 100644 --- a/drivers/hwmon/sht21.c +++ b/drivers/hwmon/sht21.c @@ -261,28 +261,7 @@ static struct i2c_driver sht21_driver = { .id_table = sht21_id, }; -/** - * sht21_init() - initialize driver - * - * Called when kernel is booted or module is inserted. - * Returns 0 on success. - */ -static int __init sht21_init(void) -{ - return i2c_add_driver(&sht21_driver); -} -module_init(sht21_init); - -/** - * sht21_init() - clean up driver - * - * Called when module is removed. - */ -static void __exit sht21_exit(void) -{ - i2c_del_driver(&sht21_driver); -} -module_exit(sht21_exit); +module_i2c_driver(sht21_driver); MODULE_AUTHOR("Urs Fleisch <urs.fleisch@sensirion.com>"); MODULE_DESCRIPTION("Sensirion SHT21 humidity and temperature sensor driver"); diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 47d7ce9af8fb..6c4d8eb9b7ca 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -1,54 +1,54 @@ /* - sis5595.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring - - Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, - Kyösti Mälkki <kmalkki@cc.hut.fi>, and - Mark D. Studebaker <mdsxyz123@yahoo.com> - Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with - the help of Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * sis5595.c - Part of lm_sensors, Linux kernel modules + * for hardware monitoring + * + * Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, + * Kyösti Mälkki <kmalkki@cc.hut.fi>, and + * Mark D. Studebaker <mdsxyz123@yahoo.com> + * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with + * the help of Jean Delvare <khali@linux-fr.org> + * + * 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. + */ /* - SiS southbridge has a LM78-like chip integrated on the same IC. - This driver is a customized copy of lm78.c - - Supports following revisions: - Version PCI ID PCI Revision - 1 1039/0008 AF or less - 2 1039/0008 B0 or greater - - Note: these chips contain a 0008 device which is incompatible with the - 5595. We recognize these by the presence of the listed - "blacklist" PCI ID and refuse to load. - - NOT SUPPORTED PCI ID BLACKLIST PCI ID - 540 0008 0540 - 550 0008 0550 - 5513 0008 5511 - 5581 0008 5597 - 5582 0008 5597 - 5597 0008 5597 - 5598 0008 5597/5598 - 630 0008 0630 - 645 0008 0645 - 730 0008 0730 - 735 0008 0735 -*/ + * SiS southbridge has a LM78-like chip integrated on the same IC. + * This driver is a customized copy of lm78.c + * + * Supports following revisions: + * Version PCI ID PCI Revision + * 1 1039/0008 AF or less + * 2 1039/0008 B0 or greater + * + * Note: these chips contain a 0008 device which is incompatible with the + * 5595. We recognize these by the presence of the listed + * "blacklist" PCI ID and refuse to load. + * + * NOT SUPPORTED PCI ID BLACKLIST PCI ID + * 540 0008 0540 + * 550 0008 0550 + * 5513 0008 5511 + * 5581 0008 5597 + * 5582 0008 5597 + * 5597 0008 5597 + * 5598 0008 5597/5598 + * 630 0008 0630 + * 645 0008 0645 + * 730 0008 0730 + * 735 0008 0735 + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -68,8 +68,10 @@ #include <linux/io.h> -/* If force_addr is set to anything different from 0, we forcibly enable - the device at the given address. */ +/* + * If force_addr is set to anything different from 0, we forcibly enable + * the device at the given address. + */ static u16 force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, @@ -98,30 +100,36 @@ static struct platform_device *pdev; #define SIS5595_REG_FAN_MIN(nr) (0x3b + (nr)) #define SIS5595_REG_FAN(nr) (0x28 + (nr)) -/* On the first version of the chip, the temp registers are separate. - On the second version, - TEMP pin is shared with IN4, configured in PCI register 0x7A. - The registers are the same as well. - OVER and HYST are really MAX and MIN. */ +/* + * On the first version of the chip, the temp registers are separate. + * On the second version, + * TEMP pin is shared with IN4, configured in PCI register 0x7A. + * The registers are the same as well. + * OVER and HYST are really MAX and MIN. + */ #define REV2MIN 0xb0 -#define SIS5595_REG_TEMP (( data->revision) >= REV2MIN) ? \ - SIS5595_REG_IN(4) : 0x27 -#define SIS5595_REG_TEMP_OVER (( data->revision) >= REV2MIN) ? \ - SIS5595_REG_IN_MAX(4) : 0x39 -#define SIS5595_REG_TEMP_HYST (( data->revision) >= REV2MIN) ? \ - SIS5595_REG_IN_MIN(4) : 0x3a +#define SIS5595_REG_TEMP (((data->revision) >= REV2MIN) ? \ + SIS5595_REG_IN(4) : 0x27) +#define SIS5595_REG_TEMP_OVER (((data->revision) >= REV2MIN) ? \ + SIS5595_REG_IN_MAX(4) : 0x39) +#define SIS5595_REG_TEMP_HYST (((data->revision) >= REV2MIN) ? \ + SIS5595_REG_IN_MIN(4) : 0x3a) #define SIS5595_REG_CONFIG 0x40 #define SIS5595_REG_ALARM1 0x41 #define SIS5595_REG_ALARM2 0x42 #define SIS5595_REG_FANDIV 0x47 -/* Conversions. Limit checking is only done on the TO_REG - variants. */ +/* + * Conversions. Limit checking is only done on the TO_REG + * variants. + */ -/* IN: mV, (0V to 4.08V) - REG: 16mV/bit */ +/* + * IN: mV, (0V to 4.08V) + * REG: 16mV/bit + */ static inline u8 IN_TO_REG(unsigned long val) { unsigned long nval = SENSORS_LIMIT(val, 0, 4080); @@ -138,11 +146,13 @@ static inline u8 FAN_TO_REG(long rpm, int div) static inline int FAN_FROM_REG(u8 val, int div) { - return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div); + return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div); } -/* TEMP: mC (-54.12C to +157.53C) - REG: 0.83C/bit + 52.12, two's complement */ +/* + * TEMP: mC (-54.12C to +157.53C) + * REG: 0.83C/bit + 52.12, two's complement + */ static inline int TEMP_FROM_REG(s8 val) { return val * 830 + 52120; @@ -150,19 +160,23 @@ static inline int TEMP_FROM_REG(s8 val) static inline s8 TEMP_TO_REG(int val) { int nval = SENSORS_LIMIT(val, -54120, 157530) ; - return nval<0 ? (nval-5212-415)/830 : (nval-5212+415)/830; + return nval < 0 ? (nval - 5212 - 415) / 830 : (nval - 5212 + 415) / 830; } -/* FAN DIV: 1, 2, 4, or 8 (defaults to 2) - REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */ +/* + * FAN DIV: 1, 2, 4, or 8 (defaults to 2) + * REG: 0, 1, 2, or 3 (respectively) (defaults to 1) + */ static inline u8 DIV_TO_REG(int val) { - return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1; + return val == 8 ? 3 : val == 4 ? 2 : val == 1 ? 0 : 1; } #define DIV_FROM_REG(val) (1 << (val)) -/* For each registered chip, we need to keep some data in memory. - The structure is dynamically allocated. */ +/* + * For each registered chip, we need to keep some data in memory. + * The structure is dynamically allocated. + */ struct sis5595_data { unsigned short addr; const char *name; @@ -240,7 +254,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *da, struct sis5595_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val); @@ -255,7 +274,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da, struct sis5595_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val); @@ -279,22 +303,30 @@ show_in_offset(3); show_in_offset(4); /* Temperature */ -static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) { struct sis5595_data *data = sis5595_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp)); } -static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, + char *buf) { struct sis5595_data *data = sis5595_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over)); } -static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct sis5595_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_over = TEMP_TO_REG(val); @@ -303,16 +335,23 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, + char *buf) { struct sis5595_data *data = sis5595_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst)); } -static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct sis5595_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_hyst = TEMP_TO_REG(val); @@ -335,7 +374,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], - DIV_FROM_REG(data->fan_div[nr])) ); + DIV_FROM_REG(data->fan_div[nr]))); } static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, @@ -344,8 +383,8 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, struct sis5595_data *data = sis5595_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], - DIV_FROM_REG(data->fan_div[nr])) ); + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr]))); } static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, @@ -354,7 +393,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, struct sis5595_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -369,13 +413,15 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, struct sis5595_data *data = sis5595_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); + return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -383,8 +429,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; unsigned long min; - unsigned long val = simple_strtoul(buf, NULL, 10); int reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], @@ -392,17 +443,25 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, reg = sis5595_read_value(data, SIS5595_REG_FANDIV); switch (val) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; + case 1: + data->fan_div[nr] = 0; + break; + case 2: + data->fan_div[nr] = 1; + break; + case 4: + data->fan_div[nr] = 2; + break; + case 8: + data->fan_div[nr] = 3; + break; default: dev_err(dev, "fan_div value %ld not " "supported. Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } - + switch (nr) { case 0: reg = (reg & 0xcf) | (data->fan_div[nr] << 4); @@ -431,7 +490,8 @@ show_fan_offset(1); show_fan_offset(2); /* Alarms */ -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, + char *buf) { struct sis5595_data *data = sis5595_update_device(dev); return sprintf(buf, "%d\n", data->alarms); @@ -521,7 +581,7 @@ static struct attribute *sis5595_attributes_temp1[] = { static const struct attribute_group sis5595_group_temp1 = { .attrs = sis5595_attributes_temp1, }; - + /* This is called when the module is loaded */ static int __devinit sis5595_probe(struct platform_device *pdev) { @@ -539,7 +599,8 @@ static int __devinit sis5595_probe(struct platform_device *pdev) goto exit; } - if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto exit_release; } @@ -550,7 +611,9 @@ static int __devinit sis5595_probe(struct platform_device *pdev) data->name = "sis5595"; platform_set_drvdata(pdev, data); - /* Check revision and pin registers to determine whether 4 or 5 voltages */ + /* + * Check revision and pin registers to determine whether 4 or 5 voltages + */ data->revision = s_bridge->revision; /* 4 voltages, 1 temp */ data->maxins = 3; @@ -560,7 +623,7 @@ static int __devinit sis5595_probe(struct platform_device *pdev) /* 5 voltages, no temps */ data->maxins = 4; } - + /* Initialize the SIS5595 chip */ sis5595_init_device(data); @@ -571,15 +634,16 @@ static int __devinit sis5595_probe(struct platform_device *pdev) } /* Register sysfs hooks */ - if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group))) + err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group); + if (err) goto exit_free; if (data->maxins == 4) { - if ((err = sysfs_create_group(&pdev->dev.kobj, - &sis5595_group_in4))) + err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group_in4); + if (err) goto exit_remove_files; } else { - if ((err = sysfs_create_group(&pdev->dev.kobj, - &sis5595_group_temp1))) + err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group_temp1); + if (err) goto exit_remove_files; } @@ -699,7 +763,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev) return data; } -static const struct pci_device_id sis5595_pci_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(sis5595_pci_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, { 0, } }; @@ -713,9 +777,11 @@ static int blacklist[] __devinitdata = { PCI_DEVICE_ID_SI_645, PCI_DEVICE_ID_SI_730, PCI_DEVICE_ID_SI_735, - PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but - that ID shows up in other chips so we - use the 5511 ID for recognition */ + PCI_DEVICE_ID_SI_5511, /* + * 5513 chip has the 0008 device but + * that ID shows up in other chips so we + * use the 5511 ID for recognition + */ PCI_DEVICE_ID_SI_5597, PCI_DEVICE_ID_SI_5598, 0 }; @@ -770,13 +836,16 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, for (i = blacklist; *i != 0; i++) { struct pci_dev *d; - if ((d = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL))) { - dev_err(&d->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i); + d = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL); + if (d) { + dev_err(&d->dev, + "Looked for SIS5595 but found unsupported device %.4x\n", + *i); pci_dev_put(d); return -ENODEV; } } - + force_addr &= ~(SIS5595_EXTENT - 1); if (force_addr) { dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", force_addr); @@ -788,10 +857,11 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, dev_err(&dev->dev, "Failed to read ISA address\n"); return -ENODEV; } - + address &= ~(SIS5595_EXTENT - 1); if (!address) { - dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); + dev_err(&dev->dev, + "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); return -ENODEV; } if (force_addr && address != force_addr) { @@ -828,7 +898,8 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, if (sis5595_device_add(address)) goto exit_unregister; - /* Always return failure here. This is to allow other drivers to bind + /* + * Always return failure here. This is to allow other drivers to bind * to this pci device. We don't really want to have control over the * pci device, we only wanted to read as few register values from it. */ diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c index 411638181fd8..cbc51fb30dba 100644 --- a/drivers/hwmon/smm665.c +++ b/drivers/hwmon/smm665.c @@ -124,9 +124,9 @@ enum chips { smm465, smm665, smm665c, smm764, smm766 }; #define SMM665_AIN_ADC_TO_VOLTS(adc) ((adc) * vref / 512) /* Temp Sensor */ -#define SMM665_TEMP_ADC_TO_CELSIUS(adc) ((adc) <= 511) ? \ +#define SMM665_TEMP_ADC_TO_CELSIUS(adc) (((adc) <= 511) ? \ ((int)(adc) * 1000 / 4) : \ - (((int)(adc) - 0x400) * 1000 / 4) + (((int)(adc) - 0x400) * 1000 / 4)) #define SMM665_NUM_ADC 11 @@ -376,7 +376,7 @@ static ssize_t smm665_show_input(struct device *dev, } #define SMM665_SHOW(what) \ - static ssize_t smm665_show_##what(struct device *dev, \ +static ssize_t smm665_show_##what(struct device *dev, \ struct device_attribute *da, char *buf) \ { \ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ @@ -389,7 +389,8 @@ SMM665_SHOW(max); SMM665_SHOW(lcrit); SMM665_SHOW(crit); -/* These macros are used below in constructing device attribute objects +/* + * These macros are used below in constructing device attribute objects * for use with sysfs_create_group() to make a sysfs device file * for each register. */ @@ -583,10 +584,9 @@ static int smm665_probe(struct i2c_client *client, if (i2c_smbus_read_byte_data(client, SMM665_ADOC_ENABLE) < 0) return -ENODEV; - ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (!data) - goto out_return; + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -595,7 +595,7 @@ static int smm665_probe(struct i2c_client *client, data->cmdreg = i2c_new_dummy(adapter, (client->addr & ~SMM665_REGMASK) | SMM665_CMDREG_BASE); if (!data->cmdreg) - goto out_kfree; + return -ENOMEM; switch (data->type) { case smm465: @@ -678,9 +678,6 @@ out_remove_group: sysfs_remove_group(&client->dev.kobj, &smm665_group); out_unregister: i2c_unregister_device(data->cmdreg); -out_kfree: - kfree(data); -out_return: return ret; } @@ -692,8 +689,6 @@ static int smm665_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &smm665_group); - kfree(data); - return 0; } @@ -718,19 +713,8 @@ static struct i2c_driver smm665_driver = { .id_table = smm665_id, }; -static int __init smm665_init(void) -{ - return i2c_add_driver(&smm665_driver); -} - -static void __exit smm665_exit(void) -{ - i2c_del_driver(&smm665_driver); -} +module_i2c_driver(smm665_driver); MODULE_AUTHOR("Guenter Roeck"); MODULE_DESCRIPTION("SMM665 driver"); MODULE_LICENSE("GPL"); - -module_init(smm665_init); -module_exit(smm665_exit); diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 65c88ff5645a..d3b778da3f86 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -1,30 +1,30 @@ /* - smsc47b397.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring - - Supports the SMSC LPC47B397-NC Super-I/O chip. - - Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> - Copyright (C) 2004 Utilitek Systems, Inc. - - derived in part from smsc47m1.c: - Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> - Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * smsc47b397.c - Part of lm_sensors, Linux kernel modules + * for hardware monitoring + * + * Supports the SMSC LPC47B397-NC Super-I/O chip. + * + * Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> + * Copyright (C) 2004 Utilitek Systems, Inc. + * + * derived in part from smsc47m1.c: + * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> + * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> + * + * 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. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -157,8 +157,10 @@ static struct smsc47b397_data *smsc47b397_update_device(struct device *dev) return data; } -/* TEMP: 0.001C/bit (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: 0.001C/bit (-128C to +127C) + * REG: 1C/bit, two's complement + */ static int temp_from_reg(u8 reg) { return (s8)reg * 1000; @@ -177,8 +179,10 @@ static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); -/* FAN: 1 RPM/bit - REG: count of 90kHz pulses / revolution */ +/* + * FAN: 1 RPM/bit + * REG: count of 90kHz pulses / revolution + */ static int fan_from_reg(u16 reg) { if (reg == 0 || reg == 0xffff) diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index f44a89aac381..c590c1469793 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -1,30 +1,30 @@ /* - smsc47m1.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring - - Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, - LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997 - Super-I/O chips. - - Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> - Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org> - Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com> - and Jean Delvare - - 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. -*/ + * smsc47m1.c - Part of lm_sensors, Linux kernel modules + * for hardware monitoring + * + * Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, + * LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997 + * Super-I/O chips. + * + * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> + * Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org> + * Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com> + * and Jean Delvare + * + * 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. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -53,8 +53,8 @@ enum chips { smsc47m1, smsc47m2 }; /* Super-I/0 registers and commands */ -#define REG 0x2e /* The register to read/write */ -#define VAL 0x2f /* The value to read/write */ +#define REG 0x2e /* The register to read/write */ +#define VAL 0x2f /* The value to read/write */ static inline void superio_outb(int reg, int val) @@ -111,10 +111,11 @@ static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 }; #define SMSC47M2_REG_PPIN3 0x2c #define SMSC47M2_REG_FANDIV3 0x6a -#define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \ - 983040/((192-(reg))*(div))) -#define FAN_FROM_REG(reg,div,preload) ((reg)<=(preload) || (reg)==255 ? 0 : \ - 983040/(((reg)-(preload))*(div))) +#define MIN_FROM_REG(reg, div) ((reg) >= 192 ? 0 : \ + 983040 / ((192 - (reg)) * (div))) +#define FAN_FROM_REG(reg, div, preload) ((reg) <= (preload) || (reg) == 255 ? \ + 0 : \ + 983040 / (((reg) - (preload)) * (div))) #define DIV_FROM_REG(reg) (1 << (reg)) #define PWM_FROM_REG(reg) (((reg) & 0x7E) << 1) #define PWM_EN_FROM_REG(reg) ((~(reg)) & 0x01) @@ -171,10 +172,12 @@ static ssize_t get_fan(struct device *dev, struct device_attribute struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); int nr = attr->index; - /* This chip (stupidly) stops monitoring fan speed if PWM is - enabled and duty cycle is 0%. This is fine if the monitoring - and control concern the same fan, but troublesome if they are - not (which could as well happen). */ + /* + * This chip (stupidly) stops monitoring fan speed if PWM is + * enabled and duty cycle is 0%. This is fine if the monitoring + * and control concern the same fan, but troublesome if they are + * not (which could as well happen). + */ int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 : FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]), @@ -238,7 +241,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = dev_get_drvdata(dev); int nr = attr->index; - long rpmdiv, val = simple_strtol(buf, NULL, 10); + long rpmdiv; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]); @@ -256,28 +265,44 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute return count; } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan clock divider. This follows the principle - of least surprise; the user doesn't expect the fan minimum to change just - because the divider changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan clock divider. This follows the principle + * of least surprise; the user doesn't expect the fan minimum to change just + * because the divider changed. + */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = dev_get_drvdata(dev); int nr = attr->index; - long new_div = simple_strtol(buf, NULL, 10), tmp; + long new_div; + int err; + long tmp; u8 old_div = DIV_FROM_REG(data->fan_div[nr]); + err = kstrtol(buf, 10, &new_div); + if (err) + return err; + if (new_div == old_div) /* No change */ return count; mutex_lock(&data->update_lock); switch (new_div) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; + case 1: + data->fan_div[nr] = 0; + break; + case 2: + data->fan_div[nr] = 1; + break; + case 4: + data->fan_div[nr] = 2; + break; + case 8: + data->fan_div[nr] = 3; + break; default: mutex_unlock(&data->update_lock); return -EINVAL; @@ -315,7 +340,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = dev_get_drvdata(dev); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; if (val < 0 || val > 255) return -EINVAL; @@ -336,9 +366,14 @@ static ssize_t set_pwm_en(struct device *dev, struct device_attribute struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = dev_get_drvdata(dev); int nr = attr->index; - long val = simple_strtol(buf, NULL, 10); - - if (val != 0 && val != 1) + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + if (val > 1) return -EINVAL; mutex_lock(&data->update_lock); @@ -380,30 +415,73 @@ static ssize_t show_name(struct device *dev, struct device_attribute } static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -/* Almost all sysfs files may or may not be created depending on the chip - setup so we create them individually. It is still convenient to define a - group to remove them all at once. */ -static struct attribute *smsc47m1_attributes[] = { +static struct attribute *smsc47m1_attributes_fan1[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan1_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group_fan1 = { + .attrs = smsc47m1_attributes_fan1, +}; + +static struct attribute *smsc47m1_attributes_fan2[] = { &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, &sensor_dev_attr_fan2_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group_fan2 = { + .attrs = smsc47m1_attributes_fan2, +}; + +static struct attribute *smsc47m1_attributes_fan3[] = { &sensor_dev_attr_fan3_input.dev_attr.attr, &sensor_dev_attr_fan3_min.dev_attr.attr, &sensor_dev_attr_fan3_div.dev_attr.attr, &sensor_dev_attr_fan3_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group_fan3 = { + .attrs = smsc47m1_attributes_fan3, +}; +static struct attribute *smsc47m1_attributes_pwm1[] = { &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group_pwm1 = { + .attrs = smsc47m1_attributes_pwm1, +}; + +static struct attribute *smsc47m1_attributes_pwm2[] = { &sensor_dev_attr_pwm2.dev_attr.attr, &sensor_dev_attr_pwm2_enable.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group_pwm2 = { + .attrs = smsc47m1_attributes_pwm2, +}; + +static struct attribute *smsc47m1_attributes_pwm3[] = { &sensor_dev_attr_pwm3.dev_attr.attr, &sensor_dev_attr_pwm3_enable.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group_pwm3 = { + .attrs = smsc47m1_attributes_pwm3, +}; +static struct attribute *smsc47m1_attributes[] = { &dev_attr_alarms.attr, &dev_attr_name.attr, NULL @@ -476,8 +554,10 @@ static int __init smsc47m1_find(unsigned short *addr, return -ENODEV; } - /* Enable only if address is set (needed at least on the - * Compaq Presario S4000NX) */ + /* + * Enable only if address is set (needed at least on the + * Compaq Presario S4000NX) + */ sio_data->activate = superio_inb(SUPERIO_REG_ACT); if ((sio_data->activate & 0x01) == 0) { pr_info("Enabling device\n"); @@ -583,6 +663,17 @@ static int smsc47m1_handle_resources(unsigned short address, enum chips type, return 0; } +static void smsc47m1_remove_files(struct device *dev) +{ + sysfs_remove_group(&dev->kobj, &smsc47m1_group); + sysfs_remove_group(&dev->kobj, &smsc47m1_group_fan1); + sysfs_remove_group(&dev->kobj, &smsc47m1_group_fan2); + sysfs_remove_group(&dev->kobj, &smsc47m1_group_fan3); + sysfs_remove_group(&dev->kobj, &smsc47m1_group_pwm1); + sysfs_remove_group(&dev->kobj, &smsc47m1_group_pwm2); + sysfs_remove_group(&dev->kobj, &smsc47m1_group_pwm3); +} + static int __init smsc47m1_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -592,7 +683,7 @@ static int __init smsc47m1_probe(struct platform_device *pdev) int err; int fan1, fan2, fan3, pwm1, pwm2, pwm3; - static const char *names[] = { + static const char * const names[] = { "smsc47m1", "smsc47m2", }; @@ -603,7 +694,8 @@ static int __init smsc47m1_probe(struct platform_device *pdev) if (err < 0) return err; - if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto error_release; } @@ -614,8 +706,10 @@ static int __init smsc47m1_probe(struct platform_device *pdev) mutex_init(&data->update_lock); platform_set_drvdata(pdev, data); - /* If no function is properly configured, there's no point in - actually registering the chip. */ + /* + * If no function is properly configured, there's no point in + * actually registering the chip. + */ pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05) == 0x04; pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05) @@ -643,84 +737,67 @@ static int __init smsc47m1_probe(struct platform_device *pdev) goto error_free; } - /* Some values (fan min, clock dividers, pwm registers) may be - needed before any update is triggered, so we better read them - at least once here. We don't usually do it that way, but in - this particular case, manually reading 5 registers out of 8 - doesn't make much sense and we're better using the existing - function. */ + /* + * Some values (fan min, clock dividers, pwm registers) may be + * needed before any update is triggered, so we better read them + * at least once here. We don't usually do it that way, but in + * this particular case, manually reading 5 registers out of 8 + * doesn't make much sense and we're better using the existing + * function. + */ smsc47m1_update_device(dev, 1); /* Register sysfs hooks */ if (fan1) { - if ((err = device_create_file(dev, - &sensor_dev_attr_fan1_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan1_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan1_div.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan1_alarm.dev_attr))) + err = sysfs_create_group(&dev->kobj, + &smsc47m1_group_fan1); + if (err) goto error_remove_files; } else dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n"); if (fan2) { - if ((err = device_create_file(dev, - &sensor_dev_attr_fan2_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan2_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan2_div.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan2_alarm.dev_attr))) + err = sysfs_create_group(&dev->kobj, + &smsc47m1_group_fan2); + if (err) goto error_remove_files; } else dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n"); if (fan3) { - if ((err = device_create_file(dev, - &sensor_dev_attr_fan3_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan3_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan3_div.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan3_alarm.dev_attr))) + err = sysfs_create_group(&dev->kobj, + &smsc47m1_group_fan3); + if (err) goto error_remove_files; } else if (data->type == smsc47m2) dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); if (pwm1) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm1.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm1_enable.dev_attr))) + err = sysfs_create_group(&dev->kobj, + &smsc47m1_group_pwm1); + if (err) goto error_remove_files; } else dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n"); if (pwm2) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm2.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm2_enable.dev_attr))) + err = sysfs_create_group(&dev->kobj, + &smsc47m1_group_pwm2); + if (err) goto error_remove_files; } else dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n"); if (pwm3) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm3.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm3_enable.dev_attr))) + err = sysfs_create_group(&dev->kobj, + &smsc47m1_group_pwm3); + if (err) goto error_remove_files; } else if (data->type == smsc47m2) dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); - if ((err = device_create_file(dev, &dev_attr_alarms))) - goto error_remove_files; - if ((err = device_create_file(dev, &dev_attr_name))) + err = sysfs_create_group(&dev->kobj, &smsc47m1_group); + if (err) goto error_remove_files; data->hwmon_dev = hwmon_device_register(dev); @@ -732,7 +809,7 @@ static int __init smsc47m1_probe(struct platform_device *pdev) return 0; error_remove_files: - sysfs_remove_group(&dev->kobj, &smsc47m1_group); + smsc47m1_remove_files(dev); error_free: platform_set_drvdata(pdev, NULL); kfree(data); @@ -747,7 +824,7 @@ static int __exit smsc47m1_remove(struct platform_device *pdev) struct resource *res; hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); + smsc47m1_remove_files(&pdev->dev); res = platform_get_resource(pdev, IORESOURCE_IO, 0); smsc47m1_handle_resources(res->start, data->type, RELEASE, &pdev->dev); diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 40b26673d87f..4705a8bf11c2 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -1,25 +1,25 @@ /* - smsc47m192.c - Support for hardware monitoring block of - SMSC LPC47M192 and compatible Super I/O chips - - Copyright (C) 2006 Hartmut Rick <linux@rick.claranet.de> - - Derived from lm78.c and other chip drivers. - - 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. -*/ + * smsc47m192.c - Support for hardware monitoring block of + * SMSC LPC47M192 and compatible Super I/O chips + * + * Copyright (C) 2006 Hartmut Rick <linux@rick.claranet.de> + * + * Derived from lm78.c and other chip drivers. + * + * 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 <linux/module.h> #include <linux/init.h> @@ -37,16 +37,16 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* SMSC47M192 registers */ -#define SMSC47M192_REG_IN(nr) ((nr)<6 ? (0x20 + (nr)) : \ +#define SMSC47M192_REG_IN(nr) ((nr) < 6 ? (0x20 + (nr)) : \ (0x50 + (nr) - 6)) -#define SMSC47M192_REG_IN_MAX(nr) ((nr)<6 ? (0x2b + (nr) * 2) : \ +#define SMSC47M192_REG_IN_MAX(nr) ((nr) < 6 ? (0x2b + (nr) * 2) : \ (0x54 + (((nr) - 6) * 2))) -#define SMSC47M192_REG_IN_MIN(nr) ((nr)<6 ? (0x2c + (nr) * 2) : \ +#define SMSC47M192_REG_IN_MIN(nr) ((nr) < 6 ? (0x2c + (nr) * 2) : \ (0x55 + (((nr) - 6) * 2))) static u8 SMSC47M192_REG_TEMP[3] = { 0x27, 0x26, 0x52 }; static u8 SMSC47M192_REG_TEMP_MAX[3] = { 0x39, 0x37, 0x58 }; static u8 SMSC47M192_REG_TEMP_MIN[3] = { 0x3A, 0x38, 0x59 }; -#define SMSC47M192_REG_TEMP_OFFSET(nr) ((nr)==2 ? 0x1e : 0x1f) +#define SMSC47M192_REG_TEMP_OFFSET(nr) ((nr) == 2 ? 0x1e : 0x1f) #define SMSC47M192_REG_ALARM1 0x41 #define SMSC47M192_REG_ALARM2 0x42 #define SMSC47M192_REG_VID 0x47 @@ -80,8 +80,10 @@ static inline u8 IN_TO_REG(unsigned long val, int n) return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255); } -/* TEMP: 0.001 degC units (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: 0.001 degC units (-128C to +127C) + * REG: 1C/bit, two's complement + */ static inline s8 TEMP_TO_REG(int val) { return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000); @@ -170,7 +172,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct smsc47m192_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val, nr); @@ -187,7 +194,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct smsc47m192_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val, nr); @@ -249,7 +261,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct smsc47m192_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[nr] = TEMP_TO_REG(val); @@ -266,7 +283,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct smsc47m192_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[nr] = TEMP_TO_REG(val); @@ -293,22 +315,29 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute struct i2c_client *client = to_i2c_client(dev); struct smsc47m192_data *data = i2c_get_clientdata(client); u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_offset[nr] = TEMP_TO_REG(val); - if (nr>1) + if (nr > 1) i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]); else if (data->temp_offset[nr] != 0) { - /* offset[0] and offset[1] share the same register, - SFR bit 4 activates offset[0] */ + /* + * offset[0] and offset[1] share the same register, + * SFR bit 4 activates offset[0] + */ i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, - (sfr & 0xef) | (nr==0 ? 0x10 : 0)); + (sfr & 0xef) | (nr == 0 ? 0x10 : 0)); data->temp_offset[1-nr] = 0; i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]); - } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) + } else if ((sfr & 0x10) == (nr == 0 ? 0x10 : 0)) i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_OFFSET(nr), 0); mutex_unlock(&data->update_lock); @@ -349,7 +378,14 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct smsc47m192_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + data->vrm = val; return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); @@ -458,13 +494,13 @@ static void smsc47m192_init_client(struct i2c_client *client) (sfr & 0xfd) | 0x02); if (!(config & 0x01)) { /* initialize alarm limits */ - for (i=0; i<8; i++) { + for (i = 0; i < 8; i++) { i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(i), 0); i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(i), 0xff); } - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[i], 0x80); i2c_smbus_write_byte_data(client, @@ -532,14 +568,16 @@ static int smsc47m192_probe(struct i2c_client *client, smsc47m192_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group))) + err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group); + if (err) goto exit_free; /* Pin 110 is either in4 (+12V) or VID4 */ config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); if (!(config & 0x20)) { - if ((err = sysfs_create_group(&client->dev.kobj, - &smsc47m192_group_in4))) + err = sysfs_create_group(&client->dev.kobj, + &smsc47m192_group_in4); + if (err) goto exit_remove_files; } @@ -606,8 +644,10 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) for (i = 1; i < 3; i++) data->temp_offset[i] = i2c_smbus_read_byte_data(client, SMSC47M192_REG_TEMP_OFFSET(i)); - /* first offset is temp_offset[0] if SFR bit 4 is set, - temp_offset[1] otherwise */ + /* + * first offset is temp_offset[0] if SFR bit 4 is set, + * temp_offset[1] otherwise + */ if (sfr & 0x10) { data->temp_offset[0] = data->temp_offset[1]; data->temp_offset[1] = 0; @@ -624,7 +664,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) data->alarms = i2c_smbus_read_byte_data(client, SMSC47M192_REG_ALARM1) | (i2c_smbus_read_byte_data(client, - SMSC47M192_REG_ALARM2) << 8); + SMSC47M192_REG_ALARM2) << 8); data->last_updated = jiffies; data->valid = 1; @@ -635,19 +675,8 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) return data; } -static int __init smsc47m192_init(void) -{ - return i2c_add_driver(&smsc47m192_driver); -} - -static void __exit smsc47m192_exit(void) -{ - i2c_del_driver(&smsc47m192_driver); -} +module_i2c_driver(smsc47m192_driver); MODULE_AUTHOR("Hartmut Rick <linux@rick.claranet.de>"); MODULE_DESCRIPTION("SMSC47M192 driver"); MODULE_LICENSE("GPL"); - -module_init(smsc47m192_init); -module_exit(smsc47m192_exit); diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 7dfb4dec4c5f..add9f019b24f 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -1,24 +1,24 @@ /* - thmc50.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl> - Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and - Philip Edelbrock <phil@netroedge.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * thmc50.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl> + * Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and + * Philip Edelbrock <phil@netroedge.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #include <linux/module.h> #include <linux/init.h> @@ -124,8 +124,13 @@ static ssize_t set_analog_out(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct thmc50_data *data = i2c_get_clientdata(client); - int tmp = simple_strtoul(buf, NULL, 10); int config; + unsigned long tmp; + int err; + + err = kstrtoul(buf, 10, &tmp); + if (err) + return err; mutex_lock(&data->update_lock); data->analog_out = SENSORS_LIMIT(tmp, 0, 255); @@ -173,7 +178,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct thmc50_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[nr] = SENSORS_LIMIT(val / 1000, -128, 127); @@ -197,7 +207,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct thmc50_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[nr] = SENSORS_LIMIT(val / 1000, -128, 127); @@ -360,14 +375,16 @@ static int thmc50_probe(struct i2c_client *client, thmc50_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &thmc50_group))) + err = sysfs_create_group(&client->dev.kobj, &thmc50_group); + if (err) goto exit_free; /* Register ADM1022 sysfs hooks */ - if (data->has_temp3) - if ((err = sysfs_create_group(&client->dev.kobj, - &temp3_group))) + if (data->has_temp3) { + err = sysfs_create_group(&client->dev.kobj, &temp3_group); + if (err) goto exit_remove_sysfs_thmc50; + } /* Register a new directory entry with module sensors */ data->hwmon_dev = hwmon_device_register(&client->dev); @@ -465,18 +482,7 @@ static struct thmc50_data *thmc50_update_device(struct device *dev) return data; } -static int __init sm_thmc50_init(void) -{ - return i2c_add_driver(&thmc50_driver); -} - -static void __exit sm_thmc50_exit(void) -{ - i2c_del_driver(&thmc50_driver); -} +module_i2c_driver(thmc50_driver); MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>"); MODULE_DESCRIPTION("THMC50 driver"); - -module_init(sm_thmc50_init); -module_exit(sm_thmc50_exit); diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index c08eee21d76e..0d466b9d8908 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -292,17 +292,7 @@ static struct i2c_driver tmp102_driver = { .id_table = tmp102_id, }; -static int __init tmp102_init(void) -{ - return i2c_add_driver(&tmp102_driver); -} -module_init(tmp102_init); - -static void __exit tmp102_exit(void) -{ - i2c_del_driver(&tmp102_driver); -} -module_exit(tmp102_exit); +module_i2c_driver(tmp102_driver); MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index 8b9a77486d57..ea54c3384671 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -624,7 +624,7 @@ static int tmp401_probe(struct i2c_client *client, goto exit_remove; } - /* Register aditional tmp411 sysfs hooks */ + /* Register additional tmp411 sysfs hooks */ if (data->kind == tmp411) { for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) { err = device_create_file(&client->dev, @@ -662,19 +662,8 @@ static struct i2c_driver tmp401_driver = { .address_list = normal_i2c, }; -static int __init tmp401_init(void) -{ - return i2c_add_driver(&tmp401_driver); -} - -static void __exit tmp401_exit(void) -{ - i2c_del_driver(&tmp401_driver); -} +module_i2c_driver(tmp401_driver); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver"); MODULE_LICENSE("GPL"); - -module_init(tmp401_init); -module_exit(tmp401_exit); diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index c48381f2cd02..8fac87a38544 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -324,20 +324,9 @@ static struct i2c_driver tmp421_driver = { .address_list = normal_i2c, }; -static int __init tmp421_init(void) -{ - return i2c_add_driver(&tmp421_driver); -} - -static void __exit tmp421_exit(void) -{ - i2c_del_driver(&tmp421_driver); -} +module_i2c_driver(tmp421_driver); MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" " driver"); MODULE_LICENSE("GPL"); - -module_init(tmp421_init); -module_exit(tmp421_exit); diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index b9a87e89bab4..c315c59f61fe 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -1,4 +1,5 @@ -/* ultra45_env.c: Driver for Ultra45 PIC16F747 environmental monitor. +/* + * ultra45_env.c: Driver for Ultra45 PIC16F747 environmental monitor. * * Copyright (C) 2008 David S. Miller <davem@davemloft.net> */ @@ -82,7 +83,8 @@ static void env_write(struct env *p, u8 ireg, u8 val) spin_unlock(&p->lock); } -/* There seems to be a adr7462 providing these values, thus a lot +/* + * There seems to be a adr7462 providing these values, thus a lot * of these calculations are borrowed from the adt7470 driver. */ #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) @@ -90,7 +92,8 @@ static void env_write(struct env *p, u8 ireg, u8 val) #define FAN_PERIOD_INVALID (0xff << 8) #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) -static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, + char *buf) { int fan_nr = to_sensor_dev_attr(attr)->index; struct env *p = dev_get_drvdata(dev); @@ -111,10 +114,15 @@ static ssize_t set_fan_speed(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int fan_nr = to_sensor_dev_attr(attr)->index; - int rpm = simple_strtol(buf, NULL, 10); + unsigned long rpm; struct env *p = dev_get_drvdata(dev); int period; u8 val; + int err; + + err = kstrtoul(buf, 10, &rpm); + if (err) + return err; if (!rpm) return -EINVAL; @@ -126,7 +134,8 @@ static ssize_t set_fan_speed(struct device *dev, struct device_attribute *attr, return count; } -static ssize_t show_fan_fault(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_fan_fault(struct device *dev, struct device_attribute *attr, + char *buf) { int fan_nr = to_sensor_dev_attr(attr)->index; struct env *p = dev_get_drvdata(dev); @@ -148,7 +157,8 @@ fan(4); static SENSOR_DEVICE_ATTR(psu_fan_fault, S_IRUGO, show_fan_fault, NULL, 6); -static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) { int temp_nr = to_sensor_dev_attr(attr)->index; struct env *p = dev_get_drvdata(dev); @@ -168,7 +178,8 @@ static SENSOR_DEVICE_ATTR(lsi1064_local_temp, S_IRUGO, show_temp, NULL, 6); static SENSOR_DEVICE_ATTR(front_panel_temp, S_IRUGO, show_temp, NULL, 7); static SENSOR_DEVICE_ATTR(psu_temp, S_IRUGO, show_temp, NULL, 13); -static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr, + char *buf) { int index = to_sensor_dev_attr(attr)->index; struct env *p = dev_get_drvdata(dev); @@ -181,9 +192,11 @@ static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr, static SENSOR_DEVICE_ATTR(fan_failure, S_IRUGO, show_stat_bit, NULL, 0); static SENSOR_DEVICE_ATTR(env_bus_busy, S_IRUGO, show_stat_bit, NULL, 1); static SENSOR_DEVICE_ATTR(env_data_stale, S_IRUGO, show_stat_bit, NULL, 2); -static SENSOR_DEVICE_ATTR(tpm_self_test_passed, S_IRUGO, show_stat_bit, NULL, 3); +static SENSOR_DEVICE_ATTR(tpm_self_test_passed, S_IRUGO, show_stat_bit, NULL, + 3); -static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, + char *buf) { struct env *p = dev_get_drvdata(dev); u8 val; @@ -194,7 +207,8 @@ static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, cha static SENSOR_DEVICE_ATTR(firmware_version, S_IRUGO, show_fwver, NULL, 0); -static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_name(struct device *dev, struct device_attribute *attr, + char *buf) { return sprintf(buf, "ultra45\n"); } diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 8eac67d769fa..8689664ef03c 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -37,6 +37,7 @@ #include <linux/cpu.h> #include <asm/msr.h> #include <asm/processor.h> +#include <asm/cpu_device_id.h> #define DRVNAME "via_cputemp" @@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; +static const struct x86_cpu_id cputemp_ids[] = { + { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ + { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ + { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */ + {} +}; +MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); + static int __init via_cputemp_init(void) { int i, err; - if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) { - printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); - err = -ENODEV; - goto exit; - } + if (!x86_match_cpu(cputemp_ids)) + return -ENODEV; err = platform_driver_register(&via_cputemp_driver); if (err) diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 25e91665a0a2..288135d85e11 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -1,34 +1,35 @@ /* - via686a.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring - - Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, - Kyösti Mälkki <kmalkki@cc.hut.fi>, - Mark Studebaker <mdsxyz123@yahoo.com>, - and Bob Dougherty <bobd@stanford.edu> - (Some conversion-factor data were contributed by Jonathan Teh Soon Yew - <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.) - - 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. -*/ + * via686a.c - Part of lm_sensors, Linux kernel modules + * for hardware monitoring + * + * Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, + * Kyösti Mälkki <kmalkki@cc.hut.fi>, + * Mark Studebaker <mdsxyz123@yahoo.com>, + * and Bob Dougherty <bobd@stanford.edu> + * + * (Some conversion-factor data were contributed by Jonathan Teh Soon Yew + * <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.) + * + * 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. + */ /* - Supports the Via VT82C686A, VT82C686B south bridges. - Reports all as a 686A. - Warning - only supports a single device. -*/ + * Supports the Via VT82C686A, VT82C686B south bridges. + * Reports all as a 686A. + * Warning - only supports a single device. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -47,8 +48,10 @@ #include <linux/io.h> -/* If force_addr is set to anything different from 0, we forcibly enable - the device at the given address. */ +/* + * If force_addr is set to anything different from 0, we forcibly enable + * the device at the given address. + */ static unsigned short force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, @@ -57,9 +60,9 @@ MODULE_PARM_DESC(force_addr, static struct platform_device *pdev; /* - The Via 686a southbridge has a LM78-like chip integrated on the same IC. - This driver is a customized copy of lm78.c -*/ + * The Via 686a southbridge has a LM78-like chip integrated on the same IC. + * This driver is a customized copy of lm78.c + */ /* Many VIA686A constants specified below */ @@ -91,40 +94,46 @@ static const u8 VIA686A_REG_TEMP_HYST[] = { 0x3a, 0x3e, 0x1e }; #define VIA686A_REG_ALARM2 0x42 #define VIA686A_REG_FANDIV 0x47 #define VIA686A_REG_CONFIG 0x40 -/* The following register sets temp interrupt mode (bits 1-0 for temp1, - 3-2 for temp2, 5-4 for temp3). Modes are: - 00 interrupt stays as long as value is out-of-range - 01 interrupt is cleared once register is read (default) - 10 comparator mode- like 00, but ignores hysteresis - 11 same as 00 */ +/* + * The following register sets temp interrupt mode (bits 1-0 for temp1, + * 3-2 for temp2, 5-4 for temp3). Modes are: + * 00 interrupt stays as long as value is out-of-range + * 01 interrupt is cleared once register is read (default) + * 10 comparator mode- like 00, but ignores hysteresis + * 11 same as 00 + */ #define VIA686A_REG_TEMP_MODE 0x4b /* We'll just assume that you want to set all 3 simultaneously: */ #define VIA686A_TEMP_MODE_MASK 0x3F #define VIA686A_TEMP_MODE_CONTINUOUS 0x00 -/* Conversions. Limit checking is only done on the TO_REG - variants. - -********* VOLTAGE CONVERSIONS (Bob Dougherty) ******** - From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew): - voltagefactor[0]=1.25/2628; (2628/1.25=2102.4) // Vccp - voltagefactor[1]=1.25/2628; (2628/1.25=2102.4) // +2.5V - voltagefactor[2]=1.67/2628; (2628/1.67=1573.7) // +3.3V - voltagefactor[3]=2.6/2628; (2628/2.60=1010.8) // +5V - voltagefactor[4]=6.3/2628; (2628/6.30=417.14) // +12V - in[i]=(data[i+2]*25.0+133)*voltagefactor[i]; - That is: - volts = (25*regVal+133)*factor - regVal = (volts/factor-133)/25 - (These conversions were contributed by Jonathan Teh Soon Yew - <j.teh@iname.com>) */ +/* + * Conversions. Limit checking is only done on the TO_REG + * variants. + * + ******** VOLTAGE CONVERSIONS (Bob Dougherty) ******** + * From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew): + * voltagefactor[0]=1.25/2628; (2628/1.25=2102.4) // Vccp + * voltagefactor[1]=1.25/2628; (2628/1.25=2102.4) // +2.5V + * voltagefactor[2]=1.67/2628; (2628/1.67=1573.7) // +3.3V + * voltagefactor[3]=2.6/2628; (2628/2.60=1010.8) // +5V + * voltagefactor[4]=6.3/2628; (2628/6.30=417.14) // +12V + * in[i]=(data[i+2]*25.0+133)*voltagefactor[i]; + * That is: + * volts = (25*regVal+133)*factor + * regVal = (volts/factor-133)/25 + * (These conversions were contributed by Jonathan Teh Soon Yew + * <j.teh@iname.com>) + */ static inline u8 IN_TO_REG(long val, int inNum) { - /* To avoid floating point, we multiply constants by 10 (100 for +12V). - Rounding is done (120500 is actually 133000 - 12500). - Remember that val is expressed in 0.001V/bit, which is why we divide - by an additional 10000 (100000 for +12V): 1000 for val and 10 (100) - for the constants. */ + /* + * To avoid floating point, we multiply constants by 10 (100 for +12V). + * Rounding is done (120500 is actually 133000 - 12500). + * Remember that val is expressed in 0.001V/bit, which is why we divide + * by an additional 10000 (100000 for +12V): 1000 for val and 10 (100) + * for the constants. + */ if (inNum <= 1) return (u8) SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255); @@ -141,9 +150,11 @@ static inline u8 IN_TO_REG(long val, int inNum) static inline long IN_FROM_REG(u8 val, int inNum) { - /* To avoid floating point, we multiply constants by 10 (100 for +12V). - We also multiply them by 1000 because we want 0.001V/bit for the - output value. Rounding is done. */ + /* + * To avoid floating point, we multiply constants by 10 (100 for +12V). + * We also multiply them by 1000 because we want 0.001V/bit for the + * output value. Rounding is done. + */ if (inNum <= 1) return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024); else if (inNum == 2) @@ -155,9 +166,11 @@ static inline long IN_FROM_REG(u8 val, int inNum) } /********* FAN RPM CONVERSIONS ********/ -/* Higher register values = slower fans (the fan's strobe gates a counter). - But this chip saturates back at 0, not at 255 like all the other chips. - So, 0 means 0 RPM */ +/* + * Higher register values = slower fans (the fan's strobe gates a counter). + * But this chip saturates back at 0, not at 255 like all the other chips. + * So, 0 means 0 RPM + */ static inline u8 FAN_TO_REG(long rpm, int div) { if (rpm == 0) @@ -166,42 +179,45 @@ static inline u8 FAN_TO_REG(long rpm, int div) return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255); } -#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div))) +#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (val) == 255 ? 0 : 1350000 / \ + ((val) * (div))) /******** TEMP CONVERSIONS (Bob Dougherty) *********/ -/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew) - if(temp<169) - return double(temp)*0.427-32.08; - else if(temp>=169 && temp<=202) - return double(temp)*0.582-58.16; - else - return double(temp)*0.924-127.33; - - A fifth-order polynomial fits the unofficial data (provided by Alex van - Kaam <darkside@chello.nl>) a bit better. It also give more reasonable - numbers on my machine (ie. they agree with what my BIOS tells me). - Here's the fifth-order fit to the 8-bit data: - temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 - - 2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0. - - (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for - finding my typos in this formula!) - - Alas, none of the elegant function-fit solutions will work because we - aren't allowed to use floating point in the kernel and doing it with - integers doesn't provide enough precision. So we'll do boring old - look-up table stuff. The unofficial data (see below) have effectively - 7-bit resolution (they are rounded to the nearest degree). I'm assuming - that the transfer function of the device is monotonic and smooth, so a - smooth function fit to the data will allow us to get better precision. - I used the 5th-order poly fit described above and solved for - VIA register values 0-255. I *10 before rounding, so we get tenth-degree - precision. (I could have done all 1024 values for our 10-bit readings, - but the function is very linear in the useful range (0-80 deg C), so - we'll just use linear interpolation for 10-bit readings.) So, tempLUT - is the temp at via register values 0-255: */ -static const s16 tempLUT[] = -{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, +/* + * linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew) + * if(temp<169) + * return double(temp)*0.427-32.08; + * else if(temp>=169 && temp<=202) + * return double(temp)*0.582-58.16; + * else + * return double(temp)*0.924-127.33; + * + * A fifth-order polynomial fits the unofficial data (provided by Alex van + * Kaam <darkside@chello.nl>) a bit better. It also give more reasonable + * numbers on my machine (ie. they agree with what my BIOS tells me). + * Here's the fifth-order fit to the 8-bit data: + * temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 - + * 2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0. + * + * (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for + * finding my typos in this formula!) + * + * Alas, none of the elegant function-fit solutions will work because we + * aren't allowed to use floating point in the kernel and doing it with + * integers doesn't provide enough precision. So we'll do boring old + * look-up table stuff. The unofficial data (see below) have effectively + * 7-bit resolution (they are rounded to the nearest degree). I'm assuming + * that the transfer function of the device is monotonic and smooth, so a + * smooth function fit to the data will allow us to get better precision. + * I used the 5th-order poly fit described above and solved for + * VIA register values 0-255. I *10 before rounding, so we get tenth-degree + * precision. (I could have done all 1024 values for our 10-bit readings, + * but the function is very linear in the useful range (0-80 deg C), so + * we'll just use linear interpolation for 10-bit readings.) So, tempLUT + * is the temp at via register values 0-255: + */ +static const s16 tempLUT[] = { + -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, -503, -487, -471, -456, -442, -428, -414, -400, -387, -375, -362, -350, -339, -327, -316, -305, -295, -285, -275, -265, -255, -246, -237, -229, -220, -212, -204, -196, -188, -180, @@ -225,29 +241,31 @@ static const s16 tempLUT[] = 1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462 }; -/* the original LUT values from Alex van Kaam <darkside@chello.nl> - (for via register values 12-240): -{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31, --30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15, --15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3, --3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12, -12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22, -22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33, -33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45, -45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60, -61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84, -85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110}; - - - Here's the reverse LUT. I got it by doing a 6-th order poly fit (needed - an extra term for a good fit to these inverse data!) and then - solving for each temp value from -50 to 110 (the useable range for - this chip). Here's the fit: - viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4 - - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01) - Note that n=161: */ -static const u8 viaLUT[] = -{ 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, +/* + * the original LUT values from Alex van Kaam <darkside@chello.nl> + * (for via register values 12-240): + * {-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31, + * -30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15, + * -15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3, + * -3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12, + * 12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22, + * 22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33, + * 33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45, + * 45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60, + * 61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84, + * 85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110}; + * + * + * Here's the reverse LUT. I got it by doing a 6-th order poly fit (needed + * an extra term for a good fit to these inverse data!) and then + * solving for each temp value from -50 to 110 (the useable range for + * this chip). Here's the fit: + * viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4 + * - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01) + * Note that n=161: + */ +static const u8 viaLUT[] = { + 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, 41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66, 69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100, @@ -262,9 +280,11 @@ static const u8 viaLUT[] = 239, 240 }; -/* Converting temps to (8-bit) hyst and over registers - No interpolation here. - The +50 is because the temps start at -50 */ +/* + * Converting temps to (8-bit) hyst and over registers + * No interpolation here. + * The +50 is because the temps start at -50 + */ static inline u8 TEMP_TO_REG(long val) { return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 : @@ -290,10 +310,12 @@ static inline long TEMP_FROM_REG10(u16 val) } #define DIV_FROM_REG(val) (1 << (val)) -#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) +#define DIV_TO_REG(val) ((val) == 8 ? 3 : (val) == 4 ? 2 : (val) == 1 ? 0 : 1) -/* For each registered chip, we need to keep some data in memory. - The structure is dynamically allocated. */ +/* + * For each registered chip, we need to keep some data in memory. + * The structure is dynamically allocated. + */ struct via686a_data { unsigned short addr; const char *name; @@ -365,7 +387,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *da, struct via686a_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val, nr); @@ -379,7 +406,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da, struct via686a_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val, nr); @@ -429,7 +461,12 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, struct via686a_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_over[nr] = TEMP_TO_REG(val); @@ -443,7 +480,12 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, struct via686a_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_hyst[nr] = TEMP_TO_REG(val); @@ -471,7 +513,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], - DIV_FROM_REG(data->fan_div[nr])) ); + DIV_FROM_REG(data->fan_div[nr]))); } static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, char *buf) { @@ -479,21 +521,27 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; return sprintf(buf, "%d\n", - FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); + FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr]))); } static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, char *buf) { struct via686a_data *data = via686a_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); + return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); } static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct via686a_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - int val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -506,8 +554,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, struct via686a_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(da); int nr = attr->index; - int val = simple_strtol(buf, NULL, 10); int old; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); old = via686a_read_value(data, VIA686A_REG_FANDIV); @@ -530,10 +583,13 @@ show_fan_offset(1); show_fan_offset(2); /* Alarms */ -static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) { +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, + char *buf) +{ struct via686a_data *data = via686a_update_device(dev); return sprintf(buf, "%u\n", data->alarms); } + static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, @@ -641,7 +697,8 @@ static int __devinit via686a_probe(struct platform_device *pdev) return -ENODEV; } - if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto exit_release; } @@ -655,7 +712,8 @@ static int __devinit via686a_probe(struct platform_device *pdev) via686a_init_device(data); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) + err = sysfs_create_group(&pdev->dev.kobj, &via686a_group); + if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&pdev->dev); @@ -748,10 +806,11 @@ static struct via686a_data *via686a_update_device(struct device *dev) via686a_read_value(data, VIA686A_REG_TEMP_HYST[i]); } - /* add in lower 2 bits - temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1 - temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 - temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 + /* + * add in lower 2 bits + * temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1 + * temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 + * temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 */ data->temp[0] |= (via686a_read_value(data, VIA686A_REG_TEMP_LOW1) @@ -777,11 +836,10 @@ static struct via686a_data *via686a_update_device(struct device *dev) return data; } -static const struct pci_device_id via686a_pci_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(via686a_pci_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, - { 0, } + { } }; - MODULE_DEVICE_TABLE(pci, via686a_pci_ids); static int __devinit via686a_device_add(unsigned short address) @@ -872,7 +930,8 @@ static int __devinit via686a_pci_probe(struct pci_dev *dev, if (via686a_device_add(address)) goto exit_unregister; - /* Always return failure here. This is to allow other drivers to bind + /* + * Always return failure here. This is to allow other drivers to bind * to this pci device. We don't really want to have control over the * pci device, we only wanted to read as few register values from it. */ diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 49163d48e966..c2c5c72fb8f0 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -151,8 +151,10 @@ struct vt1211_data { #define ISTEMP(ix, uch_config) ((ix) < 2 ? 1 : \ ((uch_config) >> (ix)) & 1) -/* in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the - driver according to the VT1211 BIOS porting guide */ +/* + * in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the + * driver according to the VT1211 BIOS porting guide + */ #define IN_FROM_REG(ix, reg) ((reg) < 3 ? 0 : (ix) == 5 ? \ (((reg) - 3) * 15882 + 479) / 958 : \ (((reg) - 3) * 10000 + 479) / 958) @@ -160,11 +162,13 @@ struct vt1211_data { ((val) * 958 + 7941) / 15882 + 3 : \ ((val) * 958 + 5000) / 10000 + 3, 0, 255)) -/* temp1 (ix = 0) is an intel thermal diode which is scaled in user space. - temp2 (ix = 1) is the internal temp diode so it's scaled in the driver - according to some measurements that I took on an EPIA M10000. - temp3-7 are thermistor based so the driver returns the voltage measured at - the pin (range 0V - 2.2V). */ +/* + * temp1 (ix = 0) is an intel thermal diode which is scaled in user space. + * temp2 (ix = 1) is the internal temp diode so it's scaled in the driver + * according to some measurements that I took on an EPIA M10000. + * temp3-7 are thermistor based so the driver returns the voltage measured at + * the pin (range 0V - 2.2V). + */ #define TEMP_FROM_REG(ix, reg) ((ix) == 0 ? (reg) * 1000 : \ (ix) == 1 ? (reg) < 51 ? 0 : \ ((reg) - 51) * 1000 : \ @@ -186,8 +190,10 @@ struct vt1211_data { * Super-I/O constants and functions * --------------------------------------------------------------------- */ -/* Configuration index port registers - * The vt1211 can live at 2 different addresses so we need to probe both */ +/* + * Configuration index port registers + * The vt1211 can live at 2 different addresses so we need to probe both + */ #define SIO_REG_CIP1 0x2e #define SIO_REG_CIP2 0x4e @@ -377,7 +383,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -446,7 +457,12 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (fn) { @@ -517,8 +533,13 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); int reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -536,16 +557,23 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, break; case SHOW_SET_FAN_DIV: switch (val) { - case 1: data->fan_div[ix] = 0; break; - case 2: data->fan_div[ix] = 1; break; - case 4: data->fan_div[ix] = 2; break; - case 8: data->fan_div[ix] = 3; break; - default: - count = -EINVAL; - dev_warn(dev, "fan div value %ld not " - "supported. Choose one of 1, 2, " - "4, or 8.\n", val); - goto EXIT; + case 1: + data->fan_div[ix] = 0; + break; + case 2: + data->fan_div[ix] = 1; + break; + case 4: + data->fan_div[ix] = 2; + break; + case 8: + data->fan_div[ix] = 3; + break; + default: + count = -EINVAL; + dev_warn(dev, "fan div value %ld not supported. " + "Choose one of 1, 2, 4, or 8.\n", val); + goto EXIT; } vt1211_write8(data, VT1211_REG_FAN_DIV, ((data->fan_div[1] << 6) | @@ -610,8 +638,13 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); int tmp, reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -628,11 +661,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, switch (val) { case 0: data->pwm_ctl[ix] &= 7; - /* disable SmartGuardian if both PWM outputs are - * disabled */ - if ((data->pwm_ctl[ix ^ 1] & 1) == 0) { + /* + * disable SmartGuardian if both PWM outputs are + * disabled + */ + if ((data->pwm_ctl[ix ^ 1] & 1) == 0) data->fan_ctl &= 0xe; - } break; case 2: data->pwm_ctl[ix] |= 8; @@ -656,16 +690,15 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, val = 135000 / SENSORS_LIMIT(val, 135000 >> 7, 135000); /* calculate tmp = log2(val) */ tmp = 0; - for (val >>= 1; val > 0; val >>= 1) { + for (val >>= 1; val > 0; val >>= 1) tmp++; - } /* sync the data cache */ reg = vt1211_read8(data, VT1211_REG_PWM_CLK); data->pwm_clk = (reg & 0xf8) | tmp; vt1211_write8(data, VT1211_REG_PWM_CLK, data->pwm_clk); break; case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: - if ((val < 1) || (val > 7)) { + if (val < 1 || val > 7) { count = -EINVAL; dev_warn(dev, "temp channel %ld not supported. " "Choose a value between 1 and 7.\n", val); @@ -741,8 +774,14 @@ static ssize_t set_pwm_auto_point_temp(struct device *dev, to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int ap = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); int reg; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); @@ -774,7 +813,7 @@ static ssize_t set_pwm_auto_point_temp(struct device *dev, * 1 1 : pwm2 low speed duty cycle (pwm_auto_pwm[1][1]) * 1 2 : pwm2 high speed duty cycle (pwm_auto_pwm[1][2]) * 1 3 : pwm2 full speed (pwm_auto_pwm[1][3], hard-wired to 255) -*/ + */ static ssize_t show_pwm_auto_point_pwm(struct device *dev, struct device_attribute *attr, @@ -798,16 +837,15 @@ static ssize_t set_pwm_auto_point_pwm(struct device *dev, to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int ap = sensor_attr_2->nr; - long val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; - if ((val < 0) || (val > 255)) { - dev_err(dev, "pwm value %ld is out of range. " - "Choose a value between 0 and 255.\n" , val); - return -EINVAL; - } + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - data->pwm_auto_pwm[ix][ap] = val; + data->pwm_auto_pwm[ix][ap] = SENSORS_LIMIT(val, 0, 255); vt1211_write8(data, VT1211_REG_PWM_AUTO_PWM(ix, ap), data->pwm_auto_pwm[ix][ap]); mutex_unlock(&data->update_lock); @@ -831,7 +869,12 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vt1211_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; data->vrm = val; @@ -866,112 +909,99 @@ static ssize_t show_alarms(struct device *dev, * Device attribute structs * --------------------------------------------------------------------- */ -#define SENSOR_ATTR_IN_INPUT(ix) \ - SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \ - show_in, NULL, SHOW_IN_INPUT, ix) - -static struct sensor_device_attribute_2 vt1211_sysfs_in_input[] = { - SENSOR_ATTR_IN_INPUT(0), - SENSOR_ATTR_IN_INPUT(1), - SENSOR_ATTR_IN_INPUT(2), - SENSOR_ATTR_IN_INPUT(3), - SENSOR_ATTR_IN_INPUT(4), - SENSOR_ATTR_IN_INPUT(5), -}; - -#define SENSOR_ATTR_IN_MIN(ix) \ +#define SENSOR_ATTR_IN(ix) \ +{ SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \ + show_in, NULL, SHOW_IN_INPUT, ix), \ SENSOR_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ - show_in, set_in, SHOW_SET_IN_MIN, ix) - -static struct sensor_device_attribute_2 vt1211_sysfs_in_min[] = { - SENSOR_ATTR_IN_MIN(0), - SENSOR_ATTR_IN_MIN(1), - SENSOR_ATTR_IN_MIN(2), - SENSOR_ATTR_IN_MIN(3), - SENSOR_ATTR_IN_MIN(4), - SENSOR_ATTR_IN_MIN(5), -}; - -#define SENSOR_ATTR_IN_MAX(ix) \ + show_in, set_in, SHOW_SET_IN_MIN, ix), \ SENSOR_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ - show_in, set_in, SHOW_SET_IN_MAX, ix) - -static struct sensor_device_attribute_2 vt1211_sysfs_in_max[] = { - SENSOR_ATTR_IN_MAX(0), - SENSOR_ATTR_IN_MAX(1), - SENSOR_ATTR_IN_MAX(2), - SENSOR_ATTR_IN_MAX(3), - SENSOR_ATTR_IN_MAX(4), - SENSOR_ATTR_IN_MAX(5), + show_in, set_in, SHOW_SET_IN_MAX, ix), \ + SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \ + show_in, NULL, SHOW_IN_ALARM, ix) \ +} + +static struct sensor_device_attribute_2 vt1211_sysfs_in[][4] = { + SENSOR_ATTR_IN(0), + SENSOR_ATTR_IN(1), + SENSOR_ATTR_IN(2), + SENSOR_ATTR_IN(3), + SENSOR_ATTR_IN(4), + SENSOR_ATTR_IN(5) }; -#define SENSOR_ATTR_IN_ALARM(ix) \ - SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \ - show_in, NULL, SHOW_IN_ALARM, ix) - -static struct sensor_device_attribute_2 vt1211_sysfs_in_alarm[] = { - SENSOR_ATTR_IN_ALARM(0), - SENSOR_ATTR_IN_ALARM(1), - SENSOR_ATTR_IN_ALARM(2), - SENSOR_ATTR_IN_ALARM(3), - SENSOR_ATTR_IN_ALARM(4), - SENSOR_ATTR_IN_ALARM(5), +#define IN_UNIT_ATTRS(X) \ +{ &vt1211_sysfs_in[X][0].dev_attr.attr, \ + &vt1211_sysfs_in[X][1].dev_attr.attr, \ + &vt1211_sysfs_in[X][2].dev_attr.attr, \ + &vt1211_sysfs_in[X][3].dev_attr.attr, \ + NULL \ +} + +static struct attribute *vt1211_in_attr[][5] = { + IN_UNIT_ATTRS(0), + IN_UNIT_ATTRS(1), + IN_UNIT_ATTRS(2), + IN_UNIT_ATTRS(3), + IN_UNIT_ATTRS(4), + IN_UNIT_ATTRS(5) }; -#define SENSOR_ATTR_TEMP_INPUT(ix) \ - SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \ - show_temp, NULL, SHOW_TEMP_INPUT, ix-1) - -static struct sensor_device_attribute_2 vt1211_sysfs_temp_input[] = { - SENSOR_ATTR_TEMP_INPUT(1), - SENSOR_ATTR_TEMP_INPUT(2), - SENSOR_ATTR_TEMP_INPUT(3), - SENSOR_ATTR_TEMP_INPUT(4), - SENSOR_ATTR_TEMP_INPUT(5), - SENSOR_ATTR_TEMP_INPUT(6), - SENSOR_ATTR_TEMP_INPUT(7), +static const struct attribute_group vt1211_in_attr_group[] = { + { .attrs = vt1211_in_attr[0] }, + { .attrs = vt1211_in_attr[1] }, + { .attrs = vt1211_in_attr[2] }, + { .attrs = vt1211_in_attr[3] }, + { .attrs = vt1211_in_attr[4] }, + { .attrs = vt1211_in_attr[5] } }; -#define SENSOR_ATTR_TEMP_MAX(ix) \ +#define SENSOR_ATTR_TEMP(ix) \ +{ SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \ + show_temp, NULL, SHOW_TEMP_INPUT, ix-1), \ SENSOR_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \ - show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1) - -static struct sensor_device_attribute_2 vt1211_sysfs_temp_max[] = { - SENSOR_ATTR_TEMP_MAX(1), - SENSOR_ATTR_TEMP_MAX(2), - SENSOR_ATTR_TEMP_MAX(3), - SENSOR_ATTR_TEMP_MAX(4), - SENSOR_ATTR_TEMP_MAX(5), - SENSOR_ATTR_TEMP_MAX(6), - SENSOR_ATTR_TEMP_MAX(7), + show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1), \ + SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \ + show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1), \ + SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \ + show_temp, NULL, SHOW_TEMP_ALARM, ix-1) \ +} + +static struct sensor_device_attribute_2 vt1211_sysfs_temp[][4] = { + SENSOR_ATTR_TEMP(1), + SENSOR_ATTR_TEMP(2), + SENSOR_ATTR_TEMP(3), + SENSOR_ATTR_TEMP(4), + SENSOR_ATTR_TEMP(5), + SENSOR_ATTR_TEMP(6), + SENSOR_ATTR_TEMP(7), }; -#define SENSOR_ATTR_TEMP_MAX_HYST(ix) \ - SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \ - show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1) - -static struct sensor_device_attribute_2 vt1211_sysfs_temp_max_hyst[] = { - SENSOR_ATTR_TEMP_MAX_HYST(1), - SENSOR_ATTR_TEMP_MAX_HYST(2), - SENSOR_ATTR_TEMP_MAX_HYST(3), - SENSOR_ATTR_TEMP_MAX_HYST(4), - SENSOR_ATTR_TEMP_MAX_HYST(5), - SENSOR_ATTR_TEMP_MAX_HYST(6), - SENSOR_ATTR_TEMP_MAX_HYST(7), +#define TEMP_UNIT_ATTRS(X) \ +{ &vt1211_sysfs_temp[X][0].dev_attr.attr, \ + &vt1211_sysfs_temp[X][1].dev_attr.attr, \ + &vt1211_sysfs_temp[X][2].dev_attr.attr, \ + &vt1211_sysfs_temp[X][3].dev_attr.attr, \ + NULL \ +} + +static struct attribute *vt1211_temp_attr[][5] = { + TEMP_UNIT_ATTRS(0), + TEMP_UNIT_ATTRS(1), + TEMP_UNIT_ATTRS(2), + TEMP_UNIT_ATTRS(3), + TEMP_UNIT_ATTRS(4), + TEMP_UNIT_ATTRS(5), + TEMP_UNIT_ATTRS(6) }; -#define SENSOR_ATTR_TEMP_ALARM(ix) \ - SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \ - show_temp, NULL, SHOW_TEMP_ALARM, ix-1) - -static struct sensor_device_attribute_2 vt1211_sysfs_temp_alarm[] = { - SENSOR_ATTR_TEMP_ALARM(1), - SENSOR_ATTR_TEMP_ALARM(2), - SENSOR_ATTR_TEMP_ALARM(3), - SENSOR_ATTR_TEMP_ALARM(4), - SENSOR_ATTR_TEMP_ALARM(5), - SENSOR_ATTR_TEMP_ALARM(6), - SENSOR_ATTR_TEMP_ALARM(7), +static const struct attribute_group vt1211_temp_attr_group[] = { + { .attrs = vt1211_temp_attr[0] }, + { .attrs = vt1211_temp_attr[1] }, + { .attrs = vt1211_temp_attr[2] }, + { .attrs = vt1211_temp_attr[3] }, + { .attrs = vt1211_temp_attr[4] }, + { .attrs = vt1211_temp_attr[5] }, + { .attrs = vt1211_temp_attr[6] } }; #define SENSOR_ATTR_FAN(ix) \ @@ -1069,7 +1099,8 @@ static void __devinit vt1211_init_device(struct vt1211_data *data) vt1211_write8(data, VT1211_REG_UCH_CONFIG, data->uch_config); } - /* Initialize the interrupt mode (if request at module load time). + /* + * Initialize the interrupt mode (if request at module load time). * The VT1211 implements 3 different modes for clearing interrupts: * 0: Clear INT when status register is read. Regenerate INT as long * as temp stays above hysteresis limit. @@ -1079,7 +1110,8 @@ static void __devinit vt1211_init_device(struct vt1211_data *data) * 2: Clear INT when temp falls below max limit. * * The driver only allows to force mode 0 since that's the only one - * that makes sense for 'sensors' */ + * that makes sense for 'sensors' + */ if (int_mode == 0) { vt1211_write8(data, VT1211_REG_TEMP1_CONFIG, 0); vt1211_write8(data, VT1211_REG_TEMP2_CONFIG, 0); @@ -1095,33 +1127,18 @@ static void vt1211_remove_sysfs(struct platform_device *pdev) struct device *dev = &pdev->dev; int i; - for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) { - device_remove_file(dev, - &vt1211_sysfs_in_input[i].dev_attr); - device_remove_file(dev, - &vt1211_sysfs_in_min[i].dev_attr); - device_remove_file(dev, - &vt1211_sysfs_in_max[i].dev_attr); - device_remove_file(dev, - &vt1211_sysfs_in_alarm[i].dev_attr); - } - for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) { - device_remove_file(dev, - &vt1211_sysfs_temp_input[i].dev_attr); - device_remove_file(dev, - &vt1211_sysfs_temp_max[i].dev_attr); - device_remove_file(dev, - &vt1211_sysfs_temp_max_hyst[i].dev_attr); - device_remove_file(dev, - &vt1211_sysfs_temp_alarm[i].dev_attr); - } + for (i = 0; i < ARRAY_SIZE(vt1211_in_attr_group); i++) + sysfs_remove_group(&dev->kobj, &vt1211_in_attr_group[i]); + + for (i = 0; i < ARRAY_SIZE(vt1211_temp_attr_group); i++) + sysfs_remove_group(&dev->kobj, &vt1211_temp_attr_group[i]); + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) { device_remove_file(dev, &vt1211_sysfs_fan_pwm[i].dev_attr); } - for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) { + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) device_remove_file(dev, &vt1211_sysfs_misc[i]); - } } static int __devinit vt1211_probe(struct platform_device *pdev) @@ -1131,7 +1148,8 @@ static int __devinit vt1211_probe(struct platform_device *pdev) struct resource *res; int i, err; - if (!(data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; dev_err(dev, "Out of memory\n"); goto EXIT; @@ -1154,47 +1172,33 @@ static int __devinit vt1211_probe(struct platform_device *pdev) vt1211_init_device(data); /* Create sysfs interface files */ - for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) { + for (i = 0; i < ARRAY_SIZE(vt1211_in_attr_group); i++) { if (ISVOLT(i, data->uch_config)) { - if ((err = device_create_file(dev, - &vt1211_sysfs_in_input[i].dev_attr)) || - (err = device_create_file(dev, - &vt1211_sysfs_in_min[i].dev_attr)) || - (err = device_create_file(dev, - &vt1211_sysfs_in_max[i].dev_attr)) || - (err = device_create_file(dev, - &vt1211_sysfs_in_alarm[i].dev_attr))) { + err = sysfs_create_group(&dev->kobj, + &vt1211_in_attr_group[i]); + if (err) goto EXIT_DEV_REMOVE; - } } } - for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) { + for (i = 0; i < ARRAY_SIZE(vt1211_temp_attr_group); i++) { if (ISTEMP(i, data->uch_config)) { - if ((err = device_create_file(dev, - &vt1211_sysfs_temp_input[i].dev_attr)) || - (err = device_create_file(dev, - &vt1211_sysfs_temp_max[i].dev_attr)) || - (err = device_create_file(dev, - &vt1211_sysfs_temp_max_hyst[i].dev_attr)) || - (err = device_create_file(dev, - &vt1211_sysfs_temp_alarm[i].dev_attr))) { + err = sysfs_create_group(&dev->kobj, + &vt1211_temp_attr_group[i]); + if (err) goto EXIT_DEV_REMOVE; - } } } for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) { err = device_create_file(dev, &vt1211_sysfs_fan_pwm[i].dev_attr); - if (err) { + if (err) goto EXIT_DEV_REMOVE; - } } for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) { err = device_create_file(dev, &vt1211_sysfs_misc[i]); - if (err) { + if (err) goto EXIT_DEV_REMOVE; - } } /* Register device */ @@ -1293,9 +1297,8 @@ static int __init vt1211_find(int sio_cip, unsigned short *address) superio_enter(sio_cip); devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID); - if (devid != SIO_VT1211_ID) { + if (devid != SIO_VT1211_ID) goto EXIT; - } superio_select(sio_cip, SIO_VT1211_LDN_HWMON); @@ -1325,35 +1328,35 @@ static int __init vt1211_init(void) int err; unsigned short address = 0; - if ((err = vt1211_find(SIO_REG_CIP1, &address)) && - (err = vt1211_find(SIO_REG_CIP2, &address))) { - goto EXIT; + err = vt1211_find(SIO_REG_CIP1, &address); + if (err) { + err = vt1211_find(SIO_REG_CIP2, &address); + if (err) + goto EXIT; } if ((uch_config < -1) || (uch_config > 31)) { err = -EINVAL; pr_warn("Invalid UCH configuration %d. " "Choose a value between 0 and 31.\n", uch_config); - goto EXIT; + goto EXIT; } if ((int_mode < -1) || (int_mode > 0)) { err = -EINVAL; pr_warn("Invalid interrupt mode %d. " "Only mode 0 is supported.\n", int_mode); - goto EXIT; + goto EXIT; } err = platform_driver_register(&vt1211_driver); - if (err) { + if (err) goto EXIT; - } /* Sets global pdev as a side effect */ err = vt1211_device_add(address); - if (err) { + if (err) goto EXIT_DRV_UNREGISTER; - } return 0; diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index db3b2e8d2a67..386a84538010 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -1,28 +1,29 @@ /* - vt8231.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring + * vt8231.c - Part of lm_sensors, Linux kernel modules + * for hardware monitoring + * + * Copyright (c) 2005 Roger Lucas <vt8231@hiddenengine.co.uk> + * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> + * Aaron M. Marsh <amarsh@sdf.lonestar.org> + * + * 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. + */ - Copyright (c) 2005 Roger Lucas <vt8231@hiddenengine.co.uk> - Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> - Aaron M. Marsh <amarsh@sdf.lonestar.org> - - 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. -*/ - -/* Supports VIA VT8231 South Bridge embedded sensors -*/ +/* + * Supports VIA VT8231 South Bridge embedded sensors + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -50,26 +51,27 @@ static struct platform_device *pdev; #define VT8231_BASE_REG 0x70 #define VT8231_ENABLE_REG 0x74 -/* The VT8231 registers - - The reset value for the input channel configuration is used (Reg 0x4A=0x07) - which sets the selected inputs marked with '*' below if multiple options are - possible: - - Voltage Mode Temperature Mode - Sensor Linux Id Linux Id VIA Id - -------- -------- -------- ------ - CPU Diode N/A temp1 0 - UIC1 in0 temp2 * 1 - UIC2 in1 * temp3 2 - UIC3 in2 * temp4 3 - UIC4 in3 * temp5 4 - UIC5 in4 * temp6 5 - 3.3V in5 N/A - - Note that the BIOS may set the configuration register to a different value - to match the motherboard configuration. -*/ +/* + * The VT8231 registers + * + * The reset value for the input channel configuration is used (Reg 0x4A=0x07) + * which sets the selected inputs marked with '*' below if multiple options are + * possible: + * + * Voltage Mode Temperature Mode + * Sensor Linux Id Linux Id VIA Id + * -------- -------- -------- ------ + * CPU Diode N/A temp1 0 + * UIC1 in0 temp2 * 1 + * UIC2 in1 * temp3 2 + * UIC3 in2 * temp4 3 + * UIC4 in3 * temp5 4 + * UIC5 in4 * temp6 5 + * 3.3V in5 N/A + * + * Note that the BIOS may set the configuration register to a different value + * to match the motherboard configuration. + */ /* fans numbered 0-1 */ #define VT8231_REG_FAN_MIN(nr) (0x3b + (nr)) @@ -81,13 +83,14 @@ static const u8 regvolt[] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 }; static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 }; static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 }; -/* Temperatures are numbered 1-6 according to the Linux kernel specification. -** -** In the VIA datasheet, however, the temperatures are numbered from zero. -** Since it is important that this driver can easily be compared to the VIA -** datasheet, we will use the VIA numbering within this driver and map the -** kernel sysfs device name to the VIA number in the sysfs callback. -*/ +/* + * Temperatures are numbered 1-6 according to the Linux kernel specification. + * + * In the VIA datasheet, however, the temperatures are numbered from zero. + * Since it is important that this driver can easily be compared to the VIA + * datasheet, we will use the VIA numbering within this driver and map the + * kernel sysfs device name to the VIA number in the sysfs callback. + */ #define VT8231_REG_TEMP_LOW01 0x49 #define VT8231_REG_TEMP_LOW25 0x4d @@ -108,9 +111,10 @@ static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 }; #define VT8231_REG_TEMP1_CONFIG 0x4b #define VT8231_REG_TEMP2_CONFIG 0x4c -/* temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux -** numbering -*/ +/* + * temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux + * numbering + */ #define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \ ((ch_config) >> ((i)+1)) & 0x01) /* voltages 0-5 */ @@ -119,24 +123,26 @@ static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 }; #define DIV_FROM_REG(val) (1 << (val)) -/* NB The values returned here are NOT temperatures. The calibration curves -** for the thermistor curves are board-specific and must go in the -** sensors.conf file. Temperature sensors are actually ten bits, but the -** VIA datasheet only considers the 8 MSBs obtained from the regtemp[] -** register. The temperature value returned should have a magnitude of 3, -** so we use the VIA scaling as the "true" scaling and use the remaining 2 -** LSBs as fractional precision. -** -** All the on-chip hardware temperature comparisons for the alarms are only -** 8-bits wide, and compare against the 8 MSBs of the temperature. The bits -** in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are -** ignored. -*/ - -/******** FAN RPM CONVERSIONS ******** -** This chip saturates back at 0, not at 255 like many the other chips. -** So, 0 means 0 RPM -*/ +/* + * NB The values returned here are NOT temperatures. The calibration curves + * for the thermistor curves are board-specific and must go in the + * sensors.conf file. Temperature sensors are actually ten bits, but the + * VIA datasheet only considers the 8 MSBs obtained from the regtemp[] + * register. The temperature value returned should have a magnitude of 3, + * so we use the VIA scaling as the "true" scaling and use the remaining 2 + * LSBs as fractional precision. + * + * All the on-chip hardware temperature comparisons for the alarms are only + * 8-bits wide, and compare against the 8 MSBs of the temperature. The bits + * in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are + * ignored. + */ + +/* + ****** FAN RPM CONVERSIONS ******** + * This chip saturates back at 0, not at 255 like many the other chips. + * So, 0 means 0 RPM + */ static inline u8 FAN_TO_REG(long rpm, int div) { if (rpm == 0) @@ -222,7 +228,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct vt8231_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); @@ -237,7 +248,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct vt8231_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); @@ -278,7 +294,12 @@ static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vt8231_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, @@ -292,7 +313,12 @@ static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vt8231_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, @@ -346,7 +372,12 @@ static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vt8231_data *data = dev_get_drvdata(dev); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); @@ -358,7 +389,12 @@ static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vt8231_data *data = dev_get_drvdata(dev); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); @@ -400,7 +436,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct vt8231_data *data = dev_get_drvdata(dev); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); @@ -414,7 +455,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct vt8231_data *data = dev_get_drvdata(dev); - int val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); @@ -423,9 +469,10 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, return count; } -/* Note that these map the Linux temperature sensor numbering (1-6) to the VIA -** temperature sensor numbering (0-5) -*/ +/* + * Note that these map the Linux temperature sensor numbering (1-6) to the VIA + * temperature sensor numbering (0-5) + */ #define define_temperature_sysfs(offset) \ static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ show_temp, NULL, offset - 1); \ @@ -436,7 +483,8 @@ static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL); static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max); -static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); +static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp0_min, + set_temp0_min); define_temperature_sysfs(2); define_temperature_sysfs(3); @@ -480,7 +528,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct vt8231_data *data = dev_get_drvdata(dev); - int val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -494,21 +547,34 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, { struct vt8231_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; int nr = sensor_attr->index; int old = vt8231_read_value(data, VT8231_REG_FANDIV); long min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); switch (val) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; + case 1: + data->fan_div[nr] = 0; + break; + case 2: + data->fan_div[nr] = 1; + break; + case 4: + data->fan_div[nr] = 2; + break; + case 8: + data->fan_div[nr] = 3; + break; default: dev_err(dev, "fan_div value %ld not supported. " - "Choose one of 1, 2, 4 or 8!\n", val); + "Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } @@ -699,7 +765,7 @@ static struct platform_driver vt8231_driver = { .remove = __devexit_p(vt8231_remove), }; -static const struct pci_device_id vt8231_pci_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(vt8231_pci_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, { 0, } }; @@ -707,7 +773,7 @@ static const struct pci_device_id vt8231_pci_ids[] = { MODULE_DEVICE_TABLE(pci, vt8231_pci_ids); static int __devinit vt8231_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id); + const struct pci_device_id *id); static struct pci_driver vt8231_pci_driver = { .name = "vt8231", @@ -730,7 +796,8 @@ static int vt8231_probe(struct platform_device *pdev) return -ENODEV; } - if (!(data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto exit_release; } @@ -743,7 +810,8 @@ static int vt8231_probe(struct platform_device *pdev) vt8231_init_device(data); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group))) + err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group); + if (err) goto exit_free; /* Must update device information to find out the config field */ @@ -751,16 +819,18 @@ static int vt8231_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { if (ISTEMP(i, data->uch_config)) { - if ((err = sysfs_create_group(&pdev->dev.kobj, - &vt8231_group_temps[i]))) + err = sysfs_create_group(&pdev->dev.kobj, + &vt8231_group_temps[i]); + if (err) goto exit_remove_files; } } for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { if (ISVOLT(i, data->uch_config)) { - if ((err = sysfs_create_group(&pdev->dev.kobj, - &vt8231_group_volts[i]))) + err = sysfs_create_group(&pdev->dev.kobj, + &vt8231_group_volts[i]); + if (err) goto exit_remove_files; } } @@ -866,17 +936,15 @@ static struct vt8231_data *vt8231_update_device(struct device *dev) (vt8231_read_value(data, VT8231_REG_ALARM2) << 8); /* Set alarm flags correctly */ - if (!data->fan[0] && data->fan_min[0]) { + if (!data->fan[0] && data->fan_min[0]) data->alarms |= 0x40; - } else if (data->fan[0] && !data->fan_min[0]) { + else if (data->fan[0] && !data->fan_min[0]) data->alarms &= ~0x40; - } - if (!data->fan[1] && data->fan_min[1]) { + if (!data->fan[1] && data->fan_min[1]) data->alarms |= 0x80; - } else if (data->fan[1] && !data->fan_min[1]) { + else if (data->fan[1] && !data->fan_min[1]) data->alarms &= ~0x80; - } data->last_updated = jiffies; data->valid = 1; @@ -971,13 +1039,16 @@ static int __devinit vt8231_pci_probe(struct pci_dev *dev, if (vt8231_device_add(address)) goto exit_unregister; - /* Always return failure here. This is to allow other drivers to bind + /* + * Always return failure here. This is to allow other drivers to bind * to this pci device. We don't really want to have control over the * pci device, we only wanted to read as few register values from it. */ - /* We do, however, mark ourselves as using the PCI device to stop it - getting unloaded. */ + /* + * We do, however, mark ourselves as using the PCI device to stop it + * getting unloaded. + */ s_bridge = pci_dev_get(dev); return -ENODEV; diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index a658d62c5e10..a25350cf9554 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -1,50 +1,49 @@ /* - w83627ehf - Driver for the hardware monitoring functionality of - the Winbond W83627EHF Super-I/O chip - Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> - Copyright (C) 2006 Yuan Mu (Winbond), - Rudolf Marek <r.marek@assembler.cz> - David Hubbard <david.c.hubbard@gmail.com> - Daniel J Blueman <daniel.blueman@gmail.com> - Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) - - Shamelessly ripped from the w83627hf driver - Copyright (C) 2003 Mark Studebaker - - Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help - in testing and debugging this driver. - - This driver also supports the W83627EHG, which is the lead-free - version of the W83627EHF. - - 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. - - - Supports the following chips: - - Chip #vin #fan #pwm #temp chip IDs man ID - w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 - 0x8860 0xa1 - w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 - w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 - w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 - w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 - w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 - nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 - nct6776f 9 5 3 9 0xC330 0xc1 0x5ca3 -*/ + * w83627ehf - Driver for the hardware monitoring functionality of + * the Winbond W83627EHF Super-I/O chip + * Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2006 Yuan Mu (Winbond), + * Rudolf Marek <r.marek@assembler.cz> + * David Hubbard <david.c.hubbard@gmail.com> + * Daniel J Blueman <daniel.blueman@gmail.com> + * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) + * + * Shamelessly ripped from the w83627hf driver + * Copyright (C) 2003 Mark Studebaker + * + * Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help + * in testing and debugging this driver. + * + * This driver also supports the W83627EHG, which is the lead-free + * version of the W83627EHF. + * + * 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. + * + * Supports the following chips: + * + * Chip #vin #fan #pwm #temp chip IDs man ID + * w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 + * 0x8860 0xa1 + * w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 + * w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 + * w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 + * w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 + * w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 + * nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 + * nct6776f 9 5 3 9 0xC330 0xc1 0x5ca3 + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -164,11 +163,13 @@ superio_exit(int ioreg) #define W83627EHF_REG_BANK 0x4E #define W83627EHF_REG_CONFIG 0x40 -/* Not currently used: +/* + * Not currently used: * REG_MAN_ID has the value 0x5ca3 for all supported chips. * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. * REG_MAN_ID is at port 0x4f - * REG_CHIP_ID is at port 0x58 */ + * REG_CHIP_ID is at port 0x58 + */ static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; @@ -239,6 +240,8 @@ static const u16 W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B[] = { 0x67, 0x69, 0x6b }; static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[] = { 0x68, 0x6a, 0x6c }; +static const u16 W83627EHF_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; + static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301 }; static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302 }; static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 0x105, 0x205, 0x305 }; @@ -393,8 +396,10 @@ div_from_reg(u8 reg) return 1 << reg; } -/* Some of the voltage inputs have internal scaling, the tables below - * contain 8 (the ADC LSB in mV) * scaling factor * 100 */ +/* + * Some of the voltage inputs have internal scaling, the tables below + * contain 8 (the ADC LSB in mV) * scaling factor * 100 + */ static const u16 scale_in_common[10] = { 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800 }; @@ -462,6 +467,7 @@ struct w83627ehf_data { u8 has_fan_min; /* some fans don't have min register */ bool has_fan_div; u8 temp_type[3]; + s8 temp_offset[3]; s16 temp[9]; s16 temp_max[9]; s16 temp_max_hyst[9]; @@ -470,12 +476,13 @@ struct w83627ehf_data { u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ u8 pwm_enable[4]; /* 1->manual - 2->thermal cruise mode (also called SmartFan I) - 3->fan speed cruise mode - 4->variable thermal cruise (also called - SmartFan III) - 5->enhanced variable thermal cruise (also called - SmartFan IV) */ + * 2->thermal cruise mode (also called SmartFan I) + * 3->fan speed cruise mode + * 4->variable thermal cruise (also called + * SmartFan III) + * 5->enhanced variable thermal cruise (also called + * SmartFan IV) + */ u8 pwm_enable_orig[4]; /* original value of pwm_enable */ u8 pwm_num; /* number of pwm */ u8 pwm[4]; @@ -492,6 +499,7 @@ struct w83627ehf_data { u8 vrm; u16 have_temp; + u16 have_temp_offset; u8 in6_skip:1; u8 temp3_val_only:1; }; @@ -816,9 +824,11 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) data->fan_min[i] = w83627ehf_read_value(data, data->REG_FAN_MIN[i]); - /* If we failed to measure the fan speed and clock - divider can be increased, let's try that for next - time */ + /* + * If we failed to measure the fan speed and clock + * divider can be increased, let's try that for next + * time + */ if (data->has_fan_div && (reg >= 0xff || (sio_data->kind == nct6775 && reg == 0x00)) @@ -887,6 +897,10 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) data->temp_max_hyst[i] = w83627ehf_read_temp(data, data->reg_temp_hyst[i]); + if (data->have_temp_offset & (1 << i)) + data->temp_offset[i] + = w83627ehf_read_value(data, + W83627EHF_REG_TEMP_OFFSET[i]); } data->alarms = w83627ehf_read_value(data, @@ -1081,25 +1095,31 @@ store_fan_min(struct device *dev, struct device_attribute *attr, new_div = data->fan_div[nr]; /* No change */ dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); } else if ((reg = 1350000U / val) >= 128 * 255) { - /* Speed below this value cannot possibly be represented, - even with the highest divider (128) */ + /* + * Speed below this value cannot possibly be represented, + * even with the highest divider (128) + */ data->fan_min[nr] = 254; new_div = 7; /* 128 == (1 << 7) */ dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " "minimum\n", nr + 1, val, data->fan_from_reg_min(254, 7)); } else if (!reg) { - /* Speed above this value cannot possibly be represented, - even with the lowest divider (1) */ + /* + * Speed above this value cannot possibly be represented, + * even with the lowest divider (1) + */ data->fan_min[nr] = 1; new_div = 0; /* 1 == (1 << 0) */ dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " "maximum\n", nr + 1, val, data->fan_from_reg_min(1, 0)); } else { - /* Automatically pick the best divider, i.e. the one such - that the min limit will correspond to a register value - in the 96..192 range */ + /* + * Automatically pick the best divider, i.e. the one such + * that the min limit will correspond to a register value + * in the 96..192 range + */ new_div = 0; while (reg > 192 && new_div < 7) { reg >>= 1; @@ -1108,8 +1128,10 @@ store_fan_min(struct device *dev, struct device_attribute *attr, data->fan_min[nr] = reg; } - /* Write both the fan clock divider (if it changed) and the new - fan min (unconditionally) */ + /* + * Write both the fan clock divider (if it changed) and the new + * fan min (unconditionally) + */ if (new_div != data->fan_div[nr]) { dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", nr + 1, div_from_reg(data->fan_div[nr]), @@ -1212,6 +1234,39 @@ store_temp_reg(reg_temp_over, temp_max); store_temp_reg(reg_temp_hyst, temp_max_hyst); static ssize_t +show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct w83627ehf_data *data = w83627ehf_update_device(dev); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + + return sprintf(buf, "%d\n", + data->temp_offset[sensor_attr->index] * 1000); +} + +static ssize_t +store_temp_offset(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct w83627ehf_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err < 0) + return err; + + val = SENSORS_LIMIT(DIV_ROUND_CLOSEST(val, 1000), -128, 127); + + mutex_lock(&data->update_lock); + data->temp_offset[nr] = val; + w83627ehf_write_value(data, W83627EHF_REG_TEMP_OFFSET[nr], val); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) { struct w83627ehf_data *data = w83627ehf_update_device(dev); @@ -1298,6 +1353,15 @@ static struct sensor_device_attribute sda_temp_type[] = { SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), }; +static struct sensor_device_attribute sda_temp_offset[] = { + SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset, + store_temp_offset, 0), + SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset, + store_temp_offset, 1), + SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset, + store_temp_offset, 2), +}; + #define show_pwm_reg(reg) \ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ char *buf) \ @@ -1736,8 +1800,10 @@ static struct sensor_device_attribute_2 sda_caseopen[] = { static void w83627ehf_device_remove_files(struct device *dev) { - /* some entries in the following arrays may not have been used in - * device_create_file(), but device_remove_file() will ignore them */ + /* + * some entries in the following arrays may not have been used in + * device_create_file(), but device_remove_file() will ignore them + */ int i; struct w83627ehf_data *data = dev_get_drvdata(dev); @@ -1788,6 +1854,7 @@ static void w83627ehf_device_remove_files(struct device *dev) continue; device_remove_file(dev, &sda_temp_alarm[i].dev_attr); device_remove_file(dev, &sda_temp_type[i].dev_attr); + device_remove_file(dev, &sda_temp_offset[i].dev_attr); } device_remove_file(dev, &sda_caseopen[0].dev_attr); @@ -2110,6 +2177,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) } else { data->temp_label = nct6775_temp_label; } + data->have_temp_offset = data->have_temp & 0x07; + for (i = 0; i < 3; i++) { + if (data->temp_src[i] > 3) + data->have_temp_offset &= ~(1 << i); + } } else if (sio_data->kind == w83667hg_b) { u8 reg; @@ -2152,6 +2224,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) data->in6_skip = 1; data->temp_label = w83667hg_b_temp_label; + data->have_temp_offset = data->have_temp & 0x07; + for (i = 0; i < 3; i++) { + if (data->temp_src[i] > 2) + data->have_temp_offset &= ~(1 << i); + } } else if (sio_data->kind == w83627uhg) { u8 reg; @@ -2188,6 +2265,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) data->in6_skip = 1; /* No VIN3 */ data->temp_label = w83667hg_b_temp_label; + data->have_temp_offset = data->have_temp & 0x03; + for (i = 0; i < 3; i++) { + if (data->temp_src[i] > 1) + data->have_temp_offset &= ~(1 << i); + } } else { w83627ehf_set_temp_reg_ehf(data, 3); @@ -2207,6 +2289,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) else data->in6_skip = 1; } + data->have_temp_offset = data->have_temp & 0x07; } if (sio_data->kind == nct6775) { @@ -2279,9 +2362,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) /* Read VID value */ if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b || sio_data->kind == nct6775 || sio_data->kind == nct6776) { - /* W83667HG has different pins for VID input and output, so - we can get the VID input values directly at logical device D - 0xe3. */ + /* + * W83667HG has different pins for VID input and output, so + * we can get the VID input values directly at logical device D + * 0xe3. + */ superio_select(sio_data->sioreg, W83667HG_LD_VID); data->vid = superio_inb(sio_data->sioreg, 0xe3); err = device_create_file(dev, &dev_attr_cpu0_vid); @@ -2290,11 +2375,13 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) } else if (sio_data->kind != w83627uhg) { superio_select(sio_data->sioreg, W83627EHF_LD_HWM); if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { - /* Set VID input sensibility if needed. In theory the - BIOS should have set it, but in practice it's not - always the case. We only do it for the W83627EHF/EHG - because the W83627DHG is more complex in this - respect. */ + /* + * Set VID input sensibility if needed. In theory the + * BIOS should have set it, but in practice it's not + * always the case. We only do it for the W83627EHF/EHG + * because the W83627DHG is more complex in this + * respect. + */ if (sio_data->kind == w83627ehf) { en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10); @@ -2468,6 +2555,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sda_temp_type[i].dev_attr))) goto exit_remove; + if (data->have_temp_offset & (1 << i)) { + err = device_create_file(dev, + &sda_temp_offset[i].dev_attr); + if (err) + goto exit_remove; + } } err = device_create_file(dev, &sda_caseopen[0].dev_attr); @@ -2616,10 +2709,12 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, return 0; } -/* when Super-I/O functions move to a separate file, the Super-I/O +/* + * when Super-I/O functions move to a separate file, the Super-I/O * bus will manage the lifetime of the device and this module will only keep * track of the w83627ehf driver. But since we platform_device_alloc(), we - * must keep track of the device */ + * must keep track of the device + */ static struct platform_device *pdev; static int __init sensors_w83627ehf_init(void) @@ -2629,11 +2724,13 @@ static int __init sensors_w83627ehf_init(void) struct resource res; struct w83627ehf_sio_data sio_data; - /* initialize sio_data->kind and sio_data->sioreg. + /* + * initialize sio_data->kind and sio_data->sioreg. * * when Super-I/O functions move to a separate file, the Super-I/O * driver will probe 0x2e and 0x4e and auto-detect the presence of a - * w83627ehf hardware monitor, and call probe() */ + * w83627ehf hardware monitor, and call probe() + */ if (w83627ehf_find(0x2e, &address, &sio_data) && w83627ehf_find(0x4e, &address, &sio_data)) return -ENODEV; diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 374118f2b9f9..5ce54a297249 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1,43 +1,43 @@ /* - w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998 - 2003 Frodo Looijaard <frodol@dds.nl>, - Philip Edelbrock <phil@netroedge.com>, - and Mark Studebaker <mdsxyz123@yahoo.com> - Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org> - Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998 - 2003 Frodo Looijaard <frodol@dds.nl>, + * Philip Edelbrock <phil@netroedge.com>, + * and Mark Studebaker <mdsxyz123@yahoo.com> + * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org> + * Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> + * + * 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. + */ /* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) - w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) - w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) - w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) - w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) - - For other winbond chips, and for i2c support in the above chips, - use w83781d.c. - - Note: automatic ("cruise") fan control for 697, 637 & 627thf not - supported yet. -*/ + * Supports following chips: + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) + * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) + * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) + * w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) + * w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) + * + * For other winbond chips, and for i2c support in the above chips, + * use w83781d.c. + * + * Note: automatic ("cruise") fan control for 697, 637 & 627thf not + * supported yet. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -80,7 +80,7 @@ module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); /* modified from kernel/include/traps.c */ -#define DEV 0x07 /* Register: Logical device select */ +#define DEV 0x07 /* Register: Logical device select */ /* logical device numbers for superio_select (below) */ #define W83627HF_LD_FDC 0x00 @@ -99,7 +99,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); #define W83627HF_LD_ACPI 0x0a #define W83627HF_LD_HWM 0x0b -#define DEVID 0x20 /* Register: Device ID */ +#define DEVID 0x20 /* Register: Device ID */ #define W83627THF_GPIO5_EN 0x30 /* w83627thf only */ #define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ @@ -248,10 +248,12 @@ static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 }; static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; #define W83781D_DEFAULT_BETA 3435 -/* Conversions. Limit checking is only done on the TO_REG - variants. Note that you should be a bit careful with which arguments - these macros are called: arguments may be evaluated more than once. - Fixing this is just not worth it. */ +/* + * Conversions. Limit checking is only done on the TO_REG + * variants. Note that you should be a bit careful with which arguments + * these macros are called: arguments may be evaluated more than once. + * Fixing this is just not worth it. + */ #define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) #define IN_FROM_REG(val) ((val) * 16) @@ -267,8 +269,10 @@ static inline u8 FAN_TO_REG(long rpm, int div) #define TEMP_MIN (-128000) #define TEMP_MAX ( 127000) -/* TEMP: 0.001C/bit (-128C to +127C) - REG: 1C/bit, two's complement */ +/* + * TEMP: 0.001C/bit (-128C to +127C) + * REG: 1C/bit, two's complement + */ static u8 TEMP_TO_REG(long temp) { int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); @@ -294,8 +298,10 @@ static inline unsigned long pwm_freq_from_reg_627hf(u8 reg) static inline u8 pwm_freq_to_reg_627hf(unsigned long val) { u8 i; - /* Only 5 dividers (1 2 4 8 16) - Search for the nearest available frequency */ + /* + * Only 5 dividers (1 2 4 8 16) + * Search for the nearest available frequency + */ for (i = 0; i < 4; i++) { if (val > (((W83627HF_BASE_PWM_FREQ >> i) + (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2)) @@ -313,7 +319,7 @@ static inline unsigned long pwm_freq_from_reg(u8 reg) /* This should not happen but anyway... */ if (reg == 0) reg++; - return (clock / (reg << 8)); + return clock / (reg << 8); } static inline u8 pwm_freq_to_reg(unsigned long val) { @@ -321,11 +327,11 @@ static inline u8 pwm_freq_to_reg(unsigned long val) if (val >= 93750) /* The highest we can do */ return 0x01; if (val >= 720) /* Use 24 MHz clock */ - return (24000000UL / (val << 8)); + return 24000000UL / (val << 8); if (val < 6) /* The lowest we can do */ return 0xFF; else /* Use 180 kHz clock */ - return (0x80 | (180000UL / (val << 8))); + return 0x80 | (180000UL / (val << 8)); } #define BEEP_MASK_FROM_REG(val) ((val) & 0xff7fff) @@ -342,11 +348,13 @@ static inline u8 DIV_TO_REG(long val) break; val >>= 1; } - return ((u8) i); + return (u8)i; } -/* For each registered chip, we need to keep some data in memory. - The structure is dynamically allocated. */ +/* + * For each registered chip, we need to keep some data in memory. + * The structure is dynamically allocated. + */ struct w83627hf_data { unsigned short addr; const char *name; @@ -372,11 +380,13 @@ struct w83627hf_data { u32 beep_mask; /* Register encoding, combined */ u8 pwm[3]; /* Register value */ u8 pwm_enable[3]; /* 1 = manual - 2 = thermal cruise (also called SmartFan I) - 3 = fan speed cruise */ + * 2 = thermal cruise (also called SmartFan I) + * 3 = fan speed cruise + */ u8 pwm_freq[3]; /* Register value */ u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; - 4 = thermistor */ + * 4 = thermistor + */ u8 vrm; u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ }; @@ -427,7 +437,12 @@ store_in_min(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val); @@ -441,7 +456,12 @@ store_in_max(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val); @@ -506,9 +526,12 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a const char *buf, size_t count) { struct w83627hf_data *data = dev_get_drvdata(dev); - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -533,9 +556,12 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a const char *buf, size_t count) { struct w83627hf_data *data = dev_get_drvdata(dev); - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -584,7 +610,12 @@ store_fan_min(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); @@ -645,9 +676,15 @@ store_temp_max(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); - u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); + u16 tmp; + long val; + int err; + err = kstrtol(buf, 10, &val); + if (err) + return err; + + tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); mutex_lock(&data->update_lock); data->temp_max[nr] = tmp; w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp); @@ -661,9 +698,15 @@ store_temp_max_hyst(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10); - u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); + u16 tmp; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; + tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); mutex_lock(&data->update_lock); data->temp_max_hyst[nr] = tmp; w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp); @@ -701,9 +744,12 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct w83627hf_data *data = dev_get_drvdata(dev); - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; data->vrm = val; return count; @@ -755,8 +801,11 @@ store_beep_mask(struct device *dev, struct device_attribute *attr, { struct w83627hf_data *data = dev_get_drvdata(dev); unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -791,10 +840,14 @@ store_beep(struct device *dev, struct device_attribute *attr, { struct w83627hf_data *data = dev_get_drvdata(dev); int bitnr = to_sensor_dev_attr(attr)->index; - unsigned long bit; u8 reg; + unsigned long bit; + int err; + + err = kstrtoul(buf, 10, &bit); + if (err) + return err; - bit = simple_strtoul(buf, NULL, 10); if (bit & ~1) return -EINVAL; @@ -872,10 +925,12 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) return sprintf(buf, "%ld\n", (long) DIV_FROM_REG(data->fan_div[nr])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) @@ -884,7 +939,12 @@ store_fan_div(struct device *dev, struct device_attribute *devattr, struct w83627hf_data *data = dev_get_drvdata(dev); unsigned long min; u8 reg; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -933,7 +993,12 @@ store_pwm(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - u32 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -974,10 +1039,15 @@ store_pwm_enable(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - unsigned long val = simple_strtoul(buf, NULL, 10); u8 reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - if (!val || (val > 3)) /* modes 1, 2 and 3 are supported */ + if (!val || val > 3) /* modes 1, 2 and 3 are supported */ return -EINVAL; mutex_lock(&data->update_lock); data->pwm_enable[nr] = val; @@ -1016,9 +1086,12 @@ store_pwm_freq(struct device *dev, struct device_attribute *devattr, int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); static const u8 mask[]={0xF8, 0x8F}; - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -1060,9 +1133,13 @@ store_temp_type(struct device *dev, struct device_attribute *devattr, { int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); - u32 val, tmp; + unsigned long val; + u32 tmp; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -1290,7 +1367,8 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) goto ERROR0; } - if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { + data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL); + if (!data) { err = -ENOMEM; goto ERROR1; } @@ -1311,7 +1389,8 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) w83627hf_update_fan_div(data); /* Register common device attributes */ - if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) + err = sysfs_create_group(&dev->kobj, &w83627hf_group); + if (err) goto ERROR3; /* Register chip-specific device attributes */ @@ -1387,10 +1466,11 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) } if (data->type == w83627thf || data->type == w83637hf - || data->type == w83687thf) - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm3.dev_attr))) + || data->type == w83687thf) { + err = device_create_file(dev, &sensor_dev_attr_pwm3.dev_attr); + if (err) goto ERROR4; + } if (data->type == w83637hf || data->type == w83687thf) if ((err = device_create_file(dev, @@ -1409,10 +1489,12 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) goto ERROR4; if (data->type == w83627thf || data->type == w83637hf - || data->type == w83687thf) - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm3_enable.dev_attr))) + || data->type == w83687thf) { + err = device_create_file(dev, + &sensor_dev_attr_pwm3_enable.dev_attr); + if (err) goto ERROR4; + } data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { @@ -1510,8 +1592,10 @@ static int __devinit w83627thf_read_gpio5(struct platform_device *pdev) goto exit; } - /* Make sure the pins are configured for input - There must be at least five (VRM 9), and possibly 6 (VRM 10) */ + /* + * Make sure the pins are configured for input + * There must be at least five (VRM 9), and possibly 6 (VRM 10) + */ sel = superio_inb(sio_data, W83627THF_GPIO5_IOSR) & 0x3f; if ((sel & 0x1f) != 0x1f) { dev_dbg(&pdev->dev, "GPIO5 not configured for VID " diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 17a8fa2d9ae9..b03d54a799e3 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1,37 +1,37 @@ /* - w83781d.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, - Philip Edelbrock <phil@netroedge.com>, - and Mark Studebaker <mdsxyz123@yahoo.com> - Copyright (c) 2007 - 2008 Jean Delvare <khali@linux-fr.org> - - 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. -*/ + * w83781d.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, + * Philip Edelbrock <phil@netroedge.com>, + * and Mark Studebaker <mdsxyz123@yahoo.com> + * Copyright (c) 2007 - 2008 Jean Delvare <khali@linux-fr.org> + * + * 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. + */ /* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - as99127f 7 3 0 3 0x31 0x12c3 yes no - as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no - w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes - w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes - w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no - -*/ + * Supports following chips: + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * as99127f 7 3 0 3 0x31 0x12c3 yes no + * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no + * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes + * w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes + * w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no + * + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -145,8 +145,10 @@ static const u8 W83781D_REG_PWM[] = { 0x5B, 0x5A, 0x5E, 0x5F }; #define W83781D_REG_I2C_ADDR 0x48 #define W83781D_REG_I2C_SUBADDR 0x4A -/* The following are undocumented in the data sheets however we - received the information in an email from Winbond tech support */ +/* + * The following are undocumented in the data sheets however we + * received the information in an email from Winbond tech support + */ /* Sensor selection - not on 781d */ #define W83781D_REG_SCFG1 0x5D static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 }; @@ -182,9 +184,9 @@ FAN_FROM_REG(u8 val, int div) #define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -127, 128) #define TEMP_FROM_REG(val) ((val) * 1000) -#define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ +#define BEEP_MASK_FROM_REG(val, type) ((type) == as99127f ? \ (~(val)) & 0x7fff : (val) & 0xff7fff) -#define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ +#define BEEP_MASK_TO_REG(val, type) ((type) == as99127f ? \ (~(val)) & 0x7fff : (val) & 0xff7fff) #define DIV_FROM_REG(val) (1 << (val)) @@ -238,9 +240,11 @@ struct w83781d_data { u32 beep_mask; /* Register encoding, combined */ u8 pwm[4]; /* Register value */ u8 pwm2_enable; /* Boolean */ - u16 sens[3]; /* 782D/783S only. - 1 = pentium diode; 2 = 3904 diode; - 4 = thermistor */ + u16 sens[3]; /* + * 782D/783S only. + * 1 = pentium diode; 2 = 3904 diode; + * 4 = thermistor + */ u8 vrm; }; @@ -254,7 +258,7 @@ static void w83781d_init_device(struct device *dev); /* following are the sysfs callback functions */ #define show_in_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \ char *buf) \ { \ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ @@ -267,20 +271,21 @@ show_in_reg(in_min); show_in_reg(in_max); #define store_in_reg(REG, reg) \ -static ssize_t store_in_##reg (struct device *dev, struct device_attribute \ +static ssize_t store_in_##reg(struct device *dev, struct device_attribute \ *da, const char *buf, size_t count) \ { \ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = dev_get_drvdata(dev); \ int nr = attr->index; \ - u32 val; \ - \ - val = simple_strtoul(buf, NULL, 10); \ - \ + unsigned long val; \ + int err = kstrtoul(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ data->in_##reg[nr] = IN_TO_REG(val); \ - w83781d_write_value(data, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ - \ + w83781d_write_value(data, W83781D_REG_IN_##REG(nr), \ + data->in_##reg[nr]); \ + \ mutex_unlock(&data->update_lock); \ return count; \ } @@ -306,12 +311,12 @@ sysfs_in_offsets(7); sysfs_in_offsets(8); #define show_fan_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \ char *buf) \ { \ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = w83781d_update_device(dev); \ - return sprintf(buf,"%ld\n", \ + return sprintf(buf, "%ld\n", \ FAN_FROM_REG(data->reg[attr->index], \ DIV_FROM_REG(data->fan_div[attr->index]))); \ } @@ -325,9 +330,12 @@ store_fan_min(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct w83781d_data *data = dev_get_drvdata(dev); int nr = attr->index; - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = @@ -350,17 +358,17 @@ static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR, show_fan_min, store_fan_min, 2); #define show_temp_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \ char *buf) \ { \ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = w83781d_update_device(dev); \ int nr = attr->index; \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ - return sprintf(buf,"%d\n", \ + return sprintf(buf, "%d\n", \ LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \ } else { /* TEMP1 */ \ - return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \ + return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->reg)); \ } \ } show_temp_reg(temp); @@ -368,16 +376,16 @@ show_temp_reg(temp_max); show_temp_reg(temp_max_hyst); #define store_temp_reg(REG, reg) \ -static ssize_t store_temp_##reg (struct device *dev, \ +static ssize_t store_temp_##reg(struct device *dev, \ struct device_attribute *da, const char *buf, size_t count) \ { \ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = dev_get_drvdata(dev); \ int nr = attr->index; \ long val; \ - \ - val = simple_strtol(buf, NULL, 10); \ - \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ @@ -425,13 +433,17 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) } static ssize_t -store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +store_vrm_reg(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct w83781d_data *data = dev_get_drvdata(dev); - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); - data->vrm = val; + err = kstrtoul(buf, 10, &val); + if (err) + return err; + data->vrm = SENSORS_LIMIT(val, 0, 255); return count; } @@ -480,7 +492,8 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp3_alarm, NULL, 0); -static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_beep_mask(struct device *dev, + struct device_attribute *attr, char *buf) { struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", @@ -492,9 +505,12 @@ store_beep_mask(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct w83781d_data *data = dev_get_drvdata(dev); - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->beep_mask &= 0x8000; /* preserve beep enable */ @@ -529,10 +545,14 @@ store_beep(struct device *dev, struct device_attribute *attr, { struct w83781d_data *data = dev_get_drvdata(dev); int bitnr = to_sensor_dev_attr(attr)->index; - unsigned long bit; u8 reg; + unsigned long bit; + int err; + + err = kstrtoul(buf, 10, &bit); + if (err) + return err; - bit = simple_strtoul(buf, NULL, 10); if (bit & ~1) return -EINVAL; @@ -620,10 +640,12 @@ show_fan_div(struct device *dev, struct device_attribute *da, char *buf) (long) DIV_FROM_REG(data->fan_div[attr->index])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *da, const char *buf, size_t count) @@ -633,7 +655,12 @@ store_fan_div(struct device *dev, struct device_attribute *da, unsigned long min; int nr = attr->index; u8 reg; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -643,10 +670,12 @@ store_fan_div(struct device *dev, struct device_attribute *da, data->fan_div[nr] = DIV_TO_REG(val, data->type); - reg = (w83781d_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) - & (nr==0 ? 0xcf : 0x3f)) - | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); - w83781d_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); + reg = (w83781d_read_value(data, nr == 2 ? + W83781D_REG_PIN : W83781D_REG_VID_FANDIV) + & (nr == 0 ? 0xcf : 0x3f)) + | ((data->fan_div[nr] & 0x03) << (nr == 0 ? 4 : 6)); + w83781d_write_value(data, nr == 2 ? + W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); /* w83781d and as99127f don't have extended divisor bits */ if (data->type != w83781d && data->type != as99127f) { @@ -693,9 +722,12 @@ store_pwm(struct device *dev, struct device_attribute *da, const char *buf, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct w83781d_data *data = dev_get_drvdata(dev); int nr = attr->index; - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); @@ -709,9 +741,13 @@ store_pwm2_enable(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct w83781d_data *data = dev_get_drvdata(dev); - u32 val, reg; + unsigned long val; + u32 reg; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -761,9 +797,13 @@ store_sensor(struct device *dev, struct device_attribute *da, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct w83781d_data *data = dev_get_drvdata(dev); int nr = attr->index; - u32 val, tmp; + unsigned long val; + u32 tmp; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -813,7 +853,8 @@ static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_sensor, store_sensor, 2); -/* Assumes that adapter is of I2C, not ISA variety. +/* + * Assumes that adapter is of I2C, not ISA variety. * OTHERWISE DON'T CALL THIS */ static int @@ -911,7 +952,7 @@ ERROR_SC_1: &sensor_dev_attr_temp##X##_alarm.dev_attr.attr, \ &sensor_dev_attr_temp##X##_beep.dev_attr.attr -static struct attribute* w83781d_attributes[] = { +static struct attribute *w83781d_attributes[] = { IN_UNIT_ATTRS(0), IN_UNIT_ATTRS(2), IN_UNIT_ATTRS(3), @@ -934,23 +975,58 @@ static const struct attribute_group w83781d_group = { .attrs = w83781d_attributes, }; -static struct attribute *w83781d_attributes_opt[] = { +static struct attribute *w83781d_attributes_in1[] = { IN_UNIT_ATTRS(1), + NULL +}; +static const struct attribute_group w83781d_group_in1 = { + .attrs = w83781d_attributes_in1, +}; + +static struct attribute *w83781d_attributes_in78[] = { IN_UNIT_ATTRS(7), IN_UNIT_ATTRS(8), + NULL +}; +static const struct attribute_group w83781d_group_in78 = { + .attrs = w83781d_attributes_in78, +}; + +static struct attribute *w83781d_attributes_temp3[] = { TEMP_UNIT_ATTRS(3), + NULL +}; +static const struct attribute_group w83781d_group_temp3 = { + .attrs = w83781d_attributes_temp3, +}; + +static struct attribute *w83781d_attributes_pwm12[] = { &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm2.dev_attr.attr, + &dev_attr_pwm2_enable.attr, + NULL +}; +static const struct attribute_group w83781d_group_pwm12 = { + .attrs = w83781d_attributes_pwm12, +}; + +static struct attribute *w83781d_attributes_pwm34[] = { &sensor_dev_attr_pwm3.dev_attr.attr, &sensor_dev_attr_pwm4.dev_attr.attr, - &dev_attr_pwm2_enable.attr, + NULL +}; +static const struct attribute_group w83781d_group_pwm34 = { + .attrs = w83781d_attributes_pwm34, +}; + +static struct attribute *w83781d_attributes_other[] = { &sensor_dev_attr_temp1_type.dev_attr.attr, &sensor_dev_attr_temp2_type.dev_attr.attr, &sensor_dev_attr_temp3_type.dev_attr.attr, NULL }; -static const struct attribute_group w83781d_group_opt = { - .attrs = w83781d_attributes_opt, +static const struct attribute_group w83781d_group_other = { + .attrs = w83781d_attributes_other, }; /* No clean up is done on error, it's up to the caller */ @@ -959,56 +1035,23 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) { int err; - if ((err = sysfs_create_group(&dev->kobj, &w83781d_group))) + err = sysfs_create_group(&dev->kobj, &w83781d_group); + if (err) return err; if (kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_in1_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in1_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in1_max.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in1_alarm.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in1_beep.dev_attr))) + err = sysfs_create_group(&dev->kobj, &w83781d_group_in1); + if (err) return err; } if (kind != as99127f && kind != w83781d && kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_in7_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in7_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in7_max.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in7_alarm.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in7_beep.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_max.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_alarm.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_beep.dev_attr))) + err = sysfs_create_group(&dev->kobj, &w83781d_group_in78); + if (err) return err; } if (kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_temp3_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp3_max.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp3_max_hyst.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp3_alarm.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp3_beep.dev_attr))) + err = sysfs_create_group(&dev->kobj, &w83781d_group_temp3); + if (err) return err; if (kind != w83781d) { @@ -1021,30 +1064,29 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) } if (kind != w83781d && kind != as99127f) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm1.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm2.dev_attr)) - || (err = device_create_file(dev, &dev_attr_pwm2_enable))) + err = sysfs_create_group(&dev->kobj, &w83781d_group_pwm12); + if (err) return err; } if (kind == w83782d && !is_isa) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm3.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm4.dev_attr))) + err = sysfs_create_group(&dev->kobj, &w83781d_group_pwm34); + if (err) return err; } if (kind != as99127f && kind != w83781d) { - if ((err = device_create_file(dev, - &sensor_dev_attr_temp1_type.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp2_type.dev_attr))) + err = device_create_file(dev, + &sensor_dev_attr_temp1_type.dev_attr); + if (err) + return err; + err = device_create_file(dev, + &sensor_dev_attr_temp2_type.dev_attr); + if (err) return err; if (kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_temp3_type.dev_attr))) + err = device_create_file(dev, + &sensor_dev_attr_temp3_type.dev_attr); + if (err) return err; } } @@ -1066,9 +1108,11 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - /* We block updates of the ISA device to minimize the risk of - concurrent access to the same W83781D chip through different - interfaces. */ + /* + * We block updates of the ISA device to minimize the risk of + * concurrent access to the same W83781D chip through different + * interfaces. + */ if (isa) mutex_lock(&isa->update_lock); @@ -1083,15 +1127,17 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info) /* Check for Winbond or Asus ID if in bank 0 */ if (!(val1 & 0x07) && ((!(val1 & 0x80) && val2 != 0xa3 && val2 != 0xc3) || - ( (val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) { + ((val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) { dev_dbg(&adapter->dev, "Detection of w83781d chip failed at step 4\n"); goto err_nodev; } - /* If Winbond SMBus, check address at 0x48. - Asus doesn't support, except for as99127f rev.2 */ + /* + * If Winbond SMBus, check address at 0x48. + * Asus doesn't support, except for as99127f rev.2 + */ if ((!(val1 & 0x80) && val2 == 0xa3) || - ( (val1 & 0x80) && val2 == 0x5c)) { + ((val1 & 0x80) && val2 == 0x5c)) { if (i2c_smbus_read_byte_data(client, W83781D_REG_I2C_ADDR) != address) { dev_dbg(&adapter->dev, @@ -1149,6 +1195,17 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info) return -ENODEV; } +static void w83781d_remove_files(struct device *dev) +{ + sysfs_remove_group(&dev->kobj, &w83781d_group); + sysfs_remove_group(&dev->kobj, &w83781d_group_in1); + sysfs_remove_group(&dev->kobj, &w83781d_group_in78); + sysfs_remove_group(&dev->kobj, &w83781d_group_temp3); + sysfs_remove_group(&dev->kobj, &w83781d_group_pwm12); + sysfs_remove_group(&dev->kobj, &w83781d_group_pwm34); + sysfs_remove_group(&dev->kobj, &w83781d_group_other); +} + static int w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1191,9 +1248,7 @@ w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; ERROR4: - sysfs_remove_group(&dev->kobj, &w83781d_group); - sysfs_remove_group(&dev->kobj, &w83781d_group_opt); - + w83781d_remove_files(dev); if (data->lm75[0]) i2c_unregister_device(data->lm75[0]); if (data->lm75[1]) @@ -1211,9 +1266,7 @@ w83781d_remove(struct i2c_client *client) struct device *dev = &client->dev; hwmon_device_unregister(data->hwmon_dev); - - sysfs_remove_group(&dev->kobj, &w83781d_group); - sysfs_remove_group(&dev->kobj, &w83781d_group_opt); + w83781d_remove_files(dev); if (data->lm75[0]) i2c_unregister_device(data->lm75[0]); @@ -1310,35 +1363,47 @@ w83781d_init_device(struct device *dev) int type = data->type; u8 tmp; - if (reset && type != as99127f) { /* this resets registers we don't have - documentation for on the as99127f */ - /* Resetting the chip has been the default for a long time, - but it causes the BIOS initializations (fan clock dividers, - thermal sensor types...) to be lost, so it is now optional. - It might even go away if nobody reports it as being useful, - as I see very little reason why this would be needed at - all. */ + if (reset && type != as99127f) { /* + * this resets registers we don't have + * documentation for on the as99127f + */ + /* + * Resetting the chip has been the default for a long time, + * but it causes the BIOS initializations (fan clock dividers, + * thermal sensor types...) to be lost, so it is now optional. + * It might even go away if nobody reports it as being useful, + * as I see very little reason why this would be needed at + * all. + */ dev_info(dev, "If reset=1 solved a problem you were " "having, please report!\n"); /* save these registers */ i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); p = w83781d_read_value(data, W83781D_REG_PWMCLK12); - /* Reset all except Watchdog values and last conversion values - This sets fan-divs to 2, among others */ + /* + * Reset all except Watchdog values and last conversion values + * This sets fan-divs to 2, among others + */ w83781d_write_value(data, W83781D_REG_CONFIG, 0x80); - /* Restore the registers and disable power-on abnormal beep. - This saves FAN 1/2/3 input/output values set by BIOS. */ + /* + * Restore the registers and disable power-on abnormal beep. + * This saves FAN 1/2/3 input/output values set by BIOS. + */ w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); w83781d_write_value(data, W83781D_REG_PWMCLK12, p); - /* Disable master beep-enable (reset turns it on). - Individual beep_mask should be reset to off but for some reason - disabling this bit helps some people not get beeped */ + /* + * Disable master beep-enable (reset turns it on). + * Individual beep_mask should be reset to off but for some + * reason disabling this bit helps some people not get beeped + */ w83781d_write_value(data, W83781D_REG_BEEP_INTS2, 0); } - /* Disable power-on abnormal beep, as advised by the datasheet. - Already done if reset=1. */ + /* + * Disable power-on abnormal beep, as advised by the datasheet. + * Already done if reset=1. + */ if (init && !reset && type != as99127f) { i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); @@ -1444,7 +1509,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) } /* Only PWM2 can be disabled */ data->pwm2_enable = (w83781d_read_value(data, - W83781D_REG_PWMCLK12) & 0x08) >> 3; + W83781D_REG_PWMCLK12) & 0x08) >> 3; } data->temp = w83781d_read_value(data, W83781D_REG_TEMP(1)); @@ -1495,8 +1560,10 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | (w83781d_read_value(data, W83782D_REG_ALARM2) << 8); } else { - /* No real-time status registers, fall back to - interrupt status registers */ + /* + * No real-time status registers, fall back to + * interrupt status registers + */ data->alarms = w83781d_read_value(data, W83781D_REG_ALARM1) | (w83781d_read_value(data, @@ -1550,8 +1617,10 @@ static struct platform_device *pdev; static unsigned short isa_address = 0x290; -/* I2C devices get this name attribute automatically, but for ISA devices - we must create it by ourselves. */ +/* + * I2C devices get this name attribute automatically, but for ISA devices + * we must create it by ourselves. + */ static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -1581,8 +1650,10 @@ static int w83781d_alias_detect(struct i2c_client *client, u8 chipid) if (w83781d_read_value(isa, W83781D_REG_WCHIPID) != chipid) return 0; /* Chip type doesn't match */ - /* We compare all the limit registers, the config register and the - * interrupt mask registers */ + /* + * We compare all the limit registers, the config register and the + * interrupt mask registers + */ for (i = 0x2b; i <= 0x3d; i++) { if (w83781d_read_value(isa, i) != i2c_smbus_read_byte_data(client, i)) @@ -1663,12 +1734,14 @@ w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value) } } -/* The SMBus locks itself, usually, but nothing may access the Winbond between - bank switches. ISA access must always be locked explicitly! - We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, - would slow down the W83781D access and should not be necessary. - There are some ugly typecasts here, but the good news is - they should - nowhere else be necessary! */ +/* + * The SMBus locks itself, usually, but nothing may access the Winbond between + * bank switches. ISA access must always be locked explicitly! + * We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, + * would slow down the W83781D access and should not be necessary. + * There are some ugly typecasts here, but the good news is - they should + * nowhere else be necessary! + */ static int w83781d_read_value(struct w83781d_data *data, u16 reg) { @@ -1754,8 +1827,7 @@ w83781d_isa_probe(struct platform_device *pdev) return 0; exit_remove_files: - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); + w83781d_remove_files(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_name); kfree(data); exit_release_region: @@ -1770,8 +1842,7 @@ w83781d_isa_remove(struct platform_device *pdev) struct w83781d_data *data = platform_get_drvdata(pdev); hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); + w83781d_remove_files(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_name); release_region(data->isa_addr + W83781D_ADDR_REG_OFFSET, 2); kfree(data); @@ -1795,9 +1866,11 @@ w83781d_isa_found(unsigned short address) int val, save, found = 0; int port; - /* Some boards declare base+0 to base+7 as a PNP device, some base+4 + /* + * Some boards declare base+0 to base+7 as a PNP device, some base+4 * to base+7 and some base+5 to base+6. So we better request each port - * individually for the probing phase. */ + * individually for the probing phase. + */ for (port = address; port < address + W83781D_EXTENT; port++) { if (!request_region(port, 1, "w83781d")) { pr_debug("Failed to request port 0x%x\n", port); @@ -1806,8 +1879,10 @@ w83781d_isa_found(unsigned short address) } #define REALLY_SLOW_IO - /* We need the timeouts for at least some W83781D-like - chips. But only if we read 'undefined' registers. */ + /* + * We need the timeouts for at least some W83781D-like + * chips. But only if we read 'undefined' registers. + */ val = inb_p(address + 1); if (inb_p(address + 2) != val || inb_p(address + 3) != val @@ -1817,8 +1892,10 @@ w83781d_isa_found(unsigned short address) } #undef REALLY_SLOW_IO - /* We should be able to change the 7 LSB of the address port. The - MSB (busy flag) should be clear initially, set after the write. */ + /* + * We should be able to change the 7 LSB of the address port. The + * MSB (busy flag) should be clear initially, set after the write. + */ save = inb_p(address + W83781D_ADDR_REG_OFFSET); if (save & 0x80) { pr_debug("Detection failed at step %d\n", 2); @@ -2004,8 +2081,10 @@ sensors_w83781d_init(void) { int res; - /* We register the ISA device first, so that we can skip the - * registration of an I2C interface to the same device. */ + /* + * We register the ISA device first, so that we can skip the + * registration of an I2C interface to the same device. + */ res = w83781d_isa_register(); if (res) goto exit; diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 35aa5149307a..2f446f92acf2 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -1,36 +1,36 @@ /* - w83791d.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - - Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * w83791d.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * + * Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - w83791d 10 5 5 3 0x71 0x5ca3 yes no - - The w83791d chip appears to be part way between the 83781d and the - 83792d. Thus, this file is derived from both the w83792d.c and - w83781d.c files. - - The w83791g chip is the same as the w83791d but lead-free. -*/ + * Supports following chips: + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * w83791d 10 5 5 3 0x71 0x5ca3 yes no + * + * The w83791d chip appears to be part way between the 83781d and the + * 83792d. Thus, this file is derived from both the w83792d.c and + * w83781d.c files. + * + * The w83791g chip is the same as the w83791d but lead-free. + */ #include <linux/module.h> #include <linux/init.h> @@ -198,10 +198,12 @@ static const u8 W83791D_REG_BEEP_CTRL[3] = { #define W83791D_REG_VBAT 0x5D #define W83791D_REG_I2C_ADDR 0x48 -/* The SMBus locks itself. The Winbond W83791D has a bank select register - (index 0x4e), but the driver only accesses registers in bank 0. Since - we don't switch banks, we don't need any special code to handle - locking access between bank switches */ +/* + * The SMBus locks itself. The Winbond W83791D has a bank select register + * (index 0x4e), but the driver only accesses registers in bank 0. Since + * we don't switch banks, we don't need any special code to handle + * locking access between bank switches + */ static inline int w83791d_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); @@ -212,9 +214,11 @@ static inline int w83791d_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -/* The analog voltage inputs have 16mV LSB. Since the sysfs output is - in mV as would be measured on the chip input pin, need to just - multiply/divide by 16 to translate from/to register values. */ +/* + * The analog voltage inputs have 16mV LSB. Since the sysfs output is + * in mV as would be measured on the chip input pin, need to just + * multiply/divide by 16 to translate from/to register values. + */ #define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8) / 16), 0, 255)) #define IN_FROM_REG(val) ((val) * 16) @@ -226,7 +230,7 @@ static u8 fan_to_reg(long rpm, int div) return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ +#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ ((val) == 255 ? 0 : \ 1350000 / ((val) * (div)))) @@ -237,10 +241,12 @@ static u8 fan_to_reg(long rpm, int div) (val) < 0 ? ((val) - 500) / 1000 : \ ((val) + 500) / 1000) -/* for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius - Assumes the top 8 bits are the integral amount and the bottom 8 bits - are the fractional amount. Since we only have 0.5 degree resolution, - the bottom 7 bits will always be zero */ +/* + * for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius + * Assumes the top 8 bits are the integral amount and the bottom 8 bits + * are the fractional amount. Since we only have 0.5 degree resolution, + * the bottom 7 bits will always be zero + */ #define TEMP23_FROM_REG(val) ((val) / 128 * 500) #define TEMP23_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ (val) >= 127500 ? 0x7F80 : \ @@ -300,17 +306,19 @@ struct w83791d_data { s8 temp1[3]; /* current, over, thyst */ s16 temp_add[2][3]; /* fixed point value. Top 8 bits are the - integral part, bottom 8 bits are the - fractional part. We only use the top - 9 bits as the resolution is only - to the 0.5 degree C... - two sensors with three values - (cur, over, hyst) */ + * integral part, bottom 8 bits are the + * fractional part. We only use the top + * 9 bits as the resolution is only + * to the 0.5 degree C... + * two sensors with three values + * (cur, over, hyst) + */ /* PWMs */ u8 pwm[5]; /* pwm duty cycle */ u8 pwm_enable[3]; /* pwm enable status for fan 1-3 - (fan 4-5 only support manual mode) */ + * (fan 4-5 only support manual mode) + */ u8 temp_target[3]; /* pwm 1-3 target temperature */ u8 temp_tolerance[3]; /* pwm 1-3 temperature tolerance */ @@ -366,7 +374,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ to_sensor_dev_attr(attr); \ struct w83791d_data *data = w83791d_update_device(dev); \ int nr = sensor_attr->index; \ - return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \ + return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \ } show_in_reg(in); @@ -382,9 +390,11 @@ static ssize_t store_in_##reg(struct device *dev, \ to_sensor_dev_attr(attr); \ struct i2c_client *client = to_i2c_client(dev); \ struct w83791d_data *data = i2c_get_clientdata(client); \ - unsigned long val = simple_strtoul(buf, NULL, 10); \ int nr = sensor_attr->index; \ - \ + unsigned long val; \ + int err = kstrtoul(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ data->in_##reg[nr] = IN_TO_REG(val); \ w83791d_write(client, W83791D_REG_IN_##REG[nr], data->in_##reg[nr]); \ @@ -455,7 +465,14 @@ static ssize_t store_beep(struct device *dev, struct device_attribute *attr, struct w83791d_data *data = i2c_get_clientdata(client); int bitnr = sensor_attr->index; int bytenr = bitnr / 8; - long val = simple_strtol(buf, NULL, 10) ? 1 : 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + val = val ? 1 : 0; mutex_lock(&data->update_lock); @@ -485,8 +502,10 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); } -/* Note: The bitmask for the beep enable/disable is different than - the bitmask for the alarm. */ +/* + * Note: The bitmask for the beep enable/disable is different than + * the bitmask for the alarm. + */ static struct sensor_device_attribute sda_in_beep[] = { SENSOR_ATTR(in0_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 0), SENSOR_ATTR(in1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 13), @@ -521,7 +540,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ to_sensor_dev_attr(attr); \ struct w83791d_data *data = w83791d_update_device(dev); \ int nr = sensor_attr->index; \ - return sprintf(buf,"%d\n", \ + return sprintf(buf, "%d\n", \ FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ } @@ -534,8 +553,13 @@ static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct i2c_client *client = to_i2c_client(dev); struct w83791d_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); int nr = sensor_attr->index; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr])); @@ -554,10 +578,12 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -572,12 +598,18 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, int indx = 0; u8 keep_mask = 0; u8 new_shift = 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; /* Save fan_min */ min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); mutex_lock(&data->update_lock); - data->fan_div[nr] = div_to_reg(nr, simple_strtoul(buf, NULL, 10)); + data->fan_div[nr] = div_to_reg(nr, val); switch (nr) { case 0: @@ -918,8 +950,13 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *devattr, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct i2c_client *client = to_i2c_client(dev); struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); int nr = attr->index; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp1[nr] = TEMP1_TO_REG(val); @@ -946,10 +983,15 @@ static ssize_t store_temp23(struct device *dev, struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct i2c_client *client = to_i2c_client(dev); struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; int nr = attr->nr; int index = attr->index; + err = kstrtol(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); data->temp_add[nr][index] = TEMP23_TO_REG(val); w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2], @@ -985,8 +1027,10 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { show_temp23, store_temp23, 1, 2), }; -/* Note: The bitmask for the beep enable/disable is different than - the bitmask for the alarm. */ +/* + * Note: The bitmask for the beep enable/disable is different than + * the bitmask for the alarm. + */ static struct sensor_device_attribute sda_temp_beep[] = { SENSOR_ATTR(temp1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 4), SENSOR_ATTR(temp2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 5), @@ -1035,13 +1079,20 @@ static ssize_t store_beep_mask(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); int i; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - /* The beep_enable state overrides any enabling request from - the masks */ + /* + * The beep_enable state overrides any enabling request from + * the masks + */ data->beep_mask = BEEP_MASK_TO_REG(val) & ~GLOBAL_BEEP_ENABLE_MASK; data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT); @@ -1063,7 +1114,12 @@ static ssize_t store_beep_enable(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct w83791d_data *data = i2c_get_clientdata(client); - long val = simple_strtol(buf, NULL, 10); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); @@ -1073,8 +1129,10 @@ static ssize_t store_beep_enable(struct device *dev, data->beep_mask &= ~GLOBAL_BEEP_ENABLE_MASK; data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT); - /* The global control is in the second beep control register - so only need to update that register */ + /* + * The global control is in the second beep control register + * so only need to update that register + */ val = (data->beep_mask >> 8) & 0xff; w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val); @@ -1113,36 +1171,44 @@ static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count) { struct w83791d_data *data = dev_get_drvdata(dev); + unsigned long val; + int err; + + /* + * No lock needed as vrm is internal to the driver + * (not read from a chip register) and so is not + * updated in w83791d_update_device() + */ - /* No lock needed as vrm is internal to the driver - (not read from a chip register) and so is not - updated in w83791d_update_device() */ - data->vrm = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; + data->vrm = val; return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); #define IN_UNIT_ATTRS(X) \ - &sda_in_input[X].dev_attr.attr, \ - &sda_in_min[X].dev_attr.attr, \ - &sda_in_max[X].dev_attr.attr, \ - &sda_in_beep[X].dev_attr.attr, \ + &sda_in_input[X].dev_attr.attr, \ + &sda_in_min[X].dev_attr.attr, \ + &sda_in_max[X].dev_attr.attr, \ + &sda_in_beep[X].dev_attr.attr, \ &sda_in_alarm[X].dev_attr.attr #define FAN_UNIT_ATTRS(X) \ - &sda_fan_input[X].dev_attr.attr, \ - &sda_fan_min[X].dev_attr.attr, \ - &sda_fan_div[X].dev_attr.attr, \ - &sda_fan_beep[X].dev_attr.attr, \ + &sda_fan_input[X].dev_attr.attr, \ + &sda_fan_min[X].dev_attr.attr, \ + &sda_fan_div[X].dev_attr.attr, \ + &sda_fan_beep[X].dev_attr.attr, \ &sda_fan_alarm[X].dev_attr.attr #define TEMP_UNIT_ATTRS(X) \ - &sda_temp_input[X].dev_attr.attr, \ - &sda_temp_max[X].dev_attr.attr, \ - &sda_temp_max_hyst[X].dev_attr.attr, \ - &sda_temp_beep[X].dev_attr.attr, \ + &sda_temp_input[X].dev_attr.attr, \ + &sda_temp_max[X].dev_attr.attr, \ + &sda_temp_max_hyst[X].dev_attr.attr, \ + &sda_temp_beep[X].dev_attr.attr, \ &sda_temp_alarm[X].dev_attr.attr static struct attribute *w83791d_attributes[] = { @@ -1186,9 +1252,11 @@ static const struct attribute_group w83791d_group = { .attrs = w83791d_attributes, }; -/* Separate group of attributes for fan/pwm 4-5. Their pins can also be - in use for GPIO in which case their sysfs-interface should not be made - available */ +/* + * Separate group of attributes for fan/pwm 4-5. Their pins can also be + * in use for GPIO in which case their sysfs-interface should not be made + * available + */ static struct attribute *w83791d_attributes_fanpwm45[] = { FAN_UNIT_ATTRS(3), FAN_UNIT_ATTRS(4), @@ -1228,9 +1296,8 @@ static int w83791d_detect_subclients(struct i2c_client *client) } val = w83791d_read(client, W83791D_REG_I2C_SUBADDR); - if (!(val & 0x08)) { + if (!(val & 0x08)) data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7)); - } if (!(val & 0x80)) { if ((data->lm75[0] != NULL) && ((val & 0x7) == ((val >> 4) & 0x7))) { @@ -1265,9 +1332,8 @@ static int w83791d_detect(struct i2c_client *client, int val1, val2; unsigned short address = client->addr; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - } if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) return -ENODEV; @@ -1277,12 +1343,14 @@ static int w83791d_detect(struct i2c_client *client, /* Check for Winbond ID if in bank 0 */ if (!(val1 & 0x07)) { if ((!(val1 & 0x80) && val2 != 0xa3) || - ( (val1 & 0x80) && val2 != 0x5c)) { + ((val1 & 0x80) && val2 != 0x5c)) { return -ENODEV; } } - /* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR - should match */ + /* + * If Winbond chip, address of chip and W83791D_REG_I2C_ADDR + * should match + */ if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) return -ENODEV; @@ -1332,14 +1400,16 @@ static int w83791d_probe(struct i2c_client *client, /* Initialize the chip */ w83791d_init_client(client); - /* If the fan_div is changed, make sure there is a rational - fan_min in place */ - for (i = 0; i < NUMBER_OF_FANIN; i++) { + /* + * If the fan_div is changed, make sure there is a rational + * fan_min in place + */ + for (i = 0; i < NUMBER_OF_FANIN; i++) data->fan_min[i] = w83791d_read(client, W83791D_REG_FAN_MIN[i]); - } /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group))) + err = sysfs_create_group(&client->dev.kobj, &w83791d_group); + if (err) goto error3; /* Check if pins of fan/pwm 4-5 are in use as GPIO */ @@ -1398,19 +1468,20 @@ static void w83791d_init_client(struct i2c_client *client) u8 tmp; u8 old_beep; - /* The difference between reset and init is that reset - does a hard reset of the chip via index 0x40, bit 7, - but init simply forces certain registers to have "sane" - values. The hope is that the BIOS has done the right - thing (which is why the default is reset=0, init=0), - but if not, reset is the hard hammer and init - is the soft mallet both of which are trying to whack - things into place... - NOTE: The data sheet makes a distinction between - "power on defaults" and "reset by MR". As far as I can tell, - the hard reset puts everything into a power-on state so I'm - not sure what "reset by MR" means or how it can happen. - */ + /* + * The difference between reset and init is that reset + * does a hard reset of the chip via index 0x40, bit 7, + * but init simply forces certain registers to have "sane" + * values. The hope is that the BIOS has done the right + * thing (which is why the default is reset=0, init=0), + * but if not, reset is the hard hammer and init + * is the soft mallet both of which are trying to whack + * things into place... + * NOTE: The data sheet makes a distinction between + * "power on defaults" and "reset by MR". As far as I can tell, + * the hard reset puts everything into a power-on state so I'm + * not sure what "reset by MR" means or how it can happen. + */ if (reset || init) { /* keep some BIOS settings when we... */ old_beep = w83791d_read(client, W83791D_REG_BEEP_CONFIG); @@ -1494,8 +1565,10 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) data->fan_div[3] = reg_array_tmp[2] & 0x07; data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; - /* The fan divisor for fans 0-2 get bit 2 from - bits 5-7 respectively of vbat register */ + /* + * The fan divisor for fans 0-2 get bit 2 from + * bits 5-7 respectively of vbat register + */ vbat_reg = w83791d_read(client, W83791D_REG_VBAT); for (i = 0; i < 3; i++) data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04; @@ -1601,12 +1674,13 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev) dev_dbg(dev, "fan_div[%d] is: 0x%02x\n", i, data->fan_div[i]); } - /* temperature math is signed, but only print out the - bits that matter */ + /* + * temperature math is signed, but only print out the + * bits that matter + */ dev_dbg(dev, "%d set of Temperatures: ===>\n", NUMBER_OF_TEMPIN); - for (i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) dev_dbg(dev, "temp1[%d] is: 0x%02x\n", i, (u8) data->temp1[i]); - } for (i = 0; i < 2; i++) { for (j = 0; j < 3; j++) { dev_dbg(dev, "temp_add[%d][%d] is: 0x%04x\n", i, j, @@ -1625,19 +1699,8 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev) } #endif -static int __init sensors_w83791d_init(void) -{ - return i2c_add_driver(&w83791d_driver); -} - -static void __exit sensors_w83791d_exit(void) -{ - i2c_del_driver(&w83791d_driver); -} +module_i2c_driver(w83791d_driver); MODULE_AUTHOR("Charles Spirakis <bezaur@gmail.com>"); MODULE_DESCRIPTION("W83791D driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_w83791d_init); -module_exit(sensors_w83791d_exit); diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index d3100eab6b2f..ffb5fdfecf0d 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -1,39 +1,39 @@ /* - w83792d.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (C) 2004, 2005 Winbond Electronics Corp. - Chunhao Huang <DZShen@Winbond.com.tw>, - Rudolf Marek <r.marek@assembler.cz> - - 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. - - Note: - 1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver. - 2. This driver is only for Winbond W83792D C version device, there - are also some motherboards with B version W83792D device. The - calculation method to in6-in7(measured value, limits) is a little - different between C and B version. C or B version can be identified - by CR[0x49h]. -*/ + * w83792d.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2004, 2005 Winbond Electronics Corp. + * Chunhao Huang <DZShen@Winbond.com.tw>, + * Rudolf Marek <r.marek@assembler.cz> + * + * 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. + * + * Note: + * 1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver. + * 2. This driver is only for Winbond W83792D C version device, there + * are also some motherboards with B version W83792D device. The + * calculation method to in6-in7(measured value, limits) is a little + * different between C and B version. C or B version can be identified + * by CR[0x49h]. + */ /* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - w83792d 9 7 7 3 0x7a 0x5ca3 yes no -*/ + * Supports following chips: + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * w83792d 9 7 7 3 0x7a 0x5ca3 yes no + */ #include <linux/module.h> #include <linux/init.h> @@ -218,14 +218,16 @@ static const u8 W83792D_REG_LEVELS[3][4] = { #define W83792D_REG_VBAT 0x5D #define W83792D_REG_I2C_ADDR 0x48 -/* Conversions. Rounding and limit checking is only done on the TO_REG - variants. Note that you should be a bit careful with which arguments - these macros are called: arguments may be evaluated more than once. - Fixing this is just not worth it. */ -#define IN_FROM_REG(nr,val) (((nr)<=1)?(val*2): \ - ((((nr)==6)||((nr)==7))?(val*6):(val*4))) -#define IN_TO_REG(nr,val) (((nr)<=1)?(val/2): \ - ((((nr)==6)||((nr)==7))?(val/6):(val/4))) +/* + * Conversions. Rounding and limit checking is only done on the TO_REG + * variants. Note that you should be a bit careful with which arguments + * these macros are called: arguments may be evaluated more than once. + * Fixing this is just not worth it. + */ +#define IN_FROM_REG(nr, val) (((nr) <= 1) ? ((val) * 2) : \ + ((((nr) == 6) || ((nr) == 7)) ? ((val) * 6) : ((val) * 4))) +#define IN_TO_REG(nr, val) (((nr) <= 1) ? ((val) / 2) : \ + ((((nr) == 6) || ((nr) == 7)) ? ((val) / 6) : ((val) / 4))) static inline u8 FAN_TO_REG(long rpm, int div) @@ -236,7 +238,7 @@ FAN_TO_REG(long rpm, int div) return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ +#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ ((val) == 255 ? 0 : \ 1350000 / ((val) * (div)))) @@ -265,7 +267,7 @@ DIV_TO_REG(long val) break; val >>= 1; } - return ((u8) i); + return (u8)i; } struct w83792d_data { @@ -287,8 +289,10 @@ struct w83792d_data { u8 temp1[3]; /* current, over, thyst */ u8 temp_add[2][6]; /* Register value */ u8 fan_div[7]; /* Register encoding, shifted right */ - u8 pwm[7]; /* We only consider the first 3 set of pwm, - although 792 chip has 7 set of pwm. */ + u8 pwm[7]; /* + * We only consider the first 3 set of pwm, + * although 792 chip has 7 set of pwm. + */ u8 pwmenable[3]; u32 alarms; /* realtime status register encoding,combined */ u8 chassis; /* Chassis status */ @@ -333,12 +337,14 @@ static struct i2c_driver w83792d_driver = { static inline long in_count_from_reg(int nr, struct w83792d_data *data) { /* in7 and in8 do not have low bits, but the formula still works */ - return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); + return (data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03); } -/* The SMBus locks itself. The Winbond W83792D chip has a bank register, - but the driver only accesses registers in bank 0, so we don't have - to switch banks and lock access between switches. */ +/* + * The SMBus locks itself. The Winbond W83792D chip has a bank register, + * but the driver only accesses registers in bank 0, so we don't have + * to switch banks and lock access between switches. + */ static inline int w83792d_read_value(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); @@ -357,37 +363,43 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); - return sprintf(buf,"%ld\n", IN_FROM_REG(nr,(in_count_from_reg(nr, data)))); + return sprintf(buf, "%ld\n", + IN_FROM_REG(nr, in_count_from_reg(nr, data))); } #define show_in_reg(reg) \ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + struct sensor_device_attribute *sensor_attr \ + = to_sensor_dev_attr(attr); \ int nr = sensor_attr->index; \ struct w83792d_data *data = w83792d_update_device(dev); \ - return sprintf(buf,"%ld\n", (long)(IN_FROM_REG(nr, (data->reg[nr])*4))); \ + return sprintf(buf, "%ld\n", \ + (long)(IN_FROM_REG(nr, data->reg[nr]) * 4)); \ } show_in_reg(in_min); show_in_reg(in_max); #define store_in_reg(REG, reg) \ -static ssize_t store_in_##reg (struct device *dev, \ +static ssize_t store_in_##reg(struct device *dev, \ struct device_attribute *attr, \ const char *buf, size_t count) \ { \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + struct sensor_device_attribute *sensor_attr \ + = to_sensor_dev_attr(attr); \ int nr = sensor_attr->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct w83792d_data *data = i2c_get_clientdata(client); \ - u32 val; \ - \ - val = simple_strtoul(buf, NULL, 10); \ + unsigned long val; \ + int err = kstrtoul(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ - data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \ - w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \ + data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val) / 4, 0, 255); \ + w83792d_write_value(client, W83792D_REG_IN_##REG[nr], \ + data->in_##reg[nr]); \ mutex_unlock(&data->update_lock); \ \ return count; \ @@ -396,13 +408,14 @@ store_in_reg(MIN, min); store_in_reg(MAX, max); #define show_fan_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + struct sensor_device_attribute *sensor_attr \ + = to_sensor_dev_attr(attr); \ int nr = sensor_attr->index - 1; \ struct w83792d_data *data = w83792d_update_device(dev); \ - return sprintf(buf,"%d\n", \ + return sprintf(buf, "%d\n", \ FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ } @@ -417,9 +430,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], @@ -439,10 +456,12 @@ show_fan_div(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr - 1])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -455,13 +474,19 @@ store_fan_div(struct device *dev, struct device_attribute *attr, /*u8 reg;*/ u8 fan_div_reg = 0; u8 tmp_fan_div; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; /* Save fan_min */ mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); - data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10)); + data->fan_div[nr] = DIV_TO_REG(val); fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]); fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8; @@ -496,9 +521,13 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - s32 val; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; - val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); data->temp1[nr] = TEMP1_TO_REG(val); w83792d_write_value(client, W83792D_REG_TEMP1[nr], @@ -513,11 +542,12 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr, static ssize_t show_temp23(struct device *dev, struct device_attribute *attr, char *buf) { - struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + struct sensor_device_attribute_2 *sensor_attr + = to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); - return sprintf(buf,"%ld\n", + return sprintf(buf, "%ld\n", (long)TEMP_ADD_FROM_REG(data->temp_add[nr][index], data->temp_add[nr][index+1])); } @@ -525,14 +555,19 @@ static ssize_t show_temp23(struct device *dev, struct device_attribute *attr, static ssize_t store_temp23(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + struct sensor_device_attribute_2 *sensor_attr + = to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - s32 val; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; - val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val); data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val); @@ -604,7 +639,13 @@ store_pwm(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255) >> 4; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255) >> 4; mutex_lock(&data->update_lock); val |= w83792d_read_value(client, W83792D_REG_PWM[nr]) & 0xf0; @@ -623,10 +664,14 @@ store_pwmenable(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); if (val < 1 || val > 3) return -EINVAL; @@ -645,7 +690,7 @@ store_pwmenable(struct device *dev, struct device_attribute *attr, cfg1_tmp = data->pwmenable[0]; cfg2_tmp = (data->pwmenable[1]) << 2; cfg3_tmp = (data->pwmenable[2]) << 4; - cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0; + cfg4_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG) & 0xc0; fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp; w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp); mutex_unlock(&data->update_lock); @@ -671,10 +716,13 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); - if (val != 0 && val != 1) + err = kstrtoul(buf, 10, &val); + if (err) + return err; + if (val > 1) return -EINVAL; mutex_lock(&data->update_lock); @@ -721,16 +769,20 @@ store_chassis_clear_legacy(struct device *dev, struct device_attribute *attr, { struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; + unsigned long val; + int err; u8 temp1 = 0, temp2 = 0; dev_warn(dev, "Attribute %s is deprecated, use intrusion0_alarm instead\n", "chassis_clear"); - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; + mutex_lock(&data->update_lock); - data->chassis_clear = SENSORS_LIMIT(val, 0 ,1); + data->chassis_clear = SENSORS_LIMIT(val, 0, 1); temp1 = ((data->chassis_clear) << 7) & 0x80; temp2 = w83792d_read_value(client, W83792D_REG_CHASSIS_CLR) & 0x7f; @@ -780,14 +832,19 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; - u8 target_tmp=0, target_mask=0; + u8 target_tmp = 0, target_mask = 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); target_tmp = val; target_tmp = target_tmp & 0x7f; mutex_lock(&data->update_lock); - target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80; + target_mask = w83792d_read_value(client, + W83792D_REG_THERMAL[nr]) & 0x80; data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255); w83792d_write_value(client, W83792D_REG_THERMAL[nr], (data->thermal_cruise[nr]) | target_mask); @@ -815,19 +872,22 @@ store_tolerance(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; u8 tol_tmp, tol_mask; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); tol_mask = w83792d_read_value(client, W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0); tol_tmp = SENSORS_LIMIT(val, 0, 15); tol_tmp &= 0x0f; data->tolerance[nr] = tol_tmp; - if (nr == 1) { + if (nr == 1) tol_tmp <<= 4; - } w83792d_write_value(client, W83792D_REG_TOLERANCE[nr], tol_mask | tol_tmp); mutex_unlock(&data->update_lock); @@ -840,7 +900,8 @@ static ssize_t show_sf2_point(struct device *dev, struct device_attribute *attr, char *buf) { - struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + struct sensor_device_attribute_2 *sensor_attr + = to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); @@ -851,15 +912,20 @@ static ssize_t store_sf2_point(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + struct sensor_device_attribute_2 *sensor_attr + = to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr - 1; int index = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; u8 mask_tmp = 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127); mask_tmp = w83792d_read_value(client, @@ -875,7 +941,8 @@ static ssize_t show_sf2_level(struct device *dev, struct device_attribute *attr, char *buf) { - struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + struct sensor_device_attribute_2 *sensor_attr + = to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; struct w83792d_data *data = w83792d_update_device(dev); @@ -887,25 +954,30 @@ static ssize_t store_sf2_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr); + struct sensor_device_attribute_2 *sensor_attr + = to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index - 1; struct i2c_client *client = to_i2c_client(dev); struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; - u8 mask_tmp=0, level_tmp=0; + u8 mask_tmp = 0, level_tmp = 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15); mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr]) - & ((nr==3) ? 0xf0 : 0x0f); - if (nr==3) { + & ((nr == 3) ? 0xf0 : 0x0f); + if (nr == 3) level_tmp = data->sf2_levels[index][nr]; - } else { + else level_tmp = data->sf2_levels[index][nr] << 4; - } - w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp); + w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], + level_tmp | mask_tmp); mutex_unlock(&data->update_lock); return count; @@ -939,9 +1011,8 @@ w83792d_detect_subclients(struct i2c_client *new_client) } val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR); - if (!(val & 0x08)) { + if (!(val & 0x08)) data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7)); - } if (!(val & 0x80)) { if ((data->lm75[0] != NULL) && ((val & 0x7) == ((val >> 4) & 0x7))) { @@ -1306,9 +1377,8 @@ w83792d_detect(struct i2c_client *client, struct i2c_board_info *info) int val1, val2; unsigned short address = client->addr; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - } if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) return -ENODEV; @@ -1318,11 +1388,13 @@ w83792d_detect(struct i2c_client *client, struct i2c_board_info *info) /* Check for Winbond ID if in bank 0 */ if (!(val1 & 0x07)) { /* is Bank0 */ if ((!(val1 & 0x80) && val2 != 0xa3) || - ( (val1 & 0x80) && val2 != 0x5c)) + ((val1 & 0x80) && val2 != 0x5c)) return -ENODEV; } - /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR - should match */ + /* + * If Winbond chip, address of chip and W83792D_REG_I2C_ADDR + * should match + */ if (w83792d_read_value(client, W83792D_REG_I2C_ADDR) != address) return -ENODEV; @@ -1374,33 +1446,40 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) } /* Register sysfs hooks */ - if ((err = sysfs_create_group(&dev->kobj, &w83792d_group))) + err = sysfs_create_group(&dev->kobj, &w83792d_group); + if (err) goto ERROR3; - /* Read GPIO enable register to check if pins for fan 4,5 are used as - GPIO */ + /* + * Read GPIO enable register to check if pins for fan 4,5 are used as + * GPIO + */ val1 = w83792d_read_value(client, W83792D_REG_GPIO_EN); - if (!(val1 & 0x40)) - if ((err = sysfs_create_group(&dev->kobj, - &w83792d_group_fan[0]))) + if (!(val1 & 0x40)) { + err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[0]); + if (err) goto exit_remove_files; + } - if (!(val1 & 0x20)) - if ((err = sysfs_create_group(&dev->kobj, - &w83792d_group_fan[1]))) + if (!(val1 & 0x20)) { + err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[1]); + if (err) goto exit_remove_files; + } val1 = w83792d_read_value(client, W83792D_REG_PIN); - if (val1 & 0x40) - if ((err = sysfs_create_group(&dev->kobj, - &w83792d_group_fan[2]))) + if (val1 & 0x40) { + err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[2]); + if (err) goto exit_remove_files; + } - if (val1 & 0x04) - if ((err = sysfs_create_group(&dev->kobj, - &w83792d_group_fan[3]))) + if (val1 & 0x04) { + err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[3]); + if (err) goto exit_remove_files; + } data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { @@ -1451,14 +1530,16 @@ w83792d_init_client(struct i2c_client *client) { u8 temp2_cfg, temp3_cfg, vid_in_b; - if (init) { + if (init) w83792d_write_value(client, W83792D_REG_CONFIG, 0x80); - } - /* Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0): - W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of - vin0/vin1 can be modified by user; - W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of - vin0/vin1 auto-updated, can NOT be modified by user. */ + + /* + * Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0): + * W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of + * vin0/vin1 can be modified by user; + * W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of + * vin0/vin1 auto-updated, can NOT be modified by user. + */ vid_in_b = w83792d_read_value(client, W83792D_REG_VID_IN_B); w83792d_write_value(client, W83792D_REG_VID_IN_B, vid_in_b & 0xbf); @@ -1527,7 +1608,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) for (i = 0; i < 2; i++) { for (j = 0; j < 6; j++) { data->temp_add[i][j] = w83792d_read_value( - client,W83792D_REG_TEMP_ADD[i][j]); + client, W83792D_REG_TEMP_ADD[i][j]); } } @@ -1572,8 +1653,9 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) /* Update Smart Fan II temperature points */ for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { - data->sf2_points[i][j] = w83792d_read_value( - client,W83792D_REG_POINTS[i][j]) & 0x7f; + data->sf2_points[i][j] + = w83792d_read_value(client, + W83792D_REG_POINTS[i][j]) & 0x7f; } } @@ -1605,10 +1687,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) #ifdef DEBUG static void w83792d_print_debug(struct w83792d_data *data, struct device *dev) { - int i=0, j=0; + int i = 0, j = 0; dev_dbg(dev, "==========The following is the debug message...========\n"); dev_dbg(dev, "9 set of Voltages: =====>\n"); - for (i=0; i<9; i++) { + for (i = 0; i < 9; i++) { dev_dbg(dev, "vin[%d] is: 0x%x\n", i, data->in[i]); dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]); dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]); @@ -1616,47 +1698,32 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev) dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff); dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8); dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n"); - for (i=0; i<7; i++) { + for (i = 0; i < 7; i++) { dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]); dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]); } dev_dbg(dev, "3 set of Temperatures: =====>\n"); - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) dev_dbg(dev, "temp1[%d] is: 0x%x\n", i, data->temp1[i]); - } - for (i=0; i<2; i++) { - for (j=0; j<6; j++) { + for (i = 0; i < 2; i++) { + for (j = 0; j < 6; j++) { dev_dbg(dev, "temp_add[%d][%d] is: 0x%x\n", i, j, data->temp_add[i][j]); } } - for (i=0; i<7; i++) { + for (i = 0; i < 7; i++) dev_dbg(dev, "fan_div[%d] is: 0x%x\n", i, data->fan_div[i]); - } - dev_dbg(dev, "==========End of the debug message...==================\n"); + + dev_dbg(dev, "==========End of the debug message...================\n"); dev_dbg(dev, "\n"); } #endif -static int __init -sensors_w83792d_init(void) -{ - return i2c_add_driver(&w83792d_driver); -} - -static void __exit -sensors_w83792d_exit(void) -{ - i2c_del_driver(&w83792d_driver); -} +module_i2c_driver(w83792d_driver); MODULE_AUTHOR("Chunhao Huang @ Winbond <DZShen@Winbond.com.tw>"); MODULE_DESCRIPTION("W83792AD/D driver for linux-2.6"); MODULE_LICENSE("GPL"); - -module_init(sensors_w83792d_init); -module_exit(sensors_w83792d_exit); - diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 45ec7e7c3c27..834e49d1827b 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1,34 +1,34 @@ /* - w83793.c - Linux kernel driver for hardware monitoring - Copyright (C) 2006 Winbond Electronics Corp. - Yuan Mu - Rudolf Marek <r.marek@assembler.cz> - Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG. - Watchdog driver part - (Based partially on fschmd driver, - Copyright 2007-2008 by Hans de Goede) - - 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 - version 2. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ + * w83793.c - Linux kernel driver for hardware monitoring + * Copyright (C) 2006 Winbond Electronics Corp. + * Yuan Mu + * Rudolf Marek <r.marek@assembler.cz> + * Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG. + * Watchdog driver part + * (Based partially on fschmd driver, + * Copyright 2007-2008 by Hans de Goede) + * + * 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 - version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + */ /* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - w83793 10 12 8 6 0x7b 0x5ca3 yes no -*/ + * Supports following chips: + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * w83793 10 12 8 6 0x7b 0x5ca3 yes no + */ #include <linux/module.h> #include <linux/init.h> @@ -78,9 +78,9 @@ MODULE_PARM_DESC(nowayout, __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* - Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved - as ID, Bank Select registers -*/ + * Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved + * as ID, Bank Select registers + */ #define W83793_REG_BANKSEL 0x00 #define W83793_REG_VENDORID 0x0d #define W83793_REG_CHIPID 0x0e @@ -110,8 +110,10 @@ static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f }; #define TEMP_CRIT_HYST 2 #define TEMP_WARN 3 #define TEMP_WARN_HYST 4 -/* only crit and crit_hyst affect real-time alarm status - current crit crit_hyst warn warn_hyst */ +/* + * only crit and crit_hyst affect real-time alarm status + * current crit crit_hyst warn warn_hyst + */ static u16 W83793_REG_TEMP[][5] = { {0x1c, 0x78, 0x79, 0x7a, 0x7b}, {0x1d, 0x7c, 0x7d, 0x7e, 0x7f}, @@ -181,7 +183,7 @@ static inline unsigned long FAN_FROM_REG(u16 val) { if ((val >= 0xfff) || (val == 0)) return 0; - return (1350000UL / val); + return 1350000UL / val; } static inline u16 FAN_TO_REG(long rpm) @@ -193,7 +195,7 @@ static inline u16 FAN_TO_REG(long rpm) static inline unsigned long TIME_FROM_REG(u8 reg) { - return (reg * 100); + return reg * 100; } static inline u8 TIME_TO_REG(unsigned long val) @@ -203,7 +205,7 @@ static inline u8 TIME_TO_REG(unsigned long val) static inline long TEMP_FROM_REG(s8 reg) { - return (reg * 1000); + return reg * 1000; } static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) @@ -218,7 +220,8 @@ struct w83793_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ unsigned long last_nonvolatile; /* In jiffies, last time we update the - nonvolatile registers */ + * nonvolatile registers + */ u8 bank; u8 vrm; @@ -233,7 +236,8 @@ struct w83793_data { s8 temp[6][5]; /* current, crit, crit_hyst,warn, warn_hyst */ u8 temp_low_bits; /* Additional resolution TD1-TD4 */ u8 temp_mode[2]; /* byte 0: Temp D1-D4 mode each has 2 bits - byte 1: Temp R1,R2 mode, each has 1 bit */ + * byte 1: Temp R1,R2 mode, each has 1 bit + */ u8 temp_critical; /* If reached all fan will be at full speed */ u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ @@ -268,17 +272,21 @@ struct w83793_data { int watchdog_timeout; /* watchdog timeout in minutes */ }; -/* Somewhat ugly :( global data pointer list with all devices, so that - we can find our device data as when using misc_register. There is no - other method to get to one's device data from the open file-op and - for usage in the reboot notifier callback. */ +/* + * Somewhat ugly :( global data pointer list with all devices, so that + * we can find our device data as when using misc_register. There is no + * other method to get to one's device data from the open file-op and + * for usage in the reboot notifier callback. + */ static LIST_HEAD(watchdog_data_list); /* Note this lock not only protect list access, but also data.kref access */ static DEFINE_MUTEX(watchdog_data_mutex); -/* Release our data struct when we're detached from the i2c client *and* all - references to our watchdog device are released */ +/* + * Release our data struct when we're detached from the i2c client *and* all + * references to our watchdog device are released + */ static void w83793_release_resources(struct kref *ref) { struct w83793_data *data = container_of(ref, struct w83793_data, kref); @@ -337,7 +345,14 @@ store_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct w83793_data *data = dev_get_drvdata(dev); - data->vrm = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + data->vrm = val; return count; } @@ -354,7 +369,7 @@ show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf) int bit = sensor_attr->index & 0x07; u8 val; - if (ALARM_STATUS == nr) { + if (nr == ALARM_STATUS) { val = (data->alarms[index] >> (bit)) & 1; } else { /* BEEP_ENABLE */ val = (data->beeps[index] >> (bit)) & 1; @@ -374,10 +389,14 @@ store_beep(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index >> 3; int shift = sensor_attr->index & 0x07; u8 beep_bit = 1 << shift; - u8 val; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); - if (val != 0 && val != 1) + if (val > 1) return -EINVAL; mutex_lock(&data->update_lock); @@ -403,9 +422,14 @@ store_beep_enable(struct device *dev, struct device_attribute *attr, { struct i2c_client *client = to_i2c_client(dev); struct w83793_data *data = i2c_get_clientdata(client); - u8 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - if (val != 0 && val != 1) + if (val > 1) return -EINVAL; mutex_lock(&data->update_lock); @@ -449,8 +473,12 @@ store_chassis_clear(struct device *dev, struct w83793_data *data = i2c_get_clientdata(client); unsigned long val; u8 reg; + int err; - if (kstrtoul(buf, 10, &val) || val != 0) + err = kstrtoul(buf, 10, &val); + if (err) + return err; + if (val) return -EINVAL; mutex_lock(&data->update_lock); @@ -473,11 +501,10 @@ show_fan(struct device *dev, struct device_attribute *attr, char *buf) struct w83793_data *data = w83793_update_device(dev); u16 val; - if (FAN_INPUT == nr) { + if (nr == FAN_INPUT) val = data->fan[index] & 0x0fff; - } else { + else val = data->fan_min[index] & 0x0fff; - } return sprintf(buf, "%lu\n", FAN_FROM_REG(val)); } @@ -491,7 +518,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83793_data *data = i2c_get_clientdata(client); - u16 val = FAN_TO_REG(simple_strtoul(buf, NULL, 10)); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + val = FAN_TO_REG(val); mutex_lock(&data->update_lock); data->fan_min[index] = val; @@ -513,7 +546,7 @@ show_pwm(struct device *dev, struct device_attribute *attr, char *buf) int nr = sensor_attr->nr; int index = sensor_attr->index; - if (PWM_STOP_TIME == nr) + if (nr == PWM_STOP_TIME) val = TIME_FROM_REG(data->pwm_stop_time[index]); else val = (data->pwm[index][nr] & 0x3f) << 2; @@ -531,17 +564,21 @@ store_pwm(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; - u8 val; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - if (PWM_STOP_TIME == nr) { - val = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); + if (nr == PWM_STOP_TIME) { + val = TIME_TO_REG(val); data->pwm_stop_time[index] = val; w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index), val); } else { - val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) - >> 2; + val = SENSORS_LIMIT(val, 0, 0xff) >> 2; data->pwm[index][nr] = w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0; data->pwm[index][nr] |= val; @@ -563,7 +600,7 @@ show_temp(struct device *dev, struct device_attribute *attr, char *buf) struct w83793_data *data = w83793_update_device(dev); long temp = TEMP_FROM_REG(data->temp[index][nr]); - if (TEMP_READ == nr && index < 4) { /* Only TD1-TD4 have low bits */ + if (nr == TEMP_READ && index < 4) { /* Only TD1-TD4 have low bits */ int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250; temp += temp > 0 ? low : -low; } @@ -580,7 +617,12 @@ store_temp(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83793_data *data = i2c_get_clientdata(client); - long tmp = simple_strtol(buf, NULL, 10); + long tmp; + int err; + + err = kstrtol(buf, 10, &tmp); + if (err) + return err; mutex_lock(&data->update_lock); data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127); @@ -591,18 +633,18 @@ store_temp(struct device *dev, struct device_attribute *attr, } /* - TD1-TD4 - each has 4 mode:(2 bits) - 0: Stop monitor - 1: Use internal temp sensor(default) - 2: Reserved - 3: Use sensor in Intel CPU and get result by PECI - - TR1-TR2 - each has 2 mode:(1 bit) - 0: Disable temp sensor monitor - 1: To enable temp sensors monitor -*/ + * TD1-TD4 + * each has 4 mode:(2 bits) + * 0: Stop monitor + * 1: Use internal temp sensor(default) + * 2: Reserved + * 3: Use sensor in Intel CPU and get result by PECI + * + * TR1-TR2 + * each has 2 mode:(1 bit) + * 0: Disable temp sensor monitor + * 1: To enable temp sensors monitor + */ /* 0 disable, 6 PECI */ static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; @@ -622,11 +664,10 @@ show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) tmp = (data->temp_mode[index] >> shift) & mask; /* for the internal sensor, found out if diode or thermistor */ - if (tmp == 1) { + if (tmp == 1) tmp = index == 0 ? 3 : 4; - } else { + else tmp = TO_TEMP_MODE[tmp]; - } return sprintf(buf, "%d\n", tmp); } @@ -642,7 +683,12 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; u8 mask = (index < 4) ? 0x03 : 0x01; u8 shift = (index < 4) ? (2 * index) : (index - 4); - u8 val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; /* transform the sysfs interface values into table above */ if ((val == 6) && (index < 4)) { @@ -681,15 +727,14 @@ show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf) struct w83793_data *data = w83793_update_device(dev); u32 val = 0; - if (SETUP_PWM_DEFAULT == nr) { + if (nr == SETUP_PWM_DEFAULT) val = (data->pwm_default & 0x3f) << 2; - } else if (SETUP_PWM_UPTIME == nr) { + else if (nr == SETUP_PWM_UPTIME) val = TIME_FROM_REG(data->pwm_uptime); - } else if (SETUP_PWM_DOWNTIME == nr) { + else if (nr == SETUP_PWM_DOWNTIME) val = TIME_FROM_REG(data->pwm_downtime); - } else if (SETUP_TEMP_CRITICAL == nr) { + else if (nr == SETUP_TEMP_CRITICAL) val = TEMP_FROM_REG(data->temp_critical & 0x7f); - } return sprintf(buf, "%d\n", val); } @@ -703,31 +748,34 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->nr; struct i2c_client *client = to_i2c_client(dev); struct w83793_data *data = i2c_get_clientdata(client); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - if (SETUP_PWM_DEFAULT == nr) { + if (nr == SETUP_PWM_DEFAULT) { data->pwm_default = w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0; - data->pwm_default |= SENSORS_LIMIT(simple_strtoul(buf, NULL, - 10), - 0, 0xff) >> 2; + data->pwm_default |= SENSORS_LIMIT(val, 0, 0xff) >> 2; w83793_write_value(client, W83793_REG_PWM_DEFAULT, data->pwm_default); - } else if (SETUP_PWM_UPTIME == nr) { - data->pwm_uptime = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); + } else if (nr == SETUP_PWM_UPTIME) { + data->pwm_uptime = TIME_TO_REG(val); data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0; w83793_write_value(client, W83793_REG_PWM_UPTIME, data->pwm_uptime); - } else if (SETUP_PWM_DOWNTIME == nr) { - data->pwm_downtime = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); + } else if (nr == SETUP_PWM_DOWNTIME) { + data->pwm_downtime = TIME_TO_REG(val); data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0; w83793_write_value(client, W83793_REG_PWM_DOWNTIME, data->pwm_downtime); } else { /* SETUP_TEMP_CRITICAL */ data->temp_critical = w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80; - data->temp_critical |= TEMP_TO_REG(simple_strtol(buf, NULL, 10), - 0, 0x7f); + data->temp_critical |= TEMP_TO_REG(val, 0, 0x7f); w83793_write_value(client, W83793_REG_TEMP_CRITICAL, data->temp_critical); } @@ -737,31 +785,31 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, } /* - Temp SmartFan control - TEMP_FAN_MAP - Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1... - It's possible two or more temp channels control the same fan, w83793 - always prefers to pick the most critical request and applies it to - the related Fan. - It's possible one fan is not in any mapping of 6 temp channels, this - means the fan is manual mode - - TEMP_PWM_ENABLE - Each temp channel has its own SmartFan mode, and temp channel - control fans that are set by TEMP_FAN_MAP - 0: SmartFanII mode - 1: Thermal Cruise Mode - - TEMP_CRUISE - Target temperature in thermal cruise mode, w83793 will try to turn - fan speed to keep the temperature of target device around this - temperature. - - TEMP_TOLERANCE - If Temp higher or lower than target with this tolerance, w83793 - will take actions to speed up or slow down the fan to keep the - temperature within the tolerance range. -*/ + * Temp SmartFan control + * TEMP_FAN_MAP + * Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1... + * It's possible two or more temp channels control the same fan, w83793 + * always prefers to pick the most critical request and applies it to + * the related Fan. + * It's possible one fan is not in any mapping of 6 temp channels, this + * means the fan is manual mode + * + * TEMP_PWM_ENABLE + * Each temp channel has its own SmartFan mode, and temp channel + * control fans that are set by TEMP_FAN_MAP + * 0: SmartFanII mode + * 1: Thermal Cruise Mode + * + * TEMP_CRUISE + * Target temperature in thermal cruise mode, w83793 will try to turn + * fan speed to keep the temperature of target device around this + * temperature. + * + * TEMP_TOLERANCE + * If Temp higher or lower than target with this tolerance, w83793 + * will take actions to speed up or slow down the fan to keep the + * temperature within the tolerance range. + */ #define TEMP_FAN_MAP 0 #define TEMP_PWM_ENABLE 1 @@ -777,12 +825,12 @@ show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf) struct w83793_data *data = w83793_update_device(dev); u32 val; - if (TEMP_FAN_MAP == nr) { + if (nr == TEMP_FAN_MAP) { val = data->temp_fan_map[index]; - } else if (TEMP_PWM_ENABLE == nr) { + } else if (nr == TEMP_PWM_ENABLE) { /* +2 to transfrom into 2 and 3 to conform with sysfs intf */ val = ((data->pwm_enable >> index) & 0x01) + 2; - } else if (TEMP_CRUISE == nr) { + } else if (nr == TEMP_CRUISE) { val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f); } else { /* TEMP_TOLERANCE */ val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0); @@ -801,16 +849,20 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83793_data *data = i2c_get_clientdata(client); - u32 val; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); - if (TEMP_FAN_MAP == nr) { - val = simple_strtoul(buf, NULL, 10) & 0xff; + if (nr == TEMP_FAN_MAP) { + val = SENSORS_LIMIT(val, 0, 255); w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val); data->temp_fan_map[index] = val; - } else if (TEMP_PWM_ENABLE == nr) { - val = simple_strtoul(buf, NULL, 10); - if (2 == val || 3 == val) { + } else if (nr == TEMP_PWM_ENABLE) { + if (val == 2 || val == 3) { data->pwm_enable = w83793_read_value(client, W83793_REG_PWM_ENABLE); if (val - 2) @@ -823,12 +875,11 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr, mutex_unlock(&data->update_lock); return -EINVAL; } - } else if (TEMP_CRUISE == nr) { + } else if (nr == TEMP_CRUISE) { data->temp_cruise[index] = w83793_read_value(client, W83793_REG_TEMP_CRUISE(index)); - val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f); data->temp_cruise[index] &= 0x80; - data->temp_cruise[index] |= val; + data->temp_cruise[index] |= TEMP_TO_REG(val, 0, 0x7f); w83793_write_value(client, W83793_REG_TEMP_CRUISE(index), data->temp_cruise[index]); @@ -838,9 +889,8 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr, data->tolerance[i] = w83793_read_value(client, W83793_REG_TEMP_TOL(i)); - val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x0f); data->tolerance[i] &= ~(0x0f << shift); - data->tolerance[i] |= val << shift; + data->tolerance[i] |= TEMP_TO_REG(val, 0, 0x0f) << shift; w83793_write_value(client, W83793_REG_TEMP_TOL(i), data->tolerance[i]); } @@ -871,7 +921,13 @@ store_sf2_pwm(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; - u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) >> 2; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 0xff) >> 2; mutex_lock(&data->update_lock); data->sf2_pwm[index][nr] = @@ -906,7 +962,13 @@ store_sf2_temp(struct device *dev, struct device_attribute *attr, to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int index = sensor_attr->index; - u8 val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f); + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; + val = TEMP_TO_REG(val, 0, 0x7f); mutex_lock(&data->update_lock); data->sf2_temp[index][nr] = @@ -948,17 +1010,19 @@ store_in(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83793_data *data = i2c_get_clientdata(client); - u32 val; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + val = (val + scale_in[index] / 2) / scale_in[index]; - val = - (simple_strtoul(buf, NULL, 10) + - scale_in[index] / 2) / scale_in[index]; mutex_lock(&data->update_lock); if (index > 2) { /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ - if (1 == nr || 2 == nr) { + if (nr == 1 || nr == 2) val -= scale_in_add[index] / scale_in[index]; - } val = SENSORS_LIMIT(val, 0, 255); } else { val = SENSORS_LIMIT(val, 0, 0x3FF); @@ -1143,9 +1207,8 @@ static struct sensor_device_attribute_2 sda_single_files[] = { static void w83793_init_client(struct i2c_client *client) { - if (reset) { + if (reset) w83793_write_value(client, W83793_REG_CONFIG, 0x80); - } /* Start monitoring */ w83793_write_value(client, W83793_REG_CONFIG, @@ -1259,10 +1322,12 @@ static int watchdog_open(struct inode *inode, struct file *filp) struct w83793_data *pos, *data = NULL; int watchdog_is_open; - /* We get called from drivers/char/misc.c with misc_mtx hold, and we - call misc_register() from w83793_probe() with watchdog_data_mutex - hold, as misc_register() takes the misc_mtx lock, this is a possible - deadlock, so we use mutex_trylock here. */ + /* + * We get called from drivers/char/misc.c with misc_mtx hold, and we + * call misc_register() from w83793_probe() with watchdog_data_mutex + * hold, as misc_register() takes the misc_mtx lock, this is a possible + * deadlock, so we use mutex_trylock here. + */ if (!mutex_trylock(&watchdog_data_mutex)) return -ERESTARTSYS; list_for_each_entry(pos, &watchdog_data_list, list) { @@ -1275,8 +1340,10 @@ static int watchdog_open(struct inode *inode, struct file *filp) /* Check, if device is already open */ watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open); - /* Increase data reference counter (if not already done). - Note we can never not have found data, so we don't check for this */ + /* + * Increase data reference counter (if not already done). + * Note we can never not have found data, so we don't check for this + */ if (!watchdog_is_open) kref_get(&data->kref); @@ -1556,9 +1623,8 @@ w83793_detect_subclients(struct i2c_client *client) } tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); - if (!(tmp & 0x08)) { + if (!(tmp & 0x08)) data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7)); - } if (!(tmp & 0x80)) { if ((data->lm75[0] != NULL) && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) { @@ -1591,9 +1657,8 @@ static int w83793_detect(struct i2c_client *client, struct i2c_adapter *adapter = client->adapter; unsigned short address = client->addr; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - } bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); @@ -1604,8 +1669,10 @@ static int w83793_detect(struct i2c_client *client, return -ENODEV; } - /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR - should match */ + /* + * If Winbond chip, address of chip and W83793_REG_I2C_ADDR + * should match + */ if ((bank & 0x07) == 0 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != (address << 1)) { @@ -1647,9 +1714,11 @@ static int w83793_probe(struct i2c_client *client, INIT_LIST_HEAD(&data->list); kref_init(&data->kref); - /* Store client pointer in our data struct for watchdog usage - (where the client is found through a data ptr instead of the - otherway around) */ + /* + * Store client pointer in our data struct for watchdog usage + * (where the client is found through a data ptr instead of the + * otherway around) + */ data->client = client; err = w83793_detect_subclients(client); @@ -1660,8 +1729,8 @@ static int w83793_probe(struct i2c_client *client, w83793_init_client(client); /* - Only fan 1-5 has their own input pins, - Pwm 1-3 has their own pins + * Only fan 1-5 has their own input pins, + * Pwm 1-3 has their own pins */ data->has_fan = 0x1f; data->has_pwm = 0x07; @@ -1723,7 +1792,7 @@ static int w83793_probe(struct i2c_client *client, } /* check the temp1-6 mode, ignore former AMDSI selected inputs */ - tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); + tmp = w83793_read_value(client, W83793_REG_TEMP_MODE[0]); if (tmp & 0x01) data->has_temp |= 0x01; if (tmp & 0x04) @@ -1733,7 +1802,7 @@ static int w83793_probe(struct i2c_client *client, if (tmp & 0x40) data->has_temp |= 0x08; - tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); + tmp = w83793_read_value(client, W83793_REG_TEMP_MODE[1]); if (tmp & 0x01) data->has_temp |= 0x10; if (tmp & 0x02) @@ -1823,9 +1892,11 @@ static int w83793_probe(struct i2c_client *client, goto exit_devunreg; } - /* Enable Watchdog registers. - Set Configuration Register to Enable Watch Dog Registers - (Bit 2) = XXXX, X1XX. */ + /* + * Enable Watchdog registers. + * Set Configuration Register to Enable Watch Dog Registers + * (Bit 2) = XXXX, X1XX. + */ tmp = w83793_read_value(client, W83793_REG_CONFIG); w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04); @@ -1839,9 +1910,11 @@ static int w83793_probe(struct i2c_client *client, /* Disable Soft Watchdog during initialiation */ watchdog_disable(data); - /* We take the data_mutex lock early so that watchdog_open() cannot - run when misc_register() has completed, but we've not yet added - our data to the watchdog_data_list (and set the default timeout) */ + /* + * We take the data_mutex lock early so that watchdog_open() cannot + * run when misc_register() has completed, but we've not yet added + * our data to the watchdog_data_list (and set the default timeout) + */ mutex_lock(&watchdog_data_mutex); for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { /* Register our watchdog part */ @@ -1921,9 +1994,9 @@ static void w83793_update_nonvolatile(struct device *dev) struct w83793_data *data = i2c_get_clientdata(client); int i, j; /* - They are somewhat "stable" registers, and to update them every time - takes so much time, it's just not worthy. Update them in a long - interval to avoid exception. + * They are somewhat "stable" registers, and to update them every time + * takes so much time, it's just not worthy. Update them in a long + * interval to avoid exception. */ if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300) || !data->valid)) @@ -1940,9 +2013,8 @@ static void w83793_update_nonvolatile(struct device *dev) for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { /* Update the Fan measured value and limits */ - if (!(data->has_fan & (1 << i))) { + if (!(data->has_fan & (1 << i))) continue; - } data->fan_min[i] = w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8; data->fan_min[i] |= @@ -1997,9 +2069,8 @@ static void w83793_update_nonvolatile(struct device *dev) w83793_read_value(client, W83793_REG_TEMP_CRITICAL); data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP); - for (i = 0; i < ARRAY_SIZE(data->beeps); i++) { + for (i = 0; i < ARRAY_SIZE(data->beeps); i++) data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i)); - } data->last_nonvolatile = jiffies; } @@ -2025,9 +2096,8 @@ static struct w83793_data *w83793_update_device(struct device *dev) w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]); for (i = 0; i < ARRAY_SIZE(data->fan); i++) { - if (!(data->has_fan & (1 << i))) { + if (!(data->has_fan & (1 << i))) continue; - } data->fan[i] = w83793_read_value(client, W83793_REG_FAN(i)) << 8; data->fan[i] |= @@ -2067,8 +2137,10 @@ END: return data; } -/* Ignore the possibility that somebody change bank outside the driver - Must be called with data->update_lock held, except during initialization */ +/* + * Ignore the possibility that somebody change bank outside the driver + * Must be called with data->update_lock held, except during initialization + */ static u8 w83793_read_value(struct i2c_client *client, u16 reg) { struct w83793_data *data = i2c_get_clientdata(client); @@ -2103,16 +2175,16 @@ static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value) new_bank |= data->bank & 0xfc; if (data->bank != new_bank) { - if ((res = i2c_smbus_write_byte_data - (client, W83793_REG_BANKSEL, new_bank)) >= 0) - data->bank = new_bank; - else { + res = i2c_smbus_write_byte_data(client, W83793_REG_BANKSEL, + new_bank); + if (res < 0) { dev_err(&client->dev, "set bank to %d failed, fall back " "to bank %d, write reg 0x%x error\n", new_bank, data->bank, reg); goto END; } + data->bank = new_bank; } res = i2c_smbus_write_byte_data(client, reg & 0xff, value); @@ -2120,19 +2192,8 @@ END: return res; } -static int __init sensors_w83793_init(void) -{ - return i2c_add_driver(&w83793_driver); -} - -static void __exit sensors_w83793_exit(void) -{ - i2c_del_driver(&w83793_driver); -} +module_i2c_driver(w83793_driver); MODULE_AUTHOR("Yuan Mu, Sven Anders"); MODULE_DESCRIPTION("w83793 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_w83793_init); -module_exit(sensors_w83793_exit); diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index aa58b25565bc..d887cb3b72e8 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c @@ -72,8 +72,10 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); #define TEMP_CRIT_HYST 2 #define TEMP_WARN 3 #define TEMP_WARN_HYST 4 -/* only crit and crit_hyst affect real-time alarm status - * current crit crit_hyst warn warn_hyst */ +/* + * only crit and crit_hyst affect real-time alarm status + * current crit crit_hyst warn warn_hyst + */ static const u16 W83795_REG_TEMP[][5] = { {0x21, 0x96, 0x97, 0x98, 0x99}, /* TD1/TR1 */ {0x22, 0x9a, 0x9b, 0x9c, 0x9d}, /* TD2/TR2 */ @@ -354,26 +356,34 @@ struct w83795_data { u8 temp_mode; /* Bit vector, 0 = TR, 1 = TD */ u8 temp_src[3]; /* Register value */ - u8 enable_dts; /* Enable PECI and SB-TSI, + u8 enable_dts; /* + * Enable PECI and SB-TSI, * bit 0: =1 enable, =0 disable, - * bit 1: =1 AMD SB-TSI, =0 Intel PECI */ + * bit 1: =1 AMD SB-TSI, =0 Intel PECI + */ u8 has_dts; /* Enable monitor DTS temp */ s8 dts[8]; /* Register value */ u8 dts_read_vrlsb[8]; /* Register value */ s8 dts_ext[4]; /* Register value */ - u8 has_pwm; /* 795g supports 8 pwm, 795adg only supports 2, + u8 has_pwm; /* + * 795g supports 8 pwm, 795adg only supports 2, * no config register, only affected by chip - * type */ - u8 pwm[8][5]; /* Register value, output, freq, start, - * non stop, stop time */ + * type + */ + u8 pwm[8][5]; /* + * Register value, output, freq, start, + * non stop, stop time + */ u16 clkin; /* CLKIN frequency in kHz */ u8 pwm_fcms[2]; /* Register value */ u8 pwm_tfmr[6]; /* Register value */ u8 pwm_fomc; /* Register value */ - u16 target_speed[8]; /* Register value, target speed for speed - * cruise */ + u16 target_speed[8]; /* + * Register value, target speed for speed + * cruise + */ u8 tol_speed; /* tolerance of target speed */ u8 pwm_temp[6][4]; /* TTTI, CTFS, HCT, HOT */ u8 sf4_reg[6][2][7]; /* 6 temp, temp/dcpwm, 7 registers */ @@ -482,8 +492,10 @@ static void w83795_update_limits(struct i2c_client *client) /* Read the fan limits */ lsb = 0; /* Silent false gcc warning */ for (i = 0; i < ARRAY_SIZE(data->fan); i++) { - /* Each register contains LSB for 2 fans, but we want to - * read it only once to save time */ + /* + * Each register contains LSB for 2 fans, but we want to + * read it only once to save time + */ if ((i & 1) == 0 && (data->has_fan & (3 << i))) lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i)); @@ -665,9 +677,11 @@ static struct w83795_data *w83795_update_device(struct device *dev) w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); } - /* Update intrusion and alarms + /* + * Update intrusion and alarms * It is important to read intrusion first, because reading from - * register SMI STS6 clears the interrupt status temporarily. */ + * register SMI STS6 clears the interrupt status temporarily. + */ tmp = w83795_read(client, W83795_REG_ALARM_CTRL); /* Switch to interrupt status for intrusion if needed */ if (tmp & ALARM_CTRL_RTSACS) @@ -929,6 +943,14 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, if (val < 1 || val > 2) return -EINVAL; +#ifndef CONFIG_SENSORS_W83795_FANCTRL + if (val > 1) { + dev_warn(dev, "Automatic fan speed control support disabled\n"); + dev_warn(dev, "Build with CONFIG_SENSORS_W83795_FANCTRL=y if you want it\n"); + return -EOPNOTSUPP; + } +#endif + mutex_lock(&data->update_lock); switch (val) { case 1: @@ -1595,8 +1617,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, #define NOT_USED -1 -/* Don't change the attribute order, _max, _min and _beep are accessed by index - * somewhere else in the code */ +/* + * Don't change the attribute order, _max, _min and _beep are accessed by index + * somewhere else in the code + */ #define SENSOR_ATTR_IN(index) { \ SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ IN_READ, index), \ @@ -1610,8 +1634,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, show_alarm_beep, store_beep, BEEP_ENABLE, \ index + ((index > 14) ? 1 : 0)) } -/* Don't change the attribute order, _beep is accessed by index - * somewhere else in the code */ +/* + * Don't change the attribute order, _beep is accessed by index + * somewhere else in the code + */ #define SENSOR_ATTR_FAN(index) { \ SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ NULL, FAN_INPUT, index - 1), \ @@ -1625,23 +1651,25 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, #define SENSOR_ATTR_PWM(index) { \ SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \ store_pwm, PWM_OUTPUT, index - 1), \ + SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ + show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ + SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ + show_pwm_mode, NULL, NOT_USED, index - 1), \ + SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO, \ + show_pwm, store_pwm, PWM_FREQ, index - 1), \ SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \ show_pwm, store_pwm, PWM_NONSTOP, index - 1), \ SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \ show_pwm, store_pwm, PWM_START, index - 1), \ SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \ show_pwm, store_pwm, PWM_STOP_TIME, index - 1), \ - SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO, \ - show_pwm, store_pwm, PWM_FREQ, index - 1), \ - SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ - show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ - SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ - show_pwm_mode, NULL, NOT_USED, index - 1), \ SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ show_fanin, store_fanin, FANIN_TARGET, index - 1) } -/* Don't change the attribute order, _beep is accessed by index - * somewhere else in the code */ +/* + * Don't change the attribute order, _beep is accessed by index + * somewhere else in the code + */ #define SENSOR_ATTR_DTS(index) { \ SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ show_dts_mode, NULL, NOT_USED, index - 7), \ @@ -1660,8 +1688,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } -/* Don't change the attribute order, _beep is accessed by index - * somewhere else in the code */ +/* + * Don't change the attribute order, _beep is accessed by index + * somewhere else in the code + */ #define SENSOR_ATTR_TEMP(index) { \ SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ @@ -1867,8 +1897,10 @@ static int w83795_get_device_id(struct i2c_client *client) device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID); - /* Special case for rev. A chips; can't be checked first because later - revisions emulate this for compatibility */ + /* + * Special case for rev. A chips; can't be checked first because later + * revisions emulate this for compatibility + */ if (device_id < 0 || (device_id & 0xf0) != 0x50) { int alt_id; @@ -1920,8 +1952,10 @@ static int w83795_detect(struct i2c_client *client, return -ENODEV; } - /* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR - should match */ + /* + * If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR + * should match + */ if ((bank & 0x07) == 0) { i2c_addr = i2c_smbus_read_byte_data(client, W83795_REG_I2C_ADDR); @@ -1933,10 +1967,12 @@ static int w83795_detect(struct i2c_client *client, } } - /* Check 795 chip type: 795G or 795ADG - Usually we don't write to chips during detection, but here we don't - quite have the choice; hopefully it's OK, we are about to return - success anyway */ + /* + * Check 795 chip type: 795G or 795ADG + * Usually we don't write to chips during detection, but here we don't + * quite have the choice; hopefully it's OK, we are about to return + * success anyway + */ if ((bank & 0x07) != 0) i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, bank & ~0x07); @@ -1953,6 +1989,14 @@ static int w83795_detect(struct i2c_client *client, return 0; } +#ifdef CONFIG_SENSORS_W83795_FANCTRL +#define NUM_PWM_ATTRIBUTES ARRAY_SIZE(w83795_pwm[0]) +#define NUM_TEMP_ATTRIBUTES ARRAY_SIZE(w83795_temp[0]) +#else +#define NUM_PWM_ATTRIBUTES 4 +#define NUM_TEMP_ATTRIBUTES 8 +#endif + static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, const struct device_attribute *)) { @@ -2006,24 +2050,18 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, } } -#ifdef CONFIG_SENSORS_W83795_FANCTRL for (i = 0; i < data->has_pwm; i++) { - for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { + for (j = 0; j < NUM_PWM_ATTRIBUTES; j++) { err = fn(dev, &w83795_pwm[i][j].dev_attr); if (err) return err; } } -#endif for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) { if (!(data->has_temp & (1 << i))) continue; -#ifdef CONFIG_SENSORS_W83795_FANCTRL - for (j = 0; j < ARRAY_SIZE(w83795_temp[0]); j++) { -#else - for (j = 0; j < 8; j++) { -#endif + for (j = 0; j < NUM_TEMP_ATTRIBUTES; j++) { if (j == 7 && !data->enable_beep) continue; err = fn(dev, &w83795_temp[i][j].dev_attr); @@ -2183,8 +2221,10 @@ static int w83795_probe(struct i2c_client *client, /* The W83795G has a dedicated BEEP pin */ data->enable_beep = 1; } else { - /* The W83795ADG has a shared pin for OVT# and BEEP, so you - * can't have both */ + /* + * The W83795ADG has a shared pin for OVT# and BEEP, so you + * can't have both + */ tmp = w83795_read(client, W83795_REG_OVT_CFG); if ((tmp & OVT_CFG_SEL) == 0) data->enable_beep = 1; @@ -2244,19 +2284,8 @@ static struct i2c_driver w83795_driver = { .address_list = normal_i2c, }; -static int __init sensors_w83795_init(void) -{ - return i2c_add_driver(&w83795_driver); -} - -static void __exit sensors_w83795_exit(void) -{ - i2c_del_driver(&w83795_driver); -} +module_i2c_driver(w83795_driver); MODULE_AUTHOR("Wei Song, Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("W83795G/ADG hardware monitoring driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_w83795_init); -module_exit(sensors_w83795_exit); diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 20781def65ed..5f14e3897058 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -86,7 +86,7 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); /* * Driver data (common to all clients) */ - + static const struct i2c_device_id w83l785ts_id[] = { { "w83l785ts", 0 }, { } @@ -116,8 +116,7 @@ struct w83l785ts_data { unsigned long last_updated; /* in jiffies */ /* registers values */ - s8 temp[2]; /* 0: input - 1: critical limit */ + s8 temp[2]; /* 0: input, 1: critical limit */ }; /* @@ -250,8 +249,10 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) struct device *dev; const char *prefix; - /* We might be called during detection, at which point the client - isn't yet fully initialized, so we can't use dev_dbg on it */ + /* + * We might be called during detection, at which point the client + * isn't yet fully initialized, so we can't use dev_dbg on it + */ if (i2c_get_clientdata(client)) { dev = &client->dev; prefix = ""; @@ -260,9 +261,11 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) prefix = "w83l785ts: "; } - /* Frequent read errors have been reported on Asus boards, so we + /* + * Frequent read errors have been reported on Asus boards, so we * retry on read errors. If it still fails (unlikely), return the - * default value requested by the caller. */ + * default value requested by the caller. + */ for (i = 1; i <= MAX_RETRIES; i++) { value = i2c_smbus_read_byte_data(client, reg); if (value >= 0) { @@ -302,19 +305,8 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev) return data; } -static int __init sensors_w83l785ts_init(void) -{ - return i2c_add_driver(&w83l785ts_driver); -} - -static void __exit sensors_w83l785ts_exit(void) -{ - i2c_del_driver(&w83l785ts_driver); -} +module_i2c_driver(w83l785ts_driver); MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); MODULE_DESCRIPTION("W83L785TS-S driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_w83l785ts_init); -module_exit(sensors_w83l785ts_exit); diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 063bd9508d8a..5850b7706088 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -1,28 +1,28 @@ /* - w83l786ng.c - Linux kernel driver for hardware monitoring - Copyright (c) 2007 Kevin Lo <kevlo@kevlo.org> - - 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 - version 2. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ + * w83l786ng.c - Linux kernel driver for hardware monitoring + * Copyright (c) 2007 Kevin Lo <kevlo@kevlo.org> + * + * 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 - version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + */ /* - Supports following chips: - - Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA - w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no -*/ + * Supports following chips: + * + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no + */ #include <linux/module.h> #include <linux/init.h> @@ -52,7 +52,7 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); #define W83L786NG_REG_CONFIG 0x40 #define W83L786NG_REG_ALARM1 0x41 -#define W83L786NG_REG_ALARM2 0x42 +#define W83L786NG_REG_ALARM2 0x42 #define W83L786NG_REG_GPIO_EN 0x47 #define W83L786NG_REG_MAN_ID2 0x4C #define W83L786NG_REG_MAN_ID1 0x4D @@ -89,19 +89,23 @@ FAN_TO_REG(long rpm, int div) return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ +#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ ((val) == 255 ? 0 : \ 1350000 / ((val) * (div)))) /* for temp */ -#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \ - : (val)) / 1000, 0, 0xff)) -#define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) - -/* The analog voltage inputs have 8mV LSB. Since the sysfs output is - in mV as would be measured on the chip input pin, need to just - multiply/divide by 8 to translate from/to register values. */ -#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 4) / 8), 0, 255)) +#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? \ + (val) + 0x100 * 1000 \ + : (val)) / 1000, 0, 0xff)) +#define TEMP_FROM_REG(val) (((val) & 0x80 ? \ + (val) - 0x100 : (val)) * 1000) + +/* + * The analog voltage inputs have 8mV LSB. Since the sysfs output is + * in mV as would be measured on the chip input pin, need to just + * multiply/divide by 8 to translate from/to register values. + */ +#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 4) / 8), 0, 255)) #define IN_FROM_REG(val) ((val) * 8) #define DIV_FROM_REG(val) (1 << (val)) @@ -116,7 +120,7 @@ DIV_TO_REG(long val) break; val >>= 1; } - return ((u8) i); + return (u8)i; } struct w83l786ng_data { @@ -125,7 +129,7 @@ struct w83l786ng_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ unsigned long last_nonvolatile; /* In jiffies, last time we update the - nonvolatile registers */ + * nonvolatile registers */ u8 in[3]; u8 in_max[3]; @@ -137,10 +141,10 @@ struct w83l786ng_data { u8 temp[2][3]; u8 pwm[2]; u8 pwm_mode[2]; /* 0->DC variable voltage - 1->PWM variable duty cycle */ + * 1->PWM variable duty cycle */ u8 pwm_enable[2]; /* 1->manual - 2->thermal cruise (also called SmartFan I) */ + * 2->thermal cruise (also called SmartFan I) */ u8 tolerance[2]; }; @@ -186,11 +190,11 @@ w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value) #define show_in_reg(reg) \ static ssize_t \ show_##reg(struct device *dev, struct device_attribute *attr, \ - char *buf) \ + char *buf) \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct w83l786ng_data *data = w83l786ng_update_device(dev); \ - return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \ + return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \ } show_in_reg(in) @@ -199,13 +203,16 @@ show_in_reg(in_max) #define store_in_reg(REG, reg) \ static ssize_t \ -store_in_##reg (struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t count) \ +store_in_##reg(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct i2c_client *client = to_i2c_client(dev); \ struct w83l786ng_data *data = i2c_get_clientdata(client); \ - unsigned long val = simple_strtoul(buf, NULL, 10); \ + unsigned long val; \ + int err = kstrtoul(buf, 10, &val); \ + if (err) \ + return err; \ mutex_lock(&data->update_lock); \ data->in_##reg[nr] = IN_TO_REG(val); \ w83l786ng_write_value(client, W83L786NG_REG_IN_##REG(nr), \ @@ -241,8 +248,8 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ { \ int nr = to_sensor_dev_attr(attr)->index; \ struct w83l786ng_data *data = w83l786ng_update_device(dev); \ - return sprintf(buf,"%d\n", \ - FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \ + return sprintf(buf, "%d\n", \ + FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \ } show_fan_reg(fan); @@ -255,9 +262,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct w83l786ng_data *data = i2c_get_clientdata(client); - u32 val; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; - val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr), @@ -276,10 +287,12 @@ show_fan_div(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr])); } -/* Note: we save and restore the fan minimum here, because its value is - determined in part by the fan divisor. This follows the principle of - least surprise; the user doesn't expect the fan minimum to change just - because the divisor changed. */ +/* + * Note: we save and restore the fan minimum here, because its value is + * determined in part by the fan divisor. This follows the principle of + * least surprise; the user doesn't expect the fan minimum to change just + * because the divisor changed. + */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -294,11 +307,18 @@ store_fan_div(struct device *dev, struct device_attribute *attr, u8 keep_mask = 0; u8 new_shift = 0; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + /* Save fan_min */ mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); - data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10)); + data->fan_div[nr] = DIV_TO_REG(val); switch (nr) { case 0: @@ -371,16 +391,20 @@ store_temp(struct device *dev, struct device_attribute *attr, int index = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct w83l786ng_data *data = i2c_get_clientdata(client); - s32 val; + long val; + int err; + + err = kstrtol(buf, 10, &val); + if (err) + return err; - val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); data->temp[nr][index] = TEMP_TO_REG(val); w83l786ng_write_value(client, W83L786NG_REG_TEMP[nr][index], data->temp[nr][index]); mutex_unlock(&data->update_lock); - return count; + return count; } static struct sensor_device_attribute_2 sda_temp_input[] = { @@ -403,8 +427,8 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { }; #define show_pwm_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ - char *buf) \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ + char *buf) \ { \ struct w83l786ng_data *data = w83l786ng_update_device(dev); \ int nr = to_sensor_dev_attr(attr)->index; \ @@ -422,8 +446,13 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct w83l786ng_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); u8 reg; + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; if (val > 1) return -EINVAL; @@ -445,7 +474,13 @@ store_pwm(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct w83l786ng_data *data = i2c_get_clientdata(client); - u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); data->pwm[nr] = val; @@ -461,11 +496,15 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct w83l786ng_data *data = i2c_get_clientdata(client); - u32 val = simple_strtoul(buf, NULL, 10); - u8 reg; + unsigned long val; + int err; - if (!val || (val > 2)) /* only modes 1 and 2 are supported */ + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + if (!val || val > 2) /* only modes 1 and 2 are supported */ return -EINVAL; mutex_lock(&data->update_lock); @@ -513,10 +552,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr, int nr = to_sensor_dev_attr(attr)->index; struct i2c_client *client = to_i2c_client(dev); struct w83l786ng_data *data = i2c_get_clientdata(client); - u32 val; u8 tol_tmp, tol_mask; + unsigned long val; + int err; - val = simple_strtoul(buf, NULL, 10); + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); tol_mask = w83l786ng_read_value(client, @@ -524,9 +566,8 @@ store_tolerance(struct device *dev, struct device_attribute *attr, tol_tmp = SENSORS_LIMIT(val, 0, 15); tol_tmp &= 0x0f; data->tolerance[nr] = tol_tmp; - if (nr == 1) { + if (nr == 1) tol_tmp <<= 4; - } w83l786ng_write_value(client, W83L786NG_REG_TOLERANCE, tol_mask | tol_tmp); @@ -591,9 +632,8 @@ w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info) u16 man_id; u8 chip_id; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - } /* Detection */ if ((w83l786ng_read_value(client, W83L786NG_REG_CONFIG) & 0x80)) { @@ -652,7 +692,8 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) data->fan_div[1] = (reg_tmp >> 4) & 0x07; /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group))) + err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group); + if (err) goto exit_remove; data->hwmon_dev = hwmon_device_register(dev); @@ -769,21 +810,8 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) return data; } -static int __init -sensors_w83l786ng_init(void) -{ - return i2c_add_driver(&w83l786ng_driver); -} - -static void __exit -sensors_w83l786ng_exit(void) -{ - i2c_del_driver(&w83l786ng_driver); -} +module_i2c_driver(w83l786ng_driver); MODULE_AUTHOR("Kevin Lo"); MODULE_DESCRIPTION("w83l786ng driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_w83l786ng_init); -module_exit(sensors_w83l786ng_exit); diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c index 9b598ed26020..07cb25ae69be 100644 --- a/drivers/hwmon/wm831x-hwmon.c +++ b/drivers/hwmon/wm831x-hwmon.c @@ -40,7 +40,7 @@ static ssize_t show_name(struct device *dev, return sprintf(buf, "wm831x\n"); } -static const char *input_names[] = { +static const char * const input_names[] = { [WM831X_AUX_SYSVDD] = "SYSVDD", [WM831X_AUX_USB] = "USB", [WM831X_AUX_BKUP_BATT] = "Backup battery", @@ -117,8 +117,10 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_chip_temp, NULL, WM831X_AUX_CHIP_TEMP); static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL, WM831X_AUX_CHIP_TEMP); -/* Report as a voltage since conversion depends on external components - * and that's what the ABI wants. */ +/* + * Report as a voltage since conversion depends on external components + * and that's what the ABI wants. + */ static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_voltage, NULL, WM831X_AUX_BATT_TEMP); static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c index 3ff67edbdc44..b955756bdb42 100644 --- a/drivers/hwmon/wm8350-hwmon.c +++ b/drivers/hwmon/wm8350-hwmon.c @@ -34,7 +34,7 @@ static ssize_t show_name(struct device *dev, return sprintf(buf, "wm8350\n"); } -static const char *input_names[] = { +static const char * const input_names[] = { [WM8350_AUXADC_USB] = "USB", [WM8350_AUXADC_LINE] = "Line", [WM8350_AUXADC_BATT] = "Battery", |