From patchwork Sun Mar 31 07:36:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 2368281 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 08AFB3FC8C for ; Sun, 31 Mar 2013 07:37:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751333Ab3CaHg6 (ORCPT ); Sun, 31 Mar 2013 03:36:58 -0400 Received: from mail-pb0-f41.google.com ([209.85.160.41]:59560 "EHLO mail-pb0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756165Ab3CaHg5 (ORCPT ); Sun, 31 Mar 2013 03:36:57 -0400 Received: by mail-pb0-f41.google.com with SMTP id mc17so313027pbc.0 for ; Sun, 31 Mar 2013 00:36:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:date:from:to:cc:subject:message-id:references :mime-version:content-type:content-disposition:in-reply-to :user-agent; bh=QVEG9K+uSVVY0CnsWKOIVWqCmHHjSmLslAUWqMXJmaw=; b=qoc0sXBZ07ZZgRbbh7RjdW3C4xYwta0FMguKHNKkoK6qxX00t0dQ4YZGEeTBYBqBir 5jYPifYmyhQ+XkMJtbXr3i2G9mHU5ewaLE+g9gClVaxIRTZgiGg/vV+TtktVwxMuK6N6 P1ODqyezS2c/wMxFkJjxpEqa18dX/V1JNk2ZzgLXqeBNPzQvTvwFgTlhvE0WSUaWwE/W AqpRhyYv+O8bK7GDKq5ZKI59tAJlvdxJ7U4kdT991lbMklXP0qK3RQWMlDfeCYnURO0N vIFIQ2lWZAmrcTMTjAqFv0SvgPot6FWbmLx/qSOs+LAke8sWEvtbtqND9m9+1mWp5vsd +DCg== X-Received: by 10.68.143.197 with SMTP id sg5mr12409926pbb.101.1364715416977; Sun, 31 Mar 2013 00:36:56 -0700 (PDT) Received: from mailhub.coreip.homeip.net (c-67-188-112-76.hsd1.ca.comcast.net. [67.188.112.76]) by mx.google.com with ESMTPS id yr10sm10348256pab.6.2013.03.31.00.36.55 (version=TLSv1 cipher=RC4-SHA bits=128/128); Sun, 31 Mar 2013 00:36:56 -0700 (PDT) Date: Sun, 31 Mar 2013 00:36:54 -0700 From: Dmitry Torokhov To: mathieu.poirier@linaro.org Cc: arve@android.com, linux-input@vger.kernel.org, kernel-team@android.com, john.stultz@linaro.org Subject: Re: [PATCH v3] sysrq: supplementing reset sequence with timeout functionality Message-ID: <20130331073654.GE7919@core.coreip.homeip.net> References: <1363963003-18796-1-git-send-email-mathieu.poirier@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1363963003-18796-1-git-send-email-mathieu.poirier@linaro.org> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Hi Mathieu, On Fri, Mar 22, 2013 at 08:36:42AM -0600, mathieu.poirier@linaro.org wrote: > + > +static void sysrq_detect_reset_sequence(struct sysrq_state *state, > unsigned int code, int value) > { > if (!test_bit(code, state->reset_keybit)) { > @@ -628,18 +640,27 @@ static bool sysrq_detect_reset_sequence(struct sysrq_state *state, > if (value && state->reset_seq_cnt) > state->reset_canceled = true; > } 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_timeout); > + I believe you need to cancel the timer also when any other key is pressed (the branch above). Can you please try the version below? I also realized that even when timer expires right away (the delay is 0) it is not executed immediately (contrary to what I said earlier) so I reverted to doing explicit call to reset instead of always using timer. Thanks. diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 3687f0c..f31f417 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,9 @@ 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; @@ -586,6 +590,7 @@ struct sysrq_state { 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 */ @@ -644,6 +649,11 @@ static bool sysrq_detect_reset_sequence(struct sysrq_state *state, return false; } +static void sysrq_do_reset(unsigned long dummy) +{ + __handle_sysrq(sysrq_xlate[KEY_B], false); +} + static void sysrq_reinject_alt_sysrq(struct work_struct *work) { struct sysrq_state *sysrq = @@ -748,10 +758,13 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, 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); - } + if (!sysrq_detect_reset_sequence(sysrq, code, value)) + del_timer(&sysrq->keyreset_timer); + else if (sysrq_reset_downtime_ms) + mod_timer(&sysrq->keyreset_timer, + jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms)); + else + sysrq_do_reset(0); } else if (value == 0 && test_and_clear_bit(code, sysrq->key_down)) { /* @@ -812,6 +825,7 @@ 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); error = input_register_handle(&sysrq->handle); if (error) { @@ -841,6 +855,7 @@ static void sysrq_disconnect(struct input_handle *handle) input_close_device(handle); cancel_work_sync(&sysrq->reinject_work); + del_timer_sync(&sysrq->keyreset_timer); input_unregister_handle(handle); kfree(sysrq); } @@ -870,8 +885,6 @@ static struct input_handler sysrq_handler = { static bool sysrq_handler_registered; -unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED }; - static inline void sysrq_register_handler(void) { unsigned short key; @@ -930,6 +943,7 @@ static struct kernel_param_ops param_ops_sysrq_reset_seq = { module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq, &sysrq_reset_seq_len, 0644); +module_param_named(reset_downtime_ms, sysrq_reset_downtime_ms, int, 0644); #else