xref: /rk3399_rockchip-uboot/include/linux/mtd/mtd.h (revision dfe64e2c89731a3f9950d7acd8681b68df2bae03)
1932394acSWolfgang Denk /*
2932394acSWolfgang Denk  * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
3932394acSWolfgang Denk  *
4932394acSWolfgang Denk  * Released under GPL
5932394acSWolfgang Denk  */
6932394acSWolfgang Denk 
7932394acSWolfgang Denk #ifndef __MTD_MTD_H__
8932394acSWolfgang Denk #define __MTD_MTD_H__
9cfa460adSWilliam Juul 
10932394acSWolfgang Denk #include <linux/types.h>
118d2effeaSStefan Roese #include <div64.h>
12*dfe64e2cSSergey Lapin #include <mtd/mtd-abi.h>
13*dfe64e2cSSergey Lapin #include <asm/errno.h>
14932394acSWolfgang Denk 
15cfa460adSWilliam Juul #define MTD_CHAR_MAJOR 90
16cfa460adSWilliam Juul #define MTD_BLOCK_MAJOR 31
17cfa460adSWilliam Juul #define MAX_MTD_DEVICES 32
18932394acSWolfgang Denk 
19932394acSWolfgang Denk #define MTD_ERASE_PENDING	0x01
20932394acSWolfgang Denk #define MTD_ERASING		0x02
21932394acSWolfgang Denk #define MTD_ERASE_SUSPEND	0x04
22932394acSWolfgang Denk #define MTD_ERASE_DONE          0x08
23932394acSWolfgang Denk #define MTD_ERASE_FAILED        0x10
24932394acSWolfgang Denk 
258d2effeaSStefan Roese #define MTD_FAIL_ADDR_UNKNOWN	-1LL
268d2effeaSStefan Roese 
27d438d508SKyungmin Park /*
28d438d508SKyungmin Park  * Enumeration for NAND/OneNAND flash chip state
29d438d508SKyungmin Park  */
30d438d508SKyungmin Park enum {
31d438d508SKyungmin Park 	FL_READY,
32d438d508SKyungmin Park 	FL_READING,
33d438d508SKyungmin Park 	FL_WRITING,
34d438d508SKyungmin Park 	FL_ERASING,
35d438d508SKyungmin Park 	FL_SYNCING,
36d438d508SKyungmin Park 	FL_CACHEDPRG,
37d438d508SKyungmin Park 	FL_RESETING,
38d438d508SKyungmin Park 	FL_UNLOCKING,
39d438d508SKyungmin Park 	FL_LOCKING,
40d438d508SKyungmin Park 	FL_PM_SUSPENDED,
41d438d508SKyungmin Park };
42d438d508SKyungmin Park 
43932394acSWolfgang Denk /* If the erase fails, fail_addr might indicate exactly which block failed.  If
448d2effeaSStefan Roese    fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not
45932394acSWolfgang Denk    specific to any particular block. */
46932394acSWolfgang Denk struct erase_info {
47932394acSWolfgang Denk 	struct mtd_info *mtd;
488d2effeaSStefan Roese 	uint64_t addr;
498d2effeaSStefan Roese 	uint64_t len;
508d2effeaSStefan Roese 	uint64_t fail_addr;
51932394acSWolfgang Denk 	u_long time;
52932394acSWolfgang Denk 	u_long retries;
53932394acSWolfgang Denk 	u_int dev;
54932394acSWolfgang Denk 	u_int cell;
55932394acSWolfgang Denk 	void (*callback) (struct erase_info *self);
56932394acSWolfgang Denk 	u_long priv;
57932394acSWolfgang Denk 	u_char state;
58932394acSWolfgang Denk 	struct erase_info *next;
596d41419fSMarek Vasut 	int scrub;
60932394acSWolfgang Denk };
61932394acSWolfgang Denk 
62932394acSWolfgang Denk struct mtd_erase_region_info {
638d2effeaSStefan Roese 	uint64_t offset;			/* At which this region starts, from the beginning of the MTD */
64932394acSWolfgang Denk 	u_int32_t erasesize;		/* For this region */
65932394acSWolfgang Denk 	u_int32_t numblocks;		/* Number of blocks of erasesize in this region */
66cfa460adSWilliam Juul 	unsigned long *lockmap;		/* If keeping bitmap of locks */
67cfa460adSWilliam Juul };
68cfa460adSWilliam Juul 
69cfa460adSWilliam Juul /**
70cfa460adSWilliam Juul  * struct mtd_oob_ops - oob operation operands
71cfa460adSWilliam Juul  * @mode:	operation mode
72cfa460adSWilliam Juul  *
73cfa460adSWilliam Juul  * @len:	number of data bytes to write/read
74cfa460adSWilliam Juul  *
75cfa460adSWilliam Juul  * @retlen:	number of data bytes written/read
76cfa460adSWilliam Juul  *
77cfa460adSWilliam Juul  * @ooblen:	number of oob bytes to write/read
78cfa460adSWilliam Juul  * @oobretlen:	number of oob bytes written/read
79cfa460adSWilliam Juul  * @ooboffs:	offset of oob data in the oob area (only relevant when
80*dfe64e2cSSergey Lapin  *		mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
81cfa460adSWilliam Juul  * @datbuf:	data buffer - if NULL only oob data are read/written
82cfa460adSWilliam Juul  * @oobbuf:	oob data buffer
83cfa460adSWilliam Juul  *
84cfa460adSWilliam Juul  * Note, it is allowed to read more then one OOB area at one go, but not write.
85cfa460adSWilliam Juul  * The interface assumes that the OOB write requests program only one page's
86cfa460adSWilliam Juul  * OOB area.
87cfa460adSWilliam Juul  */
88cfa460adSWilliam Juul struct mtd_oob_ops {
89*dfe64e2cSSergey Lapin 	unsigned int	mode;
90cfa460adSWilliam Juul 	size_t		len;
91cfa460adSWilliam Juul 	size_t		retlen;
92cfa460adSWilliam Juul 	size_t		ooblen;
93cfa460adSWilliam Juul 	size_t		oobretlen;
94cfa460adSWilliam Juul 	uint32_t	ooboffs;
95cfa460adSWilliam Juul 	uint8_t		*datbuf;
96cfa460adSWilliam Juul 	uint8_t		*oobbuf;
97932394acSWolfgang Denk };
98932394acSWolfgang Denk 
99932394acSWolfgang Denk struct mtd_info {
100932394acSWolfgang Denk 	u_char type;
101932394acSWolfgang Denk 	u_int32_t flags;
1028e5e9b94SWolfgang Denk 	uint64_t size;	 /* Total size of the MTD */
103932394acSWolfgang Denk 
104fa82f871SAlbert ARIBAUD 	/* "Major" erase size for the device. Naïve users may take this
105932394acSWolfgang Denk 	 * to be the only erase size available, or may use the more detailed
106932394acSWolfgang Denk 	 * information below if they desire
107932394acSWolfgang Denk 	 */
108932394acSWolfgang Denk 	u_int32_t erasesize;
109cfa460adSWilliam Juul 	/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
110cfa460adSWilliam Juul 	 * though individual bits can be cleared), in case of NAND flash it is
111cfa460adSWilliam Juul 	 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
112cfa460adSWilliam Juul 	 * it is of ECC block size, etc. It is illegal to have writesize = 0.
113cfa460adSWilliam Juul 	 * Any driver registering a struct mtd_info must ensure a writesize of
114cfa460adSWilliam Juul 	 * 1 or larger.
115cfa460adSWilliam Juul 	 */
116cfa460adSWilliam Juul 	u_int32_t writesize;
117932394acSWolfgang Denk 
1184b070809SWolfgang Denk 	u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */
1194b070809SWolfgang Denk 	u_int32_t oobavail;  /* Available OOB bytes per block */
120932394acSWolfgang Denk 
121*dfe64e2cSSergey Lapin 	/*
122*dfe64e2cSSergey Lapin 	 * read ops return -EUCLEAN if max number of bitflips corrected on any
123*dfe64e2cSSergey Lapin 	 * one region comprising an ecc step equals or exceeds this value.
124*dfe64e2cSSergey Lapin 	 * Settable by driver, else defaults to ecc_strength.  User can override
125*dfe64e2cSSergey Lapin 	 * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed;
126*dfe64e2cSSergey Lapin 	 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
127*dfe64e2cSSergey Lapin 	 */
128*dfe64e2cSSergey Lapin 	unsigned int bitflip_threshold;
129*dfe64e2cSSergey Lapin 
1304b070809SWolfgang Denk 	/* Kernel-only stuff starts here. */
131c45912d8SScott Wood 	const char *name;
132932394acSWolfgang Denk 	int index;
133932394acSWolfgang Denk 
134*dfe64e2cSSergey Lapin 	/* ECC layout structure pointer - read only! */
135cfa460adSWilliam Juul 	struct nand_ecclayout *ecclayout;
136932394acSWolfgang Denk 
137*dfe64e2cSSergey Lapin 	/* max number of correctible bit errors per ecc step */
138*dfe64e2cSSergey Lapin 	unsigned int ecc_strength;
139*dfe64e2cSSergey Lapin 
140932394acSWolfgang Denk 	/* Data for variable erase regions. If numeraseregions is zero,
141932394acSWolfgang Denk 	 * it means that the whole device has erasesize as given above.
142932394acSWolfgang Denk 	 */
143932394acSWolfgang Denk 	int numeraseregions;
144932394acSWolfgang Denk 	struct mtd_erase_region_info *eraseregions;
145932394acSWolfgang Denk 
146c45912d8SScott Wood 	/*
147*dfe64e2cSSergey Lapin 	 * Do not call via these pointers, use corresponding mtd_*()
148*dfe64e2cSSergey Lapin 	 * wrappers instead.
149c45912d8SScott Wood 	 */
150*dfe64e2cSSergey Lapin 	int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
151*dfe64e2cSSergey Lapin 	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
152c45912d8SScott Wood 			size_t *retlen, void **virt, phys_addr_t *phys);
153*dfe64e2cSSergey Lapin 	void (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
154*dfe64e2cSSergey Lapin 	int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
155*dfe64e2cSSergey Lapin 		     size_t *retlen, u_char *buf);
156*dfe64e2cSSergey Lapin 	int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
157*dfe64e2cSSergey Lapin 		      size_t *retlen, const u_char *buf);
158932394acSWolfgang Denk 
159c45912d8SScott Wood 	/* In blackbox flight recorder like scenarios we want to make successful
160c45912d8SScott Wood 	   writes in interrupt context. panic_write() is only intended to be
161c45912d8SScott Wood 	   called when its known the kernel is about to panic and we need the
162c45912d8SScott Wood 	   write to succeed. Since the kernel is not going to be running for much
163c45912d8SScott Wood 	   longer, this function can break locks and delay to ensure the write
164c45912d8SScott Wood 	   succeeds (but not sleep). */
165c45912d8SScott Wood 
166*dfe64e2cSSergey Lapin 	int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
167c45912d8SScott Wood 
168*dfe64e2cSSergey Lapin 	int (*_read_oob) (struct mtd_info *mtd, loff_t from,
169cfa460adSWilliam Juul 			 struct mtd_oob_ops *ops);
170*dfe64e2cSSergey Lapin 	int (*_write_oob) (struct mtd_info *mtd, loff_t to,
171cfa460adSWilliam Juul 			 struct mtd_oob_ops *ops);
172*dfe64e2cSSergey Lapin 	int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
173*dfe64e2cSSergey Lapin 				   size_t len);
174*dfe64e2cSSergey Lapin 	int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
175*dfe64e2cSSergey Lapin 				   size_t len, size_t *retlen, u_char *buf);
176*dfe64e2cSSergey Lapin 	int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
177*dfe64e2cSSergey Lapin 				   size_t len);
178*dfe64e2cSSergey Lapin 	int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
179*dfe64e2cSSergey Lapin 				   size_t len, size_t *retlen, u_char *buf);
180*dfe64e2cSSergey Lapin 	int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len,
181*dfe64e2cSSergey Lapin 				    size_t *retlen, u_char *buf);
182*dfe64e2cSSergey Lapin 	int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
183*dfe64e2cSSergey Lapin 				   size_t len);
184*dfe64e2cSSergey Lapin 	void (*_sync) (struct mtd_info *mtd);
185*dfe64e2cSSergey Lapin 	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
186*dfe64e2cSSergey Lapin 	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
187*dfe64e2cSSergey Lapin 	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
188*dfe64e2cSSergey Lapin 	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
189932394acSWolfgang Denk 	/*
190*dfe64e2cSSergey Lapin 	 * If the driver is something smart, like UBI, it may need to maintain
191*dfe64e2cSSergey Lapin 	 * its own reference counting. The below functions are only for driver.
192932394acSWolfgang Denk 	 */
193*dfe64e2cSSergey Lapin 	int (*_get_device) (struct mtd_info *mtd);
194*dfe64e2cSSergey Lapin 	void (*_put_device) (struct mtd_info *mtd);
195cfa460adSWilliam Juul 
196cfa460adSWilliam Juul /* XXX U-BOOT XXX */
197932394acSWolfgang Denk #if 0
198cfa460adSWilliam Juul 	/* kvec-based read/write methods.
199932394acSWolfgang Denk 	   NB: The 'count' parameter is the number of _vectors_, each of
200932394acSWolfgang Denk 	   which contains an (ofs, len) tuple.
201932394acSWolfgang Denk 	*/
202932394acSWolfgang Denk 	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
203932394acSWolfgang Denk #endif
204cfa460adSWilliam Juul /* XXX U-BOOT XXX */
205cfa460adSWilliam Juul #if 0
206cfa460adSWilliam Juul 	struct notifier_block reboot_notifier;  /* default mode before reboot */
207cfa460adSWilliam Juul #endif
208cfa460adSWilliam Juul 
209cfa460adSWilliam Juul 	/* ECC status information */
210cfa460adSWilliam Juul 	struct mtd_ecc_stats ecc_stats;
211cfa460adSWilliam Juul 	/* Subpage shift (NAND) */
212cfa460adSWilliam Juul 	int subpage_sft;
213cfa460adSWilliam Juul 
214932394acSWolfgang Denk 	void *priv;
215932394acSWolfgang Denk 
216932394acSWolfgang Denk 	struct module *owner;
217932394acSWolfgang Denk 	int usecount;
218932394acSWolfgang Denk };
219932394acSWolfgang Denk 
220*dfe64e2cSSergey Lapin int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
221*dfe64e2cSSergey Lapin int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
222*dfe64e2cSSergey Lapin 	     u_char *buf);
223*dfe64e2cSSergey Lapin int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
224*dfe64e2cSSergey Lapin 	      const u_char *buf);
225*dfe64e2cSSergey Lapin int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
226*dfe64e2cSSergey Lapin 		    const u_char *buf);
227*dfe64e2cSSergey Lapin 
228*dfe64e2cSSergey Lapin int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
229*dfe64e2cSSergey Lapin 
230*dfe64e2cSSergey Lapin static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
231*dfe64e2cSSergey Lapin 				struct mtd_oob_ops *ops)
232*dfe64e2cSSergey Lapin {
233*dfe64e2cSSergey Lapin 	ops->retlen = ops->oobretlen = 0;
234*dfe64e2cSSergey Lapin 	if (!mtd->_write_oob)
235*dfe64e2cSSergey Lapin 		return -EOPNOTSUPP;
236*dfe64e2cSSergey Lapin 	if (!(mtd->flags & MTD_WRITEABLE))
237*dfe64e2cSSergey Lapin 		return -EROFS;
238*dfe64e2cSSergey Lapin 	return mtd->_write_oob(mtd, to, ops);
239*dfe64e2cSSergey Lapin }
240*dfe64e2cSSergey Lapin 
241*dfe64e2cSSergey Lapin int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
242*dfe64e2cSSergey Lapin 			   size_t len);
243*dfe64e2cSSergey Lapin int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
244*dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
245*dfe64e2cSSergey Lapin int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
246*dfe64e2cSSergey Lapin 			   size_t len);
247*dfe64e2cSSergey Lapin int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
248*dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
249*dfe64e2cSSergey Lapin int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
250*dfe64e2cSSergey Lapin 			    size_t *retlen, u_char *buf);
251*dfe64e2cSSergey Lapin int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
252*dfe64e2cSSergey Lapin 
253*dfe64e2cSSergey Lapin /* XXX U-BOOT XXX */
254*dfe64e2cSSergey Lapin #if 0
255*dfe64e2cSSergey Lapin int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
256*dfe64e2cSSergey Lapin 	       unsigned long count, loff_t to, size_t *retlen);
257*dfe64e2cSSergey Lapin #endif
258*dfe64e2cSSergey Lapin 
259*dfe64e2cSSergey Lapin static inline void mtd_sync(struct mtd_info *mtd)
260*dfe64e2cSSergey Lapin {
261*dfe64e2cSSergey Lapin 	if (mtd->_sync)
262*dfe64e2cSSergey Lapin 		mtd->_sync(mtd);
263*dfe64e2cSSergey Lapin }
264*dfe64e2cSSergey Lapin 
265*dfe64e2cSSergey Lapin int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
266*dfe64e2cSSergey Lapin int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
267*dfe64e2cSSergey Lapin int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
268*dfe64e2cSSergey Lapin int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
269*dfe64e2cSSergey Lapin int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
270*dfe64e2cSSergey Lapin 
2718d2effeaSStefan Roese static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
2728d2effeaSStefan Roese {
2738d2effeaSStefan Roese 	do_div(sz, mtd->erasesize);
2748d2effeaSStefan Roese 	return sz;
2758d2effeaSStefan Roese }
2768d2effeaSStefan Roese 
2778d2effeaSStefan Roese static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
2788d2effeaSStefan Roese {
2798d2effeaSStefan Roese 	return do_div(sz, mtd->erasesize);
2808d2effeaSStefan Roese }
281932394acSWolfgang Denk 
282*dfe64e2cSSergey Lapin static inline int mtd_has_oob(const struct mtd_info *mtd)
283*dfe64e2cSSergey Lapin {
284*dfe64e2cSSergey Lapin 	return mtd->_read_oob && mtd->_write_oob;
285*dfe64e2cSSergey Lapin }
286*dfe64e2cSSergey Lapin 
287*dfe64e2cSSergey Lapin static inline int mtd_can_have_bb(const struct mtd_info *mtd)
288*dfe64e2cSSergey Lapin {
289*dfe64e2cSSergey Lapin 	return !!mtd->_block_isbad;
290*dfe64e2cSSergey Lapin }
291*dfe64e2cSSergey Lapin 
292932394acSWolfgang Denk 	/* Kernel-side ioctl definitions */
293932394acSWolfgang Denk 
294932394acSWolfgang Denk extern int add_mtd_device(struct mtd_info *mtd);
295932394acSWolfgang Denk extern int del_mtd_device (struct mtd_info *mtd);
296932394acSWolfgang Denk 
297932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
298cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name);
299932394acSWolfgang Denk 
300932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd);
3014ba692fbSBen Gardiner extern void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
3024ba692fbSBen Gardiner 				 const uint64_t length, uint64_t *len_incl_bad,
3034ba692fbSBen Gardiner 				 int *truncated);
304cfa460adSWilliam Juul /* XXX U-BOOT XXX */
305932394acSWolfgang Denk #if 0
306932394acSWolfgang Denk struct mtd_notifier {
307932394acSWolfgang Denk 	void (*add)(struct mtd_info *mtd);
308932394acSWolfgang Denk 	void (*remove)(struct mtd_info *mtd);
309932394acSWolfgang Denk 	struct list_head list;
310932394acSWolfgang Denk };
311932394acSWolfgang Denk 
312932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new);
313932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old);
314932394acSWolfgang Denk #endif
315932394acSWolfgang Denk 
316932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS
317932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr);
318932394acSWolfgang Denk #else
319932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr)
320932394acSWolfgang Denk {
321932394acSWolfgang Denk 	if (instr->callback)
322932394acSWolfgang Denk 		instr->callback(instr);
323932394acSWolfgang Denk }
324932394acSWolfgang Denk #endif
325932394acSWolfgang Denk 
326932394acSWolfgang Denk /*
327932394acSWolfgang Denk  * Debugging macro and defines
328932394acSWolfgang Denk  */
329932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */
330932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1	(1)	/* Audible */
331932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */
332932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
333932394acSWolfgang Denk 
334932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG
335*dfe64e2cSSergey Lapin #define pr_debug(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
3363167c538SScott Wood #define MTDDEBUG(n, args...)				\
337932394acSWolfgang Denk 	do {						\
338932394acSWolfgang Denk 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
339932394acSWolfgang Denk 			printk(KERN_INFO args);		\
340932394acSWolfgang Denk 	} while(0)
341932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */
342*dfe64e2cSSergey Lapin #define pr_debug(args...)
343c45912d8SScott Wood #define MTDDEBUG(n, args...)				\
344c45912d8SScott Wood 	do {						\
345c45912d8SScott Wood 		if (0)					\
346c45912d8SScott Wood 			printk(KERN_INFO args);		\
347c45912d8SScott Wood 	} while(0)
348932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */
349*dfe64e2cSSergey Lapin #define pr_info(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
350*dfe64e2cSSergey Lapin #define pr_warn(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
351*dfe64e2cSSergey Lapin #define pr_err(args...)		MTDDEBUG(MTD_DEBUG_LEVEL0, args)
352*dfe64e2cSSergey Lapin 
353*dfe64e2cSSergey Lapin static inline int mtd_is_bitflip(int err) {
354*dfe64e2cSSergey Lapin 	return err == -EUCLEAN;
355*dfe64e2cSSergey Lapin }
356*dfe64e2cSSergey Lapin 
357*dfe64e2cSSergey Lapin static inline int mtd_is_eccerr(int err) {
358*dfe64e2cSSergey Lapin 	return err == -EBADMSG;
359*dfe64e2cSSergey Lapin }
360*dfe64e2cSSergey Lapin 
361*dfe64e2cSSergey Lapin static inline int mtd_is_bitflip_or_eccerr(int err) {
362*dfe64e2cSSergey Lapin 	return mtd_is_bitflip(err) || mtd_is_eccerr(err);
363*dfe64e2cSSergey Lapin }
364932394acSWolfgang Denk 
365932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */
366