abbf61f808e8d06fd5b9b9b2bc7f5436edc48981
[lede.git] / target / linux / olpc / patches / 100-olpc.patch
1 diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
2 index 97b64d7..92ceab7 100644
3 --- a/arch/i386/Kconfig
4 +++ b/arch/i386/Kconfig
5 @@ -796,6 +796,15 @@ config SECCOMP
6  
7           If unsure, say Y. Only embedded should say N here.
8  
9 +config VGA_NOPROBE
10 +       bool "Don't probe VGA at boot" if EMBEDDED
11 +       default n
12 +       help
13 +         Saying Y here will cause the kernel to not probe VGA at boot time.
14 +         This will break everything that depends on the probed screen
15 +         data.  Say N here unless you are absolutely sure this is what you
16 +         want.
17 +
18  source kernel/Kconfig.hz
19  
20  config KEXEC
21 @@ -1120,6 +1129,9 @@ config PCI_GODIRECT
22  config PCI_GOANY
23         bool "Any"
24  
25 +config PCI_GOOLPC
26 +       bool "OLPC"
27 +
28  endchoice
29  
30  config PCI_BIOS
31 @@ -1129,7 +1141,7 @@ config PCI_BIOS
32  
33  config PCI_DIRECT
34         bool
35 -       depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
36 +       depends on PCI && ((PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC) || X86_VISWS)
37         default y
38  
39  config PCI_MMCONFIG
40 @@ -1137,6 +1149,11 @@ config PCI_MMCONFIG
41         depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
42         default y
43  
44 +config PCI_OLPC
45 +       bool
46 +       depends on PCI && PCI_GOOLPC
47 +       default y
48 +
49  source "drivers/pci/pcie/Kconfig"
50  
51  source "drivers/pci/Kconfig"
52 @@ -1206,10 +1223,43 @@ config SCx200HR_TIMER
53           processor goes idle (as is done by the scheduler).  The
54           other workaround is idle=poll boot option.
55  
56 +config GEODE_MFGPT_TIMER
57 +       bool "Geode Multi-Function General Purpose Timer (mfgpt) Support"
58 +       depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS
59 +       default y
60 +       help
61 +         This driver provides a clock event source based on the MFGPT
62 +         timer(s) in the CS5535 and CS5536 companion chip for the geode.
63 +         MFGPTs have a better resolution and max interval than the
64 +         generic PIT, and are suitable for use as high-res timers.
65 +
66  config K8_NB
67         def_bool y
68         depends on AGP_AMD64
69  
70 +config OLPC
71 +       bool "OLPC Support"
72 +       default n
73 +       help
74 +         Add support for detecting the unique features of the OLPC 
75 +         Childrens Machine
76 +
77 +config OLPC_PM
78 +       tristate "OLPC power management support"
79 +       default y
80 +       depends on OLPC
81 +       help
82 +         Add support for the Geode power management facilities on the
83 +        OLPC Childrens Machine
84 +
85 +config OPEN_FIRMWARE
86 +       bool "Support for Open Firmware"
87 +       default y if OLPC
88 +       help
89 +         This option adds support for the implementation of Open Firmware
90 +         that is used on the OLPC Children's Machine.
91 +         If unsure, say N here.
92 +
93  source "drivers/pcmcia/Kconfig"
94  
95  source "drivers/pci/hotplug/Kconfig"
96 diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
97 index 9d33b00..2e2cf42 100644
98 --- a/arch/i386/kernel/Makefile
99 +++ b/arch/i386/kernel/Makefile
100 @@ -39,13 +39,17 @@ obj-$(CONFIG_VM86)          += vm86.o
101  obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
102  obj-$(CONFIG_HPET_TIMER)       += hpet.o
103  obj-$(CONFIG_K8_NB)            += k8.o
104 -obj-$(CONFIG_MGEODE_LX)                += geode.o
105 +obj-$(CONFIG_MGEODE_LX)                += geode.o mfgpt.o
106  
107  obj-$(CONFIG_VMI)              += vmi.o vmiclock.o
108  obj-$(CONFIG_PARAVIRT)         += paravirt.o
109  obj-y                          += pcspeaker.o
110  
111  obj-$(CONFIG_SCx200)           += scx200.o
112 +obj-$(CONFIG_OLPC)             += olpc.o
113 +obj-$(CONFIG_OLPC_PM)          += olpc-pm.o olpc-wakeup.o
114 +obj-$(CONFIG_OPEN_FIRMWARE)    += ofw.o
115 +obj-$(CONFIG_PROMFS_FS)                += prom.o
116  
117  # vsyscall.o contains the vsyscall DSO images as __initdata.
118  # We must build both images before we can assemble it.
119 diff --git a/arch/i386/kernel/geode.c b/arch/i386/kernel/geode.c
120 index 41e8aec..637e301 100644
121 --- a/arch/i386/kernel/geode.c
122 +++ b/arch/i386/kernel/geode.c
123 @@ -145,10 +145,14 @@ EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
124  
125  static int __init geode_southbridge_init(void)
126  {
127 +       int timers;
128 +
129         if (!is_geode())
130                 return -ENODEV;
131  
132         init_lbars();
133 +       timers = geode_mfgpt_detect();
134 +       printk(KERN_INFO "geode-mfgpt:  %d timers available.\n", timers);
135         return 0;
136  }
137  
138 diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
139 index 8f03821..3176280 100644
140 --- a/arch/i386/kernel/head.S
141 +++ b/arch/i386/kernel/head.S
142 @@ -117,8 +117,34 @@ ENTRY(startup_32)
143         movl $(COMMAND_LINE_SIZE/4),%ecx
144         rep
145         movsl
146 +
147 +#ifdef CONFIG_OPEN_FIRMWARE
148 +/*
149 + * If Open Firmware booted us, save the OFW client interface callback address
150 + * and preserve the OFW page mappings by priming the kernel's new page
151 + * directory area with a copy of the OFW page directory.  That lets OFW stay
152 + * resident in high memory (high in both the virtual and physical spaces)
153 + * for at least long enough to copy out the device tree.
154 + */
155  1:
156 +       movl $(boot_params - __PAGE_OFFSET + OFW_INFO_OFFSET), %ebp
157 +       cmpl $0x2057464F, (%ebp)        /* Magic number "OFW " */
158 +       jne 1f
159 +
160 +       mov 0x8(%ebp), %eax     /* Save callback address */
161 +       mov %eax, call_firmware - __PAGE_OFFSET
162  
163 +       /* Copy the OFW pdir into swapper_pg_dir */
164 +       movl %esi, %edx         /* save %esi */
165 +       movl $(swapper_pg_dir - __PAGE_OFFSET), %edi
166 +       movl %cr3, %esi         /* Source is current pg_dir base address */
167 +       movl $1024, %ecx        /* Number of page directory entries */
168 +       rep
169 +       movsl
170 +       movl %edx, %esi         /* restore %esi */
171 +#endif
172 +
173 +1:
174  /*
175   * Initialize page tables.  This creates a PDE and a set of page
176   * tables, which are located immediately beyond _end.  The variable
177 @@ -129,6 +155,7 @@ ENTRY(startup_32)
178   * Warning: don't use %esi or the stack in this code.  However, %esp
179   * can be used as a GPR if you really need it...
180   */
181 +
182  page_pde_offset = (__PAGE_OFFSET >> 20);
183  
184         movl $(pg0 - __PAGE_OFFSET), %edi
185         
186
187 diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
188 index d474cd6..c4b26ba 100644
189 --- a/arch/i386/kernel/setup.c
190 +++ b/arch/i386/kernel/setup.c
191 @@ -362,8 +362,10 @@ void __init zone_sizes_init(void)
192  {
193         unsigned long max_zone_pfns[MAX_NR_ZONES];
194         memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
195 +#ifdef CONFIG_ZONE_DMA
196         max_zone_pfns[ZONE_DMA] =
197                 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
198 +#endif
199         max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
200  #ifdef CONFIG_HIGHMEM
201         max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
202 @@ -428,6 +430,9 @@ void __init setup_bootmem_allocator(void)
203          */
204         acpi_reserve_bootmem();
205  #endif
206 +#ifdef CONFIG_OLPC_PM
207 +       reserve_bootmem(0xf0000, PAGE_SIZE);
208 +#endif
209  #ifdef CONFIG_X86_FIND_SMP_CONFIG
210         /*
211          * Find and reserve possible boot-time SMP configuration:
212 diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile
213 index 44650e0..1250a7b 100644
214 --- a/arch/i386/pci/Makefile
215 +++ b/arch/i386/pci/Makefile
216 @@ -3,6 +3,7 @@ obj-y                           := i386.o init.o
217  obj-$(CONFIG_PCI_BIOS)         += pcbios.o
218  obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig.o direct.o mmconfig-shared.o
219  obj-$(CONFIG_PCI_DIRECT)       += direct.o
220 +obj-$(CONFIG_PCI_OLPC)         += olpc.o
221  
222  pci-y                          := fixup.o
223  pci-$(CONFIG_ACPI)             += acpi.o
224 diff --git a/arch/i386/pci/init.c b/arch/i386/pci/init.c
225 index 3de9f9b..0f5f7dd 100644
226 --- a/arch/i386/pci/init.c
227 +++ b/arch/i386/pci/init.c
228 @@ -14,6 +14,9 @@ static __init int pci_access_init(void)
229  #ifdef CONFIG_PCI_MMCONFIG
230         pci_mmcfg_init(type);
231  #endif
232 +#ifdef CONFIG_PCI_OLPC
233 +       pci_olpc_init();
234 +#endif
235         if (raw_pci_ops)
236                 return 0;
237  #ifdef CONFIG_PCI_BIOS
238 diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
239 index 8c66f27..a67e617 100644
240 --- a/arch/i386/pci/pci.h
241 +++ b/arch/i386/pci/pci.h
242 @@ -93,6 +93,7 @@ extern void pci_direct_init(int type);
243  extern void pci_pcbios_init(void);
244  extern void pci_mmcfg_init(int type);
245  extern void pcibios_sort(void);
246 +extern void pci_olpc_init(void);
247  
248  /* pci-mmconfig.c */
249  
250 diff --git a/drivers/Makefile b/drivers/Makefile
251 index f0878b2..c033d30 100644
252 --- a/drivers/Makefile
253 +++ b/drivers/Makefile
254 @@ -23,6 +23,8 @@ obj-y                         += char/
255  
256  obj-$(CONFIG_CONNECTOR)                += connector/
257  
258 +obj-$(CONFIG_SYSPROF)          += sysprof/
259 +
260  # i810fb and intelfb depend on char/agp/
261  obj-$(CONFIG_FB_I810)           += video/i810/
262  obj-$(CONFIG_FB_INTEL)          += video/intelfb/
263 diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
264 index c6f6f42..55ae42c 100644
265 --- a/drivers/char/vt_ioctl.c
266 +++ b/drivers/char/vt_ioctl.c
267 @@ -37,6 +37,9 @@
268  char vt_dont_switch;
269  extern struct tty_driver *console_driver;
270  
271 +/* Add a notifier chain to inform drivers of a VT_TEXT/VT_GRAPHICS switch */
272 +RAW_NOTIFIER_HEAD(console_notifier_list);
273 +
274  #define VT_IS_IN_USE(i)        (console_driver->ttys[i] && console_driver->ttys[i]->count)
275  #define VT_BUSY(i)     (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
276  
277 @@ -491,6 +494,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
278                 vc->vc_mode = (unsigned char) arg;
279                 if (console != fg_console)
280                         return 0;
281 +
282 +               /* Notify listeners if the current fg_console has switched */
283 +
284 +               raw_notifier_call_chain(&console_notifier_list,
285 +                       (arg == KD_TEXT) ?
286 +                       CONSOLE_EVENT_SWITCH_TEXT :
287 +                       CONSOLE_EVENT_SWITCH_GRAPHICS, 0);
288 +
289                 /*
290                  * explicitly blank/unblank the screen if switching modes
291                  */
292 diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
293 index e6c4a2b..874d623 100644
294 --- a/drivers/i2c/busses/scx200_acb.c
295 +++ b/drivers/i2c/busses/scx200_acb.c
296 @@ -46,6 +46,10 @@ static int base[MAX_DEVICES] = { 0x820, 0x840 };
297  module_param_array(base, int, NULL, 0);
298  MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
299  
300 +static unsigned int smbclk = 0x70;
301 +module_param(smbclk, uint, 0);
302 +MODULE_PARM_DESC(smbclk, "Specify the SMB_CLK value");
303 +
304  #define POLL_TIMEOUT   (HZ/5)
305  
306  enum scx200_acb_state {
307 @@ -108,6 +112,7 @@ struct scx200_acb_iface {
308  #define ACBADDR                (iface->base + 4)
309  #define ACBCTL2                (iface->base + 5)
310  #define    ACBCTL2_ENABLE      0x01
311 +#define ACBCTL3        (iface->base + 6)
312  
313  /************************************************************************/
314  
315 @@ -392,11 +397,13 @@ static __init int scx200_acb_probe(struct scx200_acb_iface *iface)
316  {
317         u8 val;
318  
319 -       /* Disable the ACCESS.bus device and Configure the SCL
320 -          frequency: 16 clock cycles */
321 -       outb(0x70, ACBCTL2);
322 +       /* Disable the ACCESS.bus device and Configure the SCL */
323 +
324 +       outb((smbclk & 0x7F) << 1, ACBCTL2);
325 +
326 +       outb((smbclk >> 7) & 0xFF, ACBCTL3);
327  
328 -       if (inb(ACBCTL2) != 0x70) {
329 +       if (inb(ACBCTL2) != ((smbclk & 0x7F) << 1)) {
330                 pr_debug(NAME ": ACBCTL2 readback failed\n");
331                 return -ENXIO;
332         }
333 diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
334 index 41fc3d0..a15e7a9 100644
335 --- a/drivers/input/keyboard/atkbd.c
336 +++ b/drivers/input/keyboard/atkbd.c
337 @@ -63,12 +63,25 @@ static int atkbd_extra;
338  module_param_named(extra, atkbd_extra, bool, 0);
339  MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
340  
341 +#define ATKBD_KEY_UNKNOWN        0
342 +#define ATKBD_KEY_NULL         0xFF0000FF
343 +
344 +#define ATKBD_SCR_1            0xFF0000FE
345 +#define ATKBD_SCR_2            0xFF0000FD
346 +#define ATKBD_SCR_4            0xFF0000FC
347 +#define ATKBD_SCR_8            0xFF0000FB
348 +#define ATKBD_SCR_CLICK                0xFF0000FA
349 +#define ATKBD_SCR_LEFT         0xFF0000F9
350 +#define ATKBD_SCR_RIGHT                0xFF0000F8
351 +
352 +#define ATKBD_SPECIAL          0xFF0000F8
353 +
354  /*
355   * Scancode to keycode tables. These are just the default setting, and
356   * are loadable via an userland utility.
357   */
358  
359 -static unsigned char atkbd_set2_keycode[512] = {
360 +static unsigned int atkbd_set2_keycode[512] = {
361  
362  #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
363  
364 @@ -87,11 +100,17 @@ static unsigned char atkbd_set2_keycode[512] = {
365          82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
366  
367           0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
368 -       217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
369 +
370 +       217,100,ATKBD_KEY_NULL,  0, 97,165,  0,  0,
371 +       156,  0,  0,  0,  0,  0,  0,125,
372 +
373         173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
374         159,  0,115,  0,164,  0,  0,116,158,  0,172,166,  0,  0,  0,142,
375         157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
376 -       226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
377 +
378 +       226,  0,  0,  0,  0,  0,  0,  0,
379 +         0,ATKBD_KEY_NULL, 96,  0,  0,  0,143,  0,
380 +
381           0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
382         110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
383  
384 @@ -150,19 +169,6 @@ static unsigned char atkbd_unxlate_table[128] = {
385  #define ATKBD_RET_HANGEUL      0xf2
386  #define ATKBD_RET_ERR          0xff
387  
388 -#define ATKBD_KEY_UNKNOWN        0
389 -#define ATKBD_KEY_NULL         255
390 -
391 -#define ATKBD_SCR_1            254
392 -#define ATKBD_SCR_2            253
393 -#define ATKBD_SCR_4            252
394 -#define ATKBD_SCR_8            251
395 -#define ATKBD_SCR_CLICK                250
396 -#define ATKBD_SCR_LEFT         249
397 -#define ATKBD_SCR_RIGHT                248
398 -
399 -#define ATKBD_SPECIAL          248
400 -
401  #define ATKBD_LED_EVENT_BIT    0
402  #define ATKBD_REP_EVENT_BIT    1
403  
404 @@ -174,7 +180,7 @@ static unsigned char atkbd_unxlate_table[128] = {
405  #define ATKBD_XL_HANJA         0x20
406  
407  static struct {
408 -       unsigned char keycode;
409 +       unsigned int keycode;
410         unsigned char set2;
411  } atkbd_scroll_keys[] = {
412         { ATKBD_SCR_1,     0xc5 },
413 @@ -200,7 +206,7 @@ struct atkbd {
414         char phys[32];
415  
416         unsigned short id;
417 -       unsigned char keycode[512];
418 +       unsigned int keycode[512];
419         unsigned char set;
420         unsigned char translated;
421         unsigned char extra;
422 @@ -351,7 +357,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
423         unsigned int code = data;
424         int scroll = 0, hscroll = 0, click = -1, add_release_event = 0;
425         int value;
426 -       unsigned char keycode;
427 +       unsigned int keycode;
428  
429  #ifdef ATKBD_DEBUG
430         printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
431 @@ -856,9 +862,11 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
432                                                 atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j].keycode;
433                 }
434         } else if (atkbd->set == 3) {
435 -               memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
436 +               for (i = 0; i < ARRAY_SIZE(atkbd_set3_keycode); i++)
437 +                       atkbd->keycode[i] = atkbd_set3_keycode[i];
438         } else {
439 -               memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
440 +               for (i = 0; i < ARRAY_SIZE(atkbd_set2_keycode); i++)
441 +                       atkbd->keycode[i] = atkbd_set2_keycode[i];
442  
443                 if (atkbd->scroll)
444                         for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++)
445 @@ -925,8 +933,8 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
446         }
447  
448         input_dev->keycode = atkbd->keycode;
449 -       input_dev->keycodesize = sizeof(unsigned char);
450 -       input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
451 +       input_dev->keycodesize = sizeof(unsigned int);
452 +       input_dev->keycodemax = ARRAY_SIZE(atkbd->keycode);
453  
454         for (i = 0; i < 512; i++)
455                 if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
456 @@ -1017,6 +1025,10 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
457         return err;
458  }
459  
460 +#ifdef CONFIG_OLPC
461 +#include <asm/olpc.h>
462 +#endif
463 +
464  /*
465   * atkbd_reconnect() tries to restore keyboard into a sane state and is
466   * most likely called on resume.
467 @@ -1027,6 +1039,12 @@ static int atkbd_reconnect(struct serio *serio)
468         struct atkbd *atkbd = serio_get_drvdata(serio);
469         struct serio_driver *drv = serio->drv;
470  
471 +#ifdef CONFIG_OLPC
472 +       if (olpc_rev_after(OLPC_REV_B2))
473 +               if (serio->dev.power.power_state.event != PM_EVENT_ON)
474 +                       return 0;
475 +#endif
476 +
477         if (!atkbd || !drv) {
478                 printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
479                 return -1;
480 diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
481 index 7bbea09..6febbc5 100644
482 --- a/drivers/input/mouse/Kconfig
483 +++ b/drivers/input/mouse/Kconfig
484 @@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
485  
486           If unsure, say N.
487  
488 +config MOUSE_PS2_OLPC
489 +       bool "OLPC PS/2 mouse protocol extension" if EMBEDDED
490 +       default n
491 +       depends on MOUSE_PS2 && OLPC
492 +       ---help---
493 +         Say Y here if you have an OLPC PS/2 touchpad connected to
494 +         your system.
495 +
496 +         If unsure, say N.
497 +
498  config MOUSE_SERIAL
499         tristate "Serial mouse"
500         select SERIO
501 diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
502 index 9e6e363..f4654ce 100644
503 --- a/drivers/input/mouse/Makefile
504 +++ b/drivers/input/mouse/Makefile
505 @@ -24,3 +24,4 @@ psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
506  psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK)   += lifebook.o
507  psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
508  psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)   += touchkit_ps2.o
509 +psmouse-$(CONFIG_MOUSE_PS2_OLPC)       += olpc.o
510 diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
511 index b9f0fb2..edcdb68 100644
512 --- a/drivers/input/mouse/psmouse-base.c
513 +++ b/drivers/input/mouse/psmouse-base.c
514 @@ -26,6 +26,7 @@
515  #include "synaptics.h"
516  #include "logips2pp.h"
517  #include "alps.h"
518 +#include "olpc.h"
519  #include "lifebook.h"
520  #include "trackpoint.h"
521  #include "touchkit_ps2.h"
522 @@ -103,7 +104,7 @@ static struct attribute_group psmouse_attribute_group = {
523   */
524  static DEFINE_MUTEX(psmouse_mutex);
525  
526 -static struct workqueue_struct *kpsmoused_wq;
527 +struct workqueue_struct *kpsmoused_wq;
528  
529  struct psmouse_protocol {
530         enum psmouse_type type;
531 @@ -320,7 +321,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
532                         goto out;
533                 }
534  
535 -               if (psmouse->packet[1] == PSMOUSE_RET_ID) {
536 +               if (psmouse->packet[1] == PSMOUSE_RET_ID || psmouse->packet[1] == PSMOUSE_RET_BAT) {
537                         __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
538                         serio_reconnect(serio);
539                         goto out;
540 @@ -631,8 +632,21 @@ static int psmouse_extensions(struct psmouse *psmouse,
541                 }
542         }
543  
544 +/*
545 + * Try OLPC touchpad.
546 + */
547         if (max_proto > PSMOUSE_IMEX) {
548 +               if (olpc_detect(psmouse, set_properties) == 0) {
549 +                       if (!set_properties || olpc_init(psmouse) == 0)
550 +                               return PSMOUSE_OLPC;
551 +/*
552 + * Init failed, try basic relative protocols
553 + */
554 +                       max_proto = PSMOUSE_IMEX;
555 +               }
556 +       }
557  
558 +       if (max_proto > PSMOUSE_IMEX) {
559                 if (genius_detect(psmouse, set_properties) == 0)
560                         return PSMOUSE_GENPS;
561  
562 @@ -762,6 +776,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
563                 .detect         = touchkit_ps2_detect,
564         },
565  #endif
566 +#ifdef CONFIG_MOUSE_PS2_OLPC
567 +       {
568 +               .type           = PSMOUSE_OLPC,
569 +               .name           = "OLPC",
570 +               .alias          = "olpc",
571 +               .detect         = olpc_detect,
572 +       },
573 +#endif
574         {
575                 .type           = PSMOUSE_CORTRON,
576                 .name           = "CortronPS/2",
577 diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
578 index 1317bdd..c4857df 100644
579 --- a/drivers/input/mouse/psmouse.h
580 +++ b/drivers/input/mouse/psmouse.h
581 @@ -89,6 +89,7 @@ enum psmouse_type {
582         PSMOUSE_TRACKPOINT,
583         PSMOUSE_TOUCHKIT_PS2,
584         PSMOUSE_CORTRON,
585 +       PSMOUSE_OLPC,
586         PSMOUSE_AUTO            /* This one should always be last */
587  };
588  
589 @@ -96,6 +97,7 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
590  int psmouse_reset(struct psmouse *psmouse);
591  void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
592  
593 +extern struct workqueue_struct *kpsmoused_wq;
594  
595  struct psmouse_attribute {
596         struct device_attribute dattr;
597 diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
598 index c2eea27..3510726 100644
599 --- a/drivers/input/serio/i8042.c
600 +++ b/drivers/input/serio/i8042.c
601 @@ -868,6 +868,11 @@ static long i8042_panic_blink(long count)
602  #undef DELAY
603  
604  #ifdef CONFIG_PM
605 +
606 +#ifdef CONFIG_OLPC
607 +#include <asm/olpc.h>
608 +#endif
609 +
610  /*
611   * Here we try to restore the original BIOS settings. We only want to
612   * do that once, when we really suspend, not when we taking memory
613 @@ -878,8 +883,15 @@ static long i8042_panic_blink(long count)
614  static int i8042_suspend(struct platform_device *dev, pm_message_t state)
615  {
616         if (dev->dev.power.power_state.event != state.event) {
617 +#ifdef CONFIG_OLPC
618 +               /* Anything newer than B2 remains powered; no reset needed */
619 +               if (olpc_rev_before(OLPC_REV_PRE_B3)) {
620 +#endif
621                 if (state.event == PM_EVENT_SUSPEND)
622                         i8042_controller_reset();
623 +#ifdef CONFIG_OLPC
624 +               }
625 +#endif
626  
627                 dev->dev.power.power_state = state;
628         }
629 @@ -902,9 +914,15 @@ static int i8042_resume(struct platform_device *dev)
630         if (dev->dev.power.power_state.event == PM_EVENT_ON)
631                 return 0;
632  
633 +#ifdef CONFIG_OLPC
634 +       if (olpc_rev_before(OLPC_REV_PRE_B3)) {
635 +#endif
636         error = i8042_controller_check();
637         if (error)
638                 return error;
639 +#ifdef CONFIG_OLPC
640 +       }
641 +#endif
642  
643         error = i8042_controller_selftest();
644         if (error)
645 diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
646 index 372ca49..c9e5308 100644
647 --- a/drivers/input/serio/serio.c
648 +++ b/drivers/input/serio/serio.c
649 @@ -916,11 +916,22 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
650  #endif /* CONFIG_HOTPLUG */
651  
652  #ifdef CONFIG_PM
653 +
654 +#ifdef CONFIG_OLPC
655 +#include <asm/olpc.h>
656 +#endif
657 +
658  static int serio_suspend(struct device *dev, pm_message_t state)
659  {
660         if (dev->power.power_state.event != state.event) {
661 +#ifdef CONFIG_OLPC
662 +               if (olpc_rev_before(OLPC_REV_PRE_B3)) {
663 +#endif
664                 if (state.event == PM_EVENT_SUSPEND)
665                         serio_cleanup(to_serio_port(dev));
666 +#ifdef CONFIG_OLPC
667 +               }
668 +#endif
669  
670                 dev->power.power_state = state;
671         }
672 diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
673 index ef53618..47881d2 100644
674 --- a/drivers/media/video/cafe_ccic.c
675 +++ b/drivers/media/video/cafe_ccic.c
676 @@ -63,13 +63,13 @@ MODULE_SUPPORTED_DEVICE("Video");
677   */
678  
679  #define MAX_DMA_BUFS 3
680 -static int alloc_bufs_at_load = 0;
681 -module_param(alloc_bufs_at_load, bool, 0444);
682 -MODULE_PARM_DESC(alloc_bufs_at_load,
683 -               "Non-zero value causes DMA buffers to be allocated at module "
684 -               "load time.  This increases the chances of successfully getting "
685 -               "those buffers, but at the cost of nailing down the memory from "
686 -               "the outset.");
687 +static int alloc_bufs_at_read = 0;
688 +module_param(alloc_bufs_at_read, bool, 0444);
689 +MODULE_PARM_DESC(alloc_bufs_at_read,
690 +               "Non-zero value causes DMA buffers to be allocated when the "
691 +               "video capture device is read, rather than at module load "
692 +               "time.  This saves memory, but decreases the chances of "
693 +               "successfully getting those buffers.");
694  
695  static int n_dma_bufs = 3;
696  module_param(n_dma_bufs, uint, 0644);
697 @@ -370,6 +370,10 @@ static int cafe_smbus_write_data(struct cafe_camera *cam,
698         rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
699         cafe_reg_write(cam, REG_TWSIC1, rval);
700         spin_unlock_irqrestore(&cam->dev_lock, flags);
701 +       mdelay(2); /* It'll probably take about 900µs anyway, and the
702 +                     CAFÉ is apparently quite sensitive to being poked
703 +                     at this point. If we can work out precisely what's
704 +                     going on and reduce this delay, it would be nice. */
705  
706         /*
707          * Time to wait for the write to complete.  THIS IS A RACY
708 @@ -1503,7 +1507,7 @@ static int cafe_v4l_release(struct inode *inode, struct file *filp)
709         }
710         if (cam->users == 0) {
711                 cafe_ctlr_power_down(cam);
712 -               if (! alloc_bufs_at_load)
713 +               if (alloc_bufs_at_read)
714                         cafe_free_dma_bufs(cam);
715         }
716         mutex_unlock(&cam->s_mutex);
717 @@ -2162,7 +2166,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
718         /*
719          * If so requested, try to get our DMA buffers now.
720          */
721 -       if (alloc_bufs_at_load) {
722 +       if (!alloc_bufs_at_read) {
723                 if (cafe_alloc_dma_bufs(cam, 1))
724                         cam_warn(cam, "Unable to alloc DMA buffers at load"
725                                         " will try again later.");
726 diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
727 index 73e248f..f7afde3 100644
728 --- a/drivers/misc/Kconfig
729 +++ b/drivers/misc/Kconfig
730 @@ -202,5 +202,10 @@ config THINKPAD_ACPI_BAY
731  
732           If you are not sure, say Y here.
733  
734 +config EEPROM_93CX6
735 +       tristate "EEPROM 93CX6 support"
736 +       ---help---
737 +         This is a driver for the EEPROM chipsets 93c46 and 93c66.
738 +         The driver supports both read as well as write commands.
739  
740  endif # MISC_DEVICES
741 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
742 index 93fe2e5..e17eb8e 100644
743 --- a/drivers/mmc/card/block.c
744 +++ b/drivers/mmc/card/block.c
745 @@ -229,6 +229,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
746                 if (brq.data.blocks > card->host->max_blk_count)
747                         brq.data.blocks = card->host->max_blk_count;
748  
749 +               if (mmc_card_sd(card) && !card->host->ios.clock) {
750 +                       printk(KERN_ERR "%s: I/O to stopped card\n",
751 +                              req->rq_disk->disk_name);
752 +                       goto cmd_err;
753 +               }
754                 mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
755  
756                 /*
757 diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
758 index 20a7d89..9abbb58 100644
759 --- a/drivers/mmc/host/sdhci.c
760 +++ b/drivers/mmc/host/sdhci.c
761 @@ -411,6 +411,12 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
762                         break;
763         }
764  
765 +       /*
766 +        * There's an off-by-one error in the hw that we need to
767 +        * compensate for.
768 +        */
769 +       count++;
770 +
771         if (count >= 0xF) {
772                 printk(KERN_WARNING "%s: Too large timeout requested!\n",
773                         mmc_hostname(host->mmc));
774 @@ -676,19 +682,17 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
775         if (!(host->chip->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
776                 writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
777  
778 -       pwr = SDHCI_POWER_ON;
779 -
780         switch (1 << power) {
781         case MMC_VDD_165_195:
782 -               pwr |= SDHCI_POWER_180;
783 +               pwr = SDHCI_POWER_180;
784                 break;
785         case MMC_VDD_29_30:
786         case MMC_VDD_30_31:
787 -               pwr |= SDHCI_POWER_300;
788 +               pwr = SDHCI_POWER_300;
789                 break;
790         case MMC_VDD_32_33:
791         case MMC_VDD_33_34:
792 -               pwr |= SDHCI_POWER_330;
793 +               pwr = SDHCI_POWER_330;
794                 break;
795         default:
796                 BUG();
797 @@ -696,6 +700,10 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
798  
799         writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
800  
801 +       pwr |= SDHCI_POWER_ON;
802 +
803 +       writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
804 +
805  out:
806         host->power = power;
807  }
808 diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
809 index fbec8cd..8848e8a 100644
810 --- a/drivers/mtd/Kconfig
811 +++ b/drivers/mtd/Kconfig
812 @@ -278,6 +278,14 @@ config SSFDC
813           This enables read only access to SmartMedia formatted NAND
814           flash. You can mount it with FAT file system.
815  
816 +config MTD_OOPS
817 +       tristate "Log panic/oops to an MTD buffer"
818 +       depends on MTD
819 +       help
820 +         This enables panic and oops messages to be logged to a circular
821 +         buffer in a flash partition where it can be read back at some
822 +         later point.
823 +
824  source "drivers/mtd/chips/Kconfig"
825  
826  source "drivers/mtd/maps/Kconfig"
827 diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
828 index 6d958a4..7f0b04b 100644
829 --- a/drivers/mtd/Makefile
830 +++ b/drivers/mtd/Makefile
831 @@ -22,6 +22,7 @@ obj-$(CONFIG_NFTL)            += nftl.o
832  obj-$(CONFIG_INFTL)            += inftl.o
833  obj-$(CONFIG_RFD_FTL)          += rfd_ftl.o
834  obj-$(CONFIG_SSFDC)            += ssfdc.o
835 +obj-$(CONFIG_MTD_OOPS)         += mtdoops.o
836  
837  nftl-objs              := nftlcore.o nftlmount.o
838  inftl-objs             := inftlcore.o inftlmount.o
839 diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
840 index 2f19fa7..39eff9f 100644
841 --- a/drivers/mtd/chips/cfi_cmdset_0001.c
842 +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
843 @@ -526,7 +526,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
844         struct cfi_pri_intelext *extp = cfi->cmdset_priv;
845  
846         /*
847 -        * Probing of multi-partition flash ships.
848 +        * Probing of multi-partition flash chips.
849          *
850          * To support multiple partitions when available, we simply arrange
851          * for each of them to have their own flchip structure even if they
852 @@ -1780,7 +1780,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
853         return ret;
854  }
855  
856 -int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
857 +static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
858  {
859         unsigned long ofs, len;
860         int ret;
861 @@ -1930,7 +1930,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
862         printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
863                __FUNCTION__, ofs, len);
864         cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
865 -               ofs, len, 0);
866 +               ofs, len, NULL);
867  #endif
868  
869         ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
870 @@ -1940,7 +1940,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
871         printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
872                __FUNCTION__, ret);
873         cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
874 -               ofs, len, 0);
875 +               ofs, len, NULL);
876  #endif
877  
878         return ret;
879 @@ -1954,7 +1954,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
880         printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
881                __FUNCTION__, ofs, len);
882         cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
883 -               ofs, len, 0);
884 +               ofs, len, NULL);
885  #endif
886  
887         ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
888 @@ -1964,7 +1964,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
889         printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
890                __FUNCTION__, ret);
891         cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
892 -               ofs, len, 0);
893 +               ofs, len, NULL);
894  #endif
895  
896         return ret;
897 @@ -2255,7 +2255,7 @@ static void cfi_intelext_save_locks(struct mtd_info *mtd)
898                         adr = region->offset + block * len;
899  
900                         status = cfi_varsize_frob(mtd,
901 -                                       do_getlockstatus_oneblock, adr, len, 0);
902 +                                       do_getlockstatus_oneblock, adr, len, NULL);
903                         if (status)
904                                 set_bit(block, region->lockmap);
905                         else
906 diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
907 index 1f64458..389acc6 100644
908 --- a/drivers/mtd/chips/cfi_cmdset_0002.c
909 +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
910 @@ -1609,7 +1609,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
911  }
912  
913  
914 -int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
915 +static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
916  {
917         unsigned long ofs, len;
918         int ret;
919 diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
920 index 58e561e..593e9d6 100644
921 --- a/drivers/mtd/chips/jedec_probe.c
922 +++ b/drivers/mtd/chips/jedec_probe.c
923 @@ -70,6 +70,7 @@
924  
925  /* Fujitsu */
926  #define MBM29F040C     0x00A4
927 +#define MBM29F800BA    0x2258
928  #define MBM29LV650UE   0x22D7
929  #define MBM29LV320TE   0x22F6
930  #define MBM29LV320BE   0x22F9
931 @@ -129,6 +130,7 @@
932  #define LH28F640BF     0x00b0
933  
934  /* ST - www.st.com */
935 +#define M29F800AB      0x0058
936  #define M29W800DT      0x00D7
937  #define M29W800DB      0x005B
938  #define M29W160DT      0x22C4
939 @@ -646,6 +648,23 @@ static const struct amd_flash_info jedec_table[] = {
940                 }
941         }, {
942                 .mfr_id         = MANUFACTURER_FUJITSU,
943 +               .dev_id         = MBM29F800BA,
944 +               .name           = "Fujitsu MBM29F800BA",
945 +               .uaddr          = {
946 +                       [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
947 +                       [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
948 +               },
949 +               .DevSize        = SIZE_1MiB,
950 +               .CmdSet         = P_ID_AMD_STD,
951 +               .NumEraseRegions= 4,
952 +               .regions        = {
953 +                       ERASEINFO(0x04000,1),
954 +                       ERASEINFO(0x02000,2),
955 +                       ERASEINFO(0x08000,1),
956 +                       ERASEINFO(0x10000,15),
957 +               }
958 +       }, {
959 +               .mfr_id         = MANUFACTURER_FUJITSU,
960                 .dev_id         = MBM29LV650UE,
961                 .name           = "Fujitsu MBM29LV650UE",
962                 .uaddr          = {
963 @@ -1510,6 +1529,23 @@ static const struct amd_flash_info jedec_table[] = {
964                         ERASEINFO(0x1000,256)
965                 }
966  
967 +       }, {
968 +               .mfr_id         = MANUFACTURER_ST,
969 +               .dev_id         = M29F800AB,
970 +               .name           = "ST M29F800AB",
971 +               .uaddr          = {
972 +                       [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
973 +                       [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
974 +               },
975 +               .DevSize        = SIZE_1MiB,
976 +               .CmdSet         = P_ID_AMD_STD,
977 +               .NumEraseRegions= 4,
978 +               .regions        = {
979 +                       ERASEINFO(0x04000,1),
980 +                       ERASEINFO(0x02000,2),
981 +                       ERASEINFO(0x08000,1),
982 +                       ERASEINFO(0x10000,15),
983 +               }
984         }, {
985                 .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
986                 .dev_id         = M29W800DT,
987 diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
988 index ff642f8..b4ea64d 100644
989 --- a/drivers/mtd/devices/Kconfig
990 +++ b/drivers/mtd/devices/Kconfig
991 @@ -69,12 +69,21 @@ config MTD_DATAFLASH26
992           If you have such a board and such a DataFlash, say 'Y'.
993  
994  config MTD_M25P80
995 -       tristate "Support for M25 SPI Flash"
996 +       tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
997         depends on SPI_MASTER && EXPERIMENTAL
998         help
999 -         This enables access to ST M25P80 and similar SPI flash chips,
1000 -         used for program and data storage.  Set up your spi devices
1001 -         with the right board-specific platform data.
1002 +         This enables access to most modern SPI flash chips, used for
1003 +         program and data storage.   Series supported include Atmel AT26DF,
1004 +         Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X.  Other chips
1005 +         are supported as well.  See the driver source for the current list,
1006 +         or to add other chips.
1007 +
1008 +         Note that the original DataFlash chips (AT45 series, not AT26DF),
1009 +         need an entirely different driver.
1010 +
1011 +         Set up your spi devices with the right board-specific platform data,
1012 +         if you want to specify device partitioning or to use a device which
1013 +         doesn't support the JEDEC ID instruction.
1014  
1015  config MTD_SLRAM
1016         tristate "Uncached system RAM"
1017 diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
1018 index 78c2511..98df5bc 100644
1019 --- a/drivers/mtd/devices/m25p80.c
1020 +++ b/drivers/mtd/devices/m25p80.c
1021 @@ -1,5 +1,5 @@
1022  /*
1023 - * MTD SPI driver for ST M25Pxx flash chips
1024 + * MTD SPI driver for ST M25Pxx (and similar) serial flash chips
1025   *
1026   * Author: Mike Lavender, mike@steroidmicros.com
1027   *
1028 @@ -19,33 +19,32 @@
1029  #include <linux/module.h>
1030  #include <linux/device.h>
1031  #include <linux/interrupt.h>
1032 -#include <linux/interrupt.h>
1033 +#include <linux/mutex.h>
1034 +
1035  #include <linux/mtd/mtd.h>
1036  #include <linux/mtd/partitions.h>
1037 +
1038  #include <linux/spi/spi.h>
1039  #include <linux/spi/flash.h>
1040  
1041 -#include <asm/semaphore.h>
1042 -
1043 -
1044 -/* NOTE: AT 25F and SST 25LF series are very similar,
1045 - * but commands for sector erase and chip id differ...
1046 - */
1047  
1048  #define FLASH_PAGESIZE         256
1049  
1050  /* Flash opcodes. */
1051 -#define        OPCODE_WREN             6       /* Write enable */
1052 -#define        OPCODE_RDSR             5       /* Read status register */
1053 -#define        OPCODE_READ             3       /* Read data bytes */
1054 -#define        OPCODE_PP               2       /* Page program */
1055 -#define        OPCODE_SE               0xd8    /* Sector erase */
1056 -#define        OPCODE_RES              0xab    /* Read Electronic Signature */
1057 +#define        OPCODE_WREN             0x06    /* Write enable */
1058 +#define        OPCODE_RDSR             0x05    /* Read status register */
1059 +#define        OPCODE_READ             0x03    /* Read data bytes (low frequency) */
1060 +#define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
1061 +#define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
1062 +#define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
1063 +#define        OPCODE_BE_32K           0x52    /* Erase 32KiB block */
1064 +#define        OPCODE_SE               0xd8    /* Sector erase (usually 64KiB) */
1065  #define        OPCODE_RDID             0x9f    /* Read JEDEC ID */
1066  
1067  /* Status Register bits. */
1068  #define        SR_WIP                  1       /* Write in progress */
1069  #define        SR_WEL                  2       /* Write enable latch */
1070 +/* meaning of other SR_* bits may differ between vendors */
1071  #define        SR_BP0                  4       /* Block protect 0 */
1072  #define        SR_BP1                  8       /* Block protect 1 */
1073  #define        SR_BP2                  0x10    /* Block protect 2 */
1074 @@ -65,9 +64,10 @@
1075  
1076  struct m25p {
1077         struct spi_device       *spi;
1078 -       struct semaphore        lock;
1079 +       struct mutex            lock;
1080         struct mtd_info         mtd;
1081 -       unsigned                partitioned;
1082 +       unsigned                partitioned:1;
1083 +       u8                      erase_opcode;
1084         u8                      command[4];
1085  };
1086  
1087 @@ -150,8 +150,9 @@ static int wait_till_ready(struct m25p *flash)
1088   */
1089  static int erase_sector(struct m25p *flash, u32 offset)
1090  {
1091 -       DEBUG(MTD_DEBUG_LEVEL3, "%s: %s at 0x%08x\n", flash->spi->dev.bus_id,
1092 -                       __FUNCTION__, offset);
1093 +       DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
1094 +                       flash->spi->dev.bus_id, __FUNCTION__,
1095 +                       flash->mtd.erasesize / 1024, offset);
1096  
1097         /* Wait until finished previous write command. */
1098         if (wait_till_ready(flash))
1099 @@ -161,7 +162,7 @@ static int erase_sector(struct m25p *flash, u32 offset)
1100         write_enable(flash);
1101  
1102         /* Set up command buffer. */
1103 -       flash->command[0] = OPCODE_SE;
1104 +       flash->command[0] = flash->erase_opcode;
1105         flash->command[1] = offset >> 16;
1106         flash->command[2] = offset >> 8;
1107         flash->command[3] = offset;
1108 @@ -201,13 +202,17 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
1109         addr = instr->addr;
1110         len = instr->len;
1111  
1112 -       down(&flash->lock);
1113 +       mutex_lock(&flash->lock);
1114 +
1115 +       /* REVISIT in some cases we could speed up erasing large regions
1116 +        * by using OPCODE_SE instead of OPCODE_BE_4K
1117 +        */
1118  
1119         /* now erase those sectors */
1120         while (len) {
1121                 if (erase_sector(flash, addr)) {
1122                         instr->state = MTD_ERASE_FAILED;
1123 -                       up(&flash->lock);
1124 +                       mutex_unlock(&flash->lock);
1125                         return -EIO;
1126                 }
1127  
1128 @@ -215,7 +220,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
1129                 len -= mtd->erasesize;
1130         }
1131  
1132 -       up(&flash->lock);
1133 +       mutex_unlock(&flash->lock);
1134  
1135         instr->state = MTD_ERASE_DONE;
1136         mtd_erase_callback(instr);
1137 @@ -260,16 +265,19 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
1138         if (retlen)
1139                 *retlen = 0;
1140  
1141 -       down(&flash->lock);
1142 +       mutex_lock(&flash->lock);
1143  
1144         /* Wait till previous write/erase is done. */
1145         if (wait_till_ready(flash)) {
1146                 /* REVISIT status return?? */
1147 -               up(&flash->lock);
1148 +               mutex_unlock(&flash->lock);
1149                 return 1;
1150         }
1151  
1152 -       /* NOTE:  OPCODE_FAST_READ (if available) is faster... */
1153 +       /* FIXME switch to OPCODE_FAST_READ.  It's required for higher
1154 +        * clocks; and at this writing, every chip this driver handles
1155 +        * supports that opcode.
1156 +        */
1157  
1158         /* Set up the write data buffer. */
1159         flash->command[0] = OPCODE_READ;
1160 @@ -281,7 +289,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
1161  
1162         *retlen = m.actual_length - sizeof(flash->command);
1163  
1164 -       up(&flash->lock);
1165 +       mutex_unlock(&flash->lock);
1166  
1167         return 0;
1168  }
1169 @@ -323,7 +331,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
1170         t[1].tx_buf = buf;
1171         spi_message_add_tail(&t[1], &m);
1172  
1173 -       down(&flash->lock);
1174 +       mutex_lock(&flash->lock);
1175  
1176         /* Wait until finished previous write command. */
1177         if (wait_till_ready(flash))
1178 @@ -381,10 +389,10 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
1179                         if (retlen)
1180                                 *retlen += m.actual_length
1181                                         - sizeof(flash->command);
1182 -               }
1183 -       }
1184 +               }
1185 +       }
1186  
1187 -       up(&flash->lock);
1188 +       mutex_unlock(&flash->lock);
1189  
1190         return 0;
1191  }
1192 @@ -398,24 +406,118 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
1193  
1194  struct flash_info {
1195         char            *name;
1196 -       u8              id;
1197 -       u16             jedec_id;
1198 +
1199 +       /* JEDEC id zero means "no ID" (most older chips); otherwise it has
1200 +        * a high byte of zero plus three data bytes: the manufacturer id,
1201 +        * then a two byte device id.
1202 +        */
1203 +       u32             jedec_id;
1204 +
1205 +       /* The size listed here is what works with OPCODE_SE, which isn't
1206 +        * necessarily called a "sector" by the vendor.
1207 +        */
1208         unsigned        sector_size;
1209 -       unsigned        n_sectors;
1210 +       u16             n_sectors;
1211 +
1212 +       u16             flags;
1213 +#define        SECT_4K         0x01            /* OPCODE_BE_4K works uniformly */
1214  };
1215  
1216 +
1217 +/* NOTE: double check command sets and memory organization when you add
1218 + * more flash chips.  This current list focusses on newer chips, which
1219 + * have been converging on command sets which including JEDEC ID.
1220 + */
1221  static struct flash_info __devinitdata m25p_data [] = {
1222 -       /* REVISIT: fill in JEDEC ids, for parts that have them */
1223 -       { "m25p05", 0x05, 0x2010, 32 * 1024, 2 },
1224 -       { "m25p10", 0x10, 0x2011, 32 * 1024, 4 },
1225 -       { "m25p20", 0x11, 0x2012, 64 * 1024, 4 },
1226 -       { "m25p40", 0x12, 0x2013, 64 * 1024, 8 },
1227 -       { "m25p80", 0x13, 0x0000, 64 * 1024, 16 },
1228 -       { "m25p16", 0x14, 0x2015, 64 * 1024, 32 },
1229 -       { "m25p32", 0x15, 0x2016, 64 * 1024, 64 },
1230 -       { "m25p64", 0x16, 0x2017, 64 * 1024, 128 },
1231 +
1232 +       /* Atmel -- some are (confusingly) marketed as "DataFlash" */
1233 +       { "at25fs010",  0x1f6601, 32 * 1024, 4, SECT_4K, },
1234 +       { "at25fs040",  0x1f6604, 64 * 1024, 8, SECT_4K, },
1235 +
1236 +       { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
1237 +
1238 +       { "at26f004",   0x1f0400, 64 * 1024, 8, SECT_4K, },
1239 +       { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
1240 +       { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
1241 +       { "at26df321",  0x1f4701, 64 * 1024, 64, SECT_4K, },
1242 +
1243 +       /* Spansion -- single (large) sector size only, at least
1244 +        * for the chips listed here (without boot sectors).
1245 +        */
1246 +       { "s25sl004a", 0x010212, 64 * 1024, 8, },
1247 +       { "s25sl008a", 0x010213, 64 * 1024, 16, },
1248 +       { "s25sl016a", 0x010214, 64 * 1024, 32, },
1249 +       { "s25sl032a", 0x010215, 64 * 1024, 64, },
1250 +       { "s25sl064a", 0x010216, 64 * 1024, 128, },
1251 +
1252 +       /* SST -- large erase sizes are "overlays", "sectors" are 4K */
1253 +       { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
1254 +       { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
1255 +       { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
1256 +       { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
1257 +
1258 +       /* ST Microelectronics -- newer production may have feature updates */
1259 +       { "m25p05",  0x202010,  32 * 1024, 2, },
1260 +       { "m25p10",  0x202011,  32 * 1024, 4, },
1261 +       { "m25p20",  0x202012,  64 * 1024, 4, },
1262 +       { "m25p40",  0x202013,  64 * 1024, 8, },
1263 +       { "m25p80",         0,  64 * 1024, 16, },
1264 +       { "m25p16",  0x202015,  64 * 1024, 32, },
1265 +       { "m25p32",  0x202016,  64 * 1024, 64, },
1266 +       { "m25p64",  0x202017,  64 * 1024, 128, },
1267 +       { "m25p128", 0x202018, 256 * 1024, 64, },
1268 +
1269 +       { "m45pe80", 0x204014,  64 * 1024, 16, },
1270 +       { "m45pe16", 0x204015,  64 * 1024, 32, },
1271 +
1272 +       { "m25pe80", 0x208014,  64 * 1024, 16, },
1273 +       { "m25pe16", 0x208015,  64 * 1024, 32, SECT_4K, },
1274 +
1275 +       /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
1276 +       { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
1277 +       { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
1278 +       { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
1279 +       { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
1280 +       { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
1281 +       { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
1282 +       { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
1283  };
1284  
1285 +static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
1286 +{
1287 +       int                     tmp;
1288 +       u8                      code = OPCODE_RDID;
1289 +       u8                      id[3];
1290 +       u32                     jedec;
1291 +       struct flash_info       *info;
1292 +
1293 +       /* JEDEC also defines an optional "extended device information"
1294 +        * string for after vendor-specific data, after the three bytes
1295 +        * we use here.  Supporting some chips might require using it.
1296 +        */
1297 +       tmp = spi_write_then_read(spi, &code, 1, id, 3);
1298 +       if (tmp < 0) {
1299 +               DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
1300 +                       spi->dev.bus_id, tmp);
1301 +               return NULL;
1302 +       }
1303 +       jedec = id[0];
1304 +       jedec = jedec << 8;
1305 +       jedec |= id[1];
1306 +       jedec = jedec << 8;
1307 +       jedec |= id[2];
1308 +
1309 +       for (tmp = 0, info = m25p_data;
1310 +                       tmp < ARRAY_SIZE(m25p_data);
1311 +                       tmp++, info++) {
1312 +               if (info->jedec_id == jedec)
1313 +                       return info;
1314 +       }
1315 +       dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
1316 +       return NULL;
1317 +}
1318 +
1319 +
1320  /*
1321   * board specific setup should have ensured the SPI clock used here
1322   * matches what the READ command supports, at least until this driver
1323 @@ -429,37 +531,51 @@ static int __devinit m25p_probe(struct spi_device *spi)
1324         unsigned                        i;
1325  
1326         /* Platform data helps sort out which chip type we have, as
1327 -        * well as how this board partitions it.
1328 +        * well as how this board partitions it.  If we don't have
1329 +        * a chip ID, try the JEDEC id commands; they'll work for most
1330 +        * newer chips, even if we don't recognize the particular chip.
1331          */
1332         data = spi->dev.platform_data;
1333 -       if (!data || !data->type) {
1334 -               /* FIXME some chips can identify themselves with RES
1335 -                * or JEDEC get-id commands.  Try them ...
1336 -                */
1337 -               DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n",
1338 -                               spi->dev.bus_id);
1339 -               return -ENODEV;
1340 -       }
1341 +       if (data && data->type) {
1342 +               for (i = 0, info = m25p_data;
1343 +                               i < ARRAY_SIZE(m25p_data);
1344 +                               i++, info++) {
1345 +                       if (strcmp(data->type, info->name) == 0)
1346 +                               break;
1347 +               }
1348  
1349 -       for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) {
1350 -               if (strcmp(data->type, info->name) == 0)
1351 -                       break;
1352 -       }
1353 -       if (i == ARRAY_SIZE(m25p_data)) {
1354 -               DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n",
1355 -                               spi->dev.bus_id, data->type);
1356 +               /* unrecognized chip? */
1357 +               if (i == ARRAY_SIZE(m25p_data)) {
1358 +                       DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
1359 +                                       spi->dev.bus_id, data->type);
1360 +                       info = NULL;
1361 +
1362 +               /* recognized; is that chip really what's there? */
1363 +               } else if (info->jedec_id) {
1364 +                       struct flash_info       *chip = jedec_probe(spi);
1365 +
1366 +                       if (!chip || chip != info) {
1367 +                               dev_warn(&spi->dev, "found %s, expected %s\n",
1368 +                                               chip ? chip->name : "UNKNOWN",
1369 +                                               info->name);
1370 +                               info = NULL;
1371 +                       }
1372 +               }
1373 +       } else
1374 +               info = jedec_probe(spi);
1375 +
1376 +       if (!info)
1377                 return -ENODEV;
1378 -       }
1379  
1380         flash = kzalloc(sizeof *flash, GFP_KERNEL);
1381         if (!flash)
1382                 return -ENOMEM;
1383  
1384         flash->spi = spi;
1385 -       init_MUTEX(&flash->lock);
1386 +       mutex_init(&flash->lock);
1387         dev_set_drvdata(&spi->dev, flash);
1388  
1389 -       if (data->name)
1390 +       if (data && data->name)
1391                 flash->mtd.name = data->name;
1392         else
1393                 flash->mtd.name = spi->dev.bus_id;
1394 @@ -468,17 +584,25 @@ static int __devinit m25p_probe(struct spi_device *spi)
1395         flash->mtd.writesize = 1;
1396         flash->mtd.flags = MTD_CAP_NORFLASH;
1397         flash->mtd.size = info->sector_size * info->n_sectors;
1398 -       flash->mtd.erasesize = info->sector_size;
1399         flash->mtd.erase = m25p80_erase;
1400         flash->mtd.read = m25p80_read;
1401         flash->mtd.write = m25p80_write;
1402  
1403 +       /* prefer "small sector" erase if possible */
1404 +       if (info->flags & SECT_4K) {
1405 +               flash->erase_opcode = OPCODE_BE_4K;
1406 +               flash->mtd.erasesize = 4096;
1407 +       } else {
1408 +               flash->erase_opcode = OPCODE_SE;
1409 +               flash->mtd.erasesize = info->sector_size;
1410 +       }
1411 +
1412         dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
1413                         flash->mtd.size / 1024);
1414  
1415         DEBUG(MTD_DEBUG_LEVEL2,
1416 -               "mtd .name = %s, .size = 0x%.8x (%uM) "
1417 -                       ".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n",
1418 +               "mtd .name = %s, .size = 0x%.8x (%uMiB) "
1419 +                       ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
1420                 flash->mtd.name,
1421                 flash->mtd.size, flash->mtd.size / (1024*1024),
1422                 flash->mtd.erasesize, flash->mtd.erasesize / 1024,
1423 @@ -488,7 +612,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
1424                 for (i = 0; i < flash->mtd.numeraseregions; i++)
1425                         DEBUG(MTD_DEBUG_LEVEL2,
1426                                 "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
1427 -                               ".erasesize = 0x%.8x (%uK), "
1428 +                               ".erasesize = 0x%.8x (%uKiB), "
1429                                 ".numblocks = %d }\n",
1430                                 i, flash->mtd.eraseregions[i].offset,
1431                                 flash->mtd.eraseregions[i].erasesize,
1432 @@ -516,14 +640,14 @@ static int __devinit m25p_probe(struct spi_device *spi)
1433                 }
1434  
1435                 if (nr_parts > 0) {
1436 -                       for (i = 0; i < data->nr_parts; i++) {
1437 +                       for (i = 0; i < nr_parts; i++) {
1438                                 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
1439                                         "{.name = %s, .offset = 0x%.8x, "
1440 -                                               ".size = 0x%.8x (%uK) }\n",
1441 -                                       i, data->parts[i].name,
1442 -                                       data->parts[i].offset,
1443 -                                       data->parts[i].size,
1444 -                                       data->parts[i].size / 1024);
1445 +                                               ".size = 0x%.8x (%uKiB) }\n",
1446 +                                       i, parts[i].name,
1447 +                                       parts[i].offset,
1448 +                                       parts[i].size,
1449 +                                       parts[i].size / 1024);
1450                         }
1451                         flash->partitioned = 1;
1452                         return add_mtd_partitions(&flash->mtd, parts, nr_parts);
1453 @@ -560,6 +684,11 @@ static struct spi_driver m25p80_driver = {
1454         },
1455         .probe  = m25p_probe,
1456         .remove = __devexit_p(m25p_remove),
1457 +
1458 +       /* REVISIT: many of these chips have deep power-down modes, which
1459 +        * should clearly be entered on suspend() to minimize power use.
1460 +        * And also when they're otherwise idle...
1461 +        */
1462  };
1463  
1464  
1465 diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
1466 index a987e91..a5ed6d2 100644
1467 --- a/drivers/mtd/devices/mtd_dataflash.c
1468 +++ b/drivers/mtd/devices/mtd_dataflash.c
1469 @@ -14,6 +14,7 @@
1470  #include <linux/slab.h>
1471  #include <linux/delay.h>
1472  #include <linux/device.h>
1473 +#include <linux/mutex.h>
1474  #include <linux/spi/spi.h>
1475  #include <linux/spi/flash.h>
1476  
1477 @@ -89,7 +90,7 @@ struct dataflash {
1478         unsigned short          page_offset;    /* offset in flash address */
1479         unsigned int            page_size;      /* of bytes per page */
1480  
1481 -       struct semaphore        lock;
1482 +       struct mutex            lock;
1483         struct spi_device       *spi;
1484  
1485         struct mtd_info         mtd;
1486 @@ -167,7 +168,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
1487         x.len = 4;
1488         spi_message_add_tail(&x, &msg);
1489  
1490 -       down(&priv->lock);
1491 +       mutex_lock(&priv->lock);
1492         while (instr->len > 0) {
1493                 unsigned int    pageaddr;
1494                 int             status;
1495 @@ -210,7 +211,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
1496                         instr->len -= priv->page_size;
1497                 }
1498         }
1499 -       up(&priv->lock);
1500 +       mutex_unlock(&priv->lock);
1501  
1502         /* Inform MTD subsystem that erase is complete */
1503         instr->state = MTD_ERASE_DONE;
1504 @@ -266,7 +267,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
1505         x[1].len = len;
1506         spi_message_add_tail(&x[1], &msg);
1507  
1508 -       down(&priv->lock);
1509 +       mutex_lock(&priv->lock);
1510  
1511         /* Continuous read, max clock = f(car) which may be less than
1512          * the peak rate available.  Some chips support commands with
1513 @@ -279,7 +280,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
1514         /* plus 4 "don't care" bytes */
1515  
1516         status = spi_sync(priv->spi, &msg);
1517 -       up(&priv->lock);
1518 +       mutex_unlock(&priv->lock);
1519  
1520         if (status >= 0) {
1521                 *retlen = msg.actual_length - 8;
1522 @@ -336,7 +337,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
1523         else
1524                 writelen = len;
1525  
1526 -       down(&priv->lock);
1527 +       mutex_lock(&priv->lock);
1528         while (remaining > 0) {
1529                 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
1530                         pageaddr, offset, writelen);
1531 @@ -441,7 +442,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
1532                 else
1533                         writelen = remaining;
1534         }
1535 -       up(&priv->lock);
1536 +       mutex_unlock(&priv->lock);
1537  
1538         return status;
1539  }
1540 @@ -463,7 +464,7 @@ add_dataflash(struct spi_device *spi, char *name,
1541         if (!priv)
1542                 return -ENOMEM;
1543  
1544 -       init_MUTEX(&priv->lock);
1545 +       mutex_init(&priv->lock);
1546         priv->spi = spi;
1547         priv->page_size = pagesize;
1548         priv->page_offset = pageoffset;
1549 diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
1550 index e8f686f..7060a08 100644
1551 --- a/drivers/mtd/devices/pmc551.c
1552 +++ b/drivers/mtd/devices/pmc551.c
1553 @@ -30,8 +30,8 @@
1554   *
1555   * Notes:
1556   *     Due to what I assume is more buggy SROM, the 64M PMC551 I
1557 - *     have available claims that all 4 of it's DRAM banks have 64M
1558 - *     of ram configured (making a grand total of 256M onboard).
1559 + *     have available claims that all 4 of its DRAM banks have 64MiB
1560 + *     of ram configured (making a grand total of 256MiB onboard).
1561   *     This is slightly annoying since the BAR0 size reflects the
1562   *     aperture size, not the dram size, and the V370PDC supplies no
1563   *     other method for memory size discovery.  This problem is
1564 @@ -70,7 +70,7 @@
1565   *      made the memory unusable, added a fix to code to touch up
1566   *      the DRAM some.
1567   *
1568 - * Bugs/FIXME's:
1569 + * Bugs/FIXMEs:
1570   *     * MUST fix the init function to not spin on a register
1571   *     waiting for it to set .. this does not safely handle busted
1572   *     devices that never reset the register correctly which will
1573 @@ -562,10 +562,10 @@ static u32 fixup_pmc551(struct pci_dev *dev)
1574         /*
1575          * Some screen fun
1576          */
1577 -       printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at "
1578 +       printk(KERN_DEBUG "pmc551: %d%sB (0x%x) of %sprefetchable memory at "
1579                 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ?
1580                 size >> 10 : size >> 20,
1581 -               (size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size,
1582 +               (size < 1024) ? "" : (size < 1048576) ? "Ki" : "Mi", size,
1583                 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "",
1584                 (unsigned long long)pci_resource_start(dev, 0));
1585  
1586 @@ -649,14 +649,10 @@ MODULE_DESCRIPTION(PMC551_VERSION);
1587   * Stuff these outside the ifdef so as to not bust compiled in driver support
1588   */
1589  static int msize = 0;
1590 -#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
1591 -static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE;
1592 -#else
1593  static int asize = 0;
1594 -#endif
1595  
1596  module_param(msize, int, 0);
1597 -MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]");
1598 +MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]");
1599  module_param(asize, int, 0);
1600  MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
1601  
1602 @@ -799,8 +795,7 @@ static int __init init_pmc551(void)
1603                 mtd->owner = THIS_MODULE;
1604  
1605                 if (add_mtd_device(mtd)) {
1606 -                       printk(KERN_NOTICE "pmc551: Failed to register new "
1607 -                               "device\n");
1608 +                       printk(KERN_NOTICE "pmc551: Failed to register new device\n");
1609                         pci_iounmap(PCI_Device, priv->start);
1610                         kfree(mtd->priv);
1611                         kfree(mtd);
1612 @@ -811,13 +806,13 @@ static int __init init_pmc551(void)
1613                 pci_dev_get(PCI_Device);
1614  
1615                 printk(KERN_NOTICE "Registered pmc551 memory device.\n");
1616 -               printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
1617 +               printk(KERN_NOTICE "Mapped %dMiB of memory from 0x%p to 0x%p\n",
1618                         priv->asize >> 20,
1619                         priv->start, priv->start + priv->asize);
1620 -               printk(KERN_NOTICE "Total memory is %d%c\n",
1621 +               printk(KERN_NOTICE "Total memory is %d%sB\n",
1622                         (length < 1024) ? length :
1623                         (length < 1048576) ? length >> 10 : length >> 20,
1624 -                       (length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M');
1625 +                       (length < 1024) ? "" : (length < 1048576) ? "Ki" : "Mi");
1626                 priv->nextpmc551 = pmc551list;
1627                 pmc551list = mtd;
1628                 found++;
1629 @@ -850,7 +845,7 @@ static void __exit cleanup_pmc551(void)
1630                 pmc551list = priv->nextpmc551;
1631  
1632                 if (priv->start) {
1633 -                       printk(KERN_DEBUG "pmc551: unmapping %dM starting at "
1634 +                       printk(KERN_DEBUG "pmc551: unmapping %dMiB starting at "
1635                                 "0x%p\n", priv->asize >> 20, priv->start);
1636                         pci_iounmap(priv->dev, priv->start);
1637                 }
1638 diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
1639 index 7b96cd0..0c9b305 100644
1640 --- a/drivers/mtd/maps/nettel.c
1641 +++ b/drivers/mtd/maps/nettel.c
1642 @@ -158,68 +158,11 @@ static struct notifier_block nettel_notifier_block = {
1643         nettel_reboot_notifier, NULL, 0
1644  };
1645  
1646 -/*
1647 - *     Erase the configuration file system.
1648 - *     Used to support the software reset button.
1649 - */
1650 -static void nettel_erasecallback(struct erase_info *done)
1651 -{
1652 -       wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
1653 -       wake_up(wait_q);
1654 -}
1655 -
1656 -static struct erase_info nettel_erase;
1657 -
1658 -int nettel_eraseconfig(void)
1659 -{
1660 -       struct mtd_info *mtd;
1661 -       DECLARE_WAITQUEUE(wait, current);
1662 -       wait_queue_head_t wait_q;
1663 -       int ret;
1664 -
1665 -       init_waitqueue_head(&wait_q);
1666 -       mtd = get_mtd_device(NULL, 2);
1667 -       if (!IS_ERR(mtd)) {
1668 -               nettel_erase.mtd = mtd;
1669 -               nettel_erase.callback = nettel_erasecallback;
1670 -               nettel_erase.callback = NULL;
1671 -               nettel_erase.addr = 0;
1672 -               nettel_erase.len = mtd->size;
1673 -               nettel_erase.priv = (u_long) &wait_q;
1674 -               nettel_erase.priv = 0;
1675 -
1676 -               set_current_state(TASK_INTERRUPTIBLE);
1677 -               add_wait_queue(&wait_q, &wait);
1678 -
1679 -               ret = mtd->erase(mtd, &nettel_erase);
1680 -               if (ret) {
1681 -                       set_current_state(TASK_RUNNING);
1682 -                       remove_wait_queue(&wait_q, &wait);
1683 -                       put_mtd_device(mtd);
1684 -                       return(ret);
1685 -               }
1686 -
1687 -               schedule();  /* Wait for erase to finish. */
1688 -               remove_wait_queue(&wait_q, &wait);
1689 -
1690 -               put_mtd_device(mtd);
1691 -       }
1692 -
1693 -       return(0);
1694 -}
1695 -
1696 -#else
1697 -
1698 -int nettel_eraseconfig(void)
1699 -{
1700 -       return(0);
1701 -}
1702 -
1703  #endif
1704  
1705  /****************************************************************************/
1706  
1707 -int __init nettel_init(void)
1708 +static int __init nettel_init(void)
1709  {
1710         volatile unsigned long *amdpar;
1711         unsigned long amdaddr, maxsize;
1712 @@ -421,10 +364,6 @@ int __init nettel_init(void)
1713  
1714         intel_mtd->owner = THIS_MODULE;
1715  
1716 -#ifndef CONFIG_BLK_DEV_INITRD
1717 -       ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
1718 -#endif
1719 -
1720         num_intel_partitions = sizeof(nettel_intel_partitions) /
1721                 sizeof(nettel_intel_partitions[0]);
1722  
1723 @@ -477,7 +416,7 @@ out_unmap2:
1724  
1725  /****************************************************************************/
1726  
1727 -void __exit nettel_cleanup(void)
1728 +static void __exit nettel_cleanup(void)
1729  {
1730  #ifdef CONFIG_MTD_CFI_INTELEXT
1731         unregister_reboot_notifier(&nettel_notifier_block);
1732 diff --git a/drivers/mtd/maps/pmcmsp-ramroot.c b/drivers/mtd/maps/pmcmsp-ramroot.c
1733 index 18049bc..30de5c0 100644
1734 --- a/drivers/mtd/maps/pmcmsp-ramroot.c
1735 +++ b/drivers/mtd/maps/pmcmsp-ramroot.c
1736 @@ -79,7 +79,6 @@ static int __init init_rrmap(void)
1737                 rr_mtd->owner = THIS_MODULE;
1738  
1739                 add_mtd_device(rr_mtd);
1740 -               ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, rr_mtd->index);
1741  
1742                 return 0;
1743         }
1744 diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
1745 index ef89780..74d9d30 100644
1746 --- a/drivers/mtd/mtd_blkdevs.c
1747 +++ b/drivers/mtd/mtd_blkdevs.c
1748 @@ -24,10 +24,9 @@
1749  #include <linux/kthread.h>
1750  #include <asm/uaccess.h>
1751  
1752 -static LIST_HEAD(blktrans_majors);
1753 +#include "mtdcore.h"
1754  
1755 -extern struct mutex mtd_table_mutex;
1756 -extern struct mtd_info *mtd_table[];
1757 +static LIST_HEAD(blktrans_majors);
1758  
1759  struct mtd_blkcore_priv {
1760         struct task_struct *thread;
1761 @@ -202,7 +201,7 @@ static int blktrans_ioctl(struct inode *inode, struct file *file,
1762         }
1763  }
1764  
1765 -struct block_device_operations mtd_blktrans_ops = {
1766 +static struct block_device_operations mtd_blktrans_ops = {
1767         .owner          = THIS_MODULE,
1768         .open           = blktrans_open,
1769         .release        = blktrans_release,
1770 diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
1771 index d091b24..22ed96c 100644
1772 --- a/drivers/mtd/mtdchar.c
1773 +++ b/drivers/mtd/mtdchar.c
1774 @@ -136,7 +136,8 @@ static int mtd_close(struct inode *inode, struct file *file)
1775  
1776         DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
1777  
1778 -       if (mtd->sync)
1779 +       /* Only sync if opened RW */
1780 +       if ((file->f_mode & 2) && mtd->sync)
1781                 mtd->sync(mtd);
1782  
1783         put_mtd_device(mtd);
1784 diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
1785 index c153b64..6c2645e 100644
1786 --- a/drivers/mtd/mtdcore.c
1787 +++ b/drivers/mtd/mtdcore.c
1788 @@ -22,6 +22,8 @@
1789  
1790  #include <linux/mtd/mtd.h>
1791  
1792 +#include "mtdcore.h"
1793 +
1794  /* These are exported solely for the purpose of mtd_blkdevs.c. You
1795     should not use them for _anything_ else */
1796  DEFINE_MUTEX(mtd_table_mutex);
1797 diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
1798 index f1d60b6..df25cab 100644
1799 --- a/drivers/mtd/nand/Kconfig
1800 +++ b/drivers/mtd/nand/Kconfig
1801 @@ -134,10 +134,10 @@ config MTD_NAND_S3C2410_HWECC
1802  
1803  config MTD_NAND_NDFC
1804         tristate "NDFC NanD Flash Controller"
1805 -       depends on 44x
1806 +       depends on 4xx
1807         select MTD_NAND_ECC_SMC
1808         help
1809 -        NDFC Nand Flash Controllers are integrated in EP44x SoCs
1810 +        NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
1811  
1812  config MTD_NAND_S3C2410_CLKSTOP
1813         bool "S3C2410 NAND IDLE clock stop"
1814 @@ -237,7 +237,7 @@ config MTD_NAND_CAFE
1815         select REED_SOLOMON
1816         select REED_SOLOMON_DEC16
1817         help
1818 -         Use NAND flash attached to the CAFÉ chip designed for the $100
1819 +         Use NAND flash attached to the CAFÉ chip designed for the OLPC
1820           laptop.
1821  
1822  config MTD_NAND_CS553X
1823 diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
1824 index cff969d..cca69b3 100644
1825 --- a/drivers/mtd/nand/cafe_nand.c
1826 +++ b/drivers/mtd/nand/cafe_nand.c
1827 @@ -821,14 +821,53 @@ static struct pci_device_id cafe_nand_tbl[] = {
1828  
1829  MODULE_DEVICE_TABLE(pci, cafe_nand_tbl);
1830  
1831 +static int cafe_nand_resume(struct pci_dev *pdev)
1832 +{
1833 +       uint32_t timing1, timing2, timing3;
1834 +       uint32_t ctrl;
1835 +       struct mtd_info *mtd = pci_get_drvdata(pdev);
1836 +       struct cafe_priv *cafe = mtd->priv;
1837 +
1838 +       timing1 = timing2 = timing3 = 0xffffffff;
1839 +       /* Start off by resetting the NAND controller completely */
1840 +       cafe_writel(cafe, 1, NAND_RESET);
1841 +       cafe_writel(cafe, 0, NAND_RESET);
1842 +       cafe_writel(cafe, timing1, NAND_TIMING1);
1843 +       cafe_writel(cafe, timing2, NAND_TIMING2);
1844 +       cafe_writel(cafe, timing3, NAND_TIMING3);
1845 +       cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
1846 +
1847 +        /* Disable master reset, enable NAND clock */
1848 +       ctrl = cafe_readl(cafe, GLOBAL_CTRL);
1849 +       ctrl &= 0xffffeff0;
1850 +       ctrl |= 0x00007000;
1851 +       cafe_writel(cafe, ctrl | 0x05, GLOBAL_CTRL);
1852 +       cafe_writel(cafe, ctrl | 0x0a, GLOBAL_CTRL);
1853 +       cafe_writel(cafe, 0, NAND_DMA_CTRL);
1854 +       cafe_writel(cafe, 0x7006, GLOBAL_CTRL);
1855 +       cafe_writel(cafe, 0x700a, GLOBAL_CTRL);
1856 +
1857 +       /* Set up DMA address */
1858 +       cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0);
1859 +       if (sizeof(cafe->dmaaddr) > 4)
1860 +       /* Shift in two parts to shut the compiler up */
1861 +               cafe_writel(cafe, (cafe->dmaaddr >> 16) >> 16, NAND_DMA_ADDR1);
1862 +       else
1863 +               cafe_writel(cafe, 0, NAND_DMA_ADDR1);
1864 +
1865 +       /* Enable NAND IRQ in global IRQ mask register */
1866 +       cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
1867 +       return 0;
1868 +}
1869 +
1870  static struct pci_driver cafe_nand_pci_driver = {
1871         .name = "CAFÉ NAND",
1872         .id_table = cafe_nand_tbl,
1873         .probe = cafe_nand_probe,
1874         .remove = __devexit_p(cafe_nand_remove),
1875 +       .resume = cafe_nand_resume,
1876  #ifdef CONFIG_PMx
1877         .suspend = cafe_nand_suspend,
1878 -       .resume = cafe_nand_resume,
1879  #endif
1880  };
1881  
1882 diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
1883 index fd7a8d5..1c0e89f 100644
1884 --- a/drivers/mtd/nand/ndfc.c
1885 +++ b/drivers/mtd/nand/ndfc.c
1886 @@ -24,7 +24,11 @@
1887  #include <linux/platform_device.h>
1888  
1889  #include <asm/io.h>
1890 +#ifdef CONFIG_40x
1891 +#include <asm/ibm405.h>
1892 +#else
1893  #include <asm/ibm44x.h>
1894 +#endif
1895  
1896  struct ndfc_nand_mtd {
1897         struct mtd_info                 mtd;
1898 @@ -230,7 +234,11 @@ static int ndfc_nand_probe(struct platform_device *pdev)
1899         struct ndfc_controller *ndfc = &ndfc_ctrl;
1900         unsigned long long phys = settings->ndfc_erpn | res->start;
1901  
1902 +#ifndef CONFIG_PHYS_64BIT
1903 +       ndfc->ndfcbase = ioremap((phys_addr_t)phys, res->end - res->start + 1);
1904 +#else
1905         ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
1906 +#endif
1907         if (!ndfc->ndfcbase) {
1908                 printk(KERN_ERR "NDFC: ioremap failed\n");
1909                 return -EIO;
1910 diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
1911 index c257d39..cb41cbc 100644
1912 --- a/drivers/mtd/onenand/Kconfig
1913 +++ b/drivers/mtd/onenand/Kconfig
1914 @@ -40,4 +40,27 @@ config MTD_ONENAND_OTP
1915  
1916           OTP block is fully-guaranteed to be a valid block.
1917  
1918 +config MTD_ONENAND_2X_PROGRAM
1919 +       bool "OneNAND 2X program support"
1920 +       help
1921 +         The 2X Program is an extension of Program Operation.
1922 +         Since the device is equipped with two DataRAMs, and two-plane NAND
1923 +         Flash memory array, these two component enables simultaneous program
1924 +         of 4KiB. Plane1 has only even blocks such as block0, block2, block4
1925 +         while Plane2 has only odd blocks such as block1, block3, block5.
1926 +         So MTD regards it as 4KiB page size and 256KiB block size
1927 +
1928 +         Now the following chips support it. (KFXXX16Q2M)
1929 +           Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
1930 +           Mux:   KFM2G16Q2M, KFN4G16Q2M,
1931 +
1932 +         And more recent chips
1933 +
1934 +config MTD_ONENAND_SIM
1935 +       tristate "OneNAND simulator support"
1936 +       depends on MTD_PARTITIONS
1937 +       help
1938 +         The simulator may simulate various OneNAND flash chips for the
1939 +         OneNAND MTD layer.
1940 +
1941  endif # MTD_ONENAND
1942 diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
1943 index 269cfe4..4d2eacf 100644
1944 --- a/drivers/mtd/onenand/Makefile
1945 +++ b/drivers/mtd/onenand/Makefile
1946 @@ -8,4 +8,7 @@ obj-$(CONFIG_MTD_ONENAND)               += onenand.o
1947  # Board specific.
1948  obj-$(CONFIG_MTD_ONENAND_GENERIC)      += generic.o
1949  
1950 +# Simulator
1951 +obj-$(CONFIG_MTD_ONENAND_SIM)          += onenand_sim.o
1952 +
1953  onenand-objs = onenand_base.o onenand_bbt.o
1954 diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
1955 index 0537fac..7d194cf 100644
1956 --- a/drivers/mtd/onenand/onenand_base.c
1957 +++ b/drivers/mtd/onenand/onenand_base.c
1958 @@ -206,6 +206,15 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
1959         default:
1960                 block = (int) (addr >> this->erase_shift);
1961                 page = (int) (addr >> this->page_shift);
1962 +
1963 +               if (ONENAND_IS_2PLANE(this)) {
1964 +                       /* Make the even block number */
1965 +                       block &= ~1;
1966 +                       /* Is it the odd plane? */
1967 +                       if (addr & this->writesize)
1968 +                               block++;
1969 +                       page >>= 1;
1970 +               }
1971                 page &= this->page_mask;
1972                 break;
1973         }
1974 @@ -216,8 +225,12 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
1975                 value = onenand_bufferram_address(this, block);
1976                 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
1977  
1978 -               /* Switch to the next data buffer */
1979 -               ONENAND_SET_NEXT_BUFFERRAM(this);
1980 +               if (ONENAND_IS_2PLANE(this))
1981 +                       /* It is always BufferRAM0 */
1982 +                       ONENAND_SET_BUFFERRAM0(this);
1983 +               else
1984 +                       /* Switch to the next data buffer */
1985 +                       ONENAND_SET_NEXT_BUFFERRAM(this);
1986  
1987                 return 0;
1988         }
1989 @@ -247,6 +260,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
1990                         break;
1991  
1992                 default:
1993 +                       if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
1994 +                               cmd = ONENAND_CMD_2X_PROG;
1995                         dataram = ONENAND_CURRENT_BUFFERRAM(this);
1996                         break;
1997                 }
1998 @@ -445,8 +460,9 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
1999         struct onenand_chip *this = mtd->priv;
2000  
2001         if (ONENAND_CURRENT_BUFFERRAM(this)) {
2002 +               /* Note: the 'this->writesize' is a real page size */
2003                 if (area == ONENAND_DATARAM)
2004 -                       return mtd->writesize;
2005 +                       return this->writesize;
2006                 if (area == ONENAND_SPARERAM)
2007                         return mtd->oobsize;
2008         }
2009 @@ -572,6 +588,30 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
2010  }
2011  
2012  /**
2013 + * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
2014 + * @param mtd          MTD data structure
2015 + * @param addr         address to check
2016 + * @return             blockpage address
2017 + *
2018 + * Get blockpage address at 2x program mode
2019 + */
2020 +static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
2021 +{
2022 +       struct onenand_chip *this = mtd->priv;
2023 +       int blockpage, block, page;
2024 +
2025 +       /* Calculate the even block number */
2026 +       block = (int) (addr >> this->erase_shift) & ~1;
2027 +       /* Is it the odd plane? */
2028 +       if (addr & this->writesize)
2029 +               block++;
2030 +       page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
2031 +       blockpage = (block << 7) | page;
2032 +
2033 +       return blockpage;
2034 +}
2035 +
2036 +/**
2037   * onenand_check_bufferram - [GENERIC] Check BufferRAM information
2038   * @param mtd          MTD data structure
2039   * @param addr         address to check
2040 @@ -585,7 +625,10 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
2041         int blockpage, found = 0;
2042         unsigned int i;
2043  
2044 -       blockpage = (int) (addr >> this->page_shift);
2045 +       if (ONENAND_IS_2PLANE(this))
2046 +               blockpage = onenand_get_2x_blockpage(mtd, addr);
2047 +       else
2048 +               blockpage = (int) (addr >> this->page_shift);
2049  
2050         /* Is there valid data? */
2051         i = ONENAND_CURRENT_BUFFERRAM(this);
2052 @@ -625,7 +668,10 @@ static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
2053         int blockpage;
2054         unsigned int i;
2055  
2056 -       blockpage = (int) (addr >> this->page_shift);
2057 +       if (ONENAND_IS_2PLANE(this))
2058 +               blockpage = onenand_get_2x_blockpage(mtd, addr);
2059 +       else
2060 +               blockpage = (int) (addr >> this->page_shift);
2061  
2062         /* Invalidate another BufferRAM */
2063         i = ONENAND_NEXT_BUFFERRAM(this);
2064 @@ -734,6 +780,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
2065         int read = 0, column;
2066         int thislen;
2067         int ret = 0, boundary = 0;
2068 +       int writesize = this->writesize;
2069  
2070         DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
2071  
2072 @@ -754,22 +801,22 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
2073         /* Do first load to bufferRAM */
2074         if (read < len) {
2075                 if (!onenand_check_bufferram(mtd, from)) {
2076 -                       this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
2077 +                       this->command(mtd, ONENAND_CMD_READ, from, writesize);
2078                         ret = this->wait(mtd, FL_READING);
2079                         onenand_update_bufferram(mtd, from, !ret);
2080                 }
2081         }
2082  
2083 -       thislen = min_t(int, mtd->writesize, len - read);
2084 -       column = from & (mtd->writesize - 1);
2085 -       if (column + thislen > mtd->writesize)
2086 -               thislen = mtd->writesize - column;
2087 +       thislen = min_t(int, writesize, len - read);
2088 +       column = from & (writesize - 1);
2089 +       if (column + thislen > writesize)
2090 +               thislen = writesize - column;
2091  
2092         while (!ret) {
2093                 /* If there is more to load then start next load */
2094                 from += thislen;
2095                 if (read + thislen < len) {
2096 -                       this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
2097 +                       this->command(mtd, ONENAND_CMD_READ, from, writesize);
2098                         /*
2099                          * Chip boundary handling in DDP
2100                          * Now we issued chip 1 read and pointed chip 1
2101 @@ -794,7 +841,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
2102                         this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
2103                 ONENAND_SET_NEXT_BUFFERRAM(this);
2104                 buf += thislen;
2105 -               thislen = min_t(int, mtd->writesize, len - read);
2106 +               thislen = min_t(int, writesize, len - read);
2107                 column = 0;
2108                 cond_resched();
2109                 /* Now wait for load */
2110 @@ -1079,7 +1126,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
2111                 /* Read more? */
2112                 if (read < len) {
2113                         /* Update Page size */
2114 -                       from += mtd->writesize;
2115 +                       from += this->writesize;
2116                         column = 0;
2117                 }
2118         }
2119 @@ -1135,12 +1182,12 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,
2120         int thislen, column;
2121  
2122         while (len != 0) {
2123 -               thislen = min_t(int, mtd->writesize, len);
2124 -               column = addr & (mtd->writesize - 1);
2125 -               if (column + thislen > mtd->writesize)
2126 -                       thislen = mtd->writesize - column;
2127 +               thislen = min_t(int, this->writesize, len);
2128 +               column = addr & (this->writesize - 1);
2129 +               if (column + thislen > this->writesize)
2130 +                       thislen = this->writesize - column;
2131  
2132 -               this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
2133 +               this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
2134  
2135                 onenand_update_bufferram(mtd, addr, 0);
2136  
2137 @@ -1236,6 +1283,10 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
2138  
2139                 /* In partial page write we don't update bufferram */
2140                 onenand_update_bufferram(mtd, to, !ret && !subpage);
2141 +               if (ONENAND_IS_2PLANE(this)) {
2142 +                       ONENAND_SET_BUFFERRAM1(this);
2143 +                       onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
2144 +               }
2145  
2146                 if (ret) {
2147                         printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
2148 @@ -1384,6 +1435,10 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
2149                 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
2150  
2151                 onenand_update_bufferram(mtd, to, 0);
2152 +               if (ONENAND_IS_2PLANE(this)) {
2153 +                       ONENAND_SET_BUFFERRAM1(this);
2154 +                       onenand_update_bufferram(mtd, to + this->writesize, 0);
2155 +               }
2156  
2157                 ret = this->wait(mtd, FL_WRITING);
2158                 if (ret) {
2159 @@ -2107,6 +2162,7 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
2160   *
2161   * Check and set OneNAND features
2162   * - lock scheme
2163 + * - two plane
2164   */
2165  static void onenand_check_features(struct mtd_info *mtd)
2166  {
2167 @@ -2118,19 +2174,35 @@ static void onenand_check_features(struct mtd_info *mtd)
2168         process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
2169  
2170         /* Lock scheme */
2171 -       if (density >= ONENAND_DEVICE_DENSITY_1Gb) {
2172 +       switch (density) {
2173 +       case ONENAND_DEVICE_DENSITY_4Gb:
2174 +               this->options |= ONENAND_HAS_2PLANE;
2175 +
2176 +       case ONENAND_DEVICE_DENSITY_2Gb:
2177 +               /* 2Gb DDP don't have 2 plane */
2178 +               if (!ONENAND_IS_DDP(this))
2179 +                       this->options |= ONENAND_HAS_2PLANE;
2180 +               this->options |= ONENAND_HAS_UNLOCK_ALL;
2181 +
2182 +       case ONENAND_DEVICE_DENSITY_1Gb:
2183                 /* A-Die has all block unlock */
2184 -               if (process) {
2185 -                       printk(KERN_DEBUG "Chip support all block unlock\n");
2186 +               if (process)
2187                         this->options |= ONENAND_HAS_UNLOCK_ALL;
2188 -               }
2189 -       } else {
2190 -               /* Some OneNAND has continues lock scheme */
2191 -               if (!process) {
2192 -                       printk(KERN_DEBUG "Lock scheme is Continues Lock\n");
2193 +               break;
2194 +
2195 +       default:
2196 +               /* Some OneNAND has continuous lock scheme */
2197 +               if (!process)
2198                         this->options |= ONENAND_HAS_CONT_LOCK;
2199 -               }
2200 +               break;
2201         }
2202 +
2203 +       if (this->options & ONENAND_HAS_CONT_LOCK)
2204 +               printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2205 +       if (this->options & ONENAND_HAS_UNLOCK_ALL)
2206 +               printk(KERN_DEBUG "Chip support all block unlock\n");
2207 +       if (this->options & ONENAND_HAS_2PLANE)
2208 +               printk(KERN_DEBUG "Chip has 2 plane\n");
2209  }
2210  
2211  /**
2212 @@ -2257,6 +2329,8 @@ static int onenand_probe(struct mtd_info *mtd)
2213         this->erase_shift = ffs(mtd->erasesize) - 1;
2214         this->page_shift = ffs(mtd->writesize) - 1;
2215         this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
2216 +       /* It's real page size */
2217 +       this->writesize = mtd->writesize;
2218  
2219         /* REVIST: Multichip handling */
2220  
2221 @@ -2265,6 +2339,17 @@ static int onenand_probe(struct mtd_info *mtd)
2222         /* Check OneNAND features */
2223         onenand_check_features(mtd);
2224  
2225 +       /*
2226 +        * We emulate the 4KiB page and 256KiB erase block size
2227 +        * But oobsize is still 64 bytes.
2228 +        * It is only valid if you turn on 2X program support,
2229 +        * Otherwise it will be ignored by compiler.
2230 +        */
2231 +       if (ONENAND_IS_2PLANE(this)) {
2232 +               mtd->writesize <<= 1;
2233 +               mtd->erasesize <<= 1;
2234 +       }
2235 +
2236         return 0;
2237  }
2238  
2239 diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
2240 index 1938d6d..cc01dbd 100644
2241 --- a/drivers/net/forcedeth.c
2242 +++ b/drivers/net/forcedeth.c
2243 @@ -3556,10 +3556,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
2244         }
2245         if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
2246                 if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
2247 +                       pci_intx(np->pci_dev, 0);
2248                         np->msi_flags |= NV_MSI_ENABLED;
2249                         if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
2250                                 printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
2251                                 pci_disable_msi(np->pci_dev);
2252 +                               pci_intx(np->pci_dev, 1);
2253                                 np->msi_flags &= ~NV_MSI_ENABLED;
2254                                 goto out_err;
2255                         }
2256 @@ -3601,6 +3603,7 @@ static void nv_free_irq(struct net_device *dev)
2257                 free_irq(np->pci_dev->irq, dev);
2258                 if (np->msi_flags & NV_MSI_ENABLED) {
2259                         pci_disable_msi(np->pci_dev);
2260 +                       pci_intx(np->pci_dev, 1);
2261                         np->msi_flags &= ~NV_MSI_ENABLED;
2262                 }
2263         }
2264 diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
2265 index 7dcaa09..eb69d4d 100644
2266 --- a/drivers/pci/quirks.c
2267 +++ b/drivers/pci/quirks.c
2268 @@ -1390,6 +1390,17 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,     0x260a, quirk_intel_pcie_pm);
2269  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x260b, quirk_intel_pcie_pm);
2270  
2271  /*
2272 + * According to Tom Sylla, the Geode does not support PCI power management
2273 + * transition, so we shouldn't need the D3hot delay.
2274 + */
2275 +static void __init quirk_geode_pci_pm(struct pci_dev *dev)
2276 +{
2277 +       pci_pm_d3_delay = 0;
2278 +}
2279 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, quirk_geode_pci_pm);
2280 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_geode_pci_pm);
2281 +
2282 +/*
2283   * Toshiba TC86C001 IDE controller reports the standard 8-byte BAR0 size
2284   * but the PIO transfers won't work if BAR0 falls at the odd 8 bytes.
2285   * Re-allocate the region if needed...
2286 diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
2287 index 5216c11..3e3df7e 100644
2288 --- a/drivers/video/Kconfig
2289 +++ b/drivers/video/Kconfig
2290 @@ -594,7 +594,7 @@ config FB_TGA
2291  
2292  config FB_VESA
2293         bool "VESA VGA graphics support"
2294 -       depends on (FB = y) && X86
2295 +       depends on (FB = y) && X86 && !VGA_NOPROBE
2296         select FB_CFB_FILLRECT
2297         select FB_CFB_COPYAREA
2298         select FB_CFB_IMAGEBLIT
2299 @@ -1028,7 +1028,7 @@ config FB_CARILLO_RANCH
2300  
2301  config FB_INTEL
2302         tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)"
2303 -       depends on FB && EXPERIMENTAL && PCI && X86
2304 +       depends on FB && EXPERIMENTAL && PCI && X86 && !VGA_NOPROBE
2305         select AGP
2306         select AGP_INTEL
2307         select FB_MODE_HELPERS
2308 @@ -1383,7 +1383,7 @@ config FB_SAVAGE_ACCEL
2309  
2310  config FB_SIS
2311         tristate "SiS/XGI display support"
2312 -       depends on FB && PCI
2313 +       depends on FB && PCI && !VGA_NOPROBE
2314         select FB_CFB_FILLRECT
2315         select FB_CFB_COPYAREA
2316         select FB_CFB_IMAGEBLIT
2317 @@ -1822,6 +1822,15 @@ config FB_PS3_DEFAULT_SIZE_M
2318           The default value can be overridden on the kernel command line
2319           using the "ps3fb" option (e.g. "ps3fb=9M");
2320  
2321 +config FB_OLPC_DCON
2322 +       tristate "One Laptop Per Child Display CONtroller support"
2323 +       depends on OLPC
2324 +       select I2C
2325 +       ---help---
2326 +         Add support for the OLPC DCON controller.  This controller is only
2327 +         available on OLPC platforms.   Unless you have one of these
2328 +         platforms, you will want to say 'N'.
2329 +
2330  config FB_XILINX
2331         tristate "Xilinx frame buffer support"
2332         depends on FB && XILINX_VIRTEX
2333 diff --git a/drivers/video/Makefile b/drivers/video/Makefile
2334 index 06eec7b..fc535fb 100644
2335 --- a/drivers/video/Makefile
2336 +++ b/drivers/video/Makefile
2337 @@ -111,6 +111,7 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB)  += pnx4008/
2338  obj-$(CONFIG_FB_IBM_GXT4500)     += gxt4500.o
2339  obj-$(CONFIG_FB_PS3)             += ps3fb.o
2340  obj-$(CONFIG_FB_SM501)            += sm501fb.o
2341 +obj-$(CONFIG_FB_OLPC_DCON)       += olpc_dcon.o
2342  obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
2343  obj-$(CONFIG_FB_OMAP)             += omap/
2344  
2345 diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
2346 index 0740272..4ac6a95 100644
2347 --- a/drivers/video/fbmem.c
2348 +++ b/drivers/video/fbmem.c
2349 @@ -820,6 +820,53 @@ static void try_to_load(int fb)
2350  #endif /* CONFIG_KMOD */
2351  
2352  int
2353 +fb_powerup(struct fb_info *info)
2354 +{
2355 +       int ret = 0;
2356 +
2357 +       if (!info || info->state == FBINFO_STATE_RUNNING)
2358 +               return 0;
2359 +
2360 +       if (info->fbops->fb_powerup)
2361 +               ret = info->fbops->fb_powerup(info);
2362 +
2363 +       if (!ret) {
2364 +               acquire_console_sem();
2365 +               fb_set_suspend(info, 0);
2366 +               release_console_sem();
2367 +       }
2368 +
2369 +       return ret;
2370 +}
2371 +
2372 +int
2373 +fb_powerdown(struct fb_info *info)
2374 +{
2375 +       int ret = 0;
2376 +
2377 +       if (!info || info->state == FBINFO_STATE_SUSPENDED)
2378 +               return 0;
2379 +
2380 +       /* Tell everybody that the fbdev is going down */
2381 +       acquire_console_sem();
2382 +       fb_set_suspend(info, 1);
2383 +       release_console_sem();
2384 +
2385 +       if (info->fbops->fb_powerdown)
2386 +               ret = info->fbops->fb_powerdown(info);
2387 +
2388 +       /* If the power down failed, then un-notify */
2389 +
2390 +       if (ret) {
2391 +               acquire_console_sem();
2392 +               fb_set_suspend(info, 0);
2393 +               release_console_sem();
2394 +       }
2395 +
2396 +       return ret;
2397 +}
2398 +
2399 +int
2400  fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
2401  {
2402         struct fb_fix_screeninfo *fix = &info->fix;
2403 diff --git a/drivers/video/geode/Makefile b/drivers/video/geode/Makefile
2404 index 957304b..5c98da1 100644
2405 --- a/drivers/video/geode/Makefile
2406 +++ b/drivers/video/geode/Makefile
2407 @@ -5,5 +5,5 @@ obj-$(CONFIG_FB_GEODE_GX)  += gxfb.o
2408  obj-$(CONFIG_FB_GEODE_LX)  += lxfb.o
2409  
2410  gx1fb-objs := gx1fb_core.o display_gx1.o video_cs5530.o
2411 -gxfb-objs  := gxfb_core.o display_gx.o video_gx.o
2412 +gxfb-objs  := gxfb_core.o display_gx.o video_gx.o suspend_gx.o
2413  lxfb-objs  := lxfb_core.o lxfb_ops.o
2414 diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c
2415 index 0f16e4b..a432b99 100644
2416 --- a/drivers/video/geode/display_gx.c
2417 +++ b/drivers/video/geode/display_gx.c
2418 @@ -11,26 +11,44 @@
2419   *   Free Software Foundation; either version 2 of the License, or * (at your
2420   *   option) any later version.
2421   */
2422 +
2423 +#include <linux/kernel.h>
2424  #include <linux/spinlock.h>
2425  #include <linux/fb.h>
2426  #include <linux/delay.h>
2427  #include <asm/io.h>
2428  #include <asm/div64.h>
2429  #include <asm/delay.h>
2430 +#include <asm/olpc.h>
2431  
2432  #include "geodefb.h"
2433  #include "display_gx.h"
2434  
2435 -#ifdef CONFIG_FB_GEODE_GX_SET_FBSIZE
2436 -unsigned int gx_frame_buffer_size(void)
2437 +static inline void rmwl(u32 val, u32 *reg)
2438  {
2439 -       return CONFIG_FB_GEODE_GX_FBSIZE;
2440 +       u32 in = readl(reg);
2441 +       if (in != val)
2442 +               writel(val, reg);
2443  }
2444 -#else
2445 +
2446  unsigned int gx_frame_buffer_size(void)
2447  {
2448         unsigned int val;
2449  
2450 +#ifdef CONFIG_OLPC
2451 +       if (machine_is_olpc() && !olpc_has_vsa()) {
2452 +               u32 hi,lo;      
2453 +               rdmsr(GLIU0_P2D_RO0, lo, hi);
2454 +
2455 +               /* Top page number */
2456 +               val = ((hi & 0xff) << 12) | ((lo & 0xfff00000) >> 20);  
2457 +
2458 +               val -= (lo & 0x000fffff); /* Subtract bottom page number */
2459 +               val += 1;                 /* Adjust page count */
2460 +               return (val << 12);
2461 +       }
2462 +#endif
2463 +
2464         /* FB size is reported by a virtual register */
2465         /* Virtual register class = 0x02 */
2466         /* VG_MEM_SIZE(512Kb units) = 0x00 */
2467 @@ -41,7 +59,6 @@ unsigned int gx_frame_buffer_size(void)
2468         val = (unsigned int)(inw(0xAC1E)) & 0xFFl;
2469         return (val << 19);
2470  }
2471 -#endif
2472  
2473  int gx_line_delta(int xres, int bpp)
2474  {
2475 @@ -63,23 +80,23 @@ static void gx_set_mode(struct fb_info *info)
2476         gcfg = readl(par->dc_regs + DC_GENERAL_CFG);
2477         dcfg = readl(par->dc_regs + DC_DISPLAY_CFG);
2478  
2479 -       /* Disable the timing generator. */
2480 -       dcfg &= ~(DC_DCFG_TGEN);
2481 -       writel(dcfg, par->dc_regs + DC_DISPLAY_CFG);
2482 +       /* Programming the clock is costly and ugly, so avoid if if we can */
2483  
2484 -       /* Wait for pending memory requests before disabling the FIFO load. */
2485 -       udelay(100);
2486 +       if (par->curdclk != info->var.pixclock) {
2487 +               /* Disable the timing generator. */
2488 +               dcfg &= ~(DC_DCFG_TGEN);
2489 +               writel(dcfg, par->dc_regs + DC_DISPLAY_CFG);
2490  
2491 -       /* Disable FIFO load and compression. */
2492 -       gcfg &= ~(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
2493 -       writel(gcfg, par->dc_regs + DC_GENERAL_CFG);
2494 +               /* Wait for pending memory requests before disabling the FIFO load. */
2495 +               udelay(100);
2496  
2497 -       /* Setup DCLK and its divisor. */
2498 -       par->vid_ops->set_dclk(info);
2499 +               /* Disable FIFO load and compression. */
2500 +               gcfg &= ~(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE);
2501 +               writel(gcfg, par->dc_regs + DC_GENERAL_CFG);
2502  
2503 -       /*
2504 -        * Setup new mode.
2505 -        */
2506 +               /* Setup DCLK and its divisor. */
2507 +               par->vid_ops->set_dclk(info);
2508 +       }
2509  
2510         /* Clear all unused feature bits. */
2511         gcfg &= DC_GCFG_YUVM | DC_GCFG_VDSE;
2512 @@ -90,12 +107,13 @@ static void gx_set_mode(struct fb_info *info)
2513         gcfg |= (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE;
2514  
2515         /* Framebuffer start offset. */
2516 -       writel(0, par->dc_regs + DC_FB_ST_OFFSET);
2517 +       rmwl(0, par->dc_regs + DC_FB_ST_OFFSET);
2518  
2519         /* Line delta and line buffer length. */
2520 -       writel(info->fix.line_length >> 3, par->dc_regs + DC_GFX_PITCH);
2521 -       writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2,
2522 -              par->dc_regs + DC_LINE_SIZE);
2523 +       rmwl(info->fix.line_length >> 3, par->dc_regs + DC_GFX_PITCH);
2524 +
2525 +       rmwl(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2,
2526 +            par->dc_regs + DC_LINE_SIZE);
2527  
2528  
2529         /* Enable graphics and video data and unmask address lines. */
2530 @@ -134,17 +152,16 @@ static void gx_set_mode(struct fb_info *info)
2531         vblankend = vsyncend + info->var.upper_margin;
2532         vtotal = vblankend;
2533  
2534 -       writel((hactive - 1)     | ((htotal - 1) << 16),    par->dc_regs + DC_H_ACTIVE_TIMING);
2535 -       writel((hblankstart - 1) | ((hblankend - 1) << 16), par->dc_regs + DC_H_BLANK_TIMING);
2536 -       writel((hsyncstart - 1)  | ((hsyncend - 1) << 16),  par->dc_regs + DC_H_SYNC_TIMING);
2537 -
2538 -       writel((vactive - 1)     | ((vtotal - 1) << 16),    par->dc_regs + DC_V_ACTIVE_TIMING);
2539 -       writel((vblankstart - 1) | ((vblankend - 1) << 16), par->dc_regs + DC_V_BLANK_TIMING);
2540 -       writel((vsyncstart - 1)  | ((vsyncend - 1) << 16),  par->dc_regs + DC_V_SYNC_TIMING);
2541 +       rmwl((hactive - 1)     | ((htotal - 1) << 16),    par->dc_regs + DC_H_ACTIVE_TIMING);
2542 +       rmwl((hblankstart - 1) | ((hblankend - 1) << 16), par->dc_regs + DC_H_BLANK_TIMING);
2543 +       rmwl((hsyncstart - 1)  | ((hsyncend - 1) << 16),  par->dc_regs + DC_H_SYNC_TIMING);
2544 +       rmwl((vactive - 1)     | ((vtotal - 1) << 16),    par->dc_regs + DC_V_ACTIVE_TIMING);
2545 +       rmwl((vblankstart - 1) | ((vblankend - 1) << 16), par->dc_regs + DC_V_BLANK_TIMING);
2546 +       rmwl((vsyncstart - 1)  | ((vsyncend - 1) << 16),  par->dc_regs + DC_V_SYNC_TIMING);
2547  
2548         /* Write final register values. */
2549 -       writel(dcfg, par->dc_regs + DC_DISPLAY_CFG);
2550 -       writel(gcfg, par->dc_regs + DC_GENERAL_CFG);
2551 +       rmwl(dcfg, par->dc_regs + DC_DISPLAY_CFG);
2552 +       rmwl(gcfg, par->dc_regs + DC_GENERAL_CFG);
2553  
2554         par->vid_ops->configure_display(info);
2555  
2556 diff --git a/drivers/video/geode/display_gx.h b/drivers/video/geode/display_gx.h
2557 index 0af33f3..d20b877 100644
2558 --- a/drivers/video/geode/display_gx.h
2559 +++ b/drivers/video/geode/display_gx.h
2560 @@ -20,6 +20,9 @@ extern struct geode_dc_ops gx_dc_ops;
2561  #define GLD_MSR_CONFIG   0xC0002001
2562  #define GLD_MSR_CONFIG_DM_FP 0x40
2563  
2564 +/* Used for memory dection on the OLPC */
2565 +#define GLIU0_P2D_RO0 0x10000029
2566 +
2567  /* Display controller registers */
2568  
2569  #define DC_UNLOCK 0x00
2570 diff --git a/drivers/video/geode/geodefb.h b/drivers/video/geode/geodefb.h
2571 index ae04820..0214d11 100644
2572 --- a/drivers/video/geode/geodefb.h
2573 +++ b/drivers/video/geode/geodefb.h
2574 @@ -12,6 +12,10 @@
2575  #ifndef __GEODEFB_H__
2576  #define __GEODEFB_H__
2577  
2578 +#define FB_POWER_STATE_OFF      0
2579 +#define FB_POWER_STATE_SUSPEND  1
2580 +#define FB_POWER_STATE_ON       2
2581 +
2582  struct geodefb_info;
2583  
2584  struct geode_dc_ops {
2585 @@ -21,18 +25,24 @@ struct geode_dc_ops {
2586  
2587  struct geode_vid_ops {
2588         void (*set_dclk)(struct fb_info *);
2589 +       unsigned int (*get_dclk)(struct fb_info *);
2590         void (*configure_display)(struct fb_info *);
2591         int  (*blank_display)(struct fb_info *, int blank_mode);
2592  };
2593  
2594  struct geodefb_par {
2595         int enable_crt;
2596 +       int fbactive;  /* True if the current console is in KD_GRAPHICS mode */
2597         int panel_x; /* dimensions of an attached flat panel, non-zero => enable panel */
2598         int panel_y;
2599 +       unsigned int curdclk;  /* Used by GX to avoid unnessesary clock switching */
2600         void __iomem *dc_regs;
2601         void __iomem *vid_regs;
2602 +       void __iomem *gp_regs;
2603         struct geode_dc_ops  *dc_ops;
2604         struct geode_vid_ops *vid_ops;
2605 +
2606 +       int state;
2607  };
2608  
2609  #endif /* !__GEODEFB_H__ */
2610 diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
2611 index cf841ef..3eabc53 100644
2612 --- a/drivers/video/geode/gxfb_core.c
2613 +++ b/drivers/video/geode/gxfb_core.c
2614 @@ -30,12 +30,31 @@
2615  #include <linux/fb.h>
2616  #include <linux/init.h>
2617  #include <linux/pci.h>
2618 +#include <linux/notifier.h>
2619 +#include <linux/vt_kern.h>
2620 +#include <linux/console.h>
2621 +#include <asm/uaccess.h>
2622 +#include <asm/olpc.h>
2623  
2624  #include "geodefb.h"
2625  #include "display_gx.h"
2626  #include "video_gx.h"
2627  
2628 +#define FBIOSGAMMA             _IOW('F', 0x20, void *)
2629 +#define FBIOGGAMMA             _IOW('F', 0x21, void *)
2630 +
2631 +#ifdef DEBUG
2632 +
2633 +#define FBIODUMPGP             _IOW('F', 0x22, void *)
2634 +#define FBIODUMPDC             _IOW('F', 0x23, void *)
2635 +#define FBIODUMPVP             _IOW('F', 0x24, void *)
2636 +#define FBIODUMPFP             _IOW('F', 0x25, void *)
2637 +
2638 +#endif
2639 +
2640  static char *mode_option;
2641 +static int noclear;
2642 +struct fb_info *gxfb_info;
2643  
2644  /* Modes relevant to the GX (taken from modedb.c) */
2645  static const struct fb_videomode gx_modedb[] __initdata = {
2646 @@ -103,8 +122,20 @@ static const struct fb_videomode gx_modedb[] __initdata = {
2647         { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
2648           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
2649           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
2650 +       /* 1200x900-75 - CRT timings for the OLPC mode */
2651 +       { NULL, 75, 1200, 900, 8049, 104, 240, 29, 54, 136, 3,
2652 +         0, FB_VMODE_NONINTERLACED, 0 }
2653  };
2654  
2655 +#ifdef CONFIG_OLPC
2656 +static const struct fb_videomode gx_dcon_modedb[] __initdata = {
2657 +       /* The only mode the DCON has is 1200x900 */
2658 +       { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
2659 +         0, FB_VMODE_NONINTERLACED, 0 }
2660 +};
2661 +#endif
2662 +
2663 +
2664  static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
2665  {
2666         if (var->xres > 1600 || var->yres > 1200)
2667 @@ -137,7 +168,7 @@ static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
2668         return 0;
2669  }
2670  
2671 -static int gxfb_set_par(struct fb_info *info)
2672 +int gxfb_set_par(struct fb_info *info)
2673  {
2674         struct geodefb_par *par = info->par;
2675  
2676 @@ -204,16 +235,26 @@ static int gxfb_blank(int blank_mode, struct fb_info *info)
2677         return par->vid_ops->blank_display(info, blank_mode);
2678  }
2679  
2680 +static int fbsize;
2681 +
2682  static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
2683  {
2684         struct geodefb_par *par = info->par;
2685 -       int fb_len;
2686         int ret;
2687  
2688         ret = pci_enable_device(dev);
2689         if (ret < 0)
2690                 return ret;
2691  
2692 +       ret = pci_request_region(dev, 1, "gxfb (graphics processor)");
2693 +       if (ret < 0)
2694 +               return ret;
2695 +
2696 +       par->gp_regs = ioremap(pci_resource_start(dev, 1),
2697 +                               pci_resource_len(dev, 1));
2698 +       if (!par->gp_regs)
2699 +               return -ENOMEM;
2700 +
2701         ret = pci_request_region(dev, 3, "gxfb (video processor)");
2702         if (ret < 0)
2703                 return ret;
2704 @@ -232,36 +273,118 @@ static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *de
2705         ret = pci_request_region(dev, 0, "gxfb (framebuffer)");
2706         if (ret < 0)
2707                 return ret;
2708 -       if ((fb_len = gx_frame_buffer_size()) < 0)
2709 -               return -ENOMEM;
2710 +
2711 +       /* If the fbsize wasn't specified then try to probe it */
2712 +
2713 +       if (!fbsize) {
2714 +               fbsize = gx_frame_buffer_size();
2715 +               if (fbsize == 0)
2716 +                       return -ENOMEM;
2717 +       }
2718 +
2719         info->fix.smem_start = pci_resource_start(dev, 0);
2720 -       info->fix.smem_len = fb_len;
2721 +       info->fix.smem_len = fbsize;
2722         info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
2723         if (!info->screen_base)
2724                 return -ENOMEM;
2725  
2726 -       /* Set the 16MB aligned base address of the graphics memory region
2727 +       /* Set the 16MiB aligned base address of the graphics memory region
2728          * in the display controller */
2729  
2730         writel(info->fix.smem_start & 0xFF000000,
2731                         par->dc_regs + DC_GLIU0_MEM_OFFSET);
2732  
2733 -       dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n",
2734 +       dev_info(&dev->dev, "%d KiB of video memory at 0x%lx\n",
2735                  info->fix.smem_len / 1024, info->fix.smem_start);
2736  
2737         return 0;
2738  }
2739  
2740 +static int gxfb_ioctl( struct fb_info *info, unsigned int cmd,
2741 +                      unsigned long arg)
2742 +{
2743 +       unsigned int gamma[GXFB_GAMMA_DWORDS];
2744 +       int ret = -EINVAL;
2745 +       struct geodefb_par *par = info->par;
2746 +       int i;
2747 +
2748 +       switch(cmd) {
2749 +       case FBIOSGAMMA:
2750 +               /* Read the gamma information from the user - 256 dwords */
2751 +
2752 +               if (copy_from_user(gamma, (void * __user) arg, GXFB_GAMMA_SIZE))
2753 +                       return -EFAULT;
2754 +
2755 +               writel(0, par->vid_regs + GX_GAR);
2756 +
2757 +               /* Sequential writes to the data register will increment the
2758 +                  address automatically  */
2759 +
2760 +               for(i = 0; i < GXFB_GAMMA_DWORDS; i++)
2761 +                       writel(gamma[i] & 0xFFFFFF, par->vid_regs + GX_GDR);
2762 +
2763 +               writel(readl(par->vid_regs + GX_MISC) & ~GX_MISC_GAM_EN,
2764 +                      par->vid_regs + GX_MISC);
2765 +
2766 +               ret = 0;
2767 +               break;
2768 +
2769 +       case FBIOGGAMMA:
2770 +               if (readl(par->vid_regs + GX_MISC) & GX_MISC_GAM_EN)
2771 +                       return -EINVAL;
2772 +
2773 +               memset(gamma, 0, GXFB_GAMMA_SIZE);
2774 +               writel(0, par->vid_regs + GX_GAR);
2775 +
2776 +               for(i = 0; i < GXFB_GAMMA_DWORDS;i++)
2777 +                       gamma[i] = readl(par->vid_regs + GX_GDR);
2778 +
2779 +               if (copy_to_user((void * __user) arg, gamma, GXFB_GAMMA_SIZE))
2780 +                       ret = -EFAULT;
2781 +               else
2782 +                       ret = 0;
2783 +
2784 +               break;
2785 +
2786 +#ifdef DEBUG
2787 +       case FBIODUMPGP:
2788 +               ret = 0;
2789 +               dump_regs(info, 0);
2790 +               break;
2791 +               
2792 +       case FBIODUMPDC:
2793 +               ret = 0;
2794 +               dump_regs(info, 1);
2795 +               break;
2796 +
2797 +       case FBIODUMPVP:
2798 +               ret = 0;
2799 +               dump_regs(info, 2);
2800 +               break;
2801 +
2802 +       case FBIODUMPFP:
2803 +               ret = 0;
2804 +               dump_regs(info, 3);
2805 +               break;
2806 +#endif
2807 +       }
2808 +
2809 +       return ret;
2810 +}
2811 +
2812  static struct fb_ops gxfb_ops = {
2813         .owner          = THIS_MODULE,
2814         .fb_check_var   = gxfb_check_var,
2815         .fb_set_par     = gxfb_set_par,
2816         .fb_setcolreg   = gxfb_setcolreg,
2817         .fb_blank       = gxfb_blank,
2818 +       .fb_ioctl       = gxfb_ioctl,
2819         /* No HW acceleration for now. */
2820         .fb_fillrect    = cfb_fillrect,
2821         .fb_copyarea    = cfb_copyarea,
2822         .fb_imageblit   = cfb_imageblit,
2823 +       .fb_powerdown   = gxfb_powerdown,
2824 +       .fb_powerup     = gxfb_powerup,
2825  };
2826  
2827  static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
2828 @@ -303,23 +426,86 @@ static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
2829         return info;
2830  }
2831  
2832 -static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2833 +static int gxfb_console_notify(struct notifier_block *self,
2834 +                               unsigned long action, void *data)
2835 +{
2836 +       if (gxfb_info != NULL) {
2837 +               struct geodefb_par *par = gxfb_info->par;
2838 +               par->fbactive = (action == CONSOLE_EVENT_SWITCH_TEXT) ? 0 : 1;
2839 +       }
2840 +
2841 +       return NOTIFY_OK;
2842 +}
2843 +
2844 +static struct notifier_block gxfb_console_notifier = {
2845 +       .notifier_call = gxfb_console_notify
2846 +};
2847 +
2848 +#ifdef CONFIG_PM
2849 +
2850 +static int gxfb_suspend(struct pci_dev *pdev,  pm_message_t state)
2851 +{
2852 +       struct fb_info *info = pci_get_drvdata(pdev);
2853 +       struct geodefb_par *par = info->par;
2854 +
2855 +       if (pdev->dev.power.power_state.event == state.event)
2856 +               return 0;
2857 +
2858 +       if (state.event == PM_EVENT_SUSPEND) {
2859 +        
2860 +               acquire_console_sem();
2861 +               gxfb_powerdown(info);
2862 +
2863 +               par->state = FB_POWER_STATE_OFF;
2864 +               fb_set_suspend(info, 1);
2865 +               
2866 +               release_console_sem();
2867 +       }
2868 +
2869 +       pdev->dev.power.power_state = state;
2870 +       return 0;
2871 +}
2872 +
2873 +static int gxfb_resume(struct pci_dev *pdev)
2874 +{
2875 +       struct fb_info *info = pci_get_drvdata(pdev);
2876 +
2877 +       acquire_console_sem();
2878 +       
2879 +       /* Turn the engine completely on */
2880 +
2881 +       if (gxfb_powerup(info))
2882 +         printk(KERN_ERR "gxfb:  Powerup failed\n");
2883 +
2884 +       fb_set_suspend(info, 0);
2885 +       release_console_sem();
2886 +
2887 +       pdev->dev.power.power_state = PMSG_ON;
2888 +        return 0;
2889 +}
2890 +#endif
2891 +
2892 +static int __init gxfb_probe(struct pci_dev *pdev,
2893 +                            const struct pci_device_id *id)
2894  {
2895         struct geodefb_par *par;
2896 -       struct fb_info *info;
2897         int ret;
2898         unsigned long val;
2899  
2900 -       info = gxfb_init_fbinfo(&pdev->dev);
2901 -       if (!info)
2902 +       struct fb_videomode *modedb_ptr;
2903 +       int modedb_size;
2904 +
2905 +       gxfb_info = gxfb_init_fbinfo(&pdev->dev);
2906 +       if (gxfb_info == NULL)
2907                 return -ENOMEM;
2908 -       par = info->par;
2909 +
2910 +       par = gxfb_info->par;
2911  
2912         /* GX display controller and GX video device. */
2913         par->dc_ops  = &gx_dc_ops;
2914         par->vid_ops = &gx_vid_ops;
2915  
2916 -       if ((ret = gxfb_map_video_memory(info, pdev)) < 0) {
2917 +       if ((ret = gxfb_map_video_memory(gxfb_info, pdev)) < 0) {
2918                 dev_err(&pdev->dev, "failed to map frame buffer or controller registers\n");
2919                 goto err;
2920         }
2921 @@ -333,32 +519,60 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
2922         else
2923                 par->enable_crt = 1;
2924  
2925 -       ret = fb_find_mode(&info->var, info, mode_option,
2926 -                          gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
2927 +       /* Get the current dotclock */
2928 +
2929 +       par->curdclk = (par->vid_ops->get_dclk) ? par->vid_ops->get_dclk(gxfb_info) : 0;
2930 +
2931 +       /* We need to determine a display mode right now, so we will
2932 +        * check to see if the DCON was previously detected by the BIOS
2933 +        * and use that to make our mode database decision.
2934 +        */
2935 +
2936 +       modedb_ptr = (struct fb_videomode *) gx_modedb;
2937 +       modedb_size = ARRAY_SIZE(gx_modedb);
2938 +
2939 +#ifdef CONFIG_OLPC
2940 +       if (olpc_has_dcon()) {
2941 +               modedb_ptr = (struct fb_videomode *) gx_dcon_modedb;
2942 +               modedb_size = ARRAY_SIZE(gx_dcon_modedb);
2943 +       }
2944 +#endif
2945 +
2946 +       ret = fb_find_mode(&gxfb_info->var, gxfb_info, mode_option,
2947 +                          modedb_ptr, modedb_size, NULL, 16);
2948 +
2949         if (ret == 0 || ret == 4) {
2950                 dev_err(&pdev->dev, "could not find valid video mode\n");
2951                 ret = -EINVAL;
2952                 goto err;
2953         }
2954  
2955 +       /* Clear the screen of garbage, unless noclear was specified,
2956 +        * in which case we assume the user knows what he is doing */
2957 +
2958 +       if (!noclear)
2959 +               memset_io(gxfb_info->screen_base, 0, gxfb_info->fix.smem_len);
2960 +
2961 +       gxfb_check_var(&gxfb_info->var, gxfb_info);
2962 +       gxfb_set_par(gxfb_info);
2963 +
2964 +       /* We are powered up */
2965 +       par->state = FB_POWER_STATE_ON;
2966  
2967 -       /* Clear the frame buffer of garbage. */
2968 -        memset_io(info->screen_base, 0, info->fix.smem_len);
2969  
2970 -       gxfb_check_var(&info->var, info);
2971 -       gxfb_set_par(info);
2972 +       console_event_register(&gxfb_console_notifier);
2973  
2974 -       if (register_framebuffer(info) < 0) {
2975 +       if (register_framebuffer(gxfb_info) < 0) {
2976                 ret = -EINVAL;
2977                 goto err;
2978         }
2979 -       pci_set_drvdata(pdev, info);
2980 -       printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
2981 +       pci_set_drvdata(pdev, gxfb_info);
2982 +       printk(KERN_INFO "fb%d: %s frame buffer device\n", gxfb_info->node, gxfb_info->fix.id);
2983         return 0;
2984  
2985    err:
2986 -       if (info->screen_base) {
2987 -               iounmap(info->screen_base);
2988 +       if (gxfb_info->screen_base) {
2989 +               iounmap(gxfb_info->screen_base);
2990                 pci_release_region(pdev, 0);
2991         }
2992         if (par->vid_regs) {
2993 @@ -370,8 +584,9 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
2994                 pci_release_region(pdev, 2);
2995         }
2996  
2997 -       if (info)
2998 -               framebuffer_release(info);
2999 +       if (gxfb_info)
3000 +               framebuffer_release(gxfb_info);
3001 +
3002         return ret;
3003  }
3004  
3005 @@ -397,9 +612,7 @@ static void gxfb_remove(struct pci_dev *pdev)
3006  }
3007  
3008  static struct pci_device_id gxfb_id_table[] = {
3009 -       { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_GX_VIDEO,
3010 -         PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
3011 -         0xff0000, 0 },
3012 +       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_GX_VIDEO) },
3013         { 0, }
3014  };
3015  
3016 @@ -410,22 +623,30 @@ static struct pci_driver gxfb_driver = {
3017         .id_table       = gxfb_id_table,
3018         .probe          = gxfb_probe,
3019         .remove         = gxfb_remove,
3020 +#ifdef CONFIG_PM
3021 +       .suspend        = gxfb_suspend,
3022 +       .resume         = gxfb_resume
3023 +#endif
3024  };
3025  
3026  #ifndef MODULE
3027 -static int __init gxfb_setup(char *options)
3028 -{
3029 +static int __init gxfb_setup(char *options) {
3030  
3031         char *opt;
3032  
3033         if (!options || !*options)
3034                 return 0;
3035  
3036 -       while ((opt = strsep(&options, ",")) != NULL) {
3037 +       while((opt = strsep(&options, ",")) != NULL) {
3038                 if (!*opt)
3039                         continue;
3040  
3041 -               mode_option = opt;
3042 +               if (!strncmp(opt, "fbsize:", 7))
3043 +                       fbsize = simple_strtoul(opt+7, NULL, 0);
3044 +               else if (!strcmp(opt, "noclear"))
3045 +                       noclear = 1;
3046 +               else
3047 +                       mode_option = opt;
3048         }
3049  
3050         return 0;
3051 @@ -444,7 +665,6 @@ static int __init gxfb_init(void)
3052  #endif
3053         return pci_register_driver(&gxfb_driver);
3054  }
3055 -
3056  static void __exit gxfb_cleanup(void)
3057  {
3058         pci_unregister_driver(&gxfb_driver);
3059 @@ -456,5 +676,8 @@ module_exit(gxfb_cleanup);
3060  module_param(mode_option, charp, 0);
3061  MODULE_PARM_DESC(mode_option, "video mode (<x>x<y>[-<bpp>][@<refr>])");
3062  
3063 +module_param(fbsize, int, 0);
3064 +MODULE_PARM_DESC(fbsize, "video memory size");
3065 +
3066  MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX");
3067  MODULE_LICENSE("GPL");
3068 diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h
3069 index 6c227f9..5be8a4d 100644
3070 --- a/drivers/video/geode/lxfb.h
3071 +++ b/drivers/video/geode/lxfb.h
3072 @@ -25,10 +25,23 @@ void lx_set_mode(struct fb_info *);
3073  void lx_get_gamma(struct fb_info *, unsigned int *, int);
3074  void lx_set_gamma(struct fb_info *, unsigned int *, int);
3075  unsigned int lx_framebuffer_size(void);
3076 +int lx_shutdown(struct fb_info *);
3077 +int lx_powerup(struct fb_info *);
3078  int lx_blank_display(struct fb_info *, int);
3079  void lx_set_palette_reg(struct fb_info *, unsigned int, unsigned int,
3080                         unsigned int, unsigned int);
3081  
3082 +
3083 +
3084 +/* ioctl() defines */
3085 +
3086 +#define FBIOSGAMMA              _IOW('F', 0x20, void *)
3087 +#define FBIOGGAMMA              _IOW('F', 0x21, void *)
3088 +
3089 +/* General definitions */
3090 +#define LXFB_GAMMA_DWORDS 256 /* number of dwords in the gamma ram */
3091 +#define LXFB_GAMMA_SIZE (LXFB_GAMMA_DWORDS * sizeof(unsigned int))
3092 +
3093  /* MSRS */
3094  
3095  #define MSR_LX_GLD_CONFIG    0x48002001
3096 diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
3097 index 5e30b40..c9060ed 100644
3098 --- a/drivers/video/geode/lxfb_core.c
3099 +++ b/drivers/video/geode/lxfb_core.c
3100 @@ -22,6 +22,7 @@
3101  #include <linux/init.h>
3102  #include <linux/pci.h>
3103  #include <linux/uaccess.h>
3104 +#include <asm/olpc.h>
3105  
3106  #include "lxfb.h"
3107  
3108 @@ -35,186 +36,84 @@ static int fbsize;
3109   */
3110  
3111  const struct fb_videomode geode_modedb[] __initdata = {
3112 -       /* 640x480-60 */
3113 -       { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2,
3114 +       /* 640x480-60 VESA */
3115 +       { NULL, 60, 640, 480, 39682,  48, 16, 33, 10, 96, 2,
3116 +         0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3117 +       /* 640x480-75 VESA */
3118 +       { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
3119 +         0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3120 +       /* 640x480-85 VESA */
3121 +       { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
3122 +         0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3123 +       /* 800x600-60 VESA */
3124 +       { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
3125           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3126 -         FB_VMODE_NONINTERLACED, 0 },
3127 -       /* 640x400-70 */
3128 -       { NULL, 70, 640, 400, 39770, 40, 8, 28, 5, 96, 2,
3129 -         FB_SYNC_HOR_HIGH_ACT,
3130 -         FB_VMODE_NONINTERLACED, 0 },
3131 -       /* 640x480-70 */
3132 -       { NULL, 70, 640, 480, 35014, 88, 24, 15, 2, 64, 3,
3133 -         0, FB_VMODE_NONINTERLACED, 0 },
3134 -       /* 640x480-72 */
3135 -       { NULL, 72, 640, 480, 32102, 120, 16, 20, 1, 40, 3,
3136 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3137 +       /* 800x600-75 VESA */
3138 +       { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
3139           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3140 -         FB_VMODE_NONINTERLACED, 0 },
3141 -       /* 640x480-75 */
3142 -       { NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
3143 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3144 +       /* 800x600-85 VESA */
3145 +       { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
3146           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3147 -         FB_VMODE_NONINTERLACED, 0 },
3148 -       /* 640x480-85 */
3149 -       { NULL, 85, 640, 480, 27780, 80, 56, 25, 1, 56, 3,
3150 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3151 +       /* 1024x768-60 VESA */
3152 +       { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
3153 +         0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3154 +       /* 1024x768-75 VESA */
3155 +       { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
3156           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3157 -         FB_VMODE_NONINTERLACED, 0 },
3158 -       /* 640x480-90 */
3159 -       { NULL, 90, 640, 480, 26392, 96, 32, 22, 1, 64, 3,
3160 -         0, FB_VMODE_NONINTERLACED, 0 },
3161 -       /* 640x480-100 */
3162 -       { NULL, 100, 640, 480, 23167, 104, 40, 25, 1, 64, 3,
3163 -         0, FB_VMODE_NONINTERLACED, 0 },
3164 -       /* 640x480-60 */
3165 -       { NULL, 60, 640, 480, 39682, 48, 16, 25, 10, 88, 2,
3166 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3167 +       /* 1024x768-85 VESA */
3168 +       { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
3169           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3170 -         FB_VMODE_NONINTERLACED, 0 },
3171 -       /* 800x600-56 */
3172 -       { NULL, 56, 800, 600, 27901, 128, 24, 22, 1, 72, 2,
3173 -         0, FB_VMODE_NONINTERLACED, 0 },
3174 -       /* 800x600-60 */
3175 -       { NULL, 60, 800, 600, 25131, 72, 32, 23, 1, 136, 4,
3176 -         0, FB_VMODE_NONINTERLACED, 0 },
3177 -       /* 800x600-70 */
3178 -       { NULL, 70, 800, 600, 21873, 120, 40, 21, 4, 80, 3,
3179 -         0, FB_VMODE_NONINTERLACED, 0 },
3180 -       /* 800x600-72 */
3181 -       { NULL, 72, 800, 600, 20052, 64, 56, 23, 37, 120, 6,
3182 -         0, FB_VMODE_NONINTERLACED, 0 },
3183 -       /* 800x600-75 */
3184 -       { NULL, 75, 800, 600, 20202, 160, 16, 21, 1, 80, 3,
3185 -         0, FB_VMODE_NONINTERLACED, 0 },
3186 -       /* 800x600-85 */
3187 -       { NULL, 85, 800, 600, 17790, 152, 32, 27, 1, 64, 3,
3188 -         0, FB_VMODE_NONINTERLACED, 0 },
3189 -       /* 800x600-90 */
3190 -       { NULL, 90, 800, 600, 16648, 128, 40, 28, 1, 88, 3,
3191 -         0, FB_VMODE_NONINTERLACED, 0 },
3192 -       /* 800x600-100 */
3193 -       { NULL, 100, 800, 600, 14667, 136, 48, 27, 1, 88, 3,
3194 -         0, FB_VMODE_NONINTERLACED, 0 },
3195 -       /* 800x600-60 */
3196 -       { NULL, 60, 800, 600, 25131, 88, 40, 23, 1, 128, 4,
3197 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3198 +       /* 1280x960-60 VESA */
3199 +       { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
3200           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3201 -         FB_VMODE_NONINTERLACED, 0 },
3202 -       /* 1024x768-60 */
3203 -       { NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
3204 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3205 +       /* 1280x960-85 VESA */
3206 +       { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
3207           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3208 -         FB_VMODE_NONINTERLACED, 0 },
3209 -       /* 1024x768-70 */
3210 -       { NULL, 70, 1024, 768, 13346, 144, 24, 29, 3, 136, 6,
3211 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3212 +       /* 1280x1024-60 VESA */
3213 +       { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
3214           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3215 -         FB_VMODE_NONINTERLACED, 0 },
3216 -       /* 1024x768-72 */
3217 -       { NULL, 72, 1024, 768, 12702, 168, 56, 29, 4, 112, 3,
3218 -         0, FB_VMODE_NONINTERLACED, 0 },
3219 -       /* 1024x768-75 */
3220 -       { NULL, 75, 1024, 768, 12703, 176, 16, 28, 1, 96, 3,
3221 -         0, FB_VMODE_NONINTERLACED, 0 },
3222 -       /* 1024x768-85 */
3223 -       { NULL, 85, 1024, 768, 10581, 208, 48, 36, 1, 96, 3,
3224 -         0, FB_VMODE_NONINTERLACED, 0 },
3225 -       /* 1024x768-90 */
3226 -       { NULL, 90, 1024, 768, 9981, 176, 64, 37, 1, 112, 3,
3227 -         0, FB_VMODE_NONINTERLACED, 0 },
3228 -       /* 1024x768-100 */
3229 -       { NULL, 100, 1024, 768, 8825, 184, 72, 42, 1, 112, 3,
3230 -         0, FB_VMODE_NONINTERLACED, 0 },
3231 -       /* 1024x768-60 */
3232 -       { NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
3233 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3234 +       /* 1280x1024-75 VESA */
3235 +       { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
3236           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3237 -         FB_VMODE_NONINTERLACED, 0 },
3238 -       /* 1152x864-60 */
3239 -       { NULL, 60, 1152, 864, 12251, 184, 64, 27, 1, 120, 3,
3240 -         0, FB_VMODE_NONINTERLACED, 0 },
3241 -       /* 1152x864-70 */
3242 -       { NULL, 70, 1152, 864, 10254, 192, 72, 32, 8, 120, 3,
3243 -         0, FB_VMODE_NONINTERLACED, 0 },
3244 -       /* 1152x864-72 */
3245 -       { NULL, 72, 1152, 864, 9866, 200, 72, 33, 7, 128, 3,
3246 -         0, FB_VMODE_NONINTERLACED, 0 },
3247 -       /* 1152x864-75 */
3248 -       { NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3,
3249 -         0, FB_VMODE_NONINTERLACED, 0 },
3250 -       /* 1152x864-85 */
3251 -       { NULL, 85, 1152, 864, 8357, 200, 72, 37, 3, 128, 3,
3252 -         0, FB_VMODE_NONINTERLACED, 0 },
3253 -       /* 1152x864-90 */
3254 -       { NULL, 90, 1152, 864, 7719, 208, 80, 42, 9, 128, 3,
3255 -         0, FB_VMODE_NONINTERLACED, 0 },
3256 -       /* 1152x864-100 */
3257 -       { NULL, 100, 1152, 864, 6947, 208, 80, 48, 3, 128, 3,
3258 -         0, FB_VMODE_NONINTERLACED, 0 },
3259 -       /* 1152x864-60 */
3260 -       { NULL, 60, 1152, 864, 12251, 184, 64, 27, 1, 120, 3,
3261 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3262 +       /* 1280x1024-85 VESA */
3263 +       { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
3264           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3265 -         FB_VMODE_NONINTERLACED, 0 },
3266 -       /* 1280x1024-60 */
3267 -       { NULL, 60, 1280, 1024, 9262, 248, 48, 38, 1, 112, 3,
3268 -         0, FB_VMODE_NONINTERLACED, 0 },
3269 -       /* 1280x1024-70 */
3270 -       { NULL, 70, 1280, 1024, 7719, 224, 88, 38, 6, 136, 3,
3271 -         0, FB_VMODE_NONINTERLACED, 0 },
3272 -       /* 1280x1024-72 */
3273 -       { NULL, 72, 1280, 1024, 7490, 224, 88, 39, 7, 136, 3,
3274 -         0, FB_VMODE_NONINTERLACED, 0 },
3275 -       /* 1280x1024-75 */
3276 -       { NULL, 75, 1280, 1024, 7409, 248, 16, 38, 1, 144, 3,
3277 -         0, FB_VMODE_NONINTERLACED, 0 },
3278 -       /* 1280x1024-85 */
3279 -       { NULL, 85, 1280, 1024, 6351, 224, 64, 44, 1, 160, 3,
3280 -         0, FB_VMODE_NONINTERLACED, 0 },
3281 -       /* 1280x1024-90 */
3282 -       { NULL, 90, 1280, 1024, 5791, 240, 96, 51, 12, 144, 3,
3283 -         0, FB_VMODE_NONINTERLACED, 0 },
3284 -       /* 1280x1024-100 */
3285 -       { NULL, 100, 1280, 1024, 5212, 240, 96, 57, 6, 144, 3,
3286 -         0, FB_VMODE_NONINTERLACED, 0 },
3287 -       /* 1280x1024-60 */
3288 -       { NULL, 60, 1280, 1024, 9262, 248, 48, 38, 1, 112, 3,
3289 -         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3290 -         FB_VMODE_NONINTERLACED, 0 },
3291 -       /* 1600x1200-60 */
3292 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3293 +       /* 1600x1200-60 VESA */
3294         { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
3295 -         0, FB_VMODE_NONINTERLACED, 0 },
3296 -       /* 1600x1200-70 */
3297 -       { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
3298 -         0, FB_VMODE_NONINTERLACED, 0 },
3299 -       /* 1600x1200-72 */
3300 -       { NULL, 72, 1600, 1200, 5053, 288, 112, 47, 13, 176, 3,
3301 -         0, FB_VMODE_NONINTERLACED, 0 },
3302 -       /* 1600x1200-75 */
3303 +         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3304 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3305 +       /* 1600x1200-75 VESA */
3306         { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
3307 -         0, FB_VMODE_NONINTERLACED, 0 },
3308 -       /* 1600x1200-85 */
3309 +         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3310 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3311 +       /* 1600x1200-85 VESA */
3312         { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
3313 -         0, FB_VMODE_NONINTERLACED, 0 },
3314 -       /* 1600x1200-90 */
3315 -       { NULL, 90, 1600, 1200, 3981, 304, 128, 60, 1, 176, 3,
3316 -         0, FB_VMODE_NONINTERLACED, 0 },
3317 -       /* 1600x1200-100 */
3318 -       { NULL, 100, 1600, 1200, 3563, 304, 128, 67, 1, 176, 3,
3319 -         0, FB_VMODE_NONINTERLACED, 0 },
3320 -       /* 1600x1200-60 */
3321 -       { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
3322           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3323 -         FB_VMODE_NONINTERLACED, 0 },
3324 -       /* 1920x1440-60 */
3325 -       { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 208, 3,
3326 -         0, FB_VMODE_NONINTERLACED, 0 },
3327 -       /* 1920x1440-70 */
3328 -       { NULL, 70, 1920, 1440, 3593, 360, 152, 55, 8, 208, 3,
3329 -         0, FB_VMODE_NONINTERLACED, 0 },
3330 -       /* 1920x1440-72 */
3331 -       { NULL, 72, 1920, 1440, 3472, 360, 152, 68, 4, 208, 3,
3332 -         0, FB_VMODE_NONINTERLACED, 0 },
3333 -       /* 1920x1440-75 */
3334 -       { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
3335 -         0, FB_VMODE_NONINTERLACED, 0 },
3336 -       /* 1920x1440-85 */
3337 -       { NULL, 85, 1920, 1440, 2929, 368, 152, 68, 1, 216, 3,
3338 -         0, FB_VMODE_NONINTERLACED, 0 },
3339 +         FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
3340 +       /* 1200x900-75 - CRT timings for the OLPC mode */
3341 +       { NULL, 75, 1200, 900, 8049, 104, 240, 29, 54, 136, 3,
3342 +         0, FB_VMODE_NONINTERLACED, 0 }
3343  };
3344  
3345 +#ifdef CONFIG_OLPC
3346 +const struct fb_videomode olpc_dcon_modedb[] __initdata = {
3347 +       /* The only mode the DCON has is 1200x900 */
3348 +       { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
3349 +         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
3350 +         FB_VMODE_NONINTERLACED, 0 }
3351 +};
3352 +#endif
3353 +
3354  static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
3355  {
3356         if (var->xres > 1920 || var->yres > 1440)
3357 @@ -379,16 +278,55 @@ static int __init lxfb_map_video_memory(struct fb_info *info,
3358         return 0;
3359  }
3360  
3361 +static int lxfb_set_gamma(struct fb_info *info, void * __user data)
3362 +{
3363 +       unsigned int gamma[LXFB_GAMMA_DWORDS];
3364 +
3365 +       if (copy_from_user(gamma, data, LXFB_GAMMA_SIZE))
3366 +               return -EFAULT;
3367 +
3368 +       lx_set_gamma(info, gamma, LXFB_GAMMA_SIZE);
3369 +       return 0;
3370 +}
3371 +
3372 +static int lxfb_get_gamma(struct fb_info *info, void * __user data)
3373 +{
3374 +       unsigned int gamma[LXFB_GAMMA_DWORDS];
3375 +       memset(gamma, 0, sizeof(gamma));
3376 +
3377 +       lx_get_gamma(info, gamma, LXFB_GAMMA_DWORDS);
3378 +
3379 +       return copy_to_user(data, gamma, LXFB_GAMMA_SIZE) ?
3380 +               -EFAULT : 0;
3381 +}
3382 +
3383 +static int lxfb_ioctl( struct fb_info *info, unsigned int cmd,
3384 +                      unsigned long arg)
3385 +{
3386 +       switch(cmd) {
3387 +       case FBIOSGAMMA:
3388 +               return lxfb_set_gamma(info, (void * __user) arg);
3389 +
3390 +       case FBIOGGAMMA:
3391 +               return lxfb_get_gamma(info, (void * __user) arg);
3392 +       }
3393 +
3394 +       return -ENOTTY;
3395 +}
3396 +
3397  static struct fb_ops lxfb_ops = {
3398         .owner          = THIS_MODULE,
3399         .fb_check_var   = lxfb_check_var,
3400         .fb_set_par     = lxfb_set_par,
3401         .fb_setcolreg   = lxfb_setcolreg,
3402         .fb_blank       = lxfb_blank,
3403 +       .fb_ioctl       = lxfb_ioctl,
3404         /* No HW acceleration for now. */
3405         .fb_fillrect    = cfb_fillrect,
3406         .fb_copyarea    = cfb_copyarea,
3407         .fb_imageblit   = cfb_imageblit,
3408 +       .fb_powerdown   = lx_shutdown,
3409 +       .fb_powerup     = lx_powerup,
3410  };
3411  
3412  static struct fb_info * __init lxfb_init_fbinfo(struct device *dev)
3413 @@ -431,6 +369,45 @@ static struct fb_info * __init lxfb_init_fbinfo(struct device *dev)
3414         return info;
3415  }
3416  
3417 +#ifdef CONFIG_PM
3418 +
3419 +static int lxfb_suspend(struct pci_dev *pdev,  pm_message_t state)
3420 +{
3421 +       struct fb_info *info = pci_get_drvdata(pdev);
3422 +
3423 +       if (pdev->dev.power.power_state.event == state.event)
3424 +               return 0;
3425 +
3426 +       if (state.event == PM_EVENT_SUSPEND) {
3427 +
3428 +               acquire_console_sem();
3429 +               lx_shutdown(info);
3430 +               fb_set_suspend(info, 1);
3431 +               release_console_sem();
3432 +       }
3433 +
3434 +       pdev->dev.power.power_state = state;
3435 +       return 0;
3436 +}
3437 +
3438 +static int lxfb_resume(struct pci_dev *pdev)
3439 +{
3440 +       struct fb_info *info = pci_get_drvdata(pdev);
3441 +
3442 +       acquire_console_sem();
3443 +
3444 +       /* Turn the engine completely on */
3445 +
3446 +       lx_powerup(info);
3447 +       fb_set_suspend(info, 0);
3448 +       release_console_sem();
3449 +
3450 +       pdev->dev.power.power_state = PMSG_ON;
3451 +        return 0;
3452 +}
3453 +
3454 +#endif
3455 +
3456  static int __init lxfb_probe(struct pci_dev *pdev,
3457                              const struct pci_device_id *id)
3458  {
3459 @@ -467,6 +444,13 @@ static int __init lxfb_probe(struct pci_dev *pdev,
3460         modedb_ptr = (struct fb_videomode *) geode_modedb;
3461         modedb_size = ARRAY_SIZE(geode_modedb);
3462  
3463 +#ifdef CONFIG_OLPC
3464 +       if (olpc_has_dcon()) {
3465 +               modedb_ptr = (struct fb_videomode *) olpc_dcon_modedb;
3466 +               modedb_size = ARRAY_SIZE(olpc_dcon_modedb);
3467 +       }
3468 +#endif
3469 +
3470         ret = fb_find_mode(&info->var, info, mode_option,
3471                            modedb_ptr, modedb_size, NULL, 16);
3472  
3473 @@ -556,6 +540,10 @@ static struct pci_driver lxfb_driver = {
3474         .id_table       = lxfb_id_table,
3475         .probe          = lxfb_probe,
3476         .remove         = lxfb_remove,
3477 +#ifdef CONFIG_PM
3478 +       .suspend        = lxfb_suspend,
3479 +       .resume         = lxfb_resume
3480 +#endif
3481  };
3482  
3483  #ifndef MODULE
3484 diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
3485 index 4fbc99b..47ed9de 100644
3486 --- a/drivers/video/geode/lxfb_ops.c
3487 +++ b/drivers/video/geode/lxfb_ops.c
3488 @@ -13,9 +13,13 @@
3489  #include <linux/fb.h>
3490  #include <linux/uaccess.h>
3491  #include <linux/delay.h>
3492 +#include <asm/olpc.h>
3493  
3494  #include "lxfb.h"
3495  
3496 +#define _GEODELX_
3497 +#include "geode_regs.h"
3498 +
3499  /* TODO
3500   * Support panel scaling
3501   * Add acceleration
3502 @@ -290,6 +294,19 @@ unsigned int lx_framebuffer_size(void)
3503  {
3504         unsigned int val;
3505  
3506 +#ifdef CONFIG_OLPC
3507 +        if (machine_is_olpc() && !olpc_has_vsa()) {
3508 +               u32 hi,lo;
3509 +               rdmsr(MSR_LX_GLIU0_P2D_RO0, lo, hi);
3510 +
3511 +               /* Top page number */
3512 +               val = ((hi & 0xff) << 12) | ((lo & 0xfff00000) >> 20);
3513 +               val -= (lo & 0x000fffff); /* Subtract bottom page number */
3514 +               val += 1;                 /* Adjust page count */
3515 +               return (val << 12);
3516 +       }
3517 +#endif
3518 +
3519         /* The frame buffer size is reported by a VSM in VSA II */
3520         /* Virtual Register Class    = 0x02                     */
3521         /* VG_MEM_SIZE (1MB units)   = 0x00                     */
3522 @@ -301,6 +318,34 @@ unsigned int lx_framebuffer_size(void)
3523         return (val << 20);
3524  }
3525  
3526 +void lx_set_gamma(struct fb_info *info, unsigned int *gamma, int len)
3527 +{
3528 +       int i;
3529 +       struct lxfb_par *par = info->par;
3530 +
3531 +       writel(0, par->df_regs + DF_PAR);
3532 +
3533 +       /* Sequential writes to the data register will increment the
3534 +          address automatically  */
3535 +
3536 +       for(i = 0; i < len; i++)
3537 +               writel(gamma[i] & 0xFFFFFF, par->df_regs + DF_PDR);
3538 +
3539 +       writel(readl(par->df_regs + DF_MISC) & ~DF_MISC_GAM_BYPASS,
3540 +              par->df_regs + DF_MISC);
3541 +}
3542 +
3543 +void lx_get_gamma(struct fb_info *info, unsigned int *gamma, int len)
3544 +{
3545 +       int i;
3546 +       struct lxfb_par *par = info->par;
3547 +
3548 +       writel(0, par->df_regs + DF_PAR);
3549 +
3550 +       for(i = 0; i < len;i++)
3551 +               gamma[i] = readl(par->df_regs + DF_PDR);
3552 +}
3553 +
3554  void lx_set_mode(struct fb_info *info)
3555  {
3556         struct lxfb_par *par = info->par;
3557 @@ -313,6 +358,7 @@ void lx_set_mode(struct fb_info *info)
3558         int vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal;
3559  
3560         /* Unlock the DC registers */
3561 +       readl(par->dc_regs + DC_UNLOCK);
3562         writel(DC_UNLOCK_CODE, par->dc_regs + DC_UNLOCK);
3563  
3564         lx_graphics_disable(info);
3565 @@ -534,3 +580,285 @@ int lx_blank_display(struct fb_info *info, int blank_mode)
3566  
3567         return 0;
3568  }
3569 +
3570 +static struct geoderegs saved_regs;
3571 +
3572 +static void lx_save_regs(struct fb_info *info, struct geoderegs *regs)
3573 +{
3574 +       struct lxfb_par *par = info->par;
3575 +       int i;
3576 +
3577 +       /* Wait for the command buffer to empty */
3578 +       while(!(readl(par->gp_regs + 0x44) & (1 << 4)));
3579 +
3580 +       rdmsrl(MSR_LX_DF_PADSEL, regs->msr.padsel);
3581 +       rdmsrl(MSR_LX_GLCP_DOTPLL, regs->msr.dotpll);
3582 +       rdmsrl(MSR_LX_DF_GLCONFIG, regs->msr.dfglcfg);
3583 +       rdmsrl(MSR_LX_DC_SPARE, regs->msr.dcspare);
3584 +
3585 +       writel(0x4758, par->dc_regs + 0x00);
3586 +
3587 +       memcpy(regs->gp.b, par->gp_regs, GP_REG_SIZE);
3588 +       memcpy(regs->dc.b, par->dc_regs, DC_REG_SIZE);
3589 +       memcpy(regs->vp.b, par->df_regs, VP_REG_SIZE);
3590 +       memcpy(regs->fp.b, par->df_regs + VP_FP_START, FP_REG_SIZE);
3591 +
3592 +       /* Save the palettes */
3593 +       writel(0, par->dc_regs + 0x70);
3594 +
3595 +       for(i = 0; i < DC_PAL_SIZE; i++) 
3596 +               regs->pal[i] = readl(par->dc_regs + 0x74);
3597 +       
3598 +       writel(0, par->df_regs + 0x38);
3599 +
3600 +       for(i = 0; i <= 0xFF; i++)
3601 +               regs->gamma[i] = readl(par->df_regs + 0x40);
3602 +}
3603 +
3604 +static void lx_restore_regs(struct fb_info *info, struct geoderegs *regs)
3605 +{
3606 +       struct lxfb_par *par = info->par;
3607 +       u32 val, i;
3608 +
3609 +       /* == DOTPLL == */
3610 +
3611 +       lx_set_dotpll((u32) (regs->msr.dotpll >> 32));
3612 +
3613 +       /* MSRs */
3614 +
3615 +       wrmsrl(MSR_LX_DF_GLCONFIG, regs->msr.dfglcfg);
3616 +
3617 +       /* == GP == */
3618 +
3619 +       writel(regs->gp.r.dst_offset, par->gp_regs + 0x00);
3620 +       writel(regs->gp.r.src_offset, par->gp_regs + 0x04);
3621 +       writel(regs->gp.r.stride, par->gp_regs + 0x08);
3622 +       writel(regs->gp.r.wid_height, par->gp_regs + 0x0C);
3623 +       writel(regs->gp.r.src_color_fg, par->gp_regs + 0x10);
3624 +       writel(regs->gp.r.src_color_bg, par->gp_regs + 0x14);
3625 +       writel(regs->gp.r.pat_color_0, par->gp_regs + 0x18);
3626 +       writel(regs->gp.r.pat_color_1, par->gp_regs + 0x1C);
3627 +       writel(regs->gp.r.pat_color_2, par->gp_regs + 0x20);
3628 +       writel(regs->gp.r.pat_color_3, par->gp_regs + 0x24);
3629 +       writel(regs->gp.r.pat_color_4, par->gp_regs + 0x28);
3630 +       writel(regs->gp.r.pat_color_5, par->gp_regs + 0x2C);
3631 +       writel(regs->gp.r.pat_data_0, par->gp_regs + 0x30);
3632 +       writel(regs->gp.r.pat_data_1, par->gp_regs + 0x34);
3633 +
3634 +       /* Writing to these registers would cause a blt to happen */
3635 +       /* 0x38, 0x3c, 0x40 */
3636 +
3637 +       /* Status register (0x44) is read only */
3638 +
3639 +       writel(regs->gp.r.hst_src, par->gp_regs + 0x48);
3640 +       writel(regs->gp.r.base_offset, par->gp_regs + 0x4c);
3641 +       writel(regs->gp.r.cmd_top, par->gp_regs + 0x50);
3642 +       writel(regs->gp.r.cmd_bot, par->gp_regs + 0x54);
3643 +       writel(regs->gp.r.cmd_read, par->gp_regs + 0x58);
3644 +       writel(regs->gp.r.cmd_write, par->gp_regs + 0x5C);
3645 +       writel(regs->gp.r.ch3_offset, par->gp_regs + 0x60);
3646 +       writel(regs->gp.r.ch3_mode_str, par->gp_regs + 0x64);
3647 +       writel(regs->gp.r.ch3_width, par->gp_regs + 0x6C);
3648 +       writel(regs->gp.r.ch3_hsrc, par->gp_regs + 0x70);
3649 +
3650 +       /* FIXME:  Restore the LUT data here */
3651 +
3652 +       writel(regs->gp.r.int_cntrl, par->gp_regs + 0x70);
3653 +
3654 +       /* == DC == */
3655 +
3656 +       /* Write the unlock value */
3657 +       writel(0x4758, par->dc_regs + 0x00);
3658 +
3659 +       /* Write the palette data first */
3660 +
3661 +       writel(0, par->dc_regs + 0x70);
3662 +
3663 +       for(i = 0; i < DC_PAL_SIZE; i++)
3664 +               writel(regs->pal[i], par->dc_regs + 0x74);
3665 +
3666 +       /* MSRs */
3667 +       wrmsrl(MSR_LX_DC_SPARE, regs->msr.dcspare);
3668 +
3669 +       /* Write the gcfg register without the enables */
3670 +       writel(regs->dc.r.gcfg & ~0x0F, par->dc_regs + 0x04);
3671 +
3672 +       /* Write the vcfg register without the enables */
3673 +       writel(regs->dc.r.dcfg & ~0x19, par->dc_regs + 0x08);
3674 +
3675 +       /* Write the rest of the active registers */
3676 +       writel(regs->dc.r.arb, par->dc_regs + 0x0C);
3677 +       writel(regs->dc.r.fb_st_offset, par->dc_regs + 0x10);
3678 +       writel(regs->dc.r.cb_st_offset, par->dc_regs + 0x14);
3679 +       writel(regs->dc.r.curs_st_offset, par->dc_regs + 0x18);
3680 +       writel(regs->dc.r.icon_st_offset, par->dc_regs + 0x1C);
3681 +       writel(regs->dc.r.vid_y_st_offset, par->dc_regs + 0x20);
3682 +       writel(regs->dc.r.vid_u_st_offset, par->dc_regs + 0x24);
3683 +       writel(regs->dc.r.vid_v_st_offset, par->dc_regs + 0x28);
3684 +       writel(regs->dc.r.dctop, par->dc_regs + 0x2c);
3685 +       writel(regs->dc.r.line_size, par->dc_regs + 0x30);
3686 +       writel(regs->dc.r.gfx_pitch, par->dc_regs + 0x34);
3687 +       writel(regs->dc.r.vid_yuv_pitch, par->dc_regs + 0x38);
3688 +       writel(regs->dc.r.h_active_timing, par->dc_regs + 0x40);
3689 +       writel(regs->dc.r.h_blank_timing, par->dc_regs + 0x44);
3690 +       writel(regs->dc.r.h_sync_timing, par->dc_regs + 0x48);
3691 +       writel(regs->dc.r.v_active_timing, par->dc_regs + 0x50);
3692 +       writel(regs->dc.r.v_blank_timing, par->dc_regs + 0x54);
3693 +       writel(regs->dc.r.v_sync_timing, par->dc_regs + 0x58);
3694 +       writel(regs->dc.r.fbactive, par->dc_regs + 0x5c);
3695 +       writel(regs->dc.r.dc_cursor_x, par->dc_regs + 0x60);
3696 +       writel(regs->dc.r.dc_cursor_y, par->dc_regs + 0x64);
3697 +       writel(regs->dc.r.dc_icon_x, par->dc_regs + 0x68);
3698 +
3699 +       /* Skip register 0x6C (line_cnt), 0x70/0x74 (palette),
3700 +          0x78 (diagnostic), and 0x7c (diagnostic)
3701 +       */
3702 +
3703 +       writel(regs->dc.r.dc_vid_ds_delta, par->dc_regs + 0x80);
3704 +       writel(regs->dc.r.gliu0_mem_offset, par->dc_regs + 0x84);
3705 +       writel(regs->dc.r.dv_ctl, par->dc_regs + 0x88);
3706 +       writel(regs->dc.r.dv_acc, par->dc_regs + 0x8C);
3707 +
3708 +       writel(regs->dc.r.gfx_scale, par->dc_regs + 0x90);
3709 +       writel(regs->dc.r.irq_filt_ctl, par->dc_regs + 0x94);
3710 +       writel(regs->dc.r.filt_coeff1, par->dc_regs + 0x98);
3711 +       writel(regs->dc.r.filt_coeff2, par->dc_regs + 0x9C);
3712 +       writel(regs->dc.r.vbi_event_ctl, par->dc_regs + 0xA0);
3713 +
3714 +       writel(regs->dc.r.vbi_odd_ctl, par->dc_regs + 0xA4);
3715 +       writel(regs->dc.r.vbi_hor, par->dc_regs + 0xA8);
3716 +       writel(regs->dc.r.vbi_ln_odd, par->dc_regs + 0xAC);
3717 +       writel(regs->dc.r.vbi_ln_event, par->dc_regs + 0xB0);
3718 +       writel(regs->dc.r.vbi_pitch, par->dc_regs + 0xB4);
3719 +       writel(regs->dc.r.clr_key, par->dc_regs + 0xB8);
3720 +       writel(regs->dc.r.clr_key_mask, par->dc_regs + 0xBC);
3721 +
3722 +       writel(regs->dc.r.clr_key_x, par->dc_regs + 0xC0);
3723 +       writel(regs->dc.r.clr_key_y, par->dc_regs + 0xC4);
3724 +       writel(regs->dc.r.irq, par->dc_regs + 0xC8);
3725 +       writel(regs->dc.r.genlk_ctrl, par->dc_regs + 0xD4);
3726 +
3727 +       writel(regs->dc.r.vid_even_y_st_offset, par->dc_regs + 0xD8);
3728 +       writel(regs->dc.r.vid_even_u_st_offset, par->dc_regs + 0xDC);
3729 +       writel(regs->dc.r.vid_even_v_st_offset, par->dc_regs + 0xE0);
3730 +
3731 +       writel(regs->dc.r.v_active_even_timing, par->dc_regs + 0xE4);
3732 +       writel(regs->dc.r.v_blank_even_timing, par->dc_regs + 0xE8);
3733 +       writel(regs->dc.r.v_sync_even_timing, par->dc_regs + 0xEC);
3734 +
3735 +       /* == VP == */
3736 +
3737 +       /* MSR */
3738 +       wrmsrl(MSR_LX_DF_PADSEL, regs->msr.padsel);
3739 +
3740 +       /* Write gamma information first */
3741 +
3742 +       writel(0, par->df_regs + 0x38);
3743 +
3744 +       for(i = 0; i <= 0xFF; i++)
3745 +               writel((u32) regs->gamma[i], par->df_regs + 0x40);
3746 +
3747 +       /* Don't enable video yet */
3748 +       writel((u32) regs->vp.r.vcfg & ~0x01, par->df_regs + 0x00);
3749 +
3750 +       /* Don't enable the CRT yet */
3751 +       writel((u32) regs->vp.r.dcfg & ~0x0F, par->df_regs + 0x08);
3752 +
3753 +       /* Write the rest of the VP registers */
3754 +
3755 +       writel((u32) regs->vp.r.vx, par->df_regs + 0x10);
3756 +       writel((u32) regs->vp.r.vy, par->df_regs + 0x18);
3757 +       writel((u32) regs->vp.r.vs, par->df_regs + 0x20);
3758 +       writel((u32) regs->vp.r.vck, par->df_regs + 0x28);
3759 +       writel((u32) regs->vp.r.vcm, par->df_regs + 0x30);
3760 +       writel((u32) regs->vp.r.misc, par->df_regs + 0x50);
3761 +       writel((u32) regs->vp.r.ccs, par->df_regs + 0x58);
3762 +       writel((u32) regs->vp.r.vdc, par->df_regs + 0x78);
3763 +       writel((u32) regs->vp.r.vco, par->df_regs + 0x80);
3764 +       writel((u32) regs->vp.r.crc, par->df_regs + 0x88);
3765 +       writel((u32) regs->vp.r.vde, par->df_regs + 0x98);
3766 +       writel((u32) regs->vp.r.cck, par->df_regs + 0xA0);
3767 +       writel((u32) regs->vp.r.ccm, par->df_regs + 0xA8);
3768 +       writel((u32) regs->vp.r.cc1, par->df_regs + 0xB0);
3769 +       writel((u32) regs->vp.r.cc2, par->df_regs + 0xB8);
3770 +       writel((u32) regs->vp.r.a1x, par->df_regs + 0xC0);
3771 +       writel((u32) regs->vp.r.a1y, par->df_regs + 0xC8);
3772 +       writel((u32) regs->vp.r.a1c, par->df_regs + 0xD0);
3773 +       writel((u32) regs->vp.r.a1t, par->df_regs + 0xD8);
3774 +       writel((u32) regs->vp.r.a2x, par->df_regs + 0xE0);
3775 +       writel((u32) regs->vp.r.a2y, par->df_regs + 0xE8);
3776 +       writel((u32) regs->vp.r.a2c, par->df_regs + 0xF0);
3777 +       writel((u32) regs->vp.r.a2t, par->df_regs + 0xF8);
3778 +       writel((u32) regs->vp.r.a3x, par->df_regs + 0x100);
3779 +       writel((u32) regs->vp.r.a3y, par->df_regs + 0x108);
3780 +       writel((u32) regs->vp.r.a3c, par->df_regs + 0x110);
3781 +       writel((u32) regs->vp.r.a3t, par->df_regs + 0x118);
3782 +       writel((u32) regs->vp.r.vrr, par->df_regs + 0x120);
3783 +
3784 +       writel((u32) regs->vp.r.vye, par->df_regs + 0x138);
3785 +       writel((u32) regs->vp.r.a1ye, par->df_regs + 0x140);
3786 +       writel((u32) regs->vp.r.a2ye, par->df_regs + 0x148);
3787 +       writel((u32) regs->vp.r.a3ye, par->df_regs + 0x150);
3788 +
3789 +       /* == FP == */
3790 +
3791 +       writel((u32) regs->fp.r.pt1, par->df_regs + 0x400);
3792 +       writel((u32) regs->fp.r.pt2, par->df_regs + 0x408);
3793 +       writel((u32) regs->fp.r.dfc, par->df_regs + 0x418);
3794 +       writel(regs->fp.r.dca, par->df_regs + 0x448);
3795 +       writel(regs->fp.r.dmd, par->df_regs + 0x450);
3796 +       writel(regs->fp.r.crc, par->df_regs + 0x458);
3797 +
3798 +       /* Final enables */
3799 +
3800 +       val = readl(par->df_regs + 0x410);
3801 +
3802 +       /* Control the panel */
3803 +       if (regs->fp.r.pm & (1 << 24)) {
3804 +
3805 +               if (!(val & 0x09))
3806 +                       writel(regs->fp.r.pm, par->df_regs + 0x410);
3807 +       }
3808 +       else {
3809 +               if (!(val & 0x05))
3810 +                       writel(regs->fp.r.pm, par->df_regs + 0x410);
3811 +       }
3812 +
3813 +       /* Turn everything on */
3814 +
3815 +       writel(regs->dc.r.gcfg, par->dc_regs + 0x04);
3816 +       writel((u32) regs->vp.r.vcfg, par->df_regs + 0x00);
3817 +       writel((u32) regs->vp.r.dcfg, par->df_regs + 0x08);
3818 +       writel(regs->dc.r.dcfg, par->dc_regs + 0x08);
3819 +}
3820 +
3821 +static int lx_power_on = 1;
3822 +
3823 +int lx_shutdown(struct fb_info *info)
3824 +{
3825 +       struct lxfb_par *par = info->par;
3826 +
3827 +       if (lx_power_on == 0)
3828 +               return 0;
3829 +
3830 +       writel(DC_UNLOCK_CODE, par->dc_regs + DC_UNLOCK);
3831 +       lx_save_regs(info, &saved_regs);
3832 +       lx_graphics_disable(info);
3833 +
3834 +       lx_power_on = 0;
3835 +       return 0;
3836 +}
3837 +
3838 +int lx_powerup(struct fb_info *info)
3839 +{
3840 +       struct lxfb_par *par = info->par;
3841 +
3842 +       if (lx_power_on == 1)
3843 +               return 0;
3844 +
3845 +       lx_restore_regs(info, &saved_regs);
3846 +       writel(0, par->dc_regs + DC_UNLOCK);
3847 +
3848 +       lx_power_on = 1;
3849 +       return 0;
3850 +}
3851 diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
3852 index 7f3f18d..e282e74 100644
3853 --- a/drivers/video/geode/video_gx.c
3854 +++ b/drivers/video/geode/video_gx.c
3855 @@ -16,10 +16,14 @@
3856  #include <asm/io.h>
3857  #include <asm/delay.h>
3858  #include <asm/msr.h>
3859 +#include <asm/olpc.h>
3860  
3861  #include "geodefb.h"
3862  #include "video_gx.h"
3863 +#include "display_gx.h"
3864  
3865 +/* This structure is used to store the saved registers during suspend */
3866 +static struct geoderegs gx_saved_regs;
3867  
3868  /*
3869   * Tables of register settings for various DOTCLKs.
3870 @@ -58,7 +62,7 @@ static const struct gx_pll_entry gx_pll_table_48MHz[] = {
3871         { 13888, POSTDIV3,          0x000007E1 },       /*  72.0000 */
3872         { 13426, PREMULT2,          0x00000F4A },       /*  74.4810 */
3873         { 13333, 0,                 0x00000052 },       /*  75.0000 */
3874 -       { 12698, 0,                 0x00000056 },       /*  78.7500 */
3875 +       { 12698, 0,                 0x00000056 },       /*  78.7500 */
3876         { 12500, POSTDIV3|PREMULT2, 0x00000709 },       /*  80.0000 */
3877         { 11135, PREMULT2,          0x00000262 },       /*  89.8000 */
3878         { 10582, 0,                 0x000002D2 },       /*  94.5000 */
3879 @@ -117,8 +121,9 @@ static const struct gx_pll_entry gx_pll_table_14MHz[] = {
3880         {  4357, 0, 0x0000057D },       /* 229.5000 */
3881  };
3882  
3883 -static void gx_set_dclk_frequency(struct fb_info *info)
3884 +void gx_set_dclk_frequency(struct fb_info *info)
3885  {
3886 +       struct geodefb_par *par = info->par;
3887         const struct gx_pll_entry *pll_table;
3888         int pll_table_len;
3889         int i, best_i;
3890 @@ -173,115 +178,169 @@ static void gx_set_dclk_frequency(struct fb_info *info)
3891         do {
3892                 rdmsrl(MSR_GLCP_DOTPLL, dotpll);
3893         } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
3894 +
3895 +       par->curdclk = pll_table[best_i].dotpll_value;
3896  }
3897  
3898 -static void
3899 -gx_configure_tft(struct fb_info *info)
3900 +/* Find out the current clock - we will use this information to avoid
3901 +   re-programming it if we don't need to */
3902 +
3903 +unsigned int gx_get_dclk(struct fb_info *info)
3904  {
3905 -       struct geodefb_par *par = info->par;
3906 -       unsigned long val;
3907 -       unsigned long fp;
3908 +       const struct gx_pll_entry *pll_table;
3909 +       int pll_table_len;
3910 +       u64 dotpll;
3911 +       int i;
3912  
3913 -       /* Set up the DF pad select MSR */
3914 +       if (cpu_data->x86_mask == 1) {
3915 +               pll_table = gx_pll_table_14MHz;
3916 +               pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz);
3917 +       } else {
3918 +               pll_table = gx_pll_table_48MHz;
3919 +               pll_table_len = ARRAY_SIZE(gx_pll_table_48MHz);
3920 +       }
3921  
3922 -       rdmsrl(GX_VP_MSR_PAD_SELECT, val);
3923 -       val &= ~GX_VP_PAD_SELECT_MASK;
3924 -       val |= GX_VP_PAD_SELECT_TFT;
3925 -       wrmsrl(GX_VP_MSR_PAD_SELECT, val);
3926 +       rdmsrl(MSR_GLCP_DOTPLL, dotpll);
3927  
3928 -       /* Turn off the panel */
3929 +       for(i = 0; i < pll_table_len; i++) {
3930 +               if (pll_table[i].dotpll_value == (u32) (dotpll >> 32))
3931 +                       break;
3932 +       }
3933  
3934 -       fp = readl(par->vid_regs + GX_FP_PM);
3935 -       fp &= ~GX_FP_PM_P;
3936 -       writel(fp, par->vid_regs + GX_FP_PM);
3937 +       return (i == pll_table_len) ? 0 : pll_table[i].pixclock;
3938 +}
3939 +
3940 +
3941 +#define CMP(val, mask, res) (((val) & (mask)) == (res))
3942  
3943 -       /* Set timing 1 */
3944 +static void
3945 +gx_configure_tft(struct fb_info *info) {
3946  
3947 -       fp = readl(par->vid_regs + GX_FP_PT1);
3948 -       fp &= GX_FP_PT1_VSIZE_MASK;
3949 -       fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT;
3950 -       writel(fp, par->vid_regs + GX_FP_PT1);
3951 +       struct geodefb_par *par = info->par;
3952 +       u32 val, fp = 0, fp1, fp2, sync = 0;
3953  
3954 -       /* Timing 2 */
3955 -       /* Set bits that are always on for TFT */
3956 +       /* Set up the DF pad select MSR */
3957  
3958 -       fp = 0x0F100000;
3959 +       rdmsrl(GX_VP_MSR_PAD_SELECT, val);
3960  
3961 -       /* Add sync polarity */
3962 +       if ((val & GX_VP_PAD_SELECT_MASK) != GX_VP_PAD_SELECT_TFT) {
3963 +               val &= ~GX_VP_PAD_SELECT_MASK;
3964 +               val |= GX_VP_PAD_SELECT_TFT;
3965 +               wrmsrl(GX_VP_MSR_PAD_SELECT, val);
3966 +       }
3967  
3968         if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
3969 -               fp |= GX_FP_PT2_VSP;
3970 +               sync |= GX_FP_PT2_VSP;
3971  
3972         if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
3973 -               fp |= GX_FP_PT2_HSP;
3974 +               sync |= GX_FP_PT2_HSP;
3975  
3976 -       writel(fp, par->vid_regs + GX_FP_PT2);
3977 +       /* We only need to turn off the panel if something changed */
3978  
3979 -       /*  Set the dither control */
3980 -       writel(0x70, par->vid_regs + GX_FP_DFC);
3981 +       fp1 = readl(par->vid_regs + GX_FP_PT1);
3982 +       fp2 = readl(par->vid_regs + GX_FP_PT2);
3983 +
3984 +       if (!CMP(fp1, GX_FP_PT1_VSIZE_MASK, info->var.yres << GX_FP_PT1_VSIZE_SHIFT) ||
3985 +           (fp2 != (0x0F100000 | sync))) {
3986  
3987 -       /* Enable the FP data and power (in case the BIOS didn't) */
3988 +               /* Turn off the panel */
3989  
3990 -       fp = readl(par->vid_regs + GX_DCFG);
3991 -       fp |= GX_DCFG_FP_PWR_EN | GX_DCFG_FP_DATA_EN;
3992 -       writel(fp, par->vid_regs + GX_DCFG);
3993 +#ifdef NOTUSED
3994 +               /* Do we really need to turn off the panel? */
3995 +               /* Possibly - we have a glitch somewhere */
3996  
3997 -       /* Unblank the panel */
3998 +               fp = readl(par->vid_regs + GX_FP_PM);
3999 +               fp &= ~GX_FP_PM_P;
4000 +               writel(fp, par->vid_regs + GX_FP_PM);
4001 +#endif
4002 +
4003 +               /* Timing 1 */
4004 +               fp1 &= GX_FP_PT1_VSIZE_MASK;
4005 +               fp1 |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT;
4006 +               writel(fp, par->vid_regs + GX_FP_PT1);
4007 +
4008 +               /* Timing 2 */
4009 +               writel(0x0F100000 | sync, par->vid_regs + GX_FP_PT2);
4010 +       }
4011 +
4012 +       /*  Set the dither control */
4013 +       if (readl(par->vid_regs + GX_FP_DFC) != 0x70) {
4014 +               writel(0x70, par->vid_regs + GX_FP_DFC);
4015 +       }
4016 +
4017 +       /* Turn on the panel */
4018  
4019         fp = readl(par->vid_regs + GX_FP_PM);
4020 -       fp |= GX_FP_PM_P;
4021 -       writel(fp, par->vid_regs + GX_FP_PM);
4022 +
4023 +       if (!(fp & 0x09))
4024 +               writel(fp | GX_FP_PM_P, par->vid_regs + GX_FP_PM);
4025  }
4026  
4027 +#define DCFG_DEFAULT_VAL GX_DCFG_CRT_SYNC_SKW_DFLT | GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN | \
4028 +GX_DCFG_CRT_EN | GX_DCFG_DAC_BL_EN
4029 +
4030  static void gx_configure_display(struct fb_info *info)
4031  {
4032         struct geodefb_par *par = info->par;
4033 -       u32 dcfg, misc;
4034 +       u32 dcfg, misc, sync = 0;
4035  
4036         /* Set up the MISC register */
4037 -
4038         misc = readl(par->vid_regs + GX_MISC);
4039  
4040 -       /* Power up the DAC */
4041 -       misc &= ~(GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN);
4042 +       /* We leave gamma enabled if it was already enabled.
4043 +          Although the hardware enables it without setting
4044 +          up the gamma table, the BIOS or bootloader ought
4045 +          to have either disabled it or loaded a table by now */
4046  
4047 -       /* Disable gamma correction */
4048 -       misc |= GX_MISC_GAM_EN;
4049  
4050 -       writel(misc, par->vid_regs + GX_MISC);
4051  
4052 -       /* Write the display configuration */
4053 -       dcfg = readl(par->vid_regs + GX_DCFG);
4054 +       if (par->enable_crt) {
4055 +               /* Power up the CRT DACs */
4056 +               if (misc & ( GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN)) {
4057 +                       misc &= ~(GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN);
4058 +                       writel(misc, par->vid_regs + GX_MISC);
4059 +               }
4060  
4061 -       /* Disable hsync and vsync */
4062 -       dcfg &= ~(GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN);
4063 -       writel(dcfg, par->vid_regs + GX_DCFG);
4064 +               if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
4065 +                       sync |= GX_DCFG_CRT_HSYNC_POL;
4066  
4067 -       /* Clear bits from existing mode. */
4068 -       dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK
4069 -                 | GX_DCFG_CRT_HSYNC_POL   | GX_DCFG_CRT_VSYNC_POL
4070 -                 | GX_DCFG_VSYNC_EN        | GX_DCFG_HSYNC_EN);
4071 +               if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
4072 +                       sync |= GX_DCFG_CRT_VSYNC_POL;
4073 +       }
4074 +       else {
4075 +               /* Turn off the CRT DACs in FP mode - we don't need them */
4076 +               if ((misc & (GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN))) {
4077 +                       misc |= (GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN);
4078 +                       writel(misc, par->vid_regs + GX_MISC);
4079 +               }
4080 +       }
4081  
4082 -       /* Set default sync skew.  */
4083 -       dcfg |= GX_DCFG_CRT_SYNC_SKW_DFLT;
4084 +       /* Write the display configuration */
4085 +       dcfg = readl(par->vid_regs + GX_DCFG);
4086  
4087 -       /* Enable hsync and vsync. */
4088 -       dcfg |= GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN;
4089 +       if (!CMP(dcfg, DCFG_DEFAULT_VAL | GX_DCFG_CRT_HSYNC_POL | GX_DCFG_CRT_VSYNC_POL,
4090 +                DCFG_DEFAULT_VAL | sync)) {
4091  
4092 -       /* Sync polarities. */
4093 -       if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
4094 -               dcfg |= GX_DCFG_CRT_HSYNC_POL;
4095 -       if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
4096 -               dcfg |= GX_DCFG_CRT_VSYNC_POL;
4097 +               /* Disable hsync and vsync */
4098 +               dcfg &= ~(GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN);
4099 +               writel(dcfg, par->vid_regs + GX_DCFG);
4100  
4101 -       /* Enable the display logic */
4102 -       /* Set up the DACS to blank normally */
4103 +               /* Clear bits from existing mode. */
4104 +               dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK
4105 +                         | GX_DCFG_CRT_HSYNC_POL   | GX_DCFG_CRT_VSYNC_POL
4106 +                         | GX_DCFG_VSYNC_EN        | GX_DCFG_HSYNC_EN);
4107  
4108 -       dcfg |= GX_DCFG_CRT_EN | GX_DCFG_DAC_BL_EN;
4109 +               /* Set default sync skew.  */
4110 +               dcfg |= GX_DCFG_CRT_SYNC_SKW_DFLT;
4111  
4112 -       /* Enable the external DAC VREF? */
4113 +               /* Enable hsync and vsync. */
4114 +               dcfg |= GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN;
4115  
4116 -       writel(dcfg, par->vid_regs + GX_DCFG);
4117 +               /* Enable the display logic */
4118 +               dcfg |= GX_DCFG_CRT_EN | GX_DCFG_DAC_BL_EN;
4119 +
4120 +               writel(dcfg, par->vid_regs + GX_DCFG);
4121 +       }
4122  
4123         /* Set up the flat panel (if it is enabled) */
4124  
4125 @@ -289,6 +348,100 @@ static void gx_configure_display(struct fb_info *info)
4126                 gx_configure_tft(info);
4127  }
4128  
4129 +int gxfb_powerdown(struct fb_info *info) 
4130 +{
4131 +       struct geodefb_par *par = info->par;
4132 +
4133 +       /* We're already suspended */
4134 +
4135 +       if (par->state != FB_POWER_STATE_ON)
4136 +               return 0;
4137 +
4138 +       /* Save the registers */
4139 +       gx_save_regs(info, &gx_saved_regs);
4140 +
4141 +       /* Shut down the engine */
4142 +
4143 +       writel(gx_saved_regs.vp.r.vcfg & ~0x01, par->vid_regs + GX_VCFG);
4144 +       writel(gx_saved_regs.vp.r.dcfg & ~0x0F, par->vid_regs + GX_DCFG);
4145 +
4146 +       /* Turn off the flat panel unless we are attached to a DCON */
4147 +       if (!olpc_has_dcon())
4148 +               writel(gx_saved_regs.fp.r.pm & ~GX_FP_PM_P, par->vid_regs + GX_FP_PM);
4149 +
4150 +       writel(0x4758, par->dc_regs + DC_UNLOCK);
4151 +
4152 +       writel(gx_saved_regs.dc.r.gcfg & ~0x0F,
4153 +              par->dc_regs + DC_GENERAL_CFG);
4154 +
4155 +       writel(gx_saved_regs.dc.r.dcfg & ~0x19,
4156 +              par->dc_regs + DC_DISPLAY_CFG);
4157 +       
4158 +       par->state = FB_POWER_STATE_SUSPEND;
4159 +
4160 +       return 0;
4161 +}
4162 +
4163 +int gxfb_powerup(struct fb_info *info)
4164 +{
4165 +       struct geodefb_par *par = info->par;
4166 +       u32 val;
4167 +
4168 +       if (par->state == FB_POWER_STATE_SUSPEND) {
4169 +
4170 +               writel(gx_saved_regs.dc.r.dcfg,
4171 +                      par->dc_regs + DC_DISPLAY_CFG);
4172 +
4173 +               writel(gx_saved_regs.vp.r.vcfg, par->vid_regs + GX_VCFG);
4174 +               writel(gx_saved_regs.vp.r.dcfg, par->vid_regs + GX_DCFG);
4175 +
4176 +               val = readl(par->vid_regs + GX_FP_PM);
4177 +
4178 +               /* power up the panel if it needs it; we don't always power it down */
4179 +               if (!(val & 0x09)) {
4180 +                       writel(gx_saved_regs.fp.r.pm, par->vid_regs + GX_FP_PM);
4181 +                       mdelay(64);
4182 +               }
4183 +       }
4184 +
4185 +       /* If the panel is currently on its way up, then wait up to 100ms
4186 +          for it */
4187 +       
4188 +       if (readl(par->vid_regs + GX_FP_PM) & 0x08) {
4189 +               int i;
4190 +               
4191 +               for(i = 0; i < 10; i++) {
4192 +                       if (readl(par->vid_regs + GX_FP_PM) & 0x01)
4193 +                               break;
4194 +
4195 +                       mdelay(10);
4196 +               }
4197 +
4198 +               if (i == 10) 
4199 +                       printk(KERN_ERR "gxfb:  Panel power up timed out\n");
4200 +       }
4201 +
4202 +       if (par->state == FB_POWER_STATE_ON)
4203 +               return 0;
4204 +       
4205 +       switch(par->state) {
4206 +       case FB_POWER_STATE_OFF:
4207 +               gx_restore_regs(info, &gx_saved_regs);
4208 +               break;
4209 +
4210 +       case FB_POWER_STATE_SUSPEND:
4211 +               /* Do this because it will turn on the FIFO which will
4212 +                  start the line count */
4213 +               writel(gx_saved_regs.dc.r.gcfg,
4214 +                      par->dc_regs + DC_GENERAL_CFG);
4215 +               writel(0x0, par->dc_regs + DC_UNLOCK);
4216 +               break;
4217 +       }
4218 +
4219 +       par->state = FB_POWER_STATE_ON;
4220 +       return 0;
4221 +}
4222 +
4223  static int gx_blank_display(struct fb_info *info, int blank_mode)
4224  {
4225         struct geodefb_par *par = info->par;
4226 @@ -315,6 +468,7 @@ static int gx_blank_display(struct fb_info *info, int blank_mode)
4227         default:
4228                 return -EINVAL;
4229         }
4230 +
4231         dcfg = readl(par->vid_regs + GX_DCFG);
4232         dcfg &= ~(GX_DCFG_DAC_BL_EN
4233                   | GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN);
4234 @@ -326,7 +480,7 @@ static int gx_blank_display(struct fb_info *info, int blank_mode)
4235                 dcfg |= GX_DCFG_VSYNC_EN;
4236         writel(dcfg, par->vid_regs + GX_DCFG);
4237  
4238 -       /* Power on/off flat panel. */
4239 +       /* Power on/off flat panel */
4240  
4241         if (par->enable_crt == 0) {
4242                 fp_pm = readl(par->vid_regs + GX_FP_PM);
4243 @@ -340,8 +494,37 @@ static int gx_blank_display(struct fb_info *info, int blank_mode)
4244         return 0;
4245  }
4246  
4247 +extern struct fb_info *gxfb_info;
4248 +
4249 +/* This function controls the flatpanel power sequencing - this is used
4250 +   by the OLPC power management engine to enable the FP sequencing much
4251 +   earlier in the resume process
4252 +*/
4253 +
4254 +void gxfb_flatpanel_control(int state)
4255 +{
4256 +       struct geodefb_par *par = gxfb_info->par;
4257 +       u32 val, fp = readl(par->vid_regs + GX_FP_PM);
4258 +       val  = fp;
4259 +
4260 +       /* Turn on the panel if it isn't aleady */
4261 +
4262 +       if (state) {
4263 +               if (!(val & 0x01))
4264 +                       val |= GX_FP_PM_P;
4265 +       }
4266 +       else {
4267 +               if (!(val & 0x02))
4268 +                       val &= ~GX_FP_PM_P;
4269 +       }
4270 +
4271 +       if (val != fp)
4272 +               writel(val, par->vid_regs + GX_FP_PM);
4273 +}
4274 +
4275  struct geode_vid_ops gx_vid_ops = {
4276         .set_dclk          = gx_set_dclk_frequency,
4277 +       .get_dclk          = gx_get_dclk,
4278         .configure_display = gx_configure_display,
4279         .blank_display     = gx_blank_display,
4280  };
4281 diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h
4282 index ce28d8f..c57b36b 100644
4283 --- a/drivers/video/geode/video_gx.h
4284 +++ b/drivers/video/geode/video_gx.h
4285 @@ -11,6 +11,8 @@
4286  #ifndef __VIDEO_GX_H__
4287  #define __VIDEO_GX_H__
4288  
4289 +#include "geode_regs.h"
4290 +
4291  extern struct geode_vid_ops gx_vid_ops;
4292  
4293  /* GX Flatpanel control MSR */
4294 @@ -20,6 +22,8 @@ extern struct geode_vid_ops gx_vid_ops;
4295  
4296  /* Geode GX video processor registers */
4297  
4298 +#define GX_VCFG         0x0000
4299 +
4300  #define GX_DCFG                0x0008
4301  #  define GX_DCFG_CRT_EN               0x00000001
4302  #  define GX_DCFG_HSYNC_EN             0x00000002
4303 @@ -42,6 +46,14 @@ extern struct geode_vid_ops gx_vid_ops;
4304  #define GX_MISC_DAC_PWRDN  0x00000400
4305  #define GX_MISC_A_PWRDN    0x00000800
4306  
4307 +/* Gamma correction RAM - address and data registers */
4308 +
4309 +#define GX_GAR 0x038
4310 +#define GX_GDR 0x040
4311 +
4312 +#define GXFB_GAMMA_DWORDS 256 /* number of dwords in the gamma ram */
4313 +#define GXFB_GAMMA_SIZE (GXFB_GAMMA_DWORDS * sizeof(unsigned int))
4314 +
4315  /* Geode GX flat panel display control registers */
4316  
4317  #define GX_FP_PT1 0x0400
4318 @@ -69,4 +81,13 @@ extern struct geode_vid_ops gx_vid_ops;
4319  #  define MSR_GLCP_DOTPLL_BYPASS               (0x0000000000008000ull)
4320  #  define MSR_GLCP_DOTPLL_LOCK                 (0x0000000002000000ull)
4321  
4322 +int gxfb_powerdown(struct fb_info *info);
4323 +int gxfb_powerup(struct fb_info *info);
4324 +
4325 +void gx_set_dclk_frequency(struct fb_info *info);
4326 +unsigned int gx_get_dclk(struct fb_info *info);
4327 +
4328 +void gx_save_regs(struct fb_info *info, struct geoderegs *regs);
4329 +void gx_restore_regs(struct fb_info *info, struct geoderegs *regs);
4330 +
4331  #endif /* !__VIDEO_GX_H__ */
4332 diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
4333 index 3741ad7..49f6db5 100644
4334 --- a/drivers/video/modedb.c
4335 +++ b/drivers/video/modedb.c
4336 @@ -33,6 +33,8 @@ const char *global_mode_option;
4337       *  Standard video mode definitions (taken from XFree86)
4338       */
4339  
4340 +#define DEFAULT_MODEDB_INDEX   0
4341 +
4342  static const struct fb_videomode modedb[] = {
4343      {
4344         /* 640x400 @ 70 Hz, 31.5 kHz hsync */
4345 @@ -504,7 +506,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
4346      }
4347  
4348      if (!default_mode)
4349 -       default_mode = &db[0];
4350 +           default_mode = (db == modedb) ?
4351 +                   &modedb[DEFAULT_MODEDB_INDEX] : &db[0];
4352  
4353      if (!default_bpp)
4354         default_bpp = 8;
4355 diff --git a/fs/Kconfig b/fs/Kconfig
4356 index f9eed6d..6fa3ea2 100644
4357 --- a/fs/Kconfig
4358 +++ b/fs/Kconfig
4359 @@ -999,6 +999,23 @@ config HUGETLBFS
4360  config HUGETLB_PAGE
4361         def_bool HUGETLBFS
4362  
4363 +config PROMFS_FS
4364 +       tristate "PromFS IEEE 1275 file system support"
4365 +       depends on SPARC || PPC || OLPC
4366 +       help
4367 +         PromFS is a file system interface to various IEEE-1275 compatible
4368 +         firmwares.  If you have such a firmware (Sparc64, PowerPC, and
4369 +         some other architectures and embedded systems have such firmwares,
4370 +         with names like "OpenBoot (tm)" and "OpenFirmware"), say Y here
4371 +         to be able to access the firmware's device-tree from Linux.
4372 +
4373 +         The firmware device-tree is available as a virtual file system,
4374 +         can be mounted under /prom with the command "mount -t promfs
4375 +         none /prom".
4376 +
4377 +         To compile PromFS support as a module, choose M here; the module
4378 +         will be called promfs.  If unsure, choose M.
4379 +
4380  config RAMFS
4381         bool
4382         default y
4383 @@ -1225,6 +1242,14 @@ config JFFS2_FS_WRITEBUFFER
4384             - NOR flash with transparent ECC
4385             - DataFlash
4386  
4387 +config JFFS2_FS_WBUF_VERIFY
4388 +       bool "Verify JFFS2 write-buffer reads"
4389 +       depends on JFFS2_FS_WRITEBUFFER
4390 +       default n
4391 +       help
4392 +         This causes JFFS2 to read back every page written through the
4393 +         write-buffer, and check for errors.
4394 +
4395  config JFFS2_SUMMARY
4396         bool "JFFS2 summary support (EXPERIMENTAL)"
4397         depends on JFFS2_FS && EXPERIMENTAL
4398 @@ -1295,52 +1320,52 @@ config JFFS2_ZLIB
4399         select ZLIB_DEFLATE
4400         depends on JFFS2_FS
4401         default y
4402 -        help
4403 -          Zlib is designed to be a free, general-purpose, legally unencumbered,
4404 -          lossless data-compression library for use on virtually any computer
4405 -          hardware and operating system. See <http://www.gzip.org/zlib/> for
4406 -          further information.
4407 +       help
4408 +         Zlib is designed to be a free, general-purpose, legally unencumbered,
4409 +         lossless data-compression library for use on virtually any computer
4410 +         hardware and operating system. See <http://www.gzip.org/zlib/> for
4411 +         further information.
4412  
4413 -          Say 'Y' if unsure.
4414 +         Say 'Y' if unsure.
4415  
4416  config JFFS2_RTIME
4417         bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
4418         depends on JFFS2_FS
4419         default y
4420 -        help
4421 -          Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
4422 +       help
4423 +         Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
4424  
4425  config JFFS2_RUBIN
4426         bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
4427         depends on JFFS2_FS
4428         default n
4429 -        help
4430 -          RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
4431 +       help
4432 +         RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
4433  
4434  choice
4435 -        prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
4436 -        default JFFS2_CMODE_PRIORITY
4437 -        depends on JFFS2_FS
4438 -        help
4439 -          You can set here the default compression mode of JFFS2 from
4440 -          the available compression modes. Don't touch if unsure.
4441 +       prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
4442 +       default JFFS2_CMODE_PRIORITY
4443 +       depends on JFFS2_FS
4444 +       help
4445 +         You can set here the default compression mode of JFFS2 from
4446 +         the available compression modes. Don't touch if unsure.
4447  
4448  config JFFS2_CMODE_NONE
4449 -        bool "no compression"
4450 -        help
4451 -          Uses no compression.
4452 +       bool "no compression"
4453 +       help
4454 +         Uses no compression.
4455  
4456  config JFFS2_CMODE_PRIORITY
4457 -        bool "priority"
4458 -        help
4459 -          Tries the compressors in a predefined order and chooses the first
4460 -          successful one.
4461 +       bool "priority"
4462 +       help
4463 +         Tries the compressors in a predefined order and chooses the first
4464 +         successful one.
4465  
4466  config JFFS2_CMODE_SIZE
4467 -        bool "size (EXPERIMENTAL)"
4468 -        help
4469 -          Tries all compressors and chooses the one which has the smallest
4470 -          result.
4471 +       bool "size (EXPERIMENTAL)"
4472 +       help
4473 +         Tries all compressors and chooses the one which has the smallest
4474 +         result.
4475  
4476  endchoice
4477  
4478 diff --git a/fs/Makefile b/fs/Makefile
4479 index 720c29d..61f1a4d 100644
4480 --- a/fs/Makefile
4481 +++ b/fs/Makefile
4482 @@ -108,6 +108,7 @@ obj-$(CONFIG_ADFS_FS)               += adfs/
4483  obj-$(CONFIG_FUSE_FS)          += fuse/
4484  obj-$(CONFIG_UDF_FS)           += udf/
4485  obj-$(CONFIG_SUN_OPENPROMFS)   += openpromfs/
4486 +obj-$(CONFIG_PROMFS_FS)                += promfs/
4487  obj-$(CONFIG_JFS_FS)           += jfs/
4488  obj-$(CONFIG_XFS_FS)           += xfs/
4489  obj-$(CONFIG_9P_FS)            += 9p/
4490 diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
4491 index 504643f..d568ae8 100644
4492 --- a/fs/jffs2/background.c
4493 +++ b/fs/jffs2/background.c
4494 @@ -23,8 +23,8 @@ static int jffs2_garbage_collect_thread(void *);
4495  void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
4496  {
4497         spin_lock(&c->erase_completion_lock);
4498 -        if (c->gc_task && jffs2_thread_should_wake(c))
4499 -                send_sig(SIGHUP, c->gc_task, 1);
4500 +       if (c->gc_task && jffs2_thread_should_wake(c))
4501 +               send_sig(SIGHUP, c->gc_task, 1);
4502         spin_unlock(&c->erase_completion_lock);
4503  }
4504  
4505 diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
4506 index 485d065..d90ca05 100644
4507 --- a/fs/jffs2/compr.c
4508 +++ b/fs/jffs2/compr.c
4509 @@ -5,7 +5,7 @@
4510   * Created by Arjan van de Ven <arjanv@redhat.com>
4511   *
4512   * Copyright Â© 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
4513 - *                    University of Szeged, Hungary
4514 + *                 University of Szeged, Hungary
4515   *
4516   * For licensing information, see the file 'LICENCE' in this directory.
4517   *
4518 @@ -43,121 +43,122 @@ static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_co
4519   * *datalen accordingly to show the amount of data which were compressed.
4520   */
4521  uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
4522 -                            unsigned char *data_in, unsigned char **cpage_out,
4523 -                            uint32_t *datalen, uint32_t *cdatalen)
4524 +                       unsigned char *data_in, unsigned char **cpage_out,
4525 +                       uint32_t *datalen, uint32_t *cdatalen)
4526  {
4527         int ret = JFFS2_COMPR_NONE;
4528 -        int compr_ret;
4529 -        struct jffs2_compressor *this, *best=NULL;
4530 -        unsigned char *output_buf = NULL, *tmp_buf;
4531 -        uint32_t orig_slen, orig_dlen;
4532 -        uint32_t best_slen=0, best_dlen=0;
4533 +       int compr_ret;
4534 +       struct jffs2_compressor *this, *best=NULL;
4535 +       unsigned char *output_buf = NULL, *tmp_buf;
4536 +       uint32_t orig_slen, orig_dlen;
4537 +       uint32_t best_slen=0, best_dlen=0;
4538  
4539 -        switch (jffs2_compression_mode) {
4540 -        case JFFS2_COMPR_MODE_NONE:
4541 -                break;
4542 -        case JFFS2_COMPR_MODE_PRIORITY:
4543 -                output_buf = kmalloc(*cdatalen,GFP_KERNEL);
4544 -                if (!output_buf) {
4545 -                        printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n");
4546 -                        goto out;
4547 -                }
4548 -                orig_slen = *datalen;
4549 -                orig_dlen = *cdatalen;
4550 -                spin_lock(&jffs2_compressor_list_lock);
4551 -                list_for_each_entry(this, &jffs2_compressor_list, list) {
4552 -                        /* Skip decompress-only backwards-compatibility and disabled modules */
4553 -                        if ((!this->compress)||(this->disabled))
4554 -                                continue;
4555 +       switch (jffs2_compression_mode) {
4556 +       case JFFS2_COMPR_MODE_NONE:
4557 +               break;
4558 +       case JFFS2_COMPR_MODE_PRIORITY:
4559 +               output_buf = kmalloc(*cdatalen,GFP_KERNEL);
4560 +               if (!output_buf) {
4561 +                       printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n");
4562 +                       goto out;
4563 +               }
4564 +               orig_slen = *datalen;
4565 +               orig_dlen = *cdatalen;
4566 +               spin_lock(&jffs2_compressor_list_lock);
4567 +               list_for_each_entry(this, &jffs2_compressor_list, list) {
4568 +                       /* Skip decompress-only backwards-compatibility and disabled modules */
4569 +                       if ((!this->compress)||(this->disabled))
4570 +                               continue;
4571  
4572 -                        this->usecount++;
4573 -                        spin_unlock(&jffs2_compressor_list_lock);
4574 -                        *datalen  = orig_slen;
4575 -                        *cdatalen = orig_dlen;
4576 -                        compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL);
4577 -                        spin_lock(&jffs2_compressor_list_lock);
4578 -                        this->usecount--;
4579 -                        if (!compr_ret) {
4580 -                                ret = this->compr;
4581 -                                this->stat_compr_blocks++;
4582 -                                this->stat_compr_orig_size += *datalen;
4583 -                                this->stat_compr_new_size  += *cdatalen;
4584 -                                break;
4585 -                        }
4586 -                }
4587 -                spin_unlock(&jffs2_compressor_list_lock);
4588 -                if (ret == JFFS2_COMPR_NONE) kfree(output_buf);
4589 -                break;
4590 -        case JFFS2_COMPR_MODE_SIZE:
4591 -                orig_slen = *datalen;
4592 -                orig_dlen = *cdatalen;
4593 -                spin_lock(&jffs2_compressor_list_lock);
4594 -                list_for_each_entry(this, &jffs2_compressor_list, list) {
4595 -                        /* Skip decompress-only backwards-compatibility and disabled modules */
4596 -                        if ((!this->compress)||(this->disabled))
4597 -                                continue;
4598 -                        /* Allocating memory for output buffer if necessary */
4599 -                        if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) {
4600 -                                spin_unlock(&jffs2_compressor_list_lock);
4601 -                                kfree(this->compr_buf);
4602 -                                spin_lock(&jffs2_compressor_list_lock);
4603 -                                this->compr_buf_size=0;
4604 -                                this->compr_buf=NULL;
4605 -                        }
4606 -                        if (!this->compr_buf) {
4607 -                                spin_unlock(&jffs2_compressor_list_lock);
4608 -                                tmp_buf = kmalloc(orig_dlen,GFP_KERNEL);
4609 -                                spin_lock(&jffs2_compressor_list_lock);
4610 -                                if (!tmp_buf) {
4611 -                                        printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen);
4612 -                                        continue;
4613 -                                }
4614 -                                else {
4615 -                                        this->compr_buf = tmp_buf;
4616 -                                        this->compr_buf_size = orig_dlen;
4617 -                                }
4618 -                        }
4619 -                        this->usecount++;
4620 -                        spin_unlock(&jffs2_compressor_list_lock);
4621 -                        *datalen  = orig_slen;
4622 -                        *cdatalen = orig_dlen;
4623 -                        compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL);
4624 -                        spin_lock(&jffs2_compressor_list_lock);
4625 -                        this->usecount--;
4626 -                        if (!compr_ret) {
4627 -                                if ((!best_dlen)||(best_dlen>*cdatalen)) {
4628 -                                        best_dlen = *cdatalen;
4629 -                                        best_slen = *datalen;
4630 -                                        best = this;
4631 -                                }
4632 -                        }
4633 -                }
4634 -                if (best_dlen) {
4635 -                        *cdatalen = best_dlen;
4636 -                        *datalen  = best_slen;
4637 -                        output_buf = best->compr_buf;
4638 -                        best->compr_buf = NULL;
4639 -                        best->compr_buf_size = 0;
4640 -                        best->stat_compr_blocks++;
4641 -                        best->stat_compr_orig_size += best_slen;
4642 -                        best->stat_compr_new_size  += best_dlen;
4643 -                        ret = best->compr;
4644 -                }
4645 -                spin_unlock(&jffs2_compressor_list_lock);
4646 -                break;
4647 -        default:
4648 -                printk(KERN_ERR "JFFS2: unknow compression mode.\n");
4649 -        }
4650 +                       this->usecount++;
4651 +                       spin_unlock(&jffs2_compressor_list_lock);
4652 +                       *datalen  = orig_slen;
4653 +                       *cdatalen = orig_dlen;
4654 +                       compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL);
4655 +                       spin_lock(&jffs2_compressor_list_lock);
4656 +                       this->usecount--;
4657 +                       if (!compr_ret) {
4658 +                               ret = this->compr;
4659 +                               this->stat_compr_blocks++;
4660 +                               this->stat_compr_orig_size += *datalen;
4661 +                               this->stat_compr_new_size  += *cdatalen;
4662 +                               break;
4663 +                       }
4664 +               }
4665 +               spin_unlock(&jffs2_compressor_list_lock);
4666 +               if (ret == JFFS2_COMPR_NONE)
4667 +                       kfree(output_buf);
4668 +               break;
4669 +       case JFFS2_COMPR_MODE_SIZE:
4670 +               orig_slen = *datalen;
4671 +               orig_dlen = *cdatalen;
4672 +               spin_lock(&jffs2_compressor_list_lock);
4673 +               list_for_each_entry(this, &jffs2_compressor_list, list) {
4674 +                       /* Skip decompress-only backwards-compatibility and disabled modules */
4675 +                       if ((!this->compress)||(this->disabled))
4676 +                               continue;
4677 +                       /* Allocating memory for output buffer if necessary */
4678 +                       if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) {
4679 +                               spin_unlock(&jffs2_compressor_list_lock);
4680 +                               kfree(this->compr_buf);
4681 +                               spin_lock(&jffs2_compressor_list_lock);
4682 +                               this->compr_buf_size=0;
4683 +                               this->compr_buf=NULL;
4684 +                       }
4685 +                       if (!this->compr_buf) {
4686 +                               spin_unlock(&jffs2_compressor_list_lock);
4687 +                               tmp_buf = kmalloc(orig_dlen,GFP_KERNEL);
4688 +                               spin_lock(&jffs2_compressor_list_lock);
4689 +                               if (!tmp_buf) {
4690 +                                       printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen);
4691 +                                       continue;
4692 +                               }
4693 +                               else {
4694 +                                       this->compr_buf = tmp_buf;
4695 +                                       this->compr_buf_size = orig_dlen;
4696 +                               }
4697 +                       }
4698 +                       this->usecount++;
4699 +                       spin_unlock(&jffs2_compressor_list_lock);
4700 +                       *datalen  = orig_slen;
4701 +                       *cdatalen = orig_dlen;
4702 +                       compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL);
4703 +                       spin_lock(&jffs2_compressor_list_lock);
4704 +                       this->usecount--;
4705 +                       if (!compr_ret) {
4706 +                               if ((!best_dlen)||(best_dlen>*cdatalen)) {
4707 +                                       best_dlen = *cdatalen;
4708 +                                       best_slen = *datalen;
4709 +                                       best = this;
4710 +                               }
4711 +                       }
4712 +               }
4713 +               if (best_dlen) {
4714 +                       *cdatalen = best_dlen;
4715 +                       *datalen  = best_slen;
4716 +                       output_buf = best->compr_buf;
4717 +                       best->compr_buf = NULL;
4718 +                       best->compr_buf_size = 0;
4719 +                       best->stat_compr_blocks++;
4720 +                       best->stat_compr_orig_size += best_slen;
4721 +                       best->stat_compr_new_size  += best_dlen;
4722 +                       ret = best->compr;
4723 +               }
4724 +               spin_unlock(&jffs2_compressor_list_lock);
4725 +               break;
4726 +       default:
4727 +               printk(KERN_ERR "JFFS2: unknow compression mode.\n");
4728 +       }
4729   out:
4730 -        if (ret == JFFS2_COMPR_NONE) {
4731 -               *cpage_out = data_in;
4732 -               *datalen = *cdatalen;
4733 -                none_stat_compr_blocks++;
4734 -                none_stat_compr_size += *datalen;
4735 -        }
4736 -        else {
4737 -                *cpage_out = output_buf;
4738 -        }
4739 +       if (ret == JFFS2_COMPR_NONE) {
4740 +               *cpage_out = data_in;
4741 +               *datalen = *cdatalen;
4742 +               none_stat_compr_blocks++;
4743 +               none_stat_compr_size += *datalen;
4744 +       }
4745 +       else {
4746 +               *cpage_out = output_buf;
4747 +       }
4748         return ret;
4749  }
4750  
4751 @@ -165,8 +166,8 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
4752                      uint16_t comprtype, unsigned char *cdata_in,
4753                      unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
4754  {
4755 -        struct jffs2_compressor *this;
4756 -        int ret;
4757 +       struct jffs2_compressor *this;
4758 +       int ret;
4759  
4760         /* Older code had a bug where it would write non-zero 'usercompr'
4761            fields. Deal with it. */
4762 @@ -177,32 +178,32 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
4763         case JFFS2_COMPR_NONE:
4764                 /* This should be special-cased elsewhere, but we might as well deal with it */
4765                 memcpy(data_out, cdata_in, datalen);
4766 -                none_stat_decompr_blocks++;
4767 +               none_stat_decompr_blocks++;
4768                 break;
4769         case JFFS2_COMPR_ZERO:
4770                 memset(data_out, 0, datalen);
4771                 break;
4772         default:
4773 -                spin_lock(&jffs2_compressor_list_lock);
4774 -                list_for_each_entry(this, &jffs2_compressor_list, list) {
4775 -                        if (comprtype == this->compr) {
4776 -                                this->usecount++;
4777 -                                spin_unlock(&jffs2_compressor_list_lock);
4778 -                                ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL);
4779 -                                spin_lock(&jffs2_compressor_list_lock);
4780 -                                if (ret) {
4781 -                                        printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret);
4782 -                                }
4783 -                                else {
4784 -                                        this->stat_decompr_blocks++;
4785 -                                }
4786 -                                this->usecount--;
4787 -                                spin_unlock(&jffs2_compressor_list_lock);
4788 -                                return ret;
4789 -                        }
4790 -                }
4791 +               spin_lock(&jffs2_compressor_list_lock);
4792 +               list_for_each_entry(this, &jffs2_compressor_list, list) {
4793 +                       if (comprtype == this->compr) {
4794 +                               this->usecount++;
4795 +                               spin_unlock(&jffs2_compressor_list_lock);
4796 +                               ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL);
4797 +                               spin_lock(&jffs2_compressor_list_lock);
4798 +                               if (ret) {
4799 +                                       printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret);
4800 +                               }
4801 +                               else {
4802 +                                       this->stat_decompr_blocks++;
4803 +                               }
4804 +                               this->usecount--;
4805 +                               spin_unlock(&jffs2_compressor_list_lock);
4806 +                               return ret;
4807 +                       }
4808 +               }
4809                 printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype);
4810 -                spin_unlock(&jffs2_compressor_list_lock);
4811 +               spin_unlock(&jffs2_compressor_list_lock);
4812                 return -EIO;
4813         }
4814         return 0;
4815 @@ -210,108 +211,108 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
4816  
4817  int jffs2_register_compressor(struct jffs2_compressor *comp)
4818  {
4819 -        struct jffs2_compressor *this;
4820 +       struct jffs2_compressor *this;
4821  
4822 -        if (!comp->name) {
4823 -                printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n");
4824 -                return -1;
4825 -        }
4826 -        comp->compr_buf_size=0;
4827 -        comp->compr_buf=NULL;
4828 -        comp->usecount=0;
4829 -        comp->stat_compr_orig_size=0;
4830 -        comp->stat_compr_new_size=0;
4831 -        comp->stat_compr_blocks=0;
4832 -        comp->stat_decompr_blocks=0;
4833 -        D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name));
4834 +       if (!comp->name) {
4835 +               printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n");
4836 +               return -1;
4837 +       }
4838 +       comp->compr_buf_size=0;
4839 +       comp->compr_buf=NULL;
4840 +       comp->usecount=0;
4841 +       comp->stat_compr_orig_size=0;
4842 +       comp->stat_compr_new_size=0;
4843 +       comp->stat_compr_blocks=0;
4844 +       comp->stat_decompr_blocks=0;
4845 +       D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name));
4846  
4847 -        spin_lock(&jffs2_compressor_list_lock);
4848 +       spin_lock(&jffs2_compressor_list_lock);
4849  
4850 -        list_for_each_entry(this, &jffs2_compressor_list, list) {
4851 -                if (this->priority < comp->priority) {
4852 -                        list_add(&comp->list, this->list.prev);
4853 -                        goto out;
4854 -                }
4855 -        }
4856 -        list_add_tail(&comp->list, &jffs2_compressor_list);
4857 +       list_for_each_entry(this, &jffs2_compressor_list, list) {
4858 +               if (this->priority < comp->priority) {
4859 +                       list_add(&comp->list, this->list.prev);
4860 +                       goto out;
4861 +               }
4862 +       }
4863 +       list_add_tail(&comp->list, &jffs2_compressor_list);
4864  out:
4865 -        D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
4866 -                printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
4867 -        })
4868 +       D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
4869 +               printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
4870 +       })
4871  
4872 -        spin_unlock(&jffs2_compressor_list_lock);
4873 +       spin_unlock(&jffs2_compressor_list_lock);
4874  
4875 -        return 0;
4876 +       return 0;
4877  }
4878  
4879  int jffs2_unregister_compressor(struct jffs2_compressor *comp)
4880  {
4881 -        D2(struct jffs2_compressor *this;)
4882 +       D2(struct jffs2_compressor *this;)
4883  
4884 -        D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name));
4885 +       D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name));
4886  
4887 -        spin_lock(&jffs2_compressor_list_lock);
4888 +       spin_lock(&jffs2_compressor_list_lock);
4889  
4890 -        if (comp->usecount) {
4891 -                spin_unlock(&jffs2_compressor_list_lock);
4892 -                printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n");
4893 -                return -1;
4894 -        }
4895 -        list_del(&comp->list);
4896 +       if (comp->usecount) {
4897 +               spin_unlock(&jffs2_compressor_list_lock);
4898 +               printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n");
4899 +               return -1;
4900 +       }
4901 +       list_del(&comp->list);
4902  
4903 -        D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
4904 -                printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
4905 -        })
4906 -        spin_unlock(&jffs2_compressor_list_lock);
4907 -        return 0;
4908 +       D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
4909 +               printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
4910 +       })
4911 +       spin_unlock(&jffs2_compressor_list_lock);
4912 +       return 0;
4913  }
4914  
4915  void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
4916  {
4917 -        if (orig != comprbuf)
4918 -                kfree(comprbuf);
4919 +       if (orig != comprbuf)
4920 +               kfree(comprbuf);
4921  }
4922  
4923  int __init jffs2_compressors_init(void)
4924  {
4925  /* Registering compressors */
4926  #ifdef CONFIG_JFFS2_ZLIB
4927 -        jffs2_zlib_init();
4928 +       jffs2_zlib_init();
4929  #endif
4930  #ifdef CONFIG_JFFS2_RTIME
4931 -        jffs2_rtime_init();
4932 +       jffs2_rtime_init();
4933  #endif
4934  #ifdef CONFIG_JFFS2_RUBIN
4935 -        jffs2_rubinmips_init();
4936 -        jffs2_dynrubin_init();
4937 +       jffs2_rubinmips_init();
4938 +       jffs2_dynrubin_init();
4939  #endif
4940  /* Setting default compression mode */
4941  #ifdef CONFIG_JFFS2_CMODE_NONE
4942 -        jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
4943 -        D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");)
4944 +       jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
4945 +       D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");)
4946  #else
4947  #ifdef CONFIG_JFFS2_CMODE_SIZE
4948 -        jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
4949 -        D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");)
4950 +       jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
4951 +       D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");)
4952  #else
4953 -        D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");)
4954 +       D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");)
4955  #endif
4956  #endif
4957 -        return 0;
4958 +       return 0;
4959  }
4960  
4961  int jffs2_compressors_exit(void)
4962  {
4963  /* Unregistering compressors */
4964  #ifdef CONFIG_JFFS2_RUBIN
4965 -        jffs2_dynrubin_exit();
4966 -        jffs2_rubinmips_exit();
4967 +       jffs2_dynrubin_exit();
4968 +       jffs2_rubinmips_exit();
4969  #endif
4970  #ifdef CONFIG_JFFS2_RTIME
4971 -        jffs2_rtime_exit();
4972 +       jffs2_rtime_exit();
4973  #endif
4974  #ifdef CONFIG_JFFS2_ZLIB
4975 -        jffs2_zlib_exit();
4976 +       jffs2_zlib_exit();
4977  #endif
4978 -        return 0;
4979 +       return 0;
4980  }
4981 diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
4982 index 68cc701..1070275 100644
4983 --- a/fs/jffs2/compr.h
4984 +++ b/fs/jffs2/compr.h
4985 @@ -2,7 +2,7 @@
4986   * JFFS2 -- Journalling Flash File System, Version 2.
4987   *
4988   * Copyright Â© 2004   Ferenc Havasi <havasi@inf.u-szeged.hu>,
4989 - *                    University of Szeged, Hungary
4990 + *                   University of Szeged, Hungary
4991   *
4992   * For licensing information, see the file 'LICENCE' in this directory.
4993   *
4994 @@ -32,29 +32,29 @@
4995  #define JFFS2_ZLIB_PRIORITY      60
4996  
4997  #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
4998 -#define JFFS2_DYNRUBIN_DISABLED  /*        for decompression */
4999 +#define JFFS2_DYNRUBIN_DISABLED  /*       for decompression */
5000  
5001  #define JFFS2_COMPR_MODE_NONE       0
5002  #define JFFS2_COMPR_MODE_PRIORITY   1
5003  #define JFFS2_COMPR_MODE_SIZE       2
5004  
5005  struct jffs2_compressor {
5006 -        struct list_head list;
5007 -        int priority;              /* used by prirority comr. mode */
5008 -        char *name;
5009 -        char compr;                /* JFFS2_COMPR_XXX */
5010 -        int (*compress)(unsigned char *data_in, unsigned char *cpage_out,
5011 -                        uint32_t *srclen, uint32_t *destlen, void *model);
5012 -        int (*decompress)(unsigned char *cdata_in, unsigned char *data_out,
5013 -                        uint32_t cdatalen, uint32_t datalen, void *model);
5014 -        int usecount;
5015 -        int disabled;              /* if seted the compressor won't compress */
5016 -        unsigned char *compr_buf;  /* used by size compr. mode */
5017 -        uint32_t compr_buf_size;   /* used by size compr. mode */
5018 -        uint32_t stat_compr_orig_size;
5019 -        uint32_t stat_compr_new_size;
5020 -        uint32_t stat_compr_blocks;
5021 -        uint32_t stat_decompr_blocks;
5022 +       struct list_head list;
5023 +       int priority;                   /* used by prirority comr. mode */
5024 +       char *name;
5025 +       char compr;                     /* JFFS2_COMPR_XXX */
5026 +       int (*compress)(unsigned char *data_in, unsigned char *cpage_out,
5027 +                       uint32_t *srclen, uint32_t *destlen, void *model);
5028 +       int (*decompress)(unsigned char *cdata_in, unsigned char *data_out,
5029 +                         uint32_t cdatalen, uint32_t datalen, void *model);
5030 +       int usecount;
5031 +       int disabled;           /* if set the compressor won't compress */
5032 +       unsigned char *compr_buf;       /* used by size compr. mode */
5033 +       uint32_t compr_buf_size;        /* used by size compr. mode */
5034 +       uint32_t stat_compr_orig_size;
5035 +       uint32_t stat_compr_new_size;
5036 +       uint32_t stat_compr_blocks;
5037 +       uint32_t stat_decompr_blocks;
5038  };
5039  
5040  int jffs2_register_compressor(struct jffs2_compressor *comp);
5041 @@ -64,12 +64,12 @@ int jffs2_compressors_init(void);
5042  int jffs2_compressors_exit(void);
5043  
5044  uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
5045 -                             unsigned char *data_in, unsigned char **cpage_out,
5046 -                             uint32_t *datalen, uint32_t *cdatalen);
5047 +                       unsigned char *data_in, unsigned char **cpage_out,
5048 +                       uint32_t *datalen, uint32_t *cdatalen);
5049  
5050  int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
5051 -                     uint16_t comprtype, unsigned char *cdata_in,
5052 -                     unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
5053 +                    uint16_t comprtype, unsigned char *cdata_in,
5054 +                    unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
5055  
5056  void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
5057  
5058 diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
5059 index 0d0bfd2..546d153 100644
5060 --- a/fs/jffs2/compr_rtime.c
5061 +++ b/fs/jffs2/compr_rtime.c
5062 @@ -104,7 +104,7 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
5063                         }
5064                 }
5065         }
5066 -        return 0;
5067 +       return 0;
5068  }
5069  
5070  static struct jffs2_compressor jffs2_rtime_comp = {
5071 diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c
5072 index ea0431e..c73fa89 100644
5073 --- a/fs/jffs2/compr_rubin.c
5074 +++ b/fs/jffs2/compr_rubin.c
5075 @@ -384,7 +384,7 @@ static int jffs2_rubinmips_decompress(unsigned char *data_in,
5076                                       void *model)
5077  {
5078         rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
5079 -        return 0;
5080 +       return 0;
5081  }
5082  
5083  static int jffs2_dynrubin_decompress(unsigned char *data_in,
5084 @@ -399,7 +399,7 @@ static int jffs2_dynrubin_decompress(unsigned char *data_in,
5085                 bits[c] = data_in[c];
5086  
5087         rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen);
5088 -        return 0;
5089 +       return 0;
5090  }
5091  
5092  static struct jffs2_compressor jffs2_rubinmips_comp = {
5093 diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
5094 index 2b87fcc..cfd301a 100644
5095 --- a/fs/jffs2/compr_zlib.c
5096 +++ b/fs/jffs2/compr_zlib.c
5097 @@ -181,7 +181,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in,
5098         }
5099         zlib_inflateEnd(&inf_strm);
5100         mutex_unlock(&inflate_mutex);
5101 -        return 0;
5102 +       return 0;
5103  }
5104  
5105  static struct jffs2_compressor jffs2_zlib_comp = {
5106 @@ -203,11 +203,11 @@ int __init jffs2_zlib_init(void)
5107  
5108      ret = alloc_workspaces();
5109      if (ret)
5110 -        return ret;
5111 +           return ret;
5112  
5113      ret = jffs2_register_compressor(&jffs2_zlib_comp);
5114      if (ret)
5115 -        free_workspaces();
5116 +           free_workspaces();
5117  
5118      return ret;
5119  }
5120 diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
5121 index c1dfca3..d293a1f 100644
5122 --- a/fs/jffs2/dir.c
5123 +++ b/fs/jffs2/dir.c
5124 @@ -32,7 +32,7 @@ static int jffs2_mkdir (struct inode *,struct dentry *,int);
5125  static int jffs2_rmdir (struct inode *,struct dentry *);
5126  static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t);
5127  static int jffs2_rename (struct inode *, struct dentry *,
5128 -                        struct inode *, struct dentry *);
5129 +                        struct inode *, struct dentry *);
5130  
5131  const struct file_operations jffs2_dir_operations =
5132  {
5133 @@ -770,7 +770,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
5134  }
5135  
5136  static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
5137 -                        struct inode *new_dir_i, struct dentry *new_dentry)
5138 +                        struct inode *new_dir_i, struct dentry *new_dentry)
5139  {
5140         int ret;
5141         struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
5142 diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
5143 index 66e7c2f..efd83f3 100644
5144 --- a/fs/jffs2/erase.c
5145 +++ b/fs/jffs2/erase.c
5146 @@ -38,8 +38,8 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
5147  #ifdef __ECOS
5148         ret = jffs2_flash_erase(c, jeb);
5149         if (!ret) {
5150 -               jffs2_erase_succeeded(c, jeb);
5151 -               return;
5152 +              jffs2_erase_succeeded(c, jeb);
5153 +              return;
5154         }
5155         bad_offset = jeb->offset;
5156  #else /* Linux */
5157 @@ -50,12 +50,14 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
5158         instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
5159         if (!instr) {
5160                 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
5161 +               down(&c->erase_free_sem);
5162                 spin_lock(&c->erase_completion_lock);
5163                 list_move(&jeb->list, &c->erase_pending_list);
5164                 c->erasing_size -= c->sector_size;
5165                 c->dirty_size += c->sector_size;
5166                 jeb->dirty_size = c->sector_size;
5167                 spin_unlock(&c->erase_completion_lock);
5168 +               up(&c->erase_free_sem);
5169                 return;
5170         }
5171  
5172 @@ -82,12 +84,14 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
5173         if (ret == -ENOMEM || ret == -EAGAIN) {
5174                 /* Erase failed immediately. Refile it on the list */
5175                 D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret));
5176 +               down(&c->erase_free_sem);
5177                 spin_lock(&c->erase_completion_lock);
5178                 list_move(&jeb->list, &c->erase_pending_list);
5179                 c->erasing_size -= c->sector_size;
5180                 c->dirty_size += c->sector_size;
5181                 jeb->dirty_size = c->sector_size;
5182                 spin_unlock(&c->erase_completion_lock);
5183 +               up(&c->erase_free_sem);
5184                 return;
5185         }
5186  
5187 @@ -114,6 +118,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
5188                         jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
5189                         list_del(&jeb->list);
5190                         spin_unlock(&c->erase_completion_lock);
5191 +                       up(&c->erase_free_sem);
5192                         jffs2_mark_erased_block(c, jeb);
5193  
5194                         if (!--count) {
5195 @@ -134,6 +139,7 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
5196                         jffs2_free_jeb_node_refs(c, jeb);
5197                         list_add(&jeb->list, &c->erasing_list);
5198                         spin_unlock(&c->erase_completion_lock);
5199 +                       up(&c->erase_free_sem);
5200  
5201                         jffs2_erase_block(c, jeb);
5202  
5203 @@ -142,23 +148,25 @@ void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
5204                 }
5205  
5206                 /* Be nice */
5207 -               cond_resched();
5208 +               yield();
5209 +               down(&c->erase_free_sem);
5210                 spin_lock(&c->erase_completion_lock);
5211         }
5212  
5213         spin_unlock(&c->erase_completion_lock);
5214 +       up(&c->erase_free_sem);
5215   done:
5216         D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n"));
5217 -
5218 -       up(&c->erase_free_sem);
5219  }
5220  
5221  static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
5222  {
5223         D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset));
5224 +       down(&c->erase_free_sem);
5225         spin_lock(&c->erase_completion_lock);
5226         list_move_tail(&jeb->list, &c->erase_complete_list);
5227         spin_unlock(&c->erase_completion_lock);
5228 +       up(&c->erase_free_sem);
5229         /* Ensure that kupdated calls us again to mark them clean */
5230         jffs2_erase_pending_trigger(c);
5231  }
5232 @@ -172,22 +180,26 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
5233                    failed too many times. */
5234                 if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
5235                         /* We'd like to give this block another try. */
5236 +                       down(&c->erase_free_sem);
5237                         spin_lock(&c->erase_completion_lock);
5238                         list_move(&jeb->list, &c->erase_pending_list);
5239                         c->erasing_size -= c->sector_size;
5240                         c->dirty_size += c->sector_size;
5241                         jeb->dirty_size = c->sector_size;
5242                         spin_unlock(&c->erase_completion_lock);
5243 +                       up(&c->erase_free_sem);
5244                         return;
5245                 }
5246         }
5247  
5248 +       down(&c->erase_free_sem);
5249         spin_lock(&c->erase_completion_lock);
5250         c->erasing_size -= c->sector_size;
5251         c->bad_size += c->sector_size;
5252         list_move(&jeb->list, &c->bad_list);
5253         c->nr_erasing_blocks--;
5254         spin_unlock(&c->erase_completion_lock);
5255 +       up(&c->erase_free_sem);
5256         wake_up(&c->erase_wait);
5257  }
5258  
5259 @@ -317,6 +329,33 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl
5260         size_t retlen;
5261         int ret = -EIO;
5262  
5263 +       if (c->mtd->point) {
5264 +               unsigned long *wordebuf;
5265 +
5266 +               ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf);
5267 +               if (ret) {
5268 +                       D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
5269 +                       goto do_flash_read;
5270 +               }
5271 +               if (retlen < c->sector_size) {
5272 +                       /* Don't muck about if it won't let us point to the whole erase sector */
5273 +                       D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
5274 +                       c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
5275 +                       goto do_flash_read;
5276 +               }
5277 +               wordebuf = ebuf-sizeof(*wordebuf);
5278 +               retlen /= sizeof(*wordebuf);
5279 +               do {
5280 +                  if (*++wordebuf != ~0)
5281 +                          break;
5282 +               } while(--retlen);
5283 +               c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size);
5284 +               if (retlen)
5285 +                       printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n",
5286 +                              *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf));
5287 +               return 0;
5288 +       }
5289 + do_flash_read:
5290         ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
5291         if (!ebuf) {
5292                 printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
5293 @@ -417,6 +456,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
5294                 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
5295         }
5296  
5297 +       down(&c->erase_free_sem);
5298         spin_lock(&c->erase_completion_lock);
5299         c->erasing_size -= c->sector_size;
5300         c->free_size += jeb->free_size;
5301 @@ -429,23 +469,28 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
5302         c->nr_erasing_blocks--;
5303         c->nr_free_blocks++;
5304         spin_unlock(&c->erase_completion_lock);
5305 +       up(&c->erase_free_sem);
5306         wake_up(&c->erase_wait);
5307         return;
5308  
5309  filebad:
5310 +       down(&c->erase_free_sem);
5311         spin_lock(&c->erase_completion_lock);
5312         /* Stick it on a list (any list) so erase_failed can take it
5313            right off again.  Silly, but shouldn't happen often. */
5314         list_add(&jeb->list, &c->erasing_list);
5315         spin_unlock(&c->erase_completion_lock);
5316 +       up(&c->erase_free_sem);
5317         jffs2_erase_failed(c, jeb, bad_offset);
5318         return;
5319  
5320  refile:
5321         /* Stick it back on the list from whence it came and come back later */
5322         jffs2_erase_pending_trigger(c);
5323 +       down(&c->erase_free_sem);
5324         spin_lock(&c->erase_completion_lock);
5325         list_add(&jeb->list, &c->erase_complete_list);
5326         spin_unlock(&c->erase_completion_lock);
5327 +       up(&c->erase_free_sem);
5328         return;
5329  }
5330 diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
5331 index 2d99e06..eded819 100644
5332 --- a/fs/jffs2/gc.c
5333 +++ b/fs/jffs2/gc.c
5334 @@ -556,7 +556,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
5335  
5336         node = kmalloc(rawlen, GFP_KERNEL);
5337         if (!node)
5338 -               return -ENOMEM;
5339 +               return -ENOMEM;
5340  
5341         ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node);
5342         if (!ret && retlen != rawlen)
5343 @@ -624,7 +624,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
5344  
5345         if (ret || (retlen != rawlen)) {
5346                 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
5347 -                       rawlen, phys_ofs, ret, retlen);
5348 +                      rawlen, phys_ofs, ret, retlen);
5349                 if (retlen) {
5350                         jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL);
5351                 } else {
5352 diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
5353 index b13298a..ae99cd7 100644
5354 --- a/fs/jffs2/jffs2_fs_sb.h
5355 +++ b/fs/jffs2/jffs2_fs_sb.h
5356 @@ -106,6 +106,9 @@ struct jffs2_sb_info {
5357  
5358         uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
5359  
5360 +#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
5361 +       unsigned char *wbuf_verify; /* read-back buffer for verification */
5362 +#endif
5363  #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
5364         unsigned char *wbuf; /* Write-behind buffer for NAND flash */
5365         uint32_t wbuf_ofs;
5366 diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
5367 index bc5509f..8b4955a 100644
5368 --- a/fs/jffs2/nodelist.h
5369 +++ b/fs/jffs2/nodelist.h
5370 @@ -127,7 +127,7 @@ static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_nod
5371         return ((struct jffs2_inode_cache *)raw);
5372  }
5373  
5374 -        /* flash_offset & 3 always has to be zero, because nodes are
5375 +       /* flash_offset & 3 always has to be zero, because nodes are
5376            always aligned at 4 bytes. So we have a couple of extra bits
5377            to play with, which indicate the node's status; see below: */
5378  #define REF_UNCHECKED  0       /* We haven't yet checked the CRC or built its inode */
5379 @@ -197,7 +197,7 @@ struct jffs2_inode_cache {
5380  #define RAWNODE_CLASS_XATTR_DATUM      1
5381  #define RAWNODE_CLASS_XATTR_REF                2
5382  
5383 -#define INOCACHE_HASHSIZE 128
5384 +#define INOCACHE_HASHSIZE 1024
5385  
5386  #define write_ofs(c) ((c)->nextblock->offset + (c)->sector_size - (c)->nextblock->free_size)
5387  
5388 diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
5389 index dbc908a..5b49bff 100644
5390 --- a/fs/jffs2/nodemgmt.c
5391 +++ b/fs/jffs2/nodemgmt.c
5392 @@ -154,7 +154,7 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
5393         while(ret == -EAGAIN) {
5394                 ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
5395                 if (ret) {
5396 -                       D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
5397 +                       D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
5398                 }
5399         }
5400         spin_unlock(&c->erase_completion_lock);
5401 @@ -423,7 +423,12 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
5402            even after refiling c->nextblock */
5403         if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
5404             && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
5405 -               printk(KERN_WARNING "argh. node added in wrong place\n");
5406 +               printk(KERN_WARNING "argh. node added in wrong place at 0x%08x(%d)\n", ofs & ~3, ofs & 3);
5407 +               if (c->nextblock)
5408 +                       printk(KERN_WARNING "nextblock 0x%08x", c->nextblock->offset);
5409 +               else
5410 +                       printk(KERN_WARNING "No nextblock");
5411 +               printk(", expected at %08x\n", jeb->offset + (c->sector_size - jeb->free_size));
5412                 return ERR_PTR(-EINVAL);
5413         }
5414  #endif
5415 diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
5416 index b5baa35..8d4319c 100644
5417 --- a/fs/jffs2/readinode.c
5418 +++ b/fs/jffs2/readinode.c
5419 @@ -211,7 +211,7 @@ static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *
5420   * ordering.
5421   *
5422   * Returns 0 if the node was handled (including marking it obsolete)
5423 - *         < 0 an if error occurred
5424 + *      < 0 an if error occurred
5425   */
5426  static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
5427                                 struct jffs2_readinode_info *rii,
5428 @@ -862,8 +862,8 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re
5429                 JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n",
5430                             ref_offset(ref));
5431                 JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n",
5432 -                            je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
5433 -                            je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc));
5434 +                           je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
5435 +                           je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc));
5436                 jffs2_mark_node_obsolete(c, ref);
5437                 return 0;
5438         }
5439 diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
5440 index 6c75cd4..59dd408 100644
5441 --- a/fs/jffs2/scan.c
5442 +++ b/fs/jffs2/scan.c
5443 @@ -863,7 +863,7 @@ scan_more:
5444                         switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) {
5445                         case JFFS2_FEATURE_ROCOMPAT:
5446                                 printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
5447 -                               c->flags |= JFFS2_SB_FLAG_RO;
5448 +                               c->flags |= JFFS2_SB_FLAG_RO;
5449                                 if (!(jffs2_is_readonly(c)))
5450                                         return -EROFS;
5451                                 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
5452 diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
5453 index bc9f6ba..02c39c6 100644
5454 --- a/fs/jffs2/security.c
5455 +++ b/fs/jffs2/security.c
5456 @@ -38,9 +38,9 @@ int jffs2_init_security(struct inode *inode, struct inode *dir)
5457         }
5458         rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0);
5459  
5460 -        kfree(name);
5461 -        kfree(value);
5462 -        return rc;
5463 +       kfree(name);
5464 +       kfree(value);
5465 +       return rc;
5466  }
5467  
5468  /* ---- XATTR Handler for "security.*" ----------------- */
5469 diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
5470 index d828b29..2a77d3f 100644
5471 --- a/fs/jffs2/summary.c
5472 +++ b/fs/jffs2/summary.c
5473 @@ -2,10 +2,10 @@
5474   * JFFS2 -- Journalling Flash File System, Version 2.
5475   *
5476   * Copyright Â© 2004  Ferenc Havasi <havasi@inf.u-szeged.hu>,
5477 - *                   Zoltan Sogor <weth@inf.u-szeged.hu>,
5478 - *                   Patrik Kluba <pajko@halom.u-szeged.hu>,
5479 - *                   University of Szeged, Hungary
5480 - *             2006  KaiGai Kohei <kaigai@ak.jp.nec.com>
5481 + *                  Zoltan Sogor <weth@inf.u-szeged.hu>,
5482 + *                  Patrik Kluba <pajko@halom.u-szeged.hu>,
5483 + *                  University of Szeged, Hungary
5484 + *            2006  KaiGai Kohei <kaigai@ak.jp.nec.com>
5485   *
5486   * For licensing information, see the file 'LICENCE' in this directory.
5487   *
5488 diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
5489 index 0c6669e..8bf34f2 100644
5490 --- a/fs/jffs2/summary.h
5491 +++ b/fs/jffs2/summary.h
5492 @@ -2,9 +2,9 @@
5493   * JFFS2 -- Journalling Flash File System, Version 2.
5494   *
5495   * Copyright Â© 2004  Ferenc Havasi <havasi@inf.u-szeged.hu>,
5496 - *                   Zoltan Sogor <weth@inf.u-szeged.hu>,
5497 - *                   Patrik Kluba <pajko@halom.u-szeged.hu>,
5498 - *                   University of Szeged, Hungary
5499 + *                  Zoltan Sogor <weth@inf.u-szeged.hu>,
5500 + *                  Patrik Kluba <pajko@halom.u-szeged.hu>,
5501 + *                  University of Szeged, Hungary
5502   *
5503   * For licensing information, see the file 'LICENCE' in this directory.
5504   *
5505 diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
5506 index 91d1d0f..d1d4f27 100644
5507 --- a/fs/jffs2/wbuf.c
5508 +++ b/fs/jffs2/wbuf.c
5509 @@ -220,6 +220,47 @@ static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info
5510         return NULL;
5511  }
5512  
5513 +#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
5514 +static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
5515 +                             uint32_t ofs)
5516 +{
5517 +       int ret;
5518 +       size_t retlen;
5519 +       char *eccstr;
5520 +
5521 +       ret = c->mtd->read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
5522 +       if (ret && ret != -EUCLEAN && ret != -EBADMSG) {
5523 +               printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x failed: %d\n", c->wbuf_ofs, ret);
5524 +               return ret;
5525 +       } else if (retlen != c->wbuf_pagesize) {
5526 +               printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x gave short read: %zd not %d.\n", ofs, retlen, c->wbuf_pagesize);
5527 +               return -EIO;
5528 +       }
5529 +       if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize))
5530 +               return 0;
5531 +
5532 +       if (ret == -EUCLEAN)
5533 +               eccstr = "corrected";
5534 +       else if (ret == -EBADMSG)
5535 +               eccstr = "correction failed";
5536 +       else
5537 +               eccstr = "OK or unused";
5538 +
5539 +       printk(KERN_WARNING "Write verify error (ECC %s) at %08x. Wrote:\n",
5540 +              eccstr, c->wbuf_ofs);
5541 +       print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
5542 +                      c->wbuf, c->wbuf_pagesize, 0);
5543 +
5544 +       printk(KERN_WARNING "Read back:\n");
5545 +       print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
5546 +                      c->wbuf_verify, c->wbuf_pagesize, 0);
5547 +
5548 +       return -EIO;
5549 +}
5550 +#else
5551 +#define jffs2_verify_write(c,b,o) (0)
5552 +#endif
5553 +
5554  /* Recover from failure to write wbuf. Recover the nodes up to the
5555   * wbuf, not the one which we were starting to try to write. */
5556  
5557 @@ -380,7 +421,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
5558                         ret = c->mtd->write(c->mtd, ofs, towrite, &retlen,
5559                                             rewrite_buf);
5560  
5561 -               if (ret || retlen != towrite) {
5562 +               if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) {
5563                         /* Argh. We tried. Really we did. */
5564                         printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");
5565                         kfree(buf);
5566 @@ -587,15 +628,16 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
5567  
5568                 ret = c->mtd->write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf);
5569  
5570 -       if (ret || retlen != c->wbuf_pagesize) {
5571 -               if (ret)
5572 -                       printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret);
5573 -               else {
5574 -                       printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",
5575 -                               retlen, c->wbuf_pagesize);
5576 -                       ret = -EIO;
5577 -               }
5578 -
5579 +       if (ret) {
5580 +               printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n", ret);
5581 +               goto wfail;
5582 +       } else if (retlen != c->wbuf_pagesize) {
5583 +               printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",
5584 +                      retlen, c->wbuf_pagesize);
5585 +               ret = -EIO;
5586 +               goto wfail;
5587 +       } else if ((ret = jffs2_verify_write(c, c->wbuf, c->wbuf_ofs))) {
5588 +       wfail:
5589                 jffs2_wbuf_recover(c);
5590  
5591                 return ret;
5592 @@ -966,8 +1008,8 @@ exit:
5593  
5594  #define NR_OOB_SCAN_PAGES 4
5595  
5596 -/* For historical reasons we use only 12 bytes for OOB clean marker */
5597 -#define OOB_CM_SIZE 12
5598 +/* For historical reasons we use only 8 bytes for OOB clean marker */
5599 +#define OOB_CM_SIZE 8
5600  
5601  static const struct jffs2_unknown_node oob_cleanmarker =
5602  {
5603 @@ -1021,8 +1063,8 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
5604  /*
5605   * Check for a valid cleanmarker.
5606   * Returns: 0 if a valid cleanmarker was found
5607 - *          1 if no cleanmarker was found
5608 - *          negative error code if an error occurred
5609 + *         1 if no cleanmarker was found
5610 + *         negative error code if an error occurred
5611   */
5612  int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
5613                                  struct jffs2_eraseblock *jeb)
5614 @@ -1138,11 +1180,22 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
5615                 return -ENOMEM;
5616         }
5617  
5618 +#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
5619 +       c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
5620 +       if (!c->wbuf_verify) {
5621 +               kfree(c->oobbuf);
5622 +               kfree(c->wbuf);
5623 +               return -ENOMEM;
5624 +       }
5625 +#endif
5626         return 0;
5627  }
5628  
5629  void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
5630  {
5631 +#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
5632 +       kfree(c->wbuf_verify);
5633 +#endif
5634         kfree(c->wbuf);
5635         kfree(c->oobbuf);
5636  }
5637 diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
5638 index 3b0ff29..6e3b5dd 100644
5639 --- a/fs/jffs2/xattr.h
5640 +++ b/fs/jffs2/xattr.h
5641 @@ -75,7 +75,7 @@ extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
5642  extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
5643  
5644  extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
5645 -                                                  uint32_t xid, uint32_t version);
5646 +                                                        uint32_t xid, uint32_t version);
5647  
5648  extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
5649  extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
5650 diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c
5651 index 40942bc..8bbeab9 100644
5652 --- a/fs/jffs2/xattr_user.c
5653 +++ b/fs/jffs2/xattr_user.c
5654 @@ -17,7 +17,7 @@
5655  #include "nodelist.h"
5656  
5657  static int jffs2_user_getxattr(struct inode *inode, const char *name,
5658 -                               void *buffer, size_t size)
5659 +                              void *buffer, size_t size)
5660  {
5661         if (!strcmp(name, ""))
5662                 return -EINVAL;
5663 @@ -25,7 +25,7 @@ static int jffs2_user_getxattr(struct inode *inode, const char *name,
5664  }
5665  
5666  static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer,
5667 -                               size_t size, int flags)
5668 +                              size_t size, int flags)
5669  {
5670         if (!strcmp(name, ""))
5671                 return -EINVAL;
5672 diff --git a/include/asm-i386/geode.h b/include/asm-i386/geode.h
5673 index 6da4bbb..f18ebe2 100644
5674 --- a/include/asm-i386/geode.h
5675 +++ b/include/asm-i386/geode.h
5676 @@ -135,6 +135,55 @@ static inline void geode_gpio_event_pme(unsigned int gpio, int pair)
5677         geode_gpio_setup_event(gpio, pair, 1);
5678  }
5679  
5680 +/* MFGPT */
5681 +
5682 +#define MFGPT_TIMER_ANY -1
5683 +
5684 +#define MFGPT_DOMAIN_WORKING 1
5685 +#define MFGPT_DOMAIN_STANDBY 2
5686 +#define MFGPT_DOMAIN_ANY (MFGPT_DOMAIN_WORKING | MFGPT_DOMAIN_STANDBY)
5687 +
5688 +#define MFGPT_CMP1 0
5689 +#define MFGPT_CMP2 1
5690 +
5691 +#define MFGPT_EVENT_IRQ   0
5692 +#define MFGPT_EVENT_NMI   1
5693 +#define MFGPT_EVENT_RESET 3
5694 +
5695 +#define MFGPT_REG_CMP1    0
5696 +#define MFGPT_REG_CMP2    2
5697 +#define MFGPT_REG_COUNTER 4
5698 +#define MFGPT_REG_SETUP   6
5699 +
5700 +#define MFGPT_SETUP_CNTEN  (1 << 15)
5701 +#define MFGPT_SETUP_CMP2   (1 << 14)
5702 +#define MFGPT_SETUP_CMP1   (1 << 13)
5703 +#define MFGPT_SETUP_SETUP  (1 << 12)
5704 +#define MFGPT_SETUP_STOPEN (1 << 11)
5705 +#define MFGPT_SETUP_EXTEN  (1 << 10)
5706 +#define MFGPT_SETUP_REVEN  (1 << 5)
5707 +#define MFGPT_SETUP_CLKSEL (1 << 4)
5708 +
5709 +static inline void geode_mfgpt_write(int timer, u16 reg, u16 value)
5710 +{
5711 +       u32 base = geode_get_dev_base(GEODE_DEV_MFGPT);
5712 +       outw(value, base + reg + (timer * 8));
5713 +}
5714 +
5715 +static inline u16 geode_mfgpt_read(int timer, u16 reg)
5716 +{
5717 +       u32 base = geode_get_dev_base(GEODE_DEV_MFGPT);
5718 +       return inw(base + reg + (timer * 8));
5719 +}
5720 +
5721 +extern int __init geode_mfgpt_detect(void);
5722 +extern int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable);
5723 +extern int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable);
5724 +extern int geode_mfgpt_alloc_timer(int timer, int domain, struct module *owner);
5725 +
5726 +#define geode_mfgpt_setup_irq(t,c,i) geode_mfgpt_set_irq((t),(c),(i),1)
5727 +#define geode_mfgpt_release_irq(t,c,i) geode_mfgpt_set_irq((t),(c),(i),0)
5728 +
5729  /* Specific geode tests */
5730  
5731  static inline int is_geode_gx(void)
5732
5733 diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h
5734 index 7862fe8..d7146c0 100644
5735 --- a/include/asm-i386/setup.h
5736 +++ b/include/asm-i386/setup.h
5737 @@ -24,6 +24,7 @@
5738  #define OLD_CL_BASE_ADDR       0x90000
5739  #define OLD_CL_OFFSET          0x90022
5740  #define NEW_CL_POINTER         0x228   /* Relative to real mode data */
5741 +#define OFW_INFO_OFFSET                0xb0    /* Relative to real mode data */
5742  
5743  #ifndef __ASSEMBLY__
5744  
5745 diff --git a/include/linux/console.h b/include/linux/console.h
5746 index 56a7bcd..1a8b034 100644
5747 --- a/include/linux/console.h
5748 +++ b/include/linux/console.h
5749 @@ -121,14 +121,11 @@ extern void console_stop(struct console *);
5750  extern void console_start(struct console *);
5751  extern int is_console_locked(void);
5752  
5753 -#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
5754 +extern int serial_console_suspend_enabled;
5755 +
5756  /* Suspend and resume console messages over PM events */
5757  extern void suspend_console(void);
5758  extern void resume_console(void);
5759 -#else
5760 -static inline void suspend_console(void) {}
5761 -static inline void resume_console(void) {}
5762 -#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
5763  
5764  int mda_console_init(void);
5765  void prom_con_init(void);
5766 diff --git a/include/linux/fb.h b/include/linux/fb.h
5767 index cec5410..6b59db5 100644
5768 --- a/include/linux/fb.h
5769 +++ b/include/linux/fb.h
5770 @@ -664,6 +664,12 @@ struct fb_ops {
5771         /* restore saved state */
5772         void (*fb_restore_state)(struct fb_info *info);
5773  
5774 +       /* Shut down the graphics engine to save power */
5775 +       int (*fb_powerdown)(struct fb_info *info);
5776 +
5777 +       /* Power it back up */
5778 +       int (*fb_powerup)(struct fb_info *info);
5779 +
5780         /* get capability given var */
5781         void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
5782                             struct fb_var_screeninfo *var);
5783 @@ -943,6 +949,9 @@ extern int fb_get_color_depth(struct fb_var_screeninfo *var,
5784  extern int fb_get_options(char *name, char **option);
5785  extern int fb_new_modelist(struct fb_info *info);
5786  
5787 +extern int fb_powerdown(struct fb_info *info);
5788 +extern int fb_powerup(struct fb_info *info);
5789 +
5790  extern struct fb_info *registered_fb[FB_MAX];
5791  extern int num_registered_fb;
5792  extern struct class *fb_class;
5793 diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
5794 index a56d24a..fd0a260 100644
5795 --- a/include/linux/mtd/onenand.h
5796 +++ b/include/linux/mtd/onenand.h
5797 @@ -60,6 +60,7 @@ struct onenand_bufferram {
5798   * @erase_shift:       [INTERN] number of address bits in a block
5799   * @page_shift:                [INTERN] number of address bits in a page
5800   * @page_mask:         [INTERN] a page per block mask
5801 + * @writesize:         [INTERN] a real page size
5802   * @bufferram_index:   [INTERN] BufferRAM index
5803   * @bufferram:         [INTERN] BufferRAM info
5804   * @readw:             [REPLACEABLE] hardware specific function for read short
5805 @@ -100,6 +101,7 @@ struct onenand_chip {
5806         unsigned int            erase_shift;
5807         unsigned int            page_shift;
5808         unsigned int            page_mask;
5809 +       unsigned int            writesize;
5810  
5811         unsigned int            bufferram_index;
5812         struct onenand_bufferram        bufferram[MAX_BUFFERRAM];
5813 @@ -140,6 +142,8 @@ struct onenand_chip {
5814  #define ONENAND_NEXT_BUFFERRAM(this)           (this->bufferram_index ^ 1)
5815  #define ONENAND_SET_NEXT_BUFFERRAM(this)       (this->bufferram_index ^= 1)
5816  #define ONENAND_SET_PREV_BUFFERRAM(this)       (this->bufferram_index ^= 1)
5817 +#define ONENAND_SET_BUFFERRAM0(this)           (this->bufferram_index = 0)
5818 +#define ONENAND_SET_BUFFERRAM1(this)           (this->bufferram_index = 1)
5819  
5820  #define ONENAND_GET_SYS_CFG1(this)                                     \
5821         (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
5822 @@ -149,6 +153,13 @@ struct onenand_chip {
5823  #define ONENAND_IS_DDP(this)                                           \
5824         (this->device_id & ONENAND_DEVICE_IS_DDP)
5825  
5826 +#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM
5827 +#define ONENAND_IS_2PLANE(this)                                                \
5828 +       (this->options & ONENAND_HAS_2PLANE)
5829 +#else
5830 +#define ONENAND_IS_2PLANE(this)                        (0)
5831 +#endif
5832 +
5833  /* Check byte access in OneNAND */
5834  #define ONENAND_CHECK_BYTE_ACCESS(addr)                (addr & 0x1)
5835  
5836 @@ -157,6 +168,7 @@ struct onenand_chip {
5837   */
5838  #define ONENAND_HAS_CONT_LOCK          (0x0001)
5839  #define ONENAND_HAS_UNLOCK_ALL         (0x0002)
5840 +#define ONENAND_HAS_2PLANE             (0x0004)
5841  #define ONENAND_PAGEBUF_ALLOC          (0x1000)
5842  #define ONENAND_OOBBUF_ALLOC           (0x2000)
5843  
5844 diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
5845 index af94719..c46161f 100644
5846 --- a/include/linux/mtd/onenand_regs.h
5847 +++ b/include/linux/mtd/onenand_regs.h
5848 @@ -74,6 +74,8 @@
5849  
5850  #define ONENAND_DEVICE_DENSITY_512Mb   (0x002)
5851  #define ONENAND_DEVICE_DENSITY_1Gb     (0x003)
5852 +#define ONENAND_DEVICE_DENSITY_2Gb     (0x004)
5853 +#define ONENAND_DEVICE_DENSITY_4Gb     (0x005)
5854  
5855  /*
5856   * Version ID Register F002h (R)
5857 @@ -111,6 +113,8 @@
5858  #define ONENAND_CMD_READOOB            (0x13)
5859  #define ONENAND_CMD_PROG               (0x80)
5860  #define ONENAND_CMD_PROGOOB            (0x1A)
5861 +#define ONENAND_CMD_2X_PROG            (0x7D)
5862 +#define ONENAND_CMD_2X_CACHE_PROG      (0x7F)
5863  #define ONENAND_CMD_UNLOCK             (0x23)
5864  #define ONENAND_CMD_LOCK               (0x2A)
5865  #define ONENAND_CMD_LOCK_TIGHT         (0x2C)
5866 diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
5867 index 699b7e9..b44facf 100644
5868 --- a/include/linux/vt_kern.h
5869 +++ b/include/linux/vt_kern.h
5870 @@ -95,4 +95,23 @@ struct vt_spawn_console {
5871  };
5872  extern struct vt_spawn_console vt_spawn_con;
5873  
5874 +/* A notifier list for console events  */
5875 +extern struct raw_notifier_head console_notifier_list;
5876 +
5877 +/* Called when the FG console switches to KD_TEXT mode */
5878 +#define CONSOLE_EVENT_SWITCH_TEXT 0x01
5879 +
5880 +/* Called when the FG console switches to KD_GRAPHICS mode */
5881 +#define CONSOLE_EVENT_SWITCH_GRAPHICS 0x02
5882 +
5883 +static inline int console_event_register(struct notifier_block *n)
5884 +{
5885 +       return raw_notifier_chain_register(&console_notifier_list, n);
5886 +}
5887 +
5888 +static inline int console_event_unregister(struct notifier_block *n)
5889 +{
5890 +       return raw_notifier_chain_unregister(&console_notifier_list, n);
5891 +}
5892 +
5893  #endif /* _VT_KERN_H */
5894 diff --git a/kernel/power/console.c b/kernel/power/console.c
5895 index 89bcf49..dca98f5 100644
5896 --- a/kernel/power/console.c
5897 +++ b/kernel/power/console.c
5898 @@ -9,7 +9,7 @@
5899  #include <linux/console.h>
5900  #include "power.h"
5901  
5902 -#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
5903 +#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) && !defined(CONFIG_DISABLE_SUSPEND_VT_SWITCH)
5904  #define SUSPEND_CONSOLE        (MAX_NR_CONSOLES-1)
5905  
5906  static int orig_fgconsole, orig_kmsg;