Merge branch 'next-samsung-board' into next-samsung-devel-2
diff --git a/arch/arm/configs/exynos4_defconfig b/arch/arm/configs/exynos4_defconfig
index da53ff3..cd40bb5 100644
--- a/arch/arm/configs/exynos4_defconfig
+++ b/arch/arm/configs/exynos4_defconfig
@@ -11,6 +11,7 @@
 CONFIG_MACH_ARMLEX4210=y
 CONFIG_MACH_UNIVERSAL_C210=y
 CONFIG_MACH_NURI=y
+CONFIG_MACH_ORIGEN=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index bee8f77..c595bb0 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -15,6 +15,11 @@
 	help
 	  Enable EXYNOS4210 CPU support
 
+config SOC_EXYNOS4212
+	bool
+	help
+	  Enable EXYNOS4212 SoC support
+
 config EXYNOS4_MCT
 	bool
 	default y
@@ -111,6 +116,8 @@
 
 menu "EXYNOS4 Machines"
 
+comment "EXYNOS4210 Boards"
+
 config MACH_SMDKC210
 	bool "SMDKC210"
 	select MACH_SMDKV310
@@ -203,6 +210,39 @@
 	help
 	  Machine support for Samsung Mobile NURI Board.
 
+config MACH_ORIGEN
+	bool "ORIGEN"
+	select CPU_EXYNOS4210
+	select S3C_DEV_RTC
+	select S3C_DEV_WDT
+	select S3C_DEV_HSMMC2
+	select EXYNOS4_SETUP_SDHCI
+	help
+	  Machine support for ORIGEN based on Samsung EXYNOS4210
+
+comment "EXYNOS4212 Boards"
+
+config MACH_SMDK4212
+	bool "SMDK4212"
+	select SOC_EXYNOS4212
+	select S3C_DEV_HSMMC2
+	select S3C_DEV_HSMMC3
+	select S3C_DEV_I2C1
+	select S3C_DEV_I2C3
+	select S3C_DEV_I2C7
+	select S3C_DEV_RTC
+	select S3C_DEV_WDT
+	select SAMSUNG_DEV_BACKLIGHT
+	select SAMSUNG_DEV_KEYPAD
+	select SAMSUNG_DEV_PWM
+	select EXYNOS4_SETUP_I2C1
+	select EXYNOS4_SETUP_I2C3
+	select EXYNOS4_SETUP_I2C7
+	select EXYNOS4_SETUP_KEYPAD
+	select EXYNOS4_SETUP_SDHCI
+	help
+	  Machine support for Samsung SMDK4212
+
 endmenu
 
 comment "Configuration for HSMMC bus width"
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index e3e93ea..e19cd12 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -12,8 +12,10 @@
 
 # Core support for EXYNOS4 system
 
-obj-$(CONFIG_CPU_EXYNOS4210)	+= cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o dma.o pmu.o
+obj-$(CONFIG_ARCH_EXYNOS4)	+= cpu.o init.o clock.o irq-combiner.o
+obj-$(CONFIG_ARCH_EXYNOS4)	+= setup-i2c0.o irq-eint.o dma.o pmu.o
+obj-$(CONFIG_CPU_EXYNOS4210)	+= clock-exynos4210.o
+obj-$(CONFIG_SOC_EXYNOS4212)	+= clock-exynos4212.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
@@ -30,6 +32,9 @@
 obj-$(CONFIG_MACH_ARMLEX4210)		+= mach-armlex4210.o
 obj-$(CONFIG_MACH_UNIVERSAL_C210)	+= mach-universal_c210.o
 obj-$(CONFIG_MACH_NURI)			+= mach-nuri.o
+obj-$(CONFIG_MACH_ORIGEN)		+= mach-origen.o
+
+obj-$(CONFIG_MACH_SMDK4212)		+= mach-smdk4212.o
 
 # device support
 
diff --git a/arch/arm/mach-exynos4/clock-exynos4210.c b/arch/arm/mach-exynos4/clock-exynos4210.c
new file mode 100644
index 0000000..b9d5ef6
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock-exynos4210.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/mach-exynos4/clock-exynos4210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * EXYNOS4210 - Clock 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/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos4-clock.h>
+
+static struct sleep_save exynos4210_clock_save[] = {
+	SAVE_ITEM(S5P_CLKSRC_IMAGE),
+	SAVE_ITEM(S5P_CLKSRC_LCD1),
+	SAVE_ITEM(S5P_CLKDIV_IMAGE),
+	SAVE_ITEM(S5P_CLKDIV_LCD1),
+	SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
+	SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4210),
+	SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
+	SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4210),
+};
+
+static struct clksrc_clk *sysclks[] = {
+	/* nothing here yet */
+};
+
+static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
+}
+
+static struct clksrc_clk clksrcs[] = {
+	{
+		.clk		= {
+			.name		= "sclk_sata",
+			.id		= -1,
+			.enable		= exynos4_clksrc_mask_fsys_ctrl,
+			.ctrlbit	= (1 << 24),
+		},
+		.sources = &clkset_mout_corebus,
+		.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
+		.reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+	}, {
+		.clk		= {
+			.name		= "sclk_fimd",
+			.devname	= "exynos4-fb.1",
+			.enable		= exynos4_clksrc_mask_lcd1_ctrl,
+			.ctrlbit	= (1 << 0),
+		},
+		.sources = &clkset_group,
+		.reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
+		.reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
+	},
+};
+
+static struct clk init_clocks_off[] = {
+	{
+		.name		= "sataphy",
+		.id		= -1,
+		.parent		= &clk_aclk_133.clk,
+		.enable		= exynos4_clk_ip_fsys_ctrl,
+		.ctrlbit	= (1 << 3),
+	}, {
+		.name		= "sata",
+		.id		= -1,
+		.parent		= &clk_aclk_133.clk,
+		.enable		= exynos4_clk_ip_fsys_ctrl,
+		.ctrlbit	= (1 << 10),
+	}, {
+		.name		= "fimd",
+		.devname	= "exynos4-fb.1",
+		.enable		= exynos4_clk_ip_lcd1_ctrl,
+		.ctrlbit	= (1 << 0),
+	},
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4210_clock_suspend(void)
+{
+	s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
+
+	return 0;
+}
+
+static void exynos4210_clock_resume(void)
+{
+	s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
+}
+
+#else
+#define exynos4210_clock_suspend NULL
+#define exynos4210_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4210_clock_syscore_ops = {
+	.suspend	= exynos4210_clock_suspend,
+	.resume		= exynos4210_clock_resume,
+};
+
+void __init exynos4210_register_clocks(void)
+{
+	int ptr;
+
+	clk_mout_mpll.reg_src.reg = S5P_CLKSRC_CPU;
+	clk_mout_mpll.reg_src.shift = 8;
+	clk_mout_mpll.reg_src.size = 1;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+		s3c_register_clksrc(sysclks[ptr], 1);
+
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+
+	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+	register_syscore_ops(&exynos4210_clock_syscore_ops);
+}
diff --git a/arch/arm/mach-exynos4/clock-exynos4212.c b/arch/arm/mach-exynos4/clock-exynos4212.c
new file mode 100644
index 0000000..77d5dec
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock-exynos4212.c
@@ -0,0 +1,118 @@
+/*
+ * linux/arch/arm/mach-exynos4/clock-exynos4212.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * EXYNOS4212 - Clock 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/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos4-clock.h>
+
+static struct sleep_save exynos4212_clock_save[] = {
+	SAVE_ITEM(S5P_CLKSRC_IMAGE),
+	SAVE_ITEM(S5P_CLKDIV_IMAGE),
+	SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4212),
+	SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4212),
+};
+
+static struct clk *clk_src_mpll_user_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clk_src_mpll_user = {
+	.sources	= clk_src_mpll_user_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_user_list),
+};
+
+static struct clksrc_clk clk_mout_mpll_user = {
+	.clk = {
+		.name		= "mout_mpll_user",
+	},
+	.sources	= &clk_src_mpll_user,
+	.reg_src	= { .reg = S5P_CLKSRC_CPU, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk *sysclks[] = {
+	&clk_mout_mpll_user,
+};
+
+static struct clksrc_clk clksrcs[] = {
+	/* nothing here yet */
+};
+
+static struct clk init_clocks_off[] = {
+	/* nothing here yet */
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4212_clock_suspend(void)
+{
+	s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
+
+	return 0;
+}
+
+static void exynos4212_clock_resume(void)
+{
+	s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
+}
+
+#else
+#define exynos4212_clock_suspend NULL
+#define exynos4212_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4212_clock_syscore_ops = {
+	.suspend	= exynos4212_clock_suspend,
+	.resume		= exynos4212_clock_resume,
+};
+
+void __init exynos4212_register_clocks(void)
+{
+	int ptr;
+
+	/* usbphy1 is removed */
+	clkset_group_list[4] = NULL;
+
+	/* mout_mpll_user is used */
+	clkset_group_list[6] = &clk_mout_mpll_user.clk;
+	clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
+
+	clk_mout_mpll.reg_src.reg = S5P_CLKSRC_DMC;
+	clk_mout_mpll.reg_src.shift = 12;
+	clk_mout_mpll.reg_src.size = 1;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+		s3c_register_clksrc(sysclks[ptr], 1);
+
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+
+	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+	register_syscore_ops(&exynos4212_clock_syscore_ops);
+}
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 86964d2..413c7cc 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/syscore_ops.h>
 
 #include <plat/cpu-freq.h>
 #include <plat/clock.h>
