1 /* drivers/input/keyreset.c
3 * Copyright (C) 2008 Google, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <linux/input.h>
17 #include <linux/keyreset.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/reboot.h>
21 #include <linux/sched.h>
22 #include <linux/slab.h>
23 #include <linux/syscalls.h>
26 struct keyreset_state
{
27 struct input_handler input_handler
;
28 unsigned long keybit
[BITS_TO_LONGS(KEY_CNT
)];
29 unsigned long upbit
[BITS_TO_LONGS(KEY_CNT
)];
30 unsigned long key
[BITS_TO_LONGS(KEY_CNT
)];
36 int (*reset_fn
)(void);
39 int restart_requested
;
40 static void deferred_restart(struct work_struct
*dummy
)
42 restart_requested
= 2;
44 restart_requested
= 3;
47 static DECLARE_WORK(restart_work
, deferred_restart
);
49 static void keyreset_event(struct input_handle
*handle
, unsigned int type
,
50 unsigned int code
, int value
)
53 struct keyreset_state
*state
= handle
->private;
61 if (!test_bit(code
, state
->keybit
))
64 spin_lock_irqsave(&state
->lock
, flags
);
65 if (!test_bit(code
, state
->key
) == !value
)
67 __change_bit(code
, state
->key
);
68 if (test_bit(code
, state
->upbit
)) {
70 state
->restart_disabled
= 1;
80 if (state
->key_down
== 0 && state
->key_up
== 0)
81 state
->restart_disabled
= 0;
83 pr_debug("reset key changed %d %d new state %d-%d-%d\n", code
, value
,
84 state
->key_down
, state
->key_up
, state
->restart_disabled
);
86 if (value
&& !state
->restart_disabled
&&
87 state
->key_down
== state
->key_down_target
) {
88 state
->restart_disabled
= 1;
89 if (restart_requested
)
90 panic("keyboard reset failed, %d", restart_requested
);
91 if (state
->reset_fn
) {
92 restart_requested
= state
->reset_fn();
94 pr_info("keyboard reset\n");
95 schedule_work(&restart_work
);
96 restart_requested
= 1;
100 spin_unlock_irqrestore(&state
->lock
, flags
);
103 static int keyreset_connect(struct input_handler
*handler
,
104 struct input_dev
*dev
,
105 const struct input_device_id
*id
)
109 struct input_handle
*handle
;
110 struct keyreset_state
*state
=
111 container_of(handler
, struct keyreset_state
, input_handler
);
113 for (i
= 0; i
< KEY_MAX
; i
++) {
114 if (test_bit(i
, state
->keybit
) && test_bit(i
, dev
->keybit
))
120 handle
= kzalloc(sizeof(*handle
), GFP_KERNEL
);
125 handle
->handler
= handler
;
126 handle
->name
= "keyreset";
127 handle
->private = state
;
129 ret
= input_register_handle(handle
);
131 goto err_input_register_handle
;
133 ret
= input_open_device(handle
);
135 goto err_input_open_device
;
137 pr_info("using input dev %s for key reset\n", dev
->name
);
141 err_input_open_device
:
142 input_unregister_handle(handle
);
143 err_input_register_handle
:
148 static void keyreset_disconnect(struct input_handle
*handle
)
150 input_close_device(handle
);
151 input_unregister_handle(handle
);
155 static const struct input_device_id keyreset_ids
[] = {
157 .flags
= INPUT_DEVICE_ID_MATCH_EVBIT
,
158 .evbit
= { BIT_MASK(EV_KEY
) },
162 MODULE_DEVICE_TABLE(input
, keyreset_ids
);
164 static int keyreset_probe(struct platform_device
*pdev
)
168 struct keyreset_state
*state
;
169 struct keyreset_platform_data
*pdata
= pdev
->dev
.platform_data
;
174 state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
178 spin_lock_init(&state
->lock
);
179 keyp
= pdata
->keys_down
;
180 while ((key
= *keyp
++)) {
183 state
->key_down_target
++;
184 __set_bit(key
, state
->keybit
);
186 if (pdata
->keys_up
) {
187 keyp
= pdata
->keys_up
;
188 while ((key
= *keyp
++)) {
191 __set_bit(key
, state
->keybit
);
192 __set_bit(key
, state
->upbit
);
197 state
->reset_fn
= pdata
->reset_fn
;
199 state
->input_handler
.event
= keyreset_event
;
200 state
->input_handler
.connect
= keyreset_connect
;
201 state
->input_handler
.disconnect
= keyreset_disconnect
;
202 state
->input_handler
.name
= KEYRESET_NAME
;
203 state
->input_handler
.id_table
= keyreset_ids
;
204 ret
= input_register_handler(&state
->input_handler
);
209 platform_set_drvdata(pdev
, state
);
213 int keyreset_remove(struct platform_device
*pdev
)
215 struct keyreset_state
*state
= platform_get_drvdata(pdev
);
216 input_unregister_handler(&state
->input_handler
);
222 struct platform_driver keyreset_driver
= {
223 .driver
.name
= KEYRESET_NAME
,
224 .probe
= keyreset_probe
,
225 .remove
= keyreset_remove
,
228 static int __init
keyreset_init(void)
230 return platform_driver_register(&keyreset_driver
);
233 static void __exit
keyreset_exit(void)
235 return platform_driver_unregister(&keyreset_driver
);
238 module_init(keyreset_init
);
239 module_exit(keyreset_exit
);