diff options
Diffstat (limited to 'drivers/tty/serial/sunhv.c')
| -rw-r--r-- | drivers/tty/serial/sunhv.c | 95 |
1 files changed, 47 insertions, 48 deletions
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 46e46894e918..2b3ec65d595d 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* sunhv.c: Serial driver for SUN4V hypervisor console. * * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) @@ -16,18 +17,14 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/init.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <asm/hypervisor.h> #include <asm/spitfire.h> -#include <asm/prom.h> #include <asm/irq.h> #include <asm/setup.h> -#if defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - #include <linux/serial_core.h> #include <linux/sunserialcore.h> @@ -42,32 +39,35 @@ static char *con_read_page; static int hung_up = 0; -static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit) +static void transmit_chars_putchar(struct uart_port *port, + struct tty_port *tport) { - while (!uart_circ_empty(xmit)) { - long status = sun4v_con_putchar(xmit->buf[xmit->tail]); + unsigned char ch; + + while (kfifo_peek(&tport->xmit_fifo, &ch)) { + long status = sun4v_con_putchar(ch); if (status != HV_EOK) break; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; + uart_xmit_advance(port, 1); } } -static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit) +static void transmit_chars_write(struct uart_port *port, struct tty_port *tport) { - while (!uart_circ_empty(xmit)) { - unsigned long ra = __pa(xmit->buf + xmit->tail); - unsigned long len, status, sent; + while (!kfifo_is_empty(&tport->xmit_fifo)) { + unsigned long len, ra, status, sent; + unsigned char *tail; + + len = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, + UART_XMIT_SIZE); + ra = __pa(tail); - len = CIRC_CNT_TO_END(xmit->head, xmit->tail, - UART_XMIT_SIZE); status = sun4v_con_write(ra, len, &sent); if (status != HV_EOK) break; - xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1); - port->icount.tx += sent; + uart_xmit_advance(port, sent); } } @@ -92,10 +92,10 @@ static int receive_chars_getchar(struct uart_port *port) if (c == CON_HUP) { hung_up = 1; - uart_handle_dcd_change(port, 0); + uart_handle_dcd_change(port, false); } else if (hung_up) { hung_up = 0; - uart_handle_dcd_change(port, 1); + uart_handle_dcd_change(port, true); } if (port->state == NULL) { @@ -138,7 +138,7 @@ static int receive_chars_read(struct uart_port *port) bytes_read = 1; } else if (stat == CON_HUP) { hung_up = 1; - uart_handle_dcd_change(port, 0); + uart_handle_dcd_change(port, false); continue; } else { /* HV_EWOULDBLOCK, etc. */ @@ -148,7 +148,7 @@ static int receive_chars_read(struct uart_port *port) if (hung_up) { hung_up = 0; - uart_handle_dcd_change(port, 1); + uart_handle_dcd_change(port, true); } if (port->sysrq != 0 && *con_read_page) { @@ -170,7 +170,7 @@ static int receive_chars_read(struct uart_port *port) } struct sunhv_ops { - void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); + void (*transmit_chars)(struct uart_port *port, struct tty_port *tport); int (*receive_chars)(struct uart_port *port); }; @@ -201,18 +201,18 @@ static struct tty_port *receive_chars(struct uart_port *port) static void transmit_chars(struct uart_port *port) { - struct circ_buf *xmit; + struct tty_port *tport; if (!port->state) return; - xmit = &port->state->xmit; - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) + tport = &port->state->port; + if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) return; - sunhv_ops->transmit_chars(port, xmit); + sunhv_ops->transmit_chars(port, tport); - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) uart_write_wakeup(port); } @@ -222,10 +222,10 @@ static irqreturn_t sunhv_interrupt(int irq, void *dev_id) struct tty_port *tport; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); tport = receive_chars(port); transmit_chars(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); if (tport) tty_flip_buffer_push(tport); @@ -276,7 +276,7 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) if (ch == __DISABLED_CHAR) return; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (limit-- > 0) { long status = sun4v_con_putchar(ch); @@ -285,7 +285,7 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) udelay(1); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } /* port->lock held by caller. */ @@ -300,7 +300,7 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) unsigned long flags; int limit = 10000; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (limit-- > 0) { long status = sun4v_con_putchar(CON_BREAK); @@ -309,7 +309,7 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) udelay(1); } - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } } @@ -326,14 +326,14 @@ static void sunhv_shutdown(struct uart_port *port) /* port->lock is not held. */ static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) + const struct ktermios *old) { unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); unsigned int quot = uart_get_divisor(port, baud); unsigned int iflag, cflag; unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); iflag = termios->c_iflag; cflag = termios->c_cflag; @@ -348,7 +348,7 @@ static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, cflag, (port->uartclk / (16 * quot))); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *sunhv_type(struct uart_port *port) @@ -396,7 +396,7 @@ static const struct uart_ops sunhv_pops = { static struct uart_driver sunhv_reg = { .owner = THIS_MODULE, .driver_name = "sunhv", - .dev_name = "ttyS", + .dev_name = "ttyHV", .major = TTY_MAJOR, }; @@ -442,9 +442,9 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign int locked = 1; if (port->sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); while (n > 0) { unsigned long ra = __pa(con_write_page); @@ -475,7 +475,7 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static inline void sunhv_console_putchar(struct uart_port *port, char c) @@ -497,9 +497,9 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig int i, locked = 1; if (port->sysrq || oops_in_progress) - locked = spin_trylock_irqsave(&port->lock, flags); + locked = uart_port_trylock_irqsave(port, &flags); else - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); for (i = 0; i < n; i++) { if (*s == '\n') @@ -508,7 +508,7 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig } if (locked) - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static struct console sunhv_console = { @@ -551,6 +551,7 @@ static int hv_probe(struct platform_device *op) sunhv_port = port; + port->has_sysrq = 1; port->line = 0; port->ops = &sunhv_pops; port->type = PORT_SUNHV; @@ -599,7 +600,7 @@ out_free_port: return err; } -static int hv_remove(struct platform_device *dev) +static void hv_remove(struct platform_device *dev) { struct uart_port *port = platform_get_drvdata(dev); @@ -612,8 +613,6 @@ static int hv_remove(struct platform_device *dev) kfree(con_write_page); kfree(port); sunhv_port = NULL; - - return 0; } static const struct of_device_id hv_match[] = { |
