* [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms
@ 2025-11-10 10:10 Praveen Talari
2025-11-10 10:10 ` [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm Praveen Talari
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Praveen Talari @ 2025-11-10 10:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Greg Kroah-Hartman, Jiri Slaby,
Dmitry Baryshkov, linux-arm-msm, devicetree, linux-kernel,
linux-gpio, linux-serial, alexey.klimov, krzk, bryan.odonoghue,
jorge.ramirez, dmitry.baryshkov
Cc: Konrad Dybcio, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_shazhuss, quic_cchiluve, Praveen Talari
PM runtime support was previously added to the serial driver but had to
be reverted due to wakeup IRQ storms and deadlock issues observed on the
RB1 platform.
Reference:
https://lore.kernel.org/all/DC0D53ZTNOBU.E8LSD5E5Z8TX@linaro.org/
This patch series reintroduces PM runtime support for UART on SA8255p
with fixes to resolve those issues.
The Qualcomm automotive SA8255p SoC relies on firmware to configure
platform resources, including clocks, interconnects and TLMM.
The driver requests resources operations over SCMI using power
and performance protocols.
The SCMI power protocol enables or disables resources like clocks,
interconnect paths, and TLMM (GPIOs) using runtime PM framework APIs,
such as resume/suspend, to control power states(on/off).
The SCMI performance protocol manages UART baud rates, with each baud
rate represented by a performance level. The driver uses the
dev_pm_opp_set_level() API to request the desired baud rate by
specifying the performance level.
Praveen Talari (4):
arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm
pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration
serial: qcom-geni: Enable PM runtime for serial driver
serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms
arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 2 +-
drivers/pinctrl/qcom/pinctrl-msm.c | 2 +-
drivers/tty/serial/qcom_geni_serial.c | 178 ++++++++++++++++++++---
3 files changed, 163 insertions(+), 19 deletions(-)
base-commit: ab40c92c74c6b0c611c89516794502b3a3173966
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm
2025-11-10 10:10 [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms Praveen Talari
@ 2025-11-10 10:10 ` Praveen Talari
2025-11-10 11:10 ` Konrad Dybcio
2025-11-10 10:10 ` [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration Praveen Talari
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Praveen Talari @ 2025-11-10 10:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Greg Kroah-Hartman, Jiri Slaby,
Dmitry Baryshkov, linux-arm-msm, devicetree, linux-kernel,
linux-gpio, linux-serial, alexey.klimov, krzk, bryan.odonoghue,
jorge.ramirez, dmitry.baryshkov
Cc: Konrad Dybcio, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_shazhuss, quic_cchiluve, Praveen Talari
For BT use cases, pins are configured with pull-up state in sleep state
to avoid noise. If IRQ type is configured as level high and the GPIO line
is also in a high state, it causes continuous interrupt assertions leading
to an IRQ storm when wakeup irq enables at system suspend/runtime suspend.
Switching to edge-triggered interrupt (IRQ_TYPE_EDGE_FALLING) resolves
this by only triggering on state transitions (high-to-low) rather than
maintaining sensitivity to the static level state, effectively preventing
the continuous interrupt condition and eliminating the wakeup IRQ storm.
Fixes: 9380e0a1d449 ("arm64: dts: qcom: qrb2210-rb1: add Bluetooth support")
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
index e0e362b140ad..1b9ca957a94b 100644
--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -704,7 +704,7 @@ key_volp_n: key-volp-n-state {
&uart3 {
/delete-property/ interrupts;
interrupts-extended = <&intc GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
- <&tlmm 11 IRQ_TYPE_LEVEL_HIGH>;
+ <&tlmm 11 IRQ_TYPE_EDGE_FALLING>;
pinctrl-0 = <&uart3_default>;
pinctrl-1 = <&uart3_sleep>;
pinctrl-names = "default", "sleep";
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration
2025-11-10 10:10 [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms Praveen Talari
2025-11-10 10:10 ` [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm Praveen Talari
@ 2025-11-10 10:10 ` Praveen Talari
2025-11-11 4:08 ` Bjorn Andersson
2025-11-12 12:43 ` Linus Walleij
2025-11-10 10:10 ` [PATCH v1 3/4] serial: qcom-geni: Enable PM runtime for serial driver Praveen Talari
` (2 subsequent siblings)
4 siblings, 2 replies; 11+ messages in thread
From: Praveen Talari @ 2025-11-10 10:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Greg Kroah-Hartman, Jiri Slaby,
Dmitry Baryshkov, linux-arm-msm, devicetree, linux-kernel,
linux-gpio, linux-serial, alexey.klimov, krzk, bryan.odonoghue,
jorge.ramirez, dmitry.baryshkov
Cc: Konrad Dybcio, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_shazhuss, quic_cchiluve, Praveen Talari,
Prasad Sodagudi
Replace disable_irq() with disable_irq_nosync() in msm_pinmux_set_mux()
to prevent potential deadlock when wakeup IRQ is triggered on the same
GPIO being reconfigured.
The issue occurs when a wakeup IRQ is triggered on a GPIO and the IRQ
handler attempts to reconfigure the same GPIO's pinmux. In this scenario,
msm_pinmux_set_mux() calls disable_irq() which waits for the currently
running IRQ handler to complete, creating a circular dependency that
results in deadlock.
Using disable_irq_nosync() avoids waiting for the IRQ handler to
complete, preventing the deadlock condition while still properly
disabling the interrupt during pinmux reconfiguration.
Suggested-by: Prasad Sodagudi <prasad.sodagudi@oss.qualcomm.com>
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/pinctrl/qcom/pinctrl-msm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 67525d542c5b..e99871b90ab9 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -189,7 +189,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
*/
if (d && i != gpio_func &&
!test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
- disable_irq(irq);
+ disable_irq_nosync(irq);
raw_spin_lock_irqsave(&pctrl->lock, flags);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 3/4] serial: qcom-geni: Enable PM runtime for serial driver
2025-11-10 10:10 [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms Praveen Talari
2025-11-10 10:10 ` [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm Praveen Talari
2025-11-10 10:10 ` [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration Praveen Talari
@ 2025-11-10 10:10 ` Praveen Talari
2025-11-10 10:10 ` [PATCH v1 4/4] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms Praveen Talari
2025-11-14 0:18 ` (subset) [PATCH v1 0/4] " Bjorn Andersson
4 siblings, 0 replies; 11+ messages in thread
From: Praveen Talari @ 2025-11-10 10:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Greg Kroah-Hartman, Jiri Slaby,
Dmitry Baryshkov, linux-arm-msm, devicetree, linux-kernel,
linux-gpio, linux-serial, alexey.klimov, krzk, bryan.odonoghue,
jorge.ramirez, dmitry.baryshkov
Cc: Konrad Dybcio, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_shazhuss, quic_cchiluve, Praveen Talari
The GENI serial driver currently handles power resource management
through calls to the statically defined geni_serial_resources_on() and
geni_serial_resources_off() functions. This approach reduces modularity
and limits support for platforms with diverse power management
mechanisms, including resource managed by firmware.
Improve modularity and enable better integration with platform-specific
power management, introduce support for runtime PM. Use
pm_runtime_resume_and_get() and pm_runtime_put_sync() within the
qcom_geni_serial_pm() callback to control resource power state
transitions based on UART power state changes.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/tty/serial/qcom_geni_serial.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 8058b839b26c..9c820302047c 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1650,10 +1650,10 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
old_state = UART_PM_STATE_OFF;
if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
- geni_serial_resources_on(uport);
+ pm_runtime_resume_and_get(uport->dev);
else if (new_state == UART_PM_STATE_OFF &&
old_state == UART_PM_STATE_ON)
- geni_serial_resources_off(uport);
+ pm_runtime_put_sync(uport->dev);
}
@@ -1815,6 +1815,8 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (ret)
return ret;
+ devm_pm_runtime_enable(port->se.dev);
+
ret = uart_add_one_port(drv, uport);
if (ret)
return ret;
@@ -1846,6 +1848,22 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
uart_remove_one_port(drv, &port->uport);
}
+static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev)
+{
+ struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
+ struct uart_port *uport = &port->uport;
+
+ return geni_serial_resources_off(uport);
+}
+
+static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *dev)
+{
+ struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
+ struct uart_port *uport = &port->uport;
+
+ return geni_serial_resources_on(uport);
+}
+
static int qcom_geni_serial_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
@@ -1889,6 +1907,8 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
};
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
+ SET_RUNTIME_PM_OPS(qcom_geni_serial_runtime_suspend,
+ qcom_geni_serial_runtime_resume, NULL)
SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
};
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 4/4] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms
2025-11-10 10:10 [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms Praveen Talari
` (2 preceding siblings ...)
2025-11-10 10:10 ` [PATCH v1 3/4] serial: qcom-geni: Enable PM runtime for serial driver Praveen Talari
@ 2025-11-10 10:10 ` Praveen Talari
2025-11-14 0:18 ` (subset) [PATCH v1 0/4] " Bjorn Andersson
4 siblings, 0 replies; 11+ messages in thread
From: Praveen Talari @ 2025-11-10 10:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Greg Kroah-Hartman, Jiri Slaby,
Dmitry Baryshkov, linux-arm-msm, devicetree, linux-kernel,
linux-gpio, linux-serial, alexey.klimov, krzk, bryan.odonoghue,
jorge.ramirez, dmitry.baryshkov
Cc: Konrad Dybcio, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_shazhuss, quic_cchiluve, Praveen Talari
The Qualcomm automotive SA8255p SoC relies on firmware to configure
platform resources, including clocks, interconnects and TLMM.
The driver requests resources operations over SCMI using power
and performance protocols.
The SCMI power protocol enables or disables resources like clocks,
interconnect paths, and TLMM (GPIOs) using runtime PM framework APIs,
such as resume/suspend, to control power states(on/off).
The SCMI performance protocol manages UART baud rates, with each baud
rate represented by a performance level. The driver uses the
dev_pm_opp_set_level() API to request the desired baud rate by
specifying the performance level.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/tty/serial/qcom_geni_serial.c | 158 +++++++++++++++++++++++---
1 file changed, 141 insertions(+), 17 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 9c820302047c..6ce6528f5c10 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -101,10 +102,16 @@
#define DMA_RX_BUF_SIZE 2048
static DEFINE_IDA(port_ida);
+#define DOMAIN_IDX_POWER 0
+#define DOMAIN_IDX_PERF 1
struct qcom_geni_device_data {
bool console;
enum geni_se_xfer_mode mode;
+ struct dev_pm_domain_attach_data pd_data;
+ int (*resources_init)(struct uart_port *uport);
+ int (*set_rate)(struct uart_port *uport, unsigned int baud);
+ int (*power_state)(struct uart_port *uport, bool state);
};
struct qcom_geni_private_data {
@@ -142,6 +149,7 @@ struct qcom_geni_serial_port {
struct qcom_geni_private_data private_data;
const struct qcom_geni_device_data *dev_data;
+ struct dev_pm_domain_list *pd_list;
};
static const struct uart_ops qcom_geni_console_pops;
@@ -1299,6 +1307,42 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned int baud)
return 0;
}
+static int geni_serial_set_level(struct uart_port *uport, unsigned int baud)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ struct device *perf_dev = port->pd_list->pd_devs[DOMAIN_IDX_PERF];
+
+ /*
+ * The performance protocol sets UART communication
+ * speeds by selecting different performance levels
+ * through the OPP framework.
+ *
+ * Supported perf levels for baudrates in firmware are below
+ * +---------------------+--------------------+
+ * | Perf level value | Baudrate values |
+ * +---------------------+--------------------+
+ * | 300 | 300 |
+ * | 1200 | 1200 |
+ * | 2400 | 2400 |
+ * | 4800 | 4800 |
+ * | 9600 | 9600 |
+ * | 19200 | 19200 |
+ * | 38400 | 38400 |
+ * | 57600 | 57600 |
+ * | 115200 | 115200 |
+ * | 230400 | 230400 |
+ * | 460800 | 460800 |
+ * | 921600 | 921600 |
+ * | 2000000 | 2000000 |
+ * | 3000000 | 3000000 |
+ * | 3200000 | 3200000 |
+ * | 4000000 | 4000000 |
+ * +---------------------+--------------------+
+ */
+
+ return dev_pm_opp_set_level(perf_dev, baud);
+}
+
static void qcom_geni_serial_set_termios(struct uart_port *uport,
struct ktermios *termios,
const struct ktermios *old)
@@ -1317,7 +1361,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
/* baud rate */
baud = uart_get_baud_rate(uport, termios, old, 300, 8000000);
- ret = geni_serial_set_rate(uport, baud);
+ ret = port->dev_data->set_rate(uport, baud);
if (ret)
return;
@@ -1604,8 +1648,27 @@ static int geni_serial_resources_off(struct uart_port *uport)
return 0;
}
-static int geni_serial_resource_init(struct qcom_geni_serial_port *port)
+static int geni_serial_resource_state(struct uart_port *uport, bool power_on)
+{
+ return power_on ? geni_serial_resources_on(uport) : geni_serial_resources_off(uport);
+}
+
+static int geni_serial_pwr_init(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ int ret;
+
+ ret = dev_pm_domain_attach_list(port->se.dev,
+ &port->dev_data->pd_data, &port->pd_list);
+ if (ret <= 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int geni_serial_resource_init(struct uart_port *uport)
{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
int ret;
port->se.clk = devm_clk_get(port->se.dev, "se");
@@ -1756,13 +1819,16 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->se.dev = &pdev->dev;
port->se.wrapper = dev_get_drvdata(pdev->dev.parent);
- ret = geni_serial_resource_init(port);
+ ret = port->dev_data->resources_init(uport);
if (ret)
return ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -EINVAL;
+ if (!res) {
+ ret = -EINVAL;
+ goto error;
+ }
+
uport->mapbase = res->start;
uport->rs485_config = qcom_geni_rs485_config;
@@ -1774,19 +1840,26 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (!data->console) {
port->rx_buf = devm_kzalloc(uport->dev,
DMA_RX_BUF_SIZE, GFP_KERNEL);
- if (!port->rx_buf)
- return -ENOMEM;
+ if (!port->rx_buf) {
+ ret = -ENOMEM;
+ goto error;
+ }
}
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
"qcom_geni_serial_%s%d",
uart_console(uport) ? "console" : "uart", uport->line);
- if (!port->name)
- return -ENOMEM;
+ if (!port->name) {
+ ret = -ENOMEM;
+ goto error;
+ }
irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
+ if (irq < 0) {
+ ret = irq;
+ goto error;
+ }
+
uport->irq = irq;
uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);
@@ -1808,18 +1881,18 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
- return ret;
+ goto error;
}
ret = uart_get_rs485_mode(uport);
if (ret)
- return ret;
+ goto error;
devm_pm_runtime_enable(port->se.dev);
ret = uart_add_one_port(drv, uport);
if (ret)
- return ret;
+ goto error;
if (port->wakeup_irq > 0) {
device_init_wakeup(&pdev->dev, true);
@@ -1829,11 +1902,15 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, false);
ida_free(&port_ida, uport->line);
uart_remove_one_port(drv, uport);
- return ret;
+ goto error;
}
}
return 0;
+
+error:
+ dev_pm_domain_detach_list(port->pd_list);
+ return ret;
}
static void qcom_geni_serial_remove(struct platform_device *pdev)
@@ -1846,22 +1923,31 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, false);
ida_free(&port_ida, uport->line);
uart_remove_one_port(drv, &port->uport);
+ dev_pm_domain_detach_list(port->pd_list);
}
static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
+ int ret = 0;
- return geni_serial_resources_off(uport);
+ if (port->dev_data->power_state)
+ ret = port->dev_data->power_state(uport, false);
+
+ return ret;
}
static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
+ int ret = 0;
+
+ if (port->dev_data->power_state)
+ ret = port->dev_data->power_state(uport, true);
- return geni_serial_resources_on(uport);
+ return ret;
}
static int qcom_geni_serial_suspend(struct device *dev)
@@ -1899,11 +1985,41 @@ static int qcom_geni_serial_resume(struct device *dev)
static const struct qcom_geni_device_data qcom_geni_console_data = {
.console = true,
.mode = GENI_SE_FIFO,
+ .resources_init = geni_serial_resource_init,
+ .set_rate = geni_serial_set_rate,
+ .power_state = geni_serial_resource_state,
};
static const struct qcom_geni_device_data qcom_geni_uart_data = {
.console = false,
.mode = GENI_SE_DMA,
+ .resources_init = geni_serial_resource_init,
+ .set_rate = geni_serial_set_rate,
+ .power_state = geni_serial_resource_state,
+};
+
+static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = {
+ .console = true,
+ .mode = GENI_SE_FIFO,
+ .pd_data = {
+ .pd_flags = PD_FLAG_DEV_LINK_ON,
+ .pd_names = (const char*[]) { "power", "perf" },
+ .num_pd_names = 2,
+ },
+ .resources_init = geni_serial_pwr_init,
+ .set_rate = geni_serial_set_level,
+};
+
+static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data = {
+ .console = false,
+ .mode = GENI_SE_DMA,
+ .pd_data = {
+ .pd_flags = PD_FLAG_DEV_LINK_ON,
+ .pd_names = (const char*[]) { "power", "perf" },
+ .num_pd_names = 2,
+ },
+ .resources_init = geni_serial_pwr_init,
+ .set_rate = geni_serial_set_level,
};
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
@@ -1917,10 +2033,18 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
.compatible = "qcom,geni-debug-uart",
.data = &qcom_geni_console_data,
},
+ {
+ .compatible = "qcom,sa8255p-geni-debug-uart",
+ .data = &sa8255p_qcom_geni_console_data,
+ },
{
.compatible = "qcom,geni-uart",
.data = &qcom_geni_uart_data,
},
+ {
+ .compatible = "qcom,sa8255p-geni-uart",
+ .data = &sa8255p_qcom_geni_uart_data,
+ },
{}
};
MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm
2025-11-10 10:10 ` [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm Praveen Talari
@ 2025-11-10 11:10 ` Konrad Dybcio
0 siblings, 0 replies; 11+ messages in thread
From: Konrad Dybcio @ 2025-11-10 11:10 UTC (permalink / raw)
To: Praveen Talari, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Linus Walleij,
Greg Kroah-Hartman, Jiri Slaby, Dmitry Baryshkov, linux-arm-msm,
devicetree, linux-kernel, linux-gpio, linux-serial, alexey.klimov,
krzk, bryan.odonoghue, jorge.ramirez, dmitry.baryshkov
Cc: psodagud, djaggi, quic_msavaliy, quic_vtanuku, quic_arandive,
quic_shazhuss, quic_cchiluve
On 11/10/25 11:10 AM, Praveen Talari wrote:
> For BT use cases, pins are configured with pull-up state in sleep state
> to avoid noise. If IRQ type is configured as level high and the GPIO line
> is also in a high state, it causes continuous interrupt assertions leading
> to an IRQ storm when wakeup irq enables at system suspend/runtime suspend.
>
> Switching to edge-triggered interrupt (IRQ_TYPE_EDGE_FALLING) resolves
> this by only triggering on state transitions (high-to-low) rather than
> maintaining sensitivity to the static level state, effectively preventing
> the continuous interrupt condition and eliminating the wakeup IRQ storm.
>
> Fixes: 9380e0a1d449 ("arm64: dts: qcom: qrb2210-rb1: add Bluetooth support")
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration
2025-11-10 10:10 ` [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration Praveen Talari
@ 2025-11-11 4:08 ` Bjorn Andersson
2025-11-11 5:22 ` Praveen Talari
2025-11-12 12:43 ` Linus Walleij
1 sibling, 1 reply; 11+ messages in thread
From: Bjorn Andersson @ 2025-11-11 4:08 UTC (permalink / raw)
To: Praveen Talari
Cc: Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Greg Kroah-Hartman, Jiri Slaby, Dmitry Baryshkov,
linux-arm-msm, devicetree, linux-kernel, linux-gpio, linux-serial,
alexey.klimov, krzk, bryan.odonoghue, jorge.ramirez,
dmitry.baryshkov, Konrad Dybcio, psodagud, djaggi, quic_msavaliy,
quic_vtanuku, quic_arandive, quic_shazhuss, quic_cchiluve,
Prasad Sodagudi
On Mon, Nov 10, 2025 at 03:40:41PM +0530, Praveen Talari wrote:
> Replace disable_irq() with disable_irq_nosync() in msm_pinmux_set_mux()
> to prevent potential deadlock when wakeup IRQ is triggered on the same
"potential"? In what case will calling disable_irq() from the irq
handler of that irq not deadlock?
> GPIO being reconfigured.
>
> The issue occurs when a wakeup IRQ is triggered on a GPIO and the IRQ
> handler attempts to reconfigure the same GPIO's pinmux. In this scenario,
> msm_pinmux_set_mux() calls disable_irq() which waits for the currently
> running IRQ handler to complete, creating a circular dependency that
> results in deadlock.
>
> Using disable_irq_nosync() avoids waiting for the IRQ handler to
> complete, preventing the deadlock condition while still properly
> disabling the interrupt during pinmux reconfiguration.
>
> Suggested-by: Prasad Sodagudi <prasad.sodagudi@oss.qualcomm.com>
That's weird, I debugged your deadlock for you and told you to make this
very change in:
https://lore.kernel.org/all/7sxsfyu2kqbycyfftwfhrncwk3dfnubmzhyi2rqi3jtvi5qsnh@bya3cii45zhn/
So I guess Prasad told you how to fix this issue before I invested the
time helping you?
Change looks good, and description captures the problem.
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Regards,
Bjorn
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
> drivers/pinctrl/qcom/pinctrl-msm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> index 67525d542c5b..e99871b90ab9 100644
> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> @@ -189,7 +189,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
> */
> if (d && i != gpio_func &&
> !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
> - disable_irq(irq);
> + disable_irq_nosync(irq);
>
> raw_spin_lock_irqsave(&pctrl->lock, flags);
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration
2025-11-11 4:08 ` Bjorn Andersson
@ 2025-11-11 5:22 ` Praveen Talari
2025-11-11 15:35 ` Bjorn Andersson
0 siblings, 1 reply; 11+ messages in thread
From: Praveen Talari @ 2025-11-11 5:22 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Greg Kroah-Hartman, Jiri Slaby, Dmitry Baryshkov,
linux-arm-msm, devicetree, linux-kernel, linux-gpio, linux-serial,
alexey.klimov, krzk, bryan.odonoghue, jorge.ramirez,
dmitry.baryshkov, Konrad Dybcio, psodagud, djaggi, quic_msavaliy,
quic_vtanuku, quic_arandive, quic_shazhuss, quic_cchiluve,
Prasad Sodagudi
Hi Bjorn,
Thank you for review.
On 11/11/2025 9:38 AM, Bjorn Andersson wrote:
> On Mon, Nov 10, 2025 at 03:40:41PM +0530, Praveen Talari wrote:
>> Replace disable_irq() with disable_irq_nosync() in msm_pinmux_set_mux()
>> to prevent potential deadlock when wakeup IRQ is triggered on the same
>
> "potential"? In what case will calling disable_irq() from the irq
> handler of that irq not deadlock?
>
>> GPIO being reconfigured.
>>
>> The issue occurs when a wakeup IRQ is triggered on a GPIO and the IRQ
>> handler attempts to reconfigure the same GPIO's pinmux. In this scenario,
>> msm_pinmux_set_mux() calls disable_irq() which waits for the currently
>> running IRQ handler to complete, creating a circular dependency that
>> results in deadlock.
>>
>> Using disable_irq_nosync() avoids waiting for the IRQ handler to
>> complete, preventing the deadlock condition while still properly
>> disabling the interrupt during pinmux reconfiguration.
>>
>> Suggested-by: Prasad Sodagudi <prasad.sodagudi@oss.qualcomm.com>
>
> That's weird, I debugged your deadlock for you and told you to make this
> very change in:
>
> https://lore.kernel.org/all/7sxsfyu2kqbycyfftwfhrncwk3dfnubmzhyi2rqi3jtvi5qsnh@bya3cii45zhn/
>
> So I guess Prasad told you how to fix this issue before I invested the
> time helping you?
Yes, that’s correct. Prasad had suggested it earlier.
Thanks,
Praveen Talari
>
>
> Change looks good, and description captures the problem.
>
> Reviewed-by: Bjorn Andersson <andersson@kernel.org>
>
> Regards,
> Bjorn
>
>> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
>> ---
>> drivers/pinctrl/qcom/pinctrl-msm.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
>> index 67525d542c5b..e99871b90ab9 100644
>> --- a/drivers/pinctrl/qcom/pinctrl-msm.c
>> +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
>> @@ -189,7 +189,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
>> */
>> if (d && i != gpio_func &&
>> !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
>> - disable_irq(irq);
>> + disable_irq_nosync(irq);
>>
>> raw_spin_lock_irqsave(&pctrl->lock, flags);
>>
>> --
>> 2.34.1
>>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration
2025-11-11 5:22 ` Praveen Talari
@ 2025-11-11 15:35 ` Bjorn Andersson
0 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2025-11-11 15:35 UTC (permalink / raw)
To: Praveen Talari
Cc: Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Greg Kroah-Hartman, Jiri Slaby, Dmitry Baryshkov,
linux-arm-msm, devicetree, linux-kernel, linux-gpio, linux-serial,
alexey.klimov, krzk, bryan.odonoghue, jorge.ramirez,
dmitry.baryshkov, Konrad Dybcio, psodagud, djaggi, quic_msavaliy,
quic_vtanuku, quic_arandive, quic_shazhuss, quic_cchiluve,
Prasad Sodagudi
On Tue, Nov 11, 2025 at 10:52:25AM +0530, Praveen Talari wrote:
> Hi Bjorn,
>
> Thank you for review.
>
> On 11/11/2025 9:38 AM, Bjorn Andersson wrote:
> > On Mon, Nov 10, 2025 at 03:40:41PM +0530, Praveen Talari wrote:
> > > Replace disable_irq() with disable_irq_nosync() in msm_pinmux_set_mux()
> > > to prevent potential deadlock when wakeup IRQ is triggered on the same
> >
> > "potential"? In what case will calling disable_irq() from the irq
> > handler of that irq not deadlock?
> >
> > > GPIO being reconfigured.
> > >
> > > The issue occurs when a wakeup IRQ is triggered on a GPIO and the IRQ
> > > handler attempts to reconfigure the same GPIO's pinmux. In this scenario,
> > > msm_pinmux_set_mux() calls disable_irq() which waits for the currently
> > > running IRQ handler to complete, creating a circular dependency that
> > > results in deadlock.
> > >
> > > Using disable_irq_nosync() avoids waiting for the IRQ handler to
> > > complete, preventing the deadlock condition while still properly
> > > disabling the interrupt during pinmux reconfiguration.
> > >
> > > Suggested-by: Prasad Sodagudi <prasad.sodagudi@oss.qualcomm.com>
> >
> > That's weird, I debugged your deadlock for you and told you to make this
> > very change in:
> >
> > https://lore.kernel.org/all/7sxsfyu2kqbycyfftwfhrncwk3dfnubmzhyi2rqi3jtvi5qsnh@bya3cii45zhn/
> >
> > So I guess Prasad told you how to fix this issue before I invested the
> > time helping you?
>
> Yes, that’s correct. Prasad had suggested it earlier.
>
Okay, then this patch looks good.
Regards,
Bjorn
> Thanks,
> Praveen Talari
>
> >
> >
> > Change looks good, and description captures the problem.
> >
> > Reviewed-by: Bjorn Andersson <andersson@kernel.org>
> >
> > Regards,
> > Bjorn
> >
> > > Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> > > ---
> > > drivers/pinctrl/qcom/pinctrl-msm.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
> > > index 67525d542c5b..e99871b90ab9 100644
> > > --- a/drivers/pinctrl/qcom/pinctrl-msm.c
> > > +++ b/drivers/pinctrl/qcom/pinctrl-msm.c
> > > @@ -189,7 +189,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
> > > */
> > > if (d && i != gpio_func &&
> > > !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
> > > - disable_irq(irq);
> > > + disable_irq_nosync(irq);
> > > raw_spin_lock_irqsave(&pctrl->lock, flags);
> > > --
> > > 2.34.1
> > >
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration
2025-11-10 10:10 ` [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration Praveen Talari
2025-11-11 4:08 ` Bjorn Andersson
@ 2025-11-12 12:43 ` Linus Walleij
1 sibling, 0 replies; 11+ messages in thread
From: Linus Walleij @ 2025-11-12 12:43 UTC (permalink / raw)
To: Praveen Talari
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Greg Kroah-Hartman, Jiri Slaby, Dmitry Baryshkov,
linux-arm-msm, devicetree, linux-kernel, linux-gpio, linux-serial,
alexey.klimov, krzk, bryan.odonoghue, jorge.ramirez,
dmitry.baryshkov, Konrad Dybcio, psodagud, djaggi, quic_msavaliy,
quic_vtanuku, quic_arandive, quic_shazhuss, quic_cchiluve,
Prasad Sodagudi
Hi Praveen,
thanks for your patch!
On Mon, Nov 10, 2025 at 11:11 AM Praveen Talari
<praveen.talari@oss.qualcomm.com> wrote:
> Replace disable_irq() with disable_irq_nosync() in msm_pinmux_set_mux()
> to prevent potential deadlock when wakeup IRQ is triggered on the same
> GPIO being reconfigured.
>
> The issue occurs when a wakeup IRQ is triggered on a GPIO and the IRQ
> handler attempts to reconfigure the same GPIO's pinmux. In this scenario,
> msm_pinmux_set_mux() calls disable_irq() which waits for the currently
> running IRQ handler to complete, creating a circular dependency that
> results in deadlock.
>
> Using disable_irq_nosync() avoids waiting for the IRQ handler to
> complete, preventing the deadlock condition while still properly
> disabling the interrupt during pinmux reconfiguration.
>
> Suggested-by: Prasad Sodagudi <prasad.sodagudi@oss.qualcomm.com>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
I applied this patch 2/4 to the pin control tree for fixes.
I removed the word "potential" from subject and text so as to
reflect what Bjorn is saying: it's a very real issue.
Thanks for fixing this!
Linus Walleij
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: (subset) [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms
2025-11-10 10:10 [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms Praveen Talari
` (3 preceding siblings ...)
2025-11-10 10:10 ` [PATCH v1 4/4] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms Praveen Talari
@ 2025-11-14 0:18 ` Bjorn Andersson
4 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2025-11-14 0:18 UTC (permalink / raw)
To: Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Greg Kroah-Hartman, Jiri Slaby, Dmitry Baryshkov,
linux-arm-msm, devicetree, linux-kernel, linux-gpio, linux-serial,
alexey.klimov, krzk, bryan.odonoghue, jorge.ramirez,
dmitry.baryshkov, Praveen Talari
Cc: Konrad Dybcio, psodagud, djaggi, quic_msavaliy, quic_vtanuku,
quic_arandive, quic_shazhuss, quic_cchiluve
On Mon, 10 Nov 2025 15:40:39 +0530, Praveen Talari wrote:
> PM runtime support was previously added to the serial driver but had to
> be reverted due to wakeup IRQ storms and deadlock issues observed on the
> RB1 platform.
>
> Reference:
> https://lore.kernel.org/all/DC0D53ZTNOBU.E8LSD5E5Z8TX@linaro.org/
>
> [...]
Applied, thanks!
[1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm
commit: dd5385c322857ccb760d9bf18619b64b55c27e5f
Best regards,
--
Bjorn Andersson <andersson@kernel.org>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-11-14 0:13 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-10 10:10 [PATCH v1 0/4] Enable Serial on SA8255p Qualcomm platforms Praveen Talari
2025-11-10 10:10 ` [PATCH v1 1/4] arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm Praveen Talari
2025-11-10 11:10 ` Konrad Dybcio
2025-11-10 10:10 ` [PATCH v1 2/4] pinctrl: qcom: msm: Fix potential deadlock in pinmux configuration Praveen Talari
2025-11-11 4:08 ` Bjorn Andersson
2025-11-11 5:22 ` Praveen Talari
2025-11-11 15:35 ` Bjorn Andersson
2025-11-12 12:43 ` Linus Walleij
2025-11-10 10:10 ` [PATCH v1 3/4] serial: qcom-geni: Enable PM runtime for serial driver Praveen Talari
2025-11-10 10:10 ` [PATCH v1 4/4] serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms Praveen Talari
2025-11-14 0:18 ` (subset) [PATCH v1 0/4] " Bjorn Andersson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).