Skip to content

Commit

Permalink
serial: samsung: Add support for early console
Browse files Browse the repository at this point in the history
This patch adds support for early console initialized from device tree
and kernel command line to all variants of Samsung serial driver.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
[mszyprow: added support for command line based initialization,
           fixed comments, added documentation]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
Tested-by: Alim Akhtar <alim.akhtar@samsung.com>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tomasz Figa authored and Greg Kroah-Hartman committed Feb 2, 2015
1 parent 8b6ff84 commit b94ba03
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.

smh Use ARM semihosting calls for early console.

s3c2410,<addr>
s3c2412,<addr>
s3c2440,<addr>
s3c6400,<addr>
s5pv210,<addr>
exynos4210,<addr>
Use early console provided by serial driver available
on Samsung SoCs, requires selecting proper type and
a correct base address of the selected UART port. The
serial port must already be setup and configured.
Options are not yet supported.

earlyprintk= [X86,SH,BLACKFIN,ARM,M68k]
earlyprintk=vga
earlyprintk=efi
Expand Down
1 change: 1 addition & 0 deletions drivers/tty/serial/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ config SERIAL_SAMSUNG
tristate "Samsung SoC serial support"
depends on PLAT_SAMSUNG || ARCH_EXYNOS
select SERIAL_CORE
select SERIAL_EARLYCON
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
providing /dev/ttySAC0, 1 and 2 (note, some machines may not
Expand Down
103 changes: 103 additions & 0 deletions drivers/tty/serial/samsung.c
Original file line number Diff line number Diff line change
Expand Up @@ -2403,6 +2403,109 @@ static struct platform_driver samsung_serial_driver = {

module_platform_driver(samsung_serial_driver);

/*
* Early console.
*/

struct samsung_early_console_data {
u32 txfull_mask;
};

static void samsung_early_busyuart(struct uart_port *port)
{
while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE))
;
}

static void samsung_early_busyuart_fifo(struct uart_port *port)
{
struct samsung_early_console_data *data = port->private_data;

while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask)
;
}

static void samsung_early_putc(struct uart_port *port, int c)
{
if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE)
samsung_early_busyuart_fifo(port);
else
samsung_early_busyuart(port);

writeb(c, port->membase + S3C2410_UTXH);
}

static void samsung_early_write(struct console *con, const char *s, unsigned n)
{
struct earlycon_device *dev = con->data;

uart_console_write(&dev->port, s, n, samsung_early_putc);
}

static int __init samsung_early_console_setup(struct earlycon_device *device,
const char *opt)
{
if (!device->port.membase)
return -ENODEV;

device->con->write = samsung_early_write;
return 0;
}

/* S3C2410 */
static struct samsung_early_console_data s3c2410_early_console_data = {
.txfull_mask = S3C2410_UFSTAT_TXFULL,
};

static int __init s3c2410_early_console_setup(struct earlycon_device *device,
const char *opt)
{
device->port.private_data = &s3c2410_early_console_data;
return samsung_early_console_setup(device, opt);
}
OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart",
s3c2410_early_console_setup);
EARLYCON_DECLARE(s3c2410, s3c2410_early_console_setup);

/* S3C2412, S3C2440, S3C64xx */
static struct samsung_early_console_data s3c2440_early_console_data = {
.txfull_mask = S3C2440_UFSTAT_TXFULL,
};

static int __init s3c2440_early_console_setup(struct earlycon_device *device,
const char *opt)
{
device->port.private_data = &s3c2440_early_console_data;
return samsung_early_console_setup(device, opt);
}
OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart",
s3c2440_early_console_setup);
OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart",
s3c2440_early_console_setup);
OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart",
s3c2440_early_console_setup);
EARLYCON_DECLARE(s3c2412, s3c2440_early_console_setup);
EARLYCON_DECLARE(s3c2440, s3c2440_early_console_setup);
EARLYCON_DECLARE(s3c6400, s3c2440_early_console_setup);

/* S5PV210, EXYNOS */
static struct samsung_early_console_data s5pv210_early_console_data = {
.txfull_mask = S5PV210_UFSTAT_TXFULL,
};

static int __init s5pv210_early_console_setup(struct earlycon_device *device,
const char *opt)
{
device->port.private_data = &s5pv210_early_console_data;
return samsung_early_console_setup(device, opt);
}
OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
s5pv210_early_console_setup);
OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
s5pv210_early_console_setup);
EARLYCON_DECLARE(s5pv210, s5pv210_early_console_setup);
EARLYCON_DECLARE(exynos4210, s5pv210_early_console_setup);

MODULE_ALIAS("platform:samsung-uart");
MODULE_DESCRIPTION("Samsung SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
Expand Down

0 comments on commit b94ba03

Please sign in to comment.