Merge branch 'master' of /home/sam/kernel/linux-2.6/
[pandora-kernel.git] / arch / arm / mach-ep93xx / core.c
index 865427b..a87a784 100644 (file)
@@ -13,7 +13,6 @@
  * your option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -30,7 +29,9 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/delay.h>
+#include <linux/termios.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -101,7 +102,8 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        write_seqlock(&xtime_lock);
 
        __raw_writel(1, EP93XX_TIMER1_CLEAR);
-       while (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time
+       while ((signed long)
+               (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
                                                >= TIMER4_TICKS_PER_JIFFY) {
                last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
                timer_tick(regs);
@@ -114,7 +116,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction ep93xx_timer_irq = {
        .name           = "ep93xx timer",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = ep93xx_timer_interrupt,
 };
 
@@ -122,7 +124,7 @@ static void __init ep93xx_timer_init(void)
 {
        /* Enable periodic HZ timer.  */
        __raw_writel(0x48, EP93XX_TIMER1_CONTROL);
-       __raw_writel((508000 / HZ) - 1, EP93XX_TIMER1_LOAD);
+       __raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD);
        __raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
 
        /* Enable lost jiffy timer.  */
@@ -360,10 +362,107 @@ void __init ep93xx_init_irq(void)
 /*************************************************************************
  * EP93xx peripheral handling
  *************************************************************************/
+#define EP93XX_UART_MCR_OFFSET         (0x0100)
+
+static void ep93xx_uart_set_mctrl(struct amba_device *dev,
+                                 void __iomem *base, unsigned int mctrl)
+{
+       unsigned int mcr;
+
+       mcr = 0;
+       if (!(mctrl & TIOCM_RTS))
+               mcr |= 2;
+       if (!(mctrl & TIOCM_DTR))
+               mcr |= 1;
+
+       __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET);
+}
+
+static struct amba_pl010_data ep93xx_uart_data = {
+       .set_mctrl      = ep93xx_uart_set_mctrl,
+};
+
+static struct amba_device uart1_device = {
+       .dev            = {
+               .bus_id         = "apb:uart1",
+               .platform_data  = &ep93xx_uart_data,
+       },
+       .res            = {
+               .start  = EP93XX_UART1_PHYS_BASE,
+               .end    = EP93XX_UART1_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = { IRQ_EP93XX_UART1, NO_IRQ },
+       .periphid       = 0x00041010,
+};
+
+static struct amba_device uart2_device = {
+       .dev            = {
+               .bus_id         = "apb:uart2",
+               .platform_data  = &ep93xx_uart_data,
+       },
+       .res            = {
+               .start  = EP93XX_UART2_PHYS_BASE,
+               .end    = EP93XX_UART2_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = { IRQ_EP93XX_UART2, NO_IRQ },
+       .periphid       = 0x00041010,
+};
+
+static struct amba_device uart3_device = {
+       .dev            = {
+               .bus_id         = "apb:uart3",
+               .platform_data  = &ep93xx_uart_data,
+       },
+       .res            = {
+               .start  = EP93XX_UART3_PHYS_BASE,
+               .end    = EP93XX_UART3_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = { IRQ_EP93XX_UART3, NO_IRQ },
+       .periphid       = 0x00041010,
+};
+
+
+static struct platform_device ep93xx_rtc_device = {
+       .name           = "ep93xx-rtc",
+       .id             = -1,
+       .num_resources  = 0,
+};
+
+
+static struct resource ep93xx_ohci_resources[] = {
+       [0] = {
+               .start  = EP93XX_USB_PHYS_BASE,
+               .end    = EP93XX_USB_PHYS_BASE + 0x0fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EP93XX_USB,
+               .end    = IRQ_EP93XX_USB,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device ep93xx_ohci_device = {
+       .name           = "ep93xx-ohci",
+       .id             = -1,
+       .dev            = {
+               .dma_mask               = (void *)0xffffffff,
+               .coherent_dma_mask      = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(ep93xx_ohci_resources),
+       .resource       = ep93xx_ohci_resources,
+};
+
+
 void __init ep93xx_init_devices(void)
 {
        unsigned int v;
 
+       ep93xx_clock_init();
+
        /*
         * Disallow access to MaverickCrunch initially.
         */
@@ -371,4 +470,11 @@ void __init ep93xx_init_devices(void)
        v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
        __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
        __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+
+       amba_device_register(&uart1_device, &iomem_resource);
+       amba_device_register(&uart2_device, &iomem_resource);
+       amba_device_register(&uart3_device, &iomem_resource);
+
+       platform_device_register(&ep93xx_rtc_device);
+       platform_device_register(&ep93xx_ohci_device);
 }