kernel: update kernel 4.4 to version 4.4.30
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.4 / 1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch
1 From 2c5a3db21926e9ebfd7a32e3c36a3256ed84903c Mon Sep 17 00:00:00 2001
2 From: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
3 Date: Thu, 19 Nov 2015 20:25:24 +0800
4 Subject: [PATCH 090/113] mtd: spi-nor: Add SPI NOR layer PM support
5
6 [context adjustment]
7
8 Add the Power Management API in SPI NOR framework.
9 The Power Management system will turn off power supply to SPI flash
10 when system suspending, and then the SPI flash will be in the reset
11 state after system resuming. As a result, the status&configurations
12 of SPI flash driver will mismatch with its current hardware state.
13 So reinitialize SPI flash to make sure it is resumed to the correct
14 state.
15 And the SPI NOR layer just do common configuration depending on the
16 records in structure spi_nor.
17
18 Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
19 Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
20 ---
21 drivers/mtd/spi-nor/spi-nor.c | 74 ++++++++++++++++++++++++++++++++++-------
22 include/linux/mtd/spi-nor.h | 9 +++++
23 2 files changed, 71 insertions(+), 12 deletions(-)
24
25 --- a/drivers/mtd/spi-nor/spi-nor.c
26 +++ b/drivers/mtd/spi-nor/spi-nor.c
27 @@ -1140,6 +1140,26 @@ static int spi_nor_check(struct spi_nor
28 return 0;
29 }
30
31 +/*
32 + * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
33 + * with the software protection bits set
34 + */
35 +static int spi_nor_unprotect_on_powerup(struct spi_nor *nor)
36 +{
37 + const struct flash_info *info = NULL;
38 + int ret = 0;
39 +
40 + info = spi_nor_read_id(nor);
41 + if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
42 + JEDEC_MFR(info) == SNOR_MFR_INTEL ||
43 + JEDEC_MFR(info) == SNOR_MFR_SST) {
44 + write_enable(nor);
45 + ret = write_sr(nor, 0);
46 + }
47 +
48 + return ret;
49 +}
50 +
51 int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
52 {
53 const struct flash_info *info = NULL;
54 @@ -1187,18 +1207,9 @@ int spi_nor_scan(struct spi_nor *nor, co
55
56 mutex_init(&nor->lock);
57
58 - /*
59 - * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
60 - * with the software protection bits set
61 - */
62 -
63 - if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
64 - JEDEC_MFR(info) == SNOR_MFR_INTEL ||
65 - JEDEC_MFR(info) == SNOR_MFR_MACRONIX ||
66 - JEDEC_MFR(info) == SNOR_MFR_SST) {
67 - write_enable(nor);
68 - write_sr(nor, 0);
69 - }
70 + ret = spi_nor_unprotect_on_powerup(nor);
71 + if (ret)
72 + return ret;
73
74 if (!mtd->name)
75 mtd->name = dev_name(dev);
76 @@ -1364,6 +1375,45 @@ int spi_nor_scan(struct spi_nor *nor, co
77 }
78 EXPORT_SYMBOL_GPL(spi_nor_scan);
79
80 +static int spi_nor_hw_reinit(struct spi_nor *nor)
81 +{
82 + const struct flash_info *info = NULL;
83 + struct device *dev = nor->dev;
84 + int ret;
85 +
86 + info = spi_nor_read_id(nor);
87 +
88 + ret = spi_nor_unprotect_on_powerup(nor);
89 + if (ret)
90 + return ret;
91 +
92 + if (nor->flash_read == SPI_NOR_QUAD) {
93 + ret = set_quad_mode(nor, info);
94 + if (ret) {
95 + dev_err(dev, "quad mode not supported\n");
96 + return ret;
97 + }
98 + }
99 +
100 + if (nor->addr_width == 4 &&
101 + JEDEC_MFR(info) != SNOR_MFR_SPANSION)
102 + set_4byte(nor, info, 1);
103 +
104 + return 0;
105 +}
106 +
107 +int spi_nor_suspend(struct spi_nor *nor)
108 +{
109 + return 0;
110 +}
111 +EXPORT_SYMBOL_GPL(spi_nor_suspend);
112 +
113 +int spi_nor_resume(struct spi_nor *nor)
114 +{
115 + return spi_nor_hw_reinit(nor);
116 +}
117 +EXPORT_SYMBOL_GPL(spi_nor_resume);
118 +
119 static const struct flash_info *spi_nor_match_id(const char *name)
120 {
121 const struct flash_info *id = spi_nor_ids;
122 --- a/include/linux/mtd/spi-nor.h
123 +++ b/include/linux/mtd/spi-nor.h
124 @@ -210,4 +210,13 @@ static inline struct device_node *spi_no
125 */
126 int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
127
128 +/**
129 + * spi_nor_suspend/resume() - the SPI NOR layer PM API
130 + * @nor: the spi_nor structure
131 + *
132 + * Return: 0 for success, others for failure.
133 + */
134 +int spi_nor_suspend(struct spi_nor *nor);
135 +int spi_nor_resume(struct spi_nor *nor);
136 +
137 #endif