1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* Overhauled routines for dealing with different mmap regions of flash */
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* $Id: map.h,v 1.54 2005/11/07 11:14:54 gleixner Exp $ */
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __LINUX_MTD_MAP_H__
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __LINUX_MTD_MAP_H__
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/types.h>
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/list.h>
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/string.h>
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/mtd/compatmac.h>
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/unaligned.h>
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/system.h>
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/io.h>
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth(map) 1
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_1(map) (map_bankwidth(map) == 1)
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_large(map) (0)
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_words(map) (1)
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_BANKWIDTH 1
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_1(map) (0)
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# ifdef map_bankwidth
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) ((map)->bankwidth)
32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# else
33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) 2
34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (0)
35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) (1)
36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# endif
37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_2(map) (map_bankwidth(map) == 2)
38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#undef MAX_MAP_BANKWIDTH
39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_BANKWIDTH 2
40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_2(map) (0)
42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# ifdef map_bankwidth
46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth
47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) ((map)->bankwidth)
48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# else
49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) 4
50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (0)
51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) (1)
52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# endif
53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_4(map) (map_bankwidth(map) == 4)
54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#undef MAX_MAP_BANKWIDTH
55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_BANKWIDTH 4
56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_4(map) (0)
58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* ensure we never evaluate anything shorted than an unsigned long
61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * to zero, and ensure we'll never miss the end of an comparison (bjd) */
62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long))
64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# ifdef map_bankwidth
67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth
68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) ((map)->bankwidth)
69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  if BITS_PER_LONG < 64
70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#   undef map_bankwidth_is_large
71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#   define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#   undef map_words
73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#   define map_words(map) map_calc_words(map)
74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  endif
75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# else
76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) 8
77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (BITS_PER_LONG < 64)
78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) map_calc_words(map)
79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# endif
80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_8(map) (map_bankwidth(map) == 8)
81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#undef MAX_MAP_BANKWIDTH
82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_BANKWIDTH 8
83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_8(map) (0)
85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# ifdef map_bankwidth
89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth
90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) ((map)->bankwidth)
91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth_is_large
92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_words
94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) map_calc_words(map)
95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# else
96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) 16
97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (1)
98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) map_calc_words(map)
99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# endif
100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_16(map) (map_bankwidth(map) == 16)
101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#undef MAX_MAP_BANKWIDTH
102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_BANKWIDTH 16
103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_16(map) (0)
105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# ifdef map_bankwidth
109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth
110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) ((map)->bankwidth)
111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_bankwidth_is_large
112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  undef map_words
114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) map_calc_words(map)
115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# else
116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth(map) 32
117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_bankwidth_is_large(map) (1)
118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#  define map_words(map) map_calc_words(map)
119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# endif
120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#undef MAX_MAP_BANKWIDTH
122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_BANKWIDTH 32
123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_bankwidth_is_32(map) (0)
125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef map_bankwidth
128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#error "No bus width supported. What's the point?"
129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int map_bankwidth_supported(int w)
132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	switch (w) {
134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 1:
136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 2:
139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 4:
142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 8:
145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 16:
148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 32:
151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		return 1;
153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	default:
155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		return 0;
156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG )
160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querutypedef union {
162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long x[MAX_MAP_LONGS];
163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} map_word;
164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* The map stuff is very simple. You fill in your struct map_info with
166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   a handful of routines for accessing the device, making sure they handle
167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   paging etc. correctly if your device needs it. Then you pass it off
168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   to a chip probe routine -- either JEDEC or CFI probe or both -- via
169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   do_map_probe(). If a chip is recognised, the probe code will invoke the
170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   appropriate chip driver (if present) and return a struct mtd_info.
171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   At which point, you fill in the mtd->module with your own module
172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   address, and register it with the MTD core code. Or you could partition
173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   it and register the partitions instead, or keep it for your own private
174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   use; whatever.
175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   The mtd->priv field will point to the struct map_info, and any further
177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   private data required by the chip driver is linked from the
178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   mtd->priv->fldrv_priv field. This allows the map driver to get at
179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   the destructor function map->fldrv_destroy() when it's tired
180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru   of living.
181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru*/
182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct map_info {
184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	char *name;
185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long size;
186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long phys;
187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define NO_XIP (-1UL)
188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void __iomem *virt;
190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void *cached;
191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int bankwidth; /* in octets. This isn't necessarily the width
193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		       of actual bus cycles -- it's the repeat interval
194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		      in bytes, before you are talking to the first chip again.
195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		      */
196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word (*read)(struct map_info *, unsigned long);
199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void (*write)(struct map_info *, const map_word, unsigned long);
202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	/* We can perhaps put in 'point' and 'unpoint' methods, if we really
205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   want to enable XIP for non-linear mappings. Not yet though. */
206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	/* It's possible for the map driver to use cached memory in its
208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   copy_from implementation (and _only_ with copy_from).  However,
209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   when the chip driver knows some flash area has changed contents,
210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   it will signal it to the map driver through this routine to let
211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   the map driver invalidate the corresponding cache as needed.
212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   If there is no cache to care about this can be set to NULL. */
213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	/* set_vpp() must handle being reentered -- enable, enable, disable
216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   must leave it enabled. */
217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void (*set_vpp)(struct map_info *, int);
218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long map_priv_1;
220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long map_priv_2;
221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void *fldrv_priv;
222c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	struct mtd_chip_driver *fldrv;
223c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru};
224c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
225c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct mtd_chip_driver {
226c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	struct mtd_info *(*probe)(struct map_info *map);
227c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	void (*destroy)(struct mtd_info *);
228c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	struct module *module;
229c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	char *name;
230c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	struct list_head list;
231c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru};
232c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
233c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid register_mtd_chip_driver(struct mtd_chip_driver *);
234c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid unregister_mtd_chip_driver(struct mtd_chip_driver *);
235c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
236c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct mtd_info *do_map_probe(const char *name, struct map_info *map);
237c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruvoid map_destroy(struct mtd_info *mtd);
238c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
239c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
240c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
241c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
242c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define INVALIDATE_CACHED_RANGE(map, from, size) \
243c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
244c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
245c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
246c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
247c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
248c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
249c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	for (i=0; i<map_words(map); i++) {
250c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		if (val1.x[i] != val2.x[i])
251c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			return 0;
252c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
253c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return 1;
254c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
255c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
256c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
257c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
258c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word r;
259c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
260c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
261c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	for (i=0; i<map_words(map); i++) {
262c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[i] = val1.x[i] & val2.x[i];
263c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
264c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
265c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
266c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
267c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
268c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
269c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word r;
270c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
271c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
272c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	for (i=0; i<map_words(map); i++) {
273c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[i] = val1.x[i] & ~val2.x[i];
274c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
275c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
276c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
277c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
278c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
279c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
280c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word r;
281c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
282c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
283c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	for (i=0; i<map_words(map); i++) {
284c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[i] = val1.x[i] | val2.x[i];
285c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
286c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
287c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
288c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
289c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
290c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
291c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
292c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
293c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
294c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
295c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	for (i=0; i<map_words(map); i++) {
296c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		if (val1.x[i] & val2.x[i])
297c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			return 1;
298c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
299c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return 0;
300c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
301c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
302c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word map_word_load(struct map_info *map, const void *ptr)
303c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
304c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word r;
305c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
306c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (map_bankwidth_is_1(map))
307c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = *(unsigned char *)ptr;
308c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_2(map))
309c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = get_unaligned((uint16_t *)ptr);
310c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_4(map))
311c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = get_unaligned((uint32_t *)ptr);
312c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if BITS_PER_LONG >= 64
313c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_8(map))
314c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = get_unaligned((uint64_t *)ptr);
315c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
316c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_large(map))
317c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memcpy(r.x, ptr, map->bankwidth);
318c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
319c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
320c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
321c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
322c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
323c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
324c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
325c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
326c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (map_bankwidth_is_large(map)) {
327c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		char *dest = (char *)&orig;
328c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memcpy(dest+start, buf, len);
329c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	} else {
330c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		for (i=start; i < start+len; i++) {
331c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			int bitpos;
332c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef __LITTLE_ENDIAN
333c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			bitpos = i*8;
334c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else /* __BIG_ENDIAN */
335c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			bitpos = (map_bankwidth(map)-1-i)*8;
336c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
337c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			orig.x[0] &= ~(0xff << bitpos);
338c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			orig.x[0] |= buf[i-start] << bitpos;
339c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		}
340c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
341c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return orig;
342c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
343c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
344c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if BITS_PER_LONG < 64
345c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAP_FF_LIMIT 4
346c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
347c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define MAP_FF_LIMIT 8
348c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
349c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
350c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word map_word_ff(struct map_info *map)
351c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
352c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word r;
353c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int i;
354c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
355c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (map_bankwidth(map) < MAP_FF_LIMIT) {
356c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		int bw = 8 * map_bankwidth(map);
357c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = (1 << bw) - 1;
358c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	} else {
359c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		for (i=0; i<map_words(map); i++)
360c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			r.x[i] = ~0UL;
361c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
362c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
363c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
364c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
365c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
366c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
367c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	map_word r;
368c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
369c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (map_bankwidth_is_1(map))
370c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = __raw_readb(map->virt + ofs);
371c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_2(map))
372c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = __raw_readw(map->virt + ofs);
373c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_4(map))
374c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = __raw_readl(map->virt + ofs);
375c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if BITS_PER_LONG >= 64
376c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_8(map))
377c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r.x[0] = __raw_readq(map->virt + ofs);
378c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
379c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_large(map))
380c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
381c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
382c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
383c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
384c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
385c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
386c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
387c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (map_bankwidth_is_1(map))
388c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__raw_writeb(datum.x[0], map->virt + ofs);
389c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_2(map))
390c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__raw_writew(datum.x[0], map->virt + ofs);
391c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_4(map))
392c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__raw_writel(datum.x[0], map->virt + ofs);
393c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if BITS_PER_LONG >= 64
394c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_8(map))
395c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__raw_writeq(datum.x[0], map->virt + ofs);
396c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
397c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else if (map_bankwidth_is_large(map))
398c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
399c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	mb();
400c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
401c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
402c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
403c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
404c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (map->cached)
405c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memcpy(to, (char *)map->cached + from, len);
406c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else
407c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memcpy_fromio(to, map->virt + from, len);
408c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
409c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
410c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
411c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
412c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	memcpy_toio(map->virt + to, from, len);
413c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
414c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
415c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
416c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_read(map, ofs) (map)->read(map, ofs)
417c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
418c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
419c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
420c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
421c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void simple_map_init(struct map_info *);
422c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_is_linear(map) (map->phys != NO_XIP)
423c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
424c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
425c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_read(map, ofs) inline_map_read(map, ofs)
426c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
427c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
428c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
429c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
430c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
431c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
432c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define map_is_linear(map) ({ (void)(map); 1; })
433c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
434c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
435c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
436c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __LINUX_MTD_MAP_H__ */
437