From patchwork Mon Jun 22 21:45:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 1314749 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=crapouillou.net Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=crapouillou.net header.i=@crapouillou.net header.a=rsa-sha256 header.s=mail header.b=CxR0MCFl; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49rNJr17Gkz9sSf for ; Tue, 23 Jun 2020 07:46:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730545AbgFVVqS (ORCPT ); Mon, 22 Jun 2020 17:46:18 -0400 Received: from outils.crapouillou.net ([89.234.176.41]:34164 "EHLO crapouillou.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730494AbgFVVqR (ORCPT ); Mon, 22 Jun 2020 17:46:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1592862375; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references; bh=XVivtfrUoedverxihZDUvQXhbwIsW+Ph7W4Zuj41NTM=; b=CxR0MCFl6PJNUHCHUUF4NaLFrzu7naZvhIfn6Lm6JwoZcjditrouo7ZpcUL1rCeRFGEFjr kCaU21cgk8HIekGNqYAqaicVFFoGCrQgxI39HwYbNOvWv4es2JOe/xbqlEX3ayGZSJxFRM khfX6DY8rWyRg/gN9IxIumrcgjcGbsI= From: Paul Cercueil To: Linus Walleij Cc: od@zcrc.me, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Cercueil , stable@vger.kernel.org, =?utf-8?q?Jo?= =?utf-8?q?=C3=A3o_Henrique?= Subject: [PATCH 1/2] pinctrl: ingenic: Enhance support for IRQ_TYPE_EDGE_BOTH Date: Mon, 22 Jun 2020 23:45:47 +0200 Message-Id: <20200622214548.265417-1-paul@crapouillou.net> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Ingenic SoCs don't natively support registering an interrupt for both rising and falling edges. This has to be emulated in software. Until now, this was emulated by switching back and forth between IRQ_TYPE_EDGE_RISING and IRQ_TYPE_EDGE_FALLING according to the level of the GPIO. While this worked most of the time, when used with GPIOs that need debouncing, some events would be lost. For instance, between the time a falling-edge interrupt happens and the interrupt handler configures the hardware for rising-edge, the level of the pin may have already risen, and the rising-edge event is lost. To address that issue, instead of switching back and forth between IRQ_TYPE_EDGE_RISING and IRQ_TYPE_EDGE_FALLING, we now switch back and forth between IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_LEVEL_HIGH. Since we always switch in the interrupt handler, they actually permit to detect level changes. In the example above, if the pin level rises before switching the IRQ type from IRQ_TYPE_LEVEL_LOW to IRQ_TYPE_LEVEL_HIGH, a new interrupt will raise as soon as the handler exits, and the rising-edge event will be properly detected. Cc: stable@vger.kernel.org Fixes: e72394e2ea19 ("pinctrl: ingenic: Merge GPIO functionality") Reported-by: João Henrique Tested-by: João Henrique Signed-off-by: Paul Cercueil --- drivers/pinctrl/pinctrl-ingenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index fc0d10411aa9..241e563d5814 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1813,9 +1813,9 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd) */ high = ingenic_gpio_get_value(jzgc, irq); if (high) - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING); + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_LOW); else - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING); + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH); } if (jzgc->jzpc->info->version >= ID_JZ4760) @@ -1851,7 +1851,7 @@ static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) */ bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq); - type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; + type = high ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH; } irq_set_type(jzgc, irqd->hwirq, type); From patchwork Mon Jun 22 21:45:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 1314750 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=crapouillou.net Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=crapouillou.net header.i=@crapouillou.net header.a=rsa-sha256 header.s=mail header.b=pZSCdYsq; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49rNK32gCVz9s6w for ; Tue, 23 Jun 2020 07:46:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730714AbgFVVq1 (ORCPT ); Mon, 22 Jun 2020 17:46:27 -0400 Received: from outils.crapouillou.net ([89.234.176.41]:34258 "EHLO crapouillou.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730494AbgFVVq0 (ORCPT ); Mon, 22 Jun 2020 17:46:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1592862376; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aSFfecEJZ2Br9jQI/s7igbpy7SV0eFCH93xlSkAnB1I=; b=pZSCdYsq3KfcyqRF5UgqTA2x0HMJ29OH1l3ITs89cXYN1dORtxkfkTKoreOPGr886xYg0W FBex0WdHxgL71F5kxQTQ1ikKVvrheb7huWVd4f+JB9n+q3k7dS/sMLgxsQmpPZxq5ctdZc KjSDgeDQqztsO5bB9nmOzlvFBK3jNCo= From: Paul Cercueil To: Linus Walleij Cc: od@zcrc.me, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Paul Cercueil , stable@vger.kernel.org, =?utf-8?q?Jo?= =?utf-8?q?=C3=A3o_Henrique?= Subject: [PATCH 2/2] pinctrl: ingenic: Properly detect GPIO direction when configured for IRQ Date: Mon, 22 Jun 2020 23:45:48 +0200 Message-Id: <20200622214548.265417-2-paul@crapouillou.net> In-Reply-To: <20200622214548.265417-1-paul@crapouillou.net> References: <20200622214548.265417-1-paul@crapouillou.net> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The PAT1 register contains information about the IRQ type (edge/level) for input GPIOs with IRQ enabled, and the direction for non-IRQ GPIOs. So it makes sense to read it only if the GPIO has no interrupt configured, otherwise input GPIOs configured for level IRQs are misdetected as output GPIOs. Cc: stable@vger.kernel.org Fixes: ebd6651418b6 ("pinctrl: ingenic: Implement .get_direction for GPIO chips") Reported-by: João Henrique Signed-off-by: Paul Cercueil --- drivers/pinctrl/pinctrl-ingenic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 241e563d5814..a8d1b53ec4c1 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1958,7 +1958,8 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) unsigned int pin = gc->base + offset; if (jzpc->info->version >= ID_JZ4760) { - if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1)) + if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) || + ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1)) return GPIO_LINE_DIRECTION_IN; return GPIO_LINE_DIRECTION_OUT; }