blob: 1526d075c7889f04e6117d230f2982d15b7cdc5a [file] [log] [blame]
Wolfgang Denkac7eb8a2005-09-14 23:53:32 +02001/*
Heiko Schocherff94bc42014-06-24 10:10:04 +02002 * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
Wolfgang Denk932394a2005-08-17 12:55:25 +02003 *
4 * Released under GPL
Heiko Schocherff94bc42014-06-24 10:10:04 +02005 *
Wolfgang Denk932394a2005-08-17 12:55:25 +02006 */
7
8#ifndef __MTD_MTD_H__
9#define __MTD_MTD_H__
William Juulcfa460a2007-10-31 13:53:06 +010010
Heiko Schocherff94bc42014-06-24 10:10:04 +020011#define __UBOOT__
12#ifndef __UBOOT__
Wolfgang Denk932394a2005-08-17 12:55:25 +020013#include <linux/types.h>
Heiko Schocherff94bc42014-06-24 10:10:04 +020014#include <linux/uio.h>
15#include <linux/notifier.h>
16#include <linux/device.h>
17
18#include <mtd/mtd-abi.h>
19
20#include <asm/div64.h>
21#else
22#include <linux/compat.h>
Sergey Lapindfe64e22013-01-14 03:46:50 +000023#include <mtd/mtd-abi.h>
24#include <asm/errno.h>
Heiko Schocherff94bc42014-06-24 10:10:04 +020025#include <div64.h>
Wolfgang Denk932394a2005-08-17 12:55:25 +020026
William Juulcfa460a2007-10-31 13:53:06 +010027#define MAX_MTD_DEVICES 32
Heiko Schocherff94bc42014-06-24 10:10:04 +020028#endif
Wolfgang Denk932394a2005-08-17 12:55:25 +020029
Wolfgang Denk53677ef2008-05-20 16:00:29 +020030#define MTD_ERASE_PENDING 0x01
Wolfgang Denk932394a2005-08-17 12:55:25 +020031#define MTD_ERASING 0x02
32#define MTD_ERASE_SUSPEND 0x04
Heiko Schocherff94bc42014-06-24 10:10:04 +020033#define MTD_ERASE_DONE 0x08
34#define MTD_ERASE_FAILED 0x10
Wolfgang Denk932394a2005-08-17 12:55:25 +020035
Heiko Schocherff94bc42014-06-24 10:10:04 +020036#define MTD_FAIL_ADDR_UNKNOWN -1LL
Stefan Roese8d2effe2009-05-11 16:03:55 +020037
Kyungmin Parkd438d502008-08-13 09:11:02 +090038/*
Heiko Schocherff94bc42014-06-24 10:10:04 +020039 * If the erase fails, fail_addr might indicate exactly which block failed. If
40 * fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
41 * or was not specific to any particular block.
Kyungmin Parkd438d502008-08-13 09:11:02 +090042 */
Wolfgang Denk932394a2005-08-17 12:55:25 +020043struct erase_info {
44 struct mtd_info *mtd;
Stefan Roese8d2effe2009-05-11 16:03:55 +020045 uint64_t addr;
46 uint64_t len;
47 uint64_t fail_addr;
Wolfgang Denk932394a2005-08-17 12:55:25 +020048 u_long time;
49 u_long retries;
Heiko Schocherff94bc42014-06-24 10:10:04 +020050 unsigned dev;
51 unsigned cell;
Wolfgang Denk932394a2005-08-17 12:55:25 +020052 void (*callback) (struct erase_info *self);
53 u_long priv;
54 u_char state;
55 struct erase_info *next;
Marek Vasut6d414192011-09-12 06:04:06 +020056 int scrub;
Wolfgang Denk932394a2005-08-17 12:55:25 +020057};
58
59struct mtd_erase_region_info {
Heiko Schocherff94bc42014-06-24 10:10:04 +020060 uint64_t offset; /* At which this region starts, from the beginning of the MTD */
61 uint32_t erasesize; /* For this region */
62 uint32_t numblocks; /* Number of blocks of erasesize in this region */
William Juulcfa460a2007-10-31 13:53:06 +010063 unsigned long *lockmap; /* If keeping bitmap of locks */
64};
65
William Juulcfa460a2007-10-31 13:53:06 +010066/**
67 * struct mtd_oob_ops - oob operation operands
68 * @mode: operation mode
69 *
70 * @len: number of data bytes to write/read
71 *
72 * @retlen: number of data bytes written/read
73 *
74 * @ooblen: number of oob bytes to write/read
75 * @oobretlen: number of oob bytes written/read
76 * @ooboffs: offset of oob data in the oob area (only relevant when
Sergey Lapindfe64e22013-01-14 03:46:50 +000077 * mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
William Juulcfa460a2007-10-31 13:53:06 +010078 * @datbuf: data buffer - if NULL only oob data are read/written
79 * @oobbuf: oob data buffer
80 *
Heiko Schocherff94bc42014-06-24 10:10:04 +020081 * Note, it is allowed to read more than one OOB area at one go, but not write.
William Juulcfa460a2007-10-31 13:53:06 +010082 * The interface assumes that the OOB write requests program only one page's
83 * OOB area.
84 */
85struct mtd_oob_ops {
Sergey Lapindfe64e22013-01-14 03:46:50 +000086 unsigned int mode;
William Juulcfa460a2007-10-31 13:53:06 +010087 size_t len;
88 size_t retlen;
89 size_t ooblen;
90 size_t oobretlen;
91 uint32_t ooboffs;
92 uint8_t *datbuf;
93 uint8_t *oobbuf;
Wolfgang Denk932394a2005-08-17 12:55:25 +020094};
95
Prabhakar Kushwaha68ec9c82013-10-04 13:47:58 +053096#ifdef CONFIG_SYS_NAND_MAX_OOBFREE
97#define MTD_MAX_OOBFREE_ENTRIES_LARGE CONFIG_SYS_NAND_MAX_OOBFREE
98#else
99#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
100#endif
101
102#ifdef CONFIG_SYS_NAND_MAX_ECCPOS
103#define MTD_MAX_ECCPOS_ENTRIES_LARGE CONFIG_SYS_NAND_MAX_ECCPOS
104#else
105#define MTD_MAX_ECCPOS_ENTRIES_LARGE 640
106#endif
107
108/*
Heiko Schocherff94bc42014-06-24 10:10:04 +0200109 * Internal ECC layout control structure. For historical reasons, there is a
110 * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
111 * for export to user-space via the ECCGETLAYOUT ioctl.
112 * nand_ecclayout should be expandable in the future simply by the above macros.
Prabhakar Kushwaha68ec9c82013-10-04 13:47:58 +0530113 */
114struct nand_ecclayout {
Heiko Schocherff94bc42014-06-24 10:10:04 +0200115 __u32 eccbytes;
116 __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
117 __u32 oobavail;
Prabhakar Kushwaha68ec9c82013-10-04 13:47:58 +0530118 struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
119};
120
Heiko Schocherff94bc42014-06-24 10:10:04 +0200121struct module; /* only needed for owner field in mtd_info */
122
Wolfgang Denk932394a2005-08-17 12:55:25 +0200123struct mtd_info {
124 u_char type;
Heiko Schocherff94bc42014-06-24 10:10:04 +0200125 uint32_t flags;
126 uint64_t size; // Total size of the MTD
Wolfgang Denk932394a2005-08-17 12:55:25 +0200127
Albert ARIBAUDfa82f872011-08-04 18:45:45 +0200128 /* "Major" erase size for the device. Naïve users may take this
Wolfgang Denk932394a2005-08-17 12:55:25 +0200129 * to be the only erase size available, or may use the more detailed
130 * information below if they desire
131 */
Heiko Schocherff94bc42014-06-24 10:10:04 +0200132 uint32_t erasesize;
William Juulcfa460a2007-10-31 13:53:06 +0100133 /* Minimal writable flash unit size. In case of NOR flash it is 1 (even
134 * though individual bits can be cleared), in case of NAND flash it is
135 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
136 * it is of ECC block size, etc. It is illegal to have writesize = 0.
137 * Any driver registering a struct mtd_info must ensure a writesize of
138 * 1 or larger.
139 */
Heiko Schocherff94bc42014-06-24 10:10:04 +0200140 uint32_t writesize;
Wolfgang Denk932394a2005-08-17 12:55:25 +0200141
Heiko Schocherff94bc42014-06-24 10:10:04 +0200142 /*
143 * Size of the write buffer used by the MTD. MTD devices having a write
144 * buffer can write multiple writesize chunks at a time. E.g. while
145 * writing 4 * writesize bytes to a device with 2 * writesize bytes
146 * buffer the MTD driver can (but doesn't have to) do 2 writesize
147 * operations, but not 4. Currently, all NANDs have writebufsize
148 * equivalent to writesize (NAND page size). Some NOR flashes do have
149 * writebufsize greater than writesize.
150 */
151 uint32_t writebufsize;
152
153 uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
154 uint32_t oobavail; // Available OOB bytes per block
155
156 /*
157 * If erasesize is a power of 2 then the shift is stored in
158 * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
159 */
160 unsigned int erasesize_shift;
161 unsigned int writesize_shift;
162 /* Masks based on erasesize_shift and writesize_shift */
163 unsigned int erasesize_mask;
164 unsigned int writesize_mask;
Wolfgang Denk932394a2005-08-17 12:55:25 +0200165
Sergey Lapindfe64e22013-01-14 03:46:50 +0000166 /*
167 * read ops return -EUCLEAN if max number of bitflips corrected on any
168 * one region comprising an ecc step equals or exceeds this value.
169 * Settable by driver, else defaults to ecc_strength. User can override
170 * in sysfs. N.B. The meaning of the -EUCLEAN return code has changed;
171 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
172 */
173 unsigned int bitflip_threshold;
174
Heiko Schocherff94bc42014-06-24 10:10:04 +0200175 // Kernel-only stuff starts here.
176#ifndef __UBOOT__
Scott Woodc45912d2008-10-24 16:20:43 -0500177 const char *name;
Heiko Schocherff94bc42014-06-24 10:10:04 +0200178#else
179 char *name;
180#endif
Wolfgang Denk932394a2005-08-17 12:55:25 +0200181 int index;
182
Sergey Lapindfe64e22013-01-14 03:46:50 +0000183 /* ECC layout structure pointer - read only! */
William Juulcfa460a2007-10-31 13:53:06 +0100184 struct nand_ecclayout *ecclayout;
Wolfgang Denk932394a2005-08-17 12:55:25 +0200185
Heiko Schocherff94bc42014-06-24 10:10:04 +0200186 /* the ecc step size. */
187 unsigned int ecc_step_size;
188
Sergey Lapindfe64e22013-01-14 03:46:50 +0000189 /* max number of correctible bit errors per ecc step */
190 unsigned int ecc_strength;
191
Wolfgang Denk932394a2005-08-17 12:55:25 +0200192 /* Data for variable erase regions. If numeraseregions is zero,
Wolfgang Denkac7eb8a2005-09-14 23:53:32 +0200193 * it means that the whole device has erasesize as given above.
Wolfgang Denk932394a2005-08-17 12:55:25 +0200194 */
195 int numeraseregions;
Wolfgang Denkac7eb8a2005-09-14 23:53:32 +0200196 struct mtd_erase_region_info *eraseregions;
Wolfgang Denk932394a2005-08-17 12:55:25 +0200197
Scott Woodc45912d2008-10-24 16:20:43 -0500198 /*
Sergey Lapindfe64e22013-01-14 03:46:50 +0000199 * Do not call via these pointers, use corresponding mtd_*()
200 * wrappers instead.
Scott Woodc45912d2008-10-24 16:20:43 -0500201 */
Sergey Lapindfe64e22013-01-14 03:46:50 +0000202 int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200203#ifndef __UBOOT__
Sergey Lapindfe64e22013-01-14 03:46:50 +0000204 int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200205 size_t *retlen, void **virt, resource_size_t *phys);
206 int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
207#endif
208 unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
209 unsigned long len,
210 unsigned long offset,
211 unsigned long flags);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000212 int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200213 size_t *retlen, u_char *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000214 int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200215 size_t *retlen, const u_char *buf);
216 int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
217 size_t *retlen, const u_char *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000218 int (*_read_oob) (struct mtd_info *mtd, loff_t from,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200219 struct mtd_oob_ops *ops);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000220 int (*_write_oob) (struct mtd_info *mtd, loff_t to,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200221 struct mtd_oob_ops *ops);
Heiko Schocher4e67c572014-07-15 16:08:43 +0200222 int (*_get_fact_prot_info) (struct mtd_info *mtd, size_t len,
223 size_t *retlen, struct otp_info *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000224 int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200225 size_t len, size_t *retlen, u_char *buf);
Heiko Schocher4e67c572014-07-15 16:08:43 +0200226 int (*_get_user_prot_info) (struct mtd_info *mtd, size_t len,
227 size_t *retlen, struct otp_info *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000228 int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200229 size_t len, size_t *retlen, u_char *buf);
230 int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
231 size_t len, size_t *retlen, u_char *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000232 int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
Heiko Schocherff94bc42014-06-24 10:10:04 +0200233 size_t len);
234#ifndef __UBOOT__
235 int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
236 unsigned long count, loff_t to, size_t *retlen);
237#endif
Sergey Lapindfe64e22013-01-14 03:46:50 +0000238 void (*_sync) (struct mtd_info *mtd);
239 int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
240 int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200241 int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000242 int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
243 int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200244#ifndef __UBOOT__
245 int (*_suspend) (struct mtd_info *mtd);
246 void (*_resume) (struct mtd_info *mtd);
247#endif
Wolfgang Denkac7eb8a2005-09-14 23:53:32 +0200248 /*
Sergey Lapindfe64e22013-01-14 03:46:50 +0000249 * If the driver is something smart, like UBI, it may need to maintain
250 * its own reference counting. The below functions are only for driver.
Wolfgang Denk932394a2005-08-17 12:55:25 +0200251 */
Sergey Lapindfe64e22013-01-14 03:46:50 +0000252 int (*_get_device) (struct mtd_info *mtd);
253 void (*_put_device) (struct mtd_info *mtd);
William Juulcfa460a2007-10-31 13:53:06 +0100254
Heiko Schocherff94bc42014-06-24 10:10:04 +0200255#ifndef __UBOOT__
256 /* Backing device capabilities for this device
257 * - provides mmap capabilities
258 */
259 struct backing_dev_info *backing_dev_info;
260
William Juulcfa460a2007-10-31 13:53:06 +0100261 struct notifier_block reboot_notifier; /* default mode before reboot */
262#endif
263
264 /* ECC status information */
265 struct mtd_ecc_stats ecc_stats;
266 /* Subpage shift (NAND) */
267 int subpage_sft;
268
Wolfgang Denk932394a2005-08-17 12:55:25 +0200269 void *priv;
270
271 struct module *owner;
Heiko Schocherff94bc42014-06-24 10:10:04 +0200272#ifndef __UBOOT__
273 struct device dev;
274#endif
Wolfgang Denk932394a2005-08-17 12:55:25 +0200275 int usecount;
276};
277
Sergey Lapindfe64e22013-01-14 03:46:50 +0000278int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200279#ifndef __UBOOT__
280int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
281 void **virt, resource_size_t *phys);
282int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
283#endif
284unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
285 unsigned long offset, unsigned long flags);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000286int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
287 u_char *buf);
288int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
289 const u_char *buf);
290int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
291 const u_char *buf);
292
293int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
294
295static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
296 struct mtd_oob_ops *ops)
297{
298 ops->retlen = ops->oobretlen = 0;
299 if (!mtd->_write_oob)
300 return -EOPNOTSUPP;
301 if (!(mtd->flags & MTD_WRITEABLE))
302 return -EROFS;
303 return mtd->_write_oob(mtd, to, ops);
304}
305
Heiko Schocher4e67c572014-07-15 16:08:43 +0200306int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
307 struct otp_info *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000308int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
309 size_t *retlen, u_char *buf);
Heiko Schocher4e67c572014-07-15 16:08:43 +0200310int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
311 struct otp_info *buf);
Sergey Lapindfe64e22013-01-14 03:46:50 +0000312int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
313 size_t *retlen, u_char *buf);
314int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
315 size_t *retlen, u_char *buf);
316int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
317
Heiko Schocherff94bc42014-06-24 10:10:04 +0200318#ifndef __UBOOT__
Sergey Lapindfe64e22013-01-14 03:46:50 +0000319int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
320 unsigned long count, loff_t to, size_t *retlen);
321#endif
322
323static inline void mtd_sync(struct mtd_info *mtd)
324{
325 if (mtd->_sync)
326 mtd->_sync(mtd);
327}
328
329int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
330int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
331int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
332int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
333int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
334
Heiko Schocherff94bc42014-06-24 10:10:04 +0200335#ifndef __UBOOT__
336static inline int mtd_suspend(struct mtd_info *mtd)
337{
338 return mtd->_suspend ? mtd->_suspend(mtd) : 0;
339}
340
341static inline void mtd_resume(struct mtd_info *mtd)
342{
343 if (mtd->_resume)
344 mtd->_resume(mtd);
345}
346#endif
347
Stefan Roese8d2effe2009-05-11 16:03:55 +0200348static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
349{
Heiko Schocherff94bc42014-06-24 10:10:04 +0200350 if (mtd->erasesize_shift)
351 return sz >> mtd->erasesize_shift;
Stefan Roese8d2effe2009-05-11 16:03:55 +0200352 do_div(sz, mtd->erasesize);
353 return sz;
354}
355
356static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
357{
Heiko Schocherff94bc42014-06-24 10:10:04 +0200358 if (mtd->erasesize_shift)
359 return sz & mtd->erasesize_mask;
Stefan Roese8d2effe2009-05-11 16:03:55 +0200360 return do_div(sz, mtd->erasesize);
361}
Wolfgang Denk932394a2005-08-17 12:55:25 +0200362
Heiko Schocherff94bc42014-06-24 10:10:04 +0200363static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
364{
365 if (mtd->writesize_shift)
366 return sz >> mtd->writesize_shift;
367 do_div(sz, mtd->writesize);
368 return sz;
369}
370
371static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
372{
373 if (mtd->writesize_shift)
374 return sz & mtd->writesize_mask;
375 return do_div(sz, mtd->writesize);
376}
377
Sergey Lapindfe64e22013-01-14 03:46:50 +0000378static inline int mtd_has_oob(const struct mtd_info *mtd)
379{
380 return mtd->_read_oob && mtd->_write_oob;
381}
382
Heiko Schocherff94bc42014-06-24 10:10:04 +0200383static inline int mtd_type_is_nand(const struct mtd_info *mtd)
384{
385 return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
386}
387
Sergey Lapindfe64e22013-01-14 03:46:50 +0000388static inline int mtd_can_have_bb(const struct mtd_info *mtd)
389{
390 return !!mtd->_block_isbad;
391}
392
Wolfgang Denk932394a2005-08-17 12:55:25 +0200393 /* Kernel-side ioctl definitions */
394
Heiko Schocherff94bc42014-06-24 10:10:04 +0200395struct mtd_partition;
396struct mtd_part_parser_data;
Wolfgang Denk932394a2005-08-17 12:55:25 +0200397
Heiko Schocherff94bc42014-06-24 10:10:04 +0200398extern int mtd_device_parse_register(struct mtd_info *mtd,
399 const char * const *part_probe_types,
400 struct mtd_part_parser_data *parser_data,
401 const struct mtd_partition *defparts,
402 int defnr_parts);
403#define mtd_device_register(master, parts, nr_parts) \
404 mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
405extern int mtd_device_unregister(struct mtd_info *master);
Wolfgang Denk932394a2005-08-17 12:55:25 +0200406extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200407extern int __get_mtd_device(struct mtd_info *mtd);
408extern void __put_mtd_device(struct mtd_info *mtd);
William Juulcfa460a2007-10-31 13:53:06 +0100409extern struct mtd_info *get_mtd_device_nm(const char *name);
Wolfgang Denk932394a2005-08-17 12:55:25 +0200410extern void put_mtd_device(struct mtd_info *mtd);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200411
412
413#ifndef __UBOOT__
Wolfgang Denk932394a2005-08-17 12:55:25 +0200414struct mtd_notifier {
415 void (*add)(struct mtd_info *mtd);
416 void (*remove)(struct mtd_info *mtd);
417 struct list_head list;
418};
419
Heiko Schocherff94bc42014-06-24 10:10:04 +0200420
Wolfgang Denk932394a2005-08-17 12:55:25 +0200421extern void register_mtd_user (struct mtd_notifier *new);
422extern int unregister_mtd_user (struct mtd_notifier *old);
Wolfgang Denk932394a2005-08-17 12:55:25 +0200423#endif
Heiko Schocherff94bc42014-06-24 10:10:04 +0200424void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
Wolfgang Denk932394a2005-08-17 12:55:25 +0200425
Wolfgang Denk932394a2005-08-17 12:55:25 +0200426#ifdef CONFIG_MTD_PARTITIONS
427void mtd_erase_callback(struct erase_info *instr);
428#else
429static inline void mtd_erase_callback(struct erase_info *instr)
430{
431 if (instr->callback)
432 instr->callback(instr);
433}
434#endif
435
Heiko Schocherff94bc42014-06-24 10:10:04 +0200436#ifdef __UBOOT__
Wolfgang Denk932394a2005-08-17 12:55:25 +0200437/*
438 * Debugging macro and defines
439 */
440#define MTD_DEBUG_LEVEL0 (0) /* Quiet */
441#define MTD_DEBUG_LEVEL1 (1) /* Audible */
442#define MTD_DEBUG_LEVEL2 (2) /* Loud */
443#define MTD_DEBUG_LEVEL3 (3) /* Noisy */
444
445#ifdef CONFIG_MTD_DEBUG
Sergey Lapindfe64e22013-01-14 03:46:50 +0000446#define pr_debug(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
Scott Wood3167c532008-06-20 12:38:57 -0500447#define MTDDEBUG(n, args...) \
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200448 do { \
Wolfgang Denk932394a2005-08-17 12:55:25 +0200449 if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
450 printk(KERN_INFO args); \
451 } while(0)
452#else /* CONFIG_MTD_DEBUG */
Sergey Lapindfe64e22013-01-14 03:46:50 +0000453#define pr_debug(args...)
Scott Woodc45912d2008-10-24 16:20:43 -0500454#define MTDDEBUG(n, args...) \
455 do { \
456 if (0) \
457 printk(KERN_INFO args); \
458 } while(0)
Wolfgang Denk932394a2005-08-17 12:55:25 +0200459#endif /* CONFIG_MTD_DEBUG */
Sergey Lapindfe64e22013-01-14 03:46:50 +0000460#define pr_info(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
461#define pr_warn(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
462#define pr_err(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
Heiko Schocherff94bc42014-06-24 10:10:04 +0200463#define pr_crit(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
464#define pr_cont(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
465#define pr_notice(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
466#endif
467
Sergey Lapindfe64e22013-01-14 03:46:50 +0000468static inline int mtd_is_bitflip(int err) {
469 return err == -EUCLEAN;
470}
471
472static inline int mtd_is_eccerr(int err) {
473 return err == -EBADMSG;
474}
475
476static inline int mtd_is_bitflip_or_eccerr(int err) {
477 return mtd_is_bitflip(err) || mtd_is_eccerr(err);
478}
Wolfgang Denk932394a2005-08-17 12:55:25 +0200479
Heiko Schocherff94bc42014-06-24 10:10:04 +0200480#ifdef __UBOOT__
481/* drivers/mtd/mtdcore.h */
482int add_mtd_device(struct mtd_info *mtd);
Heiko Schocherddf7bcf2014-07-15 16:08:42 +0200483int del_mtd_device(struct mtd_info *mtd);
Heiko Schocherff94bc42014-06-24 10:10:04 +0200484int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
485int del_mtd_partitions(struct mtd_info *);
486#endif
Wolfgang Denk932394a2005-08-17 12:55:25 +0200487#endif /* __MTD_MTD_H__ */