1
2/* Overhauled routines for dealing with different mmap regions of flash */
3/* $Id: map.h,v 1.1.1.1 2008/10/15 03:29:28 james26_jang 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
29struct 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	/* If it returned a 'long' I'd call it readl.
37	 * It doesn't.
38	 * I won't.
39	 * dwmw2 */
40
41	void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
42	void (*write8)(struct map_info *, __u8, unsigned long);
43	void (*write16)(struct map_info *, __u16, unsigned long);
44	void (*write32)(struct map_info *, __u32, unsigned long);
45	void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
46
47	void (*set_vpp)(struct map_info *, int);
48	/* We put these two here rather than a single void *map_priv,
49	   because we want mappers to be able to have quickly-accessible
50	   cache for the 'currently-mapped page' without the _extra_
51	   redirection that would be necessary. If you need more than
52	   two longs, turn the second into a pointer. dwmw2 */
53	unsigned long map_priv_1;
54	unsigned long map_priv_2;
55	void *fldrv_priv;
56	struct mtd_chip_driver *fldrv;
57};
58
59
60struct mtd_chip_driver {
61	struct mtd_info *(*probe)(struct map_info *map);
62	void (*destroy)(struct mtd_info *);
63	struct module *module;
64	char *name;
65	struct list_head list;
66};
67
68void register_mtd_chip_driver(struct mtd_chip_driver *);
69void unregister_mtd_chip_driver(struct mtd_chip_driver *);
70
71struct mtd_info *do_map_probe(char *name, struct map_info *map);
72
73
74/*
75 * Destroy an MTD device which was created for a map device.
76 * Make sure the MTD device is already unregistered before calling this
77 */
78static inline void map_destroy(struct mtd_info *mtd)
79{
80	struct map_info *map = mtd->priv;
81
82	if (map->fldrv->destroy)
83		map->fldrv->destroy(mtd);
84#ifdef CONFIG_MODULES
85	if (map->fldrv->module)
86		__MOD_DEC_USE_COUNT(map->fldrv->module);
87#endif
88	kfree(mtd);
89}
90
91#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
92#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
93
94#endif /* __LINUX_MTD_MAP_H__ */
95