diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/Kconfig | 55 | ||||
-rw-r--r-- | drivers/char/agp/amd64-agp.c | 6 | ||||
-rw-r--r-- | drivers/char/agp/sworks-agp.c | 4 | ||||
-rw-r--r-- | drivers/char/drm/drm_pciids.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/i915_irq.c | 5 | ||||
-rw-r--r-- | drivers/char/drm/r300_cmdbuf.c | 48 | ||||
-rw-r--r-- | drivers/char/drm/r300_reg.h | 3 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drv.h | 3 | ||||
-rw-r--r-- | drivers/char/esp.c | 22 | ||||
-rw-r--r-- | drivers/char/hpet.c | 22 | ||||
-rw-r--r-- | drivers/char/hvc_console.c | 8 | ||||
-rw-r--r-- | drivers/char/sysrq.c | 2 | ||||
-rw-r--r-- | drivers/char/tipar.c | 15 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 48 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 37 | ||||
-rw-r--r-- | drivers/char/watchdog/pcwd.c | 450 | ||||
-rw-r--r-- | drivers/char/watchdog/sa1100_wdt.c | 12 |
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 | |||
28 | config AGP_ALI | 29 | config 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 | |||
46 | config AGP_ATI | 44 | config 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 | ||
56 | config AGP_AMD | 51 | config 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 | ||
66 | config AGP_AMD64 | 58 | config 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 | ||
79 | config AGP_INTEL | 69 | config 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 | ||
92 | config AGP_NVIDIA | 80 | config 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 | ||
100 | config AGP_SIS | 87 | config 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 | ||
112 | config AGP_SWORKS | 97 | config 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 | ||
129 | config AGP_I460 | 111 | config 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 | |||
165 | config AGP_SGI_TIOCA | 144 | config 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) | |||
202 | void i915_driver_irq_uninstall(drm_device_t * dev) | 202 | void 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 | } |
493 | static __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 | ||
493 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | 538 | static __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 | */ | ||
162 | static unsigned char *tmp_buf; | ||
163 | |||
164 | static inline int serial_paranoia_check(struct esp_struct *info, | 153 | static 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 | ||
244 | static void moom_callback(void *ignored) | 244 | static 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 | ||
249 | static DECLARE_WORK(moom_work, moom_callback, NULL); | 249 | static 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 | ||
527 | out_class: | ||
528 | class_destroy(tipar_class); | ||
529 | |||
522 | out_chrdev: | 530 | out_chrdev: |
531 | devfs_remove("ticables/par"); | ||
523 | unregister_chrdev(TIPAR_MAJOR, "tipar"); | 532 | unregister_chrdev(TIPAR_MAJOR, "tipar"); |
524 | out: | 533 | out: |
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 @@ | |||
33 | static int TPM_INF_DATA; | 33 | static int TPM_INF_DATA; |
34 | static int TPM_INF_ADDR; | 34 | static int TPM_INF_ADDR; |
35 | static int TPM_INF_BASE; | 35 | static int TPM_INF_BASE; |
36 | static int TPM_INF_ADDR_LEN; | ||
36 | static int TPM_INF_PORT_LEN; | 37 | static 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 | ||
199 | recv_begin: | 201 | recv_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 | |||
496 | err_release_region: | ||
497 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | ||
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | ||
499 | |||
500 | err_last: | ||
501 | return rc; | ||
482 | } | 502 | } |
483 | 503 | ||
484 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | 504 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) |
@@ -518,5 +538,5 @@ module_exit(cleanup_inf); | |||
518 | 538 | ||
519 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 539 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
520 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 540 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
521 | MODULE_VERSION("1.6"); | 541 | MODULE_VERSION("1.7"); |
522 | MODULE_LICENSE("GPL"); | 542 | MODULE_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 */ |
131 | static atomic_t open_allowed = ATOMIC_INIT(1); | 141 | static atomic_t open_allowed = ATOMIC_INIT(1); |
132 | static char expect_close; | 142 | static char expect_close; |
133 | static struct timer_list timer; | ||
134 | static unsigned long next_heartbeat; | ||
135 | static int temp_panic; | 143 | static int temp_panic; |
136 | static int revision; /* The card's revision */ | 144 | static struct { /* this is private data for each ISA-PC watchdog card */ |
137 | static int supports_temp; /* Wether or not the card has a temperature device */ | 145 | int revision; /* The card's revision */ |
138 | static 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 */ |
139 | static int initial_status; /* The card's boot status */ | 147 | int command_mode; /* Wether or not the card is in command mode */ |
140 | static int current_readport; /* The cards I/O address */ | 148 | int boot_status; /* The card's boot status */ |
141 | static 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) | |||
208 | static void unset_command_mode(void) | 220 | static 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 | |||
231 | static inline void pcwd_check_temperature_support(void) | ||
232 | { | ||
233 | if (inb(pcwd_private.io_addr) != 0xF0) | ||
234 | pcwd_private.supports_temp = 1; | ||
235 | } | ||
236 | |||
237 | static 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 | |||
260 | static 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 | |||
273 | static 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 | ||
219 | static void pcwd_timer_ping(unsigned long data) | 314 | static 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) | |||
297 | static int pcwd_keepalive(void) | 392 | static 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 | ||
361 | static int pcwd_clear_status(void) | 456 | static 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) | |||
371 | static int pcwd_get_temperature(int *temperature) | 466 | static 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 | ||
551 | static int pcwd_temp_open(struct inode *inode, struct file *file) | 646 | static 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 | ||
619 | static inline void get_support(void) | ||
620 | { | ||
621 | if (inb(current_readport) != 0xF0) | ||
622 | supports_temp = 1; | ||
623 | } | ||
624 | |||
625 | static inline int get_revision(void) | 714 | static 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 | ||
640 | static 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 | |||
663 | static 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 | |||
676 | static int __devinit pcwatchdog_init(int base_addr) | 729 | static 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 | ||
907 | static void __exit pcwd_cleanup_module(void) | 921 | static 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: |