Message ID | 20190826154252.22952-1-dinguyen@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [PATCHv5] drivers/amba: add reset control to amba bus probe | expand |
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
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.
-----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-----
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.
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