2022-05-30 19:48:58

by Marco Felsch

[permalink] [raw]
Subject: [PATCH v2 1/2] dt-bindings: reset: Add TPS380x documentation

Add device-tree binding documentation for the tps380x reset driver. The
binding uses enum to make it easy to add more devices from that family.

Signed-off-by: Marco Felsch <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
---
Changelog:
v2:
- added Krzysztof rb

.../bindings/reset/ti,tps380x-reset.yaml | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/ti,tps380x-reset.yaml

diff --git a/Documentation/devicetree/bindings/reset/ti,tps380x-reset.yaml b/Documentation/devicetree/bindings/reset/ti,tps380x-reset.yaml
new file mode 100644
index 000000000000..afc835eda0ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/ti,tps380x-reset.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/ti,tps380x-reset.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI TPS380x reset controller node bindings
+
+maintainers:
+ - Marco Felsch <[email protected]>
+
+description: |
+ The TPS380x family [1] of supervisory circuits monitor supply voltages to
+ provide circuit initialization and timing supervision. The devices assert a
+ RESET signal if the voltage drops below a preset threshold or upon a manual
+ reset input (MR). The RESET output remains asserted for the factory
+ programmed delay after the voltage return above its threshold or after the
+ manual reset input is released.
+
+ [1] https://www.ti.com/product/TPS3801
+
+properties:
+ compatible:
+ enum:
+ - ti,tps3801
+
+ reset-gpios:
+ maxItems: 1
+ description: Reference to the GPIO connected to the MR pin.
+
+ "#reset-cells":
+ const: 0
+
+required:
+ - compatible
+ - reset-gpios
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ reset: reset-controller {
+ compatible = "ti,tps3801";
+ #reset-cells = <0>;
+ reset-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+ };
+...
--
2.30.2



2022-05-31 12:03:21

by Marco Felsch

[permalink] [raw]
Subject: [PATCH v2 2/2] reset: tps380x: Add TPS380x device driver supprt

The TI TPS380x family [1] is a voltage supervisor with a dedicated
manual reset (mr) line input and a reset output. The chip(s) have a
build in reset delay, depending on the chip partnumber. This simple
driver addresses this so the cosumer don't need to care about it.

[1] https://www.ti.com/product/TPS3801

Signed-off-by: Marco Felsch <[email protected]>
---
Changelog:
v2:
- make reset_tps380x_ops static
- fix commit message typo

drivers/reset/Kconfig | 8 +++
drivers/reset/Makefile | 1 +
drivers/reset/reset-tps380x.c | 130 ++++++++++++++++++++++++++++++++++
3 files changed, 139 insertions(+)
create mode 100644 drivers/reset/reset-tps380x.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index e0fc80e041ea..e2eb616af812 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -256,6 +256,14 @@ config RESET_TI_SYSCON
you wish to use the reset framework for such memory-mapped devices,
say Y here. Otherwise, say N.

