diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index ee5f86ca50cb..f419a28f616b 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -708,3 +708,25 @@ int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain) return ret; } EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable); + +/* + * GX GDSC is a special power domain. Normally, its disable sequence + * is managed by the GMU firmware, and high level OS must not attempt + * to disable it. The only exception is during GMU recovery, where the + * GMU driver can set GenPD’s synced_poweroff flag to allow explicitly + * disable GX GDSC in hardware. + */ +int gdsc_gx_disable(struct generic_pm_domain *domain) +{ + struct gdsc *sc = domain_to_gdsc(domain); + + if (domain->synced_poweroff) + return gdsc_disable(domain); + + /* Remove parent-supply placed in enable */ + if (sc->rsupply) + return regulator_disable(sc->rsupply); + + return 0; +} +EXPORT_SYMBOL_GPL(gdsc_gx_disable); diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 92ff6bcce7b1..2f9665b664e6 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -93,6 +93,7 @@ int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *, struct regmap *); void gdsc_unregister(struct gdsc_desc *desc); int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain); +int gdsc_gx_disable(struct generic_pm_domain *domain); #else static inline int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev,