1 
2 /* Overhauled routines for dealing with different mmap regions of flash */
3 /* $Id: map.h,v 1.29 2002/10/21 13:20:52 jocke Exp $ */
4 
5 #ifndef __LINUX_MTD_MAP_H__
6 #define __LINUX_MTD_MAP_H__
7 
8 #include <linux/config.h>
9 #include <linux/types.h>
10 #include <linux/mtd/mtd.h>
11 #include <linux/slab.h>
12 
13 /* The map stuff is very simple. You fill in your struct map_info with
14    a handful of routines for accessing the device, making sure they handle
15    paging etc. correctly if your device needs it. Then you pass it off
16    to a chip driver which deals with a mapped device - generally either
17    do_cfi_probe() or do_ram_probe(), either of which will return a
18    struct mtd_info if they liked what they saw. At which point, you
19    fill in the mtd->module with your own module address, and register
20    it.
21 
22    The mtd->priv field will point to the struct map_info, and any further
23    private data required by the chip driver is linked from the
24    mtd->priv->fldrv_priv field. This allows the map driver to get at
25    the destructor function map->fldrv_destroy() when it's tired
26    of living.
27 */
28 
29 struct map_info {
30 	char *name;
31 	unsigned long size;
32 	int buswidth; /* in octets */
33 	__u8 (*read8)(struct map_info *, unsigned long);
34 	__u16 (*read16)(struct map_info *, unsigned long);
35 	__u32 (*read32)(struct map_info *, unsigned long);
36 	__u64 (*read64)(struct map_info *, unsigned long);
37 	/* If it returned a 'long' I'd call it readl.
38 	 * It doesn't.
39 	 * I won't.
40 	 * dwmw2 */
41 
42 	void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
43 	void (*write8)(struct map_info *, __u8, unsigned long);
44 	void (*write16)(struct map_info *, __u16, unsigned long);
45 	void (*write32)(struct map_info *, __u32, unsigned long);
46 	void (*write64)(struct map_info *, __u64, unsigned long);
47 	void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
48 
49 	u_char * (*point) (struct map_info *, loff_t, size_t);
50 	void (*unpoint) (struct map_info *, u_char *, loff_t, size_t);
51 
52 	void (*set_vpp)(struct map_info *, int);
53 	/* We put these two here rather than a single void *map_priv,
54 	   because we want mappers to be able to have quickly-accessible
55 	   cache for the 'currently-mapped page' without the _extra_
56 	   redirection that would be necessary. If you need more than
57 	   two longs, turn the second into a pointer. dwmw2 */
58 	unsigned long map_priv_1;
59 	unsigned long map_priv_2;
60 	void *fldrv_priv;
61 	struct mtd_chip_driver *fldrv;
62 };
63 
64 
65 struct mtd_chip_driver {
66 	struct mtd_info *(*probe)(struct map_info *map);
67 	void (*destroy)(struct mtd_info *);
68 	struct module *module;
69 	char *name;
70 	struct list_head list;
71 };
72 
73 void register_mtd_chip_driver(struct mtd_chip_driver *);
74 void unregister_mtd_chip_driver(struct mtd_chip_driver *);
75 
76 struct mtd_info *do_map_probe(const char *name, struct map_info *map);
77 
78 
79 /*
80  * Destroy an MTD device which was created for a map device.
81  * Make sure the MTD device is already unregistered before calling this
82  */
map_destroy(struct mtd_info * mtd)83 static inline void map_destroy(struct mtd_info *mtd)
84 {
85 	struct map_info *map = mtd->priv;
86 
87 	if (map->fldrv->destroy)
88 		map->fldrv->destroy(mtd);
89 #ifdef CONFIG_MODULES
90 	if (map->fldrv->module)
91 		__MOD_DEC_USE_COUNT(map->fldrv->module);
92 #endif
93 	kfree(mtd);
94 }
95 
96 #define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
97 #define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
98 
99 #endif /* __LINUX_MTD_MAP_H__ */
100