+config RESET_TI_TPS380X
+ tristate "TI TPS380x Reset Driver"
+ select GPIOLIB
+ help
+ This enables the reset driver support for TI TPS380x devices. If
+ you wish to use the reset framework for such devices, say Y here.
+ Otherwise, say N.
+
config RESET_TN48M_CPLD
tristate "Delta Networks TN48M switch CPLD reset controller"
depends on MFD_TN48M_CPLD || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index a80a9c4008a7..66399b92b1bb 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
+obj-$(CONFIG_RESET_TI_TPS380X) += reset-tps380x.o
obj-$(CONFIG_RESET_TN48M_CPLD) += reset-tn48m.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
diff --git a/drivers/reset/reset-tps380x.c b/drivers/reset/reset-tps380x.c
new file mode 100644
index 000000000000..088158f54e6f
--- /dev/null
+++ b/drivers/reset/reset-tps380x.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * TI TPS380x Supply Voltage Supervisor and Reset Controller Driver
+ *
+ * Copyright (C) 2022 Pengutronix, Marco Felsch <[email protected]>
+ *
+ * Based on Simple Reset Controller Driver
+ *
+ * Copyright (C) 2017 Pengutronix, Philipp Zabel <[email protected]>
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/reset-controller.h>
+
+struct tps380x_reset {
+ struct reset_controller_dev rcdev;
+ struct gpio_desc *reset_gpio;
+ unsigned int reset_ms;
+};
+
+struct tps380x_reset_devdata {
+ unsigned int min_reset_ms;
+ unsigned int typ_reset_ms;
+ unsigned int max_reset_ms;
+};
+
+static inline
+struct tps380x_reset *to_tps380x_reset(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct tps380x_reset, rcdev);
+}
+
+static int
+tps380x_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct tps380x_reset *tps380x = to_tps380x_reset(rcdev);
+
+ gpiod_set_value_cansleep(tps380x->reset_gpio, 1);
+
+ return 0;
+}
+
+static int
+tps380x_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct tps380x_reset *tps380x = to_tps380x_reset(rcdev);
+
+ gpiod_set_value_cansleep(tps380x->reset_gpio, 0);
+ msleep(tps380x->reset_ms);
+
+ return 0;
+}
+
+static const struct reset_control_ops reset_tps380x_ops = {
+ .assert = tps380x_reset_assert,
+ .deassert = tps380x_reset_deassert,
+};
+
+static int tps380x_reset_of_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ /* No special handling needed, we have only one reset line per device */
+ return 0;
+}
+
+static int tps380x_reset_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct tps380x_reset_devdata *devdata;
+ struct tps380x_reset *tps380x;
+
+ devdata = device_get_match_data(dev);
+ if (!devdata)
+ return -EINVAL;
+
+ tps380x = devm_kzalloc(dev, sizeof(*tps380x), GFP_KERNEL);
+ if (!tps380x)
+ return -ENOMEM;
+
+ tps380x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(tps380x->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(tps380x->reset_gpio),
+ "Failed to get GPIO\n");
+
+ /*
+ * Todo:
+ * Add firmware handling to switch between min/typ/max reset time
+ */
+ tps380x->reset_ms = devdata->max_reset_ms;
+
+ tps380x->rcdev.ops = &reset_tps380x_ops;
+ tps380x->rcdev.owner = THIS_MODULE;
+ tps380x->rcdev.dev = dev;
+ tps380x->rcdev.of_node = dev->of_node;
+ tps380x->rcdev.of_reset_n_cells = 0;
+ tps380x->rcdev.of_xlate = tps380x_reset_of_xlate;
+ tps380x->rcdev.nr_resets = 1;
+
+ return devm_reset_controller_register(dev, &tps380x->rcdev);
+}
+
+static const struct tps380x_reset_devdata tps3801_reset_data = {
+ .min_reset_ms = 120,
+ .typ_reset_ms = 200,
+ .max_reset_ms = 280,
+};
+
+static const struct of_device_id tps380x_reset_dt_ids[] = {
+ { .compatible = "ti,tps3801", .data = &tps3801_reset_data },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tps380x_reset_dt_ids);
+
+static struct platform_driver tps380x_reset_driver = {
+ .probe = tps380x_reset_probe,
+ .driver = {
+ .name = "tps380x-reset",
+ .of_match_table = tps380x_reset_dt_ids,
+ },
+};
+module_platform_driver(tps380x_reset_driver);
+
+MODULE_AUTHOR("Marco Felsch <[email protected]>");
+MODULE_DESCRIPTION("TI TPS380x Supply Voltags Supervisor and Reset Driver");
+MODULE_LICENSE("GPL v2");
--
2.30.2


2022-07-26 08:57:39

by Marco Felsch

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] reset: tps380x: Add TPS380x device driver supprt

Hi Philipp,

gentle ping.

