diff options
| author | Daniel Ritz <daniel.ritz-ml@swissonline.ch> | 2006-06-27 12:40:54 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-27 21:36:39 -0400 |
| commit | d6fcb3b9cf776e3f748709cd3091a72cb3855c29 (patch) | |
| tree | 1b60436804d31c9500662e3b84f4b33a0d9dac6d | |
| parent | f17a2686b11453680e9662ef8bdc8d948d0dce18 (diff) | |
[PATCH] i2c-i801.c: don't pci_disable_device() after it was just enabled
Commit 02dd7ae2892e5ceff111d032769c78d3377df970 ("[PATCH] i2c-i801:
Merge setup function") has a missing return 0 in the _probe() function.
This means the error path is always executed and pci_disable_device() is
called even when the device just got successfully enabled.
Having the SMBus device disabled makes some systems (eg.
Fujitsu-Siemens Lifebook E8010) hang hard during power-off.
Intead of reverting the whole commit this patch fixes it up:
- don't ever call pci_disable_device(), also not in the _remove() function
to avoid hangs
- fix missing pci_release_region() in error path
Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 3e0d04d5a800..8b46ef7d9ff8 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -488,7 +488,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
| 488 | dev_err(&dev->dev, "SMBus base address uninitialized, " | 488 | dev_err(&dev->dev, "SMBus base address uninitialized, " |
| 489 | "upgrade BIOS\n"); | 489 | "upgrade BIOS\n"); |
| 490 | err = -ENODEV; | 490 | err = -ENODEV; |
| 491 | goto exit_disable; | 491 | goto exit; |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | err = pci_request_region(dev, SMBBAR, i801_driver.name); | 494 | err = pci_request_region(dev, SMBBAR, i801_driver.name); |
| @@ -496,7 +496,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
| 496 | dev_err(&dev->dev, "Failed to request SMBus region " | 496 | dev_err(&dev->dev, "Failed to request SMBus region " |
| 497 | "0x%lx-0x%lx\n", i801_smba, | 497 | "0x%lx-0x%lx\n", i801_smba, |
| 498 | pci_resource_end(dev, SMBBAR)); | 498 | pci_resource_end(dev, SMBBAR)); |
| 499 | goto exit_disable; | 499 | goto exit; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); | 502 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); |
| @@ -520,11 +520,12 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
| 520 | err = i2c_add_adapter(&i801_adapter); | 520 | err = i2c_add_adapter(&i801_adapter); |
| 521 | if (err) { | 521 | if (err) { |
| 522 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); | 522 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); |
| 523 | goto exit_disable; | 523 | goto exit_release; |
| 524 | } | 524 | } |
| 525 | return 0; | ||
| 525 | 526 | ||
| 526 | exit_disable: | 527 | exit_release: |
| 527 | pci_disable_device(dev); | 528 | pci_release_region(dev, SMBBAR); |
| 528 | exit: | 529 | exit: |
| 529 | return err; | 530 | return err; |
| 530 | } | 531 | } |
| @@ -533,7 +534,10 @@ static void __devexit i801_remove(struct pci_dev *dev) | |||
| 533 | { | 534 | { |
| 534 | i2c_del_adapter(&i801_adapter); | 535 | i2c_del_adapter(&i801_adapter); |
| 535 | pci_release_region(dev, SMBBAR); | 536 | pci_release_region(dev, SMBBAR); |
| 536 | pci_disable_device(dev); | 537 | /* |
| 538 | * do not call pci_disable_device(dev) since it can cause hard hangs on | ||
| 539 | * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) | ||
| 540 | */ | ||
| 537 | } | 541 | } |
| 538 | 542 | ||
| 539 | static struct pci_driver i801_driver = { | 543 | static struct pci_driver i801_driver = { |
