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__ */
|