Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / arm / mach-versatile / core.c
index 302c2a7..cebd48a 100644 (file)
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
 
 #include <asm/system.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
-#include <asm/mach-types.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_clcd.h>
+#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst307.h>
+#include <asm/hardware/vic.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
  *
  * Setup a VA for the Versatile Vectored Interrupt Controller.
  */
-#define VA_VIC_BASE             IO_ADDRESS(VERSATILE_VIC_BASE)
-#define VA_SIC_BASE             IO_ADDRESS(VERSATILE_SIC_BASE)
-
-static void vic_mask_irq(unsigned int irq)
-{
-       irq -= IRQ_VIC_START;
-       writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
-}
-
-static void vic_unmask_irq(unsigned int irq)
-{
-       irq -= IRQ_VIC_START;
-       writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE);
-}
-
-static struct irqchip vic_chip = {
-       .ack    = vic_mask_irq,
-       .mask   = vic_mask_irq,
-       .unmask = vic_unmask_irq,
-};
+#define __io_address(n)                __io(IO_ADDRESS(n))
+#define VA_VIC_BASE            __io_address(VERSATILE_VIC_BASE)
+#define VA_SIC_BASE            __io_address(VERSATILE_SIC_BASE)
 
 static void sic_mask_irq(unsigned int irq)
 {
@@ -107,7 +92,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
                irq += IRQ_SIC_START;
 
                desc = irq_desc + irq;
-               desc->handle(irq, desc, regs);
+               desc_handle_irq(irq, desc, regs);
        } while (status);
 }
 
@@ -125,43 +110,11 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 
 void __init versatile_init_irq(void)
 {
-       unsigned int i, value;
+       unsigned int i;
 
-       /* Disable all interrupts initially. */
+       vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0);
 
