Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / mtd / devices / bcm47xxsflash.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/slab.h>
4 #include <linux/delay.h>
5 #include <linux/mtd/mtd.h>
6 #include <linux/platform_device.h>
7 #include <linux/bcma/bcma.h>
8
9 #include "bcm47xxsflash.h"
10
11 MODULE_LICENSE("GPL");
12 MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
13
14 static const char * const probes[] = { "bcm47xxpart", NULL };
15
16 /**************************************************
17  * Various helpers
18  **************************************************/
19
20 static void bcm47xxsflash_cmd(struct bcm47xxsflash *b47s, u32 opcode)
21 {
22         int i;
23
24         b47s->cc_write(b47s, BCMA_CC_FLASHCTL, BCMA_CC_FLASHCTL_START | opcode);
25         for (i = 0; i < 1000; i++) {
26                 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHCTL) &
27                       BCMA_CC_FLASHCTL_BUSY))
28                         return;
29                 cpu_relax();
30         }
31         pr_err("Control command failed (timeout)!\n");
32 }
33
34 static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout)
35 {
36         unsigned long deadline = jiffies + timeout;
37
38         do {
39                 switch (b47s->type) {
40                 case BCM47XXSFLASH_TYPE_ST:
41                         bcm47xxsflash_cmd(b47s, OPCODE_ST_RDSR);
42                         if (!(b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
43                               SR_ST_WIP))
44                                 return 0;
45                         break;
46                 case BCM47XXSFLASH_TYPE_ATMEL:
47                         bcm47xxsflash_cmd(b47s, OPCODE_AT_STATUS);
48                         if (b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
49                             SR_AT_READY)
50                                 return 0;
51                         break;
52                 }
53
54                 cpu_relax();
55                 udelay(1);
56         } while (!time_after_eq(jiffies, deadline));
57
58         pr_err("Timeout waiting for flash to be ready!\n");
59
60         return -EBUSY;
61 }
62
63 /**************************************************
64  * MTD ops
65  **************************************************/
66
67 static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
68 {
69         struct bcm47xxsflash *b47s = mtd->priv;
70         int err;
71
72         switch (b47s->type) {
73         case BCM47XXSFLASH_TYPE_ST:
74                 bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
75                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr);
76                 /* Newer flashes have "sub-sectors" which can be erased
77                  * independently with a new command: ST_SSE. The ST_SE command
78                  * erases 64KB just as before.
79                  */
80                 if (b47s->blocksize < (64 * 1024))
81                         bcm47xxsflash_cmd(b47s, OPCODE_ST_SSE);
82                 else
83                         bcm47xxsflash_cmd(b47s, OPCODE_ST_SE);
84                 break;
85         case BCM47XXSFLASH_TYPE_ATMEL:
86                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr << 1);
87                 bcm47xxsflash_cmd(b47s, OPCODE_AT_PAGE_ERASE);
88                 break;
89         }
90
91         err = bcm47xxsflash_poll(b47s, HZ);
92         if (err)
93                 erase->state = MTD_ERASE_FAILED;
94         else
95                 erase->state = MTD_ERASE_DONE;
96
97         if (erase->callback)
98                 erase->callback(erase);
99
100         return err;
101 }
102
103 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
104                               size_t *retlen, u_char *buf)
105 {
106         struct bcm47xxsflash *b47s = mtd->priv;
107
108         /* Check address range */
109         if ((from + len) > mtd->size)
110                 return -EINVAL;
111
112         memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(b47s->window + from),
113                       len);
114         *retlen = len;
115
116         return len;
117 }
118
119 static int bcm47xxsflash_write_st(struct mtd_info *mtd, u32 offset, size_t len,
120                                   const u_char *buf)
121 {
122         struct bcm47xxsflash *b47s = mtd->priv;
123         int written = 0;
124
125         /* Enable writes */
126         bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
127
128         /* Write first byte */
129         b47s->cc_write(b47s, BCMA_CC_FLASHADDR, offset);
130         b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++);
131
132         /* Program page */
133         if (b47s->bcma_cc->core->id.rev < 20) {
134                 bcm47xxsflash_cmd(b47s, OPCODE_ST_PP);
135                 return 1; /* 1B written */
136         }
137
138         /* Program page and set CSA (on newer chips we can continue writing) */
139         bcm47xxsflash_cmd(b47s, OPCODE_ST_CSA | OPCODE_ST_PP);
140         offset++;
141         len--;
142         written++;
143
144         while (len > 0) {
145                 /* Page boundary, another function call is needed */
146                 if ((offset & 0xFF) == 0)
147                         break;
148
149                 bcm47xxsflash_cmd(b47s, OPCODE_ST_CSA | *buf++);
150                 offset++;
151                 len--;
152                 written++;
153         }
154
155         /* All done, drop CSA & poll */
156         b47s->cc_write(b47s, BCMA_CC_FLASHCTL, 0);
157         udelay(1);
158         if (bcm47xxsflash_poll(b47s, HZ / 10))
159                 pr_err("Flash rejected dropping CSA\n");
160
161         return written;
162 }
163
164 static int bcm47xxsflash_write_at(struct mtd_info *mtd, u32 offset, size_t len,
165                                   const u_char *buf)
166 {
167         struct bcm47xxsflash *b47s = mtd->priv;
168         u32 mask = b47s->blocksize - 1;
169         u32 page = (offset & ~mask) << 1;
170         u32 byte = offset & mask;
171         int written = 0;
172
173         /* If we don't overwrite whole page, read it to the buffer first */
174         if (byte || (len < b47s->blocksize)) {
175                 int err;
176
177                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page);
178                 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_LOAD);
179                 /* 250 us for AT45DB321B */
180                 err = bcm47xxsflash_poll(b47s, HZ / 1000);
181                 if (err) {
182                         pr_err("Timeout reading page 0x%X info buffer\n", page);
183                         return err;
184                 }
185         }
186
187         /* Change buffer content with our data */
188         while (len > 0) {
189                 /* Page boundary, another function call is needed */
190                 if (byte == b47s->blocksize)
191                         break;
192
193                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, byte++);
194                 b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++);
195                 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_WRITE);
196                 len--;
197                 written++;
198         }
199
200         /* Program page with the buffer content */
201         b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page);
202         bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_PROGRAM);
203
204         return written;
205 }
206
207 static int bcm47xxsflash_write(struct mtd_info *mtd, loff_t to, size_t len,
208                                size_t *retlen, const u_char *buf)
209 {
210         struct bcm47xxsflash *b47s = mtd->priv;
211         int written;
212
213         /* Writing functions can return without writing all passed data, for
214          * example when the hardware is too old or when we git page boundary.
215          */
216         while (len > 0) {
217                 switch (b47s->type) {
218                 case BCM47XXSFLASH_TYPE_ST:
219                         written = bcm47xxsflash_write_st(mtd, to, len, buf);
220                         break;
221                 case BCM47XXSFLASH_TYPE_ATMEL:
222                         written = bcm47xxsflash_write_at(mtd, to, len, buf);
223                         break;
224                 default:
225                         BUG_ON(1);
226                 }
227                 if (written < 0) {
228                         pr_err("Error writing at offset 0x%llX\n", to);
229                         return written;
230                 }
231                 to += (loff_t)written;
232                 len -= written;
233                 *retlen += written;
234                 buf += written;
235         }
236
237         return 0;
238 }
239
240 static void bcm47xxsflash_fill_mtd(struct bcm47xxsflash *b47s)
241 {
242         struct mtd_info *mtd = &b47s->mtd;
243
244         mtd->priv = b47s;
245         mtd->name = "bcm47xxsflash";
246         mtd->owner = THIS_MODULE;
247
248         mtd->type = MTD_NORFLASH;
249         mtd->flags = MTD_CAP_NORFLASH;
250         mtd->size = b47s->size;
251         mtd->erasesize = b47s->blocksize;
252         mtd->writesize = 1;
253         mtd->writebufsize = 1;
254
255         mtd->_erase = bcm47xxsflash_erase;
256         mtd->_read = bcm47xxsflash_read;
257         mtd->_write = bcm47xxsflash_write;
258 }
259
260 /**************************************************
261  * BCMA
262  **************************************************/
263
264 static int bcm47xxsflash_bcma_cc_read(struct bcm47xxsflash *b47s, u16 offset)
265 {
266         return bcma_cc_read32(b47s->bcma_cc, offset);
267 }
268
269 static void bcm47xxsflash_bcma_cc_write(struct bcm47xxsflash *b47s, u16 offset,
270                                         u32 value)
271 {
272         bcma_cc_write32(b47s->bcma_cc, offset, value);
273 }
274
275 static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
276 {
277         struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
278         struct bcm47xxsflash *b47s;
279         int err;
280
281         b47s = devm_kzalloc(&pdev->dev, sizeof(*b47s), GFP_KERNEL);
282         if (!b47s)
283                 return -ENOMEM;
284         sflash->priv = b47s;
285
286         b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
287         b47s->cc_read = bcm47xxsflash_bcma_cc_read;
288         b47s->cc_write = bcm47xxsflash_bcma_cc_write;
289
290         switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) {
291         case BCMA_CC_FLASHT_STSER:
292                 b47s->type = BCM47XXSFLASH_TYPE_ST;
293                 break;
294         case BCMA_CC_FLASHT_ATSER:
295                 b47s->type = BCM47XXSFLASH_TYPE_ATMEL;
296                 break;
297         }
298
299         b47s->window = sflash->window;
300         b47s->blocksize = sflash->blocksize;
301         b47s->numblocks = sflash->numblocks;
302         b47s->size = sflash->size;
303         bcm47xxsflash_fill_mtd(b47s);
304
305         err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
306         if (err) {
307                 pr_err("Failed to register MTD device: %d\n", err);
308                 return err;
309         }
310
311         if (bcm47xxsflash_poll(b47s, HZ / 10))
312                 pr_warn("Serial flash busy\n");
313
314         return 0;
315 }
316
317 static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
318 {
319         struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
320         struct bcm47xxsflash *b47s = sflash->priv;
321
322         mtd_device_unregister(&b47s->mtd);
323
324         return 0;
325 }
326
327 static struct platform_driver bcma_sflash_driver = {
328         .probe  = bcm47xxsflash_bcma_probe,
329         .remove = bcm47xxsflash_bcma_remove,
330         .driver = {
331                 .name = "bcma_sflash",
332         },
333 };
334
335 /**************************************************
336  * Init
337  **************************************************/
338
339 module_platform_driver(bcma_sflash_driver);