#include <linux/kernel.h>
 #include <linux/ktime.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset-controller.h>
        GDSC_ON
 };
 
+static int gdsc_pm_runtime_get(struct gdsc *sc)
+{
+       if (!sc->dev)
+               return 0;
+
+       return pm_runtime_resume_and_get(sc->dev);
+}
+
+static int gdsc_pm_runtime_put(struct gdsc *sc)
+{
+       if (!sc->dev)
+               return 0;
+
+       return pm_runtime_put_sync(sc->dev);
+}
+
 /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */
 static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status)
 {
        regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
 }
 
-static int gdsc_enable(struct generic_pm_domain *domain)
+static int _gdsc_enable(struct gdsc *sc)
 {
-       struct gdsc *sc = domain_to_gdsc(domain);
        int ret;
 
        if (sc->pwrsts == PWRSTS_ON)
        return 0;
 }
 
-static int gdsc_disable(struct generic_pm_domain *domain)
+static int gdsc_enable(struct generic_pm_domain *domain)
 {
        struct gdsc *sc = domain_to_gdsc(domain);
        int ret;
 
+       ret = gdsc_pm_runtime_get(sc);
+       if (ret)
+               return ret;
+
+       return _gdsc_enable(sc);
+}
+
+static int _gdsc_disable(struct gdsc *sc)
+{
+       int ret;
+
        if (sc->pwrsts == PWRSTS_ON)
                return gdsc_assert_reset(sc);
 
        return 0;
 }
 
+static int gdsc_disable(struct generic_pm_domain *domain)
+{
+       struct gdsc *sc = domain_to_gdsc(domain);
+       int ret;
+
+       ret = _gdsc_disable(sc);
+
+       gdsc_pm_runtime_put(sc);
+
+       return ret;
+}
+
 static int gdsc_init(struct gdsc *sc)
 {
        u32 mask, val;
        for (i = 0; i < num; i++) {
                if (!scs[i])
                        continue;
+               if (pm_runtime_enabled(dev))
+                       scs[i]->dev = dev;
                scs[i]->regmap = regmap;
                scs[i]->rcdev = rcdev;
                ret = gdsc_init(scs[i]);
                        continue;
                if (scs[i]->parent)
                        pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
+               else if (!IS_ERR_OR_NULL(dev->pm_domain))
+                       pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
        }
 
        return of_genpd_add_provider_onecell(dev->of_node, data);
                        continue;
                if (scs[i]->parent)
                        pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
+               else if (!IS_ERR_OR_NULL(dev->pm_domain))
+                       pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
        }
        of_genpd_del_provider(dev->of_node);
 }