Merge branch 'next/cleanup-s3c24xx' of git://git.kernel.org/pub/scm/linux/kernel...
authorOlof Johansson <olof@lixom.net>
Thu, 8 Mar 2012 16:53:14 +0000 (08:53 -0800)
committerOlof Johansson <olof@lixom.net>
Thu, 8 Mar 2012 16:53:14 +0000 (08:53 -0800)
* 'next/cleanup-s3c24xx' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: (24 commits)
  ARM: S3C24XX: remove call to s3c24xx_setup_clocks
  ARM: S3C24XX: add get_rate for clk_p on S3C2416/2443
  ARM: S3C24XX: add get_rate for clk_h on S3C2416/2443
  ARM: S3C24XX: remove XXX_setup_clocks method from S3C2443
  ARM: S3C24XX: remove obsolete S3C2416_DMA option
  ARM: S3C24XX: Reuse S3C2443 dma for S3C2416
  ARM: S3C24XX: Fix indentation of dma-s3c2443
  ARM: S3C24XX: Move device setup files to mach directory
  ARM: S3C24XX: Consolidate Simtec extensions
  ARM: S3C24XX: move simtec-specific code to mach directory
  ARM: S3C24XX: Move common-smdk code to mach directory
  ARM: S3C24XX: Move s3c2443-clock.c to mach-s3c24xx
  ARM: s3c2410_defconfig: update s3c2410_defconfig
  ARM: S3C2443: move mach-s3c2443/* into mach-s3c24xx/
  ARM: S3C2440: move mach-s3c2440/* into mach-s3c24xx/
  ARM: S3C2416: move mach-s3c2416/* into mach-s3c24xx/
  ARM: S3C2412: move mach-s3c2412/* into mach-s3c24xx/
  ARM: S3C2410: move mach-s3c2410/* into mach-s3c24xx/
  ARM: S3C24XX: change the ARCH_S3C2410 to ARCH_S3C24XX
  ARM: S3C2410: move s3c2410_baseclk_add to clock.h
  ...

26 files changed:
1  2 
arch/arm/Kconfig
arch/arm/mach-s3c24xx/clock-s3c2416.c
arch/arm/mach-s3c24xx/clock-s3c2440.c
arch/arm/mach-s3c24xx/clock-s3c244x.c
arch/arm/mach-s3c24xx/common-s3c2443.c
arch/arm/mach-s3c24xx/dma-s3c2410.c
arch/arm/mach-s3c24xx/dma-s3c2412.c
arch/arm/mach-s3c24xx/dma-s3c2440.c
arch/arm/mach-s3c24xx/dma-s3c2443.c
arch/arm/mach-s3c24xx/include/mach/entry-macro.S
arch/arm/mach-s3c24xx/irq-s3c2412.c
arch/arm/mach-s3c24xx/irq-s3c2416.c
arch/arm/mach-s3c24xx/irq-s3c2440.c
arch/arm/mach-s3c24xx/irq-s3c2443.c
arch/arm/mach-s3c24xx/irq-s3c244x.c
arch/arm/mach-s3c24xx/mach-gta02.c
arch/arm/mach-s3c24xx/mach-h1940.c
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c24xx/mach-smdk2416.c
arch/arm/mach-s3c24xx/pm-s3c2410.c
arch/arm/mach-s3c24xx/pm-s3c2412.c
arch/arm/mach-s3c24xx/pm-s3c2416.c
arch/arm/mach-s3c24xx/s3c2442.c
drivers/mmc/host/Kconfig
drivers/spi/Kconfig
drivers/usb/gadget/Kconfig

Simple merge
index 0000000,5e36905..dbc9ab4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,178 +1,172 @@@
 -void __init_or_cpufreq s3c2416_setup_clocks(void)
 -{
 -      s3c2443_common_setup_clocks(s3c2416_get_pll);
 -}
 -
 -
+ /* linux/arch/arm/mach-s3c2416/clock.c
+  *
+  * Copyright (c) 2010 Simtec Electronics
+  * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
+  *
+  * S3C2416 Clock control support
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  */
+ #include <linux/init.h>
+ #include <linux/clk.h>
+ #include <plat/s3c2416.h>
+ #include <plat/clock.h>
+ #include <plat/clock-clksrc.h>
+ #include <plat/cpu.h>
+ #include <plat/cpu-freq.h>
+ #include <plat/pll.h>
+ #include <asm/mach/map.h>
+ #include <mach/regs-clock.h>
+ #include <mach/regs-s3c2443-clock.h>
+ /* armdiv
+  *
+  * this clock is sourced from msysclk and can have a number of
+  * divider values applied to it to then be fed into armclk.
+  * The real clock definition is done in s3c2443-clock.c,
+  * only the armdiv divisor table must be defined here.
+ */
+ static unsigned int armdiv[8] = {
+       [0] = 1,
+       [1] = 2,
+       [2] = 3,
+       [3] = 4,
+       [5] = 6,
+       [7] = 8,
+ };
+ static struct clksrc_clk hsspi_eplldiv = {
+       .clk = {
+               .name   = "hsspi-eplldiv",
+               .parent = &clk_esysclk.clk,
+               .ctrlbit = (1 << 14),
+               .enable = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 },
+ };
+ static struct clk *hsspi_sources[] = {
+       [0] = &hsspi_eplldiv.clk,
+       [1] = NULL, /* to fix */
+ };
+ static struct clksrc_clk hsspi_mux = {
+       .clk    = {
+               .name   = "hsspi-if",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = hsspi_sources,
+               .nr_sources = ARRAY_SIZE(hsspi_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 },
+ };
+ static struct clksrc_clk hsmmc_div[] = {
+       [0] = {
+               .clk = {
+                       .name   = "hsmmc-div",
+                       .devname        = "s3c-sdhci.0",
+                       .parent = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
+       },
+       [1] = {
+               .clk = {
+                       .name   = "hsmmc-div",
+                       .devname        = "s3c-sdhci.1",
+                       .parent = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+       },
+ };
+ static struct clksrc_clk hsmmc_mux0 = {
+       .clk    = {
+               .name           = "hsmmc-if",
+               .devname        = "s3c-sdhci.0",
+               .ctrlbit        = (1 << 6),
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .sources        = &(struct clksrc_sources) {
+               .nr_sources     = 2,
+               .sources        = (struct clk * []) {
+                       [0]     = &hsmmc_div[0].clk,
+                       [1]     = NULL, /* to fix */
+               },
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
+ };
+ static struct clksrc_clk hsmmc_mux1 = {
+       .clk    = {
+               .name           = "hsmmc-if",
+               .devname        = "s3c-sdhci.1",
+               .ctrlbit        = (1 << 12),
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .sources        = &(struct clksrc_sources) {
+               .nr_sources     = 2,
+               .sources        = (struct clk * []) {
+                       [0]     = &hsmmc_div[1].clk,
+                       [1]     = NULL, /* to fix */
+               },
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
+ };
+ static struct clk hsmmc0_clk = {
+       .name           = "hsmmc",
+       .devname        = "s3c-sdhci.0",
+       .parent         = &clk_h,
+       .enable         = s3c2443_clkcon_enable_h,
+       .ctrlbit        = S3C2416_HCLKCON_HSMMC0,
+ };
+ static struct clksrc_clk *clksrcs[] __initdata = {
+       &hsspi_eplldiv,
+       &hsspi_mux,
+       &hsmmc_div[0],
+       &hsmmc_div[1],
+       &hsmmc_mux0,
+       &hsmmc_mux1,
+ };
+ static struct clk_lookup s3c2416_clk_lookup[] = {
+       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
+       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
+       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
+ };
+ void __init s3c2416_init_clocks(int xtal)
+ {
+       u32 epllcon = __raw_readl(S3C2443_EPLLCON);
+       u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
+       int ptr;
+       /* s3c2416 EPLL compatible with s3c64xx */
+       clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
+       clk_epll.parent = &clk_epllref.clk;
+       s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
+                                  armdiv, ARRAY_SIZE(armdiv),
+                                  S3C2416_CLKDIV0_ARMDIV_MASK);
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+       s3c24xx_register_clock(&hsmmc0_clk);
+       clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
+       s3c_pwmclk_init();
+ }
index 0000000,bedbc87..414364e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,194 +1,194 @@@
 -static int s3c2440_clk_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2440/clock.c
+  *
+  * Copyright (c) 2004-2005 Simtec Electronics
+  *    http://armlinux.simtec.co.uk/
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2440 Clock support
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/mutex.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/serial_core.h>
+ #include <mach/hardware.h>
+ #include <linux/atomic.h>
+ #include <asm/irq.h>
+ #include <mach/regs-clock.h>
+ #include <plat/clock.h>
+ #include <plat/cpu.h>
+ #include <plat/regs-serial.h>
+ /* S3C2440 extended clock support */
+ static unsigned long s3c2440_camif_upll_round(struct clk *clk,
+                                             unsigned long rate)
+ {
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+       if (rate > parent_rate)
+               return parent_rate;
+       /* note, we remove the +/- 1 calculations for the divisor */
+       div = (parent_rate / rate) / 2;
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+       return parent_rate / (div * 2);
+ }
+ static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
+ {
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+       rate = s3c2440_camif_upll_round(clk, rate);
+       camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
+       if (rate != parent_rate) {
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= (((parent_rate / rate) / 2) - 1);
+       }
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+       return 0;
+ }
+ /* Extra S3C2440 clocks */
+ static struct clk s3c2440_clk_cam = {
+       .name           = "camif",
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+ };
+ static struct clk s3c2440_clk_cam_upll = {
+       .name           = "camif-upll",
+       .ops            = &(struct clk_ops) {
+               .set_rate       = s3c2440_camif_upll_setrate,
+               .round_rate     = s3c2440_camif_upll_round,
+       },
+ };
+ static struct clk s3c2440_clk_ac97 = {
+       .name           = "ac97",
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+ };
+ static unsigned long  s3c2440_fclk_n_getrate(struct clk *clk)
+ {
+       unsigned long ucon0, ucon1, ucon2, divisor;
+       /* the fun of calculating the uart divisors on the s3c2440 */
+       ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
+       ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
+       ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
+       ucon0 &= S3C2440_UCON0_DIVMASK;
+       ucon1 &= S3C2440_UCON1_DIVMASK;
+       ucon2 &= S3C2440_UCON2_DIVMASK;
+       if (ucon0 != 0)
+               divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
+       else if (ucon1 != 0)
+               divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
+       else if (ucon2 != 0)
+               divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
+       else
+               /* manual calims 44, seems to be 9 */
+               divisor = 9;
+       return clk_get_rate(clk->parent) / divisor;
+ }
+ static struct clk s3c2440_clk_fclk_n = {
+       .name           = "fclk_n",
+       .parent         = &clk_f,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2440_fclk_n_getrate,
+       },
+ };
+ static struct clk_lookup s3c2440_clk_lookup[] = {
+       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+       CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
+ };
++static int s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
+ {
+       struct clk *clock_upll;
+       struct clk *clock_h;
+       struct clk *clock_p;
+       clock_p = clk_get(NULL, "pclk");
+       clock_h = clk_get(NULL, "hclk");
+       clock_upll = clk_get(NULL, "upll");
+       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
+               return -EINVAL;
+       }
+       s3c2440_clk_cam.parent = clock_h;
+       s3c2440_clk_ac97.parent = clock_p;
+       s3c2440_clk_cam_upll.parent = clock_upll;
+       s3c24xx_register_clock(&s3c2440_clk_fclk_n);
+       s3c24xx_register_clock(&s3c2440_clk_ac97);
+       s3c24xx_register_clock(&s3c2440_clk_cam);
+       s3c24xx_register_clock(&s3c2440_clk_cam_upll);
+       clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
+       clk_disable(&s3c2440_clk_ac97);
+       clk_disable(&s3c2440_clk_cam);
+       return 0;
+ }
+ static struct subsys_interface s3c2440_clk_interface = {
+       .name           = "s3c2440_clk",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2440_clk_add,
+ };
+ static __init int s3c24xx_clk_init(void)
+ {
+       return subsys_interface_register(&s3c2440_clk_interface);
+ }
+ arch_initcall(s3c24xx_clk_init);
index 0000000,b3fdbdd..6d9b688
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,141 +1,141 @@@
 -static int s3c244x_clk_add(struct device *dev)
+ /* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
+  *
+  * Copyright (c) 2004-2008 Simtec Electronics
+  *    http://armlinux.simtec.co.uk/
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2440/S3C2442 Common clock support
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <linux/atomic.h>
+ #include <asm/irq.h>
+ #include <mach/regs-clock.h>
+ #include <plat/clock.h>
+ #include <plat/cpu.h>
+ static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
+ {
+       unsigned long camdivn;
+       unsigned long dvs;
+       if (parent == &clk_f)
+               dvs = 0;
+       else if (parent == &clk_h)
+               dvs = S3C2440_CAMDIVN_DVSEN;
+       else
+               return -EINVAL;
+       clk->parent = parent;
+       camdivn  = __raw_readl(S3C2440_CAMDIVN);
+       camdivn &= ~S3C2440_CAMDIVN_DVSEN;
+       camdivn |= dvs;
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+       return 0;
+ }
+ static struct clk clk_arm = {
+       .name           = "armclk",
+       .id             = -1,
+       .ops            = &(struct clk_ops) {
+               .set_parent     = s3c2440_setparent_armclk,
+       },
+ };
++static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif)
+ {
+       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+       unsigned long clkdivn;
+       struct clk *clock_upll;
+       int ret;
+       printk("S3C244X: Clock Support, DVS %s\n",
+              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+       clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
+       ret = s3c24xx_register_clock(&clk_arm);
+       if (ret < 0) {
+               printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
+               return ret;
+       }
+       clock_upll = clk_get(NULL, "upll");
+       if (IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
+               return -ENOENT;
+       }
+       /* check rate of UPLL, and if it is near 96MHz, then change
+        * to using half the UPLL rate for the system */
+       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+               spin_lock(&clocks_lock);
+               clkdivn = __raw_readl(S3C2410_CLKDIVN);
+               clkdivn |= S3C2440_CLKDIVN_UCLK;
+               __raw_writel(clkdivn, S3C2410_CLKDIVN);
+               spin_unlock(&clocks_lock);
+       }
+       return 0;
+ }
+ static struct subsys_interface s3c2440_clk_interface = {
+       .name           = "s3c2440_clk",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c244x_clk_add,
+ };
+ static int s3c2440_clk_init(void)
+ {
+       return subsys_interface_register(&s3c2440_clk_interface);
+ }
+ arch_initcall(s3c2440_clk_init);
+ static struct subsys_interface s3c2442_clk_interface = {
+       .name           = "s3c2442_clk",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c244x_clk_add,
+ };
+ static int s3c2442_clk_init(void)
+ {
+       return subsys_interface_register(&s3c2442_clk_interface);
+ }
+ arch_initcall(s3c2442_clk_init);
index 0000000,7414890..4604315
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,670 +1,670 @@@
 -struct clk clk_mpllref = {
+ /*
+  * Common code for SoCs starting with the S3C2443
+  *
+  * Copyright (c) 2007, 2010 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  */
+ #include <linux/init.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <mach/regs-s3c2443-clock.h>
+ #include <plat/clock.h>
+ #include <plat/clock-clksrc.h>
+ #include <plat/cpu.h>
+ #include <plat/cpu-freq.h>
+ static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
+ {
+       u32 ctrlbit = clk->ctrlbit;
+       u32 con = __raw_readl(reg);
+       if (enable)
+               con |= ctrlbit;
+       else
+               con &= ~ctrlbit;
+       __raw_writel(con, reg);
+       return 0;
+ }
+ int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+ {
+       return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
+ }
+ int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+ {
+       return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
+ }
+ int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+ {
+       return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
+ }
+ /* mpllref is a direct descendant of clk_xtal by default, but it is not
+  * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+  * such directly equating the two source clocks is impossible.
+  */
++static struct clk clk_mpllref = {
+       .name           = "mpllref",
+       .parent         = &clk_xtal,
+ };
+ static struct clk *clk_epllref_sources[] = {
+       [0] = &clk_mpllref,
+       [1] = &clk_mpllref,
+       [2] = &clk_xtal,
+       [3] = &clk_ext,
+ };
+ struct clksrc_clk clk_epllref = {
+       .clk    = {
+               .name           = "epllref",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_epllref_sources,
+               .nr_sources = ARRAY_SIZE(clk_epllref_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
+ };
+ /* esysclk
+  *
+  * this is sourced from either the EPLL or the EPLLref clock
+ */
+ static struct clk *clk_sysclk_sources[] = {
+       [0] = &clk_epllref.clk,
+       [1] = &clk_epll,
+ };
+ struct clksrc_clk clk_esysclk = {
+       .clk    = {
+               .name           = "esysclk",
+               .parent         = &clk_epll,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_sysclk_sources,
+               .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+ };
+ static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+ {
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+       div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
+       div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
+       return parent_rate / (div + 1);
+ }
+ static struct clk clk_mdivclk = {
+       .name           = "mdivclk",
+       .parent         = &clk_mpllref,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2443_getrate_mdivclk,
+       },
+ };
+ static struct clk *clk_msysclk_sources[] = {
+       [0] = &clk_mpllref,
+       [1] = &clk_mpll,
+       [2] = &clk_mdivclk,
+       [3] = &clk_mpllref,
+ };
+ struct clksrc_clk clk_msysclk = {
+       .clk    = {
+               .name           = "msysclk",
+               .parent         = &clk_xtal,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_msysclk_sources,
+               .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
+ };
+ /* prediv
+  *
+  * this divides the msysclk down to pass to h/p/etc.
+  */
+ static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+ {
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+       clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+       clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+       return rate / (clkdiv0 + 1);
+ }
+ static struct clk clk_prediv = {
+       .name           = "prediv",
+       .parent         = &clk_msysclk.clk,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2443_prediv_getrate,
+       },
+ };
+ /* hclk divider
+  *
+  * divides the prediv and provides the hclk.
+  */
+ static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk)
+ {
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+       clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
+       return rate / (clkdiv0 + 1);
+ }
+ static struct clk_ops clk_h_ops = {
+       .get_rate       = s3c2443_hclkdiv_getrate,
+ };
+ /* pclk divider
+  *
+  * divides the hclk and provides the pclk.
+  */
+ static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk)
+ {
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+       clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0);
+       return rate / (clkdiv0 + 1);
+ }
+ static struct clk_ops clk_p_ops = {
+       .get_rate       = s3c2443_pclkdiv_getrate,
+ };
+ /* armdiv
+  *
+  * this clock is sourced from msysclk and can have a number of
+  * divider values applied to it to then be fed into armclk.
+ */
+ static unsigned int *armdiv;
+ static int nr_armdiv;
+ static int armdivmask;
+ static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+                                             unsigned long rate)
+ {
+       unsigned long parent = clk_get_rate(clk->parent);
+       unsigned long calc;
+       unsigned best = 256; /* bigger than any value */
+       unsigned div;
+       int ptr;
+       if (!nr_armdiv)
+               return -EINVAL;
+       for (ptr = 0; ptr < nr_armdiv; ptr++) {
+               div = armdiv[ptr];
+               if (div) {
+                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
+                       calc = (parent / div / 1000) * 1000;
+                       if (calc <= rate && div < best)
+                               best = div;
+               }
+       }
+       return parent / best;
+ }
+ static unsigned long s3c2443_armclk_getrate(struct clk *clk)
+ {
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkcon0;
+       int val;
+       if (!nr_armdiv || !armdivmask)
+               return -EINVAL;
+       clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+       clkcon0 &= armdivmask;
+       val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
+       return rate / armdiv[val];
+ }
+ static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
+ {
+       unsigned long parent = clk_get_rate(clk->parent);
+       unsigned long calc;
+       unsigned div;
+       unsigned best = 256; /* bigger than any value */
+       int ptr;
+       int val = -1;
+       if (!nr_armdiv || !armdivmask)
+               return -EINVAL;
+       for (ptr = 0; ptr < nr_armdiv; ptr++) {
+               div = armdiv[ptr];
+               if (div) {
+                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
+                       calc = (parent / div / 1000) * 1000;
+                       if (calc <= rate && div < best) {
+                               best = div;
+                               val = ptr;
+                       }
+               }
+       }
+       if (val >= 0) {
+               unsigned long clkcon0;
+               clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+               clkcon0 &= ~armdivmask;
+               clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+               __raw_writel(clkcon0, S3C2443_CLKDIV0);
+       }
+       return (val == -1) ? -EINVAL : 0;
+ }
+ static struct clk clk_armdiv = {
+       .name           = "armdiv",
+       .parent         = &clk_msysclk.clk,
+       .ops            = &(struct clk_ops) {
+               .round_rate = s3c2443_armclk_roundrate,
+               .get_rate = s3c2443_armclk_getrate,
+               .set_rate = s3c2443_armclk_setrate,
+       },
+ };
+ /* armclk
+  *
+  * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+  */
+ static struct clk *clk_arm_sources[] = {
+       [0] = &clk_armdiv,
+       [1] = &clk_h,
+ };
+ static struct clksrc_clk clk_arm = {
+       .clk    = {
+               .name           = "armclk",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_arm_sources,
+               .nr_sources = ARRAY_SIZE(clk_arm_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+ };
+ /* usbhost
+  *
+  * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+ */
+ static struct clksrc_clk clk_usb_bus_host = {
+       .clk    = {
+               .name           = "usb-bus-host-parent",
+               .parent         = &clk_esysclk.clk,
+               .ctrlbit        = S3C2443_SCLKCON_USBHOST,
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+ };
+ /* common clksrc clocks */
+ static struct clksrc_clk clksrc_clks[] = {
+       {
+               /* camera interface bus-clock, divided down from esysclk */
+               .clk    = {
+                       .name           = "camif-upll", /* same as 2440 name */
+                       .parent         = &clk_esysclk.clk,
+                       .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
+                       .enable         = s3c2443_clkcon_enable_s,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
+       }, {
+               .clk    = {
+                       .name           = "display-if",
+                       .parent         = &clk_esysclk.clk,
+                       .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
+                       .enable         = s3c2443_clkcon_enable_s,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
+       },
+ };
+ static struct clksrc_clk clk_esys_uart = {
+       /* ART baud-rate clock sourced from esysclk via a divisor */
+       .clk    = {
+               .name           = "uartclk",
+               .parent         = &clk_esysclk.clk,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+ };
+ static struct clk clk_i2s_ext = {
+       .name           = "i2s-ext",
+ };
+ /* i2s_eplldiv
+  *
+  * This clock is the output from the I2S divisor of ESYSCLK, and is separate
+  * from the mux that comes after it (cannot merge into one single clock)
+ */
+ static struct clksrc_clk clk_i2s_eplldiv = {
+       .clk    = {
+               .name           = "i2s-eplldiv",
+               .parent         = &clk_esysclk.clk,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
+ };
+ /* i2s-ref
+  *
+  * i2s bus reference clock, selectable from external, esysclk or epllref
+  *
+  * Note, this used to be two clocks, but was compressed into one.
+ */
+ static struct clk *clk_i2s_srclist[] = {
+       [0] = &clk_i2s_eplldiv.clk,
+       [1] = &clk_i2s_ext,
+       [2] = &clk_epllref.clk,
+       [3] = &clk_epllref.clk,
+ };
+ static struct clksrc_clk clk_i2s = {
+       .clk    = {
+               .name           = "i2s-if",
+               .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_i2s_srclist,
+               .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
+ };
+ static struct clk init_clocks_off[] = {
+       {
+               .name           = "iis",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIS,
+       }, {
+               .name           = "hsspi",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_HSSPI,
+       }, {
+               .name           = "adc",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIC,
+       }
+ };
+ static struct clk init_clocks[] = {
+       {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA0,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA1,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA2,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA3,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA4,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA5,
+       }, {
+               .name           = "gpio",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBD,
+       }, {
+               .name           = "lcd",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_LCDC,
+       }, {
+               .name           = "timers",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_PWMT,
+       }, {
+               .name           = "cfc",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_CFC,
+       }, {
+               .name           = "ssmc",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_SSMC,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.0",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.1",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.2",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART2,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.3",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART3,
+       }, {
+               .name           = "rtc",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_WDT,
+       }, {
+               .name           = "ac97",
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_AC97,
+       }, {
+               .name           = "nand",
+               .parent         = &clk_h,
+       }, {
+               .name           = "usb-bus-host",
+               .parent         = &clk_usb_bus_host.clk,
+       }
+ };
+ static struct clk hsmmc1_clk = {
+       .name           = "hsmmc",
+       .devname        = "s3c-sdhci.1",
+       .parent         = &clk_h,
+       .enable         = s3c2443_clkcon_enable_h,
+       .ctrlbit        = S3C2443_HCLKCON_HSMMC,
+ };
+ /* EPLLCON compatible enough to get on/off information */
+ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
+ {
+       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+       unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+       struct clk *xtal_clk;
+       unsigned long xtal;
+       unsigned long pll;
+       int ptr;
+       xtal_clk = clk_get(NULL, "xtal");
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+       pll = get_mpll(mpllcon, xtal);
+       clk_msysclk.clk.rate = pll;
+       clk_mpll.rate = pll;
+       printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+              (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
+              print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)),
+              print_mhz(clk_get_rate(&clk_h)),
+              print_mhz(clk_get_rate(&clk_p)));
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+               s3c_set_clksrc(&clksrc_clks[ptr], true);
+       /* ensure usb bus clock is within correct rate of 48MHz */
+       if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
+               printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+               clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
+       }
+       printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+              (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
+              print_mhz(clk_get_rate(&clk_epll)),
+              print_mhz(clk_get_rate(&clk_usb_bus)));
+ }
+ static struct clk *clks[] __initdata = {
+       &clk_prediv,
+       &clk_mpllref,
+       &clk_mdivclk,
+       &clk_ext,
+       &clk_epll,
+       &clk_usb_bus,
+       &clk_armdiv,
+       &hsmmc1_clk,
+ };
+ static struct clksrc_clk *clksrcs[] __initdata = {
+       &clk_i2s_eplldiv,
+       &clk_i2s,
+       &clk_usb_bus_host,
+       &clk_epllref,
+       &clk_esysclk,
+       &clk_msysclk,
+       &clk_arm,
+ };
+ static struct clk_lookup s3c2443_clk_lookup[] = {
+       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+       CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
+       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
+ };
+ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+                                      unsigned int *divs, int nr_divs,
+                                      int divmask)
+ {
+       int ptr;
+       armdiv = divs;
+       nr_armdiv = nr_divs;
+       armdivmask = divmask;
+       /* s3c2443 parents h clock from prediv */
+       clk_h.parent = &clk_prediv;
+       clk_h.ops = &clk_h_ops;
+       /* and p clock from h clock */
+       clk_p.parent = &clk_h;
+       clk_p.ops = &clk_p_ops;
+       clk_usb_bus.parent = &clk_usb_bus_host.clk;
+       clk_epll.parent = &clk_epllref.clk;
+       s3c24xx_register_baseclocks(xtal);
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+       s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+       /* See s3c2443/etc notes on disabling clocks at init time */
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
+       s3c2443_common_setup_clocks(get_mpll);
+ }
index 0000000,2afd000..4803338
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,185 +1,186 @@@
 -static int __init s3c2410_dma_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2410/dma.c
+  *
+  * Copyright (c) 2006 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2410 DMA selection
+  *
+  * http://armlinux.simtec.co.uk/
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+ */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/serial_core.h>
+ #include <mach/map.h>
+ #include <mach/dma.h>
+ #include <plat/cpu.h>
+ #include <plat/dma-s3c24xx.h>
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/regs-ac97.h>
+ #include <plat/regs-dma.h>
+ #include <mach/regs-mem.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-sdi.h>
+ #include <plat/regs-iis.h>
+ #include <plat/regs-spi.h>
+ static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+       },
+               [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+ };
+ static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+ {
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+ }
+ static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
+       .select         = s3c2410_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2410_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2410_dma_mappings),
+ };
+ static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
+       .channels       = {
+               [DMACH_SDI]     = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                               [2]     = 0 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_IN]  = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+       },
+ };
 -      return subsys_interface_register(&s3c2410_interface);
++static int __init s3c2410_dma_add(struct device *dev,
++                                struct subsys_interface *sif)
+ {
+       s3c2410_dma_init();
+       s3c24xx_dma_order_set(&s3c2410_dma_order);
+       return s3c24xx_dma_init_map(&s3c2410_dma_sel);
+ }
+ #if defined(CONFIG_CPU_S3C2410)
+ static struct subsys_interface s3c2410_dma_interface = {
+       .name           = "s3c2410_dma",
+       .subsys         = &s3c2410_subsys,
+       .add_dev        = s3c2410_dma_add,
+ };
+ static int __init s3c2410_dma_drvinit(void)
+ {
++      return subsys_interface_register(&s3c2410_dma_interface);
+ }
+ arch_initcall(s3c2410_dma_drvinit);
+ static struct subsys_interface s3c2410a_dma_interface = {
+       .name           = "s3c2410a_dma",
+       .subsys         = &s3c2410a_subsys,
+       .add_dev        = s3c2410_dma_add,
+ };
+ static int __init s3c2410a_dma_drvinit(void)
+ {
+       return subsys_interface_register(&s3c2410a_dma_interface);
+ }
+ arch_initcall(s3c2410a_dma_drvinit);
+ #endif
+ #if defined(CONFIG_CPU_S3C2442)
+ /* S3C2442 DMA contains the same selection table as the S3C2410 */
+ static struct subsys_interface s3c2442_dma_interface = {
+       .name           = "s3c2442_dma",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c2410_dma_add,
+ };
+ static int __init s3c2442_dma_drvinit(void)
+ {
+       return subsys_interface_register(&s3c2442_dma_interface);
+ }
+ arch_initcall(s3c2442_dma_drvinit);
+ #endif
index 0000000,142acd3..38472ac
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,179 +1,180 @@@
 -static int __init s3c2412_dma_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2412/dma.c
+  *
+  * Copyright (c) 2006 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2412 DMA selection
+  *
+  * http://armlinux.simtec.co.uk/
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+ */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/serial_core.h>
+ #include <linux/io.h>
+ #include <mach/dma.h>
+ #include <plat/dma-s3c24xx.h>
+ #include <plat/cpu.h>
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/regs-ac97.h>
+ #include <plat/regs-dma.h>
+ #include <mach/regs-mem.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-sdi.h>
+ #include <plat/regs-iis.h>
+ #include <plat/regs-spi.h>
+ #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
+ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_SDI),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_SDI),
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI0RX),
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI1RX),
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_0),
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_0),
+       },
+               [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_0),
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_1),
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_1),
+       },
+               [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_1),
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2412_DMAREQSEL_TIMER),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2SRX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_I2SRX),
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2STX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_I2STX),
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP1),
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP2),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP2),
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP3),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP3),
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP4),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP4),
+       },
+ };
+ static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
+                                 struct s3c24xx_dma_map *map,
+                                 enum dma_data_direction dir)
+ {
+       unsigned long chsel;
+       if (dir == DMA_FROM_DEVICE)
+               chsel = map->channels_rx[0];
+       else
+               chsel = map->channels[0];
+       chsel &= ~DMA_CH_VALID;
+       chsel |= S3C2412_DMAREQSEL_HW;
+       writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
+ }
+ static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+ {
+       s3c2412_dma_direction(chan, map, chan->source);
+ }
+ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
+       .select         = s3c2412_dma_select,
+       .direction      = s3c2412_dma_direction,
+       .dcon_mask      = 0,
+       .map            = s3c2412_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2412_dma_mappings),
+ };
++static int __init s3c2412_dma_add(struct device *dev,
++                                struct subsys_interface *sif)
+ {
+       s3c2410_dma_init();
+       return s3c24xx_dma_init_map(&s3c2412_dma_sel);
+ }
+ static struct subsys_interface s3c2412_dma_interface = {
+       .name           = "s3c2412_dma",
+       .subsys         = &s3c2412_subsys,
+       .add_dev        = s3c2412_dma_add,
+ };
+ static int __init s3c2412_dma_init(void)
+ {
+       return subsys_interface_register(&s3c2412_dma_interface);
+ }
+ arch_initcall(s3c2412_dma_init);
index 0000000,15b1ddf..5f0a0c8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,196 +1,197 @@@
 -static int __init s3c2440_dma_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2440/dma.c
+  *
+  * Copyright (c) 2006 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2440 DMA selection
+  *
+  * http://armlinux.simtec.co.uk/
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+ */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/serial_core.h>
+ #include <mach/map.h>
+ #include <mach/dma.h>
+ #include <plat/dma-s3c24xx.h>
+ #include <plat/cpu.h>
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/regs-ac97.h>
+ #include <plat/regs-dma.h>
+ #include <mach/regs-mem.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-sdi.h>
+ #include <plat/regs-iis.h>
+ #include <plat/regs-spi.h>
+ static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+       },
+               [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
+               .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+ };
+ static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+ {
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+ }
+ static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
+       .select         = s3c2440_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2440_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2440_dma_mappings),
+ };
+ static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
+       .channels       = {
+               [DMACH_SDI]     = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                               [2]     = 1 | DMA_CH_VALID,
+                               [3]     = 0 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_IN]  = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_OUT] = {
+                       .list   = {
+                               [0]     = 2 | DMA_CH_VALID,
+                               [1]     = 1 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_PCM_IN] = {
+                       .list   = {
+                               [0]     = 2 | DMA_CH_VALID,
+                               [1]     = 1 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_PCM_OUT] = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 3 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_MIC_IN] = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+       },
+ };
++static int __init s3c2440_dma_add(struct device *dev,
++                                struct subsys_interface *sif)
+ {
+       s3c2410_dma_init();
+       s3c24xx_dma_order_set(&s3c2440_dma_order);
+       return s3c24xx_dma_init_map(&s3c2440_dma_sel);
+ }
+ static struct subsys_interface s3c2440_dma_interface = {
+       .name           = "s3c2440_dma",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2440_dma_add,
+ };
+ static int __init s3c2440_dma_init(void)
+ {
+       return subsys_interface_register(&s3c2440_dma_interface);
+ }
+ arch_initcall(s3c2440_dma_init);
index 0000000,2504474..e227c47
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,173 +1,174 @@@
 -static int __init s3c2443_dma_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2443/dma.c
