MIPS: Alchemy: prom_putchar is board dependent
authorManuel Lauss <manuel.lauss@googlemail.com>
Thu, 15 Oct 2009 16:49:27 +0000 (18:49 +0200)
committerRalf Baechle <ralf@linux-mips.org>
Sat, 27 Feb 2010 11:52:55 +0000 (12:52 +0100)
This patch replaces the general alchemy prom_putchar() implementation
in favor of board-specific versions:  The UART where the output of
prom_putchar is directed to really depends on the board, the current
implementation hardcodes this on a per-SoC basis which is just wrong.

So a generic uart tx function is provided in the alchemy headers,
and the boards can provide their own prom_putchar with custom
destination uart, and all in-kernel alchemy boards support
early printk.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/alchemy/Kconfig
arch/mips/alchemy/common/Makefile
arch/mips/alchemy/common/puts.c [deleted file]
arch/mips/alchemy/devboards/prom.c
arch/mips/alchemy/mtx-1/init.c
arch/mips/alchemy/xxs1500/init.c
arch/mips/include/asm/mach-au1x00/au1000.h

index 00b498e97c831b193c60f02ef5865ebe9e12ee82..22f4ff5103c104586c311b79c3dd0da6f288205c 100644 (file)
@@ -20,12 +20,14 @@ config MIPS_MTX1
        select HW_HAS_PCI
        select SOC_AU1500
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_BOSPORUS
        bool "Alchemy Bosporus board"
        select SOC_AU1500
        select DMA_NONCOHERENT
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1000
        bool "Alchemy DB1000 board"
@@ -33,12 +35,14 @@ config MIPS_DB1000
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1100
        bool "Alchemy DB1100 board"
        select SOC_AU1100
        select DMA_NONCOHERENT
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1200
        bool "Alchemy DB1200 board"
@@ -46,6 +50,7 @@ config MIPS_DB1200
        select DMA_COHERENT
        select MIPS_DISABLE_OBSOLETE_IDE
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1500
        bool "Alchemy DB1500 board"
@@ -55,6 +60,7 @@ config MIPS_DB1500
        select MIPS_DISABLE_OBSOLETE_IDE
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_DB1550
        bool "Alchemy DB1550 board"
@@ -63,12 +69,14 @@ config MIPS_DB1550
        select DMA_NONCOHERENT
        select MIPS_DISABLE_OBSOLETE_IDE
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_MIRAGE
        bool "Alchemy Mirage board"
        select DMA_NONCOHERENT
        select SOC_AU1500
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1000
        bool "Alchemy PB1000 board"
@@ -77,6 +85,7 @@ config MIPS_PB1000
        select HW_HAS_PCI
        select SWAP_IO_SPACE
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1100
        bool "Alchemy PB1100 board"
@@ -85,6 +94,7 @@ config MIPS_PB1100
        select HW_HAS_PCI
        select SWAP_IO_SPACE
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1200
        bool "Alchemy PB1200 board"
@@ -92,6 +102,7 @@ config MIPS_PB1200
        select DMA_NONCOHERENT
        select MIPS_DISABLE_OBSOLETE_IDE
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1500
        bool "Alchemy PB1500 board"
@@ -99,6 +110,7 @@ config MIPS_PB1500
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_PB1550
        bool "Alchemy PB1550 board"
@@ -107,12 +119,14 @@ config MIPS_PB1550
        select HW_HAS_PCI
        select MIPS_DISABLE_OBSOLETE_IDE
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 config MIPS_XXS1500
        bool "MyCable XXS1500 board"
        select DMA_NONCOHERENT
        select SOC_AU1500
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_HAS_EARLY_PRINTK
 
 endchoice
 
index b67fb512529d11518ff6ea6e28628c6a317bcd67..abf0eb19051efb83f202a87851f47cdb39400145 100644 (file)
@@ -5,7 +5,7 @@
 # Makefile for the Alchemy Au1xx0 CPUs, generic files.
 #
 
-obj-y += prom.o irq.o puts.o time.o reset.o \
+obj-y += prom.o irq.o time.o reset.o \
        clocks.o platform.o power.o setup.o \
        sleeper.o dma.o dbdma.o
 
diff --git a/arch/mips/alchemy/common/puts.c b/arch/mips/alchemy/common/puts.c
deleted file mode 100644 (file)
index 55bbe24..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     Low level UART routines to directly access Alchemy UART.
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/mach-au1x00/au1000.h>
-
-#define SERIAL_BASE   UART_BASE
-#define SER_CMD       0x7
-#define SER_DATA      0x1
-#define TX_BUSY       0x20
-
-#define TIMEOUT       0xffffff
-#define SLOW_DOWN
-
-static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
-
-#ifdef SLOW_DOWN
-static inline void slow_down(void)
-{
-       int k;
-
-       for (k = 0; k < 10000; k++);
-}
-#else
-#define slow_down()
-#endif
-
-void
-prom_putchar(const unsigned char c)
-{
-       unsigned char ch;
-       int i = 0;
-
-       do {
-               ch = com1[SER_CMD];
-               slow_down();
-               i++;
-               if (i > TIMEOUT)
-                       break;
-       } while (0 == (ch & TX_BUSY));
-
-       com1[SER_DATA] = c;
-}
index 0042bd6b1d7dc10495afda0ffc83d372370c7838..b30df5c97ad35e46e534b047c144975c01db6b76 100644 (file)
@@ -60,3 +60,8 @@ void __init prom_init(void)
                strict_strtoul(memsize_str, 0, &memsize);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
+
+void prom_putchar(unsigned char c)
+{
+    alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
index 5e871c8d9e964d96cad974abb20743dabff72c2a..f8d25575fa05a78bb6afce909191691a96a9ba2e 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 
 #include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
 
 #include <prom.h>
 
@@ -58,3 +59,8 @@ void __init prom_init(void)
                strict_strtoul(memsize_str, 0, &memsize);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
+
+void prom_putchar(unsigned char c)
+{
+       alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
index 456fa142c0934ac094e733889b7c07cd2bbd0644..15125c2fda7d7397de3dcee2ec1f1555babc1f85 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 
 #include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
 
 #include <prom.h>
 
@@ -56,3 +57,8 @@ void __init prom_init(void)
                strict_strtoul(memsize_str, 0, &memsize);
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
+
+void prom_putchar(unsigned char c)
+{
+       alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+}
index c2e233997b6c964f29a059f31805266267831602..e11756d9aaa28440410e7313931371d1a7ccf435 100644 (file)
@@ -161,6 +161,25 @@ static inline int alchemy_get_cputype(void)
        return ALCHEMY_CPU_UNKNOWN;
 }
 
+static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
+{
+       void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
+       int timeout, i;
+
+       /* check LSR TX_EMPTY bit */
+       timeout = 0xffffff;
+       do {
+               if (__raw_readl(base + 0x1c) & 0x20)
+                       break;
+               /* slow down */
+               for (i = 10000; i; i--)
+                       asm volatile ("nop");
+       } while (--timeout);
+
+       __raw_writel(c, base + 0x04);   /* tx */
+       wmb();
+}
+
 /* arch/mips/au1000/common/clocks.c */
 extern void set_au1x00_speed(unsigned int new_freq);
 extern unsigned int get_au1x00_speed(void);