[s3c24xx] bump to 2.6.30-rc6
[openwrt.git] / target / linux / s3c24xx / patches-2.6.30 / 001-merge-openmoko.patch
1 Merge OpenMoko kernel patches
2 git://git.openmoko.org/git/kernel.git#(no
3
4 lars@lars-laptop   Thu May 14 18:33:23 UTC 2009
5
6 ---
7
8 Index: linux-2.6.30-rc6/arch/arm/mach-s3c2410/include/mach/mci.h
9 ===================================================================
10 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
11 +++ linux-2.6.30-rc6/arch/arm/mach-s3c2410/include/mach/mci.h   2009-05-18 19:07:48.000000000 +0200
12 @@ -0,0 +1,13 @@
13 +#ifndef _ARCH_MCI_H
14 +#define _ARCH_MCI_H
15 +
16 +struct s3c24xx_mci_pdata {
17 +       unsigned int    gpio_detect;
18 +       unsigned int    gpio_wprotect;
19 +       unsigned long   ocr_avail;
20 +       unsigned int    do_dma;
21 +       void            (*set_power)(unsigned char power_mode,
22 +                                    unsigned short vdd);
23 +};
24 +
25 +#endif /* _ARCH_NCI_H */
26 Index: linux-2.6.30-rc6/arch/arm/mach-s3c2410/include/mach/regs-sdi.h
27 ===================================================================
28 --- linux-2.6.30-rc6.orig/arch/arm/mach-s3c2410/include/mach/regs-sdi.h 2009-05-16 06:12:57.000000000 +0200
29 +++ linux-2.6.30-rc6/arch/arm/mach-s3c2410/include/mach/regs-sdi.h      2009-05-18 19:07:48.000000000 +0200
30 @@ -30,6 +30,7 @@
31  #define S3C2410_SDIFSTA               (0x38)
32  
33  #define S3C2410_SDIDATA               (0x3C)
34 +#define S3C2410_SDIDATA_BYTE          (0x3C)
35  #define S3C2410_SDIIMSK               (0x40)
36  
37  #define S3C2440_SDIDATA               (0x40)
38 @@ -37,6 +38,8 @@
39  
40  #define S3C2440_SDICON_SDRESET        (1<<8)
41  #define S3C2440_SDICON_MMCCLOCK       (1<<5)
42 +#define S3C2440_SDIDATA_BYTE          (0x48)
43 +
44  #define S3C2410_SDICON_BYTEORDER      (1<<4)
45  #define S3C2410_SDICON_SDIOIRQ        (1<<3)
46  #define S3C2410_SDICON_RWAITEN        (1<<2)
47 Index: linux-2.6.30-rc6/arch/arm/mach-s3c2440/s3c2440.c
48 ===================================================================
49 --- linux-2.6.30-rc6.orig/arch/arm/mach-s3c2440/s3c2440.c       2009-05-16 06:12:57.000000000 +0200
50 +++ linux-2.6.30-rc6/arch/arm/mach-s3c2440/s3c2440.c    2009-05-18 19:07:48.000000000 +0200
51 @@ -46,6 +46,9 @@
52         s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
53         s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
54  
55 +       /* make sure SD/MMC driver can distinguish 2440 from 2410 */
56 +       s3c_device_sdi.name = "s3c2440-sdi";
57 +
58         /* register our system device for everything else */
59  
60         return sysdev_register(&s3c2440_sysdev);
61 Index: linux-2.6.30-rc6/arch/arm/mach-s3c2442/s3c2442.c
62 ===================================================================
63 --- linux-2.6.30-rc6.orig/arch/arm/mach-s3c2442/s3c2442.c       2009-05-16 06:12:57.000000000 +0200
64 +++ linux-2.6.30-rc6/arch/arm/mach-s3c2442/s3c2442.c    2009-05-18 19:07:48.000000000 +0200
65 @@ -21,6 +21,7 @@
66  
67  #include <plat/s3c2442.h>
68  #include <plat/cpu.h>
69 +#include <plat/devs.h>
70  
71  static struct sys_device s3c2442_sysdev = {
72         .cls            = &s3c2442_sysclass,
73 @@ -30,5 +31,8 @@
74  {
75         printk("S3C2442: Initialising architecture\n");
76  
77 +       /* make sure SD/MMC driver can distinguish 2440 from 2410 */
78 +       s3c_device_sdi.name = "s3c2440-sdi";
79 +
80         return sysdev_register(&s3c2442_sysdev);
81  }
82 Index: linux-2.6.30-rc6/arch/arm/Makefile
83 ===================================================================
84 --- linux-2.6.30-rc6.orig/arch/arm/Makefile     2009-05-16 06:12:57.000000000 +0200
85 +++ linux-2.6.30-rc6/arch/arm/Makefile  2009-05-18 19:07:48.000000000 +0200
86 @@ -55,7 +55,8 @@
87  arch-$(CONFIG_CPU_32v6K)       :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
88  endif
89  arch-$(CONFIG_CPU_32v5)                :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
90 -arch-$(CONFIG_CPU_32v4T)       :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
91 +# We can't load armv4t modules, but still need to assemble some armv4t code to be linked in.
92 +arch-$(CONFIG_CPU_32v4T)       :=-D__LINUX_ARM_ARCH__=4 -march=armv4 -Wa,-march=armv4t
93  arch-$(CONFIG_CPU_32v4)                :=-D__LINUX_ARM_ARCH__=4 -march=armv4
94  arch-$(CONFIG_CPU_32v3)                :=-D__LINUX_ARM_ARCH__=3 -march=armv3
95  
96 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/mach/cpu.h
97 ===================================================================
98 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
99 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/mach/cpu.h       2009-05-18 19:07:48.000000000 +0200
100 @@ -0,0 +1,165 @@
101 +/*
102 + * arch/arm/plat-s3c/include/mach/cpu.h
103 + *
104 + *  S3C cpu type detection
105 + *
106 + *  Copyright (C) 2008 Samsung Electronics
107 + *  Kyungmin Park <kyungmin.park@samsung.com>
108 + *
109 + * Derived from OMAP cpu.h
110 + *
111 + * This program is free software; you can redistribute it and/or modify
112 + * it under the terms of the GNU General Public License as published by
113 + * the Free Software Foundation; either version 2 of the License, or
114 + * (at your option) any later version.
115 + *
116 + * This program is distributed in the hope that it will be useful,
117 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
118 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
119 + * GNU General Public License for more details.
120 + *
121 + * You should have received a copy of the GNU General Public License
122 + * along with this program; if not, write to the Free Software
123 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
124 + */
125 +
126 +#ifndef __ASM_ARCH_S3C_CPU_H
127 +#define __ASM_ARCH_S3C_CPU_H
128 +
129 +extern unsigned int system_rev;
130 +
131 +#define S3C_SYSTEM_REV_ATAG (system_rev & 0xffff)
132 +#define S3C_SYSTEM_REV_CPU (system_rev & 0xffff0000)
133 +
134 +/*
135 + * cpu_is_s3c24xx():   True for s3c2400, s3c2410, s3c2440 and so on
136 + * cpu_is_s3c241x():   True fro s3c2410, s3c2412
137 + * cpu_is_s3c244x():   True fro s3c2440, s3c2442, s3c2443
138 + * cpu_is_s3c64xx():   True for s3c6400, s3c6410
139 + */
140 +#define GET_S3C_CLASS  ((system_rev >> 24) & 0xff)
141 +
142 +#define IS_S3C_CLASS(class, id)                                                \
143 +static inline int is_s3c ##class (void)                                        \
144 +{                                                                      \
145 +       return (GET_S3C_CLASS == (id)) ? 1 : 0;                         \
146 +}
147 +
148 +#define GET_S3C_SUBCLASS       ((system_rev >> 20) & 0xfff)
149 +
150 +#define IS_S3C_SUBCLASS(subclass, id)                                  \
151 +static inline int is_s3c ##subclass (void)                             \
152 +{                                                                      \
153 +       return (GET_S3C_SUBCLASS == (id)) ? 1 : 0;                      \
154 +}
155 +
156 +IS_S3C_CLASS(24xx, 0x24)
157 +IS_S3C_CLASS(64xx, 0x64)
158 +
159 +IS_S3C_SUBCLASS(241x, 0x241)
160 +IS_S3C_SUBCLASS(244x, 0x244)
161 +
162 +#define cpu_is_s3c24xx()               0
163 +#define cpu_is_s3c241x()               0
164 +#define cpu_is_s3c244x()               0
165 +#define cpu_is_s3c64xx()               0
166 +
167 +#if defined(CONFIG_ARCH_S3C2410)
168 +# undef  cpu_is_s3c24xx
169 +# undef  cpu_is_s3c241x
170 +# undef  cpu_is_s3c244x
171 +# define cpu_is_s3c24xx()              is_s3c24xx()
172 +# define cpu_is_s3c241x()              is_s3c241x()
173 +# define cpu_is_s3c244x()              is_s3c244x()
174 +#endif
175 +
176 +#if defined(CONFIG_ARCH_S3C64XX)
177 +# undef  cpu_is_s3c64xx
178 +# define cpu_is_s3c64xx()              is_s3c64xx()
179 +#endif
180 +
181 +/*
182 + * Macros to detect individual cpu types.
183 + * cpu_is_s3c2410():   True for s3c2410
184 + * cpu_is_s3c2440():   True for s3c2440
185 + * cpu_is_s3c6400():   True for s3c6400
186 + * cpu_is_s3c6410():   True for s3c6410
187 + *
188 + * Exception:
189 + * Store Revision A to 1
190 + * s3c2410a -> s3c2411
191 + * s3c2440a -> s3c2441
192 + */
193 +
194 +#define GET_S3C_TYPE   ((system_rev >> 16) & 0xffff)
195 +
196 +#define IS_S3C_TYPE(type, id)                                          \
197 +static inline int is_s3c ##type (void)                                 \
198 +{                                                                      \
199 +       return (GET_S3C_TYPE == (id)) ? 1 : 0;                          \
200 +}
201 +
202 +IS_S3C_TYPE(2400, 0x2400)
203 +IS_S3C_TYPE(2410, 0x2410)
204 +IS_S3C_TYPE(2410a, 0x2411)
205 +IS_S3C_TYPE(2412, 0x2412)
206 +IS_S3C_TYPE(2440, 0x2440)
207 +IS_S3C_TYPE(2440a, 0x2441)
208 +IS_S3C_TYPE(2442, 0x2442)
209 +IS_S3C_TYPE(2443, 0x2443)
210 +IS_S3C_TYPE(6400, 0x6400)
211 +IS_S3C_TYPE(6410, 0x6410)
212 +
213 +#define cpu_is_s3c2400()               0
214 +#define cpu_is_s3c2410()               0
215 +#define cpu_is_s3c2410a()              0
216 +#define cpu_is_s3c2412()               0
217 +#define cpu_is_s3c2440()               0
218 +#define cpu_is_s3c2440a()              0
219 +#define cpu_is_s3c2442()               0
220 +#define cpu_is_s3c2443()               0
221 +#define cpu_is_s3c6400()               0
222 +#define cpu_is_s3c6410()               0
223 +
224 +#if defined(CONFIG_ARCH_S3C2410)
225 +# undef  cpu_is_s3c2400
226 +# define cpu_is_s3c2400()              is_s3c2400()
227 +#endif
228 +
229 +#if defined(CONFIG_CPU_S3C2410)
230 +# undef  cpu_is_s3c2410
231 +# undef  cpu_is_s3c2410a
232 +# define cpu_is_s3c2410()              is_s3c2410()
233 +# define cpu_is_s3c2410a()             is_s3c2410a()
234 +#endif
235 +
236 +#if defined(CONFIG_CPU_S3C2412)
237 +# undef  cpu_is_s3c2412
238 +# define cpu_is_s3c2412()              is_s3c2412()
239 +#endif
240 +
241 +#if defined(CONFIG_CPU_S3C2440)
242 +# undef  cpu_is_s3c2440
243 +# undef  cpu_is_s3c2440a
244 +# define cpu_is_s3c2440()              is_s3c2440()
245 +# define cpu_is_s3c2440a()             is_s3c2440a()
246 +#endif
247 +
248 +#if defined(CONFIG_CPU_S3C2442)
249 +# undef  cpu_is_s3c2442
250 +# define cpu_is_s3c2442()              is_s3c2442()
251 +#endif
252 +
253 +#if defined(CONFIG_CPU_S3C2443)
254 +# undef  cpu_is_s3c2443
255 +# define cpu_is_s3c2443()              is_s3c2443()
256 +#endif
257 +
258 +#if defined(CONFIG_ARCH_S3C64XX)
259 +# undef  cpu_is_s3c6400
260 +# undef  cpu_is_s3c6410
261 +# define cpu_is_s3c6400()              is_s3c6400()
262 +# define cpu_is_s3c6410()              is_s3c6410()
263 +#endif
264 +
265 +#endif
266 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/devs.h
267 ===================================================================
268 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/include/plat/devs.h 2009-05-16 06:12:57.000000000 +0200
269 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/devs.h      2009-05-18 19:07:48.000000000 +0200
270 @@ -16,6 +16,10 @@
271         unsigned long            nr_resources;
272  };
273  
274 +struct s3c_plat_otg_data {
275 +       int             phyclk;
276 +};
277 +
278  extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
279  extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
280  
281 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/gpio-core.h
282 ===================================================================
283 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/include/plat/gpio-core.h    2009-05-16 06:12:57.000000000 +0200
284 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/gpio-core.h 2009-05-18 19:07:48.000000000 +0200
285 @@ -20,6 +20,19 @@
286   * specific code.
287  */
288  
289 +struct s3c_gpio_chip;
290 +
291 +/**
292 + * struct s3c_gpio_pm - power management (suspend/resume) information
293 + * @save: Routine to save the state of the GPIO block
294 + * @resume: Routine to resume the GPIO block.
295 + */
296 +struct s3c_gpio_pm {
297 +       void (*save)(struct s3c_gpio_chip *chip);
298 +       void (*resume)(struct s3c_gpio_chip *chip);
299 +};
300 +
301 +
302  struct s3c_gpio_cfg;
303  
304  /**
305 @@ -27,6 +40,7 @@
306   * @chip: The chip structure to be exported via gpiolib.
307   * @base: The base pointer to the gpio configuration registers.
308   * @config: special function and pull-resistor control information.
309 + * @pm_save: Save information for suspend/resume support.
310   *
311   * This wrapper provides the necessary information for the Samsung
312   * specific gpios being registered with gpiolib.
313 @@ -34,7 +48,11 @@
314  struct s3c_gpio_chip {
315         struct gpio_chip        chip;
316         struct s3c_gpio_cfg     *config;
317 +       struct s3c_gpio_pm      *pm;
318         void __iomem            *base;
319 +#ifdef CONFIG_PM
320 +       u32                     pm_save[4];
321 +#endif
322  };
323  
324  static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
325 @@ -75,3 +93,16 @@
326  
327  static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
328  #endif
329 +
330 +#ifdef CONFIG_PM
331 +extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
332 +extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
333 +extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
334 +#define __gpio_pm(x) x
335 +#else
336 +#define s3c_gpio_pm_1bit NULL
337 +#define s3c_gpio_pm_2bit NULL
338 +#define s3c_gpio_pm_4bit NULL
339 +#define __gpio_pm(x) NULL
340 +
341 +#endif /* CONFIG_PM */
342 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/map-base.h
343 ===================================================================
344 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/include/plat/map-base.h     2009-05-16 06:12:57.000000000 +0200
345 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/map-base.h  2009-05-18 19:07:48.000000000 +0200
346 @@ -36,5 +36,7 @@
347  #define S3C_VA_TIMER   S3C_ADDR(0x00300000)    /* timer block */
348  #define S3C_VA_WATCHDOG        S3C_ADDR(0x00400000)    /* watchdog */
349  #define S3C_VA_UART    S3C_ADDR(0x01000000)    /* UART */
350 +#define S3C_VA_OTG     S3C_ADDR(0x03900000)    /* OTG */
351 +#define S3C_VA_OTGSFR  S3C_ADDR(0x03a00000)    /* OTGSFR */
352  
353  #endif /* __ASM_PLAT_MAP_H */
354 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/nand.h
355 ===================================================================
356 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/include/plat/nand.h 2009-05-16 06:12:57.000000000 +0200
357 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/nand.h      2009-05-18 19:07:48.000000000 +0200
358 @@ -21,11 +21,14 @@
359   * partitions   = mtd partition list
360  */
361  
362 +#define S3C2410_NAND_BBT       0x0001
363 +
364  struct s3c2410_nand_set {
365         unsigned int            disable_ecc : 1;
366  
367         int                     nr_chips;
368         int                     nr_partitions;
369 +       unsigned int            flags;
370         char                    *name;
371         int                     *nr_map;
372         struct mtd_partition    *partitions;
373 @@ -44,6 +47,9 @@
374         int                     nr_sets;
375         struct s3c2410_nand_set *sets;
376  
377 +       /* force software_ecc at runtime */
378 +       int     software_ecc;
379 +
380         void                    (*select_chip)(struct s3c2410_nand_set *,
381                                                int chip);
382  };
383 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/pm.h
384 ===================================================================
385 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/include/plat/pm.h   2009-05-16 06:12:57.000000000 +0200
386 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/pm.h        2009-05-18 19:07:48.000000000 +0200
387 @@ -9,6 +9,8 @@
388   * published by the Free Software Foundation.
389  */
390  
391 +#include <linux/sysdev.h>
392 +
393  /* s3c_pm_init
394   *
395   * called from board at initialisation time to setup the power
396 @@ -44,6 +46,8 @@
397  
398  extern unsigned long s3c_pm_flags;
399  
400 +extern unsigned char pm_uart_udivslot;  /* true to save UART UDIVSLOT */
401 +
402  /* from sleep.S */
403  
404  extern int  s3c_cpu_save(unsigned long *saveblk);
405 @@ -88,6 +92,7 @@
406         u32     ufcon;
407         u32     umcon;
408         u32     ubrdiv;
409 +       u32     udivslot;
410  };
411  
412  /* helper functions to save/restore lists of registers. */
413 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/sdhci.h
414 ===================================================================
415 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/include/plat/sdhci.h        2009-05-16 06:12:57.000000000 +0200
416 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/sdhci.h     2009-05-18 19:07:48.000000000 +0200
417 @@ -29,6 +29,7 @@
418   *            is necessary the controllers and/or GPIO blocks require the
419   *           changing of driver-strength and other controls dependant on
420   *           the card and speed of operation.
421 + * sdhci_host: Pointer kept during init, allows presence change notification
422   *
423   * Initialisation data specific to either the machine or the platform
424   * for the device driver to use or call-back when configuring gpio or
425 @@ -45,8 +46,11 @@
426                             void __iomem *regbase,
427                             struct mmc_ios *ios,
428                             struct mmc_card *card);
429 +       struct sdhci_host * sdhci_host;
430  };
431  
432 +extern void sdhci_s3c_force_presence_change(struct platform_device *pdev);
433 +
434  /**
435   * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
436   * @pd: Platform data to register to device.
437 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/init.c
438 ===================================================================
439 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/init.c      2009-05-16 06:12:57.000000000 +0200
440 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/init.c   2009-05-18 19:07:48.000000000 +0200
441 @@ -31,6 +31,34 @@
442  
443  static struct cpu_table *cpu;
444  
445 +static void __init set_system_rev(unsigned int idcode)
446 +{
447 +       /*
448 +        * system_rev encoding is as follows
449 +        * system_rev & 0xff000000 -> S3C Class (24xx/64xx)
450 +        * system_rev & 0xfff00000 -> S3C Sub Class (241x/244x)
451 +        * system_rev & 0xffff0000 -> S3C Type (2410/2440/6400/6410)
452 +        *
453 +        * Remaining[15:0] are preserved from the value set by ATAG
454 +        *
455 +        * Exception:
456 +        *  Store Revision A to 1 such as
457 +        *  s3c2410A to s3c2411
458 +        *  s3c2440A to s3c2441
459 +        */
460 +
461 +       system_rev &= 0xffff;
462 +       system_rev |= (idcode & 0x0ffff000) << 4;
463 +
464 +       if (idcode == 0x32410002 || idcode == 0x32440001)
465 +               system_rev |= (0x1 << 16);
466 +       if (idcode == 0x32440aaa        /* s3c2442 */
467 +           || idcode == 0x32440aab)    /* s3c2442b */
468 +               system_rev |= (0x2 << 16);
469 +       if (idcode == 0x0)              /* s3c2400 */
470 +               system_rev |= (0x2400 << 16);
471 +}
472 +
473  static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
474                                                 struct cpu_table *tab,
475                                                 unsigned int count)
476 @@ -53,6 +81,8 @@
477                 panic("Unknown S3C24XX CPU");
478         }
479  
480 +       set_system_rev(idcode);
481 +
482         printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
483  
484         if (cpu->map_io == NULL || cpu->init == NULL) {
485 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/Makefile
486 ===================================================================
487 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/Makefile    2009-05-16 06:12:57.000000000 +0200
488 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/Makefile 2009-05-18 19:07:48.000000000 +0200
489 @@ -21,6 +21,7 @@
490  # PM support
491  
492  obj-$(CONFIG_PM)               += pm.o
493 +obj-$(CONFIG_PM)               += pm-gpio.o
494  obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o
495  
496  # devices
497 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/pm.c
498 ===================================================================
499 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/pm.c        2009-05-16 06:12:57.000000000 +0200
500 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/pm.c     2009-05-18 19:07:48.000000000 +0200
501 @@ -21,11 +21,10 @@
502  
503  #include <asm/cacheflush.h>
504  #include <mach/hardware.h>
505 +#include <mach/map.h>
506  
507  #include <plat/regs-serial.h>
508  #include <mach/regs-clock.h>
509 -#include <mach/regs-gpio.h>
510 -#include <mach/regs-mem.h>
511  #include <mach/regs-irq.h>
512  #include <asm/irq.h>
513  
514 @@ -70,6 +69,8 @@
515  
516  /* Save the UART configurations if we are configured for debug. */
517  
518 +unsigned char pm_uart_udivslot;
519 +
520  #ifdef CONFIG_S3C2410_PM_DEBUG
521  
522  struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
523 @@ -83,6 +84,12 @@
524         save->ufcon = __raw_readl(regs + S3C2410_UFCON);
525         save->umcon = __raw_readl(regs + S3C2410_UMCON);
526         save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
527 +
528 +       if (pm_uart_udivslot)
529 +               save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
530 +
531 +       S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
532 +                 uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
533  }
534  
535  static void s3c_pm_save_uarts(void)
536 @@ -98,11 +105,16 @@
537  {
538         void __iomem *regs = S3C_VA_UARTx(uart);
539  
540 +       s3c_pm_arch_update_uart(regs, save);
541 +
542         __raw_writel(save->ulcon, regs + S3C2410_ULCON);
543         __raw_writel(save->ucon,  regs + S3C2410_UCON);
544         __raw_writel(save->ufcon, regs + S3C2410_UFCON);
545         __raw_writel(save->umcon, regs + S3C2410_UMCON);
546         __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
547 +
548 +       if (pm_uart_udivslot)
549 +               __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
550  }
551  
552  static void s3c_pm_restore_uarts(void)
553 @@ -289,11 +301,14 @@
554  
555         s3c_pm_arch_stop_clocks();
556  
557 -       /* s3c_cpu_save will also act as our return point from when
558 -        * we resume as it saves its own register state and restores it
559 -        * during the resume.  */
560 -
561 -       s3c_cpu_save(regs_save);
562 +       /* s3c2410_cpu_save will also act as our return point from when
563 +        * we resume as it saves its own register state, so use the return
564 +        * code to differentiate return from save and return from sleep */
565 +
566 +       if (s3c_cpu_save(regs_save) == 0) {
567 +               flush_cache_all();
568 +               pm_cpu_sleep();
569 +       }
570  
571         /* restore the cpu state using the kernel's cpu init code. */
572  
573 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/pm-gpio.c
574 ===================================================================
575 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
576 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/pm-gpio.c        2009-05-18 19:07:48.000000000 +0200
577 @@ -0,0 +1,378 @@
578 +/* linux/arch/arm/plat-s3c/pm-gpio.c
579 + *
580 + * Copyright 2008 Openmoko, Inc.
581 + * Copyright 2008 Simtec Electronics
582 + *     Ben Dooks <ben@simtec.co.uk>
583 + *     http://armlinux.simtec.co.uk/
584 + *
585 + * S3C series GPIO PM code
586 + *
587 + * This program is free software; you can redistribute it and/or modify
588 + * it under the terms of the GNU General Public License version 2 as
589 + * published by the Free Software Foundation.
590 +*/
591 +
592 +#include <linux/kernel.h>
593 +#include <linux/init.h>
594 +#include <linux/io.h>
595 +#include <linux/gpio.h>
596 +
597 +#include <mach/gpio-core.h>
598 +#include <plat/pm.h>
599 +
600 +/* PM GPIO helpers */
601 +
602 +#define OFFS_CON       (0x00)
603 +#define OFFS_DAT       (0X04)
604 +#define OFFS_UP                (0X08)
605 +
606 +static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
607 +{
608 +       chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
609 +       chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
610 +}
611 +
612 +static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
613 +{
614 +       void __iomem *base = chip->base;
615 +       u32 old_gpcon = __raw_readl(base + OFFS_CON);
616 +       u32 old_gpdat = __raw_readl(base + OFFS_DAT);
617 +       u32 gps_gpcon = chip->pm_save[0];
618 +       u32 gps_gpdat = chip->pm_save[1];
619 +       u32 gpcon;
620 +
621 +       /* GPACON only has one bit per control / data and no PULLUPs.
622 +        * GPACON[x] = 0 => Output, 1 => SFN */
623 +
624 +       /* first set all SFN bits to SFN */
625 +
626 +       gpcon = old_gpcon | gps_gpcon;
627 +       __raw_writel(gpcon, base + OFFS_CON);
628 +
629 +       /* now set all the other bits */
630 +
631 +       __raw_writel(gps_gpdat, base + OFFS_DAT);
632 +       __raw_writel(gps_gpcon, base + OFFS_CON);
633 +
634 +       S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
635 +                 chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
636 +}
637 +
638 +struct s3c_gpio_pm s3c_gpio_pm_1bit = {
639 +       .save   = s3c_gpio_pm_1bit_save,
640 +       .resume = s3c_gpio_pm_1bit_resume,
641 +};
642 +
643 +static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
644 +{
645 +       chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
646 +       chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
647 +       chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
648 +}
649 +
650 +/* Test whether the given masked+shifted bits of an GPIO configuration
651 + * are one of the SFN (special function) modes. */
652 +
653 +static inline int is_sfn(unsigned long con)
654 +{
655 +       return con >= 2;
656 +}
657 +
658 +/* Test if the given masked+shifted GPIO configuration is an input */
659 +
660 +static inline int is_in(unsigned long con)
661 +{
662 +       return con == 0;
663 +}
664 +
665 +/* Test if the given masked+shifted GPIO configuration is an output */
666 +
667 +static inline int is_out(unsigned long con)
668 +{
669 +       return con == 1;
670 +}
671 +
672 +/**
673 + * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
674 + * @chip: The chip information to resume.
675 + *
676 + * Restore one of the GPIO banks that was saved during suspend. This is
677 + * not as simple as once thought, due to the possibility of glitches
678 + * from the order that the CON and DAT registers are set in.
679 + *
680 + * The three states the pin can be are {IN,OUT,SFN} which gives us 9
681 + * combinations of changes to check. Three of these, if the pin stays
682 + * in the same configuration can be discounted. This leaves us with
683 + * the following:
684 + *
685 + * { IN => OUT }  Change DAT first
686 + * { IN => SFN }  Change CON first
687 + * { OUT => SFN } Change CON first, so new data will not glitch
688 + * { OUT => IN }  Change CON first, so new data will not glitch
689 + * { SFN => IN }  Change CON first
690 + * { SFN => OUT } Change DAT first, so new data will not glitch [1]
691 + *
692 + * We do not currently deal with the UP registers as these control
693 + * weak resistors, so a small delay in change should not need to bring
694 + * these into the calculations.
695 + *
696 + * [1] this assumes that writing to a pin DAT whilst in SFN will set the
697 + *     state for when it is next output.
698 + */
699 +static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
700 +{
701 +       void __iomem *base = chip->base;
702 +       u32 old_gpcon = __raw_readl(base + OFFS_CON);
703 +       u32 old_gpdat = __raw_readl(base + OFFS_DAT);
704 +       u32 gps_gpcon = chip->pm_save[0];
705 +       u32 gps_gpdat = chip->pm_save[1];
706 +       u32 gpcon, old, new, mask;
707 +       u32 change_mask = 0x0;
708 +       int nr;
709 +
710 +       /* restore GPIO pull-up settings */
711 +       __raw_writel(chip->pm_save[2], base + OFFS_UP);
712 +
713 +       /* Create a change_mask of all the items that need to have
714 +        * their CON value changed before their DAT value, so that
715 +        * we minimise the work between the two settings.
716 +        */
717 +
718 +       for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
719 +               old = (old_gpcon & mask) >> nr;
720 +               new = (gps_gpcon & mask) >> nr;
721 +
722 +               /* If there is no change, then skip */
723 +
724 +               if (old == new)
725 +                       continue;
726 +
727 +               /* If both are special function, then skip */
728 +
729 +               if (is_sfn(old) && is_sfn(new))
730 +                       continue;
731 +
732 +               /* Change is IN => OUT, do not change now */
733 +
734 +               if (is_in(old) && is_out(new))
735 +                       continue;
736 +
737 +               /* Change is SFN => OUT, do not change now */
738 +
739 +               if (is_sfn(old) && is_out(new))
740 +                       continue;
741 +
742 +               /* We should now be at the case of IN=>SFN,
743 +                * OUT=>SFN, OUT=>IN, SFN=>IN. */
744 +
745 +               change_mask |= mask;
746 +       }
747 +
748 +
749 +       /* Write the new CON settings */
750 +
751 +       gpcon = old_gpcon & ~change_mask;
752 +       gpcon |= gps_gpcon & change_mask;
753 +
754 +       __raw_writel(gpcon, base + OFFS_CON);
755 +
756 +       /* Now change any items that require DAT,CON */
757 +
758 +       __raw_writel(gps_gpdat, base + OFFS_DAT);
759 +       __raw_writel(gps_gpcon, base + OFFS_CON);
760 +
761 +       S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
762 +                 chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
763 +}
764 +
765 +struct s3c_gpio_pm s3c_gpio_pm_2bit = {
766 +       .save   = s3c_gpio_pm_2bit_save,
767 +       .resume = s3c_gpio_pm_2bit_resume,
768 +};
769 +
770 +#ifdef CONFIG_ARCH_S3C64XX
771 +static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
772 +{
773 +       chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
774 +       chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
775 +       chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
776 +
777 +       if (chip->chip.ngpio > 8)
778 +               chip->pm_save[0] = __raw_readl(chip->base - 4);
779 +}
780 +
781 +static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
782 +{
783 +       u32 old, new, mask;
784 +       u32 change_mask = 0x0;
785 +       int nr;
786 +
787 +       for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
788 +               old = (old_gpcon & mask) >> nr;
789 +               new = (gps_gpcon & mask) >> nr;
790 +
791 +               /* If there is no change, then skip */
792 +
793 +               if (old == new)
794 +                       continue;
795 +
796 +               /* If both are special function, then skip */
797 +
798 +               if (is_sfn(old) && is_sfn(new))
799 +                       continue;
800 +
801 +               /* Change is IN => OUT, do not change now */
802 +
803 +               if (is_in(old) && is_out(new))
804 +                       continue;
805 +
806 +               /* Change is SFN => OUT, do not change now */
807 +
808 +               if (is_sfn(old) && is_out(new))
809 +                       continue;
810 +
811 +               /* We should now be at the case of IN=>SFN,
812 +                * OUT=>SFN, OUT=>IN, SFN=>IN. */
813 +
814 +               change_mask |= mask;
815 +       }
816 +
817 +       return change_mask;
818 +}
819 +
820 +static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
821 +{
822 +       void __iomem *con = chip->base + (index * 4);
823 +       u32 old_gpcon = __raw_readl(con);
824 +       u32 gps_gpcon = chip->pm_save[index + 1];
825 +       u32 gpcon, mask;
826 +
827 +       mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
828 +
829 +       gpcon = old_gpcon & ~mask;
830 +       gpcon |= gps_gpcon & mask;
831 +
832 +       __raw_writel(gpcon, con);
833 +}
834 +
835 +static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
836 +{
837 +       void __iomem *base = chip->base;
838 +       u32 old_gpcon[2];
839 +       u32 old_gpdat = __raw_readl(base + OFFS_DAT);
840 +       u32 gps_gpdat = chip->pm_save[2];
841 +
842 +       /* First, modify the CON settings */
843 +
844 +       old_gpcon[0] = 0;
845 +       old_gpcon[1] = __raw_readl(base + OFFS_CON);
846 +
847 +       s3c_gpio_pm_4bit_con(chip, 0);
848 +       if (chip->chip.ngpio > 8) {
849 +               old_gpcon[0] = __raw_readl(base - 4);
850 +               s3c_gpio_pm_4bit_con(chip, -1);
851 +       }
852 +
853 +       /* Now change the configurations that require DAT,CON */
854 +
855 +       __raw_writel(chip->pm_save[2], base + OFFS_DAT);
856 +       __raw_writel(chip->pm_save[1], base + OFFS_CON);
857 +       if (chip->chip.ngpio > 8)
858 +               __raw_writel(chip->pm_save[0], base - 4);
859 +
860 +       __raw_writel(chip->pm_save[2], base + OFFS_DAT);
861 +       __raw_writel(chip->pm_save[3], base + OFFS_UP);
862 +
863 +       if (chip->chip.ngpio > 8) {
864 +               S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
865 +                         chip->chip.label, old_gpcon[0], old_gpcon[1],
866 +                         __raw_readl(base - 4),
867 +                         __raw_readl(base + OFFS_CON),
868 +                         old_gpdat, gps_gpdat);
869 +       } else
870 +               S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
871 +                         chip->chip.label, old_gpcon[1],
872 +                         __raw_readl(base + OFFS_CON),
873 +                         old_gpdat, gps_gpdat);
874 +}
875 +
876 +struct s3c_gpio_pm s3c_gpio_pm_4bit = {
877 +       .save   = s3c_gpio_pm_4bit_save,
878 +       .resume = s3c_gpio_pm_4bit_resume,
879 +};
880 +#endif /* CONFIG_ARCH_S3C64XX */
881 +
882 +/**
883 + * s3c_pm_save_gpio() - save gpio chip data for suspend
884 + * @ourchip: The chip for suspend.
885 + */
886 +static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
887 +{
888 +       struct s3c_gpio_pm *pm = ourchip->pm;
889 +
890 +       if (pm == NULL || pm->save == NULL)
891 +               S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
892 +       else
893 +               pm->save(ourchip);
894 +}
895 +
896 +/**
897 + * s3c_pm_save_gpios() - Save the state of the GPIO banks.
898 + *
899 + * For all the GPIO banks, save the state of each one ready for going
900 + * into a suspend mode.
901 + */
902 +void s3c_pm_save_gpios(void)
903 +{
904 +       struct s3c_gpio_chip *ourchip;
905 +       unsigned int gpio_nr;
906 +
907 +       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
908 +               ourchip = s3c_gpiolib_getchip(gpio_nr);
909 +               if (!ourchip)
910 +                       continue;
911 +
912 +               s3c_pm_save_gpio(ourchip);
913 +
914 +               S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
915 +                         ourchip->chip.label,
916 +                         ourchip->pm_save[0],
917 +                         ourchip->pm_save[1],
918 +                         ourchip->pm_save[2],
919 +                         ourchip->pm_save[3]);
920 +
921 +               gpio_nr += ourchip->chip.ngpio;
922 +               gpio_nr += CONFIG_S3C_GPIO_SPACE;
923 +       }
924 +}
925 +
926 +/**
927 + * s3c_pm_resume_gpio() - restore gpio chip data after suspend
928 + * @ourchip: The suspended chip.
929 + */
930 +static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
931 +{
932 +       struct s3c_gpio_pm *pm = ourchip->pm;
933 +
934 +       if (pm == NULL || pm->resume == NULL)
935 +               S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
936 +       else
937 +               pm->resume(ourchip);
938 +}
939 +
940 +void s3c_pm_restore_gpios(void)
941 +{
942 +       struct s3c_gpio_chip *ourchip;
943 +       unsigned int gpio_nr;
944 +
945 +       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
946 +               ourchip = s3c_gpiolib_getchip(gpio_nr);
947 +               if (!ourchip)
948 +                       continue;
949 +
950 +               s3c_pm_resume_gpio(ourchip);
951 +
952 +               gpio_nr += ourchip->chip.ngpio;
953 +               gpio_nr += CONFIG_S3C_GPIO_SPACE;
954 +       }
955 +}
956 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/clock-dclk.c
957 ===================================================================
958 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/clock-dclk.c    2009-05-16 06:12:57.000000000 +0200
959 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/clock-dclk.c 2009-05-18 19:07:48.000000000 +0200
960 @@ -18,6 +18,7 @@
961  
962  #include <mach/regs-clock.h>
963  #include <mach/regs-gpio.h>
964 +#include <mach/hardware.h>
965  
966  #include <plat/clock.h>
967  #include <plat/cpu.h>
968 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/cpu.c
969 ===================================================================
970 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/cpu.c   2009-05-16 06:12:57.000000000 +0200
971 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/cpu.c        2009-05-18 19:07:48.000000000 +0200
972 @@ -61,6 +61,7 @@
973  static const char name_s3c2412[]  = "S3C2412";
974  static const char name_s3c2440[]  = "S3C2440";
975  static const char name_s3c2442[]  = "S3C2442";
976 +static const char name_s3c2442b[]  = "S3C2442B";
977  static const char name_s3c2443[]  = "S3C2443";
978  static const char name_s3c2410a[] = "S3C2410A";
979  static const char name_s3c2440a[] = "S3C2440A";
980 @@ -112,6 +113,15 @@
981                 .name           = name_s3c2442
982         },
983         {
984 +               .idcode         = 0x32440aab,
985 +               .idmask         = 0xffffffff,
986 +               .map_io         = s3c244x_map_io,
987 +               .init_clocks    = s3c244x_init_clocks,
988 +               .init_uarts     = s3c244x_init_uarts,
989 +               .init           = s3c2442_init,
990 +               .name           = name_s3c2442b
991 +       },
992 +       {
993                 .idcode         = 0x32412001,
994                 .idmask         = 0xffffffff,
995                 .map_io         = s3c2412_map_io,
996 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/gpiolib.c
997 ===================================================================
998 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/gpiolib.c       2009-05-16 06:12:57.000000000 +0200
999 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/gpiolib.c    2009-05-18 19:07:48.000000000 +0200
1000 @@ -19,9 +19,10 @@
1001  #include <linux/io.h>
1002  #include <linux/gpio.h>
1003  
1004 -#include <mach/gpio-core.h>
1005 +#include <plat/gpio-core.h>
1006  #include <mach/hardware.h>
1007  #include <asm/irq.h>
1008 +#include <plat/pm.h>
1009  
1010  #include <mach/regs-gpio.h>
1011  
1012 @@ -78,6 +79,7 @@
1013  struct s3c_gpio_chip s3c24xx_gpios[] = {
1014         [0] = {
1015                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPA0),
1016 +               .pm     = __gpio_pm(&s3c_gpio_pm_1bit),
1017                 .chip   = {
1018                         .base                   = S3C2410_GPA0,
1019                         .owner                  = THIS_MODULE,
1020 @@ -89,6 +91,7 @@
1021         },
1022         [1] = {
1023                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPB0),
1024 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1025                 .chip   = {
1026                         .base                   = S3C2410_GPB0,
1027                         .owner                  = THIS_MODULE,
1028 @@ -98,6 +101,7 @@
1029         },
1030         [2] = {
1031                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPC0),
1032 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1033                 .chip   = {
1034                         .base                   = S3C2410_GPC0,
1035                         .owner                  = THIS_MODULE,
1036 @@ -107,6 +111,7 @@
1037         },
1038         [3] = {
1039                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPD0),
1040 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1041                 .chip   = {
1042                         .base                   = S3C2410_GPD0,
1043                         .owner                  = THIS_MODULE,
1044 @@ -116,6 +121,7 @@
1045         },
1046         [4] = {
1047                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPE0),
1048 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1049                 .chip   = {
1050                         .base                   = S3C2410_GPE0,
1051                         .label                  = "GPIOE",
1052 @@ -125,6 +131,7 @@
1053         },
1054         [5] = {
1055                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPF0),
1056 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1057                 .chip   = {
1058                         .base                   = S3C2410_GPF0,
1059                         .owner                  = THIS_MODULE,
1060 @@ -135,12 +142,23 @@
1061         },
1062         [6] = {
1063                 .base   = S3C24XX_GPIO_BASE(S3C2410_GPG0),
1064 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1065                 .chip   = {
1066                         .base                   = S3C2410_GPG0,
1067                         .owner                  = THIS_MODULE,
1068                         .label                  = "GPIOG",
1069 -                       .ngpio                  = 10,
1070                         .to_irq                 = s3c24xx_gpiolib_bankg_toirq,
1071 +                       .ngpio                  = 16,
1072 +               },
1073 +       },
1074 +       [7] = {
1075 +               .base   = S3C24XX_GPIO_BASE(S3C2410_GPH0),
1076 +               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
1077 +               .chip   = {
1078 +                       .base                   = S3C2410_GPH0,
1079 +                       .owner                  = THIS_MODULE,
1080 +                       .label                  = "GPIOH",
1081 +                       .ngpio                  = 11,
1082                 },
1083         },
1084  };
1085 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/include/plat/pm-core.h
1086 ===================================================================
1087 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/include/plat/pm-core.h  2009-05-16 06:12:57.000000000 +0200
1088 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/include/plat/pm-core.h       2009-05-18 19:07:48.000000000 +0200
1089 @@ -57,3 +57,8 @@
1090         s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
1091                                 s3c_irqwake_eintmask);
1092  }
1093 +
1094 +static inline void s3c_pm_arch_update_uart(void __iomem *regs,
1095 +                                          struct pm_uart_save *save)
1096 +{
1097 +}
1098 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/irq-pm.c
1099 ===================================================================
1100 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/irq-pm.c        2009-05-16 06:12:57.000000000 +0200
1101 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/irq-pm.c     2009-05-18 19:07:48.000000000 +0200
1102 @@ -15,6 +15,7 @@
1103  #include <linux/module.h>
1104  #include <linux/interrupt.h>
1105  #include <linux/sysdev.h>
1106 +#include <linux/irq.h>
1107  
1108  #include <plat/cpu.h>
1109  #include <plat/pm.h>
1110 @@ -80,7 +81,9 @@
1111  
1112  int s3c24xx_irq_resume(struct sys_device *dev)
1113  {
1114 -       unsigned int i;
1115 +       unsigned int i, irq;
1116 +       unsigned long eintpnd;
1117 +       struct irq_desc *desc;
1118  
1119         for (i = 0; i < ARRAY_SIZE(save_extint); i++)
1120                 __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
1121 @@ -91,5 +94,25 @@
1122         s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
1123         __raw_writel(save_eintmask, S3C24XX_EINTMASK);
1124  
1125 +       /*
1126 +        * ACK those interrupts which are now masked and pending.
1127 +        * Level interrupts if not ACKed here, create an interrupt storm
1128 +        * because they are not handled at all.
1129 +        */
1130 +
1131 +       eintpnd = __raw_readl(S3C24XX_EINTPEND);
1132 +
1133 +       eintpnd &= save_eintmask;
1134 +       eintpnd &= ~0xff;       /* ignore lower irqs */
1135 +
1136 +       while (eintpnd) {
1137 +               irq = __ffs(eintpnd);
1138 +               eintpnd &= ~(1 << irq);
1139 +
1140 +               irq += (IRQ_EINT4 - 4);
1141 +               desc = irq_to_desc(irq);
1142 +               desc->chip->ack(irq);
1143 +       }
1144 +
1145         return 0;
1146  }
1147 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/pm.c
1148 ===================================================================
1149 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c24xx/pm.c    2009-05-16 06:12:57.000000000 +0200
1150 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/pm.c 2009-05-18 19:07:48.000000000 +0200
1151 @@ -39,6 +39,7 @@
1152  #include <mach/regs-gpio.h>
1153  #include <mach/regs-mem.h>
1154  #include <mach/regs-irq.h>
1155 +#include <mach/hardware.h>
1156  
1157  #include <asm/mach/time.h>
1158  
1159 @@ -75,43 +76,10 @@
1160         SAVE_ITEM(S3C2410_CLKSLOW),
1161  };
1162  
1163 -static struct gpio_sleep {
1164 -       void __iomem    *base;
1165 -       unsigned int     gpcon;
1166 -       unsigned int     gpdat;
1167 -       unsigned int     gpup;
1168 -} gpio_save[] = {
1169 -       [0] = {
1170 -               .base   = S3C2410_GPACON,
1171 -       },
1172 -       [1] = {
1173 -               .base   = S3C2410_GPBCON,
1174 -       },
1175 -       [2] = {
1176 -               .base   = S3C2410_GPCCON,
1177 -       },
1178 -       [3] = {
1179 -               .base   = S3C2410_GPDCON,
1180 -       },
1181 -       [4] = {
1182 -               .base   = S3C2410_GPECON,
1183 -       },
1184 -       [5] = {
1185 -               .base   = S3C2410_GPFCON,
1186 -       },
1187 -       [6] = {
1188 -               .base   = S3C2410_GPGCON,
1189 -       },
1190 -       [7] = {
1191 -               .base   = S3C2410_GPHCON,
1192 -       },
1193 -};
1194 -
1195  static struct sleep_save misc_save[] = {
1196         SAVE_ITEM(S3C2410_DCLKCON),
1197  };
1198  
1199 -
1200  /* s3c_pm_check_resume_pin
1201   *
1202   * check to see if the pin is configured correctly for sleep mode, and
1203 @@ -165,186 +133,6 @@
1204         }
1205  }
1206  
1207 -/* offsets for CON/DAT/UP registers */
1208 -
1209 -#define OFFS_CON       (S3C2410_GPACON - S3C2410_GPACON)
1210 -#define OFFS_DAT       (S3C2410_GPADAT - S3C2410_GPACON)
1211 -#define OFFS_UP                (S3C2410_GPBUP  - S3C2410_GPBCON)
1212 -
1213 -/* s3c_pm_save_gpios()
1214 - *
1215 - * Save the state of the GPIOs
1216 - */
1217 -
1218 -void s3c_pm_save_gpios(void)
1219 -{
1220 -       struct gpio_sleep *gps = gpio_save;
1221 -       unsigned int gpio;
1222 -
1223 -       for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
1224 -               void __iomem *base = gps->base;
1225 -
1226 -               gps->gpcon = __raw_readl(base + OFFS_CON);
1227 -               gps->gpdat = __raw_readl(base + OFFS_DAT);
1228 -
1229 -               if (gpio > 0)
1230 -                       gps->gpup = __raw_readl(base + OFFS_UP);
1231 -
1232 -       }
1233 -}
1234 -
1235 -/* Test whether the given masked+shifted bits of an GPIO configuration
1236 - * are one of the SFN (special function) modes. */
1237 -
1238 -static inline int is_sfn(unsigned long con)
1239 -{
1240 -       return (con == 2 || con == 3);
1241 -}
1242 -
1243 -/* Test if the given masked+shifted GPIO configuration is an input */
1244 -
1245 -static inline int is_in(unsigned long con)
1246 -{
1247 -       return con == 0;
1248 -}
1249 -
1250 -/* Test if the given masked+shifted GPIO configuration is an output */
1251 -
1252 -static inline int is_out(unsigned long con)
1253 -{
1254 -       return con == 1;
1255 -}
1256 -
1257 -/**
1258 - * s3c2410_pm_restore_gpio() - restore the given GPIO bank
1259 - * @index: The number of the GPIO bank being resumed.
1260 - * @gps: The sleep confgiuration for the bank.
1261 - *
1262 - * Restore one of the GPIO banks that was saved during suspend. This is
1263 - * not as simple as once thought, due to the possibility of glitches
1264 - * from the order that the CON and DAT registers are set in.
1265 - *
1266 - * The three states the pin can be are {IN,OUT,SFN} which gives us 9
1267 - * combinations of changes to check. Three of these, if the pin stays
1268 - * in the same configuration can be discounted. This leaves us with
1269 - * the following:
1270 - *
1271 - * { IN => OUT }  Change DAT first
1272 - * { IN => SFN }  Change CON first
1273 - * { OUT => SFN } Change CON first, so new data will not glitch
1274 - * { OUT => IN }  Change CON first, so new data will not glitch
1275 - * { SFN => IN }  Change CON first
1276 - * { SFN => OUT } Change DAT first, so new data will not glitch [1]
1277 - *
1278 - * We do not currently deal with the UP registers as these control
1279 - * weak resistors, so a small delay in change should not need to bring
1280 - * these into the calculations.
1281 - *
1282 - * [1] this assumes that writing to a pin DAT whilst in SFN will set the
1283 - *     state for when it is next output.
1284 - */
1285 -
1286 -static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps)
1287 -{
1288 -       void __iomem *base = gps->base;
1289 -       unsigned long gps_gpcon = gps->gpcon;
1290 -       unsigned long gps_gpdat = gps->gpdat;
1291 -       unsigned long old_gpcon;
1292 -       unsigned long old_gpdat;
1293 -       unsigned long old_gpup = 0x0;
1294 -       unsigned long gpcon;
1295 -       int nr;
1296 -
1297 -       old_gpcon = __raw_readl(base + OFFS_CON);
1298 -       old_gpdat = __raw_readl(base + OFFS_DAT);
1299 -
1300 -       if (base == S3C2410_GPACON) {
1301 -               /* GPACON only has one bit per control / data and no PULLUPs.
1302 -                * GPACON[x] = 0 => Output, 1 => SFN */
1303 -
1304 -               /* first set all SFN bits to SFN */
1305 -
1306 -               gpcon = old_gpcon | gps->gpcon;
1307 -               __raw_writel(gpcon, base + OFFS_CON);
1308 -
1309 -               /* now set all the other bits */
1310 -
1311 -               __raw_writel(gps_gpdat, base + OFFS_DAT);
1312 -               __raw_writel(gps_gpcon, base + OFFS_CON);
1313 -       } else {
1314 -               unsigned long old, new, mask;
1315 -               unsigned long change_mask = 0x0;
1316 -
1317 -               old_gpup = __raw_readl(base + OFFS_UP);
1318 -
1319 -               /* Create a change_mask of all the items that need to have
1320 -                * their CON value changed before their DAT value, so that
1321 -                * we minimise the work between the two settings.
1322 -                */
1323 -
1324 -               for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
1325 -                       old = (old_gpcon & mask) >> nr;
1326 -                       new = (gps_gpcon & mask) >> nr;
1327 -
1328 -                       /* If there is no change, then skip */
1329 -
1330 -                       if (old == new)
1331 -                               continue;
1332 -
1333 -                       /* If both are special function, then skip */
1334 -
1335 -                       if (is_sfn(old) && is_sfn(new))
1336 -                               continue;
1337 -
1338 -                       /* Change is IN => OUT, do not change now */
1339 -
1340 -                       if (is_in(old) && is_out(new))
1341 -                               continue;
1342 -
1343 -                       /* Change is SFN => OUT, do not change now */
1344 -
1345 -                       if (is_sfn(old) && is_out(new))
1346 -                               continue;
1347 -
1348 -                       /* We should now be at the case of IN=>SFN,
1349 -                        * OUT=>SFN, OUT=>IN, SFN=>IN. */
1350 -
1351 -                       change_mask |= mask;
1352 -               }
1353 -
1354 -               /* Write the new CON settings */
1355 -
1356 -               gpcon = old_gpcon & ~change_mask;
1357 -               gpcon |= gps_gpcon & change_mask;
1358 -
1359 -               __raw_writel(gpcon, base + OFFS_CON);
1360 -
1361 -               /* Now change any items that require DAT,CON */
1362 -
1363 -               __raw_writel(gps_gpdat, base + OFFS_DAT);
1364 -               __raw_writel(gps_gpcon, base + OFFS_CON);
1365 -               __raw_writel(gps->gpup, base + OFFS_UP);
1366 -       }
1367 -
1368 -       S3C_PMDBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
1369 -                 index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
1370 -}
1371 -
1372 -
1373 -/** s3c2410_pm_restore_gpios()
1374 - *
1375 - * Restore the state of the GPIOs
1376 - */
1377 -
1378 -void s3c_pm_restore_gpios(void)
1379 -{
1380 -       struct gpio_sleep *gps = gpio_save;
1381 -       int gpio;
1382 -
1383 -       for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
1384 -               s3c2410_pm_restore_gpio(gpio, gps);
1385 -       }
1386 -}
1387  
1388  void s3c_pm_restore_core(void)
1389  {
1390 Index: linux-2.6.30-rc6/drivers/mmc/host/Kconfig
1391 ===================================================================
1392 --- linux-2.6.30-rc6.orig/drivers/mmc/host/Kconfig      2009-05-18 19:07:38.000000000 +0200
1393 +++ linux-2.6.30-rc6/drivers/mmc/host/Kconfig   2009-05-18 19:07:48.000000000 +0200
1394 @@ -37,13 +37,6 @@
1395  
1396           If unsure, say N.
1397  
1398 -config MMC_SDHCI_IO_ACCESSORS
1399 -       bool
1400 -       depends on MMC_SDHCI
1401 -       help
1402 -         This is silent Kconfig symbol that is selected by the drivers that
1403 -         need to overwrite SDHCI IO memory accessors.
1404 -
1405  config MMC_SDHCI_PCI
1406         tristate "SDHCI support on PCI bus"
1407         depends on MMC_SDHCI && PCI
1408 @@ -55,6 +48,18 @@
1409  
1410           If unsure, say N.
1411  
1412 +config MMC_SDHCI_S3C
1413 +       tristate "SDHCI support on Samsung S3C SoC"
1414 +       depends on MMC_SDHCI && PLAT_S3C24XX
1415 +       help
1416 +         This selects the Secure Digital Host Controller Interface (SDHCI)
1417 +         often referrered to as the HSMMC block in some of the Samsung S3C
1418 +         range of SoC.
1419 +
1420 +         If you have a controller with this interface, say Y or M here.
1421 +
1422 +         If unsure, say N.
1423 +
1424  config MMC_RICOH_MMC
1425         tristate "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
1426         depends on MMC_SDHCI_PCI
1427 @@ -72,17 +77,6 @@
1428  
1429           If unsure, say Y.
1430  
1431 -config MMC_SDHCI_OF
1432 -       tristate "SDHCI support on OpenFirmware platforms"
1433 -       depends on MMC_SDHCI && PPC_OF
1434 -       select MMC_SDHCI_IO_ACCESSORS
1435 -       help
1436 -         This selects the OF support for Secure Digital Host Controller
1437 -         Interfaces. So far, only the Freescale eSDHC controller is known
1438 -         to exist on OF platforms.
1439 -
1440 -         If unsure, say N.
1441 -
1442  config MMC_OMAP
1443         tristate "TI OMAP Multimedia Card Interface support"
1444         depends on ARCH_OMAP
1445 @@ -163,16 +157,6 @@
1446  
1447           If unsure, say N.
1448  
1449 -config MMC_MXC
1450 -       tristate "Freescale i.MX2/3 Multimedia Card Interface support"
1451 -       depends on ARCH_MXC
1452 -       help
1453 -         This selects the Freescale i.MX2/3 Multimedia card Interface.
1454 -         If you have a i.MX platform with a Multimedia Card slot,
1455 -         say Y or M here.
1456 -
1457 -         If unsure, say N.
1458 -
1459  config MMC_TIFM_SD
1460         tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
1461         depends on EXPERIMENTAL && PCI
1462 Index: linux-2.6.30-rc6/drivers/mmc/host/Makefile
1463 ===================================================================
1464 --- linux-2.6.30-rc6.orig/drivers/mmc/host/Makefile     2009-05-18 19:07:38.000000000 +0200
1465 +++ linux-2.6.30-rc6/drivers/mmc/host/Makefile  2009-05-18 19:07:48.000000000 +0200
1466 @@ -9,11 +9,10 @@
1467  obj-$(CONFIG_MMC_ARMMMCI)      += mmci.o
1468  obj-$(CONFIG_MMC_PXA)          += pxamci.o
1469  obj-$(CONFIG_MMC_IMX)          += imxmmc.o
1470 -obj-$(CONFIG_MMC_MXC)          += mxcmmc.o
1471  obj-$(CONFIG_MMC_SDHCI)                += sdhci.o
1472  obj-$(CONFIG_MMC_SDHCI_PCI)    += sdhci-pci.o
1473 +obj-$(CONFIG_MMC_SDHCI_S3C)    += sdhci-s3c.o
1474  obj-$(CONFIG_MMC_RICOH_MMC)    += ricoh_mmc.o
1475 -obj-$(CONFIG_MMC_SDHCI_OF)     += sdhci-of.o
1476  obj-$(CONFIG_MMC_WBSD)         += wbsd.o
1477  obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
1478  obj-$(CONFIG_MMC_OMAP)         += omap.o
1479 @@ -21,7 +20,6 @@
1480  obj-$(CONFIG_MMC_AT91)         += at91_mci.o
1481  obj-$(CONFIG_MMC_ATMELMCI)     += atmel-mci.o
1482  obj-$(CONFIG_MMC_TIFM_SD)      += tifm_sd.o
1483 -obj-$(CONFIG_MMC_MVSDIO)       += mvsdio.o
1484  obj-$(CONFIG_MMC_SPI)          += mmc_spi.o
1485  ifeq ($(CONFIG_OF),y)
1486  obj-$(CONFIG_MMC_SPI)          += of_mmc_spi.o
1487 Index: linux-2.6.30-rc6/drivers/mmc/host/s3cmci.c
1488 ===================================================================
1489 --- linux-2.6.30-rc6.orig/drivers/mmc/host/s3cmci.c     2009-05-16 06:12:57.000000000 +0200
1490 +++ linux-2.6.30-rc6/drivers/mmc/host/s3cmci.c  2009-05-18 19:07:48.000000000 +0200
1491 @@ -2,6 +2,7 @@
1492   *  linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver
1493   *
1494   *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>
1495 + *  Copyright (C) 2007 Harald Welte <laforge@gnumonks.org>
1496   *
1497   * Current driver maintained by Ben Dooks and Simtec Electronics
1498   *  Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org>
1499 @@ -24,9 +25,18 @@
1500  
1501  #include <mach/regs-sdi.h>
1502  #include <mach/regs-gpio.h>
1503 +#include <mach/hardware.h>
1504  
1505  #include <plat/mci.h>
1506  
1507 +#include <asm/dma.h>
1508 +#include <asm/dma-mapping.h>
1509 +
1510 +#include <asm/io.h>
1511 +#include <mach/regs-gpio.h>
1512 +#include <mach/mci.h>
1513 +#include <mach/dma.h>
1514 +
1515  #include "s3cmci.h"
1516  
1517  #define DRIVER_NAME "s3c-mci"
1518 @@ -47,6 +57,9 @@
1519  static const int dbgmap_info  = dbg_info | dbg_conf;
1520  static const int dbgmap_debug = dbg_err | dbg_debug;
1521  
1522 +static int f_max = -1; /* override maximum frequency limit */
1523 +static int persist; /* keep interface alive across suspend/resume */
1524 +
1525  #define dbg(host, channels, args...)             \
1526         do {                                      \
1527         if (dbgmap_err & channels)                \
1528 @@ -280,8 +293,11 @@
1529                  * an even multiple of 4. */
1530                 if (fifo >= host->pio_bytes)
1531                         fifo = host->pio_bytes;
1532 -               else
1533 +               else {
1534                         fifo -= fifo & 3;
1535 +                       if (!fifo)
1536 +                               break;
1537 +               }
1538  
1539                 host->pio_bytes -= fifo;
1540                 host->pio_count += fifo;
1541 @@ -329,7 +345,7 @@
1542  
1543         to_ptr = host->base + host->sdidata;
1544  
1545 -       while ((fifo = fifo_free(host)) > 3) {
1546 +       while ((fifo = fifo_free(host))) {
1547                 if (!host->pio_bytes) {
1548                         res = get_data_buffer(host, &host->pio_bytes,
1549                                                         &host->pio_ptr);
1550 @@ -353,8 +369,11 @@
1551                  * words, so round down to an even multiple of 4. */
1552                 if (fifo >= host->pio_bytes)
1553                         fifo = host->pio_bytes;
1554 -               else
1555 +               else {
1556                         fifo -= fifo & 3;
1557 +                       if (!fifo)
1558 +                               break;
1559 +               }
1560  
1561                 host->pio_bytes -= fifo;
1562                 host->pio_count += fifo;
1563 @@ -373,7 +392,6 @@
1564  {
1565         struct s3cmci_host *host = (struct s3cmci_host *) data;
1566  
1567 -
1568         disable_irq(host->irq);
1569  
1570         if (host->pio_active == XFER_WRITE)
1571 @@ -614,7 +632,6 @@
1572  
1573         spin_unlock_irqrestore(&host->complete_lock, iflags);
1574         return IRQ_HANDLED;
1575 -
1576  }
1577  
1578  /*
1579 @@ -789,11 +806,11 @@
1580  
1581         last_source = source;
1582  
1583 -       s3c2410_dma_devconfig(host->dma, source, 3,
1584 +       s3c2410_dma_devconfig(host->dma, source,
1585                               host->mem->start + host->sdidata);
1586  
1587         if (!setup_ok) {
1588 -               s3c2410_dma_config(host->dma, 4, 0);
1589 +               s3c2410_dma_config(host->dma, 4);
1590                 s3c2410_dma_set_buffdone_fn(host->dma,
1591                                             s3cmci_dma_done_callback);
1592                 s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);
1593 @@ -1026,6 +1043,7 @@
1594                         dbg(host, dbg_err, "data prepare error %d\n", res);
1595                         cmd->error = res;
1596                         cmd->data->error = res;
1597 +                       cmd->data->error = -EIO;
1598  
1599                         mmc_request_done(mmc, mrq);
1600                         return;
1601 @@ -1263,10 +1281,8 @@
1602         host->is2440    = is2440;
1603  
1604         host->pdata = pdev->dev.platform_data;
1605 -       if (!host->pdata) {
1606 -               pdev->dev.platform_data = &s3cmci_def_pdata;
1607 +       if (!host->pdata)
1608                 host->pdata = &s3cmci_def_pdata;
1609 -       }
1610  
1611         spin_lock_init(&host->complete_lock);
1612         tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
1613 @@ -1379,6 +1395,18 @@
1614         mmc->f_min      = host->clk_rate / (host->clk_div * 256);
1615         mmc->f_max      = host->clk_rate / host->clk_div;
1616  
1617 +       if (f_max >= 0) {
1618 +               unsigned f = f_max;
1619 +
1620 +               if (f < mmc->f_min)
1621 +                       f = mmc->f_min;
1622 +               if (mmc->f_max > f) {
1623 +                       dev_info(&pdev->dev, "f_max lowered from %u to %u Hz\n",
1624 +                           mmc->f_max, f);
1625 +                       mmc->f_max = f;
1626 +               }
1627 +       }
1628 +
1629         if (host->pdata->ocr_avail)
1630                 mmc->ocr_avail = host->pdata->ocr_avail;
1631  
1632 @@ -1491,18 +1519,60 @@
1633  
1634  #ifdef CONFIG_PM
1635  
1636 +static int save_regs(struct mmc_host *mmc)
1637 +{
1638 +       struct s3cmci_host *host = mmc_priv(mmc);
1639 +       unsigned long flags;
1640 +       unsigned from;
1641 +       u32 *to = host->saved;
1642 +
1643 +       mmc_flush_scheduled_work();
1644 +
1645 +       local_irq_save(flags);
1646 +       for (from = S3C2410_SDICON; from != S3C2410_SDIIMSK+4; from += 4)
1647 +               if (from != host->sdidata)
1648 +                       *to++ = readl(host->base + from);
1649 +       BUG_ON(to-host->saved != ARRAY_SIZE(host->saved));
1650 +       local_irq_restore(flags);
1651 +
1652 +       return 0;
1653 +}
1654 +
1655 +static int restore_regs(struct mmc_host *mmc)
1656 +{
1657 +       struct s3cmci_host *host = mmc_priv(mmc);
1658 +       unsigned long flags;
1659 +       unsigned to;
1660 +       u32 *from = host->saved;
1661 +
1662 +       /*
1663 +        * Before we begin with the necromancy, make sure we don't
1664 +        * inadvertently start something we'll regret microseconds later.
1665 +        */
1666 +       from[S3C2410_SDICMDCON - S3C2410_SDICON] = 0;
1667 +
1668 +       local_irq_save(flags);
1669 +       for (to = S3C2410_SDICON; to != S3C2410_SDIIMSK+4; to += 4)
1670 +               if (to != host->sdidata)
1671 +                       writel(*from++, host->base + to);
1672 +       BUG_ON(from-host->saved != ARRAY_SIZE(host->saved));
1673 +       local_irq_restore(flags);
1674 +
1675 +       return 0;
1676 +}
1677 +
1678  static int s3cmci_suspend(struct platform_device *dev, pm_message_t state)
1679  {
1680         struct mmc_host *mmc = platform_get_drvdata(dev);
1681  
1682 -       return  mmc_suspend_host(mmc, state);
1683 +       return persist ? save_regs(mmc) : mmc_suspend_host(mmc, state);
1684  }
1685  
1686  static int s3cmci_resume(struct platform_device *dev)
1687  {
1688         struct mmc_host *mmc = platform_get_drvdata(dev);
1689  
1690 -       return mmc_resume_host(mmc);
1691 +       return persist ? restore_regs(mmc) : mmc_resume_host(mmc);
1692  }
1693  
1694  #else /* CONFIG_PM */
1695 @@ -1560,9 +1630,13 @@
1696  module_init(s3cmci_init);
1697  module_exit(s3cmci_exit);
1698  
1699 +module_param(f_max, int, 0644);
1700 +module_param(persist, int, 0644);
1701 +
1702  MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
1703  MODULE_LICENSE("GPL v2");
1704  MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");
1705  MODULE_ALIAS("platform:s3c2410-sdi");
1706  MODULE_ALIAS("platform:s3c2412-sdi");
1707  MODULE_ALIAS("platform:s3c2440-sdi");
1708 +
1709 Index: linux-2.6.30-rc6/drivers/mmc/host/s3cmci.h
1710 ===================================================================
1711 --- linux-2.6.30-rc6.orig/drivers/mmc/host/s3cmci.h     2009-05-16 06:12:57.000000000 +0200
1712 +++ linux-2.6.30-rc6/drivers/mmc/host/s3cmci.h  2009-05-18 19:07:48.000000000 +0200
1713 @@ -8,6 +8,10 @@
1714   * published by the Free Software Foundation.
1715   */
1716  
1717 +
1718 +#include <mach/regs-sdi.h>
1719 +#include <linux/regulator/consumer.h>
1720 +
1721  /* FIXME: DMA Resource management ?! */
1722  #define S3CMCI_DMA 0
1723  
1724 @@ -68,7 +72,16 @@
1725         unsigned int            ccnt, dcnt;
1726         struct tasklet_struct   pio_tasklet;
1727  
1728 +       /*
1729 +        * Here's where we save the registers during suspend. Note that we skip
1730 +        * SDIDATA, which is at different positions on 2410 and 2440, so
1731 +        * there's no "+1" in the array size.
1732 +        */
1733 +       u32                     saved[(S3C2410_SDIIMSK-S3C2410_SDICON)/4];
1734 +
1735  #ifdef CONFIG_CPU_FREQ
1736         struct notifier_block   freq_transition;
1737  #endif
1738 +
1739 +       struct regulator *regulator;
1740  };
1741 Index: linux-2.6.30-rc6/drivers/mmc/host/sdhci-s3c.c
1742 ===================================================================
1743 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
1744 +++ linux-2.6.30-rc6/drivers/mmc/host/sdhci-s3c.c       2009-05-18 19:07:48.000000000 +0200
1745 @@ -0,0 +1,419 @@
1746 +/* linux/drivers/mmc/host/sdhci-s3c.c
1747 + *
1748 + * Copyright 2008 Openmoko Inc.
1749 + * Copyright 2008 Simtec Electronics
1750 + *      Ben Dooks <ben@simtec.co.uk>
1751 + *      http://armlinux.simtec.co.uk/
1752 + *
1753 + * SDHCI (HSMMC) support for Samsung SoC
1754 + *
1755 + * This program is free software; you can redistribute it and/or modify
1756 + * it under the terms of the GNU General Public License version 2 as
1757 + * published by the Free Software Foundation.
1758 + */
1759 +
1760 +#include <linux/delay.h>
1761 +#include <linux/dma-mapping.h>
1762 +#include <linux/platform_device.h>
1763 +#include <linux/clk.h>
1764 +#include <linux/io.h>
1765 +
1766 +#include <linux/mmc/host.h>
1767 +
1768 +#include <plat/regs-sdhci.h>
1769 +#include <plat/sdhci.h>
1770 +
1771 +#include "sdhci.h"
1772 +
1773 +#define MAX_BUS_CLK    (4)
1774 +
1775 +struct sdhci_s3c {
1776 +       struct sdhci_host       *host;
1777 +       struct platform_device  *pdev;
1778 +       struct resource         *ioarea;
1779 +       struct s3c_sdhci_platdata *pdata;
1780 +       unsigned int            cur_clk;
1781 +
1782 +       struct clk              *clk_io;        /* clock for io bus */
1783 +       struct clk              *clk_bus[MAX_BUS_CLK];
1784 +};
1785 +
1786 +static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
1787 +{
1788 +       return sdhci_priv(host);
1789 +}
1790 +
1791 +static u32 get_curclk(u32 ctrl2)
1792 +{
1793 +       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
1794 +       ctrl2 >>= S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
1795 +
1796 +       return ctrl2;
1797 +}
1798 +
1799 +static void sdhci_s3c_check_sclk(struct sdhci_host *host)
1800 +{
1801 +       struct sdhci_s3c *ourhost = to_s3c(host);
1802 +       u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
1803 +
1804 +       if (get_curclk(tmp) != ourhost->cur_clk) {
1805 +               dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n");
1806 +
1807 +               tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
1808 +               tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
1809 +               writel(tmp, host->ioaddr + 0x80);
1810 +       }
1811 +}
1812 +
1813 +static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
1814 +{
1815 +       struct sdhci_s3c *ourhost = to_s3c(host);
1816 +       struct clk *busclk;
1817 +       unsigned int rate, max;
1818 +       int clk;
1819 +
1820 +       /* note, a reset will reset the clock source */
1821 +
1822 +       sdhci_s3c_check_sclk(host);
1823 +
1824 +       for (max = 0, clk = 0; clk < MAX_BUS_CLK; clk++) {
1825 +               busclk = ourhost->clk_bus[clk];
1826 +               if (!busclk)
1827 +                       continue;
1828 +
1829 +               rate = clk_get_rate(busclk);
1830 +               if (rate > max)
1831 +                       max = rate;
1832 +       }
1833 +
1834 +       return max;
1835 +}
1836 +
1837 +static unsigned int sdhci_s3c_get_timeout_clk(struct sdhci_host *host)
1838 +{
1839 +       return sdhci_s3c_get_max_clk(host) / 1000000;
1840 +}
1841 +
1842 +static void sdhci_s3c_set_ios(struct sdhci_host *host,
1843 +                             struct mmc_ios *ios)
1844 +{
1845 +       struct sdhci_s3c *ourhost = to_s3c(host);
1846 +       struct s3c_sdhci_platdata *pdata = ourhost->pdata;
1847 +       int width;
1848 +
1849 +       sdhci_s3c_check_sclk(host);
1850 +
1851 +       if (ios->power_mode != MMC_POWER_OFF) {
1852 +               switch (ios->bus_width) {
1853 +               case MMC_BUS_WIDTH_4:
1854 +                       width = 4;
1855 +                       break;
1856 +               case MMC_BUS_WIDTH_1:
1857 +                       width = 1;
1858 +                       break;
1859 +               default:
1860 +                       BUG();
1861 +               }
1862 +
1863 +               if (pdata->cfg_gpio)
1864 +                       pdata->cfg_gpio(ourhost->pdev, width);
1865 +       }
1866 +
1867 +       if (pdata->cfg_card)
1868 +               pdata->cfg_card(ourhost->pdev, host->ioaddr,
1869 +                               ios, host->mmc->card);
1870 +}
1871 +
1872 +static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
1873 +                                            unsigned int src,
1874 +                                            unsigned int wanted)
1875 +{
1876 +       unsigned long rate;
1877 +       struct clk *clksrc = ourhost->clk_bus[src];
1878 +       int div;
1879 +
1880 +       if (!clksrc)
1881 +               return UINT_MAX;
1882 +
1883 +       rate = clk_get_rate(clksrc);
1884 +
1885 +       for (div = 1; div < 256; div *= 2) {
1886 +               if ((rate / div) <= wanted)
1887 +                       break;
1888 +       }
1889 +
1890 +       dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n",
1891 +               src, rate, wanted, rate / div);
1892 +
1893 +       return (wanted - (rate / div));
1894 +}
1895 +
1896 +static void sdhci_s3c_change_clock(struct sdhci_host *host, unsigned int clock)
1897 +{
1898 +       struct sdhci_s3c *ourhost = to_s3c(host);
1899 +       unsigned int best = UINT_MAX;
1900 +       unsigned int delta;
1901 +       int best_src = 0;
1902 +       int src;
1903 +       u32 ctrl;
1904 +
1905 +       for (src = 0; src < MAX_BUS_CLK; src++) {
1906 +               delta = sdhci_s3c_consider_clock(ourhost, src, clock);
1907 +               if (delta < best) {
1908 +                       best = delta;
1909 +                       best_src = src;
1910 +               }
1911 +       }
1912 +
1913 +       dev_dbg(&ourhost->pdev->dev,
1914 +               "selected source %d, clock %d, delta %d\n",
1915 +                best_src, clock, best);
1916 +
1917 +       /* turn clock off to card before changing clock source */
1918 +       writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
1919 +
1920 +       /* select the new clock source */
1921 +
1922 +       if (ourhost->cur_clk != best_src) {
1923 +               struct clk *clk = ourhost->clk_bus[best_src];
1924 +
1925 +               ourhost->cur_clk = best_src;
1926 +               host->max_clk = clk_get_rate(clk);
1927 +               host->timeout_clk = host->max_clk / 1000000;
1928 +
1929 +               ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
1930 +               ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
1931 +               ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
1932 +               writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
1933 +       }
1934 +
1935 +       sdhci_change_clock(host, clock);
1936 +}
1937 +
1938 +static struct sdhci_ops sdhci_s3c_ops = {
1939 +       .get_max_clock          = sdhci_s3c_get_max_clk,
1940 +       .get_timeout_clock      = sdhci_s3c_get_timeout_clk,
1941 +       .change_clock           = sdhci_s3c_change_clock,
1942 +       .set_ios                = sdhci_s3c_set_ios,
1943 +};
1944 +
1945 +/*
1946 + * call this when you need sd stack to recognize insertion or removal of card
1947 + * that can't be told by SDHCI regs
1948 + */
1949 +
1950 +void sdhci_s3c_force_presence_change(struct platform_device *pdev)
1951 +{
1952 +       struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
1953 +
1954 +       dev_info(&pdev->dev, "sdhci_s3c_force_presence_change called\n");
1955 +       mmc_detect_change(pdata->sdhci_host->mmc, msecs_to_jiffies(200));
1956 +}
1957 +EXPORT_SYMBOL_GPL(sdhci_s3c_force_presence_change);
1958 +
1959 +
1960 +static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
1961 +{
1962 +       struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
1963 +       struct device *dev = &pdev->dev;
1964 +       struct sdhci_host *host;
1965 +       struct sdhci_s3c *sc;
1966 +       struct resource *res;
1967 +       int ret, irq, ptr, clks;
1968 +
1969 +       if (!pdata) {
1970 +               dev_err(dev, "no device data specified\n");
1971 +               return -ENOENT;
1972 +       }
1973 +
1974 +       irq = platform_get_irq(pdev, 0);
1975 +       if (irq < 0) {
1976 +               dev_err(dev, "no irq specified\n");
1977 +               return irq;
1978 +       }
1979 +
1980 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1981 +       if (!res) {
1982 +               dev_err(dev, "no memory specified\n");
1983 +               return -ENOENT;
1984 +       }
1985 +
1986 +       host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
1987 +       if (IS_ERR(host)) {
1988 +               dev_err(dev, "sdhci_alloc_host() failed\n");
1989 +               return PTR_ERR(host);
1990 +       }
1991 +
1992 +       pdata->sdhci_host = host;
1993 +
1994 +       sc = sdhci_priv(host);
1995 +
1996 +       sc->host = host;
1997 +       sc->pdev = pdev;
1998 +       sc->pdata = pdata;
1999 +
2000 +       platform_set_drvdata(pdev, host);
2001 +
2002 +       sc->clk_io = clk_get(dev, "hsmmc");
2003 +       if (IS_ERR(sc->clk_io)) {
2004 +               dev_err(dev, "failed to get io clock\n");
2005 +               ret = PTR_ERR(sc->clk_io);
2006 +               goto err_io_clk;
2007 +       }
2008 +
2009 +       /* enable the local io clock and keep it running for the moment. */
2010 +       clk_enable(sc->clk_io);
2011 +
2012 +       for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
2013 +               struct clk *clk;
2014 +               char *name = pdata->clocks[ptr];
2015 +
2016 +               if (name == NULL)
2017 +                       continue;
2018 +
2019 +               clk = clk_get(dev, name);
2020 +               if (IS_ERR(clk)) {
2021 +                       dev_err(dev, "failed to get clock %s\n", name);
2022 +                       continue;
2023 +               }
2024 +
2025 +               clks++;
2026 +               sc->clk_bus[ptr] = clk;
2027 +               clk_enable(clk);
2028 +
2029 +               dev_info(dev, "clock source %d: %s (%ld Hz)\n",
2030 +                        ptr, name, clk_get_rate(clk));
2031 +       }
2032 +
2033 +       if (clks == 0) {
2034 +               dev_err(dev, "failed to find any bus clocks\n");
2035 +               ret = -ENOENT;
2036 +               goto err_no_busclks;
2037 +       }
2038 +
2039 +       sc->ioarea = request_mem_region(res->start, resource_size(res),
2040 +                                       mmc_hostname(host->mmc));
2041 +       if (!sc->ioarea) {
2042 +               dev_err(dev, "failed to reserve register area\n");
2043 +               ret = -ENXIO;
2044 +               goto err_req_regs;
2045 +       }
2046 +
2047 +       host->ioaddr = ioremap_nocache(res->start, resource_size(res));
2048 +       if (!host->ioaddr) {
2049 +               dev_err(dev, "failed to map registers\n");
2050 +               ret = -ENXIO;
2051 +               goto err_req_regs;
2052 +       }
2053 +
2054 +       /* Ensure we have minimal gpio selected CMD/CLK/Detect */
2055 +       if (pdata->cfg_gpio)
2056 +               pdata->cfg_gpio(pdev, 0);
2057 +
2058 +       sdhci_s3c_check_sclk(host);
2059 +
2060 +       host->hw_name = "samsung-hsmmc";
2061 +       host->ops = &sdhci_s3c_ops;
2062 +       host->quirks = 0;
2063 +       host->irq = irq;
2064 +
2065 +       /* Setup quirks for the controller */
2066 +
2067 +       /* Currently with ADMA enabled we are getting some length
2068 +        * interrupts that are not being dealt with, do disable
2069 +        * ADMA until this is sorted out. */
2070 +       host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
2071 +       host->quirks |= SDHCI_QUIRK_32BIT_ADMA_SIZE;
2072 +
2073 +       /* It seems we do not get an DATA transfer complete on non-busy
2074 +        * transfers, not sure if this is a problem with this specific
2075 +        * SDHCI block, or a missing configuration that needs to be set. */
2076 +       host->quirks |= SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY;
2077 +
2078 +       host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
2079 +                        SDHCI_QUIRK_32BIT_DMA_SIZE);
2080 +
2081 +       ret = sdhci_add_host(host);
2082 +       if (ret) {
2083 +               dev_err(dev, "sdhci_add_host() failed\n");
2084 +               goto err_add_host;
2085 +       }
2086 +
2087 +       return 0;
2088 +
2089 + err_add_host:
2090 +       release_resource(sc->ioarea);
2091 +       kfree(sc->ioarea);
2092 +
2093 + err_req_regs:
2094 +       for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
2095 +               clk_disable(sc->clk_bus[ptr]);
2096 +               clk_put(sc->clk_bus[ptr]);
2097 +       }
2098 +
2099 + err_no_busclks:
2100 +       clk_disable(sc->clk_io);
2101 +       clk_put(sc->clk_io);
2102 +
2103 + err_io_clk:
2104 +       sdhci_free_host(host);
2105 +
2106 +       return ret;
2107 +}
2108 +
2109 +static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
2110 +{
2111 +       return 0;
2112 +}
2113 +
2114 +#ifdef CONFIG_PM
2115 +
2116 +static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm)
2117 +{
2118 +       struct sdhci_host *host = platform_get_drvdata(dev);
2119 +
2120 +       sdhci_suspend_host(host, pm);
2121 +       return 0;
2122 +}
2123 +
2124 +static int sdhci_s3c_resume(struct platform_device *dev)
2125 +{
2126 +       struct sdhci_host *host = platform_get_drvdata(dev);
2127 +
2128 +       sdhci_resume_host(host);
2129 +       return 0;
2130 +}
2131 +
2132 +#else
2133 +#define sdhci_s3c_suspend NULL
2134 +#define sdhci_s3c_resume NULL
2135 +#endif
2136 +
2137 +static struct platform_driver sdhci_s3c_driver = {
2138 +       .probe          = sdhci_s3c_probe,
2139 +       .remove         = __devexit_p(sdhci_s3c_remove),
2140 +       .suspend        = sdhci_s3c_suspend,
2141 +       .resume         = sdhci_s3c_resume,
2142 +       .driver         = {
2143 +               .owner  = THIS_MODULE,
2144 +               .name   = "s3c-sdhci",
2145 +       },
2146 +};
2147 +
2148 +static int __init sdhci_s3c_init(void)
2149 +{
2150 +       return platform_driver_register(&sdhci_s3c_driver);
2151 +}
2152 +
2153 +static void __exit sdhci_s3c_exit(void)
2154 +{
2155 +       platform_driver_unregister(&sdhci_s3c_driver);
2156 +}
2157 +
2158 +module_init(sdhci_s3c_init);
2159 +module_exit(sdhci_s3c_exit);
2160 +
2161 +MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue");
2162 +MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
2163 +MODULE_LICENSE("GPL v2");
2164 +MODULE_ALIAS("platform:s3c-sdhci");
2165 Index: linux-2.6.30-rc6/drivers/mtd/nand/s3c2410.c
2166 ===================================================================
2167 --- linux-2.6.30-rc6.orig/drivers/mtd/nand/s3c2410.c    2009-05-16 06:12:57.000000000 +0200
2168 +++ linux-2.6.30-rc6/drivers/mtd/nand/s3c2410.c 2009-05-18 19:07:48.000000000 +0200
2169 @@ -438,7 +438,7 @@
2170         if ((diff0 & ~(1<<fls(diff0))) == 0)
2171                 return 1;
2172  
2173 -       return -1;
2174 +       return -EBADMSG;
2175  }
2176  
2177  /* ECC functions
2178 @@ -530,7 +530,12 @@
2179  static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
2180  {
2181         struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
2182 +       u8 *ptr = buf + (len & ~3);
2183 +       int i;
2184 +
2185         readsl(info->regs + S3C2440_NFDATA, buf, len / 4);
2186 +       for (i = 0; i != (len & 3); i++)
2187 +               ptr[i] = readb(info->regs + S3C2440_NFDATA);
2188  }
2189  
2190  static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
2191 @@ -645,17 +650,31 @@
2192  }
2193  
2194  #ifdef CONFIG_MTD_PARTITIONS
2195 +const char *part_probes[] = { "cmdlinepart", NULL };
2196  static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
2197                                       struct s3c2410_nand_mtd *mtd,
2198                                       struct s3c2410_nand_set *set)
2199  {
2200 +       struct mtd_partition *part_info;
2201 +       int nr_part = 0;
2202 +
2203         if (set == NULL)
2204                 return add_mtd_device(&mtd->mtd);
2205  
2206 -       if (set->nr_partitions > 0 && set->partitions != NULL) {
2207 -               return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);
2208 +       if (set->nr_partitions == 0) {
2209 +               mtd->mtd.name = set->name;
2210 +               nr_part = parse_mtd_partitions(&mtd->mtd, part_probes,
2211 +                                               &part_info, 0);
2212 +       } else {
2213 +               if (set->nr_partitions > 0 && set->partitions != NULL) {
2214 +                       nr_part = set->nr_partitions;
2215 +                       part_info = set->partitions;
2216 +               }
2217         }
2218  
2219 +       if (nr_part > 0 && part_info)
2220 +               return add_mtd_partitions(&mtd->mtd, part_info, nr_part);
2221 +
2222         return add_mtd_device(&mtd->mtd);
2223  }
2224  #else
2225 @@ -684,9 +703,13 @@
2226         chip->select_chip  = s3c2410_nand_select_chip;
2227         chip->chip_delay   = 50;
2228         chip->priv         = nmtd;
2229 -       chip->options      = 0;
2230         chip->controller   = &info->controller;
2231  
2232 +       if (set->flags & S3C2410_NAND_BBT)
2233 +               chip->options      = NAND_USE_FLASH_BBT;
2234 +       else
2235 +               chip->options      = 0;
2236 +
2237         switch (info->cpu_type) {
2238         case TYPE_S3C2410:
2239                 chip->IO_ADDR_W = regs + S3C2410_NFDATA;
2240 @@ -726,7 +749,7 @@
2241         nmtd->mtd.owner    = THIS_MODULE;
2242         nmtd->set          = set;
2243  
2244 -       if (hardware_ecc) {
2245 +       if (!info->platform->software_ecc && hardware_ecc) {
2246                 chip->ecc.calculate = s3c2410_nand_calculate_ecc;
2247                 chip->ecc.correct   = s3c2410_nand_correct_data;
2248                 chip->ecc.mode      = NAND_ECC_HW;
2249 Index: linux-2.6.30-rc6/drivers/mmc/core/core.c
2250 ===================================================================
2251 --- linux-2.6.30-rc6.orig/drivers/mmc/core/core.c       2009-05-16 06:12:57.000000000 +0200
2252 +++ linux-2.6.30-rc6/drivers/mmc/core/core.c    2009-05-18 19:07:48.000000000 +0200
2253 @@ -59,10 +59,11 @@
2254  /*
2255   * Internal function. Flush all scheduled work from the MMC work queue.
2256   */
2257 -static void mmc_flush_scheduled_work(void)
2258 +void mmc_flush_scheduled_work(void)
2259  {
2260         flush_workqueue(workqueue);
2261  }
2262 +EXPORT_SYMBOL_GPL(mmc_flush_scheduled_work);
2263  
2264  /**
2265   *     mmc_request_done - finish processing an MMC request