All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets
@ 2023-12-22 15:01 Krzysztof Kozlowski
  2023-12-22 15:01 ` [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios Krzysztof Kozlowski
                   ` (5 more replies)
  0 siblings, 6 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Krzysztof Kozlowski, Chris Packham, Bartosz Golaszewski, Sean Anderson

Hi,

We have at least few cases where hardware engineers decided to use one
powerdown/shutdown/reset GPIO line for multiple devices:

1. WSA884x (this and previous patch):
https://lore.kernel.org/all/b7aeda24-d638-45b7-8e30-80d287f498f8@sirena.org.uk/
2. https://lore.kernel.org/all/20231027033104.1348921-1-chris.packham@alliedtelesis.co.nz/
3. https://lore.kernel.org/lkml/20191030120440.3699-1-peter.ujfalusi@ti.com/
4. https://lore.kernel.org/all/20211018234923.1769028-1-sean.anderson@seco.com/
5. https://social.treehouse.systems/@marcan/111268780311634160

I try to solve my case, hopefuly Chris' (2), partially Sean's (4) and maybe
Hectors (5), using Rob's suggestion:

https://lore.kernel.org/all/YXi5CUCEi7YmNxXM@robh.at.kernel.org/

Best regards,
Krzysztof

Cc: Chris Packham <chris.packham@alliedtelesis.co.nz>
Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Sean Anderson <sean.anderson@seco.com>

Krzysztof Kozlowski (4):
  reset: instantiate reset GPIO controller for shared reset-gpios
  reset: add GPIO-based reset controller
  ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line
  ASoC: codecs: wsa884x: Allow sharing reset GPIO

 .../bindings/sound/qcom,wsa8840.yaml          |   9 +-
 MAINTAINERS                                   |   5 +
 drivers/reset/Kconfig                         |   9 ++
 drivers/reset/Makefile                        |   1 +
 drivers/reset/core.c                          |  70 ++++++++++--
 drivers/reset/reset-gpio.c                    | 105 ++++++++++++++++++
 include/linux/reset-controller.h              |   2 +
 sound/soc/codecs/wsa884x.c                    |  52 +++++++--
 8 files changed, 231 insertions(+), 22 deletions(-)
 create mode 100644 drivers/reset/reset-gpio.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios
  2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
@ 2023-12-22 15:01 ` Krzysztof Kozlowski
  2023-12-22 17:31   ` Bartosz Golaszewski
  2023-12-22 15:01 ` [PATCH 2/4] reset: add GPIO-based reset controller Krzysztof Kozlowski
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Krzysztof Kozlowski, Bartosz Golaszewski, Sean Anderson

Devices sharing a reset GPIO could use the reset framework for
coordinated handling of that shared GPIO line.  We have several cases of
such needs, at least for Devicetree-based platforms.

If Devicetree-based device requests a reset line which is missing but
there is a reset-gpios property, instantiate a new "reset-gpio" platform
device which will handle such reset line.  This allows seamless handling
of such shared reset-gpios without need of changing Devicetree binding [1].

The "reset-gpio" driver follows shortly.

Link: https://lore.kernel.org/all/YXi5CUCEi7YmNxXM@robh.at.kernel.org/
Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Sean Anderson <sean.anderson@seco.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 drivers/reset/core.c             | 70 +++++++++++++++++++++++++++-----
 include/linux/reset-controller.h |  2 +
 2 files changed, 61 insertions(+), 11 deletions(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 4d5a78d3c085..a1f0f515a7e0 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -10,9 +10,12 @@
 #include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/kref.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/acpi.h>
+#include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/reset-controller.h>
 #include <linux/slab.h>
@@ -813,13 +816,59 @@ static void __reset_control_put_internal(struct reset_control *rstc)
 	kref_put(&rstc->refcnt, __reset_control_release);
 }
 
+static int __reset_add_reset_gpio_device(struct device_node *node,
+					 const struct gpio_desc **out)
+{
+	struct platform_device *pdev;
+	int gpio;
+
+	/* Don't care about deprecated '-gpio' suffix. */
+	gpio = of_get_named_gpio(node, "reset-gpios", 0);
+	if (!gpio_is_valid(gpio))
+		return gpio;
+
+	pdev = platform_device_register_data(NULL, "reset-gpio",
+					     PLATFORM_DEVID_AUTO, &node,
+					     sizeof(node));
+	if (!IS_ERR(pdev))
+		*out = gpio_to_desc(gpio);
+
+	return PTR_ERR_OR_ZERO(pdev);
+}
+
+static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_args *args,
+						       const void *cookie)
+{
+	struct reset_controller_dev *r, *rcdev;
+
+	lockdep_assert_held(&reset_list_mutex);
+
+	rcdev = NULL;
+	list_for_each_entry(r, &reset_controller_list, list) {
+		if (args && args->np) {
+			if (args->np == r->of_node) {
+				rcdev = r;
+				break;
+			}
+		} else if (cookie) {
+			if (cookie == r->cookie) {
+				rcdev = r;
+				break;
+			}
+		}
+	}
+
+	return rcdev;
+}
+
 struct reset_control *
 __of_reset_control_get(struct device_node *node, const char *id, int index,
 		       bool shared, bool optional, bool acquired)
 {
+	const struct gpio_desc *gpio = NULL;
+	struct of_phandle_args args = {0};
 	struct reset_control *rstc;
-	struct reset_controller_dev *r, *rcdev;
-	struct of_phandle_args args;
+	struct reset_controller_dev *rcdev;
 	int rstc_id;
 	int ret;
 
@@ -839,17 +888,16 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
 					 index, &args);
 	if (ret == -EINVAL)
 		return ERR_PTR(ret);
-	if (ret)
-		return optional ? NULL : ERR_PTR(ret);
+	if (ret) {
+		ret = __reset_add_reset_gpio_device(node, &gpio);
+		if (ret)
+			return optional ? NULL : ERR_PTR(ret);
+
+		args.args_count = 1; /* reset-gpio has only one reset line */
+	}
 
 	mutex_lock(&reset_list_mutex);
-	rcdev = NULL;
-	list_for_each_entry(r, &reset_controller_list, list) {
-		if (args.np == r->of_node) {
-			rcdev = r;
-			break;
-		}
-	}
+	rcdev = __reset_find_rcdev(&args, gpio);
 
 	if (!rcdev) {
 		rstc = ERR_PTR(-EPROBE_DEFER);
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index 0fa4f60e1186..c0a99a8ea29e 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -61,6 +61,7 @@ struct reset_control_lookup {
  * @dev: corresponding driver model device struct
  * @of_node: corresponding device tree node as phandle target
  * @of_reset_n_cells: number of cells in reset line specifiers
+ * @cookie: for reset-gpios controllers: corresponding GPIO instead of of_node
  * @of_xlate: translation function to translate from specifier as found in the
  *            device tree to id as given to the reset control ops, defaults
  *            to :c:func:`of_reset_simple_xlate`.
@@ -74,6 +75,7 @@ struct reset_controller_dev {
 	struct device *dev;
 	struct device_node *of_node;
 	int of_reset_n_cells;
+	const void *cookie;
 	int (*of_xlate)(struct reset_controller_dev *rcdev,
 			const struct of_phandle_args *reset_spec);
 	unsigned int nr_resets;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 2/4] reset: add GPIO-based reset controller
  2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
  2023-12-22 15:01 ` [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios Krzysztof Kozlowski
@ 2023-12-22 15:01 ` Krzysztof Kozlowski
  2023-12-22 15:08   ` Krzysztof Kozlowski
  2023-12-28 16:05   ` Sean Anderson
  2023-12-22 15:01 ` [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line Krzysztof Kozlowski
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Krzysztof Kozlowski, Bartosz Golaszewski, Sean Anderson

Add simple driver to control GPIO-based resets using the reset
controller API for the cases when the GPIOs are shared and reset should
be coordinated.  The driver is expected to be used by reset core
framework for ad-hoc reset controllers.

Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Sean Anderson <sean.anderson@seco.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 MAINTAINERS                |   5 ++
 drivers/reset/Kconfig      |   9 ++++
 drivers/reset/Makefile     |   1 +
 drivers/reset/reset-gpio.c | 105 +++++++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+)
 create mode 100644 drivers/reset/reset-gpio.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7fe27cd60e1b..a0fbd4814bc7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8866,6 +8866,11 @@ F:	Documentation/i2c/muxes/i2c-mux-gpio.rst
 F:	drivers/i2c/muxes/i2c-mux-gpio.c
 F:	include/linux/platform_data/i2c-mux-gpio.h
 
+GENERIC GPIO RESET DRIVER
+M:	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+S:	Maintained
+F:	drivers/reset/reset-gpio.c
+
 GENERIC HDLC (WAN) DRIVERS
 M:	Krzysztof Halasa <khc@pm.waw.pl>
 S:	Maintained
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index ccd59ddd7610..bb1b5a326eb7 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -66,6 +66,15 @@ config RESET_BRCMSTB_RESCAL
 	  This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on
 	  BCM7216.
 
+config RESET_GPIO
+	tristate "GPIO reset controller"
+	help
+	  This enables a generic reset controller for resets attached via
+	  GPIOs.  Typically for OF platforms this driver expects "reset-gpios"
+	  property.
+
+	  If compiled as module, it will be called reset-gpio.
+
 config RESET_HSDK
 	bool "Synopsys HSDK Reset Driver"
 	depends on HAS_IOMEM
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 8270da8a4baa..fd8b49fa46fc 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
 obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
 obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
+obj-$(CONFIG_RESET_GPIO) += reset-gpio.o
 obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
diff --git a/drivers/reset/reset-gpio.c b/drivers/reset/reset-gpio.c
new file mode 100644
index 000000000000..6952996dbc9f
--- /dev/null
+++ b/drivers/reset/reset-gpio.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+struct reset_gpio_priv {
+	struct reset_controller_dev rc;
+	struct gpio_desc *reset;
+};
+
+static inline struct reset_gpio_priv
+*rc_to_reset_gpio(struct reset_controller_dev *rc)
+{
+	return container_of(rc, struct reset_gpio_priv, rc);
+}
+
+static int reset_gpio_assert(struct reset_controller_dev *rc, unsigned long id)
+{
+	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
+
+	gpiod_set_value_cansleep(priv->reset, 1);
+
+	return 0;
+}
+
+static int reset_gpio_deassert(struct reset_controller_dev *rc,
+			       unsigned long id)
+{
+	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
+
+	gpiod_set_value_cansleep(priv->reset, 0);
+
+	return 0;
+}
+
+static int reset_gpio_status(struct reset_controller_dev *rc, unsigned long id)
+{
+	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
+
+	return gpiod_get_value_cansleep(priv->reset);
+}
+
+static const struct reset_control_ops reset_gpio_ops = {
+	.assert = reset_gpio_assert,
+	.deassert = reset_gpio_deassert,
+	.status = reset_gpio_status,
+};
+
+static int reset_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node **platdata = dev_get_platdata(dev);
+	struct reset_gpio_priv *priv;
+
+	if (!platdata && !*platdata)
+		return -EINVAL;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, &priv->rc);
+	device_set_node(dev, of_fwnode_handle(*platdata));
+
+	/*
+	 * Need to get non-exclusive because it is used in reset core as cookie
+	 * to find existing controllers.  However the actual use is exclusive.
+	 */
+	priv->reset = devm_gpiod_get(dev, "reset",
+				     GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->reset))
+		return dev_err_probe(dev, PTR_ERR(priv->reset),
+				     "Could not get reset gpios\n");
+
+	priv->rc.ops = &reset_gpio_ops;
+	priv->rc.owner = THIS_MODULE;
+	priv->rc.dev = dev;
+	priv->rc.cookie = priv->reset;
+	priv->rc.nr_resets = 1;
+
+	return devm_reset_controller_register(dev, &priv->rc);
+}
+
+static const struct platform_device_id reset_gpio_ids[] = {
+	{ .name = "reset-gpio", },
+	{}
+};
+MODULE_DEVICE_TABLE(platform, reset_gpio_ids);
+
+static struct platform_driver reset_gpio_driver = {
+	.probe		= reset_gpio_probe,
+	.id_table	= reset_gpio_ids,
+	.driver	= {
+		.name = "reset-gpio",
+	},
+};
+module_platform_driver(reset_gpio_driver);
+
+MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
+MODULE_DESCRIPTION("Generic GPIO reset driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line
  2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
  2023-12-22 15:01 ` [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios Krzysztof Kozlowski
  2023-12-22 15:01 ` [PATCH 2/4] reset: add GPIO-based reset controller Krzysztof Kozlowski
@ 2023-12-22 15:01 ` Krzysztof Kozlowski
  2023-12-22 15:16   ` Krzysztof Kozlowski
  2023-12-22 16:18   ` Rob Herring
  2023-12-22 15:01 ` [PATCH 4/4] ASoC: codecs: wsa884x: Allow sharing reset GPIO Krzysztof Kozlowski
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Krzysztof Kozlowski, Bartosz Golaszewski, Sean Anderson

On newer Qualcomm platforms, like X1E80100-CRD, the WSA884x speakers
share SD_N GPIOs between two speakers, thus a coordinated assertion is
needed.  Linux supports handling shared GPIO lines through "reset-gpios"
property, thus allow specifying either powerdown or reset GPIOs (these
are the same).

Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Sean Anderson <sean.anderson@seco.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

---

If previous patches are fine, then this commit is independent and could
be taken via ASoC.
---
 .../devicetree/bindings/sound/qcom,wsa8840.yaml          | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml b/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml
index d717017b0fdb..4b4bcbeba9c1 100644
--- a/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml
@@ -28,6 +28,10 @@ properties:
     description: Powerdown/Shutdown line to use (pin SD_N)
     maxItems: 1
 
+  reset-gpios:
+    description: Powerdown/Shutdown line to use (pin SD_N)
+    maxItems: 1
+
   '#sound-dai-cells':
     const: 0
 
@@ -37,11 +41,14 @@ properties:
 required:
   - compatible
   - reg
-  - powerdown-gpios
   - '#sound-dai-cells'
   - vdd-1p8-supply
   - vdd-io-supply
 
+oneOf:
+  - powerdown-gpios
+  - reset-gpios
+
 unevaluatedProperties: false
 
 examples:
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 4/4] ASoC: codecs: wsa884x: Allow sharing reset GPIO
  2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
                   ` (2 preceding siblings ...)
  2023-12-22 15:01 ` [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line Krzysztof Kozlowski
@ 2023-12-22 15:01 ` Krzysztof Kozlowski
  2023-12-22 15:22   ` Krzysztof Kozlowski
  2023-12-22 15:09 ` [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
  2023-12-22 15:18 ` Mark Brown
  5 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:01 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Krzysztof Kozlowski, Bartosz Golaszewski, Sean Anderson

On some boards with multiple WSA8840/WSA8845 speakers, the reset
(shutdown) GPIO is shared between two speakers.  Use the reset
controller framework and its "reset-gpio" driver to handle this case.
This allows bring-up and proper handling of all WSA884x speakers on
X1E80100-CRD board.

Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Sean Anderson <sean.anderson@seco.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

---

If previous patches are fine, then this commit is independent and could
be taken via ASoC.
---
 sound/soc/codecs/wsa884x.c | 52 ++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 10 deletions(-)

diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c
index f2653df84e4a..49ae7712e6ef 100644
--- a/sound/soc/codecs/wsa884x.c
+++ b/sound/soc/codecs/wsa884x.c
@@ -13,6 +13,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/soundwire/sdw.h>
 #include <linux/soundwire/sdw_registers.h>
@@ -699,6 +700,7 @@ struct wsa884x_priv {
 	struct sdw_stream_runtime *sruntime;
 	struct sdw_port_config port_config[WSA884X_MAX_SWR_PORTS];
 	struct gpio_desc *sd_n;
+	struct reset_control *sd_reset;
 	bool port_prepared[WSA884X_MAX_SWR_PORTS];
 	bool port_enable[WSA884X_MAX_SWR_PORTS];
 	unsigned int variant;
@@ -1799,9 +1801,22 @@ static struct snd_soc_dai_driver wsa884x_dais[] = {
 	},
 };
 
-static void wsa884x_gpio_powerdown(void *data)
+static void wsa884x_reset_powerdown(void *data)
 {
-	gpiod_direction_output(data, 1);
+	struct wsa884x_priv *wsa884x = data;
+
+	if (wsa884x->sd_reset)
+		reset_control_assert(wsa884x->sd_reset);
+	else
+		gpiod_direction_output(wsa884x->sd_n, 1);
+}
+
+static void wsa884x_reset_deassert(struct wsa884x_priv *wsa884x)
+{
+	if (wsa884x->sd_reset)
+		reset_control_deassert(wsa884x->sd_reset);
+	else
+		gpiod_direction_output(wsa884x->sd_n, 0);
 }
 
 static void wsa884x_regulator_disable(void *data)
@@ -1809,6 +1824,26 @@ static void wsa884x_regulator_disable(void *data)
 	regulator_bulk_disable(WSA884X_SUPPLIES_NUM, data);
 }
 
