* [PATCH v9] reset: imx8mp-audiomix: Add AudioMix Block Control reset driver
@ 2024-06-24 3:39 Shengjiu Wang
2024-06-24 9:06 ` Abel Vesa
0 siblings, 1 reply; 2+ messages in thread
From: Shengjiu Wang @ 2024-06-24 3:39 UTC (permalink / raw)
To: p.zabel, abelvesa, peng.fan, mturquette, sboyd, robh, krzk+dt,
conor+dt, shawnguo, s.hauer, kernel, festevam, marex, linux-clk,
imx, devicetree, linux-arm-kernel, linux-kernel, shengjiu.wang
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 <shengjiu.wang@nxp.com>
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
---
changes in v9:
- only send this commits because others have been applied
- remove depends on in config
- add spin lock
- call iounmmap()
changes in v8:
https://lore.kernel.org/linux-arm-kernel/27ea1bf7de6f349426fcd7ddb056a1adfae47c73.camel@pengutronix.de/T/
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
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 fd8b49fa46fc..a6796e83900b 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 <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");
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v9] reset: imx8mp-audiomix: Add AudioMix Block Control reset driver
2024-06-24 3:39 [PATCH v9] reset: imx8mp-audiomix: Add AudioMix Block Control reset driver Shengjiu Wang
@ 2024-06-24 9:06 ` Abel Vesa
0 siblings, 0 replies; 2+ messages in thread
From: Abel Vesa @ 2024-06-24 9:06 UTC (permalink / raw)
To: Shengjiu Wang
Cc: p.zabel, abelvesa, peng.fan, mturquette, sboyd, robh, krzk+dt,
conor+dt, shawnguo, s.hauer, kernel, festevam, marex, linux-clk,
imx, devicetree, linux-arm-kernel, linux-kernel, shengjiu.wang
On 24-06-24 11:39:05, Shengjiu Wang wrote:
> 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 <shengjiu.wang@nxp.com>
> Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
> ---
> changes in v9:
> - only send this commits because others have been applied
> - remove depends on in config
> - add spin lock
> - call iounmmap()
>
> changes in v8:
> https://lore.kernel.org/linux-arm-kernel/27ea1bf7de6f349426fcd7ddb056a1adfae47c73.camel@pengutronix.de/T/
>
> 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
>
> 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 fd8b49fa46fc..a6796e83900b 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 <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");
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-06-24 9:06 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-24 3:39 [PATCH v9] reset: imx8mp-audiomix: Add AudioMix Block Control reset driver Shengjiu Wang
2024-06-24 9:06 ` Abel Vesa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).