From: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
To: Bjorn Andersson <andersson@kernel.org>,
Linus Walleij <linusw@kernel.org>
Cc: linux-arm-msm@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-kernel@vger.kernel.org,
srinivas.kandagatla@oss.qualcomm.com
Subject: [PATCH v1 1/3] pinctrl: qcom: lpass-lpi: Switch to PM clock framework for runtime PM
Date: Mon, 13 Apr 2026 17:52:31 +0530 [thread overview]
Message-ID: <20260413122233.375945-2-ajay.nandam@oss.qualcomm.com> (raw)
In-Reply-To: <20260413122233.375945-1-ajay.nandam@oss.qualcomm.com>
Convert the LPASS LPI pinctrl driver to use the PM clock framework for
runtime power management.
This allows the LPASS LPI pinctrl driver to drop clock votes when idle,
improves power efficiency on platforms using LPASS LPI island mode, and
aligns the driver with common runtime PM patterns used across Qualcomm
LPASS subsystems.
Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
---
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 36 +++++++++++++------
drivers/pinctrl/qcom/pinctrl-lpass-lpi.h | 2 ++
.../pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c | 5 +++
3 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
index 76aed3296..6d50e06ef 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
@@ -14,15 +14,16 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
+#include <linux/pm_runtime.h>
#include <linux/pinctrl/pinmux.h>
#include "../pinctrl-utils.h"
#include "pinctrl-lpass-lpi.h"
+#include <linux/pm_clock.h>
#define MAX_NR_GPIO 32
#define GPIO_FUNC 0
-#define MAX_LPI_NUM_CLKS 2
struct lpi_pinctrl {
struct device *dev;
@@ -31,7 +32,6 @@ struct lpi_pinctrl {
struct pinctrl_desc desc;
char __iomem *tlmm_base;
char __iomem *slew_base;
- struct clk_bulk_data clks[MAX_LPI_NUM_CLKS];
/* Protects from concurrent register updates */
struct mutex lock;
DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
@@ -480,9 +480,6 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
pctrl->data = data;
pctrl->dev = &pdev->dev;
- pctrl->clks[0].id = "core";
- pctrl->clks[1].id = "audio";
-
pctrl->tlmm_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctrl->tlmm_base))
return dev_err_probe(dev, PTR_ERR(pctrl->tlmm_base),
@@ -495,13 +492,17 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
"Slew resource not provided\n");
}
- ret = devm_clk_bulk_get_optional(dev, MAX_LPI_NUM_CLKS, pctrl->clks);
+ ret = devm_pm_clk_create(dev);
if (ret)
return ret;
- ret = clk_bulk_prepare_enable(MAX_LPI_NUM_CLKS, pctrl->clks);
- if (ret)
- return dev_err_probe(dev, ret, "Can't enable clocks\n");
+ ret = of_pm_clk_add_clks(dev);
+ if (ret < 0)
+ return ret;
+
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
pctrl->desc.pctlops = &lpi_gpio_pinctrl_ops;
pctrl->desc.pmxops = &lpi_gpio_pinmux_ops;
@@ -539,20 +540,33 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
return 0;
err_pinctrl:
+ pm_runtime_disable(dev);
mutex_destroy(&pctrl->lock);
- clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
return ret;
}
EXPORT_SYMBOL_GPL(lpi_pinctrl_probe);
+int lpi_pinctrl_runtime_suspend(struct device *dev)
+{
+ return pm_clk_suspend(dev);
+}
+EXPORT_SYMBOL_GPL(lpi_pinctrl_runtime_suspend);
+
+int lpi_pinctrl_runtime_resume(struct device *dev)
+{
+ return pm_clk_resume(dev);
+}
+EXPORT_SYMBOL_GPL(lpi_pinctrl_runtime_resume);
+
void lpi_pinctrl_remove(struct platform_device *pdev)
{
struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev);
int i;
+ pm_runtime_disable(pctrl->dev);
+
mutex_destroy(&pctrl->lock);
- clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
for (i = 0; i < pctrl->data->npins; i++)
pinctrl_generic_remove_group(pctrl->ctrl, i);
diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
index f48368492..ae94ef48d 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
@@ -107,5 +107,7 @@ struct lpi_pinctrl_variant_data {
int lpi_pinctrl_probe(struct platform_device *pdev);
void lpi_pinctrl_remove(struct platform_device *pdev);
+int lpi_pinctrl_runtime_suspend(struct device *dev);
+int lpi_pinctrl_runtime_resume(struct device *dev);
#endif /*__PINCTRL_LPASS_LPI_H__*/
diff --git a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c
index 750f41031..2d955643d 100644
--- a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c
@@ -139,10 +139,15 @@ static const struct of_device_id lpi_pinctrl_of_match[] = {
};
MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match);
+static const struct dev_pm_ops lpi_pinctrl_pm_ops = {
+ RUNTIME_PM_OPS(lpi_pinctrl_runtime_suspend, lpi_pinctrl_runtime_resume, NULL)
+};
+
static struct platform_driver lpi_pinctrl_driver = {
.driver = {
.name = "qcom-sc7280-lpass-lpi-pinctrl",
.of_match_table = lpi_pinctrl_of_match,
+ .pm = pm_ptr(&lpi_pinctrl_pm_ops),
},
.probe = lpi_pinctrl_probe,
.remove = lpi_pinctrl_remove,
--
2.34.1
next prev parent reply other threads:[~2026-04-13 12:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-13 12:22 [PATCH v1 0/3] pinctrl: qcom: lpass-lpi: PM clock framework cleanup and fixes Ajay Kumar Nandam
2026-04-13 12:22 ` Ajay Kumar Nandam [this message]
2026-04-14 8:33 ` [PATCH v1 1/3] pinctrl: qcom: lpass-lpi: Switch to PM clock framework for runtime PM Konrad Dybcio
2026-04-20 8:51 ` Ajay Kumar Nandam
2026-04-14 8:37 ` Konrad Dybcio
2026-04-16 12:32 ` Ajay Kumar Nandam
2026-04-13 12:22 ` [PATCH v1 2/3] pinctrl: qcom: lpass-lpi: Fix GPIO register access helper return types Ajay Kumar Nandam
2026-04-14 8:39 ` Konrad Dybcio
2026-04-20 8:42 ` Ajay Kumar Nandam
2026-04-13 12:22 ` [PATCH v1 3/3] pinctrl: qcom: lpass-lpi: Resume clocks for GPIO access Ajay Kumar Nandam
2026-04-14 8:44 ` Konrad Dybcio
2026-04-20 8:45 ` Ajay Kumar Nandam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260413122233.375945-2-ajay.nandam@oss.qualcomm.com \
--to=ajay.nandam@oss.qualcomm.com \
--cc=andersson@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=srinivas.kandagatla@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox