source: svn/trunk/newcon3bcm2_21bu/toolchain/mipsel-linux-uclibc/include/linux/mtd/map.h

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 7.2 KB
Line 
1
2/* Overhauled routines for dealing with different mmap regions of flash */
3
4#ifndef __LINUX_MTD_MAP_H__
5#define __LINUX_MTD_MAP_H__
6
7#include <linux/types.h>
8#include <asm/system.h>
9#include <asm/io.h>
10
11/* The map stuff is very simple. You fill in your struct map_info with
12   a handful of routines for accessing the device, making sure they handle
13   paging etc. correctly if your device needs it. Then you pass it off
14   to a chip driver which deals with a mapped device - generally either
15   do_cfi_probe() or do_ram_probe(), either of which will return a
16   struct mtd_info if they liked what they saw. At which point, you
17   fill in the mtd->module with your own module address, and register
18   it.
19   
20   The mtd->priv field will point to the struct map_info, and any further
21   private data required by the chip driver is linked from the
22   mtd->priv->fldrv_priv field. This allows the map driver to get at
23   the destructor function map->fldrv_destroy() when it's tired
24   of living.
25*/
26
27struct map_info {
28        char *name;
29        unsigned long size;
30        unsigned long phys;
31#define NO_XIP (-1UL)
32
33        void *virt;
34        void *cached;
35
36        int buswidth; /* in octets */
37
38#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
39        __u8 (*read8)(struct map_info *, unsigned long);
40        __u16 (*read16)(struct map_info *, unsigned long);
41        __u32 (*read32)(struct map_info *, unsigned long); 
42        __u64 (*read64)(struct map_info *, unsigned long); 
43        /* If it returned a 'long' I'd call it readl.
44         * It doesn't.
45         * I won't.
46         * dwmw2 */
47       
48        void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
49        void (*write8)(struct map_info *, __u8, unsigned long);
50        void (*write16)(struct map_info *, __u16, unsigned long);
51        void (*write32)(struct map_info *, __u32, unsigned long);
52        void (*write64)(struct map_info *, __u64, unsigned long);
53        void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
54
55        /* We can perhaps put in 'point' and 'unpoint' methods, if we really
56           want to enable XIP for non-linear mappings. Not yet though. */
57#endif
58        /* set_vpp() must handle being reentered -- enable, enable, disable
59           must leave it enabled. */
60        void (*set_vpp)(struct map_info *, int);
61
62        unsigned long map_priv_1;
63        unsigned long map_priv_2;
64        void *fldrv_priv;
65        struct mtd_chip_driver *fldrv;
66};
67
68struct mtd_chip_driver {
69        struct mtd_info *(*probe)(struct map_info *map);
70        void (*destroy)(struct mtd_info *);
71        struct module *module;
72        char *name;
73        struct list_head list;
74};
75
76void register_mtd_chip_driver(struct mtd_chip_driver *);
77void unregister_mtd_chip_driver(struct mtd_chip_driver *);
78
79struct mtd_info *do_map_probe(const char *name, struct map_info *map);
80void map_destroy(struct mtd_info *mtd);
81
82#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
83#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
84
85#define INVALIDATE_CACHED_RANGE(map, from, size) \
86        do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
87
88
89static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
90{
91        int i;
92        for (i=0; i<map_words(map); i++) {
93                if (val1.x[i] != val2.x[i])
94                        return 0;
95        }
96        return 1;
97}
98
99static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
100{
101        map_word r;
102        int i;
103
104        for (i=0; i<map_words(map); i++) {
105                r.x[i] = val1.x[i] & val2.x[i];
106        }
107        return r;
108}
109
110static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
111{
112        map_word r;
113        int i;
114
115        for (i=0; i<map_words(map); i++) {
116                r.x[i] = val1.x[i] | val2.x[i];
117        }
118        return r;
119}
120#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
121
122static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
123{
124        int i;
125
126        for (i=0; i<map_words(map); i++) {
127                if (val1.x[i] & val2.x[i])
128                        return 1;
129        }
130        return 0;
131}
132
133static inline map_word map_word_load(struct map_info *map, const void *ptr)
134{
135        map_word r;
136
137        if (map_bankwidth_is_1(map))
138                r.x[0] = *(unsigned char *)ptr;
139        else if (map_bankwidth_is_2(map))
140                r.x[0] = get_unaligned((uint16_t *)ptr);
141        else if (map_bankwidth_is_4(map))
142                r.x[0] = get_unaligned((uint32_t *)ptr);
143#if BITS_PER_LONG >= 64
144        else if (map_bankwidth_is_8(map))
145                r.x[0] = get_unaligned((uint64_t *)ptr);
146#endif
147        else if (map_bankwidth_is_large(map))
148                memcpy(r.x, ptr, map->bankwidth);
149
150        return r;
151}
152
153static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
154{
155        int i;
156
157        if (map_bankwidth_is_large(map)) {
158                char *dest = (char *)&orig;
159                memcpy(dest+start, buf, len);
160        } else {
161                for (i=start; i < start+len; i++) {
162                        int bitpos;
163#ifdef __LITTLE_ENDIAN
164                        bitpos = i*8;
165#else /* __BIG_ENDIAN */
166                        bitpos = (map_bankwidth(map)-1-i)*8;
167#endif
168                        orig.x[0] &= ~(0xff << bitpos);
169                        orig.x[0] |= buf[i-start] << bitpos;
170                }
171        }
172        return orig;
173}
174
175static inline map_word map_word_ff(struct map_info *map)
176{
177        map_word r;
178        int i;
179
180        for (i=0; i<map_words(map); i++) {
181                r.x[i] = ~0UL;
182        }
183        return r;
184}
185static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
186{
187        map_word r;
188
189        if (map_bankwidth_is_1(map))
190                r.x[0] = __raw_readb(map->virt + ofs);
191        else if (map_bankwidth_is_2(map))
192                r.x[0] = __raw_readw(map->virt + ofs);
193        else if (map_bankwidth_is_4(map))
194                r.x[0] = __raw_readl(map->virt + ofs);
195#if BITS_PER_LONG >= 64
196        else if (map_bankwidth_is_8(map))
197                r.x[0] = __raw_readq(map->virt + ofs);
198#endif
199        else if (map_bankwidth_is_large(map))
200                memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
201
202        return r;
203}
204
205static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
206{
207        if (map_bankwidth_is_1(map))
208                __raw_writeb(datum.x[0], map->virt + ofs);
209        else if (map_bankwidth_is_2(map))
210                __raw_writew(datum.x[0], map->virt + ofs);
211        else if (map_bankwidth_is_4(map))
212                __raw_writel(datum.x[0], map->virt + ofs);
213#if BITS_PER_LONG >= 64
214        else if (map_bankwidth_is_8(map))
215                __raw_writeq(datum.x[0], map->virt + ofs);
216#endif
217        else if (map_bankwidth_is_large(map))
218                memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
219        mb();
220}
221
222static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
223{
224        if (map->cached)
225                memcpy(to, (char *)map->cached + from, len);
226        else
227                memcpy_fromio(to, map->virt + from, len);
228}
229
230static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
231{
232        memcpy_toio(map->virt + to, from, len);
233}
234
235#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
236#define map_read(map, ofs) (map)->read(map, ofs)
237#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
238#define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
239#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
240
241extern void simple_map_init(struct map_info *);
242#define map_is_linear(map) (map->phys != NO_XIP)
243
244#else
245#define map_read(map, ofs) inline_map_read(map, ofs)
246#define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
247#define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
248#define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
249
250
251#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
252#define map_is_linear(map) (1)
253
254#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
255
256#endif /* __LINUX_MTD_MAP_H__ */
Note: See TracBrowser for help on using the repository browser.