+static int wsa884x_get_reset(struct device *dev, struct wsa884x_priv *wsa884x)
+{
+	wsa884x->sd_reset = devm_reset_control_get_optional_shared(dev, NULL);
+	if (IS_ERR(wsa884x->sd_reset))
+		return dev_err_probe(dev, PTR_ERR(wsa884x->sd_reset),
+				     "Failed to get reset\n");
+
+	/*
+	 * Backwards compatible way for powerdown-gpios, does not handle
+	 * sharing GPIO properly.
+	 */
+	wsa884x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
+						GPIOD_OUT_HIGH);
+	if (IS_ERR(wsa884x->sd_n))
+		return dev_err_probe(dev, PTR_ERR(wsa884x->sd_n),
+				     "Shutdown Control GPIO not found\n");
+
+	return 0;
+}
+
 static int wsa884x_probe(struct sdw_slave *pdev,
 			 const struct sdw_device_id *id)
 {
@@ -1838,11 +1873,9 @@ static int wsa884x_probe(struct sdw_slave *pdev,
 	if (ret)
 		return ret;
 
-	wsa884x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
-						GPIOD_OUT_HIGH);
-	if (IS_ERR(wsa884x->sd_n))
-		return dev_err_probe(dev, PTR_ERR(wsa884x->sd_n),
-				     "Shutdown Control GPIO not found\n");
+	ret = wsa884x_get_reset(dev, wsa884x);
+	if (ret)
+		return ret;
 
 	dev_set_drvdata(dev, wsa884x);
 	wsa884x->slave = pdev;
@@ -1858,9 +1891,8 @@ static int wsa884x_probe(struct sdw_slave *pdev,
 	pdev->prop.sink_dpn_prop = wsa884x_sink_dpn_prop;
 	pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
 
-	/* Bring out of reset */
-	gpiod_direction_output(wsa884x->sd_n, 0);
-	ret = devm_add_action_or_reset(dev, wsa884x_gpio_powerdown, wsa884x->sd_n);
+	wsa884x_reset_deassert(wsa884x);
+	ret = devm_add_action_or_reset(dev, wsa884x_reset_powerdown, wsa884x);
 	if (ret)
 		return ret;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2023-12-22 15:01 ` [PATCH 2/4] reset: add GPIO-based reset controller Krzysztof Kozlowski
@ 2023-12-22 15:08   ` Krzysztof Kozlowski
  2023-12-28 16:05   ` Sean Anderson
  1 sibling, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:08 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski, Sean Anderson

On 22/12/2023 16:01, Krzysztof Kozlowski wrote:
> Add simple driver to control GPIO-based resets using the reset
> controller API for the cases when the GPIOs are shared and reset should
> be coordinated.  The driver is expected to be used by reset core
> framework for ad-hoc reset controllers.

...

> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, &priv->rc);
> +	device_set_node(dev, of_fwnode_handle(*platdata));
> +
> +	/*
> +	 * Need to get non-exclusive because it is used in reset core as cookie
> +	 * to find existing controllers.  However the actual use is exclusive.
> +	 */

This comment is a left-over of my work-in-progress and it is not
accurate anymore. Exclusive GPIOs are not used, which should make
Bartosz happy!

I will remove it in v2.


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets
  2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
                   ` (3 preceding siblings ...)
  2023-12-22 15:01 ` [PATCH 4/4] ASoC: codecs: wsa884x: Allow sharing reset GPIO Krzysztof Kozlowski
@ 2023-12-22 15:09 ` Krzysztof Kozlowski
  2023-12-22 15:18 ` Mark Brown
  5 siblings, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:09 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Chris Packham, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel, Sean Anderson

On 22/12/2023 16:01, Krzysztof Kozlowski wrote:
> Hi,
> 
> We have at least few cases where hardware engineers decided to use one
> powerdown/shutdown/reset GPIO line for multiple devices:
> 

Bartosz,
Please kindly provide feedback whether my way of using "struct
gpio_desc" to compare cookies is acceptable.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line
  2023-12-22 15:01 ` [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line Krzysztof Kozlowski
@ 2023-12-22 15:16   ` Krzysztof Kozlowski
  2023-12-22 16:18   ` Rob Herring
  1 sibling, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:16 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski, Sean Anderson

On 22/12/2023 16:01, Krzysztof Kozlowski wrote:
> @@ -37,11 +41,14 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - powerdown-gpios
>    - '#sound-dai-cells'
>    - vdd-1p8-supply
>    - vdd-io-supply
>  
> +oneOf:
> +  - powerdown-gpios
> +  - reset-gpios

And this obviously was not tested, so Krzysztof:

It does not look like you tested the bindings, at least after quick
look. Please run `make dt_binding_check` (see
Documentation/devicetree/bindings/writing-schema.rst for instructions).
Maybe you need to update your dtschema and yamllint.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets
  2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
                   ` (4 preceding siblings ...)
  2023-12-22 15:09 ` [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
@ 2023-12-22 15:18 ` Mark Brown
  5 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2023-12-22 15:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Jaroslav Kysela, Takashi Iwai,
	linux-arm-msm, alsa-devel, linux-sound, devicetree, linux-kernel,
	Chris Packham, Bartosz Golaszewski, Sean Anderson

[-- Attachment #1: Type: text/plain, Size: 346 bytes --]

On Fri, Dec 22, 2023 at 04:01:29PM +0100, Krzysztof Kozlowski wrote:

> I try to solve my case, hopefuly Chris' (2), partially Sean's (4) and maybe
> Hectors (5), using Rob's suggestion:

Hector's case wasn't an actual reset, it was a runtime power control, so
I'm not sure it'll fit there but otherwise this looks OK from an ASoC
point of view.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/4] ASoC: codecs: wsa884x: Allow sharing reset GPIO
  2023-12-22 15:01 ` [PATCH 4/4] ASoC: codecs: wsa884x: Allow sharing reset GPIO Krzysztof Kozlowski
@ 2023-12-22 15:22   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-22 15:22 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski, Sean Anderson

On 22/12/2023 16:01, Krzysztof Kozlowski wrote:
>  
> +static int wsa884x_get_reset(struct device *dev, struct wsa884x_priv *wsa884x)
> +{
> +	wsa884x->sd_reset = devm_reset_control_get_optional_shared(dev, NULL);
> +	if (IS_ERR(wsa884x->sd_reset))
> +		return dev_err_probe(dev, PTR_ERR(wsa884x->sd_reset),
> +				     "Failed to get reset\n");
> +

When cleaning up the patchset I removed one piece too much. I should
have here:

if (wsa884x->sd_reset)
	return 0;


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line
  2023-12-22 15:01 ` [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line Krzysztof Kozlowski
  2023-12-22 15:16   ` Krzysztof Kozlowski
@ 2023-12-22 16:18   ` Rob Herring
  1 sibling, 0 replies; 26+ messages in thread
From: Rob Herring @ 2023-12-22 16:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-sound, Srinivas Kandagatla, Sean Anderson,
	Bartosz Golaszewski, Mark Brown, Konrad Dybcio, Conor Dooley,
	Takashi Iwai, alsa-devel, Banajit Goswami, Rob Herring,
	Bjorn Andersson, linux-kernel, linux-arm-msm, Liam Girdwood,
	devicetree, Krzysztof Kozlowski, Jaroslav Kysela, Philipp Zabel


On Fri, 22 Dec 2023 16:01:32 +0100, Krzysztof Kozlowski wrote:
> On newer Qualcomm platforms, like X1E80100-CRD, the WSA884x speakers
> share SD_N GPIOs between two speakers, thus a coordinated assertion is
> needed.  Linux supports handling shared GPIO lines through "reset-gpios"
> property, thus allow specifying either powerdown or reset GPIOs (these
> are the same).
> 
> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Sean Anderson <sean.anderson@seco.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> 
> ---
> 
> If previous patches are fine, then this commit is independent and could
> be taken via ASoC.
> ---
>  .../devicetree/bindings/sound/qcom,wsa8840.yaml          | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml: oneOf:0: 'powerdown-gpios' is not of type 'object', 'boolean'
	from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml: oneOf:1: 'reset-gpios' is not of type 'object', 'boolean'
	from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/sound/qcom,wsa8840.yaml: oneOf: ['powerdown-gpios', 'reset-gpios'] should not be valid under {'items': {'propertyNames': {'const': 'const'}, 'required': ['const']}}
	hint: Use 'enum' rather than 'oneOf' + 'const' entries
	from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
Traceback (most recent call last):
  File "/usr/local/bin/dt-validate", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 144, in main
    sg.check_dtb(filename)
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 89, in check_dtb
    self.check_subtree(dt, subtree, False, "/", "/", filename)
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 82, in check_subtree
    self.check_subtree(tree, value, disabled, name, fullname + name, filename)
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 82, in check_subtree
    self.check_subtree(tree, value, disabled, name, fullname + name, filename)
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 82, in check_subtree
    self.check_subtree(tree, value, disabled, name, fullname + name, filename)
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 77, in check_subtree
    self.check_node(tree, subtree, disabled, nodename, fullname, filename)
  File "/usr/local/lib/python3.11/dist-packages/dtschema/dtb_validate.py", line 33, in check_node
    for error in self.validator.iter_errors(node, filter=match_schema_file):
  File "/usr/local/lib/python3.11/dist-packages/dtschema/validator.py", line 403, in iter_errors
    for error in self.DtValidator(sch,
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/validators.py", line 288, in iter_errors
    for error in errors:
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/_validators.py", line 414, in if_
    yield from validator.descend(instance, then, schema_path="then")
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/validators.py", line 305, in descend
    for error in self.evolve(schema=schema).iter_errors(instance):
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/validators.py", line 288, in iter_errors
    for error in errors:
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/_validators.py", line 383, in oneOf
    errs = list(validator.descend(instance, subschema, schema_path=index))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/validators.py", line 305, in descend
    for error in self.evolve(schema=schema).iter_errors(instance):
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/validators.py", line 278, in iter_errors
    scope = id_of(_schema)
            ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/jsonschema/validators.py", line 101, in _id_of
    return schema.get("$id", "")
           ^^^^^^^^^^
AttributeError: 'str' object has no attribute 'get'

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20231222150133.732662-4-krzysztof.kozlowski@linaro.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios
  2023-12-22 15:01 ` [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios Krzysztof Kozlowski
@ 2023-12-22 17:31   ` Bartosz Golaszewski
  2023-12-27 12:35     ` Krzysztof Kozlowski
  0 siblings, 1 reply; 26+ messages in thread
From: Bartosz Golaszewski @ 2023-12-22 17:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel, Sean Anderson

On Fri, Dec 22, 2023 at 4:01 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> Devices sharing a reset GPIO could use the reset framework for
> coordinated handling of that shared GPIO line.  We have several cases of
> such needs, at least for Devicetree-based platforms.
>
> If Devicetree-based device requests a reset line which is missing but
> there is a reset-gpios property, instantiate a new "reset-gpio" platform
> device which will handle such reset line.  This allows seamless handling
> of such shared reset-gpios without need of changing Devicetree binding [1].
>
> The "reset-gpio" driver follows shortly.
>
> Link: https://lore.kernel.org/all/YXi5CUCEi7YmNxXM@robh.at.kernel.org/
> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Sean Anderson <sean.anderson@seco.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
>  drivers/reset/core.c             | 70 +++++++++++++++++++++++++++-----
>  include/linux/reset-controller.h |  2 +
>  2 files changed, 61 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/reset/core.c b/drivers/reset/core.c
> index 4d5a78d3c085..a1f0f515a7e0 100644
> --- a/drivers/reset/core.c
> +++ b/drivers/reset/core.c
> @@ -10,9 +10,12 @@
>  #include <linux/export.h>
>  #include <linux/kernel.h>
>  #include <linux/kref.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/of_gpio.h>
>  #include <linux/acpi.h>
> +#include <linux/platform_device.h>
>  #include <linux/reset.h>
>  #include <linux/reset-controller.h>
>  #include <linux/slab.h>
> @@ -813,13 +816,59 @@ static void __reset_control_put_internal(struct reset_control *rstc)
>         kref_put(&rstc->refcnt, __reset_control_release);
>  }
>
> +static int __reset_add_reset_gpio_device(struct device_node *node,
> +                                        const struct gpio_desc **out)
> +{
> +       struct platform_device *pdev;
> +       int gpio;
> +
> +       /* Don't care about deprecated '-gpio' suffix. */
> +       gpio = of_get_named_gpio(node, "reset-gpios", 0);

Sorry but NAK. This is a legacy API, we've managed to remove all of_
GPIO interfaces but this one. Please don't use it. Any function that
deals with the global GPIO numberspace is deprecated. See below how I
would approach it.

Side note: do we have any formal way of deprecating interfaces in the kernel?

> +       if (!gpio_is_valid(gpio))
> +               return gpio;
> +
> +       pdev = platform_device_register_data(NULL, "reset-gpio",
> +                                            PLATFORM_DEVID_AUTO, &node,
> +                                            sizeof(node));

You seem to make an assumption (in __reset_find_rcdev()) that this
device will get bound to its driver before this function returns.
There is no such guarantee. There are many situations where this may
not happen immediately (think loading the reset-gpio driver as a
module from the filesystem). You should set up a notifier callback on
the platform bus that will get invoked on bus events and wait for this
device's BUS_NOTIFY_BOUND_DRIVER event.

> +       if (!IS_ERR(pdev))
> +               *out = gpio_to_desc(gpio);
> +
> +       return PTR_ERR_OR_ZERO(pdev);
> +}
> +
> +static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_args *args,
> +                                                      const void *cookie)
> +{
> +       struct reset_controller_dev *r, *rcdev;
> +
> +       lockdep_assert_held(&reset_list_mutex);
> +
> +       rcdev = NULL;
> +       list_for_each_entry(r, &reset_controller_list, list) {
> +               if (args && args->np) {
> +                       if (args->np == r->of_node) {
> +                               rcdev = r;
> +                               break;
> +                       }
> +               } else if (cookie) {
> +                       if (cookie == r->cookie) {

As I said in private: there's no guarantee that the same GPIO
descriptor will always reference the same GPIO line. It happens to be
the case currently but it's an implementation detail.

> +                               rcdev = r;
> +                               break;
> +                       }
> +               }
> +       }
> +
> +       return rcdev;
> +}
> +
>  struct reset_control *
>  __of_reset_control_get(struct device_node *node, const char *id, int index,
>                        bool shared, bool optional, bool acquired)
>  {
> +       const struct gpio_desc *gpio = NULL;
> +       struct of_phandle_args args = {0};
>         struct reset_control *rstc;
> -       struct reset_controller_dev *r, *rcdev;
> -       struct of_phandle_args args;
> +       struct reset_controller_dev *rcdev;
>         int rstc_id;
>         int ret;
>
> @@ -839,17 +888,16 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
>                                          index, &args);
>         if (ret == -EINVAL)
>                 return ERR_PTR(ret);
> -       if (ret)
> -               return optional ? NULL : ERR_PTR(ret);
> +       if (ret) {
> +               ret = __reset_add_reset_gpio_device(node, &gpio);
> +               if (ret)
> +                       return optional ? NULL : ERR_PTR(ret);
> +
> +               args.args_count = 1; /* reset-gpio has only one reset line */
> +       }
>
>         mutex_lock(&reset_list_mutex);
> -       rcdev = NULL;
> -       list_for_each_entry(r, &reset_controller_list, list) {
> -               if (args.np == r->of_node) {
> -                       rcdev = r;
> -                       break;
> -               }
> -       }
> +       rcdev = __reset_find_rcdev(&args, gpio);
>
>         if (!rcdev) {
>                 rstc = ERR_PTR(-EPROBE_DEFER);
> diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
> index 0fa4f60e1186..c0a99a8ea29e 100644
> --- a/include/linux/reset-controller.h
> +++ b/include/linux/reset-controller.h
> @@ -61,6 +61,7 @@ struct reset_control_lookup {
>   * @dev: corresponding driver model device struct
>   * @of_node: corresponding device tree node as phandle target
>   * @of_reset_n_cells: number of cells in reset line specifiers
> + * @cookie: for reset-gpios controllers: corresponding GPIO instead of of_node
>   * @of_xlate: translation function to translate from specifier as found in the
>   *            device tree to id as given to the reset control ops, defaults
>   *            to :c:func:`of_reset_simple_xlate`.
> @@ -74,6 +75,7 @@ struct reset_controller_dev {
>         struct device *dev;
>         struct device_node *of_node;
>         int of_reset_n_cells;
> +       const void *cookie;
>         int (*of_xlate)(struct reset_controller_dev *rcdev,
>                         const struct of_phandle_args *reset_spec);
>         unsigned int nr_resets;
> --
> 2.34.1
>

I dislike this approach entirely. Here's what I would do:

In the reset core: parse the phandle of the reset-gpios property. Use
the resulting node with gpio_device_find_by_fwnode(). If the device is
not up yet, defer probe. You'll now have the GPIO device object.
Retrieve its label using gpio_device_get_label(). Now you should have
everything you need (the offset and flags of the GPIO you'll get from
__of_parse_phandle_with_args()) to set up the lookup tables. See
include/linux/gpio/machine.h. An example of that would be in:
bcm2835_spi_setup() in drivers/spi/spi-bcm2835.c.

Then with a lookup table in place, you instantiate your device and
it'll get its GPIO as it should. This is not ideal but much better
than the above.

Bartosz

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios
  2023-12-22 17:31   ` Bartosz Golaszewski
@ 2023-12-27 12:35     ` Krzysztof Kozlowski
  2023-12-27 19:13       ` Bartosz Golaszewski
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-27 12:35 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel, Sean Anderson

On 22/12/2023 18:31, Bartosz Golaszewski wrote:
>>
>> +static int __reset_add_reset_gpio_device(struct device_node *node,
>> +                                        const struct gpio_desc **out)
>> +{
>> +       struct platform_device *pdev;
>> +       int gpio;
>> +
>> +       /* Don't care about deprecated '-gpio' suffix. */
>> +       gpio = of_get_named_gpio(node, "reset-gpios", 0);
> 
> Sorry but NAK. This is a legacy API, we've managed to remove all of_

No worries, I expected problems with this patchset. I should have title
it RFC.

> GPIO interfaces but this one. Please don't use it. Any function that
> deals with the global GPIO numberspace is deprecated. See below how I
> would approach it.
> 
> Side note: do we have any formal way of deprecating interfaces in the kernel?

"DEPRECATED" message in kerneldoc would be enough for me. This could be
later used by tooling like checkpatch/sparse/toolchains.


> 
>> +       if (!gpio_is_valid(gpio))
>> +               return gpio;
>> +
>> +       pdev = platform_device_register_data(NULL, "reset-gpio",
>> +                                            PLATFORM_DEVID_AUTO, &node,
>> +                                            sizeof(node));
> 
> You seem to make an assumption (in __reset_find_rcdev()) that this
> device will get bound to its driver before this function returns.
> There is no such guarantee. There are many situations where this may
> not happen immediately (think loading the reset-gpio driver as a
> module from the filesystem). You should set up a notifier callback on

Yeah, this code is poor. In the case you mentioned, requesting a reset
line would spawn multiple platform devices of which none would bind.

> the platform bus that will get invoked on bus events and wait for this
> device's BUS_NOTIFY_BOUND_DRIVER event.

Hm, good point. Thanks.


> 
>> +       if (!IS_ERR(pdev))
>> +               *out = gpio_to_desc(gpio);
>> +
>> +       return PTR_ERR_OR_ZERO(pdev);
>> +}
>> +
>> +static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_args *args,
>> +                                                      const void *cookie)
>> +{
>> +       struct reset_controller_dev *r, *rcdev;
>> +
>> +       lockdep_assert_held(&reset_list_mutex);
>> +
>> +       rcdev = NULL;
>> +       list_for_each_entry(r, &reset_controller_list, list) {
>> +               if (args && args->np) {
>> +                       if (args->np == r->of_node) {
>> +                               rcdev = r;
>> +                               break;
>> +                       }
>> +               } else if (cookie) {
>> +                       if (cookie == r->cookie) {
> 
> As I said in private: there's no guarantee that the same GPIO
> descriptor will always reference the same GPIO line. It happens to be
> the case currently but it's an implementation detail.

I guess you commented on this further, so I will reply there.

> 
>> +                               rcdev = r;
>> +                               break;
>> +                       }
>> +               }
>> +       }
>> +
>> +       return rcdev;
>> +}
>> +
>>  struct reset_control *
>>  __of_reset_control_get(struct device_node *node, const char *id, int index,
>>                        bool shared, bool optional, bool acquired)
>>  {
>> +       const struct gpio_desc *gpio = NULL;
>> +       struct of_phandle_args args = {0};
>>         struct reset_control *rstc;
>> -       struct reset_controller_dev *r, *rcdev;
>> -       struct of_phandle_args args;
>> +       struct reset_controller_dev *rcdev;
>>         int rstc_id;
>>         int ret;
>>
>> @@ -839,17 +888,16 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
>>                                          index, &args);
>>         if (ret == -EINVAL)
>>                 return ERR_PTR(ret);
>> -       if (ret)
>> -               return optional ? NULL : ERR_PTR(ret);
>> +       if (ret) {
>> +               ret = __reset_add_reset_gpio_device(node, &gpio);
>> +               if (ret)
>> +                       return optional ? NULL : ERR_PTR(ret);
>> +
>> +               args.args_count = 1; /* reset-gpio has only one reset line */
>> +       }
>>
>>         mutex_lock(&reset_list_mutex);
>> -       rcdev = NULL;
>> -       list_for_each_entry(r, &reset_controller_list, list) {
>> -               if (args.np == r->of_node) {
>> -                       rcdev = r;
>> -                       break;
>> -               }
>> -       }
>> +       rcdev = __reset_find_rcdev(&args, gpio);
>>
>>         if (!rcdev) {
>>                 rstc = ERR_PTR(-EPROBE_DEFER);
>> diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
>> index 0fa4f60e1186..c0a99a8ea29e 100644
>> --- a/include/linux/reset-controller.h
>> +++ b/include/linux/reset-controller.h
>> @@ -61,6 +61,7 @@ struct reset_control_lookup {
>>   * @dev: corresponding driver model device struct
>>   * @of_node: corresponding device tree node as phandle target
>>   * @of_reset_n_cells: number of cells in reset line specifiers
>> + * @cookie: for reset-gpios controllers: corresponding GPIO instead of of_node
>>   * @of_xlate: translation function to translate from specifier as found in the
>>   *            device tree to id as given to the reset control ops, defaults
>>   *            to :c:func:`of_reset_simple_xlate`.
>> @@ -74,6 +75,7 @@ struct reset_controller_dev {
>>         struct device *dev;
>>         struct device_node *of_node;
>>         int of_reset_n_cells;
>> +       const void *cookie;
>>         int (*of_xlate)(struct reset_controller_dev *rcdev,
>>                         const struct of_phandle_args *reset_spec);
>>         unsigned int nr_resets;
>> --
>> 2.34.1
>>
> 
> I dislike this approach entirely. Here's what I would do:
> 
> In the reset core: parse the phandle of the reset-gpios property. Use
> the resulting node with gpio_device_find_by_fwnode(). If the device is
> not up yet, defer probe. You'll now have the GPIO device object.
> Retrieve its label using gpio_device_get_label(). Now you should have
> everything you need (the offset and flags of the GPIO you'll get from
> __of_parse_phandle_with_args()) to set up the lookup tables. See

I don't get exactly what do you want to use as the cookie for lookup
reset controller?
1. GPIO controller node? No way, not enough
2. GPIO label?
3. Or some combination of above? This would work, I guess, a bit more
complicated cookie than just one pointer/unsigned long.

> include/linux/gpio/machine.h. An example of that would be in:
> bcm2835_spi_setup() in drivers/spi/spi-bcm2835.c.
> 
> Then with a lookup table in place, you instantiate your device and
> it'll get its GPIO as it should. This is not ideal but much better
> than the above.


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios
  2023-12-27 12:35     ` Krzysztof Kozlowski
@ 2023-12-27 19:13       ` Bartosz Golaszewski
  0 siblings, 0 replies; 26+ messages in thread
From: Bartosz Golaszewski @ 2023-12-27 19:13 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Bjorn Andersson, Konrad Dybcio, Srinivas Kandagatla,
	Banajit Goswami, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel, Sean Anderson

On Wed, Dec 27, 2023 at 1:35 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>

[snip]

> >
> > I dislike this approach entirely. Here's what I would do:
> >
> > In the reset core: parse the phandle of the reset-gpios property. Use
> > the resulting node with gpio_device_find_by_fwnode(). If the device is
> > not up yet, defer probe. You'll now have the GPIO device object.
> > Retrieve its label using gpio_device_get_label(). Now you should have
> > everything you need (the offset and flags of the GPIO you'll get from
> > __of_parse_phandle_with_args()) to set up the lookup tables. See
>
> I don't get exactly what do you want to use as the cookie for lookup
> reset controller?

I'm not sure what you refer to as "cookie". :(

> 1. GPIO controller node? No way, not enough
> 2. GPIO label?
> 3. Or some combination of above? This would work, I guess, a bit more
> complicated cookie than just one pointer/unsigned long.
>

For a GPIO lookup you need:

1. The name of the target device (in your case "reset-gpio.X", you can
either keep track of device IDs yourself or live with the fact that
you may have one deferred probe between when the device is registered
and bound and when you are able to read its final name for the
lookup).
2. The label of the GPIO chip (whatever gpio_device_get_label() returns).
3. The hardware offset of the pin (which you can get by parsing the phandle).

You may need additional lookup flags but the above allows you to
correctly assign a GPIO to a device. No need for cookies.

Bart

> > include/linux/gpio/machine.h. An example of that would be in:
> > bcm2835_spi_setup() in drivers/spi/spi-bcm2835.c.
> >
> > Then with a lookup table in place, you instantiate your device and
> > it'll get its GPIO as it should. This is not ideal but much better
> > than the above.
>
>
> Best regards,
> Krzysztof
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2023-12-22 15:01 ` [PATCH 2/4] reset: add GPIO-based reset controller Krzysztof Kozlowski
  2023-12-22 15:08   ` Krzysztof Kozlowski
@ 2023-12-28 16:05   ` Sean Anderson
  2024-01-04  8:57     ` Krzysztof Kozlowski
  1 sibling, 1 reply; 26+ messages in thread
From: Sean Anderson @ 2023-12-28 16:05 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 12/22/23 10:01, Krzysztof Kozlowski wrote:
> Add simple driver to control GPIO-based resets using the reset
> controller API for the cases when the GPIOs are shared and reset should
> be coordinated.  The driver is expected to be used by reset core
> framework for ad-hoc reset controllers.

How do we handle power sequencing? Often GPIOs need some pre/post delay in
order to ensure proper power sequencing. For regular reset drivers, this is
internal to the driver.

Maybe something like

my-device {
	reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
        reset-gpios-post-deassert-us = <100>;
};

Of course, this is a bit ambiguous if you have multiple devices using the same
GPIO with different delays. Maybe we take the max? But the driver below seems
to only have access to one device. Which I suppose begs the question: how do
we know when it's safe to deassert the reset (e.g. we've gotten to the point
where all devices using this reset gpio have gotten far enough to detect that
they use it)?

--Sean

> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Sean Anderson <sean.anderson@seco.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
>  MAINTAINERS                |   5 ++
>  drivers/reset/Kconfig      |   9 ++++
>  drivers/reset/Makefile     |   1 +
>  drivers/reset/reset-gpio.c | 105 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 120 insertions(+)
>  create mode 100644 drivers/reset/reset-gpio.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7fe27cd60e1b..a0fbd4814bc7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8866,6 +8866,11 @@ F:	Documentation/i2c/muxes/i2c-mux-gpio.rst
>  F:	drivers/i2c/muxes/i2c-mux-gpio.c
>  F:	include/linux/platform_data/i2c-mux-gpio.h
>  
> +GENERIC GPIO RESET DRIVER
> +M:	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> +S:	Maintained
> +F:	drivers/reset/reset-gpio.c
> +
>  GENERIC HDLC (WAN) DRIVERS
>  M:	Krzysztof Halasa <khc@pm.waw.pl>
>  S:	Maintained
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index ccd59ddd7610..bb1b5a326eb7 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -66,6 +66,15 @@ config RESET_BRCMSTB_RESCAL
>  	  This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on
>  	  BCM7216.
>  
> +config RESET_GPIO
> +	tristate "GPIO reset controller"
> +	help
> +	  This enables a generic reset controller for resets attached via
> +	  GPIOs.  Typically for OF platforms this driver expects "reset-gpios"
> +	  property.
> +
> +	  If compiled as module, it will be called reset-gpio.
> +
>  config RESET_HSDK
>  	bool "Synopsys HSDK Reset Driver"
>  	depends on HAS_IOMEM
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 8270da8a4baa..fd8b49fa46fc 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
>  obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
>  obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
>  obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
> +obj-$(CONFIG_RESET_GPIO) += reset-gpio.o
>  obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
>  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
>  obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
> diff --git a/drivers/reset/reset-gpio.c b/drivers/reset/reset-gpio.c
> new file mode 100644
> index 000000000000..6952996dbc9f
> --- /dev/null
> +++ b/drivers/reset/reset-gpio.c
> @@ -0,0 +1,105 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +
> +struct reset_gpio_priv {
> +	struct reset_controller_dev rc;
> +	struct gpio_desc *reset;
> +};
> +
> +static inline struct reset_gpio_priv
> +*rc_to_reset_gpio(struct reset_controller_dev *rc)
> +{
> +	return container_of(rc, struct reset_gpio_priv, rc);
> +}
> +
> +static int reset_gpio_assert(struct reset_controller_dev *rc, unsigned long id)
> +{
> +	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
> +
> +	gpiod_set_value_cansleep(priv->reset, 1);
> +
> +	return 0;
> +}
> +
> +static int reset_gpio_deassert(struct reset_controller_dev *rc,
> +			       unsigned long id)
> +{
> +	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
> +
> +	gpiod_set_value_cansleep(priv->reset, 0);
> +
> +	return 0;
> +}
> +
> +static int reset_gpio_status(struct reset_controller_dev *rc, unsigned long id)
> +{
> +	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
> +
> +	return gpiod_get_value_cansleep(priv->reset);
> +}
> +
> +static const struct reset_control_ops reset_gpio_ops = {
> +	.assert = reset_gpio_assert,
> +	.deassert = reset_gpio_deassert,
> +	.status = reset_gpio_status,
> +};
> +
> +static int reset_gpio_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node **platdata = dev_get_platdata(dev);
> +	struct reset_gpio_priv *priv;
> +
> +	if (!platdata && !*platdata)
> +		return -EINVAL;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, &priv->rc);
> +	device_set_node(dev, of_fwnode_handle(*platdata));
> +
> +	/*
> +	 * Need to get non-exclusive because it is used in reset core as cookie
> +	 * to find existing controllers.  However the actual use is exclusive.
> +	 */
> +	priv->reset = devm_gpiod_get(dev, "reset",
> +				     GPIOD_OUT_HIGH);
> +	if (IS_ERR(priv->reset))
> +		return dev_err_probe(dev, PTR_ERR(priv->reset),
> +				     "Could not get reset gpios\n");
> +
> +	priv->rc.ops = &reset_gpio_ops;
> +	priv->rc.owner = THIS_MODULE;
> +	priv->rc.dev = dev;
> +	priv->rc.cookie = priv->reset;
> +	priv->rc.nr_resets = 1;
> +
> +	return devm_reset_controller_register(dev, &priv->rc);
> +}
> +
> +static const struct platform_device_id reset_gpio_ids[] = {
> +	{ .name = "reset-gpio", },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(platform, reset_gpio_ids);
> +
> +static struct platform_driver reset_gpio_driver = {
> +	.probe		= reset_gpio_probe,
> +	.id_table	= reset_gpio_ids,
> +	.driver	= {
> +		.name = "reset-gpio",
> +	},
> +};
> +module_platform_driver(reset_gpio_driver);
> +
> +MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
> +MODULE_DESCRIPTION("Generic GPIO reset driver");
> +MODULE_LICENSE("GPL");


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2023-12-28 16:05   ` Sean Anderson
@ 2024-01-04  8:57     ` Krzysztof Kozlowski
  2024-01-04 16:04       ` Sean Anderson
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2024-01-04  8:57 UTC (permalink / raw)
  To: Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 28/12/2023 17:05, Sean Anderson wrote:
> On 12/22/23 10:01, Krzysztof Kozlowski wrote:
>> Add simple driver to control GPIO-based resets using the reset
>> controller API for the cases when the GPIOs are shared and reset should
>> be coordinated.  The driver is expected to be used by reset core
>> framework for ad-hoc reset controllers.
> 
> How do we handle power sequencing? Often GPIOs need some pre/post delay in
> order to ensure proper power sequencing. For regular reset drivers, this is
> internal to the driver.

It's not part of this patchset. Power sequencing is an old topic and
generic solutions were failing, rejected, did not solve the problems,
etc (choose your reason).

Delays are device specific, so they go to drivers (depending on the
compatible). Complex power sequencing is way too much for simplified
reset-framework handling, so anyway it is expected you do it in your driver.


> 
> Maybe something like
> 
> my-device {
> 	reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
>         reset-gpios-post-deassert-us = <100>;

Feel free to add it later. This patchset, and actually all patches
should, solves one problem while allowing you to extend it later.

If there is a architectural problem in my approach not allowing you to
extend it later, then we should discuss it.

> };
> 
> Of course, this is a bit ambiguous if you have multiple devices using the same
> GPIO with different delays. Maybe we take the max? But the driver below seems
> to only have access to one device. Which I suppose begs the question: how do
> we know when it's safe to deassert the reset (e.g. we've gotten to the point
> where all devices using this reset gpio have gotten far enough to detect that
> they use it)?

The driver (reset consumer) knows when it is safe or not. You must
implement proper reset handling in your driver.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04  8:57     ` Krzysztof Kozlowski
@ 2024-01-04 16:04       ` Sean Anderson
  2024-01-04 16:08         ` Krzysztof Kozlowski
  2024-01-04 16:11         ` Krzysztof Kozlowski
  0 siblings, 2 replies; 26+ messages in thread
From: Sean Anderson @ 2024-01-04 16:04 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 1/4/24 03:57, Krzysztof Kozlowski wrote:
> On 28/12/2023 17:05, Sean Anderson wrote:
>> On 12/22/23 10:01, Krzysztof Kozlowski wrote:
>>> Add simple driver to control GPIO-based resets using the reset
>>> controller API for the cases when the GPIOs are shared and reset should
>>> be coordinated.  The driver is expected to be used by reset core
>>> framework for ad-hoc reset controllers.
>> 
>> How do we handle power sequencing? Often GPIOs need some pre/post delay in
>> order to ensure proper power sequencing. For regular reset drivers, this is
>> internal to the driver.
> 
> It's not part of this patchset. Power sequencing is an old topic and
> generic solutions were failing, rejected, did not solve the problems,
> etc (choose your reason).
> 
> Delays are device specific, so they go to drivers (depending on the
> compatible). Complex power sequencing is way too much for simplified
> reset-framework handling, so anyway it is expected you do it in your driver.

Well, the reason to bring it up is twofold:

- Traditionally, drivers expect the reset controller to handle all
  necessary delays. For example, reset-k210 includes a 10us delay
  between asserting and deasserting the reset. There's a similar thing
  in reset-imx7, and several other reset drivers.
- We would need to add custom assert/deassert delays to every driver
  using this interface. These are not always added, since any given
  device may require delays which can be inferred from its compatible.
  However, an integrated system may require delays to be different from
  what any individual device requires.

>> 
>> Maybe something like
>> 
>> my-device {
>> 	reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
>>         reset-gpios-post-deassert-us = <100>;
> 
> Feel free to add it later. This patchset, and actually all patches
> should, solves one problem while allowing you to extend it later.

Yes, but we should try to avoid creating problems for ourselves in the
future.

> If there is a architectural problem in my approach not allowing you to
> extend it later, then we should discuss it.

Well, I brought up just such an architectural issue below...

>> };
>> 
>> Of course, this is a bit ambiguous if you have multiple devices using the same
>> GPIO with different delays.

This is the most concerning one to me.

>> Maybe we take the max? But the driver below seems
>> to only have access to one device. Which I suppose begs the question: how do
>> we know when it's safe to deassert the reset (e.g. we've gotten to the point
>> where all devices using this reset gpio have gotten far enough to detect that
>> they use it)?
> 
> The driver (reset consumer) knows when it is safe or not. You must
> implement proper reset handling in your driver.

The driver has no idea whether it is safe or not. It just calls
reset_assert/deassert at the appropriate time, and the reset
framework/controller is supposed to coordinate things so e.g. the device
doesn't get reset multiple times as multiple drivers all probe.

--Sean

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04 16:04       ` Sean Anderson
@ 2024-01-04 16:08         ` Krzysztof Kozlowski
  2024-01-04 16:30           ` Sean Anderson
  2024-01-04 16:11         ` Krzysztof Kozlowski
  1 sibling, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2024-01-04 16:08 UTC (permalink / raw)
  To: Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 04/01/2024 17:04, Sean Anderson wrote:
> On 1/4/24 03:57, Krzysztof Kozlowski wrote:
>> On 28/12/2023 17:05, Sean Anderson wrote:
>>> On 12/22/23 10:01, Krzysztof Kozlowski wrote:
>>>> Add simple driver to control GPIO-based resets using the reset
>>>> controller API for the cases when the GPIOs are shared and reset should
>>>> be coordinated.  The driver is expected to be used by reset core
>>>> framework for ad-hoc reset controllers.
>>>
>>> How do we handle power sequencing? Often GPIOs need some pre/post delay in
>>> order to ensure proper power sequencing. For regular reset drivers, this is
>>> internal to the driver.
>>
>> It's not part of this patchset. Power sequencing is an old topic and
>> generic solutions were failing, rejected, did not solve the problems,
>> etc (choose your reason).
>>
>> Delays are device specific, so they go to drivers (depending on the
>> compatible). Complex power sequencing is way too much for simplified
>> reset-framework handling, so anyway it is expected you do it in your driver.
> 
> Well, the reason to bring it up is twofold:
> 
> - Traditionally, drivers expect the reset controller to handle all
>   necessary delays. For example, reset-k210 includes a 10us delay
>   between asserting and deasserting the reset. There's a similar thing
>   in reset-imx7, and several other reset drivers.
> - We would need to add custom assert/deassert delays to every driver
>   using this interface. These are not always added, since any given
>   device may require delays which can be inferred from its compatible.
>   However, an integrated system may require delays to be different from
>   what any individual device requires.
> 
>>>
>>> Maybe something like
>>>
>>> my-device {
>>> 	reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
>>>         reset-gpios-post-deassert-us = <100>;
>>
>> Feel free to add it later. This patchset, and actually all patches
>> should, solves one problem while allowing you to extend it later.
> 
> Yes, but we should try to avoid creating problems for ourselves in the
> future.
> 
>> If there is a architectural problem in my approach not allowing you to
>> extend it later, then we should discuss it.
> 
> Well, I brought up just such an architectural issue below...

Sorry, but where the issue? You did not present any arguments stating
that it is not possible to add your feature.

What is the problem to parse that property?

> 
>>> };
>>>
>>> Of course, this is a bit ambiguous if you have multiple devices using the same
>>> GPIO with different delays.
> 
> This is the most concerning one to me.
> 
>>> Maybe we take the max? But the driver below seems
>>> to only have access to one device. Which I suppose begs the question: how do
>>> we know when it's safe to deassert the reset (e.g. we've gotten to the point
>>> where all devices using this reset gpio have gotten far enough to detect that
>>> they use it)?
>>
>> The driver (reset consumer) knows when it is safe or not. You must
>> implement proper reset handling in your driver.
> 
> The driver has no idea whether it is safe or not. It just calls
> reset_assert/deassert at the appropriate time, and the reset
> framework/controller is supposed to coordinate things so e.g. the device
> doesn't get reset multiple times as multiple drivers all probe.


Sorry, then I don't get what you refer to. The driver calls deassert
when it is safe for it to do it, so the driver *knows*. Now, you claim
that driver does not know that... core also does not know, so no one knows.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04 16:04       ` Sean Anderson
  2024-01-04 16:08         ` Krzysztof Kozlowski
@ 2024-01-04 16:11         ` Krzysztof Kozlowski
  1 sibling, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2024-01-04 16:11 UTC (permalink / raw)
  To: Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 04/01/2024 17:04, Sean Anderson wrote:
> 
>>> Maybe we take the max? But the driver below seems
>>> to only have access to one device. Which I suppose begs the question: how do
>>> we know when it's safe to deassert the reset (e.g. we've gotten to the point
>>> where all devices using this reset gpio have gotten far enough to detect that
>>> they use it)?
>>
>> The driver (reset consumer) knows when it is safe or not. You must
>> implement proper reset handling in your driver.
> 
> The driver has no idea whether it is safe or not. It just calls
> reset_assert/deassert at the appropriate time, and the reset
> framework/controller is supposed to coordinate things so e.g. the device
> doesn't get reset multiple times as multiple drivers all probe.

Hm, wait, now maybe I understand your concern. Did you read the
patchset? This is for the coordinated, shared, non-exclusive reset by
design.  And as stated during previous discussions: that's the driver's
job to be sure it is called like that.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04 16:08         ` Krzysztof Kozlowski
@ 2024-01-04 16:30           ` Sean Anderson
  2024-01-04 19:08             ` Krzysztof Kozlowski
  0 siblings, 1 reply; 26+ messages in thread
From: Sean Anderson @ 2024-01-04 16:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 1/4/24 11:08, Krzysztof Kozlowski wrote:
> On 04/01/2024 17:04, Sean Anderson wrote:
>> On 1/4/24 03:57, Krzysztof Kozlowski wrote:
>>> On 28/12/2023 17:05, Sean Anderson wrote:
>>>> On 12/22/23 10:01, Krzysztof Kozlowski wrote:
>>>>> Add simple driver to control GPIO-based resets using the reset
>>>>> controller API for the cases when the GPIOs are shared and reset should
>>>>> be coordinated.  The driver is expected to be used by reset core
>>>>> framework for ad-hoc reset controllers.
>>>>
>>>> How do we handle power sequencing? Often GPIOs need some pre/post delay in
>>>> order to ensure proper power sequencing. For regular reset drivers, this is
>>>> internal to the driver.
>>>
>>> It's not part of this patchset. Power sequencing is an old topic and
>>> generic solutions were failing, rejected, did not solve the problems,
>>> etc (choose your reason).
>>>
>>> Delays are device specific, so they go to drivers (depending on the
>>> compatible). Complex power sequencing is way too much for simplified
>>> reset-framework handling, so anyway it is expected you do it in your driver.
>> 
>> Well, the reason to bring it up is twofold:
>> 
>> - Traditionally, drivers expect the reset controller to handle all
>>   necessary delays. For example, reset-k210 includes a 10us delay
>>   between asserting and deasserting the reset. There's a similar thing
>>   in reset-imx7, and several other reset drivers.
>> - We would need to add custom assert/deassert delays to every driver
>>   using this interface. These are not always added, since any given
>>   device may require delays which can be inferred from its compatible.
>>   However, an integrated system may require delays to be different from
>>   what any individual device requires.
>> 
>>>>
>>>> Maybe something like
>>>>
>>>> my-device {
>>>> 	reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
>>>>         reset-gpios-post-deassert-us = <100>;
>>>
>>> Feel free to add it later. This patchset, and actually all patches
>>> should, solves one problem while allowing you to extend it later.
>> 
>> Yes, but we should try to avoid creating problems for ourselves in the
>> future.
>> 
>>> If there is a architectural problem in my approach not allowing you to
>>> extend it later, then we should discuss it.
>> 
>> Well, I brought up just such an architectural issue below...
> 
> Sorry, but where the issue? You did not present any arguments stating
> that it is not possible to add your feature.
> 
> What is the problem to parse that property?
> 
>> 
>>>> };
>>>>
>>>> Of course, this is a bit ambiguous if you have multiple devices using the same
>>>> GPIO with different delays.
>> 
>> This is the most concerning one to me.
>> 
>>>> Maybe we take the max? But the driver below seems
>>>> to only have access to one device. Which I suppose begs the question: how do
>>>> we know when it's safe to deassert the reset (e.g. we've gotten to the point
>>>> where all devices using this reset gpio have gotten far enough to detect that
>>>> they use it)?
>>>
>>> The driver (reset consumer) knows when it is safe or not. You must
>>> implement proper reset handling in your driver.
>> 
>> The driver has no idea whether it is safe or not. It just calls
>> reset_assert/deassert at the appropriate time, and the reset
>> framework/controller is supposed to coordinate things so e.g. the device
>> doesn't get reset multiple times as multiple drivers all probe.
> 
> 
> Sorry, then I don't get what you refer to. The driver calls deassert
> when it is safe for it to do it, so the driver *knows*. Now, you claim
> that driver does not know that... core also does not know, so no one knows.

Yes! That is the problem with this design. Someone has to coordinate the
reset, and it can't be the driver. But the core also doesn't have enough
information. So no one can do it.

For example, say we want to share a reset GPIO between two devices. Each
device has the following constraints:

device post-assert delay post-deassert delay
====== ================= ===================
A                  500us                 1ms
B                    1ms               300us

If we leave things up to the drivers, then whoever probes first will get
to decide the reset sequence.

So if we choose the post-assert delay to be 1ms and the post-deassert
delay to be 1ms then everyone is happy. How can we make sure the reset
controller enforces this? Well, we can do the above thing and specify
something like

A {
    reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
    reset-gpios-post-assert-us = <1000>;
    reset-gpios-post-deassert-us = <1000>;
};

B {
    reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
};

But what if B gets probed first? Then we will have to also specify the
delays on B as well. I'm not a big fan of this because

- We have to specify (identical) delays in every consumer (instead of
  having a central place to put the delays)
- Having the delays depend on the probe order (if one of the consumers'
  delays don't match) will result in bugs for board maintainers. Maybe
  we should just warn in that case and that is enough?
- Actually, the same problem exists for reset-gpios (e.g. if one driver
  specifies ACTIVE_HIGH and another specifies ACTIVE_LOW).

Maybe the delays should go instead on the gpio controller? So something
like (taking inspiration from gpio-hog):

gpio {
	gpio-controller;
	#gpio-cells = <2>;

	my-reset {
		gpio-reset;
		gpio = <555 GPIO_ACTIVE_LOW>;
		post-assert-us = <1000>;
		post-deassert-us = <1000>;
	};
};

> Hm, wait, now maybe I understand your concern. Did you read the
> patchset? This is for the coordinated, shared, non-exclusive reset by
> design.  And as stated during previous discussions: that's the driver's
> job to be sure it is called like that.

Well, one of the major advantages of moving GPIO resets to a reset
controller is that the reset framework can coordinate things if we want.
This is a rather natural extension of this patchset IMO. Even if you are
not adding this functionality now, it is good not to make it difficult
for future work.

--Sean

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04 16:30           ` Sean Anderson
@ 2024-01-04 19:08             ` Krzysztof Kozlowski
  2024-01-05 14:31               ` Philipp Zabel
  2024-01-05 14:33               ` Mark Brown
  0 siblings, 2 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2024-01-04 19:08 UTC (permalink / raw)
  To: Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 04/01/2024 17:30, Sean Anderson wrote:
> On 1/4/24 11:08, Krzysztof Kozlowski wrote:
>> On 04/01/2024 17:04, Sean Anderson wrote:
>>> On 1/4/24 03:57, Krzysztof Kozlowski wrote:
>>>> On 28/12/2023 17:05, Sean Anderson wrote:
>>>>> On 12/22/23 10:01, Krzysztof Kozlowski wrote:
>>>>>> Add simple driver to control GPIO-based resets using the reset
>>>>>> controller API for the cases when the GPIOs are shared and reset should
>>>>>> be coordinated.  The driver is expected to be used by reset core
>>>>>> framework for ad-hoc reset controllers.
>>>>>
>>>>> How do we handle power sequencing? Often GPIOs need some pre/post delay in
>>>>> order to ensure proper power sequencing. For regular reset drivers, this is
>>>>> internal to the driver.
>>>>
>>>> It's not part of this patchset. Power sequencing is an old topic and
>>>> generic solutions were failing, rejected, did not solve the problems,
>>>> etc (choose your reason).
>>>>
>>>> Delays are device specific, so they go to drivers (depending on the
>>>> compatible). Complex power sequencing is way too much for simplified
>>>> reset-framework handling, so anyway it is expected you do it in your driver.
>>>
>>> Well, the reason to bring it up is twofold:
>>>
>>> - Traditionally, drivers expect the reset controller to handle all
>>>   necessary delays. For example, reset-k210 includes a 10us delay
>>>   between asserting and deasserting the reset. There's a similar thing
>>>   in reset-imx7, and several other reset drivers.
>>> - We would need to add custom assert/deassert delays to every driver
>>>   using this interface. These are not always added, since any given
>>>   device may require delays which can be inferred from its compatible.
>>>   However, an integrated system may require delays to be different from
>>>   what any individual device requires.
>>>
>>>>>
>>>>> Maybe something like
>>>>>
>>>>> my-device {
>>>>> 	reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
>>>>>         reset-gpios-post-deassert-us = <100>;
>>>>
>>>> Feel free to add it later. This patchset, and actually all patches
>>>> should, solves one problem while allowing you to extend it later.
>>>
>>> Yes, but we should try to avoid creating problems for ourselves in the
>>> future.
>>>
>>>> If there is a architectural problem in my approach not allowing you to
>>>> extend it later, then we should discuss it.
>>>
>>> Well, I brought up just such an architectural issue below...
>>
>> Sorry, but where the issue? You did not present any arguments stating
>> that it is not possible to add your feature.
>>
>> What is the problem to parse that property?
>>
>>>
>>>>> };
>>>>>
>>>>> Of course, this is a bit ambiguous if you have multiple devices using the same
>>>>> GPIO with different delays.
>>>
>>> This is the most concerning one to me.
>>>
>>>>> Maybe we take the max? But the driver below seems
>>>>> to only have access to one device. Which I suppose begs the question: how do
>>>>> we know when it's safe to deassert the reset (e.g. we've gotten to the point
>>>>> where all devices using this reset gpio have gotten far enough to detect that
>>>>> they use it)?
>>>>
>>>> The driver (reset consumer) knows when it is safe or not. You must
>>>> implement proper reset handling in your driver.
>>>
>>> The driver has no idea whether it is safe or not. It just calls
>>> reset_assert/deassert at the appropriate time, and the reset
>>> framework/controller is supposed to coordinate things so e.g. the device
>>> doesn't get reset multiple times as multiple drivers all probe.
>>
>>
>> Sorry, then I don't get what you refer to. The driver calls deassert
>> when it is safe for it to do it, so the driver *knows*. Now, you claim
>> that driver does not know that... core also does not know, so no one knows.
> 
> Yes! That is the problem with this design. Someone has to coordinate the
> reset, and it can't be the driver. But the core also doesn't have enough
> information. So no one can do it.

The point is that the driver coordinates.

> 
> For example, say we want to share a reset GPIO between two devices. Each
> device has the following constraints:
> 
> device post-assert delay post-deassert delay
> ====== ================= ===================
> A                  500us                 1ms
> B                    1ms               300us

And now imagine that these values are incompatible between them, so
using 1ms on device A is wrong - too long.

This is just not doable. You invented some imaginary case to prove that
hardware is broken.

Now, if we are back to realistic cases - use just the longest reset time.



> 
> If we leave things up to the drivers, then whoever probes first will get
> to decide the reset sequence.

In current design yes, but it's not a problem to change it. Where is the
limitation? Just read other values and update the reset time.

> 
> So if we choose the post-assert delay to be 1ms and the post-deassert
> delay to be 1ms then everyone is happy. How can we make sure the reset

No, not everyone is happy, if these values are incompatible. OTOH, if
they are compatible, just put same values to your DTS, because that's
the requirement of the reset line.

> controller enforces this? Well, we can do the above thing and specify
> something like
> 
> A {
>     reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
>     reset-gpios-post-assert-us = <1000>;
>     reset-gpios-post-deassert-us = <1000>;
> };
> 
> B {
>     reset-gpios = <&gpio 555 GPIO_ACTIVE_LOW>;
> };
> 
> But what if B gets probed first? Then we will have to also specify the
> delays on B as well. I'm not a big fan of this because

It's a shared reset line, thus the shared or global delays can be
described in every place. That's for DT correctness. Now from the driver
point of view, there is no problem to update the reset values after
probing A.

> 
> - We have to specify (identical) delays in every consumer (instead of
>   having a central place to put the delays)
> - Having the delays depend on the probe order (if one of the consumers'
>   delays don't match) will result in bugs for board maintainers. Maybe
>   we should just warn in that case and that is enough?

No, it does not depend. Just update the values.

> - Actually, the same problem exists for reset-gpios (e.g. if one driver
>   specifies ACTIVE_HIGH and another specifies ACTIVE_LOW).

No, actually this is handled. This is not a shared reset line and it
will not be handled. Second device probe should fail.

> 
> Maybe the delays should go instead on the gpio controller? So something
> like (taking inspiration from gpio-hog):

We talked about this for other patchsets and answer was no, that's not
the property of GPIO.

> 
> gpio {
> 	gpio-controller;
> 	#gpio-cells = <2>;
> 
> 	my-reset {
> 		gpio-reset;
> 		gpio = <555 GPIO_ACTIVE_LOW>;
> 		post-assert-us = <1000>;
> 		post-deassert-us = <1000>;
> 	};
> };
> 
>> Hm, wait, now maybe I understand your concern. Did you read the
>> patchset? This is for the coordinated, shared, non-exclusive reset by
>> design.  And as stated during previous discussions: that's the driver's
>> job to be sure it is called like that.
> 
> Well, one of the major advantages of moving GPIO resets to a reset
> controller is that the reset framework can coordinate things if we want.
> This is a rather natural extension of this patchset IMO. Even if you are
> not adding this functionality now, it is good not to make it difficult
> for future work.

And nothing is made here difficult. You want same delays on each
consumer? No problem in adding them, just few lines. You want
contradictory or inconsistent delays? A bit more code, but still nothing
here is blocked. You want totally random stuff because hardware is
broken? You might need to write dedicated reset controller for your case
because generic binding stops being generic for such cases.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04 19:08             ` Krzysztof Kozlowski
@ 2024-01-05 14:31               ` Philipp Zabel
  2024-01-09  9:41                 ` Krzysztof Kozlowski
  2024-01-05 14:33               ` Mark Brown
  1 sibling, 1 reply; 26+ messages in thread
From: Philipp Zabel @ 2024-01-05 14:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sean Anderson, Bjorn Andersson,
	Konrad Dybcio, Srinivas Kandagatla, Banajit Goswami,
	Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jaroslav Kysela, Takashi Iwai, linux-arm-msm,
	alsa-devel, linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On Do, 2024-01-04 at 20:08 +0100, Krzysztof Kozlowski wrote:
> On 04/01/2024 17:30, Sean Anderson wrote:
> > On 1/4/24 11:08, Krzysztof Kozlowski wrote:
> > > On 04/01/2024 17:04, Sean Anderson wrote:
> > > > On 1/4/24 03:57, Krzysztof Kozlowski wrote:
> > > > > The driver (reset consumer) knows when it is safe or not. You must
> > > > > implement proper reset handling in your driver.
> > > > 
> > > > The driver has no idea whether it is safe or not. It just calls
> > > > reset_assert/deassert at the appropriate time, and the reset
> > > > framework/controller is supposed to coordinate things so e.g. the device
> > > > doesn't get reset multiple times as multiple drivers all probe.
> > > 
> > > Sorry, then I don't get what you refer to. The driver calls deassert
> > > when it is safe for it to do it, so the driver *knows*. Now, you claim
> > > that driver does not know that... core also does not know, so no one knows.
> > 
> > Yes! That is the problem with this design. Someone has to coordinate the
> > reset, and it can't be the driver. But the core also doesn't have enough
> > information. So no one can do it.
> 
> The point is that the driver coordinates.

Currently the reset controller API supports two types of shared resets.
I hope distinguishing the two types and illustrating them helps the
discussion:

1) For devices that just require the reset to be deasserted while they
are active, and don't care otherwise, there is the clk-like behavior
described in [1].

  requested reset signal via reset_control_deassert/assert():
    device A: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
    device B: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺

  actual reset signal to both devices:
              ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺

In this scenario, there should be no delays in the reset controller
driver. reset_control_deassert() may return as soon as the physical
reset signal is deasserted [2]. Any post-deassert delays required by
the devices are handled in the device drivers, and they can be
different for each device. The devices have to be able to cope with a
(much) longer post-deassert delay than expected (e.g. device B in this
case). It is assumed that the reset signal is initially asserted.

The reset-gpio patchset supports this.

2) The second type is for devices that require a single reset pulse for
initialization, at any time before they become active. This is
described in [3].

  requested reset signal via reset_control_reset/rearm():
    device A: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
    device B: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽

  actual reset signal to both devices:
              ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽

Here the reset controller needs to know the delay between assertion and
deassertion - either baked into the hardware or as a delay call in the
.reset callback.

This is not supported by the reset-gpio patchset. It could be
implemented via a delay property in the device tree that would have to
be the same for all devices sharing the reset line, and by adding the
.reset callback to the reset controller driver. The only issue is that
the initial state of the reset line should be deasserted, and at
reset_control_get() time, when the reset-gpio controller is
instantiated, it is not yet known which type the driver will use.

Sharing a reset line between devices of different type is not
supported. Unfortunately, this will only fail at
reset_control_deassert() / reset_control_reset() time when the second
device tries to use the reset control in a different way than the
first.

[1] https://docs.kernel.org/driver-api/reset.html#assertion-and-deassertion
[2] https://docs.kernel.org/driver-api/reset.html#c.reset_control_deassert
[3] https://docs.kernel.org/driver-api/reset.html#triggering

> > For example, say we want to share a reset GPIO between two devices. Each
> > device has the following constraints:
> > 
> > device post-assert delay post-deassert delay
> > ====== ================= ===================
> > A                  500us                 1ms
> > B                    1ms               300us
> 
> And now imagine that these values are incompatible between them, so
> using 1ms on device A is wrong - too long.
> 
> This is just not doable. You invented some imaginary case to prove that
> hardware is broken.
> 
> Now, if we are back to realistic cases - use just the longest reset time.

Right. This all only works if no device has an upper bound to the
allowed delays on the shared reset line.

I interpret the post-assert delay to be the desired length of the reset
pulse between the rising edge and the falling edge in case 2) above,
since in case 1) a post-assert delay is not useful.

