[PATCH v3 6/8] mtd: spi-nor: fsl-quadspi: workaround qspi can't wakeup from wait mode
Frank.Li at freescale.com
Frank.Li at freescale.com
Fri Jul 24 11:06:26 PDT 2015
From: Frank Li <Frank.Li at freescale.com>
QSPI1 cannot wake up CCM from WAIT mode on SX ARD board, add pmqos to
let PM NOT enter WAIT mode when accessing QSPI1, refer to TKT245618.
Signed-off-by: Frank Li <Frank.Li at freescale.com>
Signed-off-by: Allen Xu <b45815 at freescale.com>
---
drivers/mtd/spi-nor/fsl-quadspi.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 9ee6db9..0ddc2d1 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -27,6 +27,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/spi-nor.h>
#include <linux/mutex.h>
+#include <linux/pm_qos.h>
/* Controller needs driver to swap endian */
#define QUADSPI_QUIRK_SWAP_ENDIAN (1 << 0)
@@ -37,6 +38,8 @@
* trigger data transfer even though extern data will not transferred.
*/
#define QUADSPI_QUIRK_TKT253890 (1 << 2)
+/* Controller cannot wake up from wait mode, TKT245618 */
+#define QUADSPI_QUIRK_TKT245618 (1 << 3)
/* The registers */
#define QUADSPI_MCR 0x00
@@ -231,6 +234,7 @@ static struct fsl_qspi_devtype_data imx6sx_data = {
.txfifo = 512,
.ahb_buf_size = 1024,
.driver_data = QUADSPI_QUIRK_4X_INT_CLK
+ | QUADSPI_QUIRK_TKT245618
};
static struct fsl_qspi_devtype_data imx7d_data = {
@@ -270,6 +274,7 @@ struct fsl_qspi {
unsigned int chip_base_addr; /* We may support two chips. */
bool has_second_chip;
struct mutex lock;
+ struct pm_qos_request pm_qos_req;
};
static inline int needs_swap_endian(struct fsl_qspi *q)
@@ -287,6 +292,11 @@ static inline int needs_fill_txfifo(struct fsl_qspi *q)
return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT253890;
}
+static inline int needs_wakeup_wait_mode(struct fsl_qspi *q)
+{
+ return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
+}
+
/*
* An IC bug makes us to re-arrange the 32-bit data.
* The following chips, such as IMX6SLX, have fixed this bug.
@@ -668,12 +678,18 @@ static int fsl_qspi_clk_prep_enable(struct fsl_qspi *q)
return ret;
}
+ if (needs_wakeup_wait_mode(q))
+ pm_qos_add_request(&q->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
+
return 0;
}
/* This function was used to disable and unprepare QSPI clock */
static void fsl_qspi_clk_disable_unprep(struct fsl_qspi *q)
{
+ if (needs_wakeup_wait_mode(q))
+ pm_qos_remove_request(&q->pm_qos_req);
+
clk_disable_unprepare(q->clk);
clk_disable_unprepare(q->clk_en);
@@ -925,6 +941,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (!q->nor_num || q->nor_num > FSL_QSPI_MAX_CHIP)
return -ENODEV;
+ q->dev = dev;
+ q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
+ platform_set_drvdata(pdev, q);
+
/* find the resources */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
q->iobase = devm_ioremap_resource(dev, res);
@@ -964,10 +984,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
goto irq_failed;
}
- q->dev = dev;
- q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
- platform_set_drvdata(pdev, q);
-
ret = fsl_qspi_nor_setup(q);
if (ret)
goto irq_failed;
--
1.9.1
More information about the linux-mtd
mailing list