[PATCHv5] drivers/amba: add reset control to amba bus probe
diff mbox series

Message ID 20190826154252.22952-1-dinguyen@kernel.org
State New
Headers show
Series
  • [PATCHv5] drivers/amba: add reset control to amba bus probe
Related show

Commit Message

Dinh Nguyen Aug. 26, 2019, 3:42 p.m. UTC
The primecell controller on some SoCs, i.e. SoCFPGA, is held in reset by
default. Until recently, the DMA controller was brought out of reset by the
bootloader(i.e. U-Boot). But a recent change in U-Boot, the peripherals
that are not used are held in reset and are left to Linux to bring them
out of reset.

Add a mechanism for getting the reset property and de-assert the primecell
module from reset if found. This is a not a hard fail if the reset properti
is not present in the device tree node, so the driver will continue to
probe.

Because there are different variants of the controller that may have
multiple reset signals, the code will find all reset(s) specified and
de-assert them.

Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
v5: use of_reset_control_array_get_optional_shared()
v4: cleaned up indentation in loop
    fix up a few checkpatch warnings
    add Reviewed-by:
v3: add a reset_control_put()
    add error handling
v2: move reset control to bus code
    find all reset properties and de-assert them
---
 drivers/amba/bus.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Comments

Philipp Zabel Aug. 26, 2019, 3:51 p.m. UTC | #1
On Mon, 2019-08-26 at 10:42 -0500, Dinh Nguyen wrote:
> The primecell controller on some SoCs, i.e. SoCFPGA, is held in reset by
> default. Until recently, the DMA controller was brought out of reset by the
> bootloader(i.e. U-Boot). But a recent change in U-Boot, the peripherals
> that are not used are held in reset and are left to Linux to bring them
> out of reset.
> 
> Add a mechanism for getting the reset property and de-assert the primecell
> module from reset if found. This is a not a hard fail if the reset properti
> is not present in the device tree node, so the driver will continue to
> probe.
> 
> Because there are different variants of the controller that may have
> multiple reset signals, the code will find all reset(s) specified and
> de-assert them.
> 
> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
> v5: use of_reset_control_array_get_optional_shared()
> v4: cleaned up indentation in loop
>     fix up a few checkpatch warnings
>     add Reviewed-by:
> v3: add a reset_control_put()
>     add error handling
> v2: move reset control to bus code
>     find all reset properties and de-assert them
> ---
>  drivers/amba/bus.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index 100e798a5c82..f8a7cb74c3cf 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -18,6 +18,7 @@
>  #include <linux/limits.h>
>  #include <linux/clk/clk-conf.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset.h>
>  
>  #include <asm/irq.h>
>  
> @@ -401,6 +402,24 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>  	ret = amba_get_enable_pclk(dev);
>  	if (ret == 0) {
>  		u32 pid, cid;
> +		int count;
> +		struct reset_control *rstc;
> +
> +		/*
> +		 * Find reset control(s) of the amba bus and de-assert them.
> +		 */
> +		count = reset_control_get_count(&dev->dev);
> +		while (count > 0) {
> +			rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node);

You can drop the loop, the rstc returned by of_reset_control_array_get()
already controls all resets together.

regards
Philipp
Valdis Kl ē tnieks Aug. 27, 2019, 7:25 p.m. UTC | #2
On Mon, 26 Aug 2019 10:42:52 -0500, Dinh Nguyen said:
> The primecell controller on some SoCs, i.e. SoCFPGA, is held in reset by
> default. Until recently, the DMA controller was brought out of reset by the
> bootloader(i.e. U-Boot). But a recent change in U-Boot, the peripherals
> that are not used are held in reset and are left to Linux to bring them
> out of reset.
>
> Add a mechanism for getting the reset property and de-assert the primecell
> module from reset if found. This is a not a hard fail if the reset properti
> is not present in the device tree node, so the driver will continue to
> probe.

Does this DTRT for both old and new U-Boots? My naive reading of this patch
says on an old U-Boot, we end up attempting to bring it out of reset even though
they had already been brought out.
Dinh Nguyen Aug. 28, 2019, 1:34 p.m. UTC | #3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512



On 8/27/19 2:25 PM, Valdis Kl?tnieks wrote:
> On Mon, 26 Aug 2019 10:42:52 -0500, Dinh Nguyen said:
>> The primecell controller on some SoCs, i.e. SoCFPGA, is held in
>> reset by default. Until recently, the DMA controller was brought
>> out of reset by the bootloader(i.e. U-Boot). But a recent change
>> in U-Boot, the peripherals that are not used are held in reset
>> and are left to Linux to bring them out of reset.
>> 
>> Add a mechanism for getting the reset property and de-assert the
>> primecell module from reset if found. This is a not a hard fail
>> if the reset properti is not present in the device tree node, so
>> the driver will continue to probe.
> 
> Does this DTRT for both old and new U-Boots? My naive reading of
> this patch

What is a DTRT?

> says on an old U-Boot, we end up attempting to bring it out of
> reset even though they had already been brought out.
> 

If the peripheral is already out of reset, de-asserting the reset has
no affect.

Dinh

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEoHhMeiyk5VmwVMwNGZQEC4GjKPQFAl1mgtYACgkQGZQEC4Gj
KPRKMRAArFO9bQ7FCE4oiVgO/sOLm2M/ngGD3Czi6Y8TcAbIk4EylBGVw634Gs4Z
v5vuyxShlfApBb0PqfhLOo5cXrTyMdpWOq9AQ4vEcEU2MPKN8QcyLczvEagyYcwA
ianhTLR21v1Gdfm5MHqpKrNxSrb6Nt6cWmYCXjpabLYZg0gKJnsYl2XheHIdUJ02
kD2P6sQC3mf3OC5Gou4JXZGvDMgEwLG9lHsb7YoFq6tzZW3YQvAi3HcxIZZh4J8b
jFcPR3RxxQgGwESEGDWQu2EzY/d9qStEQ9VYHl/v6QIL77S1oXUAXLbh3e6ZoSgt
M93eK2G9wGCL5JlUbHXQ402OfewHchgQW1bDpjkaZLL+d9jUiGLqALAj0Az2FqX1
HtPPtifB4z6TuaLkxNTZ1Oz7UR0cWtKeSYjsuIwi0XzQMXopgH7oKdzJajNlAfRJ
In6fSVuwp47p43wj2dmUtuCSYvzKTHAg/sVGaufEfsT8ZINSOZJY9ivDqkJIzlDR
nsOclhfOGs5PgL4NPFW5U5O58DzZ5yl9NEotB4ahacuOqJv1PUdT3gABbL5hUogx
QTAPNREbYesG3osFLeEXeachiNChyJ7r+NyWFly7RXA/ukxoer2Rkxt3h0hQib6Q
/jhAsa1ar1NEk8dJJfNO7R5pZkG7ZCbhzuSDKPB2yRZPDeQGol8=
=SFzc
-----END PGP SIGNATURE-----
Valdis Kl ē tnieks Aug. 28, 2019, 1:46 p.m. UTC | #4
On Wed, 28 Aug 2019 08:34:20 -0500, Dinh Nguyen said:

> > Does this DTRT for both old and new U-Boots? My naive reading of
> > this patch
>
> What is a DTRT?

Do The Right Thing, sorry...

> > says on an old U-Boot, we end up attempting to bring it out of
> > reset even though they had already been brought out.
> >
>
> If the peripheral is already out of reset, de-asserting the reset has
> no affect.

OK, thanks.  There's been hardware where doing that sort of thing twice will
confuse the device and cause issues.

Patch
diff mbox series

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 100e798a5c82..f8a7cb74c3cf 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -18,6 +18,7 @@ 
 #include <linux/limits.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 
 #include <asm/irq.h>
 
@@ -401,6 +402,24 @@  static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
 	ret = amba_get_enable_pclk(dev);
 	if (ret == 0) {
 		u32 pid, cid;
+		int count;
+		struct reset_control *rstc;
+
+		/*
+		 * Find reset control(s) of the amba bus and de-assert them.
+		 */
+		count = reset_control_get_count(&dev->dev);
+		while (count > 0) {
+			rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node);
+			if (IS_ERR(rstc)) {
+				if (PTR_ERR(rstc) != -EPROBE_DEFER)
+					dev_err(&dev->dev, "Can't get amba reset!\n");
+				return PTR_ERR(rstc);
+			}
+			reset_control_deassert(rstc);
+			reset_control_put(rstc);
+			count--;
+		}
 
 		/*
 		 * Read pid and cid based on size of resource