Merge branch 'ux500/dt' into next/dt2
authorArnd Bergmann <arnd@arndb.de>
Fri, 16 Mar 2012 19:51:30 +0000 (19:51 +0000)
committerArnd Bergmann <arnd@arndb.de>
Fri, 16 Mar 2012 19:51:30 +0000 (19:51 +0000)
* ux500/dt:
  ARM: ux500: Provide local timer support for Device Tree
  ARM: ux500: Enable PL022 SSP Controller in Device Tree
  ARM: ux500: Enable PL310 Level 2 Cache Controller in Device Tree
  ARM: ux500: Enable PL011 AMBA UART Controller for Device Tree
  ARM: ux500: Enable Cortex-A9 GIC (Generic Interrupt Controller) in Device Tree
  ARM: ux500: db8500: list most devices in the snowball device tree
  ARM: ux500: split dts file for snowball into generic part
  ARM: ux500: combine the board init functions for DT boot
  ARM: ux500: Initial Device Tree support for Snowball
  ARM: ux500: CONFIG: Enable Device Tree support for future endeavours
  ARM: ux500: fix compilation after local timer rework

(adds dependency on localtimer branch, irqdomain branch and ux500/soc
branch)

Conflicts:
arch/arm/mach-ux500/devices-common.c

This adds patches from Lee Jones, Niklas Hernaeus and myself to provide
initial device tree support on the ux500 platform. The pull request from
Lee contained some other changes, so I rebased the patches on top of
the branches that are actually dependencies for this.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

12 files changed:
1  2 
arch/arm/kernel/smp_twd.c
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-ux500/devices-common.c
arch/arm/mach-vexpress/ct-ca9x4.c
arch/x86/Kconfig
scripts/mod/file2alias.c

  #include <linux/smp.h>
  #include <linux/jiffies.h>
  #include <linux/clockchips.h>
- #include <linux/irq.h>
+ #include <linux/interrupt.h>
  #include <linux/io.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_address.h>
  
  #include <asm/smp_twd.h>
  #include <asm/localtimer.h>
  #include <asm/hardware/gic.h>
  
  /* set up by the platform code */
- void __iomem *twd_base;
+ static void __iomem *twd_base;
  
  static struct clk *twd_clk;
  static unsigned long twd_timer_rate;
  
  static struct clock_event_device __percpu **twd_evt;
+ static int twd_ppi;
  
  static void twd_set_mode(enum clock_event_mode mode,
                        struct clock_event_device *clk)
