aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/hvc_vio.c2
-rw-r--r--drivers/char/hvcs.c2
-rw-r--r--drivers/char/mem.c12
-rw-r--r--drivers/char/random.c34
-rw-r--r--drivers/char/rtc.c7
-rw-r--r--drivers/char/tpm/Kconfig11
-rw-r--r--drivers/char/tpm/tpm_infineon.c146
-rw-r--r--drivers/char/viotape.c2
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/char/watchdog/i8xx_tco.c41
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c49
12 files changed, 206 insertions, 110 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 4f27e5519296..7333b41d4224 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
80 80
81config COMPUTONE 81config COMPUTONE
82 tristate "Computone IntelliPort Plus serial support" 82 tristate "Computone IntelliPort Plus serial support"
83 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP 83 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32)
84 ---help--- 84 ---help---
85 This driver supports the entire family of Intelliport II/Plus 85 This driver supports the entire family of Intelliport II/Plus
86 controllers with the exception of the MicroChannel controllers and 86 controllers with the exception of the MicroChannel controllers and
@@ -138,7 +138,7 @@ config CYZ_INTR
138 138
139config DIGIEPCA 139config DIGIEPCA
140 tristate "Digiboard Intelligent Async Support" 140 tristate "Digiboard Intelligent Async Support"
141 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP 141 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (!64BIT || BROKEN)
142 ---help--- 142 ---help---
143 This is a driver for Digi International's Xx, Xeve, and Xem series 143 This is a driver for Digi International's Xx, Xeve, and Xem series
144 of cards which provide multiple serial ports. You would need 144 of cards which provide multiple serial ports. You would need
@@ -208,7 +208,7 @@ config SYNCLINK
208 208
209config SYNCLINKMP 209config SYNCLINKMP
210 tristate "SyncLink Multiport support" 210 tristate "SyncLink Multiport support"
211 depends on SERIAL_NONSTANDARD 211 depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32)
212 help 212 help
213 Enable support for the SyncLink Multiport (2 or 4 ports) 213 Enable support for the SyncLink Multiport (2 or 4 ports)
214 serial adapter, running asynchronous and HDLC communications up 214 serial adapter, running asynchronous and HDLC communications up
@@ -735,7 +735,7 @@ config SGI_IP27_RTC
735 735
736config GEN_RTC 736config GEN_RTC
737 tristate "Generic /dev/rtc emulation" 737 tristate "Generic /dev/rtc emulation"
738 depends on RTC!=y && !IA64 && !ARM && !PPC64 738 depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32
739 ---help--- 739 ---help---
740 If you say Y here and create a character special file /dev/rtc with 740 If you say Y here and create a character special file /dev/rtc with
741 major number 10 and minor number 135 using mknod ("man mknod"), you 741 major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 60bb9152b832..78d681dc35a8 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -39,7 +39,7 @@ char hvc_driver_name[] = "hvc_console";
39 39
40static struct vio_device_id hvc_driver_table[] __devinitdata = { 40static struct vio_device_id hvc_driver_table[] __devinitdata = {
41 {"serial", "hvterm1"}, 41 {"serial", "hvterm1"},
42 { NULL, } 42 { "", "" }
43}; 43};
44MODULE_DEVICE_TABLE(vio, hvc_driver_table); 44MODULE_DEVICE_TABLE(vio, hvc_driver_table);
45 45
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 3236d2404905..f47f009f9259 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -527,7 +527,7 @@ static int khvcsd(void *unused)
527 527
528static struct vio_device_id hvcs_driver_table[] __devinitdata= { 528static struct vio_device_id hvcs_driver_table[] __devinitdata= {
529 {"serial-server", "hvterm2"}, 529 {"serial-server", "hvterm2"},
530 { NULL, } 530 { "", "" }
531}; 531};
532MODULE_DEVICE_TABLE(vio, hvcs_driver_table); 532MODULE_DEVICE_TABLE(vio, hvcs_driver_table);
533 533
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 42187381506b..850a78c9c4bc 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -261,7 +261,11 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
261 261
262static int mmap_kmem(struct file * file, struct vm_area_struct * vma) 262static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
263{ 263{
264 unsigned long long val; 264 unsigned long pfn;
265
266 /* Turn a kernel-virtual address into a physical page frame */
267 pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
268
265 /* 269 /*
266 * RED-PEN: on some architectures there is more mapped memory 270 * RED-PEN: on some architectures there is more mapped memory
267 * than available in mem_map which pfn_valid checks 271 * than available in mem_map which pfn_valid checks
@@ -269,10 +273,10 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
269 * 273 *
270 * RED-PEN: vmalloc is not supported right now. 274 * RED-PEN: vmalloc is not supported right now.
271 */ 275 */
272 if (!pfn_valid(vma->vm_pgoff)) 276 if (!pfn_valid(pfn))
273 return -EIO; 277 return -EIO;
274 val = (u64)vma->vm_pgoff << PAGE_SHIFT; 278
275 vma->vm_pgoff = __pa(val) >> PAGE_SHIFT; 279 vma->vm_pgoff = pfn;
276 return mmap_mem(file, vma); 280 return mmap_mem(file, vma);
277} 281}
278 282
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 6b11d6b2129f..7999da25fe40 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1589,6 +1589,40 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp
1589EXPORT_SYMBOL(secure_tcpv6_port_ephemeral); 1589EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
1590#endif 1590#endif
1591 1591
1592#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
1593/* Similar to secure_tcp_sequence_number but generate a 48 bit value
1594 * bit's 32-47 increase every key exchange
1595 * 0-31 hash(source, dest)
1596 */
1597u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
1598 __u16 sport, __u16 dport)
1599{
1600 struct timeval tv;
1601 u64 seq;
1602 __u32 hash[4];
1603 struct keydata *keyptr = get_keyptr();
1604
1605 hash[0] = saddr;
1606 hash[1] = daddr;
1607 hash[2] = (sport << 16) + dport;
1608 hash[3] = keyptr->secret[11];
1609
1610 seq = half_md4_transform(hash, keyptr->secret);
1611 seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
1612
1613 do_gettimeofday(&tv);
1614 seq += tv.tv_usec + tv.tv_sec * 1000000;
1615 seq &= (1ull << 48) - 1;
1616#if 0
1617 printk("dccp init_seq(%lx, %lx, %d, %d) = %d\n",
1618 saddr, daddr, sport, dport, seq);
1619#endif
1620 return seq;
1621}
1622
1623EXPORT_SYMBOL(secure_dccp_sequence_number);
1624#endif
1625
1592#endif /* CONFIG_INET */ 1626#endif /* CONFIG_INET */
1593 1627
1594 1628
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index d8f9e94ae475..cd4fe8b1709f 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -1209,6 +1209,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
1209 1209
1210void rtc_get_rtc_time(struct rtc_time *rtc_tm) 1210void rtc_get_rtc_time(struct rtc_time *rtc_tm)
1211{ 1211{
1212 unsigned long uip_watchdog = jiffies;
1212 unsigned char ctrl; 1213 unsigned char ctrl;
1213#ifdef CONFIG_MACH_DECSTATION 1214#ifdef CONFIG_MACH_DECSTATION
1214 unsigned int real_year; 1215 unsigned int real_year;
@@ -1224,8 +1225,10 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
1224 * Once the read clears, read the RTC time (again via ioctl). Easy. 1225 * Once the read clears, read the RTC time (again via ioctl). Easy.
1225 */ 1226 */
1226 1227
1227 if (rtc_is_updating() != 0) 1228 while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) {
1228 msleep(20); 1229 barrier();
1230 cpu_relax();
1231 }
1229 1232
1230 /* 1233 /*
1231 * Only the values that we read from the RTC are set. We leave 1234 * Only the values that we read from the RTC are set. We leave
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
21config TCG_NSC 23config 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
38config TCG_INFINEON 40config 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 */
33static int TPM_INF_DATA = 0;
34static int TPM_INF_ADDR = 0;
31 35
32/* TPM header definitions */ 36/* TPM header definitions */
33enum infineon_tpm_header { 37enum infineon_tpm_header {
@@ -305,9 +309,10 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
305 309
306static void tpm_inf_cancel(struct tpm_chip *chip) 310static 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
353static const struct pnp_device_id tpm_pnp_tbl[] = {
354 /* Infineon TPMs */
355 {"IFX0101", 0},
356 {"IFX0102", 0},
357 {"", 0}
358};
359
360static 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
373static 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
348static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, 379static 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);
462module_exit(cleanup_inf); 528module_exit(cleanup_inf);
463 529
464MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); 530MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
465MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT"); 531MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
466MODULE_VERSION("1.4"); 532MODULE_VERSION("1.5");
467MODULE_LICENSE("GPL"); 533MODULE_LICENSE("GPL");
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 4764b4f9555d..0aff45fac2e6 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -991,7 +991,7 @@ static int viotape_remove(struct vio_dev *vdev)
991 */ 991 */
992static struct vio_device_id viotape_device_table[] __devinitdata = { 992static struct vio_device_id viotape_device_table[] __devinitdata = {
993 { "viotape", "" }, 993 { "viotape", "" },
994 { 0, } 994 { "", "" }
995}; 995};
996 996
997MODULE_DEVICE_TABLE(vio, viotape_device_table); 997MODULE_DEVICE_TABLE(vio, viotape_device_table);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 30d96739fb23..665103ccaee8 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2433,7 +2433,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2433 int ret = 0; 2433 int ret = 0;
2434 2434
2435 acquire_console_sem(); 2435 acquire_console_sem();
2436 if (tty->count == 1) { 2436 if (tty->driver_data == NULL) {
2437 ret = vc_allocate(currcons); 2437 ret = vc_allocate(currcons);
2438 if (ret == 0) { 2438 if (ret == 0) {
2439 struct vc_data *vc = vc_cons[currcons].d; 2439 struct vc_data *vc = vc_cons[currcons].d;
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
139static int tco_timer_stop (void) 150static 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)
155static int tco_timer_keepalive (void) 173static 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
506static void __exit watchdog_cleanup (void) 528static 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);
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 1b2132617dc3..fb88b4041dca 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -36,13 +36,10 @@
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37 37
38#define OSCR_FREQ CLOCK_TICK_RATE 38#define OSCR_FREQ CLOCK_TICK_RATE
39#define SA1100_CLOSE_MAGIC (0x5afc4453)
40 39
41static unsigned long sa1100wdt_users; 40static unsigned long sa1100wdt_users;
42static int expect_close;
43static int pre_margin; 41static int pre_margin;
44static int boot_status; 42static int boot_status;
45static int nowayout = WATCHDOG_NOWAYOUT;
46 43
47/* 44/*
48 * Allow only one person to hold it open 45 * Allow only one person to hold it open
@@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
62} 59}
63 60
64/* 61/*
65 * Shut off the timer. 62 * The watchdog cannot be disabled.
66 * Lock it in if it's a module and we defined ...NOWAYOUT 63 *
67 * Oddly, the watchdog can only be enabled, but we can turn off 64 * Previous comments suggested that turning off the interrupt by
68 * the interrupt, which appears to prevent the watchdog timing out. 65 * clearing OIER[E3] would prevent the watchdog timing out but this
66 * does not appear to be true (at least on the PXA255).
69 */ 67 */
70static int sa1100dog_release(struct inode *inode, struct file *file) 68static int sa1100dog_release(struct inode *inode, struct file *file)
71{ 69{
72 OSMR3 = OSCR + pre_margin; 70 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
73
74 if (expect_close == SA1100_CLOSE_MAGIC) {
75 OIER &= ~OIER_E3;
76 } else {
77 printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly. WDT will not stop!\n");
78 }
79 71
80 clear_bit(1, &sa1100wdt_users); 72 clear_bit(1, &sa1100wdt_users);
81 expect_close = 0;
82 73
83 return 0; 74 return 0;
84} 75}
85 76
86static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 77static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
87{ 78{
88 if (len) { 79 if (len)
89 if (!nowayout) {
90 size_t i;
91
92 expect_close = 0;
93
94 for (i = 0; i != len; i++) {
95 char c;
96
97 if (get_user(c, data + i))
98 return -EFAULT;
99 if (c == 'V')
100 expect_close = SA1100_CLOSE_MAGIC;
101 }
102 }
103 /* Refresh OSMR3 timer. */ 80 /* Refresh OSMR3 timer. */
104 OSMR3 = OSCR + pre_margin; 81 OSMR3 = OSCR + pre_margin;
105 }
106 82
107 return len; 83 return len;
108} 84}
109 85
110static struct watchdog_info ident = { 86static struct watchdog_info ident = {
111 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 87 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
112 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 88 .identity = "SA1100/PXA255 Watchdog",
113 .identity = "SA1100 Watchdog",
114}; 89};
115 90
116static int sa1100dog_ioctl(struct inode *inode, struct file *file, 91static int sa1100dog_ioctl(struct inode *inode, struct file *file,
@@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops =
172static struct miscdevice sa1100dog_miscdev = 147static struct miscdevice sa1100dog_miscdev =
173{ 148{
174 .minor = WATCHDOG_MINOR, 149 .minor = WATCHDOG_MINOR,
175 .name = "SA1100/PXA2xx watchdog", 150 .name = "watchdog",
176 .fops = &sa1100dog_fops, 151 .fops = &sa1100dog_fops,
177}; 152};
178 153
@@ -194,7 +169,6 @@ static int __init sa1100dog_init(void)
194 if (ret == 0) 169 if (ret == 0)
195 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", 170 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
196 margin); 171 margin);
197
198 return ret; 172 return ret;
199} 173}
200 174
@@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
212module_param(margin, int, 0); 186module_param(margin, int, 0);
213MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); 187MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
214 188
215module_param(nowayout, int, 0);
216MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
217
218MODULE_LICENSE("GPL"); 189MODULE_LICENSE("GPL");
219MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 190MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);