diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tpm/Kconfig | 11 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 146 | ||||
-rw-r--r-- | drivers/char/watchdog/i8xx_tco.c | 41 |
3 files changed, 141 insertions, 57 deletions
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 94a3b3e20bf9..79e9832ef1f3 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -17,6 +17,8 @@ config TCG_TPM | |||
17 | obtained at: <http://sourceforge.net/projects/trousers>. To | 17 | obtained at: <http://sourceforge.net/projects/trousers>. To |
18 | compile this driver as a module, choose M here; the module | 18 | compile this driver as a module, choose M here; the module |
19 | will be called tpm. If unsure, say N. | 19 | will be called tpm. If unsure, say N. |
20 | Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI_BUS | ||
21 | and CONFIG_PNPACPI. | ||
20 | 22 | ||
21 | config TCG_NSC | 23 | config TCG_NSC |
22 | tristate "National Semiconductor TPM Interface" | 24 | tristate "National Semiconductor TPM Interface" |
@@ -36,12 +38,13 @@ config TCG_ATMEL | |||
36 | as a module, choose M here; the module will be called tpm_atmel. | 38 | as a module, choose M here; the module will be called tpm_atmel. |
37 | 39 | ||
38 | config TCG_INFINEON | 40 | config TCG_INFINEON |
39 | tristate "Infineon Technologies SLD 9630 TPM Interface" | 41 | tristate "Infineon Technologies TPM Interface" |
40 | depends on TCG_TPM | 42 | depends on TCG_TPM && PNPACPI |
41 | ---help--- | 43 | ---help--- |
42 | If you have a TPM security chip from Infineon Technologies | 44 | If you have a TPM security chip from Infineon Technologies |
43 | say Yes and it will be accessible from within Linux. To | 45 | (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it |
44 | compile this driver as a module, choose M here; the module | 46 | will be accessible from within Linux. |
47 | To compile this driver as a module, choose M here; the module | ||
45 | will be called tpm_infineon. | 48 | will be called tpm_infineon. |
46 | Further information on this driver and the supported hardware | 49 | Further information on this driver and the supported hardware |
47 | can be found at http://www.prosec.rub.de/tpm | 50 | can be found at http://www.prosec.rub.de/tpm |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 0e3241645c19..dc8c540391fd 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Description: | 2 | * Description: |
3 | * Device Driver for the Infineon Technologies | 3 | * Device Driver for the Infineon Technologies |
4 | * SLD 9630 TT Trusted Platform Module | 4 | * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module |
5 | * Specifications at www.trustedcomputinggroup.org | 5 | * Specifications at www.trustedcomputinggroup.org |
6 | * | 6 | * |
7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> | 7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> |
@@ -12,9 +12,10 @@ | |||
12 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
13 | * published by the Free Software Foundation, version 2 of the | 13 | * published by the Free Software Foundation, version 2 of the |
14 | * License. | 14 | * License. |
15 | * | ||
16 | */ | 15 | */ |
17 | 16 | ||
17 | #include <acpi/acpi_bus.h> | ||
18 | #include <linux/pnp.h> | ||
18 | #include "tpm.h" | 19 | #include "tpm.h" |
19 | 20 | ||
20 | /* Infineon specific definitions */ | 21 | /* Infineon specific definitions */ |
@@ -26,8 +27,11 @@ | |||
26 | #define TPM_MSLEEP_TIME 3 | 27 | #define TPM_MSLEEP_TIME 3 |
27 | /* gives number of max. msleep()-calls before throwing timeout */ | 28 | /* gives number of max. msleep()-calls before throwing timeout */ |
28 | #define TPM_MAX_TRIES 5000 | 29 | #define TPM_MAX_TRIES 5000 |
29 | #define TCPA_INFINEON_DEV_VEN_VALUE 0x15D1 | 30 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
30 | #define TPM_DATA (TPM_ADDR + 1) & 0xff | 31 | |
32 | /* These values will be filled after ACPI-call */ | ||
33 | static int TPM_INF_DATA = 0; | ||
34 | static int TPM_INF_ADDR = 0; | ||
31 | 35 | ||
32 | /* TPM header definitions */ | 36 | /* TPM header definitions */ |
33 | enum infineon_tpm_header { | 37 | enum infineon_tpm_header { |
@@ -305,9 +309,10 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
305 | 309 | ||
306 | static void tpm_inf_cancel(struct tpm_chip *chip) | 310 | static void tpm_inf_cancel(struct tpm_chip *chip) |
307 | { | 311 | { |
308 | /* Nothing yet! | 312 | /* |
309 | This has something to do with the internal functions | 313 | Since we are using the legacy mode to communicate |
310 | of the TPM. Abort isn't really necessary... | 314 | with the TPM, we have no cancel functions, but have |
315 | a workaround for interrupting the TPM through WTX. | ||
311 | */ | 316 | */ |
312 | } | 317 | } |
313 | 318 | ||
@@ -345,6 +350,32 @@ static struct tpm_vendor_specific tpm_inf = { | |||
345 | .miscdev = {.fops = &inf_ops,}, | 350 | .miscdev = {.fops = &inf_ops,}, |
346 | }; | 351 | }; |
347 | 352 | ||
353 | static const struct pnp_device_id tpm_pnp_tbl[] = { | ||
354 | /* Infineon TPMs */ | ||
355 | {"IFX0101", 0}, | ||
356 | {"IFX0102", 0}, | ||
357 | {"", 0} | ||
358 | }; | ||
359 | |||
360 | static int __devinit tpm_inf_acpi_probe(struct pnp_dev *dev, | ||
361 | const struct pnp_device_id *dev_id) | ||
362 | { | ||
363 | TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff); | ||
364 | TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff); | ||
365 | tpm_inf.base = pnp_port_start(dev, 1); | ||
366 | dev_info(&dev->dev, "Found %s with ID %s\n", | ||
367 | dev->name, dev_id->id); | ||
368 | if (!((tpm_inf.base >> 8) & 0xff)) | ||
369 | tpm_inf.base = 0; | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static struct pnp_driver tpm_inf_pnp = { | ||
374 | .name = "tpm_inf_pnp", | ||
375 | .id_table = tpm_pnp_tbl, | ||
376 | .probe = tpm_inf_acpi_probe, | ||
377 | }; | ||
378 | |||
348 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | 379 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, |
349 | const struct pci_device_id *pci_id) | 380 | const struct pci_device_id *pci_id) |
350 | { | 381 | { |
@@ -353,64 +384,99 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
353 | int vendorid[2]; | 384 | int vendorid[2]; |
354 | int version[2]; | 385 | int version[2]; |
355 | int productid[2]; | 386 | int productid[2]; |
387 | char chipname[20]; | ||
356 | 388 | ||
357 | if (pci_enable_device(pci_dev)) | 389 | if (pci_enable_device(pci_dev)) |
358 | return -EIO; | 390 | return -EIO; |
359 | 391 | ||
360 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); | 392 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); |
361 | 393 | ||
394 | /* read IO-ports from ACPI */ | ||
395 | pnp_register_driver(&tpm_inf_pnp); | ||
396 | pnp_unregister_driver(&tpm_inf_pnp); | ||
397 | |||
398 | /* Make sure, we have received valid config ports */ | ||
399 | if (!TPM_INF_ADDR) { | ||
400 | pci_disable_device(pci_dev); | ||
401 | return -EIO; | ||
402 | } | ||
403 | |||
362 | /* query chip for its vendor, its version number a.s.o. */ | 404 | /* query chip for its vendor, its version number a.s.o. */ |
363 | outb(ENABLE_REGISTER_PAIR, TPM_ADDR); | 405 | outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); |
364 | outb(IDVENL, TPM_ADDR); | 406 | outb(IDVENL, TPM_INF_ADDR); |
365 | vendorid[1] = inb(TPM_DATA); | 407 | vendorid[1] = inb(TPM_INF_DATA); |
366 | outb(IDVENH, TPM_ADDR); | 408 | outb(IDVENH, TPM_INF_ADDR); |
367 | vendorid[0] = inb(TPM_DATA); | 409 | vendorid[0] = inb(TPM_INF_DATA); |
368 | outb(IDPDL, TPM_ADDR); | 410 | outb(IDPDL, TPM_INF_ADDR); |
369 | productid[1] = inb(TPM_DATA); | 411 | productid[1] = inb(TPM_INF_DATA); |
370 | outb(IDPDH, TPM_ADDR); | 412 | outb(IDPDH, TPM_INF_ADDR); |
371 | productid[0] = inb(TPM_DATA); | 413 | productid[0] = inb(TPM_INF_DATA); |
372 | outb(CHIP_ID1, TPM_ADDR); | 414 | outb(CHIP_ID1, TPM_INF_ADDR); |
373 | version[1] = inb(TPM_DATA); | 415 | version[1] = inb(TPM_INF_DATA); |
374 | outb(CHIP_ID2, TPM_ADDR); | 416 | outb(CHIP_ID2, TPM_INF_ADDR); |
375 | version[0] = inb(TPM_DATA); | 417 | version[0] = inb(TPM_INF_DATA); |
376 | 418 | ||
377 | if ((vendorid[0] << 8 | vendorid[1]) == (TCPA_INFINEON_DEV_VEN_VALUE)) { | 419 | switch ((productid[0] << 8) | productid[1]) { |
378 | 420 | case 6: | |
379 | /* read IO-ports from TPM */ | 421 | sprintf(chipname, " (SLD 9630 TT 1.1)"); |
380 | outb(IOLIMH, TPM_ADDR); | 422 | break; |
381 | ioh = inb(TPM_DATA); | 423 | case 11: |
382 | outb(IOLIML, TPM_ADDR); | 424 | sprintf(chipname, " (SLB 9635 TT 1.2)"); |
383 | iol = inb(TPM_DATA); | 425 | break; |
384 | tpm_inf.base = (ioh << 8) | iol; | 426 | default: |
427 | sprintf(chipname, " (unknown chip)"); | ||
428 | break; | ||
429 | } | ||
430 | chipname[19] = 0; | ||
431 | |||
432 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | ||
385 | 433 | ||
386 | if (tpm_inf.base == 0) { | 434 | if (tpm_inf.base == 0) { |
387 | dev_err(&pci_dev->dev, "No IO-ports set!\n"); | 435 | dev_err(&pci_dev->dev, "No IO-ports found!\n"); |
388 | pci_disable_device(pci_dev); | 436 | pci_disable_device(pci_dev); |
389 | return -ENODEV; | 437 | return -EIO; |
438 | } | ||
439 | /* configure TPM with IO-ports */ | ||
440 | outb(IOLIMH, TPM_INF_ADDR); | ||
441 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); | ||
442 | outb(IOLIML, TPM_INF_ADDR); | ||
443 | outb((tpm_inf.base & 0xff), TPM_INF_DATA); | ||
444 | |||
445 | /* control if IO-ports are set correctly */ | ||
446 | outb(IOLIMH, TPM_INF_ADDR); | ||
447 | ioh = inb(TPM_INF_DATA); | ||
448 | outb(IOLIML, TPM_INF_ADDR); | ||
449 | iol = inb(TPM_INF_DATA); | ||
450 | |||
451 | if ((ioh << 8 | iol) != tpm_inf.base) { | ||
452 | dev_err(&pci_dev->dev, | ||
453 | "Could not set IO-ports to %04x\n", | ||
454 | tpm_inf.base); | ||
455 | pci_disable_device(pci_dev); | ||
456 | return -EIO; | ||
390 | } | 457 | } |
391 | 458 | ||
392 | /* activate register */ | 459 | /* activate register */ |
393 | outb(TPM_DAR, TPM_ADDR); | 460 | outb(TPM_DAR, TPM_INF_ADDR); |
394 | outb(0x01, TPM_DATA); | 461 | outb(0x01, TPM_INF_DATA); |
395 | outb(DISABLE_REGISTER_PAIR, TPM_ADDR); | 462 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); |
396 | 463 | ||
397 | /* disable RESET, LP and IRQC */ | 464 | /* disable RESET, LP and IRQC */ |
398 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); | 465 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); |
399 | 466 | ||
400 | /* Finally, we're done, print some infos */ | 467 | /* Finally, we're done, print some infos */ |
401 | dev_info(&pci_dev->dev, "TPM found: " | 468 | dev_info(&pci_dev->dev, "TPM found: " |
469 | "config base 0x%x, " | ||
402 | "io base 0x%x, " | 470 | "io base 0x%x, " |
403 | "chip version %02x%02x, " | 471 | "chip version %02x%02x, " |
404 | "vendor id %x%x (Infineon), " | 472 | "vendor id %x%x (Infineon), " |
405 | "product id %02x%02x" | 473 | "product id %02x%02x" |
406 | "%s\n", | 474 | "%s\n", |
475 | TPM_INF_ADDR, | ||
407 | tpm_inf.base, | 476 | tpm_inf.base, |
408 | version[0], version[1], | 477 | version[0], version[1], |
409 | vendorid[0], vendorid[1], | 478 | vendorid[0], vendorid[1], |
410 | productid[0], productid[1], ((productid[0] == 0) | 479 | productid[0], productid[1], chipname); |
411 | && (productid[1] == | ||
412 | 6)) ? | ||
413 | " (SLD 9630 TT 1.1)" : ""); | ||
414 | 480 | ||
415 | rc = tpm_register_hardware(pci_dev, &tpm_inf); | 481 | rc = tpm_register_hardware(pci_dev, &tpm_inf); |
416 | if (rc < 0) { | 482 | if (rc < 0) { |
@@ -462,6 +528,6 @@ module_init(init_inf); | |||
462 | module_exit(cleanup_inf); | 528 | module_exit(cleanup_inf); |
463 | 529 | ||
464 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 530 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
465 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT"); | 531 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
466 | MODULE_VERSION("1.4"); | 532 | MODULE_VERSION("1.5"); |
467 | MODULE_LICENSE("GPL"); | 533 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index f975dab1ddf9..a13395e2c372 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * i8xx_tco 0.07: TCO timer driver for i8xx chipsets | 2 | * i8xx_tco: TCO timer driver for i8xx chipsets |
3 | * | 3 | * |
4 | * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved. | 4 | * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved. |
5 | * http://www.kernelconcepts.de | 5 | * http://www.kernelconcepts.de |
@@ -63,6 +63,9 @@ | |||
63 | * 20050128 Wim Van Sebroeck <wim@iguana.be> | 63 | * 20050128 Wim Van Sebroeck <wim@iguana.be> |
64 | * 0.07 Added support for the ICH4-M, ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW | 64 | * 0.07 Added support for the ICH4-M, ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW |
65 | * chipsets. Also added support for the "undocumented" ICH7 chipset. | 65 | * chipsets. Also added support for the "undocumented" ICH7 chipset. |
66 | * 20050807 Wim Van Sebroeck <wim@iguana.be> | ||
67 | * 0.08 Make sure that the watchdog is only "armed" when started. | ||
68 | * (Kernel Bug 4251) | ||
66 | */ | 69 | */ |
67 | 70 | ||
68 | /* | 71 | /* |
@@ -87,7 +90,7 @@ | |||
87 | #include "i8xx_tco.h" | 90 | #include "i8xx_tco.h" |
88 | 91 | ||
89 | /* Module and version information */ | 92 | /* Module and version information */ |
90 | #define TCO_VERSION "0.07" | 93 | #define TCO_VERSION "0.08" |
91 | #define TCO_MODULE_NAME "i8xx TCO timer" | 94 | #define TCO_MODULE_NAME "i8xx TCO timer" |
92 | #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION | 95 | #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION |
93 | #define PFX TCO_MODULE_NAME ": " | 96 | #define PFX TCO_MODULE_NAME ": " |
@@ -125,10 +128,18 @@ static int tco_timer_start (void) | |||
125 | unsigned char val; | 128 | unsigned char val; |
126 | 129 | ||
127 | spin_lock(&tco_lock); | 130 | spin_lock(&tco_lock); |
131 | |||
132 | /* disable chipset's NO_REBOOT bit */ | ||
133 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val); | ||
134 | val &= 0xfd; | ||
135 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val); | ||
136 | |||
137 | /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */ | ||
128 | val = inb (TCO1_CNT + 1); | 138 | val = inb (TCO1_CNT + 1); |
129 | val &= 0xf7; | 139 | val &= 0xf7; |
130 | outb (val, TCO1_CNT + 1); | 140 | outb (val, TCO1_CNT + 1); |
131 | val = inb (TCO1_CNT + 1); | 141 | val = inb (TCO1_CNT + 1); |
142 | |||
132 | spin_unlock(&tco_lock); | 143 | spin_unlock(&tco_lock); |
133 | 144 | ||
134 | if (val & 0x08) | 145 | if (val & 0x08) |
@@ -138,13 +149,20 @@ static int tco_timer_start (void) | |||
138 | 149 | ||
139 | static int tco_timer_stop (void) | 150 | static int tco_timer_stop (void) |
140 | { | 151 | { |
141 | unsigned char val; | 152 | unsigned char val, val1; |
142 | 153 | ||
143 | spin_lock(&tco_lock); | 154 | spin_lock(&tco_lock); |
155 | /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ | ||
144 | val = inb (TCO1_CNT + 1); | 156 | val = inb (TCO1_CNT + 1); |
145 | val |= 0x08; | 157 | val |= 0x08; |
146 | outb (val, TCO1_CNT + 1); | 158 | outb (val, TCO1_CNT + 1); |
147 | val = inb (TCO1_CNT + 1); | 159 | val = inb (TCO1_CNT + 1); |
160 | |||
161 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | ||
162 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); | ||
163 | val1 |= 0x02; | ||
164 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val1); | ||
165 | |||
148 | spin_unlock(&tco_lock); | 166 | spin_unlock(&tco_lock); |
149 | 167 | ||
150 | if ((val & 0x08) == 0) | 168 | if ((val & 0x08) == 0) |
@@ -155,6 +173,7 @@ static int tco_timer_stop (void) | |||
155 | static int tco_timer_keepalive (void) | 173 | static int tco_timer_keepalive (void) |
156 | { | 174 | { |
157 | spin_lock(&tco_lock); | 175 | spin_lock(&tco_lock); |
176 | /* Reload the timer by writing to the TCO Timer Reload register */ | ||
158 | outb (0x01, TCO1_RLD); | 177 | outb (0x01, TCO1_RLD); |
159 | spin_unlock(&tco_lock); | 178 | spin_unlock(&tco_lock); |
160 | return 0; | 179 | return 0; |
@@ -417,9 +436,8 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
417 | printk (KERN_ERR PFX "failed to get TCOBASE address\n"); | 436 | printk (KERN_ERR PFX "failed to get TCOBASE address\n"); |
418 | return 0; | 437 | return 0; |
419 | } | 438 | } |
420 | /* | 439 | |
421 | * Check chipset's NO_REBOOT bit | 440 | /* Check chipset's NO_REBOOT bit */ |
422 | */ | ||
423 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); | 441 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); |
424 | if (val1 & 0x02) { | 442 | if (val1 & 0x02) { |
425 | val1 &= 0xfd; | 443 | val1 &= 0xfd; |
@@ -430,6 +448,10 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
430 | return 0; /* Cannot reset NO_REBOOT bit */ | 448 | return 0; /* Cannot reset NO_REBOOT bit */ |
431 | } | 449 | } |
432 | } | 450 | } |
451 | /* Disable reboots untill the watchdog starts */ | ||
452 | val1 |= 0x02; | ||
453 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val1); | ||
454 | |||
433 | /* Set the TCO_EN bit in SMI_EN register */ | 455 | /* Set the TCO_EN bit in SMI_EN register */ |
434 | if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) { | 456 | if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) { |
435 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 457 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", |
@@ -505,17 +527,10 @@ out: | |||
505 | 527 | ||
506 | static void __exit watchdog_cleanup (void) | 528 | static void __exit watchdog_cleanup (void) |
507 | { | 529 | { |
508 | u8 val; | ||
509 | |||
510 | /* Stop the timer before we leave */ | 530 | /* Stop the timer before we leave */ |
511 | if (!nowayout) | 531 | if (!nowayout) |
512 | tco_timer_stop (); | 532 | tco_timer_stop (); |
513 | 533 | ||
514 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | ||
515 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val); | ||
516 | val |= 0x02; | ||
517 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val); | ||
518 | |||
519 | /* Deregister */ | 534 | /* Deregister */ |
520 | misc_deregister (&i8xx_tco_miscdev); | 535 | misc_deregister (&i8xx_tco_miscdev); |
521 | unregister_reboot_notifier(&i8xx_tco_notifier); | 536 | unregister_reboot_notifier(&i8xx_tco_notifier); |