@@ -20,26 +21,93 @@
 #include <plat/pll.h>
 #include <plat/s5p-clock.h>
 #include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 #include <mach/sysmmu.h>
+#include <mach/exynos4-clock.h>
 
-static struct clk clk_sclk_hdmi27m = {
+static struct sleep_save exynos4_clock_save[] = {
+	SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
+	SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
+	SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
+	SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
+	SAVE_ITEM(S5P_CLKSRC_TOP0),
+	SAVE_ITEM(S5P_CLKSRC_TOP1),
+	SAVE_ITEM(S5P_CLKSRC_CAM),
+	SAVE_ITEM(S5P_CLKSRC_TV),
+	SAVE_ITEM(S5P_CLKSRC_MFC),
+	SAVE_ITEM(S5P_CLKSRC_G3D),
+	SAVE_ITEM(S5P_CLKSRC_LCD0),
+	SAVE_ITEM(S5P_CLKSRC_MAUDIO),
+	SAVE_ITEM(S5P_CLKSRC_FSYS),
+	SAVE_ITEM(S5P_CLKSRC_PERIL0),
+	SAVE_ITEM(S5P_CLKSRC_PERIL1),
+	SAVE_ITEM(S5P_CLKDIV_CAM),
+	SAVE_ITEM(S5P_CLKDIV_TV),
+	SAVE_ITEM(S5P_CLKDIV_MFC),
+	SAVE_ITEM(S5P_CLKDIV_G3D),
+	SAVE_ITEM(S5P_CLKDIV_LCD0),
+	SAVE_ITEM(S5P_CLKDIV_MAUDIO),
+	SAVE_ITEM(S5P_CLKDIV_FSYS0),
+	SAVE_ITEM(S5P_CLKDIV_FSYS1),
+	SAVE_ITEM(S5P_CLKDIV_FSYS2),
+	SAVE_ITEM(S5P_CLKDIV_FSYS3),
+	SAVE_ITEM(S5P_CLKDIV_PERIL0),
+	SAVE_ITEM(S5P_CLKDIV_PERIL1),
+	SAVE_ITEM(S5P_CLKDIV_PERIL2),
+	SAVE_ITEM(S5P_CLKDIV_PERIL3),
+	SAVE_ITEM(S5P_CLKDIV_PERIL4),
+	SAVE_ITEM(S5P_CLKDIV_PERIL5),
+	SAVE_ITEM(S5P_CLKDIV_TOP),
+	SAVE_ITEM(S5P_CLKSRC_MASK_TOP),
+	SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
+	SAVE_ITEM(S5P_CLKSRC_MASK_TV),
+	SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
+	SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
+	SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
+	SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
+	SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
+	SAVE_ITEM(S5P_CLKDIV2_RATIO),
+	SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
+	SAVE_ITEM(S5P_CLKGATE_IP_CAM),
+	SAVE_ITEM(S5P_CLKGATE_IP_TV),
+	SAVE_ITEM(S5P_CLKGATE_IP_MFC),
+	SAVE_ITEM(S5P_CLKGATE_IP_G3D),
+	SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
+	SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
+	SAVE_ITEM(S5P_CLKGATE_IP_GPS),
+	SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
+	SAVE_ITEM(S5P_CLKGATE_BLOCK),
+	SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
+	SAVE_ITEM(S5P_CLKSRC_DMC),
+	SAVE_ITEM(S5P_CLKDIV_DMC0),
+	SAVE_ITEM(S5P_CLKDIV_DMC1),
+	SAVE_ITEM(S5P_CLKGATE_IP_DMC),
+	SAVE_ITEM(S5P_CLKSRC_CPU),
+	SAVE_ITEM(S5P_CLKDIV_CPU),
+	SAVE_ITEM(S5P_CLKDIV_CPU + 0x4),
+	SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
+	SAVE_ITEM(S5P_CLKGATE_IP_CPU),
+};
+
+struct clk clk_sclk_hdmi27m = {
 	.name		= "sclk_hdmi27m",
 	.rate		= 27000000,
 };
 
-static struct clk clk_sclk_hdmiphy = {
+struct clk clk_sclk_hdmiphy = {
 	.name		= "sclk_hdmiphy",
 };
 
-static struct clk clk_sclk_usbphy0 = {
+struct clk clk_sclk_usbphy0 = {
 	.name		= "sclk_usbphy0",
 	.rate		= 27000000,
 };
 
-static struct clk clk_sclk_usbphy1 = {
+struct clk clk_sclk_usbphy1 = {
 	.name		= "sclk_usbphy1",
 };
 
@@ -58,12 +126,7 @@
 	return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
 }
 
-static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
-{
-	return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
-}
-
-static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
 }
@@ -103,12 +166,12 @@
 	return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
 }
 
-static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
 }
 
-static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
 }
@@ -133,7 +196,7 @@
 	.reg_src	= { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
 };
 
