mtd: spi-nor: cadence-quadspi: add reset control
authorDinh Nguyen <dinguyen@kernel.org>
Thu, 13 Jun 2019 11:31:38 +0000 (06:31 -0500)
committerTudor Ambarus <tudor.ambarus@microchip.com>
Thu, 27 Jun 2019 14:18:13 +0000 (17:18 +0300)
Get the reset control properties for the QSPI controller and bring them
out of reset. Most will have just one reset bit, but there is an additional
OCP reset bit that is used ECC. The OCP reset bit will also need to get
de-asserted as well. [1]

The reason this patch is needed is in the case where a bootloader leaves
the QSPI controller in a reset state, or a state where init cannot occur
successfully, the patch will put the QSPI controller into a clean state.

[1] https://www.intel.com/content/www/us/en/programmable/hps/arria-10/hps.html#reg_soc_top/sfo1429890575955.html

Suggested-by: Tien-Fong Chee <tien.fong.chee@intel.com>
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>
[tudor.ambarus@microchip.com: declare rstc and rstc_ocp on the same line]
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
drivers/mtd/spi-nor/cadence-quadspi.c

index 7926287..59b8cc3 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 #include <linux/sched.h>
 #include <linux/spi/spi.h>
 #include <linux/timer.h>
@@ -1336,6 +1337,7 @@ static int cqspi_probe(struct platform_device *pdev)
        struct cqspi_st *cqspi;
        struct resource *res;
        struct resource *res_ahb;
+       struct reset_control *rstc, *rstc_ocp;
        const struct cqspi_driver_platdata *ddata;
        int ret;
        int irq;
@@ -1402,6 +1404,25 @@ static int cqspi_probe(struct platform_device *pdev)
                goto probe_clk_failed;
        }
 
+       /* Obtain QSPI reset control */
+       rstc = devm_reset_control_get_optional_exclusive(dev, "qspi");
+       if (IS_ERR(rstc)) {
+               dev_err(dev, "Cannot get QSPI reset.\n");
+               return PTR_ERR(rstc);
+       }
+
+       rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp");
+       if (IS_ERR(rstc_ocp)) {
+               dev_err(dev, "Cannot get QSPI OCP reset.\n");
+               return PTR_ERR(rstc_ocp);
+       }
+
+       reset_control_assert(rstc);
+       reset_control_deassert(rstc);
+
+       reset_control_assert(rstc_ocp);
+       reset_control_deassert(rstc_ocp);
+
        cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
        ddata  = of_device_get_match_data(dev);
        if (ddata && (ddata->quirks & CQSPI_NEEDS_WR_DELAY))