diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 51ee13e7c74ccf65009a930b198c5325a0c454d4..0f711c4394a99fedff5b4d6d15cb103d000d2b65 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -303,7 +303,7 @@ config ARCH_SA1100
 	  Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
-	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442"
+	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
 	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -371,6 +371,7 @@ source "arch/arm/mach-s3c2410/Kconfig"
 source "arch/arm/mach-s3c2412/Kconfig"
 source "arch/arm/mach-s3c2440/Kconfig"
 source "arch/arm/mach-s3c2442/Kconfig"
+source "arch/arm/mach-s3c2443/Kconfig"
 endif
 
 source "arch/arm/mach-lh7a40x/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2df1ea0a0c2d1985d3b6889c7779482bfc55a38b..93e474726725e6b3373cf813c88e6349778e769b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -165,6 +165,7 @@ core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2400/
 core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2412/
 core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2440/
 core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2442/
+core-$(CONFIG_ARCH_S3C2410)	+= arch/arm/mach-s3c2443/
 core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
 core-$(CONFIG_VFP)		+= arch/arm/vfp/
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..0d8d7bf9a96baf2e2afa0b901b815531c59cd78e
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -0,0 +1,18 @@
+# arch/arm/mach-s3c2443/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2443
+	bool
+	depends on ARCH_S3C2410
+	select S3C2443_PM if PM
+	select S3C2443_DMA if S3C2410_DMA
+	help
+	  Support for the S3C2443 SoC from the S3C24XX line
+
+menu "S3C2443 Machines"
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..397475affbe16a8616c78a42e18817c8b28909b8
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Makefile
@@ -0,0 +1,16 @@
+# arch/arm/mach-s3c2443/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o
+obj-$(CONFIG_CPU_S3C2443)	+= irq.o
+obj-$(CONFIG_CPU_S3C2443)	+= clock.o
+
+# Machine support
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
new file mode 100644
index 0000000000000000000000000000000000000000..dd2272fb1131c53e99b2ba75a85369ecafd7ffd8
--- /dev/null
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -0,0 +1,1007 @@
+/* linux/arch/arm/mach-s3c2443/clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 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.
+ *
+ * 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/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-s3c2443-clock.h>
+
+#include <asm/plat-s3c24xx/s3c2443.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
+
+	clkcon = __raw_readl(S3C2443_HCLKCON);
+
+	if (enable)
+		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
+
+	__raw_writel(clkcon, S3C2443_HCLKCON);
+
+	return 0;
+}
+
+static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
+
+	clkcon = __raw_readl(S3C2443_PCLKCON);
+
+	if (enable)
+		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
+
+	__raw_writel(clkcon, S3C2443_HCLKCON);
+
+	return 0;
+}
+
+static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->ctrlbit;
+	unsigned long clkcon;
+
+	clkcon = __raw_readl(S3C2443_SCLKCON);
+
+	if (enable)
+		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
+
+	__raw_writel(clkcon, S3C2443_SCLKCON);
+
+	return 0;
+}
+
+static unsigned long s3c2443_roundrate_clksrc(struct clk *clk,
+					      unsigned long rate,
+					      unsigned int max)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate > parent_rate)
+		return parent_rate;
+
+	/* note, we remove the +/- 1 calculations as they cancel out */
+
+	div = (rate / parent_rate);
+
+	if (div < 1)
+		div = 1;
+	else if (div > max)
+		div = max;
+
+	return parent_rate / div;
+}
+
+static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk,
+					       unsigned long rate)
+{
+	return s3c2443_roundrate_clksrc(clk, rate, 4);
+}
+
+static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk,
+						unsigned long rate)
+{
+	return s3c2443_roundrate_clksrc(clk, rate, 16);
+}
+
+static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
+						 unsigned long rate)
+{
+	return s3c2443_roundrate_clksrc(clk, rate, 256);
+}
+
+/* clock selections */
+
+/* CPU EXTCLK input */
+static struct clk clk_ext = {
+	.name		= "ext",
+	.id		= -1,
+};
+
+static struct clk clk_mpllref = {
+	.name		= "mpllref",
+	.parent		= &clk_xtal,
+	.id		= -1,
+};
+
+#if 0
+static struct clk clk_mpll = {
+	.name		= "mpll",
+	.parent		= &clk_mpllref,
+	.id		= -1,
+};
+#endif
+
+static struct clk clk_epllref;
+
+static struct clk clk_epll = {
+	.name		= "epll",
+	.parent		= &clk_epllref,
+	.id		= -1,
+};
+
+static struct clk clk_i2s_ext = {
+	.name		= "i2s-ext",
+	.id		= -1,
+};
+
+static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK;
+
+	if (parent == &clk_xtal)
+		clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL;
+	else if (parent == &clk_ext)
+		clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK;
+	else if (parent != &clk_mpllref)
+		return -EINVAL;
+
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk clk_epllref = {
+	.name		= "epllref",
+	.id		= -1,
+	.set_parent	= s3c2443_setparent_epllref,
+};
+
+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,
+	.id		= -1,
+	.get_rate	= s3c2443_getrate_mdivclk,
+};
+
+
+static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL |
+		    S3C2443_CLKSRC_EXTCLK_DIV);
+
+	if (parent == &clk_mpll)
+		clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL;
+	else if (parent == &clk_mdivclk)
+		clksrc |= S3C2443_CLKSRC_EXTCLK_DIV;
+	else if (parent != &clk_mpllref)
+		return -EINVAL;
+
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk clk_msysclk = {
+	.name		= "msysclk",
+	.parent		= &clk_xtal,
+	.id		= -1,
+	.set_parent	= s3c2443_setparent_msysclk,
+};
+
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	if (parent == &clk_epll)
+		clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL;
+	else if (parent == &clk_epllref)
+		clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL;
+	else
+		return -EINVAL;
+
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk clk_esysclk = {
+	.name		= "esysclk",
+	.parent		= &clk_epll,
+	.id		= -1,
+	.set_parent	= s3c2443_setparent_esysclk,
+};
+
+/* uartclk
+ *
+ * UART baud-rate clock sourced from esysclk via a divisor
+*/
+
+static unsigned long s3c2443_getrate_uart(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_UARTDIV_MASK;
+	div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+
+static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc16(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_uart = {
+	.name		= "uartclk",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.get_rate	= s3c2443_getrate_uart,
+	.set_rate	= s3c2443_setrate_uart,
+	.round_rate	= s3c2443_roundrate_clksrc16,
+};
+
+/* hsspi
+ *
+ * high-speed spi clock, sourced from esysclk
+*/
+
+static unsigned long s3c2443_getrate_hsspi(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_HSSPIDIV_MASK;
+	div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+
+static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc4(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_hsspi = {
+	.name		= "hsspi",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_HSSPICLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_hsspi,
+	.set_rate	= s3c2443_setrate_hsspi,
+	.round_rate	= s3c2443_roundrate_clksrc4,
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static unsigned long s3c2443_getrate_usbhost(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK;
+	div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc4(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+struct clk clk_usb_bus_host = {
+	.name		= "usb-bus-host-parent",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_USBHOST,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_usbhost,
+	.set_rate	= s3c2443_setrate_usbhost,
+	.round_rate	= s3c2443_roundrate_clksrc4,
+};
+
+/* clk_hsmcc_div
+ *
+ * this clock is sourced from epll, and is fed through a divider,
+ * to a mux controlled by sclkcon where either it or a extclk can
+ * be fed to the hsmmc block
+*/
+
+static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_HSMMCDIV_MASK;
+	div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc4(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_hsmmc_div = {
+	.name		= "hsmmc-div",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.get_rate	= s3c2443_getrate_hsmmc_div,
+	.set_rate	= s3c2443_setrate_hsmmc_div,
+	.round_rate	= s3c2443_roundrate_clksrc4,
+};
+
+static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
+
+	clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
+		    S3C2443_SCLKCON_HSMMCCLK_EPLL);
+
+	if (parent == &clk_epll)
+		clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
+	else if (parent == &clk_ext)
+		clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
+	else
+		return -EINVAL;
+
+	if (clk->usage > 0) {
+		__raw_writel(clksrc, S3C2443_SCLKCON);
+	}
+
+	clk->parent = parent;
+	return 0;
+}
+
+static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
+{
+	return s3c2443_setparent_hsmmc(clk, clk->parent);
+}
+
+static struct clk clk_hsmmc = {
+	.name		= "hsmmc-if",
+	.id		= -1,
+	.parent		= &clk_hsmmc_div,
+	.enable		= s3c2443_enable_hsmmc,
+	.set_parent	= s3c2443_setparent_hsmmc,
+};
+
+/* i2s_eplldiv
+ *
+ * this clock is the output from the i2s divisor of esysclk
+*/
+
+static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_I2SDIV_MASK;
+	div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc16(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_i2s_eplldiv = {
+	.name		= "i2s-eplldiv",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.get_rate	= s3c2443_getrate_i2s_eplldiv,
+	.set_rate	= s3c2443_setrate_i2s_eplldiv,
+	.round_rate	= s3c2443_roundrate_clksrc16,
+};
+
+/* i2s-ref
+ *
+ * i2s bus reference clock, selectable from external, esysclk or epllref
+*/
+
+static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+	clksrc &= ~S3C2443_CLKSRC_I2S_MASK;
+
+	if (parent == &clk_epllref)
+		clksrc |= S3C2443_CLKSRC_I2S_EPLLREF;
+	else if (parent == &clk_i2s_ext)
+		clksrc |= S3C2443_CLKSRC_I2S_EXT;
+	else if (parent != &clk_i2s_eplldiv)
+		return -EINVAL;
+
+	clk->parent = parent;
+	__raw_writel(clksrc, S3C2443_CLKSRC);
+
+	return 0;
+}
+
+static struct clk clk_i2s = {
+	.name		= "i2s-if",
+	.id		= -1,
+	.parent		= &clk_i2s_eplldiv,
+	.ctrlbit	= S3C2443_SCLKCON_I2SCLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.set_parent	= s3c2443_setparent_i2s,
+};
+
+/* cam-if
+ *
+ * camera interface bus-clock, divided down from esysclk
+*/
+
+static unsigned long s3c2443_getrate_cam(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div  &= S3C2443_CLKDIV1_CAMDIV_MASK;
+	div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc16(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK;
+	clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT;
+
+	__raw_writel(clkdiv1, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_cam = {
+	.name		= "camif-upll",		/* same as 2440 name */
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_cam,
+	.set_rate	= s3c2443_setrate_cam,
+	.round_rate	= s3c2443_roundrate_clksrc16,
+};
+
+/* display-if
+ *
+ * display interface clock, divided from esysclk
+*/
+
+static unsigned long s3c2443_getrate_display(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+	div &= S3C2443_CLKDIV1_DISPDIV_MASK;
+	div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_display(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+	rate = s3c2443_roundrate_clksrc256(clk, rate);
+	rate = parent_rate / rate;
+
+	clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
+	clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2443_CLKDIV1);
+	return 0;
+}
+
+static struct clk clk_display = {
+	.name		= "display-if",
+	.id		= -1,
+	.parent		= &clk_esysclk,
+	.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
+	.enable		= s3c2443_clkcon_enable_s,
+	.get_rate	= s3c2443_getrate_display,
+	.set_rate	= s3c2443_setrate_display,
+	.round_rate	= s3c2443_roundrate_clksrc256,
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+	}, {
+		.name		= "sdi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_SDI,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_ADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_IIC,
+	}, {
+		.name		= "iis",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_IIS,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_SPI1,
+	}
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "dma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA0,
+	}, {
+		.name		= "dma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA1,
+	}, {
+		.name		= "dma",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA2,
+	}, {
+		.name		= "dma",
+		.id		= 3,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA3,
+	}, {
+		.name		= "dma",
+		.id		= 4,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA4,
+	}, {
+		.name		= "dma",
+		.id		= 5,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA5,
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_LCDC,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_GPIO,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_USBH,
+	}, {
+		.name		= "usb-device",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_USBD,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_PWMT,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART3,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= S3C2443_PCLKCON_WDT,
+	}, {
+		.name		= "usb-bus-host",
+		.id		= -1,
+		.parent		= &clk_usb_bus_host,
+	}
+};
+
+/* clocks to add where we need to check their parentage */
+
+/* s3c2443_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static int __init clk_init_set_parent(struct clk *clk, struct clk *parent)
+{
+	printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name);
+	return clk_set_parent(clk, parent);
+}
+
+static void __init s3c2443_clk_initparents(void)
+{
+	unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+	struct clk *parent;
+
+	switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) {
+	case S3C2443_CLKSRC_EPLLREF_EXTCLK:
+		parent = &clk_ext;
+		break;
+
+	case S3C2443_CLKSRC_EPLLREF_XTAL:
+	default:
+		parent = &clk_xtal;
+		break;
+
+	case S3C2443_CLKSRC_EPLLREF_MPLLREF:
+	case S3C2443_CLKSRC_EPLLREF_MPLLREF2:
+		parent = &clk_mpllref;
+		break;
+	}
+
+	clk_init_set_parent(&clk_epllref, parent);
+
+	switch (clksrc & S3C2443_CLKSRC_I2S_MASK) {
+	case S3C2443_CLKSRC_I2S_EXT:
+		parent = &clk_i2s_ext;
+		break;
+
+	case S3C2443_CLKSRC_I2S_EPLLDIV:
+	default:
+		parent = &clk_i2s_eplldiv;
+		break;
+
+	case S3C2443_CLKSRC_I2S_EPLLREF:
+	case S3C2443_CLKSRC_I2S_EPLLREF3:
+		parent = &clk_epllref;
+	}
+
+	clk_init_set_parent(&clk_i2s, &clk_epllref);
+
+	/* esysclk source */
+
+	parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ?
+		&clk_epll : &clk_epllref;
+
+	clk_init_set_parent(&clk_esysclk, parent);
+
+	/* msysclk source */
+
+	if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) {
+		parent = &clk_mpll;
+	} else {
+		parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ?
+			&clk_mdivclk : &clk_mpllref;
+	}
+
+	clk_init_set_parent(&clk_msysclk, parent);
+}
+
+/* armdiv divisor table */
+
+static unsigned int armdiv[16] = {
+	[S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 1,
+	[S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 2,
+	[S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 3,
+	[S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 4,
+	[S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 6,
+	[S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 8,
+	[S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 12,
+	[S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]	= 16,
+};
+
+static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
+{
+	clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+
+	return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0)
+{
+	clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+	clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+	return clkcon0 + 1;
+}
+
+/* clocks to add straight away */
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_usb_bus_host,
+	&clk_usb_bus,
+	&clk_esysclk,
+	&clk_epllref,
+	&clk_mpllref,
+	&clk_msysclk,
+	&clk_uart,
+	&clk_display,
+	&clk_cam,
+	&clk_i2s_eplldiv,
+	&clk_i2s,
+	&clk_hsspi,
+	&clk_hsmmc_div,
+	&clk_hsmmc,
+};
+
+void __init s3c2443_init_clocks(int xtal)
+{
+	unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+	unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+	unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+	unsigned long pll;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long pclk;
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	pll = s3c2443_get_mpll(mpllcon, xtal);
+
+	fclk = pll / s3c2443_fclk_div(clkdiv0);
+	hclk = fclk / s3c2443_get_prediv(clkdiv0);
+	hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
+ 	pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+	s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+
+	printk("S3C2443: 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(fclk),
+	       print_mhz(hclk), print_mhz(pclk));
+
+	s3c2443_clk_initparents();
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+		clkp = clks[ptr];
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+
+	clk_usb_bus.parent = &clk_usb_bus_host;
+
+	/* ensure usb bus clock is within correct rate of 48MHz */
+
+	if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) {
+		printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+		clk_set_rate(&clk_usb_bus_host, 48*1000*1000);
+	}
+
+	printk("S3C2443: 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)));
+
+	/* register clocks from clock array */
+
+	clkp = init_clocks;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	/* We must be careful disabling the clocks we are not intending to
+	 * be using at boot time, as subsytems such as the LCD which do
+	 * their own DMA requests to the bus can cause the system to lockup
+	 * if they where in the middle of requesting bus access.
+	 *
+	 * Disabling the LCD clock if the LCD is active is very dangerous,
+	 * and therefore the bootloader should be careful to not enable
+	 * the LCD clock if it is not needed.
+	*/
+
+	/* install (and disable) the clocks we do not need immediately */
+
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+
+		(clkp->enable)(clkp, 0);
+	}
+}
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
new file mode 100644
index 0000000000000000000000000000000000000000..f7058823a0e1eb6eab4077ee58985709b0be684e
--- /dev/null
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -0,0 +1,130 @@
+/* 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/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+/* WDT/AC97 */
+
+static void s3c_irq_demux_wdtac97(unsigned int irq,
+				  struct irq_desc *desc)
+{
+	unsigned int subsrc, submsk;
+	struct irq_desc *mydesc;
+
+	/* 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 >>= 27;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_S3C2443_WDT;
+			desc_handle_irq(IRQ_S3C2443_WDT, mydesc);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_S3C2443_AC97;
+			desc_handle_irq(IRQ_S3C2443_AC97, mydesc);
+		}
+	}
+}
+
+
+#define INTMSK_WDT	 (1UL << (IRQ_WDT - IRQ_EINT0))
+
+static void
+s3c_irq_wdtac97_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<27);
+}
+
+static void
+s3c_irq_wdtac97_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_WDT);
+}
+
+static void
+s3c_irq_wdtac97_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<27);
+}
+
+static struct irq_chip s3c_irq_wdtac97 = {
+	.mask	    = s3c_irq_wdtac97_mask,
+	.unmask	    = s3c_irq_wdtac97_unmask,
+	.ack	    = s3c_irq_wdtac97_ack,
+};
+
+static int s3c2443_irq_add(struct sys_device *sysdev)
+{
+	unsigned int irqno;
+
+	printk("S3C2443: IRQ Support\n");
+
+	/* add new chained handler for wdt, ac7 */
+
+	set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_WDT, handle_level_irq);
+	set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+
+	for (irqno = IRQ_S3C2443_WDT; irqno <= IRQ_S3C2443_AC97; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_wdtac97);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2443_irq_driver = {
+	.add		= s3c2443_irq_add,
+};
+
+static int s3c2443_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
+}
+
+arch_initcall(s3c2443_irq_init);
+
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
new file mode 100644
index 0000000000000000000000000000000000000000..bc14f772ff245e063d8e25e42e7e054dc1c00a55
--- /dev/null
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -0,0 +1,87 @@
+/* linux/arch/arm/mach-s3c2443/s3c2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2443 Mobile CPU 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-serial.h>
+
+#include <asm/plat-s3c24xx/s3c2443.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct map_desc s3c2443_iodesc[] __initdata = {
+	IODESC_ENT(WATCHDOG),
+	IODESC_ENT(CLKPWR),
+	IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2443_sysclass = {
+	set_kset_name("s3c2443-core"),
+};
+
+static struct sys_device s3c2443_sysdev = {
+	.cls		= &s3c2443_sysclass,
+};
+
+int __init s3c2443_init(void)
+{
+	printk("S3C2443: Initialising architecture\n");
+
+	return sysdev_register(&s3c2443_sysdev);
+}
+
+void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2443_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2443_map_io(struct map_desc *mach_desc, int mach_size)
+{
+	iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
+	iotable_init(mach_desc, mach_size);
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2443 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2443_core_init(void)
+{
+	return sysdev_class_register(&s3c2443_sysclass);
+}
+
+core_initcall(s3c2443_core_init);
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 2fbb74969379563e5020936997bf90075fa194f4..6a2d1070e5a08825e35b2e9db24519e9578ff8a1 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -49,6 +49,7 @@
 #include "s3c244x.h"
 #include <asm/plat-s3c24xx/s3c2440.h>
 #include <asm/plat-s3c24xx/s3c2442.h>
+#include <asm/plat-s3c24xx/s3c2443.h>
 
 struct cpu_table {
 	unsigned long	idcode;
@@ -67,6 +68,7 @@ static const char name_s3c2410[]  = "S3C2410";
 static const char name_s3c2412[]  = "S3C2412";
 static const char name_s3c2440[]  = "S3C2440";
 static const char name_s3c2442[]  = "S3C2442";
+static const char name_s3c2443[]  = "S3C2443";
 static const char name_s3c2410a[] = "S3C2410A";
 static const char name_s3c2440a[] = "S3C2440A";
 
@@ -134,6 +136,15 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.init		= s3c2412_init,
 		.name		= name_s3c2412,
 	},
+	{
+		.idcode		= 0x32443001,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2443_map_io,
+		.init_clocks	= s3c2443_init_clocks,
+		.init_uarts	= s3c2443_init_uarts,
+		.init		= s3c2443_init,
+		.name		= name_s3c2443,
+	},
 	{
 		.idcode		= 0x0,   /* S3C2400 doesn't have an idcode */
 		.idmask		= 0xffffffff,
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
index 87aace4c8f8cdfafb56b9bf3a2f6faefbbeb17e1..767f2e9a3a555beff2d3e05388ad1ac9800f7590 100644
--- a/arch/arm/plat-s3c24xx/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2004-2006 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
- * Samsung S3C2440 and S3C2442 Mobile CPU support
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
  *
  * 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
diff --git a/include/asm-arm/plat-s3c24xx/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h
index 8181b22532bd8e1380f54add378d9cec23cf4680..15dd18810905c6f499af7f0e37cec0e0610e13b7 100644
--- a/include/asm-arm/plat-s3c24xx/cpu.h
+++ b/include/asm-arm/plat-s3c24xx/cpu.h
@@ -67,3 +67,4 @@ extern struct sysdev_class s3c2410_sysclass;
 extern struct sysdev_class s3c2412_sysclass;
 extern struct sysdev_class s3c2440_sysclass;
 extern struct sysdev_class s3c2442_sysclass;
+extern struct sysdev_class s3c2443_sysclass;
diff --git a/include/asm-arm/plat-s3c24xx/s3c2443.h b/include/asm-arm/plat-s3c24xx/s3c2443.h
new file mode 100644
index 0000000000000000000000000000000000000000..11d83b5c84e60683a8e715e13550fd7206553d1f
--- /dev/null
+++ b/include/asm-arm/plat-s3c24xx/s3c2443.h
@@ -0,0 +1,32 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2443 cpu 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2443
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2443_init(void);
+
+extern void s3c2443_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2443_init_clocks(int xtal);
+
+extern  int s3c2443_baseclk_add(void);
+
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif