summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>2023-05-05 18:23:01 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-05-13 14:00:54 +0300
commit5f949f140f73696f64acb89a1f16ff9153d017e0 (patch)
tree6197878b3eb4aed452ea5c282ab3b3ff9b4a6b9d /drivers/tty
parentf264f2f6f4788dc031cef60a0cf2881902736709 (diff)
downloadlinux-5f949f140f73696f64acb89a1f16ff9153d017e0.tar.xz
serial: qcom-geni: fix enabling deactivated interrupt
The driver have a race, experienced only with PREEMPT_RT patchset: CPU0 | CPU1 ================================================================== qcom_geni_serial_probe | uart_add_one_port | | serdev_drv_probe | qca_serdev_probe | serdev_device_open | uart_open | uart_startup | qcom_geni_serial_startup | enable_irq | __irq_startup | WARN_ON() | IRQ not activated request_threaded_irq | irq_domain_activate_irq | The warning: 894000.serial: ttyHS1 at MMIO 0x894000 (irq = 144, base_baud = 0) is a MSM serial serial0: tty port ttyHS1 registered WARNING: CPU: 7 PID: 107 at kernel/irq/chip.c:241 __irq_startup+0x78/0xd8 ... qcom_geni_serial 894000.serial: serial engine reports 0 RX bytes in! Adding UART port triggers probe of child serial devices - serdev and eventually Qualcomm Bluetooth hci_qca driver. This opens UART port which enables the interrupt before it got activated in request_threaded_irq(). The issue originates in commit f3974413cf02 ("tty: serial: qcom_geni_serial: Wakeup IRQ cleanup") and discussion on mailing list [1]. However the above commit does not explain why the uart_add_one_port() is moved above requesting interrupt. [1] https://lore.kernel.org/all/5d9f3dfa.1c69fb81.84c4b.30bf@mx.google.com/ Fixes: f3974413cf02 ("tty: serial: qcom_geni_serial: Wakeup IRQ cleanup") Cc: <stable@vger.kernel.org> Cc: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/20230505152301.2181270-1-krzysztof.kozlowski@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 08dc3e2a729c..8582479f0211 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1664,19 +1664,18 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
uport->private_data = &port->private_data;
platform_set_drvdata(pdev, port);
- ret = uart_add_one_port(drv, uport);
- if (ret)
- return ret;
-
irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr,
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
- uart_remove_one_port(drv, uport);
return ret;
}
+ ret = uart_add_one_port(drv, uport);
+ if (ret)
+ return ret;
+
/*
* Set pm_runtime status as ACTIVE so that wakeup_irq gets
* enabled/disabled from dev_pm_arm_wake_irq during system