xref: /rk3399_rockchip-uboot/include/linux/mtd/mtd.h (revision 59441ac3c135c412c679bdd1c82c8f2a9b805bbc)
1932394acSWolfgang Denk /*
2ff94bc40SHeiko Schocher  * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
3932394acSWolfgang Denk  *
478e9e71cSTom Rini  * SPDX-License-Identifier:	GPL-2.0+
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
1042580a2a7SSiva 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);
2470195a7bbSHeiko Schocher 	void (*_reboot) (struct mtd_info *mtd);
248ff94bc40SHeiko Schocher #endif
249932394acSWolfgang Denk 	/*
250dfe64e2cSSergey Lapin 	 * If the driver is something smart, like UBI, it may need to maintain
251dfe64e2cSSergey Lapin 	 * its own reference counting. The below functions are only for driver.
252932394acSWolfgang Denk 	 */
253dfe64e2cSSergey Lapin 	int (*_get_device) (struct mtd_info *mtd);
254dfe64e2cSSergey Lapin 	void (*_put_device) (struct mtd_info *mtd);
255cfa460adSWilliam Juul 
256ff94bc40SHeiko Schocher #ifndef __UBOOT__
257ff94bc40SHeiko Schocher 	/* Backing device capabilities for this device
258ff94bc40SHeiko Schocher 	 * - provides mmap capabilities
259932394acSWolfgang Denk 	 */
260ff94bc40SHeiko Schocher 	struct backing_dev_info *backing_dev_info;
261ff94bc40SHeiko Schocher 
262cfa460adSWilliam Juul 	struct notifier_block reboot_notifier;  /* default mode before reboot */
263cfa460adSWilliam Juul #endif
264cfa460adSWilliam Juul 
265cfa460adSWilliam Juul 	/* ECC status information */
266cfa460adSWilliam Juul 	struct mtd_ecc_stats ecc_stats;
267cfa460adSWilliam Juul 	/* Subpage shift (NAND) */
268cfa460adSWilliam Juul 	int subpage_sft;
269cfa460adSWilliam Juul 
270932394acSWolfgang Denk 	void *priv;
271932394acSWolfgang Denk 
272932394acSWolfgang Denk 	struct module *owner;
273ff94bc40SHeiko Schocher #ifndef __UBOOT__
274ff94bc40SHeiko Schocher 	struct device dev;
275d8587993SThomas Chou #else
276d8587993SThomas Chou 	struct udevice *dev;
277ff94bc40SHeiko Schocher #endif
278932394acSWolfgang Denk 	int usecount;
279932394acSWolfgang Denk };
280932394acSWolfgang Denk 
281ceee07b6SScott Wood static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
282ceee07b6SScott Wood {
283ceee07b6SScott Wood 	return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
284ceee07b6SScott Wood }
285ceee07b6SScott Wood 
286dfe64e2cSSergey Lapin int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
287ff94bc40SHeiko Schocher #ifndef __UBOOT__
288ff94bc40SHeiko Schocher int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
289ff94bc40SHeiko Schocher 	      void **virt, resource_size_t *phys);
290ff94bc40SHeiko Schocher int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
291ff94bc40SHeiko Schocher #endif
292ff94bc40SHeiko Schocher unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
293ff94bc40SHeiko Schocher 				    unsigned long offset, unsigned long flags);
294dfe64e2cSSergey Lapin int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
295dfe64e2cSSergey Lapin 	     u_char *buf);
296dfe64e2cSSergey Lapin int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
297dfe64e2cSSergey Lapin 	      const u_char *buf);
298dfe64e2cSSergey Lapin int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
299dfe64e2cSSergey Lapin 		    const u_char *buf);
300dfe64e2cSSergey Lapin 
301dfe64e2cSSergey Lapin int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
302dfe64e2cSSergey Lapin 
303dfe64e2cSSergey Lapin static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
304dfe64e2cSSergey Lapin 				struct mtd_oob_ops *ops)
305dfe64e2cSSergey Lapin {
306dfe64e2cSSergey Lapin 	ops->retlen = ops->oobretlen = 0;
307dfe64e2cSSergey Lapin 	if (!mtd->_write_oob)
308dfe64e2cSSergey Lapin 		return -EOPNOTSUPP;
309dfe64e2cSSergey Lapin 	if (!(mtd->flags & MTD_WRITEABLE))
310dfe64e2cSSergey Lapin 		return -EROFS;
311dfe64e2cSSergey Lapin 	return mtd->_write_oob(mtd, to, ops);
312dfe64e2cSSergey Lapin }
313dfe64e2cSSergey Lapin 
3144e67c571SHeiko Schocher int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
3154e67c571SHeiko Schocher 			   struct otp_info *buf);
316dfe64e2cSSergey Lapin int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
317dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
3184e67c571SHeiko Schocher int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
3194e67c571SHeiko Schocher 			   struct otp_info *buf);
320dfe64e2cSSergey Lapin int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
321dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
322dfe64e2cSSergey Lapin int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
323dfe64e2cSSergey Lapin 			    size_t *retlen, u_char *buf);
324dfe64e2cSSergey Lapin int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
325dfe64e2cSSergey Lapin 
326ff94bc40SHeiko Schocher #ifndef __UBOOT__
327dfe64e2cSSergey Lapin int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
328dfe64e2cSSergey Lapin 	       unsigned long count, loff_t to, size_t *retlen);
329dfe64e2cSSergey Lapin #endif
330dfe64e2cSSergey Lapin 
331dfe64e2cSSergey Lapin static inline void mtd_sync(struct mtd_info *mtd)
332dfe64e2cSSergey Lapin {
333dfe64e2cSSergey Lapin 	if (mtd->_sync)
334dfe64e2cSSergey Lapin 		mtd->_sync(mtd);
335dfe64e2cSSergey Lapin }
336dfe64e2cSSergey Lapin 
337dfe64e2cSSergey Lapin int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
338dfe64e2cSSergey Lapin int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
339dfe64e2cSSergey Lapin int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
34086a720aaSEzequiel Garcia int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
341dfe64e2cSSergey Lapin int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
342dfe64e2cSSergey Lapin int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
343dfe64e2cSSergey Lapin 
344ff94bc40SHeiko Schocher #ifndef __UBOOT__
345ff94bc40SHeiko Schocher static inline int mtd_suspend(struct mtd_info *mtd)
346ff94bc40SHeiko Schocher {
347ff94bc40SHeiko Schocher 	return mtd->_suspend ? mtd->_suspend(mtd) : 0;
348ff94bc40SHeiko Schocher }
349ff94bc40SHeiko Schocher 
350ff94bc40SHeiko Schocher static inline void mtd_resume(struct mtd_info *mtd)
351ff94bc40SHeiko Schocher {
352ff94bc40SHeiko Schocher 	if (mtd->_resume)
353ff94bc40SHeiko Schocher 		mtd->_resume(mtd);
354ff94bc40SHeiko Schocher }
355ff94bc40SHeiko Schocher #endif
356ff94bc40SHeiko Schocher 
3578d2effeaSStefan Roese static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
3588d2effeaSStefan Roese {
359ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
360ff94bc40SHeiko Schocher 		return sz >> mtd->erasesize_shift;
3618d2effeaSStefan Roese 	do_div(sz, mtd->erasesize);
3628d2effeaSStefan Roese 	return sz;
3638d2effeaSStefan Roese }
3648d2effeaSStefan Roese 
3658d2effeaSStefan Roese static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
3668d2effeaSStefan Roese {
367ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
368ff94bc40SHeiko Schocher 		return sz & mtd->erasesize_mask;
3698d2effeaSStefan Roese 	return do_div(sz, mtd->erasesize);
3708d2effeaSStefan Roese }
371932394acSWolfgang Denk 
372ff94bc40SHeiko Schocher static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
373ff94bc40SHeiko Schocher {
374ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
375ff94bc40SHeiko Schocher 		return sz >> mtd->writesize_shift;
376ff94bc40SHeiko Schocher 	do_div(sz, mtd->writesize);
377ff94bc40SHeiko Schocher 	return sz;
378ff94bc40SHeiko Schocher }
379ff94bc40SHeiko Schocher 
380ff94bc40SHeiko Schocher static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
381ff94bc40SHeiko Schocher {
382ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
383ff94bc40SHeiko Schocher 		return sz & mtd->writesize_mask;
384ff94bc40SHeiko Schocher 	return do_div(sz, mtd->writesize);
385ff94bc40SHeiko Schocher }
386ff94bc40SHeiko Schocher 
387dfe64e2cSSergey Lapin static inline int mtd_has_oob(const struct mtd_info *mtd)
388dfe64e2cSSergey Lapin {
389dfe64e2cSSergey Lapin 	return mtd->_read_oob && mtd->_write_oob;
390dfe64e2cSSergey Lapin }
391dfe64e2cSSergey Lapin 
392ff94bc40SHeiko Schocher static inline int mtd_type_is_nand(const struct mtd_info *mtd)
393ff94bc40SHeiko Schocher {
394ff94bc40SHeiko Schocher 	return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
395ff94bc40SHeiko Schocher }
396ff94bc40SHeiko Schocher 
397dfe64e2cSSergey Lapin static inline int mtd_can_have_bb(const struct mtd_info *mtd)
398dfe64e2cSSergey Lapin {
399dfe64e2cSSergey Lapin 	return !!mtd->_block_isbad;
400dfe64e2cSSergey Lapin }
401dfe64e2cSSergey Lapin 
402932394acSWolfgang Denk 	/* Kernel-side ioctl definitions */
403932394acSWolfgang Denk 
404ff94bc40SHeiko Schocher struct mtd_partition;
405ff94bc40SHeiko Schocher struct mtd_part_parser_data;
406932394acSWolfgang Denk 
407ff94bc40SHeiko Schocher extern int mtd_device_parse_register(struct mtd_info *mtd,
408ff94bc40SHeiko Schocher 				     const char * const *part_probe_types,
409ff94bc40SHeiko Schocher 				     struct mtd_part_parser_data *parser_data,
410ff94bc40SHeiko Schocher 				     const struct mtd_partition *defparts,
411ff94bc40SHeiko Schocher 				     int defnr_parts);
412ff94bc40SHeiko Schocher #define mtd_device_register(master, parts, nr_parts)	\
413ff94bc40SHeiko Schocher 	mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
414ff94bc40SHeiko Schocher extern int mtd_device_unregister(struct mtd_info *master);
415932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
416ff94bc40SHeiko Schocher extern int __get_mtd_device(struct mtd_info *mtd);
417ff94bc40SHeiko Schocher extern void __put_mtd_device(struct mtd_info *mtd);
418cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name);
419932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd);
420ff94bc40SHeiko Schocher 
421ff94bc40SHeiko Schocher 
422ff94bc40SHeiko Schocher #ifndef __UBOOT__
423932394acSWolfgang Denk struct mtd_notifier {
424932394acSWolfgang Denk 	void (*add)(struct mtd_info *mtd);
425932394acSWolfgang Denk 	void (*remove)(struct mtd_info *mtd);
426932394acSWolfgang Denk 	struct list_head list;
427932394acSWolfgang Denk };
428932394acSWolfgang Denk 
429ff94bc40SHeiko Schocher 
430932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new);
431932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old);
432932394acSWolfgang Denk #endif
433ff94bc40SHeiko Schocher void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
434932394acSWolfgang Denk 
435932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS
436932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr);
437932394acSWolfgang Denk #else
438932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr)
439932394acSWolfgang Denk {
440932394acSWolfgang Denk 	if (instr->callback)
441932394acSWolfgang Denk 		instr->callback(instr);
442932394acSWolfgang Denk }
443932394acSWolfgang Denk #endif
444932394acSWolfgang Denk 
445ff94bc40SHeiko Schocher #ifdef __UBOOT__
446932394acSWolfgang Denk /*
447932394acSWolfgang Denk  * Debugging macro and defines
448932394acSWolfgang Denk  */
449932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */
450932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1	(1)	/* Audible */
451932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */
452932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
453932394acSWolfgang Denk 
454932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG
455dfe64e2cSSergey Lapin #define pr_debug(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
4563167c538SScott Wood #define MTDDEBUG(n, args...)				\
457932394acSWolfgang Denk 	do {						\
458932394acSWolfgang Denk 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
459932394acSWolfgang Denk 			printk(KERN_INFO args);		\
460932394acSWolfgang Denk 	} while(0)
461932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */
462dfe64e2cSSergey Lapin #define pr_debug(args...)
463c45912d8SScott Wood #define MTDDEBUG(n, args...)				\
464c45912d8SScott Wood 	do {						\
465c45912d8SScott Wood 		if (0)					\
466c45912d8SScott Wood 			printk(KERN_INFO args);		\
467c45912d8SScott Wood 	} while(0)
468932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */
469dfe64e2cSSergey Lapin #define pr_info(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
470dfe64e2cSSergey Lapin #define pr_warn(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
471dfe64e2cSSergey Lapin #define pr_err(args...)		MTDDEBUG(MTD_DEBUG_LEVEL0, args)
472ff94bc40SHeiko Schocher #define pr_crit(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
473ff94bc40SHeiko Schocher #define pr_cont(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
474ff94bc40SHeiko Schocher #define pr_notice(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
475ff94bc40SHeiko Schocher #endif
476dfe64e2cSSergey Lapin 
477dfe64e2cSSergey Lapin static inline int mtd_is_bitflip(int err) {
478dfe64e2cSSergey Lapin 	return err == -EUCLEAN;
479dfe64e2cSSergey Lapin }
480dfe64e2cSSergey Lapin 
481dfe64e2cSSergey Lapin static inline int mtd_is_eccerr(int err) {
482dfe64e2cSSergey Lapin 	return err == -EBADMSG;
483dfe64e2cSSergey Lapin }
484dfe64e2cSSergey Lapin 
485dfe64e2cSSergey Lapin static inline int mtd_is_bitflip_or_eccerr(int err) {
486dfe64e2cSSergey Lapin 	return mtd_is_bitflip(err) || mtd_is_eccerr(err);
487dfe64e2cSSergey Lapin }
488932394acSWolfgang Denk 
4890195a7bbSHeiko Schocher unsigned mtd_mmap_capabilities(struct mtd_info *mtd);
4900195a7bbSHeiko Schocher 
491ff94bc40SHeiko Schocher #ifdef __UBOOT__
492ff94bc40SHeiko Schocher /* drivers/mtd/mtdcore.h */
493ff94bc40SHeiko Schocher int add_mtd_device(struct mtd_info *mtd);
494ddf7bcfaSHeiko Schocher int del_mtd_device(struct mtd_info *mtd);
495ff94bc40SHeiko Schocher int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
496ff94bc40SHeiko Schocher int del_mtd_partitions(struct mtd_info *);
49709c32807SHeiko Schocher 
49809c32807SHeiko Schocher int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
499f18d1116SMasahiro Yamada 		loff_t *maxsize, int devtype, uint64_t chipsize);
50009c32807SHeiko Schocher int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
501f18d1116SMasahiro Yamada 		     loff_t *size, loff_t *maxsize, int devtype,
502f18d1116SMasahiro Yamada 		     uint64_t chipsize);
503*59441ac3SSteve Rae 
504*59441ac3SSteve Rae /* drivers/mtd/mtdcore.c */
505*59441ac3SSteve Rae void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
506*59441ac3SSteve Rae 			  const uint64_t length, uint64_t *len_incl_bad,
507*59441ac3SSteve Rae 			  int *truncated);
508ff94bc40SHeiko Schocher #endif
509932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */
510