6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/errno.h>
13 #include <linux/serial.h>
17 #include <linux/slab.h>
22 #include <asm/hypervisor.h>
26 #include <asm/setup.h>
28 #if defined(CONFIG_MAGIC_SYSRQ)
32 #include <linux/serial_core.h>
35 #define CON_BREAK ((long)-1)
36 #define CON_HUP ((long)-2)
38 #define IGNORE_BREAK 0x1
39 #define IGNORE_ALL 0x2
41 static char *con_write_page;
42 static char *con_read_page;
44 static int hung_up = 0;
77 int saw_console_brk = 0;
88 if (uart_handle_break(port))
115 return saw_console_brk;
120 int saw_console_brk = 0;
123 while (limit-- > 0) {
124 unsigned long ra =
__pa(con_read_page);
125 unsigned long bytes_read,
i;
132 if (uart_handle_break(port))
152 for (i = 0; i < bytes_read; i++)
158 port->
icount.rx += bytes_read;
160 tty_insert_flip_string(tty, con_read_page, bytes_read);
163 return saw_console_brk;
172 .transmit_chars = transmit_chars_putchar,
173 .receive_chars = receive_chars_getchar,
177 .transmit_chars = transmit_chars_write,
178 .receive_chars = receive_chars_read,
188 tty = port->
state->port.tty;
196 static void transmit_chars(
struct uart_port *port)
203 xmit = &port->
state->xmit;
220 tty = receive_chars(port);
221 transmit_chars(port);
222 spin_unlock_irqrestore(&port->
lock, flags);
231 static unsigned int sunhv_tx_empty(
struct uart_port *port)
241 static void sunhv_set_mctrl(
struct uart_port *port,
unsigned int mctrl)
247 static unsigned int sunhv_get_mctrl(
struct uart_port *port)
253 static void sunhv_stop_tx(
struct uart_port *port)
259 static void sunhv_start_tx(
struct uart_port *port)
261 transmit_chars(port);
265 static void sunhv_send_xchar(
struct uart_port *port,
char ch)
272 while (limit-- > 0) {
279 spin_unlock_irqrestore(&port->
lock, flags);
283 static void sunhv_stop_rx(
struct uart_port *port)
288 static void sunhv_enable_ms(
struct uart_port *port)
293 static void sunhv_break_ctl(
struct uart_port *port,
int break_state)
301 while (limit-- > 0) {
308 spin_unlock_irqrestore(&port->
lock, flags);
313 static int sunhv_startup(
struct uart_port *port)
319 static void sunhv_shutdown(
struct uart_port *port)
329 unsigned int iflag,
cflag;
340 if ((cflag &
CREAD) == 0)
345 (port->
uartclk / (16 * quot)));
347 spin_unlock_irqrestore(&port->
lock, flags);
350 static const char *sunhv_type(
struct uart_port *port)
352 return "SUN4V HCONS";
355 static void sunhv_release_port(
struct uart_port *port)
359 static int sunhv_request_port(
struct uart_port *port)
364 static void sunhv_config_port(
struct uart_port *port,
int flags)
373 static struct uart_ops sunhv_pops = {
374 .tx_empty = sunhv_tx_empty,
375 .set_mctrl = sunhv_set_mctrl,
376 .get_mctrl = sunhv_get_mctrl,
377 .stop_tx = sunhv_stop_tx,
378 .start_tx = sunhv_start_tx,
379 .send_xchar = sunhv_send_xchar,
380 .stop_rx = sunhv_stop_rx,
381 .enable_ms = sunhv_enable_ms,
382 .break_ctl = sunhv_break_ctl,
383 .startup = sunhv_startup,
384 .shutdown = sunhv_shutdown,
385 .set_termios = sunhv_set_termios,
387 .release_port = sunhv_release_port,
388 .request_port = sunhv_request_port,
389 .config_port = sunhv_config_port,
390 .verify_port = sunhv_verify_port,
395 .driver_name =
"sunhv",
407 static int fill_con_write_page(
const char *
s,
unsigned int n,
408 unsigned long *page_bytes)
410 const char *orig_s =
s;
411 char *
p = con_write_page;
425 *page_bytes = p - con_write_page;
429 static void sunhv_console_write_paged(
struct console *
con,
const char *s,
unsigned n)
439 locked = spin_trylock(&port->
lock);
441 spin_lock(&port->
lock);
444 unsigned long ra =
__pa(con_write_page);
445 unsigned long page_bytes;
446 unsigned int cpy = fill_con_write_page(s, n,
451 while (page_bytes > 0) {
452 unsigned long written;
466 page_bytes -= written;
472 spin_unlock(&port->
lock);
476 static inline void sunhv_console_putchar(
struct uart_port *port,
char c)
480 while (limit-- > 0) {
488 static void sunhv_console_write_bychar(
struct console *con,
const char *s,
unsigned n)
498 locked = spin_trylock(&port->
lock);
500 spin_lock(&port->
lock);
502 for (i = 0; i <
n; i++) {
504 sunhv_console_putchar(port,
'\r');
505 sunhv_console_putchar(port, *s++);
509 spin_unlock(&port->
lock);
513 static struct console sunhv_console = {
515 .write = sunhv_console_write_bychar,
528 if (op->
archdata.irqs[0] == 0xffffffff)
545 goto out_free_con_write_page;
547 sunhv_console.
write = sunhv_console_write_paged;
548 sunhv_ops = &bywrite_ops;
554 port->
ops = &sunhv_pops;
556 port->
uartclk = ( 29491200 / 16 );
566 goto out_free_con_read_page;
569 &sunhv_reg, port->
line,
false);
573 goto out_unregister_driver;
577 goto out_remove_port;
586 out_unregister_driver:
589 out_free_con_read_page:
590 kfree(con_read_page);
592 out_free_con_write_page:
593 kfree(con_write_page);
626 .compatible =
"SUNW,sun4v-console",
636 .of_match_table = hv_match,
642 static int __init sunhv_init(
void)
650 static void __exit sunhv_exit(
void)