bool "Samsung S5PV210/S5PC110"
        select CPU_V7
        select ARCH_SPARSEMEM_ENABLE
+       select ARCH_HAS_HOLES_MEMORYMODEL
        select GENERIC_GPIO
        select HAVE_CLK
        select CLKDEV_LOOKUP
        bool "Samsung EXYNOS4"
        select CPU_V7
        select ARCH_SPARSEMEM_ENABLE
+       select ARCH_HAS_HOLES_MEMORYMODEL
        select GENERIC_GPIO
        select HAVE_CLK
        select CLKDEV_LOOKUP
 
                .name           = "fimg2d",
                .enable         = exynos4_clk_ip_image_ctrl,
                .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "mfc",
+               .devname        = "s5p-mfc",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 0),
        }, {
                .name           = "i2c",
                .devname        = "s3c2440-i2c.0",
        .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
 };
 
+static struct clk *clkset_mout_mfc0_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources clkset_mout_mfc0 = {
+       .sources        = clkset_mout_mfc0_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc0_list),
+};
+
+static struct clksrc_clk clk_mout_mfc0 = {
+       .clk    = {
+               .name           = "mout_mfc0",
+       },
+       .sources        = &clkset_mout_mfc0,
+       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_mfc1_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_mout_mfc1 = {
+       .sources        = clkset_mout_mfc1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc1_list),
+};
+
+static struct clksrc_clk clk_mout_mfc1 = {
+       .clk    = {
+               .name           = "mout_mfc1",
+       },
+       .sources        = &clkset_mout_mfc1,
+       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_mout_mfc_list[] = {
+       [0] = &clk_mout_mfc0.clk,
+       [1] = &clk_mout_mfc1.clk,
+};
+
+static struct clksrc_sources clkset_mout_mfc = {
+       .sources        = clkset_mout_mfc_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc_list),
+};
+
 static struct clksrc_clk clk_dout_mmc0 = {
        .clk            = {
                .name           = "dout_mmc0",
                .sources = &clkset_mout_g2d,
                .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
                .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mfc",
+                       .devname        = "s5p-mfc",
+               },
+               .sources = &clkset_mout_mfc,
+               .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
+               .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
        }, {
                .clk            = {
                        .name           = "sclk_mmc",
        &clk_dout_mmc2,
        &clk_dout_mmc3,
        &clk_dout_mmc4,
+       &clk_mout_mfc0,
+       &clk_mout_mfc1,
 };
 
 static int xtal_rate;
 
 
 #define EXYNOS4_PA_EHCI                        0x12580000
 #define EXYNOS4_PA_HSPHY               0x125B0000
+#define EXYNOS4_PA_MFC                 0x13400000
 
 #define EXYNOS4_PA_UART                        0x13800000
 
 #define S5P_PA_ONENAND_DMA             EXYNOS4_PA_ONENAND_DMA
 #define S5P_PA_SDRAM                   EXYNOS4_PA_SDRAM
 #define S5P_PA_SROMC                   EXYNOS4_PA_SROMC
+#define S5P_PA_MFC                     EXYNOS4_PA_MFC
 #define S5P_PA_SYSCON                  EXYNOS4_PA_SYSCON
 #define S5P_PA_TIMER                   EXYNOS4_PA_TIMER
 #define S5P_PA_EHCI                    EXYNOS4_PA_EHCI
 
                .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1 << 26),
+       }, {
+               .name           = "mfc",
+               .devname        = "s5p-mfc",
+               .parent         = &clk_pclk_psys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 16),
        }, {
                .name           = "otg",
                .parent         = &clk_hclk_psys.clk,
        }, {
                .clk            = {
                        .name           = "sclk_mfc",
+                       .devname        = "s5p-mfc",
                        .enable         = s5pv210_clk_ip0_ctrl,
                        .ctrlbit        = (1 << 16),
                },
 
 
 #define S5PV210_PA_CFCON               0xE8200000
 
+#define S5PV210_PA_MFC                 0xF1700000
+
 #define S5PV210_PA_HSMMC(x)            (0xEB000000 + ((x) * 0x100000))
 
 #define S5PV210_PA_HSOTG               0xEC000000
 #define S5P_PA_FIMC1                   S5PV210_PA_FIMC1
 #define S5P_PA_FIMC2                   S5PV210_PA_FIMC2
 #define S5P_PA_MIPI_CSIS0              S5PV210_PA_MIPI_CSIS
+#define S5P_PA_MFC                     S5PV210_PA_MFC
 #define S5P_PA_ONENAND                 S5PC110_PA_ONENAND
 #define S5P_PA_ONENAND_DMA             S5PC110_PA_ONENAND_DMA
 #define S5P_PA_SDRAM                   S5PV210_PA_SDRAM
 
        help
          Compile in platform device definitions for FIMD controller 0
 
+config S5P_DEV_MFC
+       bool
+       help
+         Compile in platform device definitions for MFC
+
 config S5P_DEV_ONENAND
        bool
        help
 
 obj-$(CONFIG_S5P_HRT)          += s5p-time.o
 
 # devices
-
+obj-$(CONFIG_S5P_DEV_MFC)      += dev-mfc.o
 obj-$(CONFIG_S5P_DEV_FIMC0)    += dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)    += dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)    += dev-fimc2.o
 
