diff options
author | Mathieu J. Poirier <mathieu.poirier@linaro.org> | 2013-08-04 04:22:08 +0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-08-13 09:31:55 +0400 |
commit | 4c076eb0cfd9fa3f8900ac3dbdcaaca2f5fc2c1e (patch) | |
tree | 9b7293b21eb84ca52442acff639f95f6e7f640d9 /drivers/tty/sysrq.c | |
parent | 401d7d108fc19595f6a7d7dd7d553458155e31fa (diff) | |
download | linux-4c076eb0cfd9fa3f8900ac3dbdcaaca2f5fc2c1e.tar.xz |
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>
Diffstat (limited to 'drivers/tty/sysrq.c')
-rw-r--r-- | drivers/tty/sysrq.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 55ba46f6207d..749dae8c3489 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -45,6 +45,7 @@ #include <linux/moduleparam.h> #include <linux/jiffies.h> #include <linux/syscalls.h> +#include <linux/of.h> #include <asm/ptrace.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) { struct sysrq_state *sysrq = @@ -914,6 +949,7 @@ static inline void sysrq_register_handler(void) int error; int i; + /* First check if a __weak interface was instantiated. */ for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) { key = platform_sysrq_reset_seq[i]; 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; } + /* + * 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); if (error) pr_err("Failed to register input handler, error %d", error); |