aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorPetr Vandrovec <vandrove@vc.cvut.cz>2005-10-07 17:11:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 17:02:09 -0400
commitada0c2f8fa087dc1dbc34e096c318739b1d6381a (patch)
treee7f80d1336e2190c138fd4226438195e2f67839d /drivers/hwmon
parentbf813b314a2271c3f3903eb3279ebf5e09b3d27a (diff)
[PATCH] hwmon: Fix w83627ehf/hf vs PNPACPI conflict (bug #4014)
This patch changes w83627hf and w83627ehf drivers to reserve only ports 0x295-0x296, instead of full 0x290-0x297 range. While some other sensors chips respond to all addresses in 0x290-0x297 range, Winbond chips respond to 0x295-0x296 only (this behavior is implied by documentation, and matches behavior observed on real systems). This is not problem alone, as no BIOS was found to put something at these unused addresses, and sensors chip itself provides nothing there as well. But in addition to only respond to these two addresses, also BIOS vendors report in their ACPI-PnP structures that there is some resource at I/O address 0x295 of length 2. And when later this hwmon driver attempts to request region with base 0x290/length 8, it fails as one request_region cannot span more than one device. Due to this we have to ask only for region this hardware really occupies, otherwise driver cannot be loaded on systems with ACPI-PnP enabled. Signed-off-by: Petr Vandrovec <vandrove@vc.cvut.cz> Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/w83627ehf.c13
-rw-r--r--drivers/hwmon/w83627hf.c21
2 files changed, 21 insertions, 13 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index b60efe8f8b26..685eeb766809 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -105,7 +105,9 @@ superio_exit(void)
105 * ISA constants 105 * ISA constants
106 */ 106 */
107 107
108#define REGION_LENGTH 8 108#define REGION_ALIGNMENT ~7
109#define REGION_OFFSET 5
110#define REGION_LENGTH 2
109#define ADDR_REG_OFFSET 5 111#define ADDR_REG_OFFSET 5
110#define DATA_REG_OFFSET 6 112#define DATA_REG_OFFSET 6
111 113
@@ -673,7 +675,8 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
673 struct w83627ehf_data *data; 675 struct w83627ehf_data *data;
674 int i, err = 0; 676 int i, err = 0;
675 677
676 if (!request_region(address, REGION_LENGTH, w83627ehf_driver.name)) { 678 if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
679 w83627ehf_driver.name)) {
677 err = -EBUSY; 680 err = -EBUSY;
678 goto exit; 681 goto exit;
679 } 682 }
@@ -762,7 +765,7 @@ exit_detach:
762exit_free: 765exit_free:
763 kfree(data); 766 kfree(data);
764exit_release: 767exit_release:
765 release_region(address, REGION_LENGTH); 768 release_region(address + REGION_OFFSET, REGION_LENGTH);
766exit: 769exit:
767 return err; 770 return err;
768} 771}
@@ -776,7 +779,7 @@ static int w83627ehf_detach_client(struct i2c_client *client)
776 779
777 if ((err = i2c_detach_client(client))) 780 if ((err = i2c_detach_client(client)))
778 return err; 781 return err;
779 release_region(client->addr, REGION_LENGTH); 782 release_region(client->addr + REGION_OFFSET, REGION_LENGTH);
780 kfree(data); 783 kfree(data);
781 784
782 return 0; 785 return 0;
@@ -807,7 +810,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr)
807 superio_select(W83627EHF_LD_HWM); 810 superio_select(W83627EHF_LD_HWM);
808 val = (superio_inb(SIO_REG_ADDR) << 8) 811 val = (superio_inb(SIO_REG_ADDR) << 8)
809 | superio_inb(SIO_REG_ADDR + 1); 812 | superio_inb(SIO_REG_ADDR + 1);
810 *addr = val & ~(REGION_LENGTH - 1); 813 *addr = val & REGION_ALIGNMENT;
811 if (*addr == 0) { 814 if (*addr == 0) {
812 superio_exit(); 815 superio_exit();
813 return -ENODEV; 816 return -ENODEV;
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 7f6f7280878d..494274d27f01 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -142,10 +142,14 @@ superio_exit(void)
142#define WINB_BASE_REG 0x60 142#define WINB_BASE_REG 0x60
143/* Constants specified below */ 143/* Constants specified below */
144 144
145/* Length of ISA address segment */ 145/* Alignment of the base address */
146#define WINB_EXTENT 8 146#define WINB_ALIGNMENT ~7
147 147
148/* Where are the ISA address/data registers relative to the base address */ 148/* Offset & size of I/O region we are interested in */
149#define WINB_REGION_OFFSET 5
150#define WINB_REGION_SIZE 2
151
152/* Where are the sensors address/data registers relative to the base address */
149#define W83781D_ADDR_REG_OFFSET 5 153#define W83781D_ADDR_REG_OFFSET 5
150#define W83781D_DATA_REG_OFFSET 6 154#define W83781D_DATA_REG_OFFSET 6
151 155
@@ -981,7 +985,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr)
981 superio_select(W83627HF_LD_HWM); 985 superio_select(W83627HF_LD_HWM);
982 val = (superio_inb(WINB_BASE_REG) << 8) | 986 val = (superio_inb(WINB_BASE_REG) << 8) |
983 superio_inb(WINB_BASE_REG + 1); 987 superio_inb(WINB_BASE_REG + 1);
984 *addr = val & ~(WINB_EXTENT - 1); 988 *addr = val & WINB_ALIGNMENT;
985 if (*addr == 0 && force_addr == 0) { 989 if (*addr == 0 && force_addr == 0) {
986 superio_exit(); 990 superio_exit();
987 return -ENODEV; 991 return -ENODEV;
@@ -1000,9 +1004,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
1000 const char *client_name = ""; 1004 const char *client_name = "";
1001 1005
1002 if(force_addr) 1006 if(force_addr)
1003 address = force_addr & ~(WINB_EXTENT - 1); 1007 address = force_addr & WINB_ALIGNMENT;
1004 1008
1005 if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) { 1009 if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
1010 w83627hf_driver.name)) {
1006 err = -EBUSY; 1011 err = -EBUSY;
1007 goto ERROR0; 1012 goto ERROR0;
1008 } 1013 }
@@ -1148,7 +1153,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
1148 ERROR2: 1153 ERROR2:
1149 kfree(data); 1154 kfree(data);
1150 ERROR1: 1155 ERROR1:
1151 release_region(address, WINB_EXTENT); 1156 release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE);
1152 ERROR0: 1157 ERROR0:
1153 return err; 1158 return err;
1154} 1159}
@@ -1163,7 +1168,7 @@ static int w83627hf_detach_client(struct i2c_client *client)
1163 if ((err = i2c_detach_client(client))) 1168 if ((err = i2c_detach_client(client)))
1164 return err; 1169 return err;
1165 1170
1166 release_region(client->addr, WINB_EXTENT); 1171 release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE);
1167 kfree(data); 1172 kfree(data);
1168 1173
1169 return 0; 1174 return 0;