xref: /rk3399_rockchip-uboot/include/linux/mtd/mtd.h (revision 2580a2a7e719ee6bf20d8d6bcbe0c01a74cd2d54)
1932394acSWolfgang Denk /*
2ff94bc40SHeiko Schocher  * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
3932394acSWolfgang Denk  *
4932394acSWolfgang Denk  * Released under GPL
5ff94bc40SHeiko Schocher  *
6932394acSWolfgang Denk  */
7932394acSWolfgang Denk 
8932394acSWolfgang Denk #ifndef __MTD_MTD_H__
9932394acSWolfgang Denk #define __MTD_MTD_H__
10cfa460adSWilliam Juul 
11ff94bc40SHeiko Schocher #ifndef __UBOOT__
12932394acSWolfgang Denk #include <linux/types.h>
13ff94bc40SHeiko Schocher #include <linux/uio.h>
14ff94bc40SHeiko Schocher #include <linux/notifier.h>
15ff94bc40SHeiko Schocher #include <linux/device.h>
16ff94bc40SHeiko Schocher 
17ff94bc40SHeiko Schocher #include <mtd/mtd-abi.h>
18ff94bc40SHeiko Schocher 
19ff94bc40SHeiko Schocher #include <asm/div64.h>
20ff94bc40SHeiko Schocher #else
21ff94bc40SHeiko Schocher #include <linux/compat.h>
22dfe64e2cSSergey Lapin #include <mtd/mtd-abi.h>
23dfe64e2cSSergey Lapin #include <asm/errno.h>
24ff94bc40SHeiko Schocher #include <div64.h>
25932394acSWolfgang Denk 
26cfa460adSWilliam Juul #define MAX_MTD_DEVICES 32
27ff94bc40SHeiko Schocher #endif
28932394acSWolfgang Denk 
29932394acSWolfgang Denk #define MTD_ERASE_PENDING	0x01
30932394acSWolfgang Denk #define MTD_ERASING		0x02
31932394acSWolfgang Denk #define MTD_ERASE_SUSPEND	0x04
32932394acSWolfgang Denk #define MTD_ERASE_DONE		0x08
33932394acSWolfgang Denk #define MTD_ERASE_FAILED	0x10
34932394acSWolfgang Denk 
358d2effeaSStefan Roese #define MTD_FAIL_ADDR_UNKNOWN -1LL
368d2effeaSStefan Roese 
37d438d508SKyungmin Park /*
38ff94bc40SHeiko Schocher  * If the erase fails, fail_addr might indicate exactly which block failed. If
39ff94bc40SHeiko Schocher  * fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
40ff94bc40SHeiko Schocher  * or was not specific to any particular block.
41d438d508SKyungmin Park  */
42932394acSWolfgang Denk struct erase_info {
43932394acSWolfgang Denk 	struct mtd_info *mtd;
448d2effeaSStefan Roese 	uint64_t addr;
458d2effeaSStefan Roese 	uint64_t len;
468d2effeaSStefan Roese 	uint64_t fail_addr;
47932394acSWolfgang Denk 	u_long time;
48932394acSWolfgang Denk 	u_long retries;
49ff94bc40SHeiko Schocher 	unsigned dev;
50ff94bc40SHeiko Schocher 	unsigned cell;
51932394acSWolfgang Denk 	void (*callback) (struct erase_info *self);
52932394acSWolfgang Denk 	u_long priv;
53932394acSWolfgang Denk 	u_char state;
54932394acSWolfgang Denk 	struct erase_info *next;
556d41419fSMarek Vasut 	int scrub;
56932394acSWolfgang Denk };
57932394acSWolfgang Denk 
58932394acSWolfgang Denk struct mtd_erase_region_info {
598d2effeaSStefan Roese 	uint64_t offset;		/* At which this region starts, from the beginning of the MTD */
60ff94bc40SHeiko Schocher 	uint32_t erasesize;		/* For this region */
61ff94bc40SHeiko Schocher 	uint32_t numblocks;		/* Number of blocks of erasesize in this region */
62cfa460adSWilliam Juul 	unsigned long *lockmap;		/* If keeping bitmap of locks */
63cfa460adSWilliam Juul };
64cfa460adSWilliam Juul 
65cfa460adSWilliam Juul /**
66cfa460adSWilliam Juul  * struct mtd_oob_ops - oob operation operands
67cfa460adSWilliam Juul  * @mode:	operation mode
68cfa460adSWilliam Juul  *
69cfa460adSWilliam Juul  * @len:	number of data bytes to write/read
70cfa460adSWilliam Juul  *
71cfa460adSWilliam Juul  * @retlen:	number of data bytes written/read
72cfa460adSWilliam Juul  *
73cfa460adSWilliam Juul  * @ooblen:	number of oob bytes to write/read
74cfa460adSWilliam Juul  * @oobretlen:	number of oob bytes written/read
75cfa460adSWilliam Juul  * @ooboffs:	offset of oob data in the oob area (only relevant when
76dfe64e2cSSergey Lapin  *		mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
77cfa460adSWilliam Juul  * @datbuf:	data buffer - if NULL only oob data are read/written
78cfa460adSWilliam Juul  * @oobbuf:	oob data buffer
79cfa460adSWilliam Juul  *
80ff94bc40SHeiko Schocher  * Note, it is allowed to read more than one OOB area at one go, but not write.
81cfa460adSWilliam Juul  * The interface assumes that the OOB write requests program only one page's
82cfa460adSWilliam Juul  * OOB area.
83cfa460adSWilliam Juul  */
84cfa460adSWilliam Juul struct mtd_oob_ops {
85dfe64e2cSSergey Lapin 	unsigned int	mode;
86cfa460adSWilliam Juul 	size_t		len;
87cfa460adSWilliam Juul 	size_t		retlen;
88cfa460adSWilliam Juul 	size_t		ooblen;
89cfa460adSWilliam Juul 	size_t		oobretlen;
90cfa460adSWilliam Juul 	uint32_t	ooboffs;
91cfa460adSWilliam Juul 	uint8_t		*datbuf;
92cfa460adSWilliam Juul 	uint8_t		*oobbuf;
93932394acSWolfgang Denk };
94932394acSWolfgang Denk 
9568ec9c85SPrabhakar Kushwaha #ifdef CONFIG_SYS_NAND_MAX_OOBFREE
9668ec9c85SPrabhakar Kushwaha #define MTD_MAX_OOBFREE_ENTRIES_LARGE	CONFIG_SYS_NAND_MAX_OOBFREE
9768ec9c85SPrabhakar Kushwaha #else
9868ec9c85SPrabhakar Kushwaha #define MTD_MAX_OOBFREE_ENTRIES_LARGE	32
9968ec9c85SPrabhakar Kushwaha #endif
10068ec9c85SPrabhakar Kushwaha 
10168ec9c85SPrabhakar Kushwaha #ifdef CONFIG_SYS_NAND_MAX_ECCPOS
10268ec9c85SPrabhakar Kushwaha #define MTD_MAX_ECCPOS_ENTRIES_LARGE	CONFIG_SYS_NAND_MAX_ECCPOS
10368ec9c85SPrabhakar Kushwaha #else
104*2580a2a7SSiva Durga Prasad Paladugu #define MTD_MAX_ECCPOS_ENTRIES_LARGE	680
10568ec9c85SPrabhakar Kushwaha #endif
10668ec9c85SPrabhakar Kushwaha 
10768ec9c85SPrabhakar Kushwaha /*
108ff94bc40SHeiko Schocher  * Internal ECC layout control structure. For historical reasons, there is a
109ff94bc40SHeiko Schocher  * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
110ff94bc40SHeiko Schocher  * for export to user-space via the ECCGETLAYOUT ioctl.
111ff94bc40SHeiko Schocher  * nand_ecclayout should be expandable in the future simply by the above macros.
11268ec9c85SPrabhakar Kushwaha  */
11368ec9c85SPrabhakar Kushwaha struct nand_ecclayout {
114ff94bc40SHeiko Schocher 	__u32 eccbytes;
115ff94bc40SHeiko Schocher 	__u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
116ff94bc40SHeiko Schocher 	__u32 oobavail;
11768ec9c85SPrabhakar Kushwaha 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
11868ec9c85SPrabhakar Kushwaha };
11968ec9c85SPrabhakar Kushwaha 
120ff94bc40SHeiko Schocher struct module;	/* only needed for owner field in mtd_info */
121ff94bc40SHeiko Schocher 
122932394acSWolfgang Denk struct mtd_info {
123932394acSWolfgang Denk 	u_char type;
124ff94bc40SHeiko Schocher 	uint32_t flags;
125ff94bc40SHeiko Schocher 	uint64_t size;	 // Total size of the MTD
126932394acSWolfgang Denk 
127fa82f871SAlbert ARIBAUD 	/* "Major" erase size for the device. Naïve users may take this
128932394acSWolfgang Denk 	 * to be the only erase size available, or may use the more detailed
129932394acSWolfgang Denk 	 * information below if they desire
130932394acSWolfgang Denk 	 */
131ff94bc40SHeiko Schocher 	uint32_t erasesize;
132cfa460adSWilliam Juul 	/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
133cfa460adSWilliam Juul 	 * though individual bits can be cleared), in case of NAND flash it is
134cfa460adSWilliam Juul 	 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
135cfa460adSWilliam Juul 	 * it is of ECC block size, etc. It is illegal to have writesize = 0.
136cfa460adSWilliam Juul 	 * Any driver registering a struct mtd_info must ensure a writesize of
137cfa460adSWilliam Juul 	 * 1 or larger.
138cfa460adSWilliam Juul 	 */
139ff94bc40SHeiko Schocher 	uint32_t writesize;
140932394acSWolfgang Denk 
141ff94bc40SHeiko Schocher 	/*
142ff94bc40SHeiko Schocher 	 * Size of the write buffer used by the MTD. MTD devices having a write
143ff94bc40SHeiko Schocher 	 * buffer can write multiple writesize chunks at a time. E.g. while
144ff94bc40SHeiko Schocher 	 * writing 4 * writesize bytes to a device with 2 * writesize bytes
145ff94bc40SHeiko Schocher 	 * buffer the MTD driver can (but doesn't have to) do 2 writesize
146ff94bc40SHeiko Schocher 	 * operations, but not 4. Currently, all NANDs have writebufsize
147ff94bc40SHeiko Schocher 	 * equivalent to writesize (NAND page size). Some NOR flashes do have
148ff94bc40SHeiko Schocher 	 * writebufsize greater than writesize.
149ff94bc40SHeiko Schocher 	 */
150ff94bc40SHeiko Schocher 	uint32_t writebufsize;
151ff94bc40SHeiko Schocher 
152ff94bc40SHeiko Schocher 	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
153ff94bc40SHeiko Schocher 	uint32_t oobavail;  // Available OOB bytes per block
154ff94bc40SHeiko Schocher 
155ff94bc40SHeiko Schocher 	/*
156ff94bc40SHeiko Schocher 	 * If erasesize is a power of 2 then the shift is stored in
157ff94bc40SHeiko Schocher 	 * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
158ff94bc40SHeiko Schocher 	 */
159ff94bc40SHeiko Schocher 	unsigned int erasesize_shift;
160ff94bc40SHeiko Schocher 	unsigned int writesize_shift;
161ff94bc40SHeiko Schocher 	/* Masks based on erasesize_shift and writesize_shift */
162ff94bc40SHeiko Schocher 	unsigned int erasesize_mask;
163ff94bc40SHeiko Schocher 	unsigned int writesize_mask;
164932394acSWolfgang Denk 
165dfe64e2cSSergey Lapin 	/*
166dfe64e2cSSergey Lapin 	 * read ops return -EUCLEAN if max number of bitflips corrected on any
167dfe64e2cSSergey Lapin 	 * one region comprising an ecc step equals or exceeds this value.
168dfe64e2cSSergey Lapin 	 * Settable by driver, else defaults to ecc_strength.  User can override
169dfe64e2cSSergey Lapin 	 * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed;
170dfe64e2cSSergey Lapin 	 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
171dfe64e2cSSergey Lapin 	 */
172dfe64e2cSSergey Lapin 	unsigned int bitflip_threshold;
173dfe64e2cSSergey Lapin 
174ff94bc40SHeiko Schocher 	// Kernel-only stuff starts here.
175ff94bc40SHeiko Schocher #ifndef __UBOOT__
176c45912d8SScott Wood 	const char *name;
177ff94bc40SHeiko Schocher #else
178ff94bc40SHeiko Schocher 	char *name;
179ff94bc40SHeiko Schocher #endif
180932394acSWolfgang Denk 	int index;
181932394acSWolfgang Denk 
182dfe64e2cSSergey Lapin 	/* ECC layout structure pointer - read only! */
183cfa460adSWilliam Juul 	struct nand_ecclayout *ecclayout;
184932394acSWolfgang Denk 
185ff94bc40SHeiko Schocher 	/* the ecc step size. */
186ff94bc40SHeiko Schocher 	unsigned int ecc_step_size;
187ff94bc40SHeiko Schocher 
188dfe64e2cSSergey Lapin 	/* max number of correctible bit errors per ecc step */
189dfe64e2cSSergey Lapin 	unsigned int ecc_strength;
190dfe64e2cSSergey Lapin 
191932394acSWolfgang Denk 	/* Data for variable erase regions. If numeraseregions is zero,
192932394acSWolfgang Denk 	 * it means that the whole device has erasesize as given above.
193932394acSWolfgang Denk 	 */
194932394acSWolfgang Denk 	int numeraseregions;
195932394acSWolfgang Denk 	struct mtd_erase_region_info *eraseregions;
196932394acSWolfgang Denk 
197c45912d8SScott Wood 	/*
198dfe64e2cSSergey Lapin 	 * Do not call via these pointers, use corresponding mtd_*()
199dfe64e2cSSergey Lapin 	 * wrappers instead.
200c45912d8SScott Wood 	 */
201dfe64e2cSSergey Lapin 	int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
202ff94bc40SHeiko Schocher #ifndef __UBOOT__
203dfe64e2cSSergey Lapin 	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
204ff94bc40SHeiko Schocher 		       size_t *retlen, void **virt, resource_size_t *phys);
205ff94bc40SHeiko Schocher 	int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
206ff94bc40SHeiko Schocher #endif
207ff94bc40SHeiko Schocher 	unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
208ff94bc40SHeiko Schocher 					     unsigned long len,
209ff94bc40SHeiko Schocher 					     unsigned long offset,
210ff94bc40SHeiko Schocher 					     unsigned long flags);
211dfe64e2cSSergey Lapin 	int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
212dfe64e2cSSergey Lapin 		      size_t *retlen, u_char *buf);
213dfe64e2cSSergey Lapin 	int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
214dfe64e2cSSergey Lapin 		       size_t *retlen, const u_char *buf);
215ff94bc40SHeiko Schocher 	int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
216ff94bc40SHeiko Schocher 			     size_t *retlen, const u_char *buf);
217dfe64e2cSSergey Lapin 	int (*_read_oob) (struct mtd_info *mtd, loff_t from,
218cfa460adSWilliam Juul 			  struct mtd_oob_ops *ops);
219dfe64e2cSSergey Lapin 	int (*_write_oob) (struct mtd_info *mtd, loff_t to,
220cfa460adSWilliam Juul 			   struct mtd_oob_ops *ops);
2214e67c571SHeiko Schocher 	int (*_get_fact_prot_info) (struct mtd_info *mtd, size_t len,
2224e67c571SHeiko Schocher 				    size_t *retlen, struct otp_info *buf);
223dfe64e2cSSergey Lapin 	int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
224dfe64e2cSSergey Lapin 				    size_t len, size_t *retlen, u_char *buf);
2254e67c571SHeiko Schocher 	int (*_get_user_prot_info) (struct mtd_info *mtd, size_t len,
2264e67c571SHeiko Schocher 				    size_t *retlen, struct otp_info *buf);
227dfe64e2cSSergey Lapin 	int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
228dfe64e2cSSergey Lapin 				    size_t len, size_t *retlen, u_char *buf);
229ff94bc40SHeiko Schocher 	int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
230ff94bc40SHeiko Schocher 				     size_t len, size_t *retlen, u_char *buf);
231dfe64e2cSSergey Lapin 	int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
232dfe64e2cSSergey Lapin 				    size_t len);
233ff94bc40SHeiko Schocher #ifndef __UBOOT__
234ff94bc40SHeiko Schocher 	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
235ff94bc40SHeiko Schocher 			unsigned long count, loff_t to, size_t *retlen);
236ff94bc40SHeiko Schocher #endif
237dfe64e2cSSergey Lapin 	void (*_sync) (struct mtd_info *mtd);
238dfe64e2cSSergey Lapin 	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
239dfe64e2cSSergey Lapin 	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
240ff94bc40SHeiko Schocher 	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
24186a720aaSEzequiel Garcia 	int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
242dfe64e2cSSergey Lapin 	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
243dfe64e2cSSergey Lapin 	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
244ff94bc40SHeiko Schocher #ifndef __UBOOT__
245ff94bc40SHeiko Schocher 	int (*_suspend) (struct mtd_info *mtd);
246ff94bc40SHeiko Schocher 	void (*_resume) (struct mtd_info *mtd);
247ff94bc40SHeiko Schocher #endif
248932394acSWolfgang Denk 	/*
249dfe64e2cSSergey Lapin 	 * If the driver is something smart, like UBI, it may need to maintain
250dfe64e2cSSergey Lapin 	 * its own reference counting. The below functions are only for driver.
251932394acSWolfgang Denk 	 */
252dfe64e2cSSergey Lapin 	int (*_get_device) (struct mtd_info *mtd);
253dfe64e2cSSergey Lapin 	void (*_put_device) (struct mtd_info *mtd);
254cfa460adSWilliam Juul 
255ff94bc40SHeiko Schocher #ifndef __UBOOT__
256ff94bc40SHeiko Schocher 	/* Backing device capabilities for this device
257ff94bc40SHeiko Schocher 	 * - provides mmap capabilities
258932394acSWolfgang Denk 	 */
259ff94bc40SHeiko Schocher 	struct backing_dev_info *backing_dev_info;
260ff94bc40SHeiko Schocher 
261cfa460adSWilliam Juul 	struct notifier_block reboot_notifier;  /* default mode before reboot */
262cfa460adSWilliam Juul #endif
263cfa460adSWilliam Juul 
264cfa460adSWilliam Juul 	/* ECC status information */
265cfa460adSWilliam Juul 	struct mtd_ecc_stats ecc_stats;
266cfa460adSWilliam Juul 	/* Subpage shift (NAND) */
267cfa460adSWilliam Juul 	int subpage_sft;
268cfa460adSWilliam Juul 
269932394acSWolfgang Denk 	void *priv;
270932394acSWolfgang Denk 
271932394acSWolfgang Denk 	struct module *owner;
272ff94bc40SHeiko Schocher #ifndef __UBOOT__
273ff94bc40SHeiko Schocher 	struct device dev;
274ff94bc40SHeiko Schocher #endif
275932394acSWolfgang Denk 	int usecount;
276932394acSWolfgang Denk };
277932394acSWolfgang Denk 
278dfe64e2cSSergey Lapin int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
279ff94bc40SHeiko Schocher #ifndef __UBOOT__
280ff94bc40SHeiko Schocher int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
281ff94bc40SHeiko Schocher 	      void **virt, resource_size_t *phys);
282ff94bc40SHeiko Schocher int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
283ff94bc40SHeiko Schocher #endif
284ff94bc40SHeiko Schocher unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
285ff94bc40SHeiko Schocher 				    unsigned long offset, unsigned long flags);
286dfe64e2cSSergey Lapin int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
287dfe64e2cSSergey Lapin 	     u_char *buf);
288dfe64e2cSSergey Lapin int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
289dfe64e2cSSergey Lapin 	      const u_char *buf);
290dfe64e2cSSergey Lapin int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
291dfe64e2cSSergey Lapin 		    const u_char *buf);
292dfe64e2cSSergey Lapin 
293dfe64e2cSSergey Lapin int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
294dfe64e2cSSergey Lapin 
295dfe64e2cSSergey Lapin static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
296dfe64e2cSSergey Lapin 				struct mtd_oob_ops *ops)
297dfe64e2cSSergey Lapin {
298dfe64e2cSSergey Lapin 	ops->retlen = ops->oobretlen = 0;
299dfe64e2cSSergey Lapin 	if (!mtd->_write_oob)
300dfe64e2cSSergey Lapin 		return -EOPNOTSUPP;
301dfe64e2cSSergey Lapin 	if (!(mtd->flags & MTD_WRITEABLE))
302dfe64e2cSSergey Lapin 		return -EROFS;
303dfe64e2cSSergey Lapin 	return mtd->_write_oob(mtd, to, ops);
304dfe64e2cSSergey Lapin }
305dfe64e2cSSergey Lapin 
3064e67c571SHeiko Schocher int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
3074e67c571SHeiko Schocher 			   struct otp_info *buf);
308dfe64e2cSSergey Lapin int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
309dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
3104e67c571SHeiko Schocher int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
3114e67c571SHeiko Schocher 			   struct otp_info *buf);
312dfe64e2cSSergey Lapin int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
313dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
314dfe64e2cSSergey Lapin int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
315dfe64e2cSSergey Lapin 			    size_t *retlen, u_char *buf);
316dfe64e2cSSergey Lapin int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
317dfe64e2cSSergey Lapin 
318ff94bc40SHeiko Schocher #ifndef __UBOOT__
319dfe64e2cSSergey Lapin int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
320dfe64e2cSSergey Lapin 	       unsigned long count, loff_t to, size_t *retlen);
321dfe64e2cSSergey Lapin #endif
322dfe64e2cSSergey Lapin 
323dfe64e2cSSergey Lapin static inline void mtd_sync(struct mtd_info *mtd)
324dfe64e2cSSergey Lapin {
325dfe64e2cSSergey Lapin 	if (mtd->_sync)
326dfe64e2cSSergey Lapin 		mtd->_sync(mtd);
327dfe64e2cSSergey Lapin }
328dfe64e2cSSergey Lapin 
329dfe64e2cSSergey Lapin int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
330dfe64e2cSSergey Lapin int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
331dfe64e2cSSergey Lapin int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
33286a720aaSEzequiel Garcia int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
333dfe64e2cSSergey Lapin int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
334dfe64e2cSSergey Lapin int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
335dfe64e2cSSergey Lapin 
336ff94bc40SHeiko Schocher #ifndef __UBOOT__
337ff94bc40SHeiko Schocher static inline int mtd_suspend(struct mtd_info *mtd)
338ff94bc40SHeiko Schocher {
339ff94bc40SHeiko Schocher 	return mtd->_suspend ? mtd->_suspend(mtd) : 0;
340ff94bc40SHeiko Schocher }
341ff94bc40SHeiko Schocher 
342ff94bc40SHeiko Schocher static inline void mtd_resume(struct mtd_info *mtd)
343ff94bc40SHeiko Schocher {
344ff94bc40SHeiko Schocher 	if (mtd->_resume)
345ff94bc40SHeiko Schocher 		mtd->_resume(mtd);
346ff94bc40SHeiko Schocher }
347ff94bc40SHeiko Schocher #endif
348ff94bc40SHeiko Schocher 
3498d2effeaSStefan Roese static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
3508d2effeaSStefan Roese {
351ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
352ff94bc40SHeiko Schocher 		return sz >> mtd->erasesize_shift;
3538d2effeaSStefan Roese 	do_div(sz, mtd->erasesize);
3548d2effeaSStefan Roese 	return sz;
3558d2effeaSStefan Roese }
3568d2effeaSStefan Roese 
3578d2effeaSStefan Roese static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
3588d2effeaSStefan Roese {
359ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
360ff94bc40SHeiko Schocher 		return sz & mtd->erasesize_mask;
3618d2effeaSStefan Roese 	return do_div(sz, mtd->erasesize);
3628d2effeaSStefan Roese }
363932394acSWolfgang Denk 
364ff94bc40SHeiko Schocher static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
365ff94bc40SHeiko Schocher {
366ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
367ff94bc40SHeiko Schocher 		return sz >> mtd->writesize_shift;
368ff94bc40SHeiko Schocher 	do_div(sz, mtd->writesize);
369ff94bc40SHeiko Schocher 	return sz;
370ff94bc40SHeiko Schocher }
371ff94bc40SHeiko Schocher 
372ff94bc40SHeiko Schocher static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
373ff94bc40SHeiko Schocher {
374ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
375ff94bc40SHeiko Schocher 		return sz & mtd->writesize_mask;
376ff94bc40SHeiko Schocher 	return do_div(sz, mtd->writesize);
377ff94bc40SHeiko Schocher }
378ff94bc40SHeiko Schocher 
379dfe64e2cSSergey Lapin static inline int mtd_has_oob(const struct mtd_info *mtd)
380dfe64e2cSSergey Lapin {
381dfe64e2cSSergey Lapin 	return mtd->_read_oob && mtd->_write_oob;
382dfe64e2cSSergey Lapin }
383dfe64e2cSSergey Lapin 
384ff94bc40SHeiko Schocher static inline int mtd_type_is_nand(const struct mtd_info *mtd)
385ff94bc40SHeiko Schocher {
386ff94bc40SHeiko Schocher 	return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
387ff94bc40SHeiko Schocher }
388ff94bc40SHeiko Schocher 
389dfe64e2cSSergey Lapin static inline int mtd_can_have_bb(const struct mtd_info *mtd)
390dfe64e2cSSergey Lapin {
391dfe64e2cSSergey Lapin 	return !!mtd->_block_isbad;
392dfe64e2cSSergey Lapin }
393dfe64e2cSSergey Lapin 
394932394acSWolfgang Denk 	/* Kernel-side ioctl definitions */
395932394acSWolfgang Denk 
396ff94bc40SHeiko Schocher struct mtd_partition;
397ff94bc40SHeiko Schocher struct mtd_part_parser_data;
398932394acSWolfgang Denk 
399ff94bc40SHeiko Schocher extern int mtd_device_parse_register(struct mtd_info *mtd,
400ff94bc40SHeiko Schocher 				     const char * const *part_probe_types,
401ff94bc40SHeiko Schocher 				     struct mtd_part_parser_data *parser_data,
402ff94bc40SHeiko Schocher 				     const struct mtd_partition *defparts,
403ff94bc40SHeiko Schocher 				     int defnr_parts);
404ff94bc40SHeiko Schocher #define mtd_device_register(master, parts, nr_parts)	\
405ff94bc40SHeiko Schocher 	mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
406ff94bc40SHeiko Schocher extern int mtd_device_unregister(struct mtd_info *master);
407932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
408ff94bc40SHeiko Schocher extern int __get_mtd_device(struct mtd_info *mtd);
409ff94bc40SHeiko Schocher extern void __put_mtd_device(struct mtd_info *mtd);
410cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name);
411932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd);
412ff94bc40SHeiko Schocher 
413ff94bc40SHeiko Schocher 
414ff94bc40SHeiko Schocher #ifndef __UBOOT__
415932394acSWolfgang Denk struct mtd_notifier {
416932394acSWolfgang Denk 	void (*add)(struct mtd_info *mtd);
417932394acSWolfgang Denk 	void (*remove)(struct mtd_info *mtd);
418932394acSWolfgang Denk 	struct list_head list;
419932394acSWolfgang Denk };
420932394acSWolfgang Denk 
421ff94bc40SHeiko Schocher 
422932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new);
423932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old);
424932394acSWolfgang Denk #endif
425ff94bc40SHeiko Schocher void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
426932394acSWolfgang Denk 
427932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS
428932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr);
429932394acSWolfgang Denk #else
430932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr)
431932394acSWolfgang Denk {
432932394acSWolfgang Denk 	if (instr->callback)
433932394acSWolfgang Denk 		instr->callback(instr);
434932394acSWolfgang Denk }
435932394acSWolfgang Denk #endif
436932394acSWolfgang Denk 
437ff94bc40SHeiko Schocher #ifdef __UBOOT__
438932394acSWolfgang Denk /*
439932394acSWolfgang Denk  * Debugging macro and defines
440932394acSWolfgang Denk  */
441932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */
442932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1	(1)	/* Audible */
443932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */
444932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
445932394acSWolfgang Denk 
446932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG
447dfe64e2cSSergey Lapin #define pr_debug(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
4483167c538SScott Wood #define MTDDEBUG(n, args...)				\
449932394acSWolfgang Denk 	do {						\
450932394acSWolfgang Denk 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
451932394acSWolfgang Denk 			printk(KERN_INFO args);		\
452932394acSWolfgang Denk 	} while(0)
453932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */
454dfe64e2cSSergey Lapin #define pr_debug(args...)
455c45912d8SScott Wood #define MTDDEBUG(n, args...)				\
456c45912d8SScott Wood 	do {						\
457c45912d8SScott Wood 		if (0)					\
458c45912d8SScott Wood 			printk(KERN_INFO args);		\
459c45912d8SScott Wood 	} while(0)
460932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */
461dfe64e2cSSergey Lapin #define pr_info(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
462dfe64e2cSSergey Lapin #define pr_warn(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
463dfe64e2cSSergey Lapin #define pr_err(args...)		MTDDEBUG(MTD_DEBUG_LEVEL0, args)
464ff94bc40SHeiko Schocher #define pr_crit(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
465ff94bc40SHeiko Schocher #define pr_cont(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
466ff94bc40SHeiko Schocher #define pr_notice(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
467ff94bc40SHeiko Schocher #endif
468dfe64e2cSSergey Lapin 
469dfe64e2cSSergey Lapin static inline int mtd_is_bitflip(int err) {
470dfe64e2cSSergey Lapin 	return err == -EUCLEAN;
471dfe64e2cSSergey Lapin }
472dfe64e2cSSergey Lapin 
473dfe64e2cSSergey Lapin static inline int mtd_is_eccerr(int err) {
474dfe64e2cSSergey Lapin 	return err == -EBADMSG;
475dfe64e2cSSergey Lapin }
476dfe64e2cSSergey Lapin 
477dfe64e2cSSergey Lapin static inline int mtd_is_bitflip_or_eccerr(int err) {
478dfe64e2cSSergey Lapin 	return mtd_is_bitflip(err) || mtd_is_eccerr(err);
479dfe64e2cSSergey Lapin }
480932394acSWolfgang Denk 
481ff94bc40SHeiko Schocher #ifdef __UBOOT__
482ff94bc40SHeiko Schocher /* drivers/mtd/mtdcore.h */
483ff94bc40SHeiko Schocher int add_mtd_device(struct mtd_info *mtd);
484ddf7bcfaSHeiko Schocher int del_mtd_device(struct mtd_info *mtd);
485ff94bc40SHeiko Schocher int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
486ff94bc40SHeiko Schocher int del_mtd_partitions(struct mtd_info *);
48709c32807SHeiko Schocher 
48809c32807SHeiko Schocher int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
489f18d1116SMasahiro Yamada 		loff_t *maxsize, int devtype, uint64_t chipsize);
49009c32807SHeiko Schocher int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
491f18d1116SMasahiro Yamada 		     loff_t *size, loff_t *maxsize, int devtype,
492f18d1116SMasahiro Yamada 		     uint64_t chipsize);
493ff94bc40SHeiko Schocher #endif
494932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */
495