Skip to content

Commit

Permalink
Input: sysrq - request graceful shutdown for key reset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mathieu J. Poirier authored and Dmitry Torokhov committed Jun 6, 2013
1 parent 64b8dd2 commit 3d28951
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions drivers/tty/sysrq.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <linux/uaccess.h>
#include <linux/moduleparam.h>
#include <linux/jiffies.h>
#include <linux/syscalls.h>

#include <asm/ptrace.h>
#include <asm/irq_regs.h>
Expand Down Expand Up @@ -586,6 +587,7 @@ struct sysrq_state {

/* reset sequence handling */
bool reset_canceled;
bool reset_requested;
unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)];
int reset_seq_len;
int reset_seq_cnt;
Expand Down Expand Up @@ -624,18 +626,26 @@ static void sysrq_parse_reset_sequence(struct sysrq_state *state)
state->reset_seq_version = sysrq_reset_seq_version;
}

static void sysrq_do_reset(unsigned long dummy)
static void sysrq_do_reset(unsigned long _state)
{
__handle_sysrq(sysrq_xlate[KEY_B], false);
struct sysrq_state *state = (struct sysrq_state *) _state;

state->reset_requested = true;

sys_sync();
kernel_restart(NULL);
}

static void sysrq_handle_reset_request(struct sysrq_state *state)
{
if (state->reset_requested)
__handle_sysrq(sysrq_xlate[KEY_B], false);

if (sysrq_reset_downtime_ms)
mod_timer(&state->keyreset_timer,
jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms));
else
sysrq_do_reset(0);
sysrq_do_reset((unsigned long)state);
}

static void sysrq_detect_reset_sequence(struct sysrq_state *state,
Expand Down Expand Up @@ -837,7 +847,8 @@ static int sysrq_connect(struct input_handler *handler,
sysrq->handle.handler = handler;
sysrq->handle.name = "sysrq";
sysrq->handle.private = sysrq;
setup_timer(&sysrq->keyreset_timer, sysrq_do_reset, 0);
setup_timer(&sysrq->keyreset_timer,
sysrq_do_reset, (unsigned long)sysrq);

error = input_register_handle(&sysrq->handle);
if (error) {
Expand Down

0 comments on commit 3d28951

Please sign in to comment.