1e3b3d0f5SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+ 2d5e54913SDavid Gibson /* 3d5e54913SDavid Gibson * udbg interface to hvc_console.c 4d5e54913SDavid Gibson * 5d5e54913SDavid Gibson * (C) Copyright David Gibson, IBM Corporation 2008. 6d5e54913SDavid Gibson */ 7d5e54913SDavid Gibson 8d5e54913SDavid Gibson #include <linux/console.h> 9d5e54913SDavid Gibson #include <linux/delay.h> 10d5e54913SDavid Gibson #include <linux/err.h> 11d5e54913SDavid Gibson #include <linux/init.h> 12d5e54913SDavid Gibson #include <linux/moduleparam.h> 13d5e54913SDavid Gibson #include <linux/types.h> 14d5e54913SDavid Gibson #include <linux/irq.h> 15d5e54913SDavid Gibson 16d5e54913SDavid Gibson #include <asm/udbg.h> 17d5e54913SDavid Gibson 18d5e54913SDavid Gibson #include "hvc_console.h" 19d5e54913SDavid Gibson 20*63bbdb4eSYu Kuai static struct hvc_struct *hvc_udbg_dev; 21d5e54913SDavid Gibson 22d5e54913SDavid Gibson static int hvc_udbg_put(uint32_t vtermno, const char *buf, int count) 23d5e54913SDavid Gibson { 24d5e54913SDavid Gibson int i; 25d5e54913SDavid Gibson 267d3d897aSBenjamin Herrenschmidt for (i = 0; i < count && udbg_putc; i++) 27d5e54913SDavid Gibson udbg_putc(buf[i]); 28d5e54913SDavid Gibson 29d5e54913SDavid Gibson return i; 30d5e54913SDavid Gibson } 31d5e54913SDavid Gibson 32d5e54913SDavid Gibson static int hvc_udbg_get(uint32_t vtermno, char *buf, int count) 33d5e54913SDavid Gibson { 34d5e54913SDavid Gibson int i, c; 35d5e54913SDavid Gibson 36d5e54913SDavid Gibson if (!udbg_getc_poll) 37d5e54913SDavid Gibson return 0; 38d5e54913SDavid Gibson 39d5e54913SDavid Gibson for (i = 0; i < count; i++) { 40d5e54913SDavid Gibson if ((c = udbg_getc_poll()) == -1) 41d5e54913SDavid Gibson break; 42d5e54913SDavid Gibson buf[i] = c; 43d5e54913SDavid Gibson } 44d5e54913SDavid Gibson 45d5e54913SDavid Gibson return i; 46d5e54913SDavid Gibson } 47d5e54913SDavid Gibson 481dff3996SRusty Russell static const struct hv_ops hvc_udbg_ops = { 49d5e54913SDavid Gibson .get_chars = hvc_udbg_get, 50d5e54913SDavid Gibson .put_chars = hvc_udbg_put, 51d5e54913SDavid Gibson }; 52d5e54913SDavid Gibson 53d5e54913SDavid Gibson static int __init hvc_udbg_init(void) 54d5e54913SDavid Gibson { 55d5e54913SDavid Gibson struct hvc_struct *hp; 56d5e54913SDavid Gibson 577d3d897aSBenjamin Herrenschmidt if (!udbg_putc) 587d3d897aSBenjamin Herrenschmidt return -ENODEV; 597d3d897aSBenjamin Herrenschmidt 60d5e54913SDavid Gibson BUG_ON(hvc_udbg_dev); 61d5e54913SDavid Gibson 62d4e33facSAlan Cox hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16); 63d5e54913SDavid Gibson if (IS_ERR(hp)) 64d5e54913SDavid Gibson return PTR_ERR(hp); 65d5e54913SDavid Gibson 66d5e54913SDavid Gibson hvc_udbg_dev = hp; 67d5e54913SDavid Gibson 68d5e54913SDavid Gibson return 0; 69d5e54913SDavid Gibson } 704fedd0bfSPaul Gortmaker device_initcall(hvc_udbg_init); 71d5e54913SDavid Gibson 72d5e54913SDavid Gibson static int __init hvc_udbg_console_init(void) 73d5e54913SDavid Gibson { 747d3d897aSBenjamin Herrenschmidt if (!udbg_putc) 757d3d897aSBenjamin Herrenschmidt return -ENODEV; 767d3d897aSBenjamin Herrenschmidt 77d5e54913SDavid Gibson hvc_instantiate(0, 0, &hvc_udbg_ops); 78d5e54913SDavid Gibson add_preferred_console("hvc", 0, NULL); 79d5e54913SDavid Gibson 80d5e54913SDavid Gibson return 0; 81d5e54913SDavid Gibson } 82d5e54913SDavid Gibson console_initcall(hvc_udbg_console_init); 83