Message ID | 20231016023504.3976746-3-chris.packham@alliedtelesis.co.nz |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp3198841vqb; Sun, 15 Oct 2023 19:35:41 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGlL3iMTprJRdHziBceeSubicvan5VJnz/iDqgcKqDFf4fAyY0NDgj1rLepGpYM1ZwQyeAA X-Received: by 2002:a25:b20b:0:b0:d9a:5fb6:68e3 with SMTP id i11-20020a25b20b000000b00d9a5fb668e3mr12220007ybj.5.1697423741223; Sun, 15 Oct 2023 19:35:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697423741; cv=none; d=google.com; s=arc-20160816; b=FI4qCjHGBIZdgK0s+JEmWy3Zbt6ii45KRwZQURUuI7LdUVFdYeROuNaRzVX7zRGs1h 76m+hQjAXuls3DOvGFITk5+5C23e04U45rn9OwAJPN0PDzzNlNvfybrPaer8LluUywSa TXQsUnAiCvpXUecRbVDj3GzO8QwFt32RwaKJRP5TV1OYYZnKe+sIx3DDnArMv7tMps7W cIwYmAJtKjFQyaJpuUzUw7ZmcwhUNkFr/MdHDY8OIX6a4oqg0jWKPHvYrhPrbzy3x0wS T687hCt26eUcDlUxYvmGhXy9iCGNr7X9rs4jwAzGvWTFSKPMhjPZnRqWwsKCMKFKhMn8 dLaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=aCgNbznu5ctmkUYc5AaiEvFzQOMDXqXtMYjFRvtkLjM=; fh=3tQj0XukzIaVVOd6lLPEALhtzKzMAG+0/N98Vq3ytYw=; b=ZJMgVm+2NKq8vpxWKy5819QYHBUzVL55PM55J1HYO2Hspqp/J/yjn+BB4mYpPtQemu PuxJoE0txreKM9UiRtYN0pjrtCQRpPXnwB4DasSgRljQoDRIPAkPAV3aN8vK3yxD7wGD 5B69IJCOWf0oD05kQSV1IZfggGFk/x4JkGewPlN/bmP5GPPJjuARs6B93Yfah7378tVr alF6pMCgILSql4JxZh9eTUP4Jnmjj0tKcPu0rwsT8MAeCDvvRbdYPHDTFMCLNnLaxDtA f6Qn6NXXUfbXNRDmvF8zTXaj6F1F4chuBcrCAX7VFtSFETqgZX8LNxlxWc7zICYczBVL 5AxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@alliedtelesis.co.nz header.s=mail181024 header.b=b5pXqZug; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=alliedtelesis.co.nz Received: from howler.vger.email (howler.vger.email. [23.128.96.34]) by mx.google.com with ESMTPS id r3-20020a63ce43000000b0056476f15584si10178575pgi.541.2023.10.15.19.35.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Oct 2023 19:35:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) client-ip=23.128.96.34; Authentication-Results: mx.google.com; dkim=pass header.i=@alliedtelesis.co.nz header.s=mail181024 header.b=b5pXqZug; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=alliedtelesis.co.nz Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 6D2A680608E6; Sun, 15 Oct 2023 19:35:38 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231294AbjJPCfP (ORCPT <rfc822;hjfbswb@gmail.com> + 18 others); Sun, 15 Oct 2023 22:35:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230283AbjJPCfN (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sun, 15 Oct 2023 22:35:13 -0400 Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [202.36.163.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8359D6 for <linux-kernel@vger.kernel.org>; Sun, 15 Oct 2023 19:35:10 -0700 (PDT) Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id E47942C0381; Mon, 16 Oct 2023 15:35:07 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1697423707; bh=aCgNbznu5ctmkUYc5AaiEvFzQOMDXqXtMYjFRvtkLjM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b5pXqZugtz0gQkC57FTOCbYsBpMB+TKmdU3EKS91m0zJl4LclBDOUZZwnE/k1l0ml 9WgB2UcNNWPsN+8w3HFjRb/O+wtxmTWncJsVpk47mKmioYM0cKJKCI6EE1e9yUWadL fC9j5p98yjA4hFkoaijR3KyWVrL8lyyUR+iMLyZd+K3umqLYlDpyby0lGLUOW3140k wAxLJbF3hfhDENZk3jNcQm50wseILsgjrc4GlnJpzkEAZ3+BSwRRLeZ/06WdRWX7ba jeZnGkxwXcITPnuubE4LErIncETWjQVcZ0YYxqyakWdjeaoG5x+EnExH6jCYnzhcdw cJ9Iz/wuMGHsA== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id <B652ca15b0002>; Mon, 16 Oct 2023 15:35:07 +1300 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by pat.atlnz.lc (Postfix) with ESMTP id AFFF513EE9B; Mon, 16 Oct 2023 15:35:07 +1300 (NZDT) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id AE1D028140C; Mon, 16 Oct 2023 15:35:07 +1300 (NZDT) From: Chris Packham <chris.packham@alliedtelesis.co.nz> To: gregory.clement@bootlin.com, andi.shyti@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org Cc: linux-i2c@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chris Packham <chris.packham@alliedtelesis.co.nz> Subject: [PATCH v2 2/2] i2c: mv64xxx: add an optional reset-gpios property Date: Mon, 16 Oct 2023 15:35:04 +1300 Message-ID: <20231016023504.3976746-3-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231016023504.3976746-1-chris.packham@alliedtelesis.co.nz> References: <20231016023504.3976746-1-chris.packham@alliedtelesis.co.nz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-SEG-SpamProfiler-Analysis: v=2.3 cv=L6ZjvNb8 c=1 sm=1 tr=0 a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=bhdUkHdE2iEA:10 a=VsZq4EHS3crWG1I_hwYA:9 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Sun, 15 Oct 2023 19:35:38 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779877796995443793 X-GMAIL-MSGID: 1779877796995443793 |
Series |
i2c: mv64xxx: reset-gpios
|
|
Commit Message
Chris Packham
Oct. 16, 2023, 2:35 a.m. UTC
Some hardware designs have a GPIO used to control the reset of all the
devices on and I2C bus. It's not possible for every child node to
declare a reset-gpios property as only the first device probed would be
able to successfully request it (the others will get -EBUSY). Represent
this kind of hardware design by associating the reset-gpios with the
parent I2C bus. The reset line will be released prior to the child I2C
devices being probed.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
Changes in v2:
- Add a property to cover the length of delay after releasing the reset
GPIO
- Use dev_err_probe() when requesing the GPIO fails
drivers/i2c/busses/i2c-mv64xxx.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
Comments
Hi! 2023-10-16 at 04:35, Chris Packham wrote: > Some hardware designs have a GPIO used to control the reset of all the > devices on and I2C bus. It's not possible for every child node to > declare a reset-gpios property as only the first device probed would be > able to successfully request it (the others will get -EBUSY). Represent > this kind of hardware design by associating the reset-gpios with the > parent I2C bus. The reset line will be released prior to the child I2C > devices being probed. > > Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz> > --- > > Notes: > Changes in v2: > - Add a property to cover the length of delay after releasing the reset > GPIO > - Use dev_err_probe() when requesing the GPIO fails > > drivers/i2c/busses/i2c-mv64xxx.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c > index efd28bbecf61..50c470e5c4be 100644 > --- a/drivers/i2c/busses/i2c-mv64xxx.c > +++ b/drivers/i2c/busses/i2c-mv64xxx.c > @@ -160,6 +160,7 @@ struct mv64xxx_i2c_data { > bool clk_n_base_0; > struct i2c_bus_recovery_info rinfo; > bool atomic; > + struct gpio_desc *reset_gpio; > }; > > static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { > @@ -1036,6 +1037,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) > struct mv64xxx_i2c_data *drv_data; > struct mv64xxx_i2c_pdata *pdata = dev_get_platdata(&pd->dev); > struct resource *res; > + u32 reset_udelay; > int rc; > > if ((!pdata && !pd->dev.of_node)) > @@ -1083,6 +1085,14 @@ mv64xxx_i2c_probe(struct platform_device *pd) > if (drv_data->irq < 0) > return drv_data->irq; > > + drv_data->reset_gpio = devm_gpiod_get_optional(&pd->dev, "reset", GPIOD_OUT_HIGH); > + if (IS_ERR(drv_data->reset_gpio)) > + return dev_err_probe(&pd->dev, PTR_ERR(drv_data->reset_gpio), > + "Cannot get reset gpio\n"); > + rc = device_property_read_u32(&pd->dev, "reset-delay-us", &reset_udelay); > + if (rc) > + reset_udelay = 1; > + > if (pdata) { > drv_data->freq_m = pdata->freq_m; > drv_data->freq_n = pdata->freq_n; > @@ -1121,6 +1131,11 @@ mv64xxx_i2c_probe(struct platform_device *pd) > goto exit_disable_pm; > } > > + if (drv_data->reset_gpio) { > + gpiod_set_value_cansleep(drv_data->reset_gpio, 0); There is no limit to how short the reset pulse will be with this implementation. What I was requesting in my comment for v1 was a way to control the length of the reset pulse (not the delay after the pulse). There are devices that behave very badly if the reset pulse is too short for their liking, others might not react at all... Some delay after the pulse might also be needed, of course. Cheers, Peter > + usleep_range(reset_udelay, reset_udelay + 10); > + } > + > rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, > MV64XXX_I2C_CTLR_NAME, drv_data); > if (rc) {
On 18/10/23 09:32, Peter Rosin wrote: > Hi! > > 2023-10-16 at 04:35, Chris Packham wrote: >> Some hardware designs have a GPIO used to control the reset of all the >> devices on and I2C bus. It's not possible for every child node to >> declare a reset-gpios property as only the first device probed would be >> able to successfully request it (the others will get -EBUSY). Represent >> this kind of hardware design by associating the reset-gpios with the >> parent I2C bus. The reset line will be released prior to the child I2C >> devices being probed. >> >> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz> >> --- >> >> Notes: >> Changes in v2: >> - Add a property to cover the length of delay after releasing the reset >> GPIO >> - Use dev_err_probe() when requesing the GPIO fails >> >> drivers/i2c/busses/i2c-mv64xxx.c | 15 +++++++++++++++ >> 1 file changed, 15 insertions(+) >> >> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c >> index efd28bbecf61..50c470e5c4be 100644 >> --- a/drivers/i2c/busses/i2c-mv64xxx.c >> +++ b/drivers/i2c/busses/i2c-mv64xxx.c >> @@ -160,6 +160,7 @@ struct mv64xxx_i2c_data { >> bool clk_n_base_0; >> struct i2c_bus_recovery_info rinfo; >> bool atomic; >> + struct gpio_desc *reset_gpio; >> }; >> >> static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { >> @@ -1036,6 +1037,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) >> struct mv64xxx_i2c_data *drv_data; >> struct mv64xxx_i2c_pdata *pdata = dev_get_platdata(&pd->dev); >> struct resource *res; >> + u32 reset_udelay; >> int rc; >> >> if ((!pdata && !pd->dev.of_node)) >> @@ -1083,6 +1085,14 @@ mv64xxx_i2c_probe(struct platform_device *pd) >> if (drv_data->irq < 0) >> return drv_data->irq; >> >> + drv_data->reset_gpio = devm_gpiod_get_optional(&pd->dev, "reset", GPIOD_OUT_HIGH); >> + if (IS_ERR(drv_data->reset_gpio)) >> + return dev_err_probe(&pd->dev, PTR_ERR(drv_data->reset_gpio), >> + "Cannot get reset gpio\n"); >> + rc = device_property_read_u32(&pd->dev, "reset-delay-us", &reset_udelay); >> + if (rc) >> + reset_udelay = 1; >> + >> if (pdata) { >> drv_data->freq_m = pdata->freq_m; >> drv_data->freq_n = pdata->freq_n; >> @@ -1121,6 +1131,11 @@ mv64xxx_i2c_probe(struct platform_device *pd) >> goto exit_disable_pm; >> } >> >> + if (drv_data->reset_gpio) { >> + gpiod_set_value_cansleep(drv_data->reset_gpio, 0); > There is no limit to how short the reset pulse will be with this > implementation. What I was requesting in my comment for v1 was > a way to control the length of the reset pulse (not the delay > after the pulse). There are devices that behave very badly if > the reset pulse is too short for their liking, others might not > react at all... Yeah you're right. I originally had the same delay before and after but decided to remove one (and chose wrong). I think I definitely need the delay before this to ensure a minimum reset pulse. I'm on the fence about the delay after, I don't think any of the devices I regularly deal with have a particular time they need to be out of reset before you can start talking to them. > > Some delay after the pulse might also be needed, of course. > > Cheers, > Peter > >> + usleep_range(reset_udelay, reset_udelay + 10); >> + } >> + >> rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, >> MV64XXX_I2C_CTLR_NAME, drv_data); >> if (rc) {
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index efd28bbecf61..50c470e5c4be 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -160,6 +160,7 @@ struct mv64xxx_i2c_data { bool clk_n_base_0; struct i2c_bus_recovery_info rinfo; bool atomic; + struct gpio_desc *reset_gpio; }; static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { @@ -1036,6 +1037,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) struct mv64xxx_i2c_data *drv_data; struct mv64xxx_i2c_pdata *pdata = dev_get_platdata(&pd->dev); struct resource *res; + u32 reset_udelay; int rc; if ((!pdata && !pd->dev.of_node)) @@ -1083,6 +1085,14 @@ mv64xxx_i2c_probe(struct platform_device *pd) if (drv_data->irq < 0) return drv_data->irq; + drv_data->reset_gpio = devm_gpiod_get_optional(&pd->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(drv_data->reset_gpio)) + return dev_err_probe(&pd->dev, PTR_ERR(drv_data->reset_gpio), + "Cannot get reset gpio\n"); + rc = device_property_read_u32(&pd->dev, "reset-delay-us", &reset_udelay); + if (rc) + reset_udelay = 1; + if (pdata) { drv_data->freq_m = pdata->freq_m; drv_data->freq_n = pdata->freq_n; @@ -1121,6 +1131,11 @@ mv64xxx_i2c_probe(struct platform_device *pd) goto exit_disable_pm; } + if (drv_data->reset_gpio) { + gpiod_set_value_cansleep(drv_data->reset_gpio, 0); + usleep_range(reset_udelay, reset_udelay + 10); + } + rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, MV64XXX_I2C_CTLR_NAME, drv_data); if (rc) {