Input: sysrq - DT binding for key sequence
Adding a simple device tree binding for the specification of key sequences. Definition of the keys found in the sequence are located in 'include/uapi/linux/input.h'. For the sysrq driver, holding the sequence of keys down for a specific amount of time will reset the system. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Acked-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
401d7d108f
commit
4c076eb0cf
2 changed files with 75 additions and 0 deletions
33
Documentation/devicetree/bindings/input/input-reset.txt
Normal file
33
Documentation/devicetree/bindings/input/input-reset.txt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
Input: sysrq reset sequence
|
||||||
|
|
||||||
|
A simple binding to represent a set of keys as described in
|
||||||
|
include/uapi/linux/input.h. This is to communicate a sequence of keys to the
|
||||||
|
sysrq driver. Upon holding the keys for a specified amount of time (if
|
||||||
|
specified) the system is sync'ed and reset.
|
||||||
|
|
||||||
|
Key sequences are global to the system but all the keys in a set must be coming
|
||||||
|
from the same input device.
|
||||||
|
|
||||||
|
The /chosen node should contain a 'linux,sysrq-reset-seq' child node to define
|
||||||
|
a set of keys.
|
||||||
|
|
||||||
|
Required property:
|
||||||
|
sysrq-reset-seq: array of Linux keycodes, one keycode per cell.
|
||||||
|
|
||||||
|
Optional property:
|
||||||
|
timeout-ms: duration keys must be pressed together in milliseconds before
|
||||||
|
generating a sysrq. If omitted the system is rebooted immediately when a valid
|
||||||
|
sequence has been recognized.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
linux,sysrq-reset-seq {
|
||||||
|
keyset = <0x03
|
||||||
|
0x04
|
||||||
|
0x0a>;
|
||||||
|
timeout-ms = <3000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Would represent KEY_2, KEY_3 and KEY_9.
|
|
@ -45,6 +45,7 @@
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/irq_regs.h>
|
#include <asm/irq_regs.h>
|
||||||
|
@ -681,6 +682,40 @@ static void sysrq_detect_reset_sequence(struct sysrq_state *state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static void sysrq_of_get_keyreset_config(void)
|
||||||
|
{
|
||||||
|
u32 key;
|
||||||
|
struct device_node *np;
|
||||||
|
struct property *prop;
|
||||||
|
const __be32 *p;
|
||||||
|
|
||||||
|
np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq");
|
||||||
|
if (!np) {
|
||||||
|
pr_debug("No sysrq node found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset in case a __weak definition was present */
|
||||||
|
sysrq_reset_seq_len = 0;
|
||||||
|
|
||||||
|
of_property_for_each_u32(np, "keyset", prop, p, key) {
|
||||||
|
if (key == KEY_RESERVED || key > KEY_MAX ||
|
||||||
|
sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX)
|
||||||
|
break;
|
||||||
|
|
||||||
|
sysrq_reset_seq[sysrq_reset_seq_len++] = (unsigned short)key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get reset timeout if any. */
|
||||||
|
of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void sysrq_of_get_keyreset_config(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void sysrq_reinject_alt_sysrq(struct work_struct *work)
|
static void sysrq_reinject_alt_sysrq(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct sysrq_state *sysrq =
|
struct sysrq_state *sysrq =
|
||||||
|
@ -914,6 +949,7 @@ static inline void sysrq_register_handler(void)
|
||||||
int error;
|
int error;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* First check if a __weak interface was instantiated. */
|
||||||
for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) {
|
for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) {
|
||||||
key = platform_sysrq_reset_seq[i];
|
key = platform_sysrq_reset_seq[i];
|
||||||
if (key == KEY_RESERVED || key > KEY_MAX)
|
if (key == KEY_RESERVED || key > KEY_MAX)
|
||||||
|
@ -922,6 +958,12 @@ static inline void sysrq_register_handler(void)
|
||||||
sysrq_reset_seq[sysrq_reset_seq_len++] = key;
|
sysrq_reset_seq[sysrq_reset_seq_len++] = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DT configuration takes precedence over anything that would
|
||||||
|
* have been defined via the __weak interface.
|
||||||
|
*/
|
||||||
|
sysrq_of_get_keyreset_config();
|
||||||
|
|
||||||
error = input_register_handler(&sysrq_handler);
|
error = input_register_handler(&sysrq_handler);
|
||||||
if (error)
|
if (error)
|
||||||
pr_err("Failed to register input handler, error %d", error);
|
pr_err("Failed to register input handler, error %d", error);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue