Message ID | 20200615090943.2936839-2-noltari@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2,1/4] spi: bcm63xx-spi: add reset support | expand |
On 6/15/2020 2:09 AM, Álvaro Fernández Rojas wrote: > bcm63xx arch resets the SPI controller at early boot. However, bmips arch > needs to perform a reset when probing the driver. > > Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> > Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> > --- > v2: use devm_reset_control_get_exclusive > > drivers/spi/spi-bcm63xx.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c > index 0f1b10a4ef0c..8ab04affaf7b 100644 > --- a/drivers/spi/spi-bcm63xx.c > +++ b/drivers/spi/spi-bcm63xx.c > @@ -18,6 +18,7 @@ > #include <linux/err.h> > #include <linux/pm_runtime.h> > #include <linux/of.h> > +#include <linux/reset.h> > > /* BCM 6338/6348 SPI core */ > #define SPI_6348_RSET_SIZE 64 > @@ -493,6 +494,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) > struct bcm63xx_spi *bs; > int ret; > u32 num_cs = BCM63XX_SPI_MAX_CS; > + struct reset_control *reset; > > if (dev->of_node) { > const struct of_device_id *match; > @@ -529,6 +531,15 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) > return PTR_ERR(clk); > } > > + reset = devm_reset_control_get_exclusive(dev, NULL); > + if (IS_ERR(reset)) { > + ret = PTR_ERR(reset); > + if (ret != -EPROBE_DEFER) > + dev_err(dev, > + "failed to get reset controller: %d\n", ret); > + return ret; > + } This should be devm_reset_control_get_exclusive_optional() for a number of reasons the first one being the most important as it reflects reality of the HW: - not all BCM63xx platforms have a dedicated reset line for the SPI controller (like the ARM-based SoCs) - until you also update all Device Tree sources to have a 'resets' property in their SPI controller node, this is likely going to be failing This also applies to patch 3.
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 0f1b10a4ef0c..8ab04affaf7b 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -18,6 +18,7 @@ #include <linux/err.h> #include <linux/pm_runtime.h> #include <linux/of.h> +#include <linux/reset.h> /* BCM 6338/6348 SPI core */ #define SPI_6348_RSET_SIZE 64 @@ -493,6 +494,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) struct bcm63xx_spi *bs; int ret; u32 num_cs = BCM63XX_SPI_MAX_CS; + struct reset_control *reset; if (dev->of_node) { const struct of_device_id *match; @@ -529,6 +531,15 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) return PTR_ERR(clk); } + reset = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(reset)) { + ret = PTR_ERR(reset); + if (ret != -EPROBE_DEFER) + dev_err(dev, + "failed to get reset controller: %d\n", ret); + return ret; + } + master = spi_alloc_master(dev, sizeof(*bs)); if (!master) { dev_err(dev, "out of memory\n"); @@ -579,6 +590,12 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) if (ret) goto out_err; + ret = reset_control_reset(reset); + if (ret) { + dev_err(dev, "unable to reset device: %d\n", ret); + goto out_clk_disable; + } + bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); /* register and we are done */