kernel: disable multicast-to-unicast translation for ipv6 neighbor solicitation ...
[openwrt.git] / target / linux / bcm53xx / patches-3.14 / 403-mtd-spi-nor-refactor-wait-till-ready.patch
1 --- a/drivers/mtd/spi-nor/fsl-quadspi.c
2 +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
3 @@ -719,16 +719,10 @@ static int fsl_qspi_read(struct spi_nor
4  {
5         struct fsl_qspi *q = nor->priv;
6         u8 cmd = nor->read_opcode;
7 -       int ret;
8  
9         dev_dbg(q->dev, "cmd [%x],read from (0x%p, 0x%.8x, 0x%.8x),len:%d\n",
10                 cmd, q->ahb_base, q->chip_base_addr, (unsigned int)from, len);
11  
12 -       /* Wait until the previous command is finished. */
13 -       ret = nor->wait_till_ready(nor);
14 -       if (ret)
15 -               return ret;
16 -
17         /* Read out the data directly from the AHB buffer.*/
18         memcpy(buf, q->ahb_base + q->chip_base_addr + from, len);
19  
20 @@ -744,16 +738,6 @@ static int fsl_qspi_erase(struct spi_nor
21         dev_dbg(nor->dev, "%dKiB at 0x%08x:0x%08x\n",
22                 nor->mtd->erasesize / 1024, q->chip_base_addr, (u32)offs);
23  
24 -       /* Wait until finished previous write command. */
25 -       ret = nor->wait_till_ready(nor);
26 -       if (ret)
27 -               return ret;
28 -
29 -       /* Send write enable, then erase commands. */
30 -       ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0);
31 -       if (ret)
32 -               return ret;
33 -
34         ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0);
35         if (ret)
36                 return ret;
37 --- a/drivers/mtd/spi-nor/spi-nor.c
38 +++ b/drivers/mtd/spi-nor/spi-nor.c
39 @@ -163,81 +163,69 @@ static inline int set_4byte(struct spi_n
40                 return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1, 0);
41         }
42  }
43 -
44 -static int spi_nor_wait_till_ready(struct spi_nor *nor)
45 +static inline int spi_nor_sr_ready(struct spi_nor *nor)
46  {
47 -       unsigned long deadline;
48 -       int sr;
49 -
50 -       deadline = jiffies + MAX_READY_WAIT_JIFFIES;
51 -
52 -       do {
53 -               cond_resched();
54 +       int sr = read_sr(nor);
55 +       if (sr < 0)
56 +               return sr;
57 +       else
58 +               return !(sr & SR_WIP);
59 +}
60  
61 -               sr = read_sr(nor);
62 -               if (sr < 0)
63 -                       break;
64 -               else if (!(sr & SR_WIP))
65 -                       return 0;
66 -       } while (!time_after_eq(jiffies, deadline));
67 +static inline int spi_nor_fsr_ready(struct spi_nor *nor)
68 +{
69 +       int fsr = read_fsr(nor);
70 +       if (fsr < 0)
71 +               return fsr;
72 +       else
73 +               return fsr & FSR_READY;
74 +}
75  
76 -       return -ETIMEDOUT;
77 +static int spi_nor_ready(struct spi_nor *nor)
78 +{
79 +       int sr, fsr;
80 +       sr = spi_nor_sr_ready(nor);
81 +       if (sr < 0)
82 +               return sr;
83 +       fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
84 +       if (fsr < 0)
85 +               return sr;
86 +       return sr && fsr;
87  }
88  
89 -static int spi_nor_wait_till_fsr_ready(struct spi_nor *nor)
90 +/*
91 + * Service routine to read status register until ready, or timeout occurs.
92 + * Returns non-zero if error.
93 + */
94 +static int spi_nor_wait_till_ready(struct spi_nor *nor)
95  {
96         unsigned long deadline;
97 -       int sr;
98 -       int fsr;
99 +       int ret;
100  
101         deadline = jiffies + MAX_READY_WAIT_JIFFIES;
102  
103         do {
104                 cond_resched();
105  
106 -               sr = read_sr(nor);
107 -               if (sr < 0) {
108 -                       break;
109 -               } else if (!(sr & SR_WIP)) {
110 -                       fsr = read_fsr(nor);
111 -                       if (fsr < 0)
112 -                               break;
113 -                       if (fsr & FSR_READY)
114 -                               return 0;
115 -               }
116 +               ret = spi_nor_ready(nor);
117 +               if (ret < 0)
118 +                       return ret;
119 +               if (ret)
120 +                       return 0;
121         } while (!time_after_eq(jiffies, deadline));
122  
123         return -ETIMEDOUT;
124  }
125  
126  /*
127 - * Service routine to read status register until ready, or timeout occurs.
128 - * Returns non-zero if error.
129 - */
130 -static int wait_till_ready(struct spi_nor *nor)
131 -{
132 -       return nor->wait_till_ready(nor);
133 -}
134 -
135 -/*
136   * Erase the whole flash memory
137   *
138   * Returns 0 if successful, non-zero otherwise.
139   */
140  static int erase_chip(struct spi_nor *nor)
141  {
142 -       int ret;
143 -
144         dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd->size >> 10));
145  
146 -       /* Wait until finished previous write command. */
147 -       ret = wait_till_ready(nor);
148 -       if (ret)
149 -               return ret;
150 -
151 -       /* Send write enable, then erase commands. */
152 -       write_enable(nor);
153 -
154         return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0, 0);
155  }
156  
157 @@ -290,6 +278,8 @@ static int spi_nor_erase(struct mtd_info
158         if (ret)
159                 return ret;
160  
161 +       write_enable(nor);
162 +
163         /* whole-chip erase? */
164         if (len == mtd->size) {
165                 if (erase_chip(nor)) {
166 @@ -297,6 +287,10 @@ static int spi_nor_erase(struct mtd_info
167                         goto erase_err;
168                 }
169  
170 +               ret = spi_nor_wait_till_ready(nor);
171 +               if (ret)
172 +                       goto erase_err;
173 +
174         /* REVISIT in some cases we could speed up erasing large regions
175          * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may have set up
176          * to use "small sector erase", but that's not always optimal.
177 @@ -312,9 +306,15 @@ static int spi_nor_erase(struct mtd_info
178  
179                         addr += mtd->erasesize;
180                         len -= mtd->erasesize;
181 +
182 +                       ret = spi_nor_wait_till_ready(nor);
183 +                       if (ret)
184 +                               goto erase_err;
185                 }
186         }
187  
188 +       write_disable(nor);
189 +
190         spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
191  
192         instr->state = MTD_ERASE_DONE;
193 @@ -339,11 +339,6 @@ static int spi_nor_lock(struct mtd_info
194         if (ret)
195                 return ret;
196  
197 -       /* Wait until finished previous command */
198 -       ret = wait_till_ready(nor);
199 -       if (ret)
200 -               goto err;
201 -
202         status_old = read_sr(nor);
203  
204         if (offset < mtd->size - (mtd->size / 2))
205 @@ -386,11 +381,6 @@ static int spi_nor_unlock(struct mtd_inf
206         if (ret)
207                 return ret;
208  
209 -       /* Wait until finished previous command */
210 -       ret = wait_till_ready(nor);
211 -       if (ret)
212 -               goto err;
213 -
214         status_old = read_sr(nor);
215  
216         if (offset+len > mtd->size - (mtd->size / 64))
217 @@ -702,11 +692,6 @@ static int sst_write(struct mtd_info *mt
218         if (ret)
219                 return ret;
220  
221 -       /* Wait until finished previous write command. */
222 -       ret = wait_till_ready(nor);
223 -       if (ret)
224 -               goto time_out;
225 -
226         write_enable(nor);
227  
228         nor->sst_write_second = false;
229 @@ -718,7 +703,7 @@ static int sst_write(struct mtd_info *mt
230  
231                 /* write one byte. */
232                 nor->write(nor, to, 1, retlen, buf);
233 -               ret = wait_till_ready(nor);
234 +               ret = spi_nor_wait_till_ready(nor);
235                 if (ret)
236                         goto time_out;
237         }
238 @@ -730,7 +715,7 @@ static int sst_write(struct mtd_info *mt
239  
240                 /* write two bytes. */
241                 nor->write(nor, to, 2, retlen, buf + actual);
242 -               ret = wait_till_ready(nor);
243 +               ret = spi_nor_wait_till_ready(nor);
244                 if (ret)
245                         goto time_out;
246                 to += 2;
247 @@ -739,7 +724,7 @@ static int sst_write(struct mtd_info *mt
248         nor->sst_write_second = false;
249  
250         write_disable(nor);
251 -       ret = wait_till_ready(nor);
252 +       ret = spi_nor_wait_till_ready(nor);
253         if (ret)
254                 goto time_out;
255  
256 @@ -750,7 +735,7 @@ static int sst_write(struct mtd_info *mt
257                 nor->program_opcode = SPINOR_OP_BP;
258                 nor->write(nor, to, 1, retlen, buf + actual);
259  
260 -               ret = wait_till_ready(nor);
261 +               ret = spi_nor_wait_till_ready(nor);
262                 if (ret)
263                         goto time_out;
264                 write_disable(nor);
265 @@ -778,11 +763,6 @@ static int spi_nor_write(struct mtd_info
266         if (ret)
267                 return ret;
268  
269 -       /* Wait until finished previous write command. */
270 -       ret = wait_till_ready(nor);
271 -       if (ret)
272 -               goto write_err;
273 -
274         write_enable(nor);
275  
276         page_offset = to & (nor->page_size - 1);
277 @@ -801,16 +781,20 @@ static int spi_nor_write(struct mtd_info
278                         if (page_size > nor->page_size)
279                                 page_size = nor->page_size;
280  
281 -                       wait_till_ready(nor);
282 +                       ret = spi_nor_wait_till_ready(nor);
283 +                       if (ret)
284 +                               goto write_err;
285 +
286                         write_enable(nor);
287  
288                         nor->write(nor, to + i, page_size, retlen, buf + i);
289                 }
290         }
291  
292 +       ret = spi_nor_wait_till_ready(nor);
293  write_err:
294         spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
295 -       return 0;
296 +       return ret;
297  }
298  
299  static int macronix_quad_enable(struct spi_nor *nor)
300 @@ -823,7 +807,7 @@ static int macronix_quad_enable(struct s
301         nor->cmd_buf[0] = val | SR_QUAD_EN_MX;
302         nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0);
303  
304 -       if (wait_till_ready(nor))
305 +       if (spi_nor_wait_till_ready(nor))
306                 return 1;
307  
308         ret = read_sr(nor);
309 @@ -905,8 +889,6 @@ static int spi_nor_check(struct spi_nor
310  
311         if (!nor->read_id)
312                 nor->read_id = spi_nor_read_id;
313 -       if (!nor->wait_till_ready)
314 -               nor->wait_till_ready = spi_nor_wait_till_ready;
315  
316         return 0;
317  }
318 @@ -977,9 +959,8 @@ int spi_nor_scan(struct spi_nor *nor, co
319         else
320                 mtd->_write = spi_nor_write;
321  
322 -       if ((info->flags & USE_FSR) &&
323 -           nor->wait_till_ready == spi_nor_wait_till_ready)
324 -               nor->wait_till_ready = spi_nor_wait_till_fsr_ready;
325 +       if (info->flags & USE_FSR)
326 +               nor->flags |= SNOR_F_USE_FSR;
327  
328  #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
329         /* prefer "small sector" erase if possible */
330 --- a/include/linux/mtd/spi-nor.h
331 +++ b/include/linux/mtd/spi-nor.h
332 @@ -116,6 +116,10 @@ enum spi_nor_ops {
333         SPI_NOR_OPS_UNLOCK,
334  };
335  
336 +enum spi_nor_option_flags {
337 +       SNOR_F_USE_FSR          = BIT(0),
338 +};
339 +
340  /**
341   * struct spi_nor - Structure for defining a the SPI NOR layer
342   * @mtd:               point to a mtd_info structure
343 @@ -129,6 +133,7 @@ enum spi_nor_ops {
344   * @program_opcode:    the program opcode
345   * @flash_read:                the mode of the read
346   * @sst_write_second:  used by the SST write operation
347 + * @flags:             flag options for the current SPI-NOR (SNOR_F_*)
348   * @cfg:               used by the read_xfer/write_xfer
349   * @cmd_buf:           used by the write_reg
350   * @prepare:           [OPTIONAL] do some preparations for the
351 @@ -141,7 +146,6 @@ enum spi_nor_ops {
352   * @write_reg:         [DRIVER-SPECIFIC] write data to the register
353   * @read_id:           [REPLACEABLE] read out the ID data, and find
354   *                     the proper spi_device_id
355 - * @wait_till_ready:   [REPLACEABLE] wait till the NOR becomes ready
356   * @read:              [DRIVER-SPECIFIC] read data from the SPI NOR
357   * @write:             [DRIVER-SPECIFIC] write data to the SPI NOR
358   * @erase:             [DRIVER-SPECIFIC] erase a sector of the SPI NOR
359 @@ -160,6 +164,7 @@ struct spi_nor {
360         u8                      program_opcode;
361         enum read_mode          flash_read;
362         bool                    sst_write_second;
363 +       u32                     flags;
364         struct spi_nor_xfer_cfg cfg;
365         u8                      cmd_buf[SPI_NOR_MAX_CMD_SIZE];
366  
367 @@ -173,7 +178,6 @@ struct spi_nor {
368         int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
369                         int write_enable);
370         const struct spi_device_id *(*read_id)(struct spi_nor *nor);
371 -       int (*wait_till_ready)(struct spi_nor *nor);
372  
373         int (*read)(struct spi_nor *nor, loff_t from,
374                         size_t len, size_t *retlen, u_char *read_buf);