18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/init.h> 38c2ecf20Sopenharmony_ci#include <linux/errno.h> 48c2ecf20Sopenharmony_ci#include <linux/console.h> 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <asm/sibyte/board.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <asm/fw/cfe/cfe_api.h> 98c2ecf20Sopenharmony_ci#include <asm/fw/cfe/cfe_error.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ciextern int cfe_cons_handle; 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic void cfe_console_write(struct console *cons, const char *str, 148c2ecf20Sopenharmony_ci unsigned int count) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci int i, last, written; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci for (i=0, last=0; i<count; i++) { 198c2ecf20Sopenharmony_ci if (!str[i]) 208c2ecf20Sopenharmony_ci /* XXXKW can/should this ever happen? */ 218c2ecf20Sopenharmony_ci return; 228c2ecf20Sopenharmony_ci if (str[i] == '\n') { 238c2ecf20Sopenharmony_ci do { 248c2ecf20Sopenharmony_ci written = cfe_write(cfe_cons_handle, &str[last], i-last); 258c2ecf20Sopenharmony_ci if (written < 0) 268c2ecf20Sopenharmony_ci ; 278c2ecf20Sopenharmony_ci last += written; 288c2ecf20Sopenharmony_ci } while (last < i); 298c2ecf20Sopenharmony_ci while (cfe_write(cfe_cons_handle, "\r", 1) <= 0) 308c2ecf20Sopenharmony_ci ; 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci } 338c2ecf20Sopenharmony_ci if (last != count) { 348c2ecf20Sopenharmony_ci do { 358c2ecf20Sopenharmony_ci written = cfe_write(cfe_cons_handle, &str[last], count-last); 368c2ecf20Sopenharmony_ci if (written < 0) 378c2ecf20Sopenharmony_ci ; 388c2ecf20Sopenharmony_ci last += written; 398c2ecf20Sopenharmony_ci } while (last < count); 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic int cfe_console_setup(struct console *cons, char *str) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci char consdev[32]; 478c2ecf20Sopenharmony_ci /* XXXKW think about interaction with 'console=' cmdline arg */ 488c2ecf20Sopenharmony_ci /* If none of the console options are configured, the build will break. */ 498c2ecf20Sopenharmony_ci if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) { 508c2ecf20Sopenharmony_ci#ifdef CONFIG_SERIAL_SB1250_DUART 518c2ecf20Sopenharmony_ci if (!strcmp(consdev, "uart0")) { 528c2ecf20Sopenharmony_ci setleds("u0cn"); 538c2ecf20Sopenharmony_ci } else if (!strcmp(consdev, "uart1")) { 548c2ecf20Sopenharmony_ci setleds("u1cn"); 558c2ecf20Sopenharmony_ci } else 568c2ecf20Sopenharmony_ci#endif 578c2ecf20Sopenharmony_ci#ifdef CONFIG_VGA_CONSOLE 588c2ecf20Sopenharmony_ci if (!strcmp(consdev, "pcconsole0")) { 598c2ecf20Sopenharmony_ci setleds("pccn"); 608c2ecf20Sopenharmony_ci } else 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci return -ENODEV; 638c2ecf20Sopenharmony_ci } 648c2ecf20Sopenharmony_ci return 0; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic struct console sb1250_cfe_cons = { 688c2ecf20Sopenharmony_ci .name = "cfe", 698c2ecf20Sopenharmony_ci .write = cfe_console_write, 708c2ecf20Sopenharmony_ci .setup = cfe_console_setup, 718c2ecf20Sopenharmony_ci .flags = CON_PRINTBUFFER, 728c2ecf20Sopenharmony_ci .index = -1, 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic int __init sb1250_cfe_console_init(void) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci register_console(&sb1250_cfe_cons); 788c2ecf20Sopenharmony_ci return 0; 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciconsole_initcall(sb1250_cfe_console_init); 82