On 22-05-30, Marco Felsch wrote:
> The TI TPS380x family [1] is a voltage supervisor with a dedicated
> manual reset (mr) line input and a reset output. The chip(s) have a
> build in reset delay, depending on the chip partnumber. This simple
> driver addresses this so the cosumer don't need to care about it.
>
> [1] https://www.ti.com/product/TPS3801
>
> Signed-off-by: Marco Felsch <[email protected]>
> ---
> Changelog:
> v2:
> - make reset_tps380x_ops static
> - fix commit message typo
>
> drivers/reset/Kconfig | 8 +++
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-tps380x.c | 130 ++++++++++++++++++++++++++++++++++
> 3 files changed, 139 insertions(+)
> create mode 100644 drivers/reset/reset-tps380x.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index e0fc80e041ea..e2eb616af812 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -256,6 +256,14 @@ config RESET_TI_SYSCON
> you wish to use the reset framework for such memory-mapped devices,
> say Y here. Otherwise, say N.
>
> +config RESET_TI_TPS380X
> + tristate "TI TPS380x Reset Driver"
> + select GPIOLIB
> + help
> + This enables the reset driver support for TI TPS380x devices. If
> + you wish to use the reset framework for such devices, say Y here.
> + Otherwise, say N.
> +
> config RESET_TN48M_CPLD
> tristate "Delta Networks TN48M switch CPLD reset controller"
> depends on MFD_TN48M_CPLD || COMPILE_TEST
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index a80a9c4008a7..66399b92b1bb 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
> obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
> obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
> obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
> +obj-$(CONFIG_RESET_TI_TPS380X) += reset-tps380x.o
> obj-$(CONFIG_RESET_TN48M_CPLD) += reset-tn48m.o
> obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
> obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
> diff --git a/drivers/reset/reset-tps380x.c b/drivers/reset/reset-tps380x.c
> new file mode 100644
> index 000000000000..088158f54e6f
> --- /dev/null
> +++ b/drivers/reset/reset-tps380x.c
> @@ -0,0 +1,130 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * TI TPS380x Supply Voltage Supervisor and Reset Controller Driver
> + *
> + * Copyright (C) 2022 Pengutronix, Marco Felsch <[email protected]>
> + *
> + * Based on Simple Reset Controller Driver
> + *
> + * Copyright (C) 2017 Pengutronix, Philipp Zabel <[email protected]>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/reset-controller.h>
> +
> +struct tps380x_reset {
> + struct reset_controller_dev rcdev;
> + struct gpio_desc *reset_gpio;
> + unsigned int reset_ms;
> +};
> +
> +struct tps380x_reset_devdata {
> + unsigned int min_reset_ms;
> + unsigned int typ_reset_ms;
> + unsigned int max_reset_ms;
> +};
> +
> +static inline
> +struct tps380x_reset *to_tps380x_reset(struct reset_controller_dev *rcdev)
> +{
> + return container_of(rcdev, struct tps380x_reset, rcdev);
> +}
> +
> +static int
> +tps380x_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + struct tps380x_reset *tps380x = to_tps380x_reset(rcdev);
> +
> + gpiod_set_value_cansleep(tps380x->reset_gpio, 1);
> +
> + return 0;
> +}
> +
> +static int
> +tps380x_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + struct tps380x_reset *tps380x = to_tps380x_reset(rcdev);
> +
> + gpiod_set_value_cansleep(tps380x->reset_gpio, 0);
> + msleep(tps380x->reset_ms);
> +
> + return 0;
> +}
> +
> +static const struct reset_control_ops reset_tps380x_ops = {
> + .assert = tps380x_reset_assert,
> + .deassert = tps380x_reset_deassert,
> +};
> +
> +static int tps380x_reset_of_xlate(struct reset_controller_dev *rcdev,
> + const struct of_phandle_args *reset_spec)
> +{
> + /* No special handling needed, we have only one reset line per device */
> + return 0;
> +}
> +
> +static int tps380x_reset_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + const struct tps380x_reset_devdata *devdata;
> + struct tps380x_reset *tps380x;
> +
> + devdata = device_get_match_data(dev);
> + if (!devdata)
> + return -EINVAL;
> +
> + tps380x = devm_kzalloc(dev, sizeof(*tps380x), GFP_KERNEL);
> + if (!tps380x)
> + return -ENOMEM;
> +
> + tps380x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
> + if (IS_ERR(tps380x->reset_gpio))
> + return dev_err_probe(dev, PTR_ERR(tps380x->reset_gpio),
> + "Failed to get GPIO\n");
> +
> + /*
> + * Todo:
> + * Add firmware handling to switch between min/typ/max reset time
> + */
> + tps380x->reset_ms = devdata->max_reset_ms;
> +
> + tps380x->rcdev.ops = &reset_tps380x_ops;
> + tps380x->rcdev.owner = THIS_MODULE;
> + tps380x->rcdev.dev = dev;
> + tps380x->rcdev.of_node = dev->of_node;
> + tps380x->rcdev.of_reset_n_cells = 0;
> + tps380x->rcdev.of_xlate = tps380x_reset_of_xlate;
> + tps380x->rcdev.nr_resets = 1;
> +
> + return devm_reset_controller_register(dev, &tps380x->rcdev);
> +}
> +
> +static const struct tps380x_reset_devdata tps3801_reset_data = {
> + .min_reset_ms = 120,
> + .typ_reset_ms = 200,
> + .max_reset_ms = 280,
> +};
> +
> +static const struct of_device_id tps380x_reset_dt_ids[] = {
> + { .compatible = "ti,tps3801", .data = &tps3801_reset_data },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, tps380x_reset_dt_ids);
> +
> +static struct platform_driver tps380x_reset_driver = {
> + .probe = tps380x_reset_probe,
> + .driver = {
> + .name = "tps380x-reset",
> + .of_match_table = tps380x_reset_dt_ids,
> + },
> +};
> +module_platform_driver(tps380x_reset_driver);
> +
> +MODULE_AUTHOR("Marco Felsch <[email protected]>");
> +MODULE_DESCRIPTION("TI TPS380x Supply Voltags Supervisor and Reset Driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.30.2
>
>

2022-07-27 09:42:33

by Philipp Zabel

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] reset: tps380x: Add TPS380x device driver supprt

Hi Marco,

On Di, 2022-07-26 at 10:45 +0200, Marco Felsch wrote:
> Hi Philipp,
>
> gentle ping.

Applied to reset/next.

I've taken liberty to remove the TODO comment, see below:

> On 22-05-30, Marco Felsch wrote:
[...]
> > + /*
> > + * Todo:
> > + * Add firmware handling to switch between min/typ/max reset time
> > + */

I've dropped this because I think waiting for max reset time is the
only way to guarantee correctness, if we expect that tps3801 delay
times actually vary between min and max reset time (whether that is due
to production variance or temperature sensitivity).

If a board vendor can guarantee that the actual max delay on a given
board is less than the specified max reset time, this could be handled
via an optional device tree parameter to overrride the delay.

regards
Philipp
>