| From 51903ef3259730bfe80f74031cfcae1bf97fa6e9 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 5 Jan 2023 16:22:54 +0100 |
| Subject: soc: renesas: r9a06g032-sysctrl: Handle h2mode setting based on USBF |
| presence |
| |
| From: Herve Codina <herve.codina@bootlin.com> |
| |
| [ Upstream commit e9fee814b054e4f6f2faf3d9c1944869fe41c9dd ] |
| |
| The CFG_USB[H2MODE] allows to switch the USB configuration. The |
| configuration supported are: |
| - One host and one device |
| or |
| - Two hosts |
| |
| Set CFG_USB[H2MODE] based on the USBF controller (USB device) |
| availability. |
| |
| Signed-off-by: Herve Codina <herve.codina@bootlin.com> |
| Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| Link: https://lore.kernel.org/r/20230105152257.310642-3-herve.codina@bootlin.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.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 | 28 ++++++++++++++++++++++++++ |
| 1 file changed, 28 insertions(+) |
| |
| diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c |
| index 983faa5707b9c..087146f2ee068 100644 |
| --- a/drivers/clk/renesas/r9a06g032-clocks.c |
| +++ b/drivers/clk/renesas/r9a06g032-clocks.c |
| @@ -25,6 +25,8 @@ |
| #include <linux/spinlock.h> |
| #include <dt-bindings/clock/r9a06g032-sysctrl.h> |
| |
| +#define R9A06G032_SYSCTRL_USB 0x00 |
| +#define R9A06G032_SYSCTRL_USB_H2MODE (1<<1) |
| #define R9A06G032_SYSCTRL_DMAMUX 0xA0 |
| |
| struct r9a06g032_gate { |
| @@ -918,6 +920,29 @@ static void r9a06g032_clocks_del_clk_provider(void *data) |
| of_clk_del_provider(data); |
| } |
| |
| +static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks) |
| +{ |
| + struct device_node *usbf_np = NULL; |
| + u32 usb; |
| + |
| + while ((usbf_np = of_find_compatible_node(usbf_np, NULL, |
| + "renesas,rzn1-usbf"))) { |
| + if (of_device_is_available(usbf_np)) |
| + break; |
| + } |
| + |
| + usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); |
| + if (usbf_np) { |
| + /* 1 host and 1 device mode */ |
| + usb &= ~R9A06G032_SYSCTRL_USB_H2MODE; |
| + of_node_put(usbf_np); |
| + } else { |
| + /* 2 hosts mode */ |
| + usb |= R9A06G032_SYSCTRL_USB_H2MODE; |
| + } |
| + writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); |
| +} |
| + |
| static int __init r9a06g032_clocks_probe(struct platform_device *pdev) |
| { |
| struct device *dev = &pdev->dev; |
| @@ -947,6 +972,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) |
| clocks->reg = of_iomap(np, 0); |
| if (WARN_ON(!clocks->reg)) |
| return -ENOMEM; |
| + |
| + r9a06g032_init_h2mode(clocks); |
| + |
| for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) { |
| const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i]; |
| const char *parent_name = d->source ? |
| -- |
| 2.51.0 |
| |