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

Input: sysrq - request graceful shutdown for key reset

Attempt to reboot the system gracefully when a key combo is detected.
If the reste combination is pressed the 2nd time we assume that graceful
reboot failed and perform emergency reboot. This fucntionality is useful
when UI is stuck but the system is otherwise working fine.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Mathieu J. Poirier and committed by
Dmitry Torokhov
3d289517 64b8dd29

+15 -4
+15 -4
drivers/tty/sysrq.c
··· 44 44 #include <linux/uaccess.h> 45 45 #include <linux/moduleparam.h> 46 46 #include <linux/jiffies.h> 47 + #include <linux/syscalls.h> 47 48 48 49 #include <asm/ptrace.h> 49 50 #include <asm/irq_regs.h> ··· 587 586 588 587 /* reset sequence handling */ 589 588 bool reset_canceled; 589 + bool reset_requested; 590 590 unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)]; 591 591 int reset_seq_len; 592 592 int reset_seq_cnt; ··· 626 624 state->reset_seq_version = sysrq_reset_seq_version; 627 625 } 628 626 629 - static void sysrq_do_reset(unsigned long dummy) 627 + static void sysrq_do_reset(unsigned long _state) 630 628 { 631 - __handle_sysrq(sysrq_xlate[KEY_B], false); 629 + struct sysrq_state *state = (struct sysrq_state *) _state; 630 + 631 + state->reset_requested = true; 632 + 633 + sys_sync(); 634 + kernel_restart(NULL); 632 635 } 633 636 634 637 static void sysrq_handle_reset_request(struct sysrq_state *state) 635 638 { 639 + if (state->reset_requested) 640 + __handle_sysrq(sysrq_xlate[KEY_B], false); 641 + 636 642 if (sysrq_reset_downtime_ms) 637 643 mod_timer(&state->keyreset_timer, 638 644 jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms)); 639 645 else 640 - sysrq_do_reset(0); 646 + sysrq_do_reset((unsigned long)state); 641 647 } 642 648 643 649 static void sysrq_detect_reset_sequence(struct sysrq_state *state, ··· 847 837 sysrq->handle.handler = handler; 848 838 sysrq->handle.name = "sysrq"; 849 839 sysrq->handle.private = sysrq; 850 - setup_timer(&sysrq->keyreset_timer, sysrq_do_reset, 0); 840 + setup_timer(&sysrq->keyreset_timer, 841 + sysrq_do_reset, (unsigned long)sysrq); 851 842 852 843 error = input_register_handle(&sysrq->handle); 853 844 if (error) {