Re: [PATCH 7/7] serial: 8250_port: Remove calls to runtime PM
From: Johan Hovold <johan@kernel.org>
Date: 2021-11-30 10:47:46
Also in:
linux-omap, lkml
On Mon, Nov 15, 2021 at 10:42:03AM +0200, Tony Lindgren wrote:
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Since we now have runtime PM calls in serial_core.c the individual drivers do not need them anymore for the struct uart_ops related functions. Remove runtime PM calls in 8250 driver. This still leaves the flag for UART_CAP_RPM for serial8250_rpm_get_tx(), serial8250_rpm_put_tx() and serial8250_wakeup() to manage the reference count for serial TX. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> [tony@atomide.com: updated to remove the exported functions too] Signed-off-by: Tony Lindgren <tony@atomide.com>
quoted hunk ↗ jump to hunk
@@ -1477,8 +1459,11 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) stop_tx_timer); struct uart_8250_port *p = em485->port; unsigned long flags; + int err; - serial8250_rpm_get(p); + err = pm_runtime_resume_and_get(p->port.dev);
This also won't work as this function is called on timer expiry; you cannot do a synchronous resume here.
quoted hunk ↗ jump to hunk
+ if (err < 0) + goto out_rpm_err; spin_lock_irqsave(&p->port.lock, flags); if (em485->active_timer == &em485->stop_tx_timer) { p->rs485_stop_tx(p);@@ -1486,8 +1471,9 @@ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) em485->tx_stopped = true; } spin_unlock_irqrestore(&p->port.lock, flags); - serial8250_rpm_put(p); - + pm_runtime_mark_last_busy(p->port.dev); + pm_runtime_put_autosuspend(p->port.dev); +out_rpm_err: return HRTIMER_NORESTART; }
quoted hunk ↗ jump to hunk
void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)@@ -1984,15 +1966,11 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) unsigned long flags; unsigned int lsr; - serial8250_rpm_get(up); - spin_lock_irqsave(&port->lock, flags); lsr = serial_port_in(port, UART_LSR); up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; spin_unlock_irqrestore(&port->lock, flags); - serial8250_rpm_put(up); - return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; }
As I mentioned elsewhere, the corresponding get+put is missing in serial core now.
quoted hunk ↗ jump to hunk
static void serial8250_put_poll_char(struct uart_port *port, unsigned char c) { unsigned int ier; struct uart_8250_port *up = up_to_u8250p(port); - serial8250_rpm_get(up); /* * First save the IER then disable the interrupts */@@ -2155,7 +2117,6 @@ static void serial8250_put_poll_char(struct uart_port *port, */ wait_for_xmitr(up, BOTH_EMPTY); serial_port_out(port, UART_IER, ier); - serial8250_rpm_put(up); }
And this is a console callback; where is it guaranteed that the console is never suspended? Johan