Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

serial: 8250_omap: Drop pm_runtime_irq_safe()

Let's drop the use of pm_runtime_irq_safe() for 8250_omap. The use of
pm_runtime_irq_safe() is not nice as it takes a permanent usage count on
the parent device.

We can finally drop pm_runtime_irq_safe() safely as the kernel now knows
when the uart port tx is active. This changed with commit 84a9582fd203
("serial: core: Start managing serial controllers to enable runtime PM").

For serial port rx, we already use Linux generic wakeirqs for 8250_omap.

To drop pm_runtime_irq_safe(), we need to add handling for shallow idle
state where the port hardware may already be awake and an IO interrupt
happens. We also need to replace the serial8250_rpm sync calls in the
interrupt handlers with async runtime PM calls.

Note that omap8250_irq() calls omap_8250_dma_handle_irq(), so we don't
need separate runtime PM calls in omap_8250_dma_handle_irq().

While at it, let's also add the missing line break to the end of
omap8250_runtime_resume() to group the calls.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20231004062650.64487-1-tony@atomide.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Tony Lindgren and committed by
Greg Kroah-Hartman
8700a7ea b9cbe7e8

+21 -8
+21 -8
drivers/tty/serial/8250/8250_omap.c
··· 8 8 * 9 9 */ 10 10 11 + #include <linux/atomic.h> 11 12 #include <linux/clk.h> 12 13 #include <linux/device.h> 13 14 #include <linux/io.h> ··· 131 130 132 131 u8 tx_trigger; 133 132 u8 rx_trigger; 133 + atomic_t active; 134 134 bool is_suspending; 135 135 int wakeirq; 136 136 int wakeups_enabled; ··· 634 632 unsigned int iir, lsr; 635 633 int ret; 636 634 635 + pm_runtime_get_noresume(port->dev); 636 + 637 + /* Shallow idle state wake-up to an IO interrupt? */ 638 + if (atomic_add_unless(&priv->active, 1, 1)) { 639 + priv->latency = priv->calc_latency; 640 + schedule_work(&priv->qos_work); 641 + } 642 + 637 643 #ifdef CONFIG_SERIAL_8250_DMA 638 644 if (up->dma) { 639 645 ret = omap_8250_dma_handle_irq(port); 646 + pm_runtime_mark_last_busy(port->dev); 647 + pm_runtime_put(port->dev); 640 648 return IRQ_RETVAL(ret); 641 649 } 642 650 #endif 643 651 644 - serial8250_rpm_get(up); 645 652 lsr = serial_port_in(port, UART_LSR); 646 653 iir = serial_port_in(port, UART_IIR); 647 654 ret = serial8250_handle_irq(port, iir); ··· 687 676 schedule_delayed_work(&up->overrun_backoff, delay); 688 677 } 689 678 690 - serial8250_rpm_put(up); 679 + pm_runtime_mark_last_busy(port->dev); 680 + pm_runtime_put(port->dev); 691 681 692 682 return IRQ_RETVAL(ret); 693 683 } ··· 1282 1270 u16 status; 1283 1271 u8 iir; 1284 1272 1285 - serial8250_rpm_get(up); 1286 - 1287 1273 iir = serial_port_in(port, UART_IIR); 1288 1274 if (iir & UART_IIR_NO_INT) { 1289 - serial8250_rpm_put(up); 1290 1275 return IRQ_HANDLED; 1291 1276 } 1292 1277 ··· 1314 1305 1315 1306 uart_unlock_and_check_sysrq(port); 1316 1307 1317 - serial8250_rpm_put(up); 1318 1308 return 1; 1319 1309 } 1320 1310 ··· 1510 1502 */ 1511 1503 if (!of_get_available_child_count(pdev->dev.of_node)) 1512 1504 pm_runtime_set_autosuspend_delay(&pdev->dev, -1); 1513 - 1514 - pm_runtime_irq_safe(&pdev->dev); 1515 1505 1516 1506 pm_runtime_get_sync(&pdev->dev); 1517 1507 ··· 1754 1748 1755 1749 priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; 1756 1750 schedule_work(&priv->qos_work); 1751 + atomic_set(&priv->active, 0); 1757 1752 1758 1753 return 0; 1759 1754 } ··· 1763 1756 { 1764 1757 struct omap8250_priv *priv = dev_get_drvdata(dev); 1765 1758 struct uart_8250_port *up = NULL; 1759 + 1760 + /* Did the hardware wake to a device IO interrupt before a wakeirq? */ 1761 + if (atomic_read(&priv->active)) 1762 + return 0; 1766 1763 1767 1764 if (priv->line >= 0) 1768 1765 up = serial8250_get_port(priv->line); ··· 1783 1772 uart_port_unlock_irq(&up->port); 1784 1773 } 1785 1774 1775 + atomic_set(&priv->active, 1); 1786 1776 priv->latency = priv->calc_latency; 1787 1777 schedule_work(&priv->qos_work); 1778 + 1788 1779 return 0; 1789 1780 } 1790 1781