1/*
2 * Common code to handle map devices which are simple RAM
3 * (C) 2000 Red Hat. GPL'd.
4 * $Id: map_ram.c,v 1.1.1.1 2008/10/15 03:26:35 james26_jang Exp $
5 */
6
7#include <linux/module.h>
8#include <linux/types.h>
9#include <linux/kernel.h>
10#include <asm/io.h>
11#include <asm/byteorder.h>
12#include <linux/errno.h>
13#include <linux/slab.h>
14
15#include <linux/mtd/map.h>
16
17
18static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
19static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
20static int mapram_erase (struct mtd_info *, struct erase_info *);
21static void mapram_nop (struct mtd_info *);
22static struct mtd_info *map_ram_probe(struct map_info *map);
23
24
25static struct mtd_chip_driver mapram_chipdrv = {
26	probe: map_ram_probe,
27	name: "map_ram",
28	module: THIS_MODULE
29};
30
31static struct mtd_info *map_ram_probe(struct map_info *map)
32{
33	struct mtd_info *mtd;
34
35	/* Check the first byte is RAM */
36	/* OK. It seems to be RAM. */
37
38	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
39	if (!mtd)
40		return NULL;
41
42	memset(mtd, 0, sizeof(*mtd));
43
44	map->fldrv = &mapram_chipdrv;
45	mtd->priv = map;
46	mtd->name = map->name;
47	mtd->type = MTD_RAM;
48	mtd->size = map->size;
49	mtd->erase = mapram_erase;
50	mtd->read = mapram_read;
51	mtd->write = mapram_write;
52	mtd->sync = mapram_nop;
53	mtd->flags = MTD_CAP_RAM | MTD_VOLATILE;
54
55	mtd->erasesize = PAGE_SIZE;
56 	while(mtd->size & (mtd->erasesize - 1))
57		mtd->erasesize >>= 1;
58
59	MOD_INC_USE_COUNT;
60	return mtd;
61}
62
63
64static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
65{
66	struct map_info *map = (struct map_info *)mtd->priv;
67
68	map->copy_from(map, buf, from, len);
69	*retlen = len;
70	return 0;
71}
72
73static int mapram_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
74{
75	struct map_info *map = (struct map_info *)mtd->priv;
76
77	map->copy_to(map, to, buf, len);
78	*retlen = len;
79	return 0;
80}
81
82static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
83{
84	/* Yeah, it's inefficient. Who cares? It's faster than a _real_
85	   flash erase. */
86	struct map_info *map = (struct map_info *)mtd->priv;
87	unsigned long i;
88
89	for (i=0; i<instr->len; i++)
90		map->write8(map, 0xFF, instr->addr + i);
91
92	if (instr->callback)
93		instr->callback(instr);
94
95	return 0;
96}
97
98static void mapram_nop(struct mtd_info *mtd)
99{
100	/* Nothing to see here */
101}
102
103int __init map_ram_init(void)
104{
105	register_mtd_chip_driver(&mapram_chipdrv);
106	return 0;
107}
108
109static void __exit map_ram_exit(void)
110{
111	unregister_mtd_chip_driver(&mapram_chipdrv);
112}
113
114module_init(map_ram_init);
115module_exit(map_ram_exit);
116
117MODULE_LICENSE("GPL");
118MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
119MODULE_DESCRIPTION("MTD chip driver for RAM chips");
120