arm: tegra: add ops for vdd_core domain
Prashant Gaikwad [Tue, 15 Oct 2013 11:01:49 +0000 (16:01 +0530)]
Before turning off VDD_CORE from CPU Idle it is
required to save context of all modules powered
from VDD_CORE rail. This change add ops to call
suspend function of all device in VDD_CORE domain.

Bug 1254633

Change-Id: I0bcacc5c7049e87f91289ccd9c2d54c9389b8ed1
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Reviewed-on: http://git-master/r/299443
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>

arch/arm/mach-tegra/pm_domains.c

index f8d3bca..e764d21 100644 (file)
@@ -175,6 +175,60 @@ static int tegra_mc_clk_power_on(struct generic_pm_domain *genpd)
        return 0;
 }
 
+static void suspend_devices_in_domain(struct generic_pm_domain *genpd)
+{
+       struct pm_domain_data *pdd;
+       struct device *dev;
+
+       list_for_each_entry(pdd, &genpd->dev_list, list_node) {
+               dev = pdd->dev;
+
+               if (dev->pm_domain && dev->pm_domain->ops.suspend)
+                       dev->pm_domain->ops.suspend(dev);
+       }
+}
+
+static void resume_devices_in_domain(struct generic_pm_domain *genpd)
+{
+       struct pm_domain_data *pdd;
+       struct device *dev;
+
+       list_for_each_entry(pdd, &genpd->dev_list, list_node) {
+               dev = pdd->dev;
+
+               if (dev->pm_domain && dev->pm_domain->ops.resume)
+                       dev->pm_domain->ops.suspend(dev);
+       }
+}
+
+static int tegra_core_power_on(struct generic_pm_domain *genpd)
+{
+       struct pm_domain_data *pdd;
+       struct gpd_link *link;
+
+       list_for_each_entry(link, &genpd->master_links, master_node)
+               resume_devices_in_domain(link->slave);
+
+       list_for_each_entry(pdd, &genpd->dev_list, list_node)
+               TEGRA_PD_DEV_CALLBACK(resume, pdd->dev);
+
+       return 0;
+}
+
+static int tegra_core_power_off(struct generic_pm_domain *genpd)
+{
+       struct pm_domain_data *pdd;
+       struct gpd_link *link;
+
+       list_for_each_entry(link, &genpd->master_links, master_node)
+               suspend_devices_in_domain(link->slave);
+
+       list_for_each_entry(pdd, &genpd->dev_list, list_node)
+               TEGRA_PD_DEV_CALLBACK(suspend, pdd->dev);
+
+       return 0;
+}
+
 static struct tegra_pm_domain tegra_mc_clk = {
        .gpd.name = "tegra_mc_clk",
        .gpd.power_off = tegra_mc_clk_power_off,