aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/Makefile1
-rw-r--r--drivers/char/agp/agp.h12
-rw-r--r--drivers/char/agp/ali-agp.c2
-rw-r--r--drivers/char/agp/alpha-agp.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c1
-rw-r--r--drivers/char/agp/amd64-agp.c11
-rw-r--r--drivers/char/agp/ati-agp.c1
-rw-r--r--drivers/char/agp/backend.c2
-rw-r--r--drivers/char/agp/compat_ioctl.c282
-rw-r--r--drivers/char/agp/compat_ioctl.h105
-rw-r--r--drivers/char/agp/efficeon-agp.c1
-rw-r--r--drivers/char/agp/frontend.c34
-rw-r--r--drivers/char/agp/generic.c125
-rw-r--r--drivers/char/agp/hp-agp.c1
-rw-r--r--drivers/char/agp/i460-agp.c7
-rw-r--r--drivers/char/agp/intel-agp.c202
-rw-r--r--drivers/char/agp/nvidia-agp.c1
-rw-r--r--drivers/char/agp/parisc-agp.c1
-rw-r--r--drivers/char/agp/sgi-agp.c1
-rw-r--r--drivers/char/agp/sis-agp.c1
-rw-r--r--drivers/char/agp/sworks-agp.c1
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/agp/via-agp.c2
-rw-r--r--drivers/char/briq_panel.c1
-rw-r--r--drivers/char/drm/ffb_context.c1
-rw-r--r--drivers/char/drm/ffb_drv.c1
-rw-r--r--drivers/char/ds1620.c1
-rw-r--r--drivers/char/dsp56k.c1
-rw-r--r--drivers/char/hangcheck-timer.c2
-rw-r--r--drivers/char/hpet.c6
-rw-r--r--drivers/char/hvsi.c1
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c1
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c2
-rw-r--r--drivers/char/keyboard.c1
-rw-r--r--drivers/char/nvram.c1
-rw-r--r--drivers/char/nwflash.c1
-rw-r--r--drivers/char/pty.c1
-rw-r--r--drivers/char/rtc.c8
-rw-r--r--drivers/char/ser_a2232.c1
-rw-r--r--drivers/char/sonypi.c1
-rw-r--r--drivers/char/sysrq.c15
-rw-r--r--drivers/char/tlclk.c1
-rw-r--r--drivers/char/toshiba.c1
-rw-r--r--drivers/char/tpm/tpm.c1
-rw-r--r--drivers/char/tty_io.c3
-rw-r--r--drivers/char/vc_screen.c1
-rw-r--r--drivers/char/vme_scc.c1
-rw-r--r--drivers/char/vt.c1
-rw-r--r--drivers/char/watchdog/acquirewdt.c155
-rw-r--r--drivers/char/watchdog/advantechwdt.c142
-rw-r--r--drivers/char/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c15
-rw-r--r--drivers/char/watchdog/cpu5wdt.c13
-rw-r--r--drivers/char/watchdog/eurotechwdt.c2
-rw-r--r--drivers/char/watchdog/i6300esb.c2
-rw-r--r--drivers/char/watchdog/i8xx_tco.c2
-rw-r--r--drivers/char/watchdog/iTCO_wdt.c6
-rw-r--r--drivers/char/watchdog/ib700wdt.c192
-rw-r--r--drivers/char/watchdog/ibmasr.c2
-rw-r--r--drivers/char/watchdog/indydog.c2
-rw-r--r--drivers/char/watchdog/machzwd.c18
-rw-r--r--drivers/char/watchdog/mixcomwd.c16
-rw-r--r--drivers/char/watchdog/pc87413_wdt.c2
-rw-r--r--drivers/char/watchdog/pcwd.c32
-rw-r--r--drivers/char/watchdog/pcwd_pci.c34
-rw-r--r--drivers/char/watchdog/pcwd_usb.c63
-rw-r--r--drivers/char/watchdog/pnx4008_wdt.c3
-rw-r--r--drivers/char/watchdog/rm9k_wdt.c2
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c62
-rw-r--r--drivers/char/watchdog/sbc60xxwdt.c14
-rw-r--r--drivers/char/watchdog/sbc8360.c2
-rw-r--r--drivers/char/watchdog/sbc_epx_c3.c2
-rw-r--r--drivers/char/watchdog/sc1200wdt.c2
-rw-r--r--drivers/char/watchdog/sc520_wdt.c14
-rw-r--r--drivers/char/watchdog/shwdt.c8
-rw-r--r--drivers/char/watchdog/smsc37b787_wdt.c2
-rw-r--r--drivers/char/watchdog/softdog.c2
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/char/watchdog/w83697hf_wdt.c2
-rw-r--r--drivers/char/watchdog/w83877f_wdt.c14
-rw-r--r--drivers/char/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/char/watchdog/wafer5823wdt.c2
-rw-r--r--drivers/char/watchdog/wdt.c2
-rw-r--r--drivers/char/watchdog/wdt977.c2
-rw-r--r--drivers/char/watchdog/wdt_pci.c2
86 files changed, 1215 insertions, 482 deletions
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index 3e581603d0a..a0d04a23dac 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -1,6 +1,7 @@
1agpgart-y := backend.o frontend.o generic.o isoch.o 1agpgart-y := backend.o frontend.o generic.o isoch.o
2 2
3obj-$(CONFIG_AGP) += agpgart.o 3obj-$(CONFIG_AGP) += agpgart.o
4obj-$(CONFIG_COMPAT) += compat_ioctl.o
4obj-$(CONFIG_AGP_ALI) += ali-agp.o 5obj-$(CONFIG_AGP_ALI) += ali-agp.o
5obj-$(CONFIG_AGP_ATI) += ati-agp.o 6obj-$(CONFIG_AGP_ATI) += ati-agp.o
6obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o 7obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 1d59e2a5b9a..9bd68d9f0f5 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -114,6 +114,7 @@ struct agp_bridge_driver {
114 void (*free_by_type)(struct agp_memory *); 114 void (*free_by_type)(struct agp_memory *);
115 void *(*agp_alloc_page)(struct agp_bridge_data *); 115 void *(*agp_alloc_page)(struct agp_bridge_data *);
116 void (*agp_destroy_page)(void *); 116 void (*agp_destroy_page)(void *);
117 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
117}; 118};
118 119
119struct agp_bridge_data { 120struct agp_bridge_data {
@@ -218,6 +219,7 @@ struct agp_bridge_data {
218#define I810_PTE_MAIN_UNCACHED 0x00000000 219#define I810_PTE_MAIN_UNCACHED 0x00000000
219#define I810_PTE_LOCAL 0x00000002 220#define I810_PTE_LOCAL 0x00000002
220#define I810_PTE_VALID 0x00000001 221#define I810_PTE_VALID 0x00000001
222#define I830_PTE_SYSTEM_CACHED 0x00000006
221#define I810_SMRAM_MISCC 0x70 223#define I810_SMRAM_MISCC 0x70
222#define I810_GFX_MEM_WIN_SIZE 0x00010000 224#define I810_GFX_MEM_WIN_SIZE 0x00010000
223#define I810_GFX_MEM_WIN_32M 0x00010000 225#define I810_GFX_MEM_WIN_32M 0x00010000
@@ -270,8 +272,16 @@ void global_cache_flush(void);
270void get_agp_version(struct agp_bridge_data *bridge); 272void get_agp_version(struct agp_bridge_data *bridge);
271unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, 273unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,
272 unsigned long addr, int type); 274 unsigned long addr, int type);
275int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge,
276 int type);
273struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); 277struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev);
274 278
279/* generic functions for user-populated AGP memory types */
280struct agp_memory *agp_generic_alloc_user(size_t page_count, int type);
281void agp_alloc_page_array(size_t size, struct agp_memory *mem);
282void agp_free_page_array(struct agp_memory *mem);
283
284
275/* generic routines for agp>=3 */ 285/* generic routines for agp>=3 */
276int agp3_generic_fetch_size(void); 286int agp3_generic_fetch_size(void);
277void agp3_generic_tlbflush(struct agp_memory *mem); 287void agp3_generic_tlbflush(struct agp_memory *mem);
@@ -288,6 +298,8 @@ extern struct aper_size_info_16 agp3_generic_sizes[];
288extern int agp_off; 298extern int agp_off;
289extern int agp_try_unsupported_boot; 299extern int agp_try_unsupported_boot;
290 300
301long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
302
291/* Chipset independant registers (from AGP Spec) */ 303/* Chipset independant registers (from AGP Spec) */
292#define AGP_APBASE 0x10 304#define AGP_APBASE 0x10
293 305
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 5a31ec7c62f..98177a93076 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -214,6 +214,7 @@ static struct agp_bridge_driver ali_generic_bridge = {
214 .free_by_type = agp_generic_free_by_type, 214 .free_by_type = agp_generic_free_by_type,
215 .agp_alloc_page = agp_generic_alloc_page, 215 .agp_alloc_page = agp_generic_alloc_page,
216 .agp_destroy_page = ali_destroy_page, 216 .agp_destroy_page = ali_destroy_page,
217 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
217}; 218};
218 219
219static struct agp_bridge_driver ali_m1541_bridge = { 220static struct agp_bridge_driver ali_m1541_bridge = {
@@ -237,6 +238,7 @@ static struct agp_bridge_driver ali_m1541_bridge = {
237 .free_by_type = agp_generic_free_by_type, 238 .free_by_type = agp_generic_free_by_type,
238 .agp_alloc_page = m1541_alloc_page, 239 .agp_alloc_page = m1541_alloc_page,
239 .agp_destroy_page = m1541_destroy_page, 240 .agp_destroy_page = m1541_destroy_page,
241 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
240}; 242};
241 243
242 244
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
index b4e00a343da..b0acf41c0db 100644
--- a/drivers/char/agp/alpha-agp.c
+++ b/drivers/char/agp/alpha-agp.c
@@ -91,6 +91,9 @@ static int alpha_core_agp_insert_memory(struct agp_memory *mem, off_t pg_start,
91 int num_entries, status; 91 int num_entries, status;
92 void *temp; 92 void *temp;
93 93
94 if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
95 return -EINVAL;
96
94 temp = agp_bridge->current_size; 97 temp = agp_bridge->current_size;
95 num_entries = A_SIZE_FIX(temp)->num_entries; 98 num_entries = A_SIZE_FIX(temp)->num_entries;
96 if ((pg_start + mem->page_count) > num_entries) 99 if ((pg_start + mem->page_count) > num_entries)
@@ -142,6 +145,7 @@ struct agp_bridge_driver alpha_core_agp_driver = {
142 .free_by_type = agp_generic_free_by_type, 145 .free_by_type = agp_generic_free_by_type,
143 .agp_alloc_page = agp_generic_alloc_page, 146 .agp_alloc_page = agp_generic_alloc_page,
144 .agp_destroy_page = agp_generic_destroy_page, 147 .agp_destroy_page = agp_generic_destroy_page,
148 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
145}; 149};
146 150
147struct agp_bridge_data *alpha_bridge; 151struct agp_bridge_data *alpha_bridge;
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index c85c8cadb6d..3d8d448bf39 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -381,6 +381,7 @@ static struct agp_bridge_driver amd_irongate_driver = {
381 .free_by_type = agp_generic_free_by_type, 381 .free_by_type = agp_generic_free_by_type,
382 .agp_alloc_page = agp_generic_alloc_page, 382 .agp_alloc_page = agp_generic_alloc_page,
383 .agp_destroy_page = agp_generic_destroy_page, 383 .agp_destroy_page = agp_generic_destroy_page,
384 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
384}; 385};
385 386
386static struct agp_device_ids amd_agp_device_ids[] __devinitdata = 387static struct agp_device_ids amd_agp_device_ids[] __devinitdata =
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 93d2209fee4..636d984ed4a 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -62,12 +62,18 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
62{ 62{
63 int i, j, num_entries; 63 int i, j, num_entries;
64 long long tmp; 64 long long tmp;
65 int mask_type;
66 struct agp_bridge_data *bridge = mem->bridge;
65 u32 pte; 67 u32 pte;
66 68
67 num_entries = agp_num_entries(); 69 num_entries = agp_num_entries();
68 70
69 if (type != 0 || mem->type != 0) 71 if (type != mem->type)
70 return -EINVAL; 72 return -EINVAL;
73 mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
74 if (mask_type != 0)
75 return -EINVAL;
76
71 77
72 /* Make sure we can fit the range in the gatt table. */ 78 /* Make sure we can fit the range in the gatt table. */
73 /* FIXME: could wrap */ 79 /* FIXME: could wrap */
@@ -90,7 +96,7 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
90 96
91 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 97 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
92 tmp = agp_bridge->driver->mask_memory(agp_bridge, 98 tmp = agp_bridge->driver->mask_memory(agp_bridge,
93 mem->memory[i], mem->type); 99 mem->memory[i], mask_type);
94 100
95 BUG_ON(tmp & 0xffffff0000000ffcULL); 101 BUG_ON(tmp & 0xffffff0000000ffcULL);
96 pte = (tmp & 0x000000ff00000000ULL) >> 28; 102 pte = (tmp & 0x000000ff00000000ULL) >> 28;
@@ -247,6 +253,7 @@ static struct agp_bridge_driver amd_8151_driver = {
247 .free_by_type = agp_generic_free_by_type, 253 .free_by_type = agp_generic_free_by_type,
248 .agp_alloc_page = agp_generic_alloc_page, 254 .agp_alloc_page = agp_generic_alloc_page,
249 .agp_destroy_page = agp_generic_destroy_page, 255 .agp_destroy_page = agp_generic_destroy_page,
256 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
250}; 257};
251 258
252/* Some basic sanity checks for the aperture. */ 259/* Some basic sanity checks for the aperture. */
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 9987dc2e0c3..77c9ad68fba 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -431,6 +431,7 @@ static struct agp_bridge_driver ati_generic_bridge = {
431 .free_by_type = agp_generic_free_by_type, 431 .free_by_type = agp_generic_free_by_type,
432 .agp_alloc_page = agp_generic_alloc_page, 432 .agp_alloc_page = agp_generic_alloc_page,
433 .agp_destroy_page = agp_generic_destroy_page, 433 .agp_destroy_page = agp_generic_destroy_page,
434 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
434}; 435};
435 436
436 437
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index d59e037ddd1..ebdd6dd66ed 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -43,7 +43,7 @@
43 * fix some real stupidity. It's only by chance we can bump 43 * fix some real stupidity. It's only by chance we can bump
44 * past 0.99 at all due to some boolean logic error. */ 44 * past 0.99 at all due to some boolean logic error. */
45#define AGPGART_VERSION_MAJOR 0 45#define AGPGART_VERSION_MAJOR 0
46#define AGPGART_VERSION_MINOR 101 46#define AGPGART_VERSION_MINOR 102
47static const struct agp_version agp_current_version = 47static const struct agp_version agp_current_version =
48{ 48{
49 .major = AGPGART_VERSION_MAJOR, 49 .major = AGPGART_VERSION_MAJOR,
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c
new file mode 100644
index 00000000000..fcb4b1bf0d4
--- /dev/null
+++ b/drivers/char/agp/compat_ioctl.c
@@ -0,0 +1,282 @@
1/*
2 * AGPGART driver frontend compatibility ioctls
3 * Copyright (C) 2004 Silicon Graphics, Inc.
4 * Copyright (C) 2002-2003 Dave Jones
5 * Copyright (C) 1999 Jeff Hartmann
6 * Copyright (C) 1999 Precision Insight, Inc.
7 * Copyright (C) 1999 Xi Graphics, Inc.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29#include <linux/kernel.h>
30#include <linux/pci.h>
31#include <linux/agpgart.h>
32#include <asm/uaccess.h>
33#include "agp.h"
34#include "compat_ioctl.h"
35
36static int compat_agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
37{
38 struct agp_info32 userinfo;
39 struct agp_kern_info kerninfo;
40
41 agp_copy_info(agp_bridge, &kerninfo);
42
43 userinfo.version.major = kerninfo.version.major;
44 userinfo.version.minor = kerninfo.version.minor;
45 userinfo.bridge_id = kerninfo.device->vendor |
46 (kerninfo.device->device << 16);
47 userinfo.agp_mode = kerninfo.mode;
48 userinfo.aper_base = (compat_long_t)kerninfo.aper_base;
49 userinfo.aper_size = kerninfo.aper_size;
50 userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
51 userinfo.pg_used = kerninfo.current_memory;
52
53 if (copy_to_user(arg, &userinfo, sizeof(userinfo)))
54 return -EFAULT;
55
56 return 0;
57}
58
59static int compat_agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
60{
61 struct agp_region32 ureserve;
62 struct agp_region kreserve;
63 struct agp_client *client;
64 struct agp_file_private *client_priv;
65
66 DBG("");
67 if (copy_from_user(&ureserve, arg, sizeof(ureserve)))
68 return -EFAULT;
69
70 if ((unsigned) ureserve.seg_count >= ~0U/sizeof(struct agp_segment32))
71 return -EFAULT;
72
73 kreserve.pid = ureserve.pid;
74 kreserve.seg_count = ureserve.seg_count;
75
76 client = agp_find_client_by_pid(kreserve.pid);
77
78 if (kreserve.seg_count == 0) {
79 /* remove a client */
80 client_priv = agp_find_private(kreserve.pid);
81
82 if (client_priv != NULL) {
83 set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
84 set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
85 }
86 if (client == NULL) {
87 /* client is already removed */
88 return 0;
89 }
90 return agp_remove_client(kreserve.pid);
91 } else {
92 struct agp_segment32 *usegment;
93 struct agp_segment *ksegment;
94 int seg;
95
96 if (ureserve.seg_count >= 16384)
97 return -EINVAL;
98
99 usegment = kmalloc(sizeof(*usegment) * ureserve.seg_count, GFP_KERNEL);
100 if (!usegment)
101 return -ENOMEM;
102
103 ksegment = kmalloc(sizeof(*ksegment) * kreserve.seg_count, GFP_KERNEL);
104 if (!ksegment) {
105 kfree(usegment);
106 return -ENOMEM;
107 }
108
109 if (copy_from_user(usegment, (void __user *) ureserve.seg_list,
110 sizeof(*usegment) * ureserve.seg_count)) {
111 kfree(usegment);
112 kfree(ksegment);
113 return -EFAULT;
114 }
115
116 for (seg = 0; seg < ureserve.seg_count; seg++) {
117 ksegment[seg].pg_start = usegment[seg].pg_start;
118 ksegment[seg].pg_count = usegment[seg].pg_count;
119 ksegment[seg].prot = usegment[seg].prot;
120 }
121
122 kfree(usegment);
123 kreserve.seg_list = ksegment;
124
125 if (client == NULL) {
126 /* Create the client and add the segment */
127 client = agp_create_client(kreserve.pid);
128
129 if (client == NULL) {
130 kfree(ksegment);
131 return -ENOMEM;
132 }
133 client_priv = agp_find_private(kreserve.pid);
134
135 if (client_priv != NULL) {
136 set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
137 set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
138 }
139 }
140 return agp_create_segment(client, &kreserve);
141 }
142 /* Will never really happen */
143 return -EINVAL;
144}
145
146static int compat_agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
147{
148 struct agp_memory *memory;
149 struct agp_allocate32 alloc;
150
151 DBG("");
152 if (copy_from_user(&alloc, arg, sizeof(alloc)))
153 return -EFAULT;
154
155 memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
156
157 if (memory == NULL)
158 return -ENOMEM;
159
160 alloc.key = memory->key;
161 alloc.physical = memory->physical;
162
163 if (copy_to_user(arg, &alloc, sizeof(alloc))) {
164 agp_free_memory_wrap(memory);
165 return -EFAULT;
166 }
167 return 0;
168}
169
170static int compat_agpioc_bind_wrap(struct agp_file_private *priv, void __user *arg)
171{
172 struct agp_bind32 bind_info;
173 struct agp_memory *memory;
174
175 DBG("");
176 if (copy_from_user(&bind_info, arg, sizeof(bind_info)))
177 return -EFAULT;
178
179 memory = agp_find_mem_by_key(bind_info.key);
180
181 if (memory == NULL)
182 return -EINVAL;
183
184 return agp_bind_memory(memory, bind_info.pg_start);
185}
186
187static int compat_agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg)
188{
189 struct agp_memory *memory;
190 struct agp_unbind32 unbind;
191
192 DBG("");
193 if (copy_from_user(&unbind, arg, sizeof(unbind)))
194 return -EFAULT;
195
196 memory = agp_find_mem_by_key(unbind.key);
197
198 if (memory == NULL)
199 return -EINVAL;
200
201 return agp_unbind_memory(memory);
202}
203
204long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
205{
206 struct agp_file_private *curr_priv = file->private_data;
207 int ret_val = -ENOTTY;
208
209 mutex_lock(&(agp_fe.agp_mutex));
210
211 if ((agp_fe.current_controller == NULL) &&
212 (cmd != AGPIOC_ACQUIRE32)) {
213 ret_val = -EINVAL;
214 goto ioctl_out;
215 }
216 if ((agp_fe.backend_acquired != TRUE) &&
217 (cmd != AGPIOC_ACQUIRE32)) {
218 ret_val = -EBUSY;
219 goto ioctl_out;
220 }
221 if (cmd != AGPIOC_ACQUIRE32) {
222 if (!(test_bit(AGP_FF_IS_CONTROLLER, &curr_priv->access_flags))) {
223 ret_val = -EPERM;
224 goto ioctl_out;
225 }
226 /* Use the original pid of the controller,
227 * in case it's threaded */
228
229 if (agp_fe.current_controller->pid != curr_priv->my_pid) {
230 ret_val = -EBUSY;
231 goto ioctl_out;
232 }
233 }
234
235 switch (cmd) {
236 case AGPIOC_INFO32:
237 ret_val = compat_agpioc_info_wrap(curr_priv, (void __user *) arg);
238 break;
239
240 case AGPIOC_ACQUIRE32:
241 ret_val = agpioc_acquire_wrap(curr_priv);
242 break;
243
244 case AGPIOC_RELEASE32:
245 ret_val = agpioc_release_wrap(curr_priv);
246 break;
247
248 case AGPIOC_SETUP32:
249 ret_val = agpioc_setup_wrap(curr_priv, (void __user *) arg);
250 break;
251
252 case AGPIOC_RESERVE32:
253 ret_val = compat_agpioc_reserve_wrap(curr_priv, (void __user *) arg);
254 break;
255
256 case AGPIOC_PROTECT32:
257 ret_val = agpioc_protect_wrap(curr_priv);
258 break;
259
260 case AGPIOC_ALLOCATE32:
261 ret_val = compat_agpioc_allocate_wrap(curr_priv, (void __user *) arg);
262 break;
263
264 case AGPIOC_DEALLOCATE32:
265 ret_val = agpioc_deallocate_wrap(curr_priv, (int) arg);
266 break;
267
268 case AGPIOC_BIND32:
269 ret_val = compat_agpioc_bind_wrap(curr_priv, (void __user *) arg);
270 break;
271
272 case AGPIOC_UNBIND32:
273 ret_val = compat_agpioc_unbind_wrap(curr_priv, (void __user *) arg);
274 break;
275 }
276
277ioctl_out:
278 DBG("ioctl returns %d\n", ret_val);
279 mutex_unlock(&(agp_fe.agp_mutex));
280 return ret_val;
281}
282
diff --git a/drivers/char/agp/compat_ioctl.h b/drivers/char/agp/compat_ioctl.h
new file mode 100644
index 00000000000..71939d63723
--- /dev/null
+++ b/drivers/char/agp/compat_ioctl.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 1999 Jeff Hartmann
3 * Copyright (C) 1999 Precision Insight, Inc.
4 * Copyright (C) 1999 Xi Graphics, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26#ifndef _AGP_COMPAT_IOCTL_H
27#define _AGP_COMPAT_IOCTL_H
28
29#include <linux/compat.h>
30#include <linux/agpgart.h>
31
32#define AGPIOC_INFO32 _IOR (AGPIOC_BASE, 0, compat_uptr_t)
33#define AGPIOC_ACQUIRE32 _IO (AGPIOC_BASE, 1)
34#define AGPIOC_RELEASE32 _IO (AGPIOC_BASE, 2)
35#define AGPIOC_SETUP32 _IOW (AGPIOC_BASE, 3, compat_uptr_t)
36#define AGPIOC_RESERVE32 _IOW (AGPIOC_BASE, 4, compat_uptr_t)
37#define AGPIOC_PROTECT32 _IOW (AGPIOC_BASE, 5, compat_uptr_t)
38#define AGPIOC_ALLOCATE32 _IOWR(AGPIOC_BASE, 6, compat_uptr_t)
39#define AGPIOC_DEALLOCATE32 _IOW (AGPIOC_BASE, 7, compat_int_t)
40#define AGPIOC_BIND32 _IOW (AGPIOC_BASE, 8, compat_uptr_t)
41#define AGPIOC_UNBIND32 _IOW (AGPIOC_BASE, 9, compat_uptr_t)
42
43struct agp_info32 {
44 struct agp_version version; /* version of the driver */
45 u32 bridge_id; /* bridge vendor/device */
46 u32 agp_mode; /* mode info of bridge */
47 compat_long_t aper_base; /* base of aperture */
48 compat_size_t aper_size; /* size of aperture */
49 compat_size_t pg_total; /* max pages (swap + system) */
50 compat_size_t pg_system; /* max pages (system) */
51 compat_size_t pg_used; /* current pages used */
52};
53
54/*
55 * The "prot" down below needs still a "sleep" flag somehow ...
56 */
57struct agp_segment32 {
58 compat_off_t pg_start; /* starting page to populate */
59 compat_size_t pg_count; /* number of pages */
60 compat_int_t prot; /* prot flags for mmap */
61};
62
63struct agp_region32 {
64 compat_pid_t pid; /* pid of process */
65 compat_size_t seg_count; /* number of segments */
66 struct agp_segment32 *seg_list;
67};
68
69struct agp_allocate32 {
70 compat_int_t key; /* tag of allocation */
71 compat_size_t pg_count; /* number of pages */
72 u32 type; /* 0 == normal, other devspec */
73 u32 physical; /* device specific (some devices
74 * need a phys address of the
75 * actual page behind the gatt
76 * table) */
77};
78
79struct agp_bind32 {
80 compat_int_t key; /* tag of allocation */
81 compat_off_t pg_start; /* starting page to populate */
82};
83
84struct agp_unbind32 {
85 compat_int_t key; /* tag of allocation */
86 u32 priority; /* priority for paging out */
87};
88
89extern struct agp_front_data agp_fe;
90
91int agpioc_acquire_wrap(struct agp_file_private *priv);
92int agpioc_release_wrap(struct agp_file_private *priv);
93int agpioc_protect_wrap(struct agp_file_private *priv);
94int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg);
95int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg);
96struct agp_file_private *agp_find_private(pid_t pid);
97struct agp_client *agp_create_client(pid_t id);
98int agp_remove_client(pid_t id);
99int agp_create_segment(struct agp_client *client, struct agp_region *region);
100void agp_free_memory_wrap(struct agp_memory *memory);
101struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type);
102struct agp_memory *agp_find_mem_by_key(int key);
103struct agp_client *agp_find_client_by_pid(pid_t id);
104
105#endif /* _AGP_COMPAT_H */
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 30f730ff81c..658cb1a72d2 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -335,6 +335,7 @@ static struct agp_bridge_driver efficeon_driver = {
335 .free_by_type = agp_generic_free_by_type, 335 .free_by_type = agp_generic_free_by_type,
336 .agp_alloc_page = agp_generic_alloc_page, 336 .agp_alloc_page = agp_generic_alloc_page,
337 .agp_destroy_page = agp_generic_destroy_page, 337 .agp_destroy_page = agp_generic_destroy_page,
338 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
338}; 339};
339 340
340static int __devinit agp_efficeon_probe(struct pci_dev *pdev, 341static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 0f2ed2aa2d8..679d7f97243 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -41,9 +41,9 @@
41#include <asm/pgtable.h> 41#include <asm/pgtable.h>
42#include "agp.h" 42#include "agp.h"
43 43
44static struct agp_front_data agp_fe; 44struct agp_front_data agp_fe;
45 45
46static struct agp_memory *agp_find_mem_by_key(int key) 46struct agp_memory *agp_find_mem_by_key(int key)
47{ 47{
48 struct agp_memory *curr; 48 struct agp_memory *curr;
49 49
@@ -159,7 +159,7 @@ static pgprot_t agp_convert_mmap_flags(int prot)
159 return vm_get_page_prot(prot_bits); 159 return vm_get_page_prot(prot_bits);
160} 160}
161 161
162static int agp_create_segment(struct agp_client *client, struct agp_region *region) 162int agp_create_segment(struct agp_client *client, struct agp_region *region)
163{ 163{
164 struct agp_segment_priv **ret_seg; 164 struct agp_segment_priv **ret_seg;
165 struct agp_segment_priv *seg; 165 struct agp_segment_priv *seg;
@@ -211,7 +211,7 @@ static void agp_insert_into_pool(struct agp_memory * temp)
211 211
212/* File private list routines */ 212/* File private list routines */
213 213
214static struct agp_file_private *agp_find_private(pid_t pid) 214struct agp_file_private *agp_find_private(pid_t pid)
215{ 215{
216 struct agp_file_private *curr; 216 struct agp_file_private *curr;
217 217
@@ -266,13 +266,13 @@ static void agp_remove_file_private(struct agp_file_private * priv)
266 * Wrappers for agp_free_memory & agp_allocate_memory 266 * Wrappers for agp_free_memory & agp_allocate_memory
267 * These make sure that internal lists are kept updated. 267 * These make sure that internal lists are kept updated.
268 */ 268 */
269static void agp_free_memory_wrap(struct agp_memory *memory) 269void agp_free_memory_wrap(struct agp_memory *memory)
270{ 270{
271 agp_remove_from_pool(memory); 271 agp_remove_from_pool(memory);
272 agp_free_memory(memory); 272 agp_free_memory(memory);
273} 273}
274 274
275static struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type) 275struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
276{ 276{
277 struct agp_memory *memory; 277 struct agp_memory *memory;
278 278
@@ -484,7 +484,7 @@ static struct agp_controller *agp_find_controller_for_client(pid_t id)
484 return NULL; 484 return NULL;
485} 485}
486 486
487static struct agp_client *agp_find_client_by_pid(pid_t id) 487struct agp_client *agp_find_client_by_pid(pid_t id)
488{ 488{
489 struct agp_client *temp; 489 struct agp_client *temp;
490 490
@@ -509,7 +509,7 @@ static void agp_insert_client(struct agp_client *client)
509 agp_fe.current_controller->num_clients++; 509 agp_fe.current_controller->num_clients++;
510} 510}
511 511
512static struct agp_client *agp_create_client(pid_t id) 512struct agp_client *agp_create_client(pid_t id)
513{ 513{
514 struct agp_client *new_client; 514 struct agp_client *new_client;
515 515
@@ -522,7 +522,7 @@ static struct agp_client *agp_create_client(pid_t id)
522 return new_client; 522 return new_client;
523} 523}
524 524
525static int agp_remove_client(pid_t id) 525int agp_remove_client(pid_t id)
526{ 526{
527 struct agp_client *client; 527 struct agp_client *client;
528 struct agp_client *prev_client; 528 struct agp_client *prev_client;
@@ -746,7 +746,7 @@ static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
746 return 0; 746 return 0;
747} 747}
748 748
749static int agpioc_acquire_wrap(struct agp_file_private *priv) 749int agpioc_acquire_wrap(struct agp_file_private *priv)
750{ 750{
751 struct agp_controller *controller; 751 struct agp_controller *controller;
752 752
@@ -789,14 +789,14 @@ static int agpioc_acquire_wrap(struct agp_file_private *priv)
789 return 0; 789 return 0;
790} 790}
791 791
792static int agpioc_release_wrap(struct agp_file_private *priv) 792int agpioc_release_wrap(struct agp_file_private *priv)
793{ 793{
794 DBG(""); 794 DBG("");
795 agp_controller_release_current(agp_fe.current_controller, priv); 795 agp_controller_release_current(agp_fe.current_controller, priv);
796 return 0; 796 return 0;
797} 797}
798 798
799static int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg) 799int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg)
800{ 800{
801 struct agp_setup mode; 801 struct agp_setup mode;
802 802
@@ -876,7 +876,7 @@ static int agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
876 return -EINVAL; 876 return -EINVAL;
877} 877}
878 878
879static int agpioc_protect_wrap(struct agp_file_private *priv) 879int agpioc_protect_wrap(struct agp_file_private *priv)
880{ 880{
881 DBG(""); 881 DBG("");
882 /* This function is not currently implemented */ 882 /* This function is not currently implemented */
@@ -892,6 +892,9 @@ static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
892 if (copy_from_user(&alloc, arg, sizeof(struct agp_allocate))) 892 if (copy_from_user(&alloc, arg, sizeof(struct agp_allocate)))
893 return -EFAULT; 893 return -EFAULT;
894 894
895 if (alloc.type >= AGP_USER_TYPES)
896 return -EINVAL;
897
895 memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type); 898 memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
896 899
897 if (memory == NULL) 900 if (memory == NULL)
@@ -907,7 +910,7 @@ static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
907 return 0; 910 return 0;
908} 911}
909 912
910static int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg) 913int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg)
911{ 914{
912 struct agp_memory *memory; 915 struct agp_memory *memory;
913 916
@@ -1043,6 +1046,9 @@ static const struct file_operations agp_fops =
1043 .read = agp_read, 1046 .read = agp_read,
1044 .write = agp_write, 1047 .write = agp_write,
1045 .ioctl = agp_ioctl, 1048 .ioctl = agp_ioctl,
1049#ifdef CONFIG_COMPAT
1050 .compat_ioctl = compat_agp_ioctl,
1051#endif
1046 .mmap = agp_mmap, 1052 .mmap = agp_mmap,
1047 .open = agp_open, 1053 .open = agp_open,
1048 .release = agp_release, 1054 .release = agp_release,
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 3491d6f84bc..7923337c3d2 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -101,6 +101,63 @@ static int agp_get_key(void)
101 return -1; 101 return -1;
102} 102}
103 103
104/*
105 * Use kmalloc if possible for the page list. Otherwise fall back to
106 * vmalloc. This speeds things up and also saves memory for small AGP
107 * regions.
108 */
109
110void agp_alloc_page_array(size_t size, struct agp_memory *mem)
111{
112 mem->memory = NULL;
113 mem->vmalloc_flag = 0;
114
115 if (size <= 2*PAGE_SIZE)
116 mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY);
117 if (mem->memory == NULL) {
118 mem->memory = vmalloc(size);
119 mem->vmalloc_flag = 1;
120 }
121}
122EXPORT_SYMBOL(agp_alloc_page_array);
123
124void agp_free_page_array(struct agp_memory *mem)
125{
126 if (mem->vmalloc_flag) {
127 vfree(mem->memory);
128 } else {
129 kfree(mem->memory);
130 }
131}
132EXPORT_SYMBOL(agp_free_page_array);
133
134
135static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages)
136{
137 struct agp_memory *new;
138 unsigned long alloc_size = num_agp_pages*sizeof(struct page *);
139
140 new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL);
141 if (new == NULL)
142 return NULL;
143
144 new->key = agp_get_key();
145
146 if (new->key < 0) {
147 kfree(new);
148 return NULL;
149 }
150
151 agp_alloc_page_array(alloc_size, new);
152
153 if (new->memory == NULL) {
154 agp_free_key(new->key);
155 kfree(new);
156 return NULL;
157 }
158 new->num_scratch_pages = 0;
159 return new;
160}
104 161
105struct agp_memory *agp_create_memory(int scratch_pages) 162struct agp_memory *agp_create_memory(int scratch_pages)
106{ 163{
@@ -116,7 +173,8 @@ struct agp_memory *agp_create_memory(int scratch_pages)
116 kfree(new); 173 kfree(new);
117 return NULL; 174 return NULL;
118 } 175 }
119 new->memory = vmalloc(PAGE_SIZE * scratch_pages); 176
177 agp_alloc_page_array(PAGE_SIZE * scratch_pages, new);
120 178
121 if (new->memory == NULL) { 179 if (new->memory == NULL) {
122 agp_free_key(new->key); 180 agp_free_key(new->key);
@@ -124,6 +182,7 @@ struct agp_memory *agp_create_memory(int scratch_pages)
124 return NULL; 182 return NULL;
125 } 183 }
126 new->num_scratch_pages = scratch_pages; 184 new->num_scratch_pages = scratch_pages;
185 new->type = AGP_NORMAL_MEMORY;
127 return new; 186 return new;
128} 187}
129EXPORT_SYMBOL(agp_create_memory); 188EXPORT_SYMBOL(agp_create_memory);
@@ -146,6 +205,11 @@ void agp_free_memory(struct agp_memory *curr)
146 if (curr->is_bound == TRUE) 205 if (curr->is_bound == TRUE)
147 agp_unbind_memory(curr); 206 agp_unbind_memory(curr);
148 207
208 if (curr->type >= AGP_USER_TYPES) {
209 agp_generic_free_by_type(curr);
210 return;
211 }
212
149 if (curr->type != 0) { 213 if (curr->type != 0) {
150 curr->bridge->driver->free_by_type(curr); 214 curr->bridge->driver->free_by_type(curr);
151 return; 215 return;
@@ -157,7 +221,7 @@ void agp_free_memory(struct agp_memory *curr)
157 flush_agp_mappings(); 221 flush_agp_mappings();
158 } 222 }
159 agp_free_key(curr->key); 223 agp_free_key(curr->key);
160 vfree(curr->memory); 224 agp_free_page_array(curr);
161 kfree(curr); 225 kfree(curr);
162} 226}
163EXPORT_SYMBOL(agp_free_memory); 227EXPORT_SYMBOL(agp_free_memory);
@@ -188,6 +252,13 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
188 if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp) 252 if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp)
189 return NULL; 253 return NULL;
190 254
255 if (type >= AGP_USER_TYPES) {
256 new = agp_generic_alloc_user(page_count, type);
257 if (new)
258 new->bridge = bridge;
259 return new;
260 }
261
191 if (type != 0) { 262 if (type != 0) {
192 new = bridge->driver->alloc_by_type(page_count, type); 263 new = bridge->driver->alloc_by_type(page_count, type);
193 if (new) 264 if (new)
@@ -960,6 +1031,7 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
960 off_t j; 1031 off_t j;
961 void *temp; 1032 void *temp;
962 struct agp_bridge_data *bridge; 1033 struct agp_bridge_data *bridge;
1034 int mask_type;
963 1035
964 bridge = mem->bridge; 1036 bridge = mem->bridge;
965 if (!bridge) 1037 if (!bridge)
@@ -995,7 +1067,11 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
995 num_entries -= agp_memory_reserved/PAGE_SIZE; 1067 num_entries -= agp_memory_reserved/PAGE_SIZE;
996 if (num_entries < 0) num_entries = 0; 1068 if (num_entries < 0) num_entries = 0;
997 1069
998 if (type != 0 || mem->type != 0) { 1070 if (type != mem->type)
1071 return -EINVAL;
1072
1073 mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
1074 if (mask_type != 0) {
999 /* The generic routines know nothing of memory types */ 1075 /* The generic routines know nothing of memory types */
1000 return -EINVAL; 1076 return -EINVAL;
1001 } 1077 }
@@ -1018,7 +1094,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
1018 } 1094 }
1019 1095
1020 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 1096 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1021 writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j); 1097 writel(bridge->driver->mask_memory(bridge, mem->memory[i], mask_type),
1098 bridge->gatt_table+j);
1022 } 1099 }
1023 readl(bridge->gatt_table+j-1); /* PCI Posting. */ 1100 readl(bridge->gatt_table+j-1); /* PCI Posting. */
1024 1101
@@ -1032,6 +1109,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1032{ 1109{
1033 size_t i; 1110 size_t i;
1034 struct agp_bridge_data *bridge; 1111 struct agp_bridge_data *bridge;
1112 int mask_type;
1035 1113
1036 bridge = mem->bridge; 1114 bridge = mem->bridge;
1037 if (!bridge) 1115 if (!bridge)
@@ -1040,7 +1118,11 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1040 if (mem->page_count == 0) 1118 if (mem->page_count == 0)
1041 return 0; 1119 return 0;
1042 1120
1043 if (type != 0 || mem->type != 0) { 1121 if (type != mem->type)
1122 return -EINVAL;
1123
1124 mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
1125 if (mask_type != 0) {
1044 /* The generic routines know nothing of memory types */ 1126 /* The generic routines know nothing of memory types */
1045 return -EINVAL; 1127 return -EINVAL;
1046 } 1128 }
@@ -1056,22 +1138,40 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
1056} 1138}
1057EXPORT_SYMBOL(agp_generic_remove_memory); 1139EXPORT_SYMBOL(agp_generic_remove_memory);
1058 1140
1059
1060struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type) 1141struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
1061{ 1142{
1062 return NULL; 1143 return NULL;
1063} 1144}
1064EXPORT_SYMBOL(agp_generic_alloc_by_type); 1145EXPORT_SYMBOL(agp_generic_alloc_by_type);
1065 1146
1066
1067void agp_generic_free_by_type(struct agp_memory *curr) 1147void agp_generic_free_by_type(struct agp_memory *curr)
1068{ 1148{
1069 vfree(curr->memory); 1149 agp_free_page_array(curr);
1070 agp_free_key(curr->key); 1150 agp_free_key(curr->key);
1071 kfree(curr); 1151 kfree(curr);
1072} 1152}
1073EXPORT_SYMBOL(agp_generic_free_by_type); 1153EXPORT_SYMBOL(agp_generic_free_by_type);
1074 1154
1155struct agp_memory *agp_generic_alloc_user(size_t page_count, int type)
1156{
1157 struct agp_memory *new;
1158 int i;
1159 int pages;
1160
1161 pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
1162 new = agp_create_user_memory(page_count);
1163 if (new == NULL)
1164 return NULL;
1165
1166 for (i = 0; i < page_count; i++)
1167 new->memory[i] = 0;
1168 new->page_count = 0;
1169 new->type = type;
1170 new->num_scratch_pages = pages;
1171
1172 return new;
1173}
1174EXPORT_SYMBOL(agp_generic_alloc_user);
1075 1175
1076/* 1176/*
1077 * Basic Page Allocation Routines - 1177 * Basic Page Allocation Routines -
@@ -1165,6 +1265,15 @@ unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,
1165} 1265}
1166EXPORT_SYMBOL(agp_generic_mask_memory); 1266EXPORT_SYMBOL(agp_generic_mask_memory);
1167 1267
1268int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge,
1269 int type)
1270{
1271 if (type >= AGP_USER_TYPES)
1272 return 0;
1273 return type;
1274}
1275EXPORT_SYMBOL(agp_generic_type_to_mask_type);
1276
1168/* 1277/*
1169 * These functions are implemented according to the AGPv3 spec, 1278 * These functions are implemented according to the AGPv3 spec,
1170 * which covers implementation details that had previously been 1279 * which covers implementation details that had previously been
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 907fb66ec4a..847deabf7f9 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -438,6 +438,7 @@ struct agp_bridge_driver hp_zx1_driver = {
438 .free_by_type = agp_generic_free_by_type, 438 .free_by_type = agp_generic_free_by_type,
439 .agp_alloc_page = agp_generic_alloc_page, 439 .agp_alloc_page = agp_generic_alloc_page,
440 .agp_destroy_page = agp_generic_destroy_page, 440 .agp_destroy_page = agp_generic_destroy_page,
441 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
441 .cant_use_aperture = 1, 442 .cant_use_aperture = 1,
442}; 443};
443 444
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 91769443d8f..3e7618653ab 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -293,6 +293,9 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
293 pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n", 293 pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
294 mem, pg_start, type, mem->memory[0]); 294 mem, pg_start, type, mem->memory[0]);
295 295
296 if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
297 return -EINVAL;
298
296 io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start; 299 io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
297 300
298 temp = agp_bridge->current_size; 301 temp = agp_bridge->current_size;
@@ -396,6 +399,9 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem,
396 struct lp_desc *start, *end, *lp; 399 struct lp_desc *start, *end, *lp;
397 void *temp; 400 void *temp;
398 401
402 if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
403 return -EINVAL;
404
399 temp = agp_bridge->current_size; 405 temp = agp_bridge->current_size;
400 num_entries = A_SIZE_8(temp)->num_entries; 406 num_entries = A_SIZE_8(temp)->num_entries;
401 407
@@ -572,6 +578,7 @@ struct agp_bridge_driver intel_i460_driver = {
572#endif 578#endif
573 .alloc_by_type = agp_generic_alloc_by_type, 579 .alloc_by_type = agp_generic_alloc_by_type,
574 .free_by_type = agp_generic_free_by_type, 580 .free_by_type = agp_generic_free_by_type,
581 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
575 .cant_use_aperture = 1, 582 .cant_use_aperture = 1,
576}; 583};
577 584
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index a3011de51f7..06b0bb6d982 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -5,6 +5,7 @@
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/pci.h> 6#include <linux/pci.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/kernel.h>
8#include <linux/pagemap.h> 9#include <linux/pagemap.h>
9#include <linux/agp_backend.h> 10#include <linux/agp_backend.h>
10#include "agp.h" 11#include "agp.h"
@@ -24,6 +25,9 @@
24 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB) 25 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB)
25 26
26 27
28extern int agp_memory_reserved;
29
30
27/* Intel 815 register */ 31/* Intel 815 register */
28#define INTEL_815_APCONT 0x51 32#define INTEL_815_APCONT 0x51
29#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF 33#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
@@ -68,12 +72,15 @@ static struct aper_size_info_fixed intel_i810_sizes[] =
68 72
69#define AGP_DCACHE_MEMORY 1 73#define AGP_DCACHE_MEMORY 1
70#define AGP_PHYS_MEMORY 2 74#define AGP_PHYS_MEMORY 2
75#define INTEL_AGP_CACHED_MEMORY 3
71 76
72static struct gatt_mask intel_i810_masks[] = 77static struct gatt_mask intel_i810_masks[] =
73{ 78{
74 {.mask = I810_PTE_VALID, .type = 0}, 79 {.mask = I810_PTE_VALID, .type = 0},
75 {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY}, 80 {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
76 {.mask = I810_PTE_VALID, .type = 0} 81 {.mask = I810_PTE_VALID, .type = 0},
82 {.mask = I810_PTE_VALID | I830_PTE_SYSTEM_CACHED,
83 .type = INTEL_AGP_CACHED_MEMORY}
77}; 84};
78 85
79static struct _intel_i810_private { 86static struct _intel_i810_private {
@@ -117,13 +124,15 @@ static int intel_i810_configure(void)
117 124
118 current_size = A_SIZE_FIX(agp_bridge->current_size); 125 current_size = A_SIZE_FIX(agp_bridge->current_size);
119 126
120 pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
121 temp &= 0xfff80000;
122
123 intel_i810_private.registers = ioremap(temp, 128 * 4096);
124 if (!intel_i810_private.registers) { 127 if (!intel_i810_private.registers) {
125 printk(KERN_ERR PFX "Unable to remap memory.\n"); 128 pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
126 return -ENOMEM; 129 temp &= 0xfff80000;
130
131 intel_i810_private.registers = ioremap(temp, 128 * 4096);
132 if (!intel_i810_private.registers) {
133 printk(KERN_ERR PFX "Unable to remap memory.\n");
134 return -ENOMEM;
135 }
127 } 136 }
128 137
129 if ((readl(intel_i810_private.registers+I810_DRAM_CTL) 138 if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
@@ -201,62 +210,79 @@ static void i8xx_destroy_pages(void *addr)
201 atomic_dec(&agp_bridge->current_memory_agp); 210 atomic_dec(&agp_bridge->current_memory_agp);
202} 211}
203 212
213static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge,
214 int type)
215{
216 if (type < AGP_USER_TYPES)
217 return type;
218 else if (type == AGP_USER_CACHED_MEMORY)
219 return INTEL_AGP_CACHED_MEMORY;
220 else
221 return 0;
222}
223
204static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, 224static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
205 int type) 225 int type)
206{ 226{
207 int i, j, num_entries; 227 int i, j, num_entries;
208 void *temp; 228 void *temp;
229 int ret = -EINVAL;
230 int mask_type;
209 231
210 if (mem->page_count == 0) 232 if (mem->page_count == 0)
211 return 0; 233 goto out;
212 234
213 temp = agp_bridge->current_size; 235 temp = agp_bridge->current_size;
214 num_entries = A_SIZE_FIX(temp)->num_entries; 236 num_entries = A_SIZE_FIX(temp)->num_entries;
215 237
216 if ((pg_start + mem->page_count) > num_entries) 238 if ((pg_start + mem->page_count) > num_entries)
217 return -EINVAL; 239 goto out_err;
218 240
219 for (j = pg_start; j < (pg_start + mem->page_count); j++) {
220 if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j)))
221 return -EBUSY;
222 }
223 241
224 if (type != 0 || mem->type != 0) { 242 for (j = pg_start; j < (pg_start + mem->page_count); j++) {
225 if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) { 243 if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j))) {
226 /* special insert */ 244 ret = -EBUSY;
227 if (!mem->is_flushed) { 245 goto out_err;
228 global_cache_flush();
229 mem->is_flushed = TRUE;
230 }
231
232 for (i = pg_start; i < (pg_start + mem->page_count); i++) {
233 writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, intel_i810_private.registers+I810_PTE_BASE+(i*4));
234 }
235 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */
236
237 agp_bridge->driver->tlb_flush(mem);
238 return 0;
239 } 246 }
240 if ((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
241 goto insert;
242 return -EINVAL;
243 } 247 }
244 248
245insert: 249 if (type != mem->type)
246 if (!mem->is_flushed) { 250 goto out_err;
247 global_cache_flush();
248 mem->is_flushed = TRUE;
249 }
250 251
251 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 252 mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
252 writel(agp_bridge->driver->mask_memory(agp_bridge, 253
253 mem->memory[i], mem->type), 254 switch (mask_type) {
254 intel_i810_private.registers+I810_PTE_BASE+(j*4)); 255 case AGP_DCACHE_MEMORY:
256 if (!mem->is_flushed)
257 global_cache_flush();
258 for (i = pg_start; i < (pg_start + mem->page_count); i++) {
259 writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
260 intel_i810_private.registers+I810_PTE_BASE+(i*4));
261 }
262 readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
263 break;
264 case AGP_PHYS_MEMORY:
265 case AGP_NORMAL_MEMORY:
266 if (!mem->is_flushed)
267 global_cache_flush();
268 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
269 writel(agp_bridge->driver->mask_memory(agp_bridge,
270 mem->memory[i],
271 mask_type),
272 intel_i810_private.registers+I810_PTE_BASE+(j*4));
273 }
274 readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
275 break;
276 default:
277 goto out_err;
255 } 278 }
256 readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4)); /* PCI Posting. */
257 279
258 agp_bridge->driver->tlb_flush(mem); 280 agp_bridge->driver->tlb_flush(mem);
259 return 0; 281out:
282 ret = 0;
283out_err:
284 mem->is_flushed = 1;
285 return ret;
260} 286}
261 287
262static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start, 288static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
@@ -337,12 +363,11 @@ static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
337 new->type = AGP_DCACHE_MEMORY; 363 new->type = AGP_DCACHE_MEMORY;
338 new->page_count = pg_count; 364 new->page_count = pg_count;
339 new->num_scratch_pages = 0; 365 new->num_scratch_pages = 0;
340 vfree(new->memory); 366 agp_free_page_array(new);
341 return new; 367 return new;
342 } 368 }
343 if (type == AGP_PHYS_MEMORY) 369 if (type == AGP_PHYS_MEMORY)
344 return alloc_agpphysmem_i8xx(pg_count, type); 370 return alloc_agpphysmem_i8xx(pg_count, type);
345
346 return NULL; 371 return NULL;
347} 372}
348 373
@@ -357,7 +382,7 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
357 gart_to_virt(curr->memory[0])); 382 gart_to_virt(curr->memory[0]));
358 global_flush_tlb(); 383 global_flush_tlb();
359 } 384 }
360 vfree(curr->memory); 385 agp_free_page_array(curr);
361 } 386 }
362 kfree(curr); 387 kfree(curr);
363} 388}
@@ -619,9 +644,11 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
619{ 644{
620 int i,j,num_entries; 645 int i,j,num_entries;
621 void *temp; 646 void *temp;
647 int ret = -EINVAL;
648 int mask_type;
622 649
623 if (mem->page_count == 0) 650 if (mem->page_count == 0)
624 return 0; 651 goto out;
625 652
626 temp = agp_bridge->current_size; 653 temp = agp_bridge->current_size;
627 num_entries = A_SIZE_FIX(temp)->num_entries; 654 num_entries = A_SIZE_FIX(temp)->num_entries;
@@ -631,34 +658,41 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
631 pg_start,intel_i830_private.gtt_entries); 658 pg_start,intel_i830_private.gtt_entries);
632 659
633 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n"); 660 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
634 return -EINVAL; 661 goto out_err;
635 } 662 }
636 663
637 if ((pg_start + mem->page_count) > num_entries) 664 if ((pg_start + mem->page_count) > num_entries)
638 return -EINVAL; 665 goto out_err;
639 666
640 /* The i830 can't check the GTT for entries since its read only, 667 /* The i830 can't check the GTT for entries since its read only,
641 * depend on the caller to make the correct offset decisions. 668 * depend on the caller to make the correct offset decisions.
642 */ 669 */
643 670
644 if ((type != 0 && type != AGP_PHYS_MEMORY) || 671 if (type != mem->type)
645 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 672 goto out_err;
646 return -EINVAL; 673
674 mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
647 675
648 if (!mem->is_flushed) { 676 if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
677 mask_type != INTEL_AGP_CACHED_MEMORY)
678 goto out_err;
679
680 if (!mem->is_flushed)
649 global_cache_flush(); 681 global_cache_flush();
650 mem->is_flushed = TRUE;
651 }
652 682
653 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 683 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
654 writel(agp_bridge->driver->mask_memory(agp_bridge, 684 writel(agp_bridge->driver->mask_memory(agp_bridge,
655 mem->memory[i], mem->type), 685 mem->memory[i], mask_type),
656 intel_i830_private.registers+I810_PTE_BASE+(j*4)); 686 intel_i830_private.registers+I810_PTE_BASE+(j*4));
657 } 687 }
658 readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4)); 688 readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
659
660 agp_bridge->driver->tlb_flush(mem); 689 agp_bridge->driver->tlb_flush(mem);
661 return 0; 690
691out:
692 ret = 0;
693out_err:
694 mem->is_flushed = 1;
695 return ret;
662} 696}
663 697
664static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start, 698static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
@@ -687,7 +721,6 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
687{ 721{
688 if (type == AGP_PHYS_MEMORY) 722 if (type == AGP_PHYS_MEMORY)
689 return alloc_agpphysmem_i8xx(pg_count, type); 723 return alloc_agpphysmem_i8xx(pg_count, type);
690
691 /* always return NULL for other allocation types for now */ 724 /* always return NULL for other allocation types for now */
692 return NULL; 725 return NULL;
693} 726}
@@ -734,9 +767,11 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
734{ 767{
735 int i,j,num_entries; 768 int i,j,num_entries;
736 void *temp; 769 void *temp;
770 int ret = -EINVAL;
771 int mask_type;
737 772
738 if (mem->page_count == 0) 773 if (mem->page_count == 0)
739 return 0; 774 goto out;
740 775
741 temp = agp_bridge->current_size; 776 temp = agp_bridge->current_size;
742 num_entries = A_SIZE_FIX(temp)->num_entries; 777 num_entries = A_SIZE_FIX(temp)->num_entries;
@@ -746,33 +781,41 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
746 pg_start,intel_i830_private.gtt_entries); 781 pg_start,intel_i830_private.gtt_entries);
747 782
748 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n"); 783 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
749 return -EINVAL; 784 goto out_err;
750 } 785 }
751 786
752 if ((pg_start + mem->page_count) > num_entries) 787 if ((pg_start + mem->page_count) > num_entries)
753 return -EINVAL; 788 goto out_err;
754 789
755 /* The i830 can't check the GTT for entries since its read only, 790 /* The i915 can't check the GTT for entries since its read only,
756 * depend on the caller to make the correct offset decisions. 791 * depend on the caller to make the correct offset decisions.
757 */ 792 */
758 793
759 if ((type != 0 && type != AGP_PHYS_MEMORY) || 794 if (type != mem->type)
760 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) 795 goto out_err;
761 return -EINVAL; 796
797 mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
762 798
763 if (!mem->is_flushed) { 799 if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
800 mask_type != INTEL_AGP_CACHED_MEMORY)
801 goto out_err;
802
803 if (!mem->is_flushed)
764 global_cache_flush(); 804 global_cache_flush();
765 mem->is_flushed = TRUE;
766 }
767 805
768 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 806 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
769 writel(agp_bridge->driver->mask_memory(agp_bridge, 807 writel(agp_bridge->driver->mask_memory(agp_bridge,
770 mem->memory[i], mem->type), intel_i830_private.gtt+j); 808 mem->memory[i], mask_type), intel_i830_private.gtt+j);
771 } 809 }
772 readl(intel_i830_private.gtt+j-1);
773 810
811 readl(intel_i830_private.gtt+j-1);
774 agp_bridge->driver->tlb_flush(mem); 812 agp_bridge->driver->tlb_flush(mem);
775 return 0; 813
814 out:
815 ret = 0;
816 out_err:
817 mem->is_flushed = 1;
818 return ret;
776} 819}
777 820
778static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start, 821static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
@@ -803,7 +846,7 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
803 */ 846 */
804static int intel_i9xx_fetch_size(void) 847static int intel_i9xx_fetch_size(void)
805{ 848{
806 int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes); 849 int num_sizes = ARRAY_SIZE(intel_i830_sizes);
807 int aper_size; /* size in megabytes */ 850 int aper_size; /* size in megabytes */
808 int i; 851 int i;
809 852
@@ -1384,6 +1427,7 @@ static struct agp_bridge_driver intel_generic_driver = {
1384 .free_by_type = agp_generic_free_by_type, 1427 .free_by_type = agp_generic_free_by_type,
1385 .agp_alloc_page = agp_generic_alloc_page, 1428 .agp_alloc_page = agp_generic_alloc_page,
1386 .agp_destroy_page = agp_generic_destroy_page, 1429 .agp_destroy_page = agp_generic_destroy_page,
1430 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1387}; 1431};
1388 1432
1389static struct agp_bridge_driver intel_810_driver = { 1433static struct agp_bridge_driver intel_810_driver = {
@@ -1408,6 +1452,7 @@ static struct agp_bridge_driver intel_810_driver = {
1408 .free_by_type = intel_i810_free_by_type, 1452 .free_by_type = intel_i810_free_by_type,
1409 .agp_alloc_page = agp_generic_alloc_page, 1453 .agp_alloc_page = agp_generic_alloc_page,
1410 .agp_destroy_page = agp_generic_destroy_page, 1454 .agp_destroy_page = agp_generic_destroy_page,
1455 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1411}; 1456};
1412 1457
1413static struct agp_bridge_driver intel_815_driver = { 1458static struct agp_bridge_driver intel_815_driver = {
@@ -1431,6 +1476,7 @@ static struct agp_bridge_driver intel_815_driver = {
1431 .free_by_type = agp_generic_free_by_type, 1476 .free_by_type = agp_generic_free_by_type,
1432 .agp_alloc_page = agp_generic_alloc_page, 1477 .agp_alloc_page = agp_generic_alloc_page,
1433 .agp_destroy_page = agp_generic_destroy_page, 1478 .agp_destroy_page = agp_generic_destroy_page,
1479 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1434}; 1480};
1435 1481
1436static struct agp_bridge_driver intel_830_driver = { 1482static struct agp_bridge_driver intel_830_driver = {
@@ -1455,6 +1501,7 @@ static struct agp_bridge_driver intel_830_driver = {
1455 .free_by_type = intel_i810_free_by_type, 1501 .free_by_type = intel_i810_free_by_type,
1456 .agp_alloc_page = agp_generic_alloc_page, 1502 .agp_alloc_page = agp_generic_alloc_page,
1457 .agp_destroy_page = agp_generic_destroy_page, 1503 .agp_destroy_page = agp_generic_destroy_page,
1504 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1458}; 1505};
1459 1506
1460static struct agp_bridge_driver intel_820_driver = { 1507static struct agp_bridge_driver intel_820_driver = {
@@ -1478,6 +1525,7 @@ static struct agp_bridge_driver intel_820_driver = {
1478 .free_by_type = agp_generic_free_by_type, 1525 .free_by_type = agp_generic_free_by_type,
1479 .agp_alloc_page = agp_generic_alloc_page, 1526 .agp_alloc_page = agp_generic_alloc_page,
1480 .agp_destroy_page = agp_generic_destroy_page, 1527 .agp_destroy_page = agp_generic_destroy_page,
1528 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1481}; 1529};
1482 1530
1483static struct agp_bridge_driver intel_830mp_driver = { 1531static struct agp_bridge_driver intel_830mp_driver = {
@@ -1501,6 +1549,7 @@ static struct agp_bridge_driver intel_830mp_driver = {
1501 .free_by_type = agp_generic_free_by_type, 1549 .free_by_type = agp_generic_free_by_type,
1502 .agp_alloc_page = agp_generic_alloc_page, 1550 .agp_alloc_page = agp_generic_alloc_page,
1503 .agp_destroy_page = agp_generic_destroy_page, 1551 .agp_destroy_page = agp_generic_destroy_page,
1552 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1504}; 1553};
1505 1554
1506static struct agp_bridge_driver intel_840_driver = { 1555static struct agp_bridge_driver intel_840_driver = {
@@ -1524,6 +1573,7 @@ static struct agp_bridge_driver intel_840_driver = {
1524 .free_by_type = agp_generic_free_by_type, 1573 .free_by_type = agp_generic_free_by_type,
1525 .agp_alloc_page = agp_generic_alloc_page, 1574 .agp_alloc_page = agp_generic_alloc_page,
1526 .agp_destroy_page = agp_generic_destroy_page, 1575 .agp_destroy_page = agp_generic_destroy_page,
1576 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1527}; 1577};
1528 1578
1529static struct agp_bridge_driver intel_845_driver = { 1579static struct agp_bridge_driver intel_845_driver = {
@@ -1547,6 +1597,7 @@ static struct agp_bridge_driver intel_845_driver = {
1547 .free_by_type = agp_generic_free_by_type, 1597 .free_by_type = agp_generic_free_by_type,
1548 .agp_alloc_page = agp_generic_alloc_page, 1598 .agp_alloc_page = agp_generic_alloc_page,
1549 .agp_destroy_page = agp_generic_destroy_page, 1599 .agp_destroy_page = agp_generic_destroy_page,
1600 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1550}; 1601};
1551 1602
1552static struct agp_bridge_driver intel_850_driver = { 1603static struct agp_bridge_driver intel_850_driver = {
@@ -1570,6 +1621,7 @@ static struct agp_bridge_driver intel_850_driver = {
1570 .free_by_type = agp_generic_free_by_type, 1621 .free_by_type = agp_generic_free_by_type,
1571 .agp_alloc_page = agp_generic_alloc_page, 1622 .agp_alloc_page = agp_generic_alloc_page,
1572 .agp_destroy_page = agp_generic_destroy_page, 1623 .agp_destroy_page = agp_generic_destroy_page,
1624 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1573}; 1625};
1574 1626
1575static struct agp_bridge_driver intel_860_driver = { 1627static struct agp_bridge_driver intel_860_driver = {
@@ -1593,6 +1645,7 @@ static struct agp_bridge_driver intel_860_driver = {
1593 .free_by_type = agp_generic_free_by_type, 1645 .free_by_type = agp_generic_free_by_type,
1594 .agp_alloc_page = agp_generic_alloc_page, 1646 .agp_alloc_page = agp_generic_alloc_page,
1595 .agp_destroy_page = agp_generic_destroy_page, 1647 .agp_destroy_page = agp_generic_destroy_page,
1648 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1596}; 1649};
1597 1650
1598static struct agp_bridge_driver intel_915_driver = { 1651static struct agp_bridge_driver intel_915_driver = {
@@ -1617,6 +1670,7 @@ static struct agp_bridge_driver intel_915_driver = {
1617 .free_by_type = intel_i810_free_by_type, 1670 .free_by_type = intel_i810_free_by_type,
1618 .agp_alloc_page = agp_generic_alloc_page, 1671 .agp_alloc_page = agp_generic_alloc_page,
1619 .agp_destroy_page = agp_generic_destroy_page, 1672 .agp_destroy_page = agp_generic_destroy_page,
1673 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1620}; 1674};
1621 1675
1622static struct agp_bridge_driver intel_i965_driver = { 1676static struct agp_bridge_driver intel_i965_driver = {
@@ -1641,6 +1695,7 @@ static struct agp_bridge_driver intel_i965_driver = {
1641 .free_by_type = intel_i810_free_by_type, 1695 .free_by_type = intel_i810_free_by_type,
1642 .agp_alloc_page = agp_generic_alloc_page, 1696 .agp_alloc_page = agp_generic_alloc_page,
1643 .agp_destroy_page = agp_generic_destroy_page, 1697 .agp_destroy_page = agp_generic_destroy_page,
1698 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1644}; 1699};
1645 1700
1646static struct agp_bridge_driver intel_7505_driver = { 1701static struct agp_bridge_driver intel_7505_driver = {
@@ -1664,6 +1719,7 @@ static struct agp_bridge_driver intel_7505_driver = {
1664 .free_by_type = agp_generic_free_by_type, 1719 .free_by_type = agp_generic_free_by_type,
1665 .agp_alloc_page = agp_generic_alloc_page, 1720 .agp_alloc_page = agp_generic_alloc_page,
1666 .agp_destroy_page = agp_generic_destroy_page, 1721 .agp_destroy_page = agp_generic_destroy_page,
1722 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1667}; 1723};
1668 1724
1669static int find_i810(u16 device) 1725static int find_i810(u16 device)
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index df7f37b2739..2563286b2fc 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -310,6 +310,7 @@ static struct agp_bridge_driver nvidia_driver = {
310 .free_by_type = agp_generic_free_by_type, 310 .free_by_type = agp_generic_free_by_type,
311 .agp_alloc_page = agp_generic_alloc_page, 311 .agp_alloc_page = agp_generic_alloc_page,
312 .agp_destroy_page = agp_generic_destroy_page, 312 .agp_destroy_page = agp_generic_destroy_page,
313 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
313}; 314};
314 315
315static int __devinit agp_nvidia_probe(struct pci_dev *pdev, 316static int __devinit agp_nvidia_probe(struct pci_dev *pdev,
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 17c50b0f83f..b7b4590673a 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -228,6 +228,7 @@ struct agp_bridge_driver parisc_agp_driver = {
228 .free_by_type = agp_generic_free_by_type, 228 .free_by_type = agp_generic_free_by_type,
229 .agp_alloc_page = agp_generic_alloc_page, 229 .agp_alloc_page = agp_generic_alloc_page,
230 .agp_destroy_page = agp_generic_destroy_page, 230 .agp_destroy_page = agp_generic_destroy_page,
231 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
231 .cant_use_aperture = 1, 232 .cant_use_aperture = 1,
232}; 233};
233 234
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 902648db7ef..92d1dc45b9b 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -265,6 +265,7 @@ struct agp_bridge_driver sgi_tioca_driver = {
265 .free_by_type = agp_generic_free_by_type, 265 .free_by_type = agp_generic_free_by_type,
266 .agp_alloc_page = sgi_tioca_alloc_page, 266 .agp_alloc_page = sgi_tioca_alloc_page,
267 .agp_destroy_page = agp_generic_destroy_page, 267 .agp_destroy_page = agp_generic_destroy_page,
268 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
268 .cant_use_aperture = 1, 269 .cant_use_aperture = 1,
269 .needs_scratch_page = 0, 270 .needs_scratch_page = 0,
270 .num_aperture_sizes = 1, 271 .num_aperture_sizes = 1,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index a00fd48a6f0..60342b70815 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -140,6 +140,7 @@ static struct agp_bridge_driver sis_driver = {
140 .free_by_type = agp_generic_free_by_type, 140 .free_by_type = agp_generic_free_by_type,
141 .agp_alloc_page = agp_generic_alloc_page, 141 .agp_alloc_page = agp_generic_alloc_page,
142 .agp_destroy_page = agp_generic_destroy_page, 142 .agp_destroy_page = agp_generic_destroy_page,
143 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
143}; 144};
144 145
145static struct agp_device_ids sis_agp_device_ids[] __devinitdata = 146static struct agp_device_ids sis_agp_device_ids[] __devinitdata =
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 4f2d7d99902..9f5ae7714f8 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -444,6 +444,7 @@ static struct agp_bridge_driver sworks_driver = {
444 .free_by_type = agp_generic_free_by_type, 444 .free_by_type = agp_generic_free_by_type,
445 .agp_alloc_page = agp_generic_alloc_page, 445 .agp_alloc_page = agp_generic_alloc_page,
446 .agp_destroy_page = agp_generic_destroy_page, 446 .agp_destroy_page = agp_generic_destroy_page,
447 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
447}; 448};
448 449
449static int __devinit agp_serverworks_probe(struct pci_dev *pdev, 450static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index dffc19382f7..6c45702e542 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -510,6 +510,7 @@ struct agp_bridge_driver uninorth_agp_driver = {
510 .free_by_type = agp_generic_free_by_type, 510 .free_by_type = agp_generic_free_by_type,
511 .agp_alloc_page = agp_generic_alloc_page, 511 .agp_alloc_page = agp_generic_alloc_page,
512 .agp_destroy_page = agp_generic_destroy_page, 512 .agp_destroy_page = agp_generic_destroy_page,
513 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
513 .cant_use_aperture = 1, 514 .cant_use_aperture = 1,
514}; 515};
515 516
@@ -534,6 +535,7 @@ struct agp_bridge_driver u3_agp_driver = {
534 .free_by_type = agp_generic_free_by_type, 535 .free_by_type = agp_generic_free_by_type,
535 .agp_alloc_page = agp_generic_alloc_page, 536 .agp_alloc_page = agp_generic_alloc_page,
536 .agp_destroy_page = agp_generic_destroy_page, 537 .agp_destroy_page = agp_generic_destroy_page,
538 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
537 .cant_use_aperture = 1, 539 .cant_use_aperture = 1,
538 .needs_scratch_page = 1, 540 .needs_scratch_page = 1,
539}; 541};
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 2ded7a280d7..2e7c04370cd 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -191,6 +191,7 @@ static struct agp_bridge_driver via_agp3_driver = {
191 .free_by_type = agp_generic_free_by_type, 191 .free_by_type = agp_generic_free_by_type,
192 .agp_alloc_page = agp_generic_alloc_page, 192 .agp_alloc_page = agp_generic_alloc_page,
193 .agp_destroy_page = agp_generic_destroy_page, 193 .agp_destroy_page = agp_generic_destroy_page,
194 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
194}; 195};
195 196
196static struct agp_bridge_driver via_driver = { 197static struct agp_bridge_driver via_driver = {
@@ -214,6 +215,7 @@ static struct agp_bridge_driver via_driver = {
214 .free_by_type = agp_generic_free_by_type, 215 .free_by_type = agp_generic_free_by_type,
215 .agp_alloc_page = agp_generic_alloc_page, 216 .agp_alloc_page = agp_generic_alloc_page,
216 .agp_destroy_page = agp_generic_destroy_page, 217 .agp_destroy_page = agp_generic_destroy_page,
218 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
217}; 219};
218 220
219static struct agp_device_ids via_agp_device_ids[] __devinitdata = 221static struct agp_device_ids via_agp_device_ids[] __devinitdata =
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index 7f60a18ef76..8dcf9d20f44 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/sched.h>
12#include <linux/tty.h> 11#include <linux/tty.h>
13#include <linux/timer.h> 12#include <linux/timer.h>
14#include <linux/kernel.h> 13#include <linux/kernel.h>
diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
index 1383727b443..ac9ab40d57a 100644
--- a/drivers/char/drm/ffb_context.c
+++ b/drivers/char/drm/ffb_context.c
@@ -7,7 +7,6 @@
7 * for authors. 7 * for authors.
8 */ 8 */
9 9
10#include <linux/sched.h>
11#include <asm/upa.h> 10#include <asm/upa.h>
12 11
13#include "ffb.h" 12#include "ffb.h"
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index dd45111a485..9a19879e3b6 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -9,7 +9,6 @@
9 9
10#include "ffb_drv.h" 10#include "ffb_drv.h"
11 11
12#include <linux/sched.h>
13#include <linux/smp_lock.h> 12#include <linux/smp_lock.h>
14#include <asm/shmparam.h> 13#include <asm/shmparam.h>
15#include <asm/oplib.h> 14#include <asm/oplib.h>
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 48cb8f0e8eb..3d7efc26aad 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -3,7 +3,6 @@
3 * thermometer driver (as used in the Rebel.com NetWinder) 3 * thermometer driver (as used in the Rebel.com NetWinder)
4 */ 4 */
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/sched.h>
7#include <linux/miscdevice.h> 6#include <linux/miscdevice.h>
8#include <linux/smp_lock.h> 7#include <linux/smp_lock.h>
9#include <linux/delay.h> 8#include <linux/delay.h>
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 06f2dbf1771..db984e481d4 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -25,7 +25,6 @@
25 25
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/slab.h> /* for kmalloc() and kfree() */ 27#include <linux/slab.h> /* for kmalloc() and kfree() */
28#include <linux/sched.h> /* for struct wait_queue etc */
29#include <linux/major.h> 28#include <linux/major.h>
30#include <linux/types.h> 29#include <linux/types.h>
31#include <linux/errno.h> 30#include <linux/errno.h>
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 1aa93a752a9..ae76a9ffe89 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -117,7 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse_reboot);
117__setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); 117__setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
118#endif /* not MODULE */ 118#endif /* not MODULE */
119 119
120#if defined(CONFIG_X86_64) || defined(CONFIG_S390) 120#if defined(CONFIG_S390)
121# define HAVE_MONOTONIC 121# define HAVE_MONOTONIC
122# define TIMER_FREQ 1000000000ULL 122# define TIMER_FREQ 1000000000ULL
123#elif defined(CONFIG_IA64) 123#elif defined(CONFIG_IA64)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 20dc3be5ecf..0be700f4e8f 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -703,7 +703,7 @@ int hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
703 703
704static ctl_table hpet_table[] = { 704static ctl_table hpet_table[] = {
705 { 705 {
706 .ctl_name = 1, 706 .ctl_name = CTL_UNNUMBERED,
707 .procname = "max-user-freq", 707 .procname = "max-user-freq",
708 .data = &hpet_max_freq, 708 .data = &hpet_max_freq,
709 .maxlen = sizeof(int), 709 .maxlen = sizeof(int),
@@ -715,7 +715,7 @@ static ctl_table hpet_table[] = {
715 715
716static ctl_table hpet_root[] = { 716static ctl_table hpet_root[] = {
717 { 717 {
718 .ctl_name = 1, 718 .ctl_name = CTL_UNNUMBERED,
719 .procname = "hpet", 719 .procname = "hpet",
720 .maxlen = 0, 720 .maxlen = 0,
721 .mode = 0555, 721 .mode = 0555,
@@ -1018,7 +1018,7 @@ static int __init hpet_init(void)
1018 if (result < 0) 1018 if (result < 0)
1019 return -ENODEV; 1019 return -ENODEV;
1020 1020
1021 sysctl_header = register_sysctl_table(dev_root, 0); 1021 sysctl_header = register_sysctl_table(dev_root);
1022 1022
1023 result = acpi_bus_register_driver(&hpet_acpi_driver); 1023 result = acpi_bus_register_driver(&hpet_acpi_driver);
1024 if (result < 0) { 1024 if (result < 0) {
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index d7806834fc1..50315d6364f 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -39,7 +39,6 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/major.h> 40#include <linux/major.h>
41#include <linux/kernel.h> 41#include <linux/kernel.h>
42#include <linux/sched.h>
43#include <linux/spinlock.h> 42#include <linux/spinlock.h>
44#include <linux/sysrq.h> 43#include <linux/sysrq.h>
45#include <linux/tty.h> 44#include <linux/tty.h>
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index ff2d052177c..c2aa44ee6eb 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -35,7 +35,6 @@
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <asm/system.h> 37#include <asm/system.h>
38#include <linux/sched.h>
39#include <linux/poll.h> 38#include <linux/poll.h>
40#include <linux/spinlock.h> 39#include <linux/spinlock.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 3aff5e99b67..8e222f2b80c 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -34,7 +34,6 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/errno.h> 35#include <linux/errno.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <linux/sched.h>
38#include <linux/poll.h> 37#include <linux/poll.h>
39#include <linux/spinlock.h> 38#include <linux/spinlock.h>
40#include <linux/mutex.h> 39#include <linux/mutex.h>
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 9d23136e598..e02893b7b30 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -686,7 +686,7 @@ static int ipmi_poweroff_init (void)
686 printk(KERN_INFO PFX "Power cycle is enabled.\n"); 686 printk(KERN_INFO PFX "Power cycle is enabled.\n");
687 687
688#ifdef CONFIG_PROC_FS 688#ifdef CONFIG_PROC_FS
689 ipmi_table_header = register_sysctl_table(ipmi_root_table, 1); 689 ipmi_table_header = register_sysctl_table(ipmi_root_table);
690 if (!ipmi_table_header) { 690 if (!ipmi_table_header) {
691 printk(KERN_ERR PFX "Unable to register powercycle sysctl\n"); 691 printk(KERN_ERR PFX "Unable to register powercycle sysctl\n");
692 rv = -ENOMEM; 692 rv = -ENOMEM;
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index c654a3e0c69..cb8d691576d 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -596,7 +596,6 @@ static void fn_spawn_con(struct vc_data *vc)
596static void fn_SAK(struct vc_data *vc) 596static void fn_SAK(struct vc_data *vc)
597{ 597{
598 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; 598 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
599 PREPARE_WORK(SAK_work, vc_SAK);
600 schedule_work(SAK_work); 599 schedule_work(SAK_work);
601} 600}
602 601
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index a39f19c35a6..204deaa0de8 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -37,7 +37,6 @@
37#define NVRAM_VERSION "1.2" 37#define NVRAM_VERSION "1.2"
38 38
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/sched.h>
41#include <linux/smp_lock.h> 40#include <linux/smp_lock.h>
42#include <linux/nvram.h> 41#include <linux/nvram.h>
43 42
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index 206cf6f5069..ba012c2bdf7 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -21,7 +21,6 @@
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/proc_fs.h> 23#include <linux/proc_fs.h>
24#include <linux/sched.h>
25#include <linux/miscdevice.h> 24#include <linux/miscdevice.h>
26#include <linux/spinlock.h> 25#include <linux/spinlock.h>
27#include <linux/rwsem.h> 26#include <linux/rwsem.h>
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index c07a1b5cd05..de14aea34e1 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -14,7 +14,6 @@
14#include <linux/module.h> /* For EXPORT_SYMBOL */ 14#include <linux/module.h> /* For EXPORT_SYMBOL */
15 15
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/sched.h>
18#include <linux/interrupt.h> 17#include <linux/interrupt.h>
19#include <linux/tty.h> 18#include <linux/tty.h>
20#include <linux/tty_flip.h> 19#include <linux/tty_flip.h>
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index b6d3072dce5..c7dac9b1335 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -282,7 +282,7 @@ irqreturn_t rtc_interrupt(int irq, void *dev_id)
282 */ 282 */
283static ctl_table rtc_table[] = { 283static ctl_table rtc_table[] = {
284 { 284 {
285 .ctl_name = 1, 285 .ctl_name = CTL_UNNUMBERED,
286 .procname = "max-user-freq", 286 .procname = "max-user-freq",
287 .data = &rtc_max_user_freq, 287 .data = &rtc_max_user_freq,
288 .maxlen = sizeof(int), 288 .maxlen = sizeof(int),
@@ -294,9 +294,8 @@ static ctl_table rtc_table[] = {
294 294
295static ctl_table rtc_root[] = { 295static ctl_table rtc_root[] = {
296 { 296 {
297 .ctl_name = 1, 297 .ctl_name = CTL_UNNUMBERED,
298 .procname = "rtc", 298 .procname = "rtc",
299 .maxlen = 0,
300 .mode = 0555, 299 .mode = 0555,
301 .child = rtc_table, 300 .child = rtc_table,
302 }, 301 },
@@ -307,7 +306,6 @@ static ctl_table dev_root[] = {
307 { 306 {
308 .ctl_name = CTL_DEV, 307 .ctl_name = CTL_DEV,
309 .procname = "dev", 308 .procname = "dev",
310 .maxlen = 0,
311 .mode = 0555, 309 .mode = 0555,
312 .child = rtc_root, 310 .child = rtc_root,
313 }, 311 },
@@ -318,7 +316,7 @@ static struct ctl_table_header *sysctl_header;
318 316
319static int __init init_sysctl(void) 317static int __init init_sysctl(void)
320{ 318{
321 sysctl_header = register_sysctl_table(dev_root, 0); 319 sysctl_header = register_sysctl_table(dev_root);
322 return 0; 320 return 0;
323} 321}
324 322
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 75de5f66517..3c869145bfd 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -86,7 +86,6 @@
86#include <linux/module.h> 86#include <linux/module.h>
87 87
88#include <linux/types.h> 88#include <linux/types.h>
89#include <linux/sched.h>
90#include <linux/interrupt.h> 89#include <linux/interrupt.h>
91#include <linux/kernel.h> 90#include <linux/kernel.h>
92#include <linux/errno.h> 91#include <linux/errno.h>
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 17d54e1331b..78237577b05 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -36,7 +36,6 @@
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/input.h> 37#include <linux/input.h>
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <linux/sched.h>
40#include <linux/init.h> 39#include <linux/init.h>
41#include <linux/interrupt.h> 40#include <linux/interrupt.h>
42#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 3757610b783..1d8c4ae6155 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -36,6 +36,7 @@
36#include <linux/workqueue.h> 36#include <linux/workqueue.h>
37#include <linux/kexec.h> 37#include <linux/kexec.h>
38#include <linux/irq.h> 38#include <linux/irq.h>
39#include <linux/hrtimer.h>
39 40
40#include <asm/ptrace.h> 41#include <asm/ptrace.h>
41#include <asm/irq_regs.h> 42#include <asm/irq_regs.h>
@@ -89,7 +90,6 @@ static struct sysrq_key_op sysrq_loglevel_op = {
89static void sysrq_handle_SAK(int key, struct tty_struct *tty) 90static void sysrq_handle_SAK(int key, struct tty_struct *tty)
90{ 91{
91 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; 92 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
92 PREPARE_WORK(SAK_work, vc_SAK);
93 schedule_work(SAK_work); 93 schedule_work(SAK_work);
94} 94}
95static struct sysrq_key_op sysrq_SAK_op = { 95static struct sysrq_key_op sysrq_SAK_op = {
@@ -159,6 +159,17 @@ static struct sysrq_key_op sysrq_sync_op = {
159 .enable_mask = SYSRQ_ENABLE_SYNC, 159 .enable_mask = SYSRQ_ENABLE_SYNC,
160}; 160};
161 161
162static void sysrq_handle_show_timers(int key, struct tty_struct *tty)
163{
164 sysrq_timer_list_show();
165}
166
167static struct sysrq_key_op sysrq_show_timers_op = {
168 .handler = sysrq_handle_show_timers,
169 .help_msg = "show-all-timers(Q)",
170 .action_msg = "Show Pending Timers",
171};
172
162static void sysrq_handle_mountro(int key, struct tty_struct *tty) 173static void sysrq_handle_mountro(int key, struct tty_struct *tty)
163{ 174{
164 emergency_remount(); 175 emergency_remount();
@@ -336,7 +347,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
336 /* o: This will often be registered as 'Off' at init time */ 347 /* o: This will often be registered as 'Off' at init time */
337 NULL, /* o */ 348 NULL, /* o */
338 &sysrq_showregs_op, /* p */ 349 &sysrq_showregs_op, /* p */
339 NULL, /* q */ 350 &sysrq_show_timers_op, /* q */
340 &sysrq_unraw_op, /* r */ 351 &sysrq_unraw_op, /* r */
341 &sysrq_sync_op, /* s */ 352 &sysrq_sync_op, /* s */
342 &sysrq_showstate_op, /* t */ 353 &sysrq_showstate_op, /* t */
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 4fac2bdf621..35e58030d29 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -29,7 +29,6 @@
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/sched.h>
33#include <linux/kernel.h> /* printk() */ 32#include <linux/kernel.h> /* printk() */
34#include <linux/fs.h> /* everything... */ 33#include <linux/fs.h> /* everything... */
35#include <linux/errno.h> /* error codes */ 34#include <linux/errno.h> /* error codes */
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index c346ec5a3dc..5422f999636 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -58,7 +58,6 @@
58 58
59#include <linux/module.h> 59#include <linux/module.h>
60#include <linux/kernel.h> 60#include <linux/kernel.h>
61#include <linux/sched.h>
62#include <linux/types.h> 61#include <linux/types.h>
63#include <linux/fcntl.h> 62#include <linux/fcntl.h>
64#include <linux/miscdevice.h> 63#include <linux/miscdevice.h>
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 2f572b97c16..e5a254a434f 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -23,7 +23,6 @@
23 * 23 *
24 */ 24 */
25 25
26#include <linux/sched.h>
27#include <linux/poll.h> 26#include <linux/poll.h>
28#include <linux/spinlock.h> 27#include <linux/spinlock.h>
29#include "tpm.h" 28#include "tpm.h"
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 65672c57470..5289254e7ab 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3442,7 +3442,6 @@ void do_SAK(struct tty_struct *tty)
3442{ 3442{
3443 if (!tty) 3443 if (!tty)
3444 return; 3444 return;
3445 PREPARE_WORK(&tty->SAK_work, do_SAK_work);
3446 schedule_work(&tty->SAK_work); 3445 schedule_work(&tty->SAK_work);
3447} 3446}
3448 3447
@@ -3568,7 +3567,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
3568 mutex_init(&tty->atomic_write_lock); 3567 mutex_init(&tty->atomic_write_lock);
3569 spin_lock_init(&tty->read_lock); 3568 spin_lock_init(&tty->read_lock);
3570 INIT_LIST_HEAD(&tty->tty_files); 3569 INIT_LIST_HEAD(&tty->tty_files);
3571 INIT_WORK(&tty->SAK_work, NULL); 3570 INIT_WORK(&tty->SAK_work, do_SAK_work);
3572} 3571}
3573 3572
3574/* 3573/*
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 26776517f04..791930320a1 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -25,7 +25,6 @@
25#include <linux/major.h> 25#include <linux/major.h>
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/tty.h> 27#include <linux/tty.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h> 28#include <linux/interrupt.h>
30#include <linux/mm.h> 29#include <linux/mm.h>
31#include <linux/init.h> 30#include <linux/init.h>
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index e01317cb1a0..bef6d886d4f 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -17,7 +17,6 @@
17#include <linux/kdev_t.h> 17#include <linux/kdev_t.h>
18#include <asm/io.h> 18#include <asm/io.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/ioport.h> 20#include <linux/ioport.h>
22#include <linux/interrupt.h> 21#include <linux/interrupt.h>
23#include <linux/errno.h> 22#include <linux/errno.h>
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 94ce3e7fc9e..c3f8e383933 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2635,6 +2635,7 @@ static int __init con_init(void)
2635 */ 2635 */
2636 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { 2636 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2637 vc_cons[currcons].d = vc = alloc_bootmem(sizeof(struct vc_data)); 2637 vc_cons[currcons].d = vc = alloc_bootmem(sizeof(struct vc_data));
2638 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
2638 visual_init(vc, currcons, 1); 2639 visual_init(vc, currcons, 1);
2639 vc->vc_screenbuf = (unsigned short *)alloc_bootmem(vc->vc_screenbuf_size); 2640 vc->vc_screenbuf = (unsigned short *)alloc_bootmem(vc->vc_screenbuf_size);
2640 vc->vc_kmalloced = 0; 2641 vc->vc_kmalloced = 0;
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
index 154d67e591e..85269c365a1 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -48,46 +48,52 @@
48 * It can be 1, 2, 10, 20, 110 or 220 seconds. 48 * It can be 1, 2, 10, 20, 110 or 220 seconds.
49 */ 49 */
50 50
51#include <linux/module.h> 51/*
52#include <linux/moduleparam.h> 52 * Includes, defines, variables, module parameters, ...
53#include <linux/types.h> 53 */
54#include <linux/miscdevice.h>
55#include <linux/watchdog.h>
56#include <linux/fs.h>
57#include <linux/ioport.h>
58#include <linux/notifier.h>
59#include <linux/reboot.h>
60#include <linux/init.h>
61
62#include <asm/io.h>
63#include <asm/uaccess.h>
64#include <asm/system.h>
65 54
55/* Includes */
56#include <linux/module.h> /* For module specific items */
57#include <linux/moduleparam.h> /* For new moduleparam's */
58#include <linux/types.h> /* For standard types (like size_t) */
59#include <linux/errno.h> /* For the -ENODEV/... values */
60#include <linux/kernel.h> /* For printk/panic/... */
61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
62#include <linux/watchdog.h> /* For the watchdog specific items */
63#include <linux/fs.h> /* For file operations */
64#include <linux/ioport.h> /* For io-port access */
65#include <linux/platform_device.h> /* For platform_driver framework */
66#include <linux/init.h> /* For __init/__exit/... */
67
68#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
69#include <asm/io.h> /* For inb/outb/... */
70
71/* Module information */
72#define DRV_NAME "acquirewdt"
73#define PFX DRV_NAME ": "
66#define WATCHDOG_NAME "Acquire WDT" 74#define WATCHDOG_NAME "Acquire WDT"
67#define PFX WATCHDOG_NAME ": "
68#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ 75#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */
69 76
77/* internal variables */
78static struct platform_device *acq_platform_device; /* the watchdog platform device */
70static unsigned long acq_is_open; 79static unsigned long acq_is_open;
71static char expect_close; 80static char expect_close;
72 81
73/* 82/* module parameters */
74 * You must set these - there is no sane way to probe for this board. 83static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */
75 */
76
77static int wdt_stop = 0x43;
78module_param(wdt_stop, int, 0); 84module_param(wdt_stop, int, 0);
79MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); 85MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)");
80 86
81static int wdt_start = 0x443; 87static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */
82module_param(wdt_start, int, 0); 88module_param(wdt_start, int, 0);
83MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); 89MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
84 90
85static int nowayout = WATCHDOG_NOWAYOUT; 91static int nowayout = WATCHDOG_NOWAYOUT;
86module_param(nowayout, int, 0); 92module_param(nowayout, int, 0);
87MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
88 94
89/* 95/*
90 * Kernel methods. 96 * Watchdog Operations
91 */ 97 */
92 98
93static void acq_keepalive(void) 99static void acq_keepalive(void)
@@ -103,7 +109,7 @@ static void acq_stop(void)
103} 109}
104 110
105/* 111/*
106 * /dev/watchdog handling. 112 * /dev/watchdog handling
107 */ 113 */
108 114
109static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 115static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
@@ -143,7 +149,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
143 { 149 {
144 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 150 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
145 .firmware_version = 1, 151 .firmware_version = 1,
146 .identity = "Acquire WDT", 152 .identity = WATCHDOG_NAME,
147 }; 153 };
148 154
149 switch(cmd) 155 switch(cmd)
@@ -214,20 +220,6 @@ static int acq_close(struct inode *inode, struct file *file)
214} 220}
215 221
216/* 222/*
217 * Notifier for system down
218 */
219
220static int acq_notify_sys(struct notifier_block *this, unsigned long code,
221 void *unused)
222{
223 if(code==SYS_DOWN || code==SYS_HALT) {
224 /* Turn the WDT off */
225 acq_stop();
226 }
227 return NOTIFY_DONE;
228}
229
230/*
231 * Kernel Interfaces 223 * Kernel Interfaces
232 */ 224 */
233 225
@@ -240,29 +232,20 @@ static const struct file_operations acq_fops = {
240 .release = acq_close, 232 .release = acq_close,
241}; 233};
242 234
243static struct miscdevice acq_miscdev= 235static struct miscdevice acq_miscdev = {
244{ 236 .minor = WATCHDOG_MINOR,
245 .minor = WATCHDOG_MINOR, 237 .name = "watchdog",
246 .name = "watchdog", 238 .fops = &acq_fops,
247 .fops = &acq_fops,
248}; 239};
249 240
250/* 241/*
251 * The WDT card needs to learn about soft shutdowns in order to 242 * Init & exit routines
252 * turn the timebomb registers off.
253 */ 243 */
254 244
255static struct notifier_block acq_notifier = 245static int __devinit acq_probe(struct platform_device *dev)
256{
257 .notifier_call = acq_notify_sys,
258};
259
260static int __init acq_init(void)
261{ 246{
262 int ret; 247 int ret;
263 248
264 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
265
266 if (wdt_stop != wdt_start) { 249 if (wdt_stop != wdt_start) {
267 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 250 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
268 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 251 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -279,18 +262,11 @@ static int __init acq_init(void)
279 goto unreg_stop; 262 goto unreg_stop;
280 } 263 }
281 264
282 ret = register_reboot_notifier(&acq_notifier);
283 if (ret != 0) {
284 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
285 ret);
286 goto unreg_regions;
287 }
288
289 ret = misc_register(&acq_miscdev); 265 ret = misc_register(&acq_miscdev);
290 if (ret != 0) { 266 if (ret != 0) {
291 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 267 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
292 WATCHDOG_MINOR, ret); 268 WATCHDOG_MINOR, ret);
293 goto unreg_reboot; 269 goto unreg_regions;
294 } 270 }
295 271
296 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", 272 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
@@ -298,8 +274,6 @@ static int __init acq_init(void)
298 274
299 return 0; 275 return 0;
300 276
301unreg_reboot:
302 unregister_reboot_notifier(&acq_notifier);
303unreg_regions: 277unreg_regions:
304 release_region(wdt_start, 1); 278 release_region(wdt_start, 1);
305unreg_stop: 279unreg_stop:
@@ -309,13 +283,60 @@ out:
309 return ret; 283 return ret;
310} 284}
311 285
312static void __exit acq_exit(void) 286static int __devexit acq_remove(struct platform_device *dev)
313{ 287{
314 misc_deregister(&acq_miscdev); 288 misc_deregister(&acq_miscdev);
315 unregister_reboot_notifier(&acq_notifier); 289 release_region(wdt_start,1);
316 if(wdt_stop != wdt_start) 290 if(wdt_stop != wdt_start)
317 release_region(wdt_stop,1); 291 release_region(wdt_stop,1);
318 release_region(wdt_start,1); 292
293 return 0;
294}
295
296static void acq_shutdown(struct platform_device *dev)
297{
298 /* Turn the WDT off if we have a soft shutdown */
299 acq_stop();
300}
301
302static struct platform_driver acquirewdt_driver = {
303 .probe = acq_probe,
304 .remove = __devexit_p(acq_remove),
305 .shutdown = acq_shutdown,
306 .driver = {
307 .owner = THIS_MODULE,
308 .name = DRV_NAME,
309 },
310};
311
312static int __init acq_init(void)
313{
314 int err;
315
316 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
317
318 err = platform_driver_register(&acquirewdt_driver);
319 if (err)
320 return err;
321
322 acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
323 if (IS_ERR(acq_platform_device)) {
324 err = PTR_ERR(acq_platform_device);
325 goto unreg_platform_driver;
326 }
327
328 return 0;
329
330unreg_platform_driver:
331 platform_driver_unregister(&acquirewdt_driver);
332 return err;
333}
334
335static void __exit acq_exit(void)
336{
337 platform_device_unregister(acq_platform_device);
338 platform_driver_unregister(&acquirewdt_driver);
339 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
319} 340}
320 341
321module_init(acq_init); 342module_init(acq_init);
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
index 9d732769ba0..8121cc24734 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -35,18 +35,19 @@
35#include <linux/watchdog.h> 35#include <linux/watchdog.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/notifier.h> 38#include <linux/platform_device.h>
39#include <linux/reboot.h>
40#include <linux/init.h> 39#include <linux/init.h>
41 40
42#include <asm/io.h> 41#include <asm/io.h>
43#include <asm/uaccess.h> 42#include <asm/uaccess.h>
44#include <asm/system.h> 43#include <asm/system.h>
45 44
45#define DRV_NAME "advantechwdt"
46#define PFX DRV_NAME ": "
46#define WATCHDOG_NAME "Advantech WDT" 47#define WATCHDOG_NAME "Advantech WDT"
47#define PFX WATCHDOG_NAME ": "
48#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 48#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
49 49
50static struct platform_device *advwdt_platform_device; /* the watchdog platform device */
50static unsigned long advwdt_is_open; 51static unsigned long advwdt_is_open;
51static char adv_expect_close; 52static char adv_expect_close;
52 53
@@ -75,10 +76,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, defaul
75 76
76static int nowayout = WATCHDOG_NOWAYOUT; 77static int nowayout = WATCHDOG_NOWAYOUT;
77module_param(nowayout, int, 0); 78module_param(nowayout, int, 0);
78MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 79MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
79 80
80/* 81/*
81 * Kernel methods. 82 * Watchdog Operations
82 */ 83 */
83 84
84static void 85static void
@@ -94,6 +95,20 @@ advwdt_disable(void)
94 inb_p(wdt_stop); 95 inb_p(wdt_stop);
95} 96}
96 97
98static int
99advwdt_set_heartbeat(int t)
100{
101 if ((t < 1) || (t > 63))
102 return -EINVAL;
103
104 timeout = t;
105 return 0;
106}
107
108/*
109 * /dev/watchdog handling
110 */
111
97static ssize_t 112static ssize_t
98advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 113advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
99{ 114{
@@ -126,7 +141,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
126 static struct watchdog_info ident = { 141 static struct watchdog_info ident = {
127 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 142 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
128 .firmware_version = 1, 143 .firmware_version = 1,
129 .identity = "Advantech WDT", 144 .identity = WATCHDOG_NAME,
130 }; 145 };
131 146
132 switch (cmd) { 147 switch (cmd) {
@@ -146,9 +161,8 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
146 case WDIOC_SETTIMEOUT: 161 case WDIOC_SETTIMEOUT:
147 if (get_user(new_timeout, p)) 162 if (get_user(new_timeout, p))
148 return -EFAULT; 163 return -EFAULT;
149 if ((new_timeout < 1) || (new_timeout > 63)) 164 if (advwdt_set_heartbeat(new_timeout))
150 return -EINVAL; 165 return -EINVAL;
151 timeout = new_timeout;
152 advwdt_ping(); 166 advwdt_ping();
153 /* Fall */ 167 /* Fall */
154 168
@@ -209,21 +223,6 @@ advwdt_close(struct inode *inode, struct file *file)
209} 223}
210 224
211/* 225/*
212 * Notifier for system down
213 */
214
215static int
216advwdt_notify_sys(struct notifier_block *this, unsigned long code,
217 void *unused)
218{
219 if (code == SYS_DOWN || code == SYS_HALT) {
220 /* Turn the WDT off */
221 advwdt_disable();
222 }
223 return NOTIFY_DONE;
224}
225
226/*
227 * Kernel Interfaces 226 * Kernel Interfaces
228 */ 227 */
229 228
@@ -237,33 +236,20 @@ static const struct file_operations advwdt_fops = {
237}; 236};
238 237
239static struct miscdevice advwdt_miscdev = { 238static struct miscdevice advwdt_miscdev = {
240 .minor = WATCHDOG_MINOR, 239 .minor = WATCHDOG_MINOR,
241 .name = "watchdog", 240 .name = "watchdog",
242 .fops = &advwdt_fops, 241 .fops = &advwdt_fops,
243}; 242};
244 243
245/* 244/*
246 * The WDT needs to learn about soft shutdowns in order to 245 * Init & exit routines
247 * turn the timebomb registers off.
248 */ 246 */
249 247
250static struct notifier_block advwdt_notifier = { 248static int __devinit
251 .notifier_call = advwdt_notify_sys, 249advwdt_probe(struct platform_device *dev)
252};
253
254static int __init
255advwdt_init(void)
256{ 250{
257 int ret; 251 int ret;
258 252
259 printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
260
261 if (timeout < 1 || timeout > 63) {
262 timeout = WATCHDOG_TIMEOUT;
263 printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
264 timeout);
265 }
266
267 if (wdt_stop != wdt_start) { 253 if (wdt_stop != wdt_start) {
268 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 254 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
269 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 255 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -280,18 +266,18 @@ advwdt_init(void)
280 goto unreg_stop; 266 goto unreg_stop;
281 } 267 }
282 268
283 ret = register_reboot_notifier(&advwdt_notifier); 269 /* Check that the heartbeat value is within it's range ; if not reset to the default */
284 if (ret != 0) { 270 if (advwdt_set_heartbeat(timeout)) {
285 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 271 advwdt_set_heartbeat(WATCHDOG_TIMEOUT);
286 ret); 272 printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
287 goto unreg_regions; 273 timeout);
288 } 274 }
289 275
290 ret = misc_register(&advwdt_miscdev); 276 ret = misc_register(&advwdt_miscdev);
291 if (ret != 0) { 277 if (ret != 0) {
292 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 278 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
293 WATCHDOG_MINOR, ret); 279 WATCHDOG_MINOR, ret);
294 goto unreg_reboot; 280 goto unreg_regions;
295 } 281 }
296 282
297 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 283 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
@@ -299,8 +285,6 @@ advwdt_init(void)
299 285
300out: 286out:
301 return ret; 287 return ret;
302unreg_reboot:
303 unregister_reboot_notifier(&advwdt_notifier);
304unreg_regions: 288unreg_regions:
305 release_region(wdt_start, 1); 289 release_region(wdt_start, 1);
306unreg_stop: 290unreg_stop:
@@ -309,14 +293,64 @@ unreg_stop:
309 goto out; 293 goto out;
310} 294}
311 295
312static void __exit 296static int __devexit
313advwdt_exit(void) 297advwdt_remove(struct platform_device *dev)
314{ 298{
315 misc_deregister(&advwdt_miscdev); 299 misc_deregister(&advwdt_miscdev);
316 unregister_reboot_notifier(&advwdt_notifier); 300 release_region(wdt_start,1);
317 if(wdt_stop != wdt_start) 301 if(wdt_stop != wdt_start)
318 release_region(wdt_stop,1); 302 release_region(wdt_stop,1);
319 release_region(wdt_start,1); 303
304 return 0;
305}
306
307static void
308advwdt_shutdown(struct platform_device *dev)
309{
310 /* Turn the WDT off if we have a soft shutdown */
311 advwdt_disable();
312}
313
314static struct platform_driver advwdt_driver = {
315 .probe = advwdt_probe,
316 .remove = __devexit_p(advwdt_remove),
317 .shutdown = advwdt_shutdown,
318 .driver = {
319 .owner = THIS_MODULE,
320 .name = DRV_NAME,
321 },
322};
323
324static int __init
325advwdt_init(void)
326{
327 int err;
328
329 printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
330
331 err = platform_driver_register(&advwdt_driver);
332 if (err)
333 return err;
334
335 advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
336 if (IS_ERR(advwdt_platform_device)) {
337 err = PTR_ERR(advwdt_platform_device);
338 goto unreg_platform_driver;
339 }
340
341 return 0;
342
343unreg_platform_driver:
344 platform_driver_unregister(&advwdt_driver);
345 return err;
346}
347
348static void __exit
349advwdt_exit(void)
350{
351 platform_device_unregister(advwdt_platform_device);
352 platform_driver_unregister(&advwdt_driver);
353 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
320} 354}
321 355
322module_init(advwdt_init); 356module_init(advwdt_init);
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index 01b0d132ee4..e3f6a7d0c83 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, defaul
40 40
41static int nowayout = WATCHDOG_NOWAYOUT; 41static int nowayout = WATCHDOG_NOWAYOUT;
42module_param(nowayout, int, 0); 42module_param(nowayout, int, 0);
43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44 44
45/* 45/*
46 * ali_start - start watchdog countdown 46 * ali_start - start watchdog countdown
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index e5b2c2ee292..67aed9f8c36 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -69,7 +69,7 @@ module_param(use_gpio, int, 0);
69MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); 69MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)");
70 70
71static void wdt_timer_ping(unsigned long); 71static void wdt_timer_ping(unsigned long);
72static struct timer_list timer; 72static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
73static unsigned long next_heartbeat; 73static unsigned long next_heartbeat;
74static unsigned long wdt_is_open; 74static unsigned long wdt_is_open;
75static char wdt_expect_close; 75static char wdt_expect_close;
@@ -78,7 +78,7 @@ static struct pci_dev *alim7101_pmu;
78static int nowayout = WATCHDOG_NOWAYOUT; 78static int nowayout = WATCHDOG_NOWAYOUT;
79module_param(nowayout, int, 0); 79module_param(nowayout, int, 0);
80MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 80MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
81 __stringify(CONFIG_WATCHDOG_NOWAYOUT) ")"); 81 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 82
83/* 83/*
84 * Whack the dog 84 * Whack the dog
@@ -108,8 +108,7 @@ static void wdt_timer_ping(unsigned long data)
108 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 108 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
109 } 109 }
110 /* Re-set the timer interval */ 110 /* Re-set the timer interval */
111 timer.expires = jiffies + WDT_INTERVAL; 111 mod_timer(&timer, jiffies + WDT_INTERVAL);
112 add_timer(&timer);
113} 112}
114 113
115/* 114/*
@@ -147,9 +146,7 @@ static void wdt_startup(void)
147 wdt_change(WDT_ENABLE); 146 wdt_change(WDT_ENABLE);
148 147
149 /* Start the timer */ 148 /* Start the timer */
150 timer.expires = jiffies + WDT_INTERVAL; 149 mod_timer(&timer, jiffies + WDT_INTERVAL);
151 add_timer(&timer);
152
153 150
154 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); 151 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
155} 152}
@@ -380,10 +377,6 @@ static int __init alim7101_wdt_init(void)
380 timeout); 377 timeout);
381 } 378 }
382 379
383 init_timer(&timer);
384 timer.function = wdt_timer_ping;
385 timer.data = 1;
386
387 rc = misc_register(&wdt_miscdev); 380 rc = misc_register(&wdt_miscdev);
388 if (rc) { 381 if (rc) {
389 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 382 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 00bdabb90f2..bcd7e36ca0a 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -80,10 +80,8 @@ static void cpu5wdt_trigger(unsigned long unused)
80 outb(1, port + CPU5WDT_TRIGGER_REG); 80 outb(1, port + CPU5WDT_TRIGGER_REG);
81 81
82 /* requeue?? */ 82 /* requeue?? */
83 if( cpu5wdt_device.queue && ticks ) { 83 if (cpu5wdt_device.queue && ticks)
84 cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL; 84 mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL);
85 add_timer(&cpu5wdt_device.timer);
86 }
87 else { 85 else {
88 /* ticks doesn't matter anyway */ 86 /* ticks doesn't matter anyway */
89 complete(&cpu5wdt_device.stop); 87 complete(&cpu5wdt_device.stop);
@@ -109,8 +107,7 @@ static void cpu5wdt_start(void)
109 outb(1, port + CPU5WDT_MODE_REG); 107 outb(1, port + CPU5WDT_MODE_REG);
110 outb(0, port + CPU5WDT_RESET_REG); 108 outb(0, port + CPU5WDT_RESET_REG);
111 outb(0, port + CPU5WDT_ENABLE_REG); 109 outb(0, port + CPU5WDT_ENABLE_REG);
112 cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL; 110 mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL);
113 add_timer(&cpu5wdt_device.timer);
114 } 111 }
115 /* if process dies, counter is not decremented */ 112 /* if process dies, counter is not decremented */
116 cpu5wdt_device.running++; 113 cpu5wdt_device.running++;
@@ -245,9 +242,7 @@ static int __devinit cpu5wdt_init(void)
245 242
246 clear_bit(0, &cpu5wdt_device.inuse); 243 clear_bit(0, &cpu5wdt_device.inuse);
247 244
248 init_timer(&cpu5wdt_device.timer); 245 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
249 cpu5wdt_device.timer.function = cpu5wdt_trigger;
250 cpu5wdt_device.timer.data = 0;
251 246
252 cpu5wdt_device.default_ticks = ticks; 247 cpu5wdt_device.default_ticks = ticks;
253 248
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index e228d6e173c..f70387f01b2 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -73,7 +73,7 @@ static char *ev = "int";
73 73
74static int nowayout = WATCHDOG_NOWAYOUT; 74static int nowayout = WATCHDOG_NOWAYOUT;
75module_param(nowayout, int, 0); 75module_param(nowayout, int, 0);
76MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 76MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
77 77
78/* 78/*
79 * Some symbolic names 79 * Some symbolic names
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
index fb64df4d7c8..c5982502c03 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/char/watchdog/i6300esb.c
@@ -91,7 +91,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, d
91 91
92static int nowayout = WATCHDOG_NOWAYOUT; 92static int nowayout = WATCHDOG_NOWAYOUT;
93module_param(nowayout, int, 0); 93module_param(nowayout, int, 0);
94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
95 95
96/* 96/*
97 * Some i6300ESB specific functions 97 * Some i6300ESB specific functions
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index e0627d79707..a62ef48a15a 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -109,7 +109,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39, def
109 109
110static int nowayout = WATCHDOG_NOWAYOUT; 110static int nowayout = WATCHDOG_NOWAYOUT;
111module_param(nowayout, int, 0); 111module_param(nowayout, int, 0);
112MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 112MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
113 113
114/* 114/*
115 * Some TCO specific functions 115 * Some TCO specific functions
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
index fd8a44a08cd..3c9684ccd2f 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) 2 * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
3 * 3 *
4 * (c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2006-2007 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -49,7 +49,7 @@
49/* Module and version information */ 49/* Module and version information */
50#define DRV_NAME "iTCO_wdt" 50#define DRV_NAME "iTCO_wdt"
51#define DRV_VERSION "1.01" 51#define DRV_VERSION "1.01"
52#define DRV_RELDATE "11-Nov-2006" 52#define DRV_RELDATE "21-Jan-2007"
53#define PFX DRV_NAME ": " 53#define PFX DRV_NAME ": "
54 54
55/* Includes */ 55/* Includes */
@@ -187,7 +187,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO
187 187
188static int nowayout = WATCHDOG_NOWAYOUT; 188static int nowayout = WATCHDOG_NOWAYOUT;
189module_param(nowayout, int, 0); 189module_param(nowayout, int, 0);
190MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 190MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
191 191
192/* iTCO Vendor Specific Support hooks */ 192/* iTCO Vendor Specific Support hooks */
193#ifdef CONFIG_ITCO_VENDOR_SUPPORT 193#ifdef CONFIG_ITCO_VENDOR_SUPPORT
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
index c1ed209a138..c3a60f52ccb 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * (c) Copyright 2001 Charles Howes <chowes@vsol.net> 4 * (c) Copyright 2001 Charles Howes <chowes@vsol.net>
5 * 5 *
6 * Based on advantechwdt.c which is based on acquirewdt.c which 6 * Based on advantechwdt.c which is based on acquirewdt.c which
7 * is based on wdt.c. 7 * is based on wdt.c.
8 * 8 *
9 * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl> 9 * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
10 * 10 *
@@ -25,9 +25,9 @@
25 * 25 *
26 * (c) Copyright 1995 Alan Cox <alan@redhat.com> 26 * (c) Copyright 1995 Alan Cox <alan@redhat.com>
27 * 27 *
28 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> 28 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
29 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT 29 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
30 * Added timeout module option to override default 30 * Added timeout module option to override default
31 * 31 *
32 */ 32 */
33 33
@@ -36,22 +36,24 @@
36#include <linux/miscdevice.h> 36#include <linux/miscdevice.h>
37#include <linux/watchdog.h> 37#include <linux/watchdog.h>
38#include <linux/ioport.h> 38#include <linux/ioport.h>
39#include <linux/notifier.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/reboot.h>
42#include <linux/init.h> 40#include <linux/init.h>
43#include <linux/spinlock.h> 41#include <linux/spinlock.h>
44#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/platform_device.h>
45 44
46#include <asm/io.h> 45#include <asm/io.h>
47#include <asm/uaccess.h> 46#include <asm/uaccess.h>
48#include <asm/system.h> 47#include <asm/system.h>
49 48
49static struct platform_device *ibwdt_platform_device;
50static unsigned long ibwdt_is_open; 50static unsigned long ibwdt_is_open;
51static spinlock_t ibwdt_lock; 51static spinlock_t ibwdt_lock;
52static char expect_close; 52static char expect_close;
53 53
54#define PFX "ib700wdt: " 54/* Module information */
55#define DRV_NAME "ib700wdt"
56#define PFX DRV_NAME ": "
55 57
56/* 58/*
57 * 59 *
@@ -118,20 +120,51 @@ static int wd_margin = WD_TIMO;
118 120
119static int nowayout = WATCHDOG_NOWAYOUT; 121static int nowayout = WATCHDOG_NOWAYOUT;
120module_param(nowayout, int, 0); 122module_param(nowayout, int, 0);
121MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 123MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
122 124
123 125
124/* 126/*
125 * Kernel methods. 127 * Watchdog Operations
126 */ 128 */
127 129
128static void 130static void
129ibwdt_ping(void) 131ibwdt_ping(void)
130{ 132{
133 spin_lock(&ibwdt_lock);
134
131 /* Write a watchdog value */ 135 /* Write a watchdog value */
132 outb_p(wd_margin, WDT_START); 136 outb_p(wd_margin, WDT_START);
137
138 spin_unlock(&ibwdt_lock);
133} 139}
134 140
141static void
142ibwdt_disable(void)
143{
144 spin_lock(&ibwdt_lock);
145 outb_p(0, WDT_STOP);
146 spin_unlock(&ibwdt_lock);
147}
148
149static int
150ibwdt_set_heartbeat(int t)
151{
152 int i;
153
154 if ((t < 0) || (t > 30))
155 return -EINVAL;
156
157 for (i = 0x0F; i > -1; i--)
158 if (wd_times[i] > t)
159 break;
160 wd_margin = i;
161 return 0;
162}
163
164/*
165 * /dev/watchdog handling
166 */
167
135static ssize_t 168static ssize_t
136ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 169ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
137{ 170{
@@ -159,7 +192,7 @@ static int
159ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 192ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
160 unsigned long arg) 193 unsigned long arg)
161{ 194{
162 int i, new_margin; 195 int new_margin;
163 void __user *argp = (void __user *)arg; 196 void __user *argp = (void __user *)arg;
164 int __user *p = argp; 197 int __user *p = argp;
165 198
@@ -176,6 +209,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
176 break; 209 break;
177 210
178 case WDIOC_GETSTATUS: 211 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS:
179 return put_user(0, p); 213 return put_user(0, p);
180 214
181 case WDIOC_KEEPALIVE: 215 case WDIOC_KEEPALIVE:
@@ -185,18 +219,33 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
185 case WDIOC_SETTIMEOUT: 219 case WDIOC_SETTIMEOUT:
186 if (get_user(new_margin, p)) 220 if (get_user(new_margin, p))
187 return -EFAULT; 221 return -EFAULT;
188 if ((new_margin < 0) || (new_margin > 30)) 222 if (ibwdt_set_heartbeat(new_margin))
189 return -EINVAL; 223 return -EINVAL;
190 for (i = 0x0F; i > -1; i--)
191 if (wd_times[i] > new_margin)
192 break;
193 wd_margin = i;
194 ibwdt_ping(); 224 ibwdt_ping();
195 /* Fall */ 225 /* Fall */
196 226
197 case WDIOC_GETTIMEOUT: 227 case WDIOC_GETTIMEOUT:
198 return put_user(wd_times[wd_margin], p); 228 return put_user(wd_times[wd_margin], p);
199 break; 229
230 case WDIOC_SETOPTIONS:
231 {
232 int options, retval = -EINVAL;
233
234 if (get_user(options, p))
235 return -EFAULT;
236
237 if (options & WDIOS_DISABLECARD) {
238 ibwdt_disable();
239 retval = 0;
240 }
241
242 if (options & WDIOS_ENABLECARD) {
243 ibwdt_ping();
244 retval = 0;
245 }
246
247 return retval;
248 }
200 249
201 default: 250 default:
202 return -ENOTTY; 251 return -ENOTTY;
@@ -207,9 +256,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
207static int 256static int
208ibwdt_open(struct inode *inode, struct file *file) 257ibwdt_open(struct inode *inode, struct file *file)
209{ 258{
210 spin_lock(&ibwdt_lock);
211 if (test_and_set_bit(0, &ibwdt_is_open)) { 259 if (test_and_set_bit(0, &ibwdt_is_open)) {
212 spin_unlock(&ibwdt_lock);
213 return -EBUSY; 260 return -EBUSY;
214 } 261 }
215 if (nowayout) 262 if (nowayout)
@@ -217,41 +264,24 @@ ibwdt_open(struct inode *inode, struct file *file)
217 264
218 /* Activate */ 265 /* Activate */
219 ibwdt_ping(); 266 ibwdt_ping();
220 spin_unlock(&ibwdt_lock);
221 return nonseekable_open(inode, file); 267 return nonseekable_open(inode, file);
222} 268}
223 269
224static int 270static int
225ibwdt_close(struct inode *inode, struct file *file) 271ibwdt_close(struct inode *inode, struct file *file)
226{ 272{
227 spin_lock(&ibwdt_lock); 273 if (expect_close == 42) {
228 if (expect_close == 42) 274 ibwdt_disable();
229 outb_p(0, WDT_STOP); 275 } else {
230 else
231 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 276 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n");
232 277 ibwdt_ping();
278 }
233 clear_bit(0, &ibwdt_is_open); 279 clear_bit(0, &ibwdt_is_open);
234 expect_close = 0; 280 expect_close = 0;
235 spin_unlock(&ibwdt_lock);
236 return 0; 281 return 0;
237} 282}
238 283
239/* 284/*
240 * Notifier for system down
241 */
242
243static int
244ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
245 void *unused)
246{
247 if (code == SYS_DOWN || code == SYS_HALT) {
248 /* Turn the WDT off */
249 outb_p(0, WDT_STOP);
250 }
251 return NOTIFY_DONE;
252}
253
254/*
255 * Kernel Interfaces 285 * Kernel Interfaces
256 */ 286 */
257 287
@@ -271,26 +301,14 @@ static struct miscdevice ibwdt_miscdev = {
271}; 301};
272 302
273/* 303/*
274 * The WDT needs to learn about soft shutdowns in order to 304 * Init & exit routines
275 * turn the timebomb registers off.
276 */ 305 */
277 306
278static struct notifier_block ibwdt_notifier = { 307static int __devinit ibwdt_probe(struct platform_device *dev)
279 .notifier_call = ibwdt_notify_sys,
280};
281
282static int __init ibwdt_init(void)
283{ 308{
284 int res; 309 int res;
285 310
286 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
287
288 spin_lock_init(&ibwdt_lock); 311 spin_lock_init(&ibwdt_lock);
289 res = misc_register(&ibwdt_miscdev);
290 if (res) {
291 printk (KERN_ERR PFX "failed to register misc device\n");
292 goto out_nomisc;
293 }
294 312
295#if WDT_START != WDT_STOP 313#if WDT_START != WDT_STOP
296 if (!request_region(WDT_STOP, 1, "IB700 WDT")) { 314 if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
@@ -305,34 +323,78 @@ static int __init ibwdt_init(void)
305 res = -EIO; 323 res = -EIO;
306 goto out_nostartreg; 324 goto out_nostartreg;
307 } 325 }
308 res = register_reboot_notifier(&ibwdt_notifier); 326
327 res = misc_register(&ibwdt_miscdev);
309 if (res) { 328 if (res) {
310 printk (KERN_ERR PFX "Failed to register reboot notifier.\n"); 329 printk (KERN_ERR PFX "failed to register misc device\n");
311 goto out_noreboot; 330 goto out_nomisc;
312 } 331 }
313 return 0; 332 return 0;
314 333
315out_noreboot: 334out_nomisc:
316 release_region(WDT_START, 1); 335 release_region(WDT_START, 1);
317out_nostartreg: 336out_nostartreg:
318#if WDT_START != WDT_STOP 337#if WDT_START != WDT_STOP
319 release_region(WDT_STOP, 1); 338 release_region(WDT_STOP, 1);
320#endif 339#endif
321out_nostopreg: 340out_nostopreg:
322 misc_deregister(&ibwdt_miscdev);
323out_nomisc:
324 return res; 341 return res;
325} 342}
326 343
327static void __exit 344static int __devexit ibwdt_remove(struct platform_device *dev)
328ibwdt_exit(void)
329{ 345{
330 misc_deregister(&ibwdt_miscdev); 346 misc_deregister(&ibwdt_miscdev);
331 unregister_reboot_notifier(&ibwdt_notifier); 347 release_region(WDT_START,1);
332#if WDT_START != WDT_STOP 348#if WDT_START != WDT_STOP
333 release_region(WDT_STOP,1); 349 release_region(WDT_STOP,1);
334#endif 350#endif
335 release_region(WDT_START,1); 351 return 0;
352}
353
354static void ibwdt_shutdown(struct platform_device *dev)
355{
356 /* Turn the WDT off if we have a soft shutdown */
357 ibwdt_disable();
358}
359
360static struct platform_driver ibwdt_driver = {
361 .probe = ibwdt_probe,
362 .remove = __devexit_p(ibwdt_remove),
363 .shutdown = ibwdt_shutdown,
364 .driver = {
365 .owner = THIS_MODULE,
366 .name = DRV_NAME,
367 },
368};
369
370static int __init ibwdt_init(void)
371{
372 int err;
373
374 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
375
376 err = platform_driver_register(&ibwdt_driver);
377 if (err)
378 return err;
379
380 ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
381 if (IS_ERR(ibwdt_platform_device)) {
382 err = PTR_ERR(ibwdt_platform_device);
383 goto unreg_platform_driver;
384 }
385
386 return 0;
387
388unreg_platform_driver:
389 platform_driver_unregister(&ibwdt_driver);
390 return err;
391}
392
393static void __exit ibwdt_exit(void)
394{
395 platform_device_unregister(ibwdt_platform_device);
396 platform_driver_unregister(&ibwdt_driver);
397 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
336} 398}
337 399
338module_init(ibwdt_init); 400module_init(ibwdt_init);
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
index dd6760f1a23..8195f5023d8 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/char/watchdog/ibmasr.c
@@ -396,7 +396,7 @@ module_init(ibmasr_init);
396module_exit(ibmasr_exit); 396module_exit(ibmasr_exit);
397 397
398module_param(nowayout, int, 0); 398module_param(nowayout, int, 0);
399MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 399MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
400 400
401MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); 401MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
402MODULE_AUTHOR("Andrey Panin"); 402MODULE_AUTHOR("Andrey Panin");
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
index 0bc23930898..788245bdaa7 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -32,7 +32,7 @@ static int indydog_alive;
32 32
33static int nowayout = WATCHDOG_NOWAYOUT; 33static int nowayout = WATCHDOG_NOWAYOUT;
34module_param(nowayout, int, 0); 34module_param(nowayout, int, 0);
35MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 35MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
36 36
37static void indydog_start(void) 37static void indydog_start(void)
38{ 38{
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 4d730fdbd52..81fb3dec180 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -95,7 +95,7 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
95 95
96static int nowayout = WATCHDOG_NOWAYOUT; 96static int nowayout = WATCHDOG_NOWAYOUT;
97module_param(nowayout, int, 0); 97module_param(nowayout, int, 0);
98MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 98MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
99 99
100#define PFX "machzwd" 100#define PFX "machzwd"
101 101
@@ -118,12 +118,14 @@ static int action = 0;
118module_param(action, int, 0); 118module_param(action, int, 0);
119MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); 119MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
120 120
121static void zf_ping(unsigned long data);
122
121static int zf_action = GEN_RESET; 123static int zf_action = GEN_RESET;
122static unsigned long zf_is_open; 124static unsigned long zf_is_open;
123static char zf_expect_close; 125static char zf_expect_close;
124static spinlock_t zf_lock; 126static spinlock_t zf_lock;
125static spinlock_t zf_port_lock; 127static spinlock_t zf_port_lock;
126static struct timer_list zf_timer; 128static DEFINE_TIMER(zf_timer, zf_ping, 0, 0);
127static unsigned long next_heartbeat = 0; 129static unsigned long next_heartbeat = 0;
128 130
129 131
@@ -220,9 +222,7 @@ static void zf_timer_on(void)
220 next_heartbeat = jiffies + ZF_USER_TIMEO; 222 next_heartbeat = jiffies + ZF_USER_TIMEO;
221 223
222 /* start the timer for internal ping */ 224 /* start the timer for internal ping */
223 zf_timer.expires = jiffies + ZF_HW_TIMEO; 225 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
224
225 add_timer(&zf_timer);
226 226
227 /* start watchdog timer */ 227 /* start watchdog timer */
228 ctrl_reg = zf_get_control(); 228 ctrl_reg = zf_get_control();
@@ -260,8 +260,7 @@ static void zf_ping(unsigned long data)
260 zf_set_control(ctrl_reg); 260 zf_set_control(ctrl_reg);
261 spin_unlock_irqrestore(&zf_port_lock, flags); 261 spin_unlock_irqrestore(&zf_port_lock, flags);
262 262
263 zf_timer.expires = jiffies + ZF_HW_TIMEO; 263 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
264 add_timer(&zf_timer);
265 }else{ 264 }else{
266 printk(KERN_CRIT PFX ": I will reset your machine\n"); 265 printk(KERN_CRIT PFX ": I will reset your machine\n");
267 } 266 }
@@ -465,11 +464,6 @@ static int __init zf_init(void)
465 zf_set_status(0); 464 zf_set_status(0);
466 zf_set_control(0); 465 zf_set_control(0);
467 466
468 /* this is the timer that will do the hard work */
469 init_timer(&zf_timer);
470 zf_timer.function = zf_ping;
471 zf_timer.data = 0;
472
473 return 0; 467 return 0;
474 468
475no_reboot: 469no_reboot:
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index c2dac0aa1d6..f35e2848aa3 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -56,16 +56,18 @@ static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 };
56#define FLASHCOM_WATCHDOG_OFFSET 0x4 56#define FLASHCOM_WATCHDOG_OFFSET 0x4
57#define FLASHCOM_ID 0x18 57#define FLASHCOM_ID 0x18
58 58
59static void mixcomwd_timerfun(unsigned long d);
60
59static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */ 61static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
60 62
61static int watchdog_port; 63static int watchdog_port;
62static int mixcomwd_timer_alive; 64static int mixcomwd_timer_alive;
63static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0); 65static DEFINE_TIMER(mixcomwd_timer, mixcomwd_timerfun, 0, 0);
64static char expect_close; 66static char expect_close;
65 67
66static int nowayout = WATCHDOG_NOWAYOUT; 68static int nowayout = WATCHDOG_NOWAYOUT;
67module_param(nowayout, int, 0); 69module_param(nowayout, int, 0);
68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 70MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 71
70static void mixcomwd_ping(void) 72static void mixcomwd_ping(void)
71{ 73{
@@ -77,7 +79,7 @@ static void mixcomwd_timerfun(unsigned long d)
77{ 79{
78 mixcomwd_ping(); 80 mixcomwd_ping();
79 81
80 mod_timer(&mixcomwd_timer,jiffies+ 5*HZ); 82 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
81} 83}
82 84
83/* 85/*
@@ -114,12 +116,8 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
114 printk(KERN_ERR "mixcomwd: release called while internal timer alive"); 116 printk(KERN_ERR "mixcomwd: release called while internal timer alive");
115 return -EBUSY; 117 return -EBUSY;
116 } 118 }
117 init_timer(&mixcomwd_timer);
118 mixcomwd_timer.expires=jiffies + 5 * HZ;
119 mixcomwd_timer.function=mixcomwd_timerfun;
120 mixcomwd_timer.data=0;
121 mixcomwd_timer_alive=1; 119 mixcomwd_timer_alive=1;
122 add_timer(&mixcomwd_timer); 120 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
123 } else { 121 } else {
124 printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly. WDT will not stop!\n"); 122 printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly. WDT will not stop!\n");
125 } 123 }
@@ -285,7 +283,7 @@ static void __exit mixcomwd_exit(void)
285 if(mixcomwd_timer_alive) { 283 if(mixcomwd_timer_alive) {
286 printk(KERN_WARNING "mixcomwd: I quit now, hardware will" 284 printk(KERN_WARNING "mixcomwd: I quit now, hardware will"
287 " probably reboot!\n"); 285 " probably reboot!\n");
288 del_timer(&mixcomwd_timer); 286 del_timer_sync(&mixcomwd_timer);
289 mixcomwd_timer_alive=0; 287 mixcomwd_timer_alive=0;
290 } 288 }
291 } 289 }
diff --git a/drivers/char/watchdog/pc87413_wdt.c b/drivers/char/watchdog/pc87413_wdt.c
index a77a90717ad..3d3deae0d64 100644
--- a/drivers/char/watchdog/pc87413_wdt.c
+++ b/drivers/char/watchdog/pc87413_wdt.c
@@ -631,5 +631,5 @@ module_param(timeout, int, 0);
631MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ")."); 631MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ").");
632 632
633module_param(nowayout, int, 0); 633module_param(nowayout, int, 0);
634MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 634MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
635 635
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 8e1e6e48e0a..6e8b5705b5b 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -2,7 +2,7 @@
2 * PC Watchdog Driver 2 * PC Watchdog Driver
3 * by Ken Hollis (khollis@bitgate.com) 3 * by Ken Hollis (khollis@bitgate.com)
4 * 4 *
5 * Permission granted from Simon Machell (73244.1270@compuserve.com) 5 * Permission granted from Simon Machell (smachell@berkprod.com)
6 * Written for the Linux Kernel, and GPLed by Ken Hollis 6 * Written for the Linux Kernel, and GPLed by Ken Hollis
7 * 7 *
8 * 960107 Added request_region routines, modulized the whole thing. 8 * 960107 Added request_region routines, modulized the whole thing.
@@ -70,8 +70,8 @@
70#include <asm/io.h> /* For inb/outb/... */ 70#include <asm/io.h> /* For inb/outb/... */
71 71
72/* Module and version information */ 72/* Module and version information */
73#define WATCHDOG_VERSION "1.17" 73#define WATCHDOG_VERSION "1.18"
74#define WATCHDOG_DATE "12 Feb 2006" 74#define WATCHDOG_DATE "21 Jan 2007"
75#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" 75#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
76#define WATCHDOG_NAME "pcwd" 76#define WATCHDOG_NAME "pcwd"
77#define PFX WATCHDOG_NAME ": " 77#define PFX WATCHDOG_NAME ": "
@@ -132,6 +132,18 @@
132#define CMD_ISA_DELAY_TIME_8SECS 0x0C 132#define CMD_ISA_DELAY_TIME_8SECS 0x0C
133#define CMD_ISA_RESET_RELAYS 0x0D 133#define CMD_ISA_RESET_RELAYS 0x0D
134 134
135/* Watchdog's Dip Switch heartbeat values */
136static const int heartbeat_tbl [] = {
137 20, /* OFF-OFF-OFF = 20 Sec */
138 40, /* OFF-OFF-ON = 40 Sec */
139 60, /* OFF-ON-OFF = 1 Min */
140 300, /* OFF-ON-ON = 5 Min */
141 600, /* ON-OFF-OFF = 10 Min */
142 1800, /* ON-OFF-ON = 30 Min */
143 3600, /* ON-ON-OFF = 1 Hour */
144 7200, /* ON-ON-ON = 2 hour */
145};
146
135/* 147/*
136 * We are using an kernel timer to do the pinging of the watchdog 148 * We are using an kernel timer to do the pinging of the watchdog
137 * every ~500ms. We try to set the internal heartbeat of the 149 * every ~500ms. We try to set the internal heartbeat of the
@@ -167,14 +179,14 @@ static int debug = QUIET;
167module_param(debug, int, 0); 179module_param(debug, int, 0);
168MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); 180MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
169 181
170#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ 182#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
171static int heartbeat = WATCHDOG_HEARTBEAT; 183static int heartbeat = WATCHDOG_HEARTBEAT;
172module_param(heartbeat, int, 0); 184module_param(heartbeat, int, 0);
173MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 185MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
174 186
175static int nowayout = WATCHDOG_NOWAYOUT; 187static int nowayout = WATCHDOG_NOWAYOUT;
176module_param(nowayout, int, 0); 188module_param(nowayout, int, 0);
177MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 189MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
178 190
179/* 191/*
180 * Internal functions 192 * Internal functions
@@ -831,9 +843,7 @@ static int __devinit pcwatchdog_init(int base_addr)
831 /* clear the "card caused reboot" flag */ 843 /* clear the "card caused reboot" flag */
832 pcwd_clear_status(); 844 pcwd_clear_status();
833 845
834 init_timer(&pcwd_private.timer); 846 setup_timer(&pcwd_private.timer, pcwd_timer_ping, 0);
835 pcwd_private.timer.function = pcwd_timer_ping;
836 pcwd_private.timer.data = 0;
837 847
838 /* Disable the board */ 848 /* Disable the board */
839 pcwd_stop(); 849 pcwd_stop();
@@ -844,6 +854,10 @@ static int __devinit pcwatchdog_init(int base_addr)
844 /* Show info about the card itself */ 854 /* Show info about the card itself */
845 pcwd_show_card_info(); 855 pcwd_show_card_info();
846 856
857 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
858 if (heartbeat == 0)
859 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)];
860
847 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 861 /* Check that the heartbeat value is within it's range ; if not reset to the default */
848 if (pcwd_set_heartbeat(heartbeat)) { 862 if (pcwd_set_heartbeat(heartbeat)) {
849 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 863 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index f4872c87106..61a89e95964 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Berkshire PCI-PC Watchdog Card Driver 2 * Berkshire PCI-PC Watchdog Card Driver
3 * 3 *
4 * (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2003-2007 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * Based on source code of the following authors: 6 * Based on source code of the following authors:
7 * Ken Hollis <kenji@bitgate.com>, 7 * Ken Hollis <kenji@bitgate.com>,
@@ -51,8 +51,8 @@
51#include <asm/io.h> /* For inb/outb/... */ 51#include <asm/io.h> /* For inb/outb/... */
52 52
53/* Module and version information */ 53/* Module and version information */
54#define WATCHDOG_VERSION "1.02" 54#define WATCHDOG_VERSION "1.03"
55#define WATCHDOG_DATE "03 Sep 2005" 55#define WATCHDOG_DATE "21 Jan 2007"
56#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" 56#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
57#define WATCHDOG_NAME "pcwd_pci" 57#define WATCHDOG_NAME "pcwd_pci"
58#define PFX WATCHDOG_NAME ": " 58#define PFX WATCHDOG_NAME ": "
@@ -96,6 +96,18 @@
96#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 96#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19
97#define CMD_GET_CLEAR_RESET_COUNT 0x84 97#define CMD_GET_CLEAR_RESET_COUNT 0x84
98 98
99/* Watchdog's Dip Switch heartbeat values */
100static const int heartbeat_tbl [] = {
101 5, /* OFF-OFF-OFF = 5 Sec */
102 10, /* OFF-OFF-ON = 10 Sec */
103 30, /* OFF-ON-OFF = 30 Sec */
104 60, /* OFF-ON-ON = 1 Min */
105 300, /* ON-OFF-OFF = 5 Min */
106 600, /* ON-OFF-ON = 10 Min */
107 1800, /* ON-ON-OFF = 30 Min */
108 3600, /* ON-ON-ON = 1 hour */
109};
110
99/* We can only use 1 card due to the /dev/watchdog restriction */ 111/* We can only use 1 card due to the /dev/watchdog restriction */
100static int cards_found; 112static int cards_found;
101 113
@@ -119,14 +131,14 @@ static int debug = QUIET;
119module_param(debug, int, 0); 131module_param(debug, int, 0);
120MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); 132MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
121 133
122#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ 134#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
123static int heartbeat = WATCHDOG_HEARTBEAT; 135static int heartbeat = WATCHDOG_HEARTBEAT;
124module_param(heartbeat, int, 0); 136module_param(heartbeat, int, 0);
125MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 137MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
126 138
127static int nowayout = WATCHDOG_NOWAYOUT; 139static int nowayout = WATCHDOG_NOWAYOUT;
128module_param(nowayout, int, 0); 140module_param(nowayout, int, 0);
129MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 141MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
130 142
131/* 143/*
132 * Internal functions 144 * Internal functions
@@ -286,7 +298,9 @@ static int pcipcwd_stop(void)
286static int pcipcwd_keepalive(void) 298static int pcipcwd_keepalive(void)
287{ 299{
288 /* Re-trigger watchdog by writing to port 0 */ 300 /* Re-trigger watchdog by writing to port 0 */
301 spin_lock(&pcipcwd_private.io_lock);
289 outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */ 302 outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */
303 spin_unlock(&pcipcwd_private.io_lock);
290 304
291 if (debug >= DEBUG) 305 if (debug >= DEBUG)
292 printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n"); 306 printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
@@ -373,7 +387,9 @@ static int pcipcwd_get_temperature(int *temperature)
373 if (!pcipcwd_private.supports_temp) 387 if (!pcipcwd_private.supports_temp)
374 return -ENODEV; 388 return -ENODEV;
375 389
390 spin_lock(&pcipcwd_private.io_lock);
376 *temperature = inb_p(pcipcwd_private.io_addr); 391 *temperature = inb_p(pcipcwd_private.io_addr);
392 spin_unlock(&pcipcwd_private.io_lock);
377 393
378 /* 394 /*
379 * Convert celsius to fahrenheit, since this was 395 * Convert celsius to fahrenheit, since this was
@@ -711,6 +727,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
711 /* Show info about the card itself */ 727 /* Show info about the card itself */
712 pcipcwd_show_card_info(); 728 pcipcwd_show_card_info();
713 729
730 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
731 if (heartbeat == 0)
732 heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
733
714 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 734 /* Check that the heartbeat value is within it's range ; if not reset to the default */
715 if (pcipcwd_set_heartbeat(heartbeat)) { 735 if (pcipcwd_set_heartbeat(heartbeat)) {
716 pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 736 pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
@@ -798,6 +818,8 @@ static int __init pcipcwd_init_module(void)
798static void __exit pcipcwd_cleanup_module(void) 818static void __exit pcipcwd_cleanup_module(void)
799{ 819{
800 pci_unregister_driver(&pcipcwd_driver); 820 pci_unregister_driver(&pcipcwd_driver);
821
822 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
801} 823}
802 824
803module_init(pcipcwd_init_module); 825module_init(pcipcwd_init_module);
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 2da5ac99687..31037f9c9ff 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Berkshire USB-PC Watchdog Card Driver 2 * Berkshire USB-PC Watchdog Card Driver
3 * 3 *
4 * (c) Copyright 2004 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2004-2007 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * Based on source code of the following authors: 6 * Based on source code of the following authors:
7 * Ken Hollis <kenji@bitgate.com>, 7 * Ken Hollis <kenji@bitgate.com>,
@@ -24,26 +24,25 @@
24 * http://www.berkprod.com/ or http://www.pcwatchdog.com/ 24 * http://www.berkprod.com/ or http://www.pcwatchdog.com/
25 */ 25 */
26 26
27#include <linux/kernel.h> 27#include <linux/module.h> /* For module specific items */
28#include <linux/errno.h> 28#include <linux/moduleparam.h> /* For new moduleparam's */
29#include <linux/init.h> 29#include <linux/types.h> /* For standard types (like size_t) */
30#include <linux/slab.h> 30#include <linux/errno.h> /* For the -ENODEV/... values */
31#include <linux/module.h> 31#include <linux/kernel.h> /* For printk/panic/... */
32#include <linux/moduleparam.h> 32#include <linux/delay.h> /* For mdelay function */
33#include <linux/types.h> 33#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
34#include <linux/delay.h> 34#include <linux/watchdog.h> /* For the watchdog specific items */
35#include <linux/miscdevice.h> 35#include <linux/notifier.h> /* For notifier support */
36#include <linux/watchdog.h> 36#include <linux/reboot.h> /* For reboot_notifier stuff */
37#include <linux/notifier.h> 37#include <linux/init.h> /* For __init/__exit/... */
38#include <linux/reboot.h> 38#include <linux/fs.h> /* For file operations */
39#include <linux/fs.h> 39#include <linux/usb.h> /* For USB functions */
40#include <linux/smp_lock.h> 40#include <linux/slab.h> /* For kmalloc, ... */
41#include <linux/completion.h> 41#include <linux/mutex.h> /* For mutex locking */
42#include <asm/uaccess.h>
43#include <linux/usb.h>
44#include <linux/mutex.h>
45#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ 42#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */
46 43
44#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
45
47 46
48#ifdef CONFIG_USB_DEBUG 47#ifdef CONFIG_USB_DEBUG
49 static int debug = 1; 48 static int debug = 1;
@@ -57,8 +56,8 @@
57 56
58 57
59/* Module and Version Information */ 58/* Module and Version Information */
60#define DRIVER_VERSION "1.01" 59#define DRIVER_VERSION "1.02"
61#define DRIVER_DATE "15 Mar 2005" 60#define DRIVER_DATE "21 Jan 2007"
62#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>" 61#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
63#define DRIVER_DESC "Berkshire USB-PC Watchdog driver" 62#define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
64#define DRIVER_LICENSE "GPL" 63#define DRIVER_LICENSE "GPL"
@@ -75,14 +74,14 @@ MODULE_ALIAS_MISCDEV(TEMP_MINOR);
75module_param(debug, int, 0); 74module_param(debug, int, 0);
76MODULE_PARM_DESC(debug, "Debug enabled or not"); 75MODULE_PARM_DESC(debug, "Debug enabled or not");
77 76
78#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ 77#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
79static int heartbeat = WATCHDOG_HEARTBEAT; 78static int heartbeat = WATCHDOG_HEARTBEAT;
80module_param(heartbeat, int, 0); 79module_param(heartbeat, int, 0);
81MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 80MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
82 81
83static int nowayout = WATCHDOG_NOWAYOUT; 82static int nowayout = WATCHDOG_NOWAYOUT;
84module_param(nowayout, int, 0); 83module_param(nowayout, int, 0);
85MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 84MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
86 85
87/* The vendor and product id's for the USB-PC Watchdog card */ 86/* The vendor and product id's for the USB-PC Watchdog card */
88#define USB_PCWD_VENDOR_ID 0x0c98 87#define USB_PCWD_VENDOR_ID 0x0c98
@@ -110,6 +109,18 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
110#define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */ 109#define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */
111#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG 110#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG
112 111
112/* Watchdog's Dip Switch heartbeat values */
113static const int heartbeat_tbl [] = {
114 5, /* OFF-OFF-OFF = 5 Sec */
115 10, /* OFF-OFF-ON = 10 Sec */
116 30, /* OFF-ON-OFF = 30 Sec */
117 60, /* OFF-ON-ON = 1 Min */
118 300, /* ON-OFF-OFF = 5 Min */
119 600, /* ON-OFF-ON = 10 Min */
120 1800, /* ON-ON-OFF = 30 Min */
121 3600, /* ON-ON-ON = 1 hour */
122};
123
113/* We can only use 1 card due to the /dev/watchdog restriction */ 124/* We can only use 1 card due to the /dev/watchdog restriction */
114static int cards_found; 125static int cards_found;
115 126
@@ -682,6 +693,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
682 ((option_switches & 0x10) ? "ON" : "OFF"), 693 ((option_switches & 0x10) ? "ON" : "OFF"),
683 ((option_switches & 0x08) ? "ON" : "OFF")); 694 ((option_switches & 0x08) ? "ON" : "OFF"));
684 695
696 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
697 if (heartbeat == 0)
698 heartbeat = heartbeat_tbl[(option_switches & 0x07)];
699
685 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 700 /* Check that the heartbeat value is within it's range ; if not reset to the default */
686 if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) { 701 if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
687 usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT); 702 usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c
index ff6f1ca1e5e..5991add702b 100644
--- a/drivers/char/watchdog/pnx4008_wdt.c
+++ b/drivers/char/watchdog/pnx4008_wdt.c
@@ -283,7 +283,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
283 wdt_base = (void __iomem *)IO_ADDRESS(res->start); 283 wdt_base = (void __iomem *)IO_ADDRESS(res->start);
284 284
285 wdt_clk = clk_get(&pdev->dev, "wdt_ck"); 285 wdt_clk = clk_get(&pdev->dev, "wdt_ck");
286 if (!wdt_clk) { 286 if (IS_ERR(wdt_clk)) {
287 ret = PTR_ERR(wdt_clk);
287 release_resource(wdt_mem); 288 release_resource(wdt_mem);
288 kfree(wdt_mem); 289 kfree(wdt_mem);
289 goto out; 290 goto out;
diff --git a/drivers/char/watchdog/rm9k_wdt.c b/drivers/char/watchdog/rm9k_wdt.c
index b4678839d3b..5c921e47156 100644
--- a/drivers/char/watchdog/rm9k_wdt.c
+++ b/drivers/char/watchdog/rm9k_wdt.c
@@ -192,7 +192,7 @@ static int wdt_gpi_open(struct inode *inode, struct file *file)
192 locked = 0; 192 locked = 0;
193 } 193 }
194 194
195 res = request_irq(wd_irq, wdt_gpi_irqhdl, SA_SHIRQ | SA_INTERRUPT, 195 res = request_irq(wd_irq, wdt_gpi_irqhdl, IRQF_SHARED | IRQF_DISABLED,
196 wdt_gpi_name, &miscdev); 196 wdt_gpi_name, &miscdev);
197 if (unlikely(res)) 197 if (unlikely(res))
198 return res; 198 return res;
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 18cb050c386..dff6cb5dc9a 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default=" __MODULE
78 78
79MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); 79MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
80 80
81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 82
83MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); 83MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");
84 84
@@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
366 wdt_mem = request_mem_region(res->start, size, pdev->name); 366 wdt_mem = request_mem_region(res->start, size, pdev->name);
367 if (wdt_mem == NULL) { 367 if (wdt_mem == NULL) {
368 printk(KERN_INFO PFX "failed to get memory region\n"); 368 printk(KERN_INFO PFX "failed to get memory region\n");
369 return -ENOENT; 369 ret = -ENOENT;
370 goto err_req;
370 } 371 }
371 372
372 wdt_base = ioremap(res->start, size); 373 wdt_base = ioremap(res->start, size);
373 if (wdt_base == 0) { 374 if (wdt_base == 0) {
374 printk(KERN_INFO PFX "failed to ioremap() region\n"); 375 printk(KERN_INFO PFX "failed to ioremap() region\n");
375 return -EINVAL; 376 ret = -EINVAL;
377 goto err_req;
376 } 378 }
377 379
378 DBG("probe: mapped wdt_base=%p\n", wdt_base); 380 DBG("probe: mapped wdt_base=%p\n", wdt_base);
@@ -380,22 +382,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
380 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 382 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
381 if (res == NULL) { 383 if (res == NULL) {
382 printk(KERN_INFO PFX "failed to get irq resource\n"); 384 printk(KERN_INFO PFX "failed to get irq resource\n");
383 iounmap(wdt_base); 385 ret = -ENOENT;
384 return -ENOENT; 386 goto err_map;
385 } 387 }
386 388
387 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); 389 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
388 if (ret != 0) { 390 if (ret != 0) {
389 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); 391 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
390 iounmap(wdt_base); 392 goto err_map;
391 return ret;
392 } 393 }
393 394
394 wdt_clock = clk_get(&pdev->dev, "watchdog"); 395 wdt_clock = clk_get(&pdev->dev, "watchdog");
395 if (wdt_clock == NULL) { 396 if (IS_ERR(wdt_clock)) {
396 printk(KERN_INFO PFX "failed to find watchdog clock source\n"); 397 printk(KERN_INFO PFX "failed to find watchdog clock source\n");
397 iounmap(wdt_base); 398 ret = PTR_ERR(wdt_clock);
398 return -ENOENT; 399 goto err_irq;
399 } 400 }
400 401
401 clk_enable(wdt_clock); 402 clk_enable(wdt_clock);
@@ -418,8 +419,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
418 if (ret) { 419 if (ret) {
419 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", 420 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
420 WATCHDOG_MINOR, ret); 421 WATCHDOG_MINOR, ret);
421 iounmap(wdt_base); 422 goto err_clk;
422 return ret;
423 } 423 }
424 424
425 if (tmr_atboot && started == 0) { 425 if (tmr_atboot && started == 0) {
@@ -434,26 +434,36 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
434 } 434 }
435 435
436 return 0; 436 return 0;
437
438 err_clk:
439 clk_disable(wdt_clock);
440 clk_put(wdt_clock);
441
442 err_irq:
443 free_irq(wdt_irq->start, pdev);
444
445 err_map:
446 iounmap(wdt_base);
447
448 err_req:
449 release_resource(wdt_mem);
450 kfree(wdt_mem);
451
452 return ret;
437} 453}
438 454
439static int s3c2410wdt_remove(struct platform_device *dev) 455static int s3c2410wdt_remove(struct platform_device *dev)
440{ 456{
441 if (wdt_mem != NULL) { 457 release_resource(wdt_mem);
442 release_resource(wdt_mem); 458 kfree(wdt_mem);
443 kfree(wdt_mem); 459 wdt_mem = NULL;
444 wdt_mem = NULL;
445 }
446 460
447 if (wdt_irq != NULL) { 461 free_irq(wdt_irq->start, dev);
448 free_irq(wdt_irq->start, dev); 462 wdt_irq = NULL;
449 wdt_irq = NULL;
450 }
451 463
452 if (wdt_clock != NULL) { 464 clk_disable(wdt_clock);
453 clk_disable(wdt_clock); 465 clk_put(wdt_clock);
454 clk_put(wdt_clock); 466 wdt_clock = NULL;
455 wdt_clock = NULL;
456 }
457 467
458 iounmap(wdt_base); 468 iounmap(wdt_base);
459 misc_deregister(&s3c2410wdt_miscdev); 469 misc_deregister(&s3c2410wdt_miscdev);
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index c7b2045bc76..b6282039198 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -100,10 +100,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
100 100
101static int nowayout = WATCHDOG_NOWAYOUT; 101static int nowayout = WATCHDOG_NOWAYOUT;
102module_param(nowayout, int, 0); 102module_param(nowayout, int, 0);
103MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 103MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
104 104
105static void wdt_timer_ping(unsigned long); 105static void wdt_timer_ping(unsigned long);
106static struct timer_list timer; 106static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
107static unsigned long next_heartbeat; 107static unsigned long next_heartbeat;
108static unsigned long wdt_is_open; 108static unsigned long wdt_is_open;
109static char wdt_expect_close; 109static char wdt_expect_close;
@@ -122,8 +122,7 @@ static void wdt_timer_ping(unsigned long data)
122 /* Ping the WDT by reading from wdt_start */ 122 /* Ping the WDT by reading from wdt_start */
123 inb_p(wdt_start); 123 inb_p(wdt_start);
124 /* Re-set the timer interval */ 124 /* Re-set the timer interval */
125 timer.expires = jiffies + WDT_INTERVAL; 125 mod_timer(&timer, jiffies + WDT_INTERVAL);
126 add_timer(&timer);
127 } else { 126 } else {
128 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 127 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
129 } 128 }
@@ -138,8 +137,7 @@ static void wdt_startup(void)
138 next_heartbeat = jiffies + (timeout * HZ); 137 next_heartbeat = jiffies + (timeout * HZ);
139 138
140 /* Start the timer */ 139 /* Start the timer */
141 timer.expires = jiffies + WDT_INTERVAL; 140 mod_timer(&timer, jiffies + WDT_INTERVAL);
142 add_timer(&timer);
143 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); 141 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
144} 142}
145 143
@@ -363,10 +361,6 @@ static int __init sbc60xxwdt_init(void)
363 } 361 }
364 } 362 }
365 363
366 init_timer(&timer);
367 timer.function = wdt_timer_ping;
368 timer.data = 0;
369
370 rc = misc_register(&wdt_miscdev); 364 rc = misc_register(&wdt_miscdev);
371 if (rc) 365 if (rc)
372 { 366 {
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
index 41fc6f80c49..67ae42685e7 100644
--- a/drivers/char/watchdog/sbc8360.c
+++ b/drivers/char/watchdog/sbc8360.c
@@ -204,7 +204,7 @@ module_param(timeout, int, 0);
204MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); 204MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
205module_param(nowayout, int, 0); 205module_param(nowayout, int, 0);
206MODULE_PARM_DESC(nowayout, 206MODULE_PARM_DESC(nowayout,
207 "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 207 "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
208 208
209/* 209/*
210 * Kernel methods. 210 * Kernel methods.
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index 8882b427d24..82cbd8809a6 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -35,7 +35,7 @@ static int epx_c3_alive;
35 35
36static int nowayout = WATCHDOG_NOWAYOUT; 36static int nowayout = WATCHDOG_NOWAYOUT;
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39 39
40#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */ 40#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */
41#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */ 41#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index e3239833e4b..1e4a8d751a7 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -92,7 +92,7 @@ MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1");
92 92
93static int nowayout = WATCHDOG_NOWAYOUT; 93static int nowayout = WATCHDOG_NOWAYOUT;
94module_param(nowayout, int, 0); 94module_param(nowayout, int, 0);
95MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 95MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
96 96
97 97
98 98
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index caec37ba750..2676a43895a 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -97,7 +97,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
97 97
98static int nowayout = WATCHDOG_NOWAYOUT; 98static int nowayout = WATCHDOG_NOWAYOUT;
99module_param(nowayout, int, 0); 99module_param(nowayout, int, 0);
100MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 100MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
101 101
102/* 102/*
103 * AMD Elan SC520 - Watchdog Timer Registers 103 * AMD Elan SC520 - Watchdog Timer Registers
@@ -121,7 +121,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
121static __u16 __iomem *wdtmrctl; 121static __u16 __iomem *wdtmrctl;
122 122
123static void wdt_timer_ping(unsigned long); 123static void wdt_timer_ping(unsigned long);
124static struct timer_list timer; 124static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
125static unsigned long next_heartbeat; 125static unsigned long next_heartbeat;
126static unsigned long wdt_is_open; 126static unsigned long wdt_is_open;
127static char wdt_expect_close; 127static char wdt_expect_close;
@@ -145,8 +145,7 @@ static void wdt_timer_ping(unsigned long data)
145 spin_unlock(&wdt_spinlock); 145 spin_unlock(&wdt_spinlock);
146 146
147 /* Re-set the timer interval */ 147 /* Re-set the timer interval */
148 timer.expires = jiffies + WDT_INTERVAL; 148 mod_timer(&timer, jiffies + WDT_INTERVAL);
149 add_timer(&timer);
150 } else { 149 } else {
151 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 150 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
152 } 151 }
@@ -179,8 +178,7 @@ static int wdt_startup(void)
179 next_heartbeat = jiffies + (timeout * HZ); 178 next_heartbeat = jiffies + (timeout * HZ);
180 179
181 /* Start the timer */ 180 /* Start the timer */
182 timer.expires = jiffies + WDT_INTERVAL; 181 mod_timer(&timer, jiffies + WDT_INTERVAL);
183 add_timer(&timer);
184 182
185 /* Start the watchdog */ 183 /* Start the watchdog */
186 wdt_config(WDT_ENB | WDT_WRST_ENB | WDT_EXP_SEL_04); 184 wdt_config(WDT_ENB | WDT_WRST_ENB | WDT_EXP_SEL_04);
@@ -389,10 +387,6 @@ static int __init sc520_wdt_init(void)
389 387
390 spin_lock_init(&wdt_spinlock); 388 spin_lock_init(&wdt_spinlock);
391 389
392 init_timer(&timer);
393 timer.function = wdt_timer_ping;
394 timer.data = 0;
395
396 /* Check that the timeout value is within it's range ; if not reset to the default */ 390 /* Check that the timeout value is within it's range ; if not reset to the default */
397 if (wdt_set_heartbeat(timeout)) { 391 if (wdt_set_heartbeat(timeout)) {
398 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 392 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
index dc403629aeb..cecbedd473a 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -65,10 +65,12 @@ static int clock_division_ratio = WTCSR_CKS_4096;
65 65
66#define next_ping_period(cks) msecs_to_jiffies(cks - 4) 66#define next_ping_period(cks) msecs_to_jiffies(cks - 4)
67 67
68static void sh_wdt_ping(unsigned long data);
69
68static unsigned long shwdt_is_open; 70static unsigned long shwdt_is_open;
69static struct watchdog_info sh_wdt_info; 71static struct watchdog_info sh_wdt_info;
70static char shwdt_expect_close; 72static char shwdt_expect_close;
71static struct timer_list timer; 73static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
72static unsigned long next_heartbeat; 74static unsigned long next_heartbeat;
73 75
74#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 76#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
@@ -433,10 +435,6 @@ static int __init sh_wdt_init(void)
433 "be 1<=x<=3600, using %d\n", heartbeat); 435 "be 1<=x<=3600, using %d\n", heartbeat);
434 } 436 }
435 437
436 init_timer(&timer);
437 timer.function = sh_wdt_ping;
438 timer.data = 0;
439
440 rc = register_reboot_notifier(&sh_wdt_notifier); 438 rc = register_reboot_notifier(&sh_wdt_notifier);
441 if (unlikely(rc)) { 439 if (unlikely(rc)) {
442 printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n", 440 printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n",
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c
index a9681d580dd..d3cb0a76602 100644
--- a/drivers/char/watchdog/smsc37b787_wdt.c
+++ b/drivers/char/watchdog/smsc37b787_wdt.c
@@ -624,4 +624,4 @@ module_param(timeout, int, 0);
624MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); 624MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
625 625
626module_param(nowayout, int, 0); 626module_param(nowayout, int, 0);
627MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 627MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index 4067e1f8a36..9c369490924 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<6
59 59
60static int nowayout = WATCHDOG_NOWAYOUT; 60static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 61module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 63
64#ifdef ONLY_TESTING 64#ifdef ONLY_TESTING
65static int soft_noboot = 1; 65static int soft_noboot = 1;
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index 07d4bff2722..337ee42c90d 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, defaul
58 58
59static int nowayout = WATCHDOG_NOWAYOUT; 59static int nowayout = WATCHDOG_NOWAYOUT;
60module_param(nowayout, int, 0); 60module_param(nowayout, int, 0);
61MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 61MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
62 62
63/* 63/*
64 * Kernel methods. 64 * Kernel methods.
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c
index c960ec110dd..d9e821d08de 100644
--- a/drivers/char/watchdog/w83697hf_wdt.c
+++ b/drivers/char/watchdog/w83697hf_wdt.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, defau
60 60
61static int nowayout = WATCHDOG_NOWAYOUT; 61static int nowayout = WATCHDOG_NOWAYOUT;
62module_param(nowayout, int, 0); 62module_param(nowayout, int, 0);
63MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 63MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
64 64
65/* 65/*
66 * Kernel methods. 66 * Kernel methods.
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
index b0e5f84d6ba..3c88fe18f4f 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -87,10 +87,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
87 87
88static int nowayout = WATCHDOG_NOWAYOUT; 88static int nowayout = WATCHDOG_NOWAYOUT;
89module_param(nowayout, int, 0); 89module_param(nowayout, int, 0);
90MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 90MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
91 91
92static void wdt_timer_ping(unsigned long); 92static void wdt_timer_ping(unsigned long);
93static struct timer_list timer; 93static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
94static unsigned long next_heartbeat; 94static unsigned long next_heartbeat;
95static unsigned long wdt_is_open; 95static unsigned long wdt_is_open;
96static char wdt_expect_close; 96static char wdt_expect_close;
@@ -114,8 +114,7 @@ static void wdt_timer_ping(unsigned long data)
114 inb_p(WDT_PING); 114 inb_p(WDT_PING);
115 115
116 /* Re-set the timer interval */ 116 /* Re-set the timer interval */
117 timer.expires = jiffies + WDT_INTERVAL; 117 mod_timer(&timer, jiffies + WDT_INTERVAL);
118 add_timer(&timer);
119 118
120 spin_unlock(&wdt_spinlock); 119 spin_unlock(&wdt_spinlock);
121 120
@@ -155,8 +154,7 @@ static void wdt_startup(void)
155 next_heartbeat = jiffies + (timeout * HZ); 154 next_heartbeat = jiffies + (timeout * HZ);
156 155
157 /* Start the timer */ 156 /* Start the timer */
158 timer.expires = jiffies + WDT_INTERVAL; 157 mod_timer(&timer, jiffies + WDT_INTERVAL);
159 add_timer(&timer);
160 158
161 wdt_change(WDT_ENABLE); 159 wdt_change(WDT_ENABLE);
162 160
@@ -377,10 +375,6 @@ static int __init w83877f_wdt_init(void)
377 goto err_out_region1; 375 goto err_out_region1;
378 } 376 }
379 377
380 init_timer(&timer);
381 timer.function = wdt_timer_ping;
382 timer.data = 0;
383
384 rc = misc_register(&wdt_miscdev); 378 rc = misc_register(&wdt_miscdev);
385 if (rc) 379 if (rc)
386 { 380 {
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
index 2c8d5d8bd4e..15796844289 100644
--- a/drivers/char/watchdog/w83977f_wdt.c
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
59 59
60static int nowayout = WATCHDOG_NOWAYOUT; 60static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 61module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 63
64/* 64/*
65 * Start the watchdog 65 * Start the watchdog
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index 163e028ef9e..950905d3c39 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, defau
65 65
66static int nowayout = WATCHDOG_NOWAYOUT; 66static int nowayout = WATCHDOG_NOWAYOUT;
67module_param(nowayout, int, 0); 67module_param(nowayout, int, 0);
68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 69
70static void wafwdt_ping(void) 70static void wafwdt_ping(void)
71{ 71{
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index 517fbd8643f..0a3de6a0244 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536,
64 64
65static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;
66module_param(nowayout, int, 0); 66module_param(nowayout, int, 0);
67MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 67MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
68 68
69/* You must set these - there is no sane way to probe for this board. */ 69/* You must set these - there is no sane way to probe for this board. */
70static int io=0x240; 70static int io=0x240;
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index 6253041b235..7d300ff7ab0 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -68,7 +68,7 @@ MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
68 68
69static int nowayout = WATCHDOG_NOWAYOUT; 69static int nowayout = WATCHDOG_NOWAYOUT;
70module_param(nowayout, int, 0); 70module_param(nowayout, int, 0);
71MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 71MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
72 72
73/* 73/*
74 * Start the watchdog 74 * Start the watchdog
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index ce1261c5cbc..6baf4ae42c9 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -90,7 +90,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536,
90 90
91static int nowayout = WATCHDOG_NOWAYOUT; 91static int nowayout = WATCHDOG_NOWAYOUT;
92module_param(nowayout, int, 0); 92module_param(nowayout, int, 0);
93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
94 94
95#ifdef CONFIG_WDT_501_PCI 95#ifdef CONFIG_WDT_501_PCI
96/* Support for the Fan Tachometer on the PCI-WDT501 */ 96/* Support for the Fan Tachometer on the PCI-WDT501 */