diff options
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r-- | drivers/tty/serial/8250/8250.h | 5 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 93 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 181 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_platform.c | 87 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_port.c | 298 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_rsa.c | 7 |
6 files changed, 309 insertions, 362 deletions
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index cfe6ba286b45..58e64c4e1e3a 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -186,6 +186,11 @@ static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up, void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p); +void serial8250_rpm_get(struct uart_8250_port *p); +void serial8250_rpm_put(struct uart_8250_port *p); +DEFINE_GUARD(serial8250_rpm, struct uart_8250_port *, + serial8250_rpm_get(_T), serial8250_rpm_put(_T)); + static inline u32 serial_dl_read(struct uart_8250_port *up) { return up->dl_read(up); diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index feb920c5b2e8..bfa421ab3253 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -72,7 +72,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) struct list_head *l, *end = NULL; int pass_counter = 0, handled = 0; - spin_lock(&i->lock); + guard(spinlock)(&i->lock); l = i->head; do { @@ -91,8 +91,6 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) break; } while (l != end); - spin_unlock(&i->lock); - return IRQ_RETVAL(handled); } @@ -132,22 +130,19 @@ static struct irq_info *serial_get_or_create_irq_info(const struct uart_8250_por { struct irq_info *i; - mutex_lock(&hash_mutex); + guard(mutex)(&hash_mutex); hash_for_each_possible(irq_lists, i, node, up->port.irq) if (i->irq == up->port.irq) - goto unlock; + return i; i = kzalloc(sizeof(*i), GFP_KERNEL); - if (i == NULL) { - i = ERR_PTR(-ENOMEM); - goto unlock; - } + if (i == NULL) + return ERR_PTR(-ENOMEM); + spin_lock_init(&i->lock); i->irq = up->port.irq; hash_add(irq_lists, &i->node, i->irq); -unlock: - mutex_unlock(&hash_mutex); return i; } @@ -161,23 +156,21 @@ static int serial_link_irq_chain(struct uart_8250_port *up) if (IS_ERR(i)) return PTR_ERR(i); - spin_lock_irq(&i->lock); + scoped_guard(spinlock_irq, &i->lock) { + if (i->head) { + list_add(&up->list, i->head); - if (i->head) { - list_add(&up->list, i->head); - spin_unlock_irq(&i->lock); + return 0; + } - ret = 0; - } else { INIT_LIST_HEAD(&up->list); i->head = &up->list; - spin_unlock_irq(&i->lock); - ret = request_irq(up->port.irq, serial8250_interrupt, - up->port.irqflags, up->port.name, i); - if (ret < 0) - serial_do_unlink(i, up); } + ret = request_irq(up->port.irq, serial8250_interrupt, up->port.irqflags, up->port.name, i); + if (ret < 0) + serial_do_unlink(i, up); + return ret; } @@ -185,20 +178,22 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) { struct irq_info *i; - mutex_lock(&hash_mutex); + guard(mutex)(&hash_mutex); hash_for_each_possible(irq_lists, i, node, up->port.irq) - if (i->irq == up->port.irq) - break; + if (i->irq == up->port.irq) { + if (WARN_ON(i->head == NULL)) + return; - BUG_ON(i == NULL); - BUG_ON(i->head == NULL); + if (list_empty(i->head)) + free_irq(up->port.irq, i); - if (list_empty(i->head)) - free_irq(up->port.irq, i); + serial_do_unlink(i, up); + + return; + } - serial_do_unlink(i, up); - mutex_unlock(&hash_mutex); + WARN_ON(1); } /* @@ -307,7 +302,7 @@ static void univ8250_release_irq(struct uart_8250_port *up) serial_unlink_irq_chain(up); } -const struct uart_ops *univ8250_port_base_ops = NULL; +const struct uart_ops *univ8250_port_base_ops; struct uart_ops univ8250_port_ops; static const struct uart_8250_ops univ8250_driver_ops = { @@ -670,16 +665,12 @@ static struct uart_8250_port *serial8250_find_match_or_unused(const struct uart_ static void serial_8250_overrun_backoff_work(struct work_struct *work) { - struct uart_8250_port *up = - container_of(to_delayed_work(work), struct uart_8250_port, - overrun_backoff); - struct uart_port *port = &up->port; - unsigned long flags; + struct uart_8250_port *up = container_of(to_delayed_work(work), struct uart_8250_port, + overrun_backoff); - uart_port_lock_irqsave(port, &flags); + guard(uart_port_lock_irqsave)(&up->port); up->ier |= UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); - uart_port_unlock_irqrestore(port, flags); } /** @@ -698,12 +689,12 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work) int serial8250_register_8250_port(const struct uart_8250_port *up) { struct uart_8250_port *uart; - int ret = -ENOSPC; + int ret; if (up->port.uartclk == 0) return -EINVAL; - mutex_lock(&serial_mutex); + guard(mutex)(&serial_mutex); uart = serial8250_find_match_or_unused(&up->port); if (!uart) { @@ -713,15 +704,13 @@ int serial8250_register_8250_port(const struct uart_8250_port *up) */ uart = serial8250_setup_port(nr_uarts); if (!uart) - goto unlock; + return -ENOSPC; nr_uarts++; } /* Check if it is CIR already. We check this below again, see there why. */ - if (uart->port.type == PORT_8250_CIR) { - ret = -ENODEV; - goto unlock; - } + if (uart->port.type == PORT_8250_CIR) + return -ENODEV; if (uart->port.dev) uart_remove_one_port(&serial8250_reg, &uart->port); @@ -855,14 +844,10 @@ int serial8250_register_8250_port(const struct uart_8250_port *up) uart->overrun_backoff_time_ms = 0; } -unlock: - mutex_unlock(&serial_mutex); - return ret; err: uart->port.dev = NULL; - mutex_unlock(&serial_mutex); return ret; } EXPORT_SYMBOL(serial8250_register_8250_port); @@ -878,14 +863,11 @@ void serial8250_unregister_port(int line) { struct uart_8250_port *uart = &serial8250_ports[line]; - mutex_lock(&serial_mutex); + guard(mutex)(&serial_mutex); if (uart->em485) { - unsigned long flags; - - uart_port_lock_irqsave(&uart->port, &flags); + guard(uart_port_lock_irqsave)(&uart->port); serial8250_em485_destroy(uart); - uart_port_unlock_irqrestore(&uart->port, flags); } uart_remove_one_port(&serial8250_reg, &uart->port); @@ -901,7 +883,6 @@ void serial8250_unregister_port(int line) } else { uart->port.dev = NULL; } - mutex_unlock(&serial_mutex); } EXPORT_SYMBOL(serial8250_unregister_port); diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 6707f55bdbe7..9e49ef48b851 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -27,6 +27,8 @@ #include <linux/pm_wakeirq.h> #include <linux/dma-mapping.h> #include <linux/sys_soc.h> +#include <linux/reboot.h> +#include <linux/pinctrl/consumer.h> #include "8250.h" @@ -145,6 +147,9 @@ struct omap8250_priv { spinlock_t rx_dma_lock; bool rx_dma_broken; bool throttled; + + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_wakeup; }; struct omap8250_dma_params { @@ -369,18 +374,12 @@ static void omap8250_restore_regs(struct uart_8250_port *up) serial8250_em485_stop_tx(up, true); } -/* - * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have - * some differences in how we want to handle flow control. - */ -static void omap_8250_set_termios(struct uart_port *port, - struct ktermios *termios, - const struct ktermios *old) +static void omap_8250_set_termios_atomic(struct uart_port *port, struct ktermios *termios, + const struct ktermios *old, unsigned int baud) { struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = port->private_data; - unsigned char cval = 0; - unsigned int baud; + u8 cval; cval = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag)); @@ -393,20 +392,14 @@ static void omap_8250_set_termios(struct uart_port *port, if (termios->c_cflag & CMSPAR) cval |= UART_LCR_SPAR; - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, - port->uartclk / 16 / UART_DIV_MAX, - port->uartclk / 13); omap_8250_get_divisor(port, baud, priv); /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - pm_runtime_get_sync(port->dev); - uart_port_lock_irq(port); + guard(serial8250_rpm)(up); + guard(uart_port_lock_irq)(port); /* * Update the per-port timeout. @@ -514,10 +507,27 @@ static void omap_8250_set_termios(struct uart_port *port, } } omap8250_restore_regs(up); +} - uart_port_unlock_irq(&up->port); - pm_runtime_mark_last_busy(port->dev); - pm_runtime_put_autosuspend(port->dev); +/* + * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have + * some differences in how we want to handle flow control. + */ +static void omap_8250_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ + struct omap8250_priv *priv = port->private_data; + unsigned int baud; + + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, + port->uartclk / 16 / UART_DIV_MAX, + port->uartclk / 13); + + omap_8250_set_termios_atomic(port, termios, old, baud); /* calculate wakeup latency constraint */ priv->calc_latency = USEC_PER_SEC * 64 * 8 / baud; @@ -537,10 +547,9 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, struct uart_8250_port *up = up_to_u8250p(port); u8 efr; - pm_runtime_get_sync(port->dev); - + guard(serial8250_rpm)(up); /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(port); + guard(uart_port_lock_irq)(port); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); efr = serial_in(up, UART_EFR); @@ -551,11 +560,6 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); - - uart_port_unlock_irq(port); - - pm_runtime_mark_last_busy(port->dev); - pm_runtime_put_autosuspend(port->dev); } static void omap_serial_fill_features_erratas(struct uart_8250_port *up, @@ -727,7 +731,11 @@ static int omap_8250_startup(struct uart_port *port) return ret; } - pm_runtime_get_sync(port->dev); +#ifdef CONFIG_PM + up->capabilities |= UART_CAP_RPM; +#endif + + guard(serial8250_rpm)(up); serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); @@ -750,14 +758,10 @@ static int omap_8250_startup(struct uart_port *port) } /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(port); - up->ier = UART_IER_RLSI | UART_IER_RDI; - serial_out(up, UART_IER, up->ier); - uart_port_unlock_irq(port); - -#ifdef CONFIG_PM - up->capabilities |= UART_CAP_RPM; -#endif + scoped_guard(uart_port_lock_irq, port) { + up->ier = UART_IER_RLSI | UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + } /* Enable module level wake up */ priv->wer = OMAP_UART_WER_MOD_WKUP; @@ -766,15 +770,12 @@ static int omap_8250_startup(struct uart_port *port) serial_out(up, UART_OMAP_WER, priv->wer); if (up->dma && !(priv->habit & UART_HAS_EFR2)) { - uart_port_lock_irq(port); + guard(uart_port_lock_irq)(port); up->dma->rx_dma(up); - uart_port_unlock_irq(port); } enable_irq(port->irq); - pm_runtime_mark_last_busy(port->dev); - pm_runtime_put_autosuspend(port->dev); return 0; } @@ -783,7 +784,7 @@ static void omap_8250_shutdown(struct uart_port *port) struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = port->private_data; - pm_runtime_get_sync(port->dev); + guard(serial8250_rpm)(up); flush_work(&priv->qos_work); if (up->dma) @@ -794,10 +795,11 @@ static void omap_8250_shutdown(struct uart_port *port) serial_out(up, UART_OMAP_EFR2, 0x0); /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(port); - up->ier = 0; - serial_out(up, UART_IER, 0); - uart_port_unlock_irq(port); + scoped_guard(uart_port_lock_irq, port) { + up->ier = 0; + serial_out(up, UART_IER, 0); + } + disable_irq_nosync(port->irq); dev_pm_clear_wake_irq(port->dev); @@ -810,46 +812,33 @@ static void omap_8250_shutdown(struct uart_port *port) if (up->lcr & UART_LCR_SBC) serial_out(up, UART_LCR, up->lcr & ~UART_LCR_SBC); serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - - pm_runtime_mark_last_busy(port->dev); - pm_runtime_put_autosuspend(port->dev); } static void omap_8250_throttle(struct uart_port *port) { struct omap8250_priv *priv = port->private_data; - unsigned long flags; - pm_runtime_get_sync(port->dev); + guard(serial8250_rpm)(up_to_u8250p(port)); + guard(uart_port_lock_irqsave)(port); - uart_port_lock_irqsave(port, &flags); port->ops->stop_rx(port); priv->throttled = true; - uart_port_unlock_irqrestore(port, flags); - - pm_runtime_mark_last_busy(port->dev); - pm_runtime_put_autosuspend(port->dev); } static void omap_8250_unthrottle(struct uart_port *port) { struct omap8250_priv *priv = port->private_data; struct uart_8250_port *up = up_to_u8250p(port); - unsigned long flags; - - pm_runtime_get_sync(port->dev); + guard(serial8250_rpm)(up); /* Synchronize UART_IER access against the console. */ - uart_port_lock_irqsave(port, &flags); + guard(uart_port_lock_irqsave)(port); + priv->throttled = false; if (up->dma) up->dma->rx_dma(up); up->ier |= UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); - uart_port_unlock_irqrestore(port, flags); - - pm_runtime_mark_last_busy(port->dev); - pm_runtime_put_autosuspend(port->dev); } static int omap8250_rs485_config(struct uart_port *port, @@ -987,30 +976,26 @@ static void __dma_rx_complete(void *param) struct omap8250_priv *priv = p->port.private_data; struct uart_8250_dma *dma = p->dma; struct dma_tx_state state; - unsigned long flags; /* Synchronize UART_IER access against the console. */ - uart_port_lock_irqsave(&p->port, &flags); + guard(uart_port_lock_irqsave)(&p->port); /* * If the tx status is not DMA_COMPLETE, then this is a delayed * completion callback. A previous RX timeout flush would have * already pushed the data, so exit. */ - if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) != - DMA_COMPLETE) { - uart_port_unlock_irqrestore(&p->port, flags); + if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) != DMA_COMPLETE) return; - } + __dma_rx_do_complete(p); - if (!priv->throttled) { - p->ier |= UART_IER_RLSI | UART_IER_RDI; - serial_out(p, UART_IER, p->ier); - if (!(priv->habit & UART_HAS_EFR2)) - omap_8250_rx_dma(p); - } + if (priv->throttled) + return; - uart_port_unlock_irqrestore(&p->port, flags); + p->ier |= UART_IER_RLSI | UART_IER_RDI; + serial_out(p, UART_IER, p->ier); + if (!(priv->habit & UART_HAS_EFR2)) + omap_8250_rx_dma(p); } static void omap_8250_rx_dma_flush(struct uart_8250_port *p) @@ -1108,14 +1093,13 @@ static void omap_8250_dma_tx_complete(void *param) struct uart_8250_port *p = param; struct uart_8250_dma *dma = p->dma; struct tty_port *tport = &p->port.state->port; - unsigned long flags; bool en_thri = false; struct omap8250_priv *priv = p->port.private_data; dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); - uart_port_lock_irqsave(&p->port, &flags); + guard(uart_port_lock_irqsave)(&p->port); dma->tx_running = 0; @@ -1143,8 +1127,6 @@ static void omap_8250_dma_tx_complete(void *param) dma->tx_err = 1; serial8250_set_THRI(p); } - - uart_port_unlock_irqrestore(&p->port, flags); } static int omap_8250_tx_dma(struct uart_8250_port *p) @@ -1372,6 +1354,18 @@ static int omap8250_no_handle_irq(struct uart_port *port) return 0; } +static int omap8250_select_wakeup_pinctrl(struct device *dev, + struct omap8250_priv *priv) +{ + if (IS_ERR_OR_NULL(priv->pinctrl_wakeup)) + return 0; + + if (!device_may_wakeup(dev)) + return 0; + + return pinctrl_select_state(priv->pinctrl, priv->pinctrl_wakeup); +} + static struct omap8250_dma_params am654_dma = { .rx_size = SZ_2K, .rx_trigger = 1, @@ -1596,6 +1590,11 @@ static int omap8250_probe(struct platform_device *pdev) priv->line = ret; pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev); + + priv->pinctrl = devm_pinctrl_get(&pdev->dev); + if (!IS_ERR_OR_NULL(priv->pinctrl)) + priv->pinctrl_wakeup = pinctrl_lookup_state(priv->pinctrl, "wakeup"); + return 0; err: pm_runtime_dont_use_autosuspend(&pdev->dev); @@ -1653,6 +1652,13 @@ static int omap8250_suspend(struct device *dev) struct uart_8250_port *up = serial8250_get_port(priv->line); int err = 0; + err = omap8250_select_wakeup_pinctrl(dev, priv); + if (err) { + dev_err(dev, "Failed to select wakeup pinctrl, aborting suspend %pe\n", + ERR_PTR(err)); + return err; + } + serial8250_suspend_port(priv->line); err = pm_runtime_resume_and_get(dev); @@ -1674,6 +1680,13 @@ static int omap8250_resume(struct device *dev) struct uart_8250_port *up = serial8250_get_port(priv->line); int err; + err = pinctrl_select_default_state(dev); + if (err) { + dev_err(dev, "Failed to select default pinctrl state on resume: %pe\n", + ERR_PTR(err)); + return err; + } + if (uart_console(&up->port) && console_suspend_enabled) { err = pm_runtime_force_resume(dev); if (err) @@ -1795,15 +1808,13 @@ static int omap8250_runtime_resume(struct device *dev) up = serial8250_get_port(priv->line); if (up && omap8250_lost_context(up)) { - uart_port_lock_irq(&up->port); + guard(uart_port_lock_irq)(&up->port); omap8250_restore_regs(up); - uart_port_unlock_irq(&up->port); } if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) { - uart_port_lock_irq(&up->port); + guard(uart_port_lock_irq)(&up->port); omap_8250_rx_dma(up); - uart_port_unlock_irq(&up->port); } atomic_set(&priv->active, 1); diff --git a/drivers/tty/serial/8250/8250_platform.c b/drivers/tty/serial/8250/8250_platform.c index c0343bfb8064..b27981340e76 100644 --- a/drivers/tty/serial/8250/8250_platform.c +++ b/drivers/tty/serial/8250/8250_platform.c @@ -10,6 +10,7 @@ */ #include <linux/acpi.h> #include <linux/array_size.h> +#include <linux/cleanup.h> #include <linux/io.h> #include <linux/module.h> #include <linux/moduleparam.h> @@ -110,41 +111,44 @@ void __init serial8250_isa_init_ports(void) static int serial8250_probe_acpi(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct uart_8250_port uart = { }; struct resource *regs; int ret, line; + struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL); + if (!uart) + return -ENOMEM; + regs = platform_get_mem_or_io(pdev, 0); if (!regs) return dev_err_probe(dev, -EINVAL, "no registers defined\n"); switch (resource_type(regs)) { case IORESOURCE_IO: - uart.port.iobase = regs->start; + uart->port.iobase = regs->start; break; case IORESOURCE_MEM: - uart.port.mapbase = regs->start; - uart.port.mapsize = resource_size(regs); - uart.port.flags = UPF_IOREMAP; + uart->port.mapbase = regs->start; + uart->port.mapsize = resource_size(regs); + uart->port.flags = UPF_IOREMAP; break; default: return -EINVAL; } /* default clock frequency */ - uart.port.uartclk = 1843200; - uart.port.type = PORT_16550A; - uart.port.dev = &pdev->dev; - uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; + uart->port.uartclk = 1843200; + uart->port.type = PORT_16550A; + uart->port.dev = &pdev->dev; + uart->port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; - ret = uart_read_and_validate_port_properties(&uart.port); + ret = uart_read_and_validate_port_properties(&uart->port); /* no interrupt -> fall back to polling */ if (ret == -ENXIO) ret = 0; if (ret) return ret; - line = serial8250_register_8250_port(&uart); + line = serial8250_register_8250_port(uart); if (line < 0) return line; @@ -153,43 +157,44 @@ static int serial8250_probe_acpi(struct platform_device *pdev) static int serial8250_probe_platform(struct platform_device *dev, struct plat_serial8250_port *p) { - struct uart_8250_port uart; int ret, i, irqflag = 0; - memset(&uart, 0, sizeof(uart)); + struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL); + if (!uart) + return -ENOMEM; if (share_irqs) irqflag = IRQF_SHARED; for (i = 0; p && p->flags != 0; p++, i++) { - uart.port.iobase = p->iobase; - uart.port.membase = p->membase; - uart.port.irq = p->irq; - uart.port.irqflags = p->irqflags; - uart.port.uartclk = p->uartclk; - uart.port.regshift = p->regshift; - uart.port.iotype = p->iotype; - uart.port.flags = p->flags; - uart.port.mapbase = p->mapbase; - uart.port.mapsize = p->mapsize; - uart.port.hub6 = p->hub6; - uart.port.has_sysrq = p->has_sysrq; - uart.port.private_data = p->private_data; - uart.port.type = p->type; - uart.bugs = p->bugs; - uart.port.serial_in = p->serial_in; - uart.port.serial_out = p->serial_out; - uart.dl_read = p->dl_read; - uart.dl_write = p->dl_write; - uart.port.handle_irq = p->handle_irq; - uart.port.handle_break = p->handle_break; - uart.port.set_termios = p->set_termios; - uart.port.set_ldisc = p->set_ldisc; - uart.port.get_mctrl = p->get_mctrl; - uart.port.pm = p->pm; - uart.port.dev = &dev->dev; - uart.port.irqflags |= irqflag; - ret = serial8250_register_8250_port(&uart); + uart->port.iobase = p->iobase; + uart->port.membase = p->membase; + uart->port.irq = p->irq; + uart->port.irqflags = p->irqflags; + uart->port.uartclk = p->uartclk; + uart->port.regshift = p->regshift; + uart->port.iotype = p->iotype; + uart->port.flags = p->flags; + uart->port.mapbase = p->mapbase; + uart->port.mapsize = p->mapsize; + uart->port.hub6 = p->hub6; + uart->port.has_sysrq = p->has_sysrq; + uart->port.private_data = p->private_data; + uart->port.type = p->type; + uart->bugs = p->bugs; + uart->port.serial_in = p->serial_in; + uart->port.serial_out = p->serial_out; + uart->dl_read = p->dl_read; + uart->dl_write = p->dl_write; + uart->port.handle_irq = p->handle_irq; + uart->port.handle_break = p->handle_break; + uart->port.set_termios = p->set_termios; + uart->port.set_ldisc = p->set_ldisc; + uart->port.get_mctrl = p->get_mctrl; + uart->port.pm = p->pm; + uart->port.dev = &dev->dev; + uart->port.irqflags |= irqflag; + ret = serial8250_register_8250_port(uart); if (ret < 0) { dev_err(&dev->dev, "unable to register port at index %d " "(IO%lx MEM%llx IRQ%d): %d\n", i, diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 2da9db960d09..719faf92aa8a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -508,20 +508,22 @@ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) } EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); -static void serial8250_rpm_get(struct uart_8250_port *p) +void serial8250_rpm_get(struct uart_8250_port *p) { if (!(p->capabilities & UART_CAP_RPM)) return; pm_runtime_get_sync(p->port.dev); } +EXPORT_SYMBOL_GPL(serial8250_rpm_get); -static void serial8250_rpm_put(struct uart_8250_port *p) +void serial8250_rpm_put(struct uart_8250_port *p) { if (!(p->capabilities & UART_CAP_RPM)) return; pm_runtime_mark_last_busy(p->port.dev); pm_runtime_put_autosuspend(p->port.dev); } +EXPORT_SYMBOL_GPL(serial8250_rpm_put); /** * serial8250_em485_init() - put uart_8250_port into rs485 emulating @@ -672,28 +674,27 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) { unsigned char lcr = 0, efr = 0; - serial8250_rpm_get(p); - - if (p->capabilities & UART_CAP_SLEEP) { - /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(&p->port); - if (p->capabilities & UART_CAP_EFR) { - lcr = serial_in(p, UART_LCR); - efr = serial_in(p, UART_EFR); - serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(p, UART_EFR, UART_EFR_ECB); - serial_out(p, UART_LCR, 0); - } - serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); - if (p->capabilities & UART_CAP_EFR) { - serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(p, UART_EFR, efr); - serial_out(p, UART_LCR, lcr); - } - uart_port_unlock_irq(&p->port); - } + guard(serial8250_rpm)(p); + + if (!(p->capabilities & UART_CAP_SLEEP)) + return; + + /* Synchronize UART_IER access against the console. */ + guard(uart_port_lock_irq)(&p->port); - serial8250_rpm_put(p); + if (p->capabilities & UART_CAP_EFR) { + lcr = serial_in(p, UART_LCR); + efr = serial_in(p, UART_EFR); + serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(p, UART_EFR, UART_EFR_ECB); + serial_out(p, UART_LCR, 0); + } + serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); + if (p->capabilities & UART_CAP_EFR) { + serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(p, UART_EFR, efr); + serial_out(p, UART_LCR, lcr); + } } /* Clear the interrupt registers. */ @@ -1229,9 +1230,8 @@ static void autoconfig_irq(struct uart_8250_port *up) probe_irq_off(probe_irq_on()); save_mcr = serial8250_in_MCR(up); /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(port); - save_ier = serial_in(up, UART_IER); - uart_port_unlock_irq(port); + scoped_guard(uart_port_lock_irq, port) + save_ier = serial_in(up, UART_IER); serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); irqs = probe_irq_on(); @@ -1244,9 +1244,8 @@ static void autoconfig_irq(struct uart_8250_port *up) UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); } /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(port); - serial_out(up, UART_IER, UART_IER_ALL_INTR); - uart_port_unlock_irq(port); + scoped_guard(uart_port_lock_irq, port) + serial_out(up, UART_IER, UART_IER_ALL_INTR); serial8250_clear_interrupts(port); serial_out(up, UART_TX, 0xFF); udelay(20); @@ -1254,9 +1253,8 @@ static void autoconfig_irq(struct uart_8250_port *up) serial8250_out_MCR(up, save_mcr); /* Synchronize UART_IER access against the console. */ - uart_port_lock_irq(port); - serial_out(up, UART_IER, save_ier); - uart_port_unlock_irq(port); + scoped_guard(uart_port_lock_irq, port) + serial_out(up, UART_IER, save_ier); if (port->flags & UPF_FOURPORT) outb_p(save_ICP, ICP); @@ -1271,12 +1269,10 @@ static void serial8250_stop_rx(struct uart_port *port) /* Port locked to synchronize UART_IER access against the console. */ lockdep_assert_held_once(&port->lock); - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); serial_port_out(port, UART_IER, up->ier); - - serial8250_rpm_put(up); } /** @@ -1320,17 +1316,15 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485, stop_tx_timer); struct uart_8250_port *p = em485->port; - unsigned long flags; - serial8250_rpm_get(p); - uart_port_lock_irqsave(&p->port, &flags); + guard(serial8250_rpm)(p); + guard(uart_port_lock_irqsave)(&p->port); + if (em485->active_timer == &em485->stop_tx_timer) { p->rs485_stop_tx(p, true); em485->active_timer = NULL; em485->tx_stopped = true; } - uart_port_unlock_irqrestore(&p->port, flags); - serial8250_rpm_put(p); return HRTIMER_NORESTART; } @@ -1405,7 +1399,7 @@ static void serial8250_stop_tx(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); __stop_tx(up); /* @@ -1415,7 +1409,6 @@ static void serial8250_stop_tx(struct uart_port *port) up->acr |= UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } - serial8250_rpm_put(up); } static inline void __start_tx(struct uart_port *port) @@ -1510,14 +1503,13 @@ static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t) struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485, start_tx_timer); struct uart_8250_port *p = em485->port; - unsigned long flags; - uart_port_lock_irqsave(&p->port, &flags); + guard(uart_port_lock_irqsave)(&p->port); + if (em485->active_timer == &em485->start_tx_timer) { __start_tx(&p->port); em485->active_timer = NULL; } - uart_port_unlock_irqrestore(&p->port, flags); return HRTIMER_NORESTART; } @@ -1585,9 +1577,8 @@ static void serial8250_enable_ms(struct uart_port *port) up->ier |= UART_IER_MSI; - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); serial_port_out(port, UART_IER, up->ier); - serial8250_rpm_put(up); } void serial8250_read_char(struct uart_8250_port *up, u16 lsr) @@ -1848,15 +1839,11 @@ static int serial8250_default_handle_irq(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); unsigned int iir; - int ret; - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); iir = serial_port_in(port, UART_IIR); - ret = serial8250_handle_irq(port, iir); - - serial8250_rpm_put(up); - return ret; + return serial8250_handle_irq(port, iir); } /* @@ -1867,16 +1854,14 @@ static int serial8250_default_handle_irq(struct uart_port *port) */ static int serial8250_tx_threshold_handle_irq(struct uart_port *port) { - unsigned long flags; unsigned int iir = serial_port_in(port, UART_IIR); /* TX Threshold IRQ triggered so load up FIFO */ if ((iir & UART_IIR_ID) == UART_IIR_THRI) { struct uart_8250_port *up = up_to_u8250p(port); - uart_port_lock_irqsave(port, &flags); + guard(uart_port_lock_irqsave)(port); serial8250_tx_chars(up); - uart_port_unlock_irqrestore(port, flags); } iir = serial_port_in(port, UART_IIR); @@ -1886,19 +1871,14 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port) static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); - unsigned int result = 0; - unsigned long flags; - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); + guard(uart_port_lock_irqsave)(port); - uart_port_lock_irqsave(port, &flags); if (!serial8250_tx_dma_running(up) && uart_lsr_tx_empty(serial_lsr_in(up))) - result = TIOCSER_TEMT; - uart_port_unlock_irqrestore(port, flags); - - serial8250_rpm_put(up); + return TIOCSER_TEMT; - return result; + return 0; } unsigned int serial8250_do_get_mctrl(struct uart_port *port) @@ -1907,9 +1887,8 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port) unsigned int status; unsigned int val; - serial8250_rpm_get(up); - status = serial8250_modem_status(up); - serial8250_rpm_put(up); + scoped_guard(serial8250_rpm, up) + status = serial8250_modem_status(up); val = serial8250_MSR_to_TIOCM(status); if (up->gpios) @@ -1953,17 +1932,15 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) static void serial8250_break_ctl(struct uart_port *port, int break_state) { struct uart_8250_port *up = up_to_u8250p(port); - unsigned long flags; - serial8250_rpm_get(up); - uart_port_lock_irqsave(port, &flags); + guard(serial8250_rpm)(up); + guard(uart_port_lock_irqsave)(port); + if (break_state == -1) up->lcr |= UART_LCR_SBC; else up->lcr &= ~UART_LCR_SBC; serial_port_out(port, UART_LCR, up->lcr); - uart_port_unlock_irqrestore(port, flags); - serial8250_rpm_put(up); } /* Returns true if @bits were set, false on timeout */ @@ -2023,22 +2000,15 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) static int serial8250_get_poll_char(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); - int status; u16 lsr; - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); lsr = serial_port_in(port, UART_LSR); + if (!(lsr & UART_LSR_DR)) + return NO_POLL_CHAR; - if (!(lsr & UART_LSR_DR)) { - status = NO_POLL_CHAR; - goto out; - } - - status = serial_port_in(port, UART_RX); -out: - serial8250_rpm_put(up); - return status; + return serial_port_in(port, UART_RX); } @@ -2056,7 +2026,7 @@ static void serial8250_put_poll_char(struct uart_port *port, * should allow safe lockless usage here. */ - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); /* * First save the IER then disable the interrupts */ @@ -2075,7 +2045,6 @@ static void serial8250_put_poll_char(struct uart_port *port, */ wait_for_xmitr(up, UART_LSR_BOTH_EMPTY); serial_port_out(port, UART_IER, ier); - serial8250_rpm_put(up); } #endif /* CONFIG_CONSOLE_POLL */ @@ -2083,16 +2052,15 @@ static void serial8250_put_poll_char(struct uart_port *port, static void serial8250_startup_special(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); - unsigned long flags; switch (port->type) { - case PORT_16C950: + case PORT_16C950: { /* * Wake up and initialize UART * * Synchronize UART_IER access against the console. */ - uart_port_lock_irqsave(port, &flags); + guard(uart_port_lock_irqsave)(port); up->acr = 0; serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); @@ -2102,18 +2070,18 @@ static void serial8250_startup_special(struct uart_port *port) serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); serial_port_out(port, UART_EFR, UART_EFR_ECB); serial_port_out(port, UART_LCR, 0); - uart_port_unlock_irqrestore(port, flags); break; + } case PORT_DA830: /* * Reset the port * * Synchronize UART_IER access against the console. */ - uart_port_lock_irqsave(port, &flags); - serial_port_out(port, UART_IER, 0); - serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); - uart_port_unlock_irqrestore(port, flags); + scoped_guard(uart_port_lock_irqsave, port) { + serial_port_out(port, UART_IER, 0); + serial_port_out(port, UART_DA830_PWREMU_MGMT, 0); + } mdelay(10); /* Enable Tx, Rx and free run mode */ @@ -2171,7 +2139,6 @@ static void serial8250_set_TRG_levels(struct uart_port *port) static void serial8250_THRE_test(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); - unsigned long flags; bool iir_noint1, iir_noint2; if (!port->irq) @@ -2191,19 +2158,17 @@ static void serial8250_THRE_test(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - uart_port_lock_irqsave(port, &flags); - - wait_for_xmitr(up, UART_LSR_THRE); - serial_port_out_sync(port, UART_IER, UART_IER_THRI); - udelay(1); /* allow THRE to set */ - iir_noint1 = serial_port_in(port, UART_IIR) & UART_IIR_NO_INT; - serial_port_out(port, UART_IER, 0); - serial_port_out_sync(port, UART_IER, UART_IER_THRI); - udelay(1); /* allow a working UART time to re-assert THRE */ - iir_noint2 = serial_port_in(port, UART_IIR) & UART_IIR_NO_INT; - serial_port_out(port, UART_IER, 0); - - uart_port_unlock_irqrestore(port, flags); + scoped_guard(uart_port_lock_irqsave, port) { + wait_for_xmitr(up, UART_LSR_THRE); + serial_port_out_sync(port, UART_IER, UART_IER_THRI); + udelay(1); /* allow THRE to set */ + iir_noint1 = serial_port_in(port, UART_IIR) & UART_IIR_NO_INT; + serial_port_out(port, UART_IER, 0); + serial_port_out_sync(port, UART_IER, UART_IER_THRI); + udelay(1); /* allow a working UART time to re-assert THRE */ + iir_noint2 = serial_port_in(port, UART_IIR) & UART_IIR_NO_INT; + serial_port_out(port, UART_IER, 0); + } if (port->irqflags & IRQF_SHARED) enable_irq(port->irq); @@ -2267,14 +2232,11 @@ static void serial8250_iir_txen_test(struct uart_port *port) static void serial8250_initialize(struct uart_port *port) { - unsigned long flags; - - uart_port_lock_irqsave(port, &flags); + guard(uart_port_lock_irqsave)(port); serial_port_out(port, UART_LCR, UART_LCR_WLEN8); serial8250_init_mctrl(port); serial8250_iir_txen_test(port); - uart_port_unlock_irqrestore(port, flags); } int serial8250_do_startup(struct uart_port *port) @@ -2293,7 +2255,7 @@ int serial8250_do_startup(struct uart_port *port) if (port->iotype != up->cur_iotype) set_io_from_upio(port); - serial8250_rpm_get(up); + guard(serial8250_rpm)(up); serial8250_startup_special(port); @@ -2313,8 +2275,7 @@ int serial8250_do_startup(struct uart_port *port) if (!(port->flags & UPF_BUGGY_UART) && (serial_port_in(port, UART_LSR) == 0xff)) { dev_info_ratelimited(port->dev, "LSR safety check engaged!\n"); - retval = -ENODEV; - goto out; + return -ENODEV; } serial8250_set_TRG_levels(port); @@ -2325,7 +2286,7 @@ int serial8250_do_startup(struct uart_port *port) retval = up->ops->setup_irq(up); if (retval) - goto out; + return retval; serial8250_THRE_test(port); @@ -2374,10 +2335,8 @@ int serial8250_do_startup(struct uart_port *port) outb_p(0x80, icp); inb_p(icp); } - retval = 0; -out: - serial8250_rpm_put(up); - return retval; + + return 0; } EXPORT_SYMBOL_GPL(serial8250_do_startup); @@ -2391,7 +2350,6 @@ static int serial8250_startup(struct uart_port *port) void serial8250_do_shutdown(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); - unsigned long flags; serial8250_rpm_get(up); /* @@ -2399,26 +2357,26 @@ void serial8250_do_shutdown(struct uart_port *port) * * Synchronize UART_IER access against the console. */ - uart_port_lock_irqsave(port, &flags); - up->ier = 0; - serial_port_out(port, UART_IER, 0); - uart_port_unlock_irqrestore(port, flags); + scoped_guard(uart_port_lock_irqsave, port) { + up->ier = 0; + serial_port_out(port, UART_IER, 0); + } synchronize_irq(port->irq); if (up->dma) serial8250_release_dma(up); - uart_port_lock_irqsave(port, &flags); - if (port->flags & UPF_FOURPORT) { - /* reset interrupts on the AST Fourport board */ - inb((port->iobase & 0xfe0) | 0x1f); - port->mctrl |= TIOCM_OUT1; - } else - port->mctrl &= ~TIOCM_OUT2; + scoped_guard(uart_port_lock_irqsave, port) { + if (port->flags & UPF_FOURPORT) { + /* reset interrupts on the AST Fourport board */ + inb((port->iobase & 0xfe0) | 0x1f); + port->mctrl |= TIOCM_OUT1; + } else + port->mctrl &= ~TIOCM_OUT2; - serial8250_set_mctrl(port, port->mctrl); - uart_port_unlock_irqrestore(port, flags); + serial8250_set_mctrl(port, port->mctrl); + } /* * Disable break condition and FIFOs @@ -2610,33 +2568,27 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) { struct tty_port *tport = &port->state->port; - struct tty_struct *tty; - tty = tty_port_tty_get(tport); - if (!tty) { - mutex_lock(&tport->mutex); - port->uartclk = uartclk; - mutex_unlock(&tport->mutex); - return; - } + scoped_guard(tty_port_tty, tport) { + struct tty_struct *tty = scoped_tty(); - down_write(&tty->termios_rwsem); - mutex_lock(&tport->mutex); + guard(rwsem_write)(&tty->termios_rwsem); + guard(mutex)(&tport->mutex); - if (port->uartclk == uartclk) - goto out_unlock; + if (port->uartclk == uartclk) + return; - port->uartclk = uartclk; + port->uartclk = uartclk; - if (!tty_port_initialized(tport)) - goto out_unlock; + if (!tty_port_initialized(tport)) + return; - serial8250_do_set_termios(port, &tty->termios, NULL); + serial8250_do_set_termios(port, &tty->termios, NULL); -out_unlock: - mutex_unlock(&tport->mutex); - up_write(&tty->termios_rwsem); - tty_kref_put(tty); + return; + } + guard(mutex)(&tport->mutex); + port->uartclk = uartclk; } EXPORT_SYMBOL_GPL(serial8250_update_uartclk); @@ -2791,7 +2743,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, const struct ktermios *old) { struct uart_8250_port *up = up_to_u8250p(port); - unsigned long flags; unsigned int baud, quot, frac = 0; u8 lcr; @@ -2801,27 +2752,24 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, quot = serial8250_get_divisor(port, baud, &frac); /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. + * Ok, we're now changing the port state. Do it with interrupts disabled. * * Synchronize UART_IER access against the console. */ - serial8250_rpm_get(up); - uart_port_lock_irqsave(port, &flags); - - up->lcr = lcr; - serial8250_set_trigger_for_slow_speed(port, termios, baud); - serial8250_set_afe(port, termios); - uart_update_timeout(port, termios->c_cflag, baud); - serial8250_set_errors_and_ignores(port, termios); - serial8250_set_ier(port, termios); - serial8250_set_efr(port, termios); - serial8250_set_divisor(port, baud, quot, frac); - serial8250_set_fcr(port, termios); - serial8250_set_mctrl(port, port->mctrl); + scoped_guard(serial8250_rpm, up) { + guard(uart_port_lock_irqsave)(port); - uart_port_unlock_irqrestore(port, flags); - serial8250_rpm_put(up); + up->lcr = lcr; + serial8250_set_trigger_for_slow_speed(port, termios, baud); + serial8250_set_afe(port, termios); + uart_update_timeout(port, termios->c_cflag, baud); + serial8250_set_errors_and_ignores(port, termios); + serial8250_set_ier(port, termios); + serial8250_set_efr(port, termios); + serial8250_set_divisor(port, baud, quot, frac); + serial8250_set_fcr(port, termios); + serial8250_set_mctrl(port, port->mctrl); + } /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) @@ -2843,15 +2791,13 @@ void serial8250_do_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; - uart_port_lock_irq(port); + guard(uart_port_lock_irq)(port); serial8250_enable_ms(port); - uart_port_unlock_irq(port); } else { port->flags &= ~UPF_HARDPPS_CD; if (!UART_ENABLE_MS(port, termios->c_cflag)) { - uart_port_lock_irq(port); + guard(uart_port_lock_irq)(port); serial8250_disable_ms(port); - uart_port_unlock_irq(port); } } } diff --git a/drivers/tty/serial/8250/8250_rsa.c b/drivers/tty/serial/8250/8250_rsa.c index 12a65b79583c..40a3dbd9e452 100644 --- a/drivers/tty/serial/8250/8250_rsa.c +++ b/drivers/tty/serial/8250/8250_rsa.c @@ -140,9 +140,8 @@ void rsa_enable(struct uart_8250_port *up) return; if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { - uart_port_lock_irq(&up->port); + guard(uart_port_lock_irq)(&up->port); __rsa_enable(up); - uart_port_unlock_irq(&up->port); } if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) serial_out(up, UART_RSA_FRR, 0); @@ -165,7 +164,8 @@ void rsa_disable(struct uart_8250_port *up) if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) return; - uart_port_lock_irq(&up->port); + guard(uart_port_lock_irq)(&up->port); + mode = serial_in(up, UART_RSA_MSR); result = !(mode & UART_RSA_MSR_FIFO); @@ -177,7 +177,6 @@ void rsa_disable(struct uart_8250_port *up) if (result) up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; - uart_port_unlock_irq(&up->port); } EXPORT_SYMBOL_FOR_MODULES(rsa_disable, "8250_base"); |