aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch')
-rw-r--r--target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch137
1 files changed, 137 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch b/target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch
new file mode 100644
index 0000000000..e959ca50d3
--- /dev/null
+++ b/target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch
@@ -0,0 +1,137 @@
+From 2c5a3db21926e9ebfd7a32e3c36a3256ed84903c Mon Sep 17 00:00:00 2001
+From: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
+Date: Thu, 19 Nov 2015 20:25:24 +0800
+Subject: [PATCH 090/113] mtd: spi-nor: Add SPI NOR layer PM support
+
+[context adjustment]
+
+Add the Power Management API in SPI NOR framework.
+The Power Management system will turn off power supply to SPI flash
+when system suspending, and then the SPI flash will be in the reset
+state after system resuming. As a result, the status&configurations
+of SPI flash driver will mismatch with its current hardware state.
+So reinitialize SPI flash to make sure it is resumed to the correct
+state.
+And the SPI NOR layer just do common configuration depending on the
+records in structure spi_nor.
+
+Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
+Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 74 ++++++++++++++++++++++++++++++++++-------
+ include/linux/mtd/spi-nor.h | 9 +++++
+ 2 files changed, 71 insertions(+), 12 deletions(-)
+
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -1139,6 +1139,26 @@ static int spi_nor_check(struct spi_nor
+ return 0;
+ }
+
++/*
++ * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
++ * with the software protection bits set
++ */
++static int spi_nor_unprotect_on_powerup(struct spi_nor *nor)
++{
++ const struct flash_info *info = NULL;
++ int ret = 0;
++
++ info = spi_nor_read_id(nor);
++ if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
++ JEDEC_MFR(info) == SNOR_MFR_INTEL ||
++ JEDEC_MFR(info) == SNOR_MFR_SST) {
++ write_enable(nor);
++ ret = write_sr(nor, 0);
++ }
++
++ return ret;
++}
++
+ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+ {
+ const struct flash_info *info = NULL;
+@@ -1186,18 +1206,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+
+ mutex_init(&nor->lock);
+
+- /*
+- * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+- * with the software protection bits set
+- */
+-
+- if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
+- JEDEC_MFR(info) == SNOR_MFR_INTEL ||
+- JEDEC_MFR(info) == SNOR_MFR_MACRONIX ||
+- JEDEC_MFR(info) == SNOR_MFR_SST) {
+- write_enable(nor);
+- write_sr(nor, 0);
+- }
++ ret = spi_nor_unprotect_on_powerup(nor);
++ if (ret)
++ return ret;
+
+ if (!mtd->name)
+ mtd->name = dev_name(dev);
+@@ -1363,6 +1374,45 @@ int spi_nor_scan(struct spi_nor *nor, co
+ }
+ EXPORT_SYMBOL_GPL(spi_nor_scan);
+
++static int spi_nor_hw_reinit(struct spi_nor *nor)
++{
++ const struct flash_info *info = NULL;
++ struct device *dev = nor->dev;
++ int ret;
++
++ info = spi_nor_read_id(nor);
++
++ ret = spi_nor_unprotect_on_powerup(nor);
++ if (ret)
++ return ret;
++
++ if (nor->flash_read == SPI_NOR_QUAD) {
++ ret = set_quad_mode(nor, info);
++ if (ret) {
++ dev_err(dev, "quad mode not supported\n");
++ return ret;
++ }
++ }
++
++ if (nor->addr_width == 4 &&
++ JEDEC_MFR(info) != SNOR_MFR_SPANSION)
++ set_4byte(nor, info, 1);
++
++ return 0;
++}
++
++int spi_nor_suspend(struct spi_nor *nor)
++{
++ return 0;
++}
++EXPORT_SYMBOL_GPL(spi_nor_suspend);
++
++int spi_nor_resume(struct spi_nor *nor)
++{
++ return spi_nor_hw_reinit(nor);
++}
++EXPORT_SYMBOL_GPL(spi_nor_resume);
++
+ static const struct flash_info *spi_nor_match_id(const char *name)
+ {
+ const struct flash_info *id = spi_nor_ids;
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -210,4 +210,13 @@ static inline struct device_node *spi_no
+ */
+ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
+
++/**
++ * spi_nor_suspend/resume() - the SPI NOR layer PM API
++ * @nor: the spi_nor structure
++ *
++ * Return: 0 for success, others for failure.
++ */
++int spi_nor_suspend(struct spi_nor *nor);
++int spi_nor_resume(struct spi_nor *nor);
++
+ #endif