#include <linux/input.h>
 #include <linux/uaccess.h>
 #include <linux/moduleparam.h>
+#include <linux/jiffies.h>
 
 #include <asm/ptrace.h>
 #include <asm/irq_regs.h>
 static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
 static bool __read_mostly sysrq_always_enabled;
 
+unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED };
+int sysrq_reset_downtime_ms __weak;
+
 static bool sysrq_on(void)
 {
        return sysrq_enabled || sysrq_always_enabled;
        int reset_seq_len;
        int reset_seq_cnt;
        int reset_seq_version;
+       struct timer_list keyreset_timer;
 };
 
 #define SYSRQ_KEY_RESET_MAX    20 /* Should be plenty */
        state->reset_seq_version = sysrq_reset_seq_version;
 }
 
-static bool sysrq_detect_reset_sequence(struct sysrq_state *state,
+static void sysrq_do_reset(unsigned long dummy)
+{
+       __handle_sysrq(sysrq_xlate[KEY_B], false);
+}
+
+static void sysrq_handle_reset_request(struct sysrq_state *state)
+{
+       if (sysrq_reset_downtime_ms)
+               mod_timer(&state->keyreset_timer,
+                       jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms));
+       else
+               sysrq_do_reset(0);
+}
+
+static void sysrq_detect_reset_sequence(struct sysrq_state *state,
                                        unsigned int code, int value)
 {
        if (!test_bit(code, state->reset_keybit)) {
                /*
                 * Pressing any key _not_ in reset sequence cancels
-                * the reset sequence.
+                * the reset sequence.  Also cancelling the timer in
+                * case additional keys were pressed after a reset
+                * has been requested.
                 */
-               if (value && state->reset_seq_cnt)
+               if (value && state->reset_seq_cnt) {
                        state->reset_canceled = true;
+                       del_timer(&state->keyreset_timer);
+               }
        } else if (value == 0) {
-               /* key release */
+               /*
+                * Key release - all keys in the reset sequence need
+                * to be pressed and held for the reset timeout
+                * to hold.
+                */
+               del_timer(&state->keyreset_timer);
+
                if (--state->reset_seq_cnt == 0)
                        state->reset_canceled = false;
        } else if (value == 1) {
                /* key press, not autorepeat */
                if (++state->reset_seq_cnt == state->reset_seq_len &&
                    !state->reset_canceled) {
-                       return true;
+                       sysrq_handle_reset_request(state);
                }
        }
-
-       return false;
 }
 
 static void sysrq_reinject_alt_sysrq(struct work_struct *work)
                if (was_active)
                        schedule_work(&sysrq->reinject_work);
 
-               if (sysrq_detect_reset_sequence(sysrq, code, value)) {
-                       /* Force emergency reboot */
-                       __handle_sysrq(sysrq_xlate[KEY_B], false);
-               }
+               /* Check for reset sequence */
+               sysrq_detect_reset_sequence(sysrq, code, value);
 
        } else if (value == 0 && test_and_clear_bit(code, sysrq->key_down)) {
                /*
        sysrq->handle.handler = handler;
        sysrq->handle.name = "sysrq";
        sysrq->handle.private = sysrq;
+       setup_timer(&sysrq->keyreset_timer, sysrq_do_reset, 0);
 
        error = input_register_handle(&sysrq->handle);
        if (error) {
 
        input_close_device(handle);
        cancel_work_sync(&sysrq->reinject_work);
+       del_timer_sync(&sysrq->keyreset_timer);
        input_unregister_handle(handle);
        kfree(sysrq);
 }
 
 static bool sysrq_handler_registered;
 
-unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED };
-
 static inline void sysrq_register_handler(void)
 {
        unsigned short key;
 module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq,
                         &sysrq_reset_seq_len, 0644);
 
+module_param_named(sysrq_downtime_ms, sysrq_reset_downtime_ms, int, 0644);
+
 #else
 
 static inline void sysrq_register_handler(void)