aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c12
-rw-r--r--drivers/char/istallion.c8
-rw-r--r--drivers/char/mem.c28
-rw-r--r--drivers/char/mxser.c8
-rw-r--r--drivers/char/ppdev.c3
-rw-r--r--drivers/char/riscom8.c8
-rw-r--r--drivers/char/sysrq.c250
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/tty_io.c4
-rw-r--r--drivers/char/watchdog/Kconfig10
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/ep93xx_wdt.c257
12 files changed, 420 insertions, 170 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index d745004281d0..abd4c5118a1b 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -736,7 +736,8 @@ int ipmi_create_user(unsigned int if_num,
736 intf = ipmi_interfaces[if_num]; 736 intf = ipmi_interfaces[if_num];
737 if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) { 737 if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) {
738 spin_unlock_irqrestore(&interfaces_lock, flags); 738 spin_unlock_irqrestore(&interfaces_lock, flags);
739 return -EINVAL; 739 rv = -EINVAL;
740 goto out_kfree;
740 } 741 }
741 742
742 /* Note that each existing user holds a refcount to the interface. */ 743 /* Note that each existing user holds a refcount to the interface. */
@@ -751,14 +752,14 @@ int ipmi_create_user(unsigned int if_num,
751 752
752 if (!try_module_get(intf->handlers->owner)) { 753 if (!try_module_get(intf->handlers->owner)) {
753 rv = -ENODEV; 754 rv = -ENODEV;
754 goto out_err; 755 goto out_kref;
755 } 756 }
756 757
757 if (intf->handlers->inc_usecount) { 758 if (intf->handlers->inc_usecount) {
758 rv = intf->handlers->inc_usecount(intf->send_info); 759 rv = intf->handlers->inc_usecount(intf->send_info);
759 if (rv) { 760 if (rv) {
760 module_put(intf->handlers->owner); 761 module_put(intf->handlers->owner);
761 goto out_err; 762 goto out_kref;
762 } 763 }
763 } 764 }
764 765
@@ -769,9 +770,10 @@ int ipmi_create_user(unsigned int if_num,
769 *user = new_user; 770 *user = new_user;
770 return 0; 771 return 0;
771 772
772 out_err: 773out_kref:
773 kfree(new_user);
774 kref_put(&intf->refcount, intf_free); 774 kref_put(&intf->refcount, intf_free);
775out_kfree:
776 kfree(new_user);
775 return rv; 777 return rv;
776} 778}
777 779
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index ede128356af2..e5247f85a446 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -378,13 +378,13 @@ MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
378MODULE_LICENSE("GPL"); 378MODULE_LICENSE("GPL");
379 379
380 380
381MODULE_PARM(board0, "1-3s"); 381module_param_array(board0, charp, NULL, 0);
382MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]"); 382MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
383MODULE_PARM(board1, "1-3s"); 383module_param_array(board1, charp, NULL, 0);
384MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]"); 384MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]");
385MODULE_PARM(board2, "1-3s"); 385module_param_array(board2, charp, NULL, 0);
386MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]"); 386MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");
387MODULE_PARM(board3, "1-3s"); 387module_param_array(board3, charp, NULL, 0);
388MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]"); 388MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");
389 389
390#endif 390#endif
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 29c41f4418c0..26d0116b48d4 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -216,11 +216,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
216 216
217 copied = copy_from_user(ptr, buf, sz); 217 copied = copy_from_user(ptr, buf, sz);
218 if (copied) { 218 if (copied) {
219 ssize_t ret; 219 written += sz - copied;
220 220 if (written)
221 ret = written + (sz - copied); 221 break;
222 if (ret)
223 return ret;
224 return -EFAULT; 222 return -EFAULT;
225 } 223 }
226 buf += sz; 224 buf += sz;
@@ -456,11 +454,9 @@ do_write_kmem(void *p, unsigned long realp, const char __user * buf,
456 454
457 copied = copy_from_user(ptr, buf, sz); 455 copied = copy_from_user(ptr, buf, sz);
458 if (copied) { 456 if (copied) {
459 ssize_t ret; 457 written += sz - copied;
460 458 if (written)
461 ret = written + (sz - copied); 459 break;
462 if (ret)
463 return ret;
464 return -EFAULT; 460 return -EFAULT;
465 } 461 }
466 buf += sz; 462 buf += sz;
@@ -514,11 +510,10 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
514 if (len) { 510 if (len) {
515 written = copy_from_user(kbuf, buf, len); 511 written = copy_from_user(kbuf, buf, len);
516 if (written) { 512 if (written) {
517 ssize_t ret; 513 if (wrote + virtr)
518 514 break;
519 free_page((unsigned long)kbuf); 515 free_page((unsigned long)kbuf);
520 ret = wrote + virtr + (len - written); 516 return -EFAULT;
521 return ret ? ret : -EFAULT;
522 } 517 }
523 } 518 }
524 len = vwrite(kbuf, (char *)p, len); 519 len = vwrite(kbuf, (char *)p, len);
@@ -563,8 +558,11 @@ static ssize_t write_port(struct file * file, const char __user * buf,
563 return -EFAULT; 558 return -EFAULT;
564 while (count-- > 0 && i < 65536) { 559 while (count-- > 0 && i < 65536) {
565 char c; 560 char c;
566 if (__get_user(c, tmp)) 561 if (__get_user(c, tmp)) {
562 if (tmp > buf)
563 break;
567 return -EFAULT; 564 return -EFAULT;
565 }
568 outb(c,i); 566 outb(c,i);
569 i++; 567 i++;
570 tmp++; 568 tmp++;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index ea725a9964e2..0fb2fb9fb024 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -243,10 +243,10 @@ static int verbose = 0;
243 243
244MODULE_AUTHOR("Casper Yang"); 244MODULE_AUTHOR("Casper Yang");
245MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); 245MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver");
246MODULE_PARM(ioaddr, "1-4i"); 246module_param_array(ioaddr, int, NULL, 0);
247MODULE_PARM(ttymajor, "i"); 247module_param(ttymajor, int, 0);
248MODULE_PARM(calloutmajor, "i"); 248module_param(calloutmajor, int, 0);
249MODULE_PARM(verbose, "i"); 249module_param(verbose, bool, 0);
250MODULE_LICENSE("GPL"); 250MODULE_LICENSE("GPL");
251 251
252struct mxser_log { 252struct mxser_log {
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 306ee0f091a4..bee6c47b45bd 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -65,10 +65,11 @@
65#include <linux/parport.h> 65#include <linux/parport.h>
66#include <linux/ctype.h> 66#include <linux/ctype.h>
67#include <linux/poll.h> 67#include <linux/poll.h>
68#include <asm/uaccess.h> 68#include <linux/major.h>
69#include <linux/ppdev.h> 69#include <linux/ppdev.h>
70#include <linux/smp_lock.h> 70#include <linux/smp_lock.h>
71#include <linux/device.h> 71#include <linux/device.h>
72#include <asm/uaccess.h>
72 73
73#define PP_VERSION "ppdev: user-space parallel port driver" 74#define PP_VERSION "ppdev: user-space parallel port driver"
74#define CHRDEV "ppdev" 75#define CHRDEV "ppdev"
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 119e629656b7..657c0d88f48c 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -1743,10 +1743,10 @@ static int iobase;
1743static int iobase1; 1743static int iobase1;
1744static int iobase2; 1744static int iobase2;
1745static int iobase3; 1745static int iobase3;
1746MODULE_PARM(iobase, "i"); 1746module_param(iobase, int, 0);
1747MODULE_PARM(iobase1, "i"); 1747module_param(iobase1, int, 0);
1748MODULE_PARM(iobase2, "i"); 1748module_param(iobase2, int, 0);
1749MODULE_PARM(iobase3, "i"); 1749module_param(iobase3, int, 0);
1750 1750
1751MODULE_LICENSE("GPL"); 1751MODULE_LICENSE("GPL");
1752#endif /* MODULE */ 1752#endif /* MODULE */
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index d58f82318853..35082dc12eae 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -42,16 +42,15 @@
42/* Whether we react on sysrq keys or just ignore them */ 42/* Whether we react on sysrq keys or just ignore them */
43int sysrq_enabled = 1; 43int sysrq_enabled = 1;
44 44
45/* Loglevel sysrq handler */
46static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs, 45static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs,
47 struct tty_struct *tty) 46 struct tty_struct *tty)
48{ 47{
49 int i; 48 int i;
50 i = key - '0'; 49 i = key - '0';
51 console_loglevel = 7; 50 console_loglevel = 7;
52 printk("Loglevel set to %d\n", i); 51 printk("Loglevel set to %d\n", i);
53 console_loglevel = i; 52 console_loglevel = i;
54} 53}
55static struct sysrq_key_op sysrq_loglevel_op = { 54static struct sysrq_key_op sysrq_loglevel_op = {
56 .handler = sysrq_handle_loglevel, 55 .handler = sysrq_handle_loglevel,
57 .help_msg = "loglevel0-8", 56 .help_msg = "loglevel0-8",
@@ -59,11 +58,9 @@ static struct sysrq_key_op sysrq_loglevel_op = {
59 .enable_mask = SYSRQ_ENABLE_LOG, 58 .enable_mask = SYSRQ_ENABLE_LOG,
60}; 59};
61 60
62
63/* SAK sysrq handler */
64#ifdef CONFIG_VT 61#ifdef CONFIG_VT
65static void sysrq_handle_SAK(int key, struct pt_regs *pt_regs, 62static void sysrq_handle_SAK(int key, struct pt_regs *pt_regs,
66 struct tty_struct *tty) 63 struct tty_struct *tty)
67{ 64{
68 if (tty) 65 if (tty)
69 do_SAK(tty); 66 do_SAK(tty);
@@ -75,12 +72,13 @@ static struct sysrq_key_op sysrq_SAK_op = {
75 .action_msg = "SAK", 72 .action_msg = "SAK",
76 .enable_mask = SYSRQ_ENABLE_KEYBOARD, 73 .enable_mask = SYSRQ_ENABLE_KEYBOARD,
77}; 74};
75#else
76#define sysrq_SAK_op (*(struct sysrq_key_op *)0)
78#endif 77#endif
79 78
80#ifdef CONFIG_VT 79#ifdef CONFIG_VT
81/* unraw sysrq handler */
82static void sysrq_handle_unraw(int key, struct pt_regs *pt_regs, 80static void sysrq_handle_unraw(int key, struct pt_regs *pt_regs,
83 struct tty_struct *tty) 81 struct tty_struct *tty)
84{ 82{
85 struct kbd_struct *kbd = &kbd_table[fg_console]; 83 struct kbd_struct *kbd = &kbd_table[fg_console];
86 84
@@ -93,10 +91,11 @@ static struct sysrq_key_op sysrq_unraw_op = {
93 .action_msg = "Keyboard mode set to XLATE", 91 .action_msg = "Keyboard mode set to XLATE",
94 .enable_mask = SYSRQ_ENABLE_KEYBOARD, 92 .enable_mask = SYSRQ_ENABLE_KEYBOARD,
95}; 93};
94#else
95#define sysrq_unraw_op (*(struct sysrq_key_op *)0)
96#endif /* CONFIG_VT */ 96#endif /* CONFIG_VT */
97 97
98#ifdef CONFIG_KEXEC 98#ifdef CONFIG_KEXEC
99/* crashdump sysrq handler */
100static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs, 99static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
101 struct tty_struct *tty) 100 struct tty_struct *tty)
102{ 101{
@@ -108,16 +107,16 @@ static struct sysrq_key_op sysrq_crashdump_op = {
108 .action_msg = "Trigger a crashdump", 107 .action_msg = "Trigger a crashdump",
109 .enable_mask = SYSRQ_ENABLE_DUMP, 108 .enable_mask = SYSRQ_ENABLE_DUMP,
110}; 109};
110#else
111#define sysrq_crashdump_op (*(struct sysrq_key_op *)0)
111#endif 112#endif
112 113
113/* reboot sysrq handler */
114static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, 114static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
115 struct tty_struct *tty) 115 struct tty_struct *tty)
116{ 116{
117 local_irq_enable(); 117 local_irq_enable();
118 emergency_restart(); 118 emergency_restart();
119} 119}
120
121static struct sysrq_key_op sysrq_reboot_op = { 120static struct sysrq_key_op sysrq_reboot_op = {
122 .handler = sysrq_handle_reboot, 121 .handler = sysrq_handle_reboot,
123 .help_msg = "reBoot", 122 .help_msg = "reBoot",
@@ -126,11 +125,10 @@ static struct sysrq_key_op sysrq_reboot_op = {
126}; 125};
127 126
128static void sysrq_handle_sync(int key, struct pt_regs *pt_regs, 127static void sysrq_handle_sync(int key, struct pt_regs *pt_regs,
129 struct tty_struct *tty) 128 struct tty_struct *tty)
130{ 129{
131 emergency_sync(); 130 emergency_sync();
132} 131}
133
134static struct sysrq_key_op sysrq_sync_op = { 132static struct sysrq_key_op sysrq_sync_op = {
135 .handler = sysrq_handle_sync, 133 .handler = sysrq_handle_sync,
136 .help_msg = "Sync", 134 .help_msg = "Sync",
@@ -139,11 +137,10 @@ static struct sysrq_key_op sysrq_sync_op = {
139}; 137};
140 138
141static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs, 139static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs,
142 struct tty_struct *tty) 140 struct tty_struct *tty)
143{ 141{
144 emergency_remount(); 142 emergency_remount();
145} 143}
146
147static struct sysrq_key_op sysrq_mountro_op = { 144static struct sysrq_key_op sysrq_mountro_op = {
148 .handler = sysrq_handle_mountro, 145 .handler = sysrq_handle_mountro,
149 .help_msg = "Unmount", 146 .help_msg = "Unmount",
@@ -151,28 +148,23 @@ static struct sysrq_key_op sysrq_mountro_op = {
151 .enable_mask = SYSRQ_ENABLE_REMOUNT, 148 .enable_mask = SYSRQ_ENABLE_REMOUNT,
152}; 149};
153 150
154/* END SYNC SYSRQ HANDLERS BLOCK */
155
156#ifdef CONFIG_DEBUG_MUTEXES 151#ifdef CONFIG_DEBUG_MUTEXES
157 152static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs,
158static void 153 struct tty_struct *tty)
159sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
160{ 154{
161 mutex_debug_show_all_locks(); 155 mutex_debug_show_all_locks();
162} 156}
163
164static struct sysrq_key_op sysrq_showlocks_op = { 157static struct sysrq_key_op sysrq_showlocks_op = {
165 .handler = sysrq_handle_showlocks, 158 .handler = sysrq_handle_showlocks,
166 .help_msg = "show-all-locks(D)", 159 .help_msg = "show-all-locks(D)",
167 .action_msg = "Show Locks Held", 160 .action_msg = "Show Locks Held",
168}; 161};
169 162#else
163#define sysrq_showlocks_op (*(struct sysrq_key_op *)0)
170#endif 164#endif
171 165
172/* SHOW SYSRQ HANDLERS BLOCK */
173
174static void sysrq_handle_showregs(int key, struct pt_regs *pt_regs, 166static void sysrq_handle_showregs(int key, struct pt_regs *pt_regs,
175 struct tty_struct *tty) 167 struct tty_struct *tty)
176{ 168{
177 if (pt_regs) 169 if (pt_regs)
178 show_regs(pt_regs); 170 show_regs(pt_regs);
@@ -184,9 +176,8 @@ static struct sysrq_key_op sysrq_showregs_op = {
184 .enable_mask = SYSRQ_ENABLE_DUMP, 176 .enable_mask = SYSRQ_ENABLE_DUMP,
185}; 177};
186 178
187
188static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs, 179static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs,
189 struct tty_struct *tty) 180 struct tty_struct *tty)
190{ 181{
191 show_state(); 182 show_state();
192} 183}
@@ -197,9 +188,8 @@ static struct sysrq_key_op sysrq_showstate_op = {
197 .enable_mask = SYSRQ_ENABLE_DUMP, 188 .enable_mask = SYSRQ_ENABLE_DUMP,
198}; 189};
199 190
200
201static void sysrq_handle_showmem(int key, struct pt_regs *pt_regs, 191static void sysrq_handle_showmem(int key, struct pt_regs *pt_regs,
202 struct tty_struct *tty) 192 struct tty_struct *tty)
203{ 193{
204 show_mem(); 194 show_mem();
205} 195}
@@ -210,13 +200,9 @@ static struct sysrq_key_op sysrq_showmem_op = {
210 .enable_mask = SYSRQ_ENABLE_DUMP, 200 .enable_mask = SYSRQ_ENABLE_DUMP,
211}; 201};
212 202
213/* SHOW SYSRQ HANDLERS BLOCK */ 203/*
214 204 * Signal sysrq helper function. Sends a signal to all user processes.
215 205 */
216/* SIGNAL SYSRQ HANDLERS BLOCK */
217
218/* signal sysrq helper function
219 * Sends a signal to all user processes */
220static void send_sig_all(int sig) 206static void send_sig_all(int sig)
221{ 207{
222 struct task_struct *p; 208 struct task_struct *p;
@@ -229,7 +215,7 @@ static void send_sig_all(int sig)
229} 215}
230 216
231static void sysrq_handle_term(int key, struct pt_regs *pt_regs, 217static void sysrq_handle_term(int key, struct pt_regs *pt_regs,
232 struct tty_struct *tty) 218 struct tty_struct *tty)
233{ 219{
234 send_sig_all(SIGTERM); 220 send_sig_all(SIGTERM);
235 console_loglevel = 8; 221 console_loglevel = 8;
@@ -243,7 +229,8 @@ static struct sysrq_key_op sysrq_term_op = {
243 229
244static void moom_callback(void *ignored) 230static void moom_callback(void *ignored)
245{ 231{
246 out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], GFP_KERNEL, 0); 232 out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL],
233 GFP_KERNEL, 0);
247} 234}
248 235
249static DECLARE_WORK(moom_work, moom_callback, NULL); 236static DECLARE_WORK(moom_work, moom_callback, NULL);
@@ -260,7 +247,7 @@ static struct sysrq_key_op sysrq_moom_op = {
260}; 247};
261 248
262static void sysrq_handle_kill(int key, struct pt_regs *pt_regs, 249static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
263 struct tty_struct *tty) 250 struct tty_struct *tty)
264{ 251{
265 send_sig_all(SIGKILL); 252 send_sig_all(SIGKILL);
266 console_loglevel = 8; 253 console_loglevel = 8;
@@ -272,8 +259,6 @@ static struct sysrq_key_op sysrq_kill_op = {
272 .enable_mask = SYSRQ_ENABLE_SIGNAL, 259 .enable_mask = SYSRQ_ENABLE_SIGNAL,
273}; 260};
274 261
275/* END SIGNAL SYSRQ HANDLERS BLOCK */
276
277static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs, 262static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs,
278 struct tty_struct *tty) 263 struct tty_struct *tty)
279{ 264{
@@ -288,110 +273,99 @@ static struct sysrq_key_op sysrq_unrt_op = {
288 273
289/* Key Operations table and lock */ 274/* Key Operations table and lock */
290static DEFINE_SPINLOCK(sysrq_key_table_lock); 275static DEFINE_SPINLOCK(sysrq_key_table_lock);
291#define SYSRQ_KEY_TABLE_LENGTH 36 276
292static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { 277static struct sysrq_key_op *sysrq_key_table[36] = {
293/* 0 */ &sysrq_loglevel_op, 278 &sysrq_loglevel_op, /* 0 */
294/* 1 */ &sysrq_loglevel_op, 279 &sysrq_loglevel_op, /* 1 */
295/* 2 */ &sysrq_loglevel_op, 280 &sysrq_loglevel_op, /* 2 */
296/* 3 */ &sysrq_loglevel_op, 281 &sysrq_loglevel_op, /* 3 */
297/* 4 */ &sysrq_loglevel_op, 282 &sysrq_loglevel_op, /* 4 */
298/* 5 */ &sysrq_loglevel_op, 283 &sysrq_loglevel_op, /* 5 */
299/* 6 */ &sysrq_loglevel_op, 284 &sysrq_loglevel_op, /* 6 */
300/* 7 */ &sysrq_loglevel_op, 285 &sysrq_loglevel_op, /* 7 */
301/* 8 */ &sysrq_loglevel_op, 286 &sysrq_loglevel_op, /* 8 */
302/* 9 */ &sysrq_loglevel_op, 287 &sysrq_loglevel_op, /* 9 */
303/* a */ NULL, /* Don't use for system provided sysrqs, 288
304 it is handled specially on the sparc 289 /*
305 and will never arrive */ 290 * Don't use for system provided sysrqs, it is handled specially on
306/* b */ &sysrq_reboot_op, 291 * sparc and will never arrive
307#ifdef CONFIG_KEXEC 292 */
308/* c */ &sysrq_crashdump_op, 293 NULL, /* a */
309#else 294 &sysrq_reboot_op, /* b */
310/* c */ NULL, 295 &sysrq_crashdump_op, /* c */
311#endif 296 &sysrq_showlocks_op, /* d */
312#ifdef CONFIG_DEBUG_MUTEXES 297 &sysrq_term_op, /* e */
313/* d */ &sysrq_showlocks_op, 298 &sysrq_moom_op, /* f */
314#else 299 NULL, /* g */
315/* d */ NULL, 300 NULL, /* h */
316#endif 301 &sysrq_kill_op, /* i */
317/* e */ &sysrq_term_op, 302 NULL, /* j */
318/* f */ &sysrq_moom_op, 303 &sysrq_SAK_op, /* k */
319/* g */ NULL, 304 NULL, /* l */
320/* h */ NULL, 305 &sysrq_showmem_op, /* m */
321/* i */ &sysrq_kill_op, 306 &sysrq_unrt_op, /* n */
322/* j */ NULL, 307 /* This will often be registered as 'Off' at init time */
323#ifdef CONFIG_VT 308 NULL, /* o */
324/* k */ &sysrq_SAK_op, 309 &sysrq_showregs_op, /* p */
325#else 310 NULL, /* q */
326/* k */ NULL, 311 &sysrq_unraw_op, /* r */
327#endif 312 &sysrq_sync_op, /* s */
328/* l */ NULL, 313 &sysrq_showstate_op, /* t */
329/* m */ &sysrq_showmem_op, 314 &sysrq_mountro_op, /* u */
330/* n */ &sysrq_unrt_op, 315 /* May be assigned at init time by SMP VOYAGER */
331/* o */ NULL, /* This will often be registered 316 NULL, /* v */
332 as 'Off' at init time */ 317 NULL, /* w */
333/* p */ &sysrq_showregs_op, 318 NULL, /* x */
334/* q */ NULL, 319 NULL, /* y */
335#ifdef CONFIG_VT 320 NULL /* z */
336/* r */ &sysrq_unraw_op,
337#else
338/* r */ NULL,
339#endif
340/* s */ &sysrq_sync_op,
341/* t */ &sysrq_showstate_op,
342/* u */ &sysrq_mountro_op,
343/* v */ NULL, /* May be assigned at init time by SMP VOYAGER */
344/* w */ NULL,
345/* x */ NULL,
346/* y */ NULL,
347/* z */ NULL
348}; 321};
349 322
350/* key2index calculation, -1 on invalid index */ 323/* key2index calculation, -1 on invalid index */
351static int sysrq_key_table_key2index(int key) { 324static int sysrq_key_table_key2index(int key)
325{
352 int retval; 326 int retval;
353 if ((key >= '0') && (key <= '9')) { 327
328 if ((key >= '0') && (key <= '9'))
354 retval = key - '0'; 329 retval = key - '0';
355 } else if ((key >= 'a') && (key <= 'z')) { 330 else if ((key >= 'a') && (key <= 'z'))
356 retval = key + 10 - 'a'; 331 retval = key + 10 - 'a';
357 } else { 332 else
358 retval = -1; 333 retval = -1;
359 }
360 return retval; 334 return retval;
361} 335}
362 336
363/* 337/*
364 * get and put functions for the table, exposed to modules. 338 * get and put functions for the table, exposed to modules.
365 */ 339 */
366 340struct sysrq_key_op *__sysrq_get_key_op(int key)
367struct sysrq_key_op *__sysrq_get_key_op (int key) { 341{
368 struct sysrq_key_op *op_p; 342 struct sysrq_key_op *op_p = NULL;
369 int i; 343 int i;
370 344
371 i = sysrq_key_table_key2index(key); 345 i = sysrq_key_table_key2index(key);
372 op_p = (i == -1) ? NULL : sysrq_key_table[i]; 346 if (i != -1)
347 op_p = sysrq_key_table[i];
373 return op_p; 348 return op_p;
374} 349}
375 350
376static void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) { 351static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
377 int i; 352{
353 int i = sysrq_key_table_key2index(key);
378 354
379 i = sysrq_key_table_key2index(key);
380 if (i != -1) 355 if (i != -1)
381 sysrq_key_table[i] = op_p; 356 sysrq_key_table[i] = op_p;
382} 357}
383 358
384/* 359/*
385 * This is the non-locking version of handle_sysrq 360 * This is the non-locking version of handle_sysrq. It must/can only be called
386 * It must/can only be called by sysrq key handlers, 361 * by sysrq key handlers, as they are inside of the lock
387 * as they are inside of the lock
388 */ 362 */
389 363void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty,
390void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty, int check_mask) 364 int check_mask)
391{ 365{
392 struct sysrq_key_op *op_p; 366 struct sysrq_key_op *op_p;
393 int orig_log_level; 367 int orig_log_level;
394 int i, j; 368 int i;
395 unsigned long flags; 369 unsigned long flags;
396 370
397 spin_lock_irqsave(&sysrq_key_table_lock, flags); 371 spin_lock_irqsave(&sysrq_key_table_lock, flags);
@@ -401,26 +375,34 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty, in
401 375
402 op_p = __sysrq_get_key_op(key); 376 op_p = __sysrq_get_key_op(key);
403 if (op_p) { 377 if (op_p) {
404 /* Should we check for enabled operations (/proc/sysrq-trigger should not) 378 /*
405 * and is the invoked operation enabled? */ 379 * Should we check for enabled operations (/proc/sysrq-trigger
380 * should not) and is the invoked operation enabled?
381 */
406 if (!check_mask || sysrq_enabled == 1 || 382 if (!check_mask || sysrq_enabled == 1 ||
407 (sysrq_enabled & op_p->enable_mask)) { 383 (sysrq_enabled & op_p->enable_mask)) {
408 printk ("%s\n", op_p->action_msg); 384 printk("%s\n", op_p->action_msg);
409 console_loglevel = orig_log_level; 385 console_loglevel = orig_log_level;
410 op_p->handler(key, pt_regs, tty); 386 op_p->handler(key, pt_regs, tty);
411 } 387 } else {
412 else
413 printk("This sysrq operation is disabled.\n"); 388 printk("This sysrq operation is disabled.\n");
389 }
414 } else { 390 } else {
415 printk("HELP : "); 391 printk("HELP : ");
416 /* Only print the help msg once per handler */ 392 /* Only print the help msg once per handler */
417 for (i=0; i<SYSRQ_KEY_TABLE_LENGTH; i++) 393 for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
418 if (sysrq_key_table[i]) { 394 if (sysrq_key_table[i]) {
419 for (j=0; sysrq_key_table[i] != sysrq_key_table[j]; j++); 395 int j;
420 if (j == i) 396
421 printk ("%s ", sysrq_key_table[i]->help_msg); 397 for (j = 0; sysrq_key_table[i] !=
398 sysrq_key_table[j]; j++)
399 ;
400 if (j != i)
401 continue;
402 printk("%s ", sysrq_key_table[i]->help_msg);
403 }
422 } 404 }
423 printk ("\n"); 405 printk("\n");
424 console_loglevel = orig_log_level; 406 console_loglevel = orig_log_level;
425 } 407 }
426 spin_unlock_irqrestore(&sysrq_key_table_lock, flags); 408 spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
@@ -430,16 +412,17 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty, in
430 * This function is called by the keyboard handler when SysRq is pressed 412 * This function is called by the keyboard handler when SysRq is pressed
431 * and any other keycode arrives. 413 * and any other keycode arrives.
432 */ 414 */
433
434void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) 415void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
435{ 416{
436 if (!sysrq_enabled) 417 if (!sysrq_enabled)
437 return; 418 return;
438 __handle_sysrq(key, pt_regs, tty, 1); 419 __handle_sysrq(key, pt_regs, tty, 1);
439} 420}
421EXPORT_SYMBOL(handle_sysrq);
440 422
441static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, 423static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
442 struct sysrq_key_op *remove_op_p) { 424 struct sysrq_key_op *remove_op_p)
425{
443 426
444 int retval; 427 int retval;
445 unsigned long flags; 428 unsigned long flags;
@@ -452,7 +435,6 @@ static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
452 retval = -1; 435 retval = -1;
453 } 436 }
454 spin_unlock_irqrestore(&sysrq_key_table_lock, flags); 437 spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
455
456 return retval; 438 return retval;
457} 439}
458 440
@@ -460,12 +442,10 @@ int register_sysrq_key(int key, struct sysrq_key_op *op_p)
460{ 442{
461 return __sysrq_swap_key_ops(key, op_p, NULL); 443 return __sysrq_swap_key_ops(key, op_p, NULL);
462} 444}
445EXPORT_SYMBOL(register_sysrq_key);
463 446
464int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) 447int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
465{ 448{
466 return __sysrq_swap_key_ops(key, NULL, op_p); 449 return __sysrq_swap_key_ops(key, NULL, op_p);
467} 450}
468
469EXPORT_SYMBOL(handle_sysrq);
470EXPORT_SYMBOL(register_sysrq_key);
471EXPORT_SYMBOL(unregister_sysrq_key); 451EXPORT_SYMBOL(unregister_sysrq_key);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index fd3a4beaa53d..dec0224b4478 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -24,6 +24,7 @@
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/miscdevice.h> 25#include <linux/miscdevice.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h>
27 28
28enum tpm_timeout { 29enum tpm_timeout {
29 TPM_TIMEOUT = 5, /* msecs */ 30 TPM_TIMEOUT = 5, /* msecs */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 76592ee1fb38..48d795bb8c4b 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -354,7 +354,7 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
354 354
355EXPORT_SYMBOL_GPL(tty_buffer_request_room); 355EXPORT_SYMBOL_GPL(tty_buffer_request_room);
356 356
357int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size) 357int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size)
358{ 358{
359 int copied = 0; 359 int copied = 0;
360 do { 360 do {
@@ -378,7 +378,7 @@ int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t
378 378
379EXPORT_SYMBOL_GPL(tty_insert_flip_string); 379EXPORT_SYMBOL_GPL(tty_insert_flip_string);
380 380
381int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size) 381int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size)
382{ 382{
383 int copied = 0; 383 int copied = 0;
384 do { 384 do {
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index c0dfcf273f0a..16e99db2e12d 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -148,6 +148,16 @@ config MPCORE_WATCHDOG
148 To compile this driver as a module, choose M here: the 148 To compile this driver as a module, choose M here: the
149 module will be called mpcore_wdt. 149 module will be called mpcore_wdt.
150 150
151config EP93XX_WATCHDOG
152 tristate "EP93xx Watchdog"
153 depends on WATCHDOG && ARCH_EP93XX
154 help
155 Say Y here if to include support for the watchdog timer
156 embedded in the Cirrus Logic EP93xx family of devices.
157
158 To compile this driver as a module, choose M here: the
159 module will be called ep93xx_wdt.
160
151# X86 (i386 + ia64 + x86_64) Architecture 161# X86 (i386 + ia64 + x86_64) Architecture
152 162
153config ACQUIRE_WDT 163config ACQUIRE_WDT
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 36c0b282b8ba..d6f27fde9905 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
30obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o 30obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
31obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o 31obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
32obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o 32obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
33obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
33 34
34# X86 (i386 + ia64 + x86_64) Architecture 35# X86 (i386 + ia64 + x86_64) Architecture
35obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o 36obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c
new file mode 100644
index 000000000000..9021dbb78299
--- /dev/null
+++ b/drivers/char/watchdog/ep93xx_wdt.c
@@ -0,0 +1,257 @@
1/*
2 * Watchdog driver for Cirrus Logic EP93xx family of devices.
3 *
4 * Copyright (c) 2004 Ray Lehtiniemi
5 * Copyright (c) 2006 Tower Technologies
6 * Based on ep93xx driver, bits from alim7101_wdt.c
7 *
8 * Authors: Ray Lehtiniemi <rayl@mail.com>,
9 * Alessandro Zummo <a.zummo@towertech.it>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 *
15 * This watchdog fires after 250msec, which is a too short interval
16 * for us to rely on the user space daemon alone. So we ping the
17 * wdt each ~200msec and eventually stop doing it if the user space
18 * daemon dies.
19 *
20 * TODO:
21 *
22 * - Test last reset from watchdog status
23 * - Add a few missing ioctls
24 */
25
26#include <linux/module.h>
27#include <linux/fs.h>
28#include <linux/miscdevice.h>
29#include <linux/watchdog.h>
30#include <linux/timer.h>
31
32#include <asm/hardware.h>
33#include <asm/uaccess.h>
34
35#define WDT_VERSION "0.3"
36#define PFX "ep93xx_wdt: "
37
38/* default timeout (secs) */
39#define WDT_TIMEOUT 30
40
41static int nowayout = WATCHDOG_NOWAYOUT;
42static int timeout = WDT_TIMEOUT;
43
44static struct timer_list timer;
45static unsigned long next_heartbeat;
46static unsigned long wdt_status;
47static unsigned long boot_status;
48
49#define WDT_IN_USE 0
50#define WDT_OK_TO_CLOSE 1
51
52#define EP93XX_WDT_REG(x) (EP93XX_WATCHDOG_BASE + (x))
53#define EP93XX_WDT_WATCHDOG EP93XX_WDT_REG(0x00)
54#define EP93XX_WDT_WDSTATUS EP93XX_WDT_REG(0x04)
55
56/* reset the wdt every ~200ms */
57#define WDT_INTERVAL (HZ/5)
58
59static void wdt_enable(void)
60{
61 __raw_writew(0xaaaa, EP93XX_WDT_WATCHDOG);
62}
63
64static void wdt_disable(void)
65{
66 __raw_writew(0xaa55, EP93XX_WDT_WATCHDOG);
67}
68
69static inline void wdt_ping(void)
70{
71 __raw_writew(0x5555, EP93XX_WDT_WATCHDOG);
72}
73
74static void wdt_startup(void)
75{
76 next_heartbeat = jiffies + (timeout * HZ);
77
78 wdt_enable();
79 mod_timer(&timer, jiffies + WDT_INTERVAL);
80}
81
82static void wdt_shutdown(void)
83{
84 del_timer_sync(&timer);
85 wdt_disable();
86}
87
88static void wdt_keepalive(void)
89{
90 /* user land ping */
91 next_heartbeat = jiffies + (timeout * HZ);
92}
93
94static int ep93xx_wdt_open(struct inode *inode, struct file *file)
95{
96 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
97 return -EBUSY;
98
99 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
100
101 wdt_startup();
102
103 return nonseekable_open(inode, file);
104}
105
106static ssize_t
107ep93xx_wdt_write(struct file *file, const char __user *data, size_t len,
108 loff_t *ppos)
109{
110 /* Can't seek (pwrite) on this device */
111 if (*ppos != file->f_pos)
112 return -ESPIPE;
113
114 if (len) {
115 if (!nowayout) {
116 size_t i;
117
118 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
119
120 for (i = 0; i != len; i++) {
121 char c;
122
123 if (get_user(c, data + i))
124 return -EFAULT;
125
126 if (c == 'V')
127 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
128 else
129 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
130 }
131 }
132 wdt_keepalive();
133 }
134
135 return len;
136}
137
138static struct watchdog_info ident = {
139 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
140 .identity = "EP93xx Watchdog",
141};
142
143static int
144ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
145 unsigned long arg)
146{
147 int ret = -ENOIOCTLCMD;
148
149 switch (cmd) {
150 case WDIOC_GETSUPPORT:
151 ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
152 sizeof(ident)) ? -EFAULT : 0;
153 break;
154
155 case WDIOC_GETSTATUS:
156 ret = put_user(0, (int __user *)arg);
157 break;
158
159 case WDIOC_GETBOOTSTATUS:
160 ret = put_user(boot_status, (int __user *)arg);
161 break;
162
163 case WDIOC_GETTIMEOUT:
164 /* actually, it is 0.250 seconds.... */
165 ret = put_user(1, (int __user *)arg);
166 break;
167
168 case WDIOC_KEEPALIVE:
169 wdt_keepalive();
170 ret = 0;
171 break;
172 }
173 return ret;
174}
175
176static int ep93xx_wdt_release(struct inode *inode, struct file *file)
177{
178 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
179 wdt_shutdown();
180 else
181 printk(KERN_CRIT PFX "Device closed unexpectedly - "
182 "timer will not stop\n");
183
184 clear_bit(WDT_IN_USE, &wdt_status);
185 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
186
187 return 0;
188}
189
190static struct file_operations ep93xx_wdt_fops = {
191 .owner = THIS_MODULE,
192 .write = ep93xx_wdt_write,
193 .ioctl = ep93xx_wdt_ioctl,
194 .open = ep93xx_wdt_open,
195 .release = ep93xx_wdt_release,
196};
197
198static struct miscdevice ep93xx_wdt_miscdev = {
199 .minor = WATCHDOG_MINOR,
200 .name = "watchdog",
201 .fops = &ep93xx_wdt_fops,
202};
203
204static void ep93xx_timer_ping(unsigned long data)
205{
206 if (time_before(jiffies, next_heartbeat))
207 wdt_ping();
208
209 /* Re-set the timer interval */
210 mod_timer(&timer, jiffies + WDT_INTERVAL);
211}
212
213static int __init ep93xx_wdt_init(void)
214{
215 int err;
216
217 err = misc_register(&ep93xx_wdt_miscdev);
218
219 boot_status = __raw_readl(EP93XX_WDT_WATCHDOG) & 0x01 ? 1 : 0;
220
221 printk(KERN_INFO PFX "EP93XX watchdog, driver version "
222 WDT_VERSION "%s\n",
223 (__raw_readl(EP93XX_WDT_WATCHDOG) & 0x08)
224 ? " (nCS1 disable detected)" : "");
225
226 if (timeout < 1 || timeout > 3600) {
227 timeout = WDT_TIMEOUT;
228 printk(KERN_INFO PFX
229 "timeout value must be 1<=x<=3600, using %d\n",
230 timeout);
231 }
232
233 setup_timer(&timer, ep93xx_timer_ping, 1);
234 return err;
235}
236
237static void __exit ep93xx_wdt_exit(void)
238{
239 wdt_shutdown();
240 misc_deregister(&ep93xx_wdt_miscdev);
241}
242
243module_init(ep93xx_wdt_init);
244module_exit(ep93xx_wdt_exit);
245
246module_param(nowayout, int, 0);
247MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
248
249module_param(timeout, int, 0);
250MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
251
252MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
253 "Alessandro Zummo <a.zummo@towertech.it>");
254MODULE_DESCRIPTION("EP93xx Watchdog");
255MODULE_LICENSE("GPL");
256MODULE_VERSION(WDT_VERSION);
257MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);