--- /dev/null
+/* linux/arch/arm/plat-s5p/dev-mfc.c
+ *
+ * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
+ *
+ * Base S5P MFC resource and device definitions
+ *
+ * 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/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/memblock.h>
+#include <linux/ioport.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/irqs.h>
+#include <plat/mfc.h>
+
+static struct resource s5p_mfc_resource[] = {
+       [0] = {
+               .start  = S5P_PA_MFC,
+               .end    = S5P_PA_MFC + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_MFC,
+               .end    = IRQ_MFC,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device s5p_device_mfc = {
+       .name           = "s5p-mfc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_mfc_resource),
+       .resource       = s5p_mfc_resource,
+};
+
+/*
+ * MFC hardware has 2 memory interfaces which are modelled as two separate
+ * platform devices to let dma-mapping distinguish between them.
+ *
+ * MFC parent device (s5p_device_mfc) must be registered before memory
+ * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
+ */
+
+static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_mfc_l = {
+       .name           = "s5p-mfc-l",
+       .id             = -1,
+       .dev            = {
+               .parent                 = &s5p_device_mfc.dev,
+               .dma_mask               = &s5p_mfc_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+struct platform_device s5p_device_mfc_r = {
+       .name           = "s5p-mfc-r",
+       .id             = -1,
+       .dev            = {
+               .parent                 = &s5p_device_mfc.dev,
+               .dma_mask               = &s5p_mfc_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+struct s5p_mfc_reserved_mem {
+       phys_addr_t     base;
+       unsigned long   size;
+       struct device   *dev;
+};
+
+static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
+
+void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
+                               phys_addr_t lbase, unsigned int lsize)
+{
+       int i;
+
+       s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev;
+       s5p_mfc_mem[0].base = rbase;
+       s5p_mfc_mem[0].size = rsize;
+
+       s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev;
+       s5p_mfc_mem[1].base = lbase;
+       s5p_mfc_mem[1].size = lsize;
+
+       for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
+               struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
+               if (memblock_remove(area->base, area->size)) {
+                       printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n",
+                              area->size, (unsigned long) area->base);
+                       area->base = 0;
+               }
+       }
+}
+
+static int __init s5p_mfc_memory_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
+               struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
+               if (!area->base)
+                       continue;
+
+               if (dma_declare_coherent_memory(area->dev, area->base,
+                               area->base, area->size,
+                               DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0)
+                       printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n",
+                              area->size, (unsigned long) area->base);
+       }
+       return 0;
+}
+device_initcall(s5p_mfc_memory_init);
 
--- /dev/null
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ *
+ * 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.
+ */
+
+#ifndef __PLAT_S5P_MFC_H
+#define __PLAT_S5P_MFC_H
+
+/**
+ * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
+ * @rbase:     base address for MFC 'right' memory interface
+ * @rsize:     size of the memory reserved for MFC 'right' interface
+ * @lbase:     base address for MFC 'left' memory interface
+ * @lsize:     size of the memory reserved for MFC 'left' interface
+ *
+ * This function reserves system memory for both MFC device memory
+ * interfaces and registers it to respective struct device entries as
+ * coherent memory.
+ */
+void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
+                               phys_addr_t lbase, unsigned int lsize);
+
+#endif /* __PLAT_S5P_MFC_H */
 
 extern struct platform_device s5p_device_fimc2;
 extern struct platform_device s5p_device_fimc3;
 
+extern struct platform_device s5p_device_mfc;
+extern struct platform_device s5p_device_mfc_l;
+extern struct platform_device s5p_device_mfc_r;
 extern struct platform_device s5p_device_mipi_csis0;
 extern struct platform_device s5p_device_mipi_csis1;