Merge tag 'multiplatform-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 May 2013 18:28:42 +0000 (11:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 May 2013 18:28:42 +0000 (11:28 -0700)
Pull late ARM Exynos multiplatform changes from Arnd Bergmann:
 "These continue the multiplatform support for exynos, adding support
  for building most of the essential drivers (clocksource, clk, irqchip)
  when combined with other platforms.  As a result, it should become
  really easy to add full multiplatform exynos support in 3.11, although
  we don't yet enable it for 3.10.

  The changes were not included in the earlier multiplatform series in
  order to avoid clashes with the other Exynos updates.

  This also includes work from Tomasz Figa to fix the pwm clocksource
  code on Exynos, which is not strictly required for multiplatform, but
  related to the other patches in this set and needed as a bug fix for
  at least one board."

* tag 'multiplatform-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (22 commits)
  ARM: dts: exynops4210: really add universal_c210 dts
  ARM: dts: exynos4210: Add basic dts file for universal_c210 board
  ARM: dts: exynos4: Add node for PWM device
  ARM: SAMSUNG: Do not register legacy timer interrupts on Exynos
  clocksource: samsung_pwm_timer: Work around rounding errors in clockevents core
  clocksource: samsung_pwm_timer: Correct programming of clock events
  clocksource: samsung_pwm_timer: Use proper clockevents max_delta
  clocksource: samsung_pwm_timer: Add support for non-DT platforms
  clocksource: samsung_pwm_timer: Drop unused samsung_pwm struct
  clocksource: samsung_pwm_timer: Keep all driver data in a structure
  clocksource: samsung_pwm_timer: Make PWM spinlock global
  clocksource: samsung_pwm_timer: Let platforms select the driver
  Documentation: Add device tree bindings for Samsung PWM timers
  clocksource: add samsung pwm timer driver
  irqchip: exynos: look up irq using irq_find_mapping
  irqchip: exynos: pass irq_base from platform
  irqchip: exynos: localize irq lookup for ATAGS
  irqchip: exynos: allocate combiner_data dynamically
  irqchip: exynos: pass max combiner number to combiner_init
  ARM: exynos: add missing properties for combiner IRQs
  ...

12 files changed:
1  2 
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/mach-exynos/common.c
arch/arm/mach-exynos/common.h
arch/arm/plat-samsung/Kconfig
drivers/clk/samsung/clk-exynos5250.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/exynos_mct.c
drivers/irqchip/exynos-combiner.c

