ramips: add linux 4.4 support, update mt7621 subtarget to 4.4
[openwrt.git] / target / linux / ramips / patches-4.4 / 0054-mtd-add-chunked-read-io-to-m25p80.patch
1 --- a/drivers/mtd/spi-nor/spi-nor.c
2 +++ b/drivers/mtd/spi-nor/spi-nor.c
3 @@ -1011,6 +1011,66 @@ write_err:
4         return ret;
5  }
6  
7 +static int spi_nor_chunked_write(struct mtd_info *mtd, loff_t _to, size_t _len,
8 +                                size_t *_retlen, const u_char *_buf)
9 +{
10 +       struct spi_nor *nor = mtd_to_spi_nor(mtd);
11 +       int chunk_size;
12 +       int retlen = 0;
13 +       int ret;
14 +
15 +       chunk_size = nor->chunk_size;
16 +       if (!chunk_size)
17 +               chunk_size = _len;
18 +
19 +       if (nor->addr_width > 3)
20 +               chunk_size -= nor->addr_width - 3;
21 +
22 +       while (retlen < _len) {
23 +               size_t len = min_t(int, chunk_size, _len - retlen);
24 +               const u_char *buf = _buf + retlen;
25 +               loff_t to = _to + retlen;
26 +
27 +               if (nor->flags & SNOR_F_SST)
28 +                       ret = sst_write(mtd, to, len, &retlen, buf);
29 +               else
30 +                       ret = spi_nor_write(mtd, to, len, &retlen, buf);
31 +               if (ret)
32 +                       return ret;
33 +       }
34 +
35 +       *_retlen += retlen;
36 +       return 0;
37 +}
38 +
39 +static int spi_nor_chunked_read(struct mtd_info *mtd, loff_t _from, size_t _len,
40 +                               size_t *_retlen, u_char *_buf)
41 +{
42 +       struct spi_nor *nor = mtd_to_spi_nor(mtd);
43 +       int chunk_size;
44 +       int ret;
45 +
46 +       chunk_size = nor->chunk_size;
47 +       if (!chunk_size)
48 +               chunk_size = _len;
49 +
50 +       *_retlen = 0;
51 +       while (*_retlen < _len) {
52 +               size_t len = min_t(int, chunk_size, _len - *_retlen);
53 +               u_char *buf = _buf + *_retlen;
54 +               loff_t from = _from + *_retlen;
55 +               int retlen = 0;
56 +
57 +               ret = spi_nor_read(mtd, from, len, &retlen, buf);
58 +               if (ret)
59 +                       return ret;
60 +
61 +               *_retlen += retlen;
62 +       }
63 +
64 +       return 0;
65 +}
66 +
67  static int macronix_quad_enable(struct spi_nor *nor)
68  {
69         int ret, val;
70 @@ -1232,10 +1292,12 @@ int spi_nor_scan(struct spi_nor *nor, co
71         }
72  
73         /* sst nor chips use AAI word program */
74 -       if (info->flags & SST_WRITE)
75 +       if (info->flags & SST_WRITE) {
76                 mtd->_write = sst_write;
77 -       else
78 +               nor->flags |= SNOR_F_SST;
79 +       } else {
80                 mtd->_write = spi_nor_write;
81 +       }
82  
83         if (info->flags & USE_FSR)
84                 nor->flags |= SNOR_F_USE_FSR;
85 @@ -1263,11 +1325,20 @@ int spi_nor_scan(struct spi_nor *nor, co
86         mtd->writebufsize = nor->page_size;
87  
88         if (np) {
89 +               u32 val;
90 +
91                 /* If we were instantiated by DT, use it */
92                 if (of_property_read_bool(np, "m25p,fast-read"))
93                         nor->flash_read = SPI_NOR_FAST;
94                 else
95                         nor->flash_read = SPI_NOR_NORMAL;
96 +
97 +               if (!of_property_read_u32(np, "m25p,chunked-io", &val)) {
98 +                       dev_info(dev, "using chunked io (size=%d)\n", val);
99 +                       mtd->_read = spi_nor_chunked_read;
100 +                       mtd->_write = spi_nor_chunked_write;
101 +                       nor->chunk_size = val;
102 +               }
103         } else {
104                 /* If we weren't instantiated by DT, default to fast-read */
105                 nor->flash_read = SPI_NOR_FAST;
106 --- a/include/linux/mtd/spi-nor.h
107 +++ b/include/linux/mtd/spi-nor.h
108 @@ -116,6 +116,7 @@ enum spi_nor_ops {
109  
110  enum spi_nor_option_flags {
111         SNOR_F_USE_FSR          = BIT(0),
112 +       SNOR_F_SST              = BIT(1),
113  };
114  
115  /**
116 @@ -156,6 +157,7 @@ struct spi_nor {
117         struct device           *dev;
118         struct device_node      *flash_node;
119         u32                     page_size;
120 +       u16                     chunk_size;
121         u8                      addr_width;
122         u8                      erase_opcode;
123         u8                      read_opcode;