xref: /rk3399_rockchip-uboot/include/linux/mtd/mtd.h (revision ddf7bcfa6c5a1d9647046c18e4945f0b0686aec5)
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 #define __UBOOT__
12ff94bc40SHeiko Schocher #ifndef __UBOOT__
13932394acSWolfgang Denk #include <linux/types.h>
14ff94bc40SHeiko Schocher #include <linux/uio.h>
15ff94bc40SHeiko Schocher #include <linux/notifier.h>
16ff94bc40SHeiko Schocher #include <linux/device.h>
17ff94bc40SHeiko Schocher 
18ff94bc40SHeiko Schocher #include <mtd/mtd-abi.h>
19ff94bc40SHeiko Schocher 
20ff94bc40SHeiko Schocher #include <asm/div64.h>
21ff94bc40SHeiko Schocher #else
22ff94bc40SHeiko Schocher #include <linux/compat.h>
23dfe64e2cSSergey Lapin #include <mtd/mtd-abi.h>
24dfe64e2cSSergey Lapin #include <asm/errno.h>
25ff94bc40SHeiko Schocher #include <div64.h>
26932394acSWolfgang Denk 
27cfa460adSWilliam Juul #define MAX_MTD_DEVICES 32
28ff94bc40SHeiko Schocher #endif
29932394acSWolfgang Denk 
30932394acSWolfgang Denk #define MTD_ERASE_PENDING	0x01
31932394acSWolfgang Denk #define MTD_ERASING		0x02
32932394acSWolfgang Denk #define MTD_ERASE_SUSPEND	0x04
33932394acSWolfgang Denk #define MTD_ERASE_DONE		0x08
34932394acSWolfgang Denk #define MTD_ERASE_FAILED	0x10
35932394acSWolfgang Denk 
368d2effeaSStefan Roese #define MTD_FAIL_ADDR_UNKNOWN -1LL
378d2effeaSStefan Roese 
38d438d508SKyungmin Park /*
39ff94bc40SHeiko Schocher  * If the erase fails, fail_addr might indicate exactly which block failed. If
40ff94bc40SHeiko Schocher  * fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
41ff94bc40SHeiko Schocher  * or was not specific to any particular block.
42d438d508SKyungmin Park  */
43932394acSWolfgang Denk struct erase_info {
44932394acSWolfgang Denk 	struct mtd_info *mtd;
458d2effeaSStefan Roese 	uint64_t addr;
468d2effeaSStefan Roese 	uint64_t len;
478d2effeaSStefan Roese 	uint64_t fail_addr;
48932394acSWolfgang Denk 	u_long time;
49932394acSWolfgang Denk 	u_long retries;
50ff94bc40SHeiko Schocher 	unsigned dev;
51ff94bc40SHeiko Schocher 	unsigned cell;
52932394acSWolfgang Denk 	void (*callback) (struct erase_info *self);
53932394acSWolfgang Denk 	u_long priv;
54932394acSWolfgang Denk 	u_char state;
55932394acSWolfgang Denk 	struct erase_info *next;
566d41419fSMarek Vasut 	int scrub;
57932394acSWolfgang Denk };
58932394acSWolfgang Denk 
59932394acSWolfgang Denk struct mtd_erase_region_info {
608d2effeaSStefan Roese 	uint64_t offset;		/* At which this region starts, from the beginning of the MTD */
61ff94bc40SHeiko Schocher 	uint32_t erasesize;		/* For this region */
62ff94bc40SHeiko Schocher 	uint32_t numblocks;		/* Number of blocks of erasesize in this region */
63cfa460adSWilliam Juul 	unsigned long *lockmap;		/* If keeping bitmap of locks */
64cfa460adSWilliam Juul };
65cfa460adSWilliam Juul 
66cfa460adSWilliam Juul /**
67cfa460adSWilliam Juul  * struct mtd_oob_ops - oob operation operands
68cfa460adSWilliam Juul  * @mode:	operation mode
69cfa460adSWilliam Juul  *
70cfa460adSWilliam Juul  * @len:	number of data bytes to write/read
71cfa460adSWilliam Juul  *
72cfa460adSWilliam Juul  * @retlen:	number of data bytes written/read
73cfa460adSWilliam Juul  *
74cfa460adSWilliam Juul  * @ooblen:	number of oob bytes to write/read
75cfa460adSWilliam Juul  * @oobretlen:	number of oob bytes written/read
76cfa460adSWilliam Juul  * @ooboffs:	offset of oob data in the oob area (only relevant when
77dfe64e2cSSergey Lapin  *		mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
78cfa460adSWilliam Juul  * @datbuf:	data buffer - if NULL only oob data are read/written
79cfa460adSWilliam Juul  * @oobbuf:	oob data buffer
80cfa460adSWilliam Juul  *
81ff94bc40SHeiko Schocher  * Note, it is allowed to read more than one OOB area at one go, but not write.
82cfa460adSWilliam Juul  * The interface assumes that the OOB write requests program only one page's
83cfa460adSWilliam Juul  * OOB area.
84cfa460adSWilliam Juul  */
85cfa460adSWilliam Juul struct mtd_oob_ops {
86dfe64e2cSSergey Lapin 	unsigned int	mode;
87cfa460adSWilliam Juul 	size_t		len;
88cfa460adSWilliam Juul 	size_t		retlen;
89cfa460adSWilliam Juul 	size_t		ooblen;
90cfa460adSWilliam Juul 	size_t		oobretlen;
91cfa460adSWilliam Juul 	uint32_t	ooboffs;
92cfa460adSWilliam Juul 	uint8_t		*datbuf;
93cfa460adSWilliam Juul 	uint8_t		*oobbuf;
94932394acSWolfgang Denk };
95932394acSWolfgang Denk 
9668ec9c85SPrabhakar Kushwaha #ifdef CONFIG_SYS_NAND_MAX_OOBFREE
9768ec9c85SPrabhakar Kushwaha #define MTD_MAX_OOBFREE_ENTRIES_LARGE	CONFIG_SYS_NAND_MAX_OOBFREE
9868ec9c85SPrabhakar Kushwaha #else
9968ec9c85SPrabhakar Kushwaha #define MTD_MAX_OOBFREE_ENTRIES_LARGE	32
10068ec9c85SPrabhakar Kushwaha #endif
10168ec9c85SPrabhakar Kushwaha 
10268ec9c85SPrabhakar Kushwaha #ifdef CONFIG_SYS_NAND_MAX_ECCPOS
10368ec9c85SPrabhakar Kushwaha #define MTD_MAX_ECCPOS_ENTRIES_LARGE	CONFIG_SYS_NAND_MAX_ECCPOS
10468ec9c85SPrabhakar Kushwaha #else
10568ec9c85SPrabhakar Kushwaha #define MTD_MAX_ECCPOS_ENTRIES_LARGE	640
10668ec9c85SPrabhakar Kushwaha #endif
10768ec9c85SPrabhakar Kushwaha 
10868ec9c85SPrabhakar Kushwaha /*
109ff94bc40SHeiko Schocher  * Internal ECC layout control structure. For historical reasons, there is a
110ff94bc40SHeiko Schocher  * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
111ff94bc40SHeiko Schocher  * for export to user-space via the ECCGETLAYOUT ioctl.
112ff94bc40SHeiko Schocher  * nand_ecclayout should be expandable in the future simply by the above macros.
11368ec9c85SPrabhakar Kushwaha  */
11468ec9c85SPrabhakar Kushwaha struct nand_ecclayout {
115ff94bc40SHeiko Schocher 	__u32 eccbytes;
116ff94bc40SHeiko Schocher 	__u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
117ff94bc40SHeiko Schocher 	__u32 oobavail;
11868ec9c85SPrabhakar Kushwaha 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
11968ec9c85SPrabhakar Kushwaha };
12068ec9c85SPrabhakar Kushwaha 
121ff94bc40SHeiko Schocher struct module;	/* only needed for owner field in mtd_info */
122ff94bc40SHeiko Schocher 
123932394acSWolfgang Denk struct mtd_info {
124932394acSWolfgang Denk 	u_char type;
125ff94bc40SHeiko Schocher 	uint32_t flags;
126ff94bc40SHeiko Schocher 	uint64_t size;	 // Total size of the MTD
127932394acSWolfgang Denk 
128fa82f871SAlbert ARIBAUD 	/* "Major" erase size for the device. Naïve users may take this
129932394acSWolfgang Denk 	 * to be the only erase size available, or may use the more detailed
130932394acSWolfgang Denk 	 * information below if they desire
131932394acSWolfgang Denk 	 */
132ff94bc40SHeiko Schocher 	uint32_t erasesize;
133cfa460adSWilliam Juul 	/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
134cfa460adSWilliam Juul 	 * though individual bits can be cleared), in case of NAND flash it is
135cfa460adSWilliam Juul 	 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
136cfa460adSWilliam Juul 	 * it is of ECC block size, etc. It is illegal to have writesize = 0.
137cfa460adSWilliam Juul 	 * Any driver registering a struct mtd_info must ensure a writesize of
138cfa460adSWilliam Juul 	 * 1 or larger.
139cfa460adSWilliam Juul 	 */
140ff94bc40SHeiko Schocher 	uint32_t writesize;
141932394acSWolfgang Denk 
142ff94bc40SHeiko Schocher 	/*
143ff94bc40SHeiko Schocher 	 * Size of the write buffer used by the MTD. MTD devices having a write
144ff94bc40SHeiko Schocher 	 * buffer can write multiple writesize chunks at a time. E.g. while
145ff94bc40SHeiko Schocher 	 * writing 4 * writesize bytes to a device with 2 * writesize bytes
146ff94bc40SHeiko Schocher 	 * buffer the MTD driver can (but doesn't have to) do 2 writesize
147ff94bc40SHeiko Schocher 	 * operations, but not 4. Currently, all NANDs have writebufsize
148ff94bc40SHeiko Schocher 	 * equivalent to writesize (NAND page size). Some NOR flashes do have
149ff94bc40SHeiko Schocher 	 * writebufsize greater than writesize.
150ff94bc40SHeiko Schocher 	 */
151ff94bc40SHeiko Schocher 	uint32_t writebufsize;
152ff94bc40SHeiko Schocher 
153ff94bc40SHeiko Schocher 	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
154ff94bc40SHeiko Schocher 	uint32_t oobavail;  // Available OOB bytes per block
155ff94bc40SHeiko Schocher 
156ff94bc40SHeiko Schocher 	/*
157ff94bc40SHeiko Schocher 	 * If erasesize is a power of 2 then the shift is stored in
158ff94bc40SHeiko Schocher 	 * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
159ff94bc40SHeiko Schocher 	 */
160ff94bc40SHeiko Schocher 	unsigned int erasesize_shift;
161ff94bc40SHeiko Schocher 	unsigned int writesize_shift;
162ff94bc40SHeiko Schocher 	/* Masks based on erasesize_shift and writesize_shift */
163ff94bc40SHeiko Schocher 	unsigned int erasesize_mask;
164ff94bc40SHeiko Schocher 	unsigned int writesize_mask;
165932394acSWolfgang Denk 
166dfe64e2cSSergey Lapin 	/*
167dfe64e2cSSergey Lapin 	 * read ops return -EUCLEAN if max number of bitflips corrected on any
168dfe64e2cSSergey Lapin 	 * one region comprising an ecc step equals or exceeds this value.
169dfe64e2cSSergey Lapin 	 * Settable by driver, else defaults to ecc_strength.  User can override
170dfe64e2cSSergey Lapin 	 * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed;
171dfe64e2cSSergey Lapin 	 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
172dfe64e2cSSergey Lapin 	 */
173dfe64e2cSSergey Lapin 	unsigned int bitflip_threshold;
174dfe64e2cSSergey Lapin 
175ff94bc40SHeiko Schocher 	// Kernel-only stuff starts here.
176ff94bc40SHeiko Schocher #ifndef __UBOOT__
177c45912d8SScott Wood 	const char *name;
178ff94bc40SHeiko Schocher #else
179ff94bc40SHeiko Schocher 	char *name;
180ff94bc40SHeiko Schocher #endif
181932394acSWolfgang Denk 	int index;
182932394acSWolfgang Denk 
183dfe64e2cSSergey Lapin 	/* ECC layout structure pointer - read only! */
184cfa460adSWilliam Juul 	struct nand_ecclayout *ecclayout;
185932394acSWolfgang Denk 
186ff94bc40SHeiko Schocher 	/* the ecc step size. */
187ff94bc40SHeiko Schocher 	unsigned int ecc_step_size;
188ff94bc40SHeiko Schocher 
189dfe64e2cSSergey Lapin 	/* max number of correctible bit errors per ecc step */
190dfe64e2cSSergey Lapin 	unsigned int ecc_strength;
191dfe64e2cSSergey Lapin 
192932394acSWolfgang Denk 	/* Data for variable erase regions. If numeraseregions is zero,
193932394acSWolfgang Denk 	 * it means that the whole device has erasesize as given above.
194932394acSWolfgang Denk 	 */
195932394acSWolfgang Denk 	int numeraseregions;
196932394acSWolfgang Denk 	struct mtd_erase_region_info *eraseregions;
197932394acSWolfgang Denk 
198c45912d8SScott Wood 	/*
199dfe64e2cSSergey Lapin 	 * Do not call via these pointers, use corresponding mtd_*()
200dfe64e2cSSergey Lapin 	 * wrappers instead.
201c45912d8SScott Wood 	 */
202dfe64e2cSSergey Lapin 	int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
203ff94bc40SHeiko Schocher #ifndef __UBOOT__
204dfe64e2cSSergey Lapin 	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
205ff94bc40SHeiko Schocher 		       size_t *retlen, void **virt, resource_size_t *phys);
206ff94bc40SHeiko Schocher 	int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
207ff94bc40SHeiko Schocher #endif
208ff94bc40SHeiko Schocher 	unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
209ff94bc40SHeiko Schocher 					     unsigned long len,
210ff94bc40SHeiko Schocher 					     unsigned long offset,
211ff94bc40SHeiko Schocher 					     unsigned long flags);
212dfe64e2cSSergey Lapin 	int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
213dfe64e2cSSergey Lapin 		      size_t *retlen, u_char *buf);
214dfe64e2cSSergey Lapin 	int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
215dfe64e2cSSergey Lapin 		       size_t *retlen, const u_char *buf);
216ff94bc40SHeiko Schocher 	int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
217ff94bc40SHeiko Schocher 			     size_t *retlen, const u_char *buf);
218dfe64e2cSSergey Lapin 	int (*_read_oob) (struct mtd_info *mtd, loff_t from,
219cfa460adSWilliam Juul 			  struct mtd_oob_ops *ops);
220dfe64e2cSSergey Lapin 	int (*_write_oob) (struct mtd_info *mtd, loff_t to,
221cfa460adSWilliam Juul 			   struct mtd_oob_ops *ops);
222dfe64e2cSSergey Lapin 	int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
223dfe64e2cSSergey Lapin 				    size_t len);
224dfe64e2cSSergey Lapin 	int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
225dfe64e2cSSergey Lapin 				    size_t len, size_t *retlen, u_char *buf);
226dfe64e2cSSergey Lapin 	int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
227dfe64e2cSSergey Lapin 				    size_t len);
228dfe64e2cSSergey Lapin 	int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
229dfe64e2cSSergey Lapin 				    size_t len, size_t *retlen, u_char *buf);
230ff94bc40SHeiko Schocher 	int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
231ff94bc40SHeiko Schocher 				     size_t len, size_t *retlen, u_char *buf);
232dfe64e2cSSergey Lapin 	int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
233dfe64e2cSSergey Lapin 				    size_t len);
234ff94bc40SHeiko Schocher #ifndef __UBOOT__
235ff94bc40SHeiko Schocher 	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
236ff94bc40SHeiko Schocher 			unsigned long count, loff_t to, size_t *retlen);
237ff94bc40SHeiko Schocher #endif
238dfe64e2cSSergey Lapin 	void (*_sync) (struct mtd_info *mtd);
239dfe64e2cSSergey Lapin 	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
240dfe64e2cSSergey Lapin 	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
241ff94bc40SHeiko Schocher 	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
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 
306dfe64e2cSSergey Lapin int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
307dfe64e2cSSergey Lapin 			   size_t len);
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);
310dfe64e2cSSergey Lapin int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
311dfe64e2cSSergey Lapin 			   size_t len);
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);
332dfe64e2cSSergey Lapin int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
333dfe64e2cSSergey Lapin int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
334dfe64e2cSSergey Lapin 
335ff94bc40SHeiko Schocher #ifndef __UBOOT__
336ff94bc40SHeiko Schocher static inline int mtd_suspend(struct mtd_info *mtd)
337ff94bc40SHeiko Schocher {
338ff94bc40SHeiko Schocher 	return mtd->_suspend ? mtd->_suspend(mtd) : 0;
339ff94bc40SHeiko Schocher }
340ff94bc40SHeiko Schocher 
341ff94bc40SHeiko Schocher static inline void mtd_resume(struct mtd_info *mtd)
342ff94bc40SHeiko Schocher {
343ff94bc40SHeiko Schocher 	if (mtd->_resume)
344ff94bc40SHeiko Schocher 		mtd->_resume(mtd);
345ff94bc40SHeiko Schocher }
346ff94bc40SHeiko Schocher #endif
347ff94bc40SHeiko Schocher 
3488d2effeaSStefan Roese static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
3498d2effeaSStefan Roese {
350ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
351ff94bc40SHeiko Schocher 		return sz >> mtd->erasesize_shift;
3528d2effeaSStefan Roese 	do_div(sz, mtd->erasesize);
3538d2effeaSStefan Roese 	return sz;
3548d2effeaSStefan Roese }
3558d2effeaSStefan Roese 
3568d2effeaSStefan Roese static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
3578d2effeaSStefan Roese {
358ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
359ff94bc40SHeiko Schocher 		return sz & mtd->erasesize_mask;
3608d2effeaSStefan Roese 	return do_div(sz, mtd->erasesize);
3618d2effeaSStefan Roese }
362932394acSWolfgang Denk 
363ff94bc40SHeiko Schocher static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
364ff94bc40SHeiko Schocher {
365ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
366ff94bc40SHeiko Schocher 		return sz >> mtd->writesize_shift;
367ff94bc40SHeiko Schocher 	do_div(sz, mtd->writesize);
368ff94bc40SHeiko Schocher 	return sz;
369ff94bc40SHeiko Schocher }
370ff94bc40SHeiko Schocher 
371ff94bc40SHeiko Schocher static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
372ff94bc40SHeiko Schocher {
373ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
374ff94bc40SHeiko Schocher 		return sz & mtd->writesize_mask;
375ff94bc40SHeiko Schocher 	return do_div(sz, mtd->writesize);
376ff94bc40SHeiko Schocher }
377ff94bc40SHeiko Schocher 
378dfe64e2cSSergey Lapin static inline int mtd_has_oob(const struct mtd_info *mtd)
379dfe64e2cSSergey Lapin {
380dfe64e2cSSergey Lapin 	return mtd->_read_oob && mtd->_write_oob;
381dfe64e2cSSergey Lapin }
382dfe64e2cSSergey Lapin 
383ff94bc40SHeiko Schocher static inline int mtd_type_is_nand(const struct mtd_info *mtd)
384ff94bc40SHeiko Schocher {
385ff94bc40SHeiko Schocher 	return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
386ff94bc40SHeiko Schocher }
387ff94bc40SHeiko Schocher 
388dfe64e2cSSergey Lapin static inline int mtd_can_have_bb(const struct mtd_info *mtd)
389dfe64e2cSSergey Lapin {
390dfe64e2cSSergey Lapin 	return !!mtd->_block_isbad;
391dfe64e2cSSergey Lapin }
392dfe64e2cSSergey Lapin 
393932394acSWolfgang Denk 	/* Kernel-side ioctl definitions */
394932394acSWolfgang Denk 
395ff94bc40SHeiko Schocher struct mtd_partition;
396ff94bc40SHeiko Schocher struct mtd_part_parser_data;
397932394acSWolfgang Denk 
398ff94bc40SHeiko Schocher extern int mtd_device_parse_register(struct mtd_info *mtd,
399ff94bc40SHeiko Schocher 				     const char * const *part_probe_types,
400ff94bc40SHeiko Schocher 				     struct mtd_part_parser_data *parser_data,
401ff94bc40SHeiko Schocher 				     const struct mtd_partition *defparts,
402ff94bc40SHeiko Schocher 				     int defnr_parts);
403ff94bc40SHeiko Schocher #define mtd_device_register(master, parts, nr_parts)	\
404ff94bc40SHeiko Schocher 	mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
405ff94bc40SHeiko Schocher extern int mtd_device_unregister(struct mtd_info *master);
406932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
407ff94bc40SHeiko Schocher extern int __get_mtd_device(struct mtd_info *mtd);
408ff94bc40SHeiko Schocher extern void __put_mtd_device(struct mtd_info *mtd);
409cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name);
410932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd);
411ff94bc40SHeiko Schocher 
412ff94bc40SHeiko Schocher 
413ff94bc40SHeiko Schocher #ifndef __UBOOT__
414932394acSWolfgang Denk struct mtd_notifier {
415932394acSWolfgang Denk 	void (*add)(struct mtd_info *mtd);
416932394acSWolfgang Denk 	void (*remove)(struct mtd_info *mtd);
417932394acSWolfgang Denk 	struct list_head list;
418932394acSWolfgang Denk };
419932394acSWolfgang Denk 
420ff94bc40SHeiko Schocher 
421932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new);
422932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old);
423932394acSWolfgang Denk #endif
424ff94bc40SHeiko Schocher void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
425932394acSWolfgang Denk 
426932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS
427932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr);
428932394acSWolfgang Denk #else
429932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr)
430932394acSWolfgang Denk {
431932394acSWolfgang Denk 	if (instr->callback)
432932394acSWolfgang Denk 		instr->callback(instr);
433932394acSWolfgang Denk }
434932394acSWolfgang Denk #endif
435932394acSWolfgang Denk 
436ff94bc40SHeiko Schocher #ifdef __UBOOT__
437932394acSWolfgang Denk /*
438932394acSWolfgang Denk  * Debugging macro and defines
439932394acSWolfgang Denk  */
440932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */
441932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1	(1)	/* Audible */
442932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */
443932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
444932394acSWolfgang Denk 
445932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG
446dfe64e2cSSergey Lapin #define pr_debug(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
4473167c538SScott Wood #define MTDDEBUG(n, args...)				\
448932394acSWolfgang Denk 	do {						\
449932394acSWolfgang Denk 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
450932394acSWolfgang Denk 			printk(KERN_INFO args);		\
451932394acSWolfgang Denk 	} while(0)
452932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */
453dfe64e2cSSergey Lapin #define pr_debug(args...)
454c45912d8SScott Wood #define MTDDEBUG(n, args...)				\
455c45912d8SScott Wood 	do {						\
456c45912d8SScott Wood 		if (0)					\
457c45912d8SScott Wood 			printk(KERN_INFO args);		\
458c45912d8SScott Wood 	} while(0)
459932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */
460dfe64e2cSSergey Lapin #define pr_info(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
461dfe64e2cSSergey Lapin #define pr_warn(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
462dfe64e2cSSergey Lapin #define pr_err(args...)		MTDDEBUG(MTD_DEBUG_LEVEL0, args)
463ff94bc40SHeiko Schocher #define pr_crit(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
464ff94bc40SHeiko Schocher #define pr_cont(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
465ff94bc40SHeiko Schocher #define pr_notice(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
466ff94bc40SHeiko Schocher #endif
467dfe64e2cSSergey Lapin 
468dfe64e2cSSergey Lapin static inline int mtd_is_bitflip(int err) {
469dfe64e2cSSergey Lapin 	return err == -EUCLEAN;
470dfe64e2cSSergey Lapin }
471dfe64e2cSSergey Lapin 
472dfe64e2cSSergey Lapin static inline int mtd_is_eccerr(int err) {
473dfe64e2cSSergey Lapin 	return err == -EBADMSG;
474dfe64e2cSSergey Lapin }
475dfe64e2cSSergey Lapin 
476dfe64e2cSSergey Lapin static inline int mtd_is_bitflip_or_eccerr(int err) {
477dfe64e2cSSergey Lapin 	return mtd_is_bitflip(err) || mtd_is_eccerr(err);
478dfe64e2cSSergey Lapin }
479932394acSWolfgang Denk 
480ff94bc40SHeiko Schocher #ifdef __UBOOT__
481ff94bc40SHeiko Schocher /* drivers/mtd/mtdcore.h */
482ff94bc40SHeiko Schocher int add_mtd_device(struct mtd_info *mtd);
483*ddf7bcfaSHeiko Schocher int del_mtd_device(struct mtd_info *mtd);
484ff94bc40SHeiko Schocher int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
485ff94bc40SHeiko Schocher int del_mtd_partitions(struct mtd_info *);
486ff94bc40SHeiko Schocher #endif
487932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */
488