index 5f1f4dfd706ece84fe9937c87cd8d178301c053a,2d870f4e4e2b18164c83ce9d63f518ee9bc86995..8562af4fe8fd46e4639c275120ce09129efac733
@@@ -3,7 -3,6 +3,7 @@@ ifeq ($(CONFIG_OF),y
  # Keep at91 dtb files sorted alphabetically for each SoC
  # rm9200
  dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb
 +dtb-$(CONFIG_ARCH_AT91) += mpa1600.dtb
  # sam9260
  dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb
  dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb
@@@ -27,17 -26,11 +27,17 @@@ dtb-$(CONFIG_ARCH_AT91) += pm9g45.dt
  # sam9n12
  dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb
  # sam9x5
 +dtb-$(CONFIG_ARCH_AT91) += at91-ariag25.dtb
  dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb
  dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb
  dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
  dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
  dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
 +# sama5d3
 +dtb-$(CONFIG_ARCH_AT91)       += sama5d31ek.dtb
 +dtb-$(CONFIG_ARCH_AT91)       += sama5d33ek.dtb
 +dtb-$(CONFIG_ARCH_AT91)       += sama5d34ek.dtb
 +dtb-$(CONFIG_ARCH_AT91)       += sama5d35ek.dtb
  
  dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
  dtb-$(CONFIG_ARCH_BCM) += bcm11351-brt.dtb
@@@ -49,11 -42,11 +49,12 @@@ dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510
  dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
        exynos4210-smdkv310.dtb \
        exynos4210-trats.dtb \
+       exynos4210-universal_c210.dtb \
        exynos4412-odroidx.dtb \
        exynos4412-smdk4412.dtb \
        exynos4412-origen.dtb \
        exynos5250-arndale.dtb \
 +      exynos5440-sd5v1.dtb \
        exynos5250-smdk5250.dtb \
        exynos5250-snow.dtb \
        exynos5440-ssdk5440.dtb
@@@ -62,8 -55,7 +63,8 @@@ dtb-$(CONFIG_ARCH_HIGHBANK) += highbank
  dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
        integratorcp.dtb
  dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 -dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \
 +dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
 +      kirkwood-dns320.dtb \
        kirkwood-dns325.dtb \
        kirkwood-dockstar.dtb \
        kirkwood-dreamplug.dtb \
@@@ -77,7 -69,6 +78,7 @@@
        kirkwood-lschlv2.dtb \
        kirkwood-lsxhl.dtb \
        kirkwood-mplcec4.dtb \
 +      kirkwood-netgear_readynas_duo_v2.dtb \
        kirkwood-ns2.dtb \
        kirkwood-ns2lite.dtb \
        kirkwood-ns2max.dtb \
@@@ -100,26 -91,19 +101,26 @@@ dtb-$(CONFIG_ARCH_MXC) += 
        imx25-karo-tx25.dtb \
        imx25-pdk.dtb \
        imx27-apf27.dtb \
 +      imx27-apf27dev.dtb \
        imx27-pdk.dtb \
 +      imx27-phytec-phycore.dtb \
        imx31-bug.dtb \
        imx51-apf51.dtb \
 +      imx51-apf51dev.dtb \
        imx51-babbage.dtb \
        imx53-ard.dtb \
        imx53-evk.dtb \
        imx53-mba53.dtb \
        imx53-qsb.dtb \
        imx53-smd.dtb \
 +      imx6dl-sabreauto.dtb \
 +      imx6dl-sabresd.dtb \
 +      imx6dl-wandboard.dtb \
        imx6q-arm2.dtb \
        imx6q-sabreauto.dtb \
        imx6q-sabrelite.dtb \
 -      imx6q-sabresd.dtb
 +      imx6q-sabresd.dtb \
 +      imx6q-sbc6x.dtb
  dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
        imx23-olinuxino.dtb \
        imx23-stmp378x_devb.dtb \
        imx28-tx28.dtb
  dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb
  dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
 +      omap3430-sdp.dtb \
        omap3-beagle.dtb \
 +      omap3-devkit8000.dtb \
        omap3-beagle-xm.dtb \
        omap3-evm.dtb \
        omap3-tobi.dtb \
 +      omap3-igep0020.dtb \
 +      omap3-igep0030.dtb \
        omap4-panda.dtb \
        omap4-panda-a4.dtb \
        omap4-panda-es.dtb \
@@@ -160,12 -140,7 +161,12 @@@ dtb-$(CONFIG_ARCH_U8500) += snowball.dt
        ccu9540.dtb
  dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
        r8a7740-armadillo800eva.dtb \
 +      r8a7778-bockw.dtb \
 +      r8a7779-marzen-reference.dtb \
 +      r8a7790-lager.dtb \
        sh73a0-kzm9g.dtb \
 +      sh73a0-kzm9g-reference.dtb \
 +      r8a73a4-ape6evm.dtb \
        sh7372-mackerel.dtb
  dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \
        socfpga_vt.dtb
@@@ -194,8 -169,6 +195,8 @@@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-har
        tegra30-cardhu-a04.dtb \
        tegra114-dalmore.dtb \
        tegra114-pluto.dtb
 +dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
 +      versatile-pb.dtb
  dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
        vexpress-v2p-ca9.dtb \
        vexpress-v2p-ca15-tc1.dtb \
index 7cfbbd3b7732bdaa0869420ddd12a09a31f67092,b620e34fbd92ae45eea9cbbcfa008231abb43823..359694c7891803e23964394f0722cd89243e266e
                i2c7 = &i2c_7;
        };
  
 +      chipid@10000000 {
 +              compatible = "samsung,exynos4210-chipid";
 +              reg = <0x10000000 0x100>;
 +      };
 +
        pd_mfc: mfc-power-domain@10023C40 {
                compatible = "samsung,exynos4210-pd";
                reg = <0x10023C40 0x20>;
                reg = <0x10440000 0x1000>;
        };
  
 +      sys_reg: sysreg {
 +              compatible = "samsung,exynos4-sysreg", "syscon";
 +              reg = <0x10010000 0x400>;
 +      };
 +
        watchdog@10060000 {
                compatible = "samsung,s3c2410-wdt";
                reg = <0x10060000 0x100>;
                interrupts = <0 58 0>;
                clocks = <&clock 317>;
                clock-names = "i2c";
 +              pinctrl-names = "default";
 +              pinctrl-0 = <&i2c0_bus>;
                status = "disabled";
        };
  
                interrupts = <0 59 0>;
                clocks = <&clock 318>;
                clock-names = "i2c";
 +              pinctrl-names = "default";
 +              pinctrl-0 = <&i2c1_bus>;
                status = "disabled";
        };
  
                #size-cells = <0>;
                clocks = <&clock 327>, <&clock 159>;
                clock-names = "spi", "spi_busclk0";
 +              pinctrl-names = "default";
 +              pinctrl-0 = <&spi0_bus>;
                status = "disabled";
        };
  
                #size-cells = <0>;
                clocks = <&clock 328>, <&clock 160>;
                clock-names = "spi", "spi_busclk0";
 +              pinctrl-names = "default";
 +              pinctrl-0 = <&spi1_bus>;
                status = "disabled";
        };
  
                #size-cells = <0>;
                clocks = <&clock 329>, <&clock 161>;
                clock-names = "spi", "spi_busclk0";
 +              pinctrl-names = "default";
 +              pinctrl-0 = <&spi2_bus>;
                status = "disabled";
        };
  
