diff options
Diffstat (limited to 'drivers/tty/serial/mpc52xx_uart.c')
| -rw-r--r-- | drivers/tty/serial/mpc52xx_uart.c | 164 |
1 files changed, 58 insertions, 106 deletions
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 3970d6a9aaca..37eb701b0b46 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs. * @@ -23,10 +24,6 @@ * Grant Likely <grant.likely@secretlab.ca> * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com> * Copyright (C) 2003 MontaVista, Software, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. */ #undef DEBUG @@ -41,16 +38,14 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/of.h> -#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> #include <linux/clk.h> #include <asm/mpc52xx.h> #include <asm/mpc52xx_psc.h> -#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - #include <linux/serial_core.h> @@ -90,11 +85,11 @@ static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port); struct psc_ops { void (*fifo_init)(struct uart_port *port); - int (*raw_rx_rdy)(struct uart_port *port); - int (*raw_tx_rdy)(struct uart_port *port); - int (*rx_rdy)(struct uart_port *port); - int (*tx_rdy)(struct uart_port *port); - int (*tx_empty)(struct uart_port *port); + unsigned int (*raw_rx_rdy)(struct uart_port *port); + unsigned int (*raw_tx_rdy)(struct uart_port *port); + unsigned int (*rx_rdy)(struct uart_port *port); + unsigned int (*tx_rdy)(struct uart_port *port); + unsigned int (*tx_empty)(struct uart_port *port); void (*stop_rx)(struct uart_port *port); void (*start_tx)(struct uart_port *port); void (*stop_tx)(struct uart_port *port); @@ -106,7 +101,7 @@ struct psc_ops { void (*cw_restore_ints)(struct uart_port *port); unsigned int (*set_baudrate)(struct uart_port *port, struct ktermios *new, - struct ktermios *old); + const struct ktermios *old); int (*clock_alloc)(struct uart_port *port); void (*clock_relse)(struct uart_port *port); int (*clock)(struct uart_port *port, int enable); @@ -210,34 +205,34 @@ static void mpc52xx_psc_fifo_init(struct uart_port *port) out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); } -static int mpc52xx_psc_raw_rx_rdy(struct uart_port *port) +static unsigned int mpc52xx_psc_raw_rx_rdy(struct uart_port *port) { return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; } -static int mpc52xx_psc_raw_tx_rdy(struct uart_port *port) +static unsigned int mpc52xx_psc_raw_tx_rdy(struct uart_port *port) { return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXRDY; } -static int mpc52xx_psc_rx_rdy(struct uart_port *port) +static unsigned int mpc52xx_psc_rx_rdy(struct uart_port *port) { return in_be16(&PSC(port)->mpc52xx_psc_isr) & port->read_status_mask & MPC52xx_PSC_IMR_RXRDY; } -static int mpc52xx_psc_tx_rdy(struct uart_port *port) +static unsigned int mpc52xx_psc_tx_rdy(struct uart_port *port) { return in_be16(&PSC(port)->mpc52xx_psc_isr) & port->read_status_mask & MPC52xx_PSC_IMR_TXRDY; } -static int mpc52xx_psc_tx_empty(struct uart_port *port) +static unsigned int mpc52xx_psc_tx_empty(struct uart_port *port) { u16 sts = in_be16(&PSC(port)->mpc52xx_psc_status); @@ -292,7 +287,7 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port, struct ktermios *new, - struct ktermios *old) + const struct ktermios *old) { unsigned int baud; unsigned int divisor; @@ -310,7 +305,7 @@ static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port, static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, struct ktermios *new, - struct ktermios *old) + const struct ktermios *old) { unsigned int baud; unsigned int divisor; @@ -443,31 +438,31 @@ static void mpc512x_psc_fifo_init(struct uart_port *port) out_be32(&FIFO_512x(port)->rximr, MPC512x_PSC_FIFO_ALARM); } -static int mpc512x_psc_raw_rx_rdy(struct uart_port *port) +static unsigned int mpc512x_psc_raw_rx_rdy(struct uart_port *port) { return !(in_be32(&FIFO_512x(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY); } -static int mpc512x_psc_raw_tx_rdy(struct uart_port *port) +static unsigned int mpc512x_psc_raw_tx_rdy(struct uart_port *port) { return !(in_be32(&FIFO_512x(port)->txsr) & MPC512x_PSC_FIFO_FULL); } -static int mpc512x_psc_rx_rdy(struct uart_port *port) +static unsigned int mpc512x_psc_rx_rdy(struct uart_port *port) { return in_be32(&FIFO_512x(port)->rxsr) & in_be32(&FIFO_512x(port)->rximr) & MPC512x_PSC_FIFO_ALARM; } -static int mpc512x_psc_tx_rdy(struct uart_port *port) +static unsigned int mpc512x_psc_tx_rdy(struct uart_port *port) { return in_be32(&FIFO_512x(port)->txsr) & in_be32(&FIFO_512x(port)->tximr) & MPC512x_PSC_FIFO_ALARM; } -static int mpc512x_psc_tx_empty(struct uart_port *port) +static unsigned int mpc512x_psc_tx_empty(struct uart_port *port) { return in_be32(&FIFO_512x(port)->txsr) & MPC512x_PSC_FIFO_EMPTY; @@ -538,7 +533,7 @@ static void mpc512x_psc_cw_restore_ints(struct uart_port *port) static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port, struct ktermios *new, - struct ktermios *old) + const struct ktermios *old) { unsigned int baud; unsigned int divisor; @@ -761,9 +756,6 @@ static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np) port->irqflags = IRQF_SHARED; port->irq = psc_fifoc_irq; } -#endif - -#ifdef CONFIG_PPC_MPC512x #define PSC_5125(port) ((struct mpc5125_psc __iomem *)((port)->membase)) #define FIFO_5125(port) ((struct mpc512x_psc_fifo __iomem *)(PSC_5125(port)+1)) @@ -787,29 +779,29 @@ static void mpc5125_psc_fifo_init(struct uart_port *port) out_be32(&FIFO_5125(port)->rximr, MPC512x_PSC_FIFO_ALARM); } -static int mpc5125_psc_raw_rx_rdy(struct uart_port *port) +static unsigned int mpc5125_psc_raw_rx_rdy(struct uart_port *port) { return !(in_be32(&FIFO_5125(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY); } -static int mpc5125_psc_raw_tx_rdy(struct uart_port *port) +static unsigned int mpc5125_psc_raw_tx_rdy(struct uart_port *port) { return !(in_be32(&FIFO_5125(port)->txsr) & MPC512x_PSC_FIFO_FULL); } -static int mpc5125_psc_rx_rdy(struct uart_port *port) +static unsigned int mpc5125_psc_rx_rdy(struct uart_port *port) { return in_be32(&FIFO_5125(port)->rxsr) & in_be32(&FIFO_5125(port)->rximr) & MPC512x_PSC_FIFO_ALARM; } -static int mpc5125_psc_tx_rdy(struct uart_port *port) +static unsigned int mpc5125_psc_tx_rdy(struct uart_port *port) { return in_be32(&FIFO_5125(port)->txsr) & in_be32(&FIFO_5125(port)->tximr) & MPC512x_PSC_FIFO_ALARM; } -static int mpc5125_psc_tx_empty(struct uart_port *port) +static unsigned int mpc5125_psc_tx_empty(struct uart_port *port) { return in_be32(&FIFO_5125(port)->txsr) & MPC512x_PSC_FIFO_EMPTY; } @@ -888,7 +880,7 @@ static inline void mpc5125_set_divisor(struct mpc5125_psc __iomem *psc, static unsigned int mpc5125_psc_set_baudrate(struct uart_port *port, struct ktermios *new, - struct ktermios *old) + const struct ktermios *old) { unsigned int baud; unsigned int divisor; @@ -1104,14 +1096,14 @@ static void mpc52xx_uart_break_ctl(struct uart_port *port, int ctl) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (ctl == -1) psc_ops->command(port, MPC52xx_PSC_START_BRK); else psc_ops->command(port, MPC52xx_PSC_STOP_BRK); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int @@ -1175,7 +1167,7 @@ mpc52xx_uart_shutdown(struct uart_port *port) static void mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, - struct ktermios *old) + const struct ktermios *old) { unsigned long flags; unsigned char mr1, mr2; @@ -1222,7 +1214,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, } /* Get the lock */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Do our best to flush TX & RX, so we don't lose anything */ /* But we don't wait indefinitely ! */ @@ -1258,7 +1250,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, psc_ops->command(port, MPC52xx_PSC_RX_ENABLE); /* We're all set, release the lock */ - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static const char * @@ -1347,7 +1339,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) } -static struct uart_ops mpc52xx_uart_ops = { +static const struct uart_ops mpc52xx_uart_ops = { .tx_empty = mpc52xx_uart_tx_empty, .set_mctrl = mpc52xx_uart_set_mctrl, .get_mctrl = mpc52xx_uart_get_mctrl, @@ -1359,7 +1351,6 @@ static struct uart_ops mpc52xx_uart_ops = { .startup = mpc52xx_uart_startup, .shutdown = mpc52xx_uart_shutdown, .set_termios = mpc52xx_uart_set_termios, -/* .pm = mpc52xx_uart_pm, Not supported yet */ .type = mpc52xx_uart_type, .release_port = mpc52xx_uart_release_port, .request_port = mpc52xx_uart_request_port, @@ -1372,7 +1363,7 @@ static struct uart_ops mpc52xx_uart_ops = { /* Interrupt handling */ /* ======================================================================== */ -static inline int +static inline bool mpc52xx_uart_int_rx_chars(struct uart_port *port) { struct tty_port *tport = &port->state->port; @@ -1385,12 +1376,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) ch = psc_ops->read_char(port); /* Handle sysreq char */ -#ifdef SUPPORT_SYSRQ - if (uart_handle_sysrq_char(port, ch)) { - port->sysrq = 0; + if (uart_handle_sysrq_char(port, ch)) continue; - } -#endif /* Store it */ @@ -1432,65 +1419,32 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) } } - spin_unlock(&port->lock); tty_flip_buffer_push(tport); - spin_lock(&port->lock); return psc_ops->raw_rx_rdy(port); } -static inline int +static inline bool mpc52xx_uart_int_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - - /* Process out of band chars */ - if (port->x_char) { - psc_ops->write_char(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - return 1; - } + u8 ch; - /* Nothing to do ? */ - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mpc52xx_uart_stop_tx(port); - return 0; - } - - /* Send chars */ - while (psc_ops->raw_tx_rdy(port)) { - psc_ops->write_char(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - /* Wake up */ - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - /* Maybe we're done after all */ - if (uart_circ_empty(xmit)) { - mpc52xx_uart_stop_tx(port); - return 0; - } - - return 1; + return uart_port_tx(port, ch, + psc_ops->raw_tx_rdy(port), + psc_ops->write_char(port, ch)); } static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port) { unsigned long pass = ISR_PASS_LIMIT; - unsigned int keepgoing; + bool keepgoing; u8 status; /* While we have stuff to do, we continue */ do { /* If we don't find anything to do, we stop */ - keepgoing = 0; + keepgoing = false; psc_ops->rx_clr_irq(port); if (psc_ops->rx_rdy(port)) @@ -1509,7 +1463,7 @@ mpc5xxx_uart_process_int(struct uart_port *port) /* Limit number of iteration */ if (!(--pass)) - keepgoing = 0; + keepgoing = false; } while (keepgoing); @@ -1522,11 +1476,11 @@ mpc52xx_uart_int(int irq, void *dev_id) struct uart_port *port = dev_id; irqreturn_t ret; - spin_lock(&port->lock); + uart_port_lock(port); ret = psc_ops->handle_irq(port); - spin_unlock(&port->lock); + uart_port_unlock(port); return ret; } @@ -1634,8 +1588,8 @@ mpc52xx_console_setup(struct console *co, char *options) return -EINVAL; } - pr_debug("Console on ttyPSC%x is %s\n", - co->index, mpc52xx_uart_nodes[co->index]->full_name); + pr_debug("Console on ttyPSC%x is %pOF\n", + co->index, mpc52xx_uart_nodes[co->index]); /* Fetch register locations */ ret = of_address_to_resource(np, 0, &res); @@ -1644,7 +1598,7 @@ mpc52xx_console_setup(struct console *co, char *options) return ret; } - uartclk = mpc5xxx_get_bus_frequency(np); + uartclk = mpc5xxx_fwnode_get_bus_frequency(of_fwnode_handle(np)); if (uartclk == 0) { pr_debug("Could not find uart clock frequency!\n"); return -EINVAL; @@ -1666,7 +1620,7 @@ mpc52xx_console_setup(struct console *co, char *options) (void *)port->mapbase, port->membase, port->irq, port->uartclk); - /* Setup the port parameters accoding to options */ + /* Setup the port parameters according to options */ if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else @@ -1755,13 +1709,13 @@ static int mpc52xx_uart_of_probe(struct platform_device *op) break; if (idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; - pr_debug("Found %s assigned to ttyPSC%x\n", - mpc52xx_uart_nodes[idx]->full_name, idx); + pr_debug("Found %pOF assigned to ttyPSC%x\n", + mpc52xx_uart_nodes[idx], idx); /* set the uart clock to the input clock of the psc, the different * prescalers are taken into account in the set_baudrate() methods * of the respective chip */ - uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node); + uartclk = mpc5xxx_get_bus_frequency(&op->dev); if (uartclk == 0) { dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); return -EINVAL; @@ -1773,6 +1727,7 @@ static int mpc52xx_uart_of_probe(struct platform_device *op) spin_lock_init(&port->lock); port->uartclk = uartclk; port->fifosize = 512; + port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MPC52xx_CONSOLE); port->iotype = UPIO_MEM; port->flags = UPF_BOOT_AUTOCONF | (uart_console(port) ? 0 : UPF_IOREMAP); @@ -1809,15 +1764,12 @@ static int mpc52xx_uart_of_probe(struct platform_device *op) return 0; } -static int -mpc52xx_uart_of_remove(struct platform_device *op) +static void mpc52xx_uart_of_remove(struct platform_device *op) { struct uart_port *port = platform_get_drvdata(op); if (port) uart_remove_one_port(&mpc52xx_uart_driver, port); - - return 0; } #ifdef CONFIG_PM @@ -1881,8 +1833,8 @@ mpc52xx_uart_of_enumerate(void) for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { if (mpc52xx_uart_nodes[i]) - pr_debug("%s assigned to ttyPSC%x\n", - mpc52xx_uart_nodes[i]->full_name, i); + pr_debug("%pOF assigned to ttyPSC%x\n", + mpc52xx_uart_nodes[i], i); } } |
