summaryrefslogtreecommitdiff
path: root/drivers/reset
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/reset')
-rw-r--r--drivers/reset/Kconfig15
-rw-r--r--drivers/reset/Makefile7
-rw-r--r--drivers/reset/hisilicon/hi6220_reset.c1
-rw-r--r--drivers/reset/reset-imx8mp-audiomix.c128
-rw-r--r--drivers/reset/reset-meson-audio-arb.c9
-rw-r--r--drivers/reset/reset-rzg2l-usbphy-ctrl.c63
-rw-r--r--drivers/reset/sti/Kconfig4
-rw-r--r--drivers/reset/tegra/Kconfig3
8 files changed, 203 insertions, 27 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 7112f5932609..67bce340a87e 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -68,6 +68,7 @@ config RESET_BRCMSTB_RESCAL
config RESET_GPIO
tristate "GPIO reset controller"
+ depends on GPIOLIB
help
This enables a generic reset controller for resets attached via
GPIOs. Typically for OF platforms this driver expects "reset-gpios"
@@ -91,6 +92,14 @@ config RESET_IMX7
help
This enables the reset controller driver for i.MX7 SoCs.
+config RESET_IMX8MP_AUDIOMIX
+ tristate "i.MX8MP AudioMix Reset Driver"
+ depends on ARCH_MXC || COMPILE_TEST
+ 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
@@ -328,6 +337,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 fd8b49fa46fc..27b0bbdfcc04 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -2,8 +2,8 @@
obj-y += core.o
obj-y += hisilicon/
obj-y += starfive/
-obj-$(CONFIG_ARCH_STI) += sti/
-obj-$(CONFIG_ARCH_TEGRA) += tegra/
+obj-y += sti/
+obj-y += tegra/
obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o
@@ -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
@@ -41,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
diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c
index 5c3267acd2b1..65aa5ff5ed82 100644
--- a/drivers/reset/hisilicon/hi6220_reset.c
+++ b/drivers/reset/hisilicon/hi6220_reset.c
@@ -219,4 +219,5 @@ static int __init hi6220_reset_init(void)
postcore_initcall(hi6220_reset_init);
+MODULE_DESCRIPTION("Hisilicon Hi6220 reset controller driver");
MODULE_LICENSE("GPL v2");
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 <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/reset-controller.h>
+
+#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 <shengjiu.wang@nxp.com>");
+MODULE_DESCRIPTION("Freescale i.MX8MP Audio Block Controller reset driver");
+MODULE_LICENSE("GPL");
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 */
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index a8dde4606360..255c894a4782 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -10,10 +10,12 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/reset-controller.h>
#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),
@@ -125,25 +141,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,13 +158,45 @@ 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;
+
+ 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:
+ pm_runtime_disable(&pdev->dev);
+ reset_control_assert(priv->rstc);
+ return error;
}
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);
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
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