diff options
Diffstat (limited to 'drivers/watchdog/iTCO_wdt.c')
-rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 143 |
1 files changed, 128 insertions, 15 deletions
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 69de8713b8e4..5fd020da7c55 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * intel TCO Watchdog Driver | 2 | * intel TCO Watchdog Driver |
3 | * | 3 | * |
4 | * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. | 4 | * (c) Copyright 2006-2010 Wim Van Sebroeck <wim@iguana.be>. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
@@ -26,12 +26,16 @@ | |||
26 | * document number 301473-002, 301474-026: 82801F (ICH6) | 26 | * document number 301473-002, 301474-026: 82801F (ICH6) |
27 | * document number 313082-001, 313075-006: 631xESB, 632xESB | 27 | * document number 313082-001, 313075-006: 631xESB, 632xESB |
28 | * document number 307013-003, 307014-024: 82801G (ICH7) | 28 | * document number 307013-003, 307014-024: 82801G (ICH7) |
29 | * document number 322896-001, 322897-001: NM10 | ||
29 | * document number 313056-003, 313057-017: 82801H (ICH8) | 30 | * document number 313056-003, 313057-017: 82801H (ICH8) |
30 | * document number 316972-004, 316973-012: 82801I (ICH9) | 31 | * document number 316972-004, 316973-012: 82801I (ICH9) |
31 | * document number 319973-002, 319974-002: 82801J (ICH10) | 32 | * document number 319973-002, 319974-002: 82801J (ICH10) |
32 | * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) | 33 | * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) |
33 | * document number 320066-003, 320257-008: EP80597 (IICH) | 34 | * document number 320066-003, 320257-008: EP80597 (IICH) |
34 | * document number TBD : Cougar Point (CPT) | 35 | * document number 324645-001, 324646-001: Cougar Point (CPT) |
36 | * document number TBD : Patsburg (PBG) | ||
37 | * document number TBD : DH89xxCC | ||
38 | * document number TBD : Panther Point | ||
35 | */ | 39 | */ |
36 | 40 | ||
37 | /* | 41 | /* |
@@ -84,6 +88,7 @@ enum iTCO_chipsets { | |||
84 | TCO_ICH7DH, /* ICH7DH */ | 88 | TCO_ICH7DH, /* ICH7DH */ |
85 | TCO_ICH7M, /* ICH7-M & ICH7-U */ | 89 | TCO_ICH7M, /* ICH7-M & ICH7-U */ |
86 | TCO_ICH7MDH, /* ICH7-M DH */ | 90 | TCO_ICH7MDH, /* ICH7-M DH */ |
91 | TCO_NM10, /* NM10 */ | ||
87 | TCO_ICH8, /* ICH8 & ICH8R */ | 92 | TCO_ICH8, /* ICH8 & ICH8R */ |
88 | TCO_ICH8DH, /* ICH8DH */ | 93 | TCO_ICH8DH, /* ICH8DH */ |
89 | TCO_ICH8DO, /* ICH8DO */ | 94 | TCO_ICH8DO, /* ICH8DO */ |
@@ -146,6 +151,41 @@ enum iTCO_chipsets { | |||
146 | TCO_CPT29, /* Cougar Point */ | 151 | TCO_CPT29, /* Cougar Point */ |
147 | TCO_CPT30, /* Cougar Point */ | 152 | TCO_CPT30, /* Cougar Point */ |
148 | TCO_CPT31, /* Cougar Point */ | 153 | TCO_CPT31, /* Cougar Point */ |
154 | TCO_PBG1, /* Patsburg */ | ||
155 | TCO_PBG2, /* Patsburg */ | ||
156 | TCO_DH89XXCC, /* DH89xxCC */ | ||
157 | TCO_PPT0, /* Panther Point */ | ||
158 | TCO_PPT1, /* Panther Point */ | ||
159 | TCO_PPT2, /* Panther Point */ | ||
160 | TCO_PPT3, /* Panther Point */ | ||
161 | TCO_PPT4, /* Panther Point */ | ||
162 | TCO_PPT5, /* Panther Point */ | ||
163 | TCO_PPT6, /* Panther Point */ | ||
164 | TCO_PPT7, /* Panther Point */ | ||
165 | TCO_PPT8, /* Panther Point */ | ||
166 | TCO_PPT9, /* Panther Point */ | ||
167 | TCO_PPT10, /* Panther Point */ | ||
168 | TCO_PPT11, /* Panther Point */ | ||
169 | TCO_PPT12, /* Panther Point */ | ||
170 | TCO_PPT13, /* Panther Point */ | ||
171 | TCO_PPT14, /* Panther Point */ | ||
172 | TCO_PPT15, /* Panther Point */ | ||
173 | TCO_PPT16, /* Panther Point */ | ||
174 | TCO_PPT17, /* Panther Point */ | ||
175 | TCO_PPT18, /* Panther Point */ | ||
176 | TCO_PPT19, /* Panther Point */ | ||
177 | TCO_PPT20, /* Panther Point */ | ||
178 | TCO_PPT21, /* Panther Point */ | ||
179 | TCO_PPT22, /* Panther Point */ | ||
180 | TCO_PPT23, /* Panther Point */ | ||
181 | TCO_PPT24, /* Panther Point */ | ||
182 | TCO_PPT25, /* Panther Point */ | ||
183 | TCO_PPT26, /* Panther Point */ | ||
184 | TCO_PPT27, /* Panther Point */ | ||
185 | TCO_PPT28, /* Panther Point */ | ||
186 | TCO_PPT29, /* Panther Point */ | ||
187 | TCO_PPT30, /* Panther Point */ | ||
188 | TCO_PPT31, /* Panther Point */ | ||
149 | }; | 189 | }; |
150 | 190 | ||
151 | static struct { | 191 | static struct { |
@@ -171,6 +211,7 @@ static struct { | |||
171 | {"ICH7DH", 2}, | 211 | {"ICH7DH", 2}, |
172 | {"ICH7-M or ICH7-U", 2}, | 212 | {"ICH7-M or ICH7-U", 2}, |
173 | {"ICH7-M DH", 2}, | 213 | {"ICH7-M DH", 2}, |
214 | {"NM10", 2}, | ||
174 | {"ICH8 or ICH8R", 2}, | 215 | {"ICH8 or ICH8R", 2}, |
175 | {"ICH8DH", 2}, | 216 | {"ICH8DH", 2}, |
176 | {"ICH8DO", 2}, | 217 | {"ICH8DO", 2}, |
@@ -233,10 +274,45 @@ static struct { | |||
233 | {"Cougar Point", 2}, | 274 | {"Cougar Point", 2}, |
234 | {"Cougar Point", 2}, | 275 | {"Cougar Point", 2}, |
235 | {"Cougar Point", 2}, | 276 | {"Cougar Point", 2}, |
277 | {"Patsburg", 2}, | ||
278 | {"Patsburg", 2}, | ||
279 | {"DH89xxCC", 2}, | ||
280 | {"Panther Point", 2}, | ||
281 | {"Panther Point", 2}, | ||
282 | {"Panther Point", 2}, | ||
283 | {"Panther Point", 2}, | ||
284 | {"Panther Point", 2}, | ||
285 | {"Panther Point", 2}, | ||
286 | {"Panther Point", 2}, | ||
287 | {"Panther Point", 2}, | ||
288 | {"Panther Point", 2}, | ||
289 | {"Panther Point", 2}, | ||
290 | {"Panther Point", 2}, | ||
291 | {"Panther Point", 2}, | ||
292 | {"Panther Point", 2}, | ||
293 | {"Panther Point", 2}, | ||
294 | {"Panther Point", 2}, | ||
295 | {"Panther Point", 2}, | ||
296 | {"Panther Point", 2}, | ||
297 | {"Panther Point", 2}, | ||
298 | {"Panther Point", 2}, | ||
299 | {"Panther Point", 2}, | ||
300 | {"Panther Point", 2}, | ||
301 | {"Panther Point", 2}, | ||
302 | {"Panther Point", 2}, | ||
303 | {"Panther Point", 2}, | ||
304 | {"Panther Point", 2}, | ||
305 | {"Panther Point", 2}, | ||
306 | {"Panther Point", 2}, | ||
307 | {"Panther Point", 2}, | ||
308 | {"Panther Point", 2}, | ||
309 | {"Panther Point", 2}, | ||
310 | {"Panther Point", 2}, | ||
311 | {"Panther Point", 2}, | ||
236 | {NULL, 0} | 312 | {NULL, 0} |
237 | }; | 313 | }; |
238 | 314 | ||
239 | #define ITCO_PCI_DEVICE(dev, data) \ | 315 | #define ITCO_PCI_DEVICE(dev, data) \ |
240 | .vendor = PCI_VENDOR_ID_INTEL, \ | 316 | .vendor = PCI_VENDOR_ID_INTEL, \ |
241 | .device = dev, \ | 317 | .device = dev, \ |
242 | .subvendor = PCI_ANY_ID, \ | 318 | .subvendor = PCI_ANY_ID, \ |
@@ -251,7 +327,7 @@ static struct { | |||
251 | * pci_driver, because the I/O Controller Hub has also other | 327 | * pci_driver, because the I/O Controller Hub has also other |
252 | * functions that probably will be registered by other drivers. | 328 | * functions that probably will be registered by other drivers. |
253 | */ | 329 | */ |
254 | static struct pci_device_id iTCO_wdt_pci_tbl[] = { | 330 | static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { |
255 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)}, | 331 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)}, |
256 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)}, | 332 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)}, |
257 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)}, | 333 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)}, |
@@ -286,6 +362,7 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
286 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_30, TCO_ICH7DH)}, | 362 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_30, TCO_ICH7DH)}, |
287 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, | 363 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)}, |
288 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, | 364 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, |
365 | { ITCO_PCI_DEVICE(0x27bc, TCO_NM10)}, | ||
289 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, | 366 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)}, |
290 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, | 367 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)}, |
291 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, | 368 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)}, |
@@ -348,6 +425,41 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
348 | { ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)}, | 425 | { ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)}, |
349 | { ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)}, | 426 | { ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)}, |
350 | { ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)}, | 427 | { ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)}, |
428 | { ITCO_PCI_DEVICE(0x1d40, TCO_PBG1)}, | ||
429 | { ITCO_PCI_DEVICE(0x1d41, TCO_PBG2)}, | ||
430 | { ITCO_PCI_DEVICE(0x2310, TCO_DH89XXCC)}, | ||
431 | { ITCO_PCI_DEVICE(0x1e40, TCO_PPT0)}, | ||
432 | { ITCO_PCI_DEVICE(0x1e41, TCO_PPT1)}, | ||
433 | { ITCO_PCI_DEVICE(0x1e42, TCO_PPT2)}, | ||
434 | { ITCO_PCI_DEVICE(0x1e43, TCO_PPT3)}, | ||
435 | { ITCO_PCI_DEVICE(0x1e44, TCO_PPT4)}, | ||
436 | { ITCO_PCI_DEVICE(0x1e45, TCO_PPT5)}, | ||
437 | { ITCO_PCI_DEVICE(0x1e46, TCO_PPT6)}, | ||
438 | { ITCO_PCI_DEVICE(0x1e47, TCO_PPT7)}, | ||
439 | { ITCO_PCI_DEVICE(0x1e48, TCO_PPT8)}, | ||
440 | { ITCO_PCI_DEVICE(0x1e49, TCO_PPT9)}, | ||
441 | { ITCO_PCI_DEVICE(0x1e4a, TCO_PPT10)}, | ||
442 | { ITCO_PCI_DEVICE(0x1e4b, TCO_PPT11)}, | ||
443 | { ITCO_PCI_DEVICE(0x1e4c, TCO_PPT12)}, | ||
444 | { ITCO_PCI_DEVICE(0x1e4d, TCO_PPT13)}, | ||
445 | { ITCO_PCI_DEVICE(0x1e4e, TCO_PPT14)}, | ||
446 | { ITCO_PCI_DEVICE(0x1e4f, TCO_PPT15)}, | ||
447 | { ITCO_PCI_DEVICE(0x1e50, TCO_PPT16)}, | ||
448 | { ITCO_PCI_DEVICE(0x1e51, TCO_PPT17)}, | ||
449 | { ITCO_PCI_DEVICE(0x1e52, TCO_PPT18)}, | ||
450 | { ITCO_PCI_DEVICE(0x1e53, TCO_PPT19)}, | ||
451 | { ITCO_PCI_DEVICE(0x1e54, TCO_PPT20)}, | ||
452 | { ITCO_PCI_DEVICE(0x1e55, TCO_PPT21)}, | ||
453 | { ITCO_PCI_DEVICE(0x1e56, TCO_PPT22)}, | ||
454 | { ITCO_PCI_DEVICE(0x1e57, TCO_PPT23)}, | ||
455 | { ITCO_PCI_DEVICE(0x1e58, TCO_PPT24)}, | ||
456 | { ITCO_PCI_DEVICE(0x1e59, TCO_PPT25)}, | ||
457 | { ITCO_PCI_DEVICE(0x1e5a, TCO_PPT26)}, | ||
458 | { ITCO_PCI_DEVICE(0x1e5b, TCO_PPT27)}, | ||
459 | { ITCO_PCI_DEVICE(0x1e5c, TCO_PPT28)}, | ||
460 | { ITCO_PCI_DEVICE(0x1e5d, TCO_PPT29)}, | ||
461 | { ITCO_PCI_DEVICE(0x1e5e, TCO_PPT30)}, | ||
462 | { ITCO_PCI_DEVICE(0x1e5f, TCO_PPT31)}, | ||
351 | { 0, }, /* End of list */ | 463 | { 0, }, /* End of list */ |
352 | }; | 464 | }; |
353 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 465 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
@@ -374,7 +486,7 @@ static char expect_release; | |||
374 | static struct { /* this is private data for the iTCO_wdt device */ | 486 | static struct { /* this is private data for the iTCO_wdt device */ |
375 | /* TCO version/generation */ | 487 | /* TCO version/generation */ |
376 | unsigned int iTCO_version; | 488 | unsigned int iTCO_version; |
377 | /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ | 489 | /* The device's ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ |
378 | unsigned long ACPIBASE; | 490 | unsigned long ACPIBASE; |
379 | /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ | 491 | /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ |
380 | unsigned long __iomem *gcs; | 492 | unsigned long __iomem *gcs; |
@@ -467,7 +579,7 @@ static int iTCO_wdt_start(void) | |||
467 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { | 579 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { |
468 | spin_unlock(&iTCO_wdt_private.io_lock); | 580 | spin_unlock(&iTCO_wdt_private.io_lock); |
469 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " | 581 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " |
470 | "reboot disabled by hardware\n"); | 582 | "reboot disabled by hardware/BIOS\n"); |
471 | return -EIO; | 583 | return -EIO; |
472 | } | 584 | } |
473 | 585 | ||
@@ -781,8 +893,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
781 | base_address &= 0x0000ff80; | 893 | base_address &= 0x0000ff80; |
782 | if (base_address == 0x00000000) { | 894 | if (base_address == 0x00000000) { |
783 | /* Something's wrong here, ACPIBASE has to be set */ | 895 | /* Something's wrong here, ACPIBASE has to be set */ |
784 | printk(KERN_ERR PFX "failed to get TCOBASE address\n"); | 896 | printk(KERN_ERR PFX "failed to get TCOBASE address, " |
785 | pci_dev_put(pdev); | 897 | "device disabled by hardware/BIOS\n"); |
786 | return -ENODEV; | 898 | return -ENODEV; |
787 | } | 899 | } |
788 | iTCO_wdt_private.iTCO_version = | 900 | iTCO_wdt_private.iTCO_version = |
@@ -797,7 +909,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
797 | if (iTCO_wdt_private.iTCO_version == 2) { | 909 | if (iTCO_wdt_private.iTCO_version == 2) { |
798 | pci_read_config_dword(pdev, 0xf0, &base_address); | 910 | pci_read_config_dword(pdev, 0xf0, &base_address); |
799 | if ((base_address & 1) == 0) { | 911 | if ((base_address & 1) == 0) { |
800 | printk(KERN_ERR PFX "RCBA is disabled by hardware\n"); | 912 | printk(KERN_ERR PFX "RCBA is disabled by hardware" |
913 | "/BIOS, device disabled\n"); | ||
801 | ret = -ENODEV; | 914 | ret = -ENODEV; |
802 | goto out; | 915 | goto out; |
803 | } | 916 | } |
@@ -808,7 +921,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
808 | /* Check chipset's NO_REBOOT bit */ | 921 | /* Check chipset's NO_REBOOT bit */ |
809 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { | 922 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { |
810 | printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, " | 923 | printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, " |
811 | "platform may have disabled it\n"); | 924 | "device disabled by hardware/BIOS\n"); |
812 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ | 925 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ |
813 | goto out_unmap; | 926 | goto out_unmap; |
814 | } | 927 | } |
@@ -819,7 +932,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
819 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ | 932 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ |
820 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { | 933 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { |
821 | printk(KERN_ERR PFX | 934 | printk(KERN_ERR PFX |
822 | "I/O address 0x%04lx already in use\n", SMI_EN); | 935 | "I/O address 0x%04lx already in use, " |
936 | "device disabled\n", SMI_EN); | ||
823 | ret = -EIO; | 937 | ret = -EIO; |
824 | goto out_unmap; | 938 | goto out_unmap; |
825 | } | 939 | } |
@@ -831,8 +945,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
831 | /* The TCO I/O registers reside in a 32-byte range pointed to | 945 | /* The TCO I/O registers reside in a 32-byte range pointed to |
832 | by the TCOBASE value */ | 946 | by the TCOBASE value */ |
833 | if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { | 947 | if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { |
834 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", | 948 | printk(KERN_ERR PFX "I/O address 0x%04lx already in use " |
835 | TCOBASE); | 949 | "device disabled\n", TCOBASE); |
836 | ret = -EIO; | 950 | ret = -EIO; |
837 | goto unreg_smi_en; | 951 | goto unreg_smi_en; |
838 | } | 952 | } |
@@ -880,7 +994,6 @@ out_unmap: | |||
880 | if (iTCO_wdt_private.iTCO_version == 2) | 994 | if (iTCO_wdt_private.iTCO_version == 2) |
881 | iounmap(iTCO_wdt_private.gcs); | 995 | iounmap(iTCO_wdt_private.gcs); |
882 | out: | 996 | out: |
883 | pci_dev_put(iTCO_wdt_private.pdev); | ||
884 | iTCO_wdt_private.ACPIBASE = 0; | 997 | iTCO_wdt_private.ACPIBASE = 0; |
885 | return ret; | 998 | return ret; |
886 | } | 999 | } |
@@ -921,7 +1034,7 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev) | |||
921 | } | 1034 | } |
922 | 1035 | ||
923 | if (!found) | 1036 | if (!found) |
924 | printk(KERN_INFO PFX "No card detected\n"); | 1037 | printk(KERN_INFO PFX "No device detected.\n"); |
925 | 1038 | ||
926 | return ret; | 1039 | return ret; |
927 | } | 1040 | } |