| From f8e16eebf617cd521687a5287495858a5c7853fa Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 27 Apr 2022 11:56:48 +0200 |
| Subject: clk: renesas: r9a06g032: Export function to set dmamux |
| |
| From: Miquel Raynal <miquel.raynal@bootlin.com> |
| |
| [ Upstream commit 885525c1e7e27ea6207d648a8db20dfbbd9e4238 ] |
| |
| The dmamux register is located within the system controller. |
| |
| Without syscon, we need an extra helper in order to give write access to |
| this register to a dmamux driver. |
| |
| Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> |
| Acked-by: Stephen Boyd <sboyd@kernel.org> |
| Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Link: https://lore.kernel.org/r/20220427095653.91804-5-miquel.raynal@bootlin.com |
| Signed-off-by: Vinod Koul <vkoul@kernel.org> |
| Stable-dep-of: f8def051bbcf ("clk: renesas: r9a06g032: Fix memory leak in error path") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/clk/renesas/r9a06g032-clocks.c | 35 ++++++++++++++++++- |
| include/linux/soc/renesas/r9a06g032-sysctrl.h | 11 ++++++ |
| 2 files changed, 45 insertions(+), 1 deletion(-) |
| create mode 100644 include/linux/soc/renesas/r9a06g032-sysctrl.h |
| |
| diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c |
| index 285f6ac25372d..65cd6ed68923e 100644 |
| --- a/drivers/clk/renesas/r9a06g032-clocks.c |
| +++ b/drivers/clk/renesas/r9a06g032-clocks.c |
| @@ -20,9 +20,12 @@ |
| #include <linux/pm_clock.h> |
| #include <linux/pm_domain.h> |
| #include <linux/slab.h> |
| +#include <linux/soc/renesas/r9a06g032-sysctrl.h> |
| #include <linux/spinlock.h> |
| #include <dt-bindings/clock/r9a06g032-sysctrl.h> |
| |
| +#define R9A06G032_SYSCTRL_DMAMUX 0xA0 |
| + |
| struct r9a06g032_gate { |
| u16 gate, reset, ready, midle, |
| scon, mirack, mistat; |
| @@ -315,6 +318,30 @@ struct r9a06g032_priv { |
| void __iomem *reg; |
| }; |
| |
| +static struct r9a06g032_priv *sysctrl_priv; |
| + |
| +/* Exported helper to access the DMAMUX register */ |
| +int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) |
| +{ |
| + unsigned long flags; |
| + u32 dmamux; |
| + |
| + if (!sysctrl_priv) |
| + return -EPROBE_DEFER; |
| + |
| + spin_lock_irqsave(&sysctrl_priv->lock, flags); |
| + |
| + dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); |
| + dmamux &= ~mask; |
| + dmamux |= val & mask; |
| + writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); |
| + |
| + spin_unlock_irqrestore(&sysctrl_priv->lock, flags); |
| + |
| + return 0; |
| +} |
| +EXPORT_SYMBOL_GPL(r9a06g032_sysctrl_set_dmamux); |
| + |
| /* register/bit pairs are encoded as an uint16_t */ |
| static void |
| clk_rdesc_set(struct r9a06g032_priv *clocks, |
| @@ -961,7 +988,13 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) |
| if (error) |
| return error; |
| |
| - return r9a06g032_add_clk_domain(dev); |
| + error = r9a06g032_add_clk_domain(dev); |
| + if (error) |
| + return error; |
| + |
| + sysctrl_priv = clocks; |
| + |
| + return 0; |
| } |
| |
| static const struct of_device_id r9a06g032_match[] = { |
| diff --git a/include/linux/soc/renesas/r9a06g032-sysctrl.h b/include/linux/soc/renesas/r9a06g032-sysctrl.h |
| new file mode 100644 |
| index 0000000000000..066dfb15cbddd |
| --- /dev/null |
| +++ b/include/linux/soc/renesas/r9a06g032-sysctrl.h |
| @@ -0,0 +1,11 @@ |
| +/* SPDX-License-Identifier: GPL-2.0 */ |
| +#ifndef __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ |
| +#define __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ |
| + |
| +#ifdef CONFIG_CLK_R9A06G032 |
| +int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val); |
| +#else |
| +static inline int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) { return -ENODEV; } |
| +#endif |
| + |
| +#endif /* __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ */ |
| -- |
| 2.51.0 |
| |