diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-23 11:26:00 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-23 11:26:00 -0700 |
commit | 3b642cf30561220b7798fac3ea1455d505e02c39 (patch) | |
tree | 1a618e8a2571d5efc9cdaeb32225268b07bf33ea /i2c | |
parent | 6b2cc2c720aef774f5773aa48d14267107634537 (diff) | |
download | patches-3b642cf30561220b7798fac3ea1455d505e02c39.tar.gz |
remove i2c and w1 patches that are in mainline
Diffstat (limited to 'i2c')
58 files changed, 0 insertions, 14323 deletions
diff --git a/i2c/drivers-w1-w1.c-fix-a-compile-error.patch b/i2c/drivers-w1-w1.c-fix-a-compile-error.patch deleted file mode 100644 index b902938fe57d29..00000000000000 --- a/i2c/drivers-w1-w1.c-fix-a-compile-error.patch +++ /dev/null @@ -1,33 +0,0 @@ -From akpm@osdl.org Thu Apr 27 02:31:41 2006 -Message-Id: <200604270930.k3R9UkoG025245@shell0.pdx.osdl.net> -Subject: [patch 1/9] drivers/w1/w1.c: fix a compile error -To: greg@kroah.com -Cc: akpm@osdl.org, bunk@stusta.de, johnpol@2ka.mipt.ru -From: akpm@osdl.org -Date: Thu, 27 Apr 2006 02:29:18 -0700 - - -From: Adrian Bunk <bunk@stusta.de> - -drivers/w1/w1.c:197: error: static declaration of 'w1_bus_type' follows non-static declaration -drivers/w1/w1.h:217: error: previous declaration of 'w1_bus_type' was here - -Signed-off-by: Adrian Bunk <bunk@stusta.de> -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Andrew Morton <akpm@osdl.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/w1.h | 1 - - 1 file changed, 1 deletion(-) - ---- gregkh-2.6.orig/drivers/w1/w1.h -+++ gregkh-2.6/drivers/w1/w1.h -@@ -211,7 +211,6 @@ static inline struct w1_master* dev_to_w - } - - extern struct device_driver w1_master_driver; --extern struct bus_type w1_bus_type; - extern struct device w1_master_device; - extern int w1_max_slave_count; - extern int w1_max_slave_ttl; diff --git a/i2c/hwmon-abituguru-fixes.patch b/i2c/hwmon-abituguru-fixes.patch deleted file mode 100644 index 06680ba23b7f27..00000000000000 --- a/i2c/hwmon-abituguru-fixes.patch +++ /dev/null @@ -1,416 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:23:04 2006 -Date: Sun, 4 Jun 2006 20:23:01 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: abituguru: Review fixes -Message-Id: <20060604202301.df24f89f.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-abituguru-fixes.patch - -From: Hans de Goede <j.w.r.degoede@hhs.nl> - -Fixes to the Abit uGuru driver as requested in review by Jean Delvare: - - exactly calculate the sysfs_names array length using macro - - use snprintf when generating names to double check that the sysfs_names - array does not overflow. - - use ARRAY_SIZE and / or defines to determine number of loops in for loops - instead of using hardcoded values. - - In abituguru_probe(), refactor the error path leaving a single call to kfree - -Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/abituguru.c | 195 +++++++++++++++++++++++++--------------------- - 1 file changed, 110 insertions(+), 85 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/abituguru.c -+++ gregkh-2.6/drivers/hwmon/abituguru.c -@@ -36,6 +36,10 @@ - #define ABIT_UGURU_SENSOR_BANK1 0x21 /* 16x volt and temp */ - #define ABIT_UGURU_FAN_PWM 0x24 /* 3x 5 bytes */ - #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! */ - /* 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 */ -@@ -74,10 +78,33 @@ - /* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */ - #define ABIT_UGURU_MAX_RETRIES 3 - #define ABIT_UGURU_RETRY_DELAY (HZ/5) --/* Maximum 2 timeouts in abituguru_update_device, iow 3 in a row is a error */ -+/* Maximum 2 timeouts in abituguru_update_device, iow 3 in a row is an error */ - #define ABIT_UGURU_MAX_TIMEOUTS 2 -+/* utility macros */ -+#define ABIT_UGURU_NAME "abituguru" -+#define ABIT_UGURU_DEBUG(level, format, arg...) \ -+ 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 */ -+#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 */ -+#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 */ -+#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 */ -+#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 ( \ -+ ABIT_UGURU_MAX_BANK1_SENSORS * ABITUGURU_IN_NAMES_LENGTH + \ -+ ABIT_UGURU_MAX_BANK2_SENSORS * ABITUGURU_FAN_NAMES_LENGTH + \ -+ ABIT_UGURU_MAX_PWMS * ABITUGURU_PWM_NAMES_LENGTH) - --/* All the variables below are named identical to the oguru and oguru2 programs -+/* 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. */ -@@ -93,11 +120,6 @@ - #define ABIT_UGURU_STATUS_READ 0x01 /* Ready to be read */ - #define ABIT_UGURU_STATUS_INPUT 0x08 /* More input */ - #define ABIT_UGURU_STATUS_READY 0x09 /* Ready to be written */ --/* utility macros */ --#define ABIT_UGURU_NAME "abituguru" --#define ABIT_UGURU_DEBUG(level, format, arg...) \ -- if (level <= verbose) \ -- printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) - - /* Constants */ - /* in (Volt) sensors go up to 3494 mV, temp to 255000 millidegrees Celsius */ -@@ -156,24 +178,23 @@ struct abituguru_data { - 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[16 * 9 + -+ struct sensor_device_attribute_2 sysfs_attr[ -+ ABIT_UGURU_MAX_BANK1_SENSORS * 9 + - ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6]; -- /* Buffer to store the dynamically generated sysfs names, we need 2120 -- bytes for bank1 (worst case scenario of 16 in sensors), 444 bytes -- for fan1-6 and 738 bytes for pwm1-6 + some room to spare in case I -- miscounted :) */ -- char bank1_names[3400]; -+ /* Buffer to store the dynamically generated sysfs names */ -+ char sysfs_names[ABITUGURU_SYSFS_NAMES_LENGTH]; - - /* Bank 1 data */ -- u8 bank1_sensors[2]; /* number of [0] in, [1] temp sensors */ -- u8 bank1_address[2][16];/* addresses of [0] in, [1] temp sensors */ -- u8 bank1_value[16]; -- /* This array holds 16 x 3 entries for all the bank 1 sensor settings -+ /* number of and addresses of [0] in, [1] temp sensors */ -+ 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). */ -- u8 bank1_settings[16][3]; -+ u8 bank1_settings[ABIT_UGURU_MAX_BANK1_SENSORS][3]; - /* Maximum value for each sensor used for scaling in mV/millidegrees - Celsius. */ -- int bank1_max_value[16]; -+ int bank1_max_value[ABIT_UGURU_MAX_BANK1_SENSORS]; - - /* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */ - u8 bank2_sensors; /* actual number of bank2 sensors found */ -@@ -379,7 +400,7 @@ abituguru_detect_bank1_sensor_type(struc - /* First read the sensor and the current settings */ - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val, - 1, ABIT_UGURU_MAX_RETRIES) != 1) -- return -EIO; -+ return -ENODEV; - - /* Test val is sane / usable for sensor type detection. */ - if ((val < 10u) || (val > 240u)) { -@@ -401,7 +422,7 @@ abituguru_detect_bank1_sensor_type(struc - buf[2] = 250; - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, - buf, 3) != 3) -- return -EIO; -+ return -ENODEV; - /* Now we need 20 ms to give the uguru time to read the sensors - and raise a voltage alarm */ - set_current_state(TASK_UNINTERRUPTIBLE); -@@ -409,19 +430,19 @@ abituguru_detect_bank1_sensor_type(struc - /* Check for alarm and check the alarm is a volt low alarm. */ - if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) -- return -EIO; -+ return -ENODEV; - if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, - sensor_addr, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) -- return -EIO; -+ return -ENODEV; - if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { - /* Restore original settings */ - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, - sensor_addr, - data->bank1_settings[sensor_addr], - 3) != 3) -- return -EIO; -+ return -ENODEV; - ABIT_UGURU_DEBUG(2, " found volt sensor\n"); - return ABIT_UGURU_IN_SENSOR; - } else -@@ -439,7 +460,7 @@ abituguru_detect_bank1_sensor_type(struc - buf[2] = 10; - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, - buf, 3) != 3) -- return -EIO; -+ return -ENODEV; - /* Now we need 50 ms to give the uguru time to read the sensors - and raise a temp alarm */ - set_current_state(TASK_UNINTERRUPTIBLE); -@@ -447,12 +468,12 @@ abituguru_detect_bank1_sensor_type(struc - /* Check for alarm and check the alarm is a temp high alarm. */ - if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) -- return -EIO; -+ return -ENODEV; - if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, - sensor_addr, buf, 3, - ABIT_UGURU_MAX_RETRIES) != 3) -- return -EIO; -+ return -ENODEV; - if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) { - ret = ABIT_UGURU_TEMP_SENSOR; - ABIT_UGURU_DEBUG(2, " found temp sensor\n"); -@@ -466,7 +487,7 @@ abituguru_detect_bank1_sensor_type(struc - /* Restore original settings */ - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, - data->bank1_settings[sensor_addr], 3) != 3) -- return -EIO; -+ return -ENODEV; - - return ret; - } -@@ -1061,21 +1082,21 @@ static const struct sensor_device_attrib - store_pwm_setting, 4, 0), - }; - --static const struct sensor_device_attribute_2 abituguru_sysfs_attr[] = { -+static struct sensor_device_attribute_2 abituguru_sysfs_attr[] = { - SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0), - }; - - static int __devinit abituguru_probe(struct platform_device *pdev) - { - struct abituguru_data *data; -- int i, j, res; -+ int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV; - char *sysfs_filename; -- int sysfs_attr_i = 0; - - /* El weirdo probe order, to keep the sysfs order identical to the - BIOS and window-appliction listing order. */ -- const u8 probe_order[16] = { 0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, -- 0x02, 0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C }; -+ 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))) - return -ENOMEM; -@@ -1092,24 +1113,18 @@ static int __devinit abituguru_probe(str - - 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) { -- kfree(data); -- return -ENODEV; -- } -+ data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3) -+ goto abituguru_probe_error; - -- for (i = 0; i < 16; i++) { -+ for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, i, - &data->bank1_value[i], 1, -- ABIT_UGURU_MAX_RETRIES) != 1) { -- kfree(data); -- return -ENODEV; -- } -+ ABIT_UGURU_MAX_RETRIES) != 1) -+ goto abituguru_probe_error; - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1+1, i, - data->bank1_settings[i], 3, -- ABIT_UGURU_MAX_RETRIES) != 3) { -- kfree(data); -- return -ENODEV; -- } -+ 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 -@@ -1119,48 +1134,45 @@ static int __devinit abituguru_probe(str - for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i, - &data->bank2_value[i], 1, -- ABIT_UGURU_MAX_RETRIES) != 1) { -- kfree(data); -- return -ENODEV; -- } -+ ABIT_UGURU_MAX_RETRIES) != 1) -+ goto abituguru_probe_error; - if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2+1, i, - data->bank2_settings[i], 2, -- ABIT_UGURU_MAX_RETRIES) != 2) { -- kfree(data); -- return -ENODEV; -- } -+ ABIT_UGURU_MAX_RETRIES) != 2) -+ goto abituguru_probe_error; - } - for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { - if (abituguru_read(data, ABIT_UGURU_FAN_PWM, i, - data->pwm_settings[i], 5, -- ABIT_UGURU_MAX_RETRIES) != 5) { -- kfree(data); -- return -ENODEV; -- } -+ ABIT_UGURU_MAX_RETRIES) != 5) -+ goto abituguru_probe_error; - } - data->last_updated = jiffies; - - /* Detect sensor types and fill the sysfs attr for bank1 */ -- sysfs_filename = data->bank1_names; -- for (i = 0; i < 16; i++) { -+ sysfs_attr_i = 0; -+ sysfs_filename = data->sysfs_names; -+ sysfs_names_free = ABITUGURU_SYSFS_NAMES_LENGTH; -+ for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { - res = abituguru_detect_bank1_sensor_type(data, probe_order[i]); -- if (res < 0) { -- kfree(data); -- return -ENODEV; -- } -+ if (res < 0) -+ goto abituguru_probe_error; - if (res == ABIT_UGURU_NC) - continue; - -+ /* res 1 (temp) sensors have 7 sysfs entries, 0 (in) 9 */ - for (j = 0; j < (res ? 7 : 9); j++) { -- const char *name_templ = abituguru_sysfs_bank1_templ[ -- res][j].dev_attr.attr.name; -+ used = snprintf(sysfs_filename, sysfs_names_free, -+ abituguru_sysfs_bank1_templ[res][j].dev_attr. -+ attr.name, data->bank1_sensors[res] + res) -+ + 1; - data->sysfs_attr[sysfs_attr_i] = - abituguru_sysfs_bank1_templ[res][j]; - data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = - sysfs_filename; -- sysfs_filename += sprintf(sysfs_filename, name_templ, -- data->bank1_sensors[res] + res) + 1; - data->sysfs_attr[sysfs_attr_i].index = probe_order[i]; -+ sysfs_filename += used; -+ sysfs_names_free -= used; - sysfs_attr_i++; - } - data->bank1_max_value[probe_order[i]] = -@@ -1172,52 +1184,65 @@ static int __devinit abituguru_probe(str - /* Detect number of sensors and fill the sysfs attr for bank2 (fans) */ - abituguru_detect_no_bank2_sensors(data); - for (i = 0; i < data->bank2_sensors; i++) { -- for (j = 0; j < 6; j++) { -- const char *name_templ = abituguru_sysfs_fan_templ[j]. -- dev_attr.attr.name; -+ for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_fan_templ); j++) { -+ used = snprintf(sysfs_filename, sysfs_names_free, -+ abituguru_sysfs_fan_templ[j].dev_attr.attr.name, -+ i + 1) + 1; - data->sysfs_attr[sysfs_attr_i] = - abituguru_sysfs_fan_templ[j]; - data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = - sysfs_filename; -- sysfs_filename += sprintf(sysfs_filename, name_templ, -- i + 1) + 1; - data->sysfs_attr[sysfs_attr_i].index = i; -+ sysfs_filename += used; -+ sysfs_names_free -= used; - sysfs_attr_i++; - } - } - /* Detect number of sensors and fill the sysfs attr for pwms */ - abituguru_detect_no_pwms(data); - for (i = 0; i < data->pwms; i++) { -- for (j = 0; j < 6; j++) { -- const char *name_templ = abituguru_sysfs_pwm_templ[j]. -- dev_attr.attr.name; -+ for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_pwm_templ); j++) { -+ used = snprintf(sysfs_filename, sysfs_names_free, -+ abituguru_sysfs_pwm_templ[j].dev_attr.attr.name, -+ i + 1) + 1; - data->sysfs_attr[sysfs_attr_i] = - abituguru_sysfs_pwm_templ[j]; - data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = - sysfs_filename; -- sysfs_filename += sprintf(sysfs_filename, name_templ, -- i + 1) + 1; - data->sysfs_attr[sysfs_attr_i].index = i; -+ sysfs_filename += used; -+ sysfs_names_free -= used; - sysfs_attr_i++; - } - } -- /* Last add any "generic" entries to sysfs */ -- for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) { -- data->sysfs_attr[sysfs_attr_i] = abituguru_sysfs_attr[i]; -- sysfs_attr_i++; -+ /* Fail safe check, this should never happen! */ -+ if (sysfs_names_free < 0) { -+ printk(KERN_ERR ABIT_UGURU_NAME ": Fatal error ran out of " -+ "space for sysfs attr names. This should never " -+ "happen please report to the abituguru maintainer " -+ "(see MAINTAINERS)\n"); -+ res = -ENAMETOOLONG; -+ goto abituguru_probe_error; - } - printk(KERN_INFO ABIT_UGURU_NAME ": found Abit uGuru\n"); - - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->class_dev)) { -- kfree(data); -- return PTR_ERR(data->class_dev); -+ res = PTR_ERR(data->class_dev); -+ goto abituguru_probe_error; - } - for (i = 0; i < sysfs_attr_i; i++) - device_create_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); -+ for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) -+ device_create_file(&pdev->dev, -+ &abituguru_sysfs_attr[i].dev_attr); - - return 0; -+ -+abituguru_probe_error: -+ kfree(data); -+ return res; - } - - static int __devexit abituguru_remove(struct platform_device *pdev) -@@ -1244,7 +1269,7 @@ static struct abituguru_data *abituguru_ - if ((err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, - data->alarms, 3, 0)) != 3) - goto LEAVE_UPDATE; -- for (i = 0; i < 16; i++) { -+ 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) diff --git a/i2c/hwmon-abituguru-new-driver.patch b/i2c/hwmon-abituguru-new-driver.patch deleted file mode 100644 index 8abb085abb2f3a..00000000000000 --- a/i2c/hwmon-abituguru-new-driver.patch +++ /dev/null @@ -1,1843 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:22:28 2006 -Date: Sun, 4 Jun 2006 20:22:24 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: abituguru: New hardware monitoring driver -Message-Id: <20060604202224.b38707bd.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-abituguru-new-driver.patch - -From: Hans de Goede <j.w.r.degoede@hhs.nl> - -New hardware monitoring driver for the Abit uGuru - -Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/abituguru | 59 + - Documentation/hwmon/abituguru-datasheet | 312 +++++++ - MAINTAINERS | 6 - drivers/hwmon/Kconfig | 12 - drivers/hwmon/Makefile | 1 - drivers/hwmon/abituguru.c | 1391 ++++++++++++++++++++++++++++++++ - 6 files changed, 1781 insertions(+) - ---- /dev/null -+++ gregkh-2.6/Documentation/hwmon/abituguru -@@ -0,0 +1,59 @@ -+Kernel driver abituguru -+======================= -+ -+Supported chips: -+ * Abit uGuru (Hardware Monitor part only) -+ Prefix: 'abituguru' -+ Addresses scanned: ISA 0x0E0 -+ Datasheet: Not available, this driver is based on reverse engineering. -+ A "Datasheet" has been written based on the reverse engineering it -+ should be available in the same dir as this file under the name -+ abituguru-datasheet. -+ -+Authors: -+ Hans de Goede <j.w.r.degoede@hhs.nl>, -+ (Initial reverse engineering done by Olle Sandberg -+ <ollebull@gmail.com>) -+ -+ -+Module Parameters -+----------------- -+ -+* force: bool Force detection. Note this parameter only causes the -+ detection to be skipped, if the uGuru can't be read -+ the module initialization (insmod) will still fail. -+* fan_sensors: int Tell the driver how many fan speed sensors there are -+ on your motherboard. Default: 0 (autodetect). -+* pwms: int Tell the driver how many fan speed controls (fan -+ pwms) your motherboard has. Default: 0 (autodetect). -+* verbose: int How verbose should the driver be? (0-3): -+ 0 normal output -+ 1 + verbose error reporting -+ 2 + sensors type probing info\n" -+ 3 + retryable error reporting -+ Default: 2 (the driver is still in the testing phase) -+ -+Notice if you need any of the first three options above please insmod the -+driver with verbose set to 3 and mail me <j.w.r.degoede@hhs.nl> the output of: -+dmesg | grep abituguru -+ -+ -+Description -+----------- -+ -+This driver supports the hardware monitoring features of the Abit uGuru chip -+found on Abit uGuru featuring motherboards (most modern Abit motherboards). -+ -+The uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit -+claiming it is "a new microprocessor designed by the ABIT Engineers"). -+Unfortunatly this doesn't help since the W83L950D is a generic -+microcontroller with a custom Abit application running on it. -+ -+Despite Abit not releasing any information regarding the uGuru, Olle -+Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part -+of the uGuru. Without his work this driver would not have been possible. -+ -+Known Issues -+------------ -+ -+The voltage and frequency control parts of the Abit uGuru are not supported. ---- /dev/null -+++ gregkh-2.6/Documentation/hwmon/abituguru-datasheet -@@ -0,0 +1,312 @@ -+uGuru datasheet -+=============== -+ -+First of all, what I know about uGuru is no fact based on any help, hints or -+datasheet from Abit. The data I have got on uGuru have I assembled through -+my weak knowledge in "backwards engineering". -+And just for the record, you may have noticed uGuru isn't a chip developed by -+Abit, as they claim it to be. It's realy just an microprocessor (uC) created by -+Winbond (W83L950D). And no, reading the manual for this specific uC or -+mailing Windbond for help won't give any usefull data about uGuru, as it is -+the program inside the uC that is responding to calls. -+ -+Olle Sandberg <ollebull@gmail.com>, 2005-05-25 -+ -+ -+Original version by Olle Sandberg who did the heavy lifting of the initial -+reverse engineering. This version has been almost fully rewritten for clarity -+and extended with write support and info on more databanks, the write support -+is once again reverse engineered by Olle the additional databanks have been -+reverse engineered by me. I would like to express my thanks to Olle, this -+document and the Linux driver could not have been written without his efforts. -+ -+Note: because of the lack of specs only the sensors part of the uGuru is -+described here and not the CPU / RAM / etc voltage & frequency control. -+ -+Hans de Goede <j.w.r.degoede@hhs.nl>, 28-01-2006 -+ -+ -+Detection -+========= -+ -+As far as known the uGuru is always placed at and using the (ISA) I/O-ports -+0xE0 and 0xE4, so we don't have to scan any port-range, just check what the two -+ports are holding for detection. We will refer to 0xE0 as CMD (command-port) -+and 0xE4 as DATA because Abit refers to them with these names. -+ -+If DATA holds 0x00 or 0x08 and CMD holds 0x00 or 0xAC an uGuru could be -+present. We have to check for two different values at data-port, because -+after a reboot uGuru will hold 0x00 here, but if the driver is removed and -+later on attached again data-port will hold 0x08, more about this later. -+ -+After wider testing of the Linux kernel driver some variants of the uGuru have -+turned up which will hold 0x00 instead of 0xAC at the CMD port, thus we also -+have to test CMD for two different values. On these uGuru's DATA will initally -+hold 0x09 and will only hold 0x08 after reading CMD first, so CMD must be read -+first! -+ -+To be really sure an uGuru is present a test read of one or more register -+sets should be done. -+ -+ -+Reading / Writing -+================= -+ -+Addressing -+---------- -+ -+The uGuru has a number of different addressing levels. The first addressing -+level we will call banks. A bank holds data for one or more sensors. The data -+in a bank for a sensor is one or more bytes large. -+ -+The number of bytes is fixed for a given bank, you should always read or write -+that many bytes, reading / writing more will fail, the results when writing -+less then the number of bytes for a given bank are undetermined. -+ -+See below for all known bank addresses, numbers of sensors in that bank, -+number of bytes data per sensor and contents/meaning of those bytes. -+ -+Although both this document and the kernel driver have kept the sensor -+terminoligy for the addressing within a bank this is not 100% correct, in -+bank 0x24 for example the addressing within the bank selects a PWM output not -+a sensor. -+ -+Notice that some banks have both a read and a write address this is how the -+uGuru determines if a read from or a write to the bank is taking place, thus -+when reading you should always use the read address and when writing the -+write address. The write address is always one (1) more then the read address. -+ -+ -+uGuru ready -+----------- -+ -+Before you can read from or write to the uGuru you must first put the uGuru -+in "ready" mode. -+ -+To put the uGuru in ready mode first write 0x00 to DATA and then wait for DATA -+to hold 0x09, DATA should read 0x09 within 250 read cycles. -+ -+Next CMD _must_ be read and should hold 0xAC, usually CMD will hold 0xAC the -+first read but sometimes it takes a while before CMD holds 0xAC and thus it -+has to be read a number of times (max 50). -+ -+After reading CMD, DATA should hold 0x08 which means that the uGuru is ready -+for input. As above DATA will usually hold 0x08 the first read but not always. -+This step can be skipped, but it is undetermined what happens if the uGuru has -+not yet reported 0x08 at DATA and you proceed with writing a bank address. -+ -+ -+Sending bank and sensor addresses to the uGuru -+---------------------------------------------- -+ -+First the uGuru must be in "ready" mode as described above, DATA should hold -+0x08 indicating that the uGuru wants input, in this case the bank address. -+ -+Next write the bank address to DATA. After the bank address has been written -+wait for to DATA to hold 0x08 again indicating that it wants / is ready for -+more input (max 250 reads). -+ -+Once DATA holds 0x08 again write the sensor address to CMD. -+ -+ -+Reading -+------- -+ -+First send the bank and sensor addresses as described above. -+Then for each byte of data you want to read wait for DATA to hold 0x01 -+which indicates that the uGuru is ready to be read (max 250 reads) and once -+DATA holds 0x01 read the byte from CMD. -+ -+Once all bytes have been read data will hold 0x09, but there is no reason to -+test for this. Notice that the number of bytes is bank address dependent see -+above and below. -+ -+After completing a successfull read it is advised to put the uGuru back in -+ready mode, so that it is ready for the next read / write cycle. This way -+if your program / driver is unloaded and later loaded again the detection -+algorithm described above will still work. -+ -+ -+ -+Writing -+------- -+ -+First send the bank and sensor addresses as described above. -+Then for each byte of data you want to write wait for DATA to hold 0x00 -+which indicates that the uGuru is ready to be written (max 250 reads) and -+once DATA holds 0x00 write the byte to CMD. -+ -+Once all bytes have been written wait for DATA to hold 0x01 (max 250 reads) -+don't ask why this is the way it is. -+ -+Once DATA holds 0x01 read CMD it should hold 0xAC now. -+ -+After completing a successfull write it is advised to put the uGuru back in -+ready mode, so that it is ready for the next read / write cycle. This way -+if your program / driver is unloaded and later loaded again the detection -+algorithm described above will still work. -+ -+ -+Gotchas -+------- -+ -+After wider testing of the Linux kernel driver some variants of the uGuru have -+turned up which do not hold 0x08 at DATA within 250 reads after writing the -+bank address. With these versions this happens quite frequent, using larger -+timeouts doesn't help, they just go offline for a second or 2, doing some -+internal callibration or whatever. Your code should be prepared to handle -+this and in case of no response in this specific case just goto sleep for a -+while and then retry. -+ -+ -+Address Map -+=========== -+ -+Bank 0x20 Alarms (R) -+-------------------- -+This bank contains 0 sensors, iow the sensor address is ignored (but must be -+written) just use 0. Bank 0x20 contains 3 bytes: -+ -+Byte 0: -+This byte holds the alarm flags for sensor 0-7 of Sensor Bank1, with bit 0 -+corresponding to sensor 0, 1 to 1, etc. -+ -+Byte 1: -+This byte holds the alarm flags for sensor 8-15 of Sensor Bank1, with bit 0 -+corresponding to sensor 8, 1 to 9, etc. -+ -+Byte 2: -+This byte holds the alarm flags for sensor 0-5 of Sensor Bank2, with bit 0 -+corresponding to sensor 0, 1 to 1, etc. -+ -+ -+Bank 0x21 Sensor Bank1 Values / Readings (R) -+-------------------------------------------- -+This bank contains 16 sensors, for each sensor it contains 1 byte. -+So far the following sensors are known to be available on all motherboards: -+Sensor 0 CPU temp -+Sensor 1 SYS temp -+Sensor 3 CPU core volt -+Sensor 4 DDR volt -+Sensor 10 DDR Vtt volt -+Sensor 15 PWM temp -+ -+Byte 0: -+This byte holds the reading from the sensor. Sensors in Bank1 can be both -+volt and temp sensors, this is motherboard specific. The uGuru however does -+seem to know (be programmed with) what kindoff sensor is attached see Sensor -+Bank1 Settings description. -+ -+Volt sensors use a linear scale, a reading 0 corresponds with 0 volt and a -+reading of 255 with 3494 mV. The sensors for higher voltages however are -+connected through a division circuit. The currently known division circuits -+in use result in ranges of: 0-4361mV, 0-6248mV or 0-14510mV. 3.3 volt sources -+use the 0-4361mV range, 5 volt the 0-6248mV and 12 volt the 0-14510mV . -+ -+Temp sensors also use a linear scale, a reading of 0 corresponds with 0 degree -+Celsius and a reading of 255 with a reading of 255 degrees Celsius. -+ -+ -+Bank 0x22 Sensor Bank1 Settings (R) -+Bank 0x23 Sensor Bank1 Settings (W) -+----------------------------------- -+ -+This bank contains 16 sensors, for each sensor it contains 3 bytes. Each -+set of 3 bytes contains the settings for the sensor with the same sensor -+address in Bank 0x21 . -+ -+Byte 0: -+Alarm behaviour for the selected sensor. A 1 enables the described behaviour. -+Bit 0: Give an alarm if measured temp is over the warning threshold (RW) * -+Bit 1: Give an alarm if measured volt is over the max threshold (RW) ** -+Bit 2: Give an alarm if measured volt is under the min threshold (RW) ** -+Bit 3: Beep if alarm (RW) -+Bit 4: 1 if alarm cause measured temp is over the warning threshold (R) -+Bit 5: 1 if alarm cause measured volt is over the max threshold (R) -+Bit 6: 1 if alarm cause measured volt is under the min threshold (R) -+Bit 7: Volt sensor: Shutdown if alarm persist for more then 4 seconds (RW) -+ Temp sensor: Shutdown if temp is over the shutdown threshold (RW) -+ -+* This bit is only honored/used by the uGuru if a temp sensor is connected -+** This bit is only honored/used by the uGuru if a volt sensor is connected -+Note with some trickery this can be used to find out what kinda sensor is -+detected see the Linux kernel driver for an example with many comments on -+how todo this. -+ -+Byte 1: -+Temp sensor: warning threshold (scale as bank 0x21) -+Volt sensor: min threshold (scale as bank 0x21) -+ -+Byte 2: -+Temp sensor: shutdown threshold (scale as bank 0x21) -+Volt sensor: max threshold (scale as bank 0x21) -+ -+ -+Bank 0x24 PWM outputs for FAN's (R) -+Bank 0x25 PWM outputs for FAN's (W) -+----------------------------------- -+ -+This bank contains 3 "sensors", for each sensor it contains 5 bytes. -+Sensor 0 usually controls the CPU fan -+Sensor 1 usually controls the NB (or chipset for single chip) fan -+Sensor 2 usually controls the System fan -+ -+Byte 0: -+Flag 0x80 to enable control, Fan runs at 100% when disabled. -+low nibble (temp)sensor address at bank 0x21 used for control. -+ -+Byte 1: -+0-255 = 0-12v (linear), specify voltage at which fan will rotate when under -+low threshold temp (specified in byte 3) -+ -+Byte 2: -+0-255 = 0-12v (linear), specify voltage at which fan will rotate when above -+high threshold temp (specified in byte 4) -+ -+Byte 3: -+Low threshold temp (scale as bank 0x21) -+ -+byte 4: -+High threshold temp (scale as bank 0x21) -+ -+ -+Bank 0x26 Sensors Bank2 Values / Readings (R) -+--------------------------------------------- -+ -+This bank contains 6 sensors (AFAIK), for each sensor it contains 1 byte. -+So far the following sensors are known to be available on all motherboards: -+Sensor 0: CPU fan speed -+Sensor 1: NB (or chipset for single chip) fan speed -+Sensor 2: SYS fan speed -+ -+Byte 0: -+This byte holds the reading from the sensor. 0-255 = 0-15300 (linear) -+ -+ -+Bank 0x27 Sensors Bank2 Settings (R) -+Bank 0x28 Sensors Bank2 Settings (W) -+------------------------------------ -+ -+This bank contains 6 sensors (AFAIK), for each sensor it contains 2 bytes. -+ -+Byte 0: -+Alarm behaviour for the selected sensor. A 1 enables the described behaviour. -+Bit 0: Give an alarm if measured rpm is under the min threshold (RW) -+Bit 3: Beep if alarm (RW) -+Bit 7: Shutdown if alarm persist for more then 4 seconds (RW) -+ -+Byte 1: -+min threshold (scale as bank 0x26) -+ -+ -+Warning for the adventerous -+=========================== -+ -+A word of caution to those who want to experiment and see if they can figure -+the voltage / clock programming out, I tried reading and only reading banks -+0-0x30 with the reading code used for the sensor banks (0x20-0x28) and this -+resulted in a _permanent_ reprogramming of the voltages, luckily I had the -+sensors part configured so that it would shutdown my system on any out of spec -+voltages which proprably safed my computer (after a reboot I managed to -+immediatly enter the bios and reload the defaults). This probably means that -+the read/write cycle for the non sensor part is different from the sensor part. ---- gregkh-2.6.orig/MAINTAINERS -+++ gregkh-2.6/MAINTAINERS -@@ -181,6 +181,12 @@ M: bcrl@kvack.org - L: linux-aio@kvack.org - S: Supported - -+ABIT UGURU HARDWARE MONITOR DRIVER -+P: Hans de Goede -+M: j.w.r.degoede@hhs.nl -+L: lm-sensors@lm-sensors.org -+S: Maintained -+ - ACENIC DRIVER - P: Jes Sorensen - M: jes@trained-monkey.org ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -27,6 +27,18 @@ config HWMON_VID - tristate - default n - -+config SENSORS_ABITUGURU -+ tristate "Abit uGuru" -+ depends on HWMON && EXPERIMENTAL -+ help -+ If you say yes here you get support for the Abit uGuru chips -+ sensor part. The voltage and frequency control parts of the Abit -+ uGuru are not supported. The Abit uGuru chip can be found on Abit -+ uGuru featuring motherboards (most modern Abit motherboards). -+ -+ This driver can also be built as a module. If so, the module -+ will be called abituguru. -+ - config SENSORS_ADM1021 - tristate "Analog Devices ADM1021 and compatibles" - depends on HWMON && I2C ---- gregkh-2.6.orig/drivers/hwmon/Makefile -+++ gregkh-2.6/drivers/hwmon/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_SENSORS_W83792D) += w83792d - obj-$(CONFIG_SENSORS_W83781D) += w83781d.o - obj-$(CONFIG_SENSORS_W83791D) += w83791d.o - -+obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o - obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o - obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o - obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o ---- /dev/null -+++ gregkh-2.6/drivers/hwmon/abituguru.c -@@ -0,0 +1,1391 @@ -+/* -+ abituguru.c Copyright (c) 2005-2006 Hans de Goede <j.w.r.degoede@hhs.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. -+*/ -+/* -+ This driver supports the sensor part of the custom Abit uGuru chip found -+ on Abit uGuru motherboards. Note: because of lack of specs the CPU / RAM / -+ etc voltage & frequency control is not supported! -+*/ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/jiffies.h> -+#include <linux/mutex.h> -+#include <linux/err.h> -+#include <linux/platform_device.h> -+#include <linux/hwmon.h> -+#include <linux/hwmon-sysfs.h> -+#include <asm/io.h> -+ -+/* Banks */ -+#define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */ -+#define ABIT_UGURU_SENSOR_BANK1 0x21 /* 16x volt and temp */ -+#define ABIT_UGURU_FAN_PWM 0x24 /* 3x 5 bytes */ -+#define ABIT_UGURU_SENSOR_BANK2 0x26 /* fans */ -+/* 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 */ -+#define ABIT_UGURU_MAX_PWMS 5 -+/* uGuru sensor bank 1 flags */ /* Alarm if: */ -+#define ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE 0x01 /* temp over warn */ -+#define ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE 0x02 /* volt over max */ -+#define ABIT_UGURU_VOLT_LOW_ALARM_ENABLE 0x04 /* volt under min */ -+#define ABIT_UGURU_TEMP_HIGH_ALARM_FLAG 0x10 /* temp is over warn */ -+#define ABIT_UGURU_VOLT_HIGH_ALARM_FLAG 0x20 /* volt is over max */ -+#define ABIT_UGURU_VOLT_LOW_ALARM_FLAG 0x40 /* volt is under min */ -+/* uGuru sensor bank 2 flags */ /* Alarm if: */ -+#define ABIT_UGURU_FAN_LOW_ALARM_ENABLE 0x01 /* fan under min */ -+/* uGuru sensor bank common flags */ -+#define ABIT_UGURU_BEEP_ENABLE 0x08 /* beep if alarm */ -+#define ABIT_UGURU_SHUTDOWN_ENABLE 0x80 /* shutdown if alarm */ -+/* uGuru fan PWM (speed control) flags */ -+#define ABIT_UGURU_FAN_PWM_ENABLE 0x80 /* enable speed control */ -+/* Values used for conversion */ -+#define ABIT_UGURU_FAN_MAX 15300 /* RPM */ -+/* Bank1 sensor types */ -+#define ABIT_UGURU_IN_SENSOR 0 -+#define ABIT_UGURU_TEMP_SENSOR 1 -+#define ABIT_UGURU_NC 2 -+/* Timeouts / Retries, if these turn out to need a lot of fiddling we could -+ convert them to params. */ -+/* 250 was determined by trial and error, 200 works most of the time, but not -+ always. I assume this is cpu-speed independent, since the ISA-bus and not -+ the CPU should be the bottleneck. Note that 250 sometimes is still not -+ enough (only reported on AN7 mb) this is handled by a higher layer. */ -+#define ABIT_UGURU_WAIT_TIMEOUT 250 -+/* Normally all expected status in abituguru_ready, are reported after the -+ first read, but sometimes not and we need to poll, 5 polls was not enough -+ 50 sofar is. */ -+#define ABIT_UGURU_READY_TIMEOUT 50 -+/* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */ -+#define ABIT_UGURU_MAX_RETRIES 3 -+#define ABIT_UGURU_RETRY_DELAY (HZ/5) -+/* Maximum 2 timeouts in abituguru_update_device, iow 3 in a row is a error */ -+#define ABIT_UGURU_MAX_TIMEOUTS 2 -+ -+/* All the variables 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 */ -+#define ABIT_UGURU_CMD 0x00 -+/* Mostly used to check if uGuru is busy */ -+#define ABIT_UGURU_DATA 0x04 -+#define ABIT_UGURU_REGION_LENGTH 5 -+/* uGuru status' */ -+#define ABIT_UGURU_STATUS_WRITE 0x00 /* Ready to be written */ -+#define ABIT_UGURU_STATUS_READ 0x01 /* Ready to be read */ -+#define ABIT_UGURU_STATUS_INPUT 0x08 /* More input */ -+#define ABIT_UGURU_STATUS_READY 0x09 /* Ready to be written */ -+/* utility macros */ -+#define ABIT_UGURU_NAME "abituguru" -+#define ABIT_UGURU_DEBUG(level, format, arg...) \ -+ if (level <= verbose) \ -+ printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) -+ -+/* 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 */ -+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. */ -+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! */ -+static const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 }; -+static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 }; -+ -+ -+/* Insmod parameters */ -+static int force; -+module_param(force, bool, 0); -+MODULE_PARM_DESC(force, "Set to one to force detection."); -+static int fan_sensors; -+module_param(fan_sensors, int, 0); -+MODULE_PARM_DESC(fan_sensors, "Number of fan sensors on the uGuru " -+ "(0 = autodetect)"); -+static int pwms; -+module_param(pwms, int, 0); -+MODULE_PARM_DESC(pwms, "Number of PWMs on the uGuru " -+ "(0 = autodetect)"); -+ -+/* Default verbose is 2, since this driver is still in the testing phase */ -+static int verbose = 2; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n" -+ " 0 normal output\n" -+ " 1 + verbose error reporting\n" -+ " 2 + sensors type probing info\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. */ -+struct abituguru_data { -+ struct class_device *class_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. */ -+ struct sensor_device_attribute_2 sysfs_attr[16 * 9 + -+ ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6]; -+ /* Buffer to store the dynamically generated sysfs names, we need 2120 -+ bytes for bank1 (worst case scenario of 16 in sensors), 444 bytes -+ for fan1-6 and 738 bytes for pwm1-6 + some room to spare in case I -+ miscounted :) */ -+ char bank1_names[3400]; -+ -+ /* Bank 1 data */ -+ u8 bank1_sensors[2]; /* number of [0] in, [1] temp sensors */ -+ u8 bank1_address[2][16];/* addresses of [0] in, [1] temp sensors */ -+ u8 bank1_value[16]; -+ /* This array holds 16 x 3 entries for all the bank 1 sensor settings -+ (flags, min, max for voltage / flags, warn, shutdown for temp). */ -+ u8 bank1_settings[16][3]; -+ /* Maximum value for each sensor used for scaling in mV/millidegrees -+ Celsius. */ -+ int bank1_max_value[16]; -+ -+ /* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */ -+ u8 bank2_sensors; /* actual number of bank2 sensors found */ -+ u8 bank2_value[ABIT_UGURU_MAX_BANK2_SENSORS]; -+ u8 bank2_settings[ABIT_UGURU_MAX_BANK2_SENSORS][2]; /* flags, min */ -+ -+ /* Alarms 2 bytes for bank1, 1 byte for bank2 */ -+ u8 alarms[3]; -+ -+ /* Fan PWM (speed control) 5 bytes per PWM */ -+ u8 pwms; /* actual number of pwms found */ -+ u8 pwm_settings[ABIT_UGURU_MAX_PWMS][5]; -+}; -+ -+/* wait till the uguru is in the specified state */ -+static int abituguru_wait(struct abituguru_data *data, u8 state) -+{ -+ int timeout = ABIT_UGURU_WAIT_TIMEOUT; -+ -+ while (inb_p(data->addr + ABIT_UGURU_DATA) != state) { -+ timeout--; -+ if (timeout == 0) -+ return -EBUSY; -+ } -+ return 0; -+} -+ -+/* Put the uguru in ready for input state */ -+static int abituguru_ready(struct abituguru_data *data) -+{ -+ int timeout = ABIT_UGURU_READY_TIMEOUT; -+ -+ if (data->uguru_ready) -+ return 0; -+ -+ /* Reset? / Prepare for next read/write cycle */ -+ outb(0x00, data->addr + ABIT_UGURU_DATA); -+ -+ /* Wait till the uguru is ready */ -+ if (abituguru_wait(data, ABIT_UGURU_STATUS_READY)) { -+ ABIT_UGURU_DEBUG(1, -+ "timeout exceeded waiting for ready state\n"); -+ return -EIO; -+ } -+ -+ /* Cmd port MUST be read now and should contain 0xAC */ -+ while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { -+ timeout--; -+ if (timeout == 0) { -+ ABIT_UGURU_DEBUG(1, -+ "CMD reg does not hold 0xAC after ready command\n"); -+ return -EIO; -+ } -+ } -+ -+ /* 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--; -+ if (timeout == 0) { -+ ABIT_UGURU_DEBUG(1, -+ "state != more input after ready command\n"); -+ return -EIO; -+ } -+ } -+ -+ data->uguru_ready = 1; -+ 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. */ -+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. */ -+ 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". */ -+ 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 */ -+ if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) { -+ if (retries) { -+ ABIT_UGURU_DEBUG(3, "timeout exceeded " -+ "waiting for more input state, %d " -+ "tries remaining\n", retries); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(ABIT_UGURU_RETRY_DELAY); -+ retries--; -+ continue; -+ } -+ if (report_errors) -+ ABIT_UGURU_DEBUG(1, "timeout exceeded " -+ "waiting for more input state " -+ "(bank: %d)\n", (int)bank_addr); -+ return -EBUSY; -+ } -+ outb(sensor_addr, data->addr + ABIT_UGURU_CMD); -+ return 0; -+ } -+} -+ -+/* 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) -+{ -+ int i; -+ -+ /* Send the address */ -+ i = abituguru_send_address(data, bank_addr, sensor_addr, retries); -+ if (i) -+ return i; -+ -+ /* And read the data */ -+ for (i = 0; i < count; i++) { -+ if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { -+ ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for " -+ "read state (bank: %d, sensor: %d)\n", -+ (int)bank_addr, (int)sensor_addr); -+ break; -+ } -+ buf[i] = inb(data->addr + ABIT_UGURU_CMD); -+ } -+ -+ /* Last put the chip back in ready state */ -+ abituguru_ready(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. */ -+static int abituguru_write(struct abituguru_data *data, -+ u8 bank_addr, u8 sensor_addr, u8 *buf, int count) -+{ -+ int i; -+ -+ /* Send the address */ -+ i = abituguru_send_address(data, bank_addr, sensor_addr, -+ ABIT_UGURU_MAX_RETRIES); -+ if (i) -+ return i; -+ -+ /* And write the data */ -+ for (i = 0; i < count; i++) { -+ if (abituguru_wait(data, ABIT_UGURU_STATUS_WRITE)) { -+ ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for " -+ "write state (bank: %d, sensor: %d)\n", -+ (int)bank_addr, (int)sensor_addr); -+ break; -+ } -+ outb(buf[i], data->addr + ABIT_UGURU_CMD); -+ } -+ -+ /* Now we need to wait till the chip is ready to be read again, -+ don't ask why */ -+ 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, -+ (int)sensor_addr); -+ return -EIO; -+ } -+ -+ /* Cmd port MUST be read now and should contain 0xAC */ -+ if (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { -+ ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after write " -+ "(bank: %d, sensor: %d)\n", (int)bank_addr, -+ (int)sensor_addr); -+ return -EIO; -+ } -+ -+ /* Last put the chip back in ready state */ -+ abituguru_ready(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. */ -+static int __devinit -+abituguru_detect_bank1_sensor_type(struct abituguru_data *data, -+ u8 sensor_addr) -+{ -+ u8 val, buf[3]; -+ int ret = ABIT_UGURU_NC; -+ -+ /* First read the sensor and the current settings */ -+ if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val, -+ 1, ABIT_UGURU_MAX_RETRIES) != 1) -+ return -EIO; -+ -+ /* Test val is sane / usable for sensor type detection. */ -+ if ((val < 10u) || (val > 240u)) { -+ printk(KERN_WARNING ABIT_UGURU_NAME -+ ": 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. */ -+ 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. If its a volt sensor this should always give us an alarm. */ -+ buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; -+ buf[1] = 245; -+ buf[2] = 250; -+ if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, -+ buf, 3) != 3) -+ return -EIO; -+ /* 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. */ -+ if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, -+ ABIT_UGURU_MAX_RETRIES) != 3) -+ return -EIO; -+ if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { -+ if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, -+ sensor_addr, buf, 3, -+ ABIT_UGURU_MAX_RETRIES) != 3) -+ return -EIO; -+ if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { -+ /* Restore original settings */ -+ if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, -+ sensor_addr, -+ data->bank1_settings[sensor_addr], -+ 3) != 3) -+ return -EIO; -+ ABIT_UGURU_DEBUG(2, " found volt sensor\n"); -+ return ABIT_UGURU_IN_SENSOR; -+ } else -+ ABIT_UGURU_DEBUG(2, " alarm raised during volt " -+ "sensor test, but volt low flag not set\n"); -+ } else -+ 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. */ -+ 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) -+ return -EIO; -+ /* 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. */ -+ if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, -+ ABIT_UGURU_MAX_RETRIES) != 3) -+ return -EIO; -+ if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { -+ if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, -+ sensor_addr, buf, 3, -+ ABIT_UGURU_MAX_RETRIES) != 3) -+ return -EIO; -+ if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) { -+ ret = ABIT_UGURU_TEMP_SENSOR; -+ ABIT_UGURU_DEBUG(2, " found temp sensor\n"); -+ } else -+ ABIT_UGURU_DEBUG(2, " alarm raised during temp " -+ "sensor test, but temp high flag not set\n"); -+ } else -+ ABIT_UGURU_DEBUG(2, " alarm not raised during temp sensor " -+ "test\n"); -+ -+ /* Restore original settings */ -+ if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, -+ data->bank1_settings[sensor_addr], 3) != 3) -+ return -EIO; -+ -+ 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. */ -+static void __devinit -+abituguru_detect_no_bank2_sensors(struct abituguru_data *data) -+{ -+ int i; -+ -+ if (fan_sensors) { -+ data->bank2_sensors = fan_sensors; -+ ABIT_UGURU_DEBUG(2, "assuming %d fan sensors because of " -+ "\"fan_sensors\" module param\n", -+ (int)data->bank2_sensors); -+ return; -+ } -+ -+ 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, at least for fan1 */ -+ if ((!i && (data->bank2_settings[i][0] & ~0xC9)) || -+ (i && (data->bank2_settings[i][0] & ~0x89))) { -+ ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " -+ "to be a fan sensor: settings[0] = %02X\n", -+ i, (unsigned int)data->bank2_settings[i][0]); -+ break; -+ } -+ -+ /* check if the threshold is within the allowed range */ -+ if (data->bank2_settings[i][1] < -+ abituguru_bank2_min_threshold) { -+ ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " -+ "to be a fan sensor: the threshold (%d) is " -+ "below the minimum (%d)\n", i, -+ (int)data->bank2_settings[i][1], -+ (int)abituguru_bank2_min_threshold); -+ break; -+ } -+ if (data->bank2_settings[i][1] > -+ abituguru_bank2_max_threshold) { -+ ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " -+ "to be a fan sensor: the threshold (%d) is " -+ "above the maximum (%d)\n", i, -+ (int)data->bank2_settings[i][1], -+ (int)abituguru_bank2_max_threshold); -+ break; -+ } -+ } -+ -+ data->bank2_sensors = i; -+ ABIT_UGURU_DEBUG(2, " found: %d fan sensors\n", -+ (int)data->bank2_sensors); -+} -+ -+static void __devinit -+abituguru_detect_no_pwms(struct abituguru_data *data) -+{ -+ int i, j; -+ -+ if (pwms) { -+ data->pwms = pwms; -+ ABIT_UGURU_DEBUG(2, "assuming %d PWM outputs because of " -+ "\"pwms\" module param\n", (int)data->pwms); -+ return; -+ } -+ -+ 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 */ -+ 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", -+ i, (unsigned int)data->pwm_settings[i][0]); -+ break; -+ } -+ -+ /* 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] == -+ (data->pwm_settings[i][0] & 0x0F)) -+ break; -+ } -+ if (j == data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) { -+ ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " -+ "to be a pwm channel: %d is not a valid temp " -+ "sensor address\n", i, -+ data->pwm_settings[i][0] & 0x0F); -+ break; -+ } -+ -+ /* check if all other settings are within the allowed range */ -+ for (j = 1; j < 5; j++) { -+ u8 min; -+ /* special case pwm1 min pwm% */ -+ if ((i == 0) && ((j == 1) || (j == 2))) -+ min = 77; -+ else -+ min = abituguru_pwm_min[j]; -+ if (data->pwm_settings[i][j] < min) { -+ ABIT_UGURU_DEBUG(2, " pwm channel %d does " -+ "not seem to be a pwm channel: " -+ "setting %d (%d) is below the minimum " -+ "value (%d)\n", i, j, -+ (int)data->pwm_settings[i][j], -+ (int)min); -+ goto abituguru_detect_no_pwms_exit; -+ } -+ if (data->pwm_settings[i][j] > abituguru_pwm_max[j]) { -+ ABIT_UGURU_DEBUG(2, " pwm channel %d does " -+ "not seem to be a pwm channel: " -+ "setting %d (%d) is above the maximum " -+ "value (%d)\n", i, j, -+ (int)data->pwm_settings[i][j], -+ (int)abituguru_pwm_max[j]); -+ goto abituguru_detect_no_pwms_exit; -+ } -+ } -+ -+ /* check that min temp < max temp and min pwm < max pwm */ -+ if (data->pwm_settings[i][1] >= data->pwm_settings[i][2]) { -+ ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " -+ "to be a pwm channel: min pwm (%d) >= " -+ "max pwm (%d)\n", i, -+ (int)data->pwm_settings[i][1], -+ (int)data->pwm_settings[i][2]); -+ break; -+ } -+ if (data->pwm_settings[i][3] >= data->pwm_settings[i][4]) { -+ ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " -+ "to be a pwm channel: min temp (%d) >= " -+ "max temp (%d)\n", i, -+ (int)data->pwm_settings[i][3], -+ (int)data->pwm_settings[i][4]); -+ break; -+ } -+ } -+ -+abituguru_detect_no_pwms_exit: -+ data->pwms = i; -+ 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. */ -+static struct abituguru_data *abituguru_update_device(struct device *dev); -+ -+static ssize_t show_bank1_value(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = abituguru_update_device(dev); -+ if (!data) -+ return -EIO; -+ return sprintf(buf, "%d\n", (data->bank1_value[attr->index] * -+ data->bank1_max_value[attr->index] + 128) / 255); -+} -+ -+static ssize_t show_bank1_setting(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ return sprintf(buf, "%d\n", -+ (data->bank1_settings[attr->index][attr->nr] * -+ data->bank1_max_value[attr->index] + 128) / 255); -+} -+ -+static ssize_t show_bank2_value(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = abituguru_update_device(dev); -+ if (!data) -+ return -EIO; -+ return sprintf(buf, "%d\n", (data->bank2_value[attr->index] * -+ ABIT_UGURU_FAN_MAX + 128) / 255); -+} -+ -+static ssize_t show_bank2_setting(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ return sprintf(buf, "%d\n", -+ (data->bank2_settings[attr->index][attr->nr] * -+ ABIT_UGURU_FAN_MAX + 128) / 255); -+} -+ -+static ssize_t store_bank1_setting(struct device *dev, struct device_attribute -+ *devattr, const char *buf, size_t count) -+{ -+ 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) / -+ data->bank1_max_value[attr->index]; -+ ssize_t ret = count; -+ -+ mutex_lock(&data->update_lock); -+ if (data->bank1_settings[attr->index][attr->nr] != val) { -+ u8 orig_val = data->bank1_settings[attr->index][attr->nr]; -+ data->bank1_settings[attr->index][attr->nr] = val; -+ if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, -+ attr->index, data->bank1_settings[attr->index], -+ 3) <= attr->nr) { -+ data->bank1_settings[attr->index][attr->nr] = orig_val; -+ ret = -EIO; -+ } -+ } -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+static ssize_t store_bank2_setting(struct device *dev, struct device_attribute -+ *devattr, const char *buf, size_t count) -+{ -+ 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; -+ -+ /* this check can be done before taking the lock */ -+ if ((val < abituguru_bank2_min_threshold) || -+ (val > abituguru_bank2_max_threshold)) -+ return -EINVAL; -+ -+ mutex_lock(&data->update_lock); -+ if (data->bank2_settings[attr->index][attr->nr] != val) { -+ u8 orig_val = data->bank2_settings[attr->index][attr->nr]; -+ data->bank2_settings[attr->index][attr->nr] = val; -+ if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK2 + 2, -+ attr->index, data->bank2_settings[attr->index], -+ 2) <= attr->nr) { -+ data->bank2_settings[attr->index][attr->nr] = orig_val; -+ ret = -EIO; -+ } -+ } -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+static ssize_t show_bank1_alarm(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ 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. */ -+ if ((data->alarms[attr->index / 8] & (0x01 << (attr->index % 8))) && -+ (data->bank1_settings[attr->index][0] & attr->nr)) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_bank2_alarm(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = abituguru_update_device(dev); -+ if (!data) -+ return -EIO; -+ if (data->alarms[2] & (0x01 << attr->index)) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_bank1_mask(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ if (data->bank1_settings[attr->index][0] & attr->nr) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t show_bank2_mask(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ if (data->bank2_settings[attr->index][0] & attr->nr) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t store_bank1_mask(struct device *dev, -+ struct device_attribute *devattr, const char *buf, size_t count) -+{ -+ 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; -+ u8 orig_val; -+ -+ mutex_lock(&data->update_lock); -+ orig_val = data->bank1_settings[attr->index][0]; -+ -+ if (mask) -+ data->bank1_settings[attr->index][0] |= attr->nr; -+ else -+ data->bank1_settings[attr->index][0] &= ~attr->nr; -+ -+ if ((data->bank1_settings[attr->index][0] != orig_val) && -+ (abituguru_write(data, -+ ABIT_UGURU_SENSOR_BANK1 + 2, attr->index, -+ data->bank1_settings[attr->index], 3) < 1)) { -+ data->bank1_settings[attr->index][0] = orig_val; -+ ret = -EIO; -+ } -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+static ssize_t store_bank2_mask(struct device *dev, -+ struct device_attribute *devattr, const char *buf, size_t count) -+{ -+ 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; -+ u8 orig_val; -+ -+ mutex_lock(&data->update_lock); -+ orig_val = data->bank2_settings[attr->index][0]; -+ -+ if (mask) -+ data->bank2_settings[attr->index][0] |= attr->nr; -+ else -+ data->bank2_settings[attr->index][0] &= ~attr->nr; -+ -+ if ((data->bank2_settings[attr->index][0] != orig_val) && -+ (abituguru_write(data, -+ ABIT_UGURU_SENSOR_BANK2 + 2, attr->index, -+ data->bank2_settings[attr->index], 2) < 1)) { -+ data->bank2_settings[attr->index][0] = orig_val; -+ ret = -EIO; -+ } -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+/* Fan PWM (speed control) */ -+static ssize_t show_pwm_setting(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ return sprintf(buf, "%d\n", data->pwm_settings[attr->index][attr->nr] * -+ abituguru_pwm_settings_multiplier[attr->nr]); -+} -+ -+static ssize_t store_pwm_setting(struct device *dev, struct device_attribute -+ *devattr, const char *buf, size_t count) -+{ -+ 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; -+ -+ /* special case pwm1 min pwm% */ -+ if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2))) -+ min = 77; -+ else -+ min = abituguru_pwm_min[attr->nr]; -+ -+ /* this check can be done before taking the lock */ -+ if ((val < min) || (val > abituguru_pwm_max[attr->nr])) -+ return -EINVAL; -+ -+ mutex_lock(&data->update_lock); -+ /* this check needs to be done after taking the lock */ -+ if ((attr->nr & 1) && -+ (val >= data->pwm_settings[attr->index][attr->nr + 1])) -+ ret = -EINVAL; -+ else if (!(attr->nr & 1) && -+ (val <= data->pwm_settings[attr->index][attr->nr - 1])) -+ ret = -EINVAL; -+ else if (data->pwm_settings[attr->index][attr->nr] != val) { -+ u8 orig_val = data->pwm_settings[attr->index][attr->nr]; -+ data->pwm_settings[attr->index][attr->nr] = val; -+ if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, -+ attr->index, data->pwm_settings[attr->index], -+ 5) <= attr->nr) { -+ data->pwm_settings[attr->index][attr->nr] = -+ orig_val; -+ ret = -EIO; -+ } -+ } -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+static ssize_t show_pwm_sensor(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ 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. */ -+ 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)) -+ return sprintf(buf, "%d\n", i+1); -+ -+ return -ENXIO; -+} -+ -+static ssize_t store_pwm_sensor(struct device *dev, struct device_attribute -+ *devattr, const char *buf, size_t count) -+{ -+ 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; -+ -+ 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; -+ } -+ } -+ } -+ else -+ ret = -EINVAL; -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+static ssize_t show_pwm_enable(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ int res = 0; -+ if (data->pwm_settings[attr->index][0] & ABIT_UGURU_FAN_PWM_ENABLE) -+ res = 2; -+ return sprintf(buf, "%d\n", res); -+} -+ -+static ssize_t store_pwm_enable(struct device *dev, struct device_attribute -+ *devattr, const char *buf, size_t count) -+{ -+ 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; -+ -+ 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; -+ } -+ if ((data->pwm_settings[attr->index][0] != orig_val) && -+ (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; -+ } -+ mutex_unlock(&data->update_lock); -+ return ret; -+} -+ -+static ssize_t show_name(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ return sprintf(buf, "%s\n", ABIT_UGURU_NAME); -+} -+ -+/* Sysfs attr templates, the real entries are generated automatically. */ -+static const -+struct sensor_device_attribute_2 abituguru_sysfs_bank1_templ[2][9] = { -+ { -+ SENSOR_ATTR_2(in%d_input, 0444, show_bank1_value, NULL, 0, 0), -+ SENSOR_ATTR_2(in%d_min, 0644, show_bank1_setting, -+ store_bank1_setting, 1, 0), -+ SENSOR_ATTR_2(in%d_min_alarm, 0444, show_bank1_alarm, NULL, -+ ABIT_UGURU_VOLT_LOW_ALARM_FLAG, 0), -+ SENSOR_ATTR_2(in%d_max, 0644, show_bank1_setting, -+ store_bank1_setting, 2, 0), -+ SENSOR_ATTR_2(in%d_max_alarm, 0444, show_bank1_alarm, NULL, -+ ABIT_UGURU_VOLT_HIGH_ALARM_FLAG, 0), -+ SENSOR_ATTR_2(in%d_beep, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0), -+ SENSOR_ATTR_2(in%d_shutdown, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), -+ SENSOR_ATTR_2(in%d_min_alarm_enable, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_VOLT_LOW_ALARM_ENABLE, 0), -+ SENSOR_ATTR_2(in%d_max_alarm_enable, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE, 0), -+ }, { -+ SENSOR_ATTR_2(temp%d_input, 0444, show_bank1_value, NULL, 0, 0), -+ SENSOR_ATTR_2(temp%d_alarm, 0444, show_bank1_alarm, NULL, -+ ABIT_UGURU_TEMP_HIGH_ALARM_FLAG, 0), -+ SENSOR_ATTR_2(temp%d_max, 0644, show_bank1_setting, -+ store_bank1_setting, 1, 0), -+ SENSOR_ATTR_2(temp%d_crit, 0644, show_bank1_setting, -+ store_bank1_setting, 2, 0), -+ SENSOR_ATTR_2(temp%d_beep, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0), -+ SENSOR_ATTR_2(temp%d_shutdown, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), -+ SENSOR_ATTR_2(temp%d_alarm_enable, 0644, show_bank1_mask, -+ store_bank1_mask, ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE, 0), -+ } -+}; -+ -+static const struct sensor_device_attribute_2 abituguru_sysfs_fan_templ[6] = { -+ SENSOR_ATTR_2(fan%d_input, 0444, show_bank2_value, NULL, 0, 0), -+ SENSOR_ATTR_2(fan%d_alarm, 0444, show_bank2_alarm, NULL, 0, 0), -+ SENSOR_ATTR_2(fan%d_min, 0644, show_bank2_setting, -+ store_bank2_setting, 1, 0), -+ SENSOR_ATTR_2(fan%d_beep, 0644, show_bank2_mask, -+ store_bank2_mask, ABIT_UGURU_BEEP_ENABLE, 0), -+ SENSOR_ATTR_2(fan%d_shutdown, 0644, show_bank2_mask, -+ store_bank2_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), -+ SENSOR_ATTR_2(fan%d_alarm_enable, 0644, show_bank2_mask, -+ store_bank2_mask, ABIT_UGURU_FAN_LOW_ALARM_ENABLE, 0), -+}; -+ -+static const struct sensor_device_attribute_2 abituguru_sysfs_pwm_templ[6] = { -+ SENSOR_ATTR_2(pwm%d_enable, 0644, show_pwm_enable, -+ store_pwm_enable, 0, 0), -+ SENSOR_ATTR_2(pwm%d_auto_channels_temp, 0644, show_pwm_sensor, -+ store_pwm_sensor, 0, 0), -+ SENSOR_ATTR_2(pwm%d_auto_point1_pwm, 0644, show_pwm_setting, -+ store_pwm_setting, 1, 0), -+ SENSOR_ATTR_2(pwm%d_auto_point2_pwm, 0644, show_pwm_setting, -+ store_pwm_setting, 2, 0), -+ SENSOR_ATTR_2(pwm%d_auto_point1_temp, 0644, show_pwm_setting, -+ store_pwm_setting, 3, 0), -+ SENSOR_ATTR_2(pwm%d_auto_point2_temp, 0644, show_pwm_setting, -+ store_pwm_setting, 4, 0), -+}; -+ -+static const struct sensor_device_attribute_2 abituguru_sysfs_attr[] = { -+ SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0), -+}; -+ -+static int __devinit abituguru_probe(struct platform_device *pdev) -+{ -+ struct abituguru_data *data; -+ int i, j, res; -+ char *sysfs_filename; -+ int sysfs_attr_i = 0; -+ -+ /* El weirdo probe order, to keep the sysfs order identical to the -+ BIOS and window-appliction listing order. */ -+ const u8 probe_order[16] = { 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))) -+ return -ENOMEM; -+ -+ data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; -+ mutex_init(&data->update_lock); -+ platform_set_drvdata(pdev, data); -+ -+ /* See if the uGuru is ready */ -+ 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. */ -+ if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, -+ data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3) { -+ kfree(data); -+ return -ENODEV; -+ } -+ -+ for (i = 0; i < 16; i++) { -+ if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, i, -+ &data->bank1_value[i], 1, -+ ABIT_UGURU_MAX_RETRIES) != 1) { -+ kfree(data); -+ return -ENODEV; -+ } -+ if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1+1, i, -+ data->bank1_settings[i], 3, -+ ABIT_UGURU_MAX_RETRIES) != 3) { -+ kfree(data); -+ return -ENODEV; -+ } -+ } -+ /* 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, -+ ABIT_UGURU_MAX_RETRIES) != 1) { -+ kfree(data); -+ return -ENODEV; -+ } -+ if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2+1, i, -+ data->bank2_settings[i], 2, -+ ABIT_UGURU_MAX_RETRIES) != 2) { -+ kfree(data); -+ return -ENODEV; -+ } -+ } -+ for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { -+ if (abituguru_read(data, ABIT_UGURU_FAN_PWM, i, -+ data->pwm_settings[i], 5, -+ ABIT_UGURU_MAX_RETRIES) != 5) { -+ kfree(data); -+ return -ENODEV; -+ } -+ } -+ data->last_updated = jiffies; -+ -+ /* Detect sensor types and fill the sysfs attr for bank1 */ -+ sysfs_filename = data->bank1_names; -+ for (i = 0; i < 16; i++) { -+ res = abituguru_detect_bank1_sensor_type(data, probe_order[i]); -+ if (res < 0) { -+ kfree(data); -+ return -ENODEV; -+ } -+ if (res == ABIT_UGURU_NC) -+ continue; -+ -+ for (j = 0; j < (res ? 7 : 9); j++) { -+ const char *name_templ = abituguru_sysfs_bank1_templ[ -+ res][j].dev_attr.attr.name; -+ data->sysfs_attr[sysfs_attr_i] = -+ abituguru_sysfs_bank1_templ[res][j]; -+ data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = -+ sysfs_filename; -+ sysfs_filename += sprintf(sysfs_filename, name_templ, -+ data->bank1_sensors[res] + res) + 1; -+ data->sysfs_attr[sysfs_attr_i].index = probe_order[i]; -+ sysfs_attr_i++; -+ } -+ data->bank1_max_value[probe_order[i]] = -+ abituguru_bank1_max_value[res]; -+ data->bank1_address[res][data->bank1_sensors[res]] = -+ probe_order[i]; -+ data->bank1_sensors[res]++; -+ } -+ /* Detect number of sensors and fill the sysfs attr for bank2 (fans) */ -+ abituguru_detect_no_bank2_sensors(data); -+ for (i = 0; i < data->bank2_sensors; i++) { -+ for (j = 0; j < 6; j++) { -+ const char *name_templ = abituguru_sysfs_fan_templ[j]. -+ dev_attr.attr.name; -+ data->sysfs_attr[sysfs_attr_i] = -+ abituguru_sysfs_fan_templ[j]; -+ data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = -+ sysfs_filename; -+ sysfs_filename += sprintf(sysfs_filename, name_templ, -+ i + 1) + 1; -+ data->sysfs_attr[sysfs_attr_i].index = i; -+ sysfs_attr_i++; -+ } -+ } -+ /* Detect number of sensors and fill the sysfs attr for pwms */ -+ abituguru_detect_no_pwms(data); -+ for (i = 0; i < data->pwms; i++) { -+ for (j = 0; j < 6; j++) { -+ const char *name_templ = abituguru_sysfs_pwm_templ[j]. -+ dev_attr.attr.name; -+ data->sysfs_attr[sysfs_attr_i] = -+ abituguru_sysfs_pwm_templ[j]; -+ data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = -+ sysfs_filename; -+ sysfs_filename += sprintf(sysfs_filename, name_templ, -+ i + 1) + 1; -+ data->sysfs_attr[sysfs_attr_i].index = i; -+ sysfs_attr_i++; -+ } -+ } -+ /* Last add any "generic" entries to sysfs */ -+ for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) { -+ data->sysfs_attr[sysfs_attr_i] = abituguru_sysfs_attr[i]; -+ sysfs_attr_i++; -+ } -+ printk(KERN_INFO ABIT_UGURU_NAME ": found Abit uGuru\n"); -+ -+ /* Register sysfs hooks */ -+ data->class_dev = hwmon_device_register(&pdev->dev); -+ if (IS_ERR(data->class_dev)) { -+ kfree(data); -+ return PTR_ERR(data->class_dev); -+ } -+ for (i = 0; i < sysfs_attr_i; i++) -+ device_create_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); -+ -+ return 0; -+} -+ -+static int __devexit abituguru_remove(struct platform_device *pdev) -+{ -+ struct abituguru_data *data = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ hwmon_device_unregister(data->class_dev); -+ kfree(data); -+ -+ return 0; -+} -+ -+static struct abituguru_data *abituguru_update_device(struct device *dev) -+{ -+ int i, err; -+ struct abituguru_data *data = dev_get_drvdata(dev); -+ /* fake a complete successful read if no update necessary. */ -+ char success = 1; -+ -+ 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) -+ goto LEAVE_UPDATE; -+ for (i = 0; i < 16; i++) { -+ if ((err = abituguru_read(data, -+ ABIT_UGURU_SENSOR_BANK1, i, -+ &data->bank1_value[i], 1, 0)) != 1) -+ goto LEAVE_UPDATE; -+ if ((err = abituguru_read(data, -+ ABIT_UGURU_SENSOR_BANK1 + 1, i, -+ data->bank1_settings[i], 3, 0)) != 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) -+ goto LEAVE_UPDATE; -+ /* success! */ -+ success = 1; -+ data->update_timeouts = 0; -+LEAVE_UPDATE: -+ /* handle timeout condition */ -+ if (err == -EBUSY) { -+ /* No overflow please */ -+ if (data->update_timeouts < 255u) -+ data->update_timeouts++; -+ if (data->update_timeouts <= ABIT_UGURU_MAX_TIMEOUTS) { -+ ABIT_UGURU_DEBUG(3, "timeout exceeded, will " -+ "try again next update\n"); -+ /* Just a timeout, fake a successful read */ -+ success = 1; -+ } else -+ ABIT_UGURU_DEBUG(1, "timeout exceeded %d " -+ "times waiting for more input state\n", -+ (int)data->update_timeouts); -+ } -+ /* On success set last_updated */ -+ if (success) -+ data->last_updated = jiffies; -+ } -+ mutex_unlock(&data->update_lock); -+ -+ if (success) -+ return data; -+ else -+ return NULL; -+} -+ -+static struct platform_driver abituguru_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = ABIT_UGURU_NAME, -+ }, -+ .probe = abituguru_probe, -+ .remove = __devexit_p(abituguru_remove), -+}; -+ -+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 initally 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)) && -+ ((cmd_val == 0x00) || (cmd_val == 0xAC))) -+ return ABIT_UGURU_BASE; -+ -+ ABIT_UGURU_DEBUG(2, "no Abit uGuru found, data = 0x%02X, cmd = " -+ "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); -+ -+ if (force) { -+ printk(KERN_INFO ABIT_UGURU_NAME ": Assuming Abit uGuru is " -+ "present because of \"force\" parameter\n"); -+ return ABIT_UGURU_BASE; -+ } -+ -+ /* No uGuru found */ -+ return -ENODEV; -+} -+ -+static struct platform_device *abituguru_pdev; -+ -+static int __init abituguru_init(void) -+{ -+ int address, err; -+ struct resource res = { .flags = IORESOURCE_IO }; -+ -+ address = abituguru_detect(); -+ if (address < 0) -+ return address; -+ -+ err = platform_driver_register(&abituguru_driver); -+ if (err) -+ goto exit; -+ -+ abituguru_pdev = platform_device_alloc(ABIT_UGURU_NAME, address); -+ if (!abituguru_pdev) { -+ printk(KERN_ERR ABIT_UGURU_NAME -+ ": Device allocation failed\n"); -+ err = -ENOMEM; -+ goto exit_driver_unregister; -+ } -+ -+ res.start = address; -+ res.end = address + ABIT_UGURU_REGION_LENGTH - 1; -+ res.name = ABIT_UGURU_NAME; -+ -+ err = platform_device_add_resources(abituguru_pdev, &res, 1); -+ if (err) { -+ printk(KERN_ERR ABIT_UGURU_NAME -+ ": Device resource addition failed (%d)\n", err); -+ goto exit_device_put; -+ } -+ -+ err = platform_device_add(abituguru_pdev); -+ if (err) { -+ printk(KERN_ERR ABIT_UGURU_NAME -+ ": Device addition failed (%d)\n", err); -+ goto exit_device_put; -+ } -+ -+ return 0; -+ -+exit_device_put: -+ platform_device_put(abituguru_pdev); -+exit_driver_unregister: -+ platform_driver_unregister(&abituguru_driver); -+exit: -+ return err; -+} -+ -+static void __exit abituguru_exit(void) -+{ -+ platform_device_unregister(abituguru_pdev); -+ platform_driver_unregister(&abituguru_driver); -+} -+ -+MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); -+MODULE_DESCRIPTION("Abit uGuru Sensor device"); -+MODULE_LICENSE("GPL"); -+ -+module_init(abituguru_init); -+module_exit(abituguru_exit); diff --git a/i2c/hwmon-abituguru-nofans-detect-fix.patch b/i2c/hwmon-abituguru-nofans-detect-fix.patch deleted file mode 100644 index 0953a2fe07a45a..00000000000000 --- a/i2c/hwmon-abituguru-nofans-detect-fix.patch +++ /dev/null @@ -1,39 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:24:17 2006 -Date: Sun, 4 Jun 2006 20:24:11 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: abituguru: Fix fan detection -Message-Id: <20060604202411.59d7dd3f.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-abituguru-nofans-detect-fix.patch - -From: Hans de Goede <j.w.r.degoede@hhs.nl> - -One of my testers had a problem where the driver only saw 2 of the 4 fan -sensors his uGuru has, this fixes this. - -accept 0x40 (bit 6) being high as a valid fan sensor setting for all fans - not just fan 1, I have a feeling this bit indicates whether or not a fan is - actually connected . - -Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/abituguru.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/abituguru.c -+++ gregkh-2.6/drivers/hwmon/abituguru.c -@@ -529,9 +529,8 @@ abituguru_detect_no_bank2_sensors(struct - -0x08 enable beep - -0x01 enable alarm - All other bits should be 0, but on some motherboards -- 0x40 (bit 6) is also high, at least for fan1 */ -- if ((!i && (data->bank2_settings[i][0] & ~0xC9)) || -- (i && (data->bank2_settings[i][0] & ~0x89))) { -+ 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", - i, (unsigned int)data->bank2_settings[i][0]); diff --git a/i2c/hwmon-f71805f-no-global-resource.patch b/i2c/hwmon-f71805f-no-global-resource.patch deleted file mode 100644 index 0a17ed3c952404..00000000000000 --- a/i2c/hwmon-f71805f-no-global-resource.patch +++ /dev/null @@ -1,56 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:39:52 2006 -Date: Thu, 23 Mar 2006 16:40:23 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: [PATCH 06/10] f71805f: Resource needs not be global -Message-Id: <20060323164023.f5380bf9.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-f71805f-no-global-resource.patch - -The F71805F I/O resource structure needs not be a global variable, -as the platform core allocs its own copy of it anyway. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/f71805f.c | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/f71805f.c -+++ gregkh-2.6/drivers/hwmon/f71805f.c -@@ -99,10 +99,6 @@ superio_exit(int base) - #define ADDR_REG_OFFSET 0 - #define DATA_REG_OFFSET 1 - --static struct resource f71805f_resource __initdata = { -- .flags = IORESOURCE_IO, --}; -- - /* - * Registers - */ -@@ -782,6 +778,11 @@ static struct platform_driver f71805f_dr - - static int __init f71805f_device_add(unsigned short address) - { -+ struct resource res = { -+ .start = address, -+ .end = address + REGION_LENGTH - 1, -+ .flags = IORESOURCE_IO, -+ }; - int err; - - pdev = platform_device_alloc(DRVNAME, address); -@@ -791,10 +792,8 @@ static int __init f71805f_device_add(uns - goto exit; - } - -- f71805f_resource.start = address; -- f71805f_resource.end = address + REGION_LENGTH - 1; -- f71805f_resource.name = pdev->name; -- err = platform_device_add_resources(pdev, &f71805f_resource, 1); -+ res.name = pdev->name; -+ err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR DRVNAME ": Device resource addition failed " - "(%d)\n", err); diff --git a/i2c/hwmon-hdaps-typo.patch b/i2c/hwmon-hdaps-typo.patch deleted file mode 100644 index 1701ce413f1124..00000000000000 --- a/i2c/hwmon-hdaps-typo.patch +++ /dev/null @@ -1,30 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:10:57 2006 -Date: Sun, 4 Jun 2006 20:10:55 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Robert Love <rlove@rlove.org> -Subject: hwmon: Fix a typo in the hdaps driver -Message-Id: <20060604201055.93571684.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-hdaps-typo.patch - -Fix a typo in the hdaps driver. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Acked-by: Robert Love <rml@novell.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/hdaps.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/drivers/hwmon/hdaps.c -+++ gregkh-2.6/drivers/hwmon/hdaps.c -@@ -41,7 +41,7 @@ - #define HDAPS_PORT_STATE 0x1611 /* device state */ - #define HDAPS_PORT_YPOS 0x1612 /* y-axis position */ - #define HDAPS_PORT_XPOS 0x1614 /* x-axis position */ --#define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in celcius */ -+#define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in Celsius */ - #define HDAPS_PORT_YVAR 0x1617 /* y-axis variance (what is this?) */ - #define HDAPS_PORT_XVAR 0x1619 /* x-axis variance (what is this?) */ - #define HDAPS_PORT_TEMP2 0x161b /* device temperature (again?) */ diff --git a/i2c/hwmon-hdaps-update-id-list.patch b/i2c/hwmon-hdaps-update-id-list.patch deleted file mode 100644 index 7c9ba948d06d8c..00000000000000 --- a/i2c/hwmon-hdaps-update-id-list.patch +++ /dev/null @@ -1,55 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 05:20:08 2006 -Date: Tue, 25 Apr 2006 14:20:11 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Arkadiusz Miskiewicz <arekm@maven.pl>, Frank Gevaerts <frank@gevaerts.be> -Subject: HWMON: hdaps: Update the list of supported systems -Message-Id: <20060425142011.6dbc8a14.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-hdaps-update-id-list.patch - -Update the list of systems supported by the hdaps driver: -* Add the "ThinkPad Z60m" entry, reported by Arkadiusz Miskiewicz. -* Add the "ThinkPad H" entry, reported by Frank Gevaerts for some - ThinkPad R52 models (1846AQG). -* Drop the "ThinkPad X41 Tablet" entry, which looks redundant to me. -And a comment update for good measure. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Cc: Arkadiusz Miskiewicz <arekm@maven.pl> -Cc: Frank Gevaerts <frank@gevaerts.be> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/hdaps.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/hdaps.c -+++ gregkh-2.6/drivers/hwmon/hdaps.c -@@ -522,13 +522,15 @@ static int __init hdaps_init(void) - { - int ret; - -- /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ -+ /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match -+ "ThinkPad T42p", so the order of the entries matters */ - struct dmi_system_id hdaps_whitelist[] = { - HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), - HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"), -+ HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), /* R52 (1846AQG) */ - HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), - HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), -@@ -536,9 +538,9 @@ static int __init hdaps_init(void) - HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), - HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), -- HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), - HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), - HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"), -+ HDAPS_DMI_MATCH_NORMAL("ThinkPad Z60m"), - { .ident = NULL } - }; - diff --git a/i2c/hwmon-improve-Kconfig-help.patch b/i2c/hwmon-improve-Kconfig-help.patch deleted file mode 100644 index 8849b4917aa9cc..00000000000000 --- a/i2c/hwmon-improve-Kconfig-help.patch +++ /dev/null @@ -1,78 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 05:23:01 2006 -Date: Tue, 25 Apr 2006 14:23:01 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: HWMON: Improve the help text for CONFIG_HWMON -Message-Id: <20060425142301.1981401b.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-improve-Kconfig-help.patch - -Improve the help text for CONFIG_HWMON to let the users know how they -pick the right hardware monitoring driver(s) for their system. - -Also fix a couple typos in the related documentation file and improve -some parts a bit. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/userspace-tools | 17 +++++++++-------- - drivers/hwmon/Kconfig | 4 ++++ - 2 files changed, 13 insertions(+), 8 deletions(-) - ---- gregkh-2.6.orig/Documentation/hwmon/userspace-tools -+++ gregkh-2.6/Documentation/hwmon/userspace-tools -@@ -6,31 +6,32 @@ voltages, fans speed). They are often co - are also connected directly through the ISA bus. - - The kernel drivers make the data from the sensor chips available in the /sys --virtual filesystem. Userspace tools are then used to display or set or the --data in a more friendly manner. -+virtual filesystem. Userspace tools are then used to display the measured -+values or configure the chips in a more friendly manner. - - Lm-sensors - ---------- - --Core set of utilites that will allow you to obtain health information, -+Core set of utilities that will allow you to obtain health information, - setup monitoring limits etc. You can get them on their homepage - http://www.lm-sensors.nu/ or as a package from your Linux distribution. - - If from website: --Get lmsensors from project web site. Please note, you need only userspace --part, so compile with "make user_install" target. -+Get lm-sensors from project web site. Please note, you need only userspace -+part, so compile with "make user" and install with "make user_install". - - General hints to get things working: - - 0) get lm-sensors userspace utils --1) compile all drivers in I2C section as modules in your kernel -+1) compile all drivers in I2C and Hardware Monitoring sections as modules -+ in your kernel - 2) run sensors-detect script, it will tell you what modules you need to load. - 3) load them and run "sensors" command, you should see some results. - 4) fix sensors.conf, labels, limits, fan divisors - 5) if any more problems consult FAQ, or documentation - --Other utilites ---------------- -+Other utilities -+--------------- - - If you want some graphical indicators of system health look for applications - like: gkrellm, ksensors, xsensors, wmtemp, wmsensors, wmgtemp, ksysguardd, ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -16,6 +16,10 @@ config HWMON - should say Y here and also to the specific driver(s) for your - sensors chip(s) below. - -+ To find out which specific driver(s) you need, use the -+ sensors-detect script from the lm_sensors package. Read -+ <file:Documentation/hwmon/userspace-tools> for details. -+ - This support can also be built as a module. If so, the module - will be called hwmon. - diff --git a/i2c/hwmon-kconfig-header-fix.patch b/i2c/hwmon-kconfig-header-fix.patch deleted file mode 100644 index d43bb98672e489..00000000000000 --- a/i2c/hwmon-kconfig-header-fix.patch +++ /dev/null @@ -1,27 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:55:28 2006 -Date: Mon, 12 Jun 2006 21:55:28 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Kaiwan N Billimoria <kaiwan@designergraphix.com> -Subject: [PATCH 12/14] hwmon: Fix the Kconfig header -Message-Id: <20060612215528.e72133d5.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-kconfig-header-fix.patch - -Hardware monitoring chips don't have to be on the I2C bus. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -1,5 +1,5 @@ - # --# I2C Sensor chip drivers configuration -+# Hardware monitoring chip drivers configuration - # - - menu "Hardware Monitoring support" diff --git a/i2c/hwmon-lm70-new-driver.patch b/i2c/hwmon-lm70-new-driver.patch deleted file mode 100644 index b4c6478cd80bf4..00000000000000 --- a/i2c/hwmon-lm70-new-driver.patch +++ /dev/null @@ -1,267 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 13:00:12 2006 -Date: Mon, 12 Jun 2006 22:00:05 +0200 -From: Kaiwan N Billimoria <kaiwan@designergraphix.com> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Kaiwan N Billimoria <kaiwan@designergraphix.com> -Subject: [PATCH 13/14] lm70: New hardware monitoring driver -Message-Id: <20060612220005.cd9ce8ad.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-lm70-new-driver.patch - -From: Kaiwan N Billimoria <kaiwan@designergraphix.com> - -This driver implements support for the National Semiconductor LM70 -temperature sensor. - -The LM70 temperature sensor chip supports a single temperature sensor. -It communicates with a host processor (or microcontroller) via an -SPI/Microwire Bus interface. - -Communication with the LM70 is simple: when the temperature is to be sensed, -the driver accesses the LM70 using SPI communication: 16 SCLK cycles -comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's -complement digital temperature (sent via the SIO line), is available in the -driver for interpretation. This driver makes use of the kernel's in-core -SPI support. - -Signed-off-by: Kaiwan N Billimoria <kaiwan@designergraphix.com> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/lm70 | 31 ++++++++ - drivers/hwmon/Kconfig | 10 ++ - drivers/hwmon/Makefile | 1 - drivers/hwmon/lm70.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 207 insertions(+) - ---- /dev/null -+++ gregkh-2.6/Documentation/hwmon/lm70 -@@ -0,0 +1,31 @@ -+Kernel driver lm70 -+================== -+ -+Supported chip: -+ * National Semiconductor LM70 -+ Datasheet: http://www.national.com/pf/LM/LM70.html -+ -+Author: -+ Kaiwan N Billimoria <kaiwan@designergraphix.com> -+ -+Description -+----------- -+ -+This driver implements support for the National Semiconductor LM70 -+temperature sensor. -+ -+The LM70 temperature sensor chip supports a single temperature sensor. -+It communicates with a host processor (or microcontroller) via an -+SPI/Microwire Bus interface. -+ -+Communication with the LM70 is simple: when the temperature is to be sensed, -+the driver accesses the LM70 using SPI communication: 16 SCLK cycles -+comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's -+complement digital temperature (sent via the SIO line), is available in the -+driver for interpretation. This driver makes use of the kernel's in-core -+SPI support. -+ -+Thanks to -+--------- -+Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver -+development. ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -204,6 +204,16 @@ config SENSORS_LM63 - This driver can also be built as a module. If so, the module - will be called lm63. - -+config SENSORS_LM70 -+ tristate "National Semiconductor LM70" -+ depends on HWMON && SPI_MASTER && EXPERIMENTAL -+ help -+ If you say yes here you get support for the National Semiconductor -+ LM70 digital temperature sensor chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called lm70. -+ - config SENSORS_LM75 - tristate "National Semiconductor LM75 and compatibles" - depends on HWMON && I2C ---- gregkh-2.6.orig/drivers/hwmon/Makefile -+++ gregkh-2.6/drivers/hwmon/Makefile -@@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm - obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o - obj-$(CONFIG_SENSORS_IT87) += it87.o - obj-$(CONFIG_SENSORS_LM63) += lm63.o -+obj-$(CONFIG_SENSORS_LM70) += lm70.o - obj-$(CONFIG_SENSORS_LM75) += lm75.o - obj-$(CONFIG_SENSORS_LM77) += lm77.o - obj-$(CONFIG_SENSORS_LM78) += lm78.o ---- /dev/null -+++ gregkh-2.6/drivers/hwmon/lm70.c -@@ -0,0 +1,165 @@ -+/* -+ * lm70.c -+ * -+ * The LM70 is a temperature sensor chip from National Semiconductor (NS). -+ * Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com> -+ * -+ * The LM70 communicates with a host processor via an SPI/Microwire Bus -+ * interface. The complete datasheet is available at National's website -+ * here: -+ * http://www.national.com/pf/LM/LM70.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/init.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/device.h> -+#include <linux/err.h> -+#include <linux/sysfs.h> -+#include <linux/hwmon.h> -+#include <linux/spi/spi.h> -+#include <asm/semaphore.h> -+ -+#define DRVNAME "lm70" -+ -+struct lm70 { -+ struct class_device *cdev; -+ struct semaphore sem; -+}; -+ -+/* sysfs hook function */ -+static ssize_t lm70_sense_temp(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct spi_device *spi = to_spi_device(dev); -+ int status, val; -+ u8 rxbuf[2]; -+ s16 raw=0; -+ struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); -+ -+ if (down_interruptible(&p_lm70->sem)) -+ return -ERESTARTSYS; -+ -+ /* -+ * spi_read() requires a DMA-safe buffer; so we use -+ * spi_write_then_read(), transmitting 0 bytes. -+ */ -+ status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2); -+ if (status < 0) { -+ printk(KERN_WARNING -+ "spi_write_then_read failed with status %d\n", status); -+ goto out; -+ } -+ dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]); -+ -+ raw = (rxbuf[1] << 8) + rxbuf[0]; -+ dev_dbg(dev, "raw=0x%x\n", raw); -+ -+ /* -+ * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's -+ * complement value. Only the MSB 11 bits (1 sign + 10 temperature -+ * bits) are meaningful; the LSB 5 bits are to be discarded. -+ * See the datasheet. -+ * -+ * Further, each bit represents 0.25 degrees Celsius; so, multiply -+ * by 0.25. Also multiply by 1000 to represent in millidegrees -+ * Celsius. -+ * So it's equivalent to multiplying by 0.25 * 1000 = 250. -+ */ -+ val = ((int)raw/32) * 250; -+ status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */ -+out: -+ up(&p_lm70->sem); -+ return status; -+} -+ -+static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); -+ -+/*----------------------------------------------------------------------*/ -+ -+static int __devinit lm70_probe(struct spi_device *spi) -+{ -+ struct lm70 *p_lm70; -+ int status; -+ -+ p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); -+ if (!p_lm70) -+ return -ENOMEM; -+ -+ init_MUTEX(&p_lm70->sem); -+ -+ /* sysfs hook */ -+ p_lm70->cdev = hwmon_device_register(&spi->dev); -+ if (IS_ERR(p_lm70->cdev)) { -+ dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); -+ status = PTR_ERR(p_lm70->cdev); -+ goto out_dev_reg_failed; -+ } -+ dev_set_drvdata(&spi->dev, p_lm70); -+ -+ if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) { -+ dev_dbg(&spi->dev, "device_create_file failure.\n"); -+ goto out_dev_create_file_failed; -+ } -+ -+ return 0; -+ -+out_dev_create_file_failed: -+ hwmon_device_unregister(p_lm70->cdev); -+out_dev_reg_failed: -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(p_lm70); -+ return status; -+} -+ -+static int __exit lm70_remove(struct spi_device *spi) -+{ -+ struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); -+ -+ device_remove_file(&spi->dev, &dev_attr_temp1_input); -+ hwmon_device_unregister(p_lm70->cdev); -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(p_lm70); -+ -+ return 0; -+} -+ -+static struct spi_driver lm70_driver = { -+ .driver = { -+ .name = "lm70", -+ .owner = THIS_MODULE, -+ }, -+ .probe = lm70_probe, -+ .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_AUTHOR("Kaiwan N Billimoria"); -+MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver"); -+MODULE_LICENSE("GPL"); diff --git a/i2c/hwmon-lm83-add-lm82-support.patch b/i2c/hwmon-lm83-add-lm82-support.patch deleted file mode 100644 index 765d97137985b9..00000000000000 --- a/i2c/hwmon-lm83-add-lm82-support.patch +++ /dev/null @@ -1,180 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:19:16 2006 -Date: Thu, 23 Mar 2006 16:19:49 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Jordan Crouse <jordan.crouse@amd.com> -Subject: [PATCH 01/10] lm83: Add LM82 support -Message-Id: <20060323161949.e6dd074b.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-lm83-add-lm82-support.patch - -From: Jordan Crouse <jordan.crouse@amd.com> - -Add LM82 temperature sensor support (similar to the LM83, -but less featureful). - -Signed-off-by: Jordan Crouse <jordan.crouse@amd.com> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/lm83 | 16 +++++++++++---- - drivers/hwmon/Kconfig | 4 +-- - drivers/hwmon/lm83.c | 50 ++++++++++++++++++++++++++++++++++------------- - 3 files changed, 51 insertions(+), 19 deletions(-) - ---- gregkh-2.6.orig/Documentation/hwmon/lm83 -+++ gregkh-2.6/Documentation/hwmon/lm83 -@@ -7,6 +7,10 @@ Supported chips: - Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e - Datasheet: Publicly available at the National Semiconductor website - http://www.national.com/pf/LM/LM83.html -+ * National Semiconductor LM82 -+ Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e -+ Datasheet: Publicly available at the National Semiconductor website -+ http://www.national.com/pf/LM/LM82.html - - - Author: Jean Delvare <khali@linux-fr.org> -@@ -15,10 +19,11 @@ Description - ----------- - - The LM83 is a digital temperature sensor. It senses its own temperature as --well as the temperature of up to three external diodes. It is compatible --with many other devices such as the LM84 and all other ADM1021 clones. --The main difference between the LM83 and the LM84 in that the later can --only sense the temperature of one external diode. -+well as the temperature of up to three external diodes. The LM82 is -+a stripped down version of the LM83 that only supports one external diode. -+Both are compatible with many other devices such as the LM84 and all -+other ADM1021 clones. The main difference between the LM83 and the LM84 -+in that the later can only sense the temperature of one external diode. - - Using the adm1021 driver for a LM83 should work, but only two temperatures - will be reported instead of four. -@@ -36,6 +41,9 @@ Unconfirmed motherboards: - Iwill MPX2 - Soltek SL-75DRV5 - -+The LM82 is confirmed to have been found on most AMD Geode reference -+designs and test platforms. -+ - The driver has been successfully tested by Magnus Forsström, who I'd - like to thank here. More testers will be of course welcome. - ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -236,11 +236,11 @@ config SENSORS_LM80 - will be called lm80. - - config SENSORS_LM83 -- tristate "National Semiconductor LM83" -+ tristate "National Semiconductor LM83 and compatibles" - depends on HWMON && I2C - help - If you say yes here you get support for National Semiconductor -- LM83 sensor chips. -+ LM82 and LM83 sensor chips. - - This driver can also be built as a module. If so, the module - will be called lm83. ---- gregkh-2.6.orig/drivers/hwmon/lm83.c -+++ gregkh-2.6/drivers/hwmon/lm83.c -@@ -12,6 +12,10 @@ - * Since the datasheet omits to give the chip stepping code, I give it - * here: 0x03 (at register 0xff). - * -+ * Also supports the LM82 temp sensor, which is basically a stripped down -+ * model of the LM83. Datasheet is here: -+ * http://www.national.com/pf/LM/LM82.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 -@@ -52,7 +56,7 @@ static unsigned short normal_i2c[] = { 0 - * Insmod parameters - */ - --I2C_CLIENT_INSMOD_1(lm83); -+I2C_CLIENT_INSMOD_2(lm83, lm82); - - /* - * The LM83 registers -@@ -283,6 +287,9 @@ static int lm83_detect(struct i2c_adapte - if (man_id == 0x01) { /* National Semiconductor */ - if (chip_id == 0x03) { - kind = lm83; -+ } else -+ if (chip_id == 0x01) { -+ kind = lm82; - } - } - -@@ -296,6 +303,9 @@ static int lm83_detect(struct i2c_adapte - - if (kind == lm83) { - name = "lm83"; -+ } else -+ if (kind == lm82) { -+ name = "lm82"; - } - - /* We can fill in the remaining client fields */ -@@ -319,32 +329,46 @@ static int lm83_detect(struct i2c_adapte - goto exit_detach; - } - -+ /* -+ * The LM82 can only monitor one external diode which is -+ * at the same register as the LM83 temp3 entry - so we -+ * declare 1 and 3 common, and then 2 and 4 only for the LM83. -+ */ -+ - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, -- &sensor_dev_attr_temp2_input.dev_attr); -- device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_input.dev_attr); -- device_create_file(&new_client->dev, -- &sensor_dev_attr_temp4_input.dev_attr); -+ - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, -- &sensor_dev_attr_temp2_max.dev_attr); -- device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_max.dev_attr); -- device_create_file(&new_client->dev, -- &sensor_dev_attr_temp4_max.dev_attr); -+ - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_crit.dev_attr); - device_create_file(&new_client->dev, -- &sensor_dev_attr_temp2_crit.dev_attr); -- device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_crit.dev_attr); -- device_create_file(&new_client->dev, -- &sensor_dev_attr_temp4_crit.dev_attr); -+ - device_create_file(&new_client->dev, &dev_attr_alarms); - -+ if (kind == lm83) { -+ device_create_file(&new_client->dev, -+ &sensor_dev_attr_temp2_input.dev_attr); -+ device_create_file(&new_client->dev, -+ &sensor_dev_attr_temp4_input.dev_attr); -+ -+ device_create_file(&new_client->dev, -+ &sensor_dev_attr_temp2_max.dev_attr); -+ device_create_file(&new_client->dev, -+ &sensor_dev_attr_temp4_max.dev_attr); -+ -+ device_create_file(&new_client->dev, -+ &sensor_dev_attr_temp2_crit.dev_attr); -+ device_create_file(&new_client->dev, -+ &sensor_dev_attr_temp4_crit.dev_attr); -+ } -+ - return 0; - - exit_detach: diff --git a/i2c/hwmon-lm83-documentation-update.patch b/i2c/hwmon-lm83-documentation-update.patch deleted file mode 100644 index c2f638ff1c9d34..00000000000000 --- a/i2c/hwmon-lm83-documentation-update.patch +++ /dev/null @@ -1,28 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 05:22:12 2006 -Date: Tue, 25 Apr 2006 14:22:14 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: HWMON: lm83: Documentation update -Message-Id: <20060425142214.1ff4b7b2.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-lm83-documentation-update.patch - -One more motherboard confirmed to have an LM83 temperature sensor chip. -Thanks to Steven Hardy for reporting. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/lm83 | 1 + - 1 file changed, 1 insertion(+) - ---- gregkh-2.6.orig/Documentation/hwmon/lm83 -+++ gregkh-2.6/Documentation/hwmon/lm83 -@@ -35,6 +35,7 @@ contact us. Note that the LM90 can easil - - Confirmed motherboards: - SBS P014 -+ SBS PSL09 - - Unconfirmed motherboards: - Gigabyte GA-8IK1100 diff --git a/i2c/hwmon-maintenance-update.patch b/i2c/hwmon-maintenance-update.patch deleted file mode 100644 index 6a245b64994d1a..00000000000000 --- a/i2c/hwmon-maintenance-update.patch +++ /dev/null @@ -1,47 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:13:04 2006 -Date: Sun, 4 Jun 2006 20:13:01 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: hwmon: Drop some maintainers entries -Message-Id: <20060604201301.0bc5da17.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-maintenance-update.patch - -I no more wish to be listed as the maintainer for the smsc47m1 and -w83l785ts drivers. I have no test device, and people will fallback -to me as the general hardware monitoring maintainer anyway. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - MAINTAINERS | 12 ------------ - 1 file changed, 12 deletions(-) - ---- gregkh-2.6.orig/MAINTAINERS -+++ gregkh-2.6/MAINTAINERS -@@ -2528,12 +2528,6 @@ M: thomas@winischhofer.net - W: http://www.winischhofer.at/linuxsisusbvga.shtml - S: Maintained - --SMSC47M1 HARDWARE MONITOR DRIVER --P: Jean Delvare --M: khali@linux-fr.org --L: lm-sensors@lm-sensors.org --S: Odd Fixes -- - SMB FILESYSTEM - P: Urban Widmark - M: urban@teststation.com -@@ -3146,12 +3140,6 @@ L: wbsd-devel@list.drzeus.cx - W: http://projects.drzeus.cx/wbsd - S: Maintained - --W83L785TS HARDWARE MONITOR DRIVER --P: Jean Delvare --M: khali@linux-fr.org --L: lm-sensors@lm-sensors.org --S: Odd Fixes -- - WATCHDOG DEVICE DRIVERS - P: Wim Van Sebroeck - M: wim@iguana.be diff --git a/i2c/hwmon-smsc47m192-new-driver.patch b/i2c/hwmon-smsc47m192-new-driver.patch deleted file mode 100644 index 9f5b8811ea3a57..00000000000000 --- a/i2c/hwmon-smsc47m192-new-driver.patch +++ /dev/null @@ -1,843 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:36:55 2006 -Date: Thu, 23 Mar 2006 16:37:23 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Hartmut Rick <linux@rick.claranet.de> -Subject: [PATCH 04/10] smsc47m192: New hwmon driver for SMSC LPC47M192/997 -Message-Id: <20060323163723.46c3c92b.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-smsc47m192-new-driver.patch - -From: Hartmut Rick <linux@rick.claranet.de> - -New driver (smsc47m192) which supports voltage and temperature -measurement features of SMSC LPC47M192 and LPC47M997 chips. - -Signed-off-by: Hartmut Rick <linux@rick.claranet.de> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/smsc47m192 | 102 +++++ - Documentation/hwmon/sysfs-interface | 6 - drivers/hwmon/Kconfig | 23 + - drivers/hwmon/Makefile | 1 - drivers/hwmon/smsc47m192.c | 648 ++++++++++++++++++++++++++++++++++++ - 5 files changed, 779 insertions(+), 1 deletion(-) - ---- /dev/null -+++ gregkh-2.6/Documentation/hwmon/smsc47m192 -@@ -0,0 +1,102 @@ -+Kernel driver smsc47m192 -+======================== -+ -+Supported chips: -+ * SMSC LPC47M192 and LPC47M997 -+ Prefix: 'smsc47m192' -+ Addresses scanned: I2C 0x2c - 0x2d -+ Datasheet: The datasheet for LPC47M192 is publicly available from -+ http://www.smsc.com/ -+ The LPC47M997 is compatible for hardware monitoring. -+ -+Author: Hartmut Rick <linux@rick.claranet.de> -+ Special thanks to Jean Delvare for careful checking -+ of the code and many helpful comments and suggestions. -+ -+ -+Description -+----------- -+ -+This driver implements support for the hardware sensor capabilities -+of the SMSC LPC47M192 and LPC47M997 Super-I/O chips. -+ -+These chips support 3 temperature channels and 8 voltage inputs -+as well as CPU voltage VID input. -+ -+They do also have fan monitoring and control capabilities, but the -+these features are accessed via ISA bus and are not supported by this -+driver. Use the 'smsc47m1' driver for fan monitoring and control. -+ -+Voltages and temperatures are measured by an 8-bit ADC, the resolution -+of the temperatures is 1 bit per degree C. -+Voltages are scaled such that the nominal voltage corresponds to -+192 counts, i.e. 3/4 of the full range. Thus the available range for -+each voltage channel is 0V ... 255/192*(nominal voltage), the resolution -+is 1 bit per (nominal voltage)/192. -+Both voltage and temperature values are scaled by 1000, the sys files -+show voltages in mV and temperatures in units of 0.001 degC. -+ -+The +12V analog voltage input channel (in4_input) is multiplexed with -+bit 4 of the encoded CPU voltage. This means that you either get -+a +12V voltage measurement or a 5 bit CPU VID, but not both. -+The default setting is to use the pin as 12V input, and use only 4 bit VID. -+This driver assumes that the information in the configuration register -+is correct, i.e. that the BIOS has updated the configuration if -+the motherboard has this input wired to VID4. -+ -+The temperature and voltage readings are updated once every 1.5 seconds. -+Reading them more often repeats the same values. -+ -+ -+sysfs interface -+--------------- -+ -+in0_input - +2.5V voltage input -+in1_input - CPU voltage input (nominal 2.25V) -+in2_input - +3.3V voltage input -+in3_input - +5V voltage input -+in4_input - +12V voltage input (may be missing if used as VID4) -+in5_input - Vcc voltage input (nominal 3.3V) -+ This is the supply voltage of the sensor chip itself. -+in6_input - +1.5V voltage input -+in7_input - +1.8V voltage input -+ -+in[0-7]_min, -+in[0-7]_max - lower and upper alarm thresholds for in[0-7]_input reading -+ -+ All voltages are read and written in mV. -+ -+in[0-7]_alarm - alarm flags for voltage inputs -+ These files read '1' in case of alarm, '0' otherwise. -+ -+temp1_input - chip temperature measured by on-chip diode -+temp[2-3]_input - temperature measured by external diodes (one of these would -+ typically be wired to the diode inside the CPU) -+ -+temp[1-3]_min, -+temp[1-3]_max - lower and upper alarm thresholds for temperatures -+ -+temp[1-3]_offset - temperature offset registers -+ The chip adds the offsets stored in these registers to -+ the corresponding temperature readings. -+ Note that temp1 and temp2 offsets share the same register, -+ they cannot both be different from zero at the same time. -+ Writing a non-zero number to one of them will reset the other -+ offset to zero. -+ -+ All temperatures and offsets are read and written in -+ units of 0.001 degC. -+ -+temp[1-3]_alarm - alarm flags for temperature inputs, '1' in case of alarm, -+ '0' otherwise. -+temp[2-3]_input_fault - diode fault flags for temperature inputs 2 and 3. -+ A fault is detected if the two pins for the corresponding -+ sensor are open or shorted, or any of the two is shorted -+ to ground or Vcc. '1' indicates a diode fault. -+ -+cpu0_vid - CPU voltage as received from the CPU -+ -+vrm - CPU VID standard used for decoding CPU voltage -+ -+ The *_min, *_max, *_offset and vrm files can be read and -+ written, all others are read-only. ---- gregkh-2.6.orig/Documentation/hwmon/sysfs-interface -+++ gregkh-2.6/Documentation/hwmon/sysfs-interface -@@ -218,6 +218,12 @@ temp[1-2]_crit_hyst - from the critical value. - Read/Write value. - -+temp[1-4]_offset -+ Temperature offset which is added to the temperature reading -+ by the chip. -+ Unit: millidegree Celsius -+ Read/Write value. -+ - If there are multiple temperature sensors, temp1_* is - generally the sensor inside the chip itself, - reported as "motherboard temperature". temp2_* to ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -333,11 +333,32 @@ config SENSORS_SMSC47M1 - help - If you say yes here you get support for the integrated fan - monitoring and control capabilities of the SMSC LPC47B27x, -- LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips. -+ LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and -+ LPC47M997 chips. -+ -+ The temperature and voltage sensor features of the LPC47M192 -+ and LPC47M997 are supported by another driver, select also -+ "SMSC LPC47M192 and compatibles" below for those. - - This driver can also be built as a module. If so, the module - will be called smsc47m1. - -+config SENSORS_SMSC47M192 -+ tristate "SMSC LPC47M192 and compatibles" -+ depends on HWMON && I2C && EXPERIMENTAL -+ select HWMON_VID -+ help -+ If you say yes here you get support for the temperature and -+ voltage sensors of the SMSC LPC47M192 and LPC47M997 chips. -+ -+ The fan monitoring and control capabilities of these chips -+ are supported by another driver, select -+ "SMSC LPC47M10x and compatibles" above. You need both drivers -+ if you want fan control and voltage/temperature sensor support. -+ -+ This driver can also be built as a module. If so, the module -+ will be called smsc47m192. -+ - config SENSORS_SMSC47B397 - tristate "SMSC LPC47B397-NC" - depends on HWMON && I2C && EXPERIMENTAL ---- gregkh-2.6.orig/drivers/hwmon/Makefile -+++ gregkh-2.6/drivers/hwmon/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360 - obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o - obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o - obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o -+obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o - obj-$(CONFIG_SENSORS_VIA686A) += via686a.o - obj-$(CONFIG_SENSORS_VT8231) += vt8231.o - obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o ---- /dev/null -+++ gregkh-2.6/drivers/hwmon/smsc47m192.c -@@ -0,0 +1,648 @@ -+/* -+ smsc47m192.c - Support for hardware monitoring block of -+ SMSC LPC47M192 and LPC47M997 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> -+#include <linux/slab.h> -+#include <linux/jiffies.h> -+#include <linux/i2c.h> -+#include <linux/hwmon.h> -+#include <linux/hwmon-sysfs.h> -+#include <linux/hwmon-vid.h> -+#include <linux/err.h> -+ -+/* Addresses to scan */ -+static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; -+ -+/* Insmod parameters */ -+I2C_CLIENT_INSMOD_1(smsc47m192); -+ -+/* SMSC47M192 registers */ -+#define SMSC47M192_REG_IN(nr) ((nr)<6 ? (0x20 + (nr)) : \ -+ (0x50 + (nr) - 6)) -+#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) : \ -+ (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_ALARM1 0x41 -+#define SMSC47M192_REG_ALARM2 0x42 -+#define SMSC47M192_REG_VID 0x47 -+#define SMSC47M192_REG_VID4 0x49 -+#define SMSC47M192_REG_CONFIG 0x40 -+#define SMSC47M192_REG_SFR 0x4f -+#define SMSC47M192_REG_COMPANY_ID 0x3e -+#define SMSC47M192_REG_VERSION 0x3f -+ -+/* generalised scaling with integer rounding */ -+static inline int SCALE(long val, int mul, int div) -+{ -+ if (val < 0) -+ return (val * mul - div / 2) / div; -+ else -+ return (val * mul + div / 2) / div; -+} -+ -+/* Conversions */ -+ -+/* smsc47m192 internally scales voltage measurements */ -+static const u16 nom_mv[] = { 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 }; -+ -+static inline unsigned int IN_FROM_REG(u8 reg, int n) -+{ -+ return SCALE(reg, nom_mv[n], 192); -+} -+ -+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 */ -+static inline s8 TEMP_TO_REG(int val) -+{ -+ return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000); -+} -+ -+static inline int TEMP_FROM_REG(s8 val) -+{ -+ return val * 1000; -+} -+ -+struct smsc47m192_data { -+ struct i2c_client client; -+ struct class_device *class_dev; -+ struct semaphore update_lock; -+ char valid; /* !=0 if following fields are valid */ -+ unsigned long last_updated; /* In jiffies */ -+ -+ u8 in[8]; /* Register value */ -+ u8 in_max[8]; /* Register value */ -+ u8 in_min[8]; /* Register value */ -+ s8 temp[3]; /* Register value */ -+ s8 temp_max[3]; /* Register value */ -+ s8 temp_min[3]; /* Register value */ -+ s8 temp_offset[3]; /* Register value */ -+ u16 alarms; /* Register encoding, combined */ -+ u8 vid; /* Register encoding, combined */ -+ u8 vrm; -+}; -+ -+static int smsc47m192_attach_adapter(struct i2c_adapter *adapter); -+static int smsc47m192_detect(struct i2c_adapter *adapter, int address, -+ int kind); -+static int smsc47m192_detach_client(struct i2c_client *client); -+static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); -+ -+static struct i2c_driver smsc47m192_driver = { -+ .driver = { -+ .name = "smsc47m192", -+ }, -+ .attach_adapter = smsc47m192_attach_adapter, -+ .detach_client = smsc47m192_detach_client, -+}; -+ -+/* Voltages */ -+static ssize_t show_in(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr)); -+} -+ -+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr)); -+} -+ -+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr)); -+} -+ -+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ 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 smsc47m192_data *data = i2c_get_clientdata(client); -+ unsigned long val = simple_strtoul(buf, NULL, 10); -+ -+ down(&data->update_lock); -+ data->in_min[nr] = IN_TO_REG(val, nr); -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), -+ data->in_min[nr]); -+ up(&data->update_lock); -+ return count; -+} -+ -+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ 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 smsc47m192_data *data = i2c_get_clientdata(client); -+ unsigned long val = simple_strtoul(buf, NULL, 10); -+ -+ down(&data->update_lock); -+ data->in_max[nr] = IN_TO_REG(val, nr); -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), -+ data->in_max[nr]); -+ up(&data->update_lock); -+ return count; -+} -+ -+#define show_in_offset(offset) \ -+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ -+ show_in, 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); -+ -+show_in_offset(0) -+show_in_offset(1) -+show_in_offset(2) -+show_in_offset(3) -+show_in_offset(4) -+show_in_offset(5) -+show_in_offset(6) -+show_in_offset(7) -+ -+/* Temperatures */ -+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); -+} -+ -+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); -+} -+ -+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); -+} -+ -+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ 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 smsc47m192_data *data = i2c_get_clientdata(client); -+ long val = simple_strtol(buf, NULL, 10); -+ -+ down(&data->update_lock); -+ data->temp_min[nr] = TEMP_TO_REG(val); -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], -+ data->temp_min[nr]); -+ up(&data->update_lock); -+ return count; -+} -+ -+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ 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 smsc47m192_data *data = i2c_get_clientdata(client); -+ long val = simple_strtol(buf, NULL, 10); -+ -+ down(&data->update_lock); -+ data->temp_max[nr] = TEMP_TO_REG(val); -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], -+ data->temp_max[nr]); -+ up(&data->update_lock); -+ return count; -+} -+ -+static ssize_t show_temp_offset(struct device *dev, struct device_attribute -+ *attr, char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr])); -+} -+ -+static ssize_t set_temp_offset(struct device *dev, struct device_attribute -+ *attr, const char *buf, size_t count) -+{ -+ 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 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); -+ -+ down(&data->update_lock); -+ data->temp_offset[nr] = TEMP_TO_REG(val); -+ 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] */ -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, -+ (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)) -+ i2c_smbus_write_byte_data(client, -+ SMSC47M192_REG_TEMP_OFFSET(nr), 0); -+ up(&data->update_lock); -+ return count; -+} -+ -+#define show_temp_index(index) \ -+static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO, \ -+ show_temp, NULL, index-1); \ -+static SENSOR_DEVICE_ATTR(temp##index##_min, S_IRUGO | S_IWUSR, \ -+ show_temp_min, set_temp_min, index-1); \ -+static SENSOR_DEVICE_ATTR(temp##index##_max, S_IRUGO | S_IWUSR, \ -+ show_temp_max, set_temp_max, index-1); \ -+static SENSOR_DEVICE_ATTR(temp##index##_offset, S_IRUGO | S_IWUSR, \ -+ show_temp_offset, set_temp_offset, index-1); -+ -+show_temp_index(1) -+show_temp_index(2) -+show_temp_index(3) -+ -+/* VID */ -+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct smsc47m192_data *data = smsc47m192_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) -+{ -+ struct smsc47m192_data *data = smsc47m192_update_device(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) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct smsc47m192_data *data = i2c_get_clientdata(client); -+ data->vrm = simple_strtoul(buf, NULL, 10); -+ return count; -+} -+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); -+ -+/* Alarms */ -+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct smsc47m192_data *data = smsc47m192_update_device(dev); -+ return sprintf(buf, "%u\n", (data->alarms & nr) ? 1 : 0); -+} -+ -+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); -+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); -+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); -+static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 0x4000); -+static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 0x8000); -+static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); -+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); -+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); -+static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 0x0008); -+static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 0x0100); -+static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200); -+static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400); -+static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800); -+ -+/* This function is called when: -+ * smsc47m192_driver is inserted (when this module is loaded), for each -+ available adapter -+ * when a new adapter is inserted (and smsc47m192_driver is still present) */ -+static int smsc47m192_attach_adapter(struct i2c_adapter *adapter) -+{ -+ if (!(adapter->class & I2C_CLASS_HWMON)) -+ return 0; -+ return i2c_probe(adapter, &addr_data, smsc47m192_detect); -+} -+ -+static void smsc47m192_init_client(struct i2c_client *client) -+{ -+ int i; -+ u8 config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); -+ u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); -+ -+ /* select cycle mode (pause 1 sec between updates) */ -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR, -+ (sfr & 0xfd) | 0x02); -+ if (!(config & 0x01)) { -+ /* initialize alarm limits */ -+ 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++) { -+ i2c_smbus_write_byte_data(client, -+ SMSC47M192_REG_TEMP_MIN[i], 0x80); -+ i2c_smbus_write_byte_data(client, -+ SMSC47M192_REG_TEMP_MAX[i], 0x7f); -+ } -+ -+ /* start monitoring */ -+ i2c_smbus_write_byte_data(client, SMSC47M192_REG_CONFIG, -+ (config & 0xf7) | 0x01); -+ } -+} -+ -+/* This function is called by i2c_probe */ -+static int smsc47m192_detect(struct i2c_adapter *adapter, int address, -+ int kind) -+{ -+ struct i2c_client *client; -+ struct smsc47m192_data *data; -+ int err = 0; -+ int version, config; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ goto exit; -+ -+ if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ client = &data->client; -+ i2c_set_clientdata(client, data); -+ client->addr = address; -+ client->adapter = adapter; -+ client->driver = &smsc47m192_driver; -+ -+ if (kind == 0) -+ kind = smsc47m192; -+ -+ /* Detection criteria from sensors_detect script */ -+ if (kind < 0) { -+ if (i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_COMPANY_ID) == 0x55 -+ && ((version = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_VERSION)) & 0xf0) == 0x20 -+ && (i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_VID) & 0x70) == 0x00 -+ && (i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_VID4) & 0xfe) == 0x80) { -+ dev_info(&adapter->dev, -+ "found SMSC47M192 or SMSC47M997, " -+ "version 2, stepping A%d\n", version & 0x0f); -+ } else { -+ dev_dbg(&adapter->dev, -+ "SMSC47M192 detection failed at 0x%02x\n", -+ address); -+ goto exit_free; -+ } -+ } -+ -+ /* Fill in the remaining client fields and put into the global list */ -+ strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); -+ data->vrm = vid_which_vrm(); -+ init_MUTEX(&data->update_lock); -+ -+ /* Tell the I2C layer a new client has arrived */ -+ if ((err = i2c_attach_client(client))) -+ goto exit_free; -+ -+ /* Initialize the SMSC47M192 chip */ -+ smsc47m192_init_client(client); -+ -+ /* Register sysfs hooks */ -+ data->class_dev = hwmon_device_register(&client->dev); -+ if (IS_ERR(data->class_dev)) { -+ err = PTR_ERR(data->class_dev); -+ goto exit_detach; -+ } -+ -+ device_create_file(&client->dev, &sensor_dev_attr_in0_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in0_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in0_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in0_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in1_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in1_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in1_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in1_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in2_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in2_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in2_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in2_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in3_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in3_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in3_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in3_alarm.dev_attr); -+ -+ /* Pin 110 is either in4 (+12V) or VID4 */ -+ config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); -+ if (!(config & 0x20)) { -+ device_create_file(&client->dev, -+ &sensor_dev_attr_in4_input.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_in4_min.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_in4_max.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_in4_alarm.dev_attr); -+ } -+ device_create_file(&client->dev, &sensor_dev_attr_in5_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in5_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in5_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in5_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in6_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in6_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in6_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in6_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in7_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in7_min.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in7_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_in7_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp1_min.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_temp1_offset.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp1_alarm.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp2_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp2_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp2_min.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_temp2_offset.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp2_alarm.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_temp2_input_fault.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp3_input.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp3_max.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp3_min.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_temp3_offset.dev_attr); -+ device_create_file(&client->dev, &sensor_dev_attr_temp3_alarm.dev_attr); -+ device_create_file(&client->dev, -+ &sensor_dev_attr_temp3_input_fault.dev_attr); -+ device_create_file(&client->dev, &dev_attr_cpu0_vid); -+ device_create_file(&client->dev, &dev_attr_vrm); -+ -+ return 0; -+ -+exit_detach: -+ i2c_detach_client(client); -+exit_free: -+ kfree(data); -+exit: -+ return err; -+} -+ -+static int smsc47m192_detach_client(struct i2c_client *client) -+{ -+ struct smsc47m192_data *data = i2c_get_clientdata(client); -+ int err; -+ -+ hwmon_device_unregister(data->class_dev); -+ -+ if ((err = i2c_detach_client(client))) -+ return err; -+ -+ kfree(data); -+ -+ return 0; -+} -+ -+static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct smsc47m192_data *data = i2c_get_clientdata(client); -+ int i, config; -+ -+ down(&data->update_lock); -+ -+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) -+ || !data->valid) { -+ u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); -+ -+ dev_dbg(&client->dev, "Starting smsc47m192 update\n"); -+ -+ for (i = 0; i <= 7; i++) { -+ data->in[i] = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_IN(i)); -+ data->in_min[i] = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_IN_MIN(i)); -+ data->in_max[i] = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_IN_MAX(i)); -+ } -+ for (i = 0; i < 3; i++) { -+ data->temp[i] = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_TEMP[i]); -+ data->temp_max[i] = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_TEMP_MAX[i]); -+ data->temp_min[i] = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_TEMP_MIN[i]); -+ } -+ 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 */ -+ if (sfr & 0x10) { -+ data->temp_offset[0] = data->temp_offset[1]; -+ data->temp_offset[1] = 0; -+ } else -+ data->temp_offset[0] = 0; -+ -+ data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID) -+ & 0x0f; -+ config = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_CONFIG); -+ if (config & 0x20) -+ data->vid |= (i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_VID4) & 0x01) << 4; -+ data->alarms = i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_ALARM1) | -+ (i2c_smbus_read_byte_data(client, -+ SMSC47M192_REG_ALARM2) << 8); -+ -+ data->last_updated = jiffies; -+ data->valid = 1; -+ } -+ -+ up(&data->update_lock); -+ -+ 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_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/i2c/hwmon-sysfs-interface-individual-alarm-files.patch b/i2c/hwmon-sysfs-interface-individual-alarm-files.patch deleted file mode 100644 index c54aabc2aa1f41..00000000000000 --- a/i2c/hwmon-sysfs-interface-individual-alarm-files.patch +++ /dev/null @@ -1,145 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:46:13 2006 -Date: Thu, 23 Mar 2006 16:46:47 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: [PATCH 07/10] hwmon: Add sysfs interface for individual alarm files -Message-Id: <20060323164647.0e89adcb.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-sysfs-interface-individual-alarm-files.patch - -Extend the sysfs interface of hardware monitoring chips, by adding -individual alarm and beep files. Contrary to the old aggregated "alarms" -and "beeps" files, individual files constitute a standard way to access -the status information, making it finally possible to implement a -chip-independant hardware monitoring chip access library (once all -drivers have been added this new interface, that is.) - -If future drivers need more individual files, the interface will be -extended as needed at the same time these drivers are merged into the -kernel tree. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/sysfs-interface | 98 ++++++++++++++++++++++++++---------- - 1 file changed, 73 insertions(+), 25 deletions(-) - ---- gregkh-2.6.orig/Documentation/hwmon/sysfs-interface -+++ gregkh-2.6/Documentation/hwmon/sysfs-interface -@@ -252,9 +252,68 @@ curr[1-n]_input Current input value - Read only. - - --********* --* Other * --********* -+********** -+* Alarms * -+********** -+ -+Each channel or limit may have an associated alarm file, containing a -+boolean value. 1 means than an alarm condition exists, 0 means no alarm. -+ -+Usually a given chip will either use channel-related alarms, or -+limit-related alarms, not both. The driver should just reflect the hardware -+implementation. -+ -+in[0-n]_alarm -+fan[1-n]_alarm -+temp[1-n]_alarm -+ Channel alarm -+ Boolean -+ Read-only -+ -+OR -+ -+in[0-n]_min_alarm -+in[0-n]_max_alarm -+fan[1-n]_min_alarm -+temp[1-n]_min_alarm -+temp[1-n]_max_alarm -+temp[1-n]_crit_alarm -+ Limit alarm -+ Boolean -+ Read-only -+ -+Each input channel may have an associated fault file. This can be used -+to notify open diodes, unconnected fans etc. where the hardware -+supports it. When this boolean has value 1, the measurement for that -+channel should not be trusted. -+ -+in[0-n]_input_fault -+fan[1-n]_input_fault -+temp[1-n]_input_fault -+ Input fault condition -+ Boolean -+ Read-only -+ -+Some chips also offer the possibility to get beeped when an alarm occurs: -+ -+beep_enable Master beep enable -+ Boolean -+ Read/Write -+ -+in[0-n]_beep -+fan[1-n]_beep -+temp[1-n]_beep -+ Channel beep -+ 0 to disable. -+ 1 to enable. -+ Read/write -+ -+In theory, a chip could provide per-limit beep masking, but no such chip -+was seen so far. -+ -+Old drivers provided a different, non-standard interface to alarms and -+beeps. These interface files are deprecated, but will be kept around -+for compatibility reasons: - - alarms Alarm bitmask. - Read only. -@@ -265,33 +324,22 @@ alarms Alarm bitmask. - if it is still valid. - Generally a direct representation of a chip's internal - alarm registers; there is no standard for the position -- of individual bits. -+ of individual bits. For this reason, the use of this -+ interface file for new drivers is discouraged. Use -+ individual *_alarm and *_fault files instead. - Bits are defined in kernel/include/sensors.h. - --alarms_in Alarm bitmask relative to in (voltage) channels -- Read only -- A '1' bit means an alarm, LSB corresponds to in0 and so on -- Prefered to 'alarms' for newer chips -- --alarms_fan Alarm bitmask relative to fan channels -- Read only -- A '1' bit means an alarm, LSB corresponds to fan1 and so on -- Prefered to 'alarms' for newer chips -- --alarms_temp Alarm bitmask relative to temp (temperature) channels -- Read only -- A '1' bit means an alarm, LSB corresponds to temp1 and so on -- Prefered to 'alarms' for newer chips -- --beep_enable Beep/interrupt enable -- 0 to disable. -- 1 to enable. -- Read/Write -- - beep_mask Bitmask for beep. -- Same format as 'alarms' with the same bit locations. -+ Same format as 'alarms' with the same bit locations, -+ use discouraged for the same reason. Use individual -+ *_beep files instead. - Read/Write - -+ -+********* -+* Other * -+********* -+ - eeprom Raw EEPROM data in binary form. - Read only. - diff --git a/i2c/hwmon-sysfs-interface-update-1.patch b/i2c/hwmon-sysfs-interface-update-1.patch deleted file mode 100644 index 8278021e4281e0..00000000000000 --- a/i2c/hwmon-sysfs-interface-update-1.patch +++ /dev/null @@ -1,379 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:03:42 2006 -Date: Sun, 4 Jun 2006 20:03:39 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Rudolf Marek <r.marek@sh.cvut.cz> -Subject: hwmon: Sysfs interface documentation update, 1 of 2 -Message-Id: <20060604200339.4ba872f7.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-sysfs-interface-update-1.patch - -From: Rudolf Marek <r.marek@sh.cvut.cz> - -This patch cleans up hwmon sysfs documentation file, plus introduces -the description of DC/PWM selection for fan speed control. - -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/sysfs-interface | 183 +++++++++++++++++++++--------------- - 1 file changed, 108 insertions(+), 75 deletions(-) - ---- gregkh-2.6.orig/Documentation/hwmon/sysfs-interface -+++ gregkh-2.6/Documentation/hwmon/sysfs-interface -@@ -69,28 +69,37 @@ to cause an alarm) is chip-dependent. - - ------------------------------------------------------------------------- - -+[0-*] denotes any positive number starting from 0 -+[1-*] denotes any positive number starting from 1 -+RO read only value -+RW read/write value -+ -+Read/write values may be read-only for some chips, depending on the -+hardware implementation. -+ - ************ - * Voltages * - ************ - --in[0-8]_min Voltage min value. -+in[0-*]_min Voltage min value. - Unit: millivolt -- Read/Write -+ RW - --in[0-8]_max Voltage max value. -+in[0-*]_max Voltage max value. - Unit: millivolt -- Read/Write -+ RW - --in[0-8]_input Voltage input value. -+in[0-*]_input Voltage input value. - Unit: millivolt -- Read only -+ RO -+ Voltage measured on the chip pin. - Actual voltage depends on the scaling resistors on the - motherboard, as recommended in the chip datasheet. - This varies by chip and by motherboard. - Because of this variation, values are generally NOT scaled - by the chip driver, and must be done by the application. - However, some drivers (notably lm87 and via686a) -- do scale, with various degrees of success. -+ do scale, because of internal resistors built into a chip. - These drivers will output the actual voltage. - - Typical usage: -@@ -104,58 +113,72 @@ in[0-8]_input Voltage input value. - in7_* varies - in8_* varies - --cpu[0-1]_vid CPU core reference voltage. -+cpu[0-*]_vid CPU core reference voltage. - Unit: millivolt -- Read only. -+ RO - Not always correct. - - vrm Voltage Regulator Module version number. -- Read only. -- Two digit number, first is major version, second is -- minor version. -+ RW (but changing it should no more be necessary) -+ Originally the VRM standard version multiplied by 10, but now -+ an arbitrary number, as not all standards have a version -+ number. - Affects the way the driver calculates the CPU core reference - voltage from the vid pins. - -+Also see the Alarms section for status flags associated with voltages. -+ - - ******** - * Fans * - ******** - --fan[1-3]_min Fan minimum value -+fan[1-*]_min Fan minimum value - Unit: revolution/min (RPM) -- Read/Write. -+ RW - --fan[1-3]_input Fan input value. -+fan[1-*]_input Fan input value. - Unit: revolution/min (RPM) -- Read only. -+ RO - --fan[1-3]_div Fan divisor. -+fan[1-*]_div Fan divisor. - Integer value in powers of two (1, 2, 4, 8, 16, 32, 64, 128). -+ RW - Some chips only support values 1, 2, 4 and 8. - Note that this is actually an internal clock divisor, which - affects the measurable speed range, not the read value. - -+Also see the Alarms section for status flags associated with fans. -+ -+ - ******* - * PWM * - ******* - --pwm[1-3] Pulse width modulation fan control. -+pwm[1-*] Pulse width modulation fan control. - Integer value in the range 0 to 255 -- Read/Write -+ RW - 255 is max or 100%. - --pwm[1-3]_enable -+pwm[1-*]_enable - Switch PWM on and off. - Not always present even if fan*_pwm is. -- 0 to turn off -- 1 to turn on in manual mode -- 2 to turn on in automatic mode -- Read/Write -+ 0: turn off -+ 1: turn on in manual mode -+ 2+: turn on in automatic mode -+ Check individual chip documentation files for automatic mode details. -+ RW -+ -+pwm[1-*]_mode -+ 0: DC mode -+ 1: PWM mode -+ RW - - pwm[1-*]_auto_channels_temp - Select which temperature channels affect this PWM output in - auto mode. Bitfield, 1 is temp1, 2 is temp2, 4 is temp3 etc... - Which values are possible depend on the chip used. -+ RW - - pwm[1-*]_auto_point[1-*]_pwm - pwm[1-*]_auto_point[1-*]_temp -@@ -163,6 +186,7 @@ pwm[1-*]_auto_point[1-*]_temp_hyst - Define the PWM vs temperature curve. Number of trip points is - chip-dependent. Use this for chips which associate trip points - to PWM output channels. -+ RW - - OR - -@@ -172,51 +196,52 @@ temp[1-*]_auto_point[1-*]_temp_hyst - Define the PWM vs temperature curve. Number of trip points is - chip-dependent. Use this for chips which associate trip points - to temperature channels. -+ RW - - - **************** - * Temperatures * - **************** - --temp[1-3]_type Sensor type selection. -+temp[1-*]_type Sensor type selection. - Integers 1 to 4 or thermistor Beta value (typically 3435) -- Read/Write. -+ RW - 1: PII/Celeron Diode - 2: 3904 transistor - 3: thermal diode - 4: thermistor (default/unknown Beta) - Not all types are supported by all chips - --temp[1-4]_max Temperature max value. -+temp[1-*]_max Temperature max value. - Unit: millidegree Celcius -- Read/Write value. -+ RW - --temp[1-3]_min Temperature min value. -+temp[1-*]_min Temperature min value. - Unit: millidegree Celcius -- Read/Write value. -+ RW - --temp[1-3]_max_hyst -+temp[1-*]_max_hyst - Temperature hysteresis value for max limit. - Unit: millidegree Celcius - Must be reported as an absolute temperature, NOT a delta - from the max value. -- Read/Write value. -+ RW - --temp[1-4]_input Temperature input value. -+temp[1-*]_input Temperature input value. - Unit: millidegree Celcius -- Read only value. -+ RO - --temp[1-4]_crit Temperature critical value, typically greater than -+temp[1-*]_crit Temperature critical value, typically greater than - corresponding temp_max values. - Unit: millidegree Celcius -- Read/Write value. -+ RW - --temp[1-2]_crit_hyst -+temp[1-*]_crit_hyst - Temperature hysteresis value for critical limit. - Unit: millidegree Celcius - Must be reported as an absolute temperature, NOT a delta - from the critical value. -- Read/Write value. -+ RW - - temp[1-4]_offset - Temperature offset which is added to the temperature reading -@@ -231,6 +256,8 @@ temp[1-4]_offset - itself, for example the thermal diode inside the CPU or - a thermistor nearby. - -+Also see the Alarms section for status flags associated with temperatures. -+ - - ************ - * Currents * -@@ -239,17 +266,17 @@ temp[1-4]_offset - Note that no known chip provides current measurements as of writing, - so this part is theoretical, so to say. - --curr[1-n]_max Current max value -+curr[1-*]_max Current max value - Unit: milliampere -- Read/Write. -+ RW - --curr[1-n]_min Current min value. -+curr[1-*]_min Current min value. - Unit: milliampere -- Read/Write. -+ RW - --curr[1-n]_input Current input value -+curr[1-*]_input Current input value - Unit: milliampere -- Read only. -+ RO - - - ********** -@@ -263,50 +290,54 @@ Usually a given chip will either use cha - limit-related alarms, not both. The driver should just reflect the hardware - implementation. - --in[0-n]_alarm --fan[1-n]_alarm --temp[1-n]_alarm -+in[0-*]_alarm -+fan[1-*]_alarm -+temp[1-*]_alarm - Channel alarm -- Boolean -- Read-only -+ 0: no alarm -+ 1: alarm -+ RO - - OR - --in[0-n]_min_alarm --in[0-n]_max_alarm --fan[1-n]_min_alarm --temp[1-n]_min_alarm --temp[1-n]_max_alarm --temp[1-n]_crit_alarm -+in[0-*]_min_alarm -+in[0-*]_max_alarm -+fan[1-*]_min_alarm -+temp[1-*]_min_alarm -+temp[1-*]_max_alarm -+temp[1-*]_crit_alarm - Limit alarm -- Boolean -- Read-only -+ 0: no alarm -+ 1: alarm -+ RO - - Each input channel may have an associated fault file. This can be used - to notify open diodes, unconnected fans etc. where the hardware - supports it. When this boolean has value 1, the measurement for that - channel should not be trusted. - --in[0-n]_input_fault --fan[1-n]_input_fault --temp[1-n]_input_fault -+in[0-*]_input_fault -+fan[1-*]_input_fault -+temp[1-*]_input_fault - Input fault condition -- Boolean -- Read-only -+ 0: no fault occured -+ 1: fault condition -+ RO - - Some chips also offer the possibility to get beeped when an alarm occurs: - - beep_enable Master beep enable -- Boolean -- Read/Write -- --in[0-n]_beep --fan[1-n]_beep --temp[1-n]_beep -+ 0: no beeps -+ 1: beeps -+ RW -+ -+in[0-*]_beep -+fan[1-*]_beep -+temp[1-*]_beep - Channel beep -- 0 to disable. -- 1 to enable. -- Read/write -+ 0: disable -+ 1: enable -+ RW - - In theory, a chip could provide per-limit beep masking, but no such chip - was seen so far. -@@ -316,7 +347,7 @@ beeps. These interface files are depreca - for compatibility reasons: - - alarms Alarm bitmask. -- Read only. -+ RO - Integer representation of one to four bytes. - A '1' bit means an alarm. - Chips should be programmed for 'comparator' mode so that -@@ -333,7 +364,7 @@ beep_mask Bitmask for beep. - Same format as 'alarms' with the same bit locations, - use discouraged for the same reason. Use individual - *_beep files instead. -- Read/Write -+ RW - - - ********* -@@ -341,7 +372,9 @@ beep_mask Bitmask for beep. - ********* - - eeprom Raw EEPROM data in binary form. -- Read only. -+ RO - - pec Enable or disable PEC (SMBus only) -- Read/Write -+ 0: disable -+ 1: enable -+ RW diff --git a/i2c/hwmon-sysfs-interface-update-2.patch b/i2c/hwmon-sysfs-interface-update-2.patch deleted file mode 100644 index 0853c078633323..00000000000000 --- a/i2c/hwmon-sysfs-interface-update-2.patch +++ /dev/null @@ -1,138 +0,0 @@ -From khali@linux-fr.org Mon Jun 5 11:31:25 2006 -Date: Mon, 5 Jun 2006 20:31:20 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Jim Cromie <jim.cromie@gmail.com> -Subject: hwmon: Sysfs interface documentation update, 2 of 2, take 2 -Message-Id: <20060605203120.b865347e.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-sysfs-interface-update-2.patch - -Reword and complete certain parts of the hwmon sysfs-interface -documentation file. Hopefully this will make things clearer for new -driver authors. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/sysfs-interface | 45 +++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 16 deletions(-) - ---- gregkh-2.6.orig/Documentation/hwmon/sysfs-interface -+++ gregkh-2.6/Documentation/hwmon/sysfs-interface -@@ -3,15 +3,15 @@ Naming and data format standards for sys - - The libsensors library offers an interface to the raw sensors data - through the sysfs interface. See libsensors documentation and source for --more further information. As of writing this document, libsensors --(from lm_sensors 2.8.3) is heavily chip-dependant. Adding or updating -+further information. As of writing this document, libsensors -+(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating - support for any given chip requires modifying the library's code. - This is because libsensors was written for the procfs interface - older kernel modules were using, which wasn't standardized enough. - Recent versions of libsensors (from lm_sensors 2.8.2 and later) have - support for the sysfs interface, though. - --The new sysfs interface was designed to be as chip-independant as -+The new sysfs interface was designed to be as chip-independent as - possible. - - Note that motherboards vary widely in the connections to sensor chips. -@@ -24,7 +24,7 @@ range using external resistors. Since th - can change from motherboard to motherboard, the conversions cannot be - hard coded into the driver and have to be done in user space. - --For this reason, even if we aim at a chip-independant libsensors, it will -+For this reason, even if we aim at a chip-independent libsensors, it will - still require a configuration file (e.g. /etc/sensors.conf) for proper - values conversion, labeling of inputs and hiding of unused inputs. - -@@ -39,15 +39,16 @@ If you are developing a userspace applic - this standard. - - Note that this standard isn't completely established yet, so it is subject --to changes, even important ones. One more reason to use the library instead --of accessing sysfs files directly. -+to changes. If you are writing a new hardware monitoring driver those -+features can't seem to fit in this interface, please contact us with your -+extension proposal. Keep in mind that backward compatibility must be -+preserved. - - Each chip gets its own directory in the sysfs /sys/devices tree. To --find all sensor chips, it is easier to follow the symlinks from --/sys/i2c/devices/ -+find all sensor chips, it is easier to follow the device symlinks from -+/sys/class/hwmon/hwmon*. - --All sysfs values are fixed point numbers. To get the true value of some --of the values, you should divide by the specified value. -+All sysfs values are fixed point numbers. - - There is only one value per file, unlike the older /proc specification. - The common scheme for files naming is: <type><number>_<item>. Usual -@@ -77,6 +78,9 @@ RW read/write value - Read/write values may be read-only for some chips, depending on the - hardware implementation. - -+All entries are optional, and should only be created in a given driver -+if the chip has the feature. -+ - ************ - * Voltages * - ************ -@@ -213,32 +217,32 @@ temp[1-*]_type Sensor type selection. - Not all types are supported by all chips - - temp[1-*]_max Temperature max value. -- Unit: millidegree Celcius -+ Unit: millidegree Celsius (or millivolt, see below) - RW - - temp[1-*]_min Temperature min value. -- Unit: millidegree Celcius -+ Unit: millidegree Celsius - RW - - temp[1-*]_max_hyst - Temperature hysteresis value for max limit. -- Unit: millidegree Celcius -+ Unit: millidegree Celsius - Must be reported as an absolute temperature, NOT a delta - from the max value. - RW - - temp[1-*]_input Temperature input value. -- Unit: millidegree Celcius -+ Unit: millidegree Celsius - RO - - temp[1-*]_crit Temperature critical value, typically greater than - corresponding temp_max values. -- Unit: millidegree Celcius -+ Unit: millidegree Celsius - RW - - temp[1-*]_crit_hyst - Temperature hysteresis value for critical limit. -- Unit: millidegree Celcius -+ Unit: millidegree Celsius - Must be reported as an absolute temperature, NOT a delta - from the critical value. - RW -@@ -256,6 +260,15 @@ temp[1-4]_offset - itself, for example the thermal diode inside the CPU or - a thermistor nearby. - -+Some chips measure temperature using external thermistors and an ADC, and -+report the temperature measurement as a voltage. Converting this voltage -+back to a temperature (or the other way around for limits) requires -+mathematical functions not available in the kernel, so the conversion -+must occur in user space. For these chips, all temp* files described -+above should contain values expressed in millivolt instead of millidegree -+Celsius. In other words, such temperature channels are handled as voltage -+channels by the driver. -+ - Also see the Alarms section for status flags associated with temperatures. - - diff --git a/i2c/hwmon-vid-add-core-and-conroe-support.patch b/i2c/hwmon-vid-add-core-and-conroe-support.patch deleted file mode 100644 index da633740be56d1..00000000000000 --- a/i2c/hwmon-vid-add-core-and-conroe-support.patch +++ /dev/null @@ -1,97 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 13:00:57 2006 -Date: Mon, 12 Jun 2006 22:00:53 +0200 -From: Rudolf Marek <r.marek@sh.cvut.cz> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Rudolf Marek <r.marek@sh.cvut.cz> -Subject: [PATCH 14/14] hwmon-vid: Add support for Intel Core and Conroe -Message-Id: <20060612220053.622e56c6.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-vid-add-core-and-conroe-support.patch - -From: Rudolf Marek <r.marek@sh.cvut.cz> - -This patch adds support for two new VID codes, supporting Intel mobile Core -processors and new Conroe based platforms. - -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/hwmon-vid.c | 35 ++++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/hwmon-vid.c -+++ gregkh-2.6/drivers/hwmon/hwmon-vid.c -@@ -58,11 +58,20 @@ - doesn't seem to be any named specification for these. The conversion - tables are detailed directly in the various Pentium M datasheets: - http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm -+ -+ The 14 specification corresponds to Intel Core series. There -+ doesn't seem to be any named specification for these. The conversion -+ tables are detailed directly in the various Pentium Core datasheets: -+ http://www.intel.com/design/mobile/datashts/309221.htm -+ -+ The 110 (VRM 11) specification corresponds to Intel Conroe based series. -+ http://www.intel.com/design/processor/applnots/313214.htm - */ - - /* vrm is the VRM/VRD document version multiplied by 10. -- val is the 4-, 5- or 6-bit VID code. -- Returned value is in mV to avoid floating point in the kernel. */ -+ val is the 4-bit or more VID code. -+ Returned value is in mV to avoid floating point in the kernel. -+ Some VID have some bits in uV scale, this is rounded to mV */ - int vid_from_reg(int val, u8 vrm) - { - int vid; -@@ -70,18 +79,24 @@ int vid_from_reg(int val, u8 vrm) - switch(vrm) { - - case 100: /* VRD 10.0 */ -+ /* compute in uV, round to mV */ - val &= 0x3f; - if((val & 0x1f) == 0x1f) - return 0; - if((val & 0x1f) <= 0x09 || val == 0x0a) -- vid = 10875 - (val & 0x1f) * 250; -+ vid = 1087500 - (val & 0x1f) * 25000; - else -- vid = 18625 - (val & 0x1f) * 250; -+ vid = 1862500 - (val & 0x1f) * 25000; - if(val & 0x20) -- vid -= 125; -- vid /= 10; /* only return 3 dec. places for now */ -- return vid; -+ vid -= 12500; -+ return((vid + 500) / 1000); - -+ case 110: /* Intel Conroe */ -+ /* compute in uV, round to mV */ -+ val &= 0xff; -+ if(((val & 0x7e) == 0xfe) || (!(val & 0x7e))) -+ return 0; -+ return((1600000 - (val - 2) * 6250 + 500) / 1000); - case 24: /* Opteron processor */ - val &= 0x1f; - return(val == 0x1f ? 0 : 1550 - val * 25); -@@ -113,6 +128,10 @@ int vid_from_reg(int val, u8 vrm) - case 13: - val &= 0x3f; - 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); - default: /* report 0 for unknown */ - printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); - return 0; -@@ -145,6 +164,8 @@ static struct vrm_model vrm_models[] = { - {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, 0x7, ANY, ANY, 0}, /* Itanium */ - {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ diff --git a/i2c/hwmon-vid-mask-per-vrm.patch b/i2c/hwmon-vid-mask-per-vrm.patch deleted file mode 100644 index fc23c5248897ea..00000000000000 --- a/i2c/hwmon-vid-mask-per-vrm.patch +++ /dev/null @@ -1,69 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 05:24:44 2006 -Date: Tue, 25 Apr 2006 14:24:46 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Rudolf Marek <r.marek@sh.cvut.cz> -Subject: HWMON: Trim VID values to correct number of bits -Message-Id: <20060425142446.4efec6a6.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-vid-mask-per-vrm.patch - -From: Rudolf Marek <r.marek@sh.cvut.cz> - -Following patch trims the VID value to correct number of bits -for each VRM. - -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/hwmon-vid.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- gregkh-2.6.orig/drivers/hwmon/hwmon-vid.c -+++ gregkh-2.6/drivers/hwmon/hwmon-vid.c -@@ -70,6 +70,7 @@ int vid_from_reg(int val, u8 vrm) - switch(vrm) { - - case 100: /* VRD 10.0 */ -+ val &= 0x3f; - if((val & 0x1f) == 0x1f) - return 0; - if((val & 0x1f) <= 0x09 || val == 0x0a) -@@ -82,14 +83,17 @@ int vid_from_reg(int val, u8 vrm) - return vid; - - case 24: /* Opteron processor */ -+ val &= 0x1f; - return(val == 0x1f ? 0 : 1550 - val * 25); - - case 91: /* VRM 9.1 */ - case 90: /* VRM 9.0 */ -+ val &= 0x1f; - return(val == 0x1f ? 0 : - 1850 - val * 25); - - case 85: /* VRM 8.5 */ -+ val &= 0x1f; - return((val & 0x10 ? 25 : 0) + - ((val & 0x0f) > 0x04 ? 2050 : 1250) - - ((val & 0x0f) * 50)); -@@ -98,14 +102,17 @@ int vid_from_reg(int val, u8 vrm) - val &= 0x0f; - /* fall through */ - case 82: /* VRM 8.2 */ -+ val &= 0x1f; - return(val == 0x1f ? 0 : - val & 0x10 ? 5100 - (val) * 100 : - 2050 - (val) * 50); - case 17: /* Intel IMVP-II */ -+ val &= 0x1f; - return(val & 0x10 ? 975 - (val & 0xF) * 25 : - 1750 - val * 50); - case 13: -- return(1708 - (val & 0x3f) * 16); -+ val &= 0x3f; -+ return(1708 - val * 16); - default: /* report 0 for unknown */ - printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); - return 0; diff --git a/i2c/hwmon-w83627ehf-add-alarms.patch b/i2c/hwmon-w83627ehf-add-alarms.patch deleted file mode 100644 index fc3def3473e024..00000000000000 --- a/i2c/hwmon-w83627ehf-add-alarms.patch +++ /dev/null @@ -1,132 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:29:53 2006 -Date: Thu, 23 Mar 2006 16:30:29 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Yuan Mu <Ymu@winbond.com.tw>, Rudolf Marek <r.marek@sh.cvut.cz> -Subject: [PATCH 03/10] w83627ehf: Add alarms support -Message-Id: <20060323163029.5d56d96d.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-w83627ehf-add-alarms.patch - -Add alarms support for the W83627EHF/EHG hardware monitoring chip. - -This is based on an earlier patch from Rudolf Marek. - -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/w83627ehf.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 46 insertions(+) - ---- gregkh-2.6.orig/drivers/hwmon/w83627ehf.c -+++ gregkh-2.6/drivers/hwmon/w83627ehf.c -@@ -141,6 +141,10 @@ static const u16 W83627EHF_REG_TEMP_CONF - #define W83627EHF_REG_DIODE 0x59 - #define W83627EHF_REG_SMI_OVT 0x4C - -+#define W83627EHF_REG_ALARM1 0x459 -+#define W83627EHF_REG_ALARM2 0x45A -+#define W83627EHF_REG_ALARM3 0x45B -+ - /* - * Conversions - */ -@@ -218,6 +222,7 @@ struct w83627ehf_data { - s16 temp[2]; - s16 temp_max[2]; - s16 temp_max_hyst[2]; -+ u32 alarms; - }; - - static inline int is_word_sized(u16 reg) -@@ -427,6 +432,13 @@ static struct w83627ehf_data *w83627ehf_ - W83627EHF_REG_TEMP_HYST[i]); - } - -+ data->alarms = w83627ehf_read_value(client, -+ W83627EHF_REG_ALARM1) | -+ (w83627ehf_read_value(client, -+ W83627EHF_REG_ALARM2) << 8) | -+ (w83627ehf_read_value(client, -+ W83627EHF_REG_ALARM3) << 16); -+ - data->last_updated = jiffies; - data->valid = 1; - } -@@ -474,6 +486,14 @@ store_in_##reg (struct device *dev, stru - store_in_reg(MIN, min) - store_in_reg(MAX, max) - -+static ssize_t show_alarm(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); -+ int nr = sensor_attr->index; -+ return sprintf(buf, "%u\n", (data->alarms >> nr) & 0x01); -+} -+ - static struct sensor_device_attribute sda_in_input[] = { - SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), - SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), -@@ -487,6 +507,19 @@ static struct sensor_device_attribute sd - SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), - }; - -+static struct sensor_device_attribute sda_in_alarm[] = { -+ SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0), -+ SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1), -+ SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2), -+ SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3), -+ SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8), -+ SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21), -+ SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20), -+ SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16), -+ SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17), -+ SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19), -+}; -+ - static struct sensor_device_attribute sda_in_min[] = { - SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), - SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), -@@ -516,6 +549,7 @@ static struct sensor_device_attribute sd - static void device_create_file_in(struct device *dev, int i) - { - device_create_file(dev, &sda_in_input[i].dev_attr); -+ device_create_file(dev, &sda_in_alarm[i].dev_attr); - device_create_file(dev, &sda_in_min[i].dev_attr); - device_create_file(dev, &sda_in_max[i].dev_attr); - } -@@ -618,6 +652,14 @@ static struct sensor_device_attribute sd - SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), - }; - -+static struct sensor_device_attribute sda_fan_alarm[] = { -+ SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6), -+ SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7), -+ SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11), -+ SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 10), -+ SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23), -+}; -+ - static struct sensor_device_attribute sda_fan_min[] = { - SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, - store_fan_min, 0), -@@ -642,6 +684,7 @@ static struct sensor_device_attribute sd - static void device_create_file_fan(struct device *dev, int i) - { - device_create_file(dev, &sda_fan_input[i].dev_attr); -+ device_create_file(dev, &sda_fan_alarm[i].dev_attr); - device_create_file(dev, &sda_fan_div[i].dev_attr); - device_create_file(dev, &sda_fan_min[i].dev_attr); - } -@@ -729,6 +772,9 @@ static struct sensor_device_attribute sd - store_temp_max_hyst, 0), - SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, - store_temp_max_hyst, 1), -+ SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), -+ SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), -+ SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), - }; - - /* diff --git a/i2c/hwmon-w83627ehf-add-voltages.patch b/i2c/hwmon-w83627ehf-add-voltages.patch deleted file mode 100644 index adce43ee714fb4..00000000000000 --- a/i2c/hwmon-w83627ehf-add-voltages.patch +++ /dev/null @@ -1,198 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:24:51 2006 -Date: Thu, 23 Mar 2006 16:25:22 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Yuan Mu <Ymu@winbond.com.tw>, Rudolf Marek <r.marek@sh.cvut.cz> -Subject: [PATCH 02/10] w83627ehf: Add voltage inputs support -Message-Id: <20060323162522.f46f7072.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-w83627ehf-add-voltages.patch - -From: Rudolf Marek <r.marek@sh.cvut.cz> - -Add the voltage measuring support to W83627EHF. The code is based -on the patch provided by Yuan Mu from Winbond. - -Signed-off-by: Yuan Mu <Ymu@winbond.com.tw> -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/w83627ehf.c | 124 ++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 120 insertions(+), 4 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/w83627ehf.c -+++ gregkh-2.6/drivers/hwmon/w83627ehf.c -@@ -30,10 +30,7 @@ - Supports the following chips: - - Chip #vin #fan #pwm #temp chip_id man_id -- w83627ehf - 5 - 3 0x88 0x5ca3 -- -- This is a preliminary version of the driver, only supporting the -- fan and temperature inputs. The chip does much more than that. -+ w83627ehf 10 5 - 3 0x88 0x5ca3 - */ - - #include <linux/module.h> -@@ -121,6 +118,14 @@ superio_exit(void) - static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; - static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; - -+/* The W83627EHF registers for nr=7,8,9 are in bank 5 */ -+#define W83627EHF_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ -+ (0x554 + (((nr) - 7) * 2))) -+#define W83627EHF_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ -+ (0x555 + (((nr) - 7) * 2))) -+#define W83627EHF_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ -+ (0x550 + (nr) - 7)) -+ - #define W83627EHF_REG_TEMP1 0x27 - #define W83627EHF_REG_TEMP1_HYST 0x3a - #define W83627EHF_REG_TEMP1_OVER 0x39 -@@ -172,6 +177,20 @@ temp1_to_reg(int temp) - return (temp + 500) / 1000; - } - -+/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ -+ -+static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 }; -+ -+static inline long in_from_reg(u8 reg, u8 nr) -+{ -+ return reg * scale_in[nr]; -+} -+ -+static inline u8 in_to_reg(u32 val, u8 nr) -+{ -+ return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, 255); -+} -+ - /* - * Data structures and manipulation thereof - */ -@@ -186,6 +205,9 @@ struct w83627ehf_data { - unsigned long last_updated; /* In jiffies */ - - /* Register values */ -+ u8 in[10]; /* Register value */ -+ u8 in_max[10]; /* Register value */ -+ u8 in_min[10]; /* Register value */ - u8 fan[5]; - u8 fan_min[5]; - u8 fan_div[5]; -@@ -349,6 +371,16 @@ static struct w83627ehf_data *w83627ehf_ - data->fan_div[3] |= (i >> 5) & 0x04; - } - -+ /* Measured voltages and limits */ -+ for (i = 0; i < 10; i++) { -+ data->in[i] = w83627ehf_read_value(client, -+ W83627EHF_REG_IN(i)); -+ data->in_min[i] = w83627ehf_read_value(client, -+ W83627EHF_REG_IN_MIN(i)); -+ data->in_max[i] = w83627ehf_read_value(client, -+ W83627EHF_REG_IN_MAX(i)); -+ } -+ - /* Measured fan speeds and limits */ - for (i = 0; i < 5; i++) { - if (!(data->has_fan & (1 << i))) -@@ -406,6 +438,87 @@ static struct w83627ehf_data *w83627ehf_ - /* - * Sysfs callback functions - */ -+#define show_in_reg(reg) \ -+static ssize_t \ -+show_##reg(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); \ -+ int nr = sensor_attr->index; \ -+ return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \ -+} -+show_in_reg(in) -+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 *attr, \ -+ const char *buf, size_t count) \ -+{ \ -+ struct i2c_client *client = to_i2c_client(dev); \ -+ struct w83627ehf_data *data = i2c_get_clientdata(client); \ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ -+ int nr = sensor_attr->index; \ -+ u32 val = simple_strtoul(buf, NULL, 10); \ -+ \ -+ mutex_lock(&data->update_lock); \ -+ data->in_##reg[nr] = in_to_reg(val, nr); \ -+ w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ -+ data->in_##reg[nr]); \ -+ mutex_unlock(&data->update_lock); \ -+ return count; \ -+} -+ -+store_in_reg(MIN, min) -+store_in_reg(MAX, max) -+ -+static struct sensor_device_attribute sda_in_input[] = { -+ SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), -+ SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), -+ SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), -+ SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), -+ SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), -+ SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), -+ SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), -+ SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), -+ SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), -+ SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), -+}; -+ -+static struct sensor_device_attribute sda_in_min[] = { -+ SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), -+ SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), -+ SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), -+ SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), -+ SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), -+ SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), -+ SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), -+ SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), -+ SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), -+ SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9), -+}; -+ -+static struct sensor_device_attribute sda_in_max[] = { -+ SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), -+ SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), -+ SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), -+ SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), -+ SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), -+ SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), -+ SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), -+ SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), -+ SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), -+ SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), -+}; -+ -+static void device_create_file_in(struct device *dev, int i) -+{ -+ device_create_file(dev, &sda_in_input[i].dev_attr); -+ device_create_file(dev, &sda_in_min[i].dev_attr); -+ device_create_file(dev, &sda_in_max[i].dev_attr); -+} - - #define show_fan_reg(reg) \ - static ssize_t \ -@@ -705,6 +818,9 @@ static int w83627ehf_detect(struct i2c_a - goto exit_detach; - } - -+ for (i = 0; i < 10; i++) -+ device_create_file_in(dev, i); -+ - for (i = 0; i < 5; i++) { - if (data->has_fan & (1 << i)) - device_create_file_fan(dev, i); diff --git a/i2c/hwmon-w83791d-new-driver.patch b/i2c/hwmon-w83791d-new-driver.patch deleted file mode 100644 index a886e7c9aa5228..00000000000000 --- a/i2c/hwmon-w83791d-new-driver.patch +++ /dev/null @@ -1,1429 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 05:21:01 2006 -Date: Tue, 25 Apr 2006 14:21:03 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Charles Spirakis <bezaur@gmail.com> -Subject: HWMON: w83791d: New hardware monitoring driver for the Winbond W83791D -Message-Id: <20060425142103.28daa195.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-w83791d-new-driver.patch - -From: Charles Spirakis <bezaur@gmail.com> - -Add support for the w83791d sensor chip. The w83791d hardware is -somewhere between the w83781d and the w83792d and this driver code -is derived from the code that supports those chips. - -Signed-off-by: Charles Spirakis <bezaur@gmail.com> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/hwmon/w83791d | 113 +++ - drivers/hwmon/Kconfig | 10 - drivers/hwmon/Makefile | 1 - drivers/hwmon/w83791d.c | 1255 ++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 1379 insertions(+) - ---- /dev/null -+++ gregkh-2.6/Documentation/hwmon/w83791d -@@ -0,0 +1,113 @@ -+Kernel driver w83791d -+===================== -+ -+Supported chips: -+ * Winbond W83791D -+ Prefix: 'w83791d' -+ Addresses scanned: I2C 0x2c - 0x2f -+ Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf -+ -+Author: Charles Spirakis <bezaur@gmail.com> -+ -+This driver was derived from the w83781d.c and w83792d.c source files. -+ -+Credits: -+ w83781d.c: -+ Frodo Looijaard <frodol@dds.nl>, -+ Philip Edelbrock <phil@netroedge.com>, -+ and Mark Studebaker <mdsxyz123@yahoo.com> -+ w83792d.c: -+ Chunhao Huang <DZShen@Winbond.com.tw>, -+ Rudolf Marek <r.marek@sh.cvut.cz> -+ -+Module Parameters -+----------------- -+ -+* init boolean -+ (default 0) -+ Use 'init=1' to have the driver do extra software initializations. -+ The default behavior is to do the minimum initialization possible -+ and depend on the BIOS to properly setup the chip. If you know you -+ have a w83791d and you're having problems, try init=1 before trying -+ reset=1. -+ -+* reset boolean -+ (default 0) -+ Use 'reset=1' to reset the chip (via index 0x40, bit 7). The default -+ behavior is no chip reset to preserve BIOS settings. -+ -+* force_subclients=bus,caddr,saddr,saddr -+ This is used to force the i2c addresses for subclients of -+ a certain chip. Example usage is `force_subclients=0,0x2f,0x4a,0x4b' -+ to force the subclients of chip 0x2f on bus 0 to i2c addresses -+ 0x4a and 0x4b. -+ -+ -+Description -+----------- -+ -+This driver implements support for the Winbond W83791D chip. -+ -+Detection of the chip can sometimes be foiled because it can be in an -+internal state that allows no clean access (Bank with ID register is not -+currently selected). If you know the address of the chip, use a 'force' -+parameter; this will put it into a more well-behaved state first. -+ -+The driver implements three temperature sensors, five fan rotation speed -+sensors, and ten voltage sensors. -+ -+Temperatures are measured in degrees Celsius and measurement resolution is 1 -+degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when -+the temperature gets higher than the Overtemperature Shutdown value; it stays -+on until the temperature falls below the Hysteresis value. -+ -+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is -+triggered if the rotation speed has dropped below a programmable limit. Fan -+readings can be divided by a programmable divider (1, 2, 4, 8 for fan 1/2/3 -+and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more -+range or accuracy. -+ -+Voltage sensors (also known as IN sensors) report their values in millivolts. -+An alarm is triggered if the voltage has crossed a programmable minimum -+or maximum limit. -+ -+Alarms are provided as output from a "realtime status register". The -+following bits are defined: -+ -+bit - alarm on: -+0 - Vcore -+1 - VINR0 -+2 - +3.3VIN -+3 - 5VDD -+4 - temp1 -+5 - temp2 -+6 - fan1 -+7 - fan2 -+8 - +12VIN -+9 - -12VIN -+10 - -5VIN -+11 - fan3 -+12 - chassis -+13 - temp3 -+14 - VINR1 -+15 - reserved -+16 - tart1 -+17 - tart2 -+18 - tart3 -+19 - VSB -+20 - VBAT -+21 - fan4 -+22 - fan5 -+23 - reserved -+ -+When an alarm goes off, you can be warned by a beeping signal through your -+computer speaker. It is possible to enable all beeping globally, or only -+the beeping for some alarms. -+ -+The driver only reads the chip values each 3 seconds; reading them more -+often will do no harm, but will return 'old' values. -+ -+W83791D TODO: -+--------------- -+Provide a patch for per-file alarms as discussed on the mailing list -+Provide a patch for smart-fan control (still need appropriate motherboard/fans) ---- gregkh-2.6.orig/drivers/hwmon/Kconfig -+++ gregkh-2.6/drivers/hwmon/Kconfig -@@ -406,6 +406,16 @@ config SENSORS_W83781D - This driver can also be built as a module. If so, the module - will be called w83781d. - -+config SENSORS_W83791D -+ tristate "Winbond W83791D" -+ depends on HWMON && I2C && EXPERIMENTAL -+ select HWMON_VID -+ help -+ If you say yes here you get support for the Winbond W83791D chip. -+ -+ This driver can also be built as a module. If so, the module -+ will be called w83791d. -+ - config SENSORS_W83792D - tristate "Winbond W83792D" - depends on HWMON && I2C && EXPERIMENTAL ---- gregkh-2.6.orig/drivers/hwmon/Makefile -+++ gregkh-2.6/drivers/hwmon/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_SENSORS_ASB100) += asb100.o - obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o - obj-$(CONFIG_SENSORS_W83792D) += w83792d.o - obj-$(CONFIG_SENSORS_W83781D) += w83781d.o -+obj-$(CONFIG_SENSORS_W83791D) += w83791d.o - - obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o - obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o ---- /dev/null -+++ gregkh-2.6/drivers/hwmon/w83791d.c -@@ -0,0 +1,1255 @@ -+/* -+ w83791d.c - Part of lm_sensors, Linux kernel modules for hardware -+ monitoring -+ -+ Copyright (C) 2006 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 3 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, but its output is more along the lines of the -+ 83781d (which means there are no changes to the user-mode sensors -+ program which treats the 83791d as an 83781d). -+*/ -+ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/hwmon.h> -+#include <linux/hwmon-vid.h> -+#include <linux/hwmon-sysfs.h> -+#include <linux/err.h> -+#include <linux/mutex.h> -+ -+#define NUMBER_OF_VIN 10 -+#define NUMBER_OF_FANIN 5 -+#define NUMBER_OF_TEMPIN 3 -+ -+/* Addresses to scan */ -+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; -+ -+/* Insmod parameters */ -+I2C_CLIENT_INSMOD_1(w83791d); -+I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " -+ "{bus, clientaddr, subclientaddr1, subclientaddr2}"); -+ -+static int reset; -+module_param(reset, bool, 0); -+MODULE_PARM_DESC(reset, "Set to one to force a hardware chip reset"); -+ -+static int init; -+module_param(init, bool, 0); -+MODULE_PARM_DESC(init, "Set to one to force extra software initialization"); -+ -+/* The W83791D registers */ -+static const u8 W83791D_REG_IN[NUMBER_OF_VIN] = { -+ 0x20, /* VCOREA in DataSheet */ -+ 0x21, /* VINR0 in DataSheet */ -+ 0x22, /* +3.3VIN in DataSheet */ -+ 0x23, /* VDD5V in DataSheet */ -+ 0x24, /* +12VIN in DataSheet */ -+ 0x25, /* -12VIN in DataSheet */ -+ 0x26, /* -5VIN in DataSheet */ -+ 0xB0, /* 5VSB in DataSheet */ -+ 0xB1, /* VBAT in DataSheet */ -+ 0xB2 /* VINR1 in DataSheet */ -+}; -+ -+static const u8 W83791D_REG_IN_MAX[NUMBER_OF_VIN] = { -+ 0x2B, /* VCOREA High Limit in DataSheet */ -+ 0x2D, /* VINR0 High Limit in DataSheet */ -+ 0x2F, /* +3.3VIN High Limit in DataSheet */ -+ 0x31, /* VDD5V High Limit in DataSheet */ -+ 0x33, /* +12VIN High Limit in DataSheet */ -+ 0x35, /* -12VIN High Limit in DataSheet */ -+ 0x37, /* -5VIN High Limit in DataSheet */ -+ 0xB4, /* 5VSB High Limit in DataSheet */ -+ 0xB6, /* VBAT High Limit in DataSheet */ -+ 0xB8 /* VINR1 High Limit in DataSheet */ -+}; -+static const u8 W83791D_REG_IN_MIN[NUMBER_OF_VIN] = { -+ 0x2C, /* VCOREA Low Limit in DataSheet */ -+ 0x2E, /* VINR0 Low Limit in DataSheet */ -+ 0x30, /* +3.3VIN Low Limit in DataSheet */ -+ 0x32, /* VDD5V Low Limit in DataSheet */ -+ 0x34, /* +12VIN Low Limit in DataSheet */ -+ 0x36, /* -12VIN Low Limit in DataSheet */ -+ 0x38, /* -5VIN Low Limit in DataSheet */ -+ 0xB5, /* 5VSB Low Limit in DataSheet */ -+ 0xB7, /* VBAT Low Limit in DataSheet */ -+ 0xB9 /* VINR1 Low Limit in DataSheet */ -+}; -+static const u8 W83791D_REG_FAN[NUMBER_OF_FANIN] = { -+ 0x28, /* FAN 1 Count in DataSheet */ -+ 0x29, /* FAN 2 Count in DataSheet */ -+ 0x2A, /* FAN 3 Count in DataSheet */ -+ 0xBA, /* FAN 4 Count in DataSheet */ -+ 0xBB, /* FAN 5 Count in DataSheet */ -+}; -+static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = { -+ 0x3B, /* FAN 1 Count Low Limit in DataSheet */ -+ 0x3C, /* FAN 2 Count Low Limit in DataSheet */ -+ 0x3D, /* FAN 3 Count Low Limit in DataSheet */ -+ 0xBC, /* FAN 4 Count Low Limit in DataSheet */ -+ 0xBD, /* FAN 5 Count Low Limit in DataSheet */ -+}; -+ -+static const u8 W83791D_REG_FAN_CFG[2] = { -+ 0x84, /* FAN 1/2 configuration */ -+ 0x95, /* FAN 3 configuration */ -+}; -+ -+static const u8 W83791D_REG_FAN_DIV[3] = { -+ 0x47, /* contains FAN1 and FAN2 Divisor */ -+ 0x4b, /* contains FAN3 Divisor */ -+ 0x5C, /* contains FAN4 and FAN5 Divisor */ -+}; -+ -+#define W83791D_REG_BANK 0x4E -+#define W83791D_REG_TEMP2_CONFIG 0xC2 -+#define W83791D_REG_TEMP3_CONFIG 0xCA -+ -+static const u8 W83791D_REG_TEMP1[3] = { -+ 0x27, /* TEMP 1 in DataSheet */ -+ 0x39, /* TEMP 1 Over in DataSheet */ -+ 0x3A, /* TEMP 1 Hyst in DataSheet */ -+}; -+ -+static const u8 W83791D_REG_TEMP_ADD[2][6] = { -+ {0xC0, /* TEMP 2 in DataSheet */ -+ 0xC1, /* TEMP 2(0.5 deg) in DataSheet */ -+ 0xC5, /* TEMP 2 Over High part in DataSheet */ -+ 0xC6, /* TEMP 2 Over Low part in DataSheet */ -+ 0xC3, /* TEMP 2 Thyst High part in DataSheet */ -+ 0xC4}, /* TEMP 2 Thyst Low part in DataSheet */ -+ {0xC8, /* TEMP 3 in DataSheet */ -+ 0xC9, /* TEMP 3(0.5 deg) in DataSheet */ -+ 0xCD, /* TEMP 3 Over High part in DataSheet */ -+ 0xCE, /* TEMP 3 Over Low part in DataSheet */ -+ 0xCB, /* TEMP 3 Thyst High part in DataSheet */ -+ 0xCC} /* TEMP 3 Thyst Low part in DataSheet */ -+}; -+ -+#define W83791D_REG_BEEP_CONFIG 0x4D -+ -+static const u8 W83791D_REG_BEEP_CTRL[3] = { -+ 0x56, /* BEEP Control Register 1 */ -+ 0x57, /* BEEP Control Register 2 */ -+ 0xA3, /* BEEP Control Register 3 */ -+}; -+ -+#define W83791D_REG_CONFIG 0x40 -+#define W83791D_REG_VID_FANDIV 0x47 -+#define W83791D_REG_DID_VID4 0x49 -+#define W83791D_REG_WCHIPID 0x58 -+#define W83791D_REG_CHIPMAN 0x4F -+#define W83791D_REG_PIN 0x4B -+#define W83791D_REG_I2C_SUBADDR 0x4A -+ -+#define W83791D_REG_ALARM1 0xA9 /* realtime status register1 */ -+#define W83791D_REG_ALARM2 0xAA /* realtime status register2 */ -+#define W83791D_REG_ALARM3 0xAB /* realtime status register3 */ -+ -+#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 */ -+static inline int w83791d_read(struct i2c_client *client, u8 reg) -+{ -+ return i2c_smbus_read_byte_data(client, reg); -+} -+ -+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. */ -+#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8) / 16), 0, 255)) -+#define IN_FROM_REG(val) ((val) * 16) -+ -+static u8 fan_to_reg(long rpm, int div) -+{ -+ if (rpm == 0) -+ return 255; -+ rpm = SENSORS_LIMIT(rpm, 1, 1000000); -+ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); -+} -+ -+#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ -+ ((val) == 255 ? 0 : \ -+ 1350000 / ((val) * (div)))) -+ -+/* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */ -+#define TEMP1_FROM_REG(val) ((val) * 1000) -+#define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \ -+ (val) >= 127000 ? 127 : \ -+ (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 */ -+#define TEMP23_FROM_REG(val) ((val) / 128 * 500) -+#define TEMP23_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ -+ (val) >= 127500 ? 0x7F80 : \ -+ (val) < 0 ? ((val) - 250) / 500 * 128 : \ -+ ((val) + 250) / 500 * 128) -+ -+ -+#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) -+#define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff) -+ -+#define DIV_FROM_REG(val) (1 << (val)) -+ -+static u8 div_to_reg(int nr, long val) -+{ -+ int i; -+ int max; -+ -+ /* first three fan's divisor max out at 8, rest max out at 128 */ -+ max = (nr < 3) ? 8 : 128; -+ val = SENSORS_LIMIT(val, 1, max) >> 1; -+ for (i = 0; i < 7; i++) { -+ if (val == 0) -+ break; -+ val >>= 1; -+ } -+ return (u8) i; -+} -+ -+struct w83791d_data { -+ struct i2c_client client; -+ struct class_device *class_dev; -+ struct mutex update_lock; -+ -+ char valid; /* !=0 if following fields are valid */ -+ unsigned long last_updated; /* In jiffies */ -+ -+ /* array of 2 pointers to subclients */ -+ struct i2c_client *lm75[2]; -+ -+ /* volts */ -+ u8 in[NUMBER_OF_VIN]; /* Register value */ -+ u8 in_max[NUMBER_OF_VIN]; /* Register value */ -+ u8 in_min[NUMBER_OF_VIN]; /* Register value */ -+ -+ /* fans */ -+ u8 fan[NUMBER_OF_FANIN]; /* Register value */ -+ u8 fan_min[NUMBER_OF_FANIN]; /* Register value */ -+ u8 fan_div[NUMBER_OF_FANIN]; /* Register encoding, shifted right */ -+ -+ /* Temperature sensors */ -+ -+ 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) */ -+ -+ /* Misc */ -+ u32 alarms; /* realtime status register encoding,combined */ -+ u8 beep_enable; /* Global beep enable */ -+ u32 beep_mask; /* Mask off specific beeps */ -+ u8 vid; /* Register encoding, combined */ -+ u8 vrm; /* hwmon-vid */ -+}; -+ -+static int w83791d_attach_adapter(struct i2c_adapter *adapter); -+static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind); -+static int w83791d_detach_client(struct i2c_client *client); -+ -+static int w83791d_read(struct i2c_client *client, u8 register); -+static int w83791d_write(struct i2c_client *client, u8 register, u8 value); -+static struct w83791d_data *w83791d_update_device(struct device *dev); -+ -+#ifdef DEBUG -+static void w83791d_print_debug(struct w83791d_data *data, struct device *dev); -+#endif -+ -+static void w83791d_init_client(struct i2c_client *client); -+ -+static struct i2c_driver w83791d_driver = { -+ .driver = { -+ .name = "w83791d", -+ }, -+ .attach_adapter = w83791d_attach_adapter, -+ .detach_client = w83791d_detach_client, -+}; -+ -+/* following are the sysfs callback functions */ -+#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 w83791d_data *data = w83791d_update_device(dev); \ -+ int nr = sensor_attr->index; \ -+ return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \ -+} -+ -+show_in_reg(in); -+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 *attr, \ -+ const char *buf, size_t count) \ -+{ \ -+ 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; \ -+ \ -+ 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]); \ -+ mutex_unlock(&data->update_lock); \ -+ \ -+ return count; \ -+} -+store_in_reg(MIN, min); -+store_in_reg(MAX, max); -+ -+static struct sensor_device_attribute sda_in_input[] = { -+ SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), -+ SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), -+ SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), -+ SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), -+ SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), -+ SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), -+ SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), -+ SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), -+ SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), -+ SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9), -+}; -+ -+static struct sensor_device_attribute sda_in_min[] = { -+ SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), -+ SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), -+ SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), -+ SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), -+ SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), -+ SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), -+ SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), -+ SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), -+ SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), -+ SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9), -+}; -+ -+static struct sensor_device_attribute sda_in_max[] = { -+ SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), -+ SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), -+ SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), -+ SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), -+ SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), -+ SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), -+ SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), -+ SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), -+ SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), -+ SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), -+}; -+ -+#define show_fan_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 w83791d_data *data = w83791d_update_device(dev); \ -+ int nr = sensor_attr->index; \ -+ return sprintf(buf,"%d\n", \ -+ FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ -+} -+ -+show_fan_reg(fan); -+show_fan_reg(fan_min); -+ -+static ssize_t store_fan_min(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 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; -+ -+ mutex_lock(&data->update_lock); -+ data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr])); -+ w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -+ int nr = sensor_attr->index; -+ struct w83791d_data *data = w83791d_update_device(dev); -+ 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 suprise; 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) -+{ -+ 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); -+ int nr = sensor_attr->index; -+ unsigned long min; -+ u8 tmp_fan_div; -+ u8 fan_div_reg; -+ int indx = 0; -+ u8 keep_mask = 0; -+ u8 new_shift = 0; -+ -+ /* 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)); -+ -+ switch (nr) { -+ case 0: -+ indx = 0; -+ keep_mask = 0xcf; -+ new_shift = 4; -+ break; -+ case 1: -+ indx = 0; -+ keep_mask = 0x3f; -+ new_shift = 6; -+ break; -+ case 2: -+ indx = 1; -+ keep_mask = 0x3f; -+ new_shift = 6; -+ break; -+ case 3: -+ indx = 2; -+ keep_mask = 0xf8; -+ new_shift = 0; -+ break; -+ case 4: -+ indx = 2; -+ keep_mask = 0x8f; -+ new_shift = 4; -+ break; -+#ifdef DEBUG -+ default: -+ dev_warn(dev, "store_fan_div: Unexpected nr seen: %d\n", nr); -+ count = -EINVAL; -+ goto err_exit; -+#endif -+ } -+ -+ fan_div_reg = w83791d_read(client, W83791D_REG_FAN_DIV[indx]) -+ & keep_mask; -+ tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask; -+ -+ w83791d_write(client, W83791D_REG_FAN_DIV[indx], -+ fan_div_reg | tmp_fan_div); -+ -+ /* Restore fan_min */ -+ data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); -+ w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); -+ -+#ifdef DEBUG -+err_exit: -+#endif -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+static struct sensor_device_attribute sda_fan_input[] = { -+ SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), -+ SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), -+ SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), -+ SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), -+ SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), -+}; -+ -+static struct sensor_device_attribute sda_fan_min[] = { -+ SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, -+ show_fan_min, store_fan_min, 0), -+ SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, -+ show_fan_min, store_fan_min, 1), -+ SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, -+ show_fan_min, store_fan_min, 2), -+ SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, -+ show_fan_min, store_fan_min, 3), -+ SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, -+ show_fan_min, store_fan_min, 4), -+}; -+ -+static struct sensor_device_attribute sda_fan_div[] = { -+ SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, -+ show_fan_div, store_fan_div, 0), -+ SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, -+ show_fan_div, store_fan_div, 1), -+ SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO, -+ show_fan_div, store_fan_div, 2), -+ SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO, -+ show_fan_div, store_fan_div, 3), -+ SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO, -+ show_fan_div, store_fan_div, 4), -+}; -+ -+/* read/write the temperature1, includes measured value and limits */ -+static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -+ struct w83791d_data *data = w83791d_update_device(dev); -+ return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[attr->index])); -+} -+ -+static ssize_t store_temp1(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 w83791d_data *data = i2c_get_clientdata(client); -+ long val = simple_strtol(buf, NULL, 10); -+ int nr = attr->index; -+ -+ mutex_lock(&data->update_lock); -+ data->temp1[nr] = TEMP1_TO_REG(val); -+ w83791d_write(client, W83791D_REG_TEMP1[nr], data->temp1[nr]); -+ mutex_unlock(&data->update_lock); -+ return count; -+} -+ -+/* read/write temperature2-3, includes measured value and limits */ -+static ssize_t show_temp23(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); -+ struct w83791d_data *data = w83791d_update_device(dev); -+ int nr = attr->nr; -+ int index = attr->index; -+ return sprintf(buf, "%d\n", TEMP23_FROM_REG(data->temp_add[nr][index])); -+} -+ -+static ssize_t store_temp23(struct device *dev, -+ struct device_attribute *devattr, -+ const char *buf, size_t count) -+{ -+ 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); -+ int nr = attr->nr; -+ int index = attr->index; -+ -+ mutex_lock(&data->update_lock); -+ data->temp_add[nr][index] = TEMP23_TO_REG(val); -+ w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2], -+ data->temp_add[nr][index] >> 8); -+ w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2 + 1], -+ data->temp_add[nr][index] & 0x80); -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+static struct sensor_device_attribute_2 sda_temp_input[] = { -+ SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0), -+ SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0), -+ SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0), -+}; -+ -+static struct sensor_device_attribute_2 sda_temp_max[] = { -+ SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, -+ show_temp1, store_temp1, 0, 1), -+ SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, -+ show_temp23, store_temp23, 0, 1), -+ SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, -+ show_temp23, store_temp23, 1, 1), -+}; -+ -+static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { -+ SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, -+ show_temp1, store_temp1, 0, 2), -+ SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, -+ show_temp23, store_temp23, 0, 2), -+ SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, -+ show_temp23, store_temp23, 1, 2), -+}; -+ -+ -+/* get reatime status of all sensors items: voltage, temp, fan */ -+static ssize_t show_alarms_reg(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w83791d_data *data = w83791d_update_device(dev); -+ return sprintf(buf, "%u\n", data->alarms); -+} -+ -+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); -+ -+/* Beep control */ -+ -+#define GLOBAL_BEEP_ENABLE_SHIFT 15 -+#define GLOBAL_BEEP_ENABLE_MASK (1 << GLOBAL_BEEP_ENABLE_SHIFT) -+ -+static ssize_t show_beep_enable(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w83791d_data *data = w83791d_update_device(dev); -+ return sprintf(buf, "%d\n", data->beep_enable); -+} -+ -+static ssize_t show_beep_mask(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w83791d_data *data = w83791d_update_device(dev); -+ return sprintf(buf, "%d\n", BEEP_MASK_FROM_REG(data->beep_mask)); -+} -+ -+ -+static ssize_t store_beep_mask(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ 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; -+ -+ mutex_lock(&data->update_lock); -+ -+ /* 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); -+ -+ val = data->beep_mask; -+ -+ for (i = 0; i < 3; i++) { -+ w83791d_write(client, W83791D_REG_BEEP_CTRL[i], (val & 0xff)); -+ val >>= 8; -+ } -+ -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+static ssize_t store_beep_enable(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct w83791d_data *data = i2c_get_clientdata(client); -+ long val = simple_strtol(buf, NULL, 10); -+ -+ mutex_lock(&data->update_lock); -+ -+ data->beep_enable = val ? 1 : 0; -+ -+ /* Keep the full mask value in sync with the current enable */ -+ 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 */ -+ val = (data->beep_mask >> 8) & 0xff; -+ -+ w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val); -+ -+ mutex_unlock(&data->update_lock); -+ -+ return count; -+} -+ -+static struct sensor_device_attribute sda_beep_ctrl[] = { -+ SENSOR_ATTR(beep_enable, S_IRUGO | S_IWUSR, -+ show_beep_enable, store_beep_enable, 0), -+ SENSOR_ATTR(beep_mask, S_IRUGO | S_IWUSR, -+ show_beep_mask, store_beep_mask, 1) -+}; -+ -+/* cpu voltage regulation information */ -+static ssize_t show_vid_reg(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w83791d_data *data = w83791d_update_device(dev); -+ return sprintf(buf, "%d\n", vid_from_reg(data->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) -+{ -+ struct w83791d_data *data = w83791d_update_device(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) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct w83791d_data *data = i2c_get_clientdata(client); -+ unsigned long val = simple_strtoul(buf, NULL, 10); -+ -+ /* 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 = val; -+ -+ return count; -+} -+ -+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); -+ -+/* This function is called when: -+ * w83791d_driver is inserted (when this module is loaded), for each -+ available adapter -+ * when a new adapter is inserted (and w83791d_driver is still present) */ -+static int w83791d_attach_adapter(struct i2c_adapter *adapter) -+{ -+ if (!(adapter->class & I2C_CLASS_HWMON)) -+ return 0; -+ return i2c_probe(adapter, &addr_data, w83791d_detect); -+} -+ -+ -+static int w83791d_create_subclient(struct i2c_adapter *adapter, -+ struct i2c_client *client, int addr, -+ struct i2c_client **sub_cli) -+{ -+ int err; -+ struct i2c_client *sub_client; -+ -+ (*sub_cli) = sub_client = -+ kzalloc(sizeof(struct i2c_client), GFP_KERNEL); -+ if (!(sub_client)) { -+ return -ENOMEM; -+ } -+ sub_client->addr = 0x48 + addr; -+ i2c_set_clientdata(sub_client, NULL); -+ sub_client->adapter = adapter; -+ sub_client->driver = &w83791d_driver; -+ strlcpy(sub_client->name, "w83791d subclient", I2C_NAME_SIZE); -+ if ((err = i2c_attach_client(sub_client))) { -+ dev_err(&client->dev, "subclient registration " -+ "at address 0x%x failed\n", sub_client->addr); -+ kfree(sub_client); -+ return err; -+ } -+ return 0; -+} -+ -+ -+static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address, -+ int kind, struct i2c_client *client) -+{ -+ struct w83791d_data *data = i2c_get_clientdata(client); -+ int i, id, err; -+ u8 val; -+ -+ id = i2c_adapter_id(adapter); -+ if (force_subclients[0] == id && force_subclients[1] == address) { -+ for (i = 2; i <= 3; i++) { -+ if (force_subclients[i] < 0x48 || -+ force_subclients[i] > 0x4f) { -+ dev_err(&client->dev, -+ "invalid subclient " -+ "address %d; must be 0x48-0x4f\n", -+ force_subclients[i]); -+ err = -ENODEV; -+ goto error_sc_0; -+ } -+ } -+ w83791d_write(client, W83791D_REG_I2C_SUBADDR, -+ (force_subclients[2] & 0x07) | -+ ((force_subclients[3] & 0x07) << 4)); -+ } -+ -+ val = w83791d_read(client, W83791D_REG_I2C_SUBADDR); -+ if (!(val & 0x08)) { -+ err = w83791d_create_subclient(adapter, client, -+ val & 0x7, &data->lm75[0]); -+ if (err < 0) -+ goto error_sc_0; -+ } -+ if (!(val & 0x80)) { -+ if ((data->lm75[0] != NULL) && -+ ((val & 0x7) == ((val >> 4) & 0x7))) { -+ dev_err(&client->dev, -+ "duplicate addresses 0x%x, " -+ "use force_subclient\n", -+ data->lm75[0]->addr); -+ err = -ENODEV; -+ goto error_sc_1; -+ } -+ err = w83791d_create_subclient(adapter, client, -+ (val >> 4) & 0x7, &data->lm75[1]); -+ if (err < 0) -+ goto error_sc_1; -+ } -+ -+ return 0; -+ -+/* Undo inits in case of errors */ -+ -+error_sc_1: -+ if (data->lm75[0] != NULL) { -+ i2c_detach_client(data->lm75[0]); -+ kfree(data->lm75[0]); -+ } -+error_sc_0: -+ return err; -+} -+ -+ -+static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) -+{ -+ struct i2c_client *client; -+ struct device *dev; -+ struct w83791d_data *data; -+ int i, val1, val2; -+ int err = 0; -+ const char *client_name = ""; -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { -+ goto error0; -+ } -+ -+ /* OK. For now, we presume we have a valid client. We now create the -+ client structure, even though we cannot fill it completely yet. -+ But it allows us to access w83791d_{read,write}_value. */ -+ if (!(data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL))) { -+ err = -ENOMEM; -+ goto error0; -+ } -+ -+ client = &data->client; -+ dev = &client->dev; -+ i2c_set_clientdata(client, data); -+ client->addr = address; -+ client->adapter = adapter; -+ client->driver = &w83791d_driver; -+ mutex_init(&data->update_lock); -+ -+ /* Now, we do the remaining detection. */ -+ -+ /* The w83791d may be stuck in some other bank than bank 0. This may -+ make reading other information impossible. Specify a force=... -+ parameter, and the Winbond will be reset to the right bank. */ -+ if (kind < 0) { -+ if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) { -+ dev_dbg(dev, "Detection failed at step 1\n"); -+ goto error1; -+ } -+ val1 = w83791d_read(client, W83791D_REG_BANK); -+ val2 = w83791d_read(client, W83791D_REG_CHIPMAN); -+ /* Check for Winbond ID if in bank 0 */ -+ if (!(val1 & 0x07)) { -+ /* yes it is Bank0 */ -+ if (((!(val1 & 0x80)) && (val2 != 0xa3)) || -+ ((val1 & 0x80) && (val2 != 0x5c))) { -+ dev_dbg(dev, "Detection failed at step 2\n"); -+ goto error1; -+ } -+ } -+ /* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR -+ should match */ -+ if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) { -+ dev_dbg(dev, "Detection failed at step 3\n"); -+ goto error1; -+ } -+ } -+ -+ /* We either have a force parameter or we have reason to -+ believe it is a Winbond chip. Either way, we want bank 0 and -+ Vendor ID high byte */ -+ val1 = w83791d_read(client, W83791D_REG_BANK) & 0x78; -+ w83791d_write(client, W83791D_REG_BANK, val1 | 0x80); -+ -+ /* Verify it is a Winbond w83791d */ -+ if (kind <= 0) { -+ /* get vendor ID */ -+ val2 = w83791d_read(client, W83791D_REG_CHIPMAN); -+ if (val2 != 0x5c) { /* the vendor is NOT Winbond */ -+ dev_dbg(dev, "Detection failed at step 4\n"); -+ goto error1; -+ } -+ val1 = w83791d_read(client, W83791D_REG_WCHIPID); -+ if (val1 == 0x71) { -+ kind = w83791d; -+ } else { -+ if (kind == 0) -+ dev_warn(dev, -+ "w83791d: Ignoring 'force' parameter " -+ "for unknown chip at adapter %d, " -+ "address 0x%02x\n", -+ i2c_adapter_id(adapter), address); -+ goto error1; -+ } -+ } -+ -+ if (kind == w83791d) { -+ client_name = "w83791d"; -+ } else { -+ dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?", -+ kind); -+ goto error1; -+ } -+ -+#ifdef DEBUG -+ val1 = w83791d_read(client, W83791D_REG_DID_VID4); -+ dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", -+ (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); -+#endif -+ -+ /* Fill in the remaining client fields and put into the global list */ -+ strlcpy(client->name, client_name, I2C_NAME_SIZE); -+ -+ /* Tell the I2C layer a new client has arrived */ -+ if ((err = i2c_attach_client(client))) -+ goto error1; -+ -+ if ((err = w83791d_detect_subclients(adapter, address, kind, client))) -+ goto error2; -+ -+ /* 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++) { -+ data->fan_min[i] = w83791d_read(client, W83791D_REG_FAN_MIN[i]); -+ } -+ -+ /* Register sysfs hooks */ -+ data->class_dev = hwmon_device_register(dev); -+ if (IS_ERR(data->class_dev)) { -+ err = PTR_ERR(data->class_dev); -+ goto error3; -+ } -+ -+ for (i = 0; i < NUMBER_OF_VIN; i++) { -+ device_create_file(dev, &sda_in_input[i].dev_attr); -+ device_create_file(dev, &sda_in_min[i].dev_attr); -+ device_create_file(dev, &sda_in_max[i].dev_attr); -+ } -+ -+ for (i = 0; i < NUMBER_OF_FANIN; i++) { -+ device_create_file(dev, &sda_fan_input[i].dev_attr); -+ device_create_file(dev, &sda_fan_div[i].dev_attr); -+ device_create_file(dev, &sda_fan_min[i].dev_attr); -+ } -+ -+ for (i = 0; i < NUMBER_OF_TEMPIN; i++) { -+ device_create_file(dev, &sda_temp_input[i].dev_attr); -+ device_create_file(dev, &sda_temp_max[i].dev_attr); -+ device_create_file(dev, &sda_temp_max_hyst[i].dev_attr); -+ } -+ -+ device_create_file(dev, &dev_attr_alarms); -+ -+ for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) { -+ device_create_file(dev, &sda_beep_ctrl[i].dev_attr); -+ } -+ -+ device_create_file(dev, &dev_attr_cpu0_vid); -+ device_create_file(dev, &dev_attr_vrm); -+ -+ return 0; -+ -+error3: -+ if (data->lm75[0] != NULL) { -+ i2c_detach_client(data->lm75[0]); -+ kfree(data->lm75[0]); -+ } -+ if (data->lm75[1] != NULL) { -+ i2c_detach_client(data->lm75[1]); -+ kfree(data->lm75[1]); -+ } -+error2: -+ i2c_detach_client(client); -+error1: -+ kfree(data); -+error0: -+ return err; -+} -+ -+static int w83791d_detach_client(struct i2c_client *client) -+{ -+ struct w83791d_data *data = i2c_get_clientdata(client); -+ int err; -+ -+ /* main client */ -+ if (data) -+ hwmon_device_unregister(data->class_dev); -+ -+ if ((err = i2c_detach_client(client))) -+ return err; -+ -+ /* main client */ -+ if (data) -+ kfree(data); -+ /* subclient */ -+ else -+ kfree(client); -+ -+ return 0; -+} -+ -+static void w83791d_init_client(struct i2c_client *client) -+{ -+ struct w83791d_data *data = i2c_get_clientdata(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. -+ */ -+ if (reset || init) { -+ /* keep some BIOS settings when we... */ -+ old_beep = w83791d_read(client, W83791D_REG_BEEP_CONFIG); -+ -+ if (reset) { -+ /* ... reset the chip and ... */ -+ w83791d_write(client, W83791D_REG_CONFIG, 0x80); -+ } -+ -+ /* ... disable power-on abnormal beep */ -+ w83791d_write(client, W83791D_REG_BEEP_CONFIG, old_beep | 0x80); -+ -+ /* disable the global beep (not done by hard reset) */ -+ tmp = w83791d_read(client, W83791D_REG_BEEP_CTRL[1]); -+ w83791d_write(client, W83791D_REG_BEEP_CTRL[1], tmp & 0xef); -+ -+ if (init) { -+ /* Make sure monitoring is turned on for add-ons */ -+ tmp = w83791d_read(client, W83791D_REG_TEMP2_CONFIG); -+ if (tmp & 1) { -+ w83791d_write(client, W83791D_REG_TEMP2_CONFIG, -+ tmp & 0xfe); -+ } -+ -+ tmp = w83791d_read(client, W83791D_REG_TEMP3_CONFIG); -+ if (tmp & 1) { -+ w83791d_write(client, W83791D_REG_TEMP3_CONFIG, -+ tmp & 0xfe); -+ } -+ -+ /* Start monitoring */ -+ tmp = w83791d_read(client, W83791D_REG_CONFIG) & 0xf7; -+ w83791d_write(client, W83791D_REG_CONFIG, tmp | 0x01); -+ } -+ } -+ -+ data->vrm = vid_which_vrm(); -+} -+ -+static struct w83791d_data *w83791d_update_device(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct w83791d_data *data = i2c_get_clientdata(client); -+ int i, j; -+ u8 reg_array_tmp[3]; -+ -+ mutex_lock(&data->update_lock); -+ -+ if (time_after(jiffies, data->last_updated + (HZ * 3)) -+ || !data->valid) { -+ dev_dbg(dev, "Starting w83791d device update\n"); -+ -+ /* Update the voltages measured value and limits */ -+ for (i = 0; i < NUMBER_OF_VIN; i++) { -+ data->in[i] = w83791d_read(client, -+ W83791D_REG_IN[i]); -+ data->in_max[i] = w83791d_read(client, -+ W83791D_REG_IN_MAX[i]); -+ data->in_min[i] = w83791d_read(client, -+ W83791D_REG_IN_MIN[i]); -+ } -+ -+ /* Update the fan counts and limits */ -+ for (i = 0; i < NUMBER_OF_FANIN; i++) { -+ /* Update the Fan measured value and limits */ -+ data->fan[i] = w83791d_read(client, -+ W83791D_REG_FAN[i]); -+ data->fan_min[i] = w83791d_read(client, -+ W83791D_REG_FAN_MIN[i]); -+ } -+ -+ /* Update the fan divisor */ -+ for (i = 0; i < 3; i++) { -+ reg_array_tmp[i] = w83791d_read(client, -+ W83791D_REG_FAN_DIV[i]); -+ } -+ data->fan_div[0] = (reg_array_tmp[0] >> 4) & 0x03; -+ data->fan_div[1] = (reg_array_tmp[0] >> 6) & 0x03; -+ data->fan_div[2] = (reg_array_tmp[1] >> 6) & 0x03; -+ data->fan_div[3] = reg_array_tmp[2] & 0x07; -+ data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; -+ -+ /* Update the first temperature sensor */ -+ for (i = 0; i < 3; i++) { -+ data->temp1[i] = w83791d_read(client, -+ W83791D_REG_TEMP1[i]); -+ } -+ -+ /* Update the rest of the temperature sensors */ -+ for (i = 0; i < 2; i++) { -+ for (j = 0; j < 3; j++) { -+ data->temp_add[i][j] = -+ (w83791d_read(client, -+ W83791D_REG_TEMP_ADD[i][j * 2]) << 8) | -+ w83791d_read(client, -+ W83791D_REG_TEMP_ADD[i][j * 2 + 1]); -+ } -+ } -+ -+ /* Update the realtime status */ -+ data->alarms = -+ w83791d_read(client, W83791D_REG_ALARM1) + -+ (w83791d_read(client, W83791D_REG_ALARM2) << 8) + -+ (w83791d_read(client, W83791D_REG_ALARM3) << 16); -+ -+ /* Update the beep configuration information */ -+ data->beep_mask = -+ w83791d_read(client, W83791D_REG_BEEP_CTRL[0]) + -+ (w83791d_read(client, W83791D_REG_BEEP_CTRL[1]) << 8) + -+ (w83791d_read(client, W83791D_REG_BEEP_CTRL[2]) << 16); -+ -+ data->beep_enable = -+ (data->beep_mask >> GLOBAL_BEEP_ENABLE_SHIFT) & 0x01; -+ -+ /* Update the cpu voltage information */ -+ i = w83791d_read(client, W83791D_REG_VID_FANDIV); -+ data->vid = i & 0x0f; -+ data->vid |= (w83791d_read(client, W83791D_REG_DID_VID4) & 0x01) -+ << 4; -+ -+ data->last_updated = jiffies; -+ data->valid = 1; -+ } -+ -+ mutex_unlock(&data->update_lock); -+ -+#ifdef DEBUG -+ w83791d_print_debug(data, dev); -+#endif -+ -+ return data; -+} -+ -+#ifdef DEBUG -+static void w83791d_print_debug(struct w83791d_data *data, struct device *dev) -+{ -+ int i = 0, j = 0; -+ -+ dev_dbg(dev, "======Start of w83791d debug values======\n"); -+ dev_dbg(dev, "%d set of Voltages: ===>\n", NUMBER_OF_VIN); -+ for (i = 0; i < NUMBER_OF_VIN; i++) { -+ dev_dbg(dev, "vin[%d] is: 0x%02x\n", i, data->in[i]); -+ dev_dbg(dev, "vin[%d] min is: 0x%02x\n", i, data->in_min[i]); -+ dev_dbg(dev, "vin[%d] max is: 0x%02x\n", i, data->in_max[i]); -+ } -+ dev_dbg(dev, "%d set of Fan Counts/Divisors: ===>\n", NUMBER_OF_FANIN); -+ for (i = 0; i < NUMBER_OF_FANIN; i++) { -+ dev_dbg(dev, "fan[%d] is: 0x%02x\n", i, data->fan[i]); -+ dev_dbg(dev, "fan[%d] min is: 0x%02x\n", i, data->fan_min[i]); -+ 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 */ -+ dev_dbg(dev, "%d set of Temperatures: ===>\n", NUMBER_OF_TEMPIN); -+ 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, -+ (u16) data->temp_add[i][j]); -+ } -+ } -+ -+ dev_dbg(dev, "Misc Information: ===>\n"); -+ dev_dbg(dev, "alarm is: 0x%08x\n", data->alarms); -+ dev_dbg(dev, "beep_mask is: 0x%08x\n", data->beep_mask); -+ dev_dbg(dev, "beep_enable is: %d\n", data->beep_enable); -+ dev_dbg(dev, "vid is: 0x%02x\n", data->vid); -+ dev_dbg(dev, "vrm is: 0x%02x\n", data->vrm); -+ dev_dbg(dev, "=======End of w83791d debug values========\n"); -+ dev_dbg(dev, "\n"); -+} -+#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_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/i2c/hwmon-w83792d-add-data-lock.patch b/i2c/hwmon-w83792d-add-data-lock.patch deleted file mode 100644 index 191f6c91446958..00000000000000 --- a/i2c/hwmon-w83792d-add-data-lock.patch +++ /dev/null @@ -1,194 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:18:49 2006 -Date: Sun, 4 Jun 2006 20:18:45 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Yuan Mu <ymu@winbond.com.tw> -Subject: w83792d: Add missing data access locks -Message-Id: <20060604201845.12ea5bfe.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-w83792d-add-data-lock.patch - -From: Yuan Mu <ymu@winbond.com.tw> - -Add missing data lock in w83792d driver to avoid unexpected -data change. - -Signed-off-by: Yuan Mu <ymu@winbond.com.tw> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/w83792d.c | 30 +++++++++++++++++++++++++----- - 1 file changed, 25 insertions(+), 5 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/w83792d.c -+++ gregkh-2.6/drivers/hwmon/w83792d.c -@@ -372,8 +372,10 @@ static ssize_t store_in_##reg (struct de - u32 val; \ - \ - val = simple_strtoul(buf, NULL, 10); \ -+ 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]); \ -+ mutex_unlock(&data->update_lock); \ - \ - return count; \ - } -@@ -440,9 +442,11 @@ store_fan_min(struct device *dev, struct - u32 val; - - 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], - data->fan_min[nr]); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -475,6 +479,7 @@ store_fan_div(struct device *dev, struct - u8 tmp_fan_div; - - /* Save fan_min */ -+ mutex_lock(&data->update_lock); - min = FAN_FROM_REG(data->fan_min[nr], - DIV_FROM_REG(data->fan_div[nr])); - -@@ -490,6 +495,7 @@ store_fan_div(struct device *dev, struct - /* Restore fan_min */ - data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); - w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -544,10 +550,11 @@ static ssize_t store_temp1(struct device - s32 val; - - 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], - data->temp1[nr]); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -577,13 +584,14 @@ static ssize_t store_temp23(struct devic - s32 val; - - 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); - w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index], - data->temp_add[nr][index]); - w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1], - data->temp_add[nr][index+1]); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -682,6 +690,10 @@ store_pwmenable(struct device *dev, stru - u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp; - - val = simple_strtoul(buf, NULL, 10); -+ if (val < 1 || val > 3) -+ return -EINVAL; -+ -+ mutex_lock(&data->update_lock); - switch (val) { - case 1: - data->pwmenable[nr] = 0; /* manual mode */ -@@ -692,8 +704,6 @@ store_pwmenable(struct device *dev, stru - case 3: - data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */ - break; -- default: -- return -EINVAL; - } - cfg1_tmp = data->pwmenable[0]; - cfg2_tmp = (data->pwmenable[1]) << 2; -@@ -701,6 +711,7 @@ store_pwmenable(struct device *dev, stru - 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); - - return count; - } -@@ -794,12 +805,13 @@ store_chassis_clear(struct device *dev, - u8 temp1 = 0, temp2 = 0; - - val = simple_strtoul(buf, NULL, 10); -- -+ mutex_lock(&data->update_lock); - data->chassis_clear = SENSORS_LIMIT(val, 0 ,1); - temp1 = ((data->chassis_clear) << 7) & 0x80; - temp2 = w83792d_read_value(client, - W83792D_REG_CHASSIS_CLR) & 0x7f; - w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -832,10 +844,12 @@ store_thermal_cruise(struct device *dev, - 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; - data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255); - w83792d_write_value(client, W83792D_REG_THERMAL[nr], - (data->thermal_cruise[nr]) | target_mask); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -872,6 +886,7 @@ store_tolerance(struct device *dev, stru - u8 tol_tmp, tol_mask; - - 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); -@@ -882,6 +897,7 @@ store_tolerance(struct device *dev, stru - } - w83792d_write_value(client, W83792D_REG_TOLERANCE[nr], - tol_mask | tol_tmp); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -920,11 +936,13 @@ store_sf2_point(struct device *dev, stru - u8 mask_tmp = 0; - - 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, - W83792D_REG_POINTS[index][nr]) & 0x80; - w83792d_write_value(client, W83792D_REG_POINTS[index][nr], - mask_tmp|data->sf2_points[index][nr]); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -984,6 +1002,7 @@ store_sf2_level(struct device *dev, stru - u8 mask_tmp=0, level_tmp=0; - - 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); -@@ -993,6 +1012,7 @@ store_sf2_level(struct device *dev, stru - level_tmp = data->sf2_levels[index][nr] << 4; - } - w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp); -+ mutex_unlock(&data->update_lock); - - return count; - } diff --git a/i2c/hwmon-w83792d-pwm-set-fix.patch b/i2c/hwmon-w83792d-pwm-set-fix.patch deleted file mode 100644 index 2f31e8478640cc..00000000000000 --- a/i2c/hwmon-w83792d-pwm-set-fix.patch +++ /dev/null @@ -1,173 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:18:08 2006 -Date: Sun, 4 Jun 2006 20:18:05 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Yuan Mu <ymu@winbond.com.tw> -Subject: w83792d: Fix setting the PWM value -Message-Id: <20060604201805.49585bea.khali@linux-fr.org> -Content-Disposition: inline; filename=hwmon-w83792d-pwm-set-fix.patch - -From: Yuan Mu <ymu@winbond.com.tw> - -W83792D use pwm register low 4 bits to store PWM/DC value, bit 7 -is used to store fan PWM/DC mode. The store_pwm function did not -convert the pwm input correctly, so it may change the fan mode -when new value is set. - -This fix the problem. Change the "index" value of pwm*_mode -and pwm* SENSOR_ATTR to simplify code. - -Signed-off-by: Yuan Mu <ymu@winbond.com.tw> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/hwmon/w83792d.c | 56 ++++++++++++++++++++++++------------------------ - 1 file changed, 29 insertions(+), 27 deletions(-) - ---- gregkh-2.6.orig/drivers/hwmon/w83792d.c -+++ gregkh-2.6/drivers/hwmon/w83792d.c -@@ -250,8 +250,6 @@ FAN_TO_REG(long rpm, int div) - : (val)) / 1000, 0, 0xff)) - #define TEMP_ADD_TO_REG_LOW(val) ((val%1000) ? 0x80 : 0x00) - --#define PWM_FROM_REG(val) (val) --#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) - #define DIV_FROM_REG(val) (1 << (val)) - - static inline u8 -@@ -291,7 +289,6 @@ struct w83792d_data { - u8 pwm[7]; /* We only consider the first 3 set of pwm, - although 792 chip has 7 set of pwm. */ - u8 pwmenable[3]; -- u8 pwm_mode[7]; /* indicates PWM or DC mode: 1->PWM; 0->DC */ - u32 alarms; /* realtime status register encoding,combined */ - u8 chassis; /* Chassis status */ - u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */ -@@ -627,7 +624,7 @@ show_pwm(struct device *dev, struct devi - 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) PWM_FROM_REG(data->pwm[nr-1])); -+ return sprintf(buf, "%d\n", (data->pwm[nr] & 0x0f) << 4); - } - - static ssize_t -@@ -659,14 +656,16 @@ store_pwm(struct device *dev, struct dev - const char *buf, size_t count) - { - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -- int nr = sensor_attr->index - 1; -+ int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83792d_data *data = i2c_get_clientdata(client); -- u32 val; -+ u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255) >> 4; - -- val = simple_strtoul(buf, NULL, 10); -- data->pwm[nr] = PWM_TO_REG(val); -+ mutex_lock(&data->update_lock); -+ val |= w83792d_read_value(client, W83792D_REG_PWM[nr]) & 0xf0; -+ data->pwm[nr] = val; - w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]); -+ mutex_unlock(&data->update_lock); - - return count; - } -@@ -707,9 +706,9 @@ store_pwmenable(struct device *dev, stru - } - - static struct sensor_device_attribute sda_pwm[] = { -- SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), -- SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), -- SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3), -+ SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0), -+ SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), -+ SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), - }; - static struct sensor_device_attribute sda_pwm_enable[] = { - SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, -@@ -728,7 +727,7 @@ show_pwm_mode(struct device *dev, struct - 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, "%d\n", data->pwm_mode[nr-1]); -+ return sprintf(buf, "%d\n", data->pwm[nr] >> 7); - } - - static ssize_t -@@ -736,29 +735,35 @@ store_pwm_mode(struct device *dev, struc - const char *buf, size_t count) - { - struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); -- int nr = sensor_attr->index - 1; -+ int nr = sensor_attr->index; - struct i2c_client *client = to_i2c_client(dev); - struct w83792d_data *data = i2c_get_clientdata(client); - u32 val; -- u8 pwm_mode_mask = 0; - - val = simple_strtoul(buf, NULL, 10); -- data->pwm_mode[nr] = SENSORS_LIMIT(val, 0, 1); -- pwm_mode_mask = w83792d_read_value(client, -- W83792D_REG_PWM[nr]) & 0x7f; -- w83792d_write_value(client, W83792D_REG_PWM[nr], -- ((data->pwm_mode[nr]) << 7) | pwm_mode_mask); -+ if (val != 0 && val != 1) -+ return -EINVAL; -+ -+ mutex_lock(&data->update_lock); -+ data->pwm[nr] = w83792d_read_value(client, W83792D_REG_PWM[nr]); -+ if (val) { /* PWM mode */ -+ data->pwm[nr] |= 0x80; -+ } else { /* DC mode */ -+ data->pwm[nr] &= 0x7f; -+ } -+ w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]); -+ mutex_unlock(&data->update_lock); - - return count; - } - - static struct sensor_device_attribute sda_pwm_mode[] = { - SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, -- show_pwm_mode, store_pwm_mode, 1), -+ show_pwm_mode, store_pwm_mode, 0), - SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, -- show_pwm_mode, store_pwm_mode, 2), -+ show_pwm_mode, store_pwm_mode, 1), - SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, -- show_pwm_mode, store_pwm_mode, 3), -+ show_pwm_mode, store_pwm_mode, 2), - }; - - -@@ -1373,7 +1378,7 @@ static struct w83792d_data *w83792d_upda - struct i2c_client *client = to_i2c_client(dev); - struct w83792d_data *data = i2c_get_clientdata(client); - int i, j; -- u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp; -+ u8 reg_array_tmp[4], reg_tmp; - - mutex_lock(&data->update_lock); - -@@ -1402,10 +1407,8 @@ static struct w83792d_data *w83792d_upda - data->fan_min[i] = w83792d_read_value(client, - W83792D_REG_FAN_MIN[i]); - /* Update the PWM/DC Value and PWM/DC flag */ -- pwm_array_tmp[i] = w83792d_read_value(client, -+ data->pwm[i] = w83792d_read_value(client, - W83792D_REG_PWM[i]); -- data->pwm[i] = pwm_array_tmp[i] & 0x0f; -- data->pwm_mode[i] = pwm_array_tmp[i] >> 7; - } - - reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); -@@ -1513,7 +1516,6 @@ static void w83792d_print_debug(struct w - 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, "pwm_mode[%d] is: 0x%x\n", i, data->pwm_mode[i]); - } - dev_dbg(dev, "3 set of Temperatures: =====>\n"); - for (i=0; i<3; i++) { diff --git a/i2c/i2c-Kconfig-suggest-N-for-rare-devices.patch b/i2c/i2c-Kconfig-suggest-N-for-rare-devices.patch deleted file mode 100644 index b129beaf081fbd..00000000000000 --- a/i2c/i2c-Kconfig-suggest-N-for-rare-devices.patch +++ /dev/null @@ -1,88 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:00:01 2006 -Date: Sun, 4 Jun 2006 19:59:57 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: i2c: Suggest N for rare devices in Kconfig -Message-Id: <20060604195957.ff0438f5.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-Kconfig-suggest-N-for-rare-devices.patch - -Improve the Kconfig help text of the follwing i2c drivers: -* busses/i2c-pca-isa.c -* chips/pcf8574.c -* chips/pcf8591.c -These are hard to detect and building them into the kernel -results in long delays at boot. - -March 2006, thread "I2C_PCA_ISA causes boot delays" -http://marc.theaimsgroup.com/?l=linux-kernel&m=114360399415744&w=2 - -April 2006, thread "i2c-related 1-minute hang during bootup" -http://marc.theaimsgroup.com/?l=linux-kernel&m=114640992330721&w=2 - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/Kconfig | 6 ++++++ - drivers/i2c/chips/Kconfig | 8 ++++++++ - 2 files changed, 14 insertions(+) - ---- gregkh-2.6.orig/drivers/i2c/busses/Kconfig -+++ gregkh-2.6/drivers/i2c/busses/Kconfig -@@ -503,6 +503,7 @@ config I2C_PCA_ISA - tristate "PCA9564 on an ISA bus" - depends on I2C - select I2C_ALGOPCA -+ default n - help - This driver supports ISA boards using the Philips PCA 9564 - Parallel bus to I2C bus controller -@@ -510,6 +511,11 @@ config I2C_PCA_ISA - This driver can also be built as a module. If so, the module - will be called i2c-pca-isa. - -+ This device is almost undetectable and using this driver on a -+ system which doesn't have this device will result in long -+ delays when I2C/SMBus chip drivers are loaded (e.g. at boot -+ time). If unsure, say N. -+ - config I2C_MV64XXX - tristate "Marvell mv64xxx I2C Controller" - depends on I2C && MV64X60 && EXPERIMENTAL ---- gregkh-2.6.orig/drivers/i2c/chips/Kconfig -+++ gregkh-2.6/drivers/i2c/chips/Kconfig -@@ -39,6 +39,7 @@ config SENSORS_EEPROM - config SENSORS_PCF8574 - tristate "Philips PCF8574 and PCF8574A" - depends on I2C && EXPERIMENTAL -+ default n - help - If you say yes here you get support for Philips PCF8574 and - PCF8574A chips. -@@ -46,6 +47,9 @@ config SENSORS_PCF8574 - This driver can also be built as a module. If so, the module - will be called pcf8574. - -+ These devices are hard to detect and rarely found on mainstream -+ hardware. If unsure, say N. -+ - config SENSORS_PCA9539 - tristate "Philips PCA9539 16-bit I/O port" - depends on I2C && EXPERIMENTAL -@@ -59,12 +63,16 @@ config SENSORS_PCA9539 - config SENSORS_PCF8591 - tristate "Philips PCF8591" - depends on I2C && EXPERIMENTAL -+ default n - help - If you say yes here you get support for Philips PCF8591 chips. - - This driver can also be built as a module. If so, the module - will be called pcf8591. - -+ These devices are hard to detect and rarely found on mainstream -+ hardware. If unsure, say N. -+ - config ISP1301_OMAP - tristate "Philips ISP1301 with OMAP OTG" - depends on I2C && ARCH_OMAP_OTG diff --git a/i2c/i2c-i2c-controllers-go-into-right-place-on-sysfs.patch b/i2c/i2c-i2c-controllers-go-into-right-place-on-sysfs.patch deleted file mode 100644 index 527b67f94cf075..00000000000000 --- a/i2c/i2c-i2c-controllers-go-into-right-place-on-sysfs.patch +++ /dev/null @@ -1,33 +0,0 @@ -From david-b@pacbell.net Tue Jun 13 09:47:37 2006 -From: David Brownell <david-b@pacbell.net> -To: Greg KH <greg@kroah.com> -Subject: I2C: I2C controllers go into right place on sysfs -Date: Tue, 13 Jun 2006 09:47:27 -0700 -Cc: Jean Delvare <khali@linux-fr.org> -Message-Id: <200606130947.28074.david-b@pacbell.net> - -I2C creates some sysfs nodes in the wrong places: not as children of parent -controllers, but as their peers (!). This puts them into the right place -always, instead of just when the adapter is on the platform bus. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/i2c-dev.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/i2c-dev.c -+++ gregkh-2.6/drivers/i2c/i2c-dev.c -@@ -426,10 +426,7 @@ static int i2cdev_attach_adapter(struct - - /* register this i2c device with the driver core */ - i2c_dev->adap = adap; -- if (adap->dev.parent == &platform_bus) -- dev = &adap->dev; -- else -- dev = adap->dev.parent; -+ dev = &adap->dev; - i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, - MKDEV(I2C_MAJOR, i2c_dev->minor), - dev, "i2c-%d", i2c_dev->minor); diff --git a/i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch b/i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch deleted file mode 100644 index cfbfec3780004c..00000000000000 --- a/i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch +++ /dev/null @@ -1,45 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:49:39 2006 -Date: Mon, 12 Jun 2006 21:49:36 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org> -Subject: [PATCH 06/14] i2c-i801: Fix block transaction poll loops -Message-Id: <20060612214936.d81fd1b9.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-i801-01-fix-block-transaction-poll-loops.patch - -i2c-i801: Fix block transaction poll loops - -Two of the three poll loops have the poll and sleep swapped, -causing an extra sleep to occur after the polled condition is -fulfilled. In practice, this doubles the amount of sleep time for -every block transaction. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/i2c-i801.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c -@@ -334,8 +334,8 @@ static int i801_block_transaction(union - /* We will always wait for a fraction of a second! */ - timeout = 0; - do { -- temp = inb_p(SMBHSTSTS); - msleep(1); -+ temp = inb_p(SMBHSTSTS); - } - while ((!(temp & 0x80)) - && (timeout++ < MAX_TIMEOUT)); -@@ -393,8 +393,8 @@ static int i801_block_transaction(union - /* wait for INTR bit as advised by Intel */ - timeout = 0; - do { -- temp = inb_p(SMBHSTSTS); - msleep(1); -+ temp = inb_p(SMBHSTSTS); - } while ((!(temp & 0x02)) - && (timeout++ < MAX_TIMEOUT)); - diff --git a/i2c/i2c-i801-02-remove-force_addr-parameter.patch b/i2c/i2c-i801-02-remove-force_addr-parameter.patch deleted file mode 100644 index 46f6b5b3dfa42f..00000000000000 --- a/i2c/i2c-i801-02-remove-force_addr-parameter.patch +++ /dev/null @@ -1,93 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:50:22 2006 -Date: Mon, 12 Jun 2006 21:50:11 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org> -Subject: [PATCH 07/14] i2c-i801: Remove force_addr parameter -Message-Id: <20060612215011.c5843671.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-i801-02-remove-force_addr-parameter.patch - -i2c-i801: Remove force_addr parameter - -Remove the force_addr module parameter. It doesn't appear to ever -have been needed, and PCI resources shouldn't be arbitrarily -changed anyway. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-i801 | 3 +-- - drivers/i2c/busses/i2c-i801.c | 35 +++++++---------------------------- - 2 files changed, 8 insertions(+), 30 deletions(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/i2c-i801 -+++ gregkh-2.6/Documentation/i2c/busses/i2c-i801 -@@ -21,8 +21,7 @@ Authors: - Module Parameters - ----------------- - --* force_addr: int -- Forcibly enable the ICH at the given address. EXTREMELY DANGEROUS! -+None. - - - Description ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c -@@ -92,15 +92,6 @@ - #define I801_START 0x40 - #define I801_PEC_EN 0x80 /* ICH4 only */ - --/* insmod parameters */ -- --/* If force_addr is set to anything different from 0, we forcibly enable -- the I801 at the given address. VERY DANGEROUS! */ --static u16 force_addr; --module_param(force_addr, ushort, 0); --MODULE_PARM_DESC(force_addr, -- "Forcibly enable the I801 at the given address. " -- "EXTREMELY DANGEROUS!"); - - static int i801_transaction(void); - static int i801_block_transaction(union i2c_smbus_data *data, char read_write, -@@ -129,16 +120,12 @@ static int i801_setup(struct pci_dev *de - isich4 = 0; - - /* Determine the address of the SMBus areas */ -- if (force_addr) { -- i801_smba = force_addr & 0xfff0; -- } else { -- pci_read_config_word(I801_dev, SMBBA, &i801_smba); -- i801_smba &= 0xfff0; -- if(i801_smba == 0) { -- dev_err(&dev->dev, "SMB base address uninitialized " -- "- upgrade BIOS or use force_addr=0xaddr\n"); -- return -ENODEV; -- } -+ pci_read_config_word(I801_dev, SMBBA, &i801_smba); -+ i801_smba &= 0xfff0; -+ if (!i801_smba) { -+ dev_err(&dev->dev, "SMBus base address uninitialized, " -+ "upgrade BIOS\n"); -+ return -ENODEV; - } - - if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) { -@@ -152,15 +139,7 @@ static int i801_setup(struct pci_dev *de - temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ - pci_write_config_byte(I801_dev, SMBHSTCFG, temp); - -- /* If force_addr is set, we program the new address here. Just to make -- sure, we disable the device first. */ -- if (force_addr) { -- pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe); -- pci_write_config_word(I801_dev, SMBBA, i801_smba); -- pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01); -- dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to " -- "new address %04x!\n", i801_smba); -- } else if ((temp & 1) == 0) { -+ if (!(temp & 1)) { - pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1); - dev_warn(&dev->dev, "enabling SMBus device\n"); - } diff --git a/i2c/i2c-i801-03-remove-pci-function-check.patch b/i2c/i2c-i801-03-remove-pci-function-check.patch deleted file mode 100644 index 7e4f8153fd17e5..00000000000000 --- a/i2c/i2c-i801-03-remove-pci-function-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:51:28 2006 -Date: Mon, 12 Jun 2006 21:51:20 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org> -Subject: [PATCH 08/14] i2c-i801: Remove PCI function check -Message-Id: <20060612215120.0578fd85.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-i801-03-remove-pci-function-check.patch - -i2c-i801: Remove PCI function check - -Remove the PCI function number check when probing devices. -This check is redundant, each function has a separate PCI device -ID, so checking for that ID is sufficient. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/i2c-i801.c | 4 ---- - 1 file changed, 4 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c -@@ -107,10 +107,6 @@ static int i801_setup(struct pci_dev *de - int error_return = 0; - unsigned char temp; - -- /* Note: we keep on searching until we have found 'function 3' */ -- if(PCI_FUNC(dev->devfn) != 3) -- return -ENODEV; -- - I801_dev = dev; - if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || - (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || diff --git a/i2c/i2c-i801-04-cleanups.patch b/i2c/i2c-i801-04-cleanups.patch deleted file mode 100644 index fb963863fbed1d..00000000000000 --- a/i2c/i2c-i801-04-cleanups.patch +++ /dev/null @@ -1,117 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:52:12 2006 -Date: Mon, 12 Jun 2006 21:52:02 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org> -Subject: [PATCH 09/14] i2c-i801: Cleanups -Message-Id: <20060612215202.7c2541df.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-i801-04-cleanups.patch - -i2c-i801: Cleanups - -Various cleanups to the i2c-i801 driver: -* Fix documentation file and self file name references. -* i801_setup can be marked __devinit. -* Drop useless error local variable and label in i801_setup. -* Avoid a double PCI configuration register write in some cases. -* Use symbolic names for SMBHSTCFG bits. -* Transmit the error code returned by i801_setup instead of forcing it - to an arbitrary value. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/i2c-i801.c | 32 +++++++++++++------------------- - 1 file changed, 13 insertions(+), 19 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c -@@ -1,5 +1,5 @@ - /* -- i801.c - Part of lm_sensors, Linux kernel modules for hardware -+ i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, - Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker -@@ -36,7 +36,7 @@ - This driver supports several versions of Intel's I/O Controller Hubs (ICH). - For SMBus support, they are similar to the PIIX4 and are part - of Intel's '810' and other chipsets. -- See the doc/busses/i2c-i801 file for details. -+ See the file Documentation/i2c/busses/i2c-i801 for details. - I2C Block Read and Process Call are not supported. - */ - -@@ -102,9 +102,8 @@ static struct pci_driver i801_driver; - static struct pci_dev *I801_dev; - static int isich4; - --static int i801_setup(struct pci_dev *dev) -+static int __devinit i801_setup(struct pci_dev *dev) - { -- int error_return = 0; - unsigned char temp; - - I801_dev = dev; -@@ -115,7 +114,7 @@ static int i801_setup(struct pci_dev *de - else - isich4 = 0; - -- /* Determine the address of the SMBus areas */ -+ /* Determine the address of the SMBus area */ - pci_read_config_word(I801_dev, SMBBA, &i801_smba); - i801_smba &= 0xfff0; - if (!i801_smba) { -@@ -127,20 +126,18 @@ static int i801_setup(struct pci_dev *de - if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) { - dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n", - i801_smba); -- error_return = -EBUSY; -- goto END; -+ return -EBUSY; - } - - pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); - temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ -- pci_write_config_byte(I801_dev, SMBHSTCFG, temp); -- -- if (!(temp & 1)) { -- pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1); -+ if (!(temp & SMBHSTCFG_HST_EN)) { - dev_warn(&dev->dev, "enabling SMBus device\n"); -+ temp |= SMBHSTCFG_HST_EN; - } -+ pci_write_config_byte(I801_dev, SMBHSTCFG, temp); - -- if (temp & 0x02) -+ if (temp & SMBHSTCFG_SMB_SMI_EN) - dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n"); - else - dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n"); -@@ -149,8 +146,7 @@ static int i801_setup(struct pci_dev *de - dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); - dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); - --END: -- return error_return; -+ return 0; - } - - static int i801_transaction(void) -@@ -516,12 +512,10 @@ MODULE_DEVICE_TABLE (pci, i801_ids); - - static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) - { -+ int err; - -- if (i801_setup(dev)) { -- dev_warn(&dev->dev, -- "I801 not detected, module not inserted.\n"); -- return -ENODEV; -- } -+ if ((err = i801_setup(dev))) -+ return err; - - /* set up the driverfs linkage to our parent device */ - i801_adapter.dev.parent = &dev->dev; diff --git a/i2c/i2c-i801-05-better-pci-subsystem-integration.patch b/i2c/i2c-i801-05-better-pci-subsystem-integration.patch deleted file mode 100644 index efe1dbbad3f596..00000000000000 --- a/i2c/i2c-i801-05-better-pci-subsystem-integration.patch +++ /dev/null @@ -1,116 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:53:08 2006 -Date: Mon, 12 Jun 2006 21:53:02 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org> -Subject: [PATCH 10/14] i2c-i801: Better pci subsystem integration -Message-Id: <20060612215302.3540ed7b.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-i801-05-better-pci-subsystem-integration.patch - -i2c-i801: Better pci subsystem integration - -Integrate the i2c-i801 driver better with the pci subsystem, by -calling pci_{enable,disable}_device and requesting the I/O region -by BAR rather than direct configuration space access. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/i2c-i801.c | 38 +++++++++++++++++++++++++++----------- - 1 file changed, 27 insertions(+), 11 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c -@@ -66,7 +66,7 @@ - #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ - - /* PCI Address Constants */ --#define SMBBA 0x020 -+#define SMBBAR 4 - #define SMBHSTCFG 0x040 - #define SMBREV 0x008 - -@@ -97,7 +97,7 @@ static int i801_transaction(void); - static int i801_block_transaction(union i2c_smbus_data *data, char read_write, - int command, int hwpec); - --static unsigned short i801_smba; -+static unsigned long i801_smba; - static struct pci_driver i801_driver; - static struct pci_dev *I801_dev; - static int isich4; -@@ -105,6 +105,7 @@ static int isich4; - static int __devinit i801_setup(struct pci_dev *dev) - { - unsigned char temp; -+ int err; - - I801_dev = dev; - if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || -@@ -114,19 +115,28 @@ static int __devinit i801_setup(struct p - else - isich4 = 0; - -+ err = pci_enable_device(dev); -+ if (err) { -+ dev_err(&dev->dev, "Failed to enable SMBus device (%d)\n", -+ err); -+ goto exit; -+ } -+ - /* Determine the address of the SMBus area */ -- pci_read_config_word(I801_dev, SMBBA, &i801_smba); -- i801_smba &= 0xfff0; -+ i801_smba = pci_resource_start(dev, SMBBAR); - if (!i801_smba) { - dev_err(&dev->dev, "SMBus base address uninitialized, " - "upgrade BIOS\n"); -- return -ENODEV; -+ err = -ENODEV; -+ goto exit_disable; - } - -- if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) { -- dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n", -- i801_smba); -- return -EBUSY; -+ err = pci_request_region(dev, SMBBAR, i801_driver.name); -+ if (err) { -+ dev_err(&dev->dev, "Failed to request SMBus region " -+ "0x%lx-0x%lx\n", i801_smba, -+ pci_resource_end(dev, SMBBAR)); -+ goto exit_disable; - } - - pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); -@@ -147,6 +157,11 @@ static int __devinit i801_setup(struct p - dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); - - return 0; -+ -+exit_disable: -+ pci_disable_device(dev); -+exit: -+ return err; - } - - static int i801_transaction(void) -@@ -521,14 +536,15 @@ static int __devinit i801_probe(struct p - i801_adapter.dev.parent = &dev->dev; - - snprintf(i801_adapter.name, I2C_NAME_SIZE, -- "SMBus I801 adapter at %04x", i801_smba); -+ "SMBus I801 adapter at %04lx", i801_smba); - return i2c_add_adapter(&i801_adapter); - } - - static void __devexit i801_remove(struct pci_dev *dev) - { - i2c_del_adapter(&i801_adapter); -- release_region(i801_smba, (isich4 ? 16 : 8)); -+ pci_release_region(dev, SMBBAR); -+ pci_disable_device(dev); - } - - static struct pci_driver i801_driver = { diff --git a/i2c/i2c-i801-06-merge-setup-function.patch b/i2c/i2c-i801-06-merge-setup-function.patch deleted file mode 100644 index 0b1fbea04f4b49..00000000000000 --- a/i2c/i2c-i801-06-merge-setup-function.patch +++ /dev/null @@ -1,178 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:53:41 2006 -Date: Mon, 12 Jun 2006 21:53:41 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org> -Subject: [PATCH 11/14] i2c-i801: Merge setup function -Message-Id: <20060612215341.cdc67d11.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-i801-06-merge-setup-function.patch - -i2c-i801: Merge setup function - -Merge i801_setup into i801_probe, as it doesn't make much sense to -have them split. This lets us handle errors better. Christopher -Hellwig had been suggesting this back in March 2003 when the driver -was merged. - -Also drop two useless debug messages (revision and base address can be -obtained from lspci, procfs or sysfs.) - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/i2c-i801.c | 121 +++++++++++++++++++----------------------- - 1 file changed, 55 insertions(+), 66 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c -@@ -68,7 +68,6 @@ - /* PCI Address Constants */ - #define SMBBAR 4 - #define SMBHSTCFG 0x040 --#define SMBREV 0x008 - - /* Host configuration bits for SMBHSTCFG */ - #define SMBHSTCFG_HST_EN 1 -@@ -102,68 +101,6 @@ static struct pci_driver i801_driver; - static struct pci_dev *I801_dev; - static int isich4; - --static int __devinit i801_setup(struct pci_dev *dev) --{ -- unsigned char temp; -- int err; -- -- I801_dev = dev; -- if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || -- (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || -- (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) -- isich4 = 1; -- else -- isich4 = 0; -- -- err = pci_enable_device(dev); -- if (err) { -- dev_err(&dev->dev, "Failed to enable SMBus device (%d)\n", -- err); -- goto exit; -- } -- -- /* Determine the address of the SMBus area */ -- i801_smba = pci_resource_start(dev, SMBBAR); -- if (!i801_smba) { -- dev_err(&dev->dev, "SMBus base address uninitialized, " -- "upgrade BIOS\n"); -- err = -ENODEV; -- goto exit_disable; -- } -- -- err = pci_request_region(dev, SMBBAR, i801_driver.name); -- if (err) { -- dev_err(&dev->dev, "Failed to request SMBus region " -- "0x%lx-0x%lx\n", i801_smba, -- pci_resource_end(dev, SMBBAR)); -- goto exit_disable; -- } -- -- pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); -- temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ -- if (!(temp & SMBHSTCFG_HST_EN)) { -- dev_warn(&dev->dev, "enabling SMBus device\n"); -- temp |= SMBHSTCFG_HST_EN; -- } -- pci_write_config_byte(I801_dev, SMBHSTCFG, temp); -- -- if (temp & SMBHSTCFG_SMB_SMI_EN) -- dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n"); -- else -- dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n"); -- -- pci_read_config_byte(I801_dev, SMBREV, &temp); -- dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); -- dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); -- -- return 0; -- --exit_disable: -- pci_disable_device(dev); --exit: -- return err; --} -- - static int i801_transaction(void) - { - int temp; -@@ -527,17 +464,69 @@ MODULE_DEVICE_TABLE (pci, i801_ids); - - static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) - { -+ unsigned char temp; - int err; - -- if ((err = i801_setup(dev))) -- return err; -+ I801_dev = dev; -+ if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || -+ (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || -+ (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) -+ isich4 = 1; -+ else -+ isich4 = 0; -+ -+ err = pci_enable_device(dev); -+ if (err) { -+ dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", -+ err); -+ goto exit; -+ } -+ -+ /* Determine the address of the SMBus area */ -+ i801_smba = pci_resource_start(dev, SMBBAR); -+ if (!i801_smba) { -+ dev_err(&dev->dev, "SMBus base address uninitialized, " -+ "upgrade BIOS\n"); -+ err = -ENODEV; -+ goto exit_disable; -+ } -+ -+ err = pci_request_region(dev, SMBBAR, i801_driver.name); -+ if (err) { -+ dev_err(&dev->dev, "Failed to request SMBus region " -+ "0x%lx-0x%lx\n", i801_smba, -+ pci_resource_end(dev, SMBBAR)); -+ goto exit_disable; -+ } -+ -+ pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); -+ temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ -+ if (!(temp & SMBHSTCFG_HST_EN)) { -+ dev_info(&dev->dev, "Enabling SMBus device\n"); -+ temp |= SMBHSTCFG_HST_EN; -+ } -+ pci_write_config_byte(I801_dev, SMBHSTCFG, temp); -+ -+ if (temp & SMBHSTCFG_SMB_SMI_EN) -+ dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); -+ else -+ dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); - - /* set up the driverfs linkage to our parent device */ - i801_adapter.dev.parent = &dev->dev; - - snprintf(i801_adapter.name, I2C_NAME_SIZE, - "SMBus I801 adapter at %04lx", i801_smba); -- return i2c_add_adapter(&i801_adapter); -+ err = i2c_add_adapter(&i801_adapter); -+ if (err) { -+ dev_err(&dev->dev, "Failed to add SMBus adapter\n"); -+ goto exit_disable; -+ } -+ -+exit_disable: -+ pci_disable_device(dev); -+exit: -+ return err; - } - - static void __devexit i801_remove(struct pci_dev *dev) diff --git a/i2c/i2c-mark-data-const-for-write-block.patch b/i2c/i2c-mark-data-const-for-write-block.patch deleted file mode 100644 index 224bacb0bcac1a..00000000000000 --- a/i2c/i2c-mark-data-const-for-write-block.patch +++ /dev/null @@ -1,61 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:42:21 2006 -Date: Mon, 12 Jun 2006 21:42:20 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Krzysztof Halasa <khc@pm.waw.pl> -Subject: [PATCH 02/14] i2c: Mark block write buffers as const -Message-Id: <20060612214220.46bb23be.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-mark-data-const-for-write-block.patch - -From: Krzysztof Halasa <khc@pm.waw.pl> - -The attached patch marks i2c_smbus_write_block_data() and -i2c_smbus_write_i2c_block_data() buffers as const. - -Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/i2c-core.c | 4 ++-- - include/linux/i2c.h | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/i2c-core.c -+++ gregkh-2.6/drivers/i2c/i2c-core.c -@@ -916,7 +916,7 @@ s32 i2c_smbus_write_word_data(struct i2c - } - - s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, -- u8 length, u8 *values) -+ u8 length, const u8 *values) - { - union i2c_smbus_data data; - -@@ -944,7 +944,7 @@ s32 i2c_smbus_read_i2c_block_data(struct - } - - s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, -- u8 length, u8 *values) -+ u8 length, const u8 *values) - { - union i2c_smbus_data data; - ---- gregkh-2.6.orig/include/linux/i2c.h -+++ gregkh-2.6/include/linux/i2c.h -@@ -97,13 +97,13 @@ extern s32 i2c_smbus_write_word_data(str - u8 command, u16 value); - extern s32 i2c_smbus_write_block_data(struct i2c_client * client, - u8 command, u8 length, -- u8 *values); -+ const u8 *values); - /* Returns the number of read bytes */ - extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, - u8 command, u8 *values); - extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, - u8 command, u8 length, -- u8 *values); -+ const u8 *values); - - /* - * A driver is capable of handling one or more physical devices present on diff --git a/i2c/i2c-nforce2-add-mcp51-mcp55-support.patch b/i2c/i2c-nforce2-add-mcp51-mcp55-support.patch deleted file mode 100644 index 75d3f9f22e45bb..00000000000000 --- a/i2c/i2c-nforce2-add-mcp51-mcp55-support.patch +++ /dev/null @@ -1,131 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 05:18:16 2006 -Date: Tue, 25 Apr 2006 14:18:16 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: I2C: i2c-nforce2: Add support for the nForce4 MCP51 and MCP55 -Message-Id: <20060425141816.a6dcb410.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-nforce2-add-mcp51-mcp55-support.patch - -Add support for the new nForce4 MCP51 (also known as nForce 410 or -430) and nForce4 MCP55 to the i2c-nforce2 driver. Some code changes -were required because the base I/O address registers have changed in -these versions. Standard BARs are now being used, while the original -nForce2 chips used non-standard ones. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-nforce2 | 2 + - drivers/i2c/busses/i2c-nforce2.c | 38 ++++++++++++++++++++++++----------- - include/linux/pci_ids.h | 2 + - 3 files changed, 31 insertions(+), 11 deletions(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/i2c-nforce2 -+++ gregkh-2.6/Documentation/i2c/busses/i2c-nforce2 -@@ -7,6 +7,8 @@ Supported adapters: - * nForce3 250Gb MCP 10de:00E4 - * nForce4 MCP 10de:0052 - * nForce4 MCP-04 10de:0034 -+ * nForce4 MCP51 10de:0264 -+ * nForce4 MCP55 10de:0368 - - Datasheet: not publically available, but seems to be similar to the - AMD-8111 SMBus 2.0 adapter. ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-nforce2.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-nforce2.c -@@ -31,6 +31,8 @@ - nForce3 250Gb MCP 00E4 - nForce4 MCP 0052 - nForce4 MCP-04 0034 -+ nForce4 MCP51 0264 -+ nForce4 MCP55 0368 - - This driver supports the 2 SMBuses that are included in the MCP of the - nForce2/3/4 chipsets. -@@ -64,6 +66,7 @@ struct nforce2_smbus { - - /* - * nVidia nForce2 SMBus control register definitions -+ * (Newer incarnations use standard BARs 4 and 5 instead) - */ - #define NFORCE_PCI_SMB1 0x50 - #define NFORCE_PCI_SMB2 0x54 -@@ -259,6 +262,8 @@ static struct pci_device_id nforce2_ids[ - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) }, - { 0 } - }; - -@@ -266,19 +271,29 @@ static struct pci_device_id nforce2_ids[ - MODULE_DEVICE_TABLE (pci, nforce2_ids); - - --static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg, -- struct nforce2_smbus *smbus, char *name) -+static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, -+ int alt_reg, struct nforce2_smbus *smbus, const char *name) - { -- u16 iobase; - int error; - -- if (pci_read_config_word(dev, reg, &iobase) != PCIBIOS_SUCCESSFUL) { -- dev_err(&smbus->adapter.dev, "Error reading PCI config for %s\n", name); -- return -1; -+ smbus->base = pci_resource_start(dev, bar); -+ if (smbus->base) { -+ smbus->size = pci_resource_len(dev, bar); -+ } else { -+ /* Older incarnations of the device used non-standard BARs */ -+ u16 iobase; -+ -+ if (pci_read_config_word(dev, alt_reg, &iobase) -+ != PCIBIOS_SUCCESSFUL) { -+ dev_err(&dev->dev, "Error reading PCI config for %s\n", -+ name); -+ return -1; -+ } -+ -+ smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK; -+ smbus->size = 8; - } -- smbus->dev = dev; -- smbus->base = iobase & 0xfffc; -- smbus->size = 8; -+ smbus->dev = dev; - - if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { - dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", -@@ -313,12 +328,13 @@ static int __devinit nforce2_probe(struc - pci_set_drvdata(dev, smbuses); - - /* SMBus adapter 1 */ -- res1 = nforce2_probe_smb (dev, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); -+ res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); - if (res1 < 0) { - dev_err(&dev->dev, "Error probing SMB1.\n"); - smbuses[0].base = 0; /* to have a check value */ - } -- res2 = nforce2_probe_smb (dev, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); -+ /* SMBus adapter 2 */ -+ res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); - if (res2 < 0) { - dev_err(&dev->dev, "Error probing SMB2.\n"); - smbuses[1].base = 0; /* to have a check value */ ---- gregkh-2.6.orig/include/linux/pci_ids.h -+++ gregkh-2.6/include/linux/pci_ids.h -@@ -1130,9 +1130,11 @@ - #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 - #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 - #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B -+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS 0x0264 - #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 - #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 - #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 -+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS 0x0368 - #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E - #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E - #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F diff --git a/i2c/i2c-opencores-cleanup.patch b/i2c/i2c-opencores-cleanup.patch deleted file mode 100644 index 0fccde54ee8466..00000000000000 --- a/i2c/i2c-opencores-cleanup.patch +++ /dev/null @@ -1,61 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:41:03 2006 -Date: Mon, 12 Jun 2006 21:40:53 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Peter Korsgaard <jacmet@sunsite.dk> -Subject: [PATCH 01/14] i2c-ocores: Minor cleanups -Message-Id: <20060612214053.4c7ebc0c.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-opencores-cleanup.patch - -From: Peter Korsgaard <jacmet@sunsite.dk> - -Minor cleanup to the i2c-ocores driver. - -Peter Korsgaard will maintain the i2c-ocores driver. - -Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - MAINTAINERS | 6 ++++++ - drivers/i2c/busses/i2c-ocores.c | 6 ++---- - 2 files changed, 8 insertions(+), 4 deletions(-) - ---- gregkh-2.6.orig/MAINTAINERS -+++ gregkh-2.6/MAINTAINERS -@@ -2063,6 +2063,12 @@ M: adaplas@pol.net - L: linux-fbdev-devel@lists.sourceforge.net - S: Maintained - -+OPENCORES I2C BUS DRIVER -+P: Peter Korsgaard -+M: jacmet@sunsite.dk -+L: lm-sensors@lm-sensors.org -+S: Maintained -+ - ORACLE CLUSTER FILESYSTEM 2 (OCFS2) - P: Mark Fasheh - M: mark.fasheh@oracle.com ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-ocores.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-ocores.c -@@ -38,8 +38,8 @@ struct ocores_i2c { - #define OCI2C_PREHIGH 1 - #define OCI2C_CONTROL 2 - #define OCI2C_DATA 3 --#define OCI2C_CMD 4 --#define OCI2C_STATUS 4 -+#define OCI2C_CMD 4 /* write only */ -+#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ - - #define OCI2C_CTRL_IEN 0x40 - #define OCI2C_CTRL_EN 0x80 -@@ -209,8 +209,6 @@ static struct i2c_adapter ocores_adapter - .name = "i2c-ocores", - .class = I2C_CLASS_HWMON, - .algo = &ocores_algorithm, -- .timeout = 2, -- .retries = 1, - }; - - diff --git a/i2c/i2c-opencores-new-driver.patch b/i2c/i2c-opencores-new-driver.patch deleted file mode 100644 index b78d687bac51e4..00000000000000 --- a/i2c/i2c-opencores-new-driver.patch +++ /dev/null @@ -1,479 +0,0 @@ -From khali@linux-fr.org Sun Jun 4 11:01:11 2006 -Date: Sun, 4 Jun 2006 20:01:08 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Peter Korsgaard <jacmet@sunsite.dk> -Subject: i2c: New bus driver for the OpenCores I2C controller -Message-Id: <20060604200108.d3bca76d.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-opencores-new-driver.patch - -From: Peter Korsgaard <jacmet@sunsite.dk> - -The following patch adds support for the OpenCores I2C controller IP -core (See http://www.opencores.org/projects.cgi/web/i2c/overview). - -Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> -Signed-off-by: Andrew Morton <akpm@osdl.org> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-ocores | 51 +++++ - drivers/i2c/busses/Kconfig | 11 + - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-ocores.c | 343 ++++++++++++++++++++++++++++++++++++ - include/linux/i2c-ocores.h | 19 + - 5 files changed, 425 insertions(+) - ---- /dev/null -+++ gregkh-2.6/Documentation/i2c/busses/i2c-ocores -@@ -0,0 +1,51 @@ -+Kernel driver i2c-ocores -+ -+Supported adapters: -+ * OpenCores.org I2C controller by Richard Herveille (see datasheet link) -+ Datasheet: http://www.opencores.org/projects.cgi/web/i2c/overview -+ -+Author: Peter Korsgaard <jacmet@sunsite.dk> -+ -+Description -+----------- -+ -+i2c-ocores is an i2c bus driver for the OpenCores.org I2C controller -+IP core by Richard Herveille. -+ -+Usage -+----- -+ -+i2c-ocores uses the platform bus, so you need to provide a struct -+platform_device with the base address and interrupt number. The -+dev.platform_data of the device should also point to a struct -+ocores_i2c_platform_data (see linux/i2c-ocores.h) describing the -+distance between registers and the input clock speed. -+ -+E.G. something like: -+ -+static struct resource ocores_resources[] = { -+ [0] = { -+ .start = MYI2C_BASEADDR, -+ .end = MYI2C_BASEADDR + 8, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = MYI2C_IRQ, -+ .end = MYI2C_IRQ, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct ocores_i2c_platform_data myi2c_data = { -+ .regstep = 2, /* two bytes between registers */ -+ .clock_khz = 50000, /* input clock of 50MHz */ -+}; -+ -+static struct platform_device myi2c = { -+ .name = "ocores-i2c", -+ .dev = { -+ .platform_data = &myi2c_data, -+ }, -+ .num_resources = ARRAY_SIZE(ocores_resources), -+ .resource = ocores_resources, -+}; ---- gregkh-2.6.orig/drivers/i2c/busses/Kconfig -+++ gregkh-2.6/drivers/i2c/busses/Kconfig -@@ -276,6 +276,17 @@ config I2C_NFORCE2 - This driver can also be built as a module. If so, the module - will be called i2c-nforce2. - -+config I2C_OCORES -+ tristate "OpenCores I2C Controller" -+ depends on I2C && EXPERIMENTAL -+ help -+ If you say yes to this option, support will be included for the -+ OpenCores I2C controller. For details see -+ http://www.opencores.org/projects.cgi/web/i2c/overview -+ -+ This driver can also be built as a module. If so, the module -+ will be called i2c-ocores. -+ - config I2C_PARPORT - tristate "Parallel port adapter" - depends on I2C && PARPORT ---- gregkh-2.6.orig/drivers/i2c/busses/Makefile -+++ gregkh-2.6/drivers/i2c/busses/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powerm - obj-$(CONFIG_I2C_MPC) += i2c-mpc.o - obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o - obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o -+obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o - obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o - obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o - obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o ---- /dev/null -+++ gregkh-2.6/drivers/i2c/busses/i2c-ocores.c -@@ -0,0 +1,343 @@ -+/* -+ * i2c-ocores.c: I2C bus driver for OpenCores I2C controller -+ * (http://www.opencores.org/projects.cgi/web/i2c/overview). -+ * -+ * Peter Korsgaard <jacmet@sunsite.dk> -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+#include <linux/config.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/sched.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/platform_device.h> -+#include <linux/i2c.h> -+#include <linux/interrupt.h> -+#include <linux/wait.h> -+#include <linux/i2c-ocores.h> -+#include <asm/io.h> -+ -+struct ocores_i2c { -+ void __iomem *base; -+ int regstep; -+ wait_queue_head_t wait; -+ struct i2c_adapter adap; -+ struct i2c_msg *msg; -+ int pos; -+ int nmsgs; -+ int state; /* see STATE_ */ -+}; -+ -+/* registers */ -+#define OCI2C_PRELOW 0 -+#define OCI2C_PREHIGH 1 -+#define OCI2C_CONTROL 2 -+#define OCI2C_DATA 3 -+#define OCI2C_CMD 4 -+#define OCI2C_STATUS 4 -+ -+#define OCI2C_CTRL_IEN 0x40 -+#define OCI2C_CTRL_EN 0x80 -+ -+#define OCI2C_CMD_START 0x91 -+#define OCI2C_CMD_STOP 0x41 -+#define OCI2C_CMD_READ 0x21 -+#define OCI2C_CMD_WRITE 0x11 -+#define OCI2C_CMD_READ_ACK 0x21 -+#define OCI2C_CMD_READ_NACK 0x29 -+#define OCI2C_CMD_IACK 0x01 -+ -+#define OCI2C_STAT_IF 0x01 -+#define OCI2C_STAT_TIP 0x02 -+#define OCI2C_STAT_ARBLOST 0x20 -+#define OCI2C_STAT_BUSY 0x40 -+#define OCI2C_STAT_NACK 0x80 -+ -+#define STATE_DONE 0 -+#define STATE_START 1 -+#define STATE_WRITE 2 -+#define STATE_READ 3 -+#define STATE_ERROR 4 -+ -+static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) -+{ -+ iowrite8(value, i2c->base + reg * i2c->regstep); -+} -+ -+static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) -+{ -+ return ioread8(i2c->base + reg * i2c->regstep); -+} -+ -+static void ocores_process(struct ocores_i2c *i2c) -+{ -+ struct i2c_msg *msg = i2c->msg; -+ u8 stat = oc_getreg(i2c, OCI2C_STATUS); -+ -+ if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { -+ /* stop has been sent */ -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); -+ wake_up(&i2c->wait); -+ return; -+ } -+ -+ /* error? */ -+ if (stat & OCI2C_STAT_ARBLOST) { -+ i2c->state = STATE_ERROR; -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); -+ return; -+ } -+ -+ if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { -+ i2c->state = -+ (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; -+ -+ if (stat & OCI2C_STAT_NACK) { -+ i2c->state = STATE_ERROR; -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); -+ return; -+ } -+ } else -+ msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); -+ -+ /* end of msg? */ -+ if (i2c->pos == msg->len) { -+ i2c->nmsgs--; -+ i2c->msg++; -+ i2c->pos = 0; -+ msg = i2c->msg; -+ -+ if (i2c->nmsgs) { /* end? */ -+ /* send start? */ -+ if (!(msg->flags & I2C_M_NOSTART)) { -+ u8 addr = (msg->addr << 1); -+ -+ if (msg->flags & I2C_M_RD) -+ addr |= 1; -+ -+ i2c->state = STATE_START; -+ -+ oc_setreg(i2c, OCI2C_DATA, addr); -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); -+ return; -+ } else -+ i2c->state = (msg->flags & I2C_M_RD) -+ ? STATE_READ : STATE_WRITE; -+ } else { -+ i2c->state = STATE_DONE; -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); -+ return; -+ } -+ } -+ -+ if (i2c->state == STATE_READ) { -+ oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? -+ OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); -+ } else { -+ oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); -+ } -+} -+ -+static irqreturn_t ocores_isr(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ struct ocores_i2c *i2c = dev_id; -+ -+ ocores_process(i2c); -+ -+ return IRQ_HANDLED; -+} -+ -+static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -+{ -+ struct ocores_i2c *i2c = i2c_get_adapdata(adap); -+ -+ i2c->msg = msgs; -+ i2c->pos = 0; -+ i2c->nmsgs = num; -+ i2c->state = STATE_START; -+ -+ oc_setreg(i2c, OCI2C_DATA, -+ (i2c->msg->addr << 1) | -+ ((i2c->msg->flags & I2C_M_RD) ? 1:0)); -+ -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); -+ -+ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || -+ (i2c->state == STATE_DONE), HZ)) -+ return (i2c->state == STATE_DONE) ? num : -EIO; -+ else -+ return -ETIMEDOUT; -+} -+ -+static void ocores_init(struct ocores_i2c *i2c, -+ struct ocores_i2c_platform_data *pdata) -+{ -+ int prescale; -+ u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); -+ -+ /* make sure the device is disabled */ -+ oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); -+ -+ prescale = (pdata->clock_khz / (5*100)) - 1; -+ oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); -+ oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); -+ -+ /* Init the device */ -+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); -+ oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); -+} -+ -+ -+static u32 ocores_func(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static struct i2c_algorithm ocores_algorithm = { -+ .master_xfer = ocores_xfer, -+ .functionality = ocores_func, -+}; -+ -+static struct i2c_adapter ocores_adapter = { -+ .owner = THIS_MODULE, -+ .name = "i2c-ocores", -+ .class = I2C_CLASS_HWMON, -+ .algo = &ocores_algorithm, -+ .timeout = 2, -+ .retries = 1, -+}; -+ -+ -+static int __devinit ocores_i2c_probe(struct platform_device *pdev) -+{ -+ struct ocores_i2c *i2c; -+ struct ocores_i2c_platform_data *pdata; -+ struct resource *res, *res2; -+ int ret; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENODEV; -+ -+ res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!res2) -+ return -ENODEV; -+ -+ pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data; -+ if (!pdata) -+ return -ENODEV; -+ -+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) -+ return -ENOMEM; -+ -+ if (!request_mem_region(res->start, res->end - res->start + 1, -+ pdev->name)) { -+ dev_err(&pdev->dev, "Memory region busy\n"); -+ ret = -EBUSY; -+ goto request_mem_failed; -+ } -+ -+ i2c->base = ioremap(res->start, res->end - res->start + 1); -+ if (!i2c->base) { -+ dev_err(&pdev->dev, "Unable to map registers\n"); -+ ret = -EIO; -+ goto map_failed; -+ } -+ -+ i2c->regstep = pdata->regstep; -+ ocores_init(i2c, pdata); -+ -+ init_waitqueue_head(&i2c->wait); -+ ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c); -+ if (ret) { -+ dev_err(&pdev->dev, "Cannot claim IRQ\n"); -+ goto request_irq_failed; -+ } -+ -+ /* hook up driver to tree */ -+ platform_set_drvdata(pdev, i2c); -+ i2c->adap = ocores_adapter; -+ i2c_set_adapdata(&i2c->adap, i2c); -+ i2c->adap.dev.parent = &pdev->dev; -+ -+ /* add i2c adapter to i2c tree */ -+ ret = i2c_add_adapter(&i2c->adap); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to add adapter\n"); -+ goto add_adapter_failed; -+ } -+ -+ return 0; -+ -+add_adapter_failed: -+ free_irq(res2->start, i2c); -+request_irq_failed: -+ iounmap(i2c->base); -+map_failed: -+ release_mem_region(res->start, res->end - res->start + 1); -+request_mem_failed: -+ kfree(i2c); -+ -+ return ret; -+} -+ -+static int __devexit ocores_i2c_remove(struct platform_device* pdev) -+{ -+ struct ocores_i2c *i2c = platform_get_drvdata(pdev); -+ struct resource *res; -+ -+ /* disable i2c logic */ -+ oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) -+ & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); -+ -+ /* remove adapter & data */ -+ i2c_del_adapter(&i2c->adap); -+ platform_set_drvdata(pdev, NULL); -+ -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (res) -+ free_irq(res->start, i2c); -+ -+ iounmap(i2c->base); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res) -+ release_mem_region(res->start, res->end - res->start + 1); -+ -+ kfree(i2c); -+ -+ return 0; -+} -+ -+static struct platform_driver ocores_i2c_driver = { -+ .probe = ocores_i2c_probe, -+ .remove = __devexit_p(ocores_i2c_remove), -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "ocores-i2c", -+ }, -+}; -+ -+static int __init ocores_i2c_init(void) -+{ -+ return platform_driver_register(&ocores_i2c_driver); -+} -+ -+static void __exit ocores_i2c_exit(void) -+{ -+ platform_driver_unregister(&ocores_i2c_driver); -+} -+ -+module_init(ocores_i2c_init); -+module_exit(ocores_i2c_exit); -+ -+MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); -+MODULE_DESCRIPTION("OpenCores I2C bus driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ gregkh-2.6/include/linux/i2c-ocores.h -@@ -0,0 +1,19 @@ -+/* -+ * i2c-ocores.h - definitions for the i2c-ocores interface -+ * -+ * Peter Korsgaard <jacmet@sunsite.dk> -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+#ifndef _LINUX_I2C_OCORES_H -+#define _LINUX_I2C_OCORES_H -+ -+struct ocores_i2c_platform_data { -+ u32 regstep; /* distance between registers */ -+ u32 clock_khz; /* input clock in kHz */ -+}; -+ -+#endif /* _LINUX_I2C_OCORES_H */ diff --git a/i2c/i2c-piix4-add-ati-smbus-support.patch b/i2c/i2c-piix4-add-ati-smbus-support.patch deleted file mode 100644 index 59c660e20aedcf..00000000000000 --- a/i2c/i2c-piix4-add-ati-smbus-support.patch +++ /dev/null @@ -1,86 +0,0 @@ -From khali@linux-fr.org Thu Mar 23 07:47:43 2006 -Date: Thu, 23 Mar 2006 16:48:09 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Rudolf Marek <r.marek@sh.cvut.cz> -Subject: [PATCH 08/10] i2c-piix4: Add ATI IXP200/300/400 support -Message-Id: <20060323164809.cdcef765.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-piix4-add-ati-smbus-support.patch - -From: Rudolf Marek <r.marek@sh.cvut.cz> - -This patch adds the ATI IXP southbridges support to i2c-piix4, -as it turned out those chips are compatible with it. - -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-piix4 | 2 ++ - drivers/i2c/busses/Kconfig | 5 ++++- - drivers/i2c/busses/i2c-piix4.c | 6 ++++++ - include/linux/pci_ids.h | 3 +++ - 4 files changed, 15 insertions(+), 1 deletion(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/i2c-piix4 -+++ gregkh-2.6/Documentation/i2c/busses/i2c-piix4 -@@ -6,6 +6,8 @@ Supported adapters: - Datasheet: Publicly available at the Intel website - * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges - Datasheet: Only available via NDA from ServerWorks -+ * ATI IXP southbridges IXP200, IXP300, IXP400 -+ Datasheet: Not publicly available - * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge - Datasheet: Publicly available at the SMSC website http://www.smsc.com - ---- gregkh-2.6.orig/drivers/i2c/busses/Kconfig -+++ gregkh-2.6/drivers/i2c/busses/Kconfig -@@ -163,7 +163,7 @@ config I2C_PXA_SLAVE - I2C bus. - - config I2C_PIIX4 -- tristate "Intel PIIX4" -+ tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" - depends on I2C && PCI - help - If you say yes to this option, support will be included for the Intel -@@ -172,6 +172,9 @@ config I2C_PIIX4 - of Broadcom): - Intel PIIX4 - Intel 440MX -+ ATI IXP200 -+ ATI IXP300 -+ ATI IXP400 - Serverworks OSB4 - Serverworks CSB5 - Serverworks CSB6 ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-piix4.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-piix4.c -@@ -413,6 +413,12 @@ static struct i2c_adapter piix4_adapter - static struct pci_device_id piix4_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), - .driver_data = 3 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS), -+ .driver_data = 0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS), -+ .driver_data = 0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS), -+ .driver_data = 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), - .driver_data = 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), ---- gregkh-2.6.orig/include/linux/pci_ids.h -+++ gregkh-2.6/include/linux/pci_ids.h -@@ -352,8 +352,11 @@ - #define PCI_DEVICE_ID_ATI_RS480 0x5950 - /* ATI IXP Chipset */ - #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 -+#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 -+#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363 - #define PCI_DEVICE_ID_ATI_IXP300_IDE 0x4369 - #define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e -+#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372 - #define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 - #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 - #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a diff --git a/i2c/i2c-piix4-fix-typo-in-documentation.patch b/i2c/i2c-piix4-fix-typo-in-documentation.patch deleted file mode 100644 index 9952790c585a9b..00000000000000 --- a/i2c/i2c-piix4-fix-typo-in-documentation.patch +++ /dev/null @@ -1,28 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 04:29:22 2006 -Date: Tue, 25 Apr 2006 13:29:26 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: I2C: i2c-piix4: Fix typo in documentation -Message-Id: <20060425132926.538d84ed.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-piix4-fix-typo-in-documentation.patch - -Fix i2c-piix4 documentation typo. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-piix4 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/i2c-piix4 -+++ gregkh-2.6/Documentation/i2c/busses/i2c-piix4 -@@ -63,7 +63,7 @@ The PIIX4E is just an new version of the - The PIIX/PIIX3 does not implement an SMBus or I2C bus, so you can't use - this driver on those mainboards. - --The ServerWorks Southbridges, the Intel 440MX, and the Victory766 are -+The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are - identical to the PIIX4 in I2C/SMBus support. - - If you own Force CPCI735 motherboard or other OSB4 based systems you may need diff --git a/i2c/i2c-piix4-improve-ibm-error-message.patch b/i2c/i2c-piix4-improve-ibm-error-message.patch deleted file mode 100644 index 9bd994632f0e60..00000000000000 --- a/i2c/i2c-piix4-improve-ibm-error-message.patch +++ /dev/null @@ -1,54 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 04:37:23 2006 -Date: Tue, 25 Apr 2006 13:37:25 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Subject: I2C: i2c-piix4: Document the IBM problem more clearly -Message-Id: <20060425133725.ef4eadd2.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-piix4-improve-ibm-error-message.patch - -Properly document on which systems the i2c-piix4 SMBus driver will -refuse to load. Hopefully this will make it clearer for users, which -were often wondering why their destop or server systems were detected -as laptops. - -Closes bug #6429. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-piix4 | 14 ++++++++++++++ - drivers/i2c/busses/i2c-piix4.c | 2 +- - 2 files changed, 15 insertions(+), 1 deletion(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/i2c-piix4 -+++ gregkh-2.6/Documentation/i2c/busses/i2c-piix4 -@@ -82,3 +82,17 @@ the SMI mode. - - Please note that you don't need to do that in all cases, just when the SMBus is - not working properly. -+ -+ -+Hardware-specific issues -+------------------------ -+ -+This driver will refuse to load on IBM systems with an Intel PIIX4 SMBus. -+Some of these machines have an RFID EEPROM (24RF08) connected to the SMBus, -+which can easily get corrupted due to a state machine bug. These are mostly -+Thinkpad laptops, but desktop systems may also be affected. We have no list -+of all affected systems, so the only safe solution was to prevent access to -+the SMBus on all IBM systems (detected using DMI data.) -+ -+For additional information, read: -+http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/README.thinkpad ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-piix4.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-piix4.c -@@ -130,7 +130,7 @@ static int __devinit piix4_setup(struct - /* Don't access SMBus on IBM systems which get corrupted eeproms */ - if (dmi_check_system(piix4_dmi_table) && - PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { -- dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module " -+ dev_err(&PIIX4_dev->dev, "IBM system detected; this module " - "may corrupt your serial eeprom! Refusing to load " - "module!\n"); - return -EPERM; diff --git a/i2c/i2c-piix4-remove-fix_hstcfg-parameter.patch b/i2c/i2c-piix4-remove-fix_hstcfg-parameter.patch deleted file mode 100644 index 9ffcf1214073d7..00000000000000 --- a/i2c/i2c-piix4-remove-fix_hstcfg-parameter.patch +++ /dev/null @@ -1,116 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 04:06:58 2006 -Date: Tue, 25 Apr 2006 13:06:41 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: Rudolf Marek <r.marek@sh.cvut.cz> -Subject: I2C: i2c-piix4: Remove the fix_hstcfg parameter -Message-Id: <20060425130641.892e4179.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-piix4-remove-fix_hstcfg-parameter.patch - -From: Rudolf Marek <r.marek@sh.cvut.cz> - -This patch removes the fix_hstcfg option from the driver and related -SMBus Interrupt Select register magic because now we know what are -valid values for this register. This patch updates the documentation -and adds new IRQ mode check so we are sure not to miss any new -"unusual" value. - -The PCI quirk for users of fix_hstcfg was not developed because the -chipset lacks of subsystem ID registers and DMI is stated "To be -filled". Impact to existing systems is minimal because the problem -showed up on motherboards like 10 years back. On the other hand users -of newer Serverworks and HT1000 systems won't be misleaded by the -message suggesting to try the fix_hstcfg any more. - -Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/i2c-piix4 | 22 ++++++++++++++++------ - drivers/i2c/busses/i2c-piix4.c | 25 +------------------------ - 2 files changed, 17 insertions(+), 30 deletions(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/i2c-piix4 -+++ gregkh-2.6/Documentation/i2c/busses/i2c-piix4 -@@ -23,8 +23,6 @@ Module Parameters - Forcibly enable the PIIX4. DANGEROUS! - * force_addr: int - Forcibly enable the PIIX4 at the given address. EXTREMELY DANGEROUS! --* fix_hstcfg: int -- Fix config register. Needed on some boards (Force CPCI735). - - - Description -@@ -68,7 +66,19 @@ this driver on those mainboards. - The ServerWorks Southbridges, the Intel 440MX, and the Victory766 are - identical to the PIIX4 in I2C/SMBus support. - --A few OSB4 southbridges are known to be misconfigured by the BIOS. In this --case, you have you use the fix_hstcfg module parameter. Do not use it --unless you know you have to, because in some cases it also breaks --configuration on southbridges that don't need it. -+If you own Force CPCI735 motherboard or other OSB4 based systems you may need -+to change the SMBus Interrupt Select register so the SMBus controller uses -+the SMI mode. -+ -+1) Use lspci command and locate the PCI device with the SMBus controller: -+ 00:0f.0 ISA bridge: ServerWorks OSB4 South Bridge (rev 4f) -+ The line may vary for different chipsets. Please consult the driver source -+ for all possible PCI ids (and lspci -n to match them). Lets assume the -+ device is located at 00:0f.0. -+2) Now you just need to change the value in 0xD2 register. Get it first with -+ command: lspci -xxx -s 00:0f.0 -+ If the value is 0x3 then you need to change it to 0x1 -+ setpci -s 00:0f.0 d2.b=1 -+ -+Please note that you don't need to do that in all cases, just when the SMBus is -+not working properly. ---- gregkh-2.6.orig/drivers/i2c/busses/i2c-piix4.c -+++ gregkh-2.6/drivers/i2c/busses/i2c-piix4.c -@@ -102,13 +102,6 @@ MODULE_PARM_DESC(force_addr, - "Forcibly enable the PIIX4 at the given address. " - "EXTREMELY DANGEROUS!"); - --/* If fix_hstcfg is set to anything different from 0, we reset one of the -- registers to be a valid value. */ --static int fix_hstcfg; --module_param (fix_hstcfg, int, 0); --MODULE_PARM_DESC(fix_hstcfg, -- "Fix config register. Needed on some boards (Force CPCI735)."); -- - static int piix4_transaction(void); - - static unsigned short piix4_smba; -@@ -166,22 +159,6 @@ static int __devinit piix4_setup(struct - - pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); - -- /* Some BIOS will set up the chipset incorrectly and leave a register -- in an undefined state (causing I2C to act very strangely). */ -- if (temp & 0x02) { -- if (fix_hstcfg) { -- dev_info(&PIIX4_dev->dev, "Working around buggy BIOS " -- "(I2C)\n"); -- temp &= 0xfd; -- pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp); -- } else { -- dev_info(&PIIX4_dev->dev, "Unusual config register " -- "value\n"); -- dev_info(&PIIX4_dev->dev, "Try using fix_hstcfg=1 if " -- "you experience problems\n"); -- } -- } -- - /* If force_addr is set, we program the new address here. Just to make - sure, we disable the PIIX4 first. */ - if (force_addr) { -@@ -214,7 +191,7 @@ static int __devinit piix4_setup(struct - } - } - -- if ((temp & 0x0E) == 8) -+ if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2)) - dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n"); - else if ((temp & 0x0E) == 0) - dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); diff --git a/i2c/i2c-scx200_acb-documentation-update.patch b/i2c/i2c-scx200_acb-documentation-update.patch deleted file mode 100644 index 5cf2c211c12cea..00000000000000 --- a/i2c/i2c-scx200_acb-documentation-update.patch +++ /dev/null @@ -1,66 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:48:10 2006 -Date: Mon, 12 Jun 2006 21:48:08 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Jordan Crouse <jordan.crouse@amd.com> -Subject: [PATCH 05/14] scx200_acb: Documentation update -Message-Id: <20060612214808.35510747.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-scx200_acb-documentation-update.patch - -Documentation update for the scx200_acb driver. Hopefully this will -help future users. - -References: - -[lm-sensors] Support of i2c-nscacb (April, May 2005) - http://lists.lm-sensors.org/pipermail/lm-sensors/2005-April/011756.html - http://lists.lm-sensors.org/pipermail/lm-sensors/2005-May/012043.html - -[lm-sensors] making a geode i2c slave driver (April 2006) - http://lists.lm-sensors.org/pipermail/lm-sensors/2006-April/015998.html - -Kernel bug #6445 - http://bugzilla.kernel.org/show_bug.cgi?id=6445 - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/i2c/busses/scx200_acb | 19 ++++++++++++++++++- - 1 file changed, 18 insertions(+), 1 deletion(-) - ---- gregkh-2.6.orig/Documentation/i2c/busses/scx200_acb -+++ gregkh-2.6/Documentation/i2c/busses/scx200_acb -@@ -2,14 +2,31 @@ Kernel driver scx200_acb - - Author: Christer Weinigel <wingel@nano-system.com> - -+The driver supersedes the older, never merged driver named i2c-nscacb. -+ - Module Parameters - ----------------- - --* base: int -+* base: up to 4 ints - Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices - -+ By default the driver uses two base addresses 0x820 and 0x840. -+ If you want only one base address, specify the second as 0 so as to -+ override this default. -+ - Description - ----------- - - Enable the use of the ACCESS.bus controller on the Geode SCx200 and - SC1100 processors and the CS5535 and CS5536 Geode companion devices. -+ -+Device-specific notes -+--------------------- -+ -+The SC1100 WRAP boards are known to use base addresses 0x810 and 0x820. -+If the scx200_acb driver is built into the kernel, add the following -+parameter to your boot command line: -+ scx200_acb.base=0x810,0x820 -+If the scx200_acb driver is built as a module, add the following line to -+the file /etc/modprobe.conf instead: -+ options scx200_acb base=0x810,0x820 diff --git a/i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch b/i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch deleted file mode 100644 index d7431ca3f2e52c..00000000000000 --- a/i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch +++ /dev/null @@ -1,30 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:46:10 2006 -Date: Mon, 12 Jun 2006 21:46:04 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Jordan Crouse <jordan.crouse@amd.com> -Subject: [PATCH 04/14] scx200_acb: Mark scx200_acb_probe __init -Message-Id: <20060612214604.3050e740.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-scx200_acb-mark-scx200_acb_probe-init.patch - -In i2c bus driver scx200_acb, function scx200_acb_probe can be -tagged __init. - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/scx200_acb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/scx200_acb.c -+++ gregkh-2.6/drivers/i2c/busses/scx200_acb.c -@@ -384,7 +384,7 @@ static struct i2c_algorithm scx200_acb_a - static struct scx200_acb_iface *scx200_acb_list; - static DECLARE_MUTEX(scx200_acb_list_mutex); - --static int scx200_acb_probe(struct scx200_acb_iface *iface) -+static __init int scx200_acb_probe(struct scx200_acb_iface *iface) - { - u8 val; - diff --git a/i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch b/i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch deleted file mode 100644 index 09e3bff6fa11a9..00000000000000 --- a/i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch +++ /dev/null @@ -1,304 +0,0 @@ -From khali@linux-fr.org Mon Jun 12 12:44:31 2006 -Date: Mon, 12 Jun 2006 21:44:28 +0200 -From: Jordan Crouse <jordan.crouse@amd.com> -To: Greg KH <greg@kroah.com> -Cc: LM Sensors <lm-sensors@lm-sensors.org>, Jordan Crouse <jordan.crouse@amd.com> -Subject: [PATCH 03/14] scx200_acb: Use PCI I/O resource when appropriate -Message-Id: <20060612214428.f1a2c46b.khali@linux-fr.org> -Content-Disposition: inline; filename=i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch - -From: Jordan Crouse <jordan.crouse@amd.com> - -On the CS5535 and CS5536, the I/O resource is allocated through PCI, -so use that instead of using the MSR backdoor. - -Signed-off-by: Jordan Crouse <jordan.crouse@amd.com> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/busses/scx200_acb.c | 200 +++++++++++++++++++++++++++++----------- - 1 file changed, 147 insertions(+), 53 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/busses/scx200_acb.c -+++ gregkh-2.6/drivers/i2c/busses/scx200_acb.c -@@ -33,7 +33,6 @@ - #include <linux/delay.h> - #include <linux/mutex.h> - #include <asm/io.h> --#include <asm/msr.h> - - #include <linux/scx200.h> - -@@ -85,6 +84,10 @@ struct scx200_acb_iface { - u8 *ptr; - char needs_reset; - unsigned len; -+ -+ /* PCI device info */ -+ struct pci_dev *pdev; -+ int bar; - }; - - /* Register Definitions */ -@@ -417,17 +420,16 @@ static int scx200_acb_probe(struct scx20 - return 0; - } - --static int __init scx200_acb_create(const char *text, int base, int index) -+static __init struct scx200_acb_iface *scx200_create_iface(const char *text, -+ int index) - { - struct scx200_acb_iface *iface; - struct i2c_adapter *adapter; -- int rc; - - iface = kzalloc(sizeof(*iface), GFP_KERNEL); - if (!iface) { - printk(KERN_ERR NAME ": can't allocate memory\n"); -- rc = -ENOMEM; -- goto errout; -+ return NULL; - } - - adapter = &iface->adapter; -@@ -440,26 +442,27 @@ static int __init scx200_acb_create(con - - mutex_init(&iface->mutex); - -- if (!request_region(base, 8, adapter->name)) { -- printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", -- base, base + 8-1); -- rc = -EBUSY; -- goto errout_free; -- } -- iface->base = base; -+ return iface; -+} -+ -+static int __init scx200_acb_create(struct scx200_acb_iface *iface) -+{ -+ struct i2c_adapter *adapter; -+ int rc; -+ -+ adapter = &iface->adapter; - - rc = scx200_acb_probe(iface); - if (rc) { - printk(KERN_WARNING NAME ": probe failed\n"); -- goto errout_release; -+ return rc; - } - - scx200_acb_reset(iface); - - if (i2c_add_adapter(adapter) < 0) { - printk(KERN_ERR NAME ": failed to register\n"); -- rc = -ENODEV; -- goto errout_release; -+ return -ENODEV; - } - - down(&scx200_acb_list_mutex); -@@ -468,64 +471,148 @@ static int __init scx200_acb_create(con - up(&scx200_acb_list_mutex); - - return 0; -+} - -- errout_release: -- release_region(iface->base, 8); -+static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, -+ int bar) -+{ -+ struct scx200_acb_iface *iface; -+ int rc; -+ -+ iface = scx200_create_iface(text, 0); -+ -+ if (iface == NULL) -+ return -ENOMEM; -+ -+ iface->pdev = pdev; -+ iface->bar = bar; -+ -+ pci_enable_device_bars(iface->pdev, 1 << iface->bar); -+ -+ rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); -+ -+ if (rc != 0) { -+ printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", -+ iface->bar); -+ goto errout_free; -+ } -+ -+ iface->base = pci_resource_start(iface->pdev, iface->bar); -+ rc = scx200_acb_create(iface); -+ -+ if (rc == 0) -+ return 0; -+ -+ pci_release_region(iface->pdev, iface->bar); -+ pci_dev_put(iface->pdev); - errout_free: - kfree(iface); -- errout: - return rc; - } - --static struct pci_device_id scx200[] = { -- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, -- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, -- { }, --}; -+static int __init scx200_create_isa(const char *text, unsigned long base, -+ int index) -+{ -+ struct scx200_acb_iface *iface; -+ int rc; -+ -+ iface = scx200_create_iface(text, index); -+ -+ if (iface == NULL) -+ return -ENOMEM; -+ -+ if (request_region(base, 8, iface->adapter.name) == 0) { -+ printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", -+ base, base + 8 - 1); -+ rc = -EBUSY; -+ goto errout_free; -+ } -+ -+ iface->base = base; -+ rc = scx200_acb_create(iface); -+ -+ if (rc == 0) -+ return 0; - --static struct pci_device_id divil_pci[] = { -- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, -- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, -- { } /* NULL entry */ -+ release_region(base, 8); -+ errout_free: -+ kfree(iface); -+ return rc; -+} -+ -+/* Driver data is an index into the scx200_data array that indicates -+ * the name and the BAR where the I/O address resource is located. ISA -+ * devices are flagged with a bar value of -1 */ -+ -+static struct pci_device_id scx200_pci[] = { -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE), -+ .driver_data = 0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE), -+ .driver_data = 0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA), -+ .driver_data = 1 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA), -+ .driver_data = 2 } - }; - --#define MSR_LBAR_SMB 0x5140000B -+static struct { -+ const char *name; -+ int bar; -+} scx200_data[] = { -+ { "SCx200", -1 }, -+ { "CS5535", 0 }, -+ { "CS5536", 0 } -+}; - --static __init int scx200_add_cs553x(void) -+static __init int scx200_scan_pci(void) - { -- u32 low, hi; -- u32 smb_base; -- -- /* Grab & reserve the SMB I/O range */ -- rdmsr(MSR_LBAR_SMB, low, hi); -+ int data, dev; -+ int rc = -ENODEV; -+ struct pci_dev *pdev; -+ -+ for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) { -+ pdev = pci_get_device(scx200_pci[dev].vendor, -+ scx200_pci[dev].device, NULL); -+ -+ if (pdev == NULL) -+ continue; -+ -+ data = scx200_pci[dev].driver_data; -+ -+ /* if .bar is greater or equal to zero, this is a -+ * PCI device - otherwise, we assume -+ that the ports are ISA based -+ */ -+ -+ if (scx200_data[data].bar >= 0) -+ rc = scx200_create_pci(scx200_data[data].name, pdev, -+ scx200_data[data].bar); -+ else { -+ int i; -+ -+ for (i = 0; i < MAX_DEVICES; ++i) { -+ if (base[i] == 0) -+ continue; -+ -+ rc = scx200_create_isa(scx200_data[data].name, -+ base[i], -+ i); -+ } -+ } - -- /* Check the IO mask and whether SMB is enabled */ -- if (hi != 0x0000F001) { -- printk(KERN_WARNING NAME ": SMBus not enabled\n"); -- return -ENODEV; -+ break; - } - -- /* SMBus IO size is 8 bytes */ -- smb_base = low & 0x0000FFF8; -- -- return scx200_acb_create("CS5535", smb_base, 0); -+ return rc; - } - - static int __init scx200_acb_init(void) - { -- int i; -- int rc = -ENODEV; -+ int rc; - - pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); - -- /* Verify that this really is a SCx200 processor */ -- if (pci_dev_present(scx200)) { -- for (i = 0; i < MAX_DEVICES; ++i) { -- if (base[i] > 0) -- rc = scx200_acb_create("SCx200", base[i], i); -- } -- } else if (pci_dev_present(divil_pci)) -- rc = scx200_add_cs553x(); -+ rc = scx200_scan_pci(); - - /* If at least one bus was created, init must succeed */ - if (scx200_acb_list) -@@ -543,7 +630,14 @@ static void __exit scx200_acb_cleanup(vo - up(&scx200_acb_list_mutex); - - i2c_del_adapter(&iface->adapter); -- release_region(iface->base, 8); -+ -+ if (iface->pdev) { -+ pci_release_region(iface->pdev, iface->bar); -+ pci_dev_put(iface->pdev); -+ } -+ else -+ release_region(iface->base, 8); -+ - kfree(iface); - down(&scx200_acb_list_mutex); - } diff --git a/i2c/rtc-add-support-for-m41t81-m41t85-chips-to-m41t00-driver.patch b/i2c/rtc-add-support-for-m41t81-m41t85-chips-to-m41t00-driver.patch deleted file mode 100644 index 01b879a361b015..00000000000000 --- a/i2c/rtc-add-support-for-m41t81-m41t85-chips-to-m41t00-driver.patch +++ /dev/null @@ -1,505 +0,0 @@ -From khali@linux-fr.org Tue Apr 25 04:06:58 2006 -Date: Tue, 25 Apr 2006 13:04:54 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: "Mark A. Greer" <mgreer@mvista.com> -Subject: I2C: m41t00: Add support for the ST M41T81 and M41T85 -Message-Id: <20060425130454.f86d68db.khali@linux-fr.org> -Content-Disposition: inline; filename=rtc-add-support-for-m41t81-m41t85-chips-to-m41t00-driver.patch - -From: "Mark A. Greer" <mgreer@mvista.com> - -This patch adds support for the ST m41t81 and m41t85 i2c rtc chips -to the existing m41t00 driver. - -Since there is no way to reliably determine what type of rtc chip -is in use, the chip type is passed in via platform_data. The i2c -address and square wave frequency are passed in via platform_data -as well. To accommodate the use of platform_data, a new header -file include/linux/m41t00.h has been added. - -The m41t81 and m41t85 chips halt the updating of their time registers -while they are being accessed. They resume when a stop condition -exists on the i2c bus or when non-time related regs are accessed. -To make the best use of that facility and to make more efficient -use of the i2c bus, this patch replaces multiple i2c_smbus_xxx calls -with a single i2c_transfer call. - -Signed-off-by: Mark A. Greer <mgreer@mvista.com> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/chips/m41t00.c | 309 ++++++++++++++++++++++++++++++++++----------- - include/linux/m41t00.h | 50 +++++++ - 2 files changed, 289 insertions(+), 70 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/chips/m41t00.c -+++ gregkh-2.6/drivers/i2c/chips/m41t00.c -@@ -1,9 +1,9 @@ - /* -- * I2C client/driver for the ST M41T00 Real-Time Clock chip. -+ * I2C client/driver for the ST M41T00 family of i2c rtc chips. - * - * Author: Mark A. Greer <mgreer@mvista.com> - * -- * 2005 (c) MontaVista Software, Inc. This file is licensed under -+ * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. -@@ -19,21 +19,17 @@ - #include <linux/i2c.h> - #include <linux/rtc.h> - #include <linux/bcd.h> --#include <linux/mutex.h> - #include <linux/workqueue.h> -- -+#include <linux/platform_device.h> -+#include <linux/m41t00.h> - #include <asm/time.h> - #include <asm/rtc.h> - --#define M41T00_DRV_NAME "m41t00" -- --static DEFINE_MUTEX(m41t00_mutex); -- - static struct i2c_driver m41t00_driver; - static struct i2c_client *save_client; - - static unsigned short ignore[] = { I2C_CLIENT_END }; --static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; -+static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END }; - - static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_addr, -@@ -41,34 +37,92 @@ static struct i2c_client_address_data ad - .ignore = ignore, - }; - -+struct m41t00_chip_info { -+ u8 type; -+ char *name; -+ u8 read_limit; -+ u8 sec; /* Offsets for chip regs */ -+ u8 min; -+ u8 hour; -+ u8 day; -+ u8 mon; -+ u8 year; -+ u8 alarm_mon; -+ u8 alarm_hour; -+ u8 sqw; -+ u8 sqw_freq; -+}; -+ -+static struct m41t00_chip_info m41t00_chip_info_tbl[] = { -+ { -+ .type = M41T00_TYPE_M41T00, -+ .name = "m41t00", -+ .read_limit = 5, -+ .sec = 0, -+ .min = 1, -+ .hour = 2, -+ .day = 4, -+ .mon = 5, -+ .year = 6, -+ }, -+ { -+ .type = M41T00_TYPE_M41T81, -+ .name = "m41t81", -+ .read_limit = 1, -+ .sec = 1, -+ .min = 2, -+ .hour = 3, -+ .day = 5, -+ .mon = 6, -+ .year = 7, -+ .alarm_mon = 0xa, -+ .alarm_hour = 0xc, -+ .sqw = 0x13, -+ }, -+ { -+ .type = M41T00_TYPE_M41T85, -+ .name = "m41t85", -+ .read_limit = 1, -+ .sec = 1, -+ .min = 2, -+ .hour = 3, -+ .day = 5, -+ .mon = 6, -+ .year = 7, -+ .alarm_mon = 0xa, -+ .alarm_hour = 0xc, -+ .sqw = 0x13, -+ }, -+}; -+static struct m41t00_chip_info *m41t00_chip; -+ - ulong - m41t00_get_rtc_time(void) - { - s32 sec, min, hour, day, mon, year; - s32 sec1, min1, hour1, day1, mon1, year1; -- ulong limit = 10; -+ u8 reads = 0; -+ u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */ -+ struct i2c_msg msgs[] = { -+ { -+ .addr = save_client->addr, -+ .flags = 0, -+ .len = 1, -+ .buf = msgbuf, -+ }, -+ { -+ .addr = save_client->addr, -+ .flags = I2C_M_RD, -+ .len = 8, -+ .buf = buf, -+ }, -+ }; - - sec = min = hour = day = mon = year = 0; -- sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; - -- mutex_lock(&m41t00_mutex); - do { -- if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) -- && ((min = i2c_smbus_read_byte_data(save_client, 1)) -- >= 0) -- && ((hour = i2c_smbus_read_byte_data(save_client, 2)) -- >= 0) -- && ((day = i2c_smbus_read_byte_data(save_client, 4)) -- >= 0) -- && ((mon = i2c_smbus_read_byte_data(save_client, 5)) -- >= 0) -- && ((year = i2c_smbus_read_byte_data(save_client, 6)) -- >= 0) -- && ((sec == sec1) && (min == min1) && (hour == hour1) -- && (day == day1) && (mon == mon1) -- && (year == year1))) -- -- break; -+ if (i2c_transfer(save_client->adapter, msgs, 2) < 0) -+ goto read_err; - - sec1 = sec; - min1 = min; -@@ -76,21 +130,21 @@ m41t00_get_rtc_time(void) - day1 = day; - mon1 = mon; - year1 = year; -- } while (--limit > 0); -- mutex_unlock(&m41t00_mutex); -- -- if (limit == 0) { -- dev_warn(&save_client->dev, -- "m41t00: can't read rtc chip\n"); -- sec = min = hour = day = mon = year = 0; -- } - -- sec &= 0x7f; -- min &= 0x7f; -- hour &= 0x3f; -- day &= 0x3f; -- mon &= 0x1f; -- year &= 0xff; -+ sec = buf[m41t00_chip->sec] & 0x7f; -+ min = buf[m41t00_chip->min] & 0x7f; -+ hour = buf[m41t00_chip->hour] & 0x3f; -+ day = buf[m41t00_chip->day] & 0x3f; -+ mon = buf[m41t00_chip->mon] & 0x1f; -+ year = buf[m41t00_chip->year]; -+ } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1) -+ || (min != min1) || (hour != hour1) || (day != day1) -+ || (mon != mon1) || (year != year1))); -+ -+ if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1) -+ || (hour != hour1) || (day != day1) || (mon != mon1) -+ || (year != year1))) -+ goto read_err; - - sec = BCD2BIN(sec); - min = BCD2BIN(min); -@@ -104,40 +158,60 @@ m41t00_get_rtc_time(void) - year += 100; - - return mktime(year, mon, day, hour, min, sec); -+ -+read_err: -+ dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n"); -+ return 0; - } -+EXPORT_SYMBOL_GPL(m41t00_get_rtc_time); - - static void - m41t00_set(void *arg) - { - struct rtc_time tm; -- ulong nowtime = *(ulong *)arg; -+ int nowtime = *(int *)arg; -+ s32 sec, min, hour, day, mon, year; -+ u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 }; -+ struct i2c_msg msgs[] = { -+ { -+ .addr = save_client->addr, -+ .flags = 0, -+ .len = 1, -+ .buf = msgbuf, -+ }, -+ { -+ .addr = save_client->addr, -+ .flags = I2C_M_RD, -+ .len = 8, -+ .buf = buf, -+ }, -+ }; - - to_tm(nowtime, &tm); - tm.tm_year = (tm.tm_year - 1900) % 100; - -- tm.tm_sec = BIN2BCD(tm.tm_sec); -- tm.tm_min = BIN2BCD(tm.tm_min); -- tm.tm_hour = BIN2BCD(tm.tm_hour); -- tm.tm_mon = BIN2BCD(tm.tm_mon); -- tm.tm_mday = BIN2BCD(tm.tm_mday); -- tm.tm_year = BIN2BCD(tm.tm_year); -- -- mutex_lock(&m41t00_mutex); -- if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) -- || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) -- < 0) -- || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) -- < 0) -- || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) -- < 0) -- || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) -- < 0) -- || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) -- < 0)) -+ sec = BIN2BCD(tm.tm_sec); -+ min = BIN2BCD(tm.tm_min); -+ hour = BIN2BCD(tm.tm_hour); -+ day = BIN2BCD(tm.tm_mday); -+ mon = BIN2BCD(tm.tm_mon); -+ year = BIN2BCD(tm.tm_year); -+ -+ /* Read reg values into buf[0..7]/wbuf[1..8] */ -+ if (i2c_transfer(save_client->adapter, msgs, 2) < 0) { -+ dev_err(&save_client->dev, "m41t00_set: Read error\n"); -+ return; -+ } - -- dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); -+ wbuf[0] = 0; /* offset into rtc's regs */ -+ buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f); -+ buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f); -+ buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f); -+ buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f); -+ buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f); - -- mutex_unlock(&m41t00_mutex); -+ if (i2c_master_send(save_client, wbuf, 9) < 0) -+ dev_err(&save_client->dev, "m41t00_set: Write error\n"); - } - - static ulong new_time; -@@ -156,6 +230,48 @@ m41t00_set_rtc_time(ulong nowtime) - - return 0; - } -+EXPORT_SYMBOL_GPL(m41t00_set_rtc_time); -+ -+/* -+ ***************************************************************************** -+ * -+ * platform_data Driver Interface -+ * -+ ***************************************************************************** -+ */ -+static int __init -+m41t00_platform_probe(struct platform_device *pdev) -+{ -+ struct m41t00_platform_data *pdata; -+ int i; -+ -+ if (pdev && (pdata = pdev->dev.platform_data)) { -+ normal_addr[0] = pdata->i2c_addr; -+ -+ for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++) -+ if (m41t00_chip_info_tbl[i].type == pdata->type) { -+ m41t00_chip = &m41t00_chip_info_tbl[i]; -+ m41t00_chip->sqw_freq = pdata->sqw_freq; -+ return 0; -+ } -+ } -+ return -ENODEV; -+} -+ -+static int __exit -+m41t00_platform_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+static struct platform_driver m41t00_platform_driver = { -+ .probe = m41t00_platform_probe, -+ .remove = m41t00_platform_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = M41T00_DRV_NAME, -+ }, -+}; - - /* - ***************************************************************************** -@@ -170,23 +286,71 @@ m41t00_probe(struct i2c_adapter *adap, i - struct i2c_client *client; - int rc; - -+ if (!i2c_check_functionality(adap, I2C_FUNC_I2C -+ | I2C_FUNC_SMBUS_BYTE_DATA)) -+ return 0; -+ - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - -- strlcpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); -+ strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE); - client->addr = addr; - client->adapter = adap; - client->driver = &m41t00_driver; - -- if ((rc = i2c_attach_client(client)) != 0) { -- kfree(client); -- return rc; -+ if ((rc = i2c_attach_client(client))) -+ goto attach_err; -+ -+ if (m41t00_chip->type != M41T00_TYPE_M41T00) { -+ /* If asked, disable SQW, set SQW frequency & re-enable */ -+ if (m41t00_chip->sqw_freq) -+ if (((rc = i2c_smbus_read_byte_data(client, -+ m41t00_chip->alarm_mon)) < 0) -+ || ((rc = i2c_smbus_write_byte_data(client, -+ m41t00_chip->alarm_mon, rc & ~0x40)) <0) -+ || ((rc = i2c_smbus_write_byte_data(client, -+ m41t00_chip->sqw, -+ m41t00_chip->sqw_freq)) < 0) -+ || ((rc = i2c_smbus_write_byte_data(client, -+ m41t00_chip->alarm_mon, rc | 0x40)) <0)) -+ goto sqw_err; -+ -+ /* Make sure HT (Halt Update) bit is cleared */ -+ if ((rc = i2c_smbus_read_byte_data(client, -+ m41t00_chip->alarm_hour)) < 0) -+ goto ht_err; -+ -+ if (rc & 0x40) -+ if ((rc = i2c_smbus_write_byte_data(client, -+ m41t00_chip->alarm_hour, rc & ~0x40))<0) -+ goto ht_err; - } - -- m41t00_wq = create_singlethread_workqueue("m41t00"); -+ /* Make sure ST (stop) bit is cleared */ -+ if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0) -+ goto st_err; -+ -+ if (rc & 0x80) -+ if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec, -+ rc & ~0x80)) < 0) -+ goto st_err; -+ -+ m41t00_wq = create_singlethread_workqueue(m41t00_chip->name); - save_client = client; - return 0; -+ -+st_err: -+ dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n"); -+ goto attach_err; -+ht_err: -+ dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n"); -+ goto attach_err; -+sqw_err: -+ dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n"); -+attach_err: -+ kfree(client); -+ return rc; - } - - static int -@@ -219,13 +383,18 @@ static struct i2c_driver m41t00_driver = - static int __init - m41t00_init(void) - { -- return i2c_add_driver(&m41t00_driver); -+ int rc; -+ -+ if (!(rc = platform_driver_register(&m41t00_platform_driver))) -+ rc = i2c_add_driver(&m41t00_driver); -+ return rc; - } - - static void __exit - m41t00_exit(void) - { - i2c_del_driver(&m41t00_driver); -+ platform_driver_unregister(&m41t00_platform_driver); - } - - module_init(m41t00_init); ---- /dev/null -+++ gregkh-2.6/include/linux/m41t00.h -@@ -0,0 +1,50 @@ -+/* -+ * Definitions for the ST M41T00 family of i2c rtc chips. -+ * -+ * Author: Mark A. Greer <mgreer@mvista.com> -+ * -+ * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under -+ * the terms of the GNU General Public License version 2. This program -+ * is licensed "as is" without any warranty of any kind, whether express -+ * or implied. -+ */ -+ -+#ifndef _M41T00_H -+#define _M41T00_H -+ -+#define M41T00_DRV_NAME "m41t00" -+#define M41T00_I2C_ADDR 0x68 -+ -+#define M41T00_TYPE_M41T00 0 -+#define M41T00_TYPE_M41T81 81 -+#define M41T00_TYPE_M41T85 85 -+ -+struct m41t00_platform_data { -+ u8 type; -+ u8 i2c_addr; -+ u8 sqw_freq; -+}; -+ -+/* SQW output disabled, this is default value by power on */ -+#define M41T00_SQW_DISABLE (0) -+ -+#define M41T00_SQW_32KHZ (1<<4) /* 32.768 KHz */ -+#define M41T00_SQW_8KHZ (2<<4) /* 8.192 KHz */ -+#define M41T00_SQW_4KHZ (3<<4) /* 4.096 KHz */ -+#define M41T00_SQW_2KHZ (4<<4) /* 2.048 KHz */ -+#define M41T00_SQW_1KHZ (5<<4) /* 1.024 KHz */ -+#define M41T00_SQW_512HZ (6<<4) /* 512 Hz */ -+#define M41T00_SQW_256HZ (7<<4) /* 256 Hz */ -+#define M41T00_SQW_128HZ (8<<4) /* 128 Hz */ -+#define M41T00_SQW_64HZ (9<<4) /* 64 Hz */ -+#define M41T00_SQW_32HZ (10<<4) /* 32 Hz */ -+#define M41T00_SQW_16HZ (11<<4) /* 16 Hz */ -+#define M41T00_SQW_8HZ (12<<4) /* 8 Hz */ -+#define M41T00_SQW_4HZ (13<<4) /* 4 Hz */ -+#define M41T00_SQW_2HZ (14<<4) /* 2 Hz */ -+#define M41T00_SQW_1HZ (15<<4) /* 1 Hz */ -+ -+extern ulong m41t00_get_rtc_time(void); -+extern int m41t00_set_rtc_time(ulong nowtime); -+ -+#endif /* _M41T00_H */ diff --git a/i2c/rtc-m41t00-driver-cleanup.patch b/i2c/rtc-m41t00-driver-cleanup.patch deleted file mode 100644 index 33b19dc0703779..00000000000000 --- a/i2c/rtc-m41t00-driver-cleanup.patch +++ /dev/null @@ -1,145 +0,0 @@ -From khali@linux-fr.org Fri Mar 31 13:06:41 2006 -Date: Fri, 31 Mar 2006 23:06:46 +0200 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: "Mark A. Greer" <mgreer@mvista.com> -Subject: [PATCH 3/3] i2c: cleanup m41t00 -Message-Id: <20060331230646.e06f73a1.khali@linux-fr.org> -Content-Disposition: inline; filename=rtc-m41t00-driver-cleanup.patch - -From: "Mark A. Greer" <mgreer@mvista.com> - -This patch does some cleanup to the m41t00 i2c/rtc driver including: -- use BCD2BIN/BIN2BCD instead of BCD_TO_BIN/BIN_TO_BCD -- use strlcpy instead of strncpy -- some whitespace cleanup - -Signed-off-by: Mark A. Greer <mgreer@mvista.com> -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/i2c/chips/m41t00.c | 49 +++++++++++++++++++-------------------------- - 1 file changed, 21 insertions(+), 28 deletions(-) - ---- gregkh-2.6.orig/drivers/i2c/chips/m41t00.c -+++ gregkh-2.6/drivers/i2c/chips/m41t00.c -@@ -1,6 +1,4 @@ - /* -- * drivers/i2c/chips/m41t00.c -- * - * I2C client/driver for the ST M41T00 Real-Time Clock chip. - * - * Author: Mark A. Greer <mgreer@mvista.com> -@@ -13,9 +11,6 @@ - /* - * This i2c client/driver wedges between the drivers/char/genrtc.c RTC - * interface and the SMBus interface of the i2c subsystem. -- * It would be more efficient to use i2c msgs/i2c_transfer directly but, as -- * recommened in .../Documentation/i2c/writing-clients section -- * "Sending and receiving", using SMBus level communication is preferred. - */ - - #include <linux/kernel.h> -@@ -41,17 +36,17 @@ static unsigned short ignore[] = { I2C_C - static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; - - static struct i2c_client_address_data addr_data = { -- .normal_i2c = normal_addr, -- .probe = ignore, -- .ignore = ignore, -+ .normal_i2c = normal_addr, -+ .probe = ignore, -+ .ignore = ignore, - }; - - ulong - m41t00_get_rtc_time(void) - { -- s32 sec, min, hour, day, mon, year; -- s32 sec1, min1, hour1, day1, mon1, year1; -- ulong limit = 10; -+ s32 sec, min, hour, day, mon, year; -+ s32 sec1, min1, hour1, day1, mon1, year1; -+ ulong limit = 10; - - sec = min = hour = day = mon = year = 0; - sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; -@@ -97,12 +92,12 @@ m41t00_get_rtc_time(void) - mon &= 0x1f; - year &= 0xff; - -- BCD_TO_BIN(sec); -- BCD_TO_BIN(min); -- BCD_TO_BIN(hour); -- BCD_TO_BIN(day); -- BCD_TO_BIN(mon); -- BCD_TO_BIN(year); -+ sec = BCD2BIN(sec); -+ min = BCD2BIN(min); -+ hour = BCD2BIN(hour); -+ day = BCD2BIN(day); -+ mon = BCD2BIN(mon); -+ year = BCD2BIN(year); - - year += 1900; - if (year < 1970) -@@ -115,17 +110,17 @@ static void - m41t00_set(void *arg) - { - struct rtc_time tm; -- ulong nowtime = *(ulong *)arg; -+ ulong nowtime = *(ulong *)arg; - - to_tm(nowtime, &tm); - tm.tm_year = (tm.tm_year - 1900) % 100; - -- BIN_TO_BCD(tm.tm_sec); -- BIN_TO_BCD(tm.tm_min); -- BIN_TO_BCD(tm.tm_hour); -- BIN_TO_BCD(tm.tm_mon); -- BIN_TO_BCD(tm.tm_mday); -- BIN_TO_BCD(tm.tm_year); -+ tm.tm_sec = BIN2BCD(tm.tm_sec); -+ tm.tm_min = BIN2BCD(tm.tm_min); -+ tm.tm_hour = BIN2BCD(tm.tm_hour); -+ tm.tm_mon = BIN2BCD(tm.tm_mon); -+ tm.tm_mday = BIN2BCD(tm.tm_mday); -+ tm.tm_year = BIN2BCD(tm.tm_year); - - mutex_lock(&m41t00_mutex); - if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) -@@ -143,7 +138,6 @@ m41t00_set(void *arg) - dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); - - mutex_unlock(&m41t00_mutex); -- return; - } - - static ulong new_time; -@@ -180,7 +174,7 @@ m41t00_probe(struct i2c_adapter *adap, i - if (!client) - return -ENOMEM; - -- strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); -+ strlcpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); - client->addr = addr; - client->adapter = adap; - client->driver = &m41t00_driver; -@@ -204,7 +198,7 @@ m41t00_attach(struct i2c_adapter *adap) - static int - m41t00_detach(struct i2c_client *client) - { -- int rc; -+ int rc; - - if ((rc = i2c_detach_client(client)) == 0) { - kfree(client); -@@ -232,7 +226,6 @@ static void __exit - m41t00_exit(void) - { - i2c_del_driver(&m41t00_driver); -- return; - } - - module_init(m41t00_init); diff --git a/i2c/w1-added-default-generic-read-write-operations.patch b/i2c/w1-added-default-generic-read-write-operations.patch deleted file mode 100644 index 87cce1b0c6efcc..00000000000000 --- a/i2c/w1-added-default-generic-read-write-operations.patch +++ /dev/null @@ -1,155 +0,0 @@ -From johnpol@2ka.mipt.ru Thu Mar 23 07:59:58 2006 -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [PATCH 1/5] w1: Added default generic read/write operations. -Date: Thu, 23 Mar 2006 19:11:58 +0300 -Message-Id: <11431303182664@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> - - -Special file in each w1 slave device's directory called "rw" is created -each time new slave and no appropriate w1 family is registered. -"rw" file supports read and write operations, which allows to perform -almost any kind of operations. Each logical operation is a transaction -in nature, which can contain several (two or one) low-level operations. -Let's see how one can read EEPROM context: -1. one must write control buffer, i.e. buffer containing command byte -and two byte address. At this step bus is reset and appropriate device -is selected using either W1_SKIP_ROM or W1_MATCH_ROM command. -Then provided control buffer is being written to the wire. -2. reading. This will issue reading eeprom response. - -It is possible that between 1. and 2. w1 master thread will reset bus for -searching and slave device will be even removed, but in this case 0xff will -be read, since no device was selected. - -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - Documentation/w1/w1.generic | 18 +++++++++-- - drivers/w1/w1.c | 69 +++++++++++++++++++++++++++++++++++++++++++- - drivers/w1/w1.h | 2 - - 3 files changed, 84 insertions(+), 5 deletions(-) - ---- gregkh-2.6.orig/Documentation/w1/w1.generic -+++ gregkh-2.6/Documentation/w1/w1.generic -@@ -27,8 +27,19 @@ When a w1 master driver registers with t - - When a device is found on the bus, w1 core checks if driver for it's family is - loaded. If so, the family driver is attached to the slave. --If there is no driver for the family, a simple sysfs entry is created --for the slave device. -+If there is no driver for the family, default one is assigned, which allows to perform -+almost any kind of operations. Each logical operation is a transaction -+in nature, which can contain several (two or one) low-level operations. -+Let's see how one can read EEPROM context: -+1. one must write control buffer, i.e. buffer containing command byte -+and two byte address. At this step bus is reset and appropriate device -+is selected using either W1_SKIP_ROM or W1_MATCH_ROM command. -+Then provided control buffer is being written to the wire. -+2. reading. This will issue reading eeprom response. -+ -+It is possible that between 1. and 2. w1 master thread will reset bus for searching -+and slave device will be even removed, but in this case 0xff will -+be read, since no device was selected. - - - W1 device families -@@ -89,4 +100,5 @@ driver - (standard) symlink - name - the device name, usually the same as the directory name - w1_slave - (optional) a binary file whose meaning depends on the - family driver -- -+rw - (optional) created for slave devices which do not have -+ appropriate family driver. Allows to read/write binary data. ---- gregkh-2.6.orig/drivers/w1/w1.c -+++ gregkh-2.6/drivers/w1/w1.c -@@ -139,7 +139,74 @@ static struct bin_attribute w1_slave_att - }; - - /* Default family */ --static struct w1_family w1_default_family; -+ -+static ssize_t w1_default_write(struct kobject *kobj, char *buf, loff_t off, size_t count) -+{ -+ struct w1_slave *sl = kobj_to_w1_slave(kobj); -+ -+ if (down_interruptible(&sl->master->mutex)) { -+ count = 0; -+ goto out; -+ } -+ -+ if (w1_reset_select_slave(sl)) { -+ count = 0; -+ goto out_up; -+ } -+ -+ w1_write_block(sl->master, buf, count); -+ -+out_up: -+ up(&sl->master->mutex); -+out: -+ return count; -+} -+ -+static ssize_t w1_default_read(struct kobject *kobj, char *buf, loff_t off, size_t count) -+{ -+ struct w1_slave *sl = kobj_to_w1_slave(kobj); -+ -+ if (down_interruptible(&sl->master->mutex)) { -+ count = 0; -+ goto out; -+ } -+ -+ w1_read_block(sl->master, buf, count); -+ -+ up(&sl->master->mutex); -+out: -+ return count; -+} -+ -+static struct bin_attribute w1_default_attr = { -+ .attr = { -+ .name = "rw", -+ .mode = S_IRUGO | S_IWUSR, -+ .owner = THIS_MODULE, -+ }, -+ .size = PAGE_SIZE, -+ .read = w1_default_read, -+ .write = w1_default_write, -+}; -+ -+static int w1_default_add_slave(struct w1_slave *sl) -+{ -+ return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr); -+} -+ -+static void w1_default_remove_slave(struct w1_slave *sl) -+{ -+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr); -+} -+ -+static struct w1_family_ops w1_default_fops = { -+ .add_slave = w1_default_add_slave, -+ .remove_slave = w1_default_remove_slave, -+}; -+ -+static struct w1_family w1_default_family = { -+ .fops = &w1_default_fops, -+}; - - static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); - ---- gregkh-2.6.orig/drivers/w1/w1.h -+++ gregkh-2.6/drivers/w1/w1.h -@@ -60,7 +60,7 @@ struct w1_reg_num - #define W1_READ_PSUPPLY 0xB4 - #define W1_MATCH_ROM 0x55 - --#define W1_SLAVE_ACTIVE (1<<0) -+#define W1_SLAVE_ACTIVE 0 - - struct w1_slave - { diff --git a/i2c/w1-clean-up-w1_con-dependency.patch b/i2c/w1-clean-up-w1_con-dependency.patch deleted file mode 100644 index 5b05226faf0e9a..00000000000000 --- a/i2c/w1-clean-up-w1_con-dependency.patch +++ /dev/null @@ -1,32 +0,0 @@ -From johnpol@2ka.mipt.ru Thu Apr 27 08:40:59 2006 -Date: Thu, 27 Apr 2006 19:40:27 +0400 -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -Subject: w1: clean up W1_CON dependency. -Message-ID: <20060427154026.GB31564@2ka.mipt.ru> -Content-Disposition: inline - -If w1 is not enabled, w1_con should not appear in configuration, -even if no logic is turned on without w1. -W1_CON should depend on W1 also. - -Signed-off-by: Randy Dunlap <rdunlap@xenotime.net> -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/w1/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/drivers/w1/Kconfig -+++ gregkh-2.6/drivers/w1/Kconfig -@@ -12,7 +12,7 @@ config W1 - will be called wire.ko. - - config W1_CON -- depends on CONNECTOR -+ depends on CONNECTOR && W1 - bool "Userspace communication over connector" - default y - --- help --- diff --git a/i2c/w1-cleanups.patch b/i2c/w1-cleanups.patch deleted file mode 100644 index 8bf8ffe221a460..00000000000000 --- a/i2c/w1-cleanups.patch +++ /dev/null @@ -1,103 +0,0 @@ -From johnpol@2ka.mipt.ru Tue Apr 4 09:38:51 2006 -Date: Tue, 4 Apr 2006 20:35:22 +0400 -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -To: Adrian Bunk <bunk@stusta.de> -Cc: Andrew Morton <akpm@osdl.org>, Greg Kroah-Hartman <gregkh@suse.de>, linux-kernel@vger.kernel.org -Subject: W1: cleanups -Message-ID: <20060404163522.GA29486@2ka.mipt.ru> -Content-Disposition: inline - -Nice cleanup spotted by Adrian Bunk, which was lost due to moving to the -completely new functionality. - -Shame-shame-shame on me. - -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/w1.c | 6 ++++-- - drivers/w1/w1.h | 10 ++++++++++ - drivers/w1/w1_int.c | 12 +----------- - 3 files changed, 15 insertions(+), 13 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/w1.c -+++ gregkh-2.6/drivers/w1/w1.c -@@ -214,11 +214,12 @@ struct device w1_master_device = { - .release = &w1_master_release - }; - --struct device_driver w1_slave_driver = { -+static struct device_driver w1_slave_driver = { - .name = "w1_slave_driver", - .bus = &w1_bus_type, - }; - -+#if 0 - struct device w1_slave_device = { - .parent = NULL, - .bus = &w1_bus_type, -@@ -226,6 +227,7 @@ struct device w1_slave_device = { - .driver = &w1_slave_driver, - .release = &w1_slave_release - }; -+#endif /* 0 */ - - static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf) - { -@@ -383,7 +385,7 @@ int w1_create_master_attributes(struct w - return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group); - } - --void w1_destroy_master_attributes(struct w1_master *master) -+static void w1_destroy_master_attributes(struct w1_master *master) - { - sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); - } ---- gregkh-2.6.orig/drivers/w1/w1.h -+++ gregkh-2.6/drivers/w1/w1.h -@@ -213,6 +213,16 @@ static inline struct w1_master* dev_to_w - return container_of(dev, struct w1_master, dev); - } - -+extern struct device_driver w1_master_driver; -+extern struct bus_type w1_bus_type; -+extern struct device w1_master_device; -+extern int w1_max_slave_count; -+extern int w1_max_slave_ttl; -+extern struct list_head w1_masters; -+extern struct mutex w1_mlock; -+ -+extern int w1_process(void *); -+ - #endif /* __KERNEL__ */ - - #endif /* __W1_H */ ---- gregkh-2.6.orig/drivers/w1/w1_int.c -+++ gregkh-2.6/drivers/w1/w1_int.c -@@ -30,16 +30,6 @@ - - static u32 w1_ids = 1; - --extern struct device_driver w1_master_driver; --extern struct bus_type w1_bus_type; --extern struct device w1_master_device; --extern int w1_max_slave_count; --extern int w1_max_slave_ttl; --extern struct list_head w1_masters; --extern struct mutex w1_mlock; -- --extern int w1_process(void *); -- - static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, - struct device_driver *driver, - struct device *device) -@@ -96,7 +86,7 @@ static struct w1_master * w1_alloc_dev(u - return dev; - } - --void w1_free_dev(struct w1_master *dev) -+static void w1_free_dev(struct w1_master *dev) - { - device_unregister(&dev->dev); - } diff --git a/i2c/w1-exports.patch b/i2c/w1-exports.patch deleted file mode 100644 index ee9e48a7b915e9..00000000000000 --- a/i2c/w1-exports.patch +++ /dev/null @@ -1,84 +0,0 @@ -From akpm@osdl.org Mon Apr 3 22:52:19 2006 -Message-Id: <200604040552.k345q7tk016068@shell0.pdx.osdl.net> -Subject: w1 exports -To: akpm@osdl.org, greg@kroah.com, johnpol@2ka.mipt.ru, mm-commits@vger.kernel.org -From: akpm@osdl.org -Date: Mon, 03 Apr 2006 22:51:17 -0700 - - -From: Andrew Morton <akpm@osdl.org> - -WARNING: "w1_read_block" [drivers/w1/slaves/w1_therm.ko] undefined! -WARNING: "w1_write_8" [drivers/w1/slaves/w1_therm.ko] undefined! -WARNING: "w1_reset_select_slave" [drivers/w1/slaves/w1_therm.ko] undefined! -WARNING: "w1_reset_bus" [drivers/w1/slaves/w1_ds2433.ko] undefined! -WARNING: "w1_write_8" [drivers/w1/slaves/w1_ds2433.ko] undefined! -WARNING: "w1_read_block" [drivers/w1/slaves/w1_ds2433.ko] undefined! -WARNING: "w1_write_block" [drivers/w1/slaves/w1_ds2433.ko] undefined! -WARNING: "w1_reset_select_slave" [drivers/w1/slaves/w1_ds2433.ko] undefined! - -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Andrew Morton <akpm@osdl.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/w1_io.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/w1_io.c -+++ gregkh-2.6/drivers/w1/w1_io.c -@@ -23,6 +23,7 @@ - - #include <linux/delay.h> - #include <linux/moduleparam.h> -+#include <linux/module.h> - - #include "w1.h" - #include "w1_log.h" -@@ -107,6 +108,7 @@ void w1_write_8(struct w1_master *dev, u - for (i = 0; i < 8; ++i) - w1_touch_bit(dev, (byte >> i) & 0x1); - } -+EXPORT_SYMBOL_GPL(w1_write_8); - - - /** -@@ -207,6 +209,7 @@ void w1_write_block(struct w1_master *de - for (i = 0; i < len; ++i) - w1_write_8(dev, buf[i]); - } -+EXPORT_SYMBOL_GPL(w1_write_block); - - /** - * Reads a series of bytes. -@@ -231,6 +234,7 @@ u8 w1_read_block(struct w1_master *dev, - - return ret; - } -+EXPORT_SYMBOL_GPL(w1_read_block); - - /** - * Issues a reset bus sequence. -@@ -256,6 +260,7 @@ int w1_reset_bus(struct w1_master *dev) - - return result; - } -+EXPORT_SYMBOL_GPL(w1_reset_bus); - - u8 w1_calc_crc8(u8 * data, int len) - { -@@ -266,6 +271,7 @@ u8 w1_calc_crc8(u8 * data, int len) - - return crc; - } -+EXPORT_SYMBOL_GPL(w1_calc_crc8); - - void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) - { -@@ -298,5 +304,4 @@ int w1_reset_select_slave(struct w1_slav - } - return 0; - } -- --EXPORT_SYMBOL_GPL(w1_calc_crc8); -+EXPORT_SYMBOL_GPL(w1_reset_select_slave); diff --git a/i2c/w1-fix-dependencies-of-w1_slave_ds2433_crc.patch b/i2c/w1-fix-dependencies-of-w1_slave_ds2433_crc.patch deleted file mode 100644 index 9a1519198b8d0d..00000000000000 --- a/i2c/w1-fix-dependencies-of-w1_slave_ds2433_crc.patch +++ /dev/null @@ -1,33 +0,0 @@ -From akpm@osdl.org Tue Apr 18 21:19:10 2006 -Message-Id: <200604190419.k3J4J1tF008521@shell0.pdx.osdl.net> -Subject: W1: fix dependencies of W1_SLAVE_DS2433_CRC -To: greg@kroah.com -Cc: akpm@osdl.org, jean-luc.leger@dspnet.fr.eu.org -From: akpm@osdl.org -Date: Tue, 18 Apr 2006 21:18:20 -0700 - - -From: Jean-Luc Leger <jean-luc.leger@dspnet.fr.eu.org> - -Default values for boolean and tristate options can only be 'y', 'm' or 'n'. -This patch fixes dependencies of W1_SLAVE_DS2433_CRC. - -Signed-off-by: Jean-Luc Leger <jean-luc.leger@dspnet.fr.eu.org> -Signed-off-by: Andrew Morton <akpm@osdl.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/slaves/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/drivers/w1/slaves/Kconfig -+++ gregkh-2.6/drivers/w1/slaves/Kconfig -@@ -28,7 +28,7 @@ config W1_SLAVE_DS2433 - - config W1_SLAVE_DS2433_CRC - bool "Protect DS2433 data with a CRC16" -- depends on W1_DS2433 -+ depends on W1_SLAVE_DS2433 - select CRC16 - help - Say Y here to protect DS2433 data with a CRC16. diff --git a/i2c/w1-make-w1-connector-notifications-depend-on-connector.patch b/i2c/w1-make-w1-connector-notifications-depend-on-connector.patch deleted file mode 100644 index 05a4cf3974a0a1..00000000000000 --- a/i2c/w1-make-w1-connector-notifications-depend-on-connector.patch +++ /dev/null @@ -1,83 +0,0 @@ -From johnpol@2ka.mipt.ru Mon Apr 3 01:01:38 2006 -Date: Mon, 3 Apr 2006 12:01:12 +0400 -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [1/2] w1: Make w1 connector notifications depend on connector. -Message-ID: <20060403080112.GA14969@2ka.mipt.ru> -Content-Disposition: inline - -Make w1 connector notifications depend on connector. - -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/Kconfig | 14 +++++++++++++- - drivers/w1/Makefile | 4 ---- - drivers/w1/w1_netlink.c | 4 +--- - 3 files changed, 14 insertions(+), 8 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/Kconfig -+++ gregkh-2.6/drivers/w1/Kconfig -@@ -3,7 +3,7 @@ menu "Dallas's 1-wire bus" - config W1 - tristate "Dallas's 1-wire support" - ---help--- -- Dallas's 1-wire bus is useful to connect slow 1-pin devices -+ Dallas' 1-wire bus is useful to connect slow 1-pin devices - such as iButtons and thermal sensors. - - If you want W1 support, you should say Y here. -@@ -11,6 +11,18 @@ config W1 - This W1 support can also be built as a module. If so, the module - will be called wire.ko. - -+config W1_CON -+ depends on CONNECTOR -+ bool "Userspace communication over connector" -+ default y -+ --- help --- -+ This allows to communicate with userspace using connector [Documentation/connector]. -+ There are three types of messages between w1 core and userspace: -+ 1. Events. They are generated each time new master or slave device found -+ either due to automatic or requested search. -+ 2. Userspace commands. Includes read/write and search/alarm search comamnds. -+ 3. Replies to userspace commands. -+ - source drivers/w1/masters/Kconfig - source drivers/w1/slaves/Kconfig - ---- gregkh-2.6.orig/drivers/w1/Makefile -+++ gregkh-2.6/drivers/w1/Makefile -@@ -2,10 +2,6 @@ - # Makefile for the Dallas's 1-wire bus. - # - --ifeq ($(CONFIG_CONNECTOR), n) --EXTRA_CFLAGS += -DNETLINK_DISABLED --endif -- - ifeq ($(CONFIG_W1_DS2433_CRC), y) - EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC - endif ---- gregkh-2.6.orig/drivers/w1/w1_netlink.c -+++ gregkh-2.6/drivers/w1/w1_netlink.c -@@ -27,7 +27,7 @@ - #include "w1_log.h" - #include "w1_netlink.h" - --#ifndef NETLINK_DISABLED -+#if defined(CONFIG_W1_CON) && (defined(CONFIG_CONNECTOR) || (defined(CONFIG_CONNECTOR_MODULE) && defined(CONFIG_W1_MODULE))) - void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) - { - char buf[sizeof(struct cn_msg) + sizeof(struct w1_netlink_msg)]; -@@ -230,8 +230,6 @@ void w1_fini_netlink(void) - cn_del_callback(&w1_id); - } - #else --#warning Netlink support is disabled. Please compile with NET support enabled. -- - void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) - { - } diff --git a/i2c/w1-move-w1-connector-definitions-into-linux-include-connector.h.patch b/i2c/w1-move-w1-connector-definitions-into-linux-include-connector.h.patch deleted file mode 100644 index 6f7f458703e225..00000000000000 --- a/i2c/w1-move-w1-connector-definitions-into-linux-include-connector.h.patch +++ /dev/null @@ -1,44 +0,0 @@ -From johnpol@2ka.mipt.ru Thu Mar 23 08:00:09 2006 -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [PATCH 4/5] w1: Move w1-connector definitions into linux/include/connector.h -Date: Thu, 23 Mar 2006 19:11:58 +0300 -Message-Id: <11431303183514@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> - - -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/w1_netlink.h | 3 --- - include/linux/connector.h | 5 ++++- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/w1_netlink.h -+++ gregkh-2.6/drivers/w1/w1_netlink.h -@@ -27,9 +27,6 @@ - - #include "w1.h" - --#define CN_W1_IDX 3 --#define CN_W1_VAL 1 -- - enum w1_netlink_message_types { - W1_SLAVE_ADD = 0, - W1_SLAVE_REMOVE, ---- gregkh-2.6.orig/include/linux/connector.h -+++ gregkh-2.6/include/linux/connector.h -@@ -34,8 +34,11 @@ - #define CN_VAL_PROC 0x1 - #define CN_IDX_CIFS 0x2 - #define CN_VAL_CIFS 0x1 -+#define CN_W1_IDX 0x3 /* w1 communication */ -+#define CN_W1_VAL 0x1 - --#define CN_NETLINK_USERS 1 -+ -+#define CN_NETLINK_USERS 4 - - /* - * Maximum connector's message size. diff --git a/i2c/w1-netlink-mark-netlink-group-1-as-unused.patch b/i2c/w1-netlink-mark-netlink-group-1-as-unused.patch deleted file mode 100644 index b09b6d27a49b2e..00000000000000 --- a/i2c/w1-netlink-mark-netlink-group-1-as-unused.patch +++ /dev/null @@ -1,29 +0,0 @@ -From johnpol@2ka.mipt.ru Thu Mar 23 08:00:20 2006 -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [PATCH 5/5] w1: netlink: Mark netlink group 1 as unused. -Date: Thu, 23 Mar 2006 19:11:58 +0300 -Message-Id: <11431303183286@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> - - -netlink_w1 was moved to connector. - -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - include/linux/netlink.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- gregkh-2.6.orig/include/linux/netlink.h -+++ gregkh-2.6/include/linux/netlink.h -@@ -5,7 +5,7 @@ - #include <linux/types.h> - - #define NETLINK_ROUTE 0 /* Routing/device hook */ --#define NETLINK_W1 1 /* 1-wire subsystem */ -+#define NETLINK_UNUSED 1 /* Unused number */ - #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ - #define NETLINK_FIREWALL 3 /* Firewalling hook */ - #define NETLINK_INET_DIAG 4 /* INET socket monitoring */ diff --git a/i2c/w1-possible-cleanups.patch b/i2c/w1-possible-cleanups.patch deleted file mode 100644 index 7c3ce2154db188..00000000000000 --- a/i2c/w1-possible-cleanups.patch +++ /dev/null @@ -1,163 +0,0 @@ -From johnpol@2ka.mipt.ru Sun Apr 23 23:46:41 2006 -Date: Mon, 24 Apr 2006 10:46:14 +0400 -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -Subject: W1: possible cleanups -Message-ID: <20060424064612.GB17636@2ka.mipt.ru> -Content-Disposition: inline - -This patch contains the following possible cleanups: -- the following file did't #include the header with the prototypes for - it's global functions: - - w1_int.c -- #if 0 the following unused global function: - - w1_family.c: w1_family_get() -- make the following needlessly global functions static: - - w1_family.c: __w1_family_put() - - w1_io.c: w1_delay() - - w1_io.c: w1_touch_bit() - - w1_io.c: w1_read_8() -- remove the following unused EXPORT_SYMBOL's: - - w1_family.c: w1_family_put - - w1_family.c: w1_family_registered - -Signed-off-by: Adrian Bunk <bunk@stusta.de> -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/w1/w1.h | 3 --- - drivers/w1/w1_family.c | 18 ++++++++---------- - drivers/w1/w1_family.h | 2 -- - drivers/w1/w1_int.c | 1 + - drivers/w1/w1_io.c | 6 +++--- - drivers/w1/w1_io.h | 3 --- - 6 files changed, 12 insertions(+), 21 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/w1.h -+++ gregkh-2.6/drivers/w1/w1.h -@@ -187,11 +187,8 @@ struct w1_slave *w1_search_slave(struct - void w1_search_process(struct w1_master *dev, u8 search_type); - struct w1_master *w1_search_master_id(u32 id); - --void w1_delay(unsigned long); --u8 w1_touch_bit(struct w1_master *, int); - u8 w1_triplet(struct w1_master *dev, int bdir); - void w1_write_8(struct w1_master *, u8); --u8 w1_read_8(struct w1_master *); - int w1_reset_bus(struct w1_master *); - u8 w1_calc_crc8(u8 *, int); - void w1_write_block(struct w1_master *, const u8 *, int); ---- gregkh-2.6.orig/drivers/w1/w1_family.c -+++ gregkh-2.6/drivers/w1/w1_family.c -@@ -107,6 +107,12 @@ struct w1_family * w1_family_registered( - return (ret) ? f : NULL; - } - -+static void __w1_family_put(struct w1_family *f) -+{ -+ if (atomic_dec_and_test(&f->refcnt)) -+ f->need_exit = 1; -+} -+ - void w1_family_put(struct w1_family *f) - { - spin_lock(&w1_flock); -@@ -114,19 +120,14 @@ void w1_family_put(struct w1_family *f) - spin_unlock(&w1_flock); - } - --void __w1_family_put(struct w1_family *f) --{ -- if (atomic_dec_and_test(&f->refcnt)) -- f->need_exit = 1; --} -- -+#if 0 - void w1_family_get(struct w1_family *f) - { - spin_lock(&w1_flock); - __w1_family_get(f); - spin_unlock(&w1_flock); -- - } -+#endif /* 0 */ - - void __w1_family_get(struct w1_family *f) - { -@@ -135,8 +136,5 @@ void __w1_family_get(struct w1_family *f - smp_mb__after_atomic_inc(); - } - --EXPORT_SYMBOL(w1_family_get); --EXPORT_SYMBOL(w1_family_put); --EXPORT_SYMBOL(w1_family_registered); - EXPORT_SYMBOL(w1_unregister_family); - EXPORT_SYMBOL(w1_register_family); ---- gregkh-2.6.orig/drivers/w1/w1_family.h -+++ gregkh-2.6/drivers/w1/w1_family.h -@@ -57,10 +57,8 @@ struct w1_family - - extern spinlock_t w1_flock; - --void w1_family_get(struct w1_family *); - void w1_family_put(struct w1_family *); - void __w1_family_get(struct w1_family *); --void __w1_family_put(struct w1_family *); - struct w1_family * w1_family_registered(u8); - void w1_unregister_family(struct w1_family *); - int w1_register_family(struct w1_family *); ---- gregkh-2.6.orig/drivers/w1/w1_int.c -+++ gregkh-2.6/drivers/w1/w1_int.c -@@ -27,6 +27,7 @@ - #include "w1.h" - #include "w1_log.h" - #include "w1_netlink.h" -+#include "w1_int.h" - - static u32 w1_ids = 1; - ---- gregkh-2.6.orig/drivers/w1/w1_io.c -+++ gregkh-2.6/drivers/w1/w1_io.c -@@ -50,7 +50,7 @@ static u8 w1_crc8_table[] = { - 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 - }; - --void w1_delay(unsigned long tm) -+static void w1_delay(unsigned long tm) - { - udelay(tm * w1_delay_parm); - } -@@ -61,7 +61,7 @@ static u8 w1_read_bit(struct w1_master * - /** - * Generates a write-0 or write-1 cycle and samples the level. - */ --u8 w1_touch_bit(struct w1_master *dev, int bit) -+static u8 w1_touch_bit(struct w1_master *dev, int bit) - { - if (dev->bus_master->touch_bit) - return dev->bus_master->touch_bit(dev->bus_master->data, bit); -@@ -177,7 +177,7 @@ u8 w1_triplet(struct w1_master *dev, int - * @param dev the master device - * @return the byte read - */ --u8 w1_read_8(struct w1_master * dev) -+static u8 w1_read_8(struct w1_master * dev) - { - int i; - u8 res = 0; ---- gregkh-2.6.orig/drivers/w1/w1_io.h -+++ gregkh-2.6/drivers/w1/w1_io.h -@@ -24,11 +24,8 @@ - - #include "w1.h" - --void w1_delay(unsigned long); --u8 w1_touch_bit(struct w1_master *, int); - u8 w1_triplet(struct w1_master *dev, int bdir); - void w1_write_8(struct w1_master *, u8); --u8 w1_read_8(struct w1_master *); - int w1_reset_bus(struct w1_master *); - u8 w1_calc_crc8(u8 *, int); - void w1_write_block(struct w1_master *, const u8 *, int); diff --git a/i2c/w1-replace-dscore-and-ds_w1_bridge-with-ds2490-driver.patch b/i2c/w1-replace-dscore-and-ds_w1_bridge-with-ds2490-driver.patch deleted file mode 100644 index 7d86442cbbc693..00000000000000 --- a/i2c/w1-replace-dscore-and-ds_w1_bridge-with-ds2490-driver.patch +++ /dev/null @@ -1,2184 +0,0 @@ -From johnpol@2ka.mipt.ru Thu Mar 23 08:00:09 2006 -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [PATCH 2/5] w1: Replace dscore and ds_w1_bridge with ds2490 driver. -Date: Thu, 23 Mar 2006 19:11:58 +0300 -Message-Id: <11431303181703@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> - - ---- - Documentation/w1/masters/ds2490 | 18 - drivers/w1/masters/Kconfig | 25 - - drivers/w1/masters/Makefile | 7 - drivers/w1/masters/ds2490.c | 947 ++++++++++++++++++++++++++++++++++++++ - drivers/w1/masters/ds_w1_bridge.c | 174 ------ - drivers/w1/masters/dscore.c | 795 ------------------------------- - drivers/w1/masters/dscore.h | 166 ------ - 7 files changed, 974 insertions(+), 1158 deletions(-) - ---- /dev/null -+++ gregkh-2.6/Documentation/w1/masters/ds2490 -@@ -0,0 +1,18 @@ -+Kernel driver ds2490 -+==================== -+ -+Supported chips: -+ * Maxim DS2490 based -+ -+Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -+ -+ -+Description -+----------- -+ -+The Maixm/Dallas Semiconductor DS2490 is a chip -+which allows to build USB <-> W1 bridges. -+ -+DS9490(R) is a USB <-> W1 bus master device -+which has 0x81 family ID integrated chip and DS2490 -+low-level operational chip. ---- gregkh-2.6.orig/drivers/w1/masters/Kconfig -+++ gregkh-2.6/drivers/w1/masters/Kconfig -@@ -15,24 +15,15 @@ config W1_MASTER_MATROX - This support is also available as a module. If so, the module - will be called matrox_w1.ko. - --config W1_MASTER_DS9490 -- tristate "DS9490R transport layer driver" -- depends on W1 && USB -- help -- Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge. -- -- This support is also available as a module. If so, the module -- will be called ds9490r.ko. -+config W1_MASTER_DS2490 -+ tristate "DS2490 USB <-> W1 transport layer for 1-wire" -+ depends on W1 && USB -+ help -+ Say Y here if you want to have a driver for DS2490 based USB <-> W1 bridges, -+ for example DS9490*. - --config W1_MASTER_DS9490_BRIDGE -- tristate "DS9490R USB <-> W1 transport layer for 1-wire" -- depends on W1_MASTER_DS9490 -- help -- Say Y here if you want to communicate with your 1-wire devices -- using DS9490R USB bridge. -- -- This support is also available as a module. If so, the module -- will be called ds_w1_bridge.ko. -+ This support is also available as a module. If so, the module -+ will be called ds2490.ko. - - config W1_MASTER_DS2482 - tristate "Maxim DS2482 I2C to 1-Wire bridge" ---- gregkh-2.6.orig/drivers/w1/masters/Makefile -+++ gregkh-2.6/drivers/w1/masters/Makefile -@@ -3,11 +3,6 @@ - # - - obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o -- --obj-$(CONFIG_W1_MASTER_DS9490) += ds9490r.o --ds9490r-objs := dscore.o -- --obj-$(CONFIG_W1_MASTER_DS9490_BRIDGE) += ds_w1_bridge.o -- -+obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o - obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o - ---- /dev/null -+++ gregkh-2.6/drivers/w1/masters/ds2490.c -@@ -0,0 +1,947 @@ -+/* -+ * dscore.c -+ * -+ * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> -+ * -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/mod_devicetable.h> -+#include <linux/usb.h> -+ -+#include "../w1_int.h" -+#include "../w1.h" -+ -+/* COMMAND TYPE CODES */ -+#define CONTROL_CMD 0x00 -+#define COMM_CMD 0x01 -+#define MODE_CMD 0x02 -+ -+/* CONTROL COMMAND CODES */ -+#define CTL_RESET_DEVICE 0x0000 -+#define CTL_START_EXE 0x0001 -+#define CTL_RESUME_EXE 0x0002 -+#define CTL_HALT_EXE_IDLE 0x0003 -+#define CTL_HALT_EXE_DONE 0x0004 -+#define CTL_FLUSH_COMM_CMDS 0x0007 -+#define CTL_FLUSH_RCV_BUFFER 0x0008 -+#define CTL_FLUSH_XMT_BUFFER 0x0009 -+#define CTL_GET_COMM_CMDS 0x000A -+ -+/* MODE COMMAND CODES */ -+#define MOD_PULSE_EN 0x0000 -+#define MOD_SPEED_CHANGE_EN 0x0001 -+#define MOD_1WIRE_SPEED 0x0002 -+#define MOD_STRONG_PU_DURATION 0x0003 -+#define MOD_PULLDOWN_SLEWRATE 0x0004 -+#define MOD_PROG_PULSE_DURATION 0x0005 -+#define MOD_WRITE1_LOWTIME 0x0006 -+#define MOD_DSOW0_TREC 0x0007 -+ -+/* COMMUNICATION COMMAND CODES */ -+#define COMM_ERROR_ESCAPE 0x0601 -+#define COMM_SET_DURATION 0x0012 -+#define COMM_BIT_IO 0x0020 -+#define COMM_PULSE 0x0030 -+#define COMM_1_WIRE_RESET 0x0042 -+#define COMM_BYTE_IO 0x0052 -+#define COMM_MATCH_ACCESS 0x0064 -+#define COMM_BLOCK_IO 0x0074 -+#define COMM_READ_STRAIGHT 0x0080 -+#define COMM_DO_RELEASE 0x6092 -+#define COMM_SET_PATH 0x00A2 -+#define COMM_WRITE_SRAM_PAGE 0x00B2 -+#define COMM_WRITE_EPROM 0x00C4 -+#define COMM_READ_CRC_PROT_PAGE 0x00D4 -+#define COMM_READ_REDIRECT_PAGE_CRC 0x21E4 -+#define COMM_SEARCH_ACCESS 0x00F4 -+ -+/* Communication command bits */ -+#define COMM_TYPE 0x0008 -+#define COMM_SE 0x0008 -+#define COMM_D 0x0008 -+#define COMM_Z 0x0008 -+#define COMM_CH 0x0008 -+#define COMM_SM 0x0008 -+#define COMM_R 0x0008 -+#define COMM_IM 0x0001 -+ -+#define COMM_PS 0x4000 -+#define COMM_PST 0x4000 -+#define COMM_CIB 0x4000 -+#define COMM_RTS 0x4000 -+#define COMM_DT 0x2000 -+#define COMM_SPU 0x1000 -+#define COMM_F 0x0800 -+#define COMM_NTP 0x0400 -+#define COMM_ICP 0x0200 -+#define COMM_RST 0x0100 -+ -+#define PULSE_PROG 0x01 -+#define PULSE_SPUE 0x02 -+ -+#define BRANCH_MAIN 0xCC -+#define BRANCH_AUX 0x33 -+ -+/* -+ * Duration of the strong pull-up pulse in milliseconds. -+ */ -+#define PULLUP_PULSE_DURATION 750 -+ -+/* Status flags */ -+#define ST_SPUA 0x01 /* Strong Pull-up is active */ -+#define ST_PRGA 0x02 /* 12V programming pulse is being generated */ -+#define ST_12VP 0x04 /* external 12V programming voltage is present */ -+#define ST_PMOD 0x08 /* DS2490 powered from USB and external sources */ -+#define ST_HALT 0x10 /* DS2490 is currently halted */ -+#define ST_IDLE 0x20 /* DS2490 is currently idle */ -+#define ST_EPOF 0x80 -+ -+#define SPEED_NORMAL 0x00 -+#define SPEED_FLEXIBLE 0x01 -+#define SPEED_OVERDRIVE 0x02 -+ -+#define NUM_EP 4 -+#define EP_CONTROL 0 -+#define EP_STATUS 1 -+#define EP_DATA_OUT 2 -+#define EP_DATA_IN 3 -+ -+struct ds_device -+{ -+ struct list_head ds_entry; -+ -+ struct usb_device *udev; -+ struct usb_interface *intf; -+ -+ int ep[NUM_EP]; -+ -+ struct w1_bus_master master; -+}; -+ -+struct ds_status -+{ -+ u8 enable; -+ u8 speed; -+ u8 pullup_dur; -+ u8 ppuls_dur; -+ u8 pulldown_slew; -+ u8 write1_time; -+ u8 write0_time; -+ u8 reserved0; -+ u8 status; -+ u8 command0; -+ u8 command1; -+ u8 command_buffer_status; -+ u8 data_out_buffer_status; -+ u8 data_in_buffer_status; -+ u8 reserved1; -+ u8 reserved2; -+ -+}; -+ -+static struct usb_device_id ds_id_table [] = { -+ { USB_DEVICE(0x04fa, 0x2490) }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(usb, ds_id_table); -+ -+static int ds_probe(struct usb_interface *, const struct usb_device_id *); -+static void ds_disconnect(struct usb_interface *); -+ -+static inline void ds_dump_status(unsigned char *, unsigned char *, int); -+static int ds_send_control(struct ds_device *, u16, u16); -+static int ds_send_control_cmd(struct ds_device *, u16, u16); -+ -+static LIST_HEAD(ds_devices); -+static DECLARE_MUTEX(ds_mutex); -+ -+static struct usb_driver ds_driver = { -+ .name = "DS9490R", -+ .probe = ds_probe, -+ .disconnect = ds_disconnect, -+ .id_table = ds_id_table, -+}; -+ -+static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) -+{ -+ int err; -+ -+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), -+ CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); -+ if (err < 0) { -+ printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", -+ value, index, err); -+ return err; -+ } -+ -+ return err; -+} -+#if 0 -+static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) -+{ -+ int err; -+ -+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), -+ MODE_CMD, 0x40, value, index, NULL, 0, 1000); -+ if (err < 0) { -+ printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", -+ value, index, err); -+ return err; -+ } -+ -+ return err; -+} -+#endif -+static int ds_send_control(struct ds_device *dev, u16 value, u16 index) -+{ -+ int err; -+ -+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), -+ COMM_CMD, 0x40, value, index, NULL, 0, 1000); -+ if (err < 0) { -+ printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", -+ value, index, err); -+ return err; -+ } -+ -+ return err; -+} -+ -+static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off) -+{ -+ printk("%45s: %8x\n", str, buf[off]); -+} -+ -+static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, -+ unsigned char *buf, int size) -+{ -+ int count, err; -+ -+ memset(st, 0, sizeof(st)); -+ -+ count = 0; -+ err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); -+ if (err < 0) { -+ printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); -+ return err; -+ } -+ -+ if (count >= sizeof(*st)) -+ memcpy(st, buf, sizeof(*st)); -+ -+ return count; -+} -+ -+static int ds_recv_status(struct ds_device *dev, struct ds_status *st) -+{ -+ unsigned char buf[64]; -+ int count, err = 0, i; -+ -+ memcpy(st, buf, sizeof(*st)); -+ -+ count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); -+ if (count < 0) -+ return err; -+ -+ printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); -+ for (i=0; i<count; ++i) -+ printk("%02x ", buf[i]); -+ printk("\n"); -+ -+ if (count >= 16) { -+ ds_dump_status(buf, "enable flag", 0); -+ ds_dump_status(buf, "1-wire speed", 1); -+ ds_dump_status(buf, "strong pullup duration", 2); -+ ds_dump_status(buf, "programming pulse duration", 3); -+ ds_dump_status(buf, "pulldown slew rate control", 4); -+ ds_dump_status(buf, "write-1 low time", 5); -+ ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); -+ ds_dump_status(buf, "reserved (test register)", 7); -+ ds_dump_status(buf, "device status flags", 8); -+ ds_dump_status(buf, "communication command byte 1", 9); -+ ds_dump_status(buf, "communication command byte 2", 10); -+ ds_dump_status(buf, "communication command buffer status", 11); -+ ds_dump_status(buf, "1-wire data output buffer status", 12); -+ ds_dump_status(buf, "1-wire data input buffer status", 13); -+ ds_dump_status(buf, "reserved", 14); -+ ds_dump_status(buf, "reserved", 15); -+ } -+ -+ memcpy(st, buf, sizeof(*st)); -+ -+ if (st->status & ST_EPOF) { -+ printk(KERN_INFO "Resetting device after ST_EPOF.\n"); -+ err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); -+ if (err) -+ return err; -+ count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); -+ if (count < 0) -+ return err; -+ } -+#if 0 -+ if (st->status & ST_IDLE) { -+ printk(KERN_INFO "Resetting pulse after ST_IDLE.\n"); -+ err = ds_start_pulse(dev, PULLUP_PULSE_DURATION); -+ if (err) -+ return err; -+ } -+#endif -+ -+ return err; -+} -+ -+static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) -+{ -+ int count, err; -+ struct ds_status st; -+ -+ count = 0; -+ err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), -+ buf, size, &count, 1000); -+ if (err < 0) { -+ printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); -+ usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); -+ ds_recv_status(dev, &st); -+ return err; -+ } -+ -+#if 0 -+ { -+ int i; -+ -+ printk("%s: count=%d: ", __func__, count); -+ for (i=0; i<count; ++i) -+ printk("%02x ", buf[i]); -+ printk("\n"); -+ } -+#endif -+ return count; -+} -+ -+static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len) -+{ -+ int count, err; -+ -+ count = 0; -+ err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); -+ if (err < 0) { -+ printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err); -+ return err; -+ } -+ -+ return err; -+} -+ -+#if 0 -+ -+int ds_stop_pulse(struct ds_device *dev, int limit) -+{ -+ struct ds_status st; -+ int count = 0, err = 0; -+ u8 buf[0x20]; -+ -+ do { -+ err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); -+ if (err) -+ break; -+ err = ds_send_control(dev, CTL_RESUME_EXE, 0); -+ if (err) -+ break; -+ err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); -+ if (err) -+ break; -+ -+ if ((st.status & ST_SPUA) == 0) { -+ err = ds_send_control_mode(dev, MOD_PULSE_EN, 0); -+ if (err) -+ break; -+ } -+ } while(++count < limit); -+ -+ return err; -+} -+ -+int ds_detect(struct ds_device *dev, struct ds_status *st) -+{ -+ int err; -+ -+ err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); -+ if (err) -+ return err; -+ -+ err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0); -+ if (err) -+ return err; -+ -+ err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40); -+ if (err) -+ return err; -+ -+ err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG); -+ if (err) -+ return err; -+ -+ err = ds_recv_status(dev, st); -+ -+ return err; -+} -+ -+#endif /* 0 */ -+ -+static int ds_wait_status(struct ds_device *dev, struct ds_status *st) -+{ -+ u8 buf[0x20]; -+ int err, count = 0; -+ -+ do { -+ err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); -+#if 0 -+ if (err >= 0) { -+ int i; -+ printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); -+ for (i=0; i<err; ++i) -+ printk("%02x ", buf[i]); -+ printk("\n"); -+ } -+#endif -+ } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); -+ -+ -+ if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { -+ ds_recv_status(dev, st); -+ return -1; -+ } else -+ return 0; -+} -+ -+static int ds_reset(struct ds_device *dev, struct ds_status *st) -+{ -+ int err; -+ -+ //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE); -+ err = ds_send_control(dev, 0x43, SPEED_NORMAL); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, st); -+#if 0 -+ if (st->command_buffer_status) { -+ printk(KERN_INFO "Short circuit.\n"); -+ return -EIO; -+ } -+#endif -+ -+ return 0; -+} -+ -+#if 0 -+static int ds_set_speed(struct ds_device *dev, int speed) -+{ -+ int err; -+ -+ if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE) -+ return -EINVAL; -+ -+ if (speed != SPEED_OVERDRIVE) -+ speed = SPEED_FLEXIBLE; -+ -+ speed &= 0xff; -+ -+ err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); -+ if (err) -+ return err; -+ -+ return err; -+} -+#endif /* 0 */ -+ -+static int ds_start_pulse(struct ds_device *dev, int delay) -+{ -+ int err; -+ u8 del = 1 + (u8)(delay >> 4); -+ struct ds_status st; -+ -+#if 0 -+ err = ds_stop_pulse(dev, 10); -+ if (err) -+ return err; -+ -+ err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); -+ if (err) -+ return err; -+#endif -+ err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); -+ if (err) -+ return err; -+ -+ err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0); -+ if (err) -+ return err; -+ -+ mdelay(delay); -+ -+ ds_wait_status(dev, &st); -+ -+ return err; -+} -+ -+static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) -+{ -+ int err, count; -+ struct ds_status st; -+ u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0); -+ u16 cmd; -+ -+ err = ds_send_control(dev, value, 0); -+ if (err) -+ return err; -+ -+ count = 0; -+ do { -+ err = ds_wait_status(dev, &st); -+ if (err) -+ return err; -+ -+ cmd = st.command0 | (st.command1 << 8); -+ } while (cmd != value && ++count < 10); -+ -+ if (err < 0 || count >= 10) { -+ printk(KERN_ERR "Failed to obtain status.\n"); -+ return -EINVAL; -+ } -+ -+ err = ds_recv_data(dev, tbit, sizeof(*tbit)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+ -+static int ds_write_bit(struct ds_device *dev, u8 bit) -+{ -+ int err; -+ struct ds_status st; -+ -+ err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ return 0; -+} -+ -+static int ds_write_byte(struct ds_device *dev, u8 byte) -+{ -+ int err; -+ struct ds_status st; -+ u8 rbyte; -+ -+ err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); -+ if (err) -+ return err; -+ -+ err = ds_wait_status(dev, &st); -+ if (err) -+ return err; -+ -+ err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); -+ if (err < 0) -+ return err; -+ -+ ds_start_pulse(dev, PULLUP_PULSE_DURATION); -+ -+ return !(byte == rbyte); -+} -+ -+static int ds_read_byte(struct ds_device *dev, u8 *byte) -+{ -+ int err; -+ struct ds_status st; -+ -+ err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM , 0xff); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ err = ds_recv_data(dev, byte, sizeof(*byte)); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+ -+static int ds_read_block(struct ds_device *dev, u8 *buf, int len) -+{ -+ struct ds_status st; -+ int err; -+ -+ if (len > 64*1024) -+ return -E2BIG; -+ -+ memset(buf, 0xFF, len); -+ -+ err = ds_send_data(dev, buf, len); -+ if (err < 0) -+ return err; -+ -+ err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ memset(buf, 0x00, len); -+ err = ds_recv_data(dev, buf, len); -+ -+ return err; -+} -+ -+static int ds_write_block(struct ds_device *dev, u8 *buf, int len) -+{ -+ int err; -+ struct ds_status st; -+ -+ err = ds_send_data(dev, buf, len); -+ if (err < 0) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ err = ds_recv_data(dev, buf, len); -+ if (err < 0) -+ return err; -+ -+ ds_start_pulse(dev, PULLUP_PULSE_DURATION); -+ -+ return !(err == len); -+} -+ -+#if 0 -+ -+static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) -+{ -+ int err; -+ u16 value, index; -+ struct ds_status st; -+ -+ memset(buf, 0, sizeof(buf)); -+ -+ err = ds_send_data(ds_dev, (unsigned char *)&init, 8); -+ if (err) -+ return err; -+ -+ ds_wait_status(ds_dev, &st); -+ -+ value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; -+ index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); -+ err = ds_send_control(ds_dev, value, index); -+ if (err) -+ return err; -+ -+ ds_wait_status(ds_dev, &st); -+ -+ err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); -+ if (err < 0) -+ return err; -+ -+ return err/8; -+} -+ -+static int ds_match_access(struct ds_device *dev, u64 init) -+{ -+ int err; -+ struct ds_status st; -+ -+ err = ds_send_data(dev, (unsigned char *)&init, sizeof(init)); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ return 0; -+} -+ -+static int ds_set_path(struct ds_device *dev, u64 init) -+{ -+ int err; -+ struct ds_status st; -+ u8 buf[9]; -+ -+ memcpy(buf, &init, 8); -+ buf[8] = BRANCH_MAIN; -+ -+ err = ds_send_data(dev, buf, sizeof(buf)); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0); -+ if (err) -+ return err; -+ -+ ds_wait_status(dev, &st); -+ -+ return 0; -+} -+ -+#endif /* 0 */ -+ -+static u8 ds9490r_touch_bit(void *data, u8 bit) -+{ -+ u8 ret; -+ struct ds_device *dev = data; -+ -+ if (ds_touch_bit(dev, bit, &ret)) -+ return 0; -+ -+ return ret; -+} -+ -+static void ds9490r_write_bit(void *data, u8 bit) -+{ -+ struct ds_device *dev = data; -+ -+ ds_write_bit(dev, bit); -+} -+ -+static void ds9490r_write_byte(void *data, u8 byte) -+{ -+ struct ds_device *dev = data; -+ -+ ds_write_byte(dev, byte); -+} -+ -+static u8 ds9490r_read_bit(void *data) -+{ -+ struct ds_device *dev = data; -+ int err; -+ u8 bit = 0; -+ -+ err = ds_touch_bit(dev, 1, &bit); -+ if (err) -+ return 0; -+ -+ return bit & 1; -+} -+ -+static u8 ds9490r_read_byte(void *data) -+{ -+ struct ds_device *dev = data; -+ int err; -+ u8 byte = 0; -+ -+ err = ds_read_byte(dev, &byte); -+ if (err) -+ return 0; -+ -+ return byte; -+} -+ -+static void ds9490r_write_block(void *data, const u8 *buf, int len) -+{ -+ struct ds_device *dev = data; -+ -+ ds_write_block(dev, (u8 *)buf, len); -+} -+ -+static u8 ds9490r_read_block(void *data, u8 *buf, int len) -+{ -+ struct ds_device *dev = data; -+ int err; -+ -+ err = ds_read_block(dev, buf, len); -+ if (err < 0) -+ return 0; -+ -+ return len; -+} -+ -+static u8 ds9490r_reset(void *data) -+{ -+ struct ds_device *dev = data; -+ struct ds_status st; -+ int err; -+ -+ memset(&st, 0, sizeof(st)); -+ -+ err = ds_reset(dev, &st); -+ if (err) -+ return 1; -+ -+ return 0; -+} -+ -+static int ds_w1_init(struct ds_device *dev) -+{ -+ memset(&dev->master, 0, sizeof(struct w1_bus_master)); -+ -+ dev->master.data = dev; -+ dev->master.touch_bit = &ds9490r_touch_bit; -+ dev->master.read_bit = &ds9490r_read_bit; -+ dev->master.write_bit = &ds9490r_write_bit; -+ dev->master.read_byte = &ds9490r_read_byte; -+ dev->master.write_byte = &ds9490r_write_byte; -+ dev->master.read_block = &ds9490r_read_block; -+ dev->master.write_block = &ds9490r_write_block; -+ dev->master.reset_bus = &ds9490r_reset; -+ -+ return w1_add_master_device(&dev->master); -+} -+ -+static void ds_w1_fini(struct ds_device *dev) -+{ -+ w1_remove_master_device(&dev->master); -+} -+ -+static int ds_probe(struct usb_interface *intf, -+ const struct usb_device_id *udev_id) -+{ -+ struct usb_device *udev = interface_to_usbdev(intf); -+ struct usb_endpoint_descriptor *endpoint; -+ struct usb_host_interface *iface_desc; -+ struct ds_device *dev; -+ int i, err; -+ -+ dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); -+ if (!dev) { -+ printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); -+ return -ENOMEM; -+ } -+ dev->udev = usb_get_dev(udev); -+ if (!dev->udev) { -+ err = -ENOMEM; -+ goto err_out_free; -+ } -+ memset(dev->ep, 0, sizeof(dev->ep)); -+ -+ usb_set_intfdata(intf, dev); -+ -+ err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); -+ if (err) { -+ printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", -+ intf->altsetting[0].desc.bInterfaceNumber, err); -+ goto err_out_clear; -+ } -+ -+ err = usb_reset_configuration(dev->udev); -+ if (err) { -+ printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); -+ goto err_out_clear; -+ } -+ -+ iface_desc = &intf->altsetting[0]; -+ if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { -+ printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); -+ err = -EINVAL; -+ goto err_out_clear; -+ } -+ -+ /* -+ * This loop doesn'd show control 0 endpoint, -+ * so we will fill only 1-3 endpoints entry. -+ */ -+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { -+ endpoint = &iface_desc->endpoint[i].desc; -+ -+ dev->ep[i+1] = endpoint->bEndpointAddress; -+#if 0 -+ printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", -+ i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), -+ (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", -+ endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); -+#endif -+ } -+ -+ err = ds_w1_init(dev); -+ if (err) -+ goto err_out_clear; -+ -+ down(&ds_mutex); -+ list_add_tail(&dev->ds_entry, &ds_devices); -+ up(&ds_mutex); -+ -+ return 0; -+ -+err_out_clear: -+ usb_set_intfdata(intf, NULL); -+ usb_put_dev(dev->udev); -+err_out_free: -+ kfree(dev); -+ return err; -+} -+ -+static void ds_disconnect(struct usb_interface *intf) -+{ -+ struct ds_device *dev; -+ -+ dev = usb_get_intfdata(intf); -+ if (!dev) -+ return; -+ -+ down(&ds_mutex); -+ list_del(&dev->ds_entry); -+ up(&ds_mutex); -+ -+ ds_w1_fini(dev); -+ -+ usb_set_intfdata(intf, NULL); -+ -+ usb_put_dev(dev->udev); -+ kfree(dev); -+} -+ -+static int ds_init(void) -+{ -+ int err; -+ -+ err = usb_register(&ds_driver); -+ if (err) { -+ printk(KERN_INFO "Failed to register DS9490R USB device: err=%d.\n", err); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void ds_fini(void) -+{ -+ usb_deregister(&ds_driver); -+} -+ -+module_init(ds_init); -+module_exit(ds_fini); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); -+MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)"); ---- gregkh-2.6.orig/drivers/w1/masters/ds_w1_bridge.c -+++ /dev/null -@@ -1,174 +0,0 @@ --/* -- * ds_w1_bridge.c -- * -- * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> -- * -- * -- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ -- --#include <linux/module.h> --#include <linux/types.h> -- --#include "../w1.h" --#include "../w1_int.h" --#include "dscore.h" -- --static struct ds_device *ds_dev; --static struct w1_bus_master *ds_bus_master; -- --static u8 ds9490r_touch_bit(void *data, u8 bit) --{ -- u8 ret; -- struct ds_device *dev = data; -- -- if (ds_touch_bit(dev, bit, &ret)) -- return 0; -- -- return ret; --} -- --static void ds9490r_write_bit(void *data, u8 bit) --{ -- struct ds_device *dev = data; -- -- ds_write_bit(dev, bit); --} -- --static void ds9490r_write_byte(void *data, u8 byte) --{ -- struct ds_device *dev = data; -- -- ds_write_byte(dev, byte); --} -- --static u8 ds9490r_read_bit(void *data) --{ -- struct ds_device *dev = data; -- int err; -- u8 bit = 0; -- -- err = ds_touch_bit(dev, 1, &bit); -- if (err) -- return 0; -- //err = ds_read_bit(dev, &bit); -- //if (err) -- // return 0; -- -- return bit & 1; --} -- --static u8 ds9490r_read_byte(void *data) --{ -- struct ds_device *dev = data; -- int err; -- u8 byte = 0; -- -- err = ds_read_byte(dev, &byte); -- if (err) -- return 0; -- -- return byte; --} -- --static void ds9490r_write_block(void *data, const u8 *buf, int len) --{ -- struct ds_device *dev = data; -- -- ds_write_block(dev, (u8 *)buf, len); --} -- --static u8 ds9490r_read_block(void *data, u8 *buf, int len) --{ -- struct ds_device *dev = data; -- int err; -- -- err = ds_read_block(dev, buf, len); -- if (err < 0) -- return 0; -- -- return len; --} -- --static u8 ds9490r_reset(void *data) --{ -- struct ds_device *dev = data; -- struct ds_status st; -- int err; -- -- memset(&st, 0, sizeof(st)); -- -- err = ds_reset(dev, &st); -- if (err) -- return 1; -- -- return 0; --} -- --static int __devinit ds_w1_init(void) --{ -- int err; -- -- ds_bus_master = kmalloc(sizeof(*ds_bus_master), GFP_KERNEL); -- if (!ds_bus_master) { -- printk(KERN_ERR "Failed to allocate DS9490R USB<->W1 bus_master structure.\n"); -- return -ENOMEM; -- } -- -- ds_dev = ds_get_device(); -- if (!ds_dev) { -- printk(KERN_ERR "DS9490R is not registered.\n"); -- err = -ENODEV; -- goto err_out_free_bus_master; -- } -- -- memset(ds_bus_master, 0, sizeof(*ds_bus_master)); -- -- ds_bus_master->data = ds_dev; -- ds_bus_master->touch_bit = &ds9490r_touch_bit; -- ds_bus_master->read_bit = &ds9490r_read_bit; -- ds_bus_master->write_bit = &ds9490r_write_bit; -- ds_bus_master->read_byte = &ds9490r_read_byte; -- ds_bus_master->write_byte = &ds9490r_write_byte; -- ds_bus_master->read_block = &ds9490r_read_block; -- ds_bus_master->write_block = &ds9490r_write_block; -- ds_bus_master->reset_bus = &ds9490r_reset; -- -- err = w1_add_master_device(ds_bus_master); -- if (err) -- goto err_out_put_device; -- -- return 0; -- --err_out_put_device: -- ds_put_device(ds_dev); --err_out_free_bus_master: -- kfree(ds_bus_master); -- -- return err; --} -- --static void __devexit ds_w1_fini(void) --{ -- w1_remove_master_device(ds_bus_master); -- ds_put_device(ds_dev); -- kfree(ds_bus_master); --} -- --module_init(ds_w1_init); --module_exit(ds_w1_fini); -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); ---- gregkh-2.6.orig/drivers/w1/masters/dscore.c -+++ /dev/null -@@ -1,795 +0,0 @@ --/* -- * dscore.c -- * -- * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> -- * -- * -- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ -- --#include <linux/module.h> --#include <linux/kernel.h> --#include <linux/mod_devicetable.h> --#include <linux/usb.h> -- --#include "dscore.h" -- --static struct usb_device_id ds_id_table [] = { -- { USB_DEVICE(0x04fa, 0x2490) }, -- { }, --}; --MODULE_DEVICE_TABLE(usb, ds_id_table); -- --static int ds_probe(struct usb_interface *, const struct usb_device_id *); --static void ds_disconnect(struct usb_interface *); -- --int ds_touch_bit(struct ds_device *, u8, u8 *); --int ds_read_byte(struct ds_device *, u8 *); --int ds_read_bit(struct ds_device *, u8 *); --int ds_write_byte(struct ds_device *, u8); --int ds_write_bit(struct ds_device *, u8); --static int ds_start_pulse(struct ds_device *, int); --int ds_reset(struct ds_device *, struct ds_status *); --struct ds_device * ds_get_device(void); --void ds_put_device(struct ds_device *); -- --static inline void ds_dump_status(unsigned char *, unsigned char *, int); --static int ds_send_control(struct ds_device *, u16, u16); --static int ds_send_control_mode(struct ds_device *, u16, u16); --static int ds_send_control_cmd(struct ds_device *, u16, u16); -- -- --static struct usb_driver ds_driver = { -- .name = "DS9490R", -- .probe = ds_probe, -- .disconnect = ds_disconnect, -- .id_table = ds_id_table, --}; -- --static struct ds_device *ds_dev; -- --struct ds_device * ds_get_device(void) --{ -- if (ds_dev) -- atomic_inc(&ds_dev->refcnt); -- return ds_dev; --} -- --void ds_put_device(struct ds_device *dev) --{ -- atomic_dec(&dev->refcnt); --} -- --static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) --{ -- int err; -- -- err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), -- CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); -- if (err < 0) { -- printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", -- value, index, err); -- return err; -- } -- -- return err; --} -- --static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) --{ -- int err; -- -- err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), -- MODE_CMD, 0x40, value, index, NULL, 0, 1000); -- if (err < 0) { -- printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", -- value, index, err); -- return err; -- } -- -- return err; --} -- --static int ds_send_control(struct ds_device *dev, u16 value, u16 index) --{ -- int err; -- -- err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), -- COMM_CMD, 0x40, value, index, NULL, 0, 1000); -- if (err < 0) { -- printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", -- value, index, err); -- return err; -- } -- -- return err; --} -- --static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off) --{ -- printk("%45s: %8x\n", str, buf[off]); --} -- --static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, -- unsigned char *buf, int size) --{ -- int count, err; -- -- memset(st, 0, sizeof(st)); -- -- count = 0; -- err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); -- if (err < 0) { -- printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); -- return err; -- } -- -- if (count >= sizeof(*st)) -- memcpy(st, buf, sizeof(*st)); -- -- return count; --} -- --static int ds_recv_status(struct ds_device *dev, struct ds_status *st) --{ -- unsigned char buf[64]; -- int count, err = 0, i; -- -- memcpy(st, buf, sizeof(*st)); -- -- count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); -- if (count < 0) -- return err; -- -- printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); -- for (i=0; i<count; ++i) -- printk("%02x ", buf[i]); -- printk("\n"); -- -- if (count >= 16) { -- ds_dump_status(buf, "enable flag", 0); -- ds_dump_status(buf, "1-wire speed", 1); -- ds_dump_status(buf, "strong pullup duration", 2); -- ds_dump_status(buf, "programming pulse duration", 3); -- ds_dump_status(buf, "pulldown slew rate control", 4); -- ds_dump_status(buf, "write-1 low time", 5); -- ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); -- ds_dump_status(buf, "reserved (test register)", 7); -- ds_dump_status(buf, "device status flags", 8); -- ds_dump_status(buf, "communication command byte 1", 9); -- ds_dump_status(buf, "communication command byte 2", 10); -- ds_dump_status(buf, "communication command buffer status", 11); -- ds_dump_status(buf, "1-wire data output buffer status", 12); -- ds_dump_status(buf, "1-wire data input buffer status", 13); -- ds_dump_status(buf, "reserved", 14); -- ds_dump_status(buf, "reserved", 15); -- } -- -- memcpy(st, buf, sizeof(*st)); -- -- if (st->status & ST_EPOF) { -- printk(KERN_INFO "Resetting device after ST_EPOF.\n"); -- err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); -- if (err) -- return err; -- count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); -- if (count < 0) -- return err; -- } --#if 0 -- if (st->status & ST_IDLE) { -- printk(KERN_INFO "Resetting pulse after ST_IDLE.\n"); -- err = ds_start_pulse(dev, PULLUP_PULSE_DURATION); -- if (err) -- return err; -- } --#endif -- -- return err; --} -- --static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) --{ -- int count, err; -- struct ds_status st; -- -- count = 0; -- err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), -- buf, size, &count, 1000); -- if (err < 0) { -- printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); -- usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); -- ds_recv_status(dev, &st); -- return err; -- } -- --#if 0 -- { -- int i; -- -- printk("%s: count=%d: ", __func__, count); -- for (i=0; i<count; ++i) -- printk("%02x ", buf[i]); -- printk("\n"); -- } --#endif -- return count; --} -- --static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len) --{ -- int count, err; -- -- count = 0; -- err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); -- if (err < 0) { -- printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err); -- return err; -- } -- -- return err; --} -- --#if 0 -- --int ds_stop_pulse(struct ds_device *dev, int limit) --{ -- struct ds_status st; -- int count = 0, err = 0; -- u8 buf[0x20]; -- -- do { -- err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); -- if (err) -- break; -- err = ds_send_control(dev, CTL_RESUME_EXE, 0); -- if (err) -- break; -- err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); -- if (err) -- break; -- -- if ((st.status & ST_SPUA) == 0) { -- err = ds_send_control_mode(dev, MOD_PULSE_EN, 0); -- if (err) -- break; -- } -- } while(++count < limit); -- -- return err; --} -- --int ds_detect(struct ds_device *dev, struct ds_status *st) --{ -- int err; -- -- err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); -- if (err) -- return err; -- -- err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0); -- if (err) -- return err; -- -- err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40); -- if (err) -- return err; -- -- err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG); -- if (err) -- return err; -- -- err = ds_recv_status(dev, st); -- -- return err; --} -- --#endif /* 0 */ -- --static int ds_wait_status(struct ds_device *dev, struct ds_status *st) --{ -- u8 buf[0x20]; -- int err, count = 0; -- -- do { -- err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); --#if 0 -- if (err >= 0) { -- int i; -- printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); -- for (i=0; i<err; ++i) -- printk("%02x ", buf[i]); -- printk("\n"); -- } --#endif -- } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); -- -- -- if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { -- ds_recv_status(dev, st); -- return -1; -- } else -- return 0; --} -- --int ds_reset(struct ds_device *dev, struct ds_status *st) --{ -- int err; -- -- //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE); -- err = ds_send_control(dev, 0x43, SPEED_NORMAL); -- if (err) -- return err; -- -- ds_wait_status(dev, st); --#if 0 -- if (st->command_buffer_status) { -- printk(KERN_INFO "Short circuit.\n"); -- return -EIO; -- } --#endif -- -- return 0; --} -- --#if 0 --int ds_set_speed(struct ds_device *dev, int speed) --{ -- int err; -- -- if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE) -- return -EINVAL; -- -- if (speed != SPEED_OVERDRIVE) -- speed = SPEED_FLEXIBLE; -- -- speed &= 0xff; -- -- err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); -- if (err) -- return err; -- -- return err; --} --#endif /* 0 */ -- --static int ds_start_pulse(struct ds_device *dev, int delay) --{ -- int err; -- u8 del = 1 + (u8)(delay >> 4); -- struct ds_status st; -- --#if 0 -- err = ds_stop_pulse(dev, 10); -- if (err) -- return err; -- -- err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); -- if (err) -- return err; --#endif -- err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); -- if (err) -- return err; -- -- err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0); -- if (err) -- return err; -- -- mdelay(delay); -- -- ds_wait_status(dev, &st); -- -- return err; --} -- --int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) --{ -- int err, count; -- struct ds_status st; -- u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0); -- u16 cmd; -- -- err = ds_send_control(dev, value, 0); -- if (err) -- return err; -- -- count = 0; -- do { -- err = ds_wait_status(dev, &st); -- if (err) -- return err; -- -- cmd = st.command0 | (st.command1 << 8); -- } while (cmd != value && ++count < 10); -- -- if (err < 0 || count >= 10) { -- printk(KERN_ERR "Failed to obtain status.\n"); -- return -EINVAL; -- } -- -- err = ds_recv_data(dev, tbit, sizeof(*tbit)); -- if (err < 0) -- return err; -- -- return 0; --} -- --int ds_write_bit(struct ds_device *dev, u8 bit) --{ -- int err; -- struct ds_status st; -- -- err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- return 0; --} -- --int ds_write_byte(struct ds_device *dev, u8 byte) --{ -- int err; -- struct ds_status st; -- u8 rbyte; -- -- err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); -- if (err) -- return err; -- -- err = ds_wait_status(dev, &st); -- if (err) -- return err; -- -- err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); -- if (err < 0) -- return err; -- -- ds_start_pulse(dev, PULLUP_PULSE_DURATION); -- -- return !(byte == rbyte); --} -- --int ds_read_bit(struct ds_device *dev, u8 *bit) --{ -- int err; -- -- err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); -- if (err) -- return err; -- -- err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0); -- if (err) -- return err; -- -- err = ds_recv_data(dev, bit, sizeof(*bit)); -- if (err < 0) -- return err; -- -- return 0; --} -- --int ds_read_byte(struct ds_device *dev, u8 *byte) --{ -- int err; -- struct ds_status st; -- -- err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM , 0xff); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- err = ds_recv_data(dev, byte, sizeof(*byte)); -- if (err < 0) -- return err; -- -- return 0; --} -- --int ds_read_block(struct ds_device *dev, u8 *buf, int len) --{ -- struct ds_status st; -- int err; -- -- if (len > 64*1024) -- return -E2BIG; -- -- memset(buf, 0xFF, len); -- -- err = ds_send_data(dev, buf, len); -- if (err < 0) -- return err; -- -- err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- memset(buf, 0x00, len); -- err = ds_recv_data(dev, buf, len); -- -- return err; --} -- --int ds_write_block(struct ds_device *dev, u8 *buf, int len) --{ -- int err; -- struct ds_status st; -- -- err = ds_send_data(dev, buf, len); -- if (err < 0) -- return err; -- -- ds_wait_status(dev, &st); -- -- err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- err = ds_recv_data(dev, buf, len); -- if (err < 0) -- return err; -- -- ds_start_pulse(dev, PULLUP_PULSE_DURATION); -- -- return !(err == len); --} -- --#if 0 -- --int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) --{ -- int err; -- u16 value, index; -- struct ds_status st; -- -- memset(buf, 0, sizeof(buf)); -- -- err = ds_send_data(ds_dev, (unsigned char *)&init, 8); -- if (err) -- return err; -- -- ds_wait_status(ds_dev, &st); -- -- value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; -- index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); -- err = ds_send_control(ds_dev, value, index); -- if (err) -- return err; -- -- ds_wait_status(ds_dev, &st); -- -- err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); -- if (err < 0) -- return err; -- -- return err/8; --} -- --int ds_match_access(struct ds_device *dev, u64 init) --{ -- int err; -- struct ds_status st; -- -- err = ds_send_data(dev, (unsigned char *)&init, sizeof(init)); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- return 0; --} -- --int ds_set_path(struct ds_device *dev, u64 init) --{ -- int err; -- struct ds_status st; -- u8 buf[9]; -- -- memcpy(buf, &init, 8); -- buf[8] = BRANCH_MAIN; -- -- err = ds_send_data(dev, buf, sizeof(buf)); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0); -- if (err) -- return err; -- -- ds_wait_status(dev, &st); -- -- return 0; --} -- --#endif /* 0 */ -- --static int ds_probe(struct usb_interface *intf, -- const struct usb_device_id *udev_id) --{ -- struct usb_device *udev = interface_to_usbdev(intf); -- struct usb_endpoint_descriptor *endpoint; -- struct usb_host_interface *iface_desc; -- int i, err; -- -- ds_dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); -- if (!ds_dev) { -- printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); -- return -ENOMEM; -- } -- -- ds_dev->udev = usb_get_dev(udev); -- usb_set_intfdata(intf, ds_dev); -- -- err = usb_set_interface(ds_dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); -- if (err) { -- printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", -- intf->altsetting[0].desc.bInterfaceNumber, err); -- return err; -- } -- -- err = usb_reset_configuration(ds_dev->udev); -- if (err) { -- printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); -- return err; -- } -- -- iface_desc = &intf->altsetting[0]; -- if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { -- printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); -- return -ENODEV; -- } -- -- atomic_set(&ds_dev->refcnt, 0); -- memset(ds_dev->ep, 0, sizeof(ds_dev->ep)); -- -- /* -- * This loop doesn'd show control 0 endpoint, -- * so we will fill only 1-3 endpoints entry. -- */ -- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { -- endpoint = &iface_desc->endpoint[i].desc; -- -- ds_dev->ep[i+1] = endpoint->bEndpointAddress; -- -- printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", -- i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), -- (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", -- endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); -- } -- --#if 0 -- { -- int err, i; -- u64 buf[3]; -- u64 init=0xb30000002078ee81ull; -- struct ds_status st; -- -- ds_reset(ds_dev, &st); -- err = ds_search(ds_dev, init, buf, 3, 0); -- if (err < 0) -- return err; -- for (i=0; i<err; ++i) -- printk("%d: %llx\n", i, buf[i]); -- -- printk("Resetting...\n"); -- ds_reset(ds_dev, &st); -- printk("Setting path for %llx.\n", init); -- err = ds_set_path(ds_dev, init); -- if (err) -- return err; -- printk("Calling MATCH_ACCESS.\n"); -- err = ds_match_access(ds_dev, init); -- if (err) -- return err; -- -- printk("Searching the bus...\n"); -- err = ds_search(ds_dev, init, buf, 3, 0); -- -- printk("ds_search() returned %d\n", err); -- -- if (err < 0) -- return err; -- for (i=0; i<err; ++i) -- printk("%d: %llx\n", i, buf[i]); -- -- return 0; -- } --#endif -- -- return 0; --} -- --static void ds_disconnect(struct usb_interface *intf) --{ -- struct ds_device *dev; -- -- dev = usb_get_intfdata(intf); -- usb_set_intfdata(intf, NULL); -- -- while (atomic_read(&dev->refcnt)) { -- printk(KERN_INFO "Waiting for DS to become free: refcnt=%d.\n", -- atomic_read(&dev->refcnt)); -- -- if (msleep_interruptible(1000)) -- flush_signals(current); -- } -- -- usb_put_dev(dev->udev); -- kfree(dev); -- ds_dev = NULL; --} -- --static int ds_init(void) --{ -- int err; -- -- err = usb_register(&ds_driver); -- if (err) { -- printk(KERN_INFO "Failed to register DS9490R USB device: err=%d.\n", err); -- return err; -- } -- -- return 0; --} -- --static void ds_fini(void) --{ -- usb_deregister(&ds_driver); --} -- --module_init(ds_init); --module_exit(ds_fini); -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); -- --EXPORT_SYMBOL(ds_touch_bit); --EXPORT_SYMBOL(ds_read_byte); --EXPORT_SYMBOL(ds_read_bit); --EXPORT_SYMBOL(ds_read_block); --EXPORT_SYMBOL(ds_write_byte); --EXPORT_SYMBOL(ds_write_bit); --EXPORT_SYMBOL(ds_write_block); --EXPORT_SYMBOL(ds_reset); --EXPORT_SYMBOL(ds_get_device); --EXPORT_SYMBOL(ds_put_device); -- --/* -- * This functions can be used for EEPROM programming, -- * when driver will be included into mainline this will -- * require uncommenting. -- */ --#if 0 --EXPORT_SYMBOL(ds_start_pulse); --EXPORT_SYMBOL(ds_set_speed); --EXPORT_SYMBOL(ds_detect); --EXPORT_SYMBOL(ds_stop_pulse); --EXPORT_SYMBOL(ds_search); --#endif ---- gregkh-2.6.orig/drivers/w1/masters/dscore.h -+++ /dev/null -@@ -1,166 +0,0 @@ --/* -- * dscore.h -- * -- * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> -- * -- * -- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ -- --#ifndef __DSCORE_H --#define __DSCORE_H -- --#include <linux/usb.h> --#include <asm/atomic.h> -- --/* COMMAND TYPE CODES */ --#define CONTROL_CMD 0x00 --#define COMM_CMD 0x01 --#define MODE_CMD 0x02 -- --/* CONTROL COMMAND CODES */ --#define CTL_RESET_DEVICE 0x0000 --#define CTL_START_EXE 0x0001 --#define CTL_RESUME_EXE 0x0002 --#define CTL_HALT_EXE_IDLE 0x0003 --#define CTL_HALT_EXE_DONE 0x0004 --#define CTL_FLUSH_COMM_CMDS 0x0007 --#define CTL_FLUSH_RCV_BUFFER 0x0008 --#define CTL_FLUSH_XMT_BUFFER 0x0009 --#define CTL_GET_COMM_CMDS 0x000A -- --/* MODE COMMAND CODES */ --#define MOD_PULSE_EN 0x0000 --#define MOD_SPEED_CHANGE_EN 0x0001 --#define MOD_1WIRE_SPEED 0x0002 --#define MOD_STRONG_PU_DURATION 0x0003 --#define MOD_PULLDOWN_SLEWRATE 0x0004 --#define MOD_PROG_PULSE_DURATION 0x0005 --#define MOD_WRITE1_LOWTIME 0x0006 --#define MOD_DSOW0_TREC 0x0007 -- --/* COMMUNICATION COMMAND CODES */ --#define COMM_ERROR_ESCAPE 0x0601 --#define COMM_SET_DURATION 0x0012 --#define COMM_BIT_IO 0x0020 --#define COMM_PULSE 0x0030 --#define COMM_1_WIRE_RESET 0x0042 --#define COMM_BYTE_IO 0x0052 --#define COMM_MATCH_ACCESS 0x0064 --#define COMM_BLOCK_IO 0x0074 --#define COMM_READ_STRAIGHT 0x0080 --#define COMM_DO_RELEASE 0x6092 --#define COMM_SET_PATH 0x00A2 --#define COMM_WRITE_SRAM_PAGE 0x00B2 --#define COMM_WRITE_EPROM 0x00C4 --#define COMM_READ_CRC_PROT_PAGE 0x00D4 --#define COMM_READ_REDIRECT_PAGE_CRC 0x21E4 --#define COMM_SEARCH_ACCESS 0x00F4 -- --/* Communication command bits */ --#define COMM_TYPE 0x0008 --#define COMM_SE 0x0008 --#define COMM_D 0x0008 --#define COMM_Z 0x0008 --#define COMM_CH 0x0008 --#define COMM_SM 0x0008 --#define COMM_R 0x0008 --#define COMM_IM 0x0001 -- --#define COMM_PS 0x4000 --#define COMM_PST 0x4000 --#define COMM_CIB 0x4000 --#define COMM_RTS 0x4000 --#define COMM_DT 0x2000 --#define COMM_SPU 0x1000 --#define COMM_F 0x0800 --#define COMM_NTP 0x0400 --#define COMM_ICP 0x0200 --#define COMM_RST 0x0100 -- --#define PULSE_PROG 0x01 --#define PULSE_SPUE 0x02 -- --#define BRANCH_MAIN 0xCC --#define BRANCH_AUX 0x33 -- --/* -- * Duration of the strong pull-up pulse in milliseconds. -- */ --#define PULLUP_PULSE_DURATION 750 -- --/* Status flags */ --#define ST_SPUA 0x01 /* Strong Pull-up is active */ --#define ST_PRGA 0x02 /* 12V programming pulse is being generated */ --#define ST_12VP 0x04 /* external 12V programming voltage is present */ --#define ST_PMOD 0x08 /* DS2490 powered from USB and external sources */ --#define ST_HALT 0x10 /* DS2490 is currently halted */ --#define ST_IDLE 0x20 /* DS2490 is currently idle */ --#define ST_EPOF 0x80 -- --#define SPEED_NORMAL 0x00 --#define SPEED_FLEXIBLE 0x01 --#define SPEED_OVERDRIVE 0x02 -- --#define NUM_EP 4 --#define EP_CONTROL 0 --#define EP_STATUS 1 --#define EP_DATA_OUT 2 --#define EP_DATA_IN 3 -- --struct ds_device --{ -- struct usb_device *udev; -- struct usb_interface *intf; -- -- int ep[NUM_EP]; -- -- atomic_t refcnt; --}; -- --struct ds_status --{ -- u8 enable; -- u8 speed; -- u8 pullup_dur; -- u8 ppuls_dur; -- u8 pulldown_slew; -- u8 write1_time; -- u8 write0_time; -- u8 reserved0; -- u8 status; -- u8 command0; -- u8 command1; -- u8 command_buffer_status; -- u8 data_out_buffer_status; -- u8 data_in_buffer_status; -- u8 reserved1; -- u8 reserved2; -- --}; -- --int ds_touch_bit(struct ds_device *, u8, u8 *); --int ds_read_byte(struct ds_device *, u8 *); --int ds_read_bit(struct ds_device *, u8 *); --int ds_write_byte(struct ds_device *, u8); --int ds_write_bit(struct ds_device *, u8); --int ds_reset(struct ds_device *, struct ds_status *); --struct ds_device * ds_get_device(void); --void ds_put_device(struct ds_device *); --int ds_write_block(struct ds_device *, u8 *, int); --int ds_read_block(struct ds_device *, u8 *, int); -- --#endif /* __DSCORE_H */ -- diff --git a/i2c/w1-use-mutexes-instead-of-semaphores.patch b/i2c/w1-use-mutexes-instead-of-semaphores.patch deleted file mode 100644 index 87026d4474efe6..00000000000000 --- a/i2c/w1-use-mutexes-instead-of-semaphores.patch +++ /dev/null @@ -1,630 +0,0 @@ -From johnpol@2ka.mipt.ru Mon Apr 3 01:05:00 2006 -Date: Mon, 3 Apr 2006 12:04:27 +0400 -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [2/2] w1: Use mutexes instead of semaphores. -Message-ID: <20060403080425.GA18802@2ka.mipt.ru> -Content-Disposition: inline - -Use mutexes instead of semaphores. -Patch tested on x86_64 and i386 with test bus master driver. - -Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/masters/ds2482.c | 24 ++++---- - drivers/w1/masters/ds2490.c | 10 +-- - drivers/w1/slaves/w1_ds2433.c | 20 +------ - drivers/w1/slaves/w1_therm.c | 12 ---- - drivers/w1/w1.c | 114 ++++++++++++++---------------------------- - drivers/w1/w1.h | 5 - - drivers/w1/w1_int.c | 8 +- - drivers/w1/w1_netlink.c | 4 - - 8 files changed, 70 insertions(+), 127 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/masters/ds2482.c -+++ gregkh-2.6/drivers/w1/masters/ds2482.c -@@ -125,7 +125,7 @@ struct ds2482_w1_chan { - - struct ds2482_data { - struct i2c_client client; -- struct semaphore access_lock; -+ struct mutex access_lock; - - /* 1-wire interface(s) */ - int w1_count; /* 1 or 8 */ -@@ -265,7 +265,7 @@ static u8 ds2482_w1_touch_bit(void *data - struct ds2482_data *pdev = pchan->pdev; - int status = -1; - -- down(&pdev->access_lock); -+ mutex_lock(&pdev->access_lock); - - /* Select the channel */ - ds2482_wait_1wire_idle(pdev); -@@ -277,7 +277,7 @@ static u8 ds2482_w1_touch_bit(void *data - bit ? 0xFF : 0)) - status = ds2482_wait_1wire_idle(pdev); - -- up(&pdev->access_lock); -+ mutex_unlock(&pdev->access_lock); - - return (status & DS2482_REG_STS_SBR) ? 1 : 0; - } -@@ -297,7 +297,7 @@ static u8 ds2482_w1_triplet(void *data, - struct ds2482_data *pdev = pchan->pdev; - int status = (3 << 5); - -- down(&pdev->access_lock); -+ mutex_lock(&pdev->access_lock); - - /* Select the channel */ - ds2482_wait_1wire_idle(pdev); -@@ -309,7 +309,7 @@ static u8 ds2482_w1_triplet(void *data, - dbit ? 0xFF : 0)) - status = ds2482_wait_1wire_idle(pdev); - -- up(&pdev->access_lock); -+ mutex_unlock(&pdev->access_lock); - - /* Decode the status */ - return (status >> 5); -@@ -326,7 +326,7 @@ static void ds2482_w1_write_byte(void *d - struct ds2482_w1_chan *pchan = data; - struct ds2482_data *pdev = pchan->pdev; - -- down(&pdev->access_lock); -+ mutex_lock(&pdev->access_lock); - - /* Select the channel */ - ds2482_wait_1wire_idle(pdev); -@@ -336,7 +336,7 @@ static void ds2482_w1_write_byte(void *d - /* Send the write byte command */ - ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte); - -- up(&pdev->access_lock); -+ mutex_unlock(&pdev->access_lock); - } - - /** -@@ -351,7 +351,7 @@ static u8 ds2482_w1_read_byte(void *data - struct ds2482_data *pdev = pchan->pdev; - int result; - -- down(&pdev->access_lock); -+ mutex_lock(&pdev->access_lock); - - /* Select the channel */ - ds2482_wait_1wire_idle(pdev); -@@ -370,7 +370,7 @@ static u8 ds2482_w1_read_byte(void *data - /* Read the data byte */ - result = i2c_smbus_read_byte(&pdev->client); - -- up(&pdev->access_lock); -+ mutex_unlock(&pdev->access_lock); - - return result; - } -@@ -389,7 +389,7 @@ static u8 ds2482_w1_reset_bus(void *data - int err; - u8 retval = 1; - -- down(&pdev->access_lock); -+ mutex_lock(&pdev->access_lock); - - /* Select the channel */ - ds2482_wait_1wire_idle(pdev); -@@ -409,7 +409,7 @@ static u8 ds2482_w1_reset_bus(void *data - 0xF0); - } - -- up(&pdev->access_lock); -+ mutex_unlock(&pdev->access_lock); - - return retval; - } -@@ -482,7 +482,7 @@ static int ds2482_detect(struct i2c_adap - snprintf(new_client->name, sizeof(new_client->name), "ds2482-%d00", - data->w1_count); - -- init_MUTEX(&data->access_lock); -+ mutex_init(&data->access_lock); - - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) ---- gregkh-2.6.orig/drivers/w1/masters/ds2490.c -+++ gregkh-2.6/drivers/w1/masters/ds2490.c -@@ -169,7 +169,7 @@ static int ds_send_control(struct ds_dev - static int ds_send_control_cmd(struct ds_device *, u16, u16); - - static LIST_HEAD(ds_devices); --static DECLARE_MUTEX(ds_mutex); -+static DEFINE_MUTEX(ds_mutex); - - static struct usb_driver ds_driver = { - .name = "DS9490R", -@@ -887,9 +887,9 @@ static int ds_probe(struct usb_interface - if (err) - goto err_out_clear; - -- down(&ds_mutex); -+ mutex_lock(&ds_mutex); - list_add_tail(&dev->ds_entry, &ds_devices); -- up(&ds_mutex); -+ mutex_unlock(&ds_mutex); - - return 0; - -@@ -909,9 +909,9 @@ static void ds_disconnect(struct usb_int - if (!dev) - return; - -- down(&ds_mutex); -+ mutex_lock(&ds_mutex); - list_del(&dev->ds_entry); -- up(&ds_mutex); -+ mutex_unlock(&ds_mutex); - - ds_w1_fini(dev); - ---- gregkh-2.6.orig/drivers/w1/slaves/w1_ds2433.c -+++ gregkh-2.6/drivers/w1/slaves/w1_ds2433.c -@@ -105,11 +105,7 @@ static ssize_t w1_f23_read_bin(struct ko - if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) - return 0; - -- atomic_inc(&sl->refcnt); -- if (down_interruptible(&sl->master->mutex)) { -- count = 0; -- goto out_dec; -- } -+ mutex_lock(&sl->master->mutex); - - #ifdef CONFIG_W1_F23_CRC - -@@ -140,9 +136,7 @@ static ssize_t w1_f23_read_bin(struct ko - #endif /* CONFIG_W1_F23_CRC */ - - out_up: -- up(&sl->master->mutex); --out_dec: -- atomic_dec(&sl->refcnt); -+ mutex_unlock(&sl->master->mutex); - - return count; - } -@@ -231,11 +225,7 @@ static ssize_t w1_f23_write_bin(struct k - } - #endif /* CONFIG_W1_F23_CRC */ - -- atomic_inc(&sl->refcnt); -- if (down_interruptible(&sl->master->mutex)) { -- count = 0; -- goto out_dec; -- } -+ mutex_lock(&sl->master->mutex); - - /* Can only write data to one page at a time */ - idx = 0; -@@ -253,9 +243,7 @@ static ssize_t w1_f23_write_bin(struct k - } - - out_up: -- up(&sl->master->mutex); --out_dec: -- atomic_dec(&sl->refcnt); -+ mutex_unlock(&sl->master->mutex); - - return count; - } ---- gregkh-2.6.orig/drivers/w1/slaves/w1_therm.c -+++ gregkh-2.6/drivers/w1/slaves/w1_therm.c -@@ -165,12 +165,7 @@ static ssize_t w1_therm_read_bin(struct - u8 rom[9], crc, verdict; - int i, max_trying = 10; - -- atomic_inc(&sl->refcnt); -- smp_mb__after_atomic_inc(); -- if (down_interruptible(&sl->master->mutex)) { -- count = 0; -- goto out_dec; -- } -+ mutex_lock(&sl->master->mutex); - - if (off > W1_SLAVE_DATA_SIZE) { - count = 0; -@@ -233,10 +228,7 @@ static ssize_t w1_therm_read_bin(struct - - count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid)); - out: -- up(&dev->mutex); --out_dec: -- smp_mb__before_atomic_inc(); -- atomic_dec(&sl->refcnt); -+ mutex_unlock(&dev->mutex); - - return count; - } ---- gregkh-2.6.orig/drivers/w1/w1.c -+++ gregkh-2.6/drivers/w1/w1.c -@@ -54,7 +54,7 @@ module_param_named(control_timeout, w1_c - module_param_named(max_slave_count, w1_max_slave_count, int, 0); - module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); - --DECLARE_MUTEX(w1_mlock); -+DEFINE_MUTEX(w1_mlock); - LIST_HEAD(w1_masters); - - static struct task_struct *w1_control_thread; -@@ -139,11 +139,7 @@ static ssize_t w1_default_write(struct k - { - struct w1_slave *sl = kobj_to_w1_slave(kobj); - -- if (down_interruptible(&sl->master->mutex)) { -- count = 0; -- goto out; -- } -- -+ mutex_lock(&sl->master->mutex); - if (w1_reset_select_slave(sl)) { - count = 0; - goto out_up; -@@ -152,8 +148,7 @@ static ssize_t w1_default_write(struct k - w1_write_block(sl->master, buf, count); - - out_up: -- up(&sl->master->mutex); --out: -+ mutex_unlock(&sl->master->mutex); - return count; - } - -@@ -161,15 +156,9 @@ static ssize_t w1_default_read(struct ko - { - struct w1_slave *sl = kobj_to_w1_slave(kobj); - -- if (down_interruptible(&sl->master->mutex)) { -- count = 0; -- goto out; -- } -- -+ mutex_lock(&sl->master->mutex); - w1_read_block(sl->master, buf, count); -- -- up(&sl->master->mutex); --out: -+ mutex_unlock(&sl->master->mutex); - return count; - } - -@@ -243,12 +232,9 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - ssize_t count; - -- if (down_interruptible (&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - count = sprintf(buf, "%s\n", md->name); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - - return count; - } -@@ -259,12 +245,9 @@ static ssize_t w1_master_attribute_store - { - struct w1_master *md = dev_to_w1_master(dev); - -- if (down_interruptible (&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - md->search_count = simple_strtol(buf, NULL, 0); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - - return count; - } -@@ -276,12 +259,9 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - ssize_t count; - -- if (down_interruptible (&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - count = sprintf(buf, "%d\n", md->search_count); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - - return count; - } -@@ -291,12 +271,9 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - ssize_t count; - -- if (down_interruptible(&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - count = sprintf(buf, "0x%p\n", md->bus_master); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - return count; - } - -@@ -312,12 +289,9 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - ssize_t count; - -- if (down_interruptible(&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - count = sprintf(buf, "%d\n", md->max_slave_count); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - return count; - } - -@@ -326,12 +300,9 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - ssize_t count; - -- if (down_interruptible(&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - count = sprintf(buf, "%lu\n", md->attempts); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - return count; - } - -@@ -340,12 +311,9 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - ssize_t count; - -- if (down_interruptible(&md->mutex)) -- return -EBUSY; -- -+ mutex_lock(&md->mutex); - count = sprintf(buf, "%d\n", md->slave_count); -- -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - return count; - } - -@@ -354,8 +322,7 @@ static ssize_t w1_master_attribute_show_ - struct w1_master *md = dev_to_w1_master(dev); - int c = PAGE_SIZE; - -- if (down_interruptible(&md->mutex)) -- return -EBUSY; -+ mutex_lock(&md->mutex); - - if (md->slave_count == 0) - c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); -@@ -370,7 +337,7 @@ static ssize_t w1_master_attribute_show_ - } - } - -- up(&md->mutex); -+ mutex_unlock(&md->mutex); - - return PAGE_SIZE - c; - } -@@ -620,7 +587,7 @@ static struct w1_master *w1_search_maste - struct w1_master *dev; - int found = 0; - -- down(&w1_mlock); -+ mutex_lock(&w1_mlock); - list_for_each_entry(dev, &w1_masters, w1_master_entry) { - if (dev->bus_master->data == data) { - found = 1; -@@ -628,7 +595,7 @@ static struct w1_master *w1_search_maste - break; - } - } -- up(&w1_mlock); -+ mutex_unlock(&w1_mlock); - - return (found)?dev:NULL; - } -@@ -638,7 +605,7 @@ struct w1_master *w1_search_master_id(u3 - struct w1_master *dev; - int found = 0; - -- down(&w1_mlock); -+ mutex_lock(&w1_mlock); - list_for_each_entry(dev, &w1_masters, w1_master_entry) { - if (dev->id == id) { - found = 1; -@@ -646,7 +613,7 @@ struct w1_master *w1_search_master_id(u3 - break; - } - } -- up(&w1_mlock); -+ mutex_unlock(&w1_mlock); - - return (found)?dev:NULL; - } -@@ -657,9 +624,9 @@ struct w1_slave *w1_search_slave(struct - struct w1_slave *sl = NULL; - int found = 0; - -- down(&w1_mlock); -+ mutex_lock(&w1_mlock); - list_for_each_entry(dev, &w1_masters, w1_master_entry) { -- down(&dev->mutex); -+ mutex_lock(&dev->mutex); - list_for_each_entry(sl, &dev->slist, w1_slave_entry) { - if (sl->reg_num.family == id->family && - sl->reg_num.id == id->id && -@@ -670,12 +637,12 @@ struct w1_slave *w1_search_slave(struct - break; - } - } -- up(&dev->mutex); -+ mutex_unlock(&dev->mutex); - - if (found) - break; - } -- up(&w1_mlock); -+ mutex_unlock(&w1_mlock); - - return (found)?sl:NULL; - } -@@ -684,13 +651,13 @@ void w1_reconnect_slaves(struct w1_famil - { - struct w1_master *dev; - -- down(&w1_mlock); -+ mutex_lock(&w1_mlock); - list_for_each_entry(dev, &w1_masters, w1_master_entry) { - dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", - dev->name, f->fid); - set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); - } -- up(&w1_mlock); -+ mutex_unlock(&w1_mlock); - } - - static void w1_slave_found(void *data, u64 rn) -@@ -845,23 +812,23 @@ static int w1_control(void *data) - if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { - set_bit(W1_MASTER_NEED_EXIT, &dev->flags); - -- down(&w1_mlock); -+ mutex_lock(&w1_mlock); - list_del(&dev->w1_master_entry); -- up(&w1_mlock); -+ mutex_unlock(&w1_mlock); - -- down(&dev->mutex); -+ mutex_lock(&dev->mutex); - list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { - w1_slave_detach(sl); - } - w1_destroy_master_attributes(dev); -- up(&dev->mutex); -+ mutex_unlock(&dev->mutex); - atomic_dec(&dev->refcnt); - continue; - } - - if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { - dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); -- down(&dev->mutex); -+ mutex_lock(&dev->mutex); - list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { - if (sl->family->fid == W1_FAMILY_DEFAULT) { - struct w1_reg_num rn; -@@ -874,7 +841,7 @@ static int w1_control(void *data) - } - dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name); - clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); -- up(&dev->mutex); -+ mutex_unlock(&dev->mutex); - } - } - } -@@ -921,12 +888,9 @@ int w1_process(void *data) - if (dev->search_count == 0) - continue; - -- if (down_interruptible(&dev->mutex)) -- continue; -- -+ mutex_lock(&dev->mutex); - w1_search_process(dev, W1_SEARCH); -- -- up(&dev->mutex); -+ mutex_unlock(&dev->mutex); - } - - atomic_dec(&dev->refcnt); ---- gregkh-2.6.orig/drivers/w1/w1.h -+++ gregkh-2.6/drivers/w1/w1.h -@@ -41,8 +41,7 @@ struct w1_reg_num - - #include <linux/completion.h> - #include <linux/device.h> -- --#include <asm/semaphore.h> -+#include <linux/mutex.h> - - #include "w1_family.h" - -@@ -171,7 +170,7 @@ struct w1_master - long flags; - - struct task_struct *thread; -- struct semaphore mutex; -+ struct mutex mutex; - - struct device_driver *driver; - struct device dev; ---- gregkh-2.6.orig/drivers/w1/w1_int.c -+++ gregkh-2.6/drivers/w1/w1_int.c -@@ -36,7 +36,7 @@ extern struct device w1_master_device; - extern int w1_max_slave_count; - extern int w1_max_slave_ttl; - extern struct list_head w1_masters; --extern struct semaphore w1_mlock; -+extern struct mutex w1_mlock; - - extern int w1_process(void *); - -@@ -74,7 +74,7 @@ static struct w1_master * w1_alloc_dev(u - atomic_set(&dev->refcnt, 2); - - INIT_LIST_HEAD(&dev->slist); -- init_MUTEX(&dev->mutex); -+ mutex_init(&dev->mutex); - - memcpy(&dev->dev, device, sizeof(struct device)); - snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), -@@ -135,9 +135,9 @@ int w1_add_master_device(struct w1_bus_m - - dev->initialized = 1; - -- down(&w1_mlock); -+ mutex_lock(&w1_mlock); - list_add(&dev->w1_master_entry, &w1_masters); -- up(&w1_mlock); -+ mutex_unlock(&w1_mlock); - - memset(&msg, 0, sizeof(msg)); - msg.id.mst.id = dev->id; ---- gregkh-2.6.orig/drivers/w1/w1_netlink.c -+++ gregkh-2.6/drivers/w1/w1_netlink.c -@@ -171,7 +171,7 @@ static void w1_cn_callback(void *data) - goto out_cont; - } - -- down(&dev->mutex); -+ mutex_lock(&dev->mutex); - - if (sl && w1_reset_select_slave(sl)) { - err = -ENODEV; -@@ -198,7 +198,7 @@ out_up: - atomic_dec(&dev->refcnt); - if (sl) - atomic_dec(&sl->refcnt); -- up(&dev->mutex); -+ mutex_unlock(&dev->mutex); - out_cont: - msg->len -= sizeof(struct w1_netlink_msg) + m->len; - m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len); diff --git a/i2c/w1-userspace-communication-protocol-over-connector.patch b/i2c/w1-userspace-communication-protocol-over-connector.patch deleted file mode 100644 index 31fb72bf7d5b27..00000000000000 --- a/i2c/w1-userspace-communication-protocol-over-connector.patch +++ /dev/null @@ -1,1037 +0,0 @@ -From johnpol@2ka.mipt.ru Thu Mar 23 08:00:09 2006 -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Subject: [PATCH 3/5] w1: Userspace communication protocol over connector. -Date: Thu, 23 Mar 2006 19:11:58 +0300 -Message-Id: <11431303182850@2ka.mipt.ru> -To: GregKH <greg@kroah.com> -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> - - -There are three types of messages between w1 core and userspace: -1. Events. They are generated each time new master or slave device found - either due to automatic or requested search. -2. Userspace commands. Includes read/write and search/alarm search comamnds. -3. Replies to userspace commands. - - -From: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - Documentation/w1/w1.netlink | 98 ++++++++++++++++++ - drivers/w1/Makefile | 2 - drivers/w1/slaves/w1_ds2433.c | 1 - drivers/w1/slaves/w1_smem.c | 1 - drivers/w1/slaves/w1_therm.c | 1 - drivers/w1/w1.c | 137 +++++++++++++++++--------- - drivers/w1/w1.h | 38 +++---- - drivers/w1/w1_family.h | 1 - drivers/w1/w1_int.c | 27 ++--- - drivers/w1/w1_io.c | 18 --- - drivers/w1/w1_netlink.c | 221 +++++++++++++++++++++++++++++++++++------- - drivers/w1/w1_netlink.h | 38 +++++-- - 12 files changed, 448 insertions(+), 135 deletions(-) - ---- /dev/null -+++ gregkh-2.6/Documentation/w1/w1.netlink -@@ -0,0 +1,98 @@ -+Userspace communication protocol over connector [1]. -+ -+ -+Message types. -+============= -+ -+There are three types of messages between w1 core and userspace: -+1. Events. They are generated each time new master or slave device found -+ either due to automatic or requested search. -+2. Userspace commands. Includes read/write and search/alarm search comamnds. -+3. Replies to userspace commands. -+ -+ -+Protocol. -+======== -+ -+[struct cn_msg] - connector header. It's length field is equal to size of the attached data. -+[struct w1_netlink_msg] - w1 netlink header. -+ __u8 type - message type. -+ W1_SLAVE_ADD/W1_SLAVE_REMOVE - slave add/remove events. -+ W1_MASTER_ADD/W1_MASTER_REMOVE - master add/remove events. -+ W1_MASTER_CMD - userspace command for bus master device (search/alarm search). -+ W1_SLAVE_CMD - userspace command for slave device (read/write/ search/alarm search -+ for bus master device where given slave device found). -+ __u8 res - reserved -+ __u16 len - size of attached to this header data. -+ union { -+ __u8 id; - slave unique device id -+ struct w1_mst { -+ __u32 id; - master's id. -+ __u32 res; - reserved -+ } mst; -+ } id; -+ -+[strucrt w1_netlink_cmd] - command for gived master or slave device. -+ __u8 cmd - command opcode. -+ W1_CMD_READ - read command. -+ W1_CMD_WRITE - write command. -+ W1_CMD_SEARCH - search command. -+ W1_CMD_ALARM_SEARCH - alarm search command. -+ __u8 res - reserved -+ __u16 len - length of data for this command. -+ For read command data must be allocated like for write command. -+ __u8 data[0] - data for this command. -+ -+ -+Each connector message can include one or more w1_netlink_msg with zero of more attached w1_netlink_cmd messages. -+ -+For event messages there are no w1_netlink_cmd embedded structures, only connector header -+and w1_netlink_msg strucutre with "len" field being zero and filled type (one of event types) -+and id - either 8 bytes of slave unique id in host order, or master's id, which is assigned -+to bus master device when it is added to w1 core. -+ -+Currently replies to userspace commands are only generated for read command request. -+One reply is generated exactly for one w1_netlink_cmd read request. -+Replies are not combined when sent - i.e. typical reply messages looks like the following: -+[cn_msg][w1_netlink_msg][w1_netlink_cmd] -+cn_msg.len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd) + cmd->len; -+w1_netlink_msg.len = sizeof(struct w1_netlink_cmd) + cmd->len; -+w1_netlink_cmd.len = cmd->len; -+ -+ -+Operation steps in w1 core when new command is received. -+======================================================= -+ -+When new message (w1_netlink_msg) is received w1 core detects if it is master of slave request, -+according to w1_netlink_msg.type field. -+Then master or slave device is searched for. -+When found, master device (requested or those one on where slave device is found) is locked. -+If slave command is requested, then reset/select procedure is started to select given device. -+ -+Then all requested in w1_netlink_msg operations are performed one by one. -+If command requires reply (like read command) it is sent on command completion. -+ -+When all commands (w1_netlink_cmd) are processed muster device is unlocked -+and next w1_netlink_msg header processing started. -+ -+ -+Connector [1] specific documentation. -+==================================== -+ -+Each connector message includes two u32 fields as "address". -+w1 uses CN_W1_IDX and CN_W1_VAL defined in include/linux/connector.h header. -+Each message also includes sequence and acknowledge numbers. -+Sequence number for event messages is appropriate bus master sequence number increased with -+each event message sent "through" this master. -+Sequence number for userspace requests is set by userspace application. -+Sequence number for reply is the same as was in request, and -+acknowledge number is set to seq+1. -+ -+ -+Additional documantion, source code examples. -+============================================ -+ -+1. Documentation/connector -+2. http://tservice.net.ru/~s0mbre/archive/w1 -+This archive includes userspace application w1d.c which -+uses read/write/search commands for all master/slave devices found on the bus. ---- gregkh-2.6.orig/drivers/w1/Makefile -+++ gregkh-2.6/drivers/w1/Makefile -@@ -2,7 +2,7 @@ - # Makefile for the Dallas's 1-wire bus. - # - --ifneq ($(CONFIG_NET), y) -+ifeq ($(CONFIG_CONNECTOR), n) - EXTRA_CFLAGS += -DNETLINK_DISABLED - endif - ---- gregkh-2.6.orig/drivers/w1/slaves/w1_ds2433.c -+++ gregkh-2.6/drivers/w1/slaves/w1_ds2433.c -@@ -22,7 +22,6 @@ - #endif - - #include "../w1.h" --#include "../w1_io.h" - #include "../w1_int.h" - #include "../w1_family.h" - ---- gregkh-2.6.orig/drivers/w1/slaves/w1_smem.c -+++ gregkh-2.6/drivers/w1/slaves/w1_smem.c -@@ -28,7 +28,6 @@ - #include <linux/types.h> - - #include "../w1.h" --#include "../w1_io.h" - #include "../w1_int.h" - #include "../w1_family.h" - ---- gregkh-2.6.orig/drivers/w1/slaves/w1_therm.c -+++ gregkh-2.6/drivers/w1/slaves/w1_therm.c -@@ -29,7 +29,6 @@ - #include <linux/delay.h> - - #include "../w1.h" --#include "../w1_io.h" - #include "../w1_int.h" - #include "../w1_family.h" - ---- gregkh-2.6.orig/drivers/w1/w1.c -+++ gregkh-2.6/drivers/w1/w1.c -@@ -35,7 +35,6 @@ - #include <asm/atomic.h> - - #include "w1.h" --#include "w1_io.h" - #include "w1_log.h" - #include "w1_int.h" - #include "w1_family.h" -@@ -55,7 +54,7 @@ module_param_named(control_timeout, w1_c - module_param_named(max_slave_count, w1_max_slave_count, int, 0); - module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); - --DEFINE_SPINLOCK(w1_mlock); -+DECLARE_MUTEX(w1_mlock); - LIST_HEAD(w1_masters); - - static struct task_struct *w1_control_thread; -@@ -75,8 +74,6 @@ static void w1_master_release(struct dev - struct w1_master *md = dev_to_w1_master(dev); - - dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); -- -- dev_fini_netlink(md); - memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); - kfree(md); - } -@@ -85,10 +82,10 @@ static void w1_slave_release(struct devi - { - struct w1_slave *sl = dev_to_w1_slave(dev); - -- dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name); -+ printk("%s: Releasing %s.\n", __func__, sl->name); - - while (atomic_read(&sl->refcnt)) { -- dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n", -+ printk("Waiting for %s to become free: refcnt=%d.\n", - sl->name, atomic_read(&sl->refcnt)); - if (msleep_interruptible(1000)) - flush_signals(current); -@@ -111,7 +108,6 @@ static ssize_t w1_slave_read_id(struct k - { - struct w1_slave *sl = kobj_to_w1_slave(kobj); - -- atomic_inc(&sl->refcnt); - if (off > 8) { - count = 0; - } else { -@@ -120,7 +116,6 @@ static ssize_t w1_slave_read_id(struct k - - memcpy(buf, (u8 *)&sl->reg_num, count); - } -- atomic_dec(&sl->refcnt); - - return count; - } -@@ -230,12 +225,11 @@ struct device w1_master_device = { - .release = &w1_master_release - }; - --static struct device_driver w1_slave_driver = { -+struct device_driver w1_slave_driver = { - .name = "w1_slave_driver", - .bus = &w1_bus_type, - }; - --#if 0 - struct device w1_slave_device = { - .parent = NULL, - .bus = &w1_bus_type, -@@ -243,7 +237,6 @@ struct device w1_slave_device = { - .driver = &w1_slave_driver, - .release = &w1_slave_release - }; --#endif /* 0 */ - - static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf) - { -@@ -423,7 +416,7 @@ int w1_create_master_attributes(struct w - return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group); - } - --static void w1_destroy_master_attributes(struct w1_master *master) -+void w1_destroy_master_attributes(struct w1_master *master) - { - sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); - } -@@ -454,14 +447,11 @@ static int w1_uevent(struct device *dev, - if (dev->driver != &w1_slave_driver || !sl) - return 0; - -- err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, -- &cur_len, "W1_FID=%02X", sl->reg_num.family); -+ err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family); - if (err) - return err; - -- err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, -- &cur_len, "W1_SLAVE_ID=%024LX", -- (unsigned long long)sl->reg_num.id); -+ err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id); - if (err) - return err; - -@@ -563,6 +553,7 @@ static int w1_attach_slave_device(struct - sl->master = dev; - set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); - -+ memset(&msg, 0, sizeof(msg)); - memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); - atomic_set(&sl->refcnt, 0); - init_completion(&sl->released); -@@ -593,7 +584,7 @@ static int w1_attach_slave_device(struct - sl->ttl = dev->slave_ttl; - dev->slave_count++; - -- memcpy(&msg.id.id, rn, sizeof(msg.id.id)); -+ memcpy(msg.id.id, rn, sizeof(msg.id)); - msg.type = W1_SLAVE_ADD; - w1_netlink_send(dev, &msg); - -@@ -611,7 +602,8 @@ static void w1_slave_detach(struct w1_sl - if (sl->family->fops && sl->family->fops->remove_slave) - sl->family->fops->remove_slave(sl); - -- memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id)); -+ memset(&msg, 0, sizeof(msg)); -+ memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); - msg.type = W1_SLAVE_REMOVE; - w1_netlink_send(sl->master, &msg); - -@@ -628,7 +620,7 @@ static struct w1_master *w1_search_maste - struct w1_master *dev; - int found = 0; - -- spin_lock_bh(&w1_mlock); -+ down(&w1_mlock); - list_for_each_entry(dev, &w1_masters, w1_master_entry) { - if (dev->bus_master->data == data) { - found = 1; -@@ -636,22 +628,69 @@ static struct w1_master *w1_search_maste - break; - } - } -- spin_unlock_bh(&w1_mlock); -+ up(&w1_mlock); -+ -+ return (found)?dev:NULL; -+} -+ -+struct w1_master *w1_search_master_id(u32 id) -+{ -+ struct w1_master *dev; -+ int found = 0; -+ -+ down(&w1_mlock); -+ list_for_each_entry(dev, &w1_masters, w1_master_entry) { -+ if (dev->id == id) { -+ found = 1; -+ atomic_inc(&dev->refcnt); -+ break; -+ } -+ } -+ up(&w1_mlock); - - return (found)?dev:NULL; - } - -+struct w1_slave *w1_search_slave(struct w1_reg_num *id) -+{ -+ struct w1_master *dev; -+ struct w1_slave *sl = NULL; -+ int found = 0; -+ -+ down(&w1_mlock); -+ list_for_each_entry(dev, &w1_masters, w1_master_entry) { -+ down(&dev->mutex); -+ list_for_each_entry(sl, &dev->slist, w1_slave_entry) { -+ if (sl->reg_num.family == id->family && -+ sl->reg_num.id == id->id && -+ sl->reg_num.crc == id->crc) { -+ found = 1; -+ atomic_inc(&dev->refcnt); -+ atomic_inc(&sl->refcnt); -+ break; -+ } -+ } -+ up(&dev->mutex); -+ -+ if (found) -+ break; -+ } -+ up(&w1_mlock); -+ -+ return (found)?sl:NULL; -+} -+ - void w1_reconnect_slaves(struct w1_family *f) - { - struct w1_master *dev; - -- spin_lock_bh(&w1_mlock); -+ down(&w1_mlock); - list_for_each_entry(dev, &w1_masters, w1_master_entry) { - dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", - dev->name, f->fid); - set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); - } -- spin_unlock_bh(&w1_mlock); -+ up(&w1_mlock); - } - - static void w1_slave_found(void *data, u64 rn) -@@ -713,7 +752,7 @@ static void w1_slave_found(void *data, u - * @dev The master device to search - * @cb Function to call when a device is found - */ --void w1_search(struct w1_master *dev, w1_slave_found_callback cb) -+void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) - { - u64 last_rn, rn, tmp64; - int i, slave_count = 0; -@@ -744,7 +783,7 @@ void w1_search(struct w1_master *dev, w1 - } - - /* Start the search */ -- w1_write_8(dev, W1_SEARCH); -+ w1_write_8(dev, search_type); - for (i = 0; i < 64; ++i) { - /* Determine the direction/search bit */ - if (i == desc_bit) -@@ -806,9 +845,9 @@ static int w1_control(void *data) - if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { - set_bit(W1_MASTER_NEED_EXIT, &dev->flags); - -- spin_lock(&w1_mlock); -+ down(&w1_mlock); - list_del(&dev->w1_master_entry); -- spin_unlock(&w1_mlock); -+ up(&w1_mlock); - - down(&dev->mutex); - list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { -@@ -843,10 +882,31 @@ static int w1_control(void *data) - return 0; - } - -+void w1_search_process(struct w1_master *dev, u8 search_type) -+{ -+ struct w1_slave *sl, *sln; -+ -+ list_for_each_entry(sl, &dev->slist, w1_slave_entry) -+ clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); -+ -+ w1_search_devices(dev, search_type, w1_slave_found); -+ -+ list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { -+ if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { -+ w1_slave_detach(sl); -+ -+ dev->slave_count--; -+ } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) -+ sl->ttl = dev->slave_ttl; -+ } -+ -+ if (dev->search_count > 0) -+ dev->search_count--; -+} -+ - int w1_process(void *data) - { - struct w1_master *dev = (struct w1_master *) data; -- struct w1_slave *sl, *sln; - - while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { - try_to_freeze(); -@@ -864,22 +924,7 @@ int w1_process(void *data) - if (down_interruptible(&dev->mutex)) - continue; - -- list_for_each_entry(sl, &dev->slist, w1_slave_entry) -- clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); -- -- w1_search_devices(dev, w1_slave_found); -- -- list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { -- if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { -- w1_slave_detach(sl); -- -- dev->slave_count--; -- } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) -- sl->ttl = dev->slave_ttl; -- } -- -- if (dev->search_count > 0) -- dev->search_count--; -+ w1_search_process(dev, W1_SEARCH); - - up(&dev->mutex); - } -@@ -895,6 +940,8 @@ static int w1_init(void) - - printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n"); - -+ w1_init_netlink(); -+ - retval = bus_register(&w1_bus_type); - if (retval) { - printk(KERN_ERR "Failed to register bus. err=%d.\n", retval); -@@ -947,6 +994,8 @@ static void w1_fini(void) - list_for_each_entry(dev, &w1_masters, w1_master_entry) - __w1_remove_master_device(dev); - -+ w1_fini_netlink(); -+ - kthread_stop(w1_control_thread); - - driver_unregister(&w1_slave_driver); ---- gregkh-2.6.orig/drivers/w1/w1.h -+++ gregkh-2.6/drivers/w1/w1.h -@@ -42,8 +42,6 @@ struct w1_reg_num - #include <linux/completion.h> - #include <linux/device.h> - --#include <net/sock.h> -- - #include <asm/semaphore.h> - - #include "w1_family.h" -@@ -52,7 +50,7 @@ struct w1_reg_num - #define W1_SLAVE_DATA_SIZE 128 - - #define W1_SEARCH 0xF0 --#define W1_CONDITIONAL_SEARCH 0xEC -+#define W1_ALARM_SEARCH 0xEC - #define W1_CONVERT_TEMP 0x44 - #define W1_SKIP_ROM 0xCC - #define W1_READ_SCRATCHPAD 0xBE -@@ -145,8 +143,8 @@ struct w1_bus_master - */ - u8 (*reset_bus)(void *); - -- /** Really nice hardware can handles the ROM searches */ -- void (*search)(void *, w1_slave_found_callback); -+ /** Really nice hardware can handles the different types of ROM search */ -+ void (*search)(void *, u8, w1_slave_found_callback); - }; - - #define W1_MASTER_NEED_EXIT 0 -@@ -180,12 +178,26 @@ struct w1_master - - struct w1_bus_master *bus_master; - -- u32 seq, groups; -- struct sock *nls; -+ u32 seq; - }; - - int w1_create_master_attributes(struct w1_master *); --void w1_search(struct w1_master *dev, w1_slave_found_callback cb); -+void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb); -+void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb); -+struct w1_slave *w1_search_slave(struct w1_reg_num *id); -+void w1_search_process(struct w1_master *dev, u8 search_type); -+struct w1_master *w1_search_master_id(u32 id); -+ -+void w1_delay(unsigned long); -+u8 w1_touch_bit(struct w1_master *, int); -+u8 w1_triplet(struct w1_master *dev, int bdir); -+void w1_write_8(struct w1_master *, u8); -+u8 w1_read_8(struct w1_master *); -+int w1_reset_bus(struct w1_master *); -+u8 w1_calc_crc8(u8 *, int); -+void w1_write_block(struct w1_master *, const u8 *, int); -+u8 w1_read_block(struct w1_master *, u8 *, int); -+int w1_reset_select_slave(struct w1_slave *sl); - - static inline struct w1_slave* dev_to_w1_slave(struct device *dev) - { -@@ -202,16 +214,6 @@ static inline struct w1_master* dev_to_w - return container_of(dev, struct w1_master, dev); - } - --extern int w1_max_slave_count; --extern int w1_max_slave_ttl; --extern spinlock_t w1_mlock; --extern struct list_head w1_masters; --extern struct device_driver w1_master_driver; --extern struct device w1_master_device; -- --int w1_process(void *data); --void w1_reconnect_slaves(struct w1_family *f); -- - #endif /* __KERNEL__ */ - - #endif /* __W1_H */ ---- gregkh-2.6.orig/drivers/w1/w1_family.h -+++ gregkh-2.6/drivers/w1/w1_family.h -@@ -64,5 +64,6 @@ void __w1_family_put(struct w1_family *) - struct w1_family * w1_family_registered(u8); - void w1_unregister_family(struct w1_family *); - int w1_register_family(struct w1_family *); -+void w1_reconnect_slaves(struct w1_family *f); - - #endif /* __W1_FAMILY_H */ ---- gregkh-2.6.orig/drivers/w1/w1_int.c -+++ gregkh-2.6/drivers/w1/w1_int.c -@@ -27,10 +27,19 @@ - #include "w1.h" - #include "w1_log.h" - #include "w1_netlink.h" --#include "w1_int.h" - - static u32 w1_ids = 1; - -+extern struct device_driver w1_master_driver; -+extern struct bus_type w1_bus_type; -+extern struct device w1_master_device; -+extern int w1_max_slave_count; -+extern int w1_max_slave_ttl; -+extern struct list_head w1_masters; -+extern struct semaphore w1_mlock; -+ -+extern int w1_process(void *); -+ - static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, - struct device_driver *driver, - struct device *device) -@@ -74,16 +83,11 @@ static struct w1_master * w1_alloc_dev(u - - dev->driver = driver; - -- dev->groups = 1; - dev->seq = 1; -- dev_init_netlink(dev); - - err = device_register(&dev->dev); - if (err) { - printk(KERN_ERR "Failed to register master device. err=%d\n", err); -- -- dev_fini_netlink(dev); -- - memset(dev, 0, sizeof(struct w1_master)); - kfree(dev); - dev = NULL; -@@ -92,7 +96,7 @@ static struct w1_master * w1_alloc_dev(u - return dev; - } - --static void w1_free_dev(struct w1_master *dev) -+void w1_free_dev(struct w1_master *dev) - { - device_unregister(&dev->dev); - } -@@ -131,12 +135,12 @@ int w1_add_master_device(struct w1_bus_m - - dev->initialized = 1; - -- spin_lock(&w1_mlock); -+ down(&w1_mlock); - list_add(&dev->w1_master_entry, &w1_masters); -- spin_unlock(&w1_mlock); -+ up(&w1_mlock); - -+ memset(&msg, 0, sizeof(msg)); - msg.id.mst.id = dev->id; -- msg.id.mst.pid = dev->thread->pid; - msg.type = W1_MASTER_ADD; - w1_netlink_send(dev, &msg); - -@@ -153,7 +157,6 @@ err_out_free_dev: - void __w1_remove_master_device(struct w1_master *dev) - { - struct w1_netlink_msg msg; -- pid_t pid = dev->thread->pid; - - set_bit(W1_MASTER_NEED_EXIT, &dev->flags); - kthread_stop(dev->thread); -@@ -166,8 +169,8 @@ void __w1_remove_master_device(struct w1 - flush_signals(current); - } - -+ memset(&msg, 0, sizeof(msg)); - msg.id.mst.id = dev->id; -- msg.id.mst.pid = pid; - msg.type = W1_MASTER_REMOVE; - w1_netlink_send(dev, &msg); - ---- gregkh-2.6.orig/drivers/w1/w1_io.c -+++ gregkh-2.6/drivers/w1/w1_io.c -@@ -26,7 +26,6 @@ - - #include "w1.h" - #include "w1_log.h" --#include "w1_io.h" - - static int w1_delay_parm = 1; - module_param_named(delay_coef, w1_delay_parm, int, 0); -@@ -268,13 +267,13 @@ u8 w1_calc_crc8(u8 * data, int len) - return crc; - } - --void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb) -+void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) - { - dev->attempts++; - if (dev->bus_master->search) -- dev->bus_master->search(dev->bus_master->data, cb); -+ dev->bus_master->search(dev->bus_master->data, search_type, cb); - else -- w1_search(dev, cb); -+ w1_search(dev, search_type, cb); - } - - /** -@@ -300,13 +299,4 @@ int w1_reset_select_slave(struct w1_slav - return 0; - } - --EXPORT_SYMBOL(w1_touch_bit); --EXPORT_SYMBOL(w1_write_8); --EXPORT_SYMBOL(w1_read_8); --EXPORT_SYMBOL(w1_reset_bus); --EXPORT_SYMBOL(w1_calc_crc8); --EXPORT_SYMBOL(w1_delay); --EXPORT_SYMBOL(w1_read_block); --EXPORT_SYMBOL(w1_write_block); --EXPORT_SYMBOL(w1_search_devices); --EXPORT_SYMBOL(w1_reset_select_slave); -+EXPORT_SYMBOL_GPL(w1_calc_crc8); ---- gregkh-2.6.orig/drivers/w1/w1_netlink.c -+++ gregkh-2.6/drivers/w1/w1_netlink.c -@@ -21,6 +21,7 @@ - - #include <linux/skbuff.h> - #include <linux/netlink.h> -+#include <linux/connector.h> - - #include "w1.h" - #include "w1_log.h" -@@ -29,50 +30,204 @@ - #ifndef NETLINK_DISABLED - void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) - { -- unsigned int size; -- struct sk_buff *skb; -- struct w1_netlink_msg *data; -- struct nlmsghdr *nlh; -- -- if (!dev->nls) -- return; -- -- size = NLMSG_SPACE(sizeof(struct w1_netlink_msg)); -- -- skb = alloc_skb(size, GFP_ATOMIC); -- if (!skb) { -- dev_err(&dev->dev, "skb_alloc() failed.\n"); -- return; -- } -+ char buf[sizeof(struct cn_msg) + sizeof(struct w1_netlink_msg)]; -+ struct cn_msg *m = (struct cn_msg *)buf; -+ struct w1_netlink_msg *w = (struct w1_netlink_msg *)(m+1); - -- nlh = NLMSG_PUT(skb, 0, dev->seq++, NLMSG_DONE, size - sizeof(*nlh)); -+ memset(buf, 0, sizeof(buf)); - -- data = (struct w1_netlink_msg *)NLMSG_DATA(nlh); -+ m->id.idx = CN_W1_IDX; -+ m->id.val = CN_W1_VAL; - -- memcpy(data, msg, sizeof(struct w1_netlink_msg)); -+ m->seq = dev->seq++; -+ m->len = sizeof(struct w1_netlink_msg); - -- NETLINK_CB(skb).dst_group = dev->groups; -- netlink_broadcast(dev->nls, skb, 0, dev->groups, GFP_ATOMIC); -+ memcpy(w, msg, sizeof(struct w1_netlink_msg)); - --nlmsg_failure: -- return; -+ cn_netlink_send(m, 0, GFP_KERNEL); - } - --int dev_init_netlink(struct w1_master *dev) -+static int w1_process_command_master(struct w1_master *dev, struct cn_msg *msg, -+ struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) - { -- dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE); -- if (!dev->nls) { -- printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n", -- NETLINK_W1, dev->dev.bus_id); -- } -+ dev_dbg(&dev->dev, "%s: %s: cmd=%02x, len=%u.\n", -+ __func__, dev->name, cmd->cmd, cmd->len); -+ -+ if (cmd->cmd != W1_CMD_SEARCH && cmd->cmd != W1_CMD_ALARM_SEARCH) -+ return -EINVAL; - -+ w1_search_process(dev, (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH); - return 0; - } - --void dev_fini_netlink(struct w1_master *dev) -+static int w1_send_read_reply(struct w1_slave *sl, struct cn_msg *msg, -+ struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) -+{ -+ void *data; -+ struct w1_netlink_msg *h; -+ struct w1_netlink_cmd *c; -+ struct cn_msg *cm; -+ int err; -+ -+ data = kzalloc(sizeof(struct cn_msg) + -+ sizeof(struct w1_netlink_msg) + -+ sizeof(struct w1_netlink_cmd) + -+ cmd->len, GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ cm = (struct cn_msg *)(data); -+ h = (struct w1_netlink_msg *)(cm + 1); -+ c = (struct w1_netlink_cmd *)(h + 1); -+ -+ memcpy(cm, msg, sizeof(struct cn_msg)); -+ memcpy(h, hdr, sizeof(struct w1_netlink_msg)); -+ memcpy(c, cmd, sizeof(struct w1_netlink_cmd)); -+ -+ cm->ack = msg->seq+1; -+ cm->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd) + cmd->len; -+ -+ h->len = sizeof(struct w1_netlink_cmd) + cmd->len; -+ -+ memcpy(c->data, cmd->data, c->len); -+ -+ err = cn_netlink_send(cm, 0, GFP_KERNEL); -+ -+ kfree(data); -+ -+ return err; -+} -+ -+static int w1_process_command_slave(struct w1_slave *sl, struct cn_msg *msg, -+ struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) -+{ -+ int err = 0; -+ -+ dev_dbg(&sl->master->dev, "%s: %02x.%012llx.%02x: cmd=%02x, len=%u.\n", -+ __func__, sl->reg_num.family, (unsigned long long)sl->reg_num.id, sl->reg_num.crc, -+ cmd->cmd, cmd->len); -+ -+ switch (cmd->cmd) { -+ case W1_CMD_READ: -+ w1_read_block(sl->master, cmd->data, cmd->len); -+ w1_send_read_reply(sl, msg, hdr, cmd); -+ break; -+ case W1_CMD_WRITE: -+ w1_write_block(sl->master, cmd->data, cmd->len); -+ break; -+ case W1_CMD_SEARCH: -+ case W1_CMD_ALARM_SEARCH: -+ w1_search_process(sl->master, -+ (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH); -+ break; -+ default: -+ err = -1; -+ break; -+ } -+ -+ return err; -+} -+ -+static void w1_cn_callback(void *data) -+{ -+ struct cn_msg *msg = data; -+ struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1); -+ struct w1_netlink_cmd *cmd; -+ struct w1_slave *sl; -+ struct w1_master *dev; -+ int err = 0; -+ -+ while (msg->len && !err) { -+ struct w1_reg_num id; -+ u16 mlen = m->len; -+ u8 *cmd_data = m->data; -+ -+ dev = NULL; -+ sl = NULL; -+ -+ memcpy(&id, m->id.id, sizeof(id)); -+#if 0 -+ printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n", -+ __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len); -+#endif -+ if (m->len + sizeof(struct w1_netlink_msg) > msg->len) { -+ err = -E2BIG; -+ break; -+ } -+ -+ if (!mlen) -+ goto out_cont; -+ -+ if (m->type == W1_MASTER_CMD) { -+ dev = w1_search_master_id(m->id.mst.id); -+ } else if (m->type == W1_SLAVE_CMD) { -+ sl = w1_search_slave(&id); -+ if (sl) -+ dev = sl->master; -+ } -+ -+ if (!dev) { -+ err = -ENODEV; -+ goto out_cont; -+ } -+ -+ down(&dev->mutex); -+ -+ if (sl && w1_reset_select_slave(sl)) { -+ err = -ENODEV; -+ goto out_up; -+ } -+ -+ while (mlen) { -+ cmd = (struct w1_netlink_cmd *)cmd_data; -+ -+ if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen) { -+ err = -E2BIG; -+ break; -+ } -+ -+ if (sl) -+ w1_process_command_slave(sl, msg, m, cmd); -+ else -+ w1_process_command_master(dev, msg, m, cmd); -+ -+ cmd_data += cmd->len + sizeof(struct w1_netlink_cmd); -+ mlen -= cmd->len + sizeof(struct w1_netlink_cmd); -+ } -+out_up: -+ atomic_dec(&dev->refcnt); -+ if (sl) -+ atomic_dec(&sl->refcnt); -+ up(&dev->mutex); -+out_cont: -+ msg->len -= sizeof(struct w1_netlink_msg) + m->len; -+ m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len); -+ -+ /* -+ * Let's allow requests for nonexisting devices. -+ */ -+ if (err == -ENODEV) -+ err = 0; -+ } -+#if 0 -+ if (err) { -+ printk("%s: malformed message. Dropping.\n", __func__); -+ } -+#endif -+} -+ -+int w1_init_netlink(void) - { -- if (dev->nls && dev->nls->sk_socket) -- sock_release(dev->nls->sk_socket); -+ struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL}; -+ -+ return cn_add_callback(&w1_id, "w1", &w1_cn_callback); -+} -+ -+void w1_fini_netlink(void) -+{ -+ struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL}; -+ -+ cn_del_callback(&w1_id); - } - #else - #warning Netlink support is disabled. Please compile with NET support enabled. -@@ -81,12 +236,12 @@ void w1_netlink_send(struct w1_master *d - { - } - --int dev_init_netlink(struct w1_master *dev) -+int w1_init_netlink(void) - { - return 0; - } - --void dev_fini_netlink(struct w1_master *dev) -+void w1_fini_netlink(void) - { - } - #endif ---- gregkh-2.6.orig/drivers/w1/w1_netlink.h -+++ gregkh-2.6/drivers/w1/w1_netlink.h -@@ -23,37 +23,55 @@ - #define __W1_NETLINK_H - - #include <asm/types.h> -+#include <linux/connector.h> - - #include "w1.h" - -+#define CN_W1_IDX 3 -+#define CN_W1_VAL 1 -+ - enum w1_netlink_message_types { - W1_SLAVE_ADD = 0, - W1_SLAVE_REMOVE, - W1_MASTER_ADD, - W1_MASTER_REMOVE, -+ W1_MASTER_CMD, -+ W1_SLAVE_CMD, - }; - - struct w1_netlink_msg - { - __u8 type; -- __u8 reserved[3]; -- union -- { -- struct w1_reg_num id; -- __u64 w1_id; -- struct -- { -+ __u8 reserved; -+ __u16 len; -+ union { -+ __u8 id[8]; -+ struct w1_mst { - __u32 id; -- __u32 pid; -+ __u32 res; - } mst; - } id; -+ __u8 data[0]; -+}; -+ -+#define W1_CMD_READ 0x0 -+#define W1_CMD_WRITE 0x1 -+#define W1_CMD_SEARCH 0x2 -+#define W1_CMD_ALARM_SEARCH 0x3 -+ -+struct w1_netlink_cmd -+{ -+ __u8 cmd; -+ __u8 res; -+ __u16 len; -+ __u8 data[0]; - }; - - #ifdef __KERNEL__ - - void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *); --int dev_init_netlink(struct w1_master *dev); --void dev_fini_netlink(struct w1_master *dev); -+int w1_init_netlink(void); -+void w1_fini_netlink(void); - - #endif /* __KERNEL__ */ - #endif /* __W1_NETLINK_H */ diff --git a/i2c/w1-warning-fix.patch b/i2c/w1-warning-fix.patch deleted file mode 100644 index df64a6f6802fcf..00000000000000 --- a/i2c/w1-warning-fix.patch +++ /dev/null @@ -1,79 +0,0 @@ -From akpm@osdl.org Sun May 14 21:47:12 2006 -Message-Id: <200605150446.k4F4kwh1023981@shell0.pdx.osdl.net> -From: Andrew Morton <akpm@osdl.org> -Subject: w1: warning fix -From: akpm@osdl.org -Date: Sun, 14 May 2006 21:43:50 -0700 - -From: Andrew Morton <akpm@osdl.org> - -drivers/w1/w1.c:423: warning: long long unsigned int format, __u64 arg (arg 8) - -u64 is not, never has been and never will be "unsigned long long"! - -While we're there, fix up some code layout - it looks awful in an 80-col -display. - -Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> -Signed-off-by: Andrew Morton <akpm@osdl.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/w1/w1.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - ---- gregkh-2.6.orig/drivers/w1/w1.c -+++ gregkh-2.6/drivers/w1/w1.c -@@ -391,7 +391,8 @@ static void w1_destroy_master_attributes - } - - #ifdef CONFIG_HOTPLUG --static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) -+static int w1_uevent(struct device *dev, char **envp, int num_envp, -+ char *buffer, int buffer_size) - { - struct w1_master *md = NULL; - struct w1_slave *sl = NULL; -@@ -411,23 +412,28 @@ static int w1_uevent(struct device *dev, - return -EINVAL; - } - -- dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id); -+ dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", -+ event_owner, name, dev->bus_id); - - if (dev->driver != &w1_slave_driver || !sl) - return 0; - -- err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family); -+ err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, -+ &cur_len, "W1_FID=%02X", sl->reg_num.family); - if (err) - return err; - -- err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id); -+ err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, -+ &cur_len, "W1_SLAVE_ID=%024LX", -+ (unsigned long long)sl->reg_num.id); - if (err) - return err; - - return 0; - }; - #else --static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) -+static int w1_uevent(struct device *dev, char **envp, int num_envp, -+ char *buffer, int buffer_size) - { - return 0; - } -@@ -451,7 +457,8 @@ static int __w1_attach_slave_device(stru - (unsigned int) sl->reg_num.family, - (unsigned long long) sl->reg_num.id); - -- dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]); -+ dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, -+ &sl->dev.bus_id[0]); - - err = device_register(&sl->dev); - if (err < 0) { |