1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * RISC-V SBI based earlycon 4 * 5 * Copyright (C) 2018 Anup Patel <anup@brainfault.org> 6 */ 7 #include <linux/kernel.h> 8 #include <linux/console.h> 9 #include <linux/init.h> 10 #include <linux/serial_core.h> 11 #include <asm/sbi.h> 12 13 static void sbi_putc(struct uart_port *port, unsigned char c) 14 { 15 sbi_console_putchar(c); 16 } 17 18 static void sbi_0_1_console_write(struct console *con, 19 const char *s, unsigned int n) 20 { 21 struct earlycon_device *dev = con->data; 22 uart_console_write(&dev->port, s, n, sbi_putc); 23 } 24 25 static void sbi_dbcn_console_write(struct console *con, 26 const char *s, unsigned int n) 27 { 28 int ret; 29 30 while (n) { 31 ret = sbi_debug_console_write(s, n); 32 if (ret < 0) 33 break; 34 35 s += ret; 36 n -= ret; 37 } 38 } 39 40 static int __init early_sbi_setup(struct earlycon_device *device, 41 const char *opt) 42 { 43 if (sbi_debug_console_available) 44 device->con->write = sbi_dbcn_console_write; 45 else if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) 46 device->con->write = sbi_0_1_console_write; 47 else 48 return -ENODEV; 49 50 return 0; 51 } 52 EARLYCON_DECLARE(sbi, early_sbi_setup); 53