-static struct clksrc_clk clk_sclk_apll = {
+struct clksrc_clk clk_sclk_apll = {
 	.clk	= {
 		.name		= "sclk_apll",
 		.parent		= &clk_mout_apll.clk,
@@ -141,7 +204,7 @@
 	.reg_div	= { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
 };
 
-static struct clksrc_clk clk_mout_epll = {
+struct clksrc_clk clk_mout_epll = {
 	.clk	= {
 		.name		= "mout_epll",
 	},
@@ -149,12 +212,13 @@
 	.reg_src	= { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
 };
 
-static struct clksrc_clk clk_mout_mpll = {
+struct clksrc_clk clk_mout_mpll = {
 	.clk = {
 		.name		= "mout_mpll",
 	},
 	.sources	= &clk_src_mpll,
-	.reg_src	= { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
+
+	/* reg_src will be added in each SoCs' clock */
 };
 
 static struct clk *clkset_moutcore_list[] = {
@@ -224,12 +288,12 @@
 
 /* Core list of CMU_CORE side */
 
-static struct clk *clkset_corebus_list[] = {
+struct clk *clkset_corebus_list[] = {
 	[0] = &clk_mout_mpll.clk,
 	[1] = &clk_sclk_apll.clk,
 };
 
-static struct clksrc_sources clkset_mout_corebus = {
+struct clksrc_sources clkset_mout_corebus = {
 	.sources	= clkset_corebus_list,
 	.nr_sources	= ARRAY_SIZE(clkset_corebus_list),
 };
@@ -284,12 +348,12 @@
 
 /* Core list of CMU_TOP side */
 
-static struct clk *clkset_aclk_top_list[] = {
+struct clk *clkset_aclk_top_list[] = {
 	[0] = &clk_mout_mpll.clk,
 	[1] = &clk_sclk_apll.clk,
 };
 
-static struct clksrc_sources clkset_aclk = {
+struct clksrc_sources clkset_aclk = {
 	.sources	= clkset_aclk_top_list,
 	.nr_sources	= ARRAY_SIZE(clkset_aclk_top_list),
 };
@@ -321,7 +385,7 @@
 	.reg_div	= { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
 };
 
-static struct clksrc_clk clk_aclk_133 = {
+struct clksrc_clk clk_aclk_133 = {
 	.clk	= {
 		.name		= "aclk_133",
 	},
@@ -360,7 +424,7 @@
 	.nr_sources	= ARRAY_SIZE(clkset_sclk_vpll_list),
 };
 
-static struct clksrc_clk clk_sclk_vpll = {
+struct clksrc_clk clk_sclk_vpll = {
 	.clk	= {
 		.name		= "sclk_vpll",
 	},
@@ -410,16 +474,6 @@
 		.enable		= exynos4_clk_ip_lcd0_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
-		.name		= "fimd",
-		.devname	= "exynos4-fb.1",
-		.enable		= exynos4_clk_ip_lcd1_ctrl,
-		.ctrlbit	= (1 << 0),
-	}, {
-		.name		= "sataphy",
-		.parent		= &clk_aclk_133.clk,
-		.enable		= exynos4_clk_ip_fsys_ctrl,
-		.ctrlbit	= (1 << 3),
-	}, {
 		.name		= "hsmmc",
 		.devname	= "s3c-sdhci.0",
 		.parent		= &clk_aclk_133.clk,
@@ -449,11 +503,6 @@
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 9),
 	}, {
-		.name		= "sata",
-		.parent		= &clk_aclk_133.clk,
-		.enable		= exynos4_clk_ip_fsys_ctrl,
-		.ctrlbit	= (1 << 10),
-	}, {
 		.name		= "pdma",
 		.devname	= "s3c-pl330.0",
 		.enable		= exynos4_clk_ip_fsys_ctrl,
@@ -673,7 +722,7 @@
 	}
 };
 
-static struct clk *clkset_group_list[] = {
+struct clk *clkset_group_list[] = {
 	[0] = &clk_ext_xtal_mux,
 	[1] = &clk_xusbxti,
 	[2] = &clk_sclk_hdmi27m,
@@ -685,7 +734,7 @@
 	[8] = &clk_sclk_vpll.clk,
 };
 
-static struct clksrc_sources clkset_group = {
+struct clksrc_sources clkset_group = {
 	.sources	= clkset_group_list,
 	.nr_sources	= ARRAY_SIZE(clkset_group_list),
 };
@@ -967,25 +1016,6 @@
 		.reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
 	}, {
 		.clk		= {
-			.name		= "sclk_fimd",
-			.devname	= "exynos4-fb.1",
-			.enable		= exynos4_clksrc_mask_lcd1_ctrl,
-			.ctrlbit	= (1 << 0),
-		},
-		.sources = &clkset_group,
-		.reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
-		.reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
-	}, {
-		.clk		= {
-			.name		= "sclk_sata",
-			.enable		= exynos4_clksrc_mask_fsys_ctrl,
-			.ctrlbit	= (1 << 24),
-		},
-		.sources = &clkset_mout_corebus,
-		.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
-		.reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
-	}, {
-		.clk		= {
 			.name		= "sclk_spi",
 			.devname	= "s3c64xx-spi.0",
 			.enable		= exynos4_clksrc_mask_peril1_ctrl,
@@ -1114,7 +1144,13 @@
 
 static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
 {
-	return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
+	if (soc_is_exynos4210())
+		return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0),
+					pll_4508);
+	else if (soc_is_exynos4212())
+		return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0));
+	else
+		return 0;
 }
 
 static struct clk_ops exynos4_fout_apll_ops = {
@@ -1124,10 +1160,10 @@
 void __init_or_cpufreq exynos4_setup_clocks(void)
 {
 	struct clk *xtal_clk;
-	unsigned long apll;
-	unsigned long mpll;
-	unsigned long epll;
-	unsigned long vpll;
+	unsigned long apll = 0;
+	unsigned long mpll = 0;
+	unsigned long epll = 0;
+	unsigned long vpll = 0;
 	unsigned long vpllsrc;
 	unsigned long xtal;
 	unsigned long armclk;
@@ -1151,14 +1187,29 @@
 
 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
 
-	apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
-	mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
-	epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
-				__raw_readl(S5P_EPLL_CON1), pll_4600);
+	if (soc_is_exynos4210()) {
+		apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0),
+					pll_4508);
+		mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0),
+					pll_4508);
+		epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
+					__raw_readl(S5P_EPLL_CON1), pll_4600);
 
-	vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
-	vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
-				__raw_readl(S5P_VPLL_CON1), pll_4650c);
+		vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+		vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
+					__raw_readl(S5P_VPLL_CON1), pll_4650c);
+	} else if (soc_is_exynos4212()) {
+		apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0));
+		mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0));
+		epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0),
+					__raw_readl(S5P_EPLL_CON1));
+
+		vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+		vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
+					__raw_readl(S5P_VPLL_CON1));
+	} else {
+		/* nothing */
+	}
 
 	clk_fout_apll.ops = &exynos4_fout_apll_ops;
 	clk_fout_mpll.rate = mpll;
@@ -1193,6 +1244,28 @@
 	/* Nothing here yet */
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int exynos4_clock_suspend(void)
+{
+	s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+	return 0;
+}
+
+static void exynos4_clock_resume(void)
+{
+	s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+}
+
+#else
+#define exynos4_clock_suspend NULL
+#define exynos4_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4_clock_syscore_ops = {
+	.suspend	= exynos4_clock_suspend,
+	.resume		= exynos4_clock_resume,
+};
+
 void __init exynos4_register_clocks(void)
 {
 	int ptr;
@@ -1208,5 +1281,6 @@
 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
+	register_syscore_ops(&exynos4_clock_syscore_ops);
 	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 746d6fc..02ec52a 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -44,11 +44,6 @@
 		.length		= SZ_4K,
 		.type	 	= MT_DEVICE,
 	}, {
-		.virtual	= (unsigned long)S5P_VA_SYSRAM,
-		.pfn		= __phys_to_pfn(EXYNOS4_PA_SYSRAM),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	}, {
 		.virtual	= (unsigned long)S5P_VA_CMU,
 		.pfn		= __phys_to_pfn(EXYNOS4_PA_CMU),
 		.length		= SZ_128K,
@@ -121,6 +116,24 @@
 	},
 };
 
