Commit 4c076eb0cfd9fa3f8900ac3dbdcaaca2f5fc2c1e

Authored by Mathieu J. Poirier
Committed by Dmitry Torokhov
1 parent 401d7d108f

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>

Showing 2 changed files with 75 additions and 0 deletions Side-by-side Diff

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.
... ... @@ -45,6 +45,7 @@
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>
... ... @@ -681,6 +682,40 @@
681 682 }
682 683 }
683 684  
  685 +#ifdef CONFIG_OF
  686 +static 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
  714 +static void sysrq_of_get_keyreset_config(void)
  715 +{
  716 +}
  717 +#endif
  718 +
684 719 static void sysrq_reinject_alt_sysrq(struct work_struct *work)
685 720 {
686 721 struct sysrq_state *sysrq =
... ... @@ -914,6 +949,7 @@
914 949 int error;
915 950 int i;
916 951  
  952 + /* First check if a __weak interface was instantiated. */
917 953 for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) {
918 954 key = platform_sysrq_reset_seq[i];
919 955 if (key == KEY_RESERVED || key > KEY_MAX)
... ... @@ -921,6 +957,12 @@
921 957  
922 958 sysrq_reset_seq[sysrq_reset_seq_len++] = key;
923 959 }
  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();
924 966  
925 967 error = input_register_handler(&sysrq_handler);
926 968 if (error)