1 2/* Overhauled routines for dealing with different mmap regions of flash */ 3/* $Id: map.h,v 1.1.1.1 2008/10/15 03:29:28 james26_jang Exp $ */ 4 5#ifndef __LINUX_MTD_MAP_H__ 6#define __LINUX_MTD_MAP_H__ 7 8#include <linux/config.h> 9#include <linux/types.h> 10#include <linux/mtd/mtd.h> 11#include <linux/slab.h> 12 13/* The map stuff is very simple. You fill in your struct map_info with 14 a handful of routines for accessing the device, making sure they handle 15 paging etc. correctly if your device needs it. Then you pass it off 16 to a chip driver which deals with a mapped device - generally either 17 do_cfi_probe() or do_ram_probe(), either of which will return a 18 struct mtd_info if they liked what they saw. At which point, you 19 fill in the mtd->module with your own module address, and register 20 it. 21 22 The mtd->priv field will point to the struct map_info, and any further 23 private data required by the chip driver is linked from the 24 mtd->priv->fldrv_priv field. This allows the map driver to get at 25 the destructor function map->fldrv_destroy() when it's tired 26 of living. 27*/ 28 29struct map_info { 30 char *name; 31 unsigned long size; 32 int buswidth; /* in octets */ 33 __u8 (*read8)(struct map_info *, unsigned long); 34 __u16 (*read16)(struct map_info *, unsigned long); 35 __u32 (*read32)(struct map_info *, unsigned long); 36 /* If it returned a 'long' I'd call it readl. 37 * It doesn't. 38 * I won't. 39 * dwmw2 */ 40 41 void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t); 42 void (*write8)(struct map_info *, __u8, unsigned long); 43 void (*write16)(struct map_info *, __u16, unsigned long); 44 void (*write32)(struct map_info *, __u32, unsigned long); 45 void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t); 46 47 void (*set_vpp)(struct map_info *, int); 48 /* We put these two here rather than a single void *map_priv, 49 because we want mappers to be able to have quickly-accessible 50 cache for the 'currently-mapped page' without the _extra_ 51 redirection that would be necessary. If you need more than 52 two longs, turn the second into a pointer. dwmw2 */ 53 unsigned long map_priv_1; 54 unsigned long map_priv_2; 55 void *fldrv_priv; 56 struct mtd_chip_driver *fldrv; 57}; 58 59 60struct mtd_chip_driver { 61 struct mtd_info *(*probe)(struct map_info *map); 62 void (*destroy)(struct mtd_info *); 63 struct module *module; 64 char *name; 65 struct list_head list; 66}; 67 68void register_mtd_chip_driver(struct mtd_chip_driver *); 69void unregister_mtd_chip_driver(struct mtd_chip_driver *); 70 71struct mtd_info *do_map_probe(char *name, struct map_info *map); 72 73 74/* 75 * Destroy an MTD device which was created for a map device. 76 * Make sure the MTD device is already unregistered before calling this 77 */ 78static inline void map_destroy(struct mtd_info *mtd) 79{ 80 struct map_info *map = mtd->priv; 81 82 if (map->fldrv->destroy) 83 map->fldrv->destroy(mtd); 84#ifdef CONFIG_MODULES 85 if (map->fldrv->module) 86 __MOD_DEC_USE_COUNT(map->fldrv->module); 87#endif 88 kfree(mtd); 89} 90 91#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0) 92#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0) 93 94#endif /* __LINUX_MTD_MAP_H__ */ 95