The post-deassert delays are not supposed to be handled by the reset
controller drivers at all, except where they are needed to reach the
deasserted state on the reset line. Reset drivers that do have post-
deassert delays in the .deassert callback might be bending the rules a
bit for convenience.

regards
Philipp



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-04 19:08             ` Krzysztof Kozlowski
  2024-01-05 14:31               ` Philipp Zabel
@ 2024-01-05 14:33               ` Mark Brown
  2024-01-06 15:32                 ` Krzysztof Kozlowski
  1 sibling, 1 reply; 26+ messages in thread
From: Mark Brown @ 2024-01-05 14:33 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 958 bytes --]

On Thu, Jan 04, 2024 at 08:08:50PM +0100, Krzysztof Kozlowski wrote:
> On 04/01/2024 17:30, Sean Anderson wrote:

> > device post-assert delay post-deassert delay
> > ====== ================= ===================
> > A                  500us                 1ms
> > B                    1ms               300us

...

> Now, if we are back to realistic cases - use just the longest reset time.

Isn't the main concern here that when one device probes we don't yet
know the times for the other devices?

> > If we leave things up to the drivers, then whoever probes first will get
> > to decide the reset sequence.

> In current design yes, but it's not a problem to change it. Where is the
> limitation? Just read other values and update the reset time.

