1 /*
2 * $Id: physmap.c,v 1.21 2002/09/05 05:12:54 acurtis Exp $
3 *
4 * Normal mappings of chips in physical memory
5 */
6
7 #include <linux/module.h>
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <asm/io.h>
11 #include <linux/mtd/mtd.h>
12 #include <linux/mtd/map.h>
13 #include <linux/config.h>
14
15 #ifdef CONFIG_MTD_PARTITIONS
16 #include <linux/mtd/partitions.h>
17 #endif
18
19 #define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START
20 #define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN
21 #define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH
22
23 static struct mtd_info *mymtd;
24
physmap_read8(struct map_info * map,unsigned long ofs)25 __u8 physmap_read8(struct map_info *map, unsigned long ofs)
26 {
27 return __raw_readb(map->map_priv_1 + ofs);
28 }
29
physmap_read16(struct map_info * map,unsigned long ofs)30 __u16 physmap_read16(struct map_info *map, unsigned long ofs)
31 {
32 return __raw_readw(map->map_priv_1 + ofs);
33 }
34
physmap_read32(struct map_info * map,unsigned long ofs)35 __u32 physmap_read32(struct map_info *map, unsigned long ofs)
36 {
37 return __raw_readl(map->map_priv_1 + ofs);
38 }
39
physmap_copy_from(struct map_info * map,void * to,unsigned long from,ssize_t len)40 void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
41 {
42 memcpy_fromio(to, map->map_priv_1 + from, len);
43 }
44
physmap_write8(struct map_info * map,__u8 d,unsigned long adr)45 void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
46 {
47 __raw_writeb(d, map->map_priv_1 + adr);
48 mb();
49 }
50
physmap_write16(struct map_info * map,__u16 d,unsigned long adr)51 void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
52 {
53 __raw_writew(d, map->map_priv_1 + adr);
54 mb();
55 }
56
physmap_write32(struct map_info * map,__u32 d,unsigned long adr)57 void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
58 {
59 __raw_writel(d, map->map_priv_1 + adr);
60 mb();
61 }
62
physmap_copy_to(struct map_info * map,unsigned long to,const void * from,ssize_t len)63 void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
64 {
65 memcpy_toio(map->map_priv_1 + to, from, len);
66 }
67
68 struct map_info physmap_map = {
69 name: "Physically mapped flash",
70 size: WINDOW_SIZE,
71 buswidth: BUSWIDTH,
72 read8: physmap_read8,
73 read16: physmap_read16,
74 read32: physmap_read32,
75 copy_from: physmap_copy_from,
76 write8: physmap_write8,
77 write16: physmap_write16,
78 write32: physmap_write32,
79 copy_to: physmap_copy_to
80 };
81
82 #ifdef CONFIG_MTD_PARTITIONS
83 #ifdef CONFIG_MTD_CMDLINE_PARTS
84 static struct mtd_partition *mtd_parts = 0;
85 static int mtd_parts_nb = 0;
86 #else
87 static struct mtd_partition physmap_partitions[] = {
88 /* Put your own partition definitions here */
89 #if 0
90 {
91 name: "bootROM",
92 size: 0x80000,
93 offset: 0,
94 mask_flags: MTD_WRITEABLE, /* force read-only */
95 }, {
96 name: "zImage",
97 size: 0x100000,
98 offset: MTDPART_OFS_APPEND,
99 mask_flags: MTD_WRITEABLE, /* force read-only */
100 }, {
101 name: "ramdisk.gz",
102 size: 0x300000,
103 offset: MTDPART_OFS_APPEND,
104 mask_flags: MTD_WRITEABLE, /* force read-only */
105 }, {
106 name: "User FS",
107 size: MTDPART_SIZ_FULL,
108 offset: MTDPART_OFS_APPEND,
109 }
110 #endif
111 };
112
113 #define NUM_PARTITIONS (sizeof(physmap_partitions)/sizeof(struct mtd_partition))
114
115 #endif
116 #endif
117
init_physmap(void)118 int __init init_physmap(void)
119 {
120 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 };
121 const char **type;
122
123 printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
124 physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
125
126 if (!physmap_map.map_priv_1) {
127 printk("Failed to ioremap\n");
128 return -EIO;
129 }
130
131 mymtd = 0;
132 type = rom_probe_types;
133 for(; !mymtd && *type; type++) {
134 mymtd = do_map_probe(*type, &physmap_map);
135 }
136 if (mymtd) {
137 mymtd->module = THIS_MODULE;
138
139 add_mtd_device(mymtd);
140 #ifdef CONFIG_MTD_PARTITIONS
141 #ifdef CONFIG_MTD_CMDLINE_PARTS
142 mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts,
143 "phys");
144 if (mtd_parts_nb > 0)
145 {
146 printk(KERN_NOTICE
147 "Using command line partition definition\n");
148 add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
149 }
150 #else
151 if (NUM_PARTITIONS != 0)
152 {
153 printk(KERN_NOTICE
154 "Using physmap partition definition\n");
155 add_mtd_partitions (mymtd, physmap_partitions, NUM_PARTITIONS);
156 }
157
158 #endif
159 #endif
160 return 0;
161 }
162
163 iounmap((void *)physmap_map.map_priv_1);
164 return -ENXIO;
165 }
166
cleanup_physmap(void)167 static void __exit cleanup_physmap(void)
168 {
169 if (mymtd) {
170 del_mtd_device(mymtd);
171 map_destroy(mymtd);
172 }
173 if (physmap_map.map_priv_1) {
174 iounmap((void *)physmap_map.map_priv_1);
175 physmap_map.map_priv_1 = 0;
176 }
177 }
178
179 module_init(init_physmap);
180 module_exit(cleanup_physmap);
181
182
183 MODULE_LICENSE("GPL");
184 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
185 MODULE_DESCRIPTION("Generic configurable MTD map driver");
186