Message ID | 20220530092226.748644-1-m.felsch@pengutronix.de |
---|---|
State | Accepted |
Commit | 729a8a57355f12d9ecba150fbef693e51b99e7ec |
Headers | show |
Series | [v2,1/2] dt-bindings: reset: Add TPS380x documentation | expand |
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 <m.felsch@pengutronix.de> > --- > 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 <kernel@pengutronix.de> > + * > + * Based on Simple Reset Controller Driver > + * > + * Copyright (C) 2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de> > + */ > + > +#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 <kernel@pengutronix.de>"); > +MODULE_DESCRIPTION("TI TPS380x Supply Voltags Supervisor and Reset Driver"); > +MODULE_LICENSE("GPL v2"); > -- > 2.30.2 > >
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 >
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 <kernel@pengutronix.de> + +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>; + }; +...