@@@ -77,7 -80,7 +80,7 @@@ static int twd_set_next_event(unsigned 
   * If a local timer interrupt has occurred, acknowledge and return 1.
   * Otherwise, return 0.
   */
- int twd_timer_ack(void)
+ static int twd_timer_ack(void)
  {
        if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
                __raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
@@@ -87,7 -90,7 +90,7 @@@
        return 0;
  }
  
- void twd_timer_stop(struct clock_event_device *clk)
+ static void twd_timer_stop(struct clock_event_device *clk)
  {
        twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
        disable_percpu_irq(clk->irq);
@@@ -129,7 -132,7 +132,7 @@@ static struct notifier_block twd_cpufre
  
  static int twd_cpufreq_init(void)
  {
 -      if (!IS_ERR(twd_clk))
 +      if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
                return cpufreq_register_notifier(&twd_cpufreq_nb,
                        CPUFREQ_TRANSITION_NOTIFIER);
  
@@@ -222,28 -225,10 +225,10 @@@ static struct clk *twd_get_clock(void
  /*
   * Setup the local clock events for a CPU.
   */
- void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
  {
        struct clock_event_device **this_cpu_clk;
  
-       if (!twd_evt) {
-               int err;
-               twd_evt = alloc_percpu(struct clock_event_device *);
-               if (!twd_evt) {
-                       pr_err("twd: can't allocate memory\n");
-                       return;
-               }
-               err = request_percpu_irq(clk->irq, twd_handler,
-                                        "twd", twd_evt);
-               if (err) {
-                       pr_err("twd: can't register interrupt %d (%d)\n",
-                              clk->irq, err);
-                       return;
-               }
-       }
        if (!twd_clk)
                twd_clk = twd_get_clock();
  
        clk->rating = 350;
        clk->set_mode = twd_set_mode;
        clk->set_next_event = twd_set_next_event;
+       clk->irq = twd_ppi;
  
        this_cpu_clk = __this_cpu_ptr(twd_evt);
        *this_cpu_clk = clk;
        clockevents_config_and_register(clk, twd_timer_rate,
                                        0xf, 0xffffffff);
        enable_percpu_irq(clk->irq, 0);
+       return 0;
+ }
+ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
+       .setup  = twd_timer_setup,
+       .stop   = twd_timer_stop,
+ };
+ static int __init twd_local_timer_common_register(void)
+ {
+       int err;
+       twd_evt = alloc_percpu(struct clock_event_device *);
+       if (!twd_evt) {
+               err = -ENOMEM;
+               goto out_free;
+       }
+       err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
+       if (err) {
+               pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
+               goto out_free;
+       }
+       err = local_timer_register(&twd_lt_ops);
+       if (err)
+               goto out_irq;
+       return 0;
+ out_irq:
+       free_percpu_irq(twd_ppi, twd_evt);
+ out_free:
+       iounmap(twd_base);
+       twd_base = NULL;
+       free_percpu(twd_evt);
+       return err;
  }
+ int __init twd_local_timer_register(struct twd_local_timer *tlt)
+ {
+       if (twd_base || twd_evt)
+               return -EBUSY;
+       twd_ppi = tlt->res[1].start;
+       twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
+       if (!twd_base)
+               return -ENOMEM;
+       return twd_local_timer_common_register();
+ }
+ #ifdef CONFIG_OF
+ const static struct of_device_id twd_of_match[] __initconst = {
+       { .compatible = "arm,cortex-a9-twd-timer",      },
+       { .compatible = "arm,cortex-a5-twd-timer",      },
+       { .compatible = "arm,arm11mp-twd-timer",        },
+       { },
+ };
+ void __init twd_local_timer_of_register(void)
+ {
+       struct device_node *np;
+       int err;
+       np = of_find_matching_node(NULL, twd_of_match);
+       if (!np) {
+               err = -ENODEV;
+               goto out;
+       }
+       twd_ppi = irq_of_parse_and_map(np, 0);
+       if (!twd_ppi) {
+               err = -EINVAL;
+               goto out;
+       }
+       twd_base = of_iomap(np, 0);
+       if (!twd_base) {
+               err = -ENOMEM;
+               goto out;
+       }
+       err = twd_local_timer_common_register();
+ out:
+       WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
+ }
+ #endif
@@@ -41,7 -41,6 +41,7 @@@ obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBO
  obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
  obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
  obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o
 +obj-$(CONFIG_MACH_IMX27_DT) += imx27-dt.o
  
  # i.MX31 based machines
  obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
@@@ -72,7 -71,6 +72,6 @@@ obj-$(CONFIG_CPU_V7) += head-v7.
  AFLAGS_head-v7.o :=-Wa,-march=armv7-a
  obj-$(CONFIG_SMP) += platsmp.o
  obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
- obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
  obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
  
  ifeq ($(CONFIG_PM),y)
@@@ -21,6 -21,7 +21,7 @@@
  #include <linux/of_platform.h>
  #include <linux/phy.h>
  #include <linux/micrel_phy.h>
+ #include <asm/smp_twd.h>
  #include <asm/hardware/cache-l2x0.h>
  #include <asm/hardware/gic.h>
  #include <asm/mach/arch.h>
@@@ -97,8 -98,7 +98,8 @@@ static int __init imx6q_gpio_add_irq_do
        static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
  
        gpio_irq_base -= 32;
 -      irq_domain_add_simple(np, gpio_irq_base);
 +      irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
 +                            NULL);
  
        return 0;
  }
@@@ -120,6 -120,7 +121,7 @@@ static void __init imx6q_init_irq(void
  static void __init imx6q_timer_init(void)
  {
        mx6q_clocks_init();
+       twd_local_timer_of_register();
  }
  
  static struct sys_timer imx6q_timer = {
  static const char *imx6q_dt_compat[] __initdata = {
        "fsl,imx6q-arm2",
        "fsl,imx6q-sabrelite",
 +      "fsl,imx6q",
        NULL,
  };
  
  #include <asm/mach/arch.h>
  #include <asm/mach/irq.h>
  #include <asm/mach/flash.h>
+ #include <asm/mach/time.h>
  
  #include <plat/gpio-nomadik.h>
  #include <plat/mtu.h>
  
- #include <mach/setup.h>
  #include <mach/nand.h>
  #include <mach/fsmc.h>
  
@@@ -185,11 -185,20 +185,11 @@@ static void __init nhk8815_onenand_init
  #endif
  }
  
 -#define __MEM_4K_RESOURCE(x) \
 -      .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
 +static AMBA_APB_DEVICE(uart0, "uart0", 0, NOMADIK_UART0_BASE,
 +      { IRQ_UART0 }, NULL);
  
 -static struct amba_device uart0_device = {
 -      .dev = { .init_name = "uart0" },
 -      __MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
 -      .irq = {IRQ_UART0, NO_IRQ},
 -};
 -
 -static struct amba_device uart1_device = {
 -      .dev = { .init_name = "uart1" },
 -      __MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
 -      .irq = {IRQ_UART1, NO_IRQ},
 -};
 +static AMBA_APB_DEVICE(uart1, "uart1", 0, NOMADIK_UART1_BASE,
 +      { IRQ_UART1 }, NULL);
  
  static struct amba_device *amba_devs[] __initdata = {
        &uart0_device,
@@@ -246,10 -255,7 +246,7 @@@ static void __init nomadik_timer_init(v
        src_cr |= SRC_CR_INIT_VAL;
        writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
  
-       /* Save global pointer to mtu, used by platform timer code */
-       mtu_base = io_p2v(NOMADIK_MTU0_BASE);
-       nmdk_timer_init();
+       nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE));
  }
  
  static struct sys_timer nomadik_timer = {
@@@ -36,7 -36,7 +36,7 @@@
  #include <asm/pgtable.h>
  #include <asm/hardware/gic.h>
  #include <asm/hardware/cache-l2x0.h>
- #include <asm/localtimer.h>
+ #include <asm/smp_twd.h>
  
  #include <asm/mach/arch.h>
  #include <asm/mach/map.h>
@@@ -135,63 -135,63 +135,63 @@@ static struct pl022_ssp_controller ssp0
  /*
   * These devices are connected via the core APB bridge
   */
 -#define GPIO2_IRQ     { IRQ_EB_GPIO2, NO_IRQ }
 -#define GPIO3_IRQ     { IRQ_EB_GPIO3, NO_IRQ }
 +#define GPIO2_IRQ     { IRQ_EB_GPIO2 }
 +#define GPIO3_IRQ     { IRQ_EB_GPIO3 }
  
 -#define AACI_IRQ      { IRQ_EB_AACI, NO_IRQ }
 +#define AACI_IRQ      { IRQ_EB_AACI }
  #define MMCI0_IRQ     { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
 -#define KMI0_IRQ      { IRQ_EB_KMI0, NO_IRQ }
 -#define KMI1_IRQ      { IRQ_EB_KMI1, NO_IRQ }
 +#define KMI0_IRQ      { IRQ_EB_KMI0 }
 +#define KMI1_IRQ      { IRQ_EB_KMI1 }
  
  /*
   * These devices are connected directly to the multi-layer AHB switch
   */
 -#define EB_SMC_IRQ    { NO_IRQ, NO_IRQ }
 -#define MPMC_IRQ      { NO_IRQ, NO_IRQ }
 -#define EB_CLCD_IRQ   { IRQ_EB_CLCD, NO_IRQ }
 -#define DMAC_IRQ      { IRQ_EB_DMA, NO_IRQ }
 +#define EB_SMC_IRQ    { }
 +#define MPMC_IRQ      { }
 +#define EB_CLCD_IRQ   { IRQ_EB_CLCD }
 +#define DMAC_IRQ      { IRQ_EB_DMA }
  
  /*
   * These devices are connected via the core APB bridge
   */
 -#define SCTL_IRQ      { NO_IRQ, NO_IRQ }
 -#define EB_WATCHDOG_IRQ       { IRQ_EB_WDOG, NO_IRQ }
 -#define EB_GPIO0_IRQ  { IRQ_EB_GPIO0, NO_IRQ }
 -#define GPIO1_IRQ     { IRQ_EB_GPIO1, NO_IRQ }
 -#define EB_RTC_IRQ    { IRQ_EB_RTC, NO_IRQ }
 +#define SCTL_IRQ      { }
 +#define EB_WATCHDOG_IRQ       { IRQ_EB_WDOG }
 +#define EB_GPIO0_IRQ  { IRQ_EB_GPIO0 }
 +#define GPIO1_IRQ     { IRQ_EB_GPIO1 }
 +#define EB_RTC_IRQ    { IRQ_EB_RTC }
  
  /*
   * These devices are connected via the DMA APB bridge
   */
 -#define SCI_IRQ               { IRQ_EB_SCI, NO_IRQ }
 -#define EB_UART0_IRQ  { IRQ_EB_UART0, NO_IRQ }
 -#define EB_UART1_IRQ  { IRQ_EB_UART1, NO_IRQ }
 -#define EB_UART2_IRQ  { IRQ_EB_UART2, NO_IRQ }
 -#define EB_UART3_IRQ  { IRQ_EB_UART3, NO_IRQ }
 -#define EB_SSP_IRQ    { IRQ_EB_SSP, NO_IRQ }
 +#define SCI_IRQ               { IRQ_EB_SCI }
 +#define EB_UART0_IRQ  { IRQ_EB_UART0 }
 +#define EB_UART1_IRQ  { IRQ_EB_UART1 }
 +#define EB_UART2_IRQ  { IRQ_EB_UART2 }
 +#define EB_UART3_IRQ  { IRQ_EB_UART3 }
 +#define EB_SSP_IRQ    { IRQ_EB_SSP }
  
  /* FPGA Primecells */
 -AMBA_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
 -AMBA_DEVICE(mmc0,  "fpga:mmc0",  MMCI0,    &realview_mmc0_plat_data);
 -AMBA_DEVICE(kmi0,  "fpga:kmi0",  KMI0,     NULL);
 -AMBA_DEVICE(kmi1,  "fpga:kmi1",  KMI1,     NULL);
 -AMBA_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
 +APB_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
 +APB_DEVICE(mmc0,  "fpga:mmc0",  MMCI0,    &realview_mmc0_plat_data);
 +APB_DEVICE(kmi0,  "fpga:kmi0",  KMI0,     NULL);
 +APB_DEVICE(kmi1,  "fpga:kmi1",  KMI1,     NULL);
 +APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
  
  /* DevChip Primecells */
 -AMBA_DEVICE(smc,   "dev:smc",   EB_SMC,   NULL);
 -AMBA_DEVICE(clcd,  "dev:clcd",  EB_CLCD,  &clcd_plat_data);
 -AMBA_DEVICE(dmac,  "dev:dmac",  DMAC,     NULL);
 -AMBA_DEVICE(sctl,  "dev:sctl",  SCTL,     NULL);
 -AMBA_DEVICE(wdog,  "dev:wdog",  EB_WATCHDOG, NULL);
 -AMBA_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
 -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1,    &gpio1_plat_data);
 -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2,    &gpio2_plat_data);
 -AMBA_DEVICE(rtc,   "dev:rtc",   EB_RTC,   NULL);
 -AMBA_DEVICE(sci0,  "dev:sci0",  SCI,      NULL);
 -AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
 -AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
 -AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
 -AMBA_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   &ssp0_plat_data);
 +AHB_DEVICE(smc,   "dev:smc",   EB_SMC,   NULL);
 +AHB_DEVICE(clcd,  "dev:clcd",  EB_CLCD,  &clcd_plat_data);
 +AHB_DEVICE(dmac,  "dev:dmac",  DMAC,     NULL);
 +AHB_DEVICE(sctl,  "dev:sctl",  SCTL,     NULL);
 +APB_DEVICE(wdog,  "dev:wdog",  EB_WATCHDOG, NULL);
 +APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
 +APB_DEVICE(gpio1, "dev:gpio1", GPIO1,    &gpio1_plat_data);
 +APB_DEVICE(gpio2, "dev:gpio2", GPIO2,    &gpio2_plat_data);
 +APB_DEVICE(rtc,   "dev:rtc",   EB_RTC,   NULL);
 +APB_DEVICE(sci0,  "dev:sci0",  SCI,      NULL);
 +APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
 +APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
 +APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
 +APB_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   &ssp0_plat_data);
  
  static struct amba_device *amba_devs[] __initdata = {
        &dmac_device,
@@@ -383,6 -383,23 +383,23 @@@ static void realview_eb11mp_fixup(void
        realview_eb_isp1761_resources[1].end    = IRQ_EB11MP_USB;
  }
  
+ #ifdef CONFIG_HAVE_ARM_TWD
+ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             REALVIEW_EB11MP_TWD_BASE,
+                             IRQ_LOCALTIMER);
+ static void __init realview_eb_twd_init(void)
+ {
+       if (core_tile_eb11mp() || core_tile_a9mp()) {
+               int err = twd_local_timer_register(&twd_local_timer);
+               if (err)
+                       pr_err("twd_local_timer_register failed %d\n", err);
+       }
+ }
+ #else
+ #define realview_eb_twd_init()        do { } while(0)
+ #endif
  static void __init realview_eb_timer_init(void)
  {
        unsigned int timer_irq;
        timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;
  
-       if (core_tile_eb11mp() || core_tile_a9mp()) {
- #ifdef CONFIG_LOCAL_TIMERS
-               twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
- #endif
+       if (core_tile_eb11mp() || core_tile_a9mp())
                timer_irq = IRQ_EB11MP_TIMER0_1;
-       } else
+       else
                timer_irq = IRQ_EB_TIMER0_1;
  
        realview_timer_init(timer_irq);
+       realview_eb_twd_init();
  }
  
  static struct sys_timer realview_eb_timer = {
@@@ -36,7 -36,7 +36,7 @@@
  #include <asm/pgtable.h>
  #include <asm/hardware/gic.h>
  #include <asm/hardware/cache-l2x0.h>
- #include <asm/localtimer.h>
+ #include <asm/smp_twd.h>
  
  #include <asm/mach/arch.h>
  #include <asm/mach/flash.h>
@@@ -127,52 -127,52 +127,52 @@@ static struct pl022_ssp_controller ssp0
   * RealView PB11MPCore AMBA devices
   */
  
 -#define GPIO2_IRQ             { IRQ_PB11MP_GPIO2, NO_IRQ }
 -#define GPIO3_IRQ             { IRQ_PB11MP_GPIO3, NO_IRQ }
 -#define AACI_IRQ              { IRQ_TC11MP_AACI, NO_IRQ }
 +#define GPIO2_IRQ             { IRQ_PB11MP_GPIO2 }
 +#define GPIO3_IRQ             { IRQ_PB11MP_GPIO3 }
 +#define AACI_IRQ              { IRQ_TC11MP_AACI }
  #define MMCI0_IRQ             { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
 -#define KMI0_IRQ              { IRQ_TC11MP_KMI0, NO_IRQ }
 -#define KMI1_IRQ              { IRQ_TC11MP_KMI1, NO_IRQ }
 -#define PB11MP_SMC_IRQ                { NO_IRQ, NO_IRQ }
 -#define MPMC_IRQ              { NO_IRQ, NO_IRQ }
 -#define PB11MP_CLCD_IRQ               { IRQ_PB11MP_CLCD, NO_IRQ }
 -#define DMAC_IRQ              { IRQ_PB11MP_DMAC, NO_IRQ }
 -#define SCTL_IRQ              { NO_IRQ, NO_IRQ }
 -#define PB11MP_WATCHDOG_IRQ   { IRQ_PB11MP_WATCHDOG, NO_IRQ }
 -#define PB11MP_GPIO0_IRQ      { IRQ_PB11MP_GPIO0, NO_IRQ }
 -#define GPIO1_IRQ             { IRQ_PB11MP_GPIO1, NO_IRQ }
 -#define PB11MP_RTC_IRQ                { IRQ_TC11MP_RTC, NO_IRQ }
 -#define SCI_IRQ                       { IRQ_PB11MP_SCI, NO_IRQ }
 -#define PB11MP_UART0_IRQ      { IRQ_TC11MP_UART0, NO_IRQ }
 -#define PB11MP_UART1_IRQ      { IRQ_TC11MP_UART1, NO_IRQ }
 -#define PB11MP_UART2_IRQ      { IRQ_PB11MP_UART2, NO_IRQ }
 -#define PB11MP_UART3_IRQ      { IRQ_PB11MP_UART3, NO_IRQ }
 -#define PB11MP_SSP_IRQ                { IRQ_PB11MP_SSP, NO_IRQ }
 +#define KMI0_IRQ              { IRQ_TC11MP_KMI0 }
 +#define KMI1_IRQ              { IRQ_TC11MP_KMI1 }
 +#define PB11MP_SMC_IRQ                { }
 +#define MPMC_IRQ              { }
 +#define PB11MP_CLCD_IRQ               { IRQ_PB11MP_CLCD }
 +#define DMAC_IRQ              { IRQ_PB11MP_DMAC }
 +#define SCTL_IRQ              { }
 +#define PB11MP_WATCHDOG_IRQ   { IRQ_PB11MP_WATCHDOG }
 +#define PB11MP_GPIO0_IRQ      { IRQ_PB11MP_GPIO0 }
 +#define GPIO1_IRQ             { IRQ_PB11MP_GPIO1 }
 +#define PB11MP_RTC_IRQ                { IRQ_TC11MP_RTC }
 +#define SCI_IRQ                       { IRQ_PB11MP_SCI }
 +#define PB11MP_UART0_IRQ      { IRQ_TC11MP_UART0 }
 +#define PB11MP_UART1_IRQ      { IRQ_TC11MP_UART1 }
 +#define PB11MP_UART2_IRQ      { IRQ_PB11MP_UART2 }
 +#define PB11MP_UART3_IRQ      { IRQ_PB11MP_UART3 }
 +#define PB11MP_SSP_IRQ                { IRQ_PB11MP_SSP }
  
  /* FPGA Primecells */
 -AMBA_DEVICE(aaci,     "fpga:aaci",    AACI,           NULL);
 -AMBA_DEVICE(mmc0,     "fpga:mmc0",    MMCI0,          &realview_mmc0_plat_data);
 -AMBA_DEVICE(kmi0,     "fpga:kmi0",    KMI0,           NULL);
 -AMBA_DEVICE(kmi1,     "fpga:kmi1",    KMI1,           NULL);
 -AMBA_DEVICE(uart3,    "fpga:uart3",   PB11MP_UART3,   NULL);
 +APB_DEVICE(aaci,      "fpga:aaci",    AACI,           NULL);
 +APB_DEVICE(mmc0,      "fpga:mmc0",    MMCI0,          &realview_mmc0_plat_data);
 +APB_DEVICE(kmi0,      "fpga:kmi0",    KMI0,           NULL);
 +APB_DEVICE(kmi1,      "fpga:kmi1",    KMI1,           NULL);
 +APB_DEVICE(uart3,     "fpga:uart3",   PB11MP_UART3,   NULL);
  
  /* DevChip Primecells */
 -AMBA_DEVICE(smc,      "dev:smc",      PB11MP_SMC,     NULL);
 -AMBA_DEVICE(sctl,     "dev:sctl",     SCTL,           NULL);
 -AMBA_DEVICE(wdog,     "dev:wdog",     PB11MP_WATCHDOG, NULL);
 -AMBA_DEVICE(gpio0,    "dev:gpio0",    PB11MP_GPIO0,   &gpio0_plat_data);
 -AMBA_DEVICE(gpio1,    "dev:gpio1",    GPIO1,          &gpio1_plat_data);
 -AMBA_DEVICE(gpio2,    "dev:gpio2",    GPIO2,          &gpio2_plat_data);
 -AMBA_DEVICE(rtc,      "dev:rtc",      PB11MP_RTC,     NULL);
 -AMBA_DEVICE(sci0,     "dev:sci0",     SCI,            NULL);
 -AMBA_DEVICE(uart0,    "dev:uart0",    PB11MP_UART0,   NULL);
 -AMBA_DEVICE(uart1,    "dev:uart1",    PB11MP_UART1,   NULL);
 -AMBA_DEVICE(uart2,    "dev:uart2",    PB11MP_UART2,   NULL);
 -AMBA_DEVICE(ssp0,     "dev:ssp0",     PB11MP_SSP,     &ssp0_plat_data);
 +AHB_DEVICE(smc,               "dev:smc",      PB11MP_SMC,     NULL);
 +AHB_DEVICE(sctl,      "dev:sctl",     SCTL,           NULL);
 +APB_DEVICE(wdog,      "dev:wdog",     PB11MP_WATCHDOG, NULL);
 +APB_DEVICE(gpio0,     "dev:gpio0",    PB11MP_GPIO0,   &gpio0_plat_data);
 +APB_DEVICE(gpio1,     "dev:gpio1",    GPIO1,          &gpio1_plat_data);
 +APB_DEVICE(gpio2,     "dev:gpio2",    GPIO2,          &gpio2_plat_data);
 +APB_DEVICE(rtc,               "dev:rtc",      PB11MP_RTC,     NULL);
 +APB_DEVICE(sci0,      "dev:sci0",     SCI,            NULL);
 +APB_DEVICE(uart0,     "dev:uart0",    PB11MP_UART0,   NULL);
 +APB_DEVICE(uart1,     "dev:uart1",    PB11MP_UART1,   NULL);
 +APB_DEVICE(uart2,     "dev:uart2",    PB11MP_UART2,   NULL);
 +APB_DEVICE(ssp0,      "dev:ssp0",     PB11MP_SSP,     &ssp0_plat_data);
  
  /* Primecells on the NEC ISSP chip */
 -AMBA_DEVICE(clcd,     "issp:clcd",    PB11MP_CLCD,    &clcd_plat_data);
 -AMBA_DEVICE(dmac,     "issp:dmac",    DMAC,           NULL);
 +AHB_DEVICE(clcd,      "issp:clcd",    PB11MP_CLCD,    &clcd_plat_data);
 +AHB_DEVICE(dmac,      "issp:dmac",    DMAC,           NULL);
  
  static struct amba_device *amba_devs[] __initdata = {
        &dmac_device,
@@@ -290,6 -290,21 +290,21 @@@ static void __init gic_init_irq(void
        gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
  }
  
+ #ifdef CONFIG_HAVE_ARM_TWD
+ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             REALVIEW_TC11MP_TWD_BASE,
+                             IRQ_LOCALTIMER);
+ static void __init realview_pb11mp_twd_init(void)
+ {
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+ }
+ #else
+ #define realview_pb11mp_twd_init()    do {} while(0)
+ #endif
  static void __init realview_pb11mp_timer_init(void)
  {
        timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE);
        timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
  
- #ifdef CONFIG_LOCAL_TIMERS
-       twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
- #endif
        realview_timer_init(IRQ_TC11MP_TIMER0_1);
+       realview_pb11mp_twd_init();
  }
  
  static struct sys_timer realview_pb11mp_timer = {
@@@ -144,52 -144,52 +144,52 @@@ static struct pl022_ssp_controller ssp0
   * RealView PBXCore AMBA devices
   */
  
 -#define GPIO2_IRQ             { IRQ_PBX_GPIO2, NO_IRQ }
 -#define GPIO3_IRQ             { IRQ_PBX_GPIO3, NO_IRQ }
 -#define AACI_IRQ              { IRQ_PBX_AACI, NO_IRQ }
 +#define GPIO2_IRQ             { IRQ_PBX_GPIO2 }
 +#define GPIO3_IRQ             { IRQ_PBX_GPIO3 }
 +#define AACI_IRQ              { IRQ_PBX_AACI }
  #define MMCI0_IRQ             { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
 -#define KMI0_IRQ              { IRQ_PBX_KMI0, NO_IRQ }
 -#define KMI1_IRQ              { IRQ_PBX_KMI1, NO_IRQ }
 -#define PBX_SMC_IRQ           { NO_IRQ, NO_IRQ }
 -#define MPMC_IRQ              { NO_IRQ, NO_IRQ }
 -#define PBX_CLCD_IRQ          { IRQ_PBX_CLCD, NO_IRQ }
 -#define DMAC_IRQ              { IRQ_PBX_DMAC, NO_IRQ }
 -#define SCTL_IRQ              { NO_IRQ, NO_IRQ }
 -#define PBX_WATCHDOG_IRQ      { IRQ_PBX_WATCHDOG, NO_IRQ }
 -#define PBX_GPIO0_IRQ         { IRQ_PBX_GPIO0, NO_IRQ }
 -#define GPIO1_IRQ             { IRQ_PBX_GPIO1, NO_IRQ }
 -#define PBX_RTC_IRQ           { IRQ_PBX_RTC, NO_IRQ }
 -#define SCI_IRQ                       { IRQ_PBX_SCI, NO_IRQ }
 -#define PBX_UART0_IRQ         { IRQ_PBX_UART0, NO_IRQ }
 -#define PBX_UART1_IRQ         { IRQ_PBX_UART1, NO_IRQ }
 -#define PBX_UART2_IRQ         { IRQ_PBX_UART2, NO_IRQ }
 -#define PBX_UART3_IRQ         { IRQ_PBX_UART3, NO_IRQ }
 -#define PBX_SSP_IRQ           { IRQ_PBX_SSP, NO_IRQ }
 +#define KMI0_IRQ              { IRQ_PBX_KMI0 }
 +#define KMI1_IRQ              { IRQ_PBX_KMI1 }
 +#define PBX_SMC_IRQ           { }
 +#define MPMC_IRQ              { }
 +#define PBX_CLCD_IRQ          { IRQ_PBX_CLCD }
 +#define DMAC_IRQ              { IRQ_PBX_DMAC }
 +#define SCTL_IRQ              { }
 +#define PBX_WATCHDOG_IRQ      { IRQ_PBX_WATCHDOG }
 +#define PBX_GPIO0_IRQ         { IRQ_PBX_GPIO0 }
 +#define GPIO1_IRQ             { IRQ_PBX_GPIO1 }
 +#define PBX_RTC_IRQ           { IRQ_PBX_RTC }
 +#define SCI_IRQ                       { IRQ_PBX_SCI }
 +#define PBX_UART0_IRQ         { IRQ_PBX_UART0 }
 +#define PBX_UART1_IRQ         { IRQ_PBX_UART1 }
 +#define PBX_UART2_IRQ         { IRQ_PBX_UART2 }
 +#define PBX_UART3_IRQ         { IRQ_PBX_UART3 }
 +#define PBX_SSP_IRQ           { IRQ_PBX_SSP }
  
  /* FPGA Primecells */
 -AMBA_DEVICE(aaci,     "fpga:aaci",    AACI,           NULL);
 -AMBA_DEVICE(mmc0,     "fpga:mmc0",    MMCI0,          &realview_mmc0_plat_data);
 -AMBA_DEVICE(kmi0,     "fpga:kmi0",    KMI0,           NULL);
 -AMBA_DEVICE(kmi1,     "fpga:kmi1",    KMI1,           NULL);
 -AMBA_DEVICE(uart3,    "fpga:uart3",   PBX_UART3,      NULL);
 +APB_DEVICE(aaci,      "fpga:aaci",    AACI,           NULL);
 +APB_DEVICE(mmc0,      "fpga:mmc0",    MMCI0,          &realview_mmc0_plat_data);
 +APB_DEVICE(kmi0,      "fpga:kmi0",    KMI0,           NULL);
 +APB_DEVICE(kmi1,      "fpga:kmi1",    KMI1,           NULL);
 +APB_DEVICE(uart3,     "fpga:uart3",   PBX_UART3,      NULL);
  
  /* DevChip Primecells */
 -AMBA_DEVICE(smc,      "dev:smc",      PBX_SMC,        NULL);
 -AMBA_DEVICE(sctl,     "dev:sctl",     SCTL,           NULL);
 -AMBA_DEVICE(wdog,     "dev:wdog",     PBX_WATCHDOG,   NULL);
 -AMBA_DEVICE(gpio0,    "dev:gpio0",    PBX_GPIO0,      &gpio0_plat_data);
 -AMBA_DEVICE(gpio1,    "dev:gpio1",    GPIO1,          &gpio1_plat_data);
 -AMBA_DEVICE(gpio2,    "dev:gpio2",    GPIO2,          &gpio2_plat_data);
 -AMBA_DEVICE(rtc,      "dev:rtc",      PBX_RTC,        NULL);
 -AMBA_DEVICE(sci0,     "dev:sci0",     SCI,            NULL);
 -AMBA_DEVICE(uart0,    "dev:uart0",    PBX_UART0,      NULL);
 -AMBA_DEVICE(uart1,    "dev:uart1",    PBX_UART1,      NULL);
 -AMBA_DEVICE(uart2,    "dev:uart2",    PBX_UART2,      NULL);
 -AMBA_DEVICE(ssp0,     "dev:ssp0",     PBX_SSP,        &ssp0_plat_data);
 +AHB_DEVICE(smc,       "dev:smc",      PBX_SMC,        NULL);
 +AHB_DEVICE(sctl,      "dev:sctl",     SCTL,           NULL);
 +APB_DEVICE(wdog,      "dev:wdog",     PBX_WATCHDOG,   NULL);
 +APB_DEVICE(gpio0,     "dev:gpio0",    PBX_GPIO0,      &gpio0_plat_data);
 +APB_DEVICE(gpio1,     "dev:gpio1",    GPIO1,          &gpio1_plat_data);
 +APB_DEVICE(gpio2,     "dev:gpio2",    GPIO2,          &gpio2_plat_data);
 +APB_DEVICE(rtc,               "dev:rtc",      PBX_RTC,        NULL);
 +APB_DEVICE(sci0,      "dev:sci0",     SCI,            NULL);
 +APB_DEVICE(uart0,     "dev:uart0",    PBX_UART0,      NULL);
 +APB_DEVICE(uart1,     "dev:uart1",    PBX_UART1,      NULL);
 +APB_DEVICE(uart2,     "dev:uart2",    PBX_UART2,      NULL);
 +APB_DEVICE(ssp0,      "dev:ssp0",     PBX_SSP,        &ssp0_plat_data);
  
  /* Primecells on the NEC ISSP chip */
 -AMBA_DEVICE(clcd,     "issp:clcd",    PBX_CLCD,       &clcd_plat_data);
 -AMBA_DEVICE(dmac,     "issp:dmac",    DMAC,           NULL);
 +AHB_DEVICE(clcd,      "issp:clcd",    PBX_CLCD,       &clcd_plat_data);
 +AHB_DEVICE(dmac,      "issp:dmac",    DMAC,           NULL);
  
  static struct amba_device *amba_devs[] __initdata = {
        &dmac_device,
@@@ -298,6 -298,21 +298,21 @@@ static void __init gic_init_irq(void
        }
  }
  
+ #ifdef CONFIG_HAVE_ARM_TWD
+ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             REALVIEW_PBX_TILE_TWD_BASE,
+                             IRQ_LOCALTIMER);
+ static void __init realview_pbx_twd_init(void)
+ {
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+ }
+ #else
+ #define realview_pbx_twd_init()       do { } while(0)
+ #endif
  static void __init realview_pbx_timer_init(void)
  {
        timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
        timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
  
- #ifdef CONFIG_LOCAL_TIMERS
-       if (core_tile_pbx11mp() || core_tile_pbxa9mp())
-               twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
- #endif
        realview_timer_init(IRQ_PBX_TIMER0_1);
+       realview_pbx_twd_init();
  }
  
  static struct sys_timer realview_pbx_timer = {
@@@ -42,6 -42,8 +42,8 @@@ static void __iomem *scu_base_addr(void
  static DEFINE_SPINLOCK(scu_lock);
  static unsigned long tmp;
  
+ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
  static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
  {
        void __iomem *scu_base = scu_base_addr();
@@@ -60,11 -62,7 +62,7 @@@ unsigned int __init sh73a0_get_core_cou
  {
        void __iomem *scu_base = scu_base_addr();
  
- #ifdef CONFIG_HAVE_ARM_TWD
-       /* twd_base needs to be initialized before percpu_timer_setup() */
-       twd_base = (void __iomem *)0xf0000600;
- #endif
+       shmobile_twd_init(&twd_local_timer);
        return scu_get_core_count(scu_base);
  }
  
@@@ -80,7 -78,7 +78,7 @@@ int __cpuinit sh73a0_boot_secondary(uns
        /* enable cache coherency */
        modify_scu_cpu_psr(0, 3 << (cpu * 8));
  
 -      if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
 +      if (((__raw_readl(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
                __raw_writel(1 << cpu, __io(WUPCR));    /* wake up */
        else
                __raw_writel(1 << cpu, __io(SRESCR));   /* reset */
  #include "devices-common.h"
  
  struct amba_device *
- dbx500_add_amba_device(const char *name, resource_size_t base,
-                      int irq, void *pdata, unsigned int periphid)
+ dbx500_add_amba_device(struct device *parent, const char *name,
+                      resource_size_t base, int irq, void *pdata,
+                      unsigned int periphid)
  {
        struct amba_device *dev;
        int ret;
  
 -      dev = kzalloc(sizeof *dev, GFP_KERNEL);
 +      dev = amba_device_alloc(name, base, SZ_4K);
        if (!dev)
                return ERR_PTR(-ENOMEM);
  
 -      dev->dev.init_name = name;
 -
 -      dev->res.start = base;
 -      dev->res.end = base + SZ_4K - 1;
 -      dev->res.flags = IORESOURCE_MEM;
 -
        dev->dma_mask = DMA_BIT_MASK(32);
        dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
  
        dev->irq[0] = irq;
 -      dev->irq[1] = NO_IRQ;
  
        dev->periphid = periphid;
  
        dev->dev.platform_data = pdata;
  
+       dev->dev.parent = parent;
 -      ret = amba_device_register(dev, &iomem_resource);
 +      ret = amba_device_add(dev, &iomem_resource);
        if (ret) {
 -              kfree(dev);
 +              amba_device_put(dev);
                return ERR_PTR(ret);
        }
  
  }
  
  static struct platform_device *
- dbx500_add_platform_device(const char *name, int id, void *pdata,
-                          struct resource *res, int resnum)
- {
-       struct platform_device *dev;
-       int ret;
-       dev = platform_device_alloc(name, id);
-       if (!dev)
-               return ERR_PTR(-ENOMEM);
-       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-       dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
-       ret = platform_device_add_resources(dev, res, resnum);
-       if (ret)
-               goto out_free;
-       dev->dev.platform_data = pdata;
-       ret = platform_device_add(dev);
-       if (ret)
-               goto out_free;
-       return dev;
- out_free:
-       platform_device_put(dev);
-       return ERR_PTR(ret);
- }
- struct platform_device *
- dbx500_add_platform_device_4k1irq(const char *name, int id,
-                                 resource_size_t base,
-                                 int irq, void *pdata)
- {
-       struct resource resources[] = {
-               [0] = {
-                       .start  = base,
-                       .end    = base + SZ_4K - 1,
-                       .flags  = IORESOURCE_MEM,
-               },
-               [1] = {
-                       .start  = irq,
-                       .end    = irq,
-                       .flags  = IORESOURCE_IRQ,
-               }
-       };
-       return dbx500_add_platform_device(name, id, pdata, resources,
-                                         ARRAY_SIZE(resources));
- }
- static struct platform_device *
- dbx500_add_gpio(int id, resource_size_t addr, int irq,
+ dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq,
                struct nmk_gpio_platform_data *pdata)
  {
        struct resource resources[] = {
                }
        };
  
-       return platform_device_register_resndata(NULL, "gpio", id,
-                               resources, ARRAY_SIZE(resources),
-                               pdata, sizeof(*pdata));
+       return platform_device_register_resndata(
+               parent,
+               "gpio",
+               id,
+               resources,
+               ARRAY_SIZE(resources),
+               pdata,
+               sizeof(*pdata));
  }
  
- void dbx500_add_gpios(resource_size_t *base, int num, int irq,
-                     struct nmk_gpio_platform_data *pdata)
+ void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
+                     int irq, struct nmk_gpio_platform_data *pdata)
  {
        int first = 0;
        int i;
                pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
                pdata->num_gpio = 32;
  
-               dbx500_add_gpio(i, base[i], irq, pdata);
+               dbx500_add_gpio(parent, i, base[i], irq, pdata);
        }
  }
@@@ -42,15 -42,26 +42,26 @@@ static struct map_desc ct_ca9x4_io_desc
  static void __init ct_ca9x4_map_io(void)
  {
        iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
- #ifdef CONFIG_LOCAL_TIMERS
-       twd_base = ioremap(A9_MPCORE_TWD, SZ_32);
- #endif
  }
  
+ #ifdef CONFIG_HAVE_ARM_TWD
+ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
+ static void __init ca9x4_twd_init(void)
+ {
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+ }
+ #else
+ #define ca9x4_twd_init()      do {} while(0)
+ #endif
  static void __init ct_ca9x4_init_irq(void)
  {
        gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
                 ioremap(A9_MPCORE_GIC_CPU, SZ_256));
+       ca9x4_twd_init();
  }
  
  static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
@@@ -81,10 -92,10 +92,10 @@@ static struct clcd_board ct_ca9x4_clcd_
        .remove         = versatile_clcd_remove_dma,
  };
  
 -static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
 -static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
 -static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
 -static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
 +static AMBA_AHB_DEVICE(clcd, "ct:clcd", 0, CT_CA9X4_CLCDC, IRQ_CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
 +static AMBA_APB_DEVICE(dmc, "ct:dmc", 0, CT_CA9X4_DMC, IRQ_CT_CA9X4_DMC, NULL);
 +static AMBA_APB_DEVICE(smc, "ct:smc", 0, CT_CA9X4_SMC, IRQ_CT_CA9X4_SMC, NULL);
 +static AMBA_APB_DEVICE(gpio, "ct:gpio", 0, CT_CA9X4_GPIO, IRQ_CT_CA9X4_GPIO, NULL);
  
  static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
        &clcd_device,
diff --combined arch/x86/Kconfig
@@@ -179,6 -179,9 +179,9 @@@ config ARCH_HAS_DEFAULT_IDL
  config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
  
+ config ARCH_HAS_CPU_AUTOPROBE
+       def_bool y
  config HAVE_SETUP_PER_CPU_AREA
        def_bool y
  
@@@ -398,7 -401,6 +401,7 @@@ config X86_INTEL_C
        select X86_REBOOTFIXUPS
        select OF
        select OF_EARLY_FLATTREE
 +      select IRQ_DOMAIN
        ---help---
          Select for the Intel CE media processor (CE4100) SOC.
          This option compiles in support for the CE4100 SOC for settop
@@@ -2077,7 -2079,6 +2080,7 @@@ config OLP
        select GPIOLIB
        select OF
        select OF_PROMTREE
 +      select IRQ_DOMAIN
        ---help---
          Add support for detecting the unique features of the OLPC
          XO hardware.
diff --combined scripts/mod/file2alias.c
@@@ -46,37 -46,11 +46,37 @@@ struct devtable 
        void *function;
  };
  
 +#define ___cat(a,b) a ## b
 +#define __cat(a,b) ___cat(a,b)
 +
 +/* we need some special handling for this host tool running eventually on
 + * Darwin. The Mach-O section handling is a bit different than ELF section
 + * handling. The differnces in detail are:
 + *  a) we have segments which have sections
 + *  b) we need a API call to get the respective section symbols */
 +#if defined(__MACH__)
 +#include <mach-o/getsect.h>
 +
 +#define INIT_SECTION(name)  do {                                      \
 +              unsigned long name ## _len;                             \
 +              char *__cat(pstart_,name) = getsectdata("__TEXT",       \
 +                      #name, &__cat(name,_len));                      \
 +              char *__cat(pstop_,name) = __cat(pstart_,name) +        \
 +                      __cat(name, _len);                              \
 +              __cat(__start_,name) = (void *)__cat(pstart_,name);     \
 +              __cat(__stop_,name) = (void *)__cat(pstop_,name);       \
 +      } while (0)
 +#define SECTION(name)   __attribute__((section("__TEXT, " #name)))
 +
 +struct devtable **__start___devtable, **__stop___devtable;
 +#else
 +#define INIT_SECTION(name) /* no-op for ELF */
 +#define SECTION(name)   __attribute__((section(#name)))
 +
  /* We construct a table of pointers in an ELF section (pointers generally
   * go unpadded by gcc).  ld creates boundary syms for us. */
  extern struct devtable *__start___devtable[], *__stop___devtable[];
 -#define ___cat(a,b) a ## b
 -#define __cat(a,b) ___cat(a,b)
 +#endif /* __MACH__ */
  
  #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
  # define __used                       __attribute__((__unused__))
@@@ -91,8 -65,8 +91,8 @@@
                                                (type *)NULL,           \
                                                (char *)NULL)),         \
                sizeof(type), (function) };                             \
 -      static struct devtable *__attribute__((section("__devtable"))) \
 -              __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
 +      static struct devtable *SECTION(__devtable) __used \
 +              __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
  
  #define ADD(str, sep, cond, field)                              \
  do {                                                            \
@@@ -1029,6 -1003,30 +1029,30 @@@ static int do_amba_entry(const char *fi
  }
  ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry);
  
