aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-02-23 22:05:47 -0500
committerPaul Mackerras <paulus@samba.org>2006-02-23 22:05:47 -0500
commita00428f5b149e36b8225b2a0812742a6dfb07b8c (patch)
treea78869cd67cf78a0eb091fb0ea5d397734bd6738 /drivers/char
parent774fee58c465ea1c7e9775e347ec307bcf2deeb3 (diff)
parentfb5c594c2acc441f0d2d8f457484a0e0e9285db3 (diff)
Merge ../powerpc-merge
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/Kconfig55
-rw-r--r--drivers/char/agp/amd64-agp.c6
-rw-r--r--drivers/char/agp/sworks-agp.c4
-rw-r--r--drivers/char/drm/drm_pciids.h1
-rw-r--r--drivers/char/drm/i915_irq.c5
-rw-r--r--drivers/char/drm/r300_cmdbuf.c48
-rw-r--r--drivers/char/drm/r300_reg.h3
-rw-r--r--drivers/char/drm/radeon_drv.h3
-rw-r--r--drivers/char/esp.c22
-rw-r--r--drivers/char/hpet.c22
-rw-r--r--drivers/char/hvc_console.c8
-rw-r--r--drivers/char/sysrq.c2
-rw-r--r--drivers/char/tipar.c15
-rw-r--r--drivers/char/tpm/tpm_infineon.c48
-rw-r--r--drivers/char/tty_io.c37
-rw-r--r--drivers/char/watchdog/pcwd.c450
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c12
17 files changed, 407 insertions, 334 deletions
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 486ed8a11b59..a4d425d2dce2 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -15,22 +15,23 @@ config AGP
15 due to kernel allocation issues), you could use PCI accesses 15 due to kernel allocation issues), you could use PCI accesses
16 and have up to a couple gigs of texture space. 16 and have up to a couple gigs of texture space.
17 17
18 Note that this is the only means to have XFree4/GLX use 18 Note that this is the only means to have X/GLX use
19 write-combining with MTRR support on the AGP bus. Without it, OpenGL 19 write-combining with MTRR support on the AGP bus. Without it, OpenGL
20 direct rendering will be a lot slower but still faster than PIO. 20 direct rendering will be a lot slower but still faster than PIO.
21 21
22 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
23 use GLX or DRI. If unsure, say N.
24
25 To compile this driver as a module, choose M here: the 22 To compile this driver as a module, choose M here: the
26 module will be called agpgart. 23 module will be called agpgart.
27 24
25 You should say Y here if you want to use GLX or DRI.
26
27 If unsure, say N.
28
28config AGP_ALI 29config AGP_ALI
29 tristate "ALI chipset support" 30 tristate "ALI chipset support"
30 depends on AGP && X86_32 31 depends on AGP && X86_32
31 ---help--- 32 ---help---
32 This option gives you AGP support for the GLX component of 33 This option gives you AGP support for the GLX component of
33 XFree86 4.x on the following ALi chipsets. The supported chipsets 34 X on the following ALi chipsets. The supported chipsets
34 include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. 35 include M1541, M1621, M1631, M1632, M1641,M1647,and M1651.
35 For the ALi-chipset question, ALi suggests you refer to 36 For the ALi-chipset question, ALi suggests you refer to
36 <http://www.ali.com.tw/eng/support/index.shtml>. 37 <http://www.ali.com.tw/eng/support/index.shtml>.
@@ -40,28 +41,19 @@ config AGP_ALI
40 timing issues, this chipset cannot do AGP 2x with the G200. 41 timing issues, this chipset cannot do AGP 2x with the G200.
41 This is a hardware limitation. AGP 1x seems to be fine, though. 42 This is a hardware limitation. AGP 1x seems to be fine, though.
42 43
43 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
44 use GLX or DRI. If unsure, say N.
45
46config AGP_ATI 44config AGP_ATI
47 tristate "ATI chipset support" 45 tristate "ATI chipset support"
48 depends on AGP && X86_32 46 depends on AGP && X86_32
49 ---help--- 47 ---help---
50 This option gives you AGP support for the GLX component of 48 This option gives you AGP support for the GLX component of
51 XFree86 4.x on the ATI RadeonIGP family of chipsets. 49 X on the ATI RadeonIGP family of chipsets.
52
53 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
54 use GLX or DRI. If unsure, say N.
55 50
56config AGP_AMD 51config AGP_AMD
57 tristate "AMD Irongate, 761, and 762 chipset support" 52 tristate "AMD Irongate, 761, and 762 chipset support"
58 depends on AGP && X86_32 53 depends on AGP && X86_32
59 help 54 help
60 This option gives you AGP support for the GLX component of 55 This option gives you AGP support for the GLX component of
61 XFree86 4.x on AMD Irongate, 761, and 762 chipsets. 56 X on AMD Irongate, 761, and 762 chipsets.
62
63 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
64 use GLX or DRI. If unsure, say N.
65 57
66config AGP_AMD64 58config AGP_AMD64
67 tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU 59 tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
@@ -69,45 +61,38 @@ config AGP_AMD64
69 default y if GART_IOMMU 61 default y if GART_IOMMU
70 help 62 help
71 This option gives you AGP support for the GLX component of 63 This option gives you AGP support for the GLX component of
72 XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. 64 X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
73 You still need an external AGP bridge like the AMD 8151, VIA 65 You still need an external AGP bridge like the AMD 8151, VIA
74 K8T400M, SiS755. It may also support other AGP bridges when loaded 66 K8T400M, SiS755. It may also support other AGP bridges when loaded
75 with agp_try_unsupported=1. 67 with agp_try_unsupported=1.
76 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
77 use GLX or DRI. If unsure, say Y
78 68
79config AGP_INTEL 69config AGP_INTEL
80 tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" 70 tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
81 depends on AGP && X86 71 depends on AGP && X86
82 help 72 help
83 This option gives you AGP support for the GLX component of XFree86 4.x 73 This option gives you AGP support for the GLX component of X
84 on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, 74 on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875,
85 E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, 75 E7205 and E7505 chipsets and full support for the 810, 815, 830M,
86 852GM, 855GM, 865G and I915 integrated graphics chipsets. 76 845G, 852GM, 855GM, 865G and I915 integrated graphics chipsets.
77
87 78
88 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
89 use GLX or DRI, or if you have any Intel integrated graphics
90 chipsets. If unsure, say Y.
91 79
92config AGP_NVIDIA 80config AGP_NVIDIA
93 tristate "NVIDIA nForce/nForce2 chipset support" 81 tristate "NVIDIA nForce/nForce2 chipset support"
94 depends on AGP && X86_32 82 depends on AGP && X86_32
95 help 83 help
96 This option gives you AGP support for the GLX component of 84 This option gives you AGP support for the GLX component of
97 XFree86 4.x on the following NVIDIA chipsets. The supported chipsets 85 X on NVIDIA chipsets including nForce and nForce2
98 include nForce and nForce2
99 86
100config AGP_SIS 87config AGP_SIS
101 tristate "SiS chipset support" 88 tristate "SiS chipset support"
102 depends on AGP && X86_32 89 depends on AGP && X86_32
103 help 90 help
104 This option gives you AGP support for the GLX component of 91 This option gives you AGP support for the GLX component of
105 XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. 92 X on Silicon Integrated Systems [SiS] chipsets.
106 93
107 Note that 5591/5592 AGP chipsets are NOT supported. 94 Note that 5591/5592 AGP chipsets are NOT supported.
108 95
109 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
110 use GLX or DRI. If unsure, say N.
111 96
112config AGP_SWORKS 97config AGP_SWORKS
113 tristate "Serverworks LE/HE chipset support" 98 tristate "Serverworks LE/HE chipset support"
@@ -121,10 +106,7 @@ config AGP_VIA
121 depends on AGP && X86_32 106 depends on AGP && X86_32
122 help 107 help
123 This option gives you AGP support for the GLX component of 108 This option gives you AGP support for the GLX component of
124 XFree86 4.x on VIA MVP3/Apollo Pro chipsets. 109 X on VIA MVP3/Apollo Pro chipsets.
125
126 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
127 use GLX or DRI. If unsure, say N.
128 110
129config AGP_I460 111config AGP_I460
130 tristate "Intel 460GX chipset support" 112 tristate "Intel 460GX chipset support"
@@ -159,9 +141,6 @@ config AGP_EFFICEON
159 This option gives you AGP support for the Transmeta Efficeon 141 This option gives you AGP support for the Transmeta Efficeon
160 series processors with integrated northbridges. 142 series processors with integrated northbridges.
161 143
162 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
163 use GLX or DRI. If unsure, say Y.
164
165config AGP_SGI_TIOCA 144config AGP_SGI_TIOCA
166 tristate "SGI TIO chipset AGP support" 145 tristate "SGI TIO chipset AGP support"
167 depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC) 146 depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC)
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 9964c508c111..1251b2515bbe 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -516,8 +516,10 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev)
516 pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); 516 pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase);
517 517
518 /* if x86-64 aperture base is beyond 4G, exit here */ 518 /* if x86-64 aperture base is beyond 4G, exit here */
519 if ( (apbase & 0x7fff) >> (32 - 25) ) 519 if ( (apbase & 0x7fff) >> (32 - 25) ) {
520 return -ENODEV; 520 printk(KERN_INFO PFX "aperture base > 4G\n");
521 return -ENODEV;
522 }
521 523
522 apbase = (apbase & 0x7fff) << 25; 524 apbase = (apbase & 0x7fff) << 25;
523 525
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 268f78d926d3..efef9999f1cf 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -468,9 +468,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
468 468
469 switch (pdev->device) { 469 switch (pdev->device) {
470 case 0x0006: 470 case 0x0006:
471 /* ServerWorks CNB20HE 471 printk (KERN_ERR PFX "ServerWorks CNB20HE is unsupported due to lack of documentation.\n");
472 Fail silently.*/
473 printk (KERN_ERR PFX "Detected ServerWorks CNB20HE chipset: No AGP present.\n");
474 return -ENODEV; 472 return -ENODEV;
475 473
476 case PCI_DEVICE_ID_SERVERWORKS_HE: 474 case PCI_DEVICE_ID_SERVERWORKS_HE:
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 8fd6357a48da..2c17e88a8847 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -85,7 +85,6 @@
85 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 85 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
86 {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 86 {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
87 {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 87 {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
88 {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
89 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 88 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
90 {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 89 {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
91 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 90 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index a1381c61aa63..d3879ac9970f 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -202,10 +202,15 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
202void i915_driver_irq_uninstall(drm_device_t * dev) 202void i915_driver_irq_uninstall(drm_device_t * dev)
203{ 203{
204 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 204 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
205 u16 temp;
206
205 if (!dev_priv) 207 if (!dev_priv)
206 return; 208 return;
207 209
208 I915_WRITE16(I915REG_HWSTAM, 0xffff); 210 I915_WRITE16(I915REG_HWSTAM, 0xffff);
209 I915_WRITE16(I915REG_INT_MASK_R, 0xffff); 211 I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
210 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); 212 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
213
214 temp = I915_READ16(I915REG_INT_IDENTITY_R);
215 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
211} 216}
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 291dbf4c8186..c08fa5076f05 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -161,6 +161,7 @@ void r300_init_reg_flags(void)
161 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); 161 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
162 ADD_RANGE(R300_GB_ENABLE, 1); 162 ADD_RANGE(R300_GB_ENABLE, 1);
163 ADD_RANGE(R300_GB_MSPOS0, 5); 163 ADD_RANGE(R300_GB_MSPOS0, 5);
164 ADD_RANGE(R300_TX_CNTL, 1);
164 ADD_RANGE(R300_TX_ENABLE, 1); 165 ADD_RANGE(R300_TX_ENABLE, 1);
165 ADD_RANGE(0x4200, 4); 166 ADD_RANGE(0x4200, 4);
166 ADD_RANGE(0x4214, 1); 167 ADD_RANGE(0x4214, 1);
@@ -489,6 +490,50 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
489 490
490 return 0; 491 return 0;
491} 492}
493static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
494 drm_radeon_kcmd_buffer_t *cmdbuf)
495{
496 u32 *cmd = (u32 *) cmdbuf->buf;
497 int count, ret;
498 RING_LOCALS;
499
500 count=(cmd[0]>>16) & 0x3fff;
501
502 if (cmd[0] & 0x8000) {
503 u32 offset;
504
505 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
506 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
507 offset = cmd[2] << 10;
508 ret = r300_check_offset(dev_priv, offset);
509 if (ret) {
510 DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
511 return DRM_ERR(EINVAL);
512 }
513 }
514
515 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
516 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
517 offset = cmd[3] << 10;
518 ret = r300_check_offset(dev_priv, offset);
519 if (ret) {
520 DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
521 return DRM_ERR(EINVAL);
522 }
523
524 }
525 }
526
527 BEGIN_RING(count+2);
528 OUT_RING(cmd[0]);
529 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
530 ADVANCE_RING();
531
532 cmdbuf->buf += (count+2)*4;
533 cmdbuf->bufsz -= (count+2)*4;
534
535 return 0;
536}
492 537
493static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, 538static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
494 drm_radeon_kcmd_buffer_t *cmdbuf) 539 drm_radeon_kcmd_buffer_t *cmdbuf)
@@ -527,6 +572,9 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
527 case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ 572 case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
528 return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); 573 return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
529 574
575 case RADEON_CNTL_BITBLT_MULTI:
576 return r300_emit_bitblt_multi(dev_priv, cmdbuf);
577
530 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ 578 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
531 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ 579 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
532 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ 580 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
index a0ed20e25221..d1e19954406b 100644
--- a/drivers/char/drm/r300_reg.h
+++ b/drivers/char/drm/r300_reg.h
@@ -451,6 +451,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
451/* END */ 451/* END */
452 452
453/* gap */ 453/* gap */
454/* Zero to flush caches. */
455#define R300_TX_CNTL 0x4100
456
454/* The upper enable bits are guessed, based on fglrx reported limits. */ 457/* The upper enable bits are guessed, based on fglrx reported limits. */
455#define R300_TX_ENABLE 0x4104 458#define R300_TX_ENABLE 0x4104
456# define R300_TX_ENABLE_0 (1 << 0) 459# define R300_TX_ENABLE_0 (1 << 0)
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 498b19b1d641..1f7d2ab8c4fc 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -90,9 +90,10 @@
90 * 1.19- Add support for gart table in FB memory and PCIE r300 90 * 1.19- Add support for gart table in FB memory and PCIE r300
91 * 1.20- Add support for r300 texrect 91 * 1.20- Add support for r300 texrect
92 * 1.21- Add support for card type getparam 92 * 1.21- Add support for card type getparam
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
93 */ 94 */
94#define DRIVER_MAJOR 1 95#define DRIVER_MAJOR 1
95#define DRIVER_MINOR 21 96#define DRIVER_MINOR 22
96#define DRIVER_PATCHLEVEL 0 97#define DRIVER_PATCHLEVEL 0
97 98
98/* 99/*
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 57539d8f9f7c..09dc4b01232c 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -150,17 +150,6 @@ static void rs_wait_until_sent(struct tty_struct *, int);
150/* Standard COM flags (except for COM4, because of the 8514 problem) */ 150/* Standard COM flags (except for COM4, because of the 8514 problem) */
151#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) 151#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
152 152
153/*
154 * tmp_buf is used as a temporary buffer by serial_write. We need to
155 * lock it in case the memcpy_fromfs blocks while swapping in a page,
156 * and some other program tries to do a serial write at the same time.
157 * Since the lock will only come under contention when the system is
158 * swapping and available memory is low, it makes sense to share one
159 * buffer across all the serial ports, since it significantly saves
160 * memory if large numbers of serial ports are open.
161 */
162static unsigned char *tmp_buf;
163
164static inline int serial_paranoia_check(struct esp_struct *info, 153static inline int serial_paranoia_check(struct esp_struct *info,
165 char *name, const char *routine) 154 char *name, const char *routine)
166{ 155{
@@ -1267,7 +1256,7 @@ static int rs_write(struct tty_struct * tty,
1267 if (serial_paranoia_check(info, tty->name, "rs_write")) 1256 if (serial_paranoia_check(info, tty->name, "rs_write"))
1268 return 0; 1257 return 0;
1269 1258
1270 if (!tty || !info->xmit_buf || !tmp_buf) 1259 if (!tty || !info->xmit_buf)
1271 return 0; 1260 return 0;
1272 1261
1273 while (1) { 1262 while (1) {
@@ -2291,11 +2280,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp)
2291 tty->driver_data = info; 2280 tty->driver_data = info;
2292 info->tty = tty; 2281 info->tty = tty;
2293 2282
2294 if (!tmp_buf) { 2283 spin_unlock_irqrestore(&info->lock, flags);
2295 tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
2296 if (!tmp_buf)
2297 return -ENOMEM;
2298 }
2299 2284
2300 /* 2285 /*
2301 * Start up serial port 2286 * Start up serial port
@@ -2602,9 +2587,6 @@ static void __exit espserial_exit(void)
2602 free_pages((unsigned long)dma_buffer, 2587 free_pages((unsigned long)dma_buffer,
2603 get_order(DMA_BUFFER_SZ)); 2588 get_order(DMA_BUFFER_SZ));
2604 2589
2605 if (tmp_buf)
2606 free_page((unsigned long)tmp_buf);
2607
2608 while (free_pio_buf) { 2590 while (free_pio_buf) {
2609 pio_buf = free_pio_buf->next; 2591 pio_buf = free_pio_buf->next;
2610 kfree(free_pio_buf); 2592 kfree(free_pio_buf);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 66a2fee06eb9..ef140ebde117 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -956,22 +956,18 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
956 } 956 }
957 } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { 957 } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
958 struct acpi_resource_extended_irq *irqp; 958 struct acpi_resource_extended_irq *irqp;
959 int i; 959 int i, irq;
960 960
961 irqp = &res->data.extended_irq; 961 irqp = &res->data.extended_irq;
962 962
963 if (irqp->interrupt_count > 0) { 963 for (i = 0; i < irqp->interrupt_count; i++) {
964 hdp->hd_nirqs = irqp->interrupt_count; 964 irq = acpi_register_gsi(irqp->interrupts[i],
965 965 irqp->triggering, irqp->polarity);
966 for (i = 0; i < hdp->hd_nirqs; i++) { 966 if (irq < 0)
967 int rc = 967 return AE_ERROR;
968 acpi_register_gsi(irqp->interrupts[i], 968
969 irqp->triggering, 969 hdp->hd_irq[hdp->hd_nirqs] = irq;
970 irqp->polarity); 970 hdp->hd_nirqs++;
971 if (rc < 0)
972 return AE_ERROR;
973 hdp->hd_irq[i] = rc;
974 }
975 } 971 }
976 } 972 }
977 973
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 1994a92d4733..f65b2e14a485 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -335,6 +335,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
335 } /* else count == 0 */ 335 } /* else count == 0 */
336 336
337 tty->driver_data = hp; 337 tty->driver_data = hp;
338 tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
339
338 hp->tty = tty; 340 hp->tty = tty;
339 /* Save for request_irq outside of spin_lock. */ 341 /* Save for request_irq outside of spin_lock. */
340 irq = hp->irq; 342 irq = hp->irq;
@@ -633,9 +635,6 @@ static int hvc_poll(struct hvc_struct *hp)
633 tty_insert_flip_char(tty, buf[i], 0); 635 tty_insert_flip_char(tty, buf[i], 0);
634 } 636 }
635 637
636 if (count)
637 tty_schedule_flip(tty);
638
639 /* 638 /*
640 * Account for the total amount read in one loop, and if above 639 * Account for the total amount read in one loop, and if above
641 * 64 bytes, we do a quick schedule loop to let the tty grok 640 * 64 bytes, we do a quick schedule loop to let the tty grok
@@ -656,6 +655,9 @@ static int hvc_poll(struct hvc_struct *hp)
656 bail: 655 bail:
657 spin_unlock_irqrestore(&hp->lock, flags); 656 spin_unlock_irqrestore(&hp->lock, flags);
658 657
658 if (read_total)
659 tty_flip_buffer_push(tty);
660
659 return poll_mask; 661 return poll_mask;
660} 662}
661 663
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 5765f672e853..d58f82318853 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -243,7 +243,7 @@ static struct sysrq_key_op sysrq_term_op = {
243 243
244static void moom_callback(void *ignored) 244static void moom_callback(void *ignored)
245{ 245{
246 out_of_memory(GFP_KERNEL, 0); 246 out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], GFP_KERNEL, 0);
247} 247}
248 248
249static DECLARE_WORK(moom_work, moom_callback, NULL); 249static DECLARE_WORK(moom_work, moom_callback, NULL);
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 41a94bc79f67..eb2eb3e12d6a 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -250,12 +250,17 @@ tipar_open(struct inode *inode, struct file *file)
250{ 250{
251 unsigned int minor = iminor(inode) - TIPAR_MINOR; 251 unsigned int minor = iminor(inode) - TIPAR_MINOR;
252 252
253 if (minor > tp_count - 1) 253 if (tp_count == 0 || minor > tp_count - 1)
254 return -ENXIO; 254 return -ENXIO;
255 255
256 if (test_and_set_bit(minor, &opened)) 256 if (test_and_set_bit(minor, &opened))
257 return -EBUSY; 257 return -EBUSY;
258 258
259 if (!table[minor].dev) {
260 printk(KERN_ERR "%s: NULL device for minor %u\n",
261 __FUNCTION__, minor);
262 return -ENXIO;
263 }
259 parport_claim_or_block(table[minor].dev); 264 parport_claim_or_block(table[minor].dev);
260 init_ti_parallel(minor); 265 init_ti_parallel(minor);
261 parport_release(table[minor].dev); 266 parport_release(table[minor].dev);
@@ -510,16 +515,20 @@ tipar_init_module(void)
510 err = PTR_ERR(tipar_class); 515 err = PTR_ERR(tipar_class);
511 goto out_chrdev; 516 goto out_chrdev;
512 } 517 }
513 if (parport_register_driver(&tipar_driver)) { 518 if (parport_register_driver(&tipar_driver) || tp_count == 0) {
514 printk(KERN_ERR "tipar: unable to register with parport\n"); 519 printk(KERN_ERR "tipar: unable to register with parport\n");
515 err = -EIO; 520 err = -EIO;
516 goto out; 521 goto out_class;
517 } 522 }
518 523
519 err = 0; 524 err = 0;
520 goto out; 525 goto out;
521 526
527out_class:
528 class_destroy(tipar_class);
529
522out_chrdev: 530out_chrdev:
531 devfs_remove("ticables/par");
523 unregister_chrdev(TIPAR_MAJOR, "tipar"); 532 unregister_chrdev(TIPAR_MAJOR, "tipar");
524out: 533out:
525 return err; 534 return err;
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index ec7590951af5..24095f6ee6da 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -33,6 +33,7 @@
33static int TPM_INF_DATA; 33static int TPM_INF_DATA;
34static int TPM_INF_ADDR; 34static int TPM_INF_ADDR;
35static int TPM_INF_BASE; 35static int TPM_INF_BASE;
36static int TPM_INF_ADDR_LEN;
36static int TPM_INF_PORT_LEN; 37static int TPM_INF_PORT_LEN;
37 38
38/* TPM header definitions */ 39/* TPM header definitions */
@@ -195,6 +196,7 @@ static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
195 int i; 196 int i;
196 int ret; 197 int ret;
197 u32 size = 0; 198 u32 size = 0;
199 number_of_wtx = 0;
198 200
199recv_begin: 201recv_begin:
200 /* start receiving header */ 202 /* start receiving header */
@@ -378,24 +380,35 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
378 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && 380 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
379 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { 381 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
380 TPM_INF_ADDR = pnp_port_start(dev, 0); 382 TPM_INF_ADDR = pnp_port_start(dev, 0);
383 TPM_INF_ADDR_LEN = pnp_port_len(dev, 0);
381 TPM_INF_DATA = (TPM_INF_ADDR + 1); 384 TPM_INF_DATA = (TPM_INF_ADDR + 1);
382 TPM_INF_BASE = pnp_port_start(dev, 1); 385 TPM_INF_BASE = pnp_port_start(dev, 1);
383 TPM_INF_PORT_LEN = pnp_port_len(dev, 1); 386 TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
384 if (!TPM_INF_PORT_LEN) 387 if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) {
385 return -EINVAL; 388 rc = -EINVAL;
389 goto err_last;
390 }
386 dev_info(&dev->dev, "Found %s with ID %s\n", 391 dev_info(&dev->dev, "Found %s with ID %s\n",
387 dev->name, dev_id->id); 392 dev->name, dev_id->id);
388 if (!((TPM_INF_BASE >> 8) & 0xff)) 393 if (!((TPM_INF_BASE >> 8) & 0xff)) {
389 return -EINVAL; 394 rc = -EINVAL;
395 goto err_last;
396 }
390 /* publish my base address and request region */ 397 /* publish my base address and request region */
391 tpm_inf.base = TPM_INF_BASE; 398 tpm_inf.base = TPM_INF_BASE;
392 if (request_region 399 if (request_region
393 (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { 400 (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
394 release_region(tpm_inf.base, TPM_INF_PORT_LEN); 401 rc = -EINVAL;
395 return -EINVAL; 402 goto err_last;
403 }
404 if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
405 "tpm_infineon0") == NULL) {
406 rc = -EINVAL;
407 goto err_last;
396 } 408 }
397 } else { 409 } else {
398 return -EINVAL; 410 rc = -EINVAL;
411 goto err_last;
399 } 412 }
400 413
401 /* query chip for its vendor, its version number a.s.o. */ 414 /* query chip for its vendor, its version number a.s.o. */
@@ -443,8 +456,8 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
443 dev_err(&dev->dev, 456 dev_err(&dev->dev,
444 "Could not set IO-ports to 0x%lx\n", 457 "Could not set IO-ports to 0x%lx\n",
445 tpm_inf.base); 458 tpm_inf.base);
446 release_region(tpm_inf.base, TPM_INF_PORT_LEN); 459 rc = -EIO;
447 return -EIO; 460 goto err_release_region;
448 } 461 }
449 462
450 /* activate register */ 463 /* activate register */
@@ -471,14 +484,21 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
471 484
472 rc = tpm_register_hardware(&dev->dev, &tpm_inf); 485 rc = tpm_register_hardware(&dev->dev, &tpm_inf);
473 if (rc < 0) { 486 if (rc < 0) {
474 release_region(tpm_inf.base, TPM_INF_PORT_LEN); 487 rc = -ENODEV;
475 return -ENODEV; 488 goto err_release_region;
476 } 489 }
477 return 0; 490 return 0;
478 } else { 491 } else {
479 dev_info(&dev->dev, "No Infineon TPM found!\n"); 492 rc = -ENODEV;
480 return -ENODEV; 493 goto err_release_region;
481 } 494 }
495
496err_release_region:
497 release_region(tpm_inf.base, TPM_INF_PORT_LEN);
498 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
499
500err_last:
501 return rc;
482} 502}
483 503
484static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) 504static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
@@ -518,5 +538,5 @@ module_exit(cleanup_inf);
518 538
519MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); 539MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
520MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); 540MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
521MODULE_VERSION("1.6"); 541MODULE_VERSION("1.7");
522MODULE_LICENSE("GPL"); 542MODULE_LICENSE("GPL");
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 076e07c1da38..e9bba94fc898 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -268,6 +268,8 @@ static struct tty_buffer *tty_buffer_alloc(size_t size)
268 p->size = size; 268 p->size = size;
269 p->next = NULL; 269 p->next = NULL;
270 p->active = 0; 270 p->active = 0;
271 p->commit = 0;
272 p->read = 0;
271 p->char_buf_ptr = (char *)(p->data); 273 p->char_buf_ptr = (char *)(p->data);
272 p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; 274 p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
273/* printk("Flip create %p\n", p); */ 275/* printk("Flip create %p\n", p); */
@@ -298,6 +300,8 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
298 *tbh = t->next; 300 *tbh = t->next;
299 t->next = NULL; 301 t->next = NULL;
300 t->used = 0; 302 t->used = 0;
303 t->commit = 0;
304 t->read = 0;
301 /* DEBUG ONLY */ 305 /* DEBUG ONLY */
302 memset(t->data, '*', size); 306 memset(t->data, '*', size);
303/* printk("Flip recycle %p\n", t); */ 307/* printk("Flip recycle %p\n", t); */
@@ -335,6 +339,7 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
335 if (b != NULL) { 339 if (b != NULL) {
336 b->next = n; 340 b->next = n;
337 b->active = 0; 341 b->active = 0;
342 b->commit = b->used;
338 } else 343 } else
339 tty->buf.head = n; 344 tty->buf.head = n;
340 tty->buf.tail = n; 345 tty->buf.tail = n;
@@ -1836,7 +1841,6 @@ static void release_dev(struct file * filp)
1836 tty_closing = tty->count <= 1; 1841 tty_closing = tty->count <= 1;
1837 o_tty_closing = o_tty && 1842 o_tty_closing = o_tty &&
1838 (o_tty->count <= (pty_master ? 1 : 0)); 1843 (o_tty->count <= (pty_master ? 1 : 0));
1839 up(&tty_sem);
1840 do_sleep = 0; 1844 do_sleep = 0;
1841 1845
1842 if (tty_closing) { 1846 if (tty_closing) {
@@ -1864,6 +1868,7 @@ static void release_dev(struct file * filp)
1864 1868
1865 printk(KERN_WARNING "release_dev: %s: read/write wait queue " 1869 printk(KERN_WARNING "release_dev: %s: read/write wait queue "
1866 "active!\n", tty_name(tty, buf)); 1870 "active!\n", tty_name(tty, buf));
1871 up(&tty_sem);
1867 schedule(); 1872 schedule();
1868 } 1873 }
1869 1874
@@ -1872,8 +1877,6 @@ static void release_dev(struct file * filp)
1872 * both sides, and we've completed the last operation that could 1877 * both sides, and we've completed the last operation that could
1873 * block, so it's safe to proceed with closing. 1878 * block, so it's safe to proceed with closing.
1874 */ 1879 */
1875
1876 down(&tty_sem);
1877 if (pty_master) { 1880 if (pty_master) {
1878 if (--o_tty->count < 0) { 1881 if (--o_tty->count < 0) {
1879 printk(KERN_WARNING "release_dev: bad pty slave count " 1882 printk(KERN_WARNING "release_dev: bad pty slave count "
@@ -1887,7 +1890,6 @@ static void release_dev(struct file * filp)
1887 tty->count, tty_name(tty, buf)); 1890 tty->count, tty_name(tty, buf));
1888 tty->count = 0; 1891 tty->count = 0;
1889 } 1892 }
1890 up(&tty_sem);
1891 1893
1892 /* 1894 /*
1893 * We've decremented tty->count, so we need to remove this file 1895 * We've decremented tty->count, so we need to remove this file
@@ -1932,6 +1934,8 @@ static void release_dev(struct file * filp)
1932 read_unlock(&tasklist_lock); 1934 read_unlock(&tasklist_lock);
1933 } 1935 }
1934 1936
1937 up(&tty_sem);
1938
1935 /* check whether both sides are closing ... */ 1939 /* check whether both sides are closing ... */
1936 if (!tty_closing || (o_tty && !o_tty_closing)) 1940 if (!tty_closing || (o_tty && !o_tty_closing))
1937 return; 1941 return;
@@ -2752,6 +2756,9 @@ static void flush_to_ldisc(void *private_)
2752 unsigned long flags; 2756 unsigned long flags;
2753 struct tty_ldisc *disc; 2757 struct tty_ldisc *disc;
2754 struct tty_buffer *tbuf; 2758 struct tty_buffer *tbuf;
2759 int count;
2760 char *char_buf;
2761 unsigned char *flag_buf;
2755 2762
2756 disc = tty_ldisc_ref(tty); 2763 disc = tty_ldisc_ref(tty);
2757 if (disc == NULL) /* !TTY_LDISC */ 2764 if (disc == NULL) /* !TTY_LDISC */
@@ -2765,16 +2772,20 @@ static void flush_to_ldisc(void *private_)
2765 goto out; 2772 goto out;
2766 } 2773 }
2767 spin_lock_irqsave(&tty->buf.lock, flags); 2774 spin_lock_irqsave(&tty->buf.lock, flags);
2768 while((tbuf = tty->buf.head) != NULL && !tbuf->active) { 2775 while((tbuf = tty->buf.head) != NULL) {
2776 while ((count = tbuf->commit - tbuf->read) != 0) {
2777 char_buf = tbuf->char_buf_ptr + tbuf->read;
2778 flag_buf = tbuf->flag_buf_ptr + tbuf->read;
2779 tbuf->read += count;
2780 spin_unlock_irqrestore(&tty->buf.lock, flags);
2781 disc->receive_buf(tty, char_buf, flag_buf, count);
2782 spin_lock_irqsave(&tty->buf.lock, flags);
2783 }
2784 if (tbuf->active)
2785 break;
2769 tty->buf.head = tbuf->next; 2786 tty->buf.head = tbuf->next;
2770 if (tty->buf.head == NULL) 2787 if (tty->buf.head == NULL)
2771 tty->buf.tail = NULL; 2788 tty->buf.tail = NULL;
2772 spin_unlock_irqrestore(&tty->buf.lock, flags);
2773 /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */
2774 disc->receive_buf(tty, tbuf->char_buf_ptr,
2775 tbuf->flag_buf_ptr,
2776 tbuf->used);
2777 spin_lock_irqsave(&tty->buf.lock, flags);
2778 tty_buffer_free(tty, tbuf); 2789 tty_buffer_free(tty, tbuf);
2779 } 2790 }
2780 spin_unlock_irqrestore(&tty->buf.lock, flags); 2791 spin_unlock_irqrestore(&tty->buf.lock, flags);
@@ -2871,8 +2882,10 @@ void tty_flip_buffer_push(struct tty_struct *tty)
2871{ 2882{
2872 unsigned long flags; 2883 unsigned long flags;
2873 spin_lock_irqsave(&tty->buf.lock, flags); 2884 spin_lock_irqsave(&tty->buf.lock, flags);
2874 if (tty->buf.tail != NULL) 2885 if (tty->buf.tail != NULL) {
2875 tty->buf.tail->active = 0; 2886 tty->buf.tail->active = 0;
2887 tty->buf.tail->commit = tty->buf.tail->used;
2888 }
2876 spin_unlock_irqrestore(&tty->buf.lock, flags); 2889 spin_unlock_irqrestore(&tty->buf.lock, flags);
2877 2890
2878 if (tty->low_latency) 2891 if (tty->low_latency)
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 37c9e13ad3ac..8d6b249ad66b 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -49,29 +49,37 @@
49 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ 49 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
50 */ 50 */
51 51
52#include <linux/module.h> 52#include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */
53#include <linux/moduleparam.h> 53#include <linux/module.h> /* For module specific items */
54#include <linux/types.h> 54#include <linux/moduleparam.h> /* For new moduleparam's */
55#include <linux/timer.h> 55#include <linux/types.h> /* For standard types (like size_t) */
56#include <linux/jiffies.h> 56#include <linux/errno.h> /* For the -ENODEV/... values */
57#include <linux/config.h> 57#include <linux/kernel.h> /* For printk/panic/... */
58#include <linux/wait.h> 58#include <linux/delay.h> /* For mdelay function */
59#include <linux/slab.h> 59#include <linux/timer.h> /* For timer related operations */
60#include <linux/ioport.h> 60#include <linux/jiffies.h> /* For jiffies stuff */
61#include <linux/delay.h> 61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
62#include <linux/fs.h> 62#include <linux/watchdog.h> /* For the watchdog specific items */
63#include <linux/miscdevice.h> 63#include <linux/notifier.h> /* For notifier support */
64#include <linux/watchdog.h> 64#include <linux/reboot.h> /* For reboot_notifier stuff */
65#include <linux/notifier.h> 65#include <linux/init.h> /* For __init/__exit/... */
66#include <linux/init.h> 66#include <linux/fs.h> /* For file operations */
67#include <linux/spinlock.h> 67#include <linux/ioport.h> /* For io-port access */
68#include <linux/reboot.h> 68#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
69#include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ 69#include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */
70#include <asm/uaccess.h> 70#include <linux/slab.h> /* For kmalloc */
71#include <asm/io.h>
72 71
73#define WD_VER "1.16 (06/12/2004)" 72#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
74#define PFX "pcwd: " 73#include <asm/io.h> /* For inb/outb/... */
74
75/* Module and version information */
76#define WATCHDOG_VERSION "1.16"
77#define WATCHDOG_DATE "03 Jan 2006"
78#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
79#define WATCHDOG_NAME "pcwd"
80#define PFX WATCHDOG_NAME ": "
81#define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n"
82#define WD_VER WATCHDOG_VERSION " (" WATCHDOG_DATE ")"
75 83
76/* 84/*
77 * It should be noted that PCWD_REVISION_B was removed because A and B 85 * It should be noted that PCWD_REVISION_B was removed because A and B
@@ -85,36 +93,38 @@
85 93
86/* 94/*
87 * These are the defines that describe the control status bits for the 95 * These are the defines that describe the control status bits for the
88 * PC Watchdog card, revision A. 96 * PCI-PC Watchdog card.
89 */ 97*/
98/* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */
90#define WD_WDRST 0x01 /* Previously reset state */ 99#define WD_WDRST 0x01 /* Previously reset state */
91#define WD_T110 0x02 /* Temperature overheat sense */ 100#define WD_T110 0x02 /* Temperature overheat sense */
92#define WD_HRTBT 0x04 /* Heartbeat sense */ 101#define WD_HRTBT 0x04 /* Heartbeat sense */
93#define WD_RLY2 0x08 /* External relay triggered */ 102#define WD_RLY2 0x08 /* External relay triggered */
94#define WD_SRLY2 0x80 /* Software external relay triggered */ 103#define WD_SRLY2 0x80 /* Software external relay triggered */
95 104/* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */
96/*
97 * These are the defines that describe the control status bits for the
98 * PC Watchdog card, revision C.
99 */
100#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ 105#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */
101#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ 106#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */
102#define WD_REVC_TTRP 0x04 /* Temperature Trip status */ 107#define WD_REVC_TTRP 0x04 /* Temperature Trip status */
108/* Port 2 : Control Status #2 */
109#define WD_WDIS 0x10 /* Watchdog Disabled */
110#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */
111#define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */
112#define WD_WCMD 0x80 /* Watchdog Command Mode */
103 113
104/* max. time we give an ISA watchdog card to process a command */ 114/* max. time we give an ISA watchdog card to process a command */
105/* 500ms for each 4 bit response (according to spec.) */ 115/* 500ms for each 4 bit response (according to spec.) */
106#define ISA_COMMAND_TIMEOUT 1000 116#define ISA_COMMAND_TIMEOUT 1000
107 117
108/* Watchdog's internal commands */ 118/* Watchdog's internal commands */
109#define CMD_ISA_IDLE 0x00 119#define CMD_ISA_IDLE 0x00
110#define CMD_ISA_VERSION_INTEGER 0x01 120#define CMD_ISA_VERSION_INTEGER 0x01
111#define CMD_ISA_VERSION_TENTH 0x02 121#define CMD_ISA_VERSION_TENTH 0x02
112#define CMD_ISA_VERSION_HUNDRETH 0x03 122#define CMD_ISA_VERSION_HUNDRETH 0x03
113#define CMD_ISA_VERSION_MINOR 0x04 123#define CMD_ISA_VERSION_MINOR 0x04
114#define CMD_ISA_SWITCH_SETTINGS 0x05 124#define CMD_ISA_SWITCH_SETTINGS 0x05
115#define CMD_ISA_DELAY_TIME_2SECS 0x0A 125#define CMD_ISA_DELAY_TIME_2SECS 0x0A
116#define CMD_ISA_DELAY_TIME_4SECS 0x0B 126#define CMD_ISA_DELAY_TIME_4SECS 0x0B
117#define CMD_ISA_DELAY_TIME_8SECS 0x0C 127#define CMD_ISA_DELAY_TIME_8SECS 0x0C
118 128
119/* 129/*
120 * We are using an kernel timer to do the pinging of the watchdog 130 * We are using an kernel timer to do the pinging of the watchdog
@@ -130,15 +140,17 @@ static int cards_found;
130/* internal variables */ 140/* internal variables */
131static atomic_t open_allowed = ATOMIC_INIT(1); 141static atomic_t open_allowed = ATOMIC_INIT(1);
132static char expect_close; 142static char expect_close;
133static struct timer_list timer;
134static unsigned long next_heartbeat;
135static int temp_panic; 143static int temp_panic;
136static int revision; /* The card's revision */ 144static struct { /* this is private data for each ISA-PC watchdog card */
137static int supports_temp; /* Wether or not the card has a temperature device */ 145 int revision; /* The card's revision */
138static int command_mode; /* Wether or not the card is in command mode */ 146 int supports_temp; /* Wether or not the card has a temperature device */
139static int initial_status; /* The card's boot status */ 147 int command_mode; /* Wether or not the card is in command mode */
140static int current_readport; /* The cards I/O address */ 148 int boot_status; /* The card's boot status */
141static spinlock_t io_lock; 149 int io_addr; /* The cards I/O address */
150 spinlock_t io_lock; /* the lock for io operations */
151 struct timer_list timer; /* The timer that pings the watchdog */
152 unsigned long next_heartbeat; /* the next_heartbeat for the timer */
153} pcwd_private;
142 154
143/* module parameters */ 155/* module parameters */
144#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ 156#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */
@@ -161,14 +173,14 @@ static int send_isa_command(int cmd)
161 int port0, last_port0; /* Double read for stabilising */ 173 int port0, last_port0; /* Double read for stabilising */
162 174
163 /* The WCMD bit must be 1 and the command is only 4 bits in size */ 175 /* The WCMD bit must be 1 and the command is only 4 bits in size */
164 control_status = (cmd & 0x0F) | 0x80; 176 control_status = (cmd & 0x0F) | WD_WCMD;
165 outb_p(control_status, current_readport + 2); 177 outb_p(control_status, pcwd_private.io_addr + 2);
166 udelay(ISA_COMMAND_TIMEOUT); 178 udelay(ISA_COMMAND_TIMEOUT);
167 179
168 port0 = inb_p(current_readport); 180 port0 = inb_p(pcwd_private.io_addr);
169 for (i = 0; i < 25; ++i) { 181 for (i = 0; i < 25; ++i) {
170 last_port0 = port0; 182 last_port0 = port0;
171 port0 = inb_p(current_readport); 183 port0 = inb_p(pcwd_private.io_addr);
172 184
173 if (port0 == last_port0) 185 if (port0 == last_port0)
174 break; /* Data is stable */ 186 break; /* Data is stable */
@@ -184,7 +196,7 @@ static int set_command_mode(void)
184 int i, found=0, count=0; 196 int i, found=0, count=0;
185 197
186 /* Set the card into command mode */ 198 /* Set the card into command mode */
187 spin_lock(&io_lock); 199 spin_lock(&pcwd_private.io_lock);
188 while ((!found) && (count < 3)) { 200 while ((!found) && (count < 3)) {
189 i = send_isa_command(CMD_ISA_IDLE); 201 i = send_isa_command(CMD_ISA_IDLE);
190 202
@@ -192,15 +204,15 @@ static int set_command_mode(void)
192 found = 1; 204 found = 1;
193 else if (i == 0xF3) { 205 else if (i == 0xF3) {
194 /* Card does not like what we've done to it */ 206 /* Card does not like what we've done to it */
195 outb_p(0x00, current_readport + 2); 207 outb_p(0x00, pcwd_private.io_addr + 2);
196 udelay(1200); /* Spec says wait 1ms */ 208 udelay(1200); /* Spec says wait 1ms */
197 outb_p(0x00, current_readport + 2); 209 outb_p(0x00, pcwd_private.io_addr + 2);
198 udelay(ISA_COMMAND_TIMEOUT); 210 udelay(ISA_COMMAND_TIMEOUT);
199 } 211 }
200 count++; 212 count++;
201 } 213 }
202 spin_unlock(&io_lock); 214 spin_unlock(&pcwd_private.io_lock);
203 command_mode = found; 215 pcwd_private.command_mode = found;
204 216
205 return(found); 217 return(found);
206} 218}
@@ -208,12 +220,95 @@ static int set_command_mode(void)
208static void unset_command_mode(void) 220static void unset_command_mode(void)
209{ 221{
210 /* Set the card into normal mode */ 222 /* Set the card into normal mode */
211 spin_lock(&io_lock); 223 spin_lock(&pcwd_private.io_lock);
212 outb_p(0x00, current_readport + 2); 224 outb_p(0x00, pcwd_private.io_addr + 2);
213 udelay(ISA_COMMAND_TIMEOUT); 225 udelay(ISA_COMMAND_TIMEOUT);
214 spin_unlock(&io_lock); 226 spin_unlock(&pcwd_private.io_lock);
227
228 pcwd_private.command_mode = 0;
229}
230
231static inline void pcwd_check_temperature_support(void)
232{
233 if (inb(pcwd_private.io_addr) != 0xF0)
234 pcwd_private.supports_temp = 1;
235}
236
237static inline char *get_firmware(void)
238{
239 int one, ten, hund, minor;
240 char *ret;
241
242 ret = kmalloc(6, GFP_KERNEL);
243 if(ret == NULL)
244 return NULL;
245
246 if (set_command_mode()) {
247 one = send_isa_command(CMD_ISA_VERSION_INTEGER);
248 ten = send_isa_command(CMD_ISA_VERSION_TENTH);
249 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH);
250 minor = send_isa_command(CMD_ISA_VERSION_MINOR);
251 sprintf(ret, "%c.%c%c%c", one, ten, hund, minor);
252 }
253 else
254 sprintf(ret, "ERROR");
255
256 unset_command_mode();
257 return(ret);
258}
259
260static inline int pcwd_get_option_switches(void)
261{
262 int option_switches=0;
263
264 if (set_command_mode()) {
265 /* Get switch settings */
266 option_switches = send_isa_command(CMD_ISA_SWITCH_SETTINGS);
267 }
268
269 unset_command_mode();
270 return(option_switches);
271}
272
273static void pcwd_show_card_info(void)
274{
275 char *firmware;
276 int option_switches;
277
278 /* Get some extra info from the hardware (in command/debug/diag mode) */
279 if (pcwd_private.revision == PCWD_REVISION_A)
280 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr);
281 else if (pcwd_private.revision == PCWD_REVISION_C) {
282 firmware = get_firmware();
283 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n",
284 pcwd_private.io_addr, firmware);
285 kfree(firmware);
286 option_switches = pcwd_get_option_switches();
287 printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
288 option_switches,
289 ((option_switches & 0x10) ? "ON" : "OFF"),
290 ((option_switches & 0x08) ? "ON" : "OFF"));
291
292 /* Reprogram internal heartbeat to 2 seconds */
293 if (set_command_mode()) {
294 send_isa_command(CMD_ISA_DELAY_TIME_2SECS);
295 unset_command_mode();
296 }
297 }
298
299 if (pcwd_private.supports_temp)
300 printk(KERN_INFO PFX "Temperature Option Detected\n");
301
302 if (pcwd_private.boot_status & WDIOF_CARDRESET)
303 printk(KERN_INFO PFX "Previous reboot was caused by the card\n");
304
305 if (pcwd_private.boot_status & WDIOF_OVERHEAT) {
306 printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n");
307 printk(KERN_EMERG PFX "CPU Overheat\n");
308 }
215 309
216 command_mode = 0; 310 if (pcwd_private.boot_status == 0)
311 printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
217} 312}
218 313
219static void pcwd_timer_ping(unsigned long data) 314static void pcwd_timer_ping(unsigned long data)
@@ -222,25 +317,25 @@ static void pcwd_timer_ping(unsigned long data)
222 317
223 /* If we got a heartbeat pulse within the WDT_INTERVAL 318 /* If we got a heartbeat pulse within the WDT_INTERVAL
224 * we agree to ping the WDT */ 319 * we agree to ping the WDT */
225 if(time_before(jiffies, next_heartbeat)) { 320 if(time_before(jiffies, pcwd_private.next_heartbeat)) {
226 /* Ping the watchdog */ 321 /* Ping the watchdog */
227 spin_lock(&io_lock); 322 spin_lock(&pcwd_private.io_lock);
228 if (revision == PCWD_REVISION_A) { 323 if (pcwd_private.revision == PCWD_REVISION_A) {
229 /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ 324 /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */
230 wdrst_stat = inb_p(current_readport); 325 wdrst_stat = inb_p(pcwd_private.io_addr);
231 wdrst_stat &= 0x0F; 326 wdrst_stat &= 0x0F;
232 wdrst_stat |= WD_WDRST; 327 wdrst_stat |= WD_WDRST;
233 328
234 outb_p(wdrst_stat, current_readport + 1); 329 outb_p(wdrst_stat, pcwd_private.io_addr + 1);
235 } else { 330 } else {
236 /* Re-trigger watchdog by writing to port 0 */ 331 /* Re-trigger watchdog by writing to port 0 */
237 outb_p(0x00, current_readport); 332 outb_p(0x00, pcwd_private.io_addr);
238 } 333 }
239 334
240 /* Re-set the timer interval */ 335 /* Re-set the timer interval */
241 mod_timer(&timer, jiffies + WDT_INTERVAL); 336 mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL);
242 337
243 spin_unlock(&io_lock); 338 spin_unlock(&pcwd_private.io_lock);
244 } else { 339 } else {
245 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 340 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
246 } 341 }
@@ -250,19 +345,19 @@ static int pcwd_start(void)
250{ 345{
251 int stat_reg; 346 int stat_reg;
252 347
253 next_heartbeat = jiffies + (heartbeat * HZ); 348 pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ);
254 349
255 /* Start the timer */ 350 /* Start the timer */
256 mod_timer(&timer, jiffies + WDT_INTERVAL); 351 mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL);
257 352
258 /* Enable the port */ 353 /* Enable the port */
259 if (revision == PCWD_REVISION_C) { 354 if (pcwd_private.revision == PCWD_REVISION_C) {
260 spin_lock(&io_lock); 355 spin_lock(&pcwd_private.io_lock);
261 outb_p(0x00, current_readport + 3); 356 outb_p(0x00, pcwd_private.io_addr + 3);
262 udelay(ISA_COMMAND_TIMEOUT); 357 udelay(ISA_COMMAND_TIMEOUT);
263 stat_reg = inb_p(current_readport + 2); 358 stat_reg = inb_p(pcwd_private.io_addr + 2);
264 spin_unlock(&io_lock); 359 spin_unlock(&pcwd_private.io_lock);
265 if (stat_reg & 0x10) { 360 if (stat_reg & WD_WDIS) {
266 printk(KERN_INFO PFX "Could not start watchdog\n"); 361 printk(KERN_INFO PFX "Could not start watchdog\n");
267 return -EIO; 362 return -EIO;
268 } 363 }
@@ -275,18 +370,18 @@ static int pcwd_stop(void)
275 int stat_reg; 370 int stat_reg;
276 371
277 /* Stop the timer */ 372 /* Stop the timer */
278 del_timer(&timer); 373 del_timer(&pcwd_private.timer);
279 374
280 /* Disable the board */ 375 /* Disable the board */
281 if (revision == PCWD_REVISION_C) { 376 if (pcwd_private.revision == PCWD_REVISION_C) {
282 spin_lock(&io_lock); 377 spin_lock(&pcwd_private.io_lock);
283 outb_p(0xA5, current_readport + 3); 378 outb_p(0xA5, pcwd_private.io_addr + 3);
284 udelay(ISA_COMMAND_TIMEOUT); 379 udelay(ISA_COMMAND_TIMEOUT);
285 outb_p(0xA5, current_readport + 3); 380 outb_p(0xA5, pcwd_private.io_addr + 3);
286 udelay(ISA_COMMAND_TIMEOUT); 381 udelay(ISA_COMMAND_TIMEOUT);
287 stat_reg = inb_p(current_readport + 2); 382 stat_reg = inb_p(pcwd_private.io_addr + 2);
288 spin_unlock(&io_lock); 383 spin_unlock(&pcwd_private.io_lock);
289 if ((stat_reg & 0x10) == 0) { 384 if ((stat_reg & WD_WDIS) == 0) {
290 printk(KERN_INFO PFX "Could not stop watchdog\n"); 385 printk(KERN_INFO PFX "Could not stop watchdog\n");
291 return -EIO; 386 return -EIO;
292 } 387 }
@@ -297,7 +392,7 @@ static int pcwd_stop(void)
297static int pcwd_keepalive(void) 392static int pcwd_keepalive(void)
298{ 393{
299 /* user land ping */ 394 /* user land ping */
300 next_heartbeat = jiffies + (heartbeat * HZ); 395 pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ);
301 return 0; 396 return 0;
302} 397}
303 398
@@ -315,23 +410,23 @@ static int pcwd_get_status(int *status)
315 int card_status; 410 int card_status;
316 411
317 *status=0; 412 *status=0;
318 spin_lock(&io_lock); 413 spin_lock(&pcwd_private.io_lock);
319 if (revision == PCWD_REVISION_A) 414 if (pcwd_private.revision == PCWD_REVISION_A)
320 /* Rev A cards return status information from 415 /* Rev A cards return status information from
321 * the base register, which is used for the 416 * the base register, which is used for the
322 * temperature in other cards. */ 417 * temperature in other cards. */
323 card_status = inb(current_readport); 418 card_status = inb(pcwd_private.io_addr);
324 else { 419 else {
325 /* Rev C cards return card status in the base 420 /* Rev C cards return card status in the base
326 * address + 1 register. And use different bits 421 * address + 1 register. And use different bits
327 * to indicate a card initiated reset, and an 422 * to indicate a card initiated reset, and an
328 * over-temperature condition. And the reboot 423 * over-temperature condition. And the reboot
329 * status can be reset. */ 424 * status can be reset. */
330 card_status = inb(current_readport + 1); 425 card_status = inb(pcwd_private.io_addr + 1);
331 } 426 }
332 spin_unlock(&io_lock); 427 spin_unlock(&pcwd_private.io_lock);
333 428
334 if (revision == PCWD_REVISION_A) { 429 if (pcwd_private.revision == PCWD_REVISION_A) {
335 if (card_status & WD_WDRST) 430 if (card_status & WD_WDRST)
336 *status |= WDIOF_CARDRESET; 431 *status |= WDIOF_CARDRESET;
337 432
@@ -360,10 +455,10 @@ static int pcwd_get_status(int *status)
360 455
361static int pcwd_clear_status(void) 456static int pcwd_clear_status(void)
362{ 457{
363 if (revision == PCWD_REVISION_C) { 458 if (pcwd_private.revision == PCWD_REVISION_C) {
364 spin_lock(&io_lock); 459 spin_lock(&pcwd_private.io_lock);
365 outb_p(0x00, current_readport + 1); /* clear reset status */ 460 outb_p(0x00, pcwd_private.io_addr + 1); /* clear reset status */
366 spin_unlock(&io_lock); 461 spin_unlock(&pcwd_private.io_lock);
367 } 462 }
368 return 0; 463 return 0;
369} 464}
@@ -371,20 +466,20 @@ static int pcwd_clear_status(void)
371static int pcwd_get_temperature(int *temperature) 466static int pcwd_get_temperature(int *temperature)
372{ 467{
373 /* check that port 0 gives temperature info and no command results */ 468 /* check that port 0 gives temperature info and no command results */
374 if (command_mode) 469 if (pcwd_private.command_mode)
375 return -1; 470 return -1;
376 471
377 *temperature = 0; 472 *temperature = 0;
378 if (!supports_temp) 473 if (!pcwd_private.supports_temp)
379 return -ENODEV; 474 return -ENODEV;
380 475
381 /* 476 /*
382 * Convert celsius to fahrenheit, since this was 477 * Convert celsius to fahrenheit, since this was
383 * the decided 'standard' for this return value. 478 * the decided 'standard' for this return value.
384 */ 479 */
385 spin_lock(&io_lock); 480 spin_lock(&pcwd_private.io_lock);
386 *temperature = ((inb(current_readport)) * 9 / 5) + 32; 481 *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32;
387 spin_unlock(&io_lock); 482 spin_unlock(&pcwd_private.io_lock);
388 483
389 return 0; 484 return 0;
390} 485}
@@ -425,7 +520,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
425 return put_user(status, argp); 520 return put_user(status, argp);
426 521
427 case WDIOC_GETBOOTSTATUS: 522 case WDIOC_GETBOOTSTATUS:
428 return put_user(initial_status, argp); 523 return put_user(pcwd_private.boot_status, argp);
429 524
430 case WDIOC_GETTEMP: 525 case WDIOC_GETTEMP:
431 if (pcwd_get_temperature(&temperature)) 526 if (pcwd_get_temperature(&temperature))
@@ -434,7 +529,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
434 return put_user(temperature, argp); 529 return put_user(temperature, argp);
435 530
436 case WDIOC_SETOPTIONS: 531 case WDIOC_SETOPTIONS:
437 if (revision == PCWD_REVISION_C) 532 if (pcwd_private.revision == PCWD_REVISION_C)
438 { 533 {
439 if(copy_from_user(&rv, argp, sizeof(int))) 534 if(copy_from_user(&rv, argp, sizeof(int)))
440 return -EFAULT; 535 return -EFAULT;
@@ -550,7 +645,7 @@ static ssize_t pcwd_temp_read(struct file *file, char __user *buf, size_t count,
550 645
551static int pcwd_temp_open(struct inode *inode, struct file *file) 646static int pcwd_temp_open(struct inode *inode, struct file *file)
552{ 647{
553 if (!supports_temp) 648 if (!pcwd_private.supports_temp)
554 return -ENODEV; 649 return -ENODEV;
555 650
556 return nonseekable_open(inode, file); 651 return nonseekable_open(inode, file);
@@ -616,68 +711,24 @@ static struct notifier_block pcwd_notifier = {
616 * Init & exit routines 711 * Init & exit routines
617 */ 712 */
618 713
619static inline void get_support(void)
620{
621 if (inb(current_readport) != 0xF0)
622 supports_temp = 1;
623}
624
625static inline int get_revision(void) 714static inline int get_revision(void)
626{ 715{
627 int r = PCWD_REVISION_C; 716 int r = PCWD_REVISION_C;
628 717
629 spin_lock(&io_lock); 718 spin_lock(&pcwd_private.io_lock);
630 /* REV A cards use only 2 io ports; test 719 /* REV A cards use only 2 io ports; test
631 * presumes a floating bus reads as 0xff. */ 720 * presumes a floating bus reads as 0xff. */
632 if ((inb(current_readport + 2) == 0xFF) || 721 if ((inb(pcwd_private.io_addr + 2) == 0xFF) ||
633 (inb(current_readport + 3) == 0xFF)) 722 (inb(pcwd_private.io_addr + 3) == 0xFF))
634 r=PCWD_REVISION_A; 723 r=PCWD_REVISION_A;
635 spin_unlock(&io_lock); 724 spin_unlock(&pcwd_private.io_lock);
636 725
637 return r; 726 return r;
638} 727}
639 728
640static inline char *get_firmware(void)
641{
642 int one, ten, hund, minor;
643 char *ret;
644
645 ret = kmalloc(6, GFP_KERNEL);
646 if(ret == NULL)
647 return NULL;
648
649 if (set_command_mode()) {
650 one = send_isa_command(CMD_ISA_VERSION_INTEGER);
651 ten = send_isa_command(CMD_ISA_VERSION_TENTH);
652 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH);
653 minor = send_isa_command(CMD_ISA_VERSION_MINOR);
654 sprintf(ret, "%c.%c%c%c", one, ten, hund, minor);
655 }
656 else
657 sprintf(ret, "ERROR");
658
659 unset_command_mode();
660 return(ret);
661}
662
663static inline int get_option_switches(void)
664{
665 int rv=0;
666
667 if (set_command_mode()) {
668 /* Get switch settings */
669 rv = send_isa_command(CMD_ISA_SWITCH_SETTINGS);
670 }
671
672 unset_command_mode();
673 return(rv);
674}
675
676static int __devinit pcwatchdog_init(int base_addr) 729static int __devinit pcwatchdog_init(int base_addr)
677{ 730{
678 int ret; 731 int ret;
679 char *firmware;
680 int option_switches;
681 732
682 cards_found++; 733 cards_found++;
683 if (cards_found == 1) 734 if (cards_found == 1)
@@ -692,104 +743,66 @@ static int __devinit pcwatchdog_init(int base_addr)
692 printk(KERN_ERR PFX "No I/O-Address for card detected\n"); 743 printk(KERN_ERR PFX "No I/O-Address for card detected\n");
693 return -ENODEV; 744 return -ENODEV;
694 } 745 }
695 current_readport = base_addr; 746 pcwd_private.io_addr = base_addr;
696 747
697 /* Check card's revision */ 748 /* Check card's revision */
698 revision = get_revision(); 749 pcwd_private.revision = get_revision();
699 750
700 if (!request_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { 751 if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) {
701 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 752 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
702 current_readport); 753 pcwd_private.io_addr);
703 current_readport = 0x0000; 754 pcwd_private.io_addr = 0x0000;
704 return -EIO; 755 return -EIO;
705 } 756 }
706 757
707 /* Initial variables */ 758 /* Initial variables */
708 supports_temp = 0; 759 pcwd_private.supports_temp = 0;
709 temp_panic = 0; 760 temp_panic = 0;
710 initial_status = 0x0000; 761 pcwd_private.boot_status = 0x0000;
711 762
712 /* get the boot_status */ 763 /* get the boot_status */
713 pcwd_get_status(&initial_status); 764 pcwd_get_status(&pcwd_private.boot_status);
714 765
715 /* clear the "card caused reboot" flag */ 766 /* clear the "card caused reboot" flag */
716 pcwd_clear_status(); 767 pcwd_clear_status();
717 768
718 init_timer(&timer); 769 init_timer(&pcwd_private.timer);
719 timer.function = pcwd_timer_ping; 770 pcwd_private.timer.function = pcwd_timer_ping;
720 timer.data = 0; 771 pcwd_private.timer.data = 0;
721 772
722 /* Disable the board */ 773 /* Disable the board */
723 pcwd_stop(); 774 pcwd_stop();
724 775
725 /* Check whether or not the card supports the temperature device */ 776 /* Check whether or not the card supports the temperature device */
726 get_support(); 777 pcwd_check_temperature_support();
727
728 /* Get some extra info from the hardware (in command/debug/diag mode) */
729 if (revision == PCWD_REVISION_A)
730 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", current_readport);
731 else if (revision == PCWD_REVISION_C) {
732 firmware = get_firmware();
733 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n",
734 current_readport, firmware);
735 kfree(firmware);
736 option_switches = get_option_switches();
737 printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
738 option_switches,
739 ((option_switches & 0x10) ? "ON" : "OFF"),
740 ((option_switches & 0x08) ? "ON" : "OFF"));
741
742 /* Reprogram internal heartbeat to 2 seconds */
743 if (set_command_mode()) {
744 send_isa_command(CMD_ISA_DELAY_TIME_2SECS);
745 unset_command_mode();
746 }
747 } else {
748 /* Should NEVER happen, unless get_revision() fails. */
749 printk(KERN_INFO PFX "Unable to get revision\n");
750 release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4);
751 current_readport = 0x0000;
752 return -1;
753 }
754 778
755 if (supports_temp) 779 /* Show info about the card itself */
756 printk(KERN_INFO PFX "Temperature Option Detected\n"); 780 pcwd_show_card_info();
757
758 if (initial_status & WDIOF_CARDRESET)
759 printk(KERN_INFO PFX "Previous reboot was caused by the card\n");
760
761 if (initial_status & WDIOF_OVERHEAT) {
762 printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n");
763 printk(KERN_EMERG PFX "CPU Overheat\n");
764 }
765
766 if (initial_status == 0)
767 printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
768 781
769 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 782 /* Check that the heartbeat value is within it's range ; if not reset to the default */
770 if (pcwd_set_heartbeat(heartbeat)) { 783 if (pcwd_set_heartbeat(heartbeat)) {
771 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 784 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
772 printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", 785 printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n",
773 WATCHDOG_HEARTBEAT); 786 WATCHDOG_HEARTBEAT);
774 } 787 }
775 788
776 ret = register_reboot_notifier(&pcwd_notifier); 789 ret = register_reboot_notifier(&pcwd_notifier);
777 if (ret) { 790 if (ret) {
778 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 791 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
779 ret); 792 ret);
780 release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 793 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
781 current_readport = 0x0000; 794 pcwd_private.io_addr = 0x0000;
782 return ret; 795 return ret;
783 } 796 }
784 797
785 if (supports_temp) { 798 if (pcwd_private.supports_temp) {
786 ret = misc_register(&temp_miscdev); 799 ret = misc_register(&temp_miscdev);
787 if (ret) { 800 if (ret) {
788 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 801 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
789 TEMP_MINOR, ret); 802 TEMP_MINOR, ret);
790 unregister_reboot_notifier(&pcwd_notifier); 803 unregister_reboot_notifier(&pcwd_notifier);
791 release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 804 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
792 current_readport = 0x0000; 805 pcwd_private.io_addr = 0x0000;
793 return ret; 806 return ret;
794 } 807 }
795 } 808 }
@@ -798,11 +811,11 @@ static int __devinit pcwatchdog_init(int base_addr)
798 if (ret) { 811 if (ret) {
799 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 812 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
800 WATCHDOG_MINOR, ret); 813 WATCHDOG_MINOR, ret);
801 if (supports_temp) 814 if (pcwd_private.supports_temp)
802 misc_deregister(&temp_miscdev); 815 misc_deregister(&temp_miscdev);
803 unregister_reboot_notifier(&pcwd_notifier); 816 unregister_reboot_notifier(&pcwd_notifier);
804 release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 817 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
805 current_readport = 0x0000; 818 pcwd_private.io_addr = 0x0000;
806 return ret; 819 return ret;
807 } 820 }
808 821
@@ -820,11 +833,12 @@ static void __devexit pcwatchdog_exit(void)
820 833
821 /* Deregister */ 834 /* Deregister */
822 misc_deregister(&pcwd_miscdev); 835 misc_deregister(&pcwd_miscdev);
823 if (supports_temp) 836 if (pcwd_private.supports_temp)
824 misc_deregister(&temp_miscdev); 837 misc_deregister(&temp_miscdev);
825 unregister_reboot_notifier(&pcwd_notifier); 838 unregister_reboot_notifier(&pcwd_notifier);
826 release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 839 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
827 current_readport = 0x0000; 840 pcwd_private.io_addr = 0x0000;
841 cards_found--;
828} 842}
829 843
830/* 844/*
@@ -887,7 +901,7 @@ static int __init pcwd_init_module(void)
887{ 901{
888 int i, found = 0; 902 int i, found = 0;
889 903
890 spin_lock_init(&io_lock); 904 spin_lock_init(&pcwd_private.io_lock);
891 905
892 for (i = 0; pcwd_ioports[i] != 0; i++) { 906 for (i = 0; pcwd_ioports[i] != 0; i++) {
893 if (pcwd_checkcard(pcwd_ioports[i])) { 907 if (pcwd_checkcard(pcwd_ioports[i])) {
@@ -906,7 +920,7 @@ static int __init pcwd_init_module(void)
906 920
907static void __exit pcwd_cleanup_module(void) 921static void __exit pcwd_cleanup_module(void)
908{ 922{
909 if (current_readport) 923 if (pcwd_private.io_addr)
910 pcwatchdog_exit(); 924 pcwatchdog_exit();
911 return; 925 return;
912} 926}
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index b474ea52d6e8..522a9370db94 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -93,23 +93,25 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
93{ 93{
94 int ret = -ENOIOCTLCMD; 94 int ret = -ENOIOCTLCMD;
95 int time; 95 int time;
96 void __user *argp = (void __user *)arg;
97 int __user *p = argp;
96 98
97 switch (cmd) { 99 switch (cmd) {
98 case WDIOC_GETSUPPORT: 100 case WDIOC_GETSUPPORT:
99 ret = copy_to_user((struct watchdog_info __user *)arg, &ident, 101 ret = copy_to_user(argp, &ident,
100 sizeof(ident)) ? -EFAULT : 0; 102 sizeof(ident)) ? -EFAULT : 0;
101 break; 103 break;
102 104
103 case WDIOC_GETSTATUS: 105 case WDIOC_GETSTATUS:
104 ret = put_user(0, (int __user *)arg); 106 ret = put_user(0, p);
105 break; 107 break;
106 108
107 case WDIOC_GETBOOTSTATUS: 109 case WDIOC_GETBOOTSTATUS:
108 ret = put_user(boot_status, (int __user *)arg); 110 ret = put_user(boot_status, p);
109 break; 111 break;
110 112
111 case WDIOC_SETTIMEOUT: 113 case WDIOC_SETTIMEOUT:
112 ret = get_user(time, (int __user *)arg); 114 ret = get_user(time, p);
113 if (ret) 115 if (ret)
114 break; 116 break;
115 117
@@ -123,7 +125,7 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
123 /*fall through*/ 125 /*fall through*/
124 126
125 case WDIOC_GETTIMEOUT: 127 case WDIOC_GETTIMEOUT:
126 ret = put_user(pre_margin / OSCR_FREQ, (int __user *)arg); 128 ret = put_user(pre_margin / OSCR_FREQ, p);
127 break; 129 break;
128 130
129 case WDIOC_KEEPALIVE: 131 case WDIOC_KEEPALIVE: