diff options
Diffstat (limited to 'drivers/hwmon')
127 files changed, 9448 insertions, 6646 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 02260406b9e4..8deedc1b9840 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -253,7 +253,8 @@ config SENSORS_K10TEMP If you say yes here you get support for the temperature sensor(s) inside your CPU. Supported are later revisions of the AMD Family 10h and all revisions of the AMD Family 11h, - 12h (Llano), 14h (Brazos) and 15h (Bulldozer) microarchitectures. + 12h (Llano), 14h (Brazos) and 15h (Bulldozer/Trinity) + microarchitectures. This driver can also be built as a module. If so, the module will be called k10temp. @@ -425,7 +426,7 @@ config SENSORS_GL520SM config SENSORS_GPIO_FAN tristate "GPIO fan" - depends on GENERIC_GPIO + depends on GPIOLIB help If you say yes here you get support for fans connected to GPIO lines. @@ -497,8 +498,9 @@ config SENSORS_JC42 If you say yes here, you get support for JEDEC JC42.4 compliant temperature sensors, which are used on many DDR3 memory modules for mobile devices and servers. Support will include, but not be limited - to, ADT7408, CAT34TS02, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, - MCP9843, SE97, SE98, STTS424(E), TSE2002B3, and TS3000B3. + to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805, + MCP98242, MCP98243, MCP9843, SE97, SE98, STTS424(E), STTS2002, + STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2. This driver can also be built as a module. If so, the module will be called jc42. @@ -597,11 +599,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. @@ -647,7 +649,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. @@ -811,6 +814,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 @@ -871,7 +884,7 @@ source drivers/hwmon/pmbus/Kconfig config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." - depends on GENERIC_GPIO + depends on GPIOLIB help If you say yes here you get support for the Sensiron SHT10, SHT11, SHT15, SHT71, SHT75 humidity and temperature sensors. @@ -1027,7 +1040,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. @@ -1043,7 +1057,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. @@ -1226,18 +1241,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 @@ -1355,10 +1371,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/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 554f046bcf20..9140236a0182 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -391,6 +391,7 @@ static ssize_t show_str(struct device *dev, break; default: BUG(); + val = ""; } return sprintf(buf, "%s\n", val); @@ -632,6 +633,7 @@ static int register_ro_attrs(struct acpi_power_meter_resource *resource, sensors->dev_attr.show = ro->show; sensors->index = ro->index; + sysfs_attr_init(&sensors->dev_attr.attr); res = device_create_file(dev, &sensors->dev_attr); if (res) { sensors->dev_attr.attr.name = NULL; @@ -661,6 +663,7 @@ static int register_rw_attrs(struct acpi_power_meter_resource *resource, sensors->dev_attr.store = rw->set; sensors->index = rw->index; + sysfs_attr_init(&sensors->dev_attr.attr); res = device_create_file(dev, &sensors->dev_attr); if (res) { sensors->dev_attr.attr.name = NULL; diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index 5d760f3d21c2..ce43642ef03e 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -128,6 +128,7 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev) ret = PTR_ERR(chip->hwmon_dev); goto error_remove_group; } + chip->spi_dev = spi_dev; return 0; error_remove_group: @@ -167,17 +168,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..44e1fd7f3d81 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,22 +228,20 @@ 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 -get_fan_auto_nearest(struct adm1031_data *data, - int chan, u8 val, u8 reg, u8 *new_reg) +get_fan_auto_nearest(struct adm1031_data *data, int chan, u8 val, u8 reg) { int i; int first_match = -1, exact_match = -1; u8 other_reg_val = (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1]; - if (val == 0) { - *new_reg = 0; + if (val == 0) return 0; - } for (i = 0; i < 8; i++) { if ((val == (*data->chan_select_table)[i][chan]) && @@ -252,7 +252,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; @@ -260,13 +261,11 @@ get_fan_auto_nearest(struct adm1031_data *data, } if (exact_match >= 0) - *new_reg = exact_match; + return exact_match; else if (first_match >= 0) - *new_reg = first_match; - else - return -EINVAL; + return first_match; - return 0; + return -EINVAL; } static ssize_t show_fan_auto_channel(struct device *dev, @@ -297,18 +296,21 @@ set_fan_auto_channel(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); - ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®); - if (ret) { + ret = get_fan_auto_nearest(data, nr, val, data->conf1); + if (ret < 0) { mutex_unlock(&data->update_lock); return ret; } + reg = ret; data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); 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 +1133,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..1958f03efd7a 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -59,14 +59,11 @@ struct ads1015_data { struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; }; -static int ads1015_read_value(struct i2c_client *client, unsigned int channel, - int *value) +static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) { u16 config; - s16 conversion; struct ads1015_data *data = i2c_get_clientdata(client); unsigned int pga = data->channel_data[channel].pga; - int fullscale; unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int conversion_time_ms; int res; @@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, if (res < 0) goto err_unlock; config = res; - fullscale = fullscale_table[pga]; conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); /* setup and start single conversion */ @@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, } res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); - if (res < 0) - goto err_unlock; - conversion = res; - - mutex_unlock(&data->update_lock); - - *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); - - return 0; err_unlock: mutex_unlock(&data->update_lock); return res; } +static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, + s16 reg) +{ + struct ads1015_data *data = i2c_get_clientdata(client); + unsigned int pga = data->channel_data[channel].pga; + int fullscale = fullscale_table[pga]; + + return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +} + /* sysfs callback function */ static ssize_t show_in(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - int in; int res; + int index = attr->index; - res = ads1015_read_value(client, attr->index, &in); + res = ads1015_read_adc(client, index); + if (res < 0) + return res; - return (res < 0) ? res : sprintf(buf, "%d\n", in); + return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res)); } static const struct sensor_device_attribute ads1015_in[] = { @@ -305,19 +304,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..ece4159bd453 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -276,6 +276,7 @@ static bool duty_mode_enabled(u8 pwm_enable) return false; default: BUG(); + return true; } } @@ -291,6 +292,7 @@ static bool auto_mode_enabled(u8 pwm_enable) return true; default: BUG(); + return false; } } @@ -917,19 +919,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..37a8fc92b44a 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); @@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) return true; } +/* + * Newer BKDG versions have an updated recommendation on how to properly + * initialize the running average range (was: 0xE, now: 0x9). This avoids + * counter saturations resulting in bogus power readings. + * We correct this value ourselves to cope with older BIOSes. + */ +static void __devinit tweak_runavg_range(struct pci_dev *pdev) +{ + u32 val; + const struct pci_device_id affected_device = { + PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }; + + /* + * let this quirk apply only to the current version of the + * northbridge, since future versions may change the behavior + */ + if (!pci_match_id(&affected_device, pdev)) + return; + + pci_bus_read_config_dword(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), + REG_TDP_RUNNING_AVERAGE, &val); + if ((val & 0xf) != 0xe) + return; + + val &= ~0xf; + val |= 0x9; + pci_bus_write_config_dword(pdev->bus, + PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), + REG_TDP_RUNNING_AVERAGE, val); +} + static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; int err; + /* + * though we ignore every other northbridge, we still have to + * do the tweaking on _each_ node in MCM processors as the counters + * are working hand-in-hand + */ + tweak_runavg_range(pdev); + if (!fam15h_power_is_internal_node0(pdev)) { err = -ENODEV; goto exit; diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index aa6d8b686f82..519ce8b9c142 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> * @@ -52,8 +53,8 @@ static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* Insmod parameters */ -static int nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, int, 0); +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); @@ -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 28c09eead36b..a9bfd6736d9a 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -64,6 +64,7 @@ static const unsigned short normal_i2c[] = { /* Manufacturer IDs */ #define ADT_MANID 0x11d4 /* Analog Devices */ +#define ATMEL_MANID 0x001f /* Atmel */ #define MAX_MANID 0x004d /* Maxim */ #define IDT_MANID 0x00b3 /* IDT */ #define MCP_MANID 0x0054 /* Microchip */ @@ -77,15 +78,25 @@ static const unsigned short normal_i2c[] = { #define ADT7408_DEVID 0x0801 #define ADT7408_DEVID_MASK 0xffff +/* Atmel */ +#define AT30TS00_DEVID 0x8201 +#define AT30TS00_DEVID_MASK 0xffff + /* IDT */ #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ #define TS3000B3_DEVID_MASK 0xffff +#define TS3000GB2_DEVID 0x2912 /* Also matches TSE2002GB2 */ +#define TS3000GB2_DEVID_MASK 0xffff + /* Maxim */ #define MAX6604_DEVID 0x3e00 #define MAX6604_DEVID_MASK 0xffff /* Microchip */ +#define MCP9804_DEVID 0x0200 +#define MCP9804_DEVID_MASK 0xfffc + #define MCP98242_DEVID 0x2000 #define MCP98242_DEVID_MASK 0xfffc @@ -113,6 +124,12 @@ static const unsigned short normal_i2c[] = { #define STTS424E_DEVID 0x0000 #define STTS424E_DEVID_MASK 0xfffe +#define STTS2002_DEVID 0x0300 +#define STTS2002_DEVID_MASK 0xffff + +#define STTS3000_DEVID 0x0200 +#define STTS3000_DEVID_MASK 0xffff + static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 }; struct jc42_chips { @@ -123,8 +140,11 @@ struct jc42_chips { static struct jc42_chips jc42_chips[] = { { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, + { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, + { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, + { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK }, { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK }, { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK }, @@ -133,6 +153,8 @@ static struct jc42_chips jc42_chips[] = { { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK }, { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, + { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK }, + { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, }; /* Each client has this additional data */ @@ -158,21 +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 }, - { "cat94ts02", 0 }, - { "cat6095", 0 }, { "jc42", 0 }, - { "max6604", 0 }, - { "mcp9805", 0 }, - { "mcp98242", 0 }, - { "mcp98243", 0 }, - { "mcp9843", 0 }, - { "se97", 0 }, - { "se97b", 0 }, - { "se98", 0 }, - { "stts424", 0 }, - { "tse2002b3", 0 }, - { "ts3000b3", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, jc42_id); @@ -324,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) @@ -441,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; @@ -473,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; @@ -522,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; } @@ -537,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; } @@ -588,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..307bb325dde9 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -33,6 +33,9 @@ static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); +/* PCI-IDs for Northbridge devices not used anywhere else */ +#define PCI_DEVICE_ID_AMD_15H_M10H_NB_F3 0x1403 + /* CPUID function 0x80000001, ebx */ #define CPUID_PKGTYPE_MASK 0xf0000000 #define CPUID_PKGTYPE_F 0x00000000 @@ -205,11 +208,12 @@ 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) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_NB_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); 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..de8f7adaccbd 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -596,8 +596,10 @@ static int max6639_remove(struct i2c_client *client) return 0; } -static int max6639_suspend(struct i2c_client *client, pm_message_t mesg) +#ifdef CONFIG_PM_SLEEP +static int max6639_suspend(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); if (data < 0) return data; @@ -606,8 +608,9 @@ static int max6639_suspend(struct i2c_client *client, pm_message_t mesg) MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY); } -static int max6639_resume(struct i2c_client *client) +static int max6639_resume(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); if (data < 0) return data; @@ -615,6 +618,7 @@ static int max6639_resume(struct i2c_client *client) return i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY); } +#endif /* CONFIG_PM_SLEEP */ static const struct i2c_device_id max6639_id[] = { {"max6639", 0}, @@ -623,33 +627,25 @@ static const struct i2c_device_id max6639_id[] = { MODULE_DEVICE_TABLE(i2c, max6639_id); +static const struct dev_pm_ops max6639_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(max6639_suspend, max6639_resume) +}; + static struct i2c_driver max6639_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "max6639", + .pm = &max6639_pm_ops, }, .probe = max6639_probe, .remove = max6639_remove, - .suspend = max6639_suspend, - .resume = max6639_resume, .id_table = max6639_id, .detect = max6639_detect, .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..ce86c5e3c2c2 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]; @@ -53,7 +59,7 @@ static int mc13783_adc_read(struct device *dev, ret = mc13xxx_adc_do_conversion(priv->mc13xxx, MC13XXX_ADC_MODE_MULT_CHAN, - channel, sample); + channel, 0, 0, sample); if (ret) return ret; @@ -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 00460d8d8423..29b319db573e 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; @@ -54,7 +57,8 @@ lcrit_alarm, crit_alarm */ #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, crit_alarm */ -#define PMBUS_POUT_BOOLEANS_PER_PAGE 2 /* alarm, crit_alarm */ +#define PMBUS_POUT_BOOLEANS_PER_PAGE 3 /* cap_alarm, alarm, crit_alarm + */ #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, lcrit_alarm, crit_alarm */ @@ -706,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data, * If a negative value is stored in any of the referenced registers, this value * reflects an error code which will be returned. */ -static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) +static int pmbus_get_boolean(struct pmbus_data *data, int index) { u8 s1 = (index >> 24) & 0xff; u8 s2 = (index >> 16) & 0xff; u8 reg = (index >> 8) & 0xff; u8 mask = index & 0xff; - int status; + int ret, status; u8 regval; status = data->status[reg]; @@ -721,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) regval = status & mask; if (!s1 && !s2) - *val = !!regval; + ret = !!regval; else { long v1, v2; struct pmbus_sensor *sensor1, *sensor2; @@ -735,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) v1 = pmbus_reg2data(data, sensor1); v2 = pmbus_reg2data(data, sensor2); - *val = !!(regval && v1 >= v2); + ret = !!(regval && v1 >= v2); } - return 0; + return ret; } static ssize_t pmbus_show_boolean(struct device *dev, @@ -746,11 +750,10 @@ static ssize_t pmbus_show_boolean(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct pmbus_data *data = pmbus_update_device(dev); int val; - int err; - err = pmbus_get_boolean(data, attr->index, &val); - if (err) - return err; + val = pmbus_get_boolean(data, attr->index); + if (val < 0) + return val; return snprintf(buf, PAGE_SIZE, "%d\n", val); } @@ -781,7 +784,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); @@ -1333,6 +1336,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", } }; @@ -1388,6 +1402,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", }, { @@ -1423,6 +1440,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", }, { @@ -1675,7 +1695,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; @@ -1687,8 +1707,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) @@ -1701,50 +1720,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); @@ -1755,8 +1773,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 */ @@ -1764,7 +1781,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)) { @@ -1776,30 +1793,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 48c7b4a716ae..fc5eed8e85bb 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -28,11 +28,13 @@ #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; ktime_t access; /* chip access time */ + int delay; /* Delay between chip accesses in uS */ struct pmbus_driver_info info; }; @@ -52,10 +54,10 @@ MODULE_PARM_DESC(delay, "Delay between chip accesses in uS"); /* Some chips need a delay between accesses */ static inline void zl6100_wait(const struct zl6100_data *data) { - if (delay) { + if (data->delay) { s64 delta = ktime_us_delta(ktime_get(), data->access); - if (delta < delay) - udelay(delay - delta); + if (delta < data->delay) + udelay(data->delay - delta); } } @@ -151,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); @@ -192,23 +196,19 @@ 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; data->id = mid->driver_data; /* - * ZL2005, ZL2008, ZL2105, and ZL6100 are known to require a wait time - * between I2C accesses. ZL2004 and ZL6105 are known to be safe. - * Other chips have not yet been tested. - * - * Only clear the wait time for chips known to be safe. The wait time - * can be cleared later for additional chips if tests show that it - * is not needed (in other words, better be safe than sorry). + * According to information from the chip vendor, all currently + * supported chips are known to require a wait time between I2C + * accesses. */ - if (data->id == zl2004 || data->id == zl6105) - delay = 0; + data->delay = delay; /* * Since there was a direct I2C device access above, wait before @@ -227,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; @@ -239,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 = { @@ -264,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..c5f6be478bad 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) @@ -339,10 +343,11 @@ exit: return err; } -static int __init smsc47b397_find(unsigned short *addr) +static int __init smsc47b397_find(void) { u8 id, rev; char *name; + unsigned short addr; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -366,14 +371,14 @@ static int __init smsc47b397_find(unsigned short *addr) rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); - *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) + addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); pr_info("found SMSC %s (base address 0x%04x, revision %u)\n", - name, *addr, rev); + name, addr, rev); superio_exit(); - return 0; + return addr; } static int __init smsc47b397_init(void) @@ -381,9 +386,10 @@ static int __init smsc47b397_init(void) unsigned short address; int ret; - ret = smsc47b397_find(&address); - if (ret) + ret = smsc47b397_find(); + if (ret < 0) return ret; + address = ret; ret = platform_driver_register(&smsc47b397_driver); if (ret) diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index f44a89aac381..b5aa38dd7ab9 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 @@ -413,10 +491,10 @@ static const struct attribute_group smsc47m1_group = { .attrs = smsc47m1_attributes, }; -static int __init smsc47m1_find(unsigned short *addr, - struct smsc47m1_sio_data *sio_data) +static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) { u8 val; + unsigned short addr; superio_enter(); val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -468,16 +546,18 @@ static int __init smsc47m1_find(unsigned short *addr, } superio_select(); - *addr = (superio_inb(SUPERIO_REG_BASE) << 8) + addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); - if (*addr == 0) { + if (addr == 0) { pr_info("Device address not set, will not use\n"); superio_exit(); 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"); @@ -485,7 +565,7 @@ static int __init smsc47m1_find(unsigned short *addr, } superio_exit(); - return 0; + return addr; } /* Restore device to its initial state */ @@ -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); @@ -861,13 +938,15 @@ static int __init sm_smsc47m1_init(void) unsigned short address; struct smsc47m1_sio_data sio_data; - if (smsc47m1_find(&address, &sio_data)) - return -ENODEV; + err = smsc47m1_find(&sio_data); + if (err < 0) + return err; + address = err; /* Sets global pdev as a side effect */ err = smsc47m1_device_add(address, &sio_data); if (err) - goto exit; + return err; err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe); if (err) @@ -878,7 +957,6 @@ static int __init sm_smsc47m1_init(void) exit_device: platform_device_unregister(pdev); smsc47m1_restore(&sio_data); -exit: return err; } 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 5276d1933dbc..54922ed12978 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 2 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) \ @@ -1607,7 +1671,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ val = step_time_to_reg(val, data->pwm_mode[nr]); \ mutex_lock(&data->update_lock); \ data->reg[nr] = val; \ - w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ + w83627ehf_write_value(data, data->REG_##REG[nr], val); \ mutex_unlock(&data->update_lock); \ return count; \ } \ @@ -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); @@ -2004,7 +2071,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) goto exit; } - data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct w83627ehf_data), + GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit_release; @@ -2109,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; @@ -2151,22 +2224,27 @@ 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; w83627ehf_set_temp_reg_ehf(data, 3); /* - * Temperature sources for temp1 and temp2 are selected with + * Temperature sources for temp2 and temp3 are selected with * bank 0, registers 0x49 and 0x4a. */ data->temp_src[0] = 0; /* SYSTIN */ reg = w83627ehf_read_value(data, 0x49) & 0x07; /* Adjust to have the same mapping as other source registers */ if (reg == 0) - data->temp_src[1]++; + data->temp_src[1] = 1; else if (reg >= 2 && reg <= 5) - data->temp_src[1] += 2; + data->temp_src[1] = reg + 2; else /* should never happen */ data->have_temp &= ~(1 << 1); reg = w83627ehf_read_value(data, 0x4a); @@ -2187,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); @@ -2206,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) { @@ -2278,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); @@ -2289,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); @@ -2467,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); @@ -2493,9 +2587,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) exit_remove: w83627ehf_device_remove_files(dev); - kfree(data); - platform_set_drvdata(pdev, NULL); exit_release: + platform_set_drvdata(pdev, NULL); release_region(res->start, IOREGION_LENGTH); exit: return err; @@ -2509,7 +2602,6 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev) w83627ehf_device_remove_files(&pdev->dev); release_region(data->addr, IOREGION_LENGTH); platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } @@ -2527,15 +2619,15 @@ static struct platform_driver w83627ehf_driver = { static int __init w83627ehf_find(int sioaddr, unsigned short *addr, struct w83627ehf_sio_data *sio_data) { - static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; - static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; - static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; - static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P"; - static const char __initdata sio_name_W83627UHG[] = "W83627UHG"; - static const char __initdata sio_name_W83667HG[] = "W83667HG"; - static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B"; - static const char __initdata sio_name_NCT6775[] = "NCT6775F"; - static const char __initdata sio_name_NCT6776[] = "NCT6776F"; + static const char sio_name_W83627EHF[] __initconst = "W83627EHF"; + static const char sio_name_W83627EHG[] __initconst = "W83627EHG"; + static const char sio_name_W83627DHG[] __initconst = "W83627DHG"; + static const char sio_name_W83627DHG_P[] __initconst = "W83627DHG-P"; + static const char sio_name_W83627UHG[] __initconst = "W83627UHG"; + static const char sio_name_W83667HG[] __initconst = "W83667HG"; + static const char sio_name_W83667HG_B[] __initconst = "W83667HG-B"; + static const char sio_name_NCT6775[] __initconst = "NCT6775F"; + static const char sio_name_NCT6776[] __initconst = "NCT6776F"; u16 val; const char *sio_name; @@ -2617,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) @@ -2630,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..d6b0bdd48651 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> @@ -71,16 +71,16 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes. 2<= timeout <=255 (default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); -static int nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, int, 0); +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __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", |