ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/ipaq-flash.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
7 *
8 * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/spinlock.h>
15 #include <linux/init.h>
16 #include <linux/slab.h>
17 #include <asm/page.h>
18 #include <asm/mach-types.h>
19 #include <asm/system.h>
20 #include <asm/errno.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/map.h>
24 #include <linux/mtd/partitions.h>
25 #ifdef CONFIG_MTD_CONCAT
26 #include <linux/mtd/concat.h>
27 #endif
29 #include <asm/hardware.h>
30 #include <asm/arch-sa1100/h3600.h>
31 #include <asm/io.h>
34 #ifndef CONFIG_IPAQ_HANDHELD
35 #error This is for iPAQ Handhelds only
36 #endif
37 #ifdef CONFIG_SA1100_JORNADA56X
39 static void jornada56x_set_vpp(struct map_info *map, int vpp)
40 {
41 if (vpp)
42 GPSR = GPIO_GPIO26;
43 else
44 GPCR = GPIO_GPIO26;
45 GPDR |= GPIO_GPIO26;
46 }
48 #endif
50 #ifdef CONFIG_SA1100_JORNADA720
52 static void jornada720_set_vpp(struct map_info *map, int vpp)
53 {
54 if (vpp)
55 PPSR |= 0x80;
56 else
57 PPSR &= ~0x80;
58 PPDR |= 0x80;
59 }
61 #endif
63 #define MAX_IPAQ_CS 2 /* Number of CS we are going to test */
65 #define IPAQ_MAP_INIT(X) \
66 { \
67 name: "IPAQ flash " X, \
68 }
71 static struct map_info ipaq_map[MAX_IPAQ_CS] = {
72 IPAQ_MAP_INIT("bank 1"),
73 IPAQ_MAP_INIT("bank 2")
74 };
76 static struct mtd_info *my_sub_mtd[MAX_IPAQ_CS] = {
77 NULL,
78 NULL
79 };
81 /*
82 * Here are partition information for all known IPAQ-based devices.
83 * See include/linux/mtd/partitions.h for definition of the mtd_partition
84 * structure.
85 *
86 * The *_max_flash_size is the maximum possible mapped flash size which
87 * is not necessarily the actual flash size. It must be no more than
88 * the value specified in the "struct map_desc *_io_desc" mapping
89 * definition for the corresponding machine.
90 *
91 * Please keep these in alphabetical order, and formatted as per existing
92 * entries. Thanks.
93 */
95 #ifdef CONFIG_IPAQ_HANDHELD
96 static unsigned long h3xxx_max_flash_size = 0x04000000;
97 static struct mtd_partition h3xxx_partitions[] = {
98 {
99 name: "H3XXX boot firmware",
100 #ifndef CONFIG_LAB
101 size: 0x00040000,
102 #else
103 size: 0x00080000,
104 #endif
105 offset: 0,
106 #ifndef CONFIG_LAB
107 mask_flags: MTD_WRITEABLE, /* force read-only */
108 #endif
109 },
110 {
111 name: "H3XXX root jffs2",
112 #ifndef CONFIG_LAB
113 size: 0x2000000 - 2*0x40000, /* Warning, this is fixed later */
114 offset: 0x00040000,
115 #else
116 size: 0x2000000 - 0x40000 - 0x80000, /* Warning, this is fixed later */
117 offset: 0x00080000,
118 #endif
119 },
120 {
121 name: "asset",
122 size: 0x40000,
123 offset: 0x2000000 - 0x40000, /* Warning, this is fixed later */
124 mask_flags: MTD_WRITEABLE, /* force read-only */
125 }
126 };
128 #ifndef CONFIG_MTD_CONCAT
129 static struct mtd_partition h3xxx_partitions_bank2[] = {
130 /* this is used only on 2 CS machines when concat is not present */
131 {
132 name: "second H3XXX root jffs2",
133 size: 0x1000000 - 0x40000, /* Warning, this is fixed later */
134 offset: 0x00000000,
135 },
136 {
137 name: "second asset",
138 size: 0x40000,
139 offset: 0x1000000 - 0x40000, /* Warning, this is fixed later */
140 mask_flags: MTD_WRITEABLE, /* force read-only */
141 }
142 };
143 #endif
145 static DEFINE_SPINLOCK(ipaq_vpp_lock);
147 static void h3xxx_set_vpp(struct map_info *map, int vpp)
148 {
149 static int nest = 0;
151 spin_lock(&ipaq_vpp_lock);
152 if (vpp)
153 nest++;
154 else
155 nest--;
156 if (nest)
157 assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 1);
158 else
159 assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 0);
160 spin_unlock(&ipaq_vpp_lock);
161 }
163 #endif
165 #if defined(CONFIG_SA1100_JORNADA56X) || defined(CONFIG_SA1100_JORNADA720)
166 static unsigned long jornada_max_flash_size = 0x02000000;
167 static struct mtd_partition jornada_partitions[] = {
168 {
169 name: "Jornada boot firmware",
170 size: 0x00040000,
171 offset: 0,
172 mask_flags: MTD_WRITEABLE, /* force read-only */
173 }, {
174 name: "Jornada root jffs2",
175 size: MTDPART_SIZ_FULL,
176 offset: 0x00040000,
177 }
178 };
179 #endif
182 static struct mtd_partition *parsed_parts;
183 static struct mtd_info *mymtd;
185 static unsigned long cs_phys[] = {
186 #ifdef CONFIG_ARCH_SA1100
187 SA1100_CS0_PHYS,
188 SA1100_CS1_PHYS,
189 SA1100_CS2_PHYS,
190 SA1100_CS3_PHYS,
191 SA1100_CS4_PHYS,
192 SA1100_CS5_PHYS,
193 #else
194 PXA_CS0_PHYS,
195 PXA_CS1_PHYS,
196 PXA_CS2_PHYS,
197 PXA_CS3_PHYS,
198 PXA_CS4_PHYS,
199 PXA_CS5_PHYS,
200 #endif
201 };
203 static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
205 static int __init h1900_special_case(void);
207 int __init ipaq_mtd_init(void)
208 {
209 struct mtd_partition *parts = NULL;
210 int nb_parts = 0;
211 int parsed_nr_parts = 0;
212 const char *part_type;
213 int i; /* used when we have >1 flash chips */
214 unsigned long tot_flashsize = 0; /* used when we have >1 flash chips */
216 /* Default flash bankwidth */
217 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
219 if (machine_is_h1900())
220 {
221 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
222 return h1900_special_case();
223 }
225 if (machine_is_h3100() || machine_is_h1900())
226 for(i=0; i<MAX_IPAQ_CS; i++)
227 ipaq_map[i].bankwidth = 2;
228 else
229 for(i=0; i<MAX_IPAQ_CS; i++)
230 ipaq_map[i].bankwidth = 4;
232 /*
233 * Static partition definition selection
234 */
235 part_type = "static";
237 simple_map_init(&ipaq_map[0]);
238 simple_map_init(&ipaq_map[1]);
240 #ifdef CONFIG_IPAQ_HANDHELD
241 if (machine_is_ipaq()) {
242 parts = h3xxx_partitions;
243 nb_parts = ARRAY_SIZE(h3xxx_partitions);
244 for(i=0; i<MAX_IPAQ_CS; i++) {
245 ipaq_map[i].size = h3xxx_max_flash_size;
246 ipaq_map[i].set_vpp = h3xxx_set_vpp;
247 ipaq_map[i].phys = cs_phys[i];
248 ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000);
249 if (machine_is_h3100 () || machine_is_h1900())
250 ipaq_map[i].bankwidth = 2;
251 }
252 if (machine_is_h3600()) {
253 /* No asset partition here */
254 h3xxx_partitions[1].size += 0x40000;
255 nb_parts--;
256 }
257 }
258 #endif
259 #ifdef CONFIG_ARCH_H5400
260 if (machine_is_h5400()) {
261 ipaq_map[0].size = 0x02000000;
262 ipaq_map[1].size = 0x02000000;
263 ipaq_map[1].phys = 0x02000000;
264 ipaq_map[1].virt = ipaq_map[0].virt + 0x02000000;
265 }
266 #endif
267 #ifdef CONFIG_ARCH_H1900
268 if (machine_is_h1900()) {
269 ipaq_map[0].size = 0x00400000;
270 ipaq_map[1].size = 0x02000000;
271 ipaq_map[1].phys = 0x00080000;
272 ipaq_map[1].virt = ipaq_map[0].virt + 0x00080000;
273 }
274 #endif
276 #ifdef CONFIG_SA1100_JORNADA56X
277 if (machine_is_jornada56x()) {
278 parts = jornada_partitions;
279 nb_parts = ARRAY_SIZE(jornada_partitions);
280 ipaq_map[0].size = jornada_max_flash_size;
281 ipaq_map[0].set_vpp = jornada56x_set_vpp;
282 ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000);
283 }
284 #endif
285 #ifdef CONFIG_SA1100_JORNADA720
286 if (machine_is_jornada720()) {
287 parts = jornada_partitions;
288 nb_parts = ARRAY_SIZE(jornada_partitions);
289 ipaq_map[0].size = jornada_max_flash_size;
290 ipaq_map[0].set_vpp = jornada720_set_vpp;
291 }
292 #endif
295 if (machine_is_ipaq()) { /* for iPAQs only */
296 for(i=0; i<MAX_IPAQ_CS; i++) {
297 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with CFI.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt);
298 my_sub_mtd[i] = do_map_probe("cfi_probe", &ipaq_map[i]);
299 if (!my_sub_mtd[i]) {
300 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[i].bankwidth*8, ipaq_map[i].virt);
301 my_sub_mtd[i] = do_map_probe("jedec_probe", &ipaq_map[i]);
302 }
303 if (!my_sub_mtd[i]) {
304 printk(KERN_NOTICE "iPAQ flash: failed to find flash.\n");
305 if (i)
306 break;
307 else
308 return -ENXIO;
309 } else
310 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
312 /* do we really need this debugging? --joshua 20030703 */
313 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
314 my_sub_mtd[i]->owner = THIS_MODULE;
315 tot_flashsize += my_sub_mtd[i]->size;
316 }
317 #ifdef CONFIG_MTD_CONCAT
318 /* fix the asset location */
319 # ifdef CONFIG_LAB
320 h3xxx_partitions[1].size = tot_flashsize - 0x40000 - 0x80000 /* extra big boot block */;
321 # else
322 h3xxx_partitions[1].size = tot_flashsize - 2 * 0x40000;
323 # endif
324 h3xxx_partitions[2].offset = tot_flashsize - 0x40000;
325 /* and concat the devices */
326 mymtd = mtd_concat_create(&my_sub_mtd[0], i,
327 "ipaq");
328 if (!mymtd) {
329 printk("Cannot create iPAQ concat device\n");
330 return -ENXIO;
331 }
332 #else
333 mymtd = my_sub_mtd[0];
335 /*
336 *In the very near future, command line partition parsing
337 * will use the device name as 'mtd-id' instead of a value
338 * passed to the parse_cmdline_partitions() routine. Since
339 * the bootldr says 'ipaq', make sure it continues to work.
340 */
341 mymtd->name = "ipaq";
343 if ((machine_is_h3600())) {
344 # ifdef CONFIG_LAB
345 h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x80000;
346 # else
347 h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000;
348 # endif
349 nb_parts = 2;
350 } else {
351 # ifdef CONFIG_LAB
352 h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000 - 0x80000; /* extra big boot block */
353 # else
354 h3xxx_partitions[1].size = my_sub_mtd[0]->size - 2*0x40000;
355 # endif
356 h3xxx_partitions[2].offset = my_sub_mtd[0]->size - 0x40000;
357 }
359 if (my_sub_mtd[1]) {
360 # ifdef CONFIG_LAB
361 h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x80000;
362 # else
363 h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x40000;
364 # endif
365 h3xxx_partitions_bank2[1].offset = my_sub_mtd[1]->size - 0x40000;
366 }
367 #endif
368 }
369 else {
370 /*
371 * Now let's probe for the actual flash. Do it here since
372 * specific machine settings might have been set above.
373 */
374 printk(KERN_NOTICE "IPAQ flash: probing %d-bit flash bus, window=%lx\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
375 mymtd = do_map_probe("cfi_probe", &ipaq_map[0]);
376 if (!mymtd)
377 return -ENXIO;
378 mymtd->owner = THIS_MODULE;
379 }
382 /*
383 * Dynamic partition selection stuff (might override the static ones)
384 */
386 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
388 if (i > 0) {
389 nb_parts = parsed_nr_parts = i;
390 parts = parsed_parts;
391 part_type = "dynamic";
392 }
394 if (!parts) {
395 printk(KERN_NOTICE "IPAQ flash: no partition info available, registering whole flash at once\n");
396 add_mtd_device(mymtd);
397 #ifndef CONFIG_MTD_CONCAT
398 if (my_sub_mtd[1])
399 add_mtd_device(my_sub_mtd[1]);
400 #endif
401 } else {
402 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
403 add_mtd_partitions(mymtd, parts, nb_parts);
404 #ifndef CONFIG_MTD_CONCAT
405 if (my_sub_mtd[1])
406 add_mtd_partitions(my_sub_mtd[1], h3xxx_partitions_bank2, ARRAY_SIZE(h3xxx_partitions_bank2));
407 #endif
408 }
410 return 0;
411 }
413 static void __exit ipaq_mtd_cleanup(void)
414 {
415 int i;
417 if (mymtd) {
418 del_mtd_partitions(mymtd);
419 #ifndef CONFIG_MTD_CONCAT
420 if (my_sub_mtd[1])
421 del_mtd_partitions(my_sub_mtd[1]);
422 #endif
423 map_destroy(mymtd);
424 #ifdef CONFIG_MTD_CONCAT
425 for(i=0; i<MAX_IPAQ_CS; i++)
426 #else
427 for(i=1; i<MAX_IPAQ_CS; i++)
428 #endif
429 {
430 if (my_sub_mtd[i])
431 map_destroy(my_sub_mtd[i]);
432 }
433 kfree(parsed_parts);
434 }
435 }
437 static int __init h1900_special_case(void)
438 {
439 /* The iPAQ h1900 is a special case - it has weird ROM. */
440 simple_map_init(&ipaq_map[0]);
441 ipaq_map[0].size = 0x80000;
442 ipaq_map[0].set_vpp = h3xxx_set_vpp;
443 ipaq_map[0].phys = 0x0;
444 ipaq_map[0].virt = ioremap(0x0, 0x04000000);
445 ipaq_map[0].bankwidth = 2;
447 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
448 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
449 if (!mymtd)
450 return -ENODEV;
451 add_mtd_device(mymtd);
452 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
454 return 0;
455 }
457 module_init(ipaq_mtd_init);
458 module_exit(ipaq_mtd_cleanup);
460 MODULE_AUTHOR("Jamey Hicks");
461 MODULE_DESCRIPTION("IPAQ CFI map driver");
462 MODULE_LICENSE("MIT");