summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHou Zhiqiang <B48286@freescale.com>2015-06-05 10:19:29 (GMT)
committerHonghua Yin <Hong-Hua.Yin@freescale.com>2015-06-05 10:58:50 (GMT)
commitc982ffa6a0a34023ab4a8072471974428c439445 (patch)
treea39e12b46f58a04a3e04ff99e5448f931cee2cf0
parente5b01f1348e90e86b9f6abadc842005f77085caa (diff)
downloadlinux-fsl-qoriq-c982ffa6a0a34023ab4a8072471974428c439445.tar.xz
spi: fsl-espi: Workaround for the deep sleep issue when boot from SPI
On T1042D4RDB, system can't resume and warm reset to uboot prompt sometimes. Disable eSPI controller hardware before enter deep sleep, and enable it after resume. Signed-off-by: Hou Zhiqiang <B48286@freescale.com> Change-Id: I0f091890ef3e3219697ff7f5bbf4a02809e6e45b Reviewed-on: http://git.am.freescale.net:8181/37469 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Honghua Yin <Hong-Hua.Yin@freescale.com>
-rw-r--r--drivers/spi/spi-fsl-espi.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index a7fdb87..0b03ae3 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -739,6 +739,35 @@ static int of_fsl_espi_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM_SLEEP
+#define DCFG_CCSR_DEVDISR4_OFF 0x7c
+#define ESPI_BIT (1 << 27)
+
+static int hw_disable_espi(int disable)
+{
+ struct device_node *np;
+ void __iomem *gut_addr = NULL; /* Local Access Control registers */
+ u32 regval;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,t1040-device-config");
+ if (!np) {
+ pr_err("could not find a guts node\n");
+ return -ENODEV;
+ }
+ gut_addr = of_iomap(np, 0);
+ if (!gut_addr)
+ return -ENODEV;
+
+ regval = in_be32(gut_addr + DCFG_CCSR_DEVDISR4_OFF);
+ if (disable == true)
+ regval |= ESPI_BIT;
+ else
+ regval &= ~ESPI_BIT;
+
+ out_be32(gut_addr + DCFG_CCSR_DEVDISR4_OFF, regval);
+
+ return 0;
+}
+
static int of_fsl_espi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
@@ -760,6 +789,8 @@ static int of_fsl_espi_suspend(struct device *dev)
regval &= ~SPMODE_ENABLE;
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
+ hw_disable_espi(true);
+
return 0;
}
@@ -772,6 +803,8 @@ static int of_fsl_espi_resume(struct device *dev)
u32 regval;
int i;
+ hw_disable_espi(false);
+
mpc8xxx_spi = spi_master_get_devdata(master);
reg_base = mpc8xxx_spi->reg_base;