File: map.h

package info (click to toggle)
linux-kernel-headers 2.5.999-test7-bk-17
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 28,268 kB
  • ctags: 214,024
  • sloc: ansic: 324,929; cpp: 783; makefile: 79; asm: 61; sh: 61
file content (172 lines) | stat: -rw-r--r-- 5,309 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

/* Overhauled routines for dealing with different mmap regions of flash */
/* $Id: map.h,v 1.34 2003/05/28 12:42:22 dwmw2 Exp $ */

#ifndef __LINUX_MTD_MAP_H__
#define __LINUX_MTD_MAP_H__

#include <linux/config.h>
#include <linux/types.h>
#include <linux/list.h>
#include <asm/system.h>
#include <asm/io.h>

/* The map stuff is very simple. You fill in your struct map_info with
   a handful of routines for accessing the device, making sure they handle
   paging etc. correctly if your device needs it. Then you pass it off
   to a chip driver which deals with a mapped device - generally either
   do_cfi_probe() or do_ram_probe(), either of which will return a 
   struct mtd_info if they liked what they saw. At which point, you
   fill in the mtd->module with your own module address, and register 
   it.
   
   The mtd->priv field will point to the struct map_info, and any further
   private data required by the chip driver is linked from the 
   mtd->priv->fldrv_priv field. This allows the map driver to get at 
   the destructor function map->fldrv_destroy() when it's tired
   of living.
*/

struct map_info {
	char *name;
	unsigned long size;
	unsigned long phys;
#define NO_XIP (-1UL)

	unsigned long virt;
	void *cached;

	int buswidth; /* in octets */

#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
	u8 (*read8)(struct map_info *, unsigned long);
	u16 (*read16)(struct map_info *, unsigned long);
	u32 (*read32)(struct map_info *, unsigned long);  
	u64 (*read64)(struct map_info *, unsigned long);  
	/* If it returned a 'long' I'd call it readl.
	 * It doesn't.
	 * I won't.
	 * dwmw2 */
	
	void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
	void (*write8)(struct map_info *, u8, unsigned long);
	void (*write16)(struct map_info *, u16, unsigned long);
	void (*write32)(struct map_info *, u32, unsigned long);
	void (*write64)(struct map_info *, u64, unsigned long);
	void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);

	/* We can perhaps put in 'point' and 'unpoint' methods, if we really
	   want to enable XIP for non-linear mappings. Not yet though. */
#endif
	/* set_vpp() must handle being reentered -- enable, enable, disable 
	   must leave it enabled. */
	void (*set_vpp)(struct map_info *, int);

	unsigned long map_priv_1;
	unsigned long map_priv_2;
	void *fldrv_priv;
	struct mtd_chip_driver *fldrv;
};

struct mtd_chip_driver {
	struct mtd_info *(*probe)(struct map_info *map);
	void (*destroy)(struct mtd_info *);
	struct module *module;
	char *name;
	struct list_head list;
};

void register_mtd_chip_driver(struct mtd_chip_driver *);
void unregister_mtd_chip_driver(struct mtd_chip_driver *);

struct mtd_info *do_map_probe(const char *name, struct map_info *map);
void map_destroy(struct mtd_info *mtd);

#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)

#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
#define map_read8(map, ofs) (map)->read8(map, ofs)
#define map_read16(map, ofs) (map)->read16(map, ofs)
#define map_read32(map, ofs) (map)->read32(map, ofs)
#define map_read64(map, ofs) (map)->read64(map, ofs)
#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
#define map_write8(map, datum, ofs) (map)->write8(map, datum, ofs)
#define map_write16(map, datum, ofs) (map)->write16(map, datum, ofs)
#define map_write32(map, datum, ofs) (map)->write32(map, datum, ofs)
#define map_write64(map, datum, ofs) (map)->write64(map, datum, ofs)
#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)

extern void simple_map_init(struct map_info *);
#define map_is_linear(map) (map->phys != NO_XIP)

#else
static inline u8 map_read8(struct map_info *map, unsigned long ofs)
{
	return __raw_readb(map->virt + ofs);
}

static inline u16 map_read16(struct map_info *map, unsigned long ofs)
{
	return __raw_readw(map->virt + ofs);
}

static inline u32 map_read32(struct map_info *map, unsigned long ofs)
{
	return __raw_readl(map->virt + ofs);
}

static inline u64 map_read64(struct map_info *map, unsigned long ofs)
{
#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
	BUG();
	return 0;
#else
	return __raw_readll(map->virt + ofs);
#endif
}

static inline void map_write8(struct map_info *map, u8 datum, unsigned long ofs)
{
	__raw_writeb(datum, map->virt + ofs);
	mb();
}

static inline void map_write16(struct map_info *map, u16 datum, unsigned long ofs)
{
	__raw_writew(datum, map->virt + ofs);
	mb();
}

static inline void map_write32(struct map_info *map, u32 datum, unsigned long ofs)
{
	__raw_writel(datum, map->virt + ofs);
	mb();
}

static inline void map_write64(struct map_info *map, u64 datum, unsigned long ofs)
{
#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
	BUG();
#else
	__raw_writell(datum, map->virt + ofs);
	mb();
#endif /* CFI_B8 */
}

static inline void map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
	memcpy_fromio(to, map->virt + from, len);
}

static inline void map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
	memcpy_toio(map->virt + to, from, len);
}

#define simple_map_init(map) do { } while (0)
#define map_is_linear(map) (1)

#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */

#endif /* __LINUX_MTD_MAP_H__ */