From patchwork Fri Jan 15 20:33:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Timo_Ter=C3=A4s?= X-Patchwork-Id: 8044541 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A05C9BEEED for ; Fri, 15 Jan 2016 20:34:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AB2CF20381 for ; Fri, 15 Jan 2016 20:34:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BBA3720390 for ; Fri, 15 Jan 2016 20:34:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753769AbcAOUd7 (ORCPT ); Fri, 15 Jan 2016 15:33:59 -0500 Received: from mail-lb0-f193.google.com ([209.85.217.193]:36150 "EHLO mail-lb0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753155AbcAOUd6 (ORCPT ); Fri, 15 Jan 2016 15:33:58 -0500 Received: by mail-lb0-f193.google.com with SMTP id ti8so29831536lbb.3 for ; Fri, 15 Jan 2016 12:33:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=xpPM8OMvtIGtHYx6KQLKGgYWCw4mkxCCsDPglSf/mhY=; b=KRp10UbJACs/s4kWkLQS6+c95WAH7zwikalEt9Fo3dsNf7MBvJ2LMAFpdCPTIRTfQ6 Mi+sQHmNOyVbkrSzeDB1eylqIhho0/wjqcFC4AttCuUyCT57DvzvLowDYg7IHRfHFQuk ol0HEtIK7GJ455hDUcAio0SNywDrfK6fC1gRqlztMmz5vDhyTIlF1kkkgY1Ml3/sg3TM eqcxTkalShHeqGIwWAmwDrXCWfU7aZIiJajeWrQnuiyq3lFU8Ile50o3cn9/3UxtkZeF HsQTC0uggzdwSzUerA1vi3HcLt8fh6xEyHFLlV97ilOA7O/Tvow6wEF2OXMxBGfokZdt xVjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type :content-transfer-encoding; bh=xpPM8OMvtIGtHYx6KQLKGgYWCw4mkxCCsDPglSf/mhY=; b=Gm9rkqtv5Uc8xAv/v8UeN5GQ/EtTq9HkVhOAcF6UN7i7vqCfxgpOZ2yodNCLawpeiK 3EyVwIqfsq182+o5rId/h6C7HyXiEOepX1NCvP6EzIz1PdrH+nRKwKJrZtODzjeSHPbp P1SMPu6HukxBUovevZUmGqODvvpVMQAvDH1H/Lvemqr4n6Hjao0qE0XsoeMBeWrytcRc WnDEcgFG4GhYwJHMegB0mPBzn17UnXJhSEpbUCPvlkeoP6Ihdy3VJxgvL/+tHiHpoEqN VxbLtuHzCnt7D8tZMvrJm77z9+hxlzeimqAVgEZvew2olGMf4gQA+L8/tyWTXRxSN5xE H3bA== X-Gm-Message-State: ALoCoQlOhnKU67SL/5HuDQOHHk/l/OzAhnqQVjbG7+is2odGCr8HfOtXaXEFHtmu3fV3antQBSFZJ7+XSBCj/WbSCHfH9uKFlg== X-Received: by 10.112.125.9 with SMTP id mm9mr3461284lbb.113.1452890037098; Fri, 15 Jan 2016 12:33:57 -0800 (PST) Received: from vostro.util.wtbts.net ([2001:1bc8:101:f402:21a:9fff:fe0c:4022]) by smtp.gmail.com with ESMTPSA id r200sm1593067lfd.35.2016.01.15.12.33.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 15 Jan 2016 12:33:56 -0800 (PST) From: =?UTF-8?q?Timo=20Ter=C3=A4s?= To: "linux-input@vger.kernel.org" Cc: =?UTF-8?q?Timo=20Ter=C3=A4s?= Subject: [PATCH 3/3] Input: rotary_encoder - use threaded irqs Date: Fri, 15 Jan 2016 22:33:50 +0200 Message-Id: <1452890030-23316-3-git-send-email-timo.teras@iki.fi> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1452890030-23316-1-git-send-email-timo.teras@iki.fi> References: <1452890030-23316-1-git-send-email-timo.teras@iki.fi> MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Convert to use threaded IRQs to support GPIOs that can sleep. Protect the irq handler with mutex as it can be triggered from two different irq lines accessing the same state. This allows using GPIO expanders behind I2C or SPI bus. Signed-off-by: Timo Teräs --- drivers/input/misc/rotary_encoder.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 156f40f..a2d47ce 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -33,6 +33,7 @@ struct rotary_encoder { struct input_dev *input; const struct rotary_encoder_platform_data *pdata; + struct mutex access_mutex; unsigned int axis; unsigned int pos; @@ -48,8 +49,8 @@ struct rotary_encoder { static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata) { - int a = !!gpio_get_value(pdata->gpio_a); - int b = !!gpio_get_value(pdata->gpio_b); + int a = !!gpio_get_value_cansleep(pdata->gpio_a); + int b = !!gpio_get_value_cansleep(pdata->gpio_b); a ^= pdata->inverted_a; b ^= pdata->inverted_b; @@ -94,6 +95,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) struct rotary_encoder *encoder = dev_id; int state; + mutex_lock(&encoder->access_mutex); state = rotary_encoder_get_state(encoder->pdata); switch (state) { @@ -114,6 +116,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) encoder->armed = true; break; } + mutex_unlock(&encoder->access_mutex); return IRQ_HANDLED; } @@ -123,6 +126,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) struct rotary_encoder *encoder = dev_id; int state; + mutex_lock(&encoder->access_mutex); state = rotary_encoder_get_state(encoder->pdata); switch (state) { @@ -139,6 +143,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) encoder->dir = (encoder->last_stable + state) & 0x01; break; } + mutex_unlock(&encoder->access_mutex); return IRQ_HANDLED; } @@ -149,6 +154,7 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id) unsigned char sum; int state; + mutex_lock(&encoder->access_mutex); state = rotary_encoder_get_state(encoder->pdata); /* @@ -189,6 +195,8 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id) out: encoder->last_stable = state; + mutex_unlock(&encoder->access_mutex); + return IRQ_HANDLED; } @@ -288,6 +296,8 @@ static int rotary_encoder_probe(struct platform_device *pdev) if (!encoder || !input) return -ENOMEM; + mutex_init(&encoder->access_mutex); + encoder->input = input; encoder->pdata = pdata; @@ -338,17 +348,17 @@ static int rotary_encoder_probe(struct platform_device *pdev) return-EINVAL; } - err = devm_request_irq(dev, encoder->irq_a, handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - DRV_NAME, encoder); + err = devm_request_threaded_irq(dev, encoder->irq_a, NULL, handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + DRV_NAME, encoder); if (err) { dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a); return err; } - err = devm_request_irq(dev, encoder->irq_b, handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - DRV_NAME, encoder); + err = devm_request_threaded_irq(dev, encoder->irq_b, NULL, handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + DRV_NAME, encoder); if (err) { dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b); return err;