xref: /rk3399_rockchip-uboot/include/linux/mtd/mtd.h (revision c44c4cceac9c673b4b47ba94a6a0fe20051aa3e8)
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>
231221ce45SMasahiro Yamada #include <linux/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
106*c44c4cceSBoris Brezillon /**
107*c44c4cceSBoris Brezillon  * struct mtd_oob_region - oob region definition
108*c44c4cceSBoris Brezillon  * @offset: region offset
109*c44c4cceSBoris Brezillon  * @length: region length
110*c44c4cceSBoris Brezillon  *
111*c44c4cceSBoris Brezillon  * This structure describes a region of the OOB area, and is used
112*c44c4cceSBoris Brezillon  * to retrieve ECC or free bytes sections.
113*c44c4cceSBoris Brezillon  * Each section is defined by an offset within the OOB area and a
114*c44c4cceSBoris Brezillon  * length.
115*c44c4cceSBoris Brezillon  */
116*c44c4cceSBoris Brezillon struct mtd_oob_region {
117*c44c4cceSBoris Brezillon 	u32 offset;
118*c44c4cceSBoris Brezillon 	u32 length;
119*c44c4cceSBoris Brezillon };
120*c44c4cceSBoris Brezillon 
121*c44c4cceSBoris Brezillon /*
122*c44c4cceSBoris Brezillon  * struct mtd_ooblayout_ops - NAND OOB layout operations
123*c44c4cceSBoris Brezillon  * @ecc: function returning an ECC region in the OOB area.
124*c44c4cceSBoris Brezillon  *	 Should return -ERANGE if %section exceeds the total number of
125*c44c4cceSBoris Brezillon  *	 ECC sections.
126*c44c4cceSBoris Brezillon  * @free: function returning a free region in the OOB area.
127*c44c4cceSBoris Brezillon  *	  Should return -ERANGE if %section exceeds the total number of
128*c44c4cceSBoris Brezillon  *	  free sections.
129*c44c4cceSBoris Brezillon  */
130*c44c4cceSBoris Brezillon struct mtd_ooblayout_ops {
131*c44c4cceSBoris Brezillon 	int (*ecc)(struct mtd_info *mtd, int section,
132*c44c4cceSBoris Brezillon 		   struct mtd_oob_region *oobecc);
133*c44c4cceSBoris Brezillon 	int (*free)(struct mtd_info *mtd, int section,
134*c44c4cceSBoris Brezillon 		    struct mtd_oob_region *oobfree);
135*c44c4cceSBoris Brezillon };
13668ec9c85SPrabhakar Kushwaha 
13768ec9c85SPrabhakar Kushwaha /*
138ff94bc40SHeiko Schocher  * Internal ECC layout control structure. For historical reasons, there is a
139ff94bc40SHeiko Schocher  * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
140ff94bc40SHeiko Schocher  * for export to user-space via the ECCGETLAYOUT ioctl.
141ff94bc40SHeiko Schocher  * nand_ecclayout should be expandable in the future simply by the above macros.
14268ec9c85SPrabhakar Kushwaha  */
14368ec9c85SPrabhakar Kushwaha struct nand_ecclayout {
144ff94bc40SHeiko Schocher 	__u32 eccbytes;
145ff94bc40SHeiko Schocher 	__u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
146ff94bc40SHeiko Schocher 	__u32 oobavail;
14768ec9c85SPrabhakar Kushwaha 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
14868ec9c85SPrabhakar Kushwaha };
14968ec9c85SPrabhakar Kushwaha 
150ff94bc40SHeiko Schocher struct module;	/* only needed for owner field in mtd_info */
151ff94bc40SHeiko Schocher 
152932394acSWolfgang Denk struct mtd_info {
153932394acSWolfgang Denk 	u_char type;
154ff94bc40SHeiko Schocher 	uint32_t flags;
155ff94bc40SHeiko Schocher 	uint64_t size;	 // Total size of the MTD
156932394acSWolfgang Denk 
157fa82f871SAlbert ARIBAUD 	/* "Major" erase size for the device. Naïve users may take this
158932394acSWolfgang Denk 	 * to be the only erase size available, or may use the more detailed
159932394acSWolfgang Denk 	 * information below if they desire
160932394acSWolfgang Denk 	 */
161ff94bc40SHeiko Schocher 	uint32_t erasesize;
162cfa460adSWilliam Juul 	/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
163cfa460adSWilliam Juul 	 * though individual bits can be cleared), in case of NAND flash it is
164cfa460adSWilliam Juul 	 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
165cfa460adSWilliam Juul 	 * it is of ECC block size, etc. It is illegal to have writesize = 0.
166cfa460adSWilliam Juul 	 * Any driver registering a struct mtd_info must ensure a writesize of
167cfa460adSWilliam Juul 	 * 1 or larger.
168cfa460adSWilliam Juul 	 */
169ff94bc40SHeiko Schocher 	uint32_t writesize;
170932394acSWolfgang Denk 
171ff94bc40SHeiko Schocher 	/*
172ff94bc40SHeiko Schocher 	 * Size of the write buffer used by the MTD. MTD devices having a write
173ff94bc40SHeiko Schocher 	 * buffer can write multiple writesize chunks at a time. E.g. while
174ff94bc40SHeiko Schocher 	 * writing 4 * writesize bytes to a device with 2 * writesize bytes
175ff94bc40SHeiko Schocher 	 * buffer the MTD driver can (but doesn't have to) do 2 writesize
176ff94bc40SHeiko Schocher 	 * operations, but not 4. Currently, all NANDs have writebufsize
177ff94bc40SHeiko Schocher 	 * equivalent to writesize (NAND page size). Some NOR flashes do have
178ff94bc40SHeiko Schocher 	 * writebufsize greater than writesize.
179ff94bc40SHeiko Schocher 	 */
180ff94bc40SHeiko Schocher 	uint32_t writebufsize;
181ff94bc40SHeiko Schocher 
182ff94bc40SHeiko Schocher 	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)
183ff94bc40SHeiko Schocher 	uint32_t oobavail;  // Available OOB bytes per block
184ff94bc40SHeiko Schocher 
185ff94bc40SHeiko Schocher 	/*
186ff94bc40SHeiko Schocher 	 * If erasesize is a power of 2 then the shift is stored in
187ff94bc40SHeiko Schocher 	 * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
188ff94bc40SHeiko Schocher 	 */
189ff94bc40SHeiko Schocher 	unsigned int erasesize_shift;
190ff94bc40SHeiko Schocher 	unsigned int writesize_shift;
191ff94bc40SHeiko Schocher 	/* Masks based on erasesize_shift and writesize_shift */
192ff94bc40SHeiko Schocher 	unsigned int erasesize_mask;
193ff94bc40SHeiko Schocher 	unsigned int writesize_mask;
194932394acSWolfgang Denk 
195dfe64e2cSSergey Lapin 	/*
196dfe64e2cSSergey Lapin 	 * read ops return -EUCLEAN if max number of bitflips corrected on any
197dfe64e2cSSergey Lapin 	 * one region comprising an ecc step equals or exceeds this value.
198dfe64e2cSSergey Lapin 	 * Settable by driver, else defaults to ecc_strength.  User can override
199dfe64e2cSSergey Lapin 	 * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed;
200dfe64e2cSSergey Lapin 	 * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
201dfe64e2cSSergey Lapin 	 */
202dfe64e2cSSergey Lapin 	unsigned int bitflip_threshold;
203dfe64e2cSSergey Lapin 
204ff94bc40SHeiko Schocher 	// Kernel-only stuff starts here.
205ff94bc40SHeiko Schocher #ifndef __UBOOT__
206c45912d8SScott Wood 	const char *name;
207ff94bc40SHeiko Schocher #else
208ff94bc40SHeiko Schocher 	char *name;
209ff94bc40SHeiko Schocher #endif
210932394acSWolfgang Denk 	int index;
211932394acSWolfgang Denk 
212*c44c4cceSBoris Brezillon 	/* OOB layout description */
213*c44c4cceSBoris Brezillon 	const struct mtd_ooblayout_ops *ooblayout;
214*c44c4cceSBoris Brezillon 
215dfe64e2cSSergey Lapin 	/* ECC layout structure pointer - read only! */
216cfa460adSWilliam Juul 	struct nand_ecclayout *ecclayout;
217932394acSWolfgang Denk 
218ff94bc40SHeiko Schocher 	/* the ecc step size. */
219ff94bc40SHeiko Schocher 	unsigned int ecc_step_size;
220ff94bc40SHeiko Schocher 
221dfe64e2cSSergey Lapin 	/* max number of correctible bit errors per ecc step */
222dfe64e2cSSergey Lapin 	unsigned int ecc_strength;
223dfe64e2cSSergey Lapin 
224932394acSWolfgang Denk 	/* Data for variable erase regions. If numeraseregions is zero,
225932394acSWolfgang Denk 	 * it means that the whole device has erasesize as given above.
226932394acSWolfgang Denk 	 */
227932394acSWolfgang Denk 	int numeraseregions;
228932394acSWolfgang Denk 	struct mtd_erase_region_info *eraseregions;
229932394acSWolfgang Denk 
230c45912d8SScott Wood 	/*
231dfe64e2cSSergey Lapin 	 * Do not call via these pointers, use corresponding mtd_*()
232dfe64e2cSSergey Lapin 	 * wrappers instead.
233c45912d8SScott Wood 	 */
234dfe64e2cSSergey Lapin 	int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
235ff94bc40SHeiko Schocher #ifndef __UBOOT__
236dfe64e2cSSergey Lapin 	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
237ff94bc40SHeiko Schocher 		       size_t *retlen, void **virt, resource_size_t *phys);
238ff94bc40SHeiko Schocher 	int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
239ff94bc40SHeiko Schocher #endif
240ff94bc40SHeiko Schocher 	unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
241ff94bc40SHeiko Schocher 					     unsigned long len,
242ff94bc40SHeiko Schocher 					     unsigned long offset,
243ff94bc40SHeiko Schocher 					     unsigned long flags);
244dfe64e2cSSergey Lapin 	int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
245dfe64e2cSSergey Lapin 		      size_t *retlen, u_char *buf);
246dfe64e2cSSergey Lapin 	int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
247dfe64e2cSSergey Lapin 		       size_t *retlen, const u_char *buf);
248ff94bc40SHeiko Schocher 	int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
249ff94bc40SHeiko Schocher 			     size_t *retlen, const u_char *buf);
250dfe64e2cSSergey Lapin 	int (*_read_oob) (struct mtd_info *mtd, loff_t from,
251cfa460adSWilliam Juul 			  struct mtd_oob_ops *ops);
252dfe64e2cSSergey Lapin 	int (*_write_oob) (struct mtd_info *mtd, loff_t to,
253cfa460adSWilliam Juul 			   struct mtd_oob_ops *ops);
2544e67c571SHeiko Schocher 	int (*_get_fact_prot_info) (struct mtd_info *mtd, size_t len,
2554e67c571SHeiko Schocher 				    size_t *retlen, struct otp_info *buf);
256dfe64e2cSSergey Lapin 	int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
257dfe64e2cSSergey Lapin 				    size_t len, size_t *retlen, u_char *buf);
2584e67c571SHeiko Schocher 	int (*_get_user_prot_info) (struct mtd_info *mtd, size_t len,
2594e67c571SHeiko Schocher 				    size_t *retlen, struct otp_info *buf);
260dfe64e2cSSergey Lapin 	int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
261dfe64e2cSSergey Lapin 				    size_t len, size_t *retlen, u_char *buf);
262ff94bc40SHeiko Schocher 	int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
263ff94bc40SHeiko Schocher 				     size_t len, size_t *retlen, u_char *buf);
264dfe64e2cSSergey Lapin 	int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
265dfe64e2cSSergey Lapin 				    size_t len);
266ff94bc40SHeiko Schocher #ifndef __UBOOT__
267ff94bc40SHeiko Schocher 	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
268ff94bc40SHeiko Schocher 			unsigned long count, loff_t to, size_t *retlen);
269ff94bc40SHeiko Schocher #endif
270dfe64e2cSSergey Lapin 	void (*_sync) (struct mtd_info *mtd);
271dfe64e2cSSergey Lapin 	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
272dfe64e2cSSergey Lapin 	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
273ff94bc40SHeiko Schocher 	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
27486a720aaSEzequiel Garcia 	int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
275dfe64e2cSSergey Lapin 	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
276dfe64e2cSSergey Lapin 	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
277ff94bc40SHeiko Schocher #ifndef __UBOOT__
278ff94bc40SHeiko Schocher 	int (*_suspend) (struct mtd_info *mtd);
279ff94bc40SHeiko Schocher 	void (*_resume) (struct mtd_info *mtd);
2800195a7bbSHeiko Schocher 	void (*_reboot) (struct mtd_info *mtd);
281ff94bc40SHeiko Schocher #endif
282932394acSWolfgang Denk 	/*
283dfe64e2cSSergey Lapin 	 * If the driver is something smart, like UBI, it may need to maintain
284dfe64e2cSSergey Lapin 	 * its own reference counting. The below functions are only for driver.
285932394acSWolfgang Denk 	 */
286dfe64e2cSSergey Lapin 	int (*_get_device) (struct mtd_info *mtd);
287dfe64e2cSSergey Lapin 	void (*_put_device) (struct mtd_info *mtd);
288cfa460adSWilliam Juul 
289ff94bc40SHeiko Schocher #ifndef __UBOOT__
290ff94bc40SHeiko Schocher 	/* Backing device capabilities for this device
291ff94bc40SHeiko Schocher 	 * - provides mmap capabilities
292932394acSWolfgang Denk 	 */
293ff94bc40SHeiko Schocher 	struct backing_dev_info *backing_dev_info;
294ff94bc40SHeiko Schocher 
295cfa460adSWilliam Juul 	struct notifier_block reboot_notifier;  /* default mode before reboot */
296cfa460adSWilliam Juul #endif
297cfa460adSWilliam Juul 
298cfa460adSWilliam Juul 	/* ECC status information */
299cfa460adSWilliam Juul 	struct mtd_ecc_stats ecc_stats;
300cfa460adSWilliam Juul 	/* Subpage shift (NAND) */
301cfa460adSWilliam Juul 	int subpage_sft;
302cfa460adSWilliam Juul 
303932394acSWolfgang Denk 	void *priv;
304932394acSWolfgang Denk 
305932394acSWolfgang Denk 	struct module *owner;
306ff94bc40SHeiko Schocher #ifndef __UBOOT__
307ff94bc40SHeiko Schocher 	struct device dev;
308d8587993SThomas Chou #else
309d8587993SThomas Chou 	struct udevice *dev;
310ff94bc40SHeiko Schocher #endif
311932394acSWolfgang Denk 	int usecount;
312932394acSWolfgang Denk };
313932394acSWolfgang Denk 
314*c44c4cceSBoris Brezillon int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
315*c44c4cceSBoris Brezillon 		      struct mtd_oob_region *oobecc);
316*c44c4cceSBoris Brezillon int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
317*c44c4cceSBoris Brezillon 				 int *section,
318*c44c4cceSBoris Brezillon 				 struct mtd_oob_region *oobregion);
319*c44c4cceSBoris Brezillon int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
320*c44c4cceSBoris Brezillon 			       const u8 *oobbuf, int start, int nbytes);
321*c44c4cceSBoris Brezillon int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
322*c44c4cceSBoris Brezillon 			       u8 *oobbuf, int start, int nbytes);
323*c44c4cceSBoris Brezillon int mtd_ooblayout_free(struct mtd_info *mtd, int section,
324*c44c4cceSBoris Brezillon 		       struct mtd_oob_region *oobfree);
325*c44c4cceSBoris Brezillon int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
326*c44c4cceSBoris Brezillon 				const u8 *oobbuf, int start, int nbytes);
327*c44c4cceSBoris Brezillon int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
328*c44c4cceSBoris Brezillon 				u8 *oobbuf, int start, int nbytes);
329*c44c4cceSBoris Brezillon int mtd_ooblayout_count_freebytes(struct mtd_info *mtd);
330*c44c4cceSBoris Brezillon int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd);
331*c44c4cceSBoris Brezillon 
332*c44c4cceSBoris Brezillon static inline void mtd_set_ooblayout(struct mtd_info *mtd,
333*c44c4cceSBoris Brezillon 				     const struct mtd_ooblayout_ops *ooblayout)
334*c44c4cceSBoris Brezillon {
335*c44c4cceSBoris Brezillon 	mtd->ooblayout = ooblayout;
336*c44c4cceSBoris Brezillon }
337*c44c4cceSBoris Brezillon 
338ceee07b6SScott Wood static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
339ceee07b6SScott Wood {
340ceee07b6SScott Wood 	return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
341ceee07b6SScott Wood }
342ceee07b6SScott Wood 
343dfe64e2cSSergey Lapin int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
344ff94bc40SHeiko Schocher #ifndef __UBOOT__
345ff94bc40SHeiko Schocher int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
346ff94bc40SHeiko Schocher 	      void **virt, resource_size_t *phys);
347ff94bc40SHeiko Schocher int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
348ff94bc40SHeiko Schocher #endif
349ff94bc40SHeiko Schocher unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
350ff94bc40SHeiko Schocher 				    unsigned long offset, unsigned long flags);
351dfe64e2cSSergey Lapin int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
352dfe64e2cSSergey Lapin 	     u_char *buf);
353dfe64e2cSSergey Lapin int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
354dfe64e2cSSergey Lapin 	      const u_char *buf);
355dfe64e2cSSergey Lapin int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
356dfe64e2cSSergey Lapin 		    const u_char *buf);
357dfe64e2cSSergey Lapin 
358dfe64e2cSSergey Lapin int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
359dfe64e2cSSergey Lapin 
360dfe64e2cSSergey Lapin static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
361dfe64e2cSSergey Lapin 				struct mtd_oob_ops *ops)
362dfe64e2cSSergey Lapin {
363dfe64e2cSSergey Lapin 	ops->retlen = ops->oobretlen = 0;
364dfe64e2cSSergey Lapin 	if (!mtd->_write_oob)
365dfe64e2cSSergey Lapin 		return -EOPNOTSUPP;
366dfe64e2cSSergey Lapin 	if (!(mtd->flags & MTD_WRITEABLE))
367dfe64e2cSSergey Lapin 		return -EROFS;
368dfe64e2cSSergey Lapin 	return mtd->_write_oob(mtd, to, ops);
369dfe64e2cSSergey Lapin }
370dfe64e2cSSergey Lapin 
3714e67c571SHeiko Schocher int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
3724e67c571SHeiko Schocher 			   struct otp_info *buf);
373dfe64e2cSSergey Lapin int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
374dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
3754e67c571SHeiko Schocher int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
3764e67c571SHeiko Schocher 			   struct otp_info *buf);
377dfe64e2cSSergey Lapin int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
378dfe64e2cSSergey Lapin 			   size_t *retlen, u_char *buf);
379dfe64e2cSSergey Lapin int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
380dfe64e2cSSergey Lapin 			    size_t *retlen, u_char *buf);
381dfe64e2cSSergey Lapin int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
382dfe64e2cSSergey Lapin 
383ff94bc40SHeiko Schocher #ifndef __UBOOT__
384dfe64e2cSSergey Lapin int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
385dfe64e2cSSergey Lapin 	       unsigned long count, loff_t to, size_t *retlen);
386dfe64e2cSSergey Lapin #endif
387dfe64e2cSSergey Lapin 
388dfe64e2cSSergey Lapin static inline void mtd_sync(struct mtd_info *mtd)
389dfe64e2cSSergey Lapin {
390dfe64e2cSSergey Lapin 	if (mtd->_sync)
391dfe64e2cSSergey Lapin 		mtd->_sync(mtd);
392dfe64e2cSSergey Lapin }
393dfe64e2cSSergey Lapin 
394dfe64e2cSSergey Lapin int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
395dfe64e2cSSergey Lapin int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
396dfe64e2cSSergey Lapin int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
39786a720aaSEzequiel Garcia int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
398dfe64e2cSSergey Lapin int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
399dfe64e2cSSergey Lapin int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
400dfe64e2cSSergey Lapin 
401ff94bc40SHeiko Schocher #ifndef __UBOOT__
402ff94bc40SHeiko Schocher static inline int mtd_suspend(struct mtd_info *mtd)
403ff94bc40SHeiko Schocher {
404ff94bc40SHeiko Schocher 	return mtd->_suspend ? mtd->_suspend(mtd) : 0;
405ff94bc40SHeiko Schocher }
406ff94bc40SHeiko Schocher 
407ff94bc40SHeiko Schocher static inline void mtd_resume(struct mtd_info *mtd)
408ff94bc40SHeiko Schocher {
409ff94bc40SHeiko Schocher 	if (mtd->_resume)
410ff94bc40SHeiko Schocher 		mtd->_resume(mtd);
411ff94bc40SHeiko Schocher }
412ff94bc40SHeiko Schocher #endif
413ff94bc40SHeiko Schocher 
4148d2effeaSStefan Roese static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
4158d2effeaSStefan Roese {
416ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
417ff94bc40SHeiko Schocher 		return sz >> mtd->erasesize_shift;
4188d2effeaSStefan Roese 	do_div(sz, mtd->erasesize);
4198d2effeaSStefan Roese 	return sz;
4208d2effeaSStefan Roese }
4218d2effeaSStefan Roese 
4228d2effeaSStefan Roese static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
4238d2effeaSStefan Roese {
424ff94bc40SHeiko Schocher 	if (mtd->erasesize_shift)
425ff94bc40SHeiko Schocher 		return sz & mtd->erasesize_mask;
4268d2effeaSStefan Roese 	return do_div(sz, mtd->erasesize);
4278d2effeaSStefan Roese }
428932394acSWolfgang Denk 
429ff94bc40SHeiko Schocher static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
430ff94bc40SHeiko Schocher {
431ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
432ff94bc40SHeiko Schocher 		return sz >> mtd->writesize_shift;
433ff94bc40SHeiko Schocher 	do_div(sz, mtd->writesize);
434ff94bc40SHeiko Schocher 	return sz;
435ff94bc40SHeiko Schocher }
436ff94bc40SHeiko Schocher 
437ff94bc40SHeiko Schocher static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
438ff94bc40SHeiko Schocher {
439ff94bc40SHeiko Schocher 	if (mtd->writesize_shift)
440ff94bc40SHeiko Schocher 		return sz & mtd->writesize_mask;
441ff94bc40SHeiko Schocher 	return do_div(sz, mtd->writesize);
442ff94bc40SHeiko Schocher }
443ff94bc40SHeiko Schocher 
444dfe64e2cSSergey Lapin static inline int mtd_has_oob(const struct mtd_info *mtd)
445dfe64e2cSSergey Lapin {
446dfe64e2cSSergey Lapin 	return mtd->_read_oob && mtd->_write_oob;
447dfe64e2cSSergey Lapin }
448dfe64e2cSSergey Lapin 
449ff94bc40SHeiko Schocher static inline int mtd_type_is_nand(const struct mtd_info *mtd)
450ff94bc40SHeiko Schocher {
451ff94bc40SHeiko Schocher 	return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
452ff94bc40SHeiko Schocher }
453ff94bc40SHeiko Schocher 
454dfe64e2cSSergey Lapin static inline int mtd_can_have_bb(const struct mtd_info *mtd)
455dfe64e2cSSergey Lapin {
456dfe64e2cSSergey Lapin 	return !!mtd->_block_isbad;
457dfe64e2cSSergey Lapin }
458dfe64e2cSSergey Lapin 
459932394acSWolfgang Denk 	/* Kernel-side ioctl definitions */
460932394acSWolfgang Denk 
461ff94bc40SHeiko Schocher struct mtd_partition;
462ff94bc40SHeiko Schocher struct mtd_part_parser_data;
463932394acSWolfgang Denk 
464ff94bc40SHeiko Schocher extern int mtd_device_parse_register(struct mtd_info *mtd,
465ff94bc40SHeiko Schocher 				     const char * const *part_probe_types,
466ff94bc40SHeiko Schocher 				     struct mtd_part_parser_data *parser_data,
467ff94bc40SHeiko Schocher 				     const struct mtd_partition *defparts,
468ff94bc40SHeiko Schocher 				     int defnr_parts);
469ff94bc40SHeiko Schocher #define mtd_device_register(master, parts, nr_parts)	\
470ff94bc40SHeiko Schocher 	mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
471ff94bc40SHeiko Schocher extern int mtd_device_unregister(struct mtd_info *master);
472932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
473ff94bc40SHeiko Schocher extern int __get_mtd_device(struct mtd_info *mtd);
474ff94bc40SHeiko Schocher extern void __put_mtd_device(struct mtd_info *mtd);
475cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name);
476932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd);
477ff94bc40SHeiko Schocher 
478ff94bc40SHeiko Schocher 
479ff94bc40SHeiko Schocher #ifndef __UBOOT__
480932394acSWolfgang Denk struct mtd_notifier {
481932394acSWolfgang Denk 	void (*add)(struct mtd_info *mtd);
482932394acSWolfgang Denk 	void (*remove)(struct mtd_info *mtd);
483932394acSWolfgang Denk 	struct list_head list;
484932394acSWolfgang Denk };
485932394acSWolfgang Denk 
486ff94bc40SHeiko Schocher 
487932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new);
488932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old);
489932394acSWolfgang Denk #endif
490ff94bc40SHeiko Schocher void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
491932394acSWolfgang Denk 
492932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS
493932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr);
494932394acSWolfgang Denk #else
495932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr)
496932394acSWolfgang Denk {
497932394acSWolfgang Denk 	if (instr->callback)
498932394acSWolfgang Denk 		instr->callback(instr);
499932394acSWolfgang Denk }
500932394acSWolfgang Denk #endif
501932394acSWolfgang Denk 
502ff94bc40SHeiko Schocher #ifdef __UBOOT__
503932394acSWolfgang Denk /*
504932394acSWolfgang Denk  * Debugging macro and defines
505932394acSWolfgang Denk  */
506932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0	(0)	/* Quiet   */
507932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1	(1)	/* Audible */
508932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2	(2)	/* Loud    */
509932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
510932394acSWolfgang Denk 
511932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG
5123167c538SScott Wood #define MTDDEBUG(n, args...)				\
513932394acSWolfgang Denk 	do {						\
514932394acSWolfgang Denk 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
515932394acSWolfgang Denk 			printk(KERN_INFO args);		\
516932394acSWolfgang Denk 	} while(0)
517932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */
518c45912d8SScott Wood #define MTDDEBUG(n, args...)				\
519c45912d8SScott Wood 	do {						\
520c45912d8SScott Wood 		if (0)					\
521c45912d8SScott Wood 			printk(KERN_INFO args);		\
522c45912d8SScott Wood 	} while(0)
523932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */
524ff94bc40SHeiko Schocher #endif
525dfe64e2cSSergey Lapin 
526dfe64e2cSSergey Lapin static inline int mtd_is_bitflip(int err) {
527dfe64e2cSSergey Lapin 	return err == -EUCLEAN;
528dfe64e2cSSergey Lapin }
529dfe64e2cSSergey Lapin 
530dfe64e2cSSergey Lapin static inline int mtd_is_eccerr(int err) {
531dfe64e2cSSergey Lapin 	return err == -EBADMSG;
532dfe64e2cSSergey Lapin }
533dfe64e2cSSergey Lapin 
534dfe64e2cSSergey Lapin static inline int mtd_is_bitflip_or_eccerr(int err) {
535dfe64e2cSSergey Lapin 	return mtd_is_bitflip(err) || mtd_is_eccerr(err);
536dfe64e2cSSergey Lapin }
537932394acSWolfgang Denk 
5380195a7bbSHeiko Schocher unsigned mtd_mmap_capabilities(struct mtd_info *mtd);
5390195a7bbSHeiko Schocher 
540ff94bc40SHeiko Schocher #ifdef __UBOOT__
541ff94bc40SHeiko Schocher /* drivers/mtd/mtdcore.h */
542ff94bc40SHeiko Schocher int add_mtd_device(struct mtd_info *mtd);
543ddf7bcfaSHeiko Schocher int del_mtd_device(struct mtd_info *mtd);
544ff94bc40SHeiko Schocher int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
545ff94bc40SHeiko Schocher int del_mtd_partitions(struct mtd_info *);
54609c32807SHeiko Schocher 
54709c32807SHeiko Schocher int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
548f18d1116SMasahiro Yamada 		loff_t *maxsize, int devtype, uint64_t chipsize);
54909c32807SHeiko Schocher int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
550f18d1116SMasahiro Yamada 		     loff_t *size, loff_t *maxsize, int devtype,
551f18d1116SMasahiro Yamada 		     uint64_t chipsize);
55259441ac3SSteve Rae 
55359441ac3SSteve Rae /* drivers/mtd/mtdcore.c */
55459441ac3SSteve Rae void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
55559441ac3SSteve Rae 			  const uint64_t length, uint64_t *len_incl_bad,
55659441ac3SSteve Rae 			  int *truncated);
557ff94bc40SHeiko Schocher #endif
558932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */
559