Merge branch 'hotfixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[pandora-kernel.git] / arch / mips / txx9 / generic / setup.c
index 8c60c78..1bc57d0 100644 (file)
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
+#include <asm/reboot.h>
 #include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
 #ifdef CONFIG_CPU_TX49XX
 #include <asm/txx9/tx4938.h>
 #endif
@@ -187,6 +191,117 @@ char * __init prom_getcmdline(void)
        return &(arcs_cmdline[0]);
 }
 
+static void __noreturn txx9_machine_halt(void)
+{
+       local_irq_disable();
+       clear_c0_status(ST0_IM);
+       while (1) {
+               if (cpu_wait) {
+                       (*cpu_wait)();
+                       if (cpu_has_counter) {
+                               /*
+                                * Clear counter interrupt while it
+                                * breaks WAIT instruction even if
+                                * masked.
+                                */
+                               write_c0_compare(0);
+                       }
+               }
+       }
+}
+
+/* Watchdog support */
+void __init txx9_wdt_init(unsigned long base)
+{
+       struct resource res = {
+               .start  = base,
+               .end    = base + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       };
+       platform_device_register_simple("txx9wdt", -1, &res, 1);
+}
+
+/* SPI support */
+void __init txx9_spi_init(int busid, unsigned long base, int irq)
+{
+       struct resource res[] = {
+               {
+                       .start  = base,
+                       .end    = base + 0x20 - 1,
+                       .flags  = IORESOURCE_MEM,
+               }, {
+                       .start  = irq,
+                       .flags  = IORESOURCE_IRQ,
+               },
+       };
+       platform_device_register_simple("spi_txx9", busid,
+                                       res, ARRAY_SIZE(res));
+}
+
+void __init txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr)
+{
+       struct platform_device *pdev =
+               platform_device_alloc("tc35815-mac", id);
+       if (!pdev ||
+           platform_device_add_data(pdev, ethaddr, 6) ||
+           platform_device_add(pdev))
+               platform_device_put(pdev);
+}
+
+void __init txx9_sio_init(unsigned long baseaddr, int irq,
+                         unsigned int line, unsigned int sclk, int nocts)
+{
+#ifdef CONFIG_SERIAL_TXX9
+       struct uart_port req;
+
+       memset(&req, 0, sizeof(req));
+       req.line = line;
+       req.iotype = UPIO_MEM;
+       req.membase = ioremap(baseaddr, 0x24);
+       req.mapbase = baseaddr;
+       req.irq = irq;
+       if (!nocts)
+               req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+       if (sclk) {
+               req.flags |= UPF_MAGIC_MULTIPLIER /*USE_SCLK*/;
+               req.uartclk = sclk;
+       } else
+               req.uartclk = TXX9_IMCLK;
+       early_serial_txx9_setup(&req);
+#endif /* CONFIG_SERIAL_TXX9 */
+}
+
+#ifdef CONFIG_EARLY_PRINTK
+static void __init null_prom_putchar(char c)
+{
+}
+void (*txx9_prom_putchar)(char c) __initdata = null_prom_putchar;
+
+void __init prom_putchar(char c)
+{
+       txx9_prom_putchar(c);
+}
+
+static void __iomem *early_txx9_sio_port;
+
+static void __init early_txx9_sio_putchar(char c)
+{
+#define TXX9_SICISR    0x0c
+#define TXX9_SITFIFO   0x1c
+#define TXX9_SICISR_TXALS      0x00000002
+       while (!(__raw_readl(early_txx9_sio_port + TXX9_SICISR) &
+                TXX9_SICISR_TXALS))
+               ;
+       __raw_writel(c, early_txx9_sio_port + TXX9_SITFIFO);
+}
+
+void __init txx9_sio_putchar_init(unsigned long baseaddr)
+{
+       early_txx9_sio_port = ioremap(baseaddr, 0x24);
+       txx9_prom_putchar = early_txx9_sio_putchar;
+}
+#endif /* CONFIG_EARLY_PRINTK */
+
 /* wrappers */
 void __init plat_mem_setup(void)
 {
@@ -194,6 +309,15 @@ void __init plat_mem_setup(void)
        ioport_resource.end = ~0UL;     /* no limit */
        iomem_resource.start = 0;
        iomem_resource.end = ~0UL;      /* no limit */
+
+       /* fallback restart/halt routines */
+       _machine_restart = (void (*)(char *))txx9_machine_halt;
+       _machine_halt = txx9_machine_halt;
+       pm_power_off = txx9_machine_halt;
+
+#ifdef CONFIG_PCI
+       pcibios_plat_setup = txx9_pcibios_setup;
+#endif
        txx9_board_vec->mem_setup();
 }