Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mathieu J. Poirier and committed by
Dmitry Torokhov
4c076eb0 401d7d10

+75
+33
Documentation/devicetree/bindings/input/input-reset.txt
··· 1 + Input: sysrq reset sequence 2 + 3 + A simple binding to represent a set of keys as described in 4 + include/uapi/linux/input.h. This is to communicate a sequence of keys to the 5 + sysrq driver. Upon holding the keys for a specified amount of time (if 6 + specified) the system is sync'ed and reset. 7 + 8 + Key sequences are global to the system but all the keys in a set must be coming 9 + from the same input device. 10 + 11 + The /chosen node should contain a 'linux,sysrq-reset-seq' child node to define 12 + a set of keys. 13 + 14 + Required property: 15 + sysrq-reset-seq: array of Linux keycodes, one keycode per cell. 16 + 17 + Optional property: 18 + timeout-ms: duration keys must be pressed together in milliseconds before 19 + generating a sysrq. If omitted the system is rebooted immediately when a valid 20 + sequence has been recognized. 21 + 22 + Example: 23 + 24 + chosen { 25 + linux,sysrq-reset-seq { 26 + keyset = <0x03 27 + 0x04 28 + 0x0a>; 29 + timeout-ms = <3000>; 30 + }; 31 + }; 32 + 33 + Would represent KEY_2, KEY_3 and KEY_9.
+42
drivers/tty/sysrq.c
··· 45 45 #include <linux/moduleparam.h> 46 46 #include <linux/jiffies.h> 47 47 #include <linux/syscalls.h> 48 + #include <linux/of.h> 48 49 49 50 #include <asm/ptrace.h> 50 51 #include <asm/irq_regs.h> ··· 682 681 } 683 682 } 684 683 684 + #ifdef CONFIG_OF 685 + static void sysrq_of_get_keyreset_config(void) 686 + { 687 + u32 key; 688 + struct device_node *np; 689 + struct property *prop; 690 + const __be32 *p; 691 + 692 + np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq"); 693 + if (!np) { 694 + pr_debug("No sysrq node found"); 695 + return; 696 + } 697 + 698 + /* Reset in case a __weak definition was present */ 699 + sysrq_reset_seq_len = 0; 700 + 701 + of_property_for_each_u32(np, "keyset", prop, p, key) { 702 + if (key == KEY_RESERVED || key > KEY_MAX || 703 + sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX) 704 + break; 705 + 706 + sysrq_reset_seq[sysrq_reset_seq_len++] = (unsigned short)key; 707 + } 708 + 709 + /* Get reset timeout if any. */ 710 + of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms); 711 + } 712 + #else 713 + static void sysrq_of_get_keyreset_config(void) 714 + { 715 + } 716 + #endif 717 + 685 718 static void sysrq_reinject_alt_sysrq(struct work_struct *work) 686 719 { 687 720 struct sysrq_state *sysrq = ··· 949 914 int error; 950 915 int i; 951 916 917 + /* First check if a __weak interface was instantiated. */ 952 918 for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) { 953 919 key = platform_sysrq_reset_seq[i]; 954 920 if (key == KEY_RESERVED || key > KEY_MAX) ··· 957 921 958 922 sysrq_reset_seq[sysrq_reset_seq_len++] = key; 959 923 } 924 + 925 + /* 926 + * DT configuration takes precedence over anything that would 927 + * have been defined via the __weak interface. 928 + */ 929 + sysrq_of_get_keyreset_config(); 960 930 961 931 error = input_register_handler(&sysrq_handler); 962 932 if (error)