+ /* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
+  * All fields are numbers. It would be nicer to use strings for vendor
+  * and feature, but getting those out of the build system here is too
+  * complicated.
+  */
+ static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id,
+                          char *alias)
+ {
+       id->feature = TO_NATIVE(id->feature);
+       id->family = TO_NATIVE(id->family);
+       id->model = TO_NATIVE(id->model);
+       id->vendor = TO_NATIVE(id->vendor);
+       strcpy(alias, "x86cpu:");
+       ADD(alias, "vendor:",  id->vendor != X86_VENDOR_ANY, id->vendor);
+       ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
+       ADD(alias, ":model:",  id->model  != X86_MODEL_ANY,  id->model);
+       ADD(alias, ":feature:*,", id->feature != X86_FEATURE_ANY, id->feature);
+       strcat(alias, ",*");
+       return 1;
+ }
+ ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id, do_x86cpu_entry);
  /* Does namelen bytes of name exactly match the symbol? */
  static bool sym_is(const char *name, unsigned namelen, const char *symbol)
  {
@@@ -1106,7 -1104,6 +1130,7 @@@ void handle_moddevtable(struct module *
                do_pnp_card_entries(symval, sym->st_size, mod);
        else {
                struct devtable **p;
 +              INIT_SECTION(__devtable);
  
                for (p = __start___devtable; p < __stop___devtable; p++) {
                        if (sym_is(name, namelen, (*p)->device_id)) {