aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMathieu J. Poirier <mathieu.poirier@linaro.org>2013-08-03 20:22:08 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-08-13 01:31:55 -0400
commit4c076eb0cfd9fa3f8900ac3dbdcaaca2f5fc2c1e (patch)
tree9b7293b21eb84ca52442acff639f95f6e7f640d9 /drivers
parent401d7d108fc19595f6a7d7dd7d553458155e31fa (diff)
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')
-rw-r--r--drivers/tty/sysrq.c42
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 @@
45#include <linux/moduleparam.h> 45#include <linux/moduleparam.h>
46#include <linux/jiffies.h> 46#include <linux/jiffies.h>
47#include <linux/syscalls.h> 47#include <linux/syscalls.h>
48#include <linux/of.h>
48 49
49#include <asm/ptrace.h> 50#include <asm/ptrace.h>
50#include <asm/irq_regs.h> 51#include <asm/irq_regs.h>
@@ -681,6 +682,40 @@ static void sysrq_detect_reset_sequence(struct sysrq_state *state,
681 } 682 }
682} 683}
683 684
685#ifdef CONFIG_OF
686static void sysrq_of_get_keyreset_config(void)
687{
688 u32 key;
689 struct device_node *np;
690 struct property *prop;
691 const __be32 *p;
692
693 np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq");
694 if (!np) {
695 pr_debug("No sysrq node found");
696 return;
697 }
698
699 /* Reset in case a __weak definition was present */
700 sysrq_reset_seq_len = 0;
701
702 of_property_for_each_u32(np, "keyset", prop, p, key) {
703 if (key == KEY_RESERVED || key > KEY_MAX ||
704 sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX)
705 break;
706
707 sysrq_reset_seq[sysrq_reset_seq_len++] = (unsigned short)key;
708 }
709
710 /* Get reset timeout if any. */
711 of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms);
712}
713#else
714static void sysrq_of_get_keyreset_config(void)
715{
716}
717#endif
718
684static void sysrq_reinject_alt_sysrq(struct work_struct *work) 719static void sysrq_reinject_alt_sysrq(struct work_struct *work)
685{ 720{
686 struct sysrq_state *sysrq = 721 struct sysrq_state *sysrq =
@@ -914,6 +949,7 @@ static inline void sysrq_register_handler(void)
914 int error; 949 int error;
915 int i; 950 int i;
916 951
952 /* First check if a __weak interface was instantiated. */
917 for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) { 953 for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) {
918 key = platform_sysrq_reset_seq[i]; 954 key = platform_sysrq_reset_seq[i];
919 if (key == KEY_RESERVED || key > KEY_MAX) 955 if (key == KEY_RESERVED || key > KEY_MAX)
@@ -922,6 +958,12 @@ static inline void sysrq_register_handler(void)
922 sysrq_reset_seq[sysrq_reset_seq_len++] = key; 958 sysrq_reset_seq[sysrq_reset_seq_len++] = key;
923 } 959 }
924 960
961 /*
962 * DT configuration takes precedence over anything that would
963 * have been defined via the __weak interface.
964 */
965 sysrq_of_get_keyreset_config();
966
925 error = input_register_handler(&sysrq_handler); 967 error = input_register_handler(&sysrq_handler);
926 if (error) 968 if (error)
927 pr_err("Failed to register input handler, error %d", error); 969 pr_err("Failed to register input handler, error %d", error);