+       pwm@139D0000 {
+               compatible = "samsung,exynos4210-pwm";
+               reg = <0x139D0000 0x1000>;
+               interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
+               #pwm-cells = <2>;
+               status = "disabled";
+       };
        amba {
                #address-cells = <1>;
                #size-cells = <1>;
                        #dma-requests = <1>;
                };
        };
 +
 +      fimd: fimd@11c00000 {
 +              compatible = "samsung,exynos4210-fimd";
 +              interrupt-parent = <&combiner>;
 +              reg = <0x11c00000 0x20000>;
 +              interrupt-names = "fifo", "vsync", "lcd_sys";
 +              interrupts = <11 0>, <11 1>, <11 2>;
 +              clocks = <&clock 140>, <&clock 283>;
 +              clock-names = "sclk_fimd", "fimd";
 +              samsung,power-domain = <&pd_lcd0>;
 +              status = "disabled";
 +      };
  };
index 66e6b03bf35e71b54f7c95cbf5e33bb6744464e0,5feccffae409ee135436a3401648aacb8ec3699b..54710de829086f8b94fd0202a696f967dea72733
@@@ -41,6 -41,7 +41,7 @@@
        };
  
        combiner:interrupt-controller@10440000 {
+               samsung,combiner-nr = <16>;
                interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
                             <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
                             <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
                reg = <0x100C0000 0x100>;
                interrupts = <2 4>;
        };
 +
 +      g2d@12800000 {
 +              compatible = "samsung,s5pv210-g2d";
 +              reg = <0x12800000 0x1000>;
 +              interrupts = <0 89 0>;
 +              status = "disabled";
 +      };
  };
index 7f428272fee646980bea4e3d5d745eecbe6983ab,f433206bd3c5ef95c4c8993d9a2d5776b8510a03..270b389e0a1ba58f7bb7f0b46db2320ec5509ac7
                cpu-offset = <0x4000>;
        };
  
+       interrupt-controller@10440000 {
+               samsung,combiner-nr = <20>;
+               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+                            <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+                            <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
+       };
        mct@10050000 {
                compatible = "samsung,exynos4412-mct";
                reg = <0x10050000 0x800>;
                                        <0x7 0 &gic 1 12 0>;
                };
        };
 +
 +      mshc@12550000 {
 +              compatible = "samsung,exynos4412-dw-mshc";
 +              reg = <0x12550000 0x1000>;
 +              interrupts = <0 77 0>;
 +              #address-cells = <1>;
 +              #size-cells = <0>;
 +      };
  };
index d126f26dbbf1e6d7a22f18e1d993154045fb2be5,4bc1c49c69f1c70b171eb82c2f87139402cddc47..745e304ad0ded17ab6b2f9d9253592739afbc1df
  #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,6 -120,17 +120,6 @@@ static struct map_desc exynos_iodesc[] 
        },
  };
  
 -#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,