+  *
+  * Copyright (c) 2007 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2443 DMA selection
+  *
+  * http://armlinux.simtec.co.uk/
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+ */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/serial_core.h>
+ #include <linux/io.h>
+ #include <mach/dma.h>
+ #include <plat/dma-s3c24xx.h>
+ #include <plat/cpu.h>
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/regs-ac97.h>
+ #include <plat/regs-dma.h>
+ #include <mach/regs-mem.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-sdi.h>
+ #include <plat/regs-iis.h>
+ #include <plat/regs-spi.h>
+ #define MAP(x) { \
+               [0]     = (x) | DMA_CH_VALID,   \
+               [1]     = (x) | DMA_CH_VALID,   \
+               [2]     = (x) | DMA_CH_VALID,   \
+               [3]     = (x) | DMA_CH_VALID,   \
+               [4]     = (x) | DMA_CH_VALID,   \
+               [5]     = (x) | DMA_CH_VALID,   \
+       }
+ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = { /* only on S3C2443 */
+               .name           = "sdi",
+               .channels       = MAP(S3C2443_DMAREQSEL_SDI),
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2443_DMAREQSEL_SPI0TX),
+       },
+       [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */
+               .name           = "spi1",
+               .channels       = MAP(S3C2443_DMAREQSEL_SPI1TX),
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART0_0),
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART1_0),
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART2_0),
+       },
+       [DMACH_UART3] = {
+               .name           = "uart3",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART3_0),
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART0_1),
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART1_1),
+       },
+       [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART2_1),
+       },
+       [DMACH_UART3_SRC2] = {
+               .name           = "uart3",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART3_1),
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2443_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2443_DMAREQSEL_I2SRX),
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2443_DMAREQSEL_I2STX),
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels       = MAP(S3C2443_DMAREQSEL_PCMIN),
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels       = MAP(S3C2443_DMAREQSEL_PCMOUT),
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels       = MAP(S3C2443_DMAREQSEL_MICIN),
+       },
+ };
+ static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+ {
+       writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
+              chan->regs + S3C2443_DMA_DMAREQSEL);
+ }
+ static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
+       .select         = s3c2443_dma_select,
+       .dcon_mask      = 0,
+       .map            = s3c2443_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2443_dma_mappings),
+ };
++static int __init s3c2443_dma_add(struct device *dev,
++                                struct subsys_interface *sif)
+ {
+       s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
+       return s3c24xx_dma_init_map(&s3c2443_dma_sel);
+ }
+ #ifdef CONFIG_CPU_S3C2416
+ /* S3C2416 DMA contains the same selection table as the S3C2443 */
+ static struct subsys_interface s3c2416_dma_interface = {
+       .name           = "s3c2416_dma",
+       .subsys         = &s3c2416_subsys,
+       .add_dev        = s3c2443_dma_add,
+ };
+ static int __init s3c2416_dma_init(void)
+ {
+       return subsys_interface_register(&s3c2416_dma_interface);
+ }
+ arch_initcall(s3c2416_dma_init);
+ #endif
+ #ifdef CONFIG_CPU_S3C2443
+ static struct subsys_interface s3c2443_dma_interface = {
+       .name           = "s3c2443_dma",
+       .subsys         = &s3c2443_subsys,
+       .add_dev        = s3c2443_dma_add,
+ };
+ static int __init s3c2443_dma_init(void)
+ {
+       return subsys_interface_register(&s3c2443_dma_interface);
+ }
+ arch_initcall(s3c2443_dma_init);
+ #endif
index 0000000,473b3cd..7615a14
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,78 +1,70 @@@
 -      .macro  arch_ret_to_user, tmp1, tmp2
 -      .endm
 -
+ /*
+  * arch/arm/mach-s3c2410/include/mach/entry-macro.S
+  *
+  * Low-level IRQ helper macros for S3C2410-based platforms
+  *
+  * This file is licensed under  the terms of the GNU General Public
+  * License version 2. This program is licensed "as is" without any
+  * warranty of any kind, whether express or implied.
+ */
+ /* We have a problem that the INTOFFSET register does not always
+  * show one interrupt. Occasionally we get two interrupts through
+  * the prioritiser, and this causes the INTOFFSET register to show
+  * what looks like the logical-or of the two interrupt numbers.
+  *
+  * Thanks to Klaus, Shannon, et al for helping to debug this problem
+ */
+ #define INTPND                (0x10)
+ #define INTOFFSET     (0x14)
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
 -
 -              /* currently don't need an disable_fiq macro */
 -
 -              .macro  disable_fiq
 -              .endm
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+               mov     \base, #S3C24XX_VA_IRQ
+               @@ try the interrupt offset register, since it is there
+               ldr     \irqstat, [ \base, #INTPND ]
+               teq     \irqstat, #0
+               beq     1002f
+               ldr     \irqnr, [ \base, #INTOFFSET ]
+               mov     \tmp, #1
+               tst     \irqstat, \tmp, lsl \irqnr
+               bne     1001f
+               @@ the number specified is not a valid irq, so try
+               @@ and work it out for ourselves
+               mov     \irqnr, #0              @@ start here
+               @@ work out which irq (if any) we got
+               movs    \tmp, \irqstat, lsl#16
+               addeq   \irqnr, \irqnr, #16
+               moveq   \irqstat, \irqstat, lsr#16
+               tst     \irqstat, #0xff
+               addeq   \irqnr, \irqnr, #8
+               moveq   \irqstat, \irqstat, lsr#8
+               tst     \irqstat, #0xf
+               addeq   \irqnr, \irqnr, #4
+               moveq   \irqstat, \irqstat, lsr#4
+               tst     \irqstat, #0x3
+               addeq   \irqnr, \irqnr, #2
+               moveq   \irqstat, \irqstat, lsr#2
+               tst     \irqstat, #0x1
+               addeq   \irqnr, \irqnr, #1
+               @@ we have the value
+ 1001:
+               adds    \irqnr, \irqnr, #IRQ_EINT0
+ 1002:
+               @@ exit here, Z flag unset if IRQ
+       .endm
index 0000000,a8a46c1..e65619d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,214 +1,214 @@@
 -static int s3c2412_irq_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2412/irq.c
+  *
+  * Copyright (c) 2006 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  *
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <mach/regs-irq.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/regs-power.h>
+ #include <plat/cpu.h>
+ #include <plat/irq.h>
+ #include <plat/pm.h>
+ #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+ #define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
+ /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
+  * having them turn up in both the INT* and the EINT* registers. Whilst
+  * both show the status, they both now need to be acked when the IRQs
+  * go off.
+ */
+ static void
+ s3c2412_irq_mask(struct irq_data *data)
+ {
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       unsigned long mask;
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask | bitval, S3C2410_INTMSK);
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask | bitval, S3C2412_EINTMASK);
+ }
+ static inline void
+ s3c2412_irq_ack(struct irq_data *data)
+ {
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       __raw_writel(bitval, S3C2412_EINTPEND);
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+ }
+ static inline void
+ s3c2412_irq_maskack(struct irq_data *data)
+ {
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       unsigned long mask;
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask|bitval, S3C2410_INTMSK);
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask | bitval, S3C2412_EINTMASK);
+       __raw_writel(bitval, S3C2412_EINTPEND);
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+ }
+ static void
+ s3c2412_irq_unmask(struct irq_data *data)
+ {
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       unsigned long mask;
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask & ~bitval, S3C2412_EINTMASK);
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask & ~bitval, S3C2410_INTMSK);
+ }
+ static struct irq_chip s3c2412_irq_eint0t4 = {
+       .irq_ack        = s3c2412_irq_ack,
+       .irq_mask       = s3c2412_irq_mask,
+       .irq_unmask     = s3c2412_irq_unmask,
+       .irq_set_wake   = s3c_irq_wake,
+       .irq_set_type   = s3c_irqext_type,
+ };
+ #define INTBIT(x)     (1 << ((x) - S3C2410_IRQSUB(0)))
+ /* CF and SDI sub interrupts */
+ static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
+ {
+       unsigned int subsrc, submsk;
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+       subsrc  &= ~submsk;
+       if (subsrc & INTBIT(IRQ_S3C2412_SDI))
+               generic_handle_irq(IRQ_S3C2412_SDI);
+       if (subsrc & INTBIT(IRQ_S3C2412_CF))
+               generic_handle_irq(IRQ_S3C2412_CF);
+ }
+ #define INTMSK_CFSDI  (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
+ #define SUBMSK_CFSDI  INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
+ static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
+ }
+ static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
+ }
+ static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
+ }
+ static struct irq_chip s3c2412_irq_cfsdi = {
+       .name           = "s3c2412-cfsdi",
+       .irq_ack        = s3c2412_irq_cfsdi_ack,
+       .irq_mask       = s3c2412_irq_cfsdi_mask,
+       .irq_unmask     = s3c2412_irq_cfsdi_unmask,
+ };
+ static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
+ {
+       unsigned long pwrcfg;
+       pwrcfg = __raw_readl(S3C2412_PWRCFG);
+       if (state)
+               pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ;
+       else
+               pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
+       __raw_writel(pwrcfg, S3C2412_PWRCFG);
+       return s3c_irq_chip.irq_set_wake(data, state);
+ }
+ static struct irq_chip s3c2412_irq_rtc_chip;
++static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif)
+ {
+       unsigned int irqno;
+       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4,
+                                        handle_edge_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+       /* add demux support for CF/SDI */
+       irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
+       for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi,
+                                        handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+       /* change RTC IRQ's set wake method */
+       s3c2412_irq_rtc_chip = s3c_irq_chip;
+       s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
+       irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
+       return 0;
+ }
+ static struct subsys_interface s3c2412_irq_interface = {
+       .name           = "s3c2412_irq",
+       .subsys         = &s3c2412_subsys,
+       .add_dev        = s3c2412_irq_add,
+ };
+ static int s3c2412_irq_init(void)
+ {
+       return subsys_interface_register(&s3c2412_irq_interface);
+ }
+ arch_initcall(s3c2412_irq_init);
index 0000000,36df761..fd49f35
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,249 +1,250 @@@
 -static int __init s3c2416_irq_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2416/irq.c
+  *
+  * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+  *    as part of OpenInkpot project
+  * Copyright (c) 2009 Promwad Innovation Company
+  *    Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  *
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <mach/regs-irq.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/irq.h>
+ #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+ static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+ {
+       unsigned int subsrc, submsk;
+       unsigned int end;
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+       subsrc  &= ~submsk;
+       subsrc >>= (irq - S3C2410_IRQSUB(0));
+       subsrc  &= (1 << len)-1;
+       end = len + irq;
+       for (; irq < end && subsrc; irq++) {
+               if (subsrc & 1)
+                       generic_handle_irq(irq);
+               subsrc >>= 1;
+       }
+ }
+ /* WDT/AC97 sub interrupts */
+ static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+ }
+ #define INTMSK_WDTAC97        (1UL << (IRQ_WDT - IRQ_EINT0))
+ #define SUBMSK_WDTAC97        INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+ static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ }
+ static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+ }
+ static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ }
+ static struct irq_chip s3c2416_irq_wdtac97 = {
+       .irq_mask       = s3c2416_irq_wdtac97_mask,
+       .irq_unmask     = s3c2416_irq_wdtac97_unmask,
+       .irq_ack        = s3c2416_irq_wdtac97_ack,
+ };
+ /* LCD sub interrupts */
+ static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+ }
+ #define INTMSK_LCD    (1UL << (IRQ_LCD - IRQ_EINT0))
+ #define SUBMSK_LCD    INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+ static void s3c2416_irq_lcd_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+ }
+ static void s3c2416_irq_lcd_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+ }
+ static void s3c2416_irq_lcd_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+ }
+ static struct irq_chip s3c2416_irq_lcd = {
+       .irq_mask       = s3c2416_irq_lcd_mask,
+       .irq_unmask     = s3c2416_irq_lcd_unmask,
+       .irq_ack        = s3c2416_irq_lcd_ack,
+ };
+ /* DMA sub interrupts */
+ static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+ }
+ #define INTMSK_DMA    (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+ #define SUBMSK_DMA    INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+ static void s3c2416_irq_dma_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+ }
+ static void s3c2416_irq_dma_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+ }
+ static void s3c2416_irq_dma_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+ }
+ static struct irq_chip s3c2416_irq_dma = {
+       .irq_mask       = s3c2416_irq_dma_mask,
+       .irq_unmask     = s3c2416_irq_dma_unmask,
+       .irq_ack        = s3c2416_irq_dma_ack,
+ };
+ /* UART3 sub interrupts */
+ static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
+ }
+ #define INTMSK_UART3  (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+ #define SUBMSK_UART3  (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+ static void s3c2416_irq_uart3_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+ }
+ static void s3c2416_irq_uart3_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+ }
+ static void s3c2416_irq_uart3_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+ }
+ static struct irq_chip s3c2416_irq_uart3 = {
+       .irq_mask       = s3c2416_irq_uart3_mask,
+       .irq_unmask     = s3c2416_irq_uart3_unmask,
+       .irq_ack        = s3c2416_irq_uart3_ack,
+ };
+ /* IRQ initialisation code */
+ static int __init s3c2416_add_sub(unsigned int base,
+                                  void (*demux)(unsigned int,
+                                                struct irq_desc *),
+                                  struct irq_chip *chip,
+                                  unsigned int start, unsigned int end)
+ {
+       unsigned int irqno;
+       irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+       irq_set_chained_handler(base, demux);
+       for (irqno = start; irqno <= end; irqno++) {
+               irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+       return 0;
+ }
++static int __init s3c2416_irq_add(struct device *dev,
++                                struct subsys_interface *sif)
+ {
+       printk(KERN_INFO "S3C2416: IRQ Support\n");
+       s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+                       IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+       s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+                       &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+       s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+                       &s3c2416_irq_uart3,
+                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+       s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+                       &s3c2416_irq_wdtac97,
+                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+       return 0;
+ }
+ static struct subsys_interface s3c2416_irq_interface = {
+       .name           = "s3c2416_irq",
+       .subsys         = &s3c2416_subsys,
+       .add_dev        = s3c2416_irq_add,
+ };
+ static int __init s3c2416_irq_init(void)
+ {
+       return subsys_interface_register(&s3c2416_irq_interface);
+ }
+ arch_initcall(s3c2416_irq_init);
index 0000000,4fee9bc..4a18cde
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,128 +1,128 @@@
 -static int s3c2440_irq_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2440/irq.c
+  *
+  * Copyright (c) 2003-2004 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  *
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <mach/regs-irq.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/irq.h>
+ /* WDT/AC97 */
+ static void s3c_irq_demux_wdtac97(unsigned int irq,
+                                 struct irq_desc *desc)
+ {
+       unsigned int subsrc, submsk;
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+       subsrc &= ~submsk;
+       subsrc >>= 13;
+       subsrc &= 3;
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       generic_handle_irq(IRQ_S3C2440_WDT);
+               }
+               if (subsrc & 2) {
+                       generic_handle_irq(IRQ_S3C2440_AC97);
+               }
+       }
+ }
+ #define INTMSK_WDT     (1UL << (IRQ_WDT - IRQ_EINT0))
+ static void
+ s3c_irq_wdtac97_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
+ }
+ static void
+ s3c_irq_wdtac97_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_WDT);
+ }
+ static void
+ s3c_irq_wdtac97_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
+ }
+ static struct irq_chip s3c_irq_wdtac97 = {
+       .irq_mask       = s3c_irq_wdtac97_mask,
+       .irq_unmask     = s3c_irq_wdtac97_unmask,
+       .irq_ack        = s3c_irq_wdtac97_ack,
+ };
++static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif)
+ {
+       unsigned int irqno;
+       printk("S3C2440: IRQ Support\n");
+       /* add new chained handler for wdt, ac7 */
+       irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip,
+                                handle_level_irq);
+       irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+       for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97,
+                                        handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+       return 0;
+ }
+ static struct subsys_interface s3c2440_irq_interface = {
+       .name           = "s3c2440_irq",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2440_irq_add,
+ };
+ static int s3c2440_irq_init(void)
+ {
+       return subsys_interface_register(&s3c2440_irq_interface);
+ }
+ arch_initcall(s3c2440_irq_init);
index 0000000,35e4ff2..ac2829f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,280 +1,281 @@@
 -static int __init s3c2443_irq_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2443/irq.c
