*
* Copyright (C) 1999, 2000 Niibe Yutaka
* Copyright (C) 2002 M. R. Brown
- * Copyright (C) 2004 Paul Mundt
+ * Copyright (C) 2004 - 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/init.h>
-#include <asm/io.h>
+#include <linux/io.h>
#ifdef CONFIG_SH_STANDARD_BIOS
#include <asm/sh_bios.h>
return 0;
}
-static struct console early_console = {
+static struct console bios_console = {
.name = "bios",
.write = sh_console_write,
.setup = sh_console_setup,
#endif
#ifdef CONFIG_EARLY_SCIF_CONSOLE
-#define SCIF_REG 0xffe80000
+#include <linux/serial_core.h>
+#include "../../../drivers/serial/sh-sci.h"
+
+static struct uart_port scif_port = {
+ .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT,
+ .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
+};
static void scif_sercon_putc(int c)
{
- while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ;
+ while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16))
+ ;
- ctrl_outb(c, SCIF_REG + 12);
- ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10);
+ sci_out(&scif_port, SCxTDR, c);
+ sci_in(&scif_port, SCxSR);
+ sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
+
+ while ((sci_in(&scif_port, SCxSR) & 0x40) == 0);
+ ;
if (c == '\n')
scif_sercon_putc('\r');
}
-static void scif_sercon_flush(void)
-{
- ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10);
-
- while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ;
-
- ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10);
-}
-
-static void scif_sercon_write(struct console *con, const char *s, unsigned count)
+static void scif_sercon_write(struct console *con, const char *s,
+ unsigned count)
{
while (count-- > 0)
scif_sercon_putc(*s++);
-
- scif_sercon_flush();
}
static int __init scif_sercon_setup(struct console *con, char *options)
return 0;
}
-static struct console early_console = {
+static struct console scif_console = {
.name = "sercon",
.write = scif_sercon_write,
.setup = scif_sercon_setup,
.index = -1,
};
-void scif_sercon_init(int baud)
+#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
+/*
+ * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
+ * devices that aren't using sh-ipl+g.
+ */
+static void scif_sercon_init(int baud)
{
- ctrl_outw(0, SCIF_REG + 8);
- ctrl_outw(0, SCIF_REG);
+ ctrl_outw(0, scif_port.mapbase + 8);
+ ctrl_outw(0, scif_port.mapbase);
/* Set baud rate */
ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
- (32 * baud) - 1, SCIF_REG + 4);
-
- ctrl_outw(12, SCIF_REG + 24);
- ctrl_outw(8, SCIF_REG + 24);
- ctrl_outw(0, SCIF_REG + 32);
- ctrl_outw(0x60, SCIF_REG + 16);
- ctrl_outw(0, SCIF_REG + 36);
- ctrl_outw(0x30, SCIF_REG + 8);
+ (32 * baud) - 1, scif_port.mapbase + 4);
+
+ ctrl_outw(12, scif_port.mapbase + 24);
+ ctrl_outw(8, scif_port.mapbase + 24);
+ ctrl_outw(0, scif_port.mapbase + 32);
+ ctrl_outw(0x60, scif_port.mapbase + 16);
+ ctrl_outw(0, scif_port.mapbase + 36);
+ ctrl_outw(0x30, scif_port.mapbase + 8);
}
+#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */
+#endif /* CONFIG_EARLY_SCIF_CONSOLE */
+
+/*
+ * Setup a default console, if more than one is compiled in, rely on the
+ * earlyprintk= parsing to give priority.
+ */
+static struct console *early_console =
+#ifdef CONFIG_SH_STANDARD_BIOS
+ &bios_console
+#elif defined(CONFIG_EARLY_SCIF_CONSOLE)
+ &scif_console
+#else
+ NULL
#endif
+ ;
+
+static int __initdata keep_early;
+static int early_console_initialized;
-void __init enable_early_printk(void)
+int __init setup_early_printk(char *buf)
{
-#ifdef CONFIG_EARLY_SCIF_CONSOLE
- scif_sercon_init(115200);
+ if (!buf)
+ return 0;
+
+ if (early_console_initialized)
+ return 0;
+ early_console_initialized = 1;
+
+ if (strstr(buf, "keep"))
+ keep_early = 1;
+
+#ifdef CONFIG_SH_STANDARD_BIOS
+ if (!strncmp(buf, "bios", 4))
+ early_console = &bios_console;
#endif
- register_console(&early_console);
+#if defined(CONFIG_EARLY_SCIF_CONSOLE)
+ if (!strncmp(buf, "serial", 6)) {
+ early_console = &scif_console;
+
+#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
+ scif_sercon_init(115200);
+#endif
+ }
+#endif
+
+ if (likely(early_console))
+ register_console(early_console);
+
+ return 0;
}
+early_param("earlyprintk", setup_early_printk);
-void disable_early_printk(void)
+void __init disable_early_printk(void)
{
- unregister_console(&early_console);
+ if (!early_console_initialized || !early_console)
+ return;
+ if (!keep_early) {
+ printk("disabling early console\n");
+ unregister_console(early_console);
+ } else
+ printk("keeping early console\n");
}
-