-       writel(0, VA_VIC_BASE + VIC_INT_SELECT);
-       writel(0, VA_VIC_BASE + VIC_IRQ_ENABLE);
-       writel(~0, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
-       writel(0, VA_VIC_BASE + VIC_IRQ_STATUS);
-       writel(0, VA_VIC_BASE + VIC_ITCR);
-       writel(~0, VA_VIC_BASE + VIC_IRQ_SOFT_CLEAR);
-
-       /*
-        * Make sure we clear all existing interrupts
-        */
-       writel(0, VA_VIC_BASE + VIC_VECT_ADDR);
-       for (i = 0; i < 19; i++) {
-               value = readl(VA_VIC_BASE + VIC_VECT_ADDR);
-               writel(value, VA_VIC_BASE + VIC_VECT_ADDR);
-       }
-
-       for (i = 0; i < 16; i++) {
-               value = readl(VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
-               writel(value | VICVectCntl_Enable | i, VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
-       }
-
-       writel(32, VA_VIC_BASE + VIC_DEF_VECT_ADDR);
-
-       for (i = IRQ_VIC_START; i <= IRQ_VIC_END; i++) {
-               if (i != IRQ_VICSOURCE31) {
-                       set_irq_chip(i, &vic_chip);
-                       set_irq_handler(i, do_level_IRQ);
-                       set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-               }
-       }
-
-       set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
-       vic_unmask_irq(IRQ_VICSOURCE31);
+       set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
 
        /* Do second interrupt controller */
        writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
@@ -185,22 +138,83 @@ void __init versatile_init_irq(void)
 }
 
 static struct map_desc versatile_io_desc[] __initdata = {
- { IO_ADDRESS(VERSATILE_SYS_BASE),   VERSATILE_SYS_BASE,   SZ_4K,      MT_DEVICE },
- { IO_ADDRESS(VERSATILE_SIC_BASE),   VERSATILE_SIC_BASE,   SZ_4K,      MT_DEVICE },
- { IO_ADDRESS(VERSATILE_VIC_BASE),   VERSATILE_VIC_BASE,   SZ_4K,      MT_DEVICE },
- { IO_ADDRESS(VERSATILE_SCTL_BASE),  VERSATILE_SCTL_BASE,  SZ_4K * 9,  MT_DEVICE },
+       {
+               .virtual        =  IO_ADDRESS(VERSATILE_SYS_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_SYS_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  IO_ADDRESS(VERSATILE_SIC_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_SIC_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  IO_ADDRESS(VERSATILE_VIC_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_VIC_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
+               .length         = SZ_4K * 9,
+               .type           = MT_DEVICE
+       },
 #ifdef CONFIG_MACH_VERSATILE_AB
- { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K,      MT_DEVICE },
- { IO_ADDRESS(VERSATILE_IB2_BASE),   VERSATILE_IB2_BASE,   SZ_64M,     MT_DEVICE },
+       {
+               .virtual        =  IO_ADDRESS(VERSATILE_GPIO0_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_GPIO0_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  IO_ADDRESS(VERSATILE_IB2_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_IB2_BASE),
+               .length         = SZ_64M,
+               .type           = MT_DEVICE
+       },
 #endif
 #ifdef CONFIG_DEBUG_LL
- { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K,      MT_DEVICE },
+       {
+               .virtual        =  IO_ADDRESS(VERSATILE_UART0_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_UART0_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       },
+#endif
+#ifdef CONFIG_PCI
+       {
+               .virtual        =  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  VERSATILE_PCI_VIRT_BASE,
+               .pfn            = __phys_to_pfn(VERSATILE_PCI_BASE),
+               .length         = VERSATILE_PCI_BASE_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  VERSATILE_PCI_CFG_VIRT_BASE,
+               .pfn            = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
+               .length         = VERSATILE_PCI_CFG_BASE_SIZE,
+               .type           = MT_DEVICE
+       },
+#if 0
+       {
+               .virtual        =  VERSATILE_PCI_VIRT_MEM_BASE0,
+               .pfn            = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
+               .length         = SZ_16M,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  VERSATILE_PCI_VIRT_MEM_BASE1,
+               .pfn            = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),
+               .length         = SZ_16M,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        =  VERSATILE_PCI_VIRT_MEM_BASE2,
+               .pfn            = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
+               .length         = SZ_16M,
+               .type           = MT_DEVICE
+       },
 #endif
-#ifdef FIXME
- { PCI_MEMORY_VADDR,                PHYS_PCI_MEM_BASE,    SZ_16M,     MT_DEVICE },
- { PCI_CONFIG_VADDR,                PHYS_PCI_CONFIG_BASE, SZ_16M,     MT_DEVICE },
- { PCI_V3_VADDR,                    PHYS_PCI_V3_BASE,     SZ_512K,    MT_DEVICE },
- { PCI_IO_VADDR,                    PHYS_PCI_IO_BASE,     SZ_64K,     MT_DEVICE },
 #endif
 };
 
@@ -209,7 +223,7 @@ void __init versatile_map_io(void)
        iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 }
 
-#define VERSATILE_REFCOUNTER   (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_REFCOUNTER   (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
 
 /*
  * This is the Versatile sched_clock implementation.  This has
@@ -226,7 +240,7 @@ unsigned long long sched_clock(void)
 }
 
 
-#define VERSATILE_FLASHCTRL    (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 
 static int versatile_flash_init(void)
 {
@@ -304,7 +318,7 @@ static struct platform_device smc91x_device = {
        .resource       = smc91x_resources,
 };
 
-#define VERSATILE_SYSMCI       (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYSMCI       (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
 
 unsigned int mmc_status(struct device *dev)
 {
@@ -338,11 +352,11 @@ static const struct icst307_params versatile_oscvco_params = {
 
 static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
 {
-       unsigned long sys_lock = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
+       void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
 #if defined(CONFIG_ARCH_VERSATILE_PB)
-       unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET;
+       void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET;
 #elif defined(CONFIG_MACH_VERSATILE_AB)
-       unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET;
+       void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET;
 #endif
        u32 val;
 
@@ -478,7 +492,7 @@ static struct clcd_panel epson_2_2_in = {
  */
 static struct clcd_panel *versatile_clcd_panel(void)
 {
-       unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+       void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
        struct clcd_panel *panel = &vga;
        u32 val;
 
@@ -505,7 +519,7 @@ static struct clcd_panel *versatile_clcd_panel(void)
  */
 static void versatile_clcd_disable(struct clcd_fb *fb)
 {
-       unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+       void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
        u32 val;
 
        val = readl(sys_clcd);
@@ -517,7 +531,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
         * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
         */
        if (fb->panel == &sanyo_2_5_in) {
-               unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL);
+               void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
                unsigned long ctrl;
 
                ctrl = readl(versatile_ib2_ctrl);
@@ -532,7 +546,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
  */
 static void versatile_clcd_enable(struct clcd_fb *fb)
 {
-       unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+       void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
        u32 val;
 
        val = readl(sys_clcd);
@@ -566,7 +580,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
         * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
         */
        if (fb->panel == &sanyo_2_5_in) {
-               unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL);
+               void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
                unsigned long ctrl;
 
                ctrl = readl(versatile_ib2_ctrl);
@@ -715,7 +729,7 @@ static struct amba_device *amba_devs[] __initdata = {
 };
 
 #ifdef CONFIG_LEDS
-#define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
+#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
 
 static void versatile_leds_event(led_event_t ledevt)
 {
@@ -773,49 +787,36 @@ void __init versatile_init(void)
 /*
  * Where is the timer (VA)?
  */
-#define TIMER0_VA_BASE          IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
-#define TIMER1_VA_BASE         (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
-#define TIMER2_VA_BASE          IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
-#define TIMER3_VA_BASE         (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE              IO_ADDRESS(VERSATILE_VIC_BASE) 
+#define TIMER0_VA_BASE          __io_address(VERSATILE_TIMER0_1_BASE)
+#define TIMER1_VA_BASE         (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_VA_BASE          __io_address(VERSATILE_TIMER2_3_BASE)
+#define TIMER3_VA_BASE         (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
+#define VA_IC_BASE              __io_address(VERSATILE_VIC_BASE) 
 
 /*
  * How long is the timer interval?
  */
 #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
 #if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)           /* Divide by 256 */
-#define TIMER_CTRL     0x88                            /* Enable, Clock / 256 */
+#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)
+#define TIMER_DIVISOR  (TIMER_CTRL_DIV256)
 #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
 #elif TIMER_INTERVAL >= 0x10000
 #define TIMER_RELOAD   (TIMER_INTERVAL >> 4)           /* Divide by 16 */
-#define TIMER_CTRL     0x84                            /* Enable, Clock / 16 */
+#define TIMER_DIVISOR  (TIMER_CTRL_DIV16)
 #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
 #else
 #define TIMER_RELOAD   (TIMER_INTERVAL)
-#define TIMER_CTRL     0x80                            /* Enable */
+#define TIMER_DIVISOR  (TIMER_CTRL_DIV1)
 #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
 #endif
 
-#define TIMER_CTRL_IE  (1 << 5)        /* Interrupt Enable */
-
-/*
- * What does it look like?
- */
-typedef struct TimerStruct {
-       unsigned long TimerLoad;
-       unsigned long TimerValue;
-       unsigned long TimerControl;
-       unsigned long TimerClear;
-} TimerStruct_t;
-
 /*
  * Returns number of ms since last clock interrupt.  Note that interrupts
  * will have been disabled by do_gettimeoffset()
  */
 static unsigned long versatile_gettimeoffset(void)
 {
-       volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
        unsigned long ticks1, ticks2, status;
 
        /*
@@ -824,11 +825,11 @@ static unsigned long versatile_gettimeoffset(void)
         * an interrupt.  We get around this by ensuring that the
         * counter has not reloaded between our two reads.
         */
-       ticks2 = timer0->TimerValue & 0xffff;
+       ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
        do {
                ticks1 = ticks2;
-               status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
-               ticks2 = timer0->TimerValue & 0xffff;
+               status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS);
+               ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
        } while (ticks2 > ticks1);
 
        /*
@@ -855,12 +856,10 @@ static unsigned long versatile_gettimeoffset(void)
  */
 static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-
        write_seqlock(&xtime_lock);
 
        // ...clear the interrupt
-       timer0->TimerClear = 1;
+       writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
        timer_tick(regs);
 
@@ -871,8 +870,8 @@ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_re
 
 static struct irqaction versatile_timer_irq = {
        .name           = "Versatile Timer Tick",
-       .flags          = SA_INTERRUPT,
-       .handler        = versatile_timer_interrupt
+       .flags          = SA_INTERRUPT | SA_TIMER,
+       .handler        = versatile_timer_interrupt,
 };
 
 /*
@@ -880,31 +879,32 @@ static struct irqaction versatile_timer_irq = {
  */
 static void __init versatile_timer_init(void)
 {
-       volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-       volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-       volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
-       volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
+       u32 val;
 
        /* 
         * set clock frequency: 
         *      VERSATILE_REFCLK is 32KHz
         *      VERSATILE_TIMCLK is 1MHz
         */
-       *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= 
-         ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
-          (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
+       val = readl(__io_address(VERSATILE_SCTL_BASE));
+       writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
+              (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+              __io_address(VERSATILE_SCTL_BASE));
 
        /*
         * Initialise to a known state (all timers off)
         */
-       timer0->TimerControl = 0;
-       timer1->TimerControl = 0;
-       timer2->TimerControl = 0;
-       timer3->TimerControl = 0;
-
-       timer0->TimerLoad    = TIMER_RELOAD;
-       timer0->TimerValue   = TIMER_RELOAD;
-       timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE;  /* periodic + IE */
+       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+
+       writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
+       writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
+       writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
+              TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
 
        /* 
         * Make irqs happen for the system timer