We might have already done a reset by that time and earlier devices
might prevent later devices from resetting again.  It shouldn't be such
an issue for the post delay, but might be one for the pre delay.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-05 14:33               ` Mark Brown
@ 2024-01-06 15:32                 ` Krzysztof Kozlowski
  0 siblings, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2024-01-06 15:32 UTC (permalink / raw)
  To: Mark Brown
  Cc: Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, alsa-devel,
	linux-sound, devicetree, linux-kernel, Bartosz Golaszewski

On 05/01/2024 15:33, Mark Brown wrote:
> On Thu, Jan 04, 2024 at 08:08:50PM +0100, Krzysztof Kozlowski wrote:
>> On 04/01/2024 17:30, Sean Anderson wrote:
> 
>>> device post-assert delay post-deassert delay
>>> ====== ================= ===================
>>> A                  500us                 1ms
>>> B                    1ms               300us
> 
> ...
> 
>> Now, if we are back to realistic cases - use just the longest reset time.
> 
> Isn't the main concern here that when one device probes we don't yet
> know the times for the other devices?

You can never know when second device will appear. It might come from
modules, DTB overlay etc. If we want to satisfy all users, then we need
to wait till all users appear, which I think is not even possible,
considering runtime loaded overlays.

> 
>>> If we leave things up to the drivers, then whoever probes first will get
>>> to decide the reset sequence.
> 
>> In current design yes, but it's not a problem to change it. Where is the
>> limitation? Just read other values and update the reset time.
> 
> We might have already done a reset by that time and earlier devices
> might prevent later devices from resetting again.  It shouldn't be such
> an issue for the post delay, but might be one for the pre delay.