+  *
+  * Copyright (c) 2007 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  *
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <mach/regs-irq.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/irq.h>
+ #define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+ static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+ {
+       unsigned int subsrc, submsk;
+       unsigned int end;
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+       subsrc  &= ~submsk;
+       subsrc >>= (irq - S3C2410_IRQSUB(0));
+       subsrc  &= (1 << len)-1;
+       end = len + irq;
+       for (; irq < end && subsrc; irq++) {
+               if (subsrc & 1)
+                       generic_handle_irq(irq);
+               subsrc >>= 1;
+       }
+ }
+ /* WDT/AC97 sub interrupts */
+ static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+ }
+ #define INTMSK_WDTAC97        (1UL << (IRQ_WDT - IRQ_EINT0))
+ #define SUBMSK_WDTAC97        INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+ static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ }
+ static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+ }
+ static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+ }
+ static struct irq_chip s3c2443_irq_wdtac97 = {
+       .irq_mask       = s3c2443_irq_wdtac97_mask,
+       .irq_unmask     = s3c2443_irq_wdtac97_unmask,
+       .irq_ack        = s3c2443_irq_wdtac97_ack,
+ };
+ /* LCD sub interrupts */
+ static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+ }
+ #define INTMSK_LCD    (1UL << (IRQ_LCD - IRQ_EINT0))
+ #define SUBMSK_LCD    INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+ static void s3c2443_irq_lcd_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+ }
+ static void s3c2443_irq_lcd_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+ }
+ static void s3c2443_irq_lcd_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+ }
+ static struct irq_chip s3c2443_irq_lcd = {
+       .irq_mask       = s3c2443_irq_lcd_mask,
+       .irq_unmask     = s3c2443_irq_lcd_unmask,
+       .irq_ack        = s3c2443_irq_lcd_ack,
+ };
+ /* DMA sub interrupts */
+ static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
+ }
+ #define INTMSK_DMA    (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+ #define SUBMSK_DMA    INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+ static void s3c2443_irq_dma_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+ }
+ static void s3c2443_irq_dma_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+ }
+ static void s3c2443_irq_dma_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+ }
+ static struct irq_chip s3c2443_irq_dma = {
+       .irq_mask       = s3c2443_irq_dma_mask,
+       .irq_unmask     = s3c2443_irq_dma_unmask,
+       .irq_ack        = s3c2443_irq_dma_ack,
+ };
+ /* UART3 sub interrupts */
+ static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
+ }
+ #define INTMSK_UART3  (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+ #define SUBMSK_UART3  (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+ static void s3c2443_irq_uart3_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+ }
+ static void s3c2443_irq_uart3_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+ }
+ static void s3c2443_irq_uart3_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+ }
+ static struct irq_chip s3c2443_irq_uart3 = {
+       .irq_mask       = s3c2443_irq_uart3_mask,
+       .irq_unmask     = s3c2443_irq_uart3_unmask,
+       .irq_ack        = s3c2443_irq_uart3_ack,
+ };
+ /* CAM sub interrupts */
+ static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+ {
+       s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+ }
+ #define INTMSK_CAM    (1UL << (IRQ_CAM - IRQ_EINT0))
+ #define SUBMSK_CAM    INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+ static void s3c2443_irq_cam_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
+ }
+ static void s3c2443_irq_cam_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+ }
+ static void s3c2443_irq_cam_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
+ }
+ static struct irq_chip s3c2443_irq_cam = {
+       .irq_mask       = s3c2443_irq_cam_mask,
+       .irq_unmask     = s3c2443_irq_cam_unmask,
+       .irq_ack        = s3c2443_irq_cam_ack,
+ };
+ /* IRQ initialisation code */
+ static int __init s3c2443_add_sub(unsigned int base,
+                                  void (*demux)(unsigned int,
+                                                struct irq_desc *),
+                                  struct irq_chip *chip,
+                                  unsigned int start, unsigned int end)
+ {
+       unsigned int irqno;
+       irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+       irq_set_chained_handler(base, demux);
+       for (irqno = start; irqno <= end; irqno++) {
+               irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+       return 0;
+ }
++static int __init s3c2443_irq_add(struct device *dev,
++                                struct subsys_interface *sif)
+ {
+       printk("S3C2443: IRQ Support\n");
+       s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+                       IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+       s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+                       IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+       s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+                       &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+       s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+                       &s3c2443_irq_uart3,
+                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+       s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+                       &s3c2443_irq_wdtac97,
+                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+       return 0;
+ }
+ static struct subsys_interface s3c2443_irq_interface = {
+       .name           = "s3c2443_irq",
+       .subsys         = &s3c2443_subsys,
+       .add_dev        = s3c2443_irq_add,
+ };
+ static int __init s3c2443_irq_init(void)
+ {
+       return subsys_interface_register(&s3c2443_irq_interface);
+ }
+ arch_initcall(s3c2443_irq_init);
index 0000000,74d3dcf..5fe8e58
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,142 +1,142 @@@
 -static int s3c244x_irq_add(struct device *dev)
+ /* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
+  *
+  * Copyright (c) 2003-2004 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  *
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <mach/regs-irq.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/irq.h>
+ /* camera irq */
+ static void s3c_irq_demux_cam(unsigned int irq,
+                             struct irq_desc *desc)
+ {
+       unsigned int subsrc, submsk;
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+       subsrc &= ~submsk;
+       subsrc >>= 11;
+       subsrc &= 3;
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       generic_handle_irq(IRQ_S3C2440_CAM_C);
+               }
+               if (subsrc & 2) {
+                       generic_handle_irq(IRQ_S3C2440_CAM_P);
+               }
+       }
+ }
+ #define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+ static void
+ s3c_irq_cam_mask(struct irq_data *data)
+ {
+       s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
+ }
+ static void
+ s3c_irq_cam_unmask(struct irq_data *data)
+ {
+       s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+ }
+ static void
+ s3c_irq_cam_ack(struct irq_data *data)
+ {
+       s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
+ }
+ static struct irq_chip s3c_irq_cam = {
+       .irq_mask       = s3c_irq_cam_mask,
+       .irq_unmask     = s3c_irq_cam_unmask,
+       .irq_ack        = s3c_irq_cam_ack,
+ };
++static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif)
+ {
+       unsigned int irqno;
+       irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip,
+                                handle_level_irq);
+       set_irq_flags(IRQ_NFCON, IRQF_VALID);
+       /* add chained handler for camera */
+       irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip,
+                                handle_level_irq);
+       irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+       for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c_irq_cam,
+                                        handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+       return 0;
+ }
+ static struct subsys_interface s3c2440_irq_interface = {
+       .name           = "s3c2440_irq",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c244x_irq_add,
+ };
+ static int s3c2440_irq_init(void)
+ {
+       return subsys_interface_register(&s3c2440_irq_interface);
+ }
+ arch_initcall(s3c2440_irq_init);
+ static struct subsys_interface s3c2442_irq_interface = {
+       .name           = "s3c2442_irq",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c244x_irq_add,
+ };
+ static int s3c2442_irq_init(void)
+ {
+       return subsys_interface_register(&s3c2442_irq_interface);
+ }
+ arch_initcall(s3c2442_irq_init);
index 0000000,cf270f5..d0e0ad4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,605 +1,605 @@@
 -struct pcf50633_platform_data gta02_pcf_pdata = {
+ /*
+  * linux/arch/arm/mach-s3c2442/mach-gta02.c
+  *
+  * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
+  *
+  * Copyright (C) 2006-2009 by Openmoko, Inc.
+  * Authors: Harald Welte <laforge@openmoko.org>
+  *          Andy Green <andy@openmoko.org>
+  *          Werner Almesberger <werner@openmoko.org>
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License as
+  * published by the Free Software Foundation; either version 2 of
+  * the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  *
+  */
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+ #include <linux/delay.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/gpio.h>
+ #include <linux/workqueue.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_core.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/s3c24xx.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/nand.h>
+ #include <linux/mtd/nand_ecc.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/physmap.h>
+ #include <linux/io.h>
+ #include <linux/i2c.h>
+ #include <linux/regulator/machine.h>
+ #include <linux/mfd/pcf50633/core.h>
+ #include <linux/mfd/pcf50633/mbc.h>
+ #include <linux/mfd/pcf50633/adc.h>
+ #include <linux/mfd/pcf50633/gpio.h>
+ #include <linux/mfd/pcf50633/pmic.h>
+ #include <linux/mfd/pcf50633/backlight.h>
+ #include <linux/input.h>
+ #include <linux/gpio_keys.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+ #include <asm/irq.h>
+ #include <asm/mach-types.h>
+ #include <mach/regs-irq.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/regs-gpioj.h>
+ #include <mach/fb.h>
+ #include <plat/usb-control.h>
+ #include <mach/regs-mem.h>
+ #include <mach/hardware.h>
+ #include <mach/gta02.h>
+ #include <plat/regs-serial.h>
+ #include <plat/nand.h>
+ #include <plat/devs.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/udc.h>
+ #include <plat/gpio-cfg.h>
+ #include <plat/iic.h>
+ #include <plat/ts.h>
+ #include "common.h"
+ static struct pcf50633 *gta02_pcf;
+ /*
+  * This gets called frequently when we paniced.
+  */
+ static long gta02_panic_blink(int state)
+ {
+       long delay = 0;
+       char led;
+       led = (state) ? 1 : 0;
+       gpio_direction_output(GTA02_GPIO_AUX_LED, led);
+       return delay;
+ }
+ static struct map_desc gta02_iodesc[] __initdata = {
+       {
+               .virtual        = 0xe0000000,
+               .pfn            = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE
+       },
+ };
+ #define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
+ #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+ #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+ static struct s3c2410_uartcfg gta02_uartcfgs[] = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
+       },
+ };
+ #ifdef CONFIG_CHARGER_PCF50633
+ /*
+  * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
+  * We use this to recognize that we can pull 1A from the USB socket.
+  *
+  * These constants are the measured pcf50633 ADC levels with the 1A
+  * charger / 48K resistor, and with no pulldown resistor.
+  */
+ #define ADC_NOM_CHG_DETECT_1A 6
+ #define ADC_NOM_CHG_DETECT_USB 43
+ static void
+ gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
+ {
+       int  ma;
+       /* Interpret charger type */
+       if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
+               /*
+                * Sanity - stop GPO driving out now that we have a 1A charger
+                * GPO controls USB Host power generation on GTA02
+                */
+               pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
+               ma = 1000;
+       } else
+               ma = 100;
+       pcf50633_mbc_usb_curlim_set(pcf, ma);
+ }
+ static struct delayed_work gta02_charger_work;
+ static int gta02_usb_vbus_draw;
+ static void gta02_charger_worker(struct work_struct *work)
+ {
+       if (gta02_usb_vbus_draw) {
+               pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
+               return;
+       }
+ #ifdef CONFIG_PCF50633_ADC
+       pcf50633_adc_async_read(gta02_pcf,
+                               PCF50633_ADCC1_MUX_ADCIN1,
+                               PCF50633_ADCC1_AVERAGE_16,
+                               gta02_configure_pmu_for_charger,
+                               NULL);
+ #else
+       /*
+        * If the PCF50633 ADC is disabled we fallback to a
+        * 100mA limit for safety.
+        */
+       pcf50633_mbc_usb_curlim_set(pcf, 100);
+ #endif
+ }
+ #define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+ static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+ {
+       if (irq == PCF50633_IRQ_USBINS) {
+               schedule_delayed_work(&gta02_charger_work,
+                                     GTA02_CHARGER_CONFIGURE_TIMEOUT);
+               return;
+       }
+       if (irq == PCF50633_IRQ_USBREM) {
+               cancel_delayed_work_sync(&gta02_charger_work);
+               gta02_usb_vbus_draw = 0;
+       }
+ }
+ static void gta02_udc_vbus_draw(unsigned int ma)
+ {
+       if (!gta02_pcf)
+               return;
+       gta02_usb_vbus_draw = ma;
+       schedule_delayed_work(&gta02_charger_work,
+                             GTA02_CHARGER_CONFIGURE_TIMEOUT);
+ }
+ #else /* !CONFIG_CHARGER_PCF50633 */
+ #define gta02_pmu_event_callback      NULL
+ #define gta02_udc_vbus_draw           NULL
+ #endif
+ /*
+  * This is called when pc50633 is probed, unfortunately quite late in the
+  * day since it is an I2C bus device. Here we can belatedly define some
+  * platform devices with the advantage that we can mark the pcf50633 as the
+  * parent. This makes them get suspended and resumed with their parent
+  * the pcf50633 still around.
+  */
+ static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+ static char *gta02_batteries[] = {
+       "battery",
+ };
+ static struct pcf50633_bl_platform_data gta02_backlight_data = {
+       .default_brightness = 0x3f,
+       .default_brightness_limit = 0,
+       .ramp_time = 5,
+ };
 -struct platform_device s3c24xx_pwm_device = {
++static struct pcf50633_platform_data gta02_pcf_pdata = {
+       .resumers = {
+               [0] =   PCF50633_INT1_USBINS |
+                       PCF50633_INT1_USBREM |
+                       PCF50633_INT1_ALARM,
+               [1] =   PCF50633_INT2_ONKEYF,
+               [2] =   PCF50633_INT3_ONKEY1S,
+               [3] =   PCF50633_INT4_LOWSYS |
+                       PCF50633_INT4_LOWBAT |
+                       PCF50633_INT4_HIGHTMP,
+       },
+       .batteries = gta02_batteries,
+       .num_batteries = ARRAY_SIZE(gta02_batteries),
+       .charger_reference_current_ma = 1000,
+       .backlight_data = &gta02_backlight_data,
+       .reg_init_data = {
+               [PCF50633_REGULATOR_AUTO] = {
+                       .constraints = {
+                               .min_uV = 3300000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .always_on = 1,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_DOWN1] = {
+                       .constraints = {
+                               .min_uV = 1300000,
+                               .max_uV = 1600000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .always_on = 1,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_DOWN2] = {
+                       .constraints = {
+                               .min_uV = 1800000,
+                               .max_uV = 1800000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .apply_uV = 1,
+                               .always_on = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_HCLDO] = {
+                       .constraints = {
+                               .min_uV = 2000000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                               REGULATOR_CHANGE_STATUS,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO1] = {
+                       .constraints = {
+                               .min_uV = 3300000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO2] = {
+                       .constraints = {
+                               .min_uV = 3300000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO3] = {
+                       .constraints = {
+                               .min_uV = 3000000,
+                               .max_uV = 3000000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO4] = {
+                       .constraints = {
+                               .min_uV = 3200000,
+                               .max_uV = 3200000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO5] = {
+                       .constraints = {
+                               .min_uV = 3000000,
+                               .max_uV = 3000000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO6] = {
+                       .constraints = {
+                               .min_uV = 3000000,
+                               .max_uV = 3000000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                       },
+               },
+               [PCF50633_REGULATOR_MEMLDO] = {
+                       .constraints = {
+                               .min_uV = 1800000,
+                               .max_uV = 1800000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                       },
+               },
+       },
+       .probe_done = gta02_pmu_attach_child_devices,
+       .mbc_event_callback = gta02_pmu_event_callback,
+ };
+ /* NOR Flash. */
+ #define GTA02_FLASH_BASE      0x18000000 /* GCS3 */
+ #define GTA02_FLASH_SIZE      0x200000 /* 2MBytes */
+ static struct physmap_flash_data gta02_nor_flash_data = {
+       .width          = 2,
+ };
+ static struct resource gta02_nor_flash_resource = {
+       .start          = GTA02_FLASH_BASE,
+       .end            = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+ };
+ static struct platform_device gta02_nor_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &gta02_nor_flash_data,
+       },
+       .resource       = &gta02_nor_flash_resource,
+       .num_resources  = 1,
+ };
++static struct platform_device s3c24xx_pwm_device = {
+       .name           = "s3c24xx_pwm",
+       .num_resources  = 0,
+ };
+ static struct platform_device gta02_dfbmcs320_device = {
+       .name = "dfbmcs320",
+ };
+ static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("pcf50633", 0x73),
+               .irq = GTA02_IRQ_PCF50633,
+               .platform_data = &gta02_pcf_pdata,
+       },
+       {
+               I2C_BOARD_INFO("wm8753", 0x1a),
+       },
+ };
+ static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
+       [0] = {
+               /*
+                * This name is also hard-coded in the boot loaders, so
+                * changing it would would require all users to upgrade
+                * their boot loaders, some of which are stored in a NOR
+                * that is considered to be immutable.
+                */
+               .name           = "neo1973-nand",
+               .nr_chips       = 1,
+               .flash_bbt      = 1,
+       },
+ };
+ /*
+  * Choose a set of timings derived from S3C@2442B MCP54
+  * data sheet (K5D2G13ACM-D075 MCP Memory).
+  */
+ static struct s3c2410_platform_nand __initdata gta02_nand_info = {
+       .tacls          = 0,
+       .twrph0         = 25,
+       .twrph1         = 15,
+       .nr_sets        = ARRAY_SIZE(gta02_nand_sets),
+       .sets           = gta02_nand_sets,
+ };
+ /* Get PMU to set USB current limit accordingly. */
+ static struct s3c2410_udc_mach_info gta02_udc_cfg __initdata = {
+       .vbus_draw      = gta02_udc_vbus_draw,
+       .pullup_pin = GTA02_GPIO_USB_PULLUP,
+ };
+ /* USB */
+ static struct s3c2410_hcd_info gta02_usb_info __initdata = {
+       .port[0]        = {
+               .flags  = S3C_HCDFLG_USED,
+       },
+       .port[1]        = {
+               .flags  = 0,
+       },
+ };
+ /* Touchscreen */
+ static struct s3c2410_ts_mach_info gta02_ts_info = {
+       .delay                  = 10000,
+       .presc                  = 0xff, /* slow as we can go */
+       .oversampling_shift     = 2,
+ };
+ /* Buttons */
+ static struct gpio_keys_button gta02_buttons[] = {
+       {
+               .gpio = GTA02_GPIO_AUX_KEY,
+               .code = KEY_PHONE,
+               .desc = "Aux",
+               .type = EV_KEY,
+               .debounce_interval = 100,
+       },
+       {
+               .gpio = GTA02_GPIO_HOLD_KEY,
+               .code = KEY_PAUSE,
+               .desc = "Hold",
+               .type = EV_KEY,
+               .debounce_interval = 100,
+       },
+ };
+ static struct gpio_keys_platform_data gta02_buttons_pdata = {
+       .buttons = gta02_buttons,
+       .nbuttons = ARRAY_SIZE(gta02_buttons),
+ };
+ static struct platform_device gta02_buttons_device = {
+       .name = "gpio-keys",
+       .id = -1,
+       .dev = {
+               .platform_data = &gta02_buttons_pdata,
+       },
+ };
+ static void __init gta02_map_io(void)
+ {
+       s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+ }
+ /* These are the guys that don't need to be children of PMU. */
+ static struct platform_device *gta02_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_sdi,
+       &s3c_device_usbgadget,
+       &s3c_device_nand,
+       &gta02_nor_flash,
+       &s3c24xx_pwm_device,
+       &s3c_device_iis,
+       &samsung_asoc_dma,
+       &s3c_device_i2c0,
+       &gta02_dfbmcs320_device,
+       &gta02_buttons_device,
+       &s3c_device_adc,
+       &s3c_device_ts,
+ };
+ /* These guys DO need to be children of PMU. */
+ static struct platform_device *gta02_devices_pmu_children[] = {
+ };
+ /*
+  * This is called when pc50633 is probed, quite late in the day since it is an
+  * I2C bus device.  Here we can define platform devices with the advantage that
+  * we can mark the pcf50633 as the parent.  This makes them get suspended and
+  * resumed with their parent the pcf50633 still around.  All devices whose
+  * operation depends on something from pcf50633 must have this relationship
+  * made explicit like this, or suspend and resume will become an unreliable
+  * hellworld.
+  */
+ static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
+ {
+       int n;
+       /* Grab a copy of the now probed PMU pointer. */
+       gta02_pcf = pcf;
+       for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
+               gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
+       platform_add_devices(gta02_devices_pmu_children,
+                            ARRAY_SIZE(gta02_devices_pmu_children));
+ }
+ static void gta02_poweroff(void)
+ {
+       pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
+ }
+ static void __init gta02_machine_init(void)
+ {
+       /* Set the panic callback to turn AUX LED on or off. */
+       panic_blink = gta02_panic_blink;
+       s3c_pm_init();
+ #ifdef CONFIG_CHARGER_PCF50633
+       INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
+ #endif
+       s3c24xx_udc_set_platdata(&gta02_udc_cfg);
+       s3c24xx_ts_set_platdata(&gta02_ts_info);
+       s3c_ohci_set_platdata(&gta02_usb_info);
+       s3c_nand_set_platdata(&gta02_nand_info);
+       s3c_i2c0_set_platdata(NULL);
+       i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+       platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
+       pm_power_off = gta02_poweroff;
+       regulator_has_full_constraints();
+ }
+ MACHINE_START(NEO1973_GTA02, "GTA02")
+       /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+       .atag_offset    = 0x100,
+       .map_io         = gta02_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = gta02_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2440_restart,
+ MACHINE_END
index 0000000,41245a6..6b21ba1
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,757 +1,757 @@@
 -struct gpio_chip h1940_latch_gpiochip = {
+ /* linux/arch/arm/mach-s3c2410/mach-h1940.c
+  *
+  * Copyright (c) 2003-2005 Simtec Electronics
+  *   Ben Dooks <ben@simtec.co.uk>
+  *
+  * http://www.handhelds.org/projects/h1940.html
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+ */
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+ #include <linux/memblock.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/serial_core.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <linux/gpio.h>
+ #include <linux/input.h>
+ #include <linux/gpio_keys.h>
+ #include <linux/pwm_backlight.h>
+ #include <linux/i2c.h>
+ #include <linux/leds.h>
+ #include <linux/pda_power.h>
+ #include <linux/s3c_adc_battery.h>
+ #include <linux/delay.h>
+ #include <video/platform_lcd.h>
+ #include <linux/mmc/host.h>
+ #include <linux/export.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach-types.h>
+ #include <plat/regs-serial.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-clock.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/gpio-fns.h>
+ #include <mach/gpio-nrs.h>
+ #include <mach/h1940.h>
+ #include <mach/h1940-latch.h>
+ #include <mach/fb.h>
+ #include <plat/udc.h>
+ #include <plat/iic.h>
+ #include <plat/gpio-cfg.h>
+ #include <plat/clock.h>
+ #include <plat/devs.h>
+ #include <plat/cpu.h>
+ #include <plat/pll.h>
+ #include <plat/pm.h>
+ #include <plat/mci.h>
+ #include <plat/ts.h>
+ #include <sound/uda1380.h>
+ #include "common.h"
+ #define H1940_LATCH           ((void __force __iomem *)0xF8000000)
+ #define H1940_PA_LATCH                S3C2410_CS2
+ #define H1940_LATCH_BIT(x)    (1 << ((x) + 16 - S3C_GPIO_END))
+ static struct map_desc h1940_iodesc[] __initdata = {
+       [0] = {
+               .virtual        = (unsigned long)H1940_LATCH,
+               .pfn            = __phys_to_pfn(H1940_PA_LATCH),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE
+       },
+ };
+ #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+ #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+ #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+ static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x245,
+               .ulcon       = 0x03,
+               .ufcon       = 0x00,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .uart_flags  = UPF_CONS_FLOW,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+ };
+ /* Board control latch control */
+ static unsigned int latch_state;
+ static void h1940_latch_control(unsigned int clear, unsigned int set)
+ {
+       unsigned long flags;
+       local_irq_save(flags);
+       latch_state &= ~clear;
+       latch_state |= set;
+       __raw_writel(latch_state, H1940_LATCH);
+       local_irq_restore(flags);
+ }
+ static inline int h1940_gpiolib_to_latch(int offset)
+ {
+       return 1 << (offset + 16);
+ }
+ static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+ {
+       int latch_bit = h1940_gpiolib_to_latch(offset);
+       h1940_latch_control(value ? 0 : latch_bit,
+               value ? latch_bit : 0);
+ }
+ static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+ {
+       h1940_gpiolib_latch_set(chip, offset, value);
+       return 0;
+ }
+ static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
+                                       unsigned offset)
+ {
+       return (latch_state >> (offset + 16)) & 1;
+ }
 -int h1940_bat_init(void)
++static struct gpio_chip h1940_latch_gpiochip = {
+       .base                   = H1940_LATCH_GPIO(0),
+       .owner                  = THIS_MODULE,
+       .label                  = "H1940_LATCH",
+       .ngpio                  = 16,
+       .direction_output       = h1940_gpiolib_latch_output,
+       .set                    = h1940_gpiolib_latch_set,
+       .get                    = h1940_gpiolib_latch_get,
+ };
+ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
+       .vbus_pin               = S3C2410_GPG(5),
+       .vbus_pin_inverted      = 1,
+       .pullup_pin             = H1940_LATCH_USB_DP,
+ };
+ static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
+               .delay = 10000,
+               .presc = 49,
+               .oversampling_shift = 2,
+               .cfg_gpio = s3c24xx_ts_cfg_gpio,
+ };
+ /**
+  * Set lcd on or off
+  **/
+ static struct s3c2410fb_display h1940_lcd __initdata = {
+       .lcdcon5=       S3C2410_LCDCON5_FRM565 | \
+                       S3C2410_LCDCON5_INVVLINE | \
+                       S3C2410_LCDCON5_HWSWP,
+       .type =         S3C2410_LCDCON1_TFT,
+       .width =        240,
+       .height =       320,
+       .pixclock =     260000,
+       .xres =         240,
+       .yres =         320,
+       .bpp =          16,
+       .left_margin =  8,
+       .right_margin = 20,
+       .hsync_len =    4,
+       .upper_margin = 8,
+       .lower_margin = 7,
+       .vsync_len =    1,
+ };
+ static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
+       .displays = &h1940_lcd,
+       .num_displays = 1,
+       .default_display = 0,
+       .lpcsel =       0x02,
+       .gpccon =       0xaa940659,
+       .gpccon_mask =  0xffffc0f0,
+       .gpcup =        0x0000ffff,
+       .gpcup_mask =   0xffffffff,
+       .gpdcon =       0xaa84aaa0,
+       .gpdcon_mask =  0xffffffff,
+       .gpdup =        0x0000faff,
+       .gpdup_mask =   0xffffffff,
+ };
+ static int power_supply_init(struct device *dev)
+ {
+       return gpio_request(S3C2410_GPF(2), "cable plugged");
+ }
+ static int h1940_is_ac_online(void)
+ {
+       return !gpio_get_value(S3C2410_GPF(2));
+ }
+ static void power_supply_exit(struct device *dev)
+ {
+       gpio_free(S3C2410_GPF(2));
+ }
+ static char *h1940_supplicants[] = {
+       "main-battery",
+       "backup-battery",
+ };
+ static struct pda_power_pdata power_supply_info = {
+       .init                   = power_supply_init,
+       .is_ac_online           = h1940_is_ac_online,
+       .exit                   = power_supply_exit,
+       .supplied_to            = h1940_supplicants,
+       .num_supplicants        = ARRAY_SIZE(h1940_supplicants),
+ };
+ static struct resource power_supply_resources[] = {
+       [0] = {
+                       .name   = "ac",
+                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+                                         IORESOURCE_IRQ_HIGHEDGE,
+                       .start  = IRQ_EINT2,
+                       .end    = IRQ_EINT2,
+       },
+ };
+ static struct platform_device power_supply = {
+       .name           = "pda-power",
+       .id             = -1,
+       .dev            = {
+                               .platform_data =
+                                       &power_supply_info,
+       },
+       .resource       = power_supply_resources,
+       .num_resources  = ARRAY_SIZE(power_supply_resources),
+ };
+ static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+       { .volt = 4070, .cur = 162, .level = 100},
+       { .volt = 4040, .cur = 165, .level = 95},
+       { .volt = 4016, .cur = 164, .level = 90},
+       { .volt = 3996, .cur = 166, .level = 85},
+       { .volt = 3971, .cur = 168, .level = 80},
+       { .volt = 3951, .cur = 168, .level = 75},
+       { .volt = 3931, .cur = 170, .level = 70},
+       { .volt = 3903, .cur = 172, .level = 65},
+       { .volt = 3886, .cur = 172, .level = 60},
+       { .volt = 3858, .cur = 176, .level = 55},
+       { .volt = 3842, .cur = 176, .level = 50},
+       { .volt = 3818, .cur = 176, .level = 45},
+       { .volt = 3789, .cur = 180, .level = 40},
+       { .volt = 3769, .cur = 180, .level = 35},
+       { .volt = 3749, .cur = 184, .level = 30},
+       { .volt = 3732, .cur = 184, .level = 25},
+       { .volt = 3716, .cur = 184, .level = 20},
+       { .volt = 3708, .cur = 184, .level = 15},
+       { .volt = 3716, .cur = 96, .level = 10},
+       { .volt = 3700, .cur = 96, .level = 5},
+       { .volt = 3684, .cur = 96, .level = 0},
+ };
+ static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+       { .volt = 4130, .cur = 0, .level = 100},
+       { .volt = 3982, .cur = 0, .level = 50},
+       { .volt = 3854, .cur = 0, .level = 10},
+       { .volt = 3841, .cur = 0, .level = 0},
+ };
 -void h1940_bat_exit(void)
