summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/st-asc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/st-asc.c')
-rw-r--r--drivers/tty/serial/st-asc.c85
1 files changed, 44 insertions, 41 deletions
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index aa471c9c24d9..6ed9a327702b 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -250,7 +250,7 @@ static void asc_receive_chars(struct uart_port *port)
struct tty_port *tport = &port->state->port;
unsigned long status, mode;
unsigned long c = 0;
- char flag;
+ u8 flag;
bool ignore_pe = false;
/*
@@ -319,7 +319,7 @@ static irqreturn_t asc_interrupt(int irq, void *ptr)
struct uart_port *port = ptr;
u32 status;
- spin_lock(&port->lock);
+ uart_port_lock(port);
status = asc_in(port, ASC_STA);
@@ -334,7 +334,7 @@ static irqreturn_t asc_interrupt(int irq, void *ptr)
asc_transmit_chars(port);
}
- spin_unlock(&port->lock);
+ uart_port_unlock(port);
return IRQ_HANDLED;
}
@@ -387,9 +387,9 @@ static unsigned int asc_get_mctrl(struct uart_port *port)
/* There are probably characters waiting to be transmitted. */
static void asc_start_tx(struct uart_port *port)
{
- struct circ_buf *xmit = &port->state->xmit;
+ struct tty_port *tport = &port->state->port;
- if (!uart_circ_empty(xmit))
+ if (!kfifo_is_empty(&tport->xmit_fifo))
asc_enable_tx_interrupts(port);
}
@@ -452,10 +452,10 @@ static void asc_pm(struct uart_port *port, unsigned int state,
* we can come to turning it off. Note this is not called with
* the port spinlock held.
*/
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN;
asc_out(port, ASC_CTL, ctl);
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
clk_disable_unprepare(ascport->clk);
break;
}
@@ -465,6 +465,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
const struct ktermios *old)
{
struct asc_port *ascport = to_asc_port(port);
+ bool manual_rts, toggle_rts = false;
struct gpio_desc *gpiod;
unsigned int baud;
u32 ctrl_val;
@@ -480,7 +481,7 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
cflag = termios->c_cflag;
- spin_lock_irqsave(&port->lock, flags);
+ uart_port_lock_irqsave(port, &flags);
/* read control register */
ctrl_val = asc_in(port, ASC_CTL);
@@ -518,25 +519,13 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
/* If flow-control selected, stop handling RTS manually */
if (ascport->rts) {
- devm_gpiod_put(port->dev, ascport->rts);
- ascport->rts = NULL;
-
- pinctrl_select_state(ascport->pinctrl,
- ascport->states[DEFAULT]);
+ toggle_rts = true;
+ manual_rts = false;
}
} else {
/* If flow-control disabled, it's safe to handle RTS manually */
- if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL]) {
- pinctrl_select_state(ascport->pinctrl,
- ascport->states[NO_HW_FLOWCTRL]);
-
- gpiod = devm_gpiod_get(port->dev, "rts", GPIOD_OUT_LOW);
- if (!IS_ERR(gpiod)) {
- gpiod_set_consumer_name(gpiod,
- port->dev->of_node->name);
- ascport->rts = gpiod;
- }
- }
+ if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL])
+ manual_rts = toggle_rts = true;
}
if ((baud < 19200) && !ascport->force_m1) {
@@ -594,7 +583,26 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
/* write final value and enable port */
asc_out(port, ASC_CTL, (ctrl_val | ASC_CTL_RUN));
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
+
+ if (toggle_rts) {
+ if (manual_rts) {
+ pinctrl_select_state(ascport->pinctrl,
+ ascport->states[NO_HW_FLOWCTRL]);
+
+ gpiod = devm_gpiod_get(port->dev, "rts", GPIOD_OUT_LOW);
+ if (!IS_ERR(gpiod)) {
+ gpiod_set_consumer_name(gpiod,
+ port->dev->of_node->name);
+ ascport->rts = gpiod;
+ }
+ } else {
+ devm_gpiod_put(port->dev, ascport->rts);
+ ascport->rts = NULL;
+ pinctrl_select_state(ascport->pinctrl,
+ ascport->states[DEFAULT]);
+ }
+ }
}
static const char *asc_type(struct uart_port *port)
@@ -691,8 +699,7 @@ static int asc_init_port(struct asc_port *ascport,
port->irq = platform_get_irq(pdev, 0);
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_ST_ASC_CONSOLE);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- port->membase = devm_ioremap_resource(&pdev->dev, res);
+ port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(port->membase))
return PTR_ERR(port->membase);
port->mapbase = res->start;
@@ -704,7 +711,9 @@ static int asc_init_port(struct asc_port *ascport,
if (WARN_ON(IS_ERR(ascport->clk)))
return -EINVAL;
/* ensure that clk rate is correct by enabling the clk */
- clk_prepare_enable(ascport->clk);
+ ret = clk_prepare_enable(ascport->clk);
+ if (ret)
+ return ret;
ascport->port.uartclk = clk_get_rate(ascport->clk);
WARN_ON(ascport->port.uartclk == 0);
clk_disable_unprepare(ascport->clk);
@@ -792,16 +801,13 @@ static int asc_serial_probe(struct platform_device *pdev)
return 0;
}
-static int asc_serial_remove(struct platform_device *pdev)
+static void asc_serial_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
uart_remove_one_port(&asc_uart_driver, port);
-
- return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int asc_serial_suspend(struct device *dev)
{
struct uart_port *port = dev_get_drvdata(dev);
@@ -816,8 +822,6 @@ static int asc_serial_resume(struct device *dev)
return uart_resume_port(&asc_uart_driver, port);
}
-#endif /* CONFIG_PM_SLEEP */
-
/*----------------------------------------------------------------------*/
#ifdef CONFIG_SERIAL_ST_ASC_CONSOLE
@@ -848,9 +852,9 @@ static void asc_console_write(struct console *co, const char *s, unsigned count)
if (port->sysrq)
locked = 0; /* asc_interrupt has already claimed the lock */
else if (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);
/*
* Disable interrupts so we don't get the IRQ line bouncing
@@ -868,7 +872,7 @@ static void asc_console_write(struct console *co, const char *s, unsigned count)
asc_out(port, ASC_INTEN, intenable);
if (locked)
- spin_unlock_irqrestore(&port->lock, flags);
+ uart_port_unlock_irqrestore(port, flags);
}
static int asc_console_setup(struct console *co, char *options)
@@ -925,16 +929,15 @@ static struct uart_driver asc_uart_driver = {
.cons = ASC_SERIAL_CONSOLE,
};
-static const struct dev_pm_ops asc_serial_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(asc_serial_suspend, asc_serial_resume)
-};
+static DEFINE_SIMPLE_DEV_PM_OPS(asc_serial_pm_ops, asc_serial_suspend,
+ asc_serial_resume);
static struct platform_driver asc_serial_driver = {
.probe = asc_serial_probe,
.remove = asc_serial_remove,
.driver = {
.name = DRIVER_NAME,
- .pm = &asc_serial_pm_ops,
+ .pm = pm_sleep_ptr(&asc_serial_pm_ops),
.of_match_table = of_match_ptr(asc_match),
},
};