Re: [PATCH v4 2/2] pinctrl: qcom: lpass-lpi: Switch to PM clock framework for runtime PM

From: Ajay Kumar Nandam

Date: Wed May 13 2026 - 10:58:58 EST




On 5/13/2026 6:22 PM, Dmitry Baryshkov wrote:
On Wed, May 13, 2026 at 05:55:26PM +0530, Ajay Kumar Nandam wrote:
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.

Guard GPIO register read/write helpers and slew-rate register programming
with synchronous runtime PM calls so the device is active during MMIO
operations whenever autosuspend is enabled.

Signed-off-by: Ajay Kumar Nandam <ajay.nandam@xxxxxxxxxxxxxxxx>
---
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 118 ++++++++++++------
.../pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c | 7 ++
2 files changed, 88 insertions(+), 37 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
index 15ced5027579..d95e28926d38 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
@@ -15,6 +15,9 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>
+#include <linux/cleanup.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
#include "../pinctrl-utils.h"
@@ -22,7 +25,6 @@
#define MAX_NR_GPIO 32
#define GPIO_FUNC 0
-#define MAX_LPI_NUM_CLKS 2
struct lpi_pinctrl {
struct device *dev;
@@ -31,7 +33,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);
@@ -39,29 +40,47 @@ struct lpi_pinctrl {
};
static int lpi_gpio_read(struct lpi_pinctrl *state, unsigned int pin,
- unsigned int addr)
+ unsigned int addr, u32 *val)
{
u32 pin_offset;
+ int ret;
if (state->data->flags & LPI_FLAG_USE_PREDEFINED_PIN_OFFSET)
pin_offset = state->data->groups[pin].pin_offset;
else
pin_offset = LPI_TLMM_REG_OFFSET * pin;
- return ioread32(state->tlmm_base + pin_offset + addr);
+ ret = pm_runtime_resume_and_get(state->dev);
+ if (ret < 0)
+ return ret;
+
+ *val = ioread32(state->tlmm_base + pin_offset + addr);
+ ret = pm_runtime_put_autosuspend(state->dev);
+ if (ret < 0)
+ return ret;
+
+ return 0;

Just `return pm_runtime_put_autosuspend(state->dev)`, no need for extra
ifs.


ACK, Addressed in V5.

Thanks
Ajay Kumar

}