@@@ -222,33 -233,6 +222,33 @@@ static struct map_desc exynos4_iodesc1[
        },
  };
  
 +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,
@@@ -337,31 -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
   *
  
  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);
@@@ -395,10 -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();
  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)
@@@ -452,13 -413,26 +452,26 @@@ void __init exynos_init_time(void
        } else {
                /* todo: remove after migrating legacy E4 platforms to dt */
  #ifdef CONFIG_ARCH_EXYNOS4
-               exynos4_clk_init(NULL);
+               exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1);
                exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
  #endif
-               mct_init();
+               mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1);
        }
  }
  
+ static unsigned int max_combiner_nr(void)
+ {
+       if (soc_is_exynos5250())
+               return EXYNOS5_MAX_COMBINER_NR;
+       else if (soc_is_exynos4412())
+               return EXYNOS4412_MAX_COMBINER_NR;
+       else if (soc_is_exynos4212())
+               return EXYNOS4212_MAX_COMBINER_NR;
+       else
+               return EXYNOS4210_MAX_COMBINER_NR;
+ }
  void __init exynos4_init_irq(void)
  {
        unsigned int gic_bank_offset;
  #endif
  
        if (!of_have_populated_dt())
-               combiner_init(S5P_VA_COMBINER_BASE, NULL);
-       /*
-        * The parameters of s5p_init_irq() are for VIC init.
-        * Theses parameters should be NULL and 0 because EXYNOS4
-        * uses GIC instead of VIC.
-        */
-       s5p_init_irq(NULL, 0);
+               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)
  #ifdef CONFIG_OF
        irqchip_init();
  #endif
-       /*
-        * The parameters of s5p_init_irq() are for VIC init.
-        * Theses parameters should be NULL and 0 because EXYNOS4
-        * uses GIC instead of VIC.
-        */
-       if (!of_machine_is_compatible("samsung,exynos5440"))
-               s5p_init_irq(NULL, 0);
        gic_arch_extn.irq_set_wake = s3c_irq_wake;
  }
  
@@@ -590,6 -548,8 +589,6 @@@ static void __init exynos4_init_uarts(s
        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);
@@@ -896,6 -856,7 +895,6 @@@ static int __init exynos_init_irq_eint(
        return 0;
  }
  arch_initcall(exynos_init_irq_eint);
 -#endif
  
  static struct resource exynos4_pmu_resource[] = {
        DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),
index b17448c1a164e931a0adf825c924ec39cd03a481,3e72d03a385e7a11f7b59c5ff7d16d1ee972ef13..60dd35cc01a608102ab629a748ea1d19ca8fc2a6
@@@ -14,7 -14,7 +14,7 @@@
  
  #include <linux/of.h>
  
extern void mct_init(void);
void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1);
  void exynos_init_time(void);
  extern unsigned long xxti_f, xusbxti_f;
  
