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

From: Dmitry Baryshkov

Date: Wed May 13 2026 - 08:56:38 EST


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.

> }
>

--
With best wishes
Dmitry