From b081f13c11500bceb8ab504797a48cc7751de4b5 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 10 Jun 2024 17:48:45 +0100 Subject: reset: rzg2l-usbphy-ctrl: Move reset controller registration As soon as the reset controller is registered, it could be used by a reset consumer. That means hardware setup to be done first and then the registration of the reset controller. So move the registration of reset controller at the end of probe(). While at it, fix the issue that the reset is not re-asserted in case devm_reset_controller_register() fails and also use goto statements to simplify the error path in probe(). Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240610164845.89666-1-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-rzg2l-usbphy-ctrl.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index a8dde4606360..bea3270fb698 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -125,25 +125,14 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) if (error) return error; - priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops; - priv->rcdev.of_reset_n_cells = 1; - priv->rcdev.nr_resets = NUM_PORTS; - priv->rcdev.of_node = dev->of_node; - priv->rcdev.dev = dev; - - error = devm_reset_controller_register(dev, &priv->rcdev); - if (error) - return error; - spin_lock_init(&priv->lock); dev_set_drvdata(dev, priv); pm_runtime_enable(&pdev->dev); error = pm_runtime_resume_and_get(&pdev->dev); if (error < 0) { - pm_runtime_disable(&pdev->dev); - reset_control_assert(priv->rstc); - return dev_err_probe(&pdev->dev, error, "pm_runtime_resume_and_get failed"); + dev_err_probe(&pdev->dev, error, "pm_runtime_resume_and_get failed"); + goto err_pm_disable_reset_deassert; } /* put pll and phy into reset state */ @@ -153,7 +142,24 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) writel(val, priv->base + RESET); spin_unlock_irqrestore(&priv->lock, flags); + priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops; + priv->rcdev.of_reset_n_cells = 1; + priv->rcdev.nr_resets = NUM_PORTS; + priv->rcdev.of_node = dev->of_node; + priv->rcdev.dev = dev; + + error = devm_reset_controller_register(dev, &priv->rcdev); + if (error) + goto err_pm_runtime_put; + return 0; + +err_pm_runtime_put: + pm_runtime_put(&pdev->dev); +err_pm_disable_reset_deassert: + pm_runtime_disable(&pdev->dev); + reset_control_assert(priv->rstc); + return error; } static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev) -- cgit v1.2.3 From 1359fc272bee9e0e8b7477d15b8d08518b818f0c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 21 Jun 2024 17:21:09 +0200 Subject: reset: sti: allow building under COMPILE_TEST The STIH407 reset driver can be compiled without ARCH_STI being enabled. Allow it to be built under COMPILE_TEST. Reviewed-by: Patrice Chotard Link: https://lore.kernel.org/r/20240621-reset-compile-sti-v1-1-b7a66ce29911@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/Makefile | 2 +- drivers/reset/sti/Kconfig | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fd8b49fa46fc..ff716f9afc84 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -2,7 +2,7 @@ obj-y += core.o obj-y += hisilicon/ obj-y += starfive/ -obj-$(CONFIG_ARCH_STI) += sti/ +obj-y += sti/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o diff --git a/drivers/reset/sti/Kconfig b/drivers/reset/sti/Kconfig index a2622e146b8b..0b599f7cf6ed 100644 --- a/drivers/reset/sti/Kconfig +++ b/drivers/reset/sti/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only -if ARCH_STI +if ARCH_STI || COMPILE_TEST config STIH407_RESET - bool + bool "STIH407 Reset Driver" if COMPILE_TEST endif -- cgit v1.2.3 From 0e8b3bca280a78ed5e41366f8018e4067fa0ea8e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 21 Jun 2024 17:28:12 +0200 Subject: reset: meson-audio-arb: Use devm_clk_get_enabled() Use devm_clk_get_enabled() to reduce a bit of boilerplate and to disable the clock in case devm_reset_controller_register() fails. Reviewed-by: Jerome Brunet Link: https://lore.kernel.org/r/20240621-reset-devm-clk-get-enabled-v1-1-8408c7962b6c@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/reset-meson-audio-arb.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-meson-audio-arb.c b/drivers/reset/reset-meson-audio-arb.c index 7891d52fa899..894ad9d37a66 100644 --- a/drivers/reset/reset-meson-audio-arb.c +++ b/drivers/reset/reset-meson-audio-arb.c @@ -129,8 +129,6 @@ static int meson_audio_arb_remove(struct platform_device *pdev) writel(0, arb->regs); spin_unlock(&arb->lock); - clk_disable_unprepare(arb->clk); - return 0; } @@ -150,7 +148,7 @@ static int meson_audio_arb_probe(struct platform_device *pdev) return -ENOMEM; platform_set_drvdata(pdev, arb); - arb->clk = devm_clk_get(dev, NULL); + arb->clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(arb->clk)) return dev_err_probe(dev, PTR_ERR(arb->clk), "failed to get clock\n"); @@ -170,11 +168,6 @@ static int meson_audio_arb_probe(struct platform_device *pdev) * In the initial state, all memory interfaces are disabled * and the general bit is on */ - ret = clk_prepare_enable(arb->clk); - if (ret) { - dev_err(dev, "failed to enable arb clock\n"); - return ret; - } writel(BIT(ARB_GENERAL_BIT), arb->regs); /* Register reset controller */ -- cgit v1.2.3 From fe125601d17cc1eacea47059a67bd5163d872ad2 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 24 Jun 2024 11:39:05 +0800 Subject: reset: imx8mp-audiomix: Add AudioMix Block Control reset driver Add support for the resets on i.MX8MP Audio Block Control module, which includes the EARC PHY software reset and EARC controller software reset. The reset controller is created using the auxiliary device framework and set up in the clock driver. Signed-off-by: Shengjiu Wang Reviewed-by: Marco Felsch Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/1719200345-32006-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 7 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-imx8mp-audiomix.c | 128 ++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 drivers/reset/reset-imx8mp-audiomix.c (limited to 'drivers/reset') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 7112f5932609..509f70e5c4c0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -91,6 +91,13 @@ config RESET_IMX7 help This enables the reset controller driver for i.MX7 SoCs. +config RESET_IMX8MP_AUDIOMIX + tristate "i.MX8MP AudioMix Reset Driver" + select AUXILIARY_BUS + default CLK_IMX8MP + help + This enables the reset controller driver for i.MX8MP AudioMix + config RESET_INTEL_GW bool "Intel Reset Controller Driver" depends on X86 || COMPILE_TEST diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index ff716f9afc84..47a8148a92f3 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -14,6 +14,7 @@ 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_IMX8MP_AUDIOMIX) += reset-imx8mp-audiomix.o obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o obj-$(CONFIG_RESET_K210) += reset-k210.o obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o diff --git a/drivers/reset/reset-imx8mp-audiomix.c b/drivers/reset/reset-imx8mp-audiomix.c new file mode 100644 index 000000000000..6e3f3069f727 --- /dev/null +++ b/drivers/reset/reset-imx8mp-audiomix.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2024 NXP + */ + +#include +#include +#include +#include +#include +#include +#include + +#define EARC 0x200 +#define EARC_RESET_MASK 0x3 + +struct imx8mp_audiomix_reset { + struct reset_controller_dev rcdev; + spinlock_t lock; /* protect register read-modify-write cycle */ + void __iomem *base; +}; + +static struct imx8mp_audiomix_reset *to_imx8mp_audiomix_reset(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct imx8mp_audiomix_reset, rcdev); +} + +static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); + void __iomem *reg_addr = priv->base; + unsigned int mask, reg; + unsigned long flags; + + mask = BIT(id); + spin_lock_irqsave(&priv->lock, flags); + reg = readl(reg_addr + EARC); + writel(reg & ~mask, reg_addr + EARC); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static int imx8mp_audiomix_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); + void __iomem *reg_addr = priv->base; + unsigned int mask, reg; + unsigned long flags; + + mask = BIT(id); + spin_lock_irqsave(&priv->lock, flags); + reg = readl(reg_addr + EARC); + writel(reg | mask, reg_addr + EARC); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static const struct reset_control_ops imx8mp_audiomix_reset_ops = { + .assert = imx8mp_audiomix_reset_assert, + .deassert = imx8mp_audiomix_reset_deassert, +}; + +static int imx8mp_audiomix_reset_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct imx8mp_audiomix_reset *priv; + struct device *dev = &adev->dev; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + + priv->rcdev.owner = THIS_MODULE; + priv->rcdev.nr_resets = fls(EARC_RESET_MASK); + priv->rcdev.ops = &imx8mp_audiomix_reset_ops; + priv->rcdev.of_node = dev->parent->of_node; + priv->rcdev.dev = dev; + priv->rcdev.of_reset_n_cells = 1; + priv->base = of_iomap(dev->parent->of_node, 0); + if (!priv->base) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + + ret = devm_reset_controller_register(dev, &priv->rcdev); + if (ret) + goto out_unmap; + + return 0; + +out_unmap: + iounmap(priv->base); + return ret; +} + +static void imx8mp_audiomix_reset_remove(struct auxiliary_device *adev) +{ + struct imx8mp_audiomix_reset *priv = dev_get_drvdata(&adev->dev); + + iounmap(priv->base); +} + +static const struct auxiliary_device_id imx8mp_audiomix_reset_ids[] = { + { + .name = "clk_imx8mp_audiomix.reset", + }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, imx8mp_audiomix_reset_ids); + +static struct auxiliary_driver imx8mp_audiomix_reset_driver = { + .probe = imx8mp_audiomix_reset_probe, + .remove = imx8mp_audiomix_reset_remove, + .id_table = imx8mp_audiomix_reset_ids, +}; + +module_auxiliary_driver(imx8mp_audiomix_reset_driver); + +MODULE_AUTHOR("Shengjiu Wang "); +MODULE_DESCRIPTION("Freescale i.MX8MP Audio Block Controller reset driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4f6a43ad2b05fd51e3294c67bb2e3da270324fbf Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 21 Jun 2024 17:24:47 +0200 Subject: reset: zynqmp: allow building under COMPILE_TEST The ZynqMP reset driver can be compiled without ARCH_ZYNQMP being enabled. Allow it to be built under COMPILE_TEST. Acked-by: Michal Simek Link: https://lore.kernel.org/r/20240621-reset-compile-zynqmp-v1-1-ede43ab18101@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 6 ++++++ drivers/reset/Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 509f70e5c4c0..e59da17ea0b2 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -335,6 +335,12 @@ config RESET_ZYNQ help This enables the reset controller driver for Xilinx Zynq SoCs. +config RESET_ZYNQMP + bool "ZYNQMP Reset Driver" if COMPILE_TEST + default ARCH_ZYNQMP + help + This enables the reset controller driver for Xilinx ZynqMP SoCs. + source "drivers/reset/starfive/Kconfig" source "drivers/reset/sti/Kconfig" source "drivers/reset/hisilicon/Kconfig" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 47a8148a92f3..1b814f08fed7 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -42,4 +42,4 @@ obj-$(CONFIG_RESET_TN48M_CPLD) += reset-tn48m.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o -obj-$(CONFIG_ARCH_ZYNQMP) += reset-zynqmp.o +obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o -- cgit v1.2.3 From eb5d88b1538850c6d9ddfcd0b59dc7c84831b530 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 25 Jun 2024 13:57:48 +0200 Subject: reset: RESET_IMX8MP_AUDIOMIX should depend on ARCH_MXC The i.MX8MP AudioMix reset controller is only present on Freescale i.MX8 SoCs. Hence add a dependency on ARCH_MXC, to prevent asking the user about this driver when configuring a kernel without i.MX SoC support. Fixes: fe125601d17cc1ea ("reset: imx8mp-audiomix: Add AudioMix Block Control reset driver") Signed-off-by: Geert Uytterhoeven Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/6d8116a56186fbf468229e823c7c8dfcd9488959.1719316665.git.geert+renesas@glider.be Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/reset') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index e59da17ea0b2..36cfdb81cd34 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -93,6 +93,7 @@ config RESET_IMX7 config RESET_IMX8MP_AUDIOMIX tristate "i.MX8MP AudioMix Reset Driver" + depends on ARCH_MXC || COMPILE_TEST select AUXILIARY_BUS default CLK_IMX8MP help -- cgit v1.2.3 From fd88137bfbb83bee678abef840dcafa13262f5ca Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 25 Jun 2024 14:51:41 +0200 Subject: reset: tegra-bpmp: allow building under COMPILE_TEST The Tegra BPMP reset driver can be compiled without TEGRA_BPMP being enabled. Allow it to be built under COMPILE_TEST. Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20240625-reset-compile-bpmp-v1-1-647e846303d8@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/Makefile | 2 +- drivers/reset/tegra/Kconfig | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 1b814f08fed7..27b0bbdfcc04 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -3,7 +3,7 @@ obj-y += core.o obj-y += hisilicon/ obj-y += starfive/ obj-y += sti/ -obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-y += tegra/ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o diff --git a/drivers/reset/tegra/Kconfig b/drivers/reset/tegra/Kconfig index e4a9a389e98c..4a2d26d1210a 100644 --- a/drivers/reset/tegra/Kconfig +++ b/drivers/reset/tegra/Kconfig @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only config RESET_TEGRA_BPMP - def_bool TEGRA_BPMP + bool "Tegra BPMP Reset Driver" if COMPILE_TEST + default TEGRA_BPMP -- cgit v1.2.3 From 4068f22e4b47f7352fc369c22800e04d2860416b Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 2 Jul 2024 19:00:16 +0100 Subject: reset: renesas: Add USB VBUS regulator device as child As per RZ/G2L HW manual, VBUS enable can be controlled by the VBOUT bit of the VBUS Control Register(VBENCTL) register in the USBPHY Control. Expose this register as regmap and instantiate the USB VBUS regulator device, so that consumer can control the vbus using regulator API's Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20240702180032.207275-3-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-rzg2l-usbphy-ctrl.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index bea3270fb698..255c894a4782 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #define RESET 0x000 +#define VBENCTL 0x03c #define RESET_SEL_PLLRESET BIT(12) #define RESET_PLLRESET BIT(8) @@ -32,6 +34,7 @@ struct rzg2l_usbphy_ctrl_priv { struct reset_controller_dev rcdev; struct reset_control *rstc; void __iomem *base; + struct platform_device *vdev; spinlock_t lock; }; @@ -100,10 +103,19 @@ static const struct reset_control_ops rzg2l_usbphy_ctrl_reset_ops = { .status = rzg2l_usbphy_ctrl_status, }; +static const struct regmap_config rzg2l_usb_regconf = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 1, +}; + static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rzg2l_usbphy_ctrl_priv *priv; + struct platform_device *vdev; + struct regmap *regmap; unsigned long flags; int error; u32 val; @@ -116,6 +128,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + regmap = devm_regmap_init_mmio(dev, priv->base + VBENCTL, &rzg2l_usb_regconf); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(priv->rstc)) return dev_err_probe(dev, PTR_ERR(priv->rstc), @@ -152,8 +168,22 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) if (error) goto err_pm_runtime_put; + vdev = platform_device_alloc("rzg2l-usb-vbus-regulator", pdev->id); + if (!vdev) { + error = -ENOMEM; + goto err_pm_runtime_put; + } + vdev->dev.parent = dev; + priv->vdev = vdev; + + error = platform_device_add(vdev); + if (error) + goto err_device_put; + return 0; +err_device_put: + platform_device_put(vdev); err_pm_runtime_put: pm_runtime_put(&pdev->dev); err_pm_disable_reset_deassert: @@ -166,6 +196,7 @@ static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev) { struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(&pdev->dev); + platform_device_unregister(priv->vdev); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); reset_control_assert(priv->rstc); -- cgit v1.2.3