devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Packham <chris.packham@alliedtelesis.co.nz>
To: wsa@kernel.org, andi.shyti@kernel.org, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
	gregory.clement@bootlin.com
Cc: linux-i2c@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Chris Packham <chris.packham@alliedtelesis.co.nz>
Subject: [PATCH v6 2/2] i2c: add an optional bus-reset-gpios property
Date: Wed, 15 Nov 2023 16:57:53 +1300	[thread overview]
Message-ID: <20231115035753.925534-3-chris.packham@alliedtelesis.co.nz> (raw)
In-Reply-To: <20231115035753.925534-1-chris.packham@alliedtelesis.co.nz>

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. Represent this kind of hardware design
by associating the bus-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 v6:
    - Retarget changes at the i2c core instead of an individual driver
    Changes in v5:
    - Rename reset-gpios and reset-duration-us to bus-reset-gpios and
      bus-reset-duration-us as requested by Wolfram
    Changes in v4:
    - Add missing gpio/consumer.h
    - use fsleep() for enforcing reset-duration
    Changes in v3:
    - Rename reset-delay to reset-duration
    - Use reset-duration-us property to control the reset pulse rather than
      delaying after the reset
    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/i2c-core-base.c | 39 +++++++++++++++++++++++++++++++++++++
 include/linux/i2c.h         |  3 +++
 2 files changed, 42 insertions(+)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 60746652fd52..d7f53272487b 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1468,6 +1468,39 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr)
 }
 EXPORT_SYMBOL_GPL(i2c_handle_smbus_host_notify);
 
+static int i2c_setup_bus_reset_gpio(struct i2c_adapter *adap)
+{
+	int res;
+
+	adap->reset_gpios = devm_gpiod_get_array_optional(&adap->dev, "bus-reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(adap->reset_gpios))
+		return dev_err_probe(&adap->dev, PTR_ERR(adap->reset_gpios),
+				     "Cannot get reset gpio\n");
+	res = device_property_read_u32(&adap->dev, "bus-reset-duration-us", &adap->reset_duration);
+	if (res)
+		adap->reset_duration = 1;
+
+	return 0;
+}
+
+static void i2c_deassert_bus_reset_gpio(struct i2c_adapter *adap)
+{
+	unsigned long *values;
+
+	if (!adap->reset_gpios)
+		return;
+
+	values = bitmap_zalloc(adap->reset_gpios->ndescs, GFP_KERNEL);
+	if (!values)
+		return;
+
+	gpiod_set_array_value_cansleep(adap->reset_gpios->ndescs,
+			adap->reset_gpios->desc, adap->reset_gpios->info,
+			values);
+
+	bitmap_free(values);
+}
+
 static int i2c_register_adapter(struct i2c_adapter *adap)
 {
 	int res = -EINVAL;
@@ -1521,6 +1554,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 	if (res)
 		goto out_reg;
 
+	res = i2c_setup_bus_reset_gpio(adap);
+	if (res)
+		goto out_reg;
+
 	device_enable_async_suspend(&adap->dev);
 	pm_runtime_no_callbacks(&adap->dev);
 	pm_suspend_ignore_children(&adap->dev, true);
@@ -1539,6 +1576,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 		dev_warn(&adap->dev,
 			 "Failed to create compatibility class link\n");
 #endif
+	/* bring downstream devices out of reset */
+	i2c_deassert_bus_reset_gpio(adap);
 
 	/* create pre-declared device nodes */
 	of_i2c_register_devices(adap);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 0dae9db27538..1110a49dcdaf 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -746,6 +746,9 @@ struct i2c_adapter {
 
 	struct irq_domain *host_notify_domain;
 	struct regulator *bus_regulator;
+
+	struct gpio_descs *reset_gpios;
+	u32 reset_duration;
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
-- 
2.42.0


      parent reply	other threads:[~2023-11-15  3:58 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-15  3:57 [PATCH v6 0/2] i2c: bus-reset-gpios Chris Packham
2023-11-15  3:57 ` [PATCH v6 1/2] dt-bindings: i2c: add bus-reset-gpios property Chris Packham
2023-11-15 21:29   ` Krzysztof Kozlowski
2023-11-15 21:53     ` Chris Packham
2023-11-16 11:37       ` Krzysztof Kozlowski
2023-12-19 17:02       ` wsa
2023-12-19 19:28         ` Chris Packham
2023-12-19 20:50           ` wsa
2023-12-19 23:25             ` Andi Shyti
2023-12-20  7:22               ` Krzysztof Kozlowski
2023-12-20 11:03                 ` wsa
2023-12-20 11:29                   ` Krzysztof Kozlowski
2023-12-20 11:52                     ` wsa
2023-12-21  0:40                 ` Andi Shyti
2023-11-15  3:57 ` Chris Packham [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231115035753.925534-3-chris.packham@alliedtelesis.co.nz \
    --to=chris.packham@alliedtelesis.co.nz \
    --cc=andi.shyti@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregory.clement@bootlin.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=wsa@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).