From 8402a1588a4f63465079e98481dd83d1d9cc9a98 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 15 Oct 2009 18:49:27 +0200 Subject: [PATCH] MIPS: Alchemy: prom_putchar is board dependent 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 Signed-off-by: Ralf Baechle --- arch/mips/alchemy/Kconfig | 14 +++++ arch/mips/alchemy/common/Makefile | 2 +- arch/mips/alchemy/common/puts.c | 68 ---------------------- arch/mips/alchemy/devboards/prom.c | 5 ++ arch/mips/alchemy/mtx-1/init.c | 6 ++ arch/mips/alchemy/xxs1500/init.c | 6 ++ arch/mips/include/asm/mach-au1x00/au1000.h | 19 ++++++ 7 files changed, 51 insertions(+), 69 deletions(-) delete mode 100644 arch/mips/alchemy/common/puts.c diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index 00b498e97c83..22f4ff5103c1 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig @@ -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 diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index b67fb512529d..abf0eb19051e 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile @@ -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 index 55bbe24d45b6..000000000000 --- a/arch/mips/alchemy/common/puts.c +++ /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. - * - * 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 - -#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; -} diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c index 0042bd6b1d7d..b30df5c97ad3 100644 --- a/arch/mips/alchemy/devboards/prom.c +++ b/arch/mips/alchemy/devboards/prom.c @@ -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); +} diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c index 5e871c8d9e96..f8d25575fa05 100644 --- a/arch/mips/alchemy/mtx-1/init.c +++ b/arch/mips/alchemy/mtx-1/init.c @@ -32,6 +32,7 @@ #include #include +#include #include @@ -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); +} diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c index 456fa142c093..15125c2fda7d 100644 --- a/arch/mips/alchemy/xxs1500/init.c +++ b/arch/mips/alchemy/xxs1500/init.c @@ -30,6 +30,7 @@ #include #include +#include #include @@ -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); +} diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index c2e233997b6c..e11756d9aaa2 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h @@ -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);