From nobody Thu Oct 2 11:51:16 2025 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A9A66ADD for ; Wed, 17 Sep 2025 01:04:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758071088; cv=none; b=c50NChTzjFZ6t5P1M1e9PLbgmkyv7eC6C+pa3B8PSG4p9fe3pi+oOpToA2Wn0+2rQc4KBrs9Vd+yoorqo+27L1D/gMG+7U5o34b8lkhrjm8tpATKDja8r7GYNgd2JuDNyKi2rb5YwVUtSZI2NhdkzxhdUkkWFVQ0IXSCTuzLJK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758071088; c=relaxed/simple; bh=4ZcqJ75pPAujwrk5oKHUOHnezTrHikXVf2O8dJL0dbY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Olxq7xcbb1nrr2wzsobGcRzMUINFZrogzl8vHng2OIJlaJ/jtR4znLSZ3hGOYwD0JYuU0CeT30Oh/xGSAtG3ZwPn1shX+CrcKfUProWknqYI4wofnZ43v8nQZpKvoo3jQTpwwgDdYvWSanhueAAbMNK0DzyeGxkKZlsx2ZF871E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=J919dC6T; arc=none smtp.client-ip=209.85.215.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="J919dC6T" Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-b4741e1cde5so493547a12.3 for ; Tue, 16 Sep 2025 18:04:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1758071086; x=1758675886; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=UYOA6+LwL18jl8u1tk3jFNcDy8ykZEeWJOtJwJB5cDo=; b=J919dC6T35y3o3dvGgPmkwcTN5ROt2kPltUjvWSsX5tdLFZOwR7mExMMTRoE0fEBfP fHw/B7+FNob1HXF/1/ufMeXYpojJHsY/ThJb/V5dn0eRLFwq5H7+piE+anB0ieocPPFE TK2I5jp4f0F4JI68nL92p0CJoBa1EXhv6r5gIdfg7/L+oFsHRBlnib3tGexnAn2wmce/ 7jcLn46Xbc9nEzj97OI1BAGk96ssl8qMIl4PPH3jDydlgb6lM+oipI1NTcjm5nDevkCW NjS6yzYp+yhW/fb+OTf7S8gevMZspmoot4Ly62lQI8mCW5MYK7lJJL6tZXicw/VKhDCE hKlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758071086; x=1758675886; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=UYOA6+LwL18jl8u1tk3jFNcDy8ykZEeWJOtJwJB5cDo=; b=m9Wyj0+zuWePTMU3By4qMVt6M3/x+CZUCmXuiynAIrcvuR9MtKHrvuWVb/LLsQmZoR qC+sQp9RTKciN1z257KJLNDhA1CM2COAs1aftpLNWsXLNVFJAwVcBFBP1P4ydgDNR/Ko FqYyzA5MS3uxSXTA1xquG+5ppg2hKMeu9f+AMqXCjYhDUs/Q4cy6lLPJRsCbmj6ZeqYy oaXtk4ZGc/nTYZ+IQwfnnC6wfsY+TWOTVjvQCe8aewwpflTRwsrP29u6NPqpfNAPkkSz bPKM8ICpP5ZoqY5ieT5QgSs/qvVZ9i60u3Sm6zr1kZ213d9vUzNf9iRAMclRTw781JxM 0D/Q== X-Forwarded-Encrypted: i=1; AJvYcCXeRBPX+1Ly7q0i9crMpp/5vdY8g7//KSQa9GS0C2SLTH7UQSenSksKyszxfJR0BmV+Ia5tNS7r3YKGM4A=@vger.kernel.org X-Gm-Message-State: AOJu0YztL87su+QnKV5WqrDEvCGe9sFDrrKW+993KzFfAPBjFbSaGDqW UeYQf/7fjoVmhctSVeHMl5xpMWnjFVW/rOb+96VRRa/stwCHZYDmhR7xBUsT3yqL9C4= X-Gm-Gg: ASbGnctJjp1gBJKkU/IsbPd/QnSwUMhDva5o1QZCv+RxlWEen52VaEvOrmGDQLFjSKs KFVh7Ou4TVWkN54ovl/LIC50zoHFIlQPNDTvdGW/UiehMdyc1PU1hmcgtbtpRA3nKu88uoilP1s wTCFTAm2DeSmCuW4VmKBST22AYbCoUhRCyP5mTOIN6/SnytbKmAz/sqKQyjPTS26Y6irKF8mBx/ l8APm6CmK/YbnyJvA8DEyFvGEXz51FRMBhvSX5SjTjVlaUJwlJyNW8Gs94+JA49NOowVohcObxZ 0L/I2QfwGsWuIU0KllJDswCdnt9L7opBa5OlhsxVijVCpydwY5uB7ZyDCLqmDU7JfEv4uIxS2wj IoiakmlhZ2vfcB7VqZhscmCThSjuxmDY= X-Google-Smtp-Source: AGHT+IG4cg2s7I7MouXl4q8VgdPiSIQsWLG1cTbVLWxNQsLo9TxoOObZ2J8dnaVABh816nCyCR12iw== X-Received: by 2002:a17:90b:33c8:b0:32d:f925:ce58 with SMTP id 98e67ed59e1d1-32ee3fa406cmr221938a91.5.1758071085719; Tue, 16 Sep 2025 18:04:45 -0700 (PDT) Received: from kuoka.. ([218.51.42.121]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7760955263fsm16852911b3a.8.2025.09.16.18.04.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Sep 2025 18:04:45 -0700 (PDT) From: Krzysztof Kozlowski To: Greg Kroah-Hartman , Jiri Slaby , Praveen Talari , "Bryan O'Donoghue" , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org Cc: Krzysztof Kozlowski , Alexey Klimov Subject: [PATCH v2] serial: qcom-geni: Fix blocked task Date: Wed, 17 Sep 2025 10:04:38 +0900 Message-ID: <20250917010437.129912-2-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.48.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Revert commit 1afa70632c39 ("serial: qcom-geni: Enable PM runtime for serial driver") and its dependent commit 86fa39dd6fb7 ("serial: qcom-geni: Enable Serial on SA8255p Qualcomm platforms") because the first one causes regression - hang task on Qualcomm RB1 board (QRB2210) and unable to use serial at all during normal boot: INFO: task kworker/u16:0:12 blocked for more than 42 seconds. Not tainted 6.17.0-rc1-00004-g53e760d89498 #9 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:kworker/u16:0 state:D stack:0 pid:12 tgid:12 ppid:2 = task_flags:0x4208060 flags:0x00000010 Workqueue: async async_run_entry_fn Call trace: __switch_to+0xe8/0x1a0 (T) __schedule+0x290/0x7c0 schedule+0x34/0x118 rpm_resume+0x14c/0x66c rpm_resume+0x2a4/0x66c rpm_resume+0x2a4/0x66c rpm_resume+0x2a4/0x66c __pm_runtime_resume+0x50/0x9c __driver_probe_device+0x58/0x120 driver_probe_device+0x3c/0x154 __driver_attach_async_helper+0x4c/0xc0 async_run_entry_fn+0x34/0xe0 process_one_work+0x148/0x290 worker_thread+0x2c4/0x3e0 kthread+0x118/0x1c0 ret_from_fork+0x10/0x20 The issue was reported on 12th of August and was ignored by author of commits introducing issue for two weeks. Only after complaining author produced a fix which did not work, so if original commits cannot be reliably fixed for 5 weeks, they obviously are buggy and need to be dropped. Fixes: 1afa70632c39 ("serial: qcom-geni: Enable PM runtime for serial drive= r") Reported-by: Alexey Klimov Closes: https://lore.kernel.org/all/DC0D53ZTNOBU.E8LSD5E5Z8TX@linaro.org/ Signed-off-by: Krzysztof Kozlowski Reviewed-by: Alexey Klimov Reviewed-by: Bryan O'Donoghue Tested-by: Alexey Klimov --- Changes in v2: 1. Correct reference to cause (proper commit) in the commit msg. --- drivers/tty/serial/qcom_geni_serial.c | 176 +++----------------------- 1 file changed, 16 insertions(+), 160 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qco= m_geni_serial.c index 0fdda3a1e70b..7c5befe5490d 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -102,16 +101,10 @@ #define DMA_RX_BUF_SIZE 2048 =20 static DEFINE_IDA(port_ida); -#define DOMAIN_IDX_POWER 0 -#define DOMAIN_IDX_PERF 1 =20 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); }; =20 struct qcom_geni_private_data { @@ -149,7 +142,6 @@ struct qcom_geni_serial_port { =20 struct qcom_geni_private_data private_data; const struct qcom_geni_device_data *dev_data; - struct dev_pm_domain_list *pd_list; }; =20 static const struct uart_ops qcom_geni_console_pops; @@ -1301,42 +1293,6 @@ static int geni_serial_set_rate(struct uart_port *up= ort, unsigned int baud) return 0; } =20 -static int geni_serial_set_level(struct uart_port *uport, unsigned int bau= d) -{ - struct qcom_geni_serial_port *port =3D to_dev_port(uport); - struct device *perf_dev =3D 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) @@ -1355,7 +1311,7 @@ static void qcom_geni_serial_set_termios(struct uart_= port *uport, /* baud rate */ baud =3D uart_get_baud_rate(uport, termios, old, 300, 8000000); =20 - ret =3D port->dev_data->set_rate(uport, baud); + ret =3D geni_serial_set_rate(uport, baud); if (ret) return; =20 @@ -1642,27 +1598,8 @@ static int geni_serial_resources_off(struct uart_por= t *uport) return 0; } =20 -static int geni_serial_resource_state(struct uart_port *uport, bool power_= on) +static int geni_serial_resource_init(struct qcom_geni_serial_port *port) { - 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 =3D to_dev_port(uport); - int ret; - - ret =3D dev_pm_domain_attach_list(port->se.dev, - &port->dev_data->pd_data, &port->pd_list); - if (ret <=3D 0) - return -EINVAL; - - return 0; -} - -static int geni_serial_resource_init(struct uart_port *uport) -{ - struct qcom_geni_serial_port *port =3D to_dev_port(uport); int ret; =20 port->se.clk =3D devm_clk_get(port->se.dev, "se"); @@ -1707,10 +1644,10 @@ static void qcom_geni_serial_pm(struct uart_port *u= port, old_state =3D UART_PM_STATE_OFF; =20 if (new_state =3D=3D UART_PM_STATE_ON && old_state =3D=3D UART_PM_STATE_O= FF) - pm_runtime_resume_and_get(uport->dev); + geni_serial_resources_on(uport); else if (new_state =3D=3D UART_PM_STATE_OFF && old_state =3D=3D UART_PM_STATE_ON) - pm_runtime_put_sync(uport->dev); + geni_serial_resources_off(uport); =20 } =20 @@ -1813,16 +1750,13 @@ static int qcom_geni_serial_probe(struct platform_d= evice *pdev) port->se.dev =3D &pdev->dev; port->se.wrapper =3D dev_get_drvdata(pdev->dev.parent); =20 - ret =3D port->dev_data->resources_init(uport); + ret =3D geni_serial_resource_init(port); if (ret) return ret; =20 res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret =3D -EINVAL; - goto error; - } - + if (!res) + return -EINVAL; uport->mapbase =3D res->start; =20 uport->rs485_config =3D qcom_geni_rs485_config; @@ -1834,26 +1768,19 @@ static int qcom_geni_serial_probe(struct platform_d= evice *pdev) if (!data->console) { port->rx_buf =3D devm_kzalloc(uport->dev, DMA_RX_BUF_SIZE, GFP_KERNEL); - if (!port->rx_buf) { - ret =3D -ENOMEM; - goto error; - } + if (!port->rx_buf) + return -ENOMEM; } =20 port->name =3D devm_kasprintf(uport->dev, GFP_KERNEL, "qcom_geni_serial_%s%d", uart_console(uport) ? "console" : "uart", uport->line); - if (!port->name) { - ret =3D -ENOMEM; - goto error; - } + if (!port->name) + return -ENOMEM; =20 irq =3D platform_get_irq(pdev, 0); - if (irq < 0) { - ret =3D irq; - goto error; - } - + if (irq < 0) + return irq; uport->irq =3D irq; uport->has_sysrq =3D IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE); =20 @@ -1875,18 +1802,16 @@ static int qcom_geni_serial_probe(struct platform_d= evice *pdev) IRQF_TRIGGER_HIGH, port->name, uport); if (ret) { dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret); - goto error; + return ret; } =20 ret =3D uart_get_rs485_mode(uport); if (ret) return ret; =20 - devm_pm_runtime_enable(port->se.dev); - ret =3D uart_add_one_port(drv, uport); if (ret) - goto error; + return ret; =20 if (port->wakeup_irq > 0) { device_init_wakeup(&pdev->dev, true); @@ -1896,15 +1821,11 @@ static int qcom_geni_serial_probe(struct platform_d= evice *pdev) device_init_wakeup(&pdev->dev, false); ida_free(&port_ida, uport->line); uart_remove_one_port(drv, uport); - goto error; + return ret; } } =20 return 0; - -error: - dev_pm_domain_detach_list(port->pd_list); - return ret; } =20 static void qcom_geni_serial_remove(struct platform_device *pdev) @@ -1917,31 +1838,6 @@ 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 =3D dev_get_drvdata(dev); - struct uart_port *uport =3D &port->uport; - int ret =3D 0; - - if (port->dev_data->power_state) - ret =3D port->dev_data->power_state(uport, false); - - return ret; -} - -static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *d= ev) -{ - struct qcom_geni_serial_port *port =3D dev_get_drvdata(dev); - struct uart_port *uport =3D &port->uport; - int ret =3D 0; - - if (port->dev_data->power_state) - ret =3D port->dev_data->power_state(uport, true); - - return ret; } =20 static int qcom_geni_serial_suspend(struct device *dev) @@ -1979,46 +1875,14 @@ static int qcom_geni_serial_resume(struct device *d= ev) static const struct qcom_geni_device_data qcom_geni_console_data =3D { .console =3D true, .mode =3D GENI_SE_FIFO, - .resources_init =3D geni_serial_resource_init, - .set_rate =3D geni_serial_set_rate, - .power_state =3D geni_serial_resource_state, }; =20 static const struct qcom_geni_device_data qcom_geni_uart_data =3D { .console =3D false, .mode =3D GENI_SE_DMA, - .resources_init =3D geni_serial_resource_init, - .set_rate =3D geni_serial_set_rate, - .power_state =3D geni_serial_resource_state, -}; - -static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = =3D { - .console =3D true, - .mode =3D GENI_SE_FIFO, - .pd_data =3D { - .pd_flags =3D PD_FLAG_DEV_LINK_ON, - .pd_names =3D (const char*[]) { "power", "perf" }, - .num_pd_names =3D 2, - }, - .resources_init =3D geni_serial_pwr_init, - .set_rate =3D geni_serial_set_level, -}; - -static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data =3D { - .console =3D false, - .mode =3D GENI_SE_DMA, - .pd_data =3D { - .pd_flags =3D PD_FLAG_DEV_LINK_ON, - .pd_names =3D (const char*[]) { "power", "perf" }, - .num_pd_names =3D 2, - }, - .resources_init =3D geni_serial_pwr_init, - .set_rate =3D geni_serial_set_level, }; =20 static const struct dev_pm_ops qcom_geni_serial_pm_ops =3D { - 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) }; =20 @@ -2027,18 +1891,10 @@ static const struct of_device_id qcom_geni_serial_m= atch_table[] =3D { .compatible =3D "qcom,geni-debug-uart", .data =3D &qcom_geni_console_data, }, - { - .compatible =3D "qcom,sa8255p-geni-debug-uart", - .data =3D &sa8255p_qcom_geni_console_data, - }, { .compatible =3D "qcom,geni-uart", .data =3D &qcom_geni_uart_data, }, - { - .compatible =3D "qcom,sa8255p-geni-uart", - .data =3D &sa8255p_qcom_geni_uart_data, - }, {} }; MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table); --=20 2.48.1