+static struct map_desc exynos4_iodesc0[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM,
+		.pfn		= __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static struct map_desc exynos4_iodesc1[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM,
+		.pfn		= __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
 static void exynos4_idle(void)
 {
 	if (!need_resched())
@@ -143,6 +156,11 @@
 {
 	iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
 
+	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
+		iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0));
+	else
+		iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
+
 	/* initialize device information early */
 	exynos4_default_sdhci0();
 	exynos4_default_sdhci1();
@@ -170,6 +188,12 @@
 
 	s3c24xx_register_baseclocks(xtal);
 	s5p_register_clocks(xtal);
+
+	if (soc_is_exynos4210())
+		exynos4210_register_clocks();
+	else if (soc_is_exynos4212())
+		exynos4212_register_clocks();
+
 	exynos4_register_clocks();
 	exynos4_setup_clocks();
 }
@@ -223,7 +247,11 @@
 {
 	/* TAG, Data Latency Control: 2cycle */
 	__raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
-	__raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+
+	if (soc_is_exynos4210())
+		__raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+	else if (soc_is_exynos4212())
+		__raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
 
 	/* L2X0 Prefetch Control */
 	__raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
diff --git a/arch/arm/mach-exynos4/include/mach/exynos4-clock.h b/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
new file mode 100644
index 0000000..a07fcbf
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Header file for exynos4 clock 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.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clk clk_sclk_hdmi27m;
+extern struct clk clk_sclk_usbphy0;
+extern struct clk clk_sclk_usbphy1;
+extern struct clk clk_sclk_hdmiphy;
+
+extern struct clksrc_clk clk_sclk_apll;
+extern struct clksrc_clk clk_mout_mpll;
+extern struct clksrc_clk clk_aclk_133;
+extern struct clksrc_clk clk_mout_epll;
+extern struct clksrc_clk clk_sclk_vpll;
+
+extern struct clk *clkset_corebus_list[];
+extern struct clksrc_sources clkset_mout_corebus;
+
+extern struct clk *clkset_aclk_top_list[];
+extern struct clksrc_sources clkset_aclk;
+
+extern struct clk *clkset_group_list[];
+extern struct clksrc_sources clkset_group;
+
+extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index d32296d..7073ac7 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -23,7 +23,8 @@
 
 #include <plat/map-s5p.h>
 
-#define EXYNOS4_PA_SYSRAM		0x02020000
+#define EXYNOS4_PA_SYSRAM0		0x02025000
+#define EXYNOS4_PA_SYSRAM1		0x02020000
 
 #define EXYNOS4_PA_FIMC0		0x11800000
 #define EXYNOS4_PA_FIMC1		0x11810000
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
index d493fdb..6c37ebe 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
@@ -13,6 +13,7 @@
 #ifndef __ASM_ARCH_REGS_CLOCK_H
 #define __ASM_ARCH_REGS_CLOCK_H __FILE__
 
+#include <plat/cpu.h>
 #include <mach/map.h>
 
 #define S5P_CLKREG(x)			(S5P_VA_CMU + (x))
@@ -41,12 +42,20 @@
 #define S5P_CLKSRC_G3D			S5P_CLKREG(0x0C22C)
 #define S5P_CLKSRC_IMAGE		S5P_CLKREG(0x0C230)
 #define S5P_CLKSRC_LCD0			S5P_CLKREG(0x0C234)
-#define S5P_CLKSRC_LCD1			S5P_CLKREG(0x0C238)
 #define S5P_CLKSRC_MAUDIO		S5P_CLKREG(0x0C23C)
 #define S5P_CLKSRC_FSYS			S5P_CLKREG(0x0C240)
 #define S5P_CLKSRC_PERIL0		S5P_CLKREG(0x0C250)
 #define S5P_CLKSRC_PERIL1		S5P_CLKREG(0x0C254)
 
+#define S5P_CLKSRC_MASK_TOP		S5P_CLKREG(0x0C310)
+#define S5P_CLKSRC_MASK_CAM		S5P_CLKREG(0x0C320)
+#define S5P_CLKSRC_MASK_TV		S5P_CLKREG(0x0C324)
+#define S5P_CLKSRC_MASK_LCD0		S5P_CLKREG(0x0C334)
+#define S5P_CLKSRC_MASK_MAUDIO		S5P_CLKREG(0x0C33C)
+#define S5P_CLKSRC_MASK_FSYS		S5P_CLKREG(0x0C340)
+#define S5P_CLKSRC_MASK_PERIL0		S5P_CLKREG(0x0C350)
+#define S5P_CLKSRC_MASK_PERIL1		S5P_CLKREG(0x0C354)
+
 #define S5P_CLKDIV_TOP			S5P_CLKREG(0x0C510)
 #define S5P_CLKDIV_CAM			S5P_CLKREG(0x0C520)
 #define S5P_CLKDIV_TV			S5P_CLKREG(0x0C524)
@@ -54,7 +63,6 @@
 #define S5P_CLKDIV_G3D			S5P_CLKREG(0x0C52C)
 #define S5P_CLKDIV_IMAGE		S5P_CLKREG(0x0C530)
 #define S5P_CLKDIV_LCD0			S5P_CLKREG(0x0C534)
-#define S5P_CLKDIV_LCD1			S5P_CLKREG(0x0C538)
 #define S5P_CLKDIV_MAUDIO		S5P_CLKREG(0x0C53C)
 #define S5P_CLKDIV_FSYS0		S5P_CLKREG(0x0C540)
 #define S5P_CLKDIV_FSYS1		S5P_CLKREG(0x0C544)
@@ -68,16 +76,6 @@
 #define S5P_CLKDIV_PERIL5		S5P_CLKREG(0x0C564)
 #define S5P_CLKDIV2_RATIO		S5P_CLKREG(0x0C580)
 
-#define S5P_CLKSRC_MASK_TOP		S5P_CLKREG(0x0C310)
-#define S5P_CLKSRC_MASK_CAM		S5P_CLKREG(0x0C320)
-#define S5P_CLKSRC_MASK_TV		S5P_CLKREG(0x0C324)
-#define S5P_CLKSRC_MASK_LCD0		S5P_CLKREG(0x0C334)
-#define S5P_CLKSRC_MASK_LCD1		S5P_CLKREG(0x0C338)
-#define S5P_CLKSRC_MASK_MAUDIO		S5P_CLKREG(0x0C33C)
-#define S5P_CLKSRC_MASK_FSYS		S5P_CLKREG(0x0C340)
-#define S5P_CLKSRC_MASK_PERIL0		S5P_CLKREG(0x0C350)
-#define S5P_CLKSRC_MASK_PERIL1		S5P_CLKREG(0x0C354)
-
 #define S5P_CLKDIV_STAT_TOP		S5P_CLKREG(0x0C610)
 
 #define S5P_CLKGATE_SCLKCAM		S5P_CLKREG(0x0C820)
@@ -85,13 +83,20 @@
 #define S5P_CLKGATE_IP_TV		S5P_CLKREG(0x0C924)
 #define S5P_CLKGATE_IP_MFC		S5P_CLKREG(0x0C928)
 #define S5P_CLKGATE_IP_G3D		S5P_CLKREG(0x0C92C)
-#define S5P_CLKGATE_IP_IMAGE		S5P_CLKREG(0x0C930)
+#define S5P_CLKGATE_IP_IMAGE		(soc_is_exynos4210() ? \
+					S5P_CLKREG(0x0C930) : \
+					S5P_CLKREG(0x04930))
+#define S5P_CLKGATE_IP_IMAGE_4210	S5P_CLKREG(0x0C930)
+#define S5P_CLKGATE_IP_IMAGE_4212	S5P_CLKREG(0x04930)
 #define S5P_CLKGATE_IP_LCD0		S5P_CLKREG(0x0C934)
-#define S5P_CLKGATE_IP_LCD1		S5P_CLKREG(0x0C938)
 #define S5P_CLKGATE_IP_FSYS		S5P_CLKREG(0x0C940)
 #define S5P_CLKGATE_IP_GPS		S5P_CLKREG(0x0C94C)
 #define S5P_CLKGATE_IP_PERIL		S5P_CLKREG(0x0C950)
-#define S5P_CLKGATE_IP_PERIR		S5P_CLKREG(0x0C960)
+#define S5P_CLKGATE_IP_PERIR		(soc_is_exynos4210() ? \
+					S5P_CLKREG(0x0C960) : \
+					S5P_CLKREG(0x08960))
+#define S5P_CLKGATE_IP_PERIR_4210	S5P_CLKREG(0x0C960)
+#define S5P_CLKGATE_IP_PERIR_4212	S5P_CLKREG(0x08960)
 #define S5P_CLKGATE_BLOCK		S5P_CLKREG(0x0C970)
 
 #define S5P_CLKSRC_MASK_DMC		S5P_CLKREG(0x10300)
@@ -102,11 +107,17 @@
 #define S5P_CLKGATE_IP_DMC		S5P_CLKREG(0x10900)
 
 #define S5P_APLL_LOCK			S5P_CLKREG(0x14000)
-#define S5P_MPLL_LOCK			S5P_CLKREG(0x14004)
+#define S5P_MPLL_LOCK			(soc_is_exynos4210() ? \
+					S5P_CLKREG(0x14004) :  \
+					S5P_CLKREG(0x10008))
 #define S5P_APLL_CON0			S5P_CLKREG(0x14100)
 #define S5P_APLL_CON1			S5P_CLKREG(0x14104)
-#define S5P_MPLL_CON0			S5P_CLKREG(0x14108)
-#define S5P_MPLL_CON1			S5P_CLKREG(0x1410C)
+#define S5P_MPLL_CON0			(soc_is_exynos4210() ? \
+					S5P_CLKREG(0x14108) : \
+					S5P_CLKREG(0x10108))
+#define S5P_MPLL_CON1			(soc_is_exynos4210() ? \
+					S5P_CLKREG(0x1410C) : \
+					S5P_CLKREG(0x1010C))
 
 #define S5P_CLKSRC_CPU			S5P_CLKREG(0x14200)
 #define S5P_CLKMUX_STATCPU		S5P_CLKREG(0x14400)
@@ -183,6 +194,13 @@
 #define S5P_CLKDIV_BUS_GPLR_SHIFT	(4)
 #define S5P_CLKDIV_BUS_GPLR_MASK	(0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
 
+/* Only for EXYNOS4210 */
+
+#define S5P_CLKSRC_LCD1			S5P_CLKREG(0x0C238)
+#define S5P_CLKSRC_MASK_LCD1		S5P_CLKREG(0x0C338)
+#define S5P_CLKDIV_LCD1			S5P_CLKREG(0x0C538)
+#define S5P_CLKGATE_IP_LCD1		S5P_CLKREG(0x0C938)
+
 /* Compatibility defines and inclusion */
 
 #include <mach/regs-pmu.h>
diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c
new file mode 100644
index 0000000..ed59f86
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-origen.c
@@ -0,0 +1,108 @@
+/* linux/arch/arm/mach-exynos4/mach-origen.c
+ *
+ * Copyright (c) 2011 Insignal Co., Ltd.
+ *		http://www.insignal.co.kr/
+ *
+ * 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/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/input.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/iic.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define ORIGEN_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
+				 S3C2410_UCON_RXILEVEL |	\
+				 S3C2410_UCON_TXIRQMODE |	\
+				 S3C2410_UCON_RXIRQMODE |	\
+				 S3C2410_UCON_RXFIFO_TOI |	\
+				 S3C2443_UCON_RXERR_IRQEN)
+
+#define ORIGEN_ULCON_DEFAULT	S3C2410_LCON_CS8
+
+#define ORIGEN_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
+				 S5PV210_UFCON_TXTRIG4 |	\
+				 S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport		= 0,
+		.flags		= 0,
+		.ucon		= ORIGEN_UCON_DEFAULT,
+		.ulcon		= ORIGEN_ULCON_DEFAULT,
+		.ufcon		= ORIGEN_UFCON_DEFAULT,
+	},
+	[1] = {
+		.hwport		= 1,
+		.flags		= 0,
+		.ucon		= ORIGEN_UCON_DEFAULT,
+		.ulcon		= ORIGEN_ULCON_DEFAULT,
+		.ufcon		= ORIGEN_UFCON_DEFAULT,
+	},
+	[2] = {
+		.hwport		= 2,
+		.flags		= 0,
+		.ucon		= ORIGEN_UCON_DEFAULT,
+		.ulcon		= ORIGEN_ULCON_DEFAULT,
+		.ufcon		= ORIGEN_UFCON_DEFAULT,
+	},
+	[3] = {
+		.hwport		= 3,
+		.flags		= 0,
+		.ucon		= ORIGEN_UCON_DEFAULT,
+		.ulcon		= ORIGEN_ULCON_DEFAULT,
+		.ufcon		= ORIGEN_UFCON_DEFAULT,
+	},
+};
+
+static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
+	.cd_type		= S3C_SDHCI_CD_GPIO,
+	.ext_cd_gpio		= EXYNOS4_GPK2(2),
+	.ext_cd_gpio_invert	= 1,
+	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct platform_device *origen_devices[] __initdata = {
+	&s3c_device_hsmmc2,
+	&s3c_device_rtc,
+	&s3c_device_wdt,
+};
+
+static void __init origen_map_io(void)
+{
+	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	s3c24xx_init_clocks(24000000);
+	s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
+}
+
+static void __init origen_machine_init(void)
+{
+	s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
+	platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
+}
+
+MACHINE_START(ORIGEN, "ORIGEN")
+	/* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
+	.boot_params	= S5P_PA_SDRAM + 0x100,
+	.init_irq	= exynos4_init_irq,
+	.map_io		= origen_map_io,
+	.init_machine	= origen_machine_init,
+	.timer		= &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdk4212.c b/arch/arm/mach-exynos4/mach-smdk4212.c
new file mode 100644
index 0000000..3479a93
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-smdk4212.c
@@ -0,0 +1,292 @@
+/*
+ * linux/arch/arm/mach-exynos4/mach-smdk4212.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.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/gpio.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/machine.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/backlight.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/keypad.h>
+#include <plat/regs-serial.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK4212_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
+				 S3C2410_UCON_RXILEVEL |	\
+				 S3C2410_UCON_TXIRQMODE |	\
+				 S3C2410_UCON_RXIRQMODE |	\
+				 S3C2410_UCON_RXFIFO_TOI |	\
+				 S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK4212_ULCON_DEFAULT	S3C2410_LCON_CS8
+
+#define SMDK4212_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
+				 S5PV210_UFCON_TXTRIG4 |	\
+				 S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk4212_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport		= 0,
+		.flags		= 0,
+		.ucon		= SMDK4212_UCON_DEFAULT,
+		.ulcon		= SMDK4212_ULCON_DEFAULT,
+		.ufcon		= SMDK4212_UFCON_DEFAULT,
+	},
+	[1] = {
+		.hwport		= 1,
+		.flags		= 0,
+		.ucon		= SMDK4212_UCON_DEFAULT,
+		.ulcon		= SMDK4212_ULCON_DEFAULT,
+		.ufcon		= SMDK4212_UFCON_DEFAULT,
+	},
+	[2] = {
+		.hwport		= 2,
+		.flags		= 0,
+		.ucon		= SMDK4212_UCON_DEFAULT,
+		.ulcon		= SMDK4212_ULCON_DEFAULT,
+		.ufcon		= SMDK4212_UFCON_DEFAULT,
+	},
+	[3] = {
+		.hwport		= 3,
+		.flags		= 0,
+		.ucon		= SMDK4212_UCON_DEFAULT,
+		.ulcon		= SMDK4212_ULCON_DEFAULT,
+		.ufcon		= SMDK4212_UFCON_DEFAULT,
+	},
+};
+
+static struct s3c_sdhci_platdata smdk4212_hsmmc2_pdata __initdata = {
+	.cd_type		= S3C_SDHCI_CD_INTERNAL,
+	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+	.max_width		= 8,
+	.host_caps		= MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdk4212_hsmmc3_pdata __initdata = {
+	.cd_type		= S3C_SDHCI_CD_INTERNAL,
+	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply max8997_buck1 =
+	REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2 =
+	REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max8997_buck3 =
+	REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_init_data max8997_buck1_data = {
+	.constraints	= {
+		.name		= "VDD_ARM_SMDK4212",
+		.min_uV		= 925000,
+		.max_uV		= 1350000,
+		.always_on	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+		.state_mem	= {
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &max8997_buck1,
+};
+
+static struct regulator_init_data max8997_buck2_data = {
+	.constraints	= {
+		.name		= "VDD_INT_SMDK4212",
+		.min_uV		= 950000,
+		.max_uV		= 1150000,
+		.always_on	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+		.state_mem	= {
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &max8997_buck2,
+};
+
+static struct regulator_init_data max8997_buck3_data = {
+	.constraints	= {
+		.name		= "VDD_G3D_SMDK4212",
+		.min_uV		= 950000,
+		.max_uV		= 1150000,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+		.state_mem	= {
+			.disabled	= 1,
+		},
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &max8997_buck3,
+};
+
+static struct max8997_regulator_data smdk4212_max8997_regulators[] = {
+	{ MAX8997_BUCK1, &max8997_buck1_data },
+	{ MAX8997_BUCK2, &max8997_buck2_data },
+	{ MAX8997_BUCK3, &max8997_buck3_data },
+};
+
+static struct max8997_platform_data smdk4212_max8997_pdata = {
+	.num_regulators	= ARRAY_SIZE(smdk4212_max8997_regulators),
+	.regulators	= smdk4212_max8997_regulators,
+
+	.buck1_voltage[0] = 1100000,	/* 1.1V */
+	.buck1_voltage[1] = 1100000,	/* 1.1V */
+	.buck1_voltage[2] = 1100000,	/* 1.1V */
+	.buck1_voltage[3] = 1100000,	/* 1.1V */
+	.buck1_voltage[4] = 1100000,	/* 1.1V */
+	.buck1_voltage[5] = 1100000,	/* 1.1V */
+	.buck1_voltage[6] = 1000000,	/* 1.0V */
+	.buck1_voltage[7] = 950000,	/* 0.95V */
+
+	.buck2_voltage[0] = 1100000,	/* 1.1V */
+	.buck2_voltage[1] = 1000000,	/* 1.0V */
+	.buck2_voltage[2] = 950000,	/* 0.95V */
+	.buck2_voltage[3] = 900000,	/* 0.9V */
+	.buck2_voltage[4] = 1100000,	/* 1.1V */
+	.buck2_voltage[5] = 1000000,	/* 1.0V */
+	.buck2_voltage[6] = 950000,	/* 0.95V */
+	.buck2_voltage[7] = 900000,	/* 0.9V */
+
+	.buck5_voltage[0] = 1100000,	/* 1.1V */
+	.buck5_voltage[1] = 1100000,	/* 1.1V */
+	.buck5_voltage[2] = 1100000,	/* 1.1V */
+	.buck5_voltage[3] = 1100000,	/* 1.1V */
+	.buck5_voltage[4] = 1100000,	/* 1.1V */
+	.buck5_voltage[5] = 1100000,	/* 1.1V */
+	.buck5_voltage[6] = 1100000,	/* 1.1V */
+	.buck5_voltage[7] = 1100000,	/* 1.1V */
+};
+
+static struct i2c_board_info smdk4212_i2c_devs0[] __initdata = {
+	{
+		I2C_BOARD_INFO("max8997", 0x66),
+		.platform_data	= &smdk4212_max8997_pdata,
+	}
+};
+
+static struct i2c_board_info smdk4212_i2c_devs1[] __initdata = {
+	{ I2C_BOARD_INFO("wm8994", 0x1a), }
+};
+
+static struct i2c_board_info smdk4212_i2c_devs3[] __initdata = {
+	/* nothing here yet */
+};
+
+static struct i2c_board_info smdk4212_i2c_devs7[] __initdata = {
+	/* nothing here yet */
+};
+
+static struct samsung_bl_gpio_info smdk4212_bl_gpio_info = {
+	.no = EXYNOS4_GPD0(1),
+	.func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk4212_bl_data = {
+	.pwm_id = 1,
+	.pwm_period_ns  = 1000,
+};
+
+static uint32_t smdk4212_keymap[] __initdata = {
+	/* KEY(row, col, keycode) */
+	KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B),
+	KEY(1, 3, KEY_E), KEY(1, 4, KEY_C)
+};
+
+static struct matrix_keymap_data smdk4212_keymap_data __initdata = {
+	.keymap		= smdk4212_keymap,
+	.keymap_size	= ARRAY_SIZE(smdk4212_keymap),
+};
+
+static struct samsung_keypad_platdata smdk4212_keypad_data __initdata = {
+	.keymap_data	= &smdk4212_keymap_data,
+	.rows		= 2,
+	.cols		= 5,
+};
+
+static struct platform_device *smdk4212_devices[] __initdata = {
+	&s3c_device_hsmmc2,
+	&s3c_device_hsmmc3,
+	&s3c_device_i2c0,
+	&s3c_device_i2c1,
+	&s3c_device_i2c3,
+	&s3c_device_i2c7,
+	&s3c_device_rtc,
+	&s3c_device_wdt,
+	&samsung_device_keypad,
+};
+
+static void __init smdk4212_map_io(void)
+{
+	clk_xusbxti.rate = 24000000;
+
+	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	s3c24xx_init_clocks(clk_xusbxti.rate);
+	s3c24xx_init_uarts(smdk4212_uartcfgs, ARRAY_SIZE(smdk4212_uartcfgs));
+}
+
+static void __init smdk4212_machine_init(void)
+{
+	s3c_i2c0_set_platdata(NULL);
+	i2c_register_board_info(0, smdk4212_i2c_devs0,
+				ARRAY_SIZE(smdk4212_i2c_devs0));
+
+	s3c_i2c1_set_platdata(NULL);
+	i2c_register_board_info(1, smdk4212_i2c_devs1,
+				ARRAY_SIZE(smdk4212_i2c_devs1));
+
+	s3c_i2c3_set_platdata(NULL);
+	i2c_register_board_info(3, smdk4212_i2c_devs3,
+				ARRAY_SIZE(smdk4212_i2c_devs3));
+
+	s3c_i2c7_set_platdata(NULL);
+	i2c_register_board_info(7, smdk4212_i2c_devs7,
+				ARRAY_SIZE(smdk4212_i2c_devs7));
+
+	samsung_bl_set(&smdk4212_bl_gpio_info, &smdk4212_bl_data);
+
+	samsung_keypad_set_platdata(&smdk4212_keypad_data);
+
+	s3c_sdhci2_set_platdata(&smdk4212_hsmmc2_pdata);
+	s3c_sdhci3_set_platdata(&smdk4212_hsmmc3_pdata);
+
+	platform_add_devices(smdk4212_devices, ARRAY_SIZE(smdk4212_devices));
+}
+
+MACHINE_START(SMDK4212, "SMDK4212")
+	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+	.boot_params	= S5P_PA_SDRAM + 0x100,
+	.init_irq	= exynos4_init_irq,
+	.map_io		= smdk4212_map_io,
+	.init_machine	= smdk4212_machine_init,
+	.timer		= &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index df6ef1b..a3346e3 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -30,9 +30,12 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-pmu.h>
 
