linux/arch/arm/mach-integrator/integrator_ap.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-integrator/integrator_ap.c
   3 *
   4 *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20#include <linux/types.h>
  21#include <linux/kernel.h>
  22#include <linux/init.h>
  23#include <linux/list.h>
  24#include <linux/platform_device.h>
  25#include <linux/slab.h>
  26#include <linux/string.h>
  27#include <linux/syscore_ops.h>
  28#include <linux/amba/bus.h>
  29#include <linux/amba/kmi.h>
  30#include <linux/clocksource.h>
  31#include <linux/clockchips.h>
  32#include <linux/interrupt.h>
  33#include <linux/io.h>
  34#include <linux/irqchip/versatile-fpga.h>
  35#include <linux/mtd/physmap.h>
  36#include <linux/clk.h>
  37#include <linux/platform_data/clk-integrator.h>
  38#include <linux/of_irq.h>
  39#include <linux/of_address.h>
  40#include <linux/of_platform.h>
  41#include <linux/stat.h>
  42#include <linux/sys_soc.h>
  43#include <linux/termios.h>
  44#include <video/vga.h>
  45
  46#include <mach/hardware.h>
  47#include <mach/platform.h>
  48#include <asm/hardware/arm_timer.h>
  49#include <asm/setup.h>
  50#include <asm/param.h>          /* HZ */
  51#include <asm/mach-types.h>
  52#include <asm/sched_clock.h>
  53
  54#include <mach/lm.h>
  55#include <mach/irqs.h>
  56
  57#include <asm/mach/arch.h>
  58#include <asm/mach/irq.h>
  59#include <asm/mach/map.h>
  60#include <asm/mach/pci.h>
  61#include <asm/mach/time.h>
  62
  63#include "common.h"
  64
  65/* Base address to the AP system controller */
  66void __iomem *ap_syscon_base;
  67
  68/*
  69 * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
  70 * is the (PA >> 12).
  71 *
  72 * Setup a VA for the Integrator interrupt controller (for header #0,
  73 * just for now).
  74 */
  75#define VA_IC_BASE      __io_address(INTEGRATOR_IC_BASE)
  76#define VA_EBI_BASE     __io_address(INTEGRATOR_EBI_BASE)
  77#define VA_CMIC_BASE    __io_address(INTEGRATOR_HDR_IC)
  78
  79/*
  80 * Logical      Physical
  81 * e8000000     40000000        PCI memory              PHYS_PCI_MEM_BASE       (max 512M)
  82 * ec000000     61000000        PCI config space        PHYS_PCI_CONFIG_BASE    (max 16M)
  83 * ed000000     62000000        PCI V3 regs             PHYS_PCI_V3_BASE        (max 64k)
  84 * fee00000     60000000        PCI IO                  PHYS_PCI_IO_BASE        (max 16M)
  85 * ef000000                     Cache flush
  86 * f1000000     10000000        Core module registers
  87 * f1100000     11000000        System controller registers
  88 * f1200000     12000000        EBI registers
  89 * f1300000     13000000        Counter/Timer
  90 * f1400000     14000000        Interrupt controller
  91 * f1600000     16000000        UART 0
  92 * f1700000     17000000        UART 1
  93 * f1a00000     1a000000        Debug LEDs
  94 * f1b00000     1b000000        GPIO
  95 */
  96
  97static struct map_desc ap_io_desc[] __initdata __maybe_unused = {
  98        {
  99                .virtual        = IO_ADDRESS(INTEGRATOR_HDR_BASE),
 100                .pfn            = __phys_to_pfn(INTEGRATOR_HDR_BASE),
 101                .length         = SZ_4K,
 102                .type           = MT_DEVICE
 103        }, {
 104                .virtual        = IO_ADDRESS(INTEGRATOR_EBI_BASE),
 105                .pfn            = __phys_to_pfn(INTEGRATOR_EBI_BASE),
 106                .length         = SZ_4K,
 107                .type           = MT_DEVICE
 108        }, {
 109                .virtual        = IO_ADDRESS(INTEGRATOR_CT_BASE),
 110                .pfn            = __phys_to_pfn(INTEGRATOR_CT_BASE),
 111                .length         = SZ_4K,
 112                .type           = MT_DEVICE
 113        }, {
 114                .virtual        = IO_ADDRESS(INTEGRATOR_IC_BASE),
 115                .pfn            = __phys_to_pfn(INTEGRATOR_IC_BASE),
 116                .length         = SZ_4K,
 117                .type           = MT_DEVICE
 118        }, {
 119                .virtual        = IO_ADDRESS(INTEGRATOR_UART0_BASE),
 120                .pfn            = __phys_to_pfn(INTEGRATOR_UART0_BASE),
 121                .length         = SZ_4K,
 122                .type           = MT_DEVICE
 123        }, {
 124                .virtual        = IO_ADDRESS(INTEGRATOR_DBG_BASE),
 125                .pfn            = __phys_to_pfn(INTEGRATOR_DBG_BASE),
 126                .length         = SZ_4K,
 127                .type           = MT_DEVICE
 128        }, {
 129                .virtual        = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE),
 130                .pfn            = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE),
 131                .length         = SZ_4K,
 132                .type           = MT_DEVICE
 133        }, {
 134                .virtual        = (unsigned long)PCI_MEMORY_VADDR,
 135                .pfn            = __phys_to_pfn(PHYS_PCI_MEM_BASE),
 136                .length         = SZ_16M,
 137                .type           = MT_DEVICE
 138        }, {
 139                .virtual        = (unsigned long)PCI_CONFIG_VADDR,
 140                .pfn            = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
 141                .length         = SZ_16M,
 142                .type           = MT_DEVICE
 143        }, {
 144                .virtual        = (unsigned long)PCI_V3_VADDR,
 145                .pfn            = __phys_to_pfn(PHYS_PCI_V3_BASE),
 146                .length         = SZ_64K,
 147                .type           = MT_DEVICE
 148        }
 149};
 150
 151static void __init ap_map_io(void)
 152{
 153        iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
 154        vga_base = (unsigned long)PCI_MEMORY_VADDR;
 155        pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
 156}
 157
 158#ifdef CONFIG_PM
 159static unsigned long ic_irq_enable;
 160
 161static int irq_suspend(void)
 162{
 163        ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
 164        return 0;
 165}
 166
 167static void irq_resume(void)
 168{
 169        /* disable all irq sources */
 170        writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
 171        writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 172        writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 173
 174        writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
 175}
 176#else
 177#define irq_suspend NULL
 178#define irq_resume NULL
 179#endif
 180
 181static struct syscore_ops irq_syscore_ops = {
 182        .suspend        = irq_suspend,
 183        .resume         = irq_resume,
 184};
 185
 186static int __init irq_syscore_init(void)
 187{
 188        register_syscore_ops(&irq_syscore_ops);
 189
 190        return 0;
 191}
 192
 193device_initcall(irq_syscore_init);
 194
 195/*
 196 * Flash handling.
 197 */
 198#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
 199#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
 200
 201static int ap_flash_init(struct platform_device *dev)
 202{
 203        u32 tmp;
 204
 205        writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
 206               ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
 207
 208        tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
 209        writel(tmp, EBI_CSR1);
 210
 211        if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
 212                writel(0xa05f, EBI_LOCK);
 213                writel(tmp, EBI_CSR1);
 214                writel(0, EBI_LOCK);
 215        }
 216        return 0;
 217}
 218
 219static void ap_flash_exit(struct platform_device *dev)
 220{
 221        u32 tmp;
 222
 223        writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP,
 224               ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
 225
 226        tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
 227        writel(tmp, EBI_CSR1);
 228
 229        if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
 230                writel(0xa05f, EBI_LOCK);
 231                writel(tmp, EBI_CSR1);
 232                writel(0, EBI_LOCK);
 233        }
 234}
 235
 236static void ap_flash_set_vpp(struct platform_device *pdev, int on)
 237{
 238        if (on)
 239                writel(INTEGRATOR_SC_CTRL_nFLVPPEN,
 240                       ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
 241        else
 242                writel(INTEGRATOR_SC_CTRL_nFLVPPEN,
 243                       ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
 244}
 245
 246static struct physmap_flash_data ap_flash_data = {
 247        .width          = 4,
 248        .init           = ap_flash_init,
 249        .exit           = ap_flash_exit,
 250        .set_vpp        = ap_flash_set_vpp,
 251};
 252
 253/*
 254 * For the PL010 found in the Integrator/AP some of the UART control is
 255 * implemented in the system controller and accessed using a callback
 256 * from the driver.
 257 */
 258static void integrator_uart_set_mctrl(struct amba_device *dev,
 259                                void __iomem *base, unsigned int mctrl)
 260{
 261        unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
 262        u32 phybase = dev->res.start;
 263
 264        if (phybase == INTEGRATOR_UART0_BASE) {
 265                /* UART0 */
 266                rts_mask = 1 << 4;
 267                dtr_mask = 1 << 5;
 268        } else {
 269                /* UART1 */
 270                rts_mask = 1 << 6;
 271                dtr_mask = 1 << 7;
 272        }
 273
 274        if (mctrl & TIOCM_RTS)
 275                ctrlc |= rts_mask;
 276        else
 277                ctrls |= rts_mask;
 278
 279        if (mctrl & TIOCM_DTR)
 280                ctrlc |= dtr_mask;
 281        else
 282                ctrls |= dtr_mask;
 283
 284        __raw_writel(ctrls, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
 285        __raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
 286}
 287
 288struct amba_pl010_data ap_uart_data = {
 289        .set_mctrl = integrator_uart_set_mctrl,
 290};
 291
 292/*
 293 * Where is the timer (VA)?
 294 */
 295#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
 296#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
 297#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
 298
 299static unsigned long timer_reload;
 300
 301static u32 notrace integrator_read_sched_clock(void)
 302{
 303        return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
 304}
 305
 306static void integrator_clocksource_init(unsigned long inrate,
 307                                        void __iomem *base)
 308{
 309        u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
 310        unsigned long rate = inrate;
 311
 312        if (rate >= 1500000) {
 313                rate /= 16;
 314                ctrl |= TIMER_CTRL_DIV16;
 315        }
 316
 317        writel(0xffff, base + TIMER_LOAD);
 318        writel(ctrl, base + TIMER_CTRL);
 319
 320        clocksource_mmio_init(base + TIMER_VALUE, "timer2",
 321                        rate, 200, 16, clocksource_mmio_readl_down);
 322        setup_sched_clock(integrator_read_sched_clock, 16, rate);
 323}
 324
 325static void __iomem * clkevt_base;
 326
 327/*
 328 * IRQ handler for the timer
 329 */
 330static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
 331{
 332        struct clock_event_device *evt = dev_id;
 333
 334        /* clear the interrupt */
 335        writel(1, clkevt_base + TIMER_INTCLR);
 336
 337        evt->event_handler(evt);
 338
 339        return IRQ_HANDLED;
 340}
 341
 342static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
 343{
 344        u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
 345
 346        /* Disable timer */
 347        writel(ctrl, clkevt_base + TIMER_CTRL);
 348
 349        switch (mode) {
 350        case CLOCK_EVT_MODE_PERIODIC:
 351                /* Enable the timer and start the periodic tick */
 352                writel(timer_reload, clkevt_base + TIMER_LOAD);
 353                ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
 354                writel(ctrl, clkevt_base + TIMER_CTRL);
 355                break;
 356        case CLOCK_EVT_MODE_ONESHOT:
 357                /* Leave the timer disabled, .set_next_event will enable it */
 358                ctrl &= ~TIMER_CTRL_PERIODIC;
 359                writel(ctrl, clkevt_base + TIMER_CTRL);
 360                break;
 361        case CLOCK_EVT_MODE_UNUSED:
 362        case CLOCK_EVT_MODE_SHUTDOWN:
 363        case CLOCK_EVT_MODE_RESUME:
 364        default:
 365                /* Just leave in disabled state */
 366                break;
 367        }
 368
 369}
 370
 371static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
 372{
 373        unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
 374
 375        writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
 376        writel(next, clkevt_base + TIMER_LOAD);
 377        writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
 378
 379        return 0;
 380}
 381
 382static struct clock_event_device integrator_clockevent = {
 383        .name           = "timer1",
 384        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 385        .set_mode       = clkevt_set_mode,
 386        .set_next_event = clkevt_set_next_event,
 387        .rating         = 300,
 388};
 389
 390static struct irqaction integrator_timer_irq = {
 391        .name           = "timer",
 392        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
 393        .handler        = integrator_timer_interrupt,
 394        .dev_id         = &integrator_clockevent,
 395};
 396
 397static void integrator_clockevent_init(unsigned long inrate,
 398                                void __iomem *base, int irq)
 399{
 400        unsigned long rate = inrate;
 401        unsigned int ctrl = 0;
 402
 403        clkevt_base = base;
 404        /* Calculate and program a divisor */
 405        if (rate > 0x100000 * HZ) {
 406                rate /= 256;
 407                ctrl |= TIMER_CTRL_DIV256;
 408        } else if (rate > 0x10000 * HZ) {
 409                rate /= 16;
 410                ctrl |= TIMER_CTRL_DIV16;
 411        }
 412        timer_reload = rate / HZ;
 413        writel(ctrl, clkevt_base + TIMER_CTRL);
 414
 415        setup_irq(irq, &integrator_timer_irq);
 416        clockevents_config_and_register(&integrator_clockevent,
 417                                        rate,
 418                                        1,
 419                                        0xffffU);
 420}
 421
 422void __init ap_init_early(void)
 423{
 424}
 425
 426#ifdef CONFIG_OF
 427
 428static void __init ap_of_timer_init(void)
 429{
 430        struct device_node *node;
 431        const char *path;
 432        void __iomem *base;
 433        int err;
 434        int irq;
 435        struct clk *clk;
 436        unsigned long rate;
 437
 438        clk = clk_get_sys("ap_timer", NULL);
 439        BUG_ON(IS_ERR(clk));
 440        clk_prepare_enable(clk);
 441        rate = clk_get_rate(clk);
 442
 443        err = of_property_read_string(of_aliases,
 444                                "arm,timer-primary", &path);
 445        if (WARN_ON(err))
 446                return;
 447        node = of_find_node_by_path(path);
 448        base = of_iomap(node, 0);
 449        if (WARN_ON(!base))
 450                return;
 451        writel(0, base + TIMER_CTRL);
 452        integrator_clocksource_init(rate, base);
 453
 454        err = of_property_read_string(of_aliases,
 455                                "arm,timer-secondary", &path);
 456        if (WARN_ON(err))
 457                return;
 458        node = of_find_node_by_path(path);
 459        base = of_iomap(node, 0);
 460        if (WARN_ON(!base))
 461                return;
 462        irq = irq_of_parse_and_map(node, 0);
 463        writel(0, base + TIMER_CTRL);
 464        integrator_clockevent_init(rate, base, irq);
 465}
 466
 467static const struct of_device_id fpga_irq_of_match[] __initconst = {
 468        { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
 469        { /* Sentinel */ }
 470};
 471
 472static void __init ap_init_irq_of(void)
 473{
 474        /* disable core module IRQs */
 475        writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
 476        of_irq_init(fpga_irq_of_match);
 477        integrator_clk_init(false);
 478}
 479
 480/* For the Device Tree, add in the UART callbacks as AUXDATA */
 481static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
 482        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
 483                "rtc", NULL),
 484        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
 485                "uart0", &ap_uart_data),
 486        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
 487                "uart1", &ap_uart_data),
 488        OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
 489                "kmi0", NULL),
 490        OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
 491                "kmi1", NULL),
 492        OF_DEV_AUXDATA("cfi-flash", INTEGRATOR_FLASH_BASE,
 493                "physmap-flash", &ap_flash_data),
 494        { /* sentinel */ },
 495};
 496
 497static void __init ap_init_of(void)
 498{
 499        unsigned long sc_dec;
 500        struct device_node *root;
 501        struct device_node *syscon;
 502        struct device *parent;
 503        struct soc_device *soc_dev;
 504        struct soc_device_attribute *soc_dev_attr;
 505        u32 ap_sc_id;
 506        int err;
 507        int i;
 508
 509        /* Here we create an SoC device for the root node */
 510        root = of_find_node_by_path("/");
 511        if (!root)
 512                return;
 513        syscon = of_find_node_by_path("/syscon");
 514        if (!syscon)
 515                return;
 516
 517        ap_syscon_base = of_iomap(syscon, 0);
 518        if (!ap_syscon_base)
 519                return;
 520
 521        ap_sc_id = readl(ap_syscon_base);
 522
 523        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 524        if (!soc_dev_attr)
 525                return;
 526
 527        err = of_property_read_string(root, "compatible",
 528                                      &soc_dev_attr->soc_id);
 529        if (err)
 530                return;
 531        err = of_property_read_string(root, "model", &soc_dev_attr->machine);
 532        if (err)
 533                return;
 534        soc_dev_attr->family = "Integrator";
 535        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
 536                                           'A' + (ap_sc_id & 0x0f));
 537
 538        soc_dev = soc_device_register(soc_dev_attr);
 539        if (IS_ERR(soc_dev)) {
 540                kfree(soc_dev_attr->revision);
 541                kfree(soc_dev_attr);
 542                return;
 543        }
 544
 545        parent = soc_device_to_device(soc_dev);
 546        integrator_init_sysfs(parent, ap_sc_id);
 547
 548        of_platform_populate(root, of_default_bus_match_table,
 549                        ap_auxdata_lookup, parent);
 550
 551        sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
 552        for (i = 0; i < 4; i++) {
 553                struct lm_device *lmdev;
 554
 555                if ((sc_dec & (16 << i)) == 0)
 556                        continue;
 557
 558                lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
 559                if (!lmdev)
 560                        continue;
 561
 562                lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
 563                lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
 564                lmdev->resource.flags = IORESOURCE_MEM;
 565                lmdev->irq = IRQ_AP_EXPINT0 + i;
 566                lmdev->id = i;
 567
 568                lm_device_register(lmdev);
 569        }
 570}
 571
 572static const char * ap_dt_board_compat[] = {
 573        "arm,integrator-ap",
 574        NULL,
 575};
 576
 577DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
 578        .reserve        = integrator_reserve,
 579        .map_io         = ap_map_io,
 580        .init_early     = ap_init_early,
 581        .init_irq       = ap_init_irq_of,
 582        .handle_irq     = fpga_handle_irq,
 583        .init_time      = ap_of_timer_init,
 584        .init_machine   = ap_init_of,
 585        .restart        = integrator_restart,
 586        .dt_compat      = ap_dt_board_compat,
 587MACHINE_END
 588
 589#endif
 590
 591#ifdef CONFIG_ATAGS
 592
 593/*
 594 * For the ATAG boot some static mappings are needed. This will
 595 * go away with the ATAG support down the road.
 596 */
 597
 598static struct map_desc ap_io_desc_atag[] __initdata = {
 599        {
 600                .virtual        = IO_ADDRESS(INTEGRATOR_SC_BASE),
 601                .pfn            = __phys_to_pfn(INTEGRATOR_SC_BASE),
 602                .length         = SZ_4K,
 603                .type           = MT_DEVICE
 604        },
 605};
 606
 607static void __init ap_map_io_atag(void)
 608{
 609        iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag));
 610        ap_map_io();
 611}
 612
 613/*
 614 * This is where non-devicetree initialization code is collected and stashed
 615 * for eventual deletion.
 616 */
 617
 618static struct resource cfi_flash_resource = {
 619        .start          = INTEGRATOR_FLASH_BASE,
 620        .end            = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
 621        .flags          = IORESOURCE_MEM,
 622};
 623
 624static struct platform_device cfi_flash_device = {
 625        .name           = "physmap-flash",
 626        .id             = 0,
 627        .dev            = {
 628                .platform_data  = &ap_flash_data,
 629        },
 630        .num_resources  = 1,
 631        .resource       = &cfi_flash_resource,
 632};
 633
 634static void __init ap_timer_init(void)
 635{
 636        struct clk *clk;
 637        unsigned long rate;
 638
 639        clk = clk_get_sys("ap_timer", NULL);
 640        BUG_ON(IS_ERR(clk));
 641        clk_prepare_enable(clk);
 642        rate = clk_get_rate(clk);
 643
 644        writel(0, TIMER0_VA_BASE + TIMER_CTRL);
 645        writel(0, TIMER1_VA_BASE + TIMER_CTRL);
 646        writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 647
 648        integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
 649        integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
 650                                IRQ_TIMERINT1);
 651}
 652
 653#define INTEGRATOR_SC_VALID_INT 0x003fffff
 654
 655static void __init ap_init_irq(void)
 656{
 657        /* Disable all interrupts initially. */
 658        /* Do the core module ones */
 659        writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
 660
 661        /* do the header card stuff next */
 662        writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 663        writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 664
 665        fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
 666                -1, INTEGRATOR_SC_VALID_INT, NULL);
 667        integrator_clk_init(false);
 668}
 669
 670static void __init ap_init(void)
 671{
 672        unsigned long sc_dec;
 673        int i;
 674
 675        platform_device_register(&cfi_flash_device);
 676
 677        ap_syscon_base = __io_address(INTEGRATOR_SC_BASE);
 678        sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
 679        for (i = 0; i < 4; i++) {
 680                struct lm_device *lmdev;
 681
 682                if ((sc_dec & (16 << i)) == 0)
 683                        continue;
 684
 685                lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
 686                if (!lmdev)
 687                        continue;
 688
 689                lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
 690                lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
 691                lmdev->resource.flags = IORESOURCE_MEM;
 692                lmdev->irq = IRQ_AP_EXPINT0 + i;
 693                lmdev->id = i;
 694
 695                lm_device_register(lmdev);
 696        }
 697
 698        integrator_init(false);
 699}
 700
 701MACHINE_START(INTEGRATOR, "ARM-Integrator")
 702        /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 703        .atag_offset    = 0x100,
 704        .reserve        = integrator_reserve,
 705        .map_io         = ap_map_io_atag,
 706        .init_early     = ap_init_early,
 707        .init_irq       = ap_init_irq,
 708        .handle_irq     = fpga_handle_irq,
 709        .init_time      = ap_timer_init,
 710        .init_machine   = ap_init,
 711        .restart        = integrator_restart,
 712MACHINE_END
 713
 714#endif
 715