If the reset deassert (or assert, depending what's the default state) is
triggered in the probe, then it will happen with the probe of the first
device. If the delays of that reset are not suitable for the second -
not yet probed - then what do you propose? I have the answer: do not use
the simple, generic solution. The simple and generic solutions work for
simple and generic cases.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-05 14:31               ` Philipp Zabel
@ 2024-01-09  9:41                 ` Krzysztof Kozlowski
  2024-01-09 15:51                   ` Sean Anderson
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2024-01-09  9:41 UTC (permalink / raw)
  To: Philipp Zabel, Sean Anderson, Bjorn Andersson, Konrad Dybcio,
	Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
	Takashi Iwai, linux-arm-msm, alsa-devel, linux-sound, devicetree,
	linux-kernel
  Cc: Bartosz Golaszewski

On 05/01/2024 15:31, Philipp Zabel wrote:
>>>> Sorry, then I don't get what you refer to. The driver calls deassert
>>>> when it is safe for it to do it, so the driver *knows*. Now, you claim
>>>> that driver does not know that... core also does not know, so no one knows.
>>>
>>> Yes! That is the problem with this design. Someone has to coordinate the
>>> reset, and it can't be the driver. But the core also doesn't have enough
>>> information. So no one can do it.
>>
>> The point is that the driver coordinates.
> 
> Currently the reset controller API supports two types of shared resets.
> I hope distinguishing the two types and illustrating them helps the
> discussion:
> 
> 1) For devices that just require the reset to be deasserted while they
> are active, and don't care otherwise, there is the clk-like behavior
> described in [1].
> 
>   requested reset signal via reset_control_deassert/assert():
>     device A: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
>     device B: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
> 
>   actual reset signal to both devices:
>               ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
> 
> In this scenario, there should be no delays in the reset controller
> driver. reset_control_deassert() may return as soon as the physical
> reset signal is deasserted [2]. Any post-deassert delays required by
> the devices are handled in the device drivers, and they can be
> different for each device. The devices have to be able to cope with a
> (much) longer post-deassert delay than expected (e.g. device B in this
> case). It is assumed that the reset signal is initially asserted.
> 
> The reset-gpio patchset supports this.

Yep! :)

> 
> 2) The second type is for devices that require a single reset pulse for
> initialization, at any time before they become active. This is
> described in [3].
> 
>   requested reset signal via reset_control_reset/rearm():
>     device A: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
>     device B: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
> 
>   actual reset signal to both devices:
>               ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
> 
> Here the reset controller needs to know the delay between assertion and
> deassertion - either baked into the hardware or as a delay call in the
> .reset callback.
> 
> This is not supported by the reset-gpio patchset. It could be

Yep, as well.

> implemented via a delay property in the device tree that would have to
> be the same for all devices sharing the reset line, and by adding the

Or through dedicated node to which reset-gpio binds, just like in Sean's
code some years ago. Nothing stops achieving that, except of course
convincing Rob. The point is that although my design does not solve it,
it also does not prevent it in the future.

> .reset callback to the reset controller driver. The only issue is that
> the initial state of the reset line should be deasserted, and at
> reset_control_get() time, when the reset-gpio controller is
> instantiated, it is not yet known which type the driver will use.
> 
> Sharing a reset line between devices of different type is not
> supported. Unfortunately, this will only fail at
> reset_control_deassert() / reset_control_reset() time when the second
> device tries to use the reset control in a different way than the
> first.
> 
> [1] https://docs.kernel.org/driver-api/reset.html#assertion-and-deassertion
> [2] https://docs.kernel.org/driver-api/reset.html#c.reset_control_deassert
> [3] https://docs.kernel.org/driver-api/reset.html#triggering
> 
>>> For example, say we want to share a reset GPIO between two devices. Each
>>> device has the following constraints:
>>>
>>> device post-assert delay post-deassert delay
>>> ====== ================= ===================
>>> A                  500us                 1ms
>>> B                    1ms               300us
>>
>> And now imagine that these values are incompatible between them, so
>> using 1ms on device A is wrong - too long.
>>
>> This is just not doable. You invented some imaginary case to prove that
>> hardware is broken.
>>
>> Now, if we are back to realistic cases - use just the longest reset time.
> 
> Right. This all only works if no device has an upper bound to the
> allowed delays on the shared reset line.

If device had an upper bound, it would be quite a conflicting design,
tricky to implement. I don't think we should target such case with
generic solution.

> 
> I interpret the post-assert delay to be the desired length of the reset
> pulse between the rising edge and the falling edge in case 2) above,
> since in case 1) a post-assert delay is not useful.
> 
> The post-deassert delays are not supposed to be handled by the reset
> controller drivers at all, except where they are needed to reach the
> deasserted state on the reset line. Reset drivers that do have post-
> deassert delays in the .deassert callback might be bending the rules a
> bit for convenience.


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/4] reset: add GPIO-based reset controller
  2024-01-09  9:41                 ` Krzysztof Kozlowski
@ 2024-01-09 15:51                   ` Sean Anderson
  0 siblings, 0 replies; 26+ messages in thread
From: Sean Anderson @ 2024-01-09 15:51 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Philipp Zabel, Bjorn Andersson,
	Konrad Dybcio, Srinivas Kandagatla, Banajit Goswami,
	Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jaroslav Kysela, Takashi Iwai, linux-arm-msm,
	alsa-devel, linux-sound, devicetree, linux-kernel
  Cc: Bartosz Golaszewski

On 1/9/24 04:41, Krzysztof Kozlowski wrote:
> On 05/01/2024 15:31, Philipp Zabel wrote:
>>>>> Sorry, then I don't get what you refer to. The driver calls deassert
>>>>> when it is safe for it to do it, so the driver *knows*. Now, you claim
>>>>> that driver does not know that... core also does not know, so no one knows.
>>>>
>>>> Yes! That is the problem with this design. Someone has to coordinate the
>>>> reset, and it can't be the driver. But the core also doesn't have enough
>>>> information. So no one can do it.
>>>
>>> The point is that the driver coordinates.
>> 
>> Currently the reset controller API supports two types of shared resets.
>> I hope distinguishing the two types and illustrating them helps the
>> discussion:
>> 
>> 1) For devices that just require the reset to be deasserted while they
>> are active, and don't care otherwise, there is the clk-like behavior
>> described in [1].
>> 
>>   requested reset signal via reset_control_deassert/assert():
>>     device A: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
>>     device B: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
>> 
>>   actual reset signal to both devices:
>>               ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
>> 
>> In this scenario, there should be no delays in the reset controller
>> driver. reset_control_deassert() may return as soon as the physical
>> reset signal is deasserted [2]. Any post-deassert delays required by
>> the devices are handled in the device drivers, and they can be
>> different for each device. The devices have to be able to cope with a
>> (much) longer post-deassert delay than expected (e.g. device B in this
>> case). It is assumed that the reset signal is initially asserted.
>> 
>> The reset-gpio patchset supports this.
> 
> Yep! :)
> 
>> 
>> 2) The second type is for devices that require a single reset pulse for
>> initialization, at any time before they become active. This is
>> described in [3].
>> 
>>   requested reset signal via reset_control_reset/rearm():
>>     device A: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
>>     device B: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
>> 
>>   actual reset signal to both devices:
>>               ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
>> 
>> Here the reset controller needs to know the delay between assertion and
>> deassertion - either baked into the hardware or as a delay call in the
>> .reset callback.
>> 
>> This is not supported by the reset-gpio patchset. It could be
> 
> Yep, as well.
> 
>> implemented via a delay property in the device tree that would have to
>> be the same for all devices sharing the reset line, and by adding the
> 
> Or through dedicated node to which reset-gpio binds, just like in Sean's
> code some years ago. Nothing stops achieving that, except of course
> convincing Rob. The point is that although my design does not solve it,
> it also does not prevent it in the future.

Given this and

> If the reset deassert (or assert, depending what's the default state) is
> triggered in the probe, then it will happen with the probe of the first
> device. If the delays of that reset are not suitable for the second -
> not yet probed - then what do you propose? I have the answer: do not use
> the simple, generic solution. The simple and generic solutions work for
> simple and generic cases.

I think a separate pseudo-device is necessary a generic solution. So I
guess I will revive my patchset.

>> .reset callback to the reset controller driver. The only issue is that
>> the initial state of the reset line should be deasserted, and at
>> reset_control_get() time, when the reset-gpio controller is
>> instantiated, it is not yet known which type the driver will use.
>> 
>> Sharing a reset line between devices of different type is not
>> supported. Unfortunately, this will only fail at
>> reset_control_deassert() / reset_control_reset() time when the second
>> device tries to use the reset control in a different way than the
>> first.
>> 
>> [1] https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2fdocs.kernel.org%2fdriver%2dapi%2freset.html%23assertion%2dand%2ddeassertion&umid=0ba4c26a-9b7a-4e4b-8dba-ac7f2f194fcd&auth=d807158c60b7d2502abde8a2fc01f40662980862-4bd780a2a258eadb798324d4af563d691f01efb6
>> [2] https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2fdocs.kernel.org%2fdriver%2dapi%2freset.html%23c.reset%5fcontrol%5fdeassert&umid=0ba4c26a-9b7a-4e4b-8dba-ac7f2f194fcd&auth=d807158c60b7d2502abde8a2fc01f40662980862-d6349120c92e1887c5765842e10b274192584bde
>> [3] https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2fdocs.kernel.org%2fdriver%2dapi%2freset.html%23triggering&umid=0ba4c26a-9b7a-4e4b-8dba-ac7f2f194fcd&auth=d807158c60b7d2502abde8a2fc01f40662980862-973380c68f114aad02c47e69b5ceb92a23759963
>> 
>>>> For example, say we want to share a reset GPIO between two devices. Each
>>>> device has the following constraints:
>>>>
>>>> device post-assert delay post-deassert delay
>>>> ====== ================= ===================
>>>> A                  500us                 1ms
>>>> B                    1ms               300us
>>>
>>> And now imagine that these values are incompatible between them, so
>>> using 1ms on device A is wrong - too long.
>>>
>>> This is just not doable. You invented some imaginary case to prove that
>>> hardware is broken.
>>>
>>> Now, if we are back to realistic cases - use just the longest reset time.
>> 
>> Right. This all only works if no device has an upper bound to the
>> allowed delays on the shared reset line.
> 
> If device had an upper bound, it would be quite a conflicting design,
> tricky to implement. I don't think we should target such case with
> generic solution.

This is why I had explicit properties for the various durations. That
way the system integrator can go through the reset requirements
and specify something which satisfies all devices.

--Sean

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2024-01-09 15:51 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-22 15:01 [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
2023-12-22 15:01 ` [PATCH 1/4] reset: instantiate reset GPIO controller for shared reset-gpios Krzysztof Kozlowski
2023-12-22 17:31   ` Bartosz Golaszewski
2023-12-27 12:35     ` Krzysztof Kozlowski
2023-12-27 19:13       ` Bartosz Golaszewski
2023-12-22 15:01 ` [PATCH 2/4] reset: add GPIO-based reset controller Krzysztof Kozlowski
2023-12-22 15:08   ` Krzysztof Kozlowski
2023-12-28 16:05   ` Sean Anderson
2024-01-04  8:57     ` Krzysztof Kozlowski
2024-01-04 16:04       ` Sean Anderson
2024-01-04 16:08         ` Krzysztof Kozlowski
2024-01-04 16:30           ` Sean Anderson
2024-01-04 19:08             ` Krzysztof Kozlowski
2024-01-05 14:31               ` Philipp Zabel
2024-01-09  9:41                 ` Krzysztof Kozlowski
2024-01-09 15:51                   ` Sean Anderson
2024-01-05 14:33               ` Mark Brown
2024-01-06 15:32                 ` Krzysztof Kozlowski
2024-01-04 16:11         ` Krzysztof Kozlowski
2023-12-22 15:01 ` [PATCH 3/4] ASoC: dt-bindings: qcom,wsa8840: Add reset-gpios for shared line Krzysztof Kozlowski
2023-12-22 15:16   ` Krzysztof Kozlowski
2023-12-22 16:18   ` Rob Herring
2023-12-22 15:01 ` [PATCH 4/4] ASoC: codecs: wsa884x: Allow sharing reset GPIO Krzysztof Kozlowski
2023-12-22 15:22   ` Krzysztof Kozlowski
2023-12-22 15:09 ` [PATCH 0/4] reset: gpio: ASoC: shared GPIO resets Krzysztof Kozlowski
2023-12-22 15:18 ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.