[PATCH v2 12/19] reset: at91: Add reset driver for basic assert/deassert operations
Claudiu.Beznea at microchip.com
Claudiu.Beznea at microchip.com
Mon Dec 12 11:43:23 CET 2022
On 08.12.2022 11:47, Sergiu Moga wrote:
> Add support for at91 reset controller's basic assert/deassert
> operations. Since this driver conflicts with the
> SYSRESET driver because they both bind to the same RSTC node,
> implement a custom bind hook that would manually bind the
> sysreset driver, if enabled, to the same RSTC DT node.
> Furthermore, delete the no longer needed compatibles from the
> SYSRESET driver and rename it to make sure than any possible
> conflicts are avoided.
>
> Signed-off-by: Sergiu Moga <sergiu.moga at microchip.com>
> Tested-by: Mihai Sain <mihai.sain at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>
> v1 -> v2:
> - No change
>
> drivers/reset/Kconfig | 8 ++
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-at91.c | 141 +++++++++++++++++++++++++++++++
> drivers/sysreset/sysreset_at91.c | 10 +--
> 4 files changed, 151 insertions(+), 9 deletions(-)
> create mode 100644 drivers/reset/reset-at91.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 4cb0ba0850..e4039d7474 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -211,4 +211,12 @@ config RESET_DRA7
> help
> Support for TI DRA7-RESET subsystem. Basic Assert/Deassert
> is supported.
> +
> +config RESET_AT91
> + bool "Enable support for Microchip/Atmel Reset Controller driver"
> + depends on DM_RESET && ARCH_AT91
> + help
> + This enables the Reset Controller driver support for Microchip/Atmel
> + SoCs. Mainly used to expose assert/deassert methods to other drivers
> + that require it.
> endmenu
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 0620b62809..6c8b45ecba 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
> obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
> obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
> obj-$(CONFIG_RESET_DRA7) += reset-dra7.o
> +obj-$(CONFIG_RESET_AT91) += reset-at91.o
> diff --git a/drivers/reset/reset-at91.c b/drivers/reset/reset-at91.c
> new file mode 100644
> index 0000000000..165c87acdc
> --- /dev/null
> +++ b/drivers/reset/reset-at91.c
> @@ -0,0 +1,141 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Support for Atmel/Microchip Reset Controller.
> + *
> + * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Sergiu Moga <sergiu.moga at microchip.com>
> + */
> +
> +#include <clk.h>
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <dm/lists.h>
> +#include <reset-uclass.h>
> +#include <asm/arch/at91_rstc.h>
> +#include <dt-bindings/reset/sama7g5-reset.h>
> +
> +struct at91_reset {
> + void __iomem *dev_base;
> + struct at91_reset_data *data;
> +};
> +
> +struct at91_reset_data {
> + u32 n_device_reset;
> + u8 device_reset_min_id;
> + u8 device_reset_max_id;
> +};
> +
> +static const struct at91_reset_data sama7g5_data = {
> + .n_device_reset = 3,
> + .device_reset_min_id = SAMA7G5_RESET_USB_PHY1,
> + .device_reset_max_id = SAMA7G5_RESET_USB_PHY3,
> +};
> +
> +static int at91_rst_update(struct at91_reset *reset, unsigned long id,
> + bool assert)
> +{
> + u32 val;
> +
> + if (!reset->dev_base)
> + return 0;
> +
> + val = readl(reset->dev_base);
> + if (assert)
> + val |= BIT(id);
> + else
> + val &= ~BIT(id);
> + writel(val, reset->dev_base);
> +
> + return 0;
> +}
> +
> +static int at91_reset_of_xlate(struct reset_ctl *reset_ctl,
> + struct ofnode_phandle_args *args)
> +{
> + struct at91_reset *reset = dev_get_priv(reset_ctl->dev);
> +
> + if (!reset->data->n_device_reset ||
> + args->args[0] < reset->data->device_reset_min_id ||
> + args->args[0] > reset->data->device_reset_max_id)
> + return -EINVAL;
> +
> + reset_ctl->id = args->args[0];
> +
> + return 0;
> +}
> +
> +static int at91_rst_assert(struct reset_ctl *reset_ctl)
> +{
> + struct at91_reset *reset = dev_get_priv(reset_ctl->dev);
> +
> + return at91_rst_update(reset, reset_ctl->id, true);
> +}
> +
> +static int at91_rst_deassert(struct reset_ctl *reset_ctl)
> +{
> + struct at91_reset *reset = dev_get_priv(reset_ctl->dev);
> +
> + return at91_rst_update(reset, reset_ctl->id, false);
> +}
> +
> +struct reset_ops at91_reset_ops = {
> + .of_xlate = at91_reset_of_xlate,
> + .rst_assert = at91_rst_assert,
> + .rst_deassert = at91_rst_deassert,
> +};
> +
> +static int at91_reset_probe(struct udevice *dev)
> +{
> + struct at91_reset *reset = dev_get_priv(dev);
> + struct clk sclk;
> + int ret;
> +
> + reset->data = (struct at91_reset_data *)dev_get_driver_data(dev);
> + reset->dev_base = dev_remap_addr_index(dev, 1);
> + if (reset->data && reset->data->n_device_reset && !reset->dev_base)
> + return -EINVAL;
> +
> + ret = clk_get_by_index(dev, 0, &sclk);
> + if (ret)
> + return ret;
> +
> + return clk_prepare_enable(&sclk);
> +}
> +
> +static int at91_reset_bind(struct udevice *dev)
> +{
> + struct udevice *at91_sysreset;
> +
> + if (CONFIG_IS_ENABLED(SYSRESET_AT91))
> + return device_bind_driver_to_node(dev, "at91_sysreset",
> + "at91_sysreset",
> + dev_ofnode(dev),
> + &at91_sysreset);
> +
> + return 0;
> +}
> +
> +static const struct udevice_id at91_reset_ids[] = {
> + {
> + .compatible = "microchip,sama7g5-rstc",
> + .data = (ulong)&sama7g5_data,
> + },
> + {
> + .compatible = "atmel,sama5d3-rstc",
> + },
> + {
> + .compatible = "microchip,sam9x60-rstc",
> + },
> + { }
> +};
> +
> +U_BOOT_DRIVER(at91_reset) = {
> + .name = "at91_reset",
> + .id = UCLASS_RESET,
> + .of_match = at91_reset_ids,
> + .bind = at91_reset_bind,
> + .probe = at91_reset_probe,
> + .priv_auto = sizeof(struct at91_reset),
> + .ops = &at91_reset_ops,
> +};
> diff --git a/drivers/sysreset/sysreset_at91.c b/drivers/sysreset/sysreset_at91.c
> index 6119a29927..fc85f31ebf 100644
> --- a/drivers/sysreset/sysreset_at91.c
> +++ b/drivers/sysreset/sysreset_at91.c
> @@ -56,17 +56,9 @@ static struct sysreset_ops at91_sysreset = {
> .request = at91_sysreset_request,
> };
>
> -static const struct udevice_id a91_sysreset_ids[] = {
> - { .compatible = "atmel,sama5d3-rstc" },
> - { .compatible = "microchip,sam9x60-rstc" },
> - { .compatible = "microchip,sama7g5-rstc" },
> - { }
> -};
> -
> U_BOOT_DRIVER(sysreset_at91) = {
> .id = UCLASS_SYSRESET,
> - .name = "at91_reset",
> + .name = "at91_sysreset",
> .ops = &at91_sysreset,
> .probe = at91_sysreset_probe,
> - .of_match = a91_sysreset_ids,
> };
More information about the U-Boot
mailing list