0001
0002
0003
0004
0005
0006
0007
0008 #ifndef __LINUX_MTD_MAP_H__
0009 #define __LINUX_MTD_MAP_H__
0010
0011 #include <linux/types.h>
0012 #include <linux/list.h>
0013 #include <linux/string.h>
0014 #include <linux/bug.h>
0015 #include <linux/kernel.h>
0016 #include <linux/io.h>
0017
0018 #include <asm/unaligned.h>
0019 #include <asm/barrier.h>
0020
0021 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
0022 #define map_bankwidth(map) 1
0023 #define map_bankwidth_is_1(map) (map_bankwidth(map) == 1)
0024 #define map_bankwidth_is_large(map) (0)
0025 #define map_words(map) (1)
0026 #define MAX_MAP_BANKWIDTH 1
0027 #else
0028 #define map_bankwidth_is_1(map) (0)
0029 #endif
0030
0031 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
0032 # ifdef map_bankwidth
0033 # undef map_bankwidth
0034 # define map_bankwidth(map) ((map)->bankwidth)
0035 # else
0036 # define map_bankwidth(map) 2
0037 # define map_bankwidth_is_large(map) (0)
0038 # define map_words(map) (1)
0039 # endif
0040 #define map_bankwidth_is_2(map) (map_bankwidth(map) == 2)
0041 #undef MAX_MAP_BANKWIDTH
0042 #define MAX_MAP_BANKWIDTH 2
0043 #else
0044 #define map_bankwidth_is_2(map) (0)
0045 #endif
0046
0047 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
0048 # ifdef map_bankwidth
0049 # undef map_bankwidth
0050 # define map_bankwidth(map) ((map)->bankwidth)
0051 # else
0052 # define map_bankwidth(map) 4
0053 # define map_bankwidth_is_large(map) (0)
0054 # define map_words(map) (1)
0055 # endif
0056 #define map_bankwidth_is_4(map) (map_bankwidth(map) == 4)
0057 #undef MAX_MAP_BANKWIDTH
0058 #define MAX_MAP_BANKWIDTH 4
0059 #else
0060 #define map_bankwidth_is_4(map) (0)
0061 #endif
0062
0063
0064
0065
0066 #define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1)) / sizeof(unsigned long))
0067
0068 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
0069 # ifdef map_bankwidth
0070 # undef map_bankwidth
0071 # define map_bankwidth(map) ((map)->bankwidth)
0072 # if BITS_PER_LONG < 64
0073 # undef map_bankwidth_is_large
0074 # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
0075 # undef map_words
0076 # define map_words(map) map_calc_words(map)
0077 # endif
0078 # else
0079 # define map_bankwidth(map) 8
0080 # define map_bankwidth_is_large(map) (BITS_PER_LONG < 64)
0081 # define map_words(map) map_calc_words(map)
0082 # endif
0083 #define map_bankwidth_is_8(map) (map_bankwidth(map) == 8)
0084 #undef MAX_MAP_BANKWIDTH
0085 #define MAX_MAP_BANKWIDTH 8
0086 #else
0087 #define map_bankwidth_is_8(map) (0)
0088 #endif
0089
0090 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
0091 # ifdef map_bankwidth
0092 # undef map_bankwidth
0093 # define map_bankwidth(map) ((map)->bankwidth)
0094 # undef map_bankwidth_is_large
0095 # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
0096 # undef map_words
0097 # define map_words(map) map_calc_words(map)
0098 # else
0099 # define map_bankwidth(map) 16
0100 # define map_bankwidth_is_large(map) (1)
0101 # define map_words(map) map_calc_words(map)
0102 # endif
0103 #define map_bankwidth_is_16(map) (map_bankwidth(map) == 16)
0104 #undef MAX_MAP_BANKWIDTH
0105 #define MAX_MAP_BANKWIDTH 16
0106 #else
0107 #define map_bankwidth_is_16(map) (0)
0108 #endif
0109
0110 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
0111
0112 # undef map_bankwidth
0113 # define map_bankwidth(map) ((map)->bankwidth)
0114 # undef map_bankwidth_is_large
0115 # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
0116 # undef map_words
0117 # define map_words(map) map_calc_words(map)
0118 #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
0119 #undef MAX_MAP_BANKWIDTH
0120 #define MAX_MAP_BANKWIDTH 32
0121 #else
0122 #define map_bankwidth_is_32(map) (0)
0123 #endif
0124
0125 #ifndef map_bankwidth
0126 #ifdef CONFIG_MTD
0127 #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work"
0128 #endif
0129 static inline int map_bankwidth(void *map)
0130 {
0131 BUG();
0132 return 0;
0133 }
0134 #define map_bankwidth_is_large(map) (0)
0135 #define map_words(map) (0)
0136 #define MAX_MAP_BANKWIDTH 1
0137 #endif
0138
0139 static inline int map_bankwidth_supported(int w)
0140 {
0141 switch (w) {
0142 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
0143 case 1:
0144 #endif
0145 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
0146 case 2:
0147 #endif
0148 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
0149 case 4:
0150 #endif
0151 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
0152 case 8:
0153 #endif
0154 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
0155 case 16:
0156 #endif
0157 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
0158 case 32:
0159 #endif
0160 return 1;
0161
0162 default:
0163 return 0;
0164 }
0165 }
0166
0167 #define MAX_MAP_LONGS (((MAX_MAP_BANKWIDTH * 8) + BITS_PER_LONG - 1) / BITS_PER_LONG)
0168
0169 typedef union {
0170 unsigned long x[MAX_MAP_LONGS];
0171 } map_word;
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 struct map_info {
0192 const char *name;
0193 unsigned long size;
0194 resource_size_t phys;
0195 #define NO_XIP (-1UL)
0196
0197 void __iomem *virt;
0198 void *cached;
0199
0200 int swap;
0201 int bankwidth;
0202
0203
0204
0205
0206 #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
0207 map_word (*read)(struct map_info *, unsigned long);
0208 void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
0209
0210 void (*write)(struct map_info *, const map_word, unsigned long);
0211 void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
0212
0213
0214
0215 #endif
0216
0217
0218
0219
0220
0221
0222 void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
0223
0224
0225
0226
0227
0228
0229 void (*set_vpp)(struct map_info *, int);
0230
0231 unsigned long pfow_base;
0232 unsigned long map_priv_1;
0233 unsigned long map_priv_2;
0234 struct device_node *device_node;
0235 void *fldrv_priv;
0236 struct mtd_chip_driver *fldrv;
0237 };
0238
0239 struct mtd_chip_driver {
0240 struct mtd_info *(*probe)(struct map_info *map);
0241 void (*destroy)(struct mtd_info *);
0242 struct module *module;
0243 char *name;
0244 struct list_head list;
0245 };
0246
0247 void register_mtd_chip_driver(struct mtd_chip_driver *);
0248 void unregister_mtd_chip_driver(struct mtd_chip_driver *);
0249
0250 struct mtd_info *do_map_probe(const char *name, struct map_info *map);
0251 void map_destroy(struct mtd_info *mtd);
0252
0253 #define ENABLE_VPP(map) do { if (map->set_vpp) map->set_vpp(map, 1); } while (0)
0254 #define DISABLE_VPP(map) do { if (map->set_vpp) map->set_vpp(map, 0); } while (0)
0255
0256 #define INVALIDATE_CACHED_RANGE(map, from, size) \
0257 do { if (map->inval_cache) map->inval_cache(map, from, size); } while (0)
0258
0259 #define map_word_equal(map, val1, val2) \
0260 ({ \
0261 int i, ret = 1; \
0262 for (i = 0; i < map_words(map); i++) \
0263 if ((val1).x[i] != (val2).x[i]) { \
0264 ret = 0; \
0265 break; \
0266 } \
0267 ret; \
0268 })
0269
0270 #define map_word_and(map, val1, val2) \
0271 ({ \
0272 map_word r; \
0273 int i; \
0274 for (i = 0; i < map_words(map); i++) \
0275 r.x[i] = (val1).x[i] & (val2).x[i]; \
0276 r; \
0277 })
0278
0279 #define map_word_clr(map, val1, val2) \
0280 ({ \
0281 map_word r; \
0282 int i; \
0283 for (i = 0; i < map_words(map); i++) \
0284 r.x[i] = (val1).x[i] & ~(val2).x[i]; \
0285 r; \
0286 })
0287
0288 #define map_word_or(map, val1, val2) \
0289 ({ \
0290 map_word r; \
0291 int i; \
0292 for (i = 0; i < map_words(map); i++) \
0293 r.x[i] = (val1).x[i] | (val2).x[i]; \
0294 r; \
0295 })
0296
0297 #define map_word_andequal(map, val1, val2, val3) \
0298 ({ \
0299 int i, ret = 1; \
0300 for (i = 0; i < map_words(map); i++) { \
0301 if (((val1).x[i] & (val2).x[i]) != (val3).x[i]) { \
0302 ret = 0; \
0303 break; \
0304 } \
0305 } \
0306 ret; \
0307 })
0308
0309 #define map_word_bitsset(map, val1, val2) \
0310 ({ \
0311 int i, ret = 0; \
0312 for (i = 0; i < map_words(map); i++) { \
0313 if ((val1).x[i] & (val2).x[i]) { \
0314 ret = 1; \
0315 break; \
0316 } \
0317 } \
0318 ret; \
0319 })
0320
0321 static inline map_word map_word_load(struct map_info *map, const void *ptr)
0322 {
0323 map_word r;
0324
0325 if (map_bankwidth_is_1(map))
0326 r.x[0] = *(unsigned char *)ptr;
0327 else if (map_bankwidth_is_2(map))
0328 r.x[0] = get_unaligned((uint16_t *)ptr);
0329 else if (map_bankwidth_is_4(map))
0330 r.x[0] = get_unaligned((uint32_t *)ptr);
0331 #if BITS_PER_LONG >= 64
0332 else if (map_bankwidth_is_8(map))
0333 r.x[0] = get_unaligned((uint64_t *)ptr);
0334 #endif
0335 else if (map_bankwidth_is_large(map))
0336 memcpy(r.x, ptr, map->bankwidth);
0337 else
0338 BUG();
0339
0340 return r;
0341 }
0342
0343 static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
0344 {
0345 int i;
0346
0347 if (map_bankwidth_is_large(map)) {
0348 char *dest = (char *)&orig;
0349
0350 memcpy(dest+start, buf, len);
0351 } else {
0352 for (i = start; i < start+len; i++) {
0353 int bitpos;
0354
0355 #ifdef __LITTLE_ENDIAN
0356 bitpos = i * 8;
0357 #else
0358 bitpos = (map_bankwidth(map) - 1 - i) * 8;
0359 #endif
0360 orig.x[0] &= ~(0xff << bitpos);
0361 orig.x[0] |= (unsigned long)buf[i-start] << bitpos;
0362 }
0363 }
0364 return orig;
0365 }
0366
0367 #if BITS_PER_LONG < 64
0368 #define MAP_FF_LIMIT 4
0369 #else
0370 #define MAP_FF_LIMIT 8
0371 #endif
0372
0373 static inline map_word map_word_ff(struct map_info *map)
0374 {
0375 map_word r;
0376 int i;
0377
0378 if (map_bankwidth(map) < MAP_FF_LIMIT) {
0379 int bw = 8 * map_bankwidth(map);
0380
0381 r.x[0] = (1UL << bw) - 1;
0382 } else {
0383 for (i = 0; i < map_words(map); i++)
0384 r.x[i] = ~0UL;
0385 }
0386 return r;
0387 }
0388
0389 static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
0390 {
0391 map_word r;
0392
0393 if (map_bankwidth_is_1(map))
0394 r.x[0] = __raw_readb(map->virt + ofs);
0395 else if (map_bankwidth_is_2(map))
0396 r.x[0] = __raw_readw(map->virt + ofs);
0397 else if (map_bankwidth_is_4(map))
0398 r.x[0] = __raw_readl(map->virt + ofs);
0399 #if BITS_PER_LONG >= 64
0400 else if (map_bankwidth_is_8(map))
0401 r.x[0] = __raw_readq(map->virt + ofs);
0402 #endif
0403 else if (map_bankwidth_is_large(map))
0404 memcpy_fromio(r.x, map->virt + ofs, map->bankwidth);
0405 else
0406 BUG();
0407
0408 return r;
0409 }
0410
0411 static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
0412 {
0413 if (map_bankwidth_is_1(map))
0414 __raw_writeb(datum.x[0], map->virt + ofs);
0415 else if (map_bankwidth_is_2(map))
0416 __raw_writew(datum.x[0], map->virt + ofs);
0417 else if (map_bankwidth_is_4(map))
0418 __raw_writel(datum.x[0], map->virt + ofs);
0419 #if BITS_PER_LONG >= 64
0420 else if (map_bankwidth_is_8(map))
0421 __raw_writeq(datum.x[0], map->virt + ofs);
0422 #endif
0423 else if (map_bankwidth_is_large(map))
0424 memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
0425 else
0426 BUG();
0427 mb();
0428 }
0429
0430 static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
0431 {
0432 if (map->cached)
0433 memcpy(to, (char *)map->cached + from, len);
0434 else
0435 memcpy_fromio(to, map->virt + from, len);
0436 }
0437
0438 static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
0439 {
0440 memcpy_toio(map->virt + to, from, len);
0441 }
0442
0443 #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
0444 #define map_read(map, ofs) (map)->read(map, ofs)
0445 #define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
0446 #define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
0447 #define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
0448
0449 extern void simple_map_init(struct map_info *);
0450 #define map_is_linear(map) (map->phys != NO_XIP)
0451
0452 #else
0453 #define map_read(map, ofs) inline_map_read(map, ofs)
0454 #define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
0455 #define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
0456 #define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
0457
0458
0459 #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
0460 #define map_is_linear(map) ({ (void)(map); 1; })
0461
0462 #endif
0463
0464 #endif