@@@ -27,11 -27,9 +27,11 @@@ void exynos5_restart(char mode, const c
  void exynos_init_late(void);
  
  /* ToDo: remove these after migrating legacy exynos4 platforms to dt */
- void exynos4_clk_init(struct device_node *np);
+ void exynos4_clk_init(struct device_node *np, int is_exynos4210, void __iomem *reg_base, unsigned long xom);
  void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
  
 +void exynos_firmware_init(void);
 +
  #ifdef CONFIG_PM_GENERIC_DOMAINS
  int exynos_pm_late_initcall(void);
  #else
@@@ -71,7 -69,8 +71,8 @@@ void exynos4212_register_clocks(void)
  #endif
  
  struct device_node;
- void combiner_init(void __iomem *combiner_base, struct device_node *np);
+ void combiner_init(void __iomem *combiner_base, struct device_node *np,
+                       unsigned int max_nr, int irq_base);
  
  extern struct smp_operations exynos_smp_ops;
  
index 54d186106f9f2c9727ee1f662adf44ac1cad83d5,53b2d59ca252f6d52683a9d8c9d433f36a5328ac..f8ed2de0a6783cfe498577b3cab7de531b192761
@@@ -13,6 -13,10 +13,6 @@@ config PLAT_SAMSUN
        help
          Base platform code for all Samsung SoC based systems
  
 -config PLAT_SAMSUNG_SINGLE
 -      def_bool PLAT_SAMSUNG && !ARCH_MULTIPLATFORM
 -      
 -
  config PLAT_S5P
        bool
        depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
@@@ -23,7 -27,7 +23,7 @@@
        select GIC_NON_BANKED if ARCH_EXYNOS4
        select NO_IOPORT
        select PLAT_SAMSUNG
 -      select S3C_GPIO_TRACK if PLAT_SAMSUNG_SINGLE
 +      select S3C_GPIO_TRACK
        select S5P_GPIO_DRVSTR
        select SAMSUNG_CLKSRC if !COMMON_CLK
        select SAMSUNG_GPIOLIB_4BIT
@@@ -37,6 -41,14 +37,6 @@@ if PLAT_SAMSUN
  
  comment "Boot options"
  
 -config S3C_BOOT_WATCHDOG
 -      bool "S3C Initialisation watchdog"
 -      depends on S3C2410_WATCHDOG
 -      help
 -        Say y to enable the watchdog during the kernel decompression
 -        stage. If the kernel fails to uncompress, then the watchdog
 -        will trigger a reset and the system should restart.
 -
  config S3C_BOOT_ERROR_RESET
        bool "S3C Reboot on decompression error"
        help
@@@ -93,9 -105,9 +93,9 @@@ config SAMSUNG_IRQ_VIC_TIME
           Internal configuration to build the VIC timer interrupt code.
  
  config S5P_IRQ
-       def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+       def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
        help
-         Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs
+         Support common interrupt part for ARCH_S5P SoCs
  
  config S5P_EXT_INT
        bool
@@@ -117,6 -129,12 +117,6 @@@ config SAMSUNG_GPIOLIB_4BI
          configuration. GPIOlib shall be compiled only for S3C64XX and S5P
          series of processors.
  
 -config S3C_GPIO_CFG_S3C64XX
 -      bool
 -      help
 -        Internal configuration to enable S3C64XX style GPIO configuration
 -        functions.
 -
  config S5P_GPIO_DRVSTR
        bool
        help
@@@ -164,6 -182,7 +164,6 @@@ config S5P_DEV_UAR
  
  config S3C_ADC
        bool "ADC common driver support"
 -      depends on PLAT_SAMSUNG_SINGLE
        help
          Core support for the ADC block found in the Samsung SoC systems
          for drivers such as the touchscreen and hwmon to use to share
index bb54606ff035d28ab4a8a3b34b46306e94380fc6,61068cda2ab3837a76a5e86ed447e034c863c6fe..5c97e75924a8a87b4aebfa5e7ddfde1f31231fff
@@@ -16,7 -16,6 +16,6 @@@
  #include <linux/of.h>
  #include <linux/of_address.h>
  
- #include <plat/cpu.h>
  #include "clk.h"
  #include "clk-pll.h"
  
@@@ -276,10 -275,10 +275,10 @@@ struct samsung_div_clock exynos5250_div
        DIV(none, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8),
        DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
        DIV(none, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4),
 -      DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 8, 8),
 -      DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 24, 8),
 -      DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 8, 8),
 -      DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 24, 8),
 +      DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
 +      DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
 +      DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
 +      DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4),
        DIV(none, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4),
        DIV(none, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4),
        DIV(none, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4),
