d8b268164ec650b000633c908bc7a8099e372bf3
[openwrt/staging/nbd.git] / target / linux / pistachio / patches-4.9 / 413-mtd-Introduce-SPI-NAND-framework.patch
1 From 082a89a78e29b15008284df90441747cb742f149 Mon Sep 17 00:00:00 2001
2 From: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
3 Date: Tue, 2 Dec 2014 09:58:52 -0300
4 Subject: mtd: Introduce SPI NAND framework
5
6 Add a new framework, to support SPI NAND devices. The framework registers
7 a NAND chip and handles the generic SPI NAND protocol, calling device-specific
8 hooks for each SPI NAND command.
9
10 The following is the stack design, from userspace to hardware. This commit
11 adds the "SPI NAND core" layer.
12
13 Userspace
14 ------------------
15 MTD
16 ------------------
17 NAND core
18 ------------------
19 SPI NAND core
20 ------------------
21 SPI NAND device
22 ------------------
23 SPI core
24 ------------------
25 SPI master
26 ------------------
27 Hardware
28
29 (based on http://lists.infradead.org/pipermail/linux-mtd/2014-December/056763.html)
30
31 Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
32 Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
33 Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
34 ---
35 drivers/mtd/Kconfig | 2 +
36 drivers/mtd/Makefile | 1 +
37 drivers/mtd/spi-nand/Kconfig | 7 +
38 drivers/mtd/spi-nand/Makefile | 1 +
39 drivers/mtd/spi-nand/spi-nand-base.c | 566 +++++++++++++++++++++++++++++++++++
40 include/linux/mtd/spi-nand.h | 54 ++++
41 6 files changed, 631 insertions(+)
42 create mode 100644 drivers/mtd/spi-nand/Kconfig
43 create mode 100644 drivers/mtd/spi-nand/Makefile
44 create mode 100644 drivers/mtd/spi-nand/spi-nand-base.c
45 create mode 100644 include/linux/mtd/spi-nand.h
46
47 diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
48 index e83a279..9163d7f 100644
49 --- a/drivers/mtd/Kconfig
50 +++ b/drivers/mtd/Kconfig
51 @@ -334,6 +334,8 @@ source "drivers/mtd/onenand/Kconfig"
52
53 source "drivers/mtd/lpddr/Kconfig"
54
55 +source "drivers/mtd/spi-nand/Kconfig"
56 +
57 source "drivers/mtd/spi-nor/Kconfig"
58
59 source "drivers/mtd/ubi/Kconfig"
60 diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
61 index 99bb9a1..38a4756 100644
62 --- a/drivers/mtd/Makefile
63 +++ b/drivers/mtd/Makefile
64 @@ -32,5 +32,6 @@ inftl-objs := inftlcore.o inftlmount.o
65
66 obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
67
68 +obj-$(CONFIG_MTD_SPI_NAND) += spi-nand/
69 obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
70 obj-$(CONFIG_MTD_UBI) += ubi/
71 diff --git a/drivers/mtd/spi-nand/Kconfig b/drivers/mtd/spi-nand/Kconfig
72 new file mode 100644
73 index 0000000..17b31e1
74 --- /dev/null
75 +++ b/drivers/mtd/spi-nand/Kconfig
76 @@ -0,0 +1,7 @@
77 +menuconfig MTD_SPI_NAND
78 + tristate "SPI NAND device support"
79 + depends on MTD
80 + select MTD_NAND
81 + help
82 + This is the framework for the SPI NAND.
83 +
84 diff --git a/drivers/mtd/spi-nand/Makefile b/drivers/mtd/spi-nand/Makefile
85 new file mode 100644
86 index 0000000..d454c52
87 --- /dev/null
88 +++ b/drivers/mtd/spi-nand/Makefile
89 @@ -0,0 +1 @@
90 +obj-$(CONFIG_MTD_SPI_NAND) += spi-nand-base.o
91 diff --git a/drivers/mtd/spi-nand/spi-nand-base.c b/drivers/mtd/spi-nand/spi-nand-base.c
92 new file mode 100644
93 index 0000000..5d79f85
94 --- /dev/null
95 +++ b/drivers/mtd/spi-nand/spi-nand-base.c
96 @@ -0,0 +1,566 @@
97 +/*
98 + * Copyright (C) 2014 Imagination Technologies Ltd.
99 + *
100 + * This program is free software; you can redistribute it and/or modify
101 + * it under the terms of the GNU General Public License as published by
102 + * the Free Software Foundation; version 2 of the License.
103 + *
104 + * Notes:
105 + * 1. Erase and program operations need to call write_enable() first,
106 + * to clear the enable bit. This bit is cleared automatically after
107 + * the erase or program operation.
108 + *
109 + */
110 +
111 +#include <linux/device.h>
112 +#include <linux/err.h>
113 +#include <linux/errno.h>
114 +#include <linux/kernel.h>
115 +#include <linux/module.h>
116 +#include <linux/mtd/nand.h>
117 +#include <linux/mtd/mtd.h>
118 +#include <linux/mtd/partitions.h>
119 +#include <linux/mtd/spi-nand.h>
120 +#include <linux/of.h>
121 +#include <linux/slab.h>
122 +
123 +/* Registers common to all devices */
124 +#define SPI_NAND_LOCK_REG 0xa0
125 +#define SPI_NAND_PROT_UNLOCK_ALL 0x0
126 +
127 +#define SPI_NAND_FEATURE_REG 0xb0
128 +#define SPI_NAND_ECC_EN BIT(4)
129 +#define SPI_NAND_QUAD_EN BIT(0)
130 +
131 +#define SPI_NAND_STATUS_REG 0xc0
132 +#define SPI_NAND_STATUS_REG_ECC_MASK 0x3
133 +#define SPI_NAND_STATUS_REG_ECC_SHIFT 4
134 +#define SPI_NAND_STATUS_REG_PROG_FAIL BIT(3)
135 +#define SPI_NAND_STATUS_REG_ERASE_FAIL BIT(2)
136 +#define SPI_NAND_STATUS_REG_WREN BIT(1)
137 +#define SPI_NAND_STATUS_REG_BUSY BIT(0)
138 +
139 +#define SPI_NAND_CMD_BUF_LEN 8
140 +
141 +/* Rewind and fill the buffer with 0xff */
142 +static void spi_nand_clear_buffer(struct spi_nand *snand)
143 +{
144 + snand->buf_start = 0;
145 + memset(snand->data_buf, 0xff, snand->buf_size);
146 +}
147 +
148 +static int spi_nand_enable_ecc(struct spi_nand *snand)
149 +{
150 + int ret;
151 +
152 + ret = snand->read_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
153 + if (ret)
154 + return ret;
155 +
156 + snand->buf[0] |= SPI_NAND_ECC_EN;
157 + ret = snand->write_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
158 + if (ret)
159 + return ret;
160 + snand->ecc = true;
161 +
162 + return 0;
163 +}
164 +
165 +static int spi_nand_disable_ecc(struct spi_nand *snand)
166 +{
167 + int ret;
168 +
169 + ret = snand->read_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
170 + if (ret)
171 + return ret;
172 +
173 + snand->buf[0] &= ~SPI_NAND_ECC_EN;
174 + ret = snand->write_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
175 + if (ret)
176 + return ret;
177 + snand->ecc = false;
178 +
179 + return 0;
180 +}
181 +
182 +static int spi_nand_enable_quad(struct spi_nand *snand)
183 +{
184 + int ret;
185 +
186 + ret = snand->read_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
187 + if (ret)
188 + return ret;
189 +
190 + snand->buf[0] |= SPI_NAND_QUAD_EN;
191 + ret = snand->write_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
192 + if (ret)
193 + return ret;
194 +
195 + return 0;
196 +}
197 +/*
198 + * Wait until the status register busy bit is cleared.
199 + * Returns a negatie errno on error or time out, and a non-negative status
200 + * value if the device is ready.
201 + */
202 +static int spi_nand_wait_till_ready(struct spi_nand *snand)
203 +{
204 + unsigned long deadline = jiffies + msecs_to_jiffies(100);
205 + bool timeout = false;
206 + int ret;
207 +
208 + /*
209 + * Perhaps we should set a different timeout for each
210 + * operation (reset, read, write, erase).
211 + */
212 + while (!timeout) {
213 + if (time_after_eq(jiffies, deadline))
214 + timeout = true;
215 +
216 + ret = snand->read_reg(snand, SPI_NAND_STATUS_REG, snand->buf);
217 + if (ret < 0) {
218 + dev_err(snand->dev, "error reading status register\n");
219 + return ret;
220 + } else if (!(snand->buf[0] & SPI_NAND_STATUS_REG_BUSY)) {
221 + return snand->buf[0];
222 + }
223 +
224 + cond_resched();
225 + }
226 +
227 + dev_err(snand->dev, "operation timed out\n");
228 +
229 + return -ETIMEDOUT;
230 +}
231 +
232 +static int spi_nand_reset(struct spi_nand *snand)
233 +{
234 + int ret;
235 +
236 + ret = snand->reset(snand);
237 + if (ret < 0) {
238 + dev_err(snand->dev, "reset command failed\n");
239 + return ret;
240 + }
241 +
242 + /*
243 + * The NAND core won't wait after a device reset, so we need
244 + * to do that here.
245 + */
246 + ret = spi_nand_wait_till_ready(snand);
247 + if (ret < 0)
248 + return ret;
249 + return 0;
250 +}
251 +
252 +static int spi_nand_status(struct spi_nand *snand)
253 +{
254 + int ret, status;
255 +
256 + ret = snand->read_reg(snand, SPI_NAND_STATUS_REG, snand->buf);
257 + if (ret < 0) {
258 + dev_err(snand->dev, "error reading status register\n");
259 + return ret;
260 + }
261 + status = snand->buf[0];
262 +
263 + /* Convert this into standard NAND_STATUS values */
264 + if (status & SPI_NAND_STATUS_REG_BUSY)
265 + snand->buf[0] = 0;
266 + else
267 + snand->buf[0] = NAND_STATUS_READY;
268 +
269 + if (status & SPI_NAND_STATUS_REG_PROG_FAIL ||
270 + status & SPI_NAND_STATUS_REG_ERASE_FAIL)
271 + snand->buf[0] |= NAND_STATUS_FAIL;
272 +
273 + /*
274 + * Since we unlock the entire device at initialization, unconditionally
275 + * set the WP bit to indicate it's not protected.
276 + */
277 + snand->buf[0] |= NAND_STATUS_WP;
278 + return 0;
279 +}
280 +
281 +static int spi_nand_erase(struct spi_nand *snand, int page_addr)
282 +{
283 + int ret;
284 +
285 + ret = snand->write_enable(snand);
286 + if (ret < 0) {
287 + dev_err(snand->dev, "write enable command failed\n");
288 + return ret;
289 + }
290 +
291 + ret = snand->block_erase(snand, page_addr);
292 + if (ret < 0) {
293 + dev_err(snand->dev, "block erase command failed\n");
294 + return ret;
295 + }
296 +
297 + return 0;
298 +}
299 +
300 +static int spi_nand_write(struct spi_nand *snand)
301 +{
302 + int ret;
303 +
304 + /* Enable quad mode */
305 + ret = spi_nand_enable_quad(snand);
306 + if (ret) {
307 + dev_err(snand->dev, "error %d enabling quad mode\n", ret);
308 + return ret;
309 + }
310 + /* Store the page to cache */
311 + ret = snand->store_cache(snand, 0, snand->buf_size, snand->data_buf);
312 + if (ret < 0) {
313 + dev_err(snand->dev, "error %d storing page 0x%x to cache\n",
314 + ret, snand->page_addr);
315 + return ret;
316 + }
317 +
318 + ret = snand->write_enable(snand);
319 + if (ret < 0) {
320 + dev_err(snand->dev, "write enable command failed\n");
321 + return ret;
322 + }
323 +
324 + /* Get page from the device cache into our internal buffer */
325 + ret = snand->write_page(snand, snand->page_addr);
326 + if (ret < 0) {
327 + dev_err(snand->dev, "error %d reading page 0x%x from cache\n",
328 + ret, snand->page_addr);
329 + return ret;
330 + }
331 +
332 + return 0;
333 +}
334 +
335 +static int spi_nand_read_id(struct spi_nand *snand)
336 +{
337 + int ret;
338 +
339 + ret = snand->read_id(snand, snand->data_buf);
340 + if (ret < 0) {
341 + dev_err(snand->dev, "error %d reading ID\n", ret);
342 + return ret;
343 + }
344 + return 0;
345 +}
346 +
347 +static int spi_nand_read_page(struct spi_nand *snand, unsigned int page_addr,
348 + unsigned int page_offset, size_t length)
349 +{
350 + unsigned int corrected = 0, ecc_error = 0;
351 + int ret;
352 +
353 + /* Load a page into the cache register */
354 + ret = snand->load_page(snand, page_addr);
355 + if (ret < 0) {
356 + dev_err(snand->dev, "error %d loading page 0x%x to cache\n",
357 + ret, page_addr);
358 + return ret;
359 + }
360 +
361 + ret = spi_nand_wait_till_ready(snand);
362 + if (ret < 0)
363 + return ret;
364 +
365 + if (snand->ecc) {
366 + snand->get_ecc_status(ret, &corrected, &ecc_error);
367 + snand->bitflips = corrected;
368 +
369 + /*
370 + * If there's an ECC error, print a message and notify MTD
371 + * about it. Then complete the read, to load actual data on
372 + * the buffer (instead of the status result).
373 + */
374 + if (ecc_error) {
375 + dev_err(snand->dev,
376 + "internal ECC error reading page 0x%x\n",
377 + page_addr);
378 + snand->nand_chip.mtd.ecc_stats.failed++;
379 + } else {
380 + snand->nand_chip.mtd.ecc_stats.corrected += corrected;
381 + }
382 + }
383 +
384 + /* Enable quad mode */
385 + ret = spi_nand_enable_quad(snand);
386 + if (ret) {
387 + dev_err(snand->dev, "error %d enabling quad mode\n", ret);
388 + return ret;
389 + }
390 + /* Get page from the device cache into our internal buffer */
391 + ret = snand->read_cache(snand, page_offset, length, snand->data_buf);
392 + if (ret < 0) {
393 + dev_err(snand->dev, "error %d reading page 0x%x from cache\n",
394 + ret, page_addr);
395 + return ret;
396 + }
397 + return 0;
398 +}
399 +
400 +static u8 spi_nand_read_byte(struct mtd_info *mtd)
401 +{
402 + struct nand_chip *chip = mtd_to_nand(mtd);
403 + struct spi_nand *snand = nand_get_controller_data(chip);
404 + char val = 0xff;
405 +
406 + if (snand->buf_start < snand->buf_size)
407 + val = snand->data_buf[snand->buf_start++];
408 + return val;
409 +}
410 +
411 +static void spi_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
412 +{
413 + struct nand_chip *chip = mtd_to_nand(mtd);
414 + struct spi_nand *snand = nand_get_controller_data(chip);
415 + size_t n = min_t(size_t, len, snand->buf_size - snand->buf_start);
416 +
417 + memcpy(snand->data_buf + snand->buf_start, buf, n);
418 + snand->buf_start += n;
419 +}
420 +
421 +static void spi_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
422 +{
423 + struct nand_chip *chip = mtd_to_nand(mtd);
424 + struct spi_nand *snand = nand_get_controller_data(chip);
425 + size_t n = min_t(size_t, len, snand->buf_size - snand->buf_start);
426 +
427 + memcpy(buf, snand->data_buf + snand->buf_start, n);
428 + snand->buf_start += n;
429 +}
430 +
431 +static int spi_nand_write_page_hwecc(struct mtd_info *mtd,
432 + struct nand_chip *chip, const uint8_t *buf, int oob_required,
433 + int page)
434 +{
435 + chip->write_buf(mtd, buf, mtd->writesize);
436 + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
437 +
438 + return 0;
439 +}
440 +
441 +static int spi_nand_read_page_hwecc(struct mtd_info *mtd,
442 + struct nand_chip *chip, uint8_t *buf, int oob_required,
443 + int page)
444 +{
445 + struct spi_nand *snand = nand_get_controller_data(chip);
446 +
447 + chip->read_buf(mtd, buf, mtd->writesize);
448 + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
449 +
450 + return snand->bitflips;
451 +}
452 +
453 +static int spi_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
454 +{
455 + struct spi_nand *snand = nand_get_controller_data(chip);
456 + int ret;
457 +
458 + ret = spi_nand_wait_till_ready(snand);
459 +
460 + if (ret < 0) {
461 + return NAND_STATUS_FAIL;
462 + } else if (ret & SPI_NAND_STATUS_REG_PROG_FAIL) {
463 + dev_err(snand->dev, "page program failed\n");
464 + return NAND_STATUS_FAIL;
465 + } else if (ret & SPI_NAND_STATUS_REG_ERASE_FAIL) {
466 + dev_err(snand->dev, "block erase failed\n");
467 + return NAND_STATUS_FAIL;
468 + }
469 +
470 + return NAND_STATUS_READY;
471 +}
472 +
473 +static void spi_nand_cmdfunc(struct mtd_info *mtd, unsigned int command,
474 + int column, int page_addr)
475 +{
476 + struct nand_chip *chip = mtd_to_nand(mtd);
477 + struct spi_nand *snand = nand_get_controller_data(chip);
478 +
479 + /*
480 + * In case there's any unsupported command, let's make sure
481 + * we don't keep garbage around in the buffer.
482 + */
483 + if (command != NAND_CMD_PAGEPROG) {
484 + spi_nand_clear_buffer(snand);
485 + snand->page_addr = 0;
486 + }
487 +
488 + switch (command) {
489 + case NAND_CMD_READ0:
490 + spi_nand_read_page(snand, page_addr, 0, mtd->writesize);
491 + break;
492 + case NAND_CMD_READOOB:
493 + spi_nand_disable_ecc(snand);
494 + spi_nand_read_page(snand, page_addr, mtd->writesize,
495 + mtd->oobsize);
496 + spi_nand_enable_ecc(snand);
497 + break;
498 + case NAND_CMD_READID:
499 + spi_nand_read_id(snand);
500 + break;
501 + case NAND_CMD_ERASE1:
502 + spi_nand_erase(snand, page_addr);
503 + break;
504 + case NAND_CMD_ERASE2:
505 + /* There's nothing to do here, as the erase is one-step */
506 + break;
507 + case NAND_CMD_SEQIN:
508 + snand->buf_start = column;
509 + snand->page_addr = page_addr;
510 + break;
511 + case NAND_CMD_PAGEPROG:
512 + spi_nand_write(snand);
513 + break;
514 + case NAND_CMD_STATUS:
515 + spi_nand_status(snand);
516 + break;
517 + case NAND_CMD_RESET:
518 + spi_nand_reset(snand);
519 + break;
520 + default:
521 + dev_err(&mtd->dev, "unknown command 0x%x\n", command);
522 + }
523 +}
524 +
525 +static void spi_nand_select_chip(struct mtd_info *mtd, int chip)
526 +{
527 + /* We need this to override the default */
528 +}
529 +
530 +int spi_nand_check(struct spi_nand *snand)
531 +{
532 + if (!snand->dev)
533 + return -ENODEV;
534 + if (!snand->read_cache)
535 + return -ENODEV;
536 + if (!snand->load_page)
537 + return -ENODEV;
538 + if (!snand->store_cache)
539 + return -ENODEV;
540 + if (!snand->write_page)
541 + return -ENODEV;
542 + if (!snand->write_reg)
543 + return -ENODEV;
544 + if (!snand->read_reg)
545 + return -ENODEV;
546 + if (!snand->block_erase)
547 + return -ENODEV;
548 + if (!snand->reset)
549 + return -ENODEV;
550 + if (!snand->write_enable)
551 + return -ENODEV;
552 + if (!snand->write_disable)
553 + return -ENODEV;
554 + if (!snand->get_ecc_status)
555 + return -ENODEV;
556 + return 0;
557 +}
558 +
559 +int spi_nand_register(struct spi_nand *snand, struct nand_flash_dev *flash_ids)
560 +{
561 + struct nand_chip *chip = &snand->nand_chip;
562 + struct mtd_info *mtd = nand_to_mtd(chip);
563 + struct device_node *np = snand->dev->of_node;
564 + const char __maybe_unused *of_mtd_name = NULL;
565 + int ret;
566 +
567 + /* Let's check all the hooks are in-place so we don't panic later */
568 + ret = spi_nand_check(snand);
569 + if (ret)
570 + return ret;
571 +
572 + nand_set_controller_data(chip, snand);
573 + nand_set_flash_node(chip, np);
574 + chip->read_buf = spi_nand_read_buf;
575 + chip->write_buf = spi_nand_write_buf;
576 + chip->read_byte = spi_nand_read_byte;
577 + chip->cmdfunc = spi_nand_cmdfunc;
578 + chip->waitfunc = spi_nand_waitfunc;
579 + chip->select_chip = spi_nand_select_chip;
580 + chip->options |= NAND_NO_SUBPAGE_WRITE;
581 + chip->bits_per_cell = 1;
582 +
583 + mtd_set_ooblayout(mtd, snand->ooblayout);
584 + chip->ecc.read_page = spi_nand_read_page_hwecc;
585 + chip->ecc.write_page = spi_nand_write_page_hwecc;
586 + chip->ecc.mode = NAND_ECC_HW;
587 +
588 + if (of_property_read_bool(np, "nand-on-flash-bbt"))
589 + chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
590 +
591 +#ifdef CONFIG_MTD_OF_PARTS
592 + of_property_read_string(np, "linux,mtd-name", &of_mtd_name);
593 +#endif
594 + if (of_mtd_name)
595 + mtd->name = of_mtd_name;
596 + else
597 + mtd->name = snand->name;
598 + mtd->owner = THIS_MODULE;
599 +
600 + /* Allocate buffer to be used to read/write the internal registers */
601 + snand->buf = kmalloc(SPI_NAND_CMD_BUF_LEN, GFP_KERNEL);
602 + if (!snand->buf)
603 + return -ENOMEM;
604 +
605 + /* This is enabled at device power up but we'd better make sure */
606 + ret = spi_nand_enable_ecc(snand);
607 + if (ret)
608 + return ret;
609 +
610 + /* Preallocate buffer for flash identification (NAND_CMD_READID) */
611 + snand->buf_size = SPI_NAND_CMD_BUF_LEN;
612 + snand->data_buf = kmalloc(snand->buf_size, GFP_KERNEL);
613 +
614 + ret = nand_scan_ident(mtd, 1, flash_ids);
615 + if (ret)
616 + return ret;
617 +
618 + /*
619 + * SPI NAND has on-die ECC, which means we can correct as much as
620 + * we are required to. This must be done after identification of
621 + * the device.
622 + */
623 + chip->ecc.strength = chip->ecc_strength_ds;
624 + chip->ecc.size = chip->ecc_step_ds;
625 +
626 + /*
627 + * Unlock all the device before calling nand_scan_tail. This is needed
628 + * in case the in-flash bad block table needs to be created.
629 + * We could override __nand_unlock(), but since it's not currently used
630 + * by the NAND core we call this explicitly.
631 + */
632 + snand->buf[0] = SPI_NAND_PROT_UNLOCK_ALL;
633 + ret = snand->write_reg(snand, SPI_NAND_LOCK_REG, snand->buf);
634 + if (ret)
635 + return ret;
636 +
637 + /* Free the buffer and allocate a good one, to fit a page plus OOB */
638 + kfree(snand->data_buf);
639 +
640 + snand->buf_size = mtd->writesize + mtd->oobsize;
641 + snand->data_buf = kmalloc(snand->buf_size, GFP_KERNEL);
642 + if (!snand->data_buf)
643 + return -ENOMEM;
644 +
645 + ret = nand_scan_tail(mtd);
646 + if (ret)
647 + return ret;
648 +
649 + return mtd_device_register(mtd, NULL, 0);
650 +}
651 +EXPORT_SYMBOL_GPL(spi_nand_register);
652 +
653 +void spi_nand_unregister(struct spi_nand *snand)
654 +{
655 + kfree(snand->buf);
656 + kfree(snand->data_buf);
657 +}
658 +EXPORT_SYMBOL_GPL(spi_nand_unregister);
659 +
660 +MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@imgtec.com>");
661 +MODULE_DESCRIPTION("Framework for SPI NAND");
662 +MODULE_LICENSE("GPL v2");
663 diff --git a/include/linux/mtd/spi-nand.h b/include/linux/mtd/spi-nand.h
664 new file mode 100644
665 index 0000000..b5cc99f
666 --- /dev/null
667 +++ b/include/linux/mtd/spi-nand.h
668 @@ -0,0 +1,54 @@
669 +/*
670 + * Copyright (C) 2014 Imagination Technologies Ltd.
671 + *
672 + * This program is free software; you can redistribute it and/or modify
673 + * it under the terms of the GNU General Public License as published by
674 + * the Free Software Foundation; version 2 of the License.
675 + */
676 +
677 +#ifndef __LINUX_MTD_SPI_NAND_H
678 +#define __LINUX_MTD_SPI_NAND_H
679 +
680 +#include <linux/mtd/mtd.h>
681 +#include <linux/mtd/nand.h>
682 +
683 +struct spi_nand {
684 + struct nand_chip nand_chip;
685 + struct device *dev;
686 + const char *name;
687 +
688 + u8 *buf, *data_buf;
689 + size_t buf_size;
690 + off_t buf_start;
691 + unsigned int page_addr;
692 + unsigned int bitflips;
693 + bool ecc;
694 + struct mtd_ooblayout_ops *ooblayout;
695 +
696 + int (*reset)(struct spi_nand *snand);
697 + int (*read_id)(struct spi_nand *snand, u8 *buf);
698 +
699 + int (*write_disable)(struct spi_nand *snand);
700 + int (*write_enable)(struct spi_nand *snand);
701 +
702 + int (*read_reg)(struct spi_nand *snand, u8 opcode, u8 *buf);
703 + int (*write_reg)(struct spi_nand *snand, u8 opcode, u8 *buf);
704 + void (*get_ecc_status)(unsigned int status,
705 + unsigned int *corrected,
706 + unsigned int *ecc_errors);
707 +
708 + int (*store_cache)(struct spi_nand *snand, unsigned int page_offset,
709 + size_t length, u8 *write_buf);
710 + int (*write_page)(struct spi_nand *snand, unsigned int page_addr);
711 + int (*load_page)(struct spi_nand *snand, unsigned int page_addr);
712 + int (*read_cache)(struct spi_nand *snand, unsigned int page_offset,
713 + size_t length, u8 *read_buf);
714 + int (*block_erase)(struct spi_nand *snand, unsigned int page_addr);
715 +
716 + void *priv;
717 +};
718 +
719 +int spi_nand_register(struct spi_nand *snand, struct nand_flash_dev *flash_ids);
720 +void spi_nand_unregister(struct spi_nand *snand);
721 +
722 +#endif
723 --
724 2.7.4
725