+#include <plat/cpu.h>
+
 extern void exynos4_secondary_startup(void);
 
-#define CPU1_BOOT_REG S5P_VA_SYSRAM
+#define CPU1_BOOT_REG		(samsung_rev() == EXYNOS4210_REV_1_1 ? \
+				S5P_INFORM5 : S5P_VA_SYSRAM)
 
 /*
  * control for which core is the next to come out of the secondary
@@ -218,5 +221,6 @@
 	 * until it receives a soft interrupt, and then the
 	 * secondary CPU branches to this address.
 	 */
-	__raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), S5P_VA_SYSRAM);
+	__raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
+			CPU1_BOOT_REG);
 }
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c
index bc6ca94..62e4f43 100644
--- a/arch/arm/mach-exynos4/pm.c
+++ b/arch/arm/mach-exynos4/pm.c
@@ -41,7 +41,6 @@
 	{ .reg = S5P_CLKSRC_MASK_CAM			, .val = 0x11111111, },
 	{ .reg = S5P_CLKSRC_MASK_TV			, .val = 0x00000111, },
 	{ .reg = S5P_CLKSRC_MASK_LCD0			, .val = 0x00001111, },
-	{ .reg = S5P_CLKSRC_MASK_LCD1			, .val = 0x00001111, },
 	{ .reg = S5P_CLKSRC_MASK_MAUDIO			, .val = 0x00000001, },
 	{ .reg = S5P_CLKSRC_MASK_FSYS			, .val = 0x01011111, },
 	{ .reg = S5P_CLKSRC_MASK_PERIL0			, .val = 0x01111111, },
@@ -49,6 +48,10 @@
 	{ .reg = S5P_CLKSRC_MASK_DMC			, .val = 0x00010000, },
 };
 
+static struct sleep_save exynos4210_set_clksrc[] = {
+	{ .reg = S5P_CLKSRC_MASK_LCD1			, .val = 0x00001111, },
+};
+
 static struct sleep_save exynos4_epll_save[] = {
 	SAVE_ITEM(S5P_EPLL_CON0),
 	SAVE_ITEM(S5P_EPLL_CON1),
@@ -60,77 +63,6 @@
 };
 
 static struct sleep_save exynos4_core_save[] = {
-	/* CMU side */
-	SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
-	SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
-	SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
-	SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
-	SAVE_ITEM(S5P_CLKSRC_TOP0),
-	SAVE_ITEM(S5P_CLKSRC_TOP1),
-	SAVE_ITEM(S5P_CLKSRC_CAM),
-	SAVE_ITEM(S5P_CLKSRC_TV),
-	SAVE_ITEM(S5P_CLKSRC_MFC),
-	SAVE_ITEM(S5P_CLKSRC_G3D),
-	SAVE_ITEM(S5P_CLKSRC_IMAGE),
-	SAVE_ITEM(S5P_CLKSRC_LCD0),
-	SAVE_ITEM(S5P_CLKSRC_LCD1),
-	SAVE_ITEM(S5P_CLKSRC_MAUDIO),
-	SAVE_ITEM(S5P_CLKSRC_FSYS),
-	SAVE_ITEM(S5P_CLKSRC_PERIL0),
-	SAVE_ITEM(S5P_CLKSRC_PERIL1),
-	SAVE_ITEM(S5P_CLKDIV_CAM),
-	SAVE_ITEM(S5P_CLKDIV_TV),
-	SAVE_ITEM(S5P_CLKDIV_MFC),
-	SAVE_ITEM(S5P_CLKDIV_G3D),
-	SAVE_ITEM(S5P_CLKDIV_IMAGE),
-	SAVE_ITEM(S5P_CLKDIV_LCD0),
-	SAVE_ITEM(S5P_CLKDIV_LCD1),
-	SAVE_ITEM(S5P_CLKDIV_MAUDIO),
-	SAVE_ITEM(S5P_CLKDIV_FSYS0),
-	SAVE_ITEM(S5P_CLKDIV_FSYS1),
-	SAVE_ITEM(S5P_CLKDIV_FSYS2),
-	SAVE_ITEM(S5P_CLKDIV_FSYS3),
-	SAVE_ITEM(S5P_CLKDIV_PERIL0),
-	SAVE_ITEM(S5P_CLKDIV_PERIL1),
-	SAVE_ITEM(S5P_CLKDIV_PERIL2),
-	SAVE_ITEM(S5P_CLKDIV_PERIL3),
-	SAVE_ITEM(S5P_CLKDIV_PERIL4),
-	SAVE_ITEM(S5P_CLKDIV_PERIL5),
-	SAVE_ITEM(S5P_CLKDIV_TOP),
-	SAVE_ITEM(S5P_CLKSRC_MASK_TOP),
-	SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
-	SAVE_ITEM(S5P_CLKSRC_MASK_TV),
-	SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
-	SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
-	SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
-	SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
-	SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
-	SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
-	SAVE_ITEM(S5P_CLKDIV2_RATIO),
-	SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
-	SAVE_ITEM(S5P_CLKGATE_IP_CAM),
-	SAVE_ITEM(S5P_CLKGATE_IP_TV),
-	SAVE_ITEM(S5P_CLKGATE_IP_MFC),
-	SAVE_ITEM(S5P_CLKGATE_IP_G3D),
-	SAVE_ITEM(S5P_CLKGATE_IP_IMAGE),
-	SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
-	SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
-	SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
-	SAVE_ITEM(S5P_CLKGATE_IP_GPS),
-	SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
-	SAVE_ITEM(S5P_CLKGATE_IP_PERIR),
-	SAVE_ITEM(S5P_CLKGATE_BLOCK),
-	SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
-	SAVE_ITEM(S5P_CLKSRC_DMC),
-	SAVE_ITEM(S5P_CLKDIV_DMC0),
-	SAVE_ITEM(S5P_CLKDIV_DMC1),
-	SAVE_ITEM(S5P_CLKGATE_IP_DMC),
-	SAVE_ITEM(S5P_CLKSRC_CPU),
-	SAVE_ITEM(S5P_CLKDIV_CPU),
-	SAVE_ITEM(S5P_CLKDIV_CPU + 0x4),
-	SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
-	SAVE_ITEM(S5P_CLKGATE_IP_CPU),
-
 	/* GIC side */
 	SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
 	SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
@@ -268,6 +200,9 @@
 
 	s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
 
+	if (soc_is_exynos4210())
+		s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
+
 }
 
 static int exynos4_pm_add(struct sys_device *sysdev)
diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c
index 374e45e..6c498f9 100644
--- a/arch/arm/mach-s3c64xx/cpu.c
+++ b/arch/arm/mach-s3c64xx/cpu.c
@@ -43,16 +43,16 @@
 
 static struct cpu_table cpu_ids[] __initdata = {
 	{
-		.idcode		= 0x36400000,
-		.idmask		= 0xfffff000,
+		.idcode		= S3C6400_CPU_ID,
+		.idmask		= S3C64XX_CPU_MASK,
 		.map_io		= s3c6400_map_io,
 		.init_clocks	= s3c6400_init_clocks,
 		.init_uarts	= s3c6400_init_uarts,
 		.init		= s3c6400_init,
 		.name		= name_s3c6400,
 	}, {
-		.idcode		= 0x36410100,
-		.idmask		= 0xffffff00,
+		.idcode		= S3C6410_CPU_ID,
+		.idmask		= S3C64XX_CPU_MASK,
 		.map_io		= s3c6410_map_io,
 		.init_clocks	= s3c6410_init_clocks,
 		.init_uarts	= s3c6410_init_uarts,
@@ -140,22 +140,14 @@
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 {
-	unsigned long idcode;
-
 	/* initialise the io descriptors we need for initialisation */
 	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
 	iotable_init(mach_desc, size);
 
-	idcode = __raw_readl(S3C_VA_SYS + 0x118);
-	if (!idcode) {
-		/* S3C6400 has the ID register in a different place,
-		 * and needs a write before it can be read. */
+	/* detect cpu id */
+	s3c64xx_init_cpu();
 
-		__raw_writel(0x0, S3C_VA_SYS + 0xA1C);
-		idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
-	}
-
-	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 }
 
 static __init int s3c64xx_sysdev_init(void)
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
index ac825e8..1fd9c79 100644
--- a/arch/arm/mach-s5p64x0/dev-spi.c
+++ b/arch/arm/mach-s5p64x0/dev-spi.c
@@ -21,6 +21,7 @@
 #include <mach/regs-clock.h>
 #include <mach/spi-clocks.h>
 
+#include <plat/cpu.h>
 #include <plat/s3c64xx-spi.h>
 #include <plat/gpio-cfg.h>
 
@@ -185,11 +186,8 @@
 
 void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
 {
-	unsigned int id;
 	struct s3c64xx_spi_info *pd;
 
-	id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
-
 	/* Reject invalid configuration */
 	if (!num_cs || src_clk_nr < 0
 			|| src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
@@ -199,7 +197,7 @@
 
 	switch (cntrlr) {
 	case 0:
-		if (id == 0x50000)
+		if (soc_is_s5p6450())
 			pd = &s5p6450_spi0_pdata;
 		else
 			pd = &s5p6440_spi0_pdata;
@@ -207,7 +205,7 @@
 		s5p64x0_device_spi0.dev.platform_data = pd;
 		break;
 	case 1:
-		if (id == 0x50000)
+		if (soc_is_s5p6450())
 			pd = &s5p6450_spi1_pdata;
 		else
 			pd = &s5p6440_spi1_pdata;
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index d7ad944..0e5b3e6 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -28,6 +28,7 @@
 #include <mach/irqs.h>
 #include <mach/regs-clock.h>
 
+#include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/s3c-pl330-pdata.h>
 
@@ -133,11 +134,7 @@
 
 static int __init s5p64x0_dma_init(void)
 {
-	unsigned int id;
-
-	id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
-
-	if (id == 0x50000)
+	if (soc_is_s5p6450())
 		s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
 	else
 		s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
diff --git a/arch/arm/mach-s5p64x0/gpiolib.c b/arch/arm/mach-s5p64x0/gpiolib.c
index e7fb3b0..700dac6 100644
--- a/arch/arm/mach-s5p64x0/gpiolib.c
+++ b/arch/arm/mach-s5p64x0/gpiolib.c
@@ -19,6 +19,7 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
 
+#include <plat/cpu.h>
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
@@ -473,14 +474,10 @@
 
 static int __init s5p64x0_gpiolib_init(void)
 {
-	unsigned int chipid;
-
-	chipid = __raw_readl(S5P64X0_SYS_ID);
-
 	s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
 				ARRAY_SIZE(s5p64x0_gpio_cfgs));
 
-	if ((chipid & 0xff000) == 0x50000) {
+	if (soc_is_s5p6450()) {
 		samsung_gpiolib_add_2bit_chips(s5p6450_gpio_2bit,
 					ARRAY_SIZE(s5p6450_gpio_2bit));
 
diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c
index fe7380f..494e1a8 100644
--- a/arch/arm/mach-s5p64x0/irq-eint.c
+++ b/arch/arm/mach-s5p64x0/irq-eint.c
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 
+#include <plat/cpu.h>
 #include <plat/regs-irqtype.h>
 #include <plat/gpio-cfg.h>
 
@@ -67,7 +68,7 @@
 	__raw_writel(ctrl, S5P64X0_EINT0CON0);
 
 	/* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
-	if (0x50000 == (__raw_readl(S5P64X0_SYS_ID) & 0xFF000))
+	if (soc_is_s5p6450())
 		s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
 	else
 		s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index c1fc6c6..3c63353 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -215,19 +215,18 @@
 
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
-	unsigned long idcode = 0x0;
-
 	/* initialise the io descriptors we need for initialisation */
 	iotable_init(mach_desc, size);
 	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
 
 	if (cpu_architecture() >= CPU_ARCH_ARMv5) {
-		idcode = s3c24xx_read_idcode_v5();
+		samsung_cpu_id = s3c24xx_read_idcode_v5();
 	} else {
-		idcode = s3c24xx_read_idcode_v4();
+		samsung_cpu_id = s3c24xx_read_idcode_v4();
 	}
+	s3c24xx_init_cpu();
 
 	arm_pm_restart = s3c24xx_pm_restart;
 
-	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 }
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index bbc2aa7..909507b 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -33,48 +33,57 @@
 static const char name_s5pc100[] = "S5PC100";
 static const char name_s5pv210[] = "S5PV210/S5PC110";
 static const char name_exynos4210[] = "EXYNOS4210";
+static const char name_exynos4212[] = "EXYNOS4212";
 
 static struct cpu_table cpu_ids[] __initdata = {
 	{
-		.idcode		= 0x56440100,
-		.idmask		= 0xfffff000,
+		.idcode		= S5P6440_CPU_ID,
+		.idmask		= S5P64XX_CPU_MASK,
 		.map_io		= s5p6440_map_io,
 		.init_clocks	= s5p6440_init_clocks,
 		.init_uarts	= s5p6440_init_uarts,
 		.init		= s5p64x0_init,
 		.name		= name_s5p6440,
 	}, {
-		.idcode		= 0x36450000,
-		.idmask		= 0xfffff000,
+		.idcode		= S5P6450_CPU_ID,
+		.idmask		= S5P64XX_CPU_MASK,
 		.map_io		= s5p6450_map_io,
 		.init_clocks	= s5p6450_init_clocks,
 		.init_uarts	= s5p6450_init_uarts,
 		.init		= s5p64x0_init,
 		.name		= name_s5p6450,
 	}, {
-		.idcode		= 0x43100000,
-		.idmask		= 0xfffff000,
+		.idcode		= S5PC100_CPU_ID,
+		.idmask		= S5PC100_CPU_MASK,
 		.map_io		= s5pc100_map_io,
 		.init_clocks	= s5pc100_init_clocks,
 		.init_uarts	= s5pc100_init_uarts,
 		.init		= s5pc100_init,
 		.name		= name_s5pc100,
 	}, {
-		.idcode		= 0x43110000,
-		.idmask		= 0xfffff000,
+		.idcode		= S5PV210_CPU_ID,
+		.idmask		= S5PV210_CPU_MASK,
 		.map_io		= s5pv210_map_io,
 		.init_clocks	= s5pv210_init_clocks,
 		.init_uarts	= s5pv210_init_uarts,
 		.init		= s5pv210_init,
 		.name		= name_s5pv210,
 	}, {
-		.idcode		= 0x43210000,
-		.idmask		= 0xfffe0000,
+		.idcode		= EXYNOS4210_CPU_ID,
+		.idmask		= EXYNOS4_CPU_MASK,
 		.map_io		= exynos4_map_io,
 		.init_clocks	= exynos4_init_clocks,
 		.init_uarts	= exynos4_init_uarts,
 		.init		= exynos4_init,
 		.name		= name_exynos4210,
+	}, {
+		.idcode		= EXYNOS4212_CPU_ID,
+		.idmask		= EXYNOS4_CPU_MASK,
+		.map_io		= exynos4_map_io,
+		.init_clocks	= exynos4_init_clocks,
+		.init_uarts	= exynos4_init_uarts,
+		.init		= exynos4_init,
+		.name		= name_exynos4212,
 	},
 };
 
@@ -114,13 +123,13 @@
 void __init s5p_init_io(struct map_desc *mach_desc,
 			int size, void __iomem *cpuid_addr)
 {
-	unsigned long idcode;
-
 	/* initialize the io descriptors we need for initialization */
 	iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
 	if (mach_desc)
 		iotable_init(mach_desc, size);
 
-	idcode = __raw_readl(cpuid_addr);
-	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+	/* detect cpu id and rev. */
+	s5p_init_cpu(cpuid_addr);
+
+	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 }
diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-s5p/include/plat/exynos4.h
index 907caab..f680a14 100644
--- a/arch/arm/plat-s5p/include/plat/exynos4.h
+++ b/arch/arm/plat-s5p/include/plat/exynos4.h
@@ -14,10 +14,11 @@
 
 extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void exynos4_register_clocks(void);
+extern void exynos4210_register_clocks(void);
+extern void exynos4212_register_clocks(void);
 extern void exynos4_setup_clocks(void);
 
-#ifdef CONFIG_CPU_EXYNOS4210
-
+#ifdef CONFIG_ARCH_EXYNOS4
 extern  int exynos4_init(void);
 extern void exynos4_init_irq(void);
 extern void exynos4_map_io(void);
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index ebc142c..3e21b94 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -12,6 +12,59 @@
  * published by the Free Software Foundation.
 */
 
+#include <asm/div64.h>
+
+#define PLL35XX_MDIV_MASK	(0x3FF)
+#define PLL35XX_PDIV_MASK	(0x3F)
+#define PLL35XX_SDIV_MASK	(0x7)
+#define PLL35XX_MDIV_SHIFT	(16)
+#define PLL35XX_PDIV_SHIFT	(8)
+#define PLL35XX_SDIV_SHIFT	(0)
+
+static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
+{
+	u32 mdiv, pdiv, sdiv;
+	u64 fvco = baseclk;
+
+	mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+	pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+	sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+#define PLL36XX_KDIV_MASK	(0xFFFF)
+#define PLL36XX_MDIV_MASK	(0x1FF)
+#define PLL36XX_PDIV_MASK	(0x3F)
+#define PLL36XX_SDIV_MASK	(0x7)
+#define PLL36XX_MDIV_SHIFT	(16)
+#define PLL36XX_PDIV_SHIFT	(8)
+#define PLL36XX_SDIV_SHIFT	(0)
+
+static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
+					    u32 pll_con0, u32 pll_con1)
+{
+	unsigned long result;
+	u32 mdiv, pdiv, sdiv, kdiv;
+	u64 tmp;
+
+	mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+	pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+	sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+	kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+	tmp = baseclk;
+
+	tmp *= (mdiv << 16) + kdiv;
+	do_div(tmp, (pdiv << sdiv));
+	result = tmp >> 16;
+
+	return result;
+}
+
 #define PLL45XX_MDIV_MASK	(0x3FF)
 #define PLL45XX_PDIV_MASK	(0x3F)
 #define PLL45XX_SDIV_MASK	(0x7)
@@ -19,8 +72,6 @@
 #define PLL45XX_PDIV_SHIFT	(8)
 #define PLL45XX_SDIV_SHIFT	(0)
 
-#include <asm/div64.h>
-
 enum pll45xx_type_t {
 	pll_4500,
 	pll_4502,
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 853764b..3de756d 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -11,7 +11,7 @@
 
 # Objects we always build independent of SoC choice
 
-obj-y				+= init.o
+obj-y				+= init.o cpu.o
 obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET)   += time.o
 obj-y				+= clock.o
 obj-y				+= pwm-clock.o
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
new file mode 100644
index 0000000..81c06d4
--- /dev/null
+++ b/arch/arm/plat-samsung/cpu.c
@@ -0,0 +1,58 @@
+/* linux/arch/arm/plat-samsung/cpu.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+
+unsigned long samsung_cpu_id;
+static unsigned int samsung_cpu_rev;
+
+unsigned int samsung_rev(void)
+{
+	return samsung_cpu_rev;
+}
+EXPORT_SYMBOL(samsung_rev);
+
+void __init s3c24xx_init_cpu(void)
+{
+	/* nothing here yet */
+
+	samsung_cpu_rev = 0;
+}
+
+void __init s3c64xx_init_cpu(void)
+{
+	samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118);
+	if (!samsung_cpu_id) {
+		/*
+		 * S3C6400 has the ID register in a different place,
+		 * and needs a write before it can be read.
+		 */
+		__raw_writel(0x0, S3C_VA_SYS + 0xA1C);
+		samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0xA1C);
+	}
+
+	samsung_cpu_rev = 0;
+}
+
+void __init s5p_init_cpu(void __iomem *cpuid_addr)
+{
+	samsung_cpu_id = __raw_readl(cpuid_addr);
+	samsung_cpu_rev = samsung_cpu_id & 0xFF;
+}
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index c0a5741..1bbbbb4 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -1,9 +1,12 @@
 /* linux/arch/arm/plat-samsung/include/plat/cpu.h
  *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
  * Copyright (c) 2004-2005 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * Header file for S3C24XX CPU support
+ * Header file for Samsung 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
@@ -15,6 +18,100 @@
 #ifndef __SAMSUNG_PLAT_CPU_H
 #define __SAMSUNG_PLAT_CPU_H
 
+extern unsigned long samsung_cpu_id;
+
+#define S3C24XX_CPU_ID		0x32400000
+#define S3C24XX_CPU_MASK	0xFFF00000
+
+#define S3C6400_CPU_ID		0x36400000
+#define S3C6410_CPU_ID		0x36410000
+#define S3C64XX_CPU_ID		(S3C6400_CPU_ID & S3C6410_CPU_ID)
+#define S3C64XX_CPU_MASK	0xFFFFF000
+
+#define S5P6440_CPU_ID		0x56440000
+#define S5P6450_CPU_ID		0x36450000
+#define S5P64XX_CPU_MASK	0xFFFFF000
+
+#define S5PC100_CPU_ID		0x43100000
+#define S5PC100_CPU_MASK	0xFFFFF000
+
+#define S5PV210_CPU_ID		0x43110000
+#define S5PV210_CPU_MASK	0xFFFFF000
+
+#define EXYNOS4210_CPU_ID	0x43210000
+#define EXYNOS4212_CPU_ID	0x43220000
+#define EXYNOS4_CPU_MASK	0xFFFE0000
+
+#define IS_SAMSUNG_CPU(name, id, mask)		\
+static inline int is_samsung_##name(void)	\
+{						\
+	return ((samsung_cpu_id & mask) == (id & mask));	\
+}
+
+IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK)
+IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+    defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
+    defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
+    defined(CONFIG_CPU_S3C2443)
+# define soc_is_s3c24xx()	is_samsung_s3c24xx()
+#else
+# define soc_is_s3c24xx()	0
+#endif
+
+#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c64xx()	is_samsung_s3c64xx()
+#else
+# define soc_is_s3c64xx()	0
+#endif
+
+#if defined(CONFIG_CPU_S5P6440)
+# define soc_is_s5p6440()	is_samsung_s5p6440()
+#else
+# define soc_is_s5p6440()	0
+#endif
+
+#if defined(CONFIG_CPU_S5P6450)
+# define soc_is_s5p6450()	is_samsung_s5p6450()
+#else
+# define soc_is_s5p6450()	0
+#endif
+
+#if defined(CONFIG_CPU_S5PC100)
+# define soc_is_s5pc100()	is_samsung_s5pc100()
+#else
+# define soc_is_s5pc100()	0
+#endif
+
+#if defined(CONFIG_CPU_S5PV210)
+# define soc_is_s5pv210()	is_samsung_s5pv210()
+#else
+# define soc_is_s5pv210()	0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+# define soc_is_exynos4210()	is_samsung_exynos4210()
+#else
+# define soc_is_exynos4210()	0
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS4212)
+# define soc_is_exynos4212()	is_samsung_exynos4212()
+#else
+# define soc_is_exynos4212()	0
+#endif
+
+#define EXYNOS4210_REV_0	(0x0)
+#define EXYNOS4210_REV_1_0	(0x10)
+#define EXYNOS4210_REV_1_1	(0x11)
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
@@ -55,6 +152,12 @@
 extern void s5p_init_io(struct map_desc *mach_desc,
 			int size, void __iomem *cpuid_addr);
 
+extern void s3c24xx_init_cpu(void);
+extern void s3c64xx_init_cpu(void);
+extern void s5p_init_cpu(void __iomem *cpuid_addr);
+
+extern unsigned int samsung_rev(void);
+
 extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
 extern void s3c24xx_init_clocks(int xtal);