diff options
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.patch | 137 |
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 0000000..e959ca5 --- /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 |