++static int h1940_bat_init(void)
+ {
+       int ret;
+       ret = gpio_request(H1940_LATCH_SM803_ENABLE, "h1940-charger-enable");
+       if (ret)
+               return ret;
+       gpio_direction_output(H1940_LATCH_SM803_ENABLE, 0);
+       return 0;
+ }
 -void h1940_enable_charger(void)
++static void h1940_bat_exit(void)
+ {
+       gpio_free(H1940_LATCH_SM803_ENABLE);
+ }
 -void h1940_disable_charger(void)
++static void h1940_enable_charger(void)
+ {
+       gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
+ }
 -DEFINE_SPINLOCK(h1940_blink_spin);
++static void h1940_disable_charger(void)
+ {
+       gpio_set_value(H1940_LATCH_SM803_ENABLE, 0);
+ }
+ static struct s3c_adc_bat_pdata h1940_bat_cfg = {
+       .init = h1940_bat_init,
+       .exit = h1940_bat_exit,
+       .enable_charger = h1940_enable_charger,
+       .disable_charger = h1940_disable_charger,
+       .gpio_charge_finished = S3C2410_GPF(3),
+       .gpio_inverted = 1,
+       .lut_noac = bat_lut_noac,
+       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+       .lut_acin = bat_lut_acin,
+       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+       .volt_channel = 0,
+       .current_channel = 1,
+       .volt_mult = 4056,
+       .current_mult = 1893,
+       .internal_impedance = 200,
+       .backup_volt_channel = 3,
+       /* TODO Check backup volt multiplier */
+       .backup_volt_mult = 4056,
+       .backup_volt_min = 0,
+       .backup_volt_max = 4149288
+ };
+ static struct platform_device h1940_battery = {
+       .name             = "s3c-adc-battery",
+       .id               = -1,
+       .dev = {
+               .parent = &s3c_device_adc.dev,
+               .platform_data = &h1940_bat_cfg,
+       },
+ };
++static DEFINE_SPINLOCK(h1940_blink_spin);
+ int h1940_led_blink_set(unsigned gpio, int state,
+       unsigned long *delay_on, unsigned long *delay_off)
+ {
+       int blink_gpio, check_gpio1, check_gpio2;
+       switch (gpio) {
+       case H1940_LATCH_LED_GREEN:
+               blink_gpio = S3C2410_GPA(7);
+               check_gpio1 = S3C2410_GPA(1);
+               check_gpio2 = S3C2410_GPA(3);
+               break;
+       case H1940_LATCH_LED_RED:
+               blink_gpio = S3C2410_GPA(1);
+               check_gpio1 = S3C2410_GPA(7);
+               check_gpio2 = S3C2410_GPA(3);
+               break;
+       default:
+               blink_gpio = S3C2410_GPA(3);
+               check_gpio1 = S3C2410_GPA(1);
+               check_gpio1 = S3C2410_GPA(7);
+               break;
+       }
+       if (delay_on && delay_off && !*delay_on && !*delay_off)
+               *delay_on = *delay_off = 500;
+       spin_lock(&h1940_blink_spin);
+       switch (state) {
+       case GPIO_LED_NO_BLINK_LOW:
+       case GPIO_LED_NO_BLINK_HIGH:
+               if (!gpio_get_value(check_gpio1) &&
+                   !gpio_get_value(check_gpio2))
+                       gpio_set_value(H1940_LATCH_LED_FLASH, 0);
+               gpio_set_value(blink_gpio, 0);
+               if (gpio_is_valid(gpio))
+                       gpio_set_value(gpio, state);
+               break;
+       case GPIO_LED_BLINK:
+               if (gpio_is_valid(gpio))
+                       gpio_set_value(gpio, 0);
+               gpio_set_value(H1940_LATCH_LED_FLASH, 1);
+               gpio_set_value(blink_gpio, 1);
+               break;
+       }
+       spin_unlock(&h1940_blink_spin);
+       return 0;
+ }
+ EXPORT_SYMBOL(h1940_led_blink_set);
+ static struct gpio_led h1940_leds_desc[] = {
+       {
+               .name                   = "Green",
+               .default_trigger        = "main-battery-full",
+               .gpio                   = H1940_LATCH_LED_GREEN,
+               .retain_state_suspended = 1,
+       },
+       {
+               .name                   = "Red",
+               .default_trigger
+                       = "main-battery-charging-blink-full-solid",
+               .gpio                   = H1940_LATCH_LED_RED,
+               .retain_state_suspended = 1,
+       },
+ };
+ static struct gpio_led_platform_data h1940_leds_pdata = {
+       .num_leds       = ARRAY_SIZE(h1940_leds_desc),
+       .leds           = h1940_leds_desc,
+       .gpio_blink_set = h1940_led_blink_set,
+ };
+ static struct platform_device h1940_device_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+                       .platform_data = &h1940_leds_pdata,
+       },
+ };
+ static struct platform_device h1940_device_bluetooth = {
+       .name             = "h1940-bt",
+       .id               = -1,
+ };
+ static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+ {
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_set_value(H1940_LATCH_SD_POWER, 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_set_value(H1940_LATCH_SD_POWER, 1);
+               break;
+       default:
+               break;
+       };
+ }
+ static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
+       .gpio_detect   = S3C2410_GPF(5),
+       .gpio_wprotect = S3C2410_GPH(8),
+       .set_power     = h1940_set_mmc_power,
+       .ocr_avail     = MMC_VDD_32_33,
+ };
+ static int h1940_backlight_init(struct device *dev)
+ {
+       gpio_request(S3C2410_GPB(0), "Backlight");
+       gpio_direction_output(S3C2410_GPB(0), 0);
+       s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+       return 0;
+ }
+ static int h1940_backlight_notify(struct device *dev, int brightness)
+ {
+       if (!brightness) {
+               gpio_direction_output(S3C2410_GPB(0), 1);
+               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+       } else {
+               gpio_direction_output(S3C2410_GPB(0), 0);
+               s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+       }
+       return brightness;
+ }
+ static void h1940_backlight_exit(struct device *dev)
+ {
+       gpio_direction_output(S3C2410_GPB(0), 1);
+       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+ }
+ static struct platform_pwm_backlight_data backlight_data = {
+       .pwm_id         = 0,
+       .max_brightness = 100,
+       .dft_brightness = 50,
+       /* tcnt = 0x31 */
+       .pwm_period_ns  = 36296,
+       .init           = h1940_backlight_init,
+       .notify         = h1940_backlight_notify,
+       .exit           = h1940_backlight_exit,
+ };
+ static struct platform_device h1940_backlight = {
+       .name = "pwm-backlight",
+       .dev  = {
+               .parent = &s3c_device_timer[0].dev,
+               .platform_data = &backlight_data,
+       },
+       .id   = -1,
+ };
+ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
+                                       unsigned int power)
+ {
+       int value, retries = 100;
+       if (!power) {
+               gpio_set_value(S3C2410_GPC(0), 0);
+               /* wait for 3ac */
+               do {
+                       value = gpio_get_value(S3C2410_GPC(6));
+               } while (value && retries--);
+               gpio_set_value(H1940_LATCH_LCD_P2, 0);
+               gpio_set_value(H1940_LATCH_LCD_P3, 0);
+               gpio_set_value(H1940_LATCH_LCD_P4, 0);
+               gpio_direction_output(S3C2410_GPC(1), 0);
+               gpio_direction_output(S3C2410_GPC(4), 0);
+               gpio_set_value(H1940_LATCH_LCD_P1, 0);
+               gpio_set_value(H1940_LATCH_LCD_P0, 0);
+               gpio_set_value(S3C2410_GPC(5), 0);
+       } else {
+               gpio_set_value(H1940_LATCH_LCD_P0, 1);
+               gpio_set_value(H1940_LATCH_LCD_P1, 1);
+               gpio_direction_input(S3C2410_GPC(1));
+               gpio_direction_input(S3C2410_GPC(4));
+               mdelay(10);
+               s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
+               gpio_set_value(S3C2410_GPC(5), 1);
+               gpio_set_value(S3C2410_GPC(0), 1);
+               gpio_set_value(H1940_LATCH_LCD_P3, 1);
+               gpio_set_value(H1940_LATCH_LCD_P2, 1);
+               gpio_set_value(H1940_LATCH_LCD_P4, 1);
+       }
+ }
+ static struct plat_lcd_data h1940_lcd_power_data = {
+       .set_power      = h1940_lcd_power_set,
+ };
+ static struct platform_device h1940_lcd_powerdev = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s3c_device_lcd.dev,
+       .dev.platform_data      = &h1940_lcd_power_data,
+ };
+ static struct uda1380_platform_data uda1380_info = {
+       .gpio_power     = H1940_LATCH_UDA_POWER,
+       .gpio_reset     = S3C2410_GPA(12),
+       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
+ };
+ static struct i2c_board_info h1940_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("uda1380", 0x1a),
+               .platform_data = &uda1380_info,
+       },
+ };
+ #define DECLARE_BUTTON(p, k, n, w)    \
+       {                               \
+               .gpio           = p,    \
+               .code           = k,    \
+               .desc           = n,    \
+               .wakeup         = w,    \
+               .active_low     = 1,    \
+       }
+ static struct gpio_keys_button h1940_buttons[] = {
+       DECLARE_BUTTON(S3C2410_GPF(0),       KEY_POWER,          "Power", 1),
+       DECLARE_BUTTON(S3C2410_GPF(6),       KEY_ENTER,         "Select", 1),
+       DECLARE_BUTTON(S3C2410_GPF(7),      KEY_RECORD,         "Record", 0),
+       DECLARE_BUTTON(S3C2410_GPG(0),         KEY_F11,       "Calendar", 0),
+       DECLARE_BUTTON(S3C2410_GPG(2),         KEY_F12,       "Contacts", 0),
+       DECLARE_BUTTON(S3C2410_GPG(3),        KEY_MAIL,           "Mail", 0),
+       DECLARE_BUTTON(S3C2410_GPG(6),        KEY_LEFT,     "Left_arrow", 0),
+       DECLARE_BUTTON(S3C2410_GPG(7),    KEY_HOMEPAGE,           "Home", 0),
+       DECLARE_BUTTON(S3C2410_GPG(8),       KEY_RIGHT,    "Right_arrow", 0),
+       DECLARE_BUTTON(S3C2410_GPG(9),          KEY_UP,       "Up_arrow", 0),
+       DECLARE_BUTTON(S3C2410_GPG(10),       KEY_DOWN,     "Down_arrow", 0),
+ };
+ static struct gpio_keys_platform_data h1940_buttons_data = {
+       .buttons        = h1940_buttons,
+       .nbuttons       = ARRAY_SIZE(h1940_buttons),
+ };
+ static struct platform_device h1940_dev_buttons = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &h1940_buttons_data,
+       }
+ };
+ static struct platform_device *h1940_devices[] __initdata = {
+       &h1940_dev_buttons,
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &samsung_asoc_dma,
+       &s3c_device_usbgadget,
+       &h1940_device_leds,
+       &h1940_device_bluetooth,
+       &s3c_device_sdi,
+       &s3c_device_rtc,
+       &s3c_device_timer[0],
+       &h1940_backlight,
+       &h1940_lcd_powerdev,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &power_supply,
+       &h1940_battery,
+ };
+ static void __init h1940_map_io(void)
+ {
+       s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+       /* setup PM */
+ #ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+ #endif
+       s3c_pm_init();
+       /* Add latch gpio chip, set latch initial value */
+       h1940_latch_control(0, 0);
+       WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
+ }
+ /* H1940 and RX3715 need to reserve this for suspend */
+ static void __init h1940_reserve(void)
+ {
+       memblock_reserve(0x30003000, 0x1000);
+       memblock_reserve(0x30081000, 0x1000);
+ }
+ static void __init h1940_init_irq(void)
+ {
+       s3c24xx_init_irq();
+ }
+ static void __init h1940_init(void)
+ {
+       u32 tmp;
+       s3c24xx_fb_set_platdata(&h1940_fb_info);
+       s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
+       s3c24xx_udc_set_platdata(&h1940_udc_cfg);
+       s3c24xx_ts_set_platdata(&h1940_ts_cfg);
+       s3c_i2c0_set_platdata(NULL);
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+       tmp =   (0x78 << S3C24XX_PLL_MDIV_SHIFT)
+             | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
+             | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
+       writel(tmp, S3C2410_UPLLCON);
+       gpio_request(S3C2410_GPC(0), "LCD power");
+       gpio_request(S3C2410_GPC(1), "LCD power");
+       gpio_request(S3C2410_GPC(4), "LCD power");
+       gpio_request(S3C2410_GPC(5), "LCD power");
+       gpio_request(S3C2410_GPC(6), "LCD power");
+       gpio_request(H1940_LATCH_LCD_P0, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P1, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P2, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P3, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P4, "LCD power");
+       gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
+       gpio_direction_output(S3C2410_GPC(0), 0);
+       gpio_direction_output(S3C2410_GPC(1), 0);
+       gpio_direction_output(S3C2410_GPC(4), 0);
+       gpio_direction_output(S3C2410_GPC(5), 0);
+       gpio_direction_input(S3C2410_GPC(6));
+       gpio_direction_output(H1940_LATCH_LCD_P0, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P1, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P2, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P3, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P4, 0);
+       gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+       gpio_request(H1940_LATCH_SD_POWER, "SD power");
+       gpio_direction_output(H1940_LATCH_SD_POWER, 0);
+       platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
+       gpio_request(S3C2410_GPA(1), "Red LED blink");
+       gpio_request(S3C2410_GPA(3), "Blue LED blink");
+       gpio_request(S3C2410_GPA(7), "Green LED blink");
+       gpio_request(H1940_LATCH_LED_FLASH, "LED blink");
+       gpio_direction_output(S3C2410_GPA(1), 0);
+       gpio_direction_output(S3C2410_GPA(3), 0);
+       gpio_direction_output(S3C2410_GPA(7), 0);
+       gpio_direction_output(H1940_LATCH_LED_FLASH, 0);
+       i2c_register_board_info(0, h1940_i2c_devices,
+               ARRAY_SIZE(h1940_i2c_devices));
+ }
+ MACHINE_START(H1940, "IPAQ-H1940")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+       .map_io         = h1940_map_io,
+       .reserve        = h1940_reserve,
+       .init_irq       = h1940_init_irq,
+       .init_machine   = h1940_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+ MACHINE_END
index 0000000,80077f6..4a8e2d3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,826 +1,826 @@@
 -int rx1950_bat_init(void)
