aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices/phram.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/devices/phram.c')
-rw-r--r--drivers/mtd/devices/phram.c76
1 files changed, 37 insertions, 39 deletions
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 23423bd00b06..67823de68db6 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -33,45 +33,33 @@ struct phram_mtd_list {
33 33
34static LIST_HEAD(phram_list); 34static LIST_HEAD(phram_list);
35 35
36
37static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) 36static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
38{ 37{
39 u_char *start = mtd->priv; 38 u_char *start = mtd->priv;
40 39
41 if (instr->addr + instr->len > mtd->size)
42 return -EINVAL;
43
44 memset(start + instr->addr, 0xff, instr->len); 40 memset(start + instr->addr, 0xff, instr->len);
45 41
46 /* This'll catch a few races. Free the thing before returning :) 42 /*
43 * This'll catch a few races. Free the thing before returning :)
47 * I don't feel at all ashamed. This kind of thing is possible anyway 44 * I don't feel at all ashamed. This kind of thing is possible anyway
48 * with flash, but unlikely. 45 * with flash, but unlikely.
49 */ 46 */
50
51 instr->state = MTD_ERASE_DONE; 47 instr->state = MTD_ERASE_DONE;
52
53 mtd_erase_callback(instr); 48 mtd_erase_callback(instr);
54
55 return 0; 49 return 0;
56} 50}
57 51
58static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, 52static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
59 size_t *retlen, void **virt, resource_size_t *phys) 53 size_t *retlen, void **virt, resource_size_t *phys)
60{ 54{
61 if (from + len > mtd->size)
62 return -EINVAL;
63
64 /* can we return a physical address with this driver? */
65 if (phys)
66 return -EINVAL;
67
68 *virt = mtd->priv + from; 55 *virt = mtd->priv + from;
69 *retlen = len; 56 *retlen = len;
70 return 0; 57 return 0;
71} 58}
72 59
73static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 60static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
74{ 61{
62 return 0;
75} 63}
76 64
77static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, 65static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -79,14 +67,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
79{ 67{
80 u_char *start = mtd->priv; 68 u_char *start = mtd->priv;
81 69
82 if (from >= mtd->size)
83 return -EINVAL;
84
85 if (len > mtd->size - from)
86 len = mtd->size - from;
87
88 memcpy(buf, start + from, len); 70 memcpy(buf, start + from, len);
89
90 *retlen = len; 71 *retlen = len;
91 return 0; 72 return 0;
92} 73}
@@ -96,20 +77,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
96{ 77{
97 u_char *start = mtd->priv; 78 u_char *start = mtd->priv;
98 79
99 if (to >= mtd->size)
100 return -EINVAL;
101
102 if (len > mtd->size - to)
103 len = mtd->size - to;
104
105 memcpy(start + to, buf, len); 80 memcpy(start + to, buf, len);
106
107 *retlen = len; 81 *retlen = len;
108 return 0; 82 return 0;
109} 83}
110 84
111
112
113static void unregister_devices(void) 85static void unregister_devices(void)
114{ 86{
115 struct phram_mtd_list *this, *safe; 87 struct phram_mtd_list *this, *safe;
@@ -142,11 +114,11 @@ static int register_device(char *name, unsigned long start, unsigned long len)
142 new->mtd.name = name; 114 new->mtd.name = name;
143 new->mtd.size = len; 115 new->mtd.size = len;
144 new->mtd.flags = MTD_CAP_RAM; 116 new->mtd.flags = MTD_CAP_RAM;
145 new->mtd.erase = phram_erase; 117 new->mtd._erase = phram_erase;
146 new->mtd.point = phram_point; 118 new->mtd._point = phram_point;
147 new->mtd.unpoint = phram_unpoint; 119 new->mtd._unpoint = phram_unpoint;
148 new->mtd.read = phram_read; 120 new->mtd._read = phram_read;
149 new->mtd.write = phram_write; 121 new->mtd._write = phram_write;
150 new->mtd.owner = THIS_MODULE; 122 new->mtd.owner = THIS_MODULE;
151 new->mtd.type = MTD_RAM; 123 new->mtd.type = MTD_RAM;
152 new->mtd.erasesize = PAGE_SIZE; 124 new->mtd.erasesize = PAGE_SIZE;
@@ -233,7 +205,17 @@ static inline void kill_final_newline(char *str)
233 return 1; \ 205 return 1; \
234} while (0) 206} while (0)
235 207
236static int phram_setup(const char *val, struct kernel_param *kp) 208/*
209 * This shall contain the module parameter if any. It is of the form:
210 * - phram=<device>,<address>,<size> for module case
211 * - phram.phram=<device>,<address>,<size> for built-in case
212 * We leave 64 bytes for the device name, 12 for the address and 12 for the
213 * size.
214 * Example: phram.phram=rootfs,0xa0000000,512Mi
215 */
216static __initdata char phram_paramline[64+12+12];
217
218static int __init phram_setup(const char *val)
237{ 219{
238 char buf[64+12+12], *str = buf; 220 char buf[64+12+12], *str = buf;
239 char *token[3]; 221 char *token[3];
@@ -282,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp)
282 return ret; 264 return ret;
283} 265}
284 266
285module_param_call(phram, phram_setup, NULL, NULL, 000); 267static int __init phram_param_call(const char *val, struct kernel_param *kp)
268{
269 /*
270 * This function is always called before 'init_phram()', whether
271 * built-in or module.
272 */
273 if (strlen(val) >= sizeof(phram_paramline))
274 return -ENOSPC;
275 strcpy(phram_paramline, val);
276
277 return 0;
278}
279
280module_param_call(phram, phram_param_call, NULL, NULL, 000);
286MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); 281MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\"");
287 282
288 283
289static int __init init_phram(void) 284static int __init init_phram(void)
290{ 285{
286 if (phram_paramline[0])
287 return phram_setup(phram_paramline);
288
291 return 0; 289 return 0;
292} 290}
293 291