diff options
Diffstat (limited to 'drivers/watchdog/iTCO_wdt.c')
| -rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 648250b998c4..6a51edde6ea7 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
| @@ -236,19 +236,19 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | |||
| 236 | 236 | ||
| 237 | /* Address definitions for the TCO */ | 237 | /* Address definitions for the TCO */ |
| 238 | /* TCO base address */ | 238 | /* TCO base address */ |
| 239 | #define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 | 239 | #define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60) |
| 240 | /* SMI Control and Enable Register */ | 240 | /* SMI Control and Enable Register */ |
| 241 | #define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 | 241 | #define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30) |
| 242 | 242 | ||
| 243 | #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ | 243 | #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ |
| 244 | #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ | 244 | #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ |
| 245 | #define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ | 245 | #define TCO_DAT_IN (TCOBASE + 0x02) /* TCO Data In Register */ |
| 246 | #define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ | 246 | #define TCO_DAT_OUT (TCOBASE + 0x03) /* TCO Data Out Register */ |
| 247 | #define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ | 247 | #define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */ |
| 248 | #define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ | 248 | #define TCO2_STS (TCOBASE + 0x06) /* TCO2 Status Register */ |
| 249 | #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ | 249 | #define TCO1_CNT (TCOBASE + 0x08) /* TCO1 Control Register */ |
| 250 | #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ | 250 | #define TCO2_CNT (TCOBASE + 0x0a) /* TCO2 Control Register */ |
| 251 | #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ | 251 | #define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */ |
| 252 | 252 | ||
| 253 | /* internal variables */ | 253 | /* internal variables */ |
| 254 | static unsigned long is_active; | 254 | static unsigned long is_active; |
| @@ -666,6 +666,11 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 666 | GCS = RCBA + ICH6_GCS(0x3410). */ | 666 | GCS = RCBA + ICH6_GCS(0x3410). */ |
| 667 | if (iTCO_wdt_private.iTCO_version == 2) { | 667 | if (iTCO_wdt_private.iTCO_version == 2) { |
| 668 | pci_read_config_dword(pdev, 0xf0, &base_address); | 668 | pci_read_config_dword(pdev, 0xf0, &base_address); |
| 669 | if ((base_address & 1) == 0) { | ||
| 670 | printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); | ||
| 671 | ret = -ENODEV; | ||
| 672 | goto out; | ||
| 673 | } | ||
| 669 | RCBA = base_address & 0xffffc000; | 674 | RCBA = base_address & 0xffffc000; |
| 670 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); | 675 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); |
| 671 | } | 676 | } |
| @@ -675,7 +680,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 675 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " | 680 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " |
| 676 | "reboot disabled by hardware\n"); | 681 | "reboot disabled by hardware\n"); |
| 677 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ | 682 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ |
| 678 | goto out; | 683 | goto out_unmap; |
| 679 | } | 684 | } |
| 680 | 685 | ||
| 681 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | 686 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ |
| @@ -686,7 +691,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
| 686 | printk(KERN_ERR PFX | 691 | printk(KERN_ERR PFX |
| 687 | "I/O address 0x%04lx already in use\n", SMI_EN); | 692 | "I/O address 0x%04lx already in use\n", SMI_EN); |
| 688 | ret = -EIO; | 693 | ret = -EIO; |
| 689 | goto out; | 694 | goto out_unmap; |
| 690 | } | 695 | } |
| 691 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ | 696 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ |
| 692 | val32 = inl(SMI_EN); | 697 | val32 = inl(SMI_EN); |
| @@ -742,9 +747,10 @@ unreg_region: | |||
| 742 | release_region(TCOBASE, 0x20); | 747 | release_region(TCOBASE, 0x20); |
| 743 | unreg_smi_en: | 748 | unreg_smi_en: |
| 744 | release_region(SMI_EN, 4); | 749 | release_region(SMI_EN, 4); |
| 745 | out: | 750 | out_unmap: |
| 746 | if (iTCO_wdt_private.iTCO_version == 2) | 751 | if (iTCO_wdt_private.iTCO_version == 2) |
| 747 | iounmap(iTCO_wdt_private.gcs); | 752 | iounmap(iTCO_wdt_private.gcs); |
| 753 | out: | ||
| 748 | pci_dev_put(iTCO_wdt_private.pdev); | 754 | pci_dev_put(iTCO_wdt_private.pdev); |
| 749 | iTCO_wdt_private.ACPIBASE = 0; | 755 | iTCO_wdt_private.ACPIBASE = 0; |
| 750 | return ret; | 756 | return ret; |