+ /* linux/arch/arm/mach-s3c2440/mach-rx1950.c
+  *
+  * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
+  * Copyright (c) 2007-2010 Vasily Khoruzhick
+  *
+  * based on smdk2440 written by Ben Dooks
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+ */
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+ #include <linux/memblock.h>
+ #include <linux/delay.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/gpio.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_core.h>
+ #include <linux/input.h>
+ #include <linux/gpio_keys.h>
+ #include <linux/device.h>
+ #include <linux/pda_power.h>
+ #include <linux/pwm_backlight.h>
+ #include <linux/pwm.h>
+ #include <linux/s3c_adc_battery.h>
+ #include <linux/leds.h>
+ #include <linux/i2c.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/mmc/host.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach-types.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/regs-gpioj.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/h1940.h>
+ #include <mach/fb.h>
+ #include <plat/clock.h>
+ #include <plat/regs-serial.h>
+ #include <plat/regs-iic.h>
+ #include <plat/mci.h>
+ #include <plat/udc.h>
+ #include <plat/nand.h>
+ #include <plat/iic.h>
+ #include <plat/devs.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/irq.h>
+ #include <plat/ts.h>
+ #include <sound/uda1380.h>
+ #include "common.h"
+ #define LCD_PWM_PERIOD 192960
+ #define LCD_PWM_DUTY 127353
+ static struct map_desc rx1950_iodesc[] __initdata = {
+ };
+ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
+       [0] = {
+              .hwport = 0,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+               .clk_sel = S3C2410_UCON_CLKSEL3,
+       },
+       [1] = {
+              .hwport = 1,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+               .clk_sel = S3C2410_UCON_CLKSEL3,
+       },
+       /* IR port */
+       [2] = {
+              .hwport = 2,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x43,
+              .ufcon = 0xf1,
+               .clk_sel = S3C2410_UCON_CLKSEL3,
+       },
+ };
+ static struct s3c2410fb_display rx1950_display = {
+       .type = S3C2410_LCDCON1_TFT,
+       .width = 240,
+       .height = 320,
+       .xres = 240,
+       .yres = 320,
+       .bpp = 16,
+       .pixclock = 260000,
+       .left_margin = 10,
+       .right_margin = 20,
+       .hsync_len = 10,
+       .upper_margin = 2,
+       .lower_margin = 2,
+       .vsync_len = 2,
+       .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVCLK |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_HWSWP |
+                          (0x02 << 13) |
+                          (0x02 << 15),
+ };
+ static int power_supply_init(struct device *dev)
+ {
+       return gpio_request(S3C2410_GPF(2), "cable plugged");
+ }
+ static int rx1950_is_ac_online(void)
+ {
+       return !gpio_get_value(S3C2410_GPF(2));
+ }
+ static void power_supply_exit(struct device *dev)
+ {
+       gpio_free(S3C2410_GPF(2));
+ }
+ static char *rx1950_supplicants[] = {
+       "main-battery"
+ };
+ static struct pda_power_pdata power_supply_info = {
+       .init                   = power_supply_init,
+       .is_ac_online           = rx1950_is_ac_online,
+       .exit                   = power_supply_exit,
+       .supplied_to            = rx1950_supplicants,
+       .num_supplicants        = ARRAY_SIZE(rx1950_supplicants),
+ };
+ static struct resource power_supply_resources[] = {
+       [0] = {
+                       .name   = "ac",
+                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+                                         IORESOURCE_IRQ_HIGHEDGE,
+                       .start  = IRQ_EINT2,
+                       .end    = IRQ_EINT2,
+       },
+ };
+ static struct platform_device power_supply = {
+       .name                   = "pda-power",
+       .id                     = -1,
+       .dev                    = {
+                                       .platform_data =
+                                               &power_supply_info,
+       },
+       .resource               = power_supply_resources,
+       .num_resources          = ARRAY_SIZE(power_supply_resources),
+ };
+ static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+       { .volt = 4100, .cur = 156, .level = 100},
+       { .volt = 4050, .cur = 156, .level = 95},
+       { .volt = 4025, .cur = 141, .level = 90},
+       { .volt = 3995, .cur = 144, .level = 85},
+       { .volt = 3957, .cur = 162, .level = 80},
+       { .volt = 3931, .cur = 147, .level = 75},
+       { .volt = 3902, .cur = 147, .level = 70},
+       { .volt = 3863, .cur = 153, .level = 65},
+       { .volt = 3838, .cur = 150, .level = 60},
+       { .volt = 3800, .cur = 153, .level = 55},
+       { .volt = 3765, .cur = 153, .level = 50},
+       { .volt = 3748, .cur = 172, .level = 45},
+       { .volt = 3740, .cur = 153, .level = 40},
+       { .volt = 3714, .cur = 175, .level = 35},
+       { .volt = 3710, .cur = 156, .level = 30},
+       { .volt = 3963, .cur = 156, .level = 25},
+       { .volt = 3672, .cur = 178, .level = 20},
+       { .volt = 3651, .cur = 178, .level = 15},
+       { .volt = 3629, .cur = 178, .level = 10},
+       { .volt = 3612, .cur = 162, .level = 5},
+       { .volt = 3605, .cur = 162, .level = 0},
+ };
+ static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+       { .volt = 4200, .cur = 0, .level = 100},
+       { .volt = 4190, .cur = 0, .level = 99},
+       { .volt = 4178, .cur = 0, .level = 95},
+       { .volt = 4110, .cur = 0, .level = 70},
+       { .volt = 4076, .cur = 0, .level = 65},
+       { .volt = 4046, .cur = 0, .level = 60},
+       { .volt = 4021, .cur = 0, .level = 55},
+       { .volt = 3999, .cur = 0, .level = 50},
+       { .volt = 3982, .cur = 0, .level = 45},
+       { .volt = 3965, .cur = 0, .level = 40},
+       { .volt = 3957, .cur = 0, .level = 35},
+       { .volt = 3948, .cur = 0, .level = 30},
+       { .volt = 3936, .cur = 0, .level = 25},
+       { .volt = 3927, .cur = 0, .level = 20},
+       { .volt = 3906, .cur = 0, .level = 15},
+       { .volt = 3880, .cur = 0, .level = 10},
+       { .volt = 3829, .cur = 0, .level = 5},
+       { .volt = 3820, .cur = 0, .level = 0},
+ };
 -void rx1950_bat_exit(void)