@@@ -421,13 -420,13 +420,13 @@@ struct samsung_gate_clock exynos5250_ga
                        SRC_MASK_DISP1_0, 20, 0, 0),
        GATE(sclk_audio0, "sclk_audio0", "div_audio0",
                        SRC_MASK_MAU, 0, CLK_SET_RATE_PARENT, 0),
 -      GATE(sclk_mmc0, "sclk_mmc0", "div_mmc0",
 +      GATE(sclk_mmc0, "sclk_mmc0", "div_mmc_pre0",
                        SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
 -      GATE(sclk_mmc1, "sclk_mmc1", "div_mmc1",
 +      GATE(sclk_mmc1, "sclk_mmc1", "div_mmc_pre1",
                        SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0),
 -      GATE(sclk_mmc2, "sclk_mmc2", "div_mmc2",
 +      GATE(sclk_mmc2, "sclk_mmc2", "div_mmc_pre2",
                        SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0),
 -      GATE(sclk_mmc3, "sclk_mmc3", "div_mmc3",
 +      GATE(sclk_mmc3, "sclk_mmc3", "div_mmc_pre3",
                        SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0),
        GATE(sclk_sata, "sclk_sata", "div_sata",
                        SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
index c20de4a85cbd69c3107fbf0e9befde5b1047ca7b,5d9bab2b5012a2ad0ce3439361c88190511ed4c3..f151c6cf27c336ffa756c68a69dc2d4dd20dfb8f
@@@ -25,7 -25,7 +25,7 @@@ config DW_APB_TIMER_O
  config ARMADA_370_XP_TIMER
        bool
  
 -config SUNXI_TIMER
 +config SUN4I_TIMER
        bool
  
  config VT8500_TIMER
@@@ -65,7 -65,6 +65,7 @@@ config CLKSRC_DBX500_PRCMU_SCHED_CLOC
  
  config ARM_ARCH_TIMER
        bool
 +      select CLKSRC_OF if OF
  
  config CLKSRC_METAG_GENERIC
        def_bool y if METAG
@@@ -76,3 -75,12 +76,12 @@@ config CLKSRC_EXYNOS_MC
        def_bool y if ARCH_EXYNOS
        help
          Support for Multi Core Timer controller on Exynos SoCs.
+ config CLKSRC_SAMSUNG_PWM
+       bool
+       select CLKSRC_MMIO
+       help
+         This is a new clocksource driver for the PWM timer found in
+         Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
+         for all devicetree enabled platforms. This driver will be
+         needed only on systems that do not have the Exynos MCT available.
index caacdb63aff982a97e4950759fa3527cfe37d51b,2289f0cb4c4c517405b21cd8c862369314d37822..8d979c72aa946a97a19c940a23133b762f6d33d8
@@@ -16,15 -16,12 +16,16 @@@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU)   += nom
  obj-$(CONFIG_CLKSRC_DBX500_PRCMU)     += clksrc-dbx500-prcmu.o
  obj-$(CONFIG_ARMADA_370_XP_TIMER)     += time-armada-370-xp.o
  obj-$(CONFIG_ARCH_BCM2835)    += bcm2835_timer.o
 -obj-$(CONFIG_SUNXI_TIMER)     += sunxi_timer.o
 +obj-$(CONFIG_ARCH_MARCO)      += timer-marco.o
 +obj-$(CONFIG_ARCH_MXS)                += mxs_timer.o
 +obj-$(CONFIG_ARCH_PRIMA2)     += timer-prima2.o
 +obj-$(CONFIG_SUN4I_TIMER)     += sun4i_timer.o
  obj-$(CONFIG_ARCH_TEGRA)      += tegra20_timer.o
  obj-$(CONFIG_VT8500_TIMER)    += vt8500_timer.o
 +obj-$(CONFIG_ARCH_BCM)                += bcm_kona_timer.o
  obj-$(CONFIG_CADENCE_TTC_TIMER)       += cadence_ttc_timer.o
  obj-$(CONFIG_CLKSRC_EXYNOS_MCT)       += exynos_mct.o
+ obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)      += samsung_pwm_timer.o
  
  obj-$(CONFIG_ARM_ARCH_TIMER)          += arm_arch_timer.o
  obj-$(CONFIG_CLKSRC_METAG_GENERIC)    += metag_generic.o
index 13a9e4923a0350fd59ea5d914c366d9739819d81,a6ca0fb0693985c843434a18b18ba98aa5327ee3..662fcc065821f3100e55e014b2ce1801966e87e8
  #include <linux/of_address.h>
  #include <linux/clocksource.h>
  
 -#include <asm/arch_timer.h>
  #include <asm/localtimer.h>
- #include <plat/cpu.h>
- #include <mach/map.h>
- #include <mach/irqs.h>
  #include <asm/mach/time.h>
  
  #define EXYNOS4_MCTREG(x)             (x)
@@@ -510,18 -506,14 +505,14 @@@ static void __init exynos4_timer_resour
  #endif /* CONFIG_LOCAL_TIMERS */
  }
  
- void __init mct_init(void)
+ void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1)
  {
-       if (soc_is_exynos4210()) {
-               mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0;
-               mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0;
-               mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1;
-               mct_int_type = MCT_INT_SPI;
-       } else {
-               panic("unable to determine mct controller type\n");
-       }
+       mct_irqs[MCT_G0_IRQ] = irq_g0;
+       mct_irqs[MCT_L0_IRQ] = irq_l0;
+       mct_irqs[MCT_L1_IRQ] = irq_l1;
+       mct_int_type = MCT_INT_SPI;
  
-       exynos4_timer_resources(NULL, S5P_VA_SYSTIMER);
+       exynos4_timer_resources(NULL, base);
        exynos4_clocksource_init();
        exynos4_clockevent_init();
  }
index 02492ab20d22a466a7ba4923e94c02ed892870f3,494c2e21b538a0b060a5c3044fc34acfa1e5f09c..a9d2b2fa4afd3149b261fb256fb47bcde79c81aa
  #include <linux/export.h>
  #include <linux/init.h>
  #include <linux/io.h>
+ #include <linux/slab.h>
  #include <linux/irqdomain.h>
 +#include <linux/irqchip/chained_irq.h>
  #include <linux/of_address.h>
  #include <linux/of_irq.h>
  #include <asm/mach/irq.h>
  
+ #ifdef CONFIG_EXYNOS_ATAGS
  #include <plat/cpu.h>
+ #endif
  
  #include "irqchip.h"
  
  #define COMBINER_ENABLE_CLEAR 0x4
  #define COMBINER_INT_STATUS   0xC
  
+ #define IRQ_IN_COMBINER               8
  static DEFINE_SPINLOCK(irq_controller_lock);
  
  struct combiner_chip_data {
-       unsigned int irq_offset;
+       unsigned int hwirq_offset;
        unsigned int irq_mask;
        void __iomem *base;
        unsigned int parent_irq;
  };
  
  static struct irq_domain *combiner_irq_domain;
- static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
  
  static inline void __iomem *combiner_base(struct irq_data *data)
  {
@@@ -77,11 -80,11 +81,11 @@@ static void combiner_handle_cascade_irq
        if (status == 0)
                goto out;
  
-       combiner_irq = __ffs(status);
+       combiner_irq = chip_data->hwirq_offset + __ffs(status);
+       cascade_irq = irq_find_mapping(combiner_irq_domain, combiner_irq);
  
-       cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
-       if (unlikely(cascade_irq >= NR_IRQS))
-               do_bad_IRQ(cascade_irq, desc);
+       if (unlikely(!cascade_irq))
+               do_bad_IRQ(irq, desc);
        else
                generic_handle_irq(cascade_irq);
  
@@@ -113,40 -116,25 +117,25 @@@ static struct irq_chip combiner_chip = 
  #endif
  };
  
- static unsigned int max_combiner_nr(void)
- {
-       if (soc_is_exynos5250())
-               return EXYNOS5_MAX_COMBINER_NR;
-       else if (soc_is_exynos4412())
-               return EXYNOS4412_MAX_COMBINER_NR;
-       else if (soc_is_exynos4212())
-               return EXYNOS4212_MAX_COMBINER_NR;
-       else
-               return EXYNOS4210_MAX_COMBINER_NR;
- }
- static void __init combiner_cascade_irq(unsigned int combiner_nr,
+ static void __init combiner_cascade_irq(struct combiner_chip_data *combiner_data,
                                        unsigned int irq)
  {
-       if (combiner_nr >= max_combiner_nr())
-               BUG();
-       if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
+       if (irq_set_handler_data(irq, combiner_data) != 0)
                BUG();
        irq_set_chained_handler(irq, combiner_handle_cascade_irq);
  }
  
- static void __init combiner_init_one(unsigned int combiner_nr,
+ static void __init combiner_init_one(struct combiner_chip_data *combiner_data,
+                                    unsigned int combiner_nr,
                                     void __iomem *base, unsigned int irq)
  {
-       combiner_data[combiner_nr].base = base;
-       combiner_data[combiner_nr].irq_offset = irq_find_mapping(
-               combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
-       combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
-       combiner_data[combiner_nr].parent_irq = irq;
+       combiner_data->base = base;
+       combiner_data->hwirq_offset = (combiner_nr & ~3) * IRQ_IN_COMBINER;
+       combiner_data->irq_mask = 0xff << ((combiner_nr % 4) << 3);
+       combiner_data->parent_irq = irq;
  
        /* Disable all interrupts */
-       __raw_writel(combiner_data[combiner_nr].irq_mask,
-                    base + COMBINER_ENABLE_CLEAR);
+       __raw_writel(combiner_data->irq_mask, base + COMBINER_ENABLE_CLEAR);
  }
  
  #ifdef CONFIG_OF
@@@ -162,7 -150,7 +151,7 @@@ static int combiner_irq_domain_xlate(st
        if (intsize < 2)
                return -EINVAL;
  
-       *out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1];
+       *out_hwirq = intspec[0] * IRQ_IN_COMBINER + intspec[1];
        *out_type = 0;
  
        return 0;
@@@ -181,6 -169,8 +170,8 @@@ static int combiner_irq_domain_xlate(st
  static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
                                   irq_hw_number_t hw)
  {
+       struct combiner_chip_data *combiner_data = d->host_data;
        irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
        irq_set_chip_data(irq, &combiner_data[hw >> 3]);
        set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
@@@ -193,8 -183,12 +184,12 @@@ static struct irq_domain_ops combiner_i
        .map    = combiner_irq_domain_map,
  };
  
- static unsigned int exynos4x12_combiner_extra_irq(int group)
+ static unsigned int combiner_lookup_irq(int group)
  {
+ #ifdef CONFIG_EXYNOS_ATAGS
+       if (group < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
+               return IRQ_SPI(group);
        switch (group) {
        case 16:
                return IRQ_SPI(107);
                return IRQ_SPI(48);
        case 19:
                return IRQ_SPI(42);
-       default:
-               return 0;
        }
+ #endif
+       return 0;
  }
  
  void __init combiner_init(void __iomem *combiner_base,
-                         struct device_node *np)
+                         struct device_node *np,
+                         unsigned int max_nr,
+                         int irq_base)
  {
-       int i, irq, irq_base;
-       unsigned int max_nr, nr_irq;
+       int i, irq;
+       unsigned int nr_irq;
+       struct combiner_chip_data *combiner_data;
  
-       max_nr = max_combiner_nr();
+       nr_irq = max_nr * IRQ_IN_COMBINER;
  
-       if (np) {
-               if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
-                       pr_info("%s: number of combiners not specified, "
-                               "setting default as %d.\n",
-                               __func__, max_nr);
-               }
-       }
-       nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
-       irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
-       if (IS_ERR_VALUE(irq_base)) {
-               irq_base = COMBINER_IRQ(0, 0);
-               pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base);
+       combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL);
+       if (!combiner_data) {
+               pr_warning("%s: could not allocate combiner data\n", __func__);
+               return;
        }
  
-       combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
-                               &combiner_irq_domain_ops, &combiner_data);
+       combiner_irq_domain = irq_domain_add_simple(np, nr_irq, irq_base,
+                               &combiner_irq_domain_ops, combiner_data);
        if (WARN_ON(!combiner_irq_domain)) {
                pr_warning("%s: irq domain init failed\n", __func__);
                return;
        }
  
        for (i = 0; i < max_nr; i++) {
-               if (i < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
-                       irq = IRQ_SPI(i);
-               else
-                       irq = exynos4x12_combiner_extra_irq(i);
  #ifdef CONFIG_OF
                if (np)
                        irq = irq_of_parse_and_map(np, i);
+               else
  #endif
-               combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq);
-               combiner_cascade_irq(i, irq);
+                       irq = combiner_lookup_irq(i);
+               combiner_init_one(&combiner_data[i], i,
+                                 combiner_base + (i >> 2) * 0x10, irq);
+               combiner_cascade_irq(&combiner_data[i], irq);
        }
  }
  
@@@ -259,6 -246,8 +247,8 @@@ static int __init combiner_of_init(stru
                                   struct device_node *parent)
  {
        void __iomem *combiner_base;
+       unsigned int max_nr = 20;
+       int irq_base = -1;
  
        combiner_base = of_iomap(np, 0);
        if (!combiner_base) {
                return -ENXIO;
        }
  
-       combiner_init(combiner_base, np);
+       if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
+               pr_info("%s: number of combiners not specified, "
+                       "setting default as %d.\n",
+                       __func__, max_nr);
+       }
+       /* 
+        * FIXME: This is a hardwired COMBINER_IRQ(0,0). Once all devices
+        * get their IRQ from DT, remove this in order to get dynamic
+        * allocation.
+        */
+       irq_base = 160;
+       combiner_init(combiner_base, np, max_nr, irq_base);
  
        return 0;
  }