summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/mpc52xx_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/mpc52xx_uart.c')
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c164
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);
}
}