++static int rx1950_bat_init(void)
+ {
+       int ret;
+       ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
+       if (ret)
+               goto err_gpio1;
+       ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
+       if (ret)
+               goto err_gpio2;
+       return 0;
+ err_gpio2:
+       gpio_free(S3C2410_GPJ(2));
+ err_gpio1:
+       return ret;
+ }
 -void rx1950_enable_charger(void)
++static void rx1950_bat_exit(void)
+ {
+       gpio_free(S3C2410_GPJ(2));
+       gpio_free(S3C2410_GPJ(3));
+ }
 -void rx1950_disable_charger(void)
++static void rx1950_enable_charger(void)
+ {
+       gpio_direction_output(S3C2410_GPJ(2), 1);
+       gpio_direction_output(S3C2410_GPJ(3), 1);
+ }
 -DEFINE_SPINLOCK(rx1950_blink_spin);
++static void rx1950_disable_charger(void)
+ {
+       gpio_direction_output(S3C2410_GPJ(2), 0);
+       gpio_direction_output(S3C2410_GPJ(3), 0);
+ }
 -void rx1950_lcd_power(int enable)
++static DEFINE_SPINLOCK(rx1950_blink_spin);
+ static int rx1950_led_blink_set(unsigned gpio, int state,
+       unsigned long *delay_on, unsigned long *delay_off)
+ {
+       int blink_gpio, check_gpio;
+       switch (gpio) {
+       case S3C2410_GPA(6):
+               blink_gpio = S3C2410_GPA(4);
+               check_gpio = S3C2410_GPA(3);
+               break;
+       case S3C2410_GPA(7):
+               blink_gpio = S3C2410_GPA(3);
+               check_gpio = S3C2410_GPA(4);
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+       if (delay_on && delay_off && !*delay_on && !*delay_off)
+               *delay_on = *delay_off = 500;
+       spin_lock(&rx1950_blink_spin);
+       switch (state) {
+       case GPIO_LED_NO_BLINK_LOW:
+       case GPIO_LED_NO_BLINK_HIGH:
+               if (!gpio_get_value(check_gpio))
+                       gpio_set_value(S3C2410_GPJ(6), 0);
+               gpio_set_value(blink_gpio, 0);
+               gpio_set_value(gpio, state);
+               break;
+       case GPIO_LED_BLINK:
+               gpio_set_value(gpio, 0);
+               gpio_set_value(S3C2410_GPJ(6), 1);
+               gpio_set_value(blink_gpio, 1);
+               break;
+       }
+       spin_unlock(&rx1950_blink_spin);
+       return 0;
+ }
+ static struct gpio_led rx1950_leds_desc[] = {
+       {
+               .name                   = "Green",
+               .default_trigger        = "main-battery-full",
+               .gpio                   = S3C2410_GPA(6),
+               .retain_state_suspended = 1,
+       },
+       {
+               .name                   = "Red",
+               .default_trigger
+                       = "main-battery-charging-blink-full-solid",
+               .gpio                   = S3C2410_GPA(7),
+               .retain_state_suspended = 1,
+       },
+       {
+               .name                   = "Blue",
+               .default_trigger        = "rx1950-acx-mem",
+               .gpio                   = S3C2410_GPA(11),
+               .retain_state_suspended = 1,
+       },
+ };
+ static struct gpio_led_platform_data rx1950_leds_pdata = {
+       .num_leds       = ARRAY_SIZE(rx1950_leds_desc),
+       .leds           = rx1950_leds_desc,
+       .gpio_blink_set = rx1950_led_blink_set,
+ };
+ static struct platform_device rx1950_leds = {
+       .name   = "leds-gpio",
+       .id             = -1,
+       .dev    = {
+                               .platform_data = &rx1950_leds_pdata,
+       },
+ };
+ static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
+       .init = rx1950_bat_init,
+       .exit = rx1950_bat_exit,
+       .enable_charger = rx1950_enable_charger,
+       .disable_charger = rx1950_disable_charger,
+       .gpio_charge_finished = S3C2410_GPF(3),
+       .lut_noac = bat_lut_noac,
+       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+       .lut_acin = bat_lut_acin,
+       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+       .volt_channel = 0,
+       .current_channel = 1,
+       .volt_mult = 4235,
+       .current_mult = 2900,
+       .internal_impedance = 200,
+ };
+ static struct platform_device rx1950_battery = {
+       .name             = "s3c-adc-battery",
+       .id               = -1,
+       .dev = {
+               .parent = &s3c_device_adc.dev,
+               .platform_data = &rx1950_bat_cfg,
+       },
+ };
+ static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
+       .displays = &rx1950_display,
+       .num_displays = 1,
+       .default_display = 0,
+       .lpcsel = 0x02,
+       .gpccon = 0xaa9556a9,
+       .gpccon_mask = 0xffc003fc,
+       .gpcup = 0x0000ffff,
+       .gpcup_mask = 0xffffffff,
+       .gpdcon = 0xaa90aaa1,
+       .gpdcon_mask = 0xffc0fff0,
+       .gpdup = 0x0000fcfd,
+       .gpdup_mask = 0xffffffff,
+ };
+ static struct pwm_device *lcd_pwm;
++static void rx1950_lcd_power(int enable)
+ {
+       int i;
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+               /* GPC11-GPC15->OUTPUT */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 1);
+               /* Wait a bit here... */
+               mdelay(100);
+               /* GPD2-GPD7->OUTPUT */
+               /* GPD11-GPD15->OUTPUT */
+               /* GPD2-GPD7->1, GPD11-GPD15->1 */
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+               /* Wait a bit here...*/
+               mdelay(100);
+               /* GPB0->OUTPUT, GPB0->0 */
+               gpio_direction_output(S3C2410_GPB(0), 0);
+               /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
+               for (i = 1; i < 5; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+               /* GPC15-GPC11->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+               /* GPD15-GPD11->0, GPD2->GPD7->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+               /* GPC6->0, GPC7->0, GPC5->0 */
+               gpio_direction_output(S3C2410_GPC(6), 0);
+               gpio_direction_output(S3C2410_GPC(7), 0);
+               gpio_direction_output(S3C2410_GPC(5), 0);
+               /* GPB1->OUTPUT, GPB1->0 */
+               gpio_direction_output(S3C2410_GPB(1), 0);
+               pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
+               pwm_disable(lcd_pwm);
+               /* GPC0->0, GPC10->0 */
+               gpio_direction_output(S3C2410_GPC(0), 0);
+               gpio_direction_output(S3C2410_GPC(10), 0);
+       } else {
+               pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
+               pwm_enable(lcd_pwm);
+               gpio_direction_output(S3C2410_GPC(0), 1);
+               gpio_direction_output(S3C2410_GPC(5), 1);
+               s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
+               gpio_direction_output(S3C2410_GPC(7), 1);
+               for (i = 1; i < 5; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+               for (i = 2; i < 8; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+               gpio_direction_output(S3C2410_GPC(10), 1);
+               gpio_direction_output(S3C2410_GPC(6), 1);
+       }
+       enabled = enable;
+ }
+ static void rx1950_bl_power(int enable)
+ {
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+                       gpio_direction_output(S3C2410_GPB(0), 0);
+       } else {
+                       /* LED driver need a "push" to power on */
+                       gpio_direction_output(S3C2410_GPB(0), 1);
+                       /* Warm up backlight for one period of PWM.
+                        * Without this trick its almost impossible to
+                        * enable backlight with low brightness value
+                        */
+                       ndelay(48000);
+                       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       }
+       enabled = enable;
+ }
+ static int rx1950_backlight_init(struct device *dev)
+ {
+       WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
+       lcd_pwm = pwm_request(1, "RX1950 LCD");
+       if (IS_ERR(lcd_pwm)) {
+               dev_err(dev, "Unable to request PWM for LCD power!\n");
+               return PTR_ERR(lcd_pwm);
+       }
+       rx1950_lcd_power(1);
+       rx1950_bl_power(1);
+       return 0;
+ }
+ static void rx1950_backlight_exit(struct device *dev)
+ {
+       rx1950_bl_power(0);
+       rx1950_lcd_power(0);
+       pwm_free(lcd_pwm);
+       gpio_free(S3C2410_GPB(0));
+ }
+ static int rx1950_backlight_notify(struct device *dev, int brightness)
+ {
+       if (!brightness) {
+               rx1950_bl_power(0);
+               rx1950_lcd_power(0);
+       } else {
+               rx1950_lcd_power(1);
+               rx1950_bl_power(1);
+       }
+       return brightness;
+ }
+ static struct platform_pwm_backlight_data rx1950_backlight_data = {
+       .pwm_id = 0,
+       .max_brightness = 24,
+       .dft_brightness = 4,
+       .pwm_period_ns = 48000,
+       .init = rx1950_backlight_init,
+       .notify = rx1950_backlight_notify,
+       .exit = rx1950_backlight_exit,
+ };
+ static struct platform_device rx1950_backlight = {
+       .name = "pwm-backlight",
+       .dev = {
+               .parent = &s3c_device_timer[0].dev,
+               .platform_data = &rx1950_backlight_data,
+       },
+ };
+ static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+ {
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_direction_output(S3C2410_GPJ(1), 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_direction_output(S3C2410_GPJ(1), 1);
+               break;
+       default:
+               break;
+       }
+ }
+ static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
+       .gpio_detect = S3C2410_GPF(5),
+       .gpio_wprotect = S3C2410_GPH(8),
+       .set_power = rx1950_set_mmc_power,
+       .ocr_avail = MMC_VDD_32_33,
+ };
+ static struct mtd_partition rx1950_nand_part[] = {
+       [0] = {
+                       .name = "Boot0",
+                       .offset = 0,
+                       .size = 0x4000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [1] = {
+                       .name = "Boot1",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x40000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [2] = {
+                       .name = "Kernel",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x300000,
+                       .mask_flags = 0,
+       },
+       [3] = {
+                       .name = "Filesystem",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = MTDPART_SIZ_FULL,
+                       .mask_flags = 0,
+       },
+ };
+ static struct s3c2410_nand_set rx1950_nand_sets[] = {
+       [0] = {
+                       .name = "Internal",
+                       .nr_chips = 1,
+                       .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
+                       .partitions = rx1950_nand_part,
+       },
+ };
+ static struct s3c2410_platform_nand rx1950_nand_info = {
+       .tacls = 25,
+       .twrph0 = 50,
+       .twrph1 = 15,
+       .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
+       .sets = rx1950_nand_sets,
+ };
+ static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
+       .vbus_pin = S3C2410_GPG(5),
+       .vbus_pin_inverted = 1,
+       .pullup_pin = S3C2410_GPJ(5),
+ };
+ static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
+       .delay = 10000,
+       .presc = 49,
+       .oversampling_shift = 3,
+ };
+ static struct gpio_keys_button rx1950_gpio_keys_table[] = {
+       {
+               .code           = KEY_POWER,
+               .gpio           = S3C2410_GPF(0),
+               .active_low     = 1,
+               .desc           = "Power button",
+               .wakeup         = 1,
+       },
+       {
+               .code           = KEY_F5,
+               .gpio           = S3C2410_GPF(7),
+               .active_low     = 1,
+               .desc           = "Record button",
+       },
+       {
+               .code           = KEY_F1,
+               .gpio           = S3C2410_GPG(0),
+               .active_low     = 1,
+               .desc           = "Calendar button",
+       },
+       {
+               .code           = KEY_F2,
+               .gpio           = S3C2410_GPG(2),
+               .active_low     = 1,
+               .desc           = "Contacts button",
+       },
+       {
+               .code           = KEY_F3,
+               .gpio           = S3C2410_GPG(3),
+               .active_low     = 1,
+               .desc           = "Mail button",
+       },
+       {
+               .code           = KEY_F4,
+               .gpio           = S3C2410_GPG(7),
+               .active_low     = 1,
+               .desc           = "WLAN button",
+       },
+       {
+               .code           = KEY_LEFT,
+               .gpio           = S3C2410_GPG(10),
+               .active_low     = 1,
+               .desc           = "Left button",
+       },
+       {
+               .code           = KEY_RIGHT,
+               .gpio           = S3C2410_GPG(11),
+               .active_low     = 1,
+               .desc           = "Right button",
+       },
+       {
+               .code           = KEY_UP,
+               .gpio           = S3C2410_GPG(4),
+               .active_low     = 1,
+               .desc           = "Up button",
+       },
+       {
+               .code           = KEY_DOWN,
+               .gpio           = S3C2410_GPG(6),
+               .active_low     = 1,
+               .desc           = "Down button",
+       },
+       {
+               .code           = KEY_ENTER,
+               .gpio           = S3C2410_GPG(9),
+               .active_low     = 1,
+               .desc           = "Ok button"
+       },
+ };
+ static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
+       .buttons = rx1950_gpio_keys_table,
+       .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
+ };
+ static struct platform_device rx1950_device_gpiokeys = {
+       .name = "gpio-keys",
+       .dev.platform_data = &rx1950_gpio_keys_data,
+ };
+ static struct uda1380_platform_data uda1380_info = {
+       .gpio_power     = S3C2410_GPJ(0),
+       .gpio_reset     = S3C2410_GPD(0),
+       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
+ };
+ static struct i2c_board_info rx1950_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("uda1380", 0x1a),
+               .platform_data = &uda1380_info,
+       },
+ };
+ static struct platform_device *rx1950_devices[] __initdata = {
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &samsung_asoc_dma,
+       &s3c_device_usbgadget,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &s3c_device_sdi,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &s3c_device_timer[0],
+       &s3c_device_timer[1],
+       &rx1950_backlight,
+       &rx1950_device_gpiokeys,
+       &power_supply,
+       &rx1950_battery,
+       &rx1950_leds,
+ };
+ static struct clk *rx1950_clocks[] __initdata = {
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+ };
+ static void __init rx1950_map_io(void)
+ {
+       s3c24xx_clkout0.parent  = &clk_h;
+       s3c24xx_clkout1.parent  = &clk_f;
+       s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+       s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+       s3c24xx_init_clocks(16934000);
+       s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+       /* setup PM */
+ #ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
+ #endif
+       s3c_pm_init();
+ }
+ static void __init rx1950_init_machine(void)
+ {
+       int i;
+       s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
+       s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
+       s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
+       s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
+       s3c_i2c0_set_platdata(NULL);
+       s3c_nand_set_platdata(&rx1950_nand_info);
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                                               S3C2410_MISCCR_USBSUSPND0 |
+                                               S3C2410_MISCCR_USBSUSPND1, 0x0);
+       /* mmc power is disabled by default */
+       WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
+       gpio_direction_output(S3C2410_GPJ(1), 0);
+       for (i = 0; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+       for (i = 10; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+       for (i = 2; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+       for (i = 11; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+       WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
+       WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink"));
+       WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink"));
+       WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink"));
+       gpio_direction_output(S3C2410_GPA(3), 0);
+       gpio_direction_output(S3C2410_GPA(4), 0);
+       gpio_direction_output(S3C2410_GPJ(6), 0);
+       platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+       i2c_register_board_info(0, rx1950_i2c_devices,
+               ARRAY_SIZE(rx1950_i2c_devices));
+ }
+ /* H1940 and RX3715 need to reserve this for suspend */
+ static void __init rx1950_reserve(void)
+ {
+       memblock_reserve(0x30003000, 0x1000);
+       memblock_reserve(0x30081000, 0x1000);
+ }
+ MACHINE_START(RX1950, "HP iPAQ RX1950")
+     /* Maintainers: Vasily Khoruzhick */
+       .atag_offset = 0x100,
+       .map_io = rx1950_map_io,
+       .reserve        = rx1950_reserve,
+       .init_irq = s3c24xx_init_irq,
+       .init_machine = rx1950_init_machine,
+       .timer = &s3c24xx_timer,
+       .restart        = s3c2440_restart,
+ MACHINE_END
index 0000000,eebe1e7..30a44f8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,256 +1,256 @@@
 -void smdk2416_hsudc_gpio_init(void)
+ /* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
+  *
+  * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+  *    as part of OpenInkpot project
+  * Copyright (c) 2009 Promwad Innovation Company
+  *    Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+ */
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/serial_core.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/gpio.h>
+ #include <linux/fb.h>
+ #include <linux/delay.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+ #include <mach/hardware.h>
+ #include <asm/irq.h>
+ #include <asm/mach-types.h>
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-s3c2443-clock.h>
+ #include <mach/idle.h>
+ #include <mach/leds-gpio.h>
+ #include <plat/iic.h>
+ #include <plat/s3c2416.h>
+ #include <plat/gpio-cfg.h>
+ #include <plat/clock.h>
+ #include <plat/devs.h>
+ #include <plat/cpu.h>
+ #include <plat/nand.h>
+ #include <plat/sdhci.h>
+ #include <plat/udc.h>
+ #include <linux/platform_data/s3c-hsudc.h>
+ #include <plat/regs-fb-v4.h>
+ #include <plat/fb.h>
+ #include <plat/common-smdk.h>
+ static struct map_desc smdk2416_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+ };
+ #define UCON (S3C2410_UCON_DEFAULT    | \
+               S3C2440_UCON_PCLK       | \
+               S3C2443_UCON_RXERR_IRQEN)
+ #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+ #define UFCON (S3C2410_UFCON_RXTRIG8  | \
+               S3C2410_UFCON_FIFOMODE  | \
+               S3C2440_UFCON_TXTRIG16)
+ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON | 0x50,
+               .ufcon       = UFCON,
+       },
+       [3] = {
+               .hwport      = 3,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+ };
 -void smdk2416_hsudc_gpio_uninit(void)
