Message ID | 20230606091747.2031168-1-wenst@chromium.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp3263725vqr; Tue, 6 Jun 2023 02:34:09 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5BpC+FztMp9FTB0BPjrwTlhV9ZsADgEMg7YfK1bJvRGO609ploIc3dB7HlJsrWqI/DTNV7 X-Received: by 2002:a05:620a:688b:b0:75b:23a0:e7e6 with SMTP id rv11-20020a05620a688b00b0075b23a0e7e6mr1406781qkn.71.1686044049530; Tue, 06 Jun 2023 02:34:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686044049; cv=none; d=google.com; s=arc-20160816; b=iiv2Vdg3kI6vOtbnKn9BdW4uimDlZnbaFoG9At05iaua8XmIezktXGJ2nIgFZcv0xl XzGpkz1pbKvpP6tpmtBJ68Y76/gn+IDmnioPN3gTzs2MxScUdsH7pAv7YKE4r2dXvjs8 p9j6Hr/rP0bcB5BeZJKuHf0d1YU4RftAFF1rzsubvF5rvS9f5uz8fjk06SlTAoV1T/B3 OmSJmLTVNJ4dsFRMIj/8Ajgt4UWDaFPlaeeFc3BIO3pXywBBW9ULrN86mqxTPrxPaBNx grL7arSKrndiQTMKmw8MpvLMlI9rDyoJV5oOmKasLPhEexmYTf0l6FQupAaNI+VvXVLM pMaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=rGevTo0TxQWBjnNLZAtO8QaXWz49rHiQrkaKxeAJxbo=; b=GTp7ybgGh/PycwV7TZXMDQ5S/DV0MdlkUioUXEsWXzIX7Ppu7OPfccoU2FV3z6XpqP lqgyAUO76DEQzwQXUSBmqpxKtHor85CLdQVfQ2rNpdfhQ4ALK2NL8FbplcP0puj5mECD GqdnztB72AKz4Ajw8fBKu1zSeUqqkgIFko7C/5GVWOnsuMi5OQ5Z4M4b8RiFijlpJAHu k57Br6Ap7DHTmoUxC2ifyN30q+mj2znxTN4F7H1/JTvYCyeo6uL6rTEz3kOLLehN47DI BubdtROSXLbPT/l+vchf3MnSrey7Np9rG/40tFKQ9+/CPVYaUZuNqOewflG4ZePRJcBI B/uQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=X+lnGIqf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a13-20020a05620a124d00b0075c9cb484edsi5653686qkl.628.2023.06.06.02.33.55; Tue, 06 Jun 2023 02:34:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=X+lnGIqf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237222AbjFFJUN (ORCPT <rfc822;xxoosimple@gmail.com> + 99 others); Tue, 6 Jun 2023 05:20:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237518AbjFFJUE (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 6 Jun 2023 05:20:04 -0400 Received: from mail-yb1-xb31.google.com (mail-yb1-xb31.google.com [IPv6:2607:f8b0:4864:20::b31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A417E41 for <linux-kernel@vger.kernel.org>; Tue, 6 Jun 2023 02:19:45 -0700 (PDT) Received: by mail-yb1-xb31.google.com with SMTP id 3f1490d57ef6-ba8374001abso6540797276.2 for <linux-kernel@vger.kernel.org>; Tue, 06 Jun 2023 02:19:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1686043171; x=1688635171; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=rGevTo0TxQWBjnNLZAtO8QaXWz49rHiQrkaKxeAJxbo=; b=X+lnGIqfj9O8lA2Ca9TiRtWIfHxjljaEh5reYjc1R1UKjZBJnVs/FhQpyes/Wowwgo iD8E/pSCYtA5ixJ//GPlCZo/kwNsFF2fg0wHuQ8YDEN4c2T7r72aGFKFlJi2e0BVu3uj 90Hv//yDdkM67yzIxz3u5hZGP3mXT9m7UR1NI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686043171; x=1688635171; 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=rGevTo0TxQWBjnNLZAtO8QaXWz49rHiQrkaKxeAJxbo=; b=PQLgZUmr088lI8cufvpE2t+J5tmpkipfd6Oj9v9xBAgHLPaczM8A2A+bml2cGDeCAx 8l0OS8weZ7EsvwOHMswTIfQn1cRtQ6IOF23No8T7w9zpRIdQla9+iCPOwf23idqhwuty EzURWVWhfSrcoCdxHwFqHW8/Yocnl7jnZ/zaDkQjTEMqoQFxLkkxJUXK7iYOxTDQJ6lV 7Zc8MWQUk26s97cHCF2Q/jaCLQjKHdBThbUmpBZCEE7nXujaxZL99apVZsyuPZVvaloT NSSZzdU54OMQLZ/NLVcx74CJiAKhfYftHK4gG3/QDKXeI3jnEWBe2NMM/P5cgRt1JsD/ 4A5Q== X-Gm-Message-State: AC+VfDz/bNFkubb48C9BhO8vTvQkZsVOKc4z20RcGOZz2ycdnJpq5bM+ fVk9yhklWNjAargI6F6xXct/iA== X-Received: by 2002:a5b:6cb:0:b0:b9e:8a8b:b073 with SMTP id r11-20020a5b06cb000000b00b9e8a8bb073mr1351788ybq.39.1686043171422; Tue, 06 Jun 2023 02:19:31 -0700 (PDT) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:62f6:f76c:5e28:6293]) by smtp.gmail.com with ESMTPSA id h8-20020a170902f54800b001993a1fce7bsm8042854plf.196.2023.06.06.02.19.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jun 2023 02:19:31 -0700 (PDT) From: Chen-Yu Tsai <wenst@chromium.org> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jiri Slaby <jirislaby@kernel.org>, Matthias Brugger <matthias.bgg@gmail.com> Cc: Chen-Yu Tsai <wenst@chromium.org>, John Ogness <john.ogness@linutronix.de>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, linux-serial@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Tony Lindgren <tony@atomide.com> Subject: [PATCH] serial: 8250_mtk: Simplify clock sequencing and runtime PM Date: Tue, 6 Jun 2023 17:17:45 +0800 Message-ID: <20230606091747.2031168-1-wenst@chromium.org> X-Mailer: git-send-email 2.41.0.rc0.172.g3f132b7071-goog MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767945325261954146?= X-GMAIL-MSGID: =?utf-8?q?1767945325261954146?= |
Series |
serial: 8250_mtk: Simplify clock sequencing and runtime PM
|
|
Commit Message
Chen-Yu Tsai
June 6, 2023, 9:17 a.m. UTC
The 8250_mtk driver's runtime PM support has some issues:
- The bus clock is enabled (through runtime PM callback) later than a
register write
- runtime PM resume callback directly called in probe, but no
pm_runtime_set_active() call is present
- UART PM function calls the callbacks directly, _and_ calls runtime
PM API
- runtime PM callbacks try to do reference counting, adding yet another
count between runtime PM and clocks
This fragile setup worked in a way, but broke recently with runtime PM
support added to the serial core. The system would hang when the UART
console was probed and brought up.
Tony provided some potential fixes [1][2], though they were still a bit
complicated. The 8250_dw driver, which the 8250_mtk driver might have
been based on, has a similar structure but simpler runtime PM usage.
Simplify clock sequencing and runtime PM support in the 8250_mtk driver.
Specifically, the clock is acquired enabled and assumed to be active,
unless toggled through runtime PM suspend/resume. Reference counting is
removed and left to the runtime PM core. The serial pm function now
only calls the runtime PM API.
[1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/
[2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/
Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM")
Suggested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/tty/serial/8250/8250_mtk.c | 50 ++++++------------------------
1 file changed, 10 insertions(+), 40 deletions(-)
Comments
Il 06/06/23 11:17, Chen-Yu Tsai ha scritto: > The 8250_mtk driver's runtime PM support has some issues: > > - The bus clock is enabled (through runtime PM callback) later than a > register write > - runtime PM resume callback directly called in probe, but no > pm_runtime_set_active() call is present > - UART PM function calls the callbacks directly, _and_ calls runtime > PM API > - runtime PM callbacks try to do reference counting, adding yet another > count between runtime PM and clocks > > This fragile setup worked in a way, but broke recently with runtime PM > support added to the serial core. The system would hang when the UART > console was probed and brought up. > > Tony provided some potential fixes [1][2], though they were still a bit > complicated. The 8250_dw driver, which the 8250_mtk driver might have > been based on, has a similar structure but simpler runtime PM usage. > > Simplify clock sequencing and runtime PM support in the 8250_mtk driver. > Specifically, the clock is acquired enabled and assumed to be active, > unless toggled through runtime PM suspend/resume. Reference counting is > removed and left to the runtime PM core. The serial pm function now > only calls the runtime PM API. > > [1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/ > [2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > > Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") > Suggested-by: Tony Lindgren <tony@atomide.com> > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> You're both cleaning this up and solving a critical issue and I completely agree about doing that. I can imagine what actually fixes the driver, but still, is it possible to split this commit in two? One that solves the issue, one that performs the much needed cleanups. If it's not possible, then we can leave this commit as it is... and if the problem about splitting is the Fixes tag... well, we don't forcefully need it: after all, issues started arising after runtime PM support for 8250 landed and before that the driver technically worked, even though it was fragile. Thanks, Angelo > --- > drivers/tty/serial/8250/8250_mtk.c | 50 ++++++------------------------ > 1 file changed, 10 insertions(+), 40 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c > index aa8e98164d68..74da5676ce67 100644 > --- a/drivers/tty/serial/8250/8250_mtk.c > +++ b/drivers/tty/serial/8250/8250_mtk.c > @@ -431,12 +431,7 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) > while > (serial_in(up, MTK_UART_DEBUG0)); > > - if (data->clk_count == 0U) { > - dev_dbg(dev, "%s clock count is 0\n", __func__); > - } else { > - clk_disable_unprepare(data->bus_clk); > - data->clk_count--; > - } > + clk_disable_unprepare(data->bus_clk); > > return 0; > } > @@ -444,19 +439,8 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) > static int __maybe_unused mtk8250_runtime_resume(struct device *dev) > { > struct mtk8250_data *data = dev_get_drvdata(dev); > - int err; > > - if (data->clk_count > 0U) { > - dev_dbg(dev, "%s clock count is %d\n", __func__, > - data->clk_count); > - } else { > - err = clk_prepare_enable(data->bus_clk); > - if (err) { > - dev_warn(dev, "Can't enable bus clock\n"); > - return err; > - } > - data->clk_count++; > - } > + clk_prepare_enable(data->bus_clk); > > return 0; > } > @@ -465,14 +449,12 @@ static void > mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) > { > if (!state) > - if (!mtk8250_runtime_resume(port->dev)) > - pm_runtime_get_sync(port->dev); > + pm_runtime_get_sync(port->dev); > > serial8250_do_pm(port, state, old); > > if (state) > - if (!pm_runtime_put_sync_suspend(port->dev)) > - mtk8250_runtime_suspend(port->dev); > + pm_runtime_put_sync_suspend(port->dev); > } > > #ifdef CONFIG_SERIAL_8250_DMA > @@ -504,7 +486,7 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, > return 0; > } > > - data->bus_clk = devm_clk_get(&pdev->dev, "bus"); > + data->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); > if (IS_ERR(data->bus_clk)) > return PTR_ERR(data->bus_clk); > > @@ -587,25 +569,16 @@ static int mtk8250_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, data); > > - pm_runtime_enable(&pdev->dev); > - err = mtk8250_runtime_resume(&pdev->dev); > - if (err) > - goto err_pm_disable; > - > data->line = serial8250_register_8250_port(&uart); > - if (data->line < 0) { > - err = data->line; > - goto err_pm_disable; > - } > + if (data->line < 0) > + return data->line; > > data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1); > > - return 0; > - > -err_pm_disable: > - pm_runtime_disable(&pdev->dev); > + pm_runtime_set_active(&pdev->dev); > + pm_runtime_enable(&pdev->dev); > > - return err; > + return 0; > } > > static int mtk8250_remove(struct platform_device *pdev) > @@ -619,9 +592,6 @@ static int mtk8250_remove(struct platform_device *pdev) > pm_runtime_disable(&pdev->dev); > pm_runtime_put_noidle(&pdev->dev); > > - if (!pm_runtime_status_suspended(&pdev->dev)) > - mtk8250_runtime_suspend(&pdev->dev); > - > return 0; > } >
On Tue, Jun 6, 2023 at 5:36 PM AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> wrote: > > Il 06/06/23 11:17, Chen-Yu Tsai ha scritto: > > The 8250_mtk driver's runtime PM support has some issues: > > > > - The bus clock is enabled (through runtime PM callback) later than a > > register write > > - runtime PM resume callback directly called in probe, but no > > pm_runtime_set_active() call is present > > - UART PM function calls the callbacks directly, _and_ calls runtime > > PM API > > - runtime PM callbacks try to do reference counting, adding yet another > > count between runtime PM and clocks > > > > This fragile setup worked in a way, but broke recently with runtime PM > > support added to the serial core. The system would hang when the UART > > console was probed and brought up. > > > > Tony provided some potential fixes [1][2], though they were still a bit > > complicated. The 8250_dw driver, which the 8250_mtk driver might have > > been based on, has a similar structure but simpler runtime PM usage. > > > > Simplify clock sequencing and runtime PM support in the 8250_mtk driver. > > Specifically, the clock is acquired enabled and assumed to be active, > > unless toggled through runtime PM suspend/resume. Reference counting is > > removed and left to the runtime PM core. The serial pm function now > > only calls the runtime PM API. > > > > [1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/ > > [2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > > > > Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") > > Suggested-by: Tony Lindgren <tony@atomide.com> > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> > > You're both cleaning this up and solving a critical issue and I completely agree > about doing that. > > I can imagine what actually fixes the driver, but still, is it possible to split > this commit in two? > One that solves the issue, one that performs the much needed cleanups. > > If it's not possible, then we can leave this commit as it is... and if the problem > about splitting is the Fixes tag... well, we don't forcefully need it: after all, > issues started arising after runtime PM support for 8250 landed and before that the > driver technically worked, even though it was fragile. The pure fix would look like what Tony posted [1]. However it would add stuff that isn't strictly needed after the cleanup. Doing it in one patch results in less churn. Think of it another way: it's a nice cleanup that just so happens to fix a regression. As for the fixes tag, it's there so other people potentially doing backports of the 8250 runtime PM work can spot this followup fix. ChenYu [1] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > Thanks, > Angelo > > > --- > > drivers/tty/serial/8250/8250_mtk.c | 50 ++++++------------------------ > > 1 file changed, 10 insertions(+), 40 deletions(-) > > > > diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c > > index aa8e98164d68..74da5676ce67 100644 > > --- a/drivers/tty/serial/8250/8250_mtk.c > > +++ b/drivers/tty/serial/8250/8250_mtk.c > > @@ -431,12 +431,7 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) > > while > > (serial_in(up, MTK_UART_DEBUG0)); > > > > - if (data->clk_count == 0U) { > > - dev_dbg(dev, "%s clock count is 0\n", __func__); > > - } else { > > - clk_disable_unprepare(data->bus_clk); > > - data->clk_count--; > > - } > > + clk_disable_unprepare(data->bus_clk); > > > > return 0; > > } > > @@ -444,19 +439,8 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) > > static int __maybe_unused mtk8250_runtime_resume(struct device *dev) > > { > > struct mtk8250_data *data = dev_get_drvdata(dev); > > - int err; > > > > - if (data->clk_count > 0U) { > > - dev_dbg(dev, "%s clock count is %d\n", __func__, > > - data->clk_count); > > - } else { > > - err = clk_prepare_enable(data->bus_clk); > > - if (err) { > > - dev_warn(dev, "Can't enable bus clock\n"); > > - return err; > > - } > > - data->clk_count++; > > - } > > + clk_prepare_enable(data->bus_clk); > > > > return 0; > > } > > @@ -465,14 +449,12 @@ static void > > mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) > > { > > if (!state) > > - if (!mtk8250_runtime_resume(port->dev)) > > - pm_runtime_get_sync(port->dev); > > + pm_runtime_get_sync(port->dev); > > > > serial8250_do_pm(port, state, old); > > > > if (state) > > - if (!pm_runtime_put_sync_suspend(port->dev)) > > - mtk8250_runtime_suspend(port->dev); > > + pm_runtime_put_sync_suspend(port->dev); > > } > > > > #ifdef CONFIG_SERIAL_8250_DMA > > @@ -504,7 +486,7 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, > > return 0; > > } > > > > - data->bus_clk = devm_clk_get(&pdev->dev, "bus"); > > + data->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); > > if (IS_ERR(data->bus_clk)) > > return PTR_ERR(data->bus_clk); > > > > @@ -587,25 +569,16 @@ static int mtk8250_probe(struct platform_device *pdev) > > > > platform_set_drvdata(pdev, data); > > > > - pm_runtime_enable(&pdev->dev); > > - err = mtk8250_runtime_resume(&pdev->dev); > > - if (err) > > - goto err_pm_disable; > > - > > data->line = serial8250_register_8250_port(&uart); > > - if (data->line < 0) { > > - err = data->line; > > - goto err_pm_disable; > > - } > > + if (data->line < 0) > > + return data->line; > > > > data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1); > > > > - return 0; > > - > > -err_pm_disable: > > - pm_runtime_disable(&pdev->dev); > > + pm_runtime_set_active(&pdev->dev); > > + pm_runtime_enable(&pdev->dev); > > > > - return err; > > + return 0; > > } > > > > static int mtk8250_remove(struct platform_device *pdev) > > @@ -619,9 +592,6 @@ static int mtk8250_remove(struct platform_device *pdev) > > pm_runtime_disable(&pdev->dev); > > pm_runtime_put_noidle(&pdev->dev); > > > > - if (!pm_runtime_status_suspended(&pdev->dev)) > > - mtk8250_runtime_suspend(&pdev->dev); > > - > > return 0; > > } > > > >
On Tue, 6 Jun 2023, Chen-Yu Tsai wrote: > On Tue, Jun 6, 2023 at 5:36 PM AngeloGioacchino Del Regno > <angelogioacchino.delregno@collabora.com> wrote: > > > > Il 06/06/23 11:17, Chen-Yu Tsai ha scritto: > > > The 8250_mtk driver's runtime PM support has some issues: > > > > > > - The bus clock is enabled (through runtime PM callback) later than a > > > register write > > > - runtime PM resume callback directly called in probe, but no > > > pm_runtime_set_active() call is present > > > - UART PM function calls the callbacks directly, _and_ calls runtime > > > PM API > > > - runtime PM callbacks try to do reference counting, adding yet another > > > count between runtime PM and clocks > > > > > > This fragile setup worked in a way, but broke recently with runtime PM > > > support added to the serial core. The system would hang when the UART > > > console was probed and brought up. > > > > > > Tony provided some potential fixes [1][2], though they were still a bit > > > complicated. The 8250_dw driver, which the 8250_mtk driver might have > > > been based on, has a similar structure but simpler runtime PM usage. > > > > > > Simplify clock sequencing and runtime PM support in the 8250_mtk driver. > > > Specifically, the clock is acquired enabled and assumed to be active, > > > unless toggled through runtime PM suspend/resume. Reference counting is > > > removed and left to the runtime PM core. The serial pm function now > > > only calls the runtime PM API. > > > > > > [1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/ > > > [2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > > > > > > Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") > > > Suggested-by: Tony Lindgren <tony@atomide.com> > > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> > > > > You're both cleaning this up and solving a critical issue and I > > completely agree about doing that. > > > > I can imagine what actually fixes the driver, but still, is it > > possible to split this commit in two? > > One that solves the issue, one that performs the much needed cleanups. > > > > If it's not possible, then we can leave this commit as it is... and if the problem > > about splitting is the Fixes tag... well, we don't forcefully need it: after all, > > issues started arising after runtime PM support for 8250 landed and before that the > > driver technically worked, even though it was fragile. > > The pure fix would look like what Tony posted [1]. However it would add stuff > that isn't strictly needed after the cleanup. Doing it in one patch results > in less churn. Think of it another way: it's a nice cleanup that just so > happens to fix a regression. > > As for the fixes tag, it's there so other people potentially doing backports > of the 8250 runtime PM work can spot this followup fix. Tony's patch is recent enough to not have progressed beyond tty-next so fixing it shouldn't really require paying that much attention to stable rules wrt. Fixes tag and minimality. As the target currently is tty-next, a cleanup which also happens to fix the issue seems perfectly fine.
On Tue, Jun 06, 2023 at 01:21:55PM +0300, Ilpo Järvinen wrote: > On Tue, 6 Jun 2023, Chen-Yu Tsai wrote: > > > On Tue, Jun 6, 2023 at 5:36 PM AngeloGioacchino Del Regno > > <angelogioacchino.delregno@collabora.com> wrote: > > > > > > Il 06/06/23 11:17, Chen-Yu Tsai ha scritto: > > > > The 8250_mtk driver's runtime PM support has some issues: > > > > > > > > - The bus clock is enabled (through runtime PM callback) later than a > > > > register write > > > > - runtime PM resume callback directly called in probe, but no > > > > pm_runtime_set_active() call is present > > > > - UART PM function calls the callbacks directly, _and_ calls runtime > > > > PM API > > > > - runtime PM callbacks try to do reference counting, adding yet another > > > > count between runtime PM and clocks > > > > > > > > This fragile setup worked in a way, but broke recently with runtime PM > > > > support added to the serial core. The system would hang when the UART > > > > console was probed and brought up. > > > > > > > > Tony provided some potential fixes [1][2], though they were still a bit > > > > complicated. The 8250_dw driver, which the 8250_mtk driver might have > > > > been based on, has a similar structure but simpler runtime PM usage. > > > > > > > > Simplify clock sequencing and runtime PM support in the 8250_mtk driver. > > > > Specifically, the clock is acquired enabled and assumed to be active, > > > > unless toggled through runtime PM suspend/resume. Reference counting is > > > > removed and left to the runtime PM core. The serial pm function now > > > > only calls the runtime PM API. > > > > > > > > [1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/ > > > > [2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > > > > > > > > Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") > > > > Suggested-by: Tony Lindgren <tony@atomide.com> > > > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> > > > > > > You're both cleaning this up and solving a critical issue and I > > > completely agree about doing that. > > > > > > I can imagine what actually fixes the driver, but still, is it > > > possible to split this commit in two? > > > One that solves the issue, one that performs the much needed cleanups. > > > > > > If it's not possible, then we can leave this commit as it is... and if the problem > > > about splitting is the Fixes tag... well, we don't forcefully need it: after all, > > > issues started arising after runtime PM support for 8250 landed and before that the > > > driver technically worked, even though it was fragile. > > > > The pure fix would look like what Tony posted [1]. However it would add stuff > > that isn't strictly needed after the cleanup. Doing it in one patch results > > in less churn. Think of it another way: it's a nice cleanup that just so > > happens to fix a regression. > > > > As for the fixes tag, it's there so other people potentially doing backports > > of the 8250 runtime PM work can spot this followup fix. > > Tony's patch is recent enough to not have progressed beyond tty-next so > fixing it shouldn't really require paying that much attention to stable > rules wrt. Fixes tag and minimality. > > As the target currently is tty-next, a cleanup which also happens to fix > the issue seems perfectly fine. The Fixes: tag is relevant here, please don't dissuade people from using them. greg k-h
On Tue, 6 Jun 2023, Greg Kroah-Hartman wrote: > On Tue, Jun 06, 2023 at 01:21:55PM +0300, Ilpo Järvinen wrote: > > On Tue, 6 Jun 2023, Chen-Yu Tsai wrote: > > > > > On Tue, Jun 6, 2023 at 5:36 PM AngeloGioacchino Del Regno > > > <angelogioacchino.delregno@collabora.com> wrote: > > > > > > > > Il 06/06/23 11:17, Chen-Yu Tsai ha scritto: > > > > > The 8250_mtk driver's runtime PM support has some issues: > > > > > > > > > > - The bus clock is enabled (through runtime PM callback) later than a > > > > > register write > > > > > - runtime PM resume callback directly called in probe, but no > > > > > pm_runtime_set_active() call is present > > > > > - UART PM function calls the callbacks directly, _and_ calls runtime > > > > > PM API > > > > > - runtime PM callbacks try to do reference counting, adding yet another > > > > > count between runtime PM and clocks > > > > > > > > > > This fragile setup worked in a way, but broke recently with runtime PM > > > > > support added to the serial core. The system would hang when the UART > > > > > console was probed and brought up. > > > > > > > > > > Tony provided some potential fixes [1][2], though they were still a bit > > > > > complicated. The 8250_dw driver, which the 8250_mtk driver might have > > > > > been based on, has a similar structure but simpler runtime PM usage. > > > > > > > > > > Simplify clock sequencing and runtime PM support in the 8250_mtk driver. > > > > > Specifically, the clock is acquired enabled and assumed to be active, > > > > > unless toggled through runtime PM suspend/resume. Reference counting is > > > > > removed and left to the runtime PM core. The serial pm function now > > > > > only calls the runtime PM API. > > > > > > > > > > [1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/ > > > > > [2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > > > > > > > > > > Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") > > > > > Suggested-by: Tony Lindgren <tony@atomide.com> > > > > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> > > > > > > > > You're both cleaning this up and solving a critical issue and I > > > > completely agree about doing that. > > > > > > > > I can imagine what actually fixes the driver, but still, is it > > > > possible to split this commit in two? > > > > One that solves the issue, one that performs the much needed cleanups. > > > > > > > > If it's not possible, then we can leave this commit as it is... and if the problem > > > > about splitting is the Fixes tag... well, we don't forcefully need it: after all, > > > > issues started arising after runtime PM support for 8250 landed and before that the > > > > driver technically worked, even though it was fragile. > > > > > > The pure fix would look like what Tony posted [1]. However it would add stuff > > > that isn't strictly needed after the cleanup. Doing it in one patch results > > > in less churn. Think of it another way: it's a nice cleanup that just so > > > happens to fix a regression. > > > > > > As for the fixes tag, it's there so other people potentially doing backports > > > of the 8250 runtime PM work can spot this followup fix. > > > > Tony's patch is recent enough to not have progressed beyond tty-next so > > fixing it shouldn't really require paying that much attention to stable > > rules wrt. Fixes tag and minimality. > > > > As the target currently is tty-next, a cleanup which also happens to fix > > the issue seems perfectly fine. > > The Fixes: tag is relevant here, please don't dissuade people from using > them. Not including Fixes tag was definitely among the things I tried to say. What I meant was that this patch, given the current time frame, likely gets included within the same "next cycle". So it fixes the issue even before the commit it fixes ends up into any rc not to speak of stables. As such, stable kernel rules don't seem relevant. So creating a "fix patch" with extra stuff just for the sake of it and then removing the extra stuff away in the cleanup change seems unnecessary to me as the cleanup itself would fix the same issue. I'm not even sure if it's proper to call this change a cleanup, it just takes a different avenue to fix the problem by removing some complexity from old.
Il 06/06/23 11:17, Chen-Yu Tsai ha scritto: > The 8250_mtk driver's runtime PM support has some issues: > > - The bus clock is enabled (through runtime PM callback) later than a > register write > - runtime PM resume callback directly called in probe, but no > pm_runtime_set_active() call is present > - UART PM function calls the callbacks directly, _and_ calls runtime > PM API > - runtime PM callbacks try to do reference counting, adding yet another > count between runtime PM and clocks > > This fragile setup worked in a way, but broke recently with runtime PM > support added to the serial core. The system would hang when the UART > console was probed and brought up. > > Tony provided some potential fixes [1][2], though they were still a bit > complicated. The 8250_dw driver, which the 8250_mtk driver might have > been based on, has a similar structure but simpler runtime PM usage. > > Simplify clock sequencing and runtime PM support in the 8250_mtk driver. > Specifically, the clock is acquired enabled and assumed to be active, > unless toggled through runtime PM suspend/resume. Reference counting is > removed and left to the runtime PM core. The serial pm function now > only calls the runtime PM API. > > [1] https://lore.kernel.org/linux-serial/20230602092701.GP14287@atomide.com/ > [2] https://lore.kernel.org/linux-serial/20230605061511.GW14287@atomide.com/ > > Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") > Suggested-by: Tony Lindgren <tony@atomide.com> > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/tty/serial/8250/8250_mtk.c | 50 ++++++------------------------ > 1 file changed, 10 insertions(+), 40 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c > index aa8e98164d68..74da5676ce67 100644 > --- a/drivers/tty/serial/8250/8250_mtk.c > +++ b/drivers/tty/serial/8250/8250_mtk.c > @@ -431,12 +431,7 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) > while > (serial_in(up, MTK_UART_DEBUG0)); > > - if (data->clk_count == 0U) { > - dev_dbg(dev, "%s clock count is 0\n", __func__); > - } else { > - clk_disable_unprepare(data->bus_clk); > - data->clk_count--; > - } > + clk_disable_unprepare(data->bus_clk); > > return 0; > } > @@ -444,19 +439,8 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) > static int __maybe_unused mtk8250_runtime_resume(struct device *dev) > { > struct mtk8250_data *data = dev_get_drvdata(dev); > - int err; > > - if (data->clk_count > 0U) { > - dev_dbg(dev, "%s clock count is %d\n", __func__, > - data->clk_count); > - } else { > - err = clk_prepare_enable(data->bus_clk); > - if (err) { > - dev_warn(dev, "Can't enable bus clock\n"); > - return err; > - } > - data->clk_count++; > - } > + clk_prepare_enable(data->bus_clk); > > return 0; > } > @@ -465,14 +449,12 @@ static void > mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) > { > if (!state) > - if (!mtk8250_runtime_resume(port->dev)) > - pm_runtime_get_sync(port->dev); > + pm_runtime_get_sync(port->dev); > > serial8250_do_pm(port, state, old); > > if (state) > - if (!pm_runtime_put_sync_suspend(port->dev)) > - mtk8250_runtime_suspend(port->dev); > + pm_runtime_put_sync_suspend(port->dev); > } > > #ifdef CONFIG_SERIAL_8250_DMA > @@ -504,7 +486,7 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, > return 0; > } > > - data->bus_clk = devm_clk_get(&pdev->dev, "bus"); > + data->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); > if (IS_ERR(data->bus_clk)) > return PTR_ERR(data->bus_clk); > > @@ -587,25 +569,16 @@ static int mtk8250_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, data); > > - pm_runtime_enable(&pdev->dev); > - err = mtk8250_runtime_resume(&pdev->dev); > - if (err) > - goto err_pm_disable; > - > data->line = serial8250_register_8250_port(&uart); > - if (data->line < 0) { > - err = data->line; > - goto err_pm_disable; > - } > + if (data->line < 0) > + return data->line; > > data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1); > > - return 0; > - > -err_pm_disable: > - pm_runtime_disable(&pdev->dev); > + pm_runtime_set_active(&pdev->dev); > + pm_runtime_enable(&pdev->dev); > > - return err; > + return 0; > } > > static int mtk8250_remove(struct platform_device *pdev) > @@ -619,9 +592,6 @@ static int mtk8250_remove(struct platform_device *pdev) > pm_runtime_disable(&pdev->dev); > pm_runtime_put_noidle(&pdev->dev); > > - if (!pm_runtime_status_suspended(&pdev->dev)) > - mtk8250_runtime_suspend(&pdev->dev); > - > return 0; > } >
* Chen-Yu Tsai <wenst@chromium.org> [230606 09:19]: > The 8250_mtk driver's runtime PM support has some issues: > > - The bus clock is enabled (through runtime PM callback) later than a > register write > - runtime PM resume callback directly called in probe, but no > pm_runtime_set_active() call is present > - UART PM function calls the callbacks directly, _and_ calls runtime > PM API > - runtime PM callbacks try to do reference counting, adding yet another > count between runtime PM and clocks > > This fragile setup worked in a way, but broke recently with runtime PM > support added to the serial core. The system would hang when the UART > console was probed and brought up. Great, looks like a good for Linux next to me: Reviewed-by: Tony Lindgren <tony@atomide.com>
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index aa8e98164d68..74da5676ce67 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -431,12 +431,7 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) while (serial_in(up, MTK_UART_DEBUG0)); - if (data->clk_count == 0U) { - dev_dbg(dev, "%s clock count is 0\n", __func__); - } else { - clk_disable_unprepare(data->bus_clk); - data->clk_count--; - } + clk_disable_unprepare(data->bus_clk); return 0; } @@ -444,19 +439,8 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) static int __maybe_unused mtk8250_runtime_resume(struct device *dev) { struct mtk8250_data *data = dev_get_drvdata(dev); - int err; - if (data->clk_count > 0U) { - dev_dbg(dev, "%s clock count is %d\n", __func__, - data->clk_count); - } else { - err = clk_prepare_enable(data->bus_clk); - if (err) { - dev_warn(dev, "Can't enable bus clock\n"); - return err; - } - data->clk_count++; - } + clk_prepare_enable(data->bus_clk); return 0; } @@ -465,14 +449,12 @@ static void mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) { if (!state) - if (!mtk8250_runtime_resume(port->dev)) - pm_runtime_get_sync(port->dev); + pm_runtime_get_sync(port->dev); serial8250_do_pm(port, state, old); if (state) - if (!pm_runtime_put_sync_suspend(port->dev)) - mtk8250_runtime_suspend(port->dev); + pm_runtime_put_sync_suspend(port->dev); } #ifdef CONFIG_SERIAL_8250_DMA @@ -504,7 +486,7 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, return 0; } - data->bus_clk = devm_clk_get(&pdev->dev, "bus"); + data->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); if (IS_ERR(data->bus_clk)) return PTR_ERR(data->bus_clk); @@ -587,25 +569,16 @@ static int mtk8250_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - pm_runtime_enable(&pdev->dev); - err = mtk8250_runtime_resume(&pdev->dev); - if (err) - goto err_pm_disable; - data->line = serial8250_register_8250_port(&uart); - if (data->line < 0) { - err = data->line; - goto err_pm_disable; - } + if (data->line < 0) + return data->line; data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1); - return 0; - -err_pm_disable: - pm_runtime_disable(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); - return err; + return 0; } static int mtk8250_remove(struct platform_device *pdev) @@ -619,9 +592,6 @@ static int mtk8250_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); - if (!pm_runtime_status_suspended(&pdev->dev)) - mtk8250_runtime_suspend(&pdev->dev); - return 0; }