diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 3f926b0..69487f7 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_PLAT_SAMSUNG)	+= clk.o
+obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
new file mode 100644
index 0000000..e74b004
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2012 Linaro Ltd.
+ *
+ * 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.
+ *
+ * Common Clock Framework support for all Exynos4 platforms
+ * ToDo: Remove all static instantiation of clocks after migrating all Exynos4
+ *	 based boards to use device tree support.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/pll.h>
+#include <plat/cpu.h>
+#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
+#include <plat/map-s5p.h>
+#include "clk.h"
+
+#define EXYNOS4_OP_MODE		(S5P_VA_CHIPID + 8)
+
+/* base address of io remapped clock controller register space */
+static	void __iomem *clk_base;
+
+static const char *pll_parent_names[] __initdata = { "fin_pll" };
+static const char *fin_pll_parents[] __initdata = { "xxti", "xusbxti" };
+static const char *mout_apll_parents[] __initdata = { "fin_pll", "fout_apll", };
+static const char *mout_mpll_parents[] __initdata = { "fin_pll", "fout_mpll", };
+static const char *mout_epll_parents[] __initdata = { "fin_pll", "fout_epll", };
+
+static const char *sclk_ampll_parents[] __initdata = {
+		"mout_mpll", "sclk_apll", };
+
+static const char *sclk_evpll_parents[] __initdata = {
+		"mout_epll", "mout_vpll", };
+
+static const char *mout_core_parents[] __initdata = {
+		"mout_apll", "mout_mpll", };
+
+static const char *mout_mfc_parents[] __initdata = {
+		"mout_mfc0", "mout_mfc1", };
+
+static const char *mout_dac_parents[] __initdata = {
+		"mout_vpll", "sclk_hdmiphy", };
+
+static const char *mout_hdmi_parents[] __initdata = {
+		"sclk_pixel", "sclk_hdmiphy", };
+
+static const char *mout_mixer_parents[] __initdata = {
+		"sclk_dac", "sclk_hdmi", };
+
+static const char *group1_parents[] __initdata = {
+		"xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+		"none", "sclk_hdmiphy", "mout_mpll", "mout_epll",
+		"mout_vpll" };
+
+static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
+	FRATE_CLK(NULL, "xxti", NULL, CLK_IS_ROOT, 24000000),
+	FRATE_CLK(NULL, "xusbxti", NULL, CLK_IS_ROOT, 24000000),
+	FRATE_CLK(NULL, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
+	FRATE_CLK(NULL, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+	FRATE_CLK(NULL, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+};
+
+static struct samsung_mux_clock exynos4_mux_clks[] = {
+	MUXCLK(NULL, "fin_pll", fin_pll_parents, 0,
+			EXYNOS4_OP_MODE, 0, 1, 0),
+	MUXCLK(NULL, "mout_apll", mout_apll_parents, 0,
+			EXYNOS4_CLKSRC_CPU, 0, 1, 0),
+	MUXCLK(NULL, "mout_epll", mout_epll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 4, 1, 0),
+	MUXCLK(NULL, "mout_core", mout_core_parents, 0,
+			EXYNOS4_CLKSRC_CPU, 16, 1, 0),
+	MUXCLK(NULL, "mout_aclk_200", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 12, 1, 0),
+	MUXCLK(NULL, "mout_aclk_100", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 16, 1, 0),
+	MUXCLK(NULL, "mout_aclk_160", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 20, 1, 0),
+	MUXCLK(NULL, "mout_aclk_133", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 24, 1, 0),
+	MUXCLK("exynos4210-uart.0", "mout_uart0", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 0, 4, 0),
+	MUXCLK("exynos4210-uart.1", "mout_uart1", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 4, 4, 0),
+	MUXCLK("exynos4210-uart.2", "mout_uart2", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 8, 4, 0),
+	MUXCLK("exynos4210-uart.3", "mout_uart3", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL0, 12, 4, 0),
+	MUXCLK("exynos4-sdhci.0", "mout_mmc0", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 0, 4, 0),
+	MUXCLK("exynos4-sdhci.1", "mout_mmc1", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 4, 4, 0),
+	MUXCLK("exynos4-sdhci.1", "mout_mmc2", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 8, 4, 0),
+	MUXCLK("exynos4-sdhci.1", "mout_mmc3", group1_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 12, 4, 0),
+	MUXCLK("exynos4210-spi.0", "mout_spi0", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL1, 16, 4, 0),
+	MUXCLK("exynos4210-spi.1", "mout_spi1", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL1, 20, 4, 0),
+	MUXCLK("exynos4210-spi.2", "mout_spi2", group1_parents, 0,
+			EXYNOS4_CLKSRC_PERIL1, 24, 4, 0),
+	MUXCLK(NULL, "mout_sata", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_FSYS, 24, 1, 0),
+	MUXCLK(NULL, "mout_mfc0", sclk_ampll_parents, 0,
+			EXYNOS4_CLKSRC_MFC, 0, 1, 0),
+	MUXCLK(NULL, "mout_mfc1", sclk_evpll_parents, 0,
+			EXYNOS4_CLKSRC_MFC, 4, 1, 0),
+	MUXCLK("s5p-mfc", "mout_mfc", mout_mfc_parents, 0,
+			EXYNOS4_CLKSRC_MFC, 8, 1, 0),
+	MUXCLK("s5p-mipi-csis.0", "mout_csis0", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 24, 4, 0),
+	MUXCLK("s5p-mipi-csis.1", "mout_csis1", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 28, 4, 0),
+	MUXCLK(NULL, "mout_cam0", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 16, 4, 0),
+	MUXCLK(NULL, "mout_cam1", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 20, 4, 0),
+	MUXCLK("exynos4-fimc.0", "mout_fimc0", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 0, 4, 0),
+	MUXCLK("exynos4-fimc.1", "mout_fimc1", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 4, 4, 0),
+	MUXCLK("exynos4-fimc.2", "mout_fimc2", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 8, 4, 0),
+	MUXCLK("exynos4-fimc.3", "mout_fimc3", group1_parents, 0,
+			EXYNOS4_CLKSRC_CAM, 12, 4, 0),
+	MUXCLK("exynos4-fb.0", "mout_fimd0", group1_parents, 0,
+			EXYNOS4_CLKSRC_LCD0, 0, 4, 0),
+	MUXCLK(NULL, "sclk_dac", mout_dac_parents, 0,
+			EXYNOS4_CLKSRC_TV, 8, 1, 0),
+	MUXCLK(NULL, "sclk_hdmi", mout_hdmi_parents, 0,
+			EXYNOS4_CLKSRC_TV, 0, 1, 0),
+	MUXCLK(NULL, "sclk_mixer", mout_mixer_parents, 0,
+			EXYNOS4_CLKSRC_TV, 4, 1, 0),
+};
+
+static struct samsung_div_clock exynos4_div_clks[] = {
+	DIVCLK(NULL, "sclk_apll", "mout_apll", 0,
+			EXYNOS4_CLKDIV_CPU, 24, 3, 0),
+	DIVCLK(NULL, "div_core", "mout_core", 0,
+			EXYNOS4_CLKDIV_CPU, 0, 3, 0),
+	DIVCLK(NULL, "armclk", "div_core", 0,
+			EXYNOS4_CLKDIV_CPU, 28, 3, 0),
+	DIVCLK(NULL, "aclk_200", "mout_aclk_200", 0,
+			EXYNOS4_CLKDIV_TOP, 0, 3, 0),
+	DIVCLK(NULL, "aclk_100", "mout_aclk_100", 0,
+			EXYNOS4_CLKDIV_TOP, 4, 4, 0),
+	DIVCLK(NULL, "aclk_160", "mout_aclk_160", 0,
+			EXYNOS4_CLKDIV_TOP, 8, 3, 0),
+	DIVCLK(NULL, "aclk_133", "mout_aclk_133", 0,
+			EXYNOS4_CLKDIV_TOP, 12, 3, 0),
+	DIVCLK("exynos4210-uart.0", "div_uart0", "mout_uart0", 0,
+			EXYNOS4_CLKDIV_PERIL0, 0, 4, 0),
+	DIVCLK("exynos4210-uart.1", "div_uart1", "mout_uart1", 0,
+			EXYNOS4_CLKDIV_PERIL0, 4, 4, 0),
+	DIVCLK("exynos4210-uart.2", "div_uart2", "mout_uart2", 0,
+			EXYNOS4_CLKDIV_PERIL0, 8, 4, 0),
+	DIVCLK("exynos4210-uart.3", "div_uart3", "mout_uart3", 0,
+			EXYNOS4_CLKDIV_PERIL0, 12, 4, 0),
+	DIVCLK("exynos4-sdhci.0", "div_mmc0", "mout_mmc0", 0,
+			EXYNOS4_CLKDIV_FSYS1, 0, 4, 0),
+	DIVCLK("exynos4-sdhci.0", "div_mmc0_pre", "div_mmc0", 0,
+			EXYNOS4_CLKDIV_FSYS1, 8, 8, 0),
+	DIVCLK("exynos4-sdhci.1", "div_mmc1", "mout_mmc1", 0,
+			EXYNOS4_CLKDIV_FSYS1, 16, 4, 0),
+	DIVCLK("exynos4-sdhci.1", "div_mmc1_pre", "div_mmc1", 0,
+			EXYNOS4_CLKDIV_FSYS1, 24, 8, 0),
+	DIVCLK("exynos4-sdhci.2", "div_mmc2", "mout_mmc2", 0,
+			EXYNOS4_CLKDIV_FSYS2, 0, 4, 0),
+	DIVCLK("exynos4-sdhci.2", "div_mmc2_pre", "div_mmc2", 0,
+			EXYNOS4_CLKDIV_FSYS2, 8, 8, 0),
+	DIVCLK("exynos4-sdhci.3", "div_mmc3", "mout_mmc3", 0,
+			EXYNOS4_CLKDIV_FSYS2, 16, 4, 0),
+	DIVCLK("exynos4-sdhci.3", "div_mmc3_pre", "div_mmc3", 0,
+			EXYNOS4_CLKDIV_FSYS2, 24, 8, 0),
+	DIVCLK("exynos4210-spi.0", "div_spi0", "mout_spi0", 0,
+			EXYNOS4_CLKDIV_PERIL1, 0, 4, 0),
+	DIVCLK("exynos4210-spi.1", "div_spi1", "mout_spi1", 0,
+			EXYNOS4_CLKDIV_PERIL1, 16, 4, 0),
+	DIVCLK("exynos4210-spi.2", "div_spi2", "mout_spi2", 0,
+			EXYNOS4_CLKDIV_PERIL2, 0, 4, 0),
+	DIVCLK("exynos4210-spi.0", "div_spi0_pre", "div_spi0", 0,
+			EXYNOS4_CLKDIV_PERIL1, 8, 8, 0),
+	DIVCLK("exynos4210-spi.1", "div_spi1_pre", "div_spi1", 0,
+			EXYNOS4_CLKDIV_PERIL1, 24, 8, 0),
+	DIVCLK("exynos4210-spi.2", "div_spi2_pre", "div_spi2", 0,
+			EXYNOS4_CLKDIV_PERIL2, 8, 8, 0),
+	DIVCLK(NULL, "div_sata", "mout_sata", 0,
+			EXYNOS4_CLKDIV_FSYS0, 20, 4, 0),
+	DIVCLK("s5p-mfc", "div_mfc", "mout_mfc", 0,
+			EXYNOS4_CLKDIV_MFC, 0, 4, 0),
+	DIVCLK("s5p-mipi-csis.0", "div_csis0", "mout_csis0", 0,
+			EXYNOS4_CLKDIV_CAM, 24, 4, 0),
+	DIVCLK("s5p-mipi-csis.1", "div_csis1", "mout_csis1", 0,
+			EXYNOS4_CLKDIV_CAM, 28, 4, 0),
+	DIVCLK(NULL, "div_cam0", "mout_cam0", 0,
+			EXYNOS4_CLKDIV_CAM, 16, 4, 0),
+	DIVCLK(NULL, "div_cam1", "mout_cam1", 0,
+			EXYNOS4_CLKDIV_CAM, 20, 4, 0),
+	DIVCLK("exynos4-fimc.0", "div_fimc0", "mout_fimc0", 0,
+			EXYNOS4_CLKDIV_CAM, 0, 4, 0),
+	DIVCLK("exynos4-fimc.1", "div_fimc1", "mout_fimc1", 0,
+			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
+	DIVCLK("exynos4-fimc.2", "div_fimc2", "mout_fimc2", 0,
+			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
+	DIVCLK("exynos4-fimc.3", "div_fimc3", "mout_fimc3", 0,
+			EXYNOS4_CLKDIV_CAM, 4, 4, 0),
+	DIVCLK("exynos4-fb.0", "div_fimd0", "mout_fimd0", 0,
+			EXYNOS4_CLKDIV_LCD0, 0, 4, 0),
+	DIVCLK(NULL, "sclk_pixel", "mout_vpll", 0,
+			EXYNOS4_CLKDIV_TV, 0, 4, 0),
+};
+
+struct samsung_gate_clock exynos4_gate_clks[] = {
+	GATECLK("exynos4210-uart.0", "uart0", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 0, "uart"),
+	GATECLK("exynos4210-uart.1", "uart1", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 1, "uart"),
+	GATECLK("exynos4210-uart.2", "uart2", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 2, "uart"),
+	GATECLK("exynos4210-uart.3", "uart3", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 3, "uart"),
+	GATECLK("exynos4210-uart.4", "uart4", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 4, "uart"),
+	GATECLK("exynos4210-uart.5", "uart5", "aclk_100", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKGATE_IP_PERIL, 5, "uart"),
+	GATECLK("exynos4210-uart.0", "uclk0", "div_uart0", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 0, "clk_uart_baud0"),
+	GATECLK("exynos4210-uart.1", "uclk1", "div_uart1", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 4, "clk_uart_baud0"),
+	GATECLK("exynos4210-uart.2", "uclk2", "div_uart2", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 8, "clk_uart_baud0"),
+	GATECLK("exynos4210-uart.3", "uclk3", "div_uart3", CLK_SET_RATE_PARENT,
+			EXYNOS4_CLKSRC_MASK_PERIL0, 12, "clk_uart_baud0"),
+	GATECLK(NULL, "timers", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 24, NULL),
+	GATECLK("s5p-mipi-csis.0", "csis", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 5, NULL),
+	GATECLK(NULL, "jpeg", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 6, NULL),
+	GATECLK("exynos4-fimc.0", "fimc0", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 0, "fimc"),
+	GATECLK("exynos4-fimc.1", "fimc1", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 1, "fimc"),
+	GATECLK("exynos4-fimc.2", "fimc2", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 2, "fimc"),
+	GATECLK("exynos4-fimc.3", "fimc3", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 3, "fimc"),
+	GATECLK("exynos4-sdhci.0", "hsmmc0", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 5, "hsmmc"),
+	GATECLK("exynos4-sdhci.1", "hsmmc1", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 6, "hsmmc"),
+	GATECLK("exynos4-sdhci.2", "hsmmc2", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 7, "hsmmc"),
+	GATECLK("exynos4-sdhci.3", "hsmmc3", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 8, "hsmmc"),
+	GATECLK(NULL, "dwmmc", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 9, NULL),
+	GATECLK("s5p-sdo", "dac", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 2, NULL),
+	GATECLK("s5p-mixer", "mixer", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 1, NULL),
+	GATECLK("s5p-mixer", "vp", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 0, NULL),
+	GATECLK("exynos4-hdmi", "hdmi", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 3, NULL),
+	GATECLK("exynos4-hdmi", "hdmiphy", "aclk_160", 0,
+			S5P_HDMI_PHY_CONTROL, 0, NULL),
+	GATECLK("s5p-sdo", "dacphy", "aclk_160", 0,
+			S5P_DAC_PHY_CONTROL, 0, NULL),
+	GATECLK(NULL, "adc", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 15, NULL),
+	GATECLK(NULL, "keypad", "aclk_100", 0,
+			EXYNOS4210_CLKGATE_IP_PERIR, 16, NULL),
+	GATECLK(NULL, "rtc", "aclk_100", 0,
+			EXYNOS4210_CLKGATE_IP_PERIR, 15, NULL),
+	GATECLK(NULL, "watchdog", "aclk_100", 0,
+			EXYNOS4210_CLKGATE_IP_PERIR, 14, NULL),
+	GATECLK(NULL, "usbhost", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 12, NULL),
+	GATECLK(NULL, "otg", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 13, NULL),
+	GATECLK("exynos4210-spi.0", "spi0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 16, "spi"),
+	GATECLK("exynos4210-spi.1", "spi1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 17, "spi"),
+	GATECLK("exynos4210-spi.2", "spi2", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 18, "spi"),
+	GATECLK("samsung-i2s.0", "iis0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 19, "iis"),
+	GATECLK("samsung-i2s.1", "iis1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 20, "iis"),
+	GATECLK("samsung-i2s.2", "iis2", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 21, "iis"),
+	GATECLK("samsung-ac97", "ac97", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 27, NULL),
+	GATECLK("s5p-mfc", "mfc", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_MFC, 0, NULL),
+	GATECLK("s3c2440-i2c.0", "i2c0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 6, "i2c"),
+	GATECLK("s3c2440-i2c.1", "i2c1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 7, "i2c"),
+	GATECLK("s3c2440-i2c.2", "i2c2", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 8, "i2c"),
+	GATECLK("s3c2440-i2c.3", "i2c3", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 9, "i2c"),
+	GATECLK("s3c2440-i2c.4", "i2c4", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 10, "i2c"),
+	GATECLK("s3c2440-i2c.5", "i2c5", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 11, "i2c"),
+	GATECLK("s3c2440-i2c.6", "i2c6", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 12, "i2c"),
+	GATECLK("s3c2440-i2c.7", "i2c7", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 13, "i2c"),
+	GATECLK("s3c2440-hdmiphy-i2c", "i2c", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_PERIL, 14, NULL),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_l, 0), "sysmmu0", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_MFC, 1, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_r, 1), "sysmmu1", "aclk_100", 0,
+			EXYNOS4_CLKGATE_IP_MFC, 2, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(tv, 2), "sysmmu2", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_TV, 4, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(jpeg, 3), "sysmmu3", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 11, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(rot, 4), "sysmmu4", "aclk_200", 0,
+			EXYNOS4210_CLKGATE_IP_IMAGE, 4, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc0, 5), "sysmmu5", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 7, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc1, 6), "sysmmu6", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 8, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc2, 7), "sysmmu7", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 9, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimc3, 8), "sysmmu8", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_CAM, 10, "sysmmu"),
+	GATECLK(SYSMMU_CLOCK_DEVNAME(fimd, 10), "sysmmu10", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_LCD0, 4, "sysmmu"),
+	GATECLK("dma-pl330.0", "dma0", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 0, "dma"),
+	GATECLK("dma-pl330.1", "dma1", "aclk_133", 0,
+			EXYNOS4_CLKGATE_IP_FSYS, 1, "dma"),
+	GATECLK("exynos4-fb.0", "fimd", "aclk_160", 0,
+			EXYNOS4_CLKGATE_IP_LCD0, 0, "lcd"),
+	GATECLK("exynos4210-spi.0", "sclk_spi0", "div_spi0_pre", 0,
+			EXYNOS4_CLKSRC_MASK_PERIL1, 16, "spi_busclk0"),
+	GATECLK("exynos4210-spi.1", "sclk_spi1", "div_spi1_pre", 0,
+			EXYNOS4_CLKSRC_MASK_PERIL1, 20, "spi_busclk0"),
+	GATECLK("exynos4210-spi.2", "sclk_spi2", "div_spi2_pre", 0,
+			EXYNOS4_CLKSRC_MASK_PERIL1, 24, "spi_busclk0"),
+	GATECLK("exynos4-sdhci.0", "sclk_mmc0", "div_mmc0_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 0, "mmc_busclk.2"),
+	GATECLK("exynos4-sdhci.1", "sclk_mmc1", "div_mmc1_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 4, "mmc_busclk.2"),
+	GATECLK("exynos4-sdhci.2", "sclk_mmc2", "div_mmc2_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 8, "mmc_busclk.2"),
+	GATECLK("exynos4-sdhci.3", "sclk_mmc3", "div_mmc3_pre", 0,
+			EXYNOS4_CLKSRC_MASK_FSYS, 12, "mmc_busclk.2"),
+	GATECLK("s5p-mipi-csis.0", "sclk_csis0", "div_csis0", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 24, "sclk_csis"),
+	GATECLK("s5p-mipi-csis.1", "sclk_csis1", "div_csis1", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 28, "sclk_csis"),
+	GATECLK(NULL, "sclk_cam0", "div_cam0", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 16, NULL),
+	GATECLK(NULL, "sclk_cam1", "div_cam1", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 20, NULL),
+	GATECLK("exynos4-fimc.0", "sclk_fimc", "div_fimc0", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 0, "sclk_fimc"),
+	GATECLK("exynos4-fimc.1", "sclk_fimc", "div_fimc1", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 4, "sclk_fimc"),
+	GATECLK("exynos4-fimc.2", "sclk_fimc", "div_fimc2", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 8, "sclk_fimc"),
+	GATECLK("exynos4-fimc.3", "sclk_fimc", "div_fimc3", 0,
+			EXYNOS4_CLKSRC_MASK_CAM, 12, "sclk_fimc"),
+	GATECLK("exynos4-fb.0", "sclk_fimd", "div_fimd0", 0,
+			EXYNOS4_CLKSRC_MASK_LCD0, 0, "sclk_fimd"),
+};
+
+/* register clock common to all Exynos4 platforms */
+void __init exynos4_clk_init(void)
+{
+	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
+			ARRAY_SIZE(exynos4_fixed_rate_clks));
+	samsung_clk_register_mux(exynos4_mux_clks,
+			ARRAY_SIZE(exynos4_mux_clks));
+	samsung_clk_register_div(exynos4_div_clks,
+			ARRAY_SIZE(exynos4_div_clks));
+	samsung_clk_register_gate(exynos4_gate_clks,
+			ARRAY_SIZE(exynos4_gate_clks));
+}
+
+/*
+ * Exynos4210 Specific Clocks
+ */
+
+static const char *exynos4210_vpll_parent_names[] __initdata = {
+		"mout_vpll_src" };
+static const char *mout_vpll_src_parents[] __initdata = {
+		"fin_pll", "sclk_hdmi24m" };
+static const char *exynos4210_mout_vpll_parents[] __initdata = {
+		"mout_vpll_src", "fout_vpll", };
+
+/* Exynos4210 specific fixed rate clocks */
+static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
+	FRATE_CLK(NULL, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* Exynos4210 specific mux-type clocks */
+static struct samsung_mux_clock exynos4210_mux_clks[] = {
+	MUXCLK(NULL, "mout_vpll_src", mout_vpll_src_parents, 0,
+			EXYNOS4_CLKSRC_TOP1, 0, 1, 0),
+	MUXCLK(NULL, "mout_vpll", exynos4210_mout_vpll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 8, 1, 0),
+	MUXCLK(NULL, "mout_mpll", mout_mpll_parents, 0,
+			EXYNOS4_CLKSRC_CPU, 8, 1, 0),
+};
+
+static unsigned long exynos4210_get_rate_apll(unsigned long xtal_rate)
+{
+	return s5p_get_pll45xx(xtal_rate,
+		__raw_readl(EXYNOS4_APLL_CON0), pll_4508);
+}
+
+static unsigned long exynos4210_get_rate_mpll(unsigned long xtal_rate)
+{
+	return s5p_get_pll45xx(xtal_rate,
+		__raw_readl(EXYNOS4_MPLL_CON0), pll_4508);
+}
+
+static unsigned long exynos4210_get_rate_epll(unsigned long xtal_rate)
+{
+	return s5p_get_pll46xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0),
+		__raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
+}
+
+static unsigned long exynos4210_get_rate_vpll(unsigned long vpllsrc_rate)
+{
+	return s5p_get_pll46xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0),
+		__raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
+}
+
+static u32 exynos4_vpll_div[][8] = {
+	{  54000000, 3, 53, 3, 1024, 0, 17, 0 },
+	{ 108000000, 3, 53, 2, 1024, 0, 17, 0 },
+};
+
+static int exynos4210_vpll_set_rate(unsigned long rate)
+{
+	unsigned int vpll_con0, vpll_con1 = 0;
+	unsigned int i;
+
+	vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+	vpll_con0 &= ~(0x1 << 27 |					\
+			PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |	\
+			PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |	\
+			PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+	vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
+	vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |	\
+			PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT |	\
+			PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
+
+	for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) {
+		if (exynos4_vpll_div[i][0] == rate) {
+			vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
+			vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
+			vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
+			vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
+			vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT;
+			vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT;
+			vpll_con0 |= exynos4_vpll_div[i][7] << 27;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(exynos4_vpll_div)) {
+		pr_err("%s: Invalid Clock VPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
+	__raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
+
+	/* Wait for VPLL lock */
+	while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
+		continue;
+
+	return 0;
+}
+
+static const __initconst struct of_device_id clk_match[] = {
+	{ .compatible = "fixed-clock",
+		.data = of_fixed_clk_setup, },
+	{ .compatible = "samsung,clock-mux",
+		.data = samsung_of_clk_register_mux, },
+	{ .compatible = "samsung,clock-pll",
+		.data = samsung_of_clk_register_pll, },
+	{ .compatible = "samsung,clock-div",
+		.data = samsung_of_clk_register_div, },
+	{ .compatible = "samsung,clock-gate",
+		.data = samsung_of_clk_register_gate, },
+	{},
+};
+
+#ifdef CONFIG_OF
+void __init exynos4_of_clk_init(void)
+{
+	struct device_node *np;
+	struct clk *clk;
+
+	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4-clock-ctrl");
+	if (!np) {
+		pr_err("%s: clock controller node not found\n", __func__);
+		return;
+	}
+
+	clk_base = of_iomap(np, 0);
+	WARN(!clk_base, "unable to map clocks registers\n");
+
+	samsung_clk_set_ctrl_base(clk_base);
+	samsung_clk_set_finpll_reg(EXYNOS4_OP_MODE);
+	of_clk_init(clk_match);
+
+	clk = clk_get(NULL, "fout_apll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_apll);
+	clk = clk_get(NULL, "fout_mpll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_mpll);
+	clk = clk_get(NULL, "fout_epll");
+	samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_epll);
+	clk = clk_get(NULL, "fout_vpll");
+	samsung_pll_clk_set_cb(clk, exynos4210_vpll_set_rate,
+				exynos4210_get_rate_mpll);
+}
+#else
+void __init exynos4_of_clk_init(void)
+{
+}
+#endif
+
+/* Exynos4210 specific clock registration */
+void __init exynos4210_clk_init(void)
+{
+	if (of_have_populated_dt()) {
+		exynos4_of_clk_init();
+		goto disp_rates;
+	}
+
+	/* exynos4210 specific fix up for group1_parents */
+	group1_parents[4] = "sclk_usbphy1";
+
+	samsung_clk_set_ctrl_base(S5P_VA_CMU);
+	exynos4_clk_init();
+	samsung_clk_register_pll("fout_apll", pll_parent_names, NULL,
+		NULL, exynos4210_get_rate_apll);
+	samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL,
+		NULL, exynos4210_get_rate_mpll);
+	samsung_clk_register_pll("fout_epll", pll_parent_names, NULL,
+		NULL, exynos4210_get_rate_epll);
+	samsung_clk_register_pll("fout_vpll", exynos4210_vpll_parent_names,
+		NULL, exynos4210_vpll_set_rate, exynos4210_get_rate_vpll);
+
+	samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks,
+			ARRAY_SIZE(exynos4210_fixed_rate_clks));
+	samsung_clk_register_mux(exynos4210_mux_clks,
+			ARRAY_SIZE(exynos4210_mux_clks));
+
+disp_rates:
+	pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n",
+		_get_rate("fout_apll"), _get_rate("fout_mpll"),
+		_get_rate("fout_epll"), _get_rate("fout_vpll"));
+
+	pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n"
+		"         ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"),
+		_get_rate("aclk_200"), _get_rate("aclk_100"),
+		_get_rate("aclk_160"), _get_rate("aclk_133"));
+}
+
+/*
+ * Exynos4x12 Specific Clocks
+ */
+
+static const char *exynos4x12_mout_vpll_parents[] __initdata = {
+		"fin_pll", "fout_vpll", };
+
+/* Exynos4x12 specific mux clocks */
+static struct samsung_mux_clock exynos4x12_mux_clks[] = {
+	MUXCLK(NULL, "mout_mpll", mout_mpll_parents, 0,
+			EXYNOS4_CLKSRC_DMC, 12, 1, 0),
+	MUXCLK(NULL, "mout_vpll", exynos4x12_mout_vpll_parents, 0,
+			EXYNOS4_CLKSRC_TOP0, 8, 1, 0),
+};
+
+static unsigned long exynos4x12_get_rate_apll(unsigned long xtal_rate)
+{
+	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
+}
+
+static unsigned long exynos4x12_get_rate_mpll(unsigned long xtal_rate)
+{
+	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_MPLL_CON0));
+}
+
+static unsigned long exynos4x12_get_rate_epll(unsigned long xtal_rate)
+{
+	return s5p_get_pll36xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0),
+		__raw_readl(EXYNOS4_EPLL_CON1));
+}
+
+static unsigned long exynos4x12_get_rate_vpll(unsigned long vpllsrc_rate)
+{
+	return s5p_get_pll36xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0),
+		__raw_readl(EXYNOS4_VPLL_CON1));
+}
+
+/* Exynos4x12 specific clock registeration */
+void __init exynos4x12_clk_init(void)
+{
+	exynos4_clk_init();
+
+	samsung_clk_register_pll("fout_apll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_apll);
+	samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_mpll);
+	samsung_clk_register_pll("fout_epll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_epll);
+	samsung_clk_register_pll("fout_vpll", pll_parent_names, NULL,
+		NULL, exynos4x12_get_rate_vpll);
+
+	samsung_clk_register_mux(exynos4x12_mux_clks,
+			ARRAY_SIZE(exynos4x12_mux_clks));
+
+	pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n",
+		_get_rate("fout_apll"), _get_rate("fout_mpll"),
+		_get_rate("fout_epll"), _get_rate("fout_vpll"));
+
+	pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n"
+		"         ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"),
+		_get_rate("aclk_200"), _get_rate("aclk_100"),
+		_get_rate("aclk_160"), _get_rate("aclk_133"));
+}