++static void smdk2416_hsudc_gpio_init(void)
+ {
+       s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
+       s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));
+       s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
+ }
 -struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
++static void smdk2416_hsudc_gpio_uninit(void)
+ {
+       s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
+       s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
+ }
 -struct s3c_fb_pd_win smdk2416_fb_win[] = {
++static struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
+       .epnum = 9,
+       .gpio_init = smdk2416_hsudc_gpio_init,
+       .gpio_uninit = smdk2416_hsudc_gpio_uninit,
+ };
++static struct s3c_fb_pd_win smdk2416_fb_win[] = {
+       [0] = {
+               /* think this is the same as the smdk6410 */
+               .win_mode       = {
+                       .pixclock       = 41094,
+                       .left_margin    = 8,
+                       .right_margin   = 13,
+                       .upper_margin   = 7,
+                       .lower_margin   = 5,
+                       .hsync_len      = 3,
+                       .vsync_len      = 1,
+                       .xres           = 800,
+                       .yres           = 480,
+               },
+               .default_bpp    = 16,
+               .max_bpp        = 32,
+       },
+ };
+ static void s3c2416_fb_gpio_setup_24bpp(void)
+ {
+       unsigned int gpio;
+       for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+       for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+       for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+ }
+ static struct s3c_fb_platdata smdk2416_fb_platdata = {
+       .win[0]         = &smdk2416_fb_win[0],
+       .setup_gpio     = s3c2416_fb_gpio_setup_24bpp,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ };
+ static struct s3c_sdhci_platdata smdk2416_hsmmc0_pdata __initdata = {
+       .max_width              = 4,
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S3C2410_GPF(1),
+       .ext_cd_gpio_invert     = 1,
+ };
+ static struct s3c_sdhci_platdata smdk2416_hsmmc1_pdata __initdata = {
+       .max_width              = 4,
+       .cd_type                = S3C_SDHCI_CD_NONE,
+ };
+ static struct platform_device *smdk2416_devices[] __initdata = {
+       &s3c_device_fb,
+       &s3c_device_wdt,
+       &s3c_device_ohci,
+       &s3c_device_i2c0,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_usb_hsudc,
+ };
+ static void __init smdk2416_map_io(void)
+ {
+       s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+ }
+ static void __init smdk2416_machine_init(void)
+ {
+       s3c_i2c0_set_platdata(NULL);
+       s3c_fb_set_platdata(&smdk2416_fb_platdata);
+       s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
+       s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
+       s3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);
+       gpio_request(S3C2410_GPB(4), "USBHost Power");
+       gpio_direction_output(S3C2410_GPB(4), 1);
+       gpio_request(S3C2410_GPB(3), "Display Power");
+       gpio_direction_output(S3C2410_GPB(3), 1);
+       gpio_request(S3C2410_GPB(1), "Display Reset");
+       gpio_direction_output(S3C2410_GPB(1), 1);
+       platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
+       smdk_machine_init();
+ }
+ MACHINE_START(SMDK2416, "SMDK2416")
+       /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2416_map_io,
+       .init_machine   = smdk2416_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2416_restart,
+ MACHINE_END
index 0000000,fda5385..03f706d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,180 +1,180 @@@
 -static int s3c2410_pm_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2410/pm.c
+  *
+  * Copyright (c) 2006 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ #include <linux/init.h>
+ #include <linux/suspend.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+ #include <linux/device.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/gpio.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/mach-types.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/h1940.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ static void s3c2410_pm_prepare(void)
+ {
+       /* ensure at least GSTATUS3 has the resume address */
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3);
+       S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+       S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
+       if (machine_is_h1940()) {
+               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+               unsigned long ptr;
+               unsigned long calc = 0;
+               /* generate check for the bootloader to check on resume */
+               for (ptr = 0; ptr < 0x40000; ptr += 0x400)
+                       calc += __raw_readl(base+ptr);
+               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+       }
+       /* RX3715 and RX1950 use similar to H1940 code and the
+        * same offsets for resume and checksum pointers */
+       if (machine_is_rx3715() || machine_is_rx1950()) {
+               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+               unsigned long ptr;
+               unsigned long calc = 0;
+               /* generate check for the bootloader to check on resume */
+               for (ptr = 0; ptr < 0x40000; ptr += 0x4)
+                       calc += __raw_readl(base+ptr);
+               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+       }
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
+       if (machine_is_rx1950()) {
+               /* According to S3C2442 user's manual, page 7-17,
+                * when the system is operating in NAND boot mode,
+                * the hardware pin configuration - EINT[23:21] –
+                * must be set as input for starting up after
+                * wakeup from sleep mode
+                */
+               s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
+       }
+ }
+ static void s3c2410_pm_resume(void)
+ {
+       unsigned long tmp;
+       /* unset the return-from-sleep flag, to ensure reset */
+       tmp = __raw_readl(S3C2410_GSTATUS2);
+       tmp &= S3C2410_GSTATUS2_OFFRESET;
+       __raw_writel(tmp, S3C2410_GSTATUS2);
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+ }
+ struct syscore_ops s3c2410_pm_syscore_ops = {
+       .resume         = s3c2410_pm_resume,
+ };
++static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
+ {
+       pm_cpu_prep = s3c2410_pm_prepare;
+       pm_cpu_sleep = s3c2410_cpu_suspend;
+       return 0;
+ }
+ #if defined(CONFIG_CPU_S3C2410)
+ static struct subsys_interface s3c2410_pm_interface = {
+       .name           = "s3c2410_pm",
+       .subsys         = &s3c2410_subsys,
+       .add_dev        = s3c2410_pm_add,
+ };
+ /* register ourselves */
+ static int __init s3c2410_pm_drvinit(void)
+ {
+       return subsys_interface_register(&s3c2410_pm_interface);
+ }
+ arch_initcall(s3c2410_pm_drvinit);
+ static struct subsys_interface s3c2410a_pm_interface = {
+       .name           = "s3c2410a_pm",
+       .subsys         = &s3c2410a_subsys,
+       .add_dev        = s3c2410_pm_add,
+ };
+ static int __init s3c2410a_pm_drvinit(void)
+ {
+       return subsys_interface_register(&s3c2410a_pm_interface);
+ }
+ arch_initcall(s3c2410a_pm_drvinit);
+ #endif
+ #if defined(CONFIG_CPU_S3C2440)
+ static struct subsys_interface s3c2440_pm_interface = {
+       .name           = "s3c2440_pm",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2410_pm_add,
+ };
+ static int __init s3c2440_pm_drvinit(void)
+ {
+       return subsys_interface_register(&s3c2440_pm_interface);
+ }
+ arch_initcall(s3c2440_pm_drvinit);
+ #endif
+ #if defined(CONFIG_CPU_S3C2442)
+ static struct subsys_interface s3c2442_pm_interface = {
+       .name           = "s3c2442_pm",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c2410_pm_add,
+ };
+ static int __init s3c2442_pm_drvinit(void)
+ {
+       return subsys_interface_register(&s3c2442_pm_interface);
+ }
+ arch_initcall(s3c2442_pm_drvinit);
+ #endif
index 0000000,d1adfa6..d045885
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,124 +1,124 @@@
 -static int s3c2412_pm_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2412/pm.c
+  *
+  * Copyright (c) 2006 Simtec Electronics
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * http://armlinux.simtec.co.uk/.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+ */
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <asm/cacheflush.h>
+ #include <asm/irq.h>
+ #include <mach/regs-power.h>
+ #include <mach/regs-gpioj.h>
+ #include <mach/regs-gpio.h>
+ #include <mach/regs-dsc.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ #include <plat/s3c2412.h>
+ extern void s3c2412_sleep_enter(void);
+ static int s3c2412_cpu_suspend(unsigned long arg)
+ {
+       unsigned long tmp;
+       /* set our standby method to sleep */
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+       s3c2412_sleep_enter();
+       panic("sleep resumed to originator?");
+ }
+ static void s3c2412_pm_prepare(void)
+ {
+ }
++static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif)
+ {
+       pm_cpu_prep = s3c2412_pm_prepare;
+       pm_cpu_sleep = s3c2412_cpu_suspend;
+       return 0;
+ }
+ static struct sleep_save s3c2412_sleep[] = {
+       SAVE_ITEM(S3C2412_DSC0),
+       SAVE_ITEM(S3C2412_DSC1),
+       SAVE_ITEM(S3C2413_GPJDAT),
+       SAVE_ITEM(S3C2413_GPJCON),
+       SAVE_ITEM(S3C2413_GPJUP),
+       /* save the PWRCFG to get back to original sleep method */
+       SAVE_ITEM(S3C2412_PWRCFG),
+       /* save the sleep configuration anyway, just in case these
+        * get damaged during wakeup */
+       SAVE_ITEM(S3C2412_GPBSLPCON),
+       SAVE_ITEM(S3C2412_GPCSLPCON),
+       SAVE_ITEM(S3C2412_GPDSLPCON),
+       SAVE_ITEM(S3C2412_GPFSLPCON),
+       SAVE_ITEM(S3C2412_GPGSLPCON),
+       SAVE_ITEM(S3C2412_GPHSLPCON),
+       SAVE_ITEM(S3C2413_GPJSLPCON),
+ };
+ static struct subsys_interface s3c2412_pm_interface = {
+       .name           = "s3c2412_pm",
+       .subsys         = &s3c2412_subsys,
+       .add_dev        = s3c2412_pm_add,
+ };
+ static __init int s3c2412_pm_init(void)
+ {
+       return subsys_interface_register(&s3c2412_pm_interface);
+ }
+ arch_initcall(s3c2412_pm_init);
+ static int s3c2412_pm_suspend(void)
+ {
+       s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+       return 0;
+ }
+ static void s3c2412_pm_resume(void)
+ {
+       unsigned long tmp;
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+       tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+       s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+ }
+ struct syscore_ops s3c2412_pm_syscore_ops = {
+       .suspend        = s3c2412_pm_suspend,
+       .resume         = s3c2412_pm_resume,
+ };
index 0000000,3bdb15a..1bd4817
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,83 +1,83 @@@
 -static int s3c2416_pm_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2416/pm.c
+  *
+  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+  *            http://www.samsung.com
+  *
+  * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+ */
+ #include <linux/device.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/io.h>
+ #include <asm/cacheflush.h>
+ #include <mach/regs-power.h>
+ #include <mach/regs-s3c2443-clock.h>
+ #include <plat/cpu.h>
+ #include <plat/pm.h>
+ extern void s3c2412_sleep_enter(void);
+ static int s3c2416_cpu_suspend(unsigned long arg)
+ {
+       /* enable wakeup sources regardless of battery state */
+       __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
+       /* set the mode as sleep, 2BED represents "Go to BED" */
+       __raw_writel(0x2BED, S3C2443_PWRMODE);
+       s3c2412_sleep_enter();
+       panic("sleep resumed to originator?");
+ }
+ static void s3c2416_pm_prepare(void)
+ {
+       /*
+        * write the magic value u-boot uses to check for resume into
+        * the INFORM0 register, and ensure INFORM1 is set to the
+        * correct address to resume from.
+        */
+       __raw_writel(0x2BED, S3C2412_INFORM0);
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+ }
++static int s3c2416_pm_add(struct device *dev, struct subsys_interface *sif)
+ {
+       pm_cpu_prep = s3c2416_pm_prepare;
+       pm_cpu_sleep = s3c2416_cpu_suspend;
+       return 0;
+ }
+ static struct subsys_interface s3c2416_pm_interface = {
+       .name           = "s3c2416_pm",
+       .subsys         = &s3c2416_subsys,
+       .add_dev        = s3c2416_pm_add,
+ };
+ static __init int s3c2416_pm_init(void)
+ {
+       return subsys_interface_register(&s3c2416_pm_interface);
+ }
+ arch_initcall(s3c2416_pm_init);
+ static void s3c2416_pm_resume(void)
+ {
+       /* unset the return-from-sleep amd inform flags */
+       __raw_writel(0x0, S3C2443_PWRMODE);
+       __raw_writel(0x0, S3C2412_INFORM0);
+       __raw_writel(0x0, S3C2412_INFORM1);
+ }
+ struct syscore_ops s3c2416_pm_syscore_ops = {
+       .resume         = s3c2416_pm_resume,
+ };
index 0000000,8004e04..22cb7c9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,188 +1,188 @@@
 -static int s3c2442_clk_add(struct device *dev)
+ /* linux/arch/arm/mach-s3c2442/s3c2442.c
+  *
+  * Copyright (c) 2004-2005 Simtec Electronics
+  *    http://armlinux.simtec.co.uk/
+  *    Ben Dooks <ben@simtec.co.uk>
+  *
+  * S3C2442 core and lock support
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/errno.h>
+ #include <linux/err.h>
+ #include <linux/device.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/mutex.h>
+ #include <linux/gpio.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <mach/hardware.h>
+ #include <linux/atomic.h>
+ #include <asm/irq.h>
+ #include <mach/regs-clock.h>
+ #include <plat/clock.h>
+ #include <plat/cpu.h>
+ #include <plat/s3c244x.h>
+ #include <plat/pm.h>
+ #include <plat/gpio-core.h>
+ #include <plat/gpio-cfg.h>
+ #include <plat/gpio-cfg-helpers.h>
+ /* S3C2442 extended clock support */
+ static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+                                             unsigned long rate)
+ {
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+       if (rate > parent_rate)
+               return parent_rate;
+       div = parent_rate / rate;
+       if (div == 3)
+               return parent_rate / 3;
+       /* note, we remove the +/- 1 calculations for the divisor */
+       div /= 2;
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+       return parent_rate / (div * 2);
+ }
+ static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+ {
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+       rate = s3c2442_camif_upll_round(clk, rate);
+       camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+       if (rate == parent_rate) {
+               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+       } else if ((parent_rate / rate) == 3) {
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+       } else {
+               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= (((parent_rate / rate) / 2) - 1);
+       }
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+       return 0;
+ }
+ /* Extra S3C2442 clocks */
+ static struct clk s3c2442_clk_cam = {
+       .name           = "camif",
+       .id             = -1,
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+ };
+ static struct clk s3c2442_clk_cam_upll = {
+       .name           = "camif-upll",
+       .id             = -1,
+       .ops            = &(struct clk_ops) {
+               .set_rate       = s3c2442_camif_upll_setrate,
+               .round_rate     = s3c2442_camif_upll_round,
+       },
+ };
++static int s3c2442_clk_add(struct device *dev, struct subsys_interface *sif)
+ {
+       struct clk *clock_upll;
+       struct clk *clock_h;
+       struct clk *clock_p;
+       clock_p = clk_get(NULL, "pclk");
+       clock_h = clk_get(NULL, "hclk");
+       clock_upll = clk_get(NULL, "upll");
+       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+               return -EINVAL;
+       }
+       s3c2442_clk_cam.parent = clock_h;
+       s3c2442_clk_cam_upll.parent = clock_upll;
+       s3c24xx_register_clock(&s3c2442_clk_cam);
+       s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+       clk_disable(&s3c2442_clk_cam);
+       return 0;
+ }
+ static struct subsys_interface s3c2442_clk_interface = {
+       .name           = "s3c2442_clk",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c2442_clk_add,
+ };
+ static __init int s3c2442_clk_init(void)
+ {
+       return subsys_interface_register(&s3c2442_clk_interface);
+ }
+ arch_initcall(s3c2442_clk_init);
+ static struct device s3c2442_dev = {
+       .bus            = &s3c2442_subsys,
+ };
+ int __init s3c2442_init(void)
+ {
+       printk("S3C2442: Initialising architecture\n");
+ #ifdef CONFIG_PM
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+ #endif
+       register_syscore_ops(&s3c244x_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+       return device_register(&s3c2442_dev);
+ }
+ void __init s3c2442_map_io(void)
+ {
+       s3c244x_map_io();
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1down;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1down;
+ }
Simple merge
Simple merge
Simple merge