aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-10-17 17:51:15 +0200
committerJean Delvare <khali@mahadeva.delvare>2008-10-17 17:51:15 +0200
commit47c15532ddcd6818f51cb15f914d63864b3ee9ab (patch)
tree65abe5a3fd40d9a4468550c522dd2db30ebeb988 /drivers
parentf908037a01e53a48ff8eb049bb4a1fbb15449908 (diff)
hwmon: (lm78) Fix I/O resource conflict with PNP
Only request I/O ports 0x295-0x296 instead of the full I/O address range. This solves a conflict with PNP resources on a few motherboards. Also request the I/O ports in two parts (4 low ports, 4 high ports) during device detection, otherwise the PNP resource make the request (and thus the detection) fail. This is the exact same fix that was applied to driver w83781d in March 2008 to address the same problem: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2961cb22ef02850d90e7a12c28a14d74e327df8d Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/lm78.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index ed7859f0e16..2c96d8a548f 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -655,7 +655,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
/* Reserve the ISA region */
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!request_region(res->start, LM78_EXTENT, "lm78")) {
+ if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
err = -EBUSY;
goto exit;
}
@@ -699,7 +699,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_name);
kfree(data);
exit_release_region:
- release_region(res->start, LM78_EXTENT);
+ release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
exit:
return err;
}
@@ -711,7 +711,7 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
device_remove_file(&pdev->dev, &dev_attr_name);
- release_region(data->client.addr, LM78_EXTENT);
+ release_region(data->client.addr + LM78_ADDR_REG_OFFSET, 2);
kfree(data);
return 0;
@@ -837,8 +837,17 @@ static int __init lm78_isa_found(unsigned short address)
{
int val, save, found = 0;
- if (!request_region(address, LM78_EXTENT, "lm78"))
+ /* We have to request the region in two parts because some
+ boards declare base+4 to base+7 as a PNP device */
+ if (!request_region(address, 4, "lm78")) {
+ pr_debug("lm78: Failed to request low part of region\n");
return 0;
+ }
+ if (!request_region(address + 4, 4, "lm78")) {
+ pr_debug("lm78: Failed to request high part of region\n");
+ release_region(address, 4);
+ return 0;
+ }
#define REALLY_SLOW_IO
/* We need the timeouts for at least some LM78-like
@@ -901,7 +910,8 @@ static int __init lm78_isa_found(unsigned short address)
val & 0x80 ? "LM79" : "LM78", (int)address);
release:
- release_region(address, LM78_EXTENT);
+ release_region(address + 4, 4);
+ release_region(address, 4);
return found;
}