From patchwork Thu Feb 24 16:10:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 545992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C9BFC433F5 for ; Thu, 24 Feb 2022 16:12:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229617AbiBXQM6 (ORCPT ); Thu, 24 Feb 2022 11:12:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230112AbiBXQMy (ORCPT ); Thu, 24 Feb 2022 11:12:54 -0500 Received: from ssl.serverraum.org (ssl.serverraum.org [IPv6:2a01:4f8:151:8464::1:2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DB11141FDE; Thu, 24 Feb 2022 08:12:15 -0800 (PST) Received: from mwalle01.kontron.local. (unknown [213.135.10.150]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ssl.serverraum.org (Postfix) with ESMTPSA id 92435223EF; Thu, 24 Feb 2022 17:10:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2016061301; t=1645719038; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+y+BxTTNJQzbFxHr7bW2D/PlpySv4+4O8TfivZabfgA=; b=lQ8s3GalJm274l7UbnEJjMk4HOjcnSD7cwVf0kPLliB2uiaEfq1YKXJ3M+Pn0ONKm6MOWV emEhxjIhzecoo3k5T+yT2aMgx/SkDfUYTcwYP5FE3btuUusw24q4SGBDwMajRxcKv7uerw 1P66HZWTMhAjDC2PwHdHfjzcrvzPpRM= From: Michael Walle To: Lars Povlsen , Steen Hegelund , Linus Walleij Cc: UNGLinuxDriver@microchip.com, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Colin Foster , Michael Walle Subject: [PATCH v1 3/5] pinctrl: microchip-sgpio: use regmap_update_bits() Date: Thu, 24 Feb 2022 17:10:19 +0100 Message-Id: <20220224161021.2197263-4-michael@walle.cc> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220224161021.2197263-1-michael@walle.cc> References: <20220224161021.2197263-1-michael@walle.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Convert sgpio_clrsetbits() to use regmap_update_bits() and drop the spinlocks because regmap already takes care of the locking. Signed-off-by: Michael Walle --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index 31c4401f725e..f01ca94943da 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -168,12 +168,11 @@ static void sgpio_writel(struct sgpio_priv *priv, static inline void sgpio_clrsetbits(struct sgpio_priv *priv, u32 rno, u32 off, u32 clear, u32 set) { - u32 val = sgpio_readl(priv, rno, off); - - val &= ~clear; - val |= set; + u32 addr = sgpio_get_addr(priv, rno, off); + int ret; - sgpio_writel(priv, val, rno, off); + ret = regmap_update_bits(priv->regs, addr, clear | set, set); + WARN_ONCE(ret, "error updating sgpio reg %d\n", ret); } static inline void sgpio_configure_bitstream(struct sgpio_priv *priv) @@ -231,7 +230,6 @@ static void sgpio_output_set(struct sgpio_priv *priv, int value) { unsigned int bit = SGPIO_SRC_BITS * addr->bit; - unsigned long flags; u32 clr, set; switch (priv->properties->arch) { @@ -251,9 +249,7 @@ static void sgpio_output_set(struct sgpio_priv *priv, return; } - spin_lock_irqsave(&priv->lock, flags); sgpio_clrsetbits(priv, REG_PORT_CONFIG, addr->port, clr, set); - spin_unlock_irqrestore(&priv->lock, flags); } static int sgpio_output_get(struct sgpio_priv *priv, @@ -616,16 +612,13 @@ static void microchip_sgpio_irq_setreg(struct irq_data *data, struct sgpio_bank *bank = gpiochip_get_data(chip); unsigned int gpio = irqd_to_hwirq(data); struct sgpio_port_addr addr; - unsigned long flags; sgpio_pin_to_addr(bank->priv, gpio, &addr); - spin_lock_irqsave(&bank->priv->lock, flags); if (clear) sgpio_clrsetbits(bank->priv, reg, addr.bit, BIT(addr.port), 0); else sgpio_clrsetbits(bank->priv, reg, addr.bit, 0, BIT(addr.port)); - spin_unlock_irqrestore(&bank->priv->lock, flags); } static void microchip_sgpio_irq_mask(struct irq_data *data) From patchwork Thu Feb 24 16:10:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 545991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 043CFC433FE for ; Thu, 24 Feb 2022 16:12:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229493AbiBXQM7 (ORCPT ); Thu, 24 Feb 2022 11:12:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229521AbiBXQM6 (ORCPT ); Thu, 24 Feb 2022 11:12:58 -0500 Received: from ssl.serverraum.org (ssl.serverraum.org [IPv6:2a01:4f8:151:8464::1:2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11A04158EA6; Thu, 24 Feb 2022 08:12:21 -0800 (PST) Received: from mwalle01.kontron.local. (unknown [213.135.10.150]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ssl.serverraum.org (Postfix) with ESMTPSA id EB69B223F0; Thu, 24 Feb 2022 17:10:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2016061301; t=1645719039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qzw+kR2qzAEtlrrCdkWu8sUT4TvXDm0xnydMaXN0U6I=; b=rgRn87mdvKSuqxmhsGaWcf7Uf3NdGYh6yH3fe42Upqfdo2lZ7dVCykpvyiYS52bdkFSbJo sngrLJo8PI5OTdD4wn6JUvHSyJdMaqEekj1n7KeZVfEoEYffzAIKVFang0iEeisQTvZu3d k85bfMdb7FxfYBfCv3AjSXt3Zh2HZ5Y= From: Michael Walle To: Lars Povlsen , Steen Hegelund , Linus Walleij Cc: UNGLinuxDriver@microchip.com, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Colin Foster , Michael Walle Subject: [PATCH v1 4/5] pinctrl: microchip-sgpio: return error in spgio_output_set() Date: Thu, 24 Feb 2022 17:10:20 +0100 Message-Id: <20220224161021.2197263-5-michael@walle.cc> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220224161021.2197263-1-michael@walle.cc> References: <20220224161021.2197263-1-michael@walle.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Make sgpio_output_set() return an error value. Don't just ignore the return value of any regmap access but propagate it to our callers. Even if the accesses never fail, this is a preparation patch to add single shot mode where we need to poll a bit and thus we might get -ETIMEDOUT. Signed-off-by: Michael Walle --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index f01ca94943da..3f3b8c482f3a 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -225,9 +225,9 @@ static inline void sgpio_configure_clock(struct sgpio_priv *priv, u32 clkfrq) sgpio_clrsetbits(priv, REG_SIO_CLOCK, 0, clr, set); } -static void sgpio_output_set(struct sgpio_priv *priv, - struct sgpio_port_addr *addr, - int value) +static int sgpio_output_set(struct sgpio_priv *priv, + struct sgpio_port_addr *addr, + int value) { unsigned int bit = SGPIO_SRC_BITS * addr->bit; u32 clr, set; @@ -246,10 +246,12 @@ static void sgpio_output_set(struct sgpio_priv *priv, set = FIELD_PREP(SGPIO_SPARX5_BIT_SOURCE, value << bit); break; default: - return; + return -EINVAL; } sgpio_clrsetbits(priv, REG_PORT_CONFIG, addr->port, clr, set); + + return 0; } static int sgpio_output_get(struct sgpio_priv *priv, @@ -335,7 +337,7 @@ static int sgpio_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, case PIN_CONFIG_OUTPUT: if (bank->is_input) return -EINVAL; - sgpio_output_set(priv, &addr, arg); + err = sgpio_output_set(priv, &addr, arg); break; default: @@ -475,9 +477,7 @@ static int microchip_sgpio_direction_output(struct gpio_chip *gc, sgpio_pin_to_addr(priv, gpio, &addr); - sgpio_output_set(priv, &addr, value); - - return 0; + return sgpio_output_set(priv, &addr, value); } static int microchip_sgpio_get_direction(struct gpio_chip *gc, unsigned int gpio) From patchwork Thu Feb 24 16:10:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Walle X-Patchwork-Id: 545990 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1051C433F5 for ; Thu, 24 Feb 2022 16:17:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229498AbiBXQSK (ORCPT ); Thu, 24 Feb 2022 11:18:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229876AbiBXQSJ (ORCPT ); Thu, 24 Feb 2022 11:18:09 -0500 Received: from ssl.serverraum.org (ssl.serverraum.org [IPv6:2a01:4f8:151:8464::1:2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C07181B3A75; Thu, 24 Feb 2022 08:17:35 -0800 (PST) Received: from mwalle01.kontron.local. (unknown [213.135.10.150]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ssl.serverraum.org (Postfix) with ESMTPSA id 3811B223F6; Thu, 24 Feb 2022 17:10:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2016061301; t=1645719039; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H2eMkw48G2IEnPpAZYbRz1ozQ55FXZI5S0Cuz1HtPj4=; b=GCZJy+ixU/kQqEaic+jy/Y9fxRXjENytHV1qZM6uYGHjx5itI9KLWTyEPccFDlM99paT6j bCO2xHKvPz1Qk3mrUit4WXtxgmqOmba5ZW0ezShWKfuIvH3I0ZhG/Tuf2crXzHRsqcF4Qi hMNLtcxHAHNH5PMqv+NiTxdQVW9mdHc= From: Michael Walle To: Lars Povlsen , Steen Hegelund , Linus Walleij Cc: UNGLinuxDriver@microchip.com, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Colin Foster , Michael Walle Subject: [PATCH v1 5/5] pinctrl: microchip-sgpio: wait until output is actually set Date: Thu, 24 Feb 2022 17:10:21 +0100 Message-Id: <20220224161021.2197263-6-michael@walle.cc> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220224161021.2197263-1-michael@walle.cc> References: <20220224161021.2197263-1-michael@walle.cc> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Right now, when a gpio value is set, the actual hardware pin gets set asynchronously. When linux write the output register, it takes some time until it is actually propagated to the output shift registers. If that output port is connected to an I2C mux for example, the linux driver assumes the I2C bus is already switched although it is not. Fortunately, there is a single shot mode with a feedback: you can trigger the single shot and the hardware will clear that bit once it has finished the clocking and strobed the load signal of the shift registers. This can take a considerable amount of time though. Measuremens have shown that it takes up to a whole burst cycle gap which is about 50ms on the largest setting. Therefore, we have to mark the output bank as sleepable. To avoid unnecessary waiting, just trigger the single shot if the value was actually changed. Signed-off-by: Michael Walle --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 58 ++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index 3f3b8c482f3a..768b69929c99 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -69,6 +69,7 @@ struct sgpio_properties { #define SGPIO_OCELOT_BIT_SOURCE GENMASK(23, 12) #define SGPIO_SPARX5_AUTO_REPEAT BIT(6) +#define SGPIO_SPARX5_SINGLE_SHOT BIT(7) #define SGPIO_SPARX5_PORT_WIDTH GENMASK(4, 3) #define SGPIO_SPARX5_CLK_FREQ GENMASK(19, 8) #define SGPIO_SPARX5_BIT_SOURCE GENMASK(23, 12) @@ -118,6 +119,8 @@ struct sgpio_priv { struct regmap *regs; const struct sgpio_properties *properties; spinlock_t lock; + /* protects the config register and single shot mode */ + struct mutex poll_lock; }; struct sgpio_port_addr { @@ -225,12 +228,54 @@ static inline void sgpio_configure_clock(struct sgpio_priv *priv, u32 clkfrq) sgpio_clrsetbits(priv, REG_SIO_CLOCK, 0, clr, set); } +static int sgpio_single_shot(struct sgpio_priv *priv) +{ + u32 addr = sgpio_get_addr(priv, REG_SIO_CONFIG, 0); + int ret, ret2; + u32 ctrl; + + /* Only supported on SparX-5 for now. */ + if (priv->properties->arch != SGPIO_ARCH_SPARX5) + return 0; + + /* + * Trigger immediate burst. This only works when auto repeat is turned + * off. Otherwise, the single shot bit will never be cleared by the + * hardware. Measurements showed that an update might take as long as + * the burst gap. On a LAN9668 this is about 50ms for the largest + * setting. + * After the manual burst, reenable the auto repeat mode again. + */ + mutex_lock(&priv->poll_lock); + ret = regmap_update_bits(priv->regs, addr, + SGPIO_SPARX5_SINGLE_SHOT | SGPIO_SPARX5_AUTO_REPEAT, + SGPIO_SPARX5_SINGLE_SHOT); + if (ret) + goto out; + + ret = regmap_read_poll_timeout(priv->regs, addr, ctrl, + !(ctrl & SGPIO_SPARX5_SINGLE_SHOT), + 100, 60000); + + /* reenable auto repeat mode even if there was an error */ + ret2 = regmap_update_bits(priv->regs, addr, + SGPIO_SPARX5_AUTO_REPEAT, + SGPIO_SPARX5_AUTO_REPEAT); +out: + mutex_unlock(&priv->poll_lock); + + return ret ?: ret2; +} + static int sgpio_output_set(struct sgpio_priv *priv, struct sgpio_port_addr *addr, int value) { unsigned int bit = SGPIO_SRC_BITS * addr->bit; + u32 reg = sgpio_get_addr(priv, REG_PORT_CONFIG, addr->port); + bool changed; u32 clr, set; + int ret; switch (priv->properties->arch) { case SGPIO_ARCH_LUTON: @@ -249,7 +294,16 @@ static int sgpio_output_set(struct sgpio_priv *priv, return -EINVAL; } - sgpio_clrsetbits(priv, REG_PORT_CONFIG, addr->port, clr, set); + ret = regmap_update_bits_check(priv->regs, reg, clr | set, set, + &changed); + if (ret) + return ret; + + if (changed) { + ret = sgpio_single_shot(priv); + if (ret) + return ret; + } return 0; } @@ -788,6 +842,7 @@ static int microchip_sgpio_register_bank(struct device *dev, gc->of_gpio_n_cells = 3; gc->base = -1; gc->ngpio = ngpios; + gc->can_sleep = !bank->is_input; if (bank->is_input && priv->properties->flags & SGPIO_FLAGS_HAS_IRQ) { int irq = fwnode_irq_get(fwnode, 0); @@ -848,6 +903,7 @@ static int microchip_sgpio_probe(struct platform_device *pdev) priv->dev = dev; spin_lock_init(&priv->lock); + mutex_init(&priv->poll_lock); reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch"); if (IS_ERR(reset))