* [PATCH v4 0/3] usb: renesas_usbhs: add reset_control and multiple clocks management
@ 2018-09-10 9:52 Yoshihiro Shimoda
2018-09-10 9:52 ` [v4,1/3] " Yoshihiro Shimoda
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw)
To: balbi, robh+dt, mark.rutland
Cc: gregkh, linux-usb, linux-renesas-soc, devicetree,
Yoshihiro Shimoda
This patch set is based on Felipe's usb.git / testing/next branch
(the commit id is 5b394b2ddf0347bef56e50c69a58773c94343ff3) with
the following patch:
https://patchwork.kernel.org/patch/10574875/
Changes from v3:
- Change the dt-bindings not to use clock-names in patch 2.
- To achieve backward compatibility with old DT, the driver should get
the first clock and the second clock is an optional.
- Add "clk_put" calling in the remove function.
Changes from v2:
- Use clk_bulk_enable_prepare() instead of two functions on patch 3/3.
Changes from v1:
- Fix error path on patch 3/3.
- Use clk_bulk_disable_unprepare() instead of two functions on patch 3/3.
- Use staic array of struct clk_bulk_data instead of a pointer on patch 3/3.
Yoshihiro Shimoda (3):
usb: renesas_usbhs: Add reset_control
dt-bindings: usb: renesas_usbhs: add clock-names property
usb: renesas_usbhs: Add multiple clocks management
.../devicetree/bindings/usb/renesas_usbhs.txt | 4 +-
drivers/usb/renesas_usbhs/common.c | 100 +++++++++++++++++++++
drivers/usb/renesas_usbhs/common.h | 4 +
3 files changed, 107 insertions(+), 1 deletion(-)
--
1.9.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v4 1/3] usb: renesas_usbhs: Add reset_control @ 2018-09-10 9:52 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw) To: balbi, robh+dt, mark.rutland Cc: gregkh, linux-usb, linux-renesas-soc, devicetree, Yoshihiro Shimoda R-Car Gen3 needs to deassert resets of both host and peripheral. Since [eo]hci-platform is possible to assert the reset(s) when the probing failed, renesas_usbhs driver doesn't work correctly regardless of finished probing. To fix this issue, this patch adds reset_control on this renesas_usbhs driver. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- drivers/usb/renesas_usbhs/common.c | 12 ++++++++++++ drivers/usb/renesas_usbhs/common.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 4310df4..1d355d5 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -12,6 +12,7 @@ #include <linux/of_device.h> #include <linux/of_gpio.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/slab.h> #include <linux/sysfs.h> #include "common.h" @@ -574,6 +575,10 @@ static int usbhs_probe(struct platform_device *pdev) return PTR_ERR(priv->edev); } + priv->rsts = devm_reset_control_array_get_optional_shared(&pdev->dev); + if (IS_ERR(priv->rsts)) + return PTR_ERR(priv->rsts); + /* * care platform info */ @@ -658,6 +663,10 @@ static int usbhs_probe(struct platform_device *pdev) /* dev_set_drvdata should be called after usbhs_mod_init */ platform_set_drvdata(pdev, priv); + ret = reset_control_deassert(priv->rsts); + if (ret) + goto probe_fail_rst; + /* * deviece reset here because * USB device might be used in boot loader. @@ -711,6 +720,8 @@ static int usbhs_probe(struct platform_device *pdev) return ret; probe_end_mod_exit: + reset_control_assert(priv->rsts); +probe_fail_rst: usbhs_mod_remove(priv); probe_end_fifo_exit: usbhs_fifo_remove(priv); @@ -739,6 +750,7 @@ static int usbhs_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); usbhs_platform_call(priv, hardware_exit, pdev); + reset_control_assert(priv->rsts); usbhs_mod_remove(priv); usbhs_fifo_remove(priv); usbhs_pipe_remove(priv); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 6137f79..bce7d35 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -10,6 +10,7 @@ #include <linux/extcon.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/usb/renesas_usbhs.h> struct usbhs_priv; @@ -277,6 +278,7 @@ struct usbhs_priv { struct usbhs_fifo_info fifo_info; struct phy *phy; + struct reset_control *rsts; }; /* -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [v4,1/3] usb: renesas_usbhs: Add reset_control @ 2018-09-10 9:52 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw) To: balbi, robh+dt, mark.rutland Cc: gregkh, linux-usb, linux-renesas-soc, devicetree, Yoshihiro Shimoda R-Car Gen3 needs to deassert resets of both host and peripheral. Since [eo]hci-platform is possible to assert the reset(s) when the probing failed, renesas_usbhs driver doesn't work correctly regardless of finished probing. To fix this issue, this patch adds reset_control on this renesas_usbhs driver. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- drivers/usb/renesas_usbhs/common.c | 12 ++++++++++++ drivers/usb/renesas_usbhs/common.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 4310df4..1d355d5 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -12,6 +12,7 @@ #include <linux/of_device.h> #include <linux/of_gpio.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/slab.h> #include <linux/sysfs.h> #include "common.h" @@ -574,6 +575,10 @@ static int usbhs_probe(struct platform_device *pdev) return PTR_ERR(priv->edev); } + priv->rsts = devm_reset_control_array_get_optional_shared(&pdev->dev); + if (IS_ERR(priv->rsts)) + return PTR_ERR(priv->rsts); + /* * care platform info */ @@ -658,6 +663,10 @@ static int usbhs_probe(struct platform_device *pdev) /* dev_set_drvdata should be called after usbhs_mod_init */ platform_set_drvdata(pdev, priv); + ret = reset_control_deassert(priv->rsts); + if (ret) + goto probe_fail_rst; + /* * deviece reset here because * USB device might be used in boot loader. @@ -711,6 +720,8 @@ static int usbhs_probe(struct platform_device *pdev) return ret; probe_end_mod_exit: + reset_control_assert(priv->rsts); +probe_fail_rst: usbhs_mod_remove(priv); probe_end_fifo_exit: usbhs_fifo_remove(priv); @@ -739,6 +750,7 @@ static int usbhs_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); usbhs_platform_call(priv, hardware_exit, pdev); + reset_control_assert(priv->rsts); usbhs_mod_remove(priv); usbhs_fifo_remove(priv); usbhs_pipe_remove(priv); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 6137f79..bce7d35 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -10,6 +10,7 @@ #include <linux/extcon.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/usb/renesas_usbhs.h> struct usbhs_priv; @@ -277,6 +278,7 @@ struct usbhs_priv { struct usbhs_fifo_info fifo_info; struct phy *phy; + struct reset_control *rsts; }; /* ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 2/3] dt-bindings: usb: renesas_usbhs: add clock-names property @ 2018-09-10 9:52 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw) To: balbi, robh+dt, mark.rutland Cc: gregkh, linux-usb, linux-renesas-soc, devicetree, Yoshihiro Shimoda R-Car Gen3 needs to enable clocks of both host and peripheral. Otherwise, other side device cannot work correctly. So, this patch adds a property of clock-names for R-Car Gen3 as an optional. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index 087140a..dbdb92c 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -26,7 +26,9 @@ Required properties: - reg: Base address and length of the register for the USBHS - interrupts: Interrupt specifier for the USBHS - - clocks: A list of phandle + clock specifier pairs + - clocks: A list of phandle + clock specifier pairs. In case of + "renesas,rcar-gen3-usbhs" compatible device, first clock should be + peripheral and second one should be host. Optional properties: - renesas,buswait: Integer to use BUSWAIT register -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [v4,2/3] dt-bindings: usb: renesas_usbhs: add clock-names property @ 2018-09-10 9:52 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw) To: balbi, robh+dt, mark.rutland Cc: gregkh, linux-usb, linux-renesas-soc, devicetree, Yoshihiro Shimoda R-Car Gen3 needs to enable clocks of both host and peripheral. Otherwise, other side device cannot work correctly. So, this patch adds a property of clock-names for R-Car Gen3 as an optional. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index 087140a..dbdb92c 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -26,7 +26,9 @@ Required properties: - reg: Base address and length of the register for the USBHS - interrupts: Interrupt specifier for the USBHS - - clocks: A list of phandle + clock specifier pairs + - clocks: A list of phandle + clock specifier pairs. In case of + "renesas,rcar-gen3-usbhs" compatible device, first clock should be + peripheral and second one should be host. Optional properties: - renesas,buswait: Integer to use BUSWAIT register ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/3] dt-bindings: usb: renesas_usbhs: add clock-names property @ 2018-09-10 18:26 ` Rob Herring 0 siblings, 0 replies; 11+ messages in thread From: Rob Herring @ 2018-09-10 18:26 UTC (permalink / raw) To: Yoshihiro Shimoda Cc: balbi, mark.rutland, gregkh, linux-usb, linux-renesas-soc, devicetree On Mon, Sep 10, 2018 at 06:52:19PM +0900, Yoshihiro Shimoda wrote: > R-Car Gen3 needs to enable clocks of both host and peripheral. > Otherwise, other side device cannot work correctly. So, this patch > adds a property of clock-names for R-Car Gen3 as an optional. > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > --- > Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > index 087140a..dbdb92c 100644 > --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > @@ -26,7 +26,9 @@ Required properties: > > - reg: Base address and length of the register for the USBHS > - interrupts: Interrupt specifier for the USBHS > - - clocks: A list of phandle + clock specifier pairs > + - clocks: A list of phandle + clock specifier pairs. In case of > + "renesas,rcar-gen3-usbhs" compatible device, first clock should be > + peripheral and second one should be host. This should have said how many clocks. That's still not clear except for "renesas,rcar-gen3-usbhs". Rob ^ permalink raw reply [flat|nested] 11+ messages in thread
* [v4,2/3] dt-bindings: usb: renesas_usbhs: add clock-names property @ 2018-09-10 18:26 ` Rob Herring 0 siblings, 0 replies; 11+ messages in thread From: Rob Herring @ 2018-09-10 18:26 UTC (permalink / raw) To: Yoshihiro Shimoda Cc: balbi, mark.rutland, gregkh, linux-usb, linux-renesas-soc, devicetree On Mon, Sep 10, 2018 at 06:52:19PM +0900, Yoshihiro Shimoda wrote: > R-Car Gen3 needs to enable clocks of both host and peripheral. > Otherwise, other side device cannot work correctly. So, this patch > adds a property of clock-names for R-Car Gen3 as an optional. > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > --- > Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > index 087140a..dbdb92c 100644 > --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > @@ -26,7 +26,9 @@ Required properties: > > - reg: Base address and length of the register for the USBHS > - interrupts: Interrupt specifier for the USBHS > - - clocks: A list of phandle + clock specifier pairs > + - clocks: A list of phandle + clock specifier pairs. In case of > + "renesas,rcar-gen3-usbhs" compatible device, first clock should be > + peripheral and second one should be host. This should have said how many clocks. That's still not clear except for "renesas,rcar-gen3-usbhs". Rob ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH v4 2/3] dt-bindings: usb: renesas_usbhs: add clock-names property @ 2018-09-11 2:38 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-11 2:38 UTC (permalink / raw) To: Rob Herring Cc: balbi@kernel.org, mark.rutland@arm.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org Hi Rob, > From: Rob Herring, Sent: Tuesday, September 11, 2018 3:27 AM > > On Mon, Sep 10, 2018 at 06:52:19PM +0900, Yoshihiro Shimoda wrote: > > R-Car Gen3 needs to enable clocks of both host and peripheral. > > Otherwise, other side device cannot work correctly. So, this patch > > adds a property of clock-names for R-Car Gen3 as an optional. > > > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > > --- > > Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > > index 087140a..dbdb92c 100644 > > --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > > +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > > @@ -26,7 +26,9 @@ Required properties: > > > > - reg: Base address and length of the register for the USBHS > > - interrupts: Interrupt specifier for the USBHS > > - - clocks: A list of phandle + clock specifier pairs > > + - clocks: A list of phandle + clock specifier pairs. In case of > > + "renesas,rcar-gen3-usbhs" compatible device, first clock should be > > + peripheral and second one should be host. > > This should have said how many clocks. That's still not clear except for > "renesas,rcar-gen3-usbhs". Thank you for your comments! I'll revise it. Best regards, Yoshihiro Shimoda > Rob ^ permalink raw reply [flat|nested] 11+ messages in thread
* [v4,2/3] dt-bindings: usb: renesas_usbhs: add clock-names property @ 2018-09-11 2:38 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-11 2:38 UTC (permalink / raw) To: Rob Herring Cc: balbi@kernel.org, mark.rutland@arm.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-renesas-soc@vger.kernel.org, devicetree@vger.kernel.org Hi Rob, > From: Rob Herring, Sent: Tuesday, September 11, 2018 3:27 AM > > On Mon, Sep 10, 2018 at 06:52:19PM +0900, Yoshihiro Shimoda wrote: > > R-Car Gen3 needs to enable clocks of both host and peripheral. > > Otherwise, other side device cannot work correctly. So, this patch > > adds a property of clock-names for R-Car Gen3 as an optional. > > > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > > --- > > Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > > index 087140a..dbdb92c 100644 > > --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > > +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt > > @@ -26,7 +26,9 @@ Required properties: > > > > - reg: Base address and length of the register for the USBHS > > - interrupts: Interrupt specifier for the USBHS > > - - clocks: A list of phandle + clock specifier pairs > > + - clocks: A list of phandle + clock specifier pairs. In case of > > + "renesas,rcar-gen3-usbhs" compatible device, first clock should be > > + peripheral and second one should be host. > > This should have said how many clocks. That's still not clear except for > "renesas,rcar-gen3-usbhs". Thank you for your comments! I'll revise it. Best regards, Yoshihiro Shimoda > Rob ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 3/3] usb: renesas_usbhs: Add multiple clocks management @ 2018-09-10 9:52 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw) To: balbi, robh+dt, mark.rutland Cc: gregkh, linux-usb, linux-renesas-soc, devicetree, Yoshihiro Shimoda R-Car Gen3 needs to enable clocks of both host and peripheral. Since [eo]hci-platform disables the reset(s) when the drivers are removed, renesas_usbhs driver doesn't work correctly. To fix this issue, this patch adds multiple clocks management on this renesas_usbhs driver. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- drivers/usb/renesas_usbhs/common.c | 88 ++++++++++++++++++++++++++++++++++++++ drivers/usb/renesas_usbhs/common.h | 2 + 2 files changed, 90 insertions(+) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 1d355d5..d6c39ba 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -5,6 +5,7 @@ * Copyright (C) 2011 Renesas Solutions Corp. * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> */ +#include <linux/clk.h> #include <linux/err.h> #include <linux/gpio.h> #include <linux/io.h> @@ -291,6 +292,79 @@ static void usbhsc_set_buswait(struct usbhs_priv *priv) usbhs_bset(priv, BUSWAIT, 0x000F, wait); } +static bool usbhsc_is_multi_clks(struct usbhs_priv *priv) +{ + if (priv->dparam.type == USBHS_TYPE_RCAR_GEN3 || + priv->dparam.type == USBHS_TYPE_RCAR_GEN3_WITH_PLL) + return true; + + return false; +} + +static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv) +{ + if (!usbhsc_is_multi_clks(priv)) + return 0; + + /* The first clock should exist */ + priv->clks[0] = of_clk_get(dev->of_node, 0); + if (IS_ERR(priv->clks[0])) + return PTR_ERR(priv->clks[0]); + + /* + * To backward compatibility with old DT, this driver checks the return + * value if it's -ENOENT or not. + */ + priv->clks[1] = of_clk_get(dev->of_node, 1); + if (PTR_ERR(priv->clks[1]) == -ENOENT) + priv->clks[1] = NULL; + else if (IS_ERR(priv->clks[1])) + return PTR_ERR(priv->clks[1]); + + return 0; +} + +static void usbhsc_clk_put(struct usbhs_priv *priv) +{ + int i; + + if (!usbhsc_is_multi_clks(priv)) + return; + + for (i = 0; i < ARRAY_SIZE(priv->clks); i++) + clk_put(priv->clks[i]); +} + +static int usbhsc_clk_prepare_enable(struct usbhs_priv *priv) +{ + int i, ret; + + if (!usbhsc_is_multi_clks(priv)) + return 0; + + for (i = 0; i < ARRAY_SIZE(priv->clks); i++) { + ret = clk_prepare_enable(priv->clks[i]); + if (ret) { + while (--i >= 0) + clk_disable_unprepare(priv->clks[i]); + return ret; + } + } + + return ret; +} + +static void usbhsc_clk_disable_unprepare(struct usbhs_priv *priv) +{ + int i; + + if (!usbhsc_is_multi_clks(priv)) + return; + + for (i = 0; i < ARRAY_SIZE(priv->clks); i++) + clk_disable_unprepare(priv->clks[i]); +} + /* * platform default param */ @@ -341,6 +415,10 @@ static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) /* enable PM */ pm_runtime_get_sync(dev); + /* enable clks */ + if (usbhsc_clk_prepare_enable(priv)) + return; + /* enable platform power */ usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); @@ -353,6 +431,9 @@ static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) /* disable platform power */ usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); + /* disable clks */ + usbhsc_clk_disable_unprepare(priv); + /* disable PM */ pm_runtime_put_sync(dev); } @@ -667,6 +748,10 @@ static int usbhs_probe(struct platform_device *pdev) if (ret) goto probe_fail_rst; + ret = usbhsc_clk_get(&pdev->dev, priv); + if (ret) + goto probe_fail_clks; + /* * deviece reset here because * USB device might be used in boot loader. @@ -720,6 +805,8 @@ static int usbhs_probe(struct platform_device *pdev) return ret; probe_end_mod_exit: + usbhsc_clk_put(priv); +probe_fail_clks: reset_control_assert(priv->rsts); probe_fail_rst: usbhs_mod_remove(priv); @@ -750,6 +837,7 @@ static int usbhs_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); usbhs_platform_call(priv, hardware_exit, pdev); + usbhsc_clk_put(priv); reset_control_assert(priv->rsts); usbhs_mod_remove(priv); usbhs_fifo_remove(priv); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index bce7d35..555b3e7 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -8,6 +8,7 @@ #ifndef RENESAS_USB_DRIVER_H #define RENESAS_USB_DRIVER_H +#include <linux/clk.h> #include <linux/extcon.h> #include <linux/platform_device.h> #include <linux/reset.h> @@ -279,6 +280,7 @@ struct usbhs_priv { struct phy *phy; struct reset_control *rsts; + struct clk *clks[2]; }; /* -- 1.9.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [v4,3/3] usb: renesas_usbhs: Add multiple clocks management @ 2018-09-10 9:52 ` Yoshihiro Shimoda 0 siblings, 0 replies; 11+ messages in thread From: Yoshihiro Shimoda @ 2018-09-10 9:52 UTC (permalink / raw) To: balbi, robh+dt, mark.rutland Cc: gregkh, linux-usb, linux-renesas-soc, devicetree, Yoshihiro Shimoda R-Car Gen3 needs to enable clocks of both host and peripheral. Since [eo]hci-platform disables the reset(s) when the drivers are removed, renesas_usbhs driver doesn't work correctly. To fix this issue, this patch adds multiple clocks management on this renesas_usbhs driver. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- drivers/usb/renesas_usbhs/common.c | 88 ++++++++++++++++++++++++++++++++++++++ drivers/usb/renesas_usbhs/common.h | 2 + 2 files changed, 90 insertions(+) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 1d355d5..d6c39ba 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -5,6 +5,7 @@ * Copyright (C) 2011 Renesas Solutions Corp. * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> */ +#include <linux/clk.h> #include <linux/err.h> #include <linux/gpio.h> #include <linux/io.h> @@ -291,6 +292,79 @@ static void usbhsc_set_buswait(struct usbhs_priv *priv) usbhs_bset(priv, BUSWAIT, 0x000F, wait); } +static bool usbhsc_is_multi_clks(struct usbhs_priv *priv) +{ + if (priv->dparam.type == USBHS_TYPE_RCAR_GEN3 || + priv->dparam.type == USBHS_TYPE_RCAR_GEN3_WITH_PLL) + return true; + + return false; +} + +static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv) +{ + if (!usbhsc_is_multi_clks(priv)) + return 0; + + /* The first clock should exist */ + priv->clks[0] = of_clk_get(dev->of_node, 0); + if (IS_ERR(priv->clks[0])) + return PTR_ERR(priv->clks[0]); + + /* + * To backward compatibility with old DT, this driver checks the return + * value if it's -ENOENT or not. + */ + priv->clks[1] = of_clk_get(dev->of_node, 1); + if (PTR_ERR(priv->clks[1]) == -ENOENT) + priv->clks[1] = NULL; + else if (IS_ERR(priv->clks[1])) + return PTR_ERR(priv->clks[1]); + + return 0; +} + +static void usbhsc_clk_put(struct usbhs_priv *priv) +{ + int i; + + if (!usbhsc_is_multi_clks(priv)) + return; + + for (i = 0; i < ARRAY_SIZE(priv->clks); i++) + clk_put(priv->clks[i]); +} + +static int usbhsc_clk_prepare_enable(struct usbhs_priv *priv) +{ + int i, ret; + + if (!usbhsc_is_multi_clks(priv)) + return 0; + + for (i = 0; i < ARRAY_SIZE(priv->clks); i++) { + ret = clk_prepare_enable(priv->clks[i]); + if (ret) { + while (--i >= 0) + clk_disable_unprepare(priv->clks[i]); + return ret; + } + } + + return ret; +} + +static void usbhsc_clk_disable_unprepare(struct usbhs_priv *priv) +{ + int i; + + if (!usbhsc_is_multi_clks(priv)) + return; + + for (i = 0; i < ARRAY_SIZE(priv->clks); i++) + clk_disable_unprepare(priv->clks[i]); +} + /* * platform default param */ @@ -341,6 +415,10 @@ static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) /* enable PM */ pm_runtime_get_sync(dev); + /* enable clks */ + if (usbhsc_clk_prepare_enable(priv)) + return; + /* enable platform power */ usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); @@ -353,6 +431,9 @@ static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) /* disable platform power */ usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); + /* disable clks */ + usbhsc_clk_disable_unprepare(priv); + /* disable PM */ pm_runtime_put_sync(dev); } @@ -667,6 +748,10 @@ static int usbhs_probe(struct platform_device *pdev) if (ret) goto probe_fail_rst; + ret = usbhsc_clk_get(&pdev->dev, priv); + if (ret) + goto probe_fail_clks; + /* * deviece reset here because * USB device might be used in boot loader. @@ -720,6 +805,8 @@ static int usbhs_probe(struct platform_device *pdev) return ret; probe_end_mod_exit: + usbhsc_clk_put(priv); +probe_fail_clks: reset_control_assert(priv->rsts); probe_fail_rst: usbhs_mod_remove(priv); @@ -750,6 +837,7 @@ static int usbhs_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); usbhs_platform_call(priv, hardware_exit, pdev); + usbhsc_clk_put(priv); reset_control_assert(priv->rsts); usbhs_mod_remove(priv); usbhs_fifo_remove(priv); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index bce7d35..555b3e7 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -8,6 +8,7 @@ #ifndef RENESAS_USB_DRIVER_H #define RENESAS_USB_DRIVER_H +#include <linux/clk.h> #include <linux/extcon.h> #include <linux/platform_device.h> #include <linux/reset.h> @@ -279,6 +280,7 @@ struct usbhs_priv { struct phy *phy; struct reset_control *rsts; + struct clk *clks[2]; }; /* ^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2018-09-11 2:38 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-09-10 9:52 [PATCH v4 0/3] usb: renesas_usbhs: add reset_control and multiple clocks management Yoshihiro Shimoda 2018-09-10 9:52 ` [PATCH v4 1/3] usb: renesas_usbhs: Add reset_control Yoshihiro Shimoda 2018-09-10 9:52 ` [v4,1/3] " Yoshihiro Shimoda 2018-09-10 9:52 ` [PATCH v4 2/3] dt-bindings: usb: renesas_usbhs: add clock-names property Yoshihiro Shimoda 2018-09-10 9:52 ` [v4,2/3] " Yoshihiro Shimoda 2018-09-10 18:26 ` [PATCH v4 2/3] " Rob Herring 2018-09-10 18:26 ` [v4,2/3] " Rob Herring 2018-09-11 2:38 ` [PATCH v4 2/3] " Yoshihiro Shimoda 2018-09-11 2:38 ` [v4,2/3] " Yoshihiro Shimoda 2018-09-10 9:52 ` [PATCH v4 3/3] usb: renesas_usbhs: Add multiple clocks management Yoshihiro Shimoda 2018-09-10 9:52 ` [v4,3/3] " Yoshihiro Shimoda
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.