Merge tag 'acpi-4.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[cascardo/linux.git] / 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/ioport.h>
6 #include <linux/mtd/mtd.h>
7 #include <linux/platform_device.h>
8 #include <linux/bcma/bcma.h>
9
10 #include "bcm47xxsflash.h"
11
12 MODULE_LICENSE("GPL");
13 MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
14
15 static const char * const probes[] = { "bcm47xxpart", NULL };
16
17 /**************************************************
18  * Various helpers
19  **************************************************/
20
21 static void bcm47xxsflash_cmd(struct bcm47xxsflash *b47s, u32 opcode)
22 {
23         int i;
24
25         b47s->cc_write(b47s, BCMA_CC_FLASHCTL, BCMA_CC_FLASHCTL_START | opcode);
26         for (i = 0; i < 1000; i++) {
27                 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHCTL) &
28                       BCMA_CC_FLASHCTL_BUSY))
29                         return;
30                 cpu_relax();
31         }
32         pr_err("Control command failed (timeout)!\n");
33 }
34
35 static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout)
36 {
37         unsigned long deadline = jiffies + timeout;
38
39         do {
40                 switch (b47s->type) {
41                 case BCM47XXSFLASH_TYPE_ST:
42                         bcm47xxsflash_cmd(b47s, OPCODE_ST_RDSR);
43                         if (!(b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
44                               SR_ST_WIP))
45                                 return 0;
46                         break;
47                 case BCM47XXSFLASH_TYPE_ATMEL:
48                         bcm47xxsflash_cmd(b47s, OPCODE_AT_STATUS);
49                         if (b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
50                             SR_AT_READY)
51                                 return 0;
52                         break;
53                 }
54
55                 cpu_relax();
56                 udelay(1);
57         } while (!time_after_eq(jiffies, deadline));
58
59         pr_err("Timeout waiting for flash to be ready!\n");
60
61         return -EBUSY;
62 }
63
64 /**************************************************
65  * MTD ops
66  **************************************************/
67
68 static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
69 {
70         struct bcm47xxsflash *b47s = mtd->priv;
71         int err;
72
73         switch (b47s->type) {
74         case BCM47XXSFLASH_TYPE_ST:
75                 bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
76                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr);
77                 /* Newer flashes have "sub-sectors" which can be erased
78                  * independently with a new command: ST_SSE. The ST_SE command
79                  * erases 64KB just as before.
80                  */
81                 if (b47s->blocksize < (64 * 1024))
82                         bcm47xxsflash_cmd(b47s, OPCODE_ST_SSE);
83                 else
84                         bcm47xxsflash_cmd(b47s, OPCODE_ST_SE);
85                 break;
86         case BCM47XXSFLASH_TYPE_ATMEL:
87                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr << 1);
88                 bcm47xxsflash_cmd(b47s, OPCODE_AT_PAGE_ERASE);
89                 break;
90         }
91
92         err = bcm47xxsflash_poll(b47s, HZ);
93         if (err)
94                 erase->state = MTD_ERASE_FAILED;
95         else
96                 erase->state = MTD_ERASE_DONE;
97
98         if (erase->callback)
99                 erase->callback(erase);
100
101         return err;
102 }
103
104 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
105                               size_t *retlen, u_char *buf)
106 {
107         struct bcm47xxsflash *b47s = mtd->priv;
108
109         /* Check address range */
110         if ((from + len) > mtd->size)
111                 return -EINVAL;
112
113         memcpy_fromio(buf, b47s->window + from, 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                                    struct device *dev)
242 {
243         struct mtd_info *mtd = &b47s->mtd;
244
245         mtd->priv = b47s;
246         mtd->dev.parent = dev;
247         mtd->name = "bcm47xxsflash";
248
249         mtd->type = MTD_NORFLASH;
250         mtd->flags = MTD_CAP_NORFLASH;
251         mtd->size = b47s->size;
252         mtd->erasesize = b47s->blocksize;
253         mtd->writesize = 1;
254         mtd->writebufsize = 1;
255
256         mtd->_erase = bcm47xxsflash_erase;
257         mtd->_read = bcm47xxsflash_read;
258         mtd->_write = bcm47xxsflash_write;
259 }
260
261 /**************************************************
262  * BCMA
263  **************************************************/
264
265 static int bcm47xxsflash_bcma_cc_read(struct bcm47xxsflash *b47s, u16 offset)
266 {
267         return bcma_cc_read32(b47s->bcma_cc, offset);
268 }
269
270 static void bcm47xxsflash_bcma_cc_write(struct bcm47xxsflash *b47s, u16 offset,
271                                         u32 value)
272 {
273         bcma_cc_write32(b47s->bcma_cc, offset, value);
274 }
275
276 static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
277 {
278         struct device *dev = &pdev->dev;
279         struct bcma_sflash *sflash = dev_get_platdata(dev);
280         struct bcm47xxsflash *b47s;
281         struct resource *res;
282         int err;
283
284         b47s = devm_kzalloc(dev, sizeof(*b47s), GFP_KERNEL);
285         if (!b47s)
286                 return -ENOMEM;
287         sflash->priv = b47s;
288
289         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
290         if (!res) {
291                 dev_err(dev, "invalid resource\n");
292                 return -EINVAL;
293         }
294         if (!devm_request_mem_region(dev, res->start, resource_size(res),
295                                      res->name)) {
296                 dev_err(dev, "can't request region for resource %pR\n", res);
297                 return -EBUSY;
298         }
299         b47s->window = ioremap_cache(res->start, resource_size(res));
300         if (!b47s->window) {
301                 dev_err(dev, "ioremap failed for resource %pR\n", res);
302                 return -ENOMEM;
303         }
304
305         b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
306         b47s->cc_read = bcm47xxsflash_bcma_cc_read;
307         b47s->cc_write = bcm47xxsflash_bcma_cc_write;
308
309         switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) {
310         case BCMA_CC_FLASHT_STSER:
311                 b47s->type = BCM47XXSFLASH_TYPE_ST;
312                 break;
313         case BCMA_CC_FLASHT_ATSER:
314                 b47s->type = BCM47XXSFLASH_TYPE_ATMEL;
315                 break;
316         }
317
318         b47s->blocksize = sflash->blocksize;
319         b47s->numblocks = sflash->numblocks;
320         b47s->size = sflash->size;
321         bcm47xxsflash_fill_mtd(b47s, &pdev->dev);
322
323         err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
324         if (err) {
325                 pr_err("Failed to register MTD device: %d\n", err);
326                 iounmap(b47s->window);
327                 return err;
328         }
329
330         if (bcm47xxsflash_poll(b47s, HZ / 10))
331                 pr_warn("Serial flash busy\n");
332
333         return 0;
334 }
335
336 static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
337 {
338         struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
339         struct bcm47xxsflash *b47s = sflash->priv;
340
341         mtd_device_unregister(&b47s->mtd);
342         iounmap(b47s->window);
343
344         return 0;
345 }
346
347 static struct platform_driver bcma_sflash_driver = {
348         .probe  = bcm47xxsflash_bcma_probe,
349         .remove = bcm47xxsflash_bcma_remove,
350         .driver = {
351                 .name = "bcma_sflash",
352         },
353 };
354
355 /**************************************************
356  * Init
357  **************************************************/
358
359 module_platform_driver(bcma_sflash_driver);