Merge tag 'multiplatform-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / arch / arm / mach-exynos / common.c
index 4bc1c49c69f1c70b171eb82c2f87139402cddc47..745e304ad0ded17ab6b2f9d9253592739afbc1df 100644 (file)
 #include <linux/of_irq.h>
 #include <linux/export.h>
 #include <linux/irqdomain.h>
-#include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <linux/clocksource.h>
 #include <linux/clk-provider.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/irqchip/chained_irq.h>
 
 #include <asm/proc-fns.h>
 #include <asm/exception.h>
@@ -120,17 +120,6 @@ static struct map_desc exynos_iodesc[] __initdata = {
        },
 };
 
-#ifdef CONFIG_ARCH_EXYNOS5
-static struct map_desc exynos5440_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_CHIPID,
-               .pfn            = __phys_to_pfn(EXYNOS5440_PA_CHIPID),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-#endif
-
 static struct map_desc exynos4_iodesc[] __initdata = {
        {
                .virtual        = (unsigned long)S3C_VA_SYS,
@@ -233,6 +222,33 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
        },
 };
 
+static struct map_desc exynos4210_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
+               .pfn            = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4x12_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
+               .pfn            = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos5250_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM_NS,
+               .pfn            = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
 static struct map_desc exynos5_iodesc[] __initdata = {
        {
                .virtual        = (unsigned long)S3C_VA_SYS,
@@ -321,6 +337,31 @@ void __init exynos_init_late(void)
        exynos_pm_late_initcall();
 }
 
+#ifdef CONFIG_OF
+int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
+                                       int depth, void *data)
+{
+       struct map_desc iodesc;
+       __be32 *reg;
+       unsigned long len;
+
+       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
+               !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
+               return 0;
+
+       reg = of_get_flat_dt_prop(node, "reg", &len);
+       if (reg == NULL || len != (sizeof(unsigned long) * 2))
+               return 0;
+
+       iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
+       iodesc.length = be32_to_cpu(reg[1]) - 1;
+       iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
+       iodesc.type = MT_DEVICE;
+       iotable_init(&iodesc, 1);
+       return 1;
+}
+#endif
+
 /*
  * exynos_map_io
  *
@@ -329,19 +370,12 @@ void __init exynos_init_late(void)
 
 void __init exynos_init_io(struct map_desc *mach_desc, int size)
 {
-       struct map_desc *iodesc = exynos_iodesc;
-       int iodesc_sz = ARRAY_SIZE(exynos_iodesc);
-#if defined(CONFIG_OF) && defined(CONFIG_ARCH_EXYNOS5)
-       unsigned long root = of_get_flat_dt_root();
-
-       /* initialize the io descriptors we need for initialization */
-       if (of_flat_dt_is_compatible(root, "samsung,exynos5440")) {
-               iodesc = exynos5440_iodesc;
-               iodesc_sz = ARRAY_SIZE(exynos5440_iodesc);
-       }
+#ifdef CONFIG_OF
+       if (initial_boot_params)
+               of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
+       else
 #endif
-
-       iotable_init(iodesc, iodesc_sz);
+               iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
 
        if (mach_desc)
                iotable_init(mach_desc, size);
@@ -361,8 +395,10 @@ static void __init exynos4_map_io(void)
        else
                iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
 
-       if (!IS_ENABLED(CONFIG_EXYNOS_ATAGS))
-               return
+       if (soc_is_exynos4210())
+               iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
+       if (soc_is_exynos4212() || soc_is_exynos4412())
+               iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
 
        /* initialize device information early */
        exynos4_default_sdhci0();
@@ -396,6 +432,9 @@ static void __init exynos4_map_io(void)
 static void __init exynos5_map_io(void)
 {
        iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
+
+       if (soc_is_exynos5250())
+               iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
 }
 
 static void __init exynos5440_map_io(void)
@@ -449,6 +488,8 @@ void __init exynos4_init_irq(void)
        if (!of_have_populated_dt())
                combiner_init(S5P_VA_COMBINER_BASE, NULL,
                              max_combiner_nr(), COMBINER_IRQ(0, 0));
+
+       gic_arch_extn.irq_set_wake = s3c_irq_wake;
 }
 
 void __init exynos5_init_irq(void)
@@ -548,8 +589,6 @@ static void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
        s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
 }
 
-
-#ifdef CONFIG_EXYNOS_ATAGS
 static void __iomem *exynos_eint_base;
 
 static DEFINE_SPINLOCK(eint_lock);
@@ -856,7 +895,6 @@ static int __init exynos_init_irq_eint(void)
        return 0;
 }
 arch_initcall(exynos_init_irq_eint);
-#endif
 
 static struct resource exynos4_pmu_resource[] = {
        DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),