162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/init.h> 362306a36Sopenharmony_ci#include <linux/errno.h> 462306a36Sopenharmony_ci#include <linux/console.h> 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <asm/sibyte/board.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/fw/cfe/cfe_api.h> 962306a36Sopenharmony_ci#include <asm/fw/cfe/cfe_error.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciextern int cfe_cons_handle; 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic void cfe_console_write(struct console *cons, const char *str, 1462306a36Sopenharmony_ci unsigned int count) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci int i, last, written; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci for (i=0, last=0; i<count; i++) { 1962306a36Sopenharmony_ci if (!str[i]) 2062306a36Sopenharmony_ci /* XXXKW can/should this ever happen? */ 2162306a36Sopenharmony_ci return; 2262306a36Sopenharmony_ci if (str[i] == '\n') { 2362306a36Sopenharmony_ci do { 2462306a36Sopenharmony_ci written = cfe_write(cfe_cons_handle, &str[last], i-last); 2562306a36Sopenharmony_ci if (written < 0) 2662306a36Sopenharmony_ci ; 2762306a36Sopenharmony_ci last += written; 2862306a36Sopenharmony_ci } while (last < i); 2962306a36Sopenharmony_ci while (cfe_write(cfe_cons_handle, "\r", 1) <= 0) 3062306a36Sopenharmony_ci ; 3162306a36Sopenharmony_ci } 3262306a36Sopenharmony_ci } 3362306a36Sopenharmony_ci if (last != count) { 3462306a36Sopenharmony_ci do { 3562306a36Sopenharmony_ci written = cfe_write(cfe_cons_handle, &str[last], count-last); 3662306a36Sopenharmony_ci if (written < 0) 3762306a36Sopenharmony_ci ; 3862306a36Sopenharmony_ci last += written; 3962306a36Sopenharmony_ci } while (last < count); 4062306a36Sopenharmony_ci } 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic int cfe_console_setup(struct console *cons, char *str) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci char consdev[32]; 4762306a36Sopenharmony_ci /* XXXKW think about interaction with 'console=' cmdline arg */ 4862306a36Sopenharmony_ci /* If none of the console options are configured, the build will break. */ 4962306a36Sopenharmony_ci if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) { 5062306a36Sopenharmony_ci#ifdef CONFIG_SERIAL_SB1250_DUART 5162306a36Sopenharmony_ci if (!strcmp(consdev, "uart0")) { 5262306a36Sopenharmony_ci setleds("u0cn"); 5362306a36Sopenharmony_ci } else if (!strcmp(consdev, "uart1")) { 5462306a36Sopenharmony_ci setleds("u1cn"); 5562306a36Sopenharmony_ci } else 5662306a36Sopenharmony_ci#endif 5762306a36Sopenharmony_ci#ifdef CONFIG_VGA_CONSOLE 5862306a36Sopenharmony_ci if (!strcmp(consdev, "pcconsole0")) { 5962306a36Sopenharmony_ci setleds("pccn"); 6062306a36Sopenharmony_ci } else 6162306a36Sopenharmony_ci#endif 6262306a36Sopenharmony_ci return -ENODEV; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci return 0; 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic struct console sb1250_cfe_cons = { 6862306a36Sopenharmony_ci .name = "cfe", 6962306a36Sopenharmony_ci .write = cfe_console_write, 7062306a36Sopenharmony_ci .setup = cfe_console_setup, 7162306a36Sopenharmony_ci .flags = CON_PRINTBUFFER, 7262306a36Sopenharmony_ci .index = -1, 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic int __init sb1250_cfe_console_init(void) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci register_console(&sb1250_cfe_cons); 7862306a36Sopenharmony_ci return 0; 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciconsole_initcall(sb1250_cfe_console_init); 82