[PATCH v8 3/4] soc: qcom: geni-se: Keep pinctrl active for multi-owner controllers

From: Mukesh Kumar Savaliya

Date: Wed Jul 08 2026 - 01:11:15 EST


On platforms where a GENI Serial Engine is shared with another system
processor, selecting the "sleep" pinctrl state can disrupt ongoing
transfers initiated by the other processor.

Teach geni_se_resources_off() to skip selecting the pinctrl sleep state
when the Serial Engine is marked as shared, while still allowing the
rest of the resource shutdown sequence to proceed.

This is required for multi-owner configurations (described via DeviceTree
with qcom,qup-multi-owner on the protocol controller node).

Reviewed-by: Konrad Dybcio <konrad.dybcio@xxxxxxxxxxxxxxxx>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@xxxxxxxxxxxxxxxx>
---
drivers/soc/qcom/qcom-geni-se.c | 14 +++++++++++---
include/linux/soc/qcom/geni-se.h | 2 ++
2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 15636a8dc907..3441ae3431e6 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -607,9 +607,17 @@ int geni_se_resources_off(struct geni_se *se)
if (has_acpi_companion(se->dev))
return 0;

- ret = pinctrl_pm_select_sleep_state(se->dev);
- if (ret)
- return ret;
+ /*
+ * Select the "sleep" pinctrl state only when the serial engine is
+ * exclusively owned by this system processor. For shared controller
+ * configurations, another system processor may still be using the pins,
+ * and switching them to "sleep" can disrupt ongoing transfers.
+ */
+ if (!se->multi_owner) {
+ ret = pinctrl_pm_select_sleep_state(se->dev);
+ if (ret)
+ return ret;
+ }

geni_se_clks_off(se);
return 0;
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index c5e6ab85df09..9571da2c51a8 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -66,6 +66,7 @@ struct geni_icc_path {
* @icc_paths: Array of ICC paths for SE
* @pd_list: Power domain list for managing power domains
* @has_opp: Indicates if OPP is supported
+ * @multi_owner: True if SE is shared between multiple owners.
*/
struct geni_se {
void __iomem *base;
@@ -78,6 +79,7 @@ struct geni_se {
struct geni_icc_path icc_paths[3];
struct dev_pm_domain_list *pd_list;
bool has_opp;
+ bool multi_owner;
};

/* Common SE registers */
--
2.43.0