[PATCH V3 15/19] soc: tegra: pmc: Add generic PM domain support

Jon Hunter jonathanh at nvidia.com
Mon Jul 13 05:39:53 PDT 2015


Adds generic PM support to the PMC driver where the PM domains are
populated from device-tree and the PM domain consumer devices are
bound to their relevant PM domains via device-tree as well.

Update the tegra_powergate_power_on_legacy/off_legacy() APIs so that
internally they call the same tegra_powergate_xxx functions that are
used by the tegra generic power domain code for consistency.

This is based upon work by Thierry Reding <treding at nvidia.com>
and Vince Hsu <vinceh at nvidia.com>.

Signed-off-by: Jon Hunter <jonathanh at nvidia.com>
---
 drivers/soc/tegra/pmc.c                     | 545 +++++++++++++++++++++++++++-
 include/dt-bindings/power/tegra-powergate.h |  42 +++
 include/soc/tegra/pmc.h                     |  52 +--
 3 files changed, 580 insertions(+), 59 deletions(-)
 create mode 100644 include/dt-bindings/power/tegra-powergate.h

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 934653785bb7..4de92a9dae65 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -19,8 +19,11 @@
 
 #define pr_fmt(fmt) "tegra-pmc: " fmt
 
+#include <dt-bindings/power/tegra-powergate.h>
+
 #include <linux/kernel.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
@@ -30,17 +33,24 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/reboot.h>
+#include <linux/regulator/consumer.h>
 #include <linux/reset.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/spinlock.h>
 
 #include <soc/tegra/common.h>
 #include <soc/tegra/fuse.h>
+#include <soc/tegra/mc.h>
 #include <soc/tegra/pmc.h>
 
+#define PMC_POWERGATE_ARRAY_MAX		10
+
 #define PMC_CNTRL			0x0
 #define  PMC_CNTRL_SYSCLK_POLARITY	(1 << 10)  /* sys clk polarity */
 #define  PMC_CNTRL_SYSCLK_OE		(1 << 11)  /* system clock enable */
@@ -106,6 +116,22 @@
 
 #define PMC_PWRGATE_STATE(val, id)	(!!(val & BIT(id)))
 
+struct tegra_powergate {
+	struct generic_pm_domain genpd;
+	struct tegra_pmc *pmc;
+	struct tegra_mc *mc;
+	unsigned int id;
+	struct list_head node;
+	struct device_node *of_node;
+	struct regulator *vdd;
+	struct clk **clks;
+	struct reset_control **resets;
+	const struct tegra_mc_flush **flushes;
+	u32 num_clks;
+	u32 num_resets;
+	u32 num_flushes;
+};
+
 struct tegra_pmc_soc {
 	unsigned int num_powergates;
 	const char *const *powergates;
@@ -118,8 +144,10 @@ struct tegra_pmc_soc {
 
 /**
  * struct tegra_pmc - NVIDIA Tegra PMC
+ * @dev: pointer to parent device
  * @base: pointer to I/O remapped register region
  * @clk: pointer to pclk clock
+ * @soc: SoC-specific data
  * @rate: currently configured rate of pclk
  * @suspend_mode: lowest suspend mode available
  * @cpu_good_time: CPU power good time (in microseconds)
@@ -133,6 +161,7 @@ struct tegra_pmc_soc {
  * @cpu_pwr_good_en: CPU power good signal is enabled
  * @lp0_vec_phys: physical base address of the LP0 warm boot code
  * @lp0_vec_size: size of the LP0 warm boot code
+ * @powergates_list: list of power gates
  * @powergates_lock: mutex for power gate register access
  */
 struct tegra_pmc {
@@ -157,6 +186,7 @@ struct tegra_pmc {
 	u32 lp0_vec_phys;
 	u32 lp0_vec_size;
 
+	struct list_head powergates_list;
 	struct mutex powergates_lock;
 };
 
@@ -165,6 +195,12 @@ static struct tegra_pmc *pmc = &(struct tegra_pmc) {
 	.suspend_mode = TEGRA_SUSPEND_NONE,
 };
 
+static inline struct tegra_powergate *
+to_powergate(struct generic_pm_domain *domain)
+{
+	return container_of(domain, struct tegra_powergate, genpd);
+}
+
 static u32 tegra_pmc_readl(unsigned long offset)
 {
 	return readl(pmc->base + offset);
@@ -175,6 +211,37 @@ static void tegra_pmc_writel(u32 value, unsigned long offset)
 	writel(value, pmc->base + offset);
 }
 
+static int tegra_powergate_get_regulator(struct tegra_powergate *powergate)
+{
+	struct platform_device *pdev;
+
+	if (powergate->id != TEGRA_POWERGATE_EXT)
+		return -EINVAL;
+
+	pdev = of_find_device_by_node(powergate->of_node);
+	if (!pdev)
+		return -EINVAL;
+
+	powergate->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
+	if (IS_ERR(powergate->vdd))
+		return PTR_ERR(powergate->vdd);
+
+	return 0;
+}
+
+static int tegra_powergate_enable_regulator(struct tegra_powergate *powergate)
+{
+	int ret = 0;
+
+	if (IS_ERR_OR_NULL(powergate->vdd))
+		ret = tegra_powergate_get_regulator(powergate);
+
+	if (!ret)
+		ret = regulator_enable(powergate->vdd);
+
+	return ret;
+}
+
 /**
  * tegra_powergate_set() - set the state of a partition
  * @id: partition ID
@@ -207,6 +274,215 @@ static int tegra_powergate_set(int id, bool new_state, bool wait)
 	return ret;
 }
 
+static int tegra_powergate_enable(struct tegra_powergate *powergate,
+				  bool enable)
+{
+	if (powergate->id != TEGRA_POWERGATE_EXT)
+		return tegra_powergate_set(powergate->id, enable, true);
+
+	if (enable)
+		return tegra_powergate_enable_regulator(powergate);
+	else
+		return regulator_disable(powergate->vdd);
+}
+
+static bool tegra_powergate_is_supported(int id)
+{
+	switch (id) {
+	case TEGRA_POWERGATE_CPU:
+	case TEGRA_POWERGATE_CPU1:
+	case TEGRA_POWERGATE_CPU2:
+	case TEGRA_POWERGATE_CPU3:
+	case TEGRA_POWERGATE_CPU0:
+	case TEGRA_POWERGATE_C0NC:
+	case TEGRA_POWERGATE_IRAM:
+		return false;
+	default:
+		return true;
+	}
+}
+
+static bool _tegra_powergate_is_powered(struct tegra_powergate *powergate)
+{
+	if (powergate->id != TEGRA_POWERGATE_EXT)
+		return tegra_powergate_is_powered(powergate->id);
+
+	if (IS_ERR(powergate->vdd))
+		return false;
+	else
+		return regulator_is_enabled(powergate->vdd);
+}
+
+static void tegra_powergate_disable_clocks(struct tegra_powergate *powergate)
+{
+	int i;
+
+	for (i = 0; i < powergate->num_clks; i++)
+		clk_disable_unprepare(powergate->clks[i]);
+}
+
+static int tegra_powergate_enable_clocks(struct tegra_powergate *powergate)
+{
+	int err, i;
+
+	for (i = 0; i < powergate->num_clks; i++) {
+		err = clk_prepare_enable(powergate->clks[i]);
+		if (err)
+			goto out;
+	}
+
+	return 0;
+
+out:
+	while (i--)
+		clk_disable_unprepare(powergate->clks[i]);
+
+	return err;
+}
+
+static int tegra_powergate_mc_flush(struct tegra_powergate *powergate,
+				    bool enable)
+{
+	int i, err;
+
+	for (i = 0; i < powergate->num_flushes; i++) {
+		err = tegra_mc_flush(powergate->mc, powergate->flushes[i],
+				     enable);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int tegra_powergate_reset_assert(struct tegra_powergate *powergate)
+{
+	int err, i;
+
+	for (i = 0; i < powergate->num_resets; i++) {
+		err = reset_control_assert(powergate->resets[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int tegra_powergate_reset_deassert(struct tegra_powergate *powergate)
+{
+	int err, i;
+
+	for (i = 0; i < powergate->num_resets; i++) {
+		err = reset_control_deassert(powergate->resets[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int tegra_powergate_seq_power_up(struct tegra_powergate *powergate)
+{
+	int err;
+
+	err = tegra_powergate_reset_assert(powergate);
+	if (err)
+		goto out;
+	udelay(10);
+
+	err = tegra_powergate_enable(powergate, true);
+	if (err < 0)
+		goto out;
+	udelay(10);
+
+	err = tegra_powergate_enable_clocks(powergate);
+	if (err)
+		goto out;
+	udelay(10);
+
+	tegra_powergate_remove_clamping(powergate->id);
+
+	udelay(10);
+
+	err = tegra_powergate_reset_deassert(powergate);
+	if (err)
+		goto out;
+	udelay(10);
+
+	err = tegra_powergate_mc_flush(powergate, false);
+	if (err)
+		goto out;
+	udelay(10);
+
+	tegra_powergate_disable_clocks(powergate);
+
+	return 0;
+
+out:
+	return err;
+}
+
+static int tegra_powergate_seq_power_down(struct tegra_powergate *powergate)
+{
+	int err;
+
+	err = tegra_powergate_enable_clocks(powergate);
+	if (err)
+		goto out;
+	udelay(10);
+
+	err = tegra_powergate_mc_flush(powergate, true);
+	if (err)
+		goto out;
+	udelay(10);
+
+	err = tegra_powergate_reset_assert(powergate);
+	if (err)
+		goto out;
+	udelay(10);
+
+	tegra_powergate_disable_clocks(powergate);
+
+	udelay(10);
+
+	err = tegra_powergate_enable(powergate, false);
+	if (err)
+		goto out;
+
+	return 0;
+
+out:
+	return err;
+}
+
+static int tegra_genpd_power_on(struct generic_pm_domain *domain)
+{
+	struct tegra_powergate *powergate = to_powergate(domain);
+	struct tegra_pmc *pmc = powergate->pmc;
+	int err;
+
+	err = tegra_powergate_seq_power_up(powergate);
+
+	if (err)
+		dev_err(pmc->dev, "Failed to turn on PM Domain (%d)\n", err);
+
+	return 0;
+}
+
+static int tegra_genpd_power_off(struct generic_pm_domain *domain)
+{
+	struct tegra_powergate *powergate = to_powergate(domain);
+	struct tegra_pmc *pmc = powergate->pmc;
+	int err;
+
+	err = tegra_powergate_seq_power_down(powergate);
+
+	if (err)
+		dev_err(pmc->dev, "Failed to turn off PM Domain (%d)\n", err);
+
+	return err;
+}
+
 /**
  * tegra_powergate_power_on() - power on partition
  * @id: partition ID
@@ -247,6 +523,8 @@ int tegra_powergate_is_powered(int id)
 /**
  * tegra_powergate_remove_clamping() - remove power clamps for partition
  * @id: partition ID
+ *
+ * TODO: make this function static once we get rid of all outside callers
  */
 int tegra_powergate_remove_clamping(int id)
 {
@@ -331,26 +609,41 @@ err_power:
 }
 EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
 
-int tegra_powergate_power_off_legacy(int id, struct clk *clk,
-				     struct reset_control *rst)
+int tegra_powergate_power_on_legacy(int id, struct clk *clk,
+				    struct reset_control *rst)
 {
-	int ret;
+	struct tegra_powergate powergate;
 
-	ret = clk_prepare_enable(clk);
-	if (ret)
-		return ret;
+	if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
+		return -EINVAL;
 
-	usleep_range(10, 20);
+	powergate.id = id;
+	powergate.clks = &clk;
+	powergate.resets = &rst;
+	powergate.num_clks = 1;
+	powergate.num_resets = 1;
+	powergate.num_flushes = 0;
 
-	reset_control_assert(rst);
+	return tegra_powergate_seq_power_up(&powergate);
+}
+EXPORT_SYMBOL(tegra_powergate_power_on_legacy);
 
-	usleep_range(10, 20);
+int tegra_powergate_power_off_legacy(int id, struct clk *clk,
+				     struct reset_control *rst)
+{
+	struct tegra_powergate powergate;
 
-	clk_disable_unprepare(clk);
+	if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
+		return -EINVAL;
 
-	usleep_range(10, 20);
+	powergate.id = id;
+	powergate.clks = &clk;
+	powergate.resets = &rst;
+	powergate.num_clks = 1;
+	powergate.num_resets = 1;
+	powergate.num_flushes = 0;
 
-	return tegra_powergate_power_off(id);
+	return tegra_powergate_seq_power_down(&powergate);
 }
 EXPORT_SYMBOL(tegra_powergate_power_off_legacy);
 
@@ -493,6 +786,228 @@ static int tegra_powergate_debugfs_init(void)
 	return 0;
 }
 
+static int tegra_powergate_of_get_clks(struct device *dev,
+				       struct tegra_powergate *powergate)
+{
+	struct clk *clks[PMC_POWERGATE_ARRAY_MAX];
+	int i = 0;
+
+	for (i = 0; i < PMC_POWERGATE_ARRAY_MAX; i++) {
+		clks[i] = of_clk_get(powergate->of_node, i);
+		if (IS_ERR(clks[i])) {
+			if (PTR_ERR(clks[i]) != -ENOENT)
+				return PTR_ERR(clks[i]);
+			break;
+		}
+	}
+
+	if (PTR_ERR(clks[i]) != -ENOENT) {
+		dev_err(dev, "unsupported number of clocks defined\n");
+		return -EINVAL;
+	}
+
+	powergate->clks = devm_kcalloc(dev, i, sizeof(*clks), GFP_KERNEL);
+	if (!powergate->clks)
+		return -ENOMEM;
+
+	memcpy(powergate->clks, clks, sizeof(*clks) * i);
+	powergate->num_clks = i;
+
+	return 0;
+}
+
+static int tegra_powergate_of_get_resets(struct device *dev,
+					 struct tegra_powergate *powergate)
+{
+	struct reset_control *rsts[PMC_POWERGATE_ARRAY_MAX];
+	int i = 0;
+
+	for (i = 0; i < PMC_POWERGATE_ARRAY_MAX; i++) {
+		rsts[i] = of_reset_control_get_by_index(powergate->of_node, i);
+		if (IS_ERR(rsts[i])) {
+			if (PTR_ERR(rsts[i]) != -ENOENT)
+				return PTR_ERR(rsts[i]);
+			break;
+		}
+	}
+
+	if (PTR_ERR(rsts[i]) != -ENOENT) {
+		dev_err(dev, "unsupported number of resets defined\n");
+		return -EINVAL;
+	}
+
+	powergate->resets = devm_kcalloc(dev, i, sizeof(*rsts), GFP_KERNEL);
+	if (!powergate->resets)
+		return -ENOMEM;
+
+	memcpy(powergate->resets, rsts, sizeof(*rsts) * i);
+	powergate->num_resets = i;
+
+	return 0;
+}
+
+static int tegra_powergate_of_get_mc_flush(struct device *dev,
+					   struct tegra_powergate *powergate)
+{
+	struct platform_device *pdev;
+	struct of_phandle_args args;
+	int i = 0, ret = 0;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "nvidia-swgroups",
+					"#nvidia,swgroup-cells", 0, &args);
+	if (ret < 0) {
+		/*
+		 * The nvidia-swgroups property is
+		 * optional and so if missing simply return.
+		 */
+		if (ret == -ENOENT)
+			return 0;
+
+		dev_err(dev, "nvidia-swgroups property invalid for %s (%d)\n",
+			powergate->of_node->name, ret);
+		return ret;
+	}
+
+	powergate->flushes = devm_kcalloc(dev, args.args_count,
+					  sizeof(powergate->flushes),
+					  GFP_KERNEL);
+	if (!powergate->flushes) {
+		dev_err(dev, "failed to allocate memory for powergate flush\n");
+		return -ENOMEM;
+	}
+
+	pdev = of_find_device_by_node(args.np);
+	if (!pdev)
+		return -ENODEV;
+
+	powergate->mc = platform_get_drvdata(pdev);
+	if (!powergate->mc)
+		return -EINVAL;
+
+	for (i = 0; i < args.args_count; i++) {
+		powergate->flushes[i] = tegra_mc_flush_get(powergate->mc,
+							   args.args[i]);
+		if (!powergate->flushes[i])
+			return -EINVAL;
+	}
+
+	powergate->num_flushes = args.args_count;
+
+	return 0;
+}
+
+static int tegra_powergate_init_powerdomain(struct tegra_pmc *pmc,
+					    struct device_node *np,
+					    struct tegra_powergate *pg)
+{
+	bool off;
+	int err;
+
+	err = of_property_read_u32(np, "nvidia,powergate", &pg->id);
+	if (err) {
+		dev_err(pmc->dev, "no powergate ID for domain\n");
+		goto err;
+	}
+
+	if (tegra_powergate_is_supported(pg->id) == false) {
+		dev_warn(pmc->dev, "%s not currently supported by genpd\n",
+			 np->name);
+		return -EINVAL;
+	}
+
+	if (pg->id == TEGRA_POWERGATE_EXT) {
+		err = tegra_powergate_get_regulator(pg);
+		if (err) {
+			/*
+			 * The regulator might not be ready yet, so just
+			 * give a warning instead of failing the whole
+			 * init.
+			 */
+			dev_warn(pmc->dev, "couldn't locate regulator\n");
+		}
+	}
+
+	pg->of_node = np;
+	pg->genpd.name = np->name;
+	pg->genpd.power_off = tegra_genpd_power_off;
+	pg->genpd.power_on = tegra_genpd_power_on;
+	pg->pmc = pmc;
+
+	err = tegra_powergate_of_get_clks(pmc->dev, pg);
+	if (err)
+		goto err;
+
+	err = tegra_powergate_of_get_resets(pmc->dev, pg);
+	if (err)
+		goto err;
+
+	err = tegra_powergate_of_get_mc_flush(pmc->dev, pg);
+	if (err)
+		goto err;
+
+	list_add_tail(&pg->node, &pmc->powergates_list);
+
+	if (!IS_ERR(pg->vdd) || pg->id != TEGRA_POWERGATE_EXT)
+		tegra_genpd_power_off(&pg->genpd);
+
+	off = !_tegra_powergate_is_powered(pg);
+
+	pm_genpd_init(&pg->genpd, NULL, off);
+
+	dev_info(pmc->dev, "added power domain %s\n", np->name);
+
+	return 0;
+
+err:
+	dev_err(pmc->dev, "failed to add power domain for node %s\n",
+		np->name);
+	return err;
+}
+
+static int tegra_powergate_add_powerdomains(struct tegra_pmc *pmc,
+					    struct device_node *parent,
+					    struct generic_pm_domain *pd_parent)
+{
+	struct device_node *np;
+	int ret;
+
+	for_each_child_of_node(parent, np) {
+		struct tegra_powergate *pg;
+
+		pg = devm_kzalloc(pmc->dev, sizeof(*pg), GFP_KERNEL);
+		if (!pg)
+			return -ENOMEM;
+
+		ret = tegra_powergate_init_powerdomain(pmc, np, pg);
+		if (ret)
+			return ret;
+
+		if (pd_parent)
+			pm_genpd_add_subdomain(pd_parent, &pg->genpd);
+
+		of_genpd_add_provider_simple(np, &pg->genpd);
+
+		tegra_powergate_add_powerdomains(pmc, np, &pg->genpd);
+	}
+
+	return 0;
+}
+
+static int tegra_powergate_init(struct tegra_pmc *pmc)
+{
+	struct device_node *np;
+
+	INIT_LIST_HEAD(&pmc->powergates_list);
+
+	np = of_get_child_by_name(pmc->dev->of_node, "pm-domains");
+	if (!np) {
+		dev_dbg(pmc->dev, "power-domains node not found\n");
+		return 0;
+	}
+
+	return tegra_powergate_add_powerdomains(pmc, np, NULL);
+}
+
 static int tegra_io_rail_prepare(int id, unsigned long *request,
 				 unsigned long *status, unsigned int *bit)
 {
@@ -875,6 +1390,12 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 
 	tegra_pmc_init_tsense_reset(pmc);
 
+	if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
+		err = tegra_powergate_init(pmc);
+		if (err < 0)
+			return err;
+	}
+
 	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
 		err = tegra_powergate_debugfs_init();
 		if (err < 0)
diff --git a/include/dt-bindings/power/tegra-powergate.h b/include/dt-bindings/power/tegra-powergate.h
new file mode 100644
index 000000000000..b1d51f028a99
--- /dev/null
+++ b/include/dt-bindings/power/tegra-powergate.h
@@ -0,0 +1,42 @@
+#ifndef _DT_BINDINGS_POWER_TEGRA_POWERGATE_H
+#define _DT_BINDINGS_POWER_TEGRA_POWERGATE_H
+
+#define TEGRA_POWERGATE_CPU	0
+#define TEGRA_POWERGATE_3D	1
+#define TEGRA_POWERGATE_VENC	2
+#define TEGRA_POWERGATE_PCIE	3
+#define TEGRA_POWERGATE_VDEC	4
+#define TEGRA_POWERGATE_L2	5
+#define TEGRA_POWERGATE_MPE	6
+#define TEGRA_POWERGATE_HEG	7
+#define TEGRA_POWERGATE_SATA	8
+#define TEGRA_POWERGATE_CPU1	9
+#define TEGRA_POWERGATE_CPU2	10
+#define TEGRA_POWERGATE_CPU3	11
+#define TEGRA_POWERGATE_CELP	12
+#define TEGRA_POWERGATE_3D1	13
+#define TEGRA_POWERGATE_CPU0	14
+#define TEGRA_POWERGATE_C0NC	15
+#define TEGRA_POWERGATE_C1NC	16
+#define TEGRA_POWERGATE_SOR	17
+#define TEGRA_POWERGATE_DIS	18
+#define TEGRA_POWERGATE_DISB	19
+#define TEGRA_POWERGATE_XUSBA	20
+#define TEGRA_POWERGATE_XUSBB	21
+#define TEGRA_POWERGATE_XUSBC	22
+#define TEGRA_POWERGATE_VIC	23
+#define TEGRA_POWERGATE_IRAM	24
+#define TEGRA_POWERGATE_NVDEC	25
+#define TEGRA_POWERGATE_NVJPG	26
+#define TEGRA_POWERGATE_AUD	27
+#define TEGRA_POWERGATE_DFD	28
+#define TEGRA_POWERGATE_VE2	29
+
+/*
+ * Pseudo powergate for power-domains that are power-gated externally.
+ * Make this a large number to allow other powergates to be added.
+ */
+#define TEGRA_POWERGATE_EXT	1000
+
+
+#endif
diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h
index 4ca91d39304d..67b75d82edc7 100644
--- a/include/soc/tegra/pmc.h
+++ b/include/soc/tegra/pmc.h
@@ -19,6 +19,8 @@
 #ifndef __SOC_TEGRA_PMC_H__
 #define __SOC_TEGRA_PMC_H__
 
+#include <dt-bindings/power/tegra-powergate.h>
+
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
@@ -41,42 +43,8 @@ int tegra_pmc_cpu_remove_clamping(int cpuid);
 #endif /* CONFIG_SMP */
 
 /*
- * powergate and I/O rail APIs
+ * I/O rail APIs
  */
-
-#define TEGRA_POWERGATE_CPU	0
-#define TEGRA_POWERGATE_3D	1
-#define TEGRA_POWERGATE_VENC	2
-#define TEGRA_POWERGATE_PCIE	3
-#define TEGRA_POWERGATE_VDEC	4
-#define TEGRA_POWERGATE_L2	5
-#define TEGRA_POWERGATE_MPE	6
-#define TEGRA_POWERGATE_HEG	7
-#define TEGRA_POWERGATE_SATA	8
-#define TEGRA_POWERGATE_CPU1	9
-#define TEGRA_POWERGATE_CPU2	10
-#define TEGRA_POWERGATE_CPU3	11
-#define TEGRA_POWERGATE_CELP	12
-#define TEGRA_POWERGATE_3D1	13
-#define TEGRA_POWERGATE_CPU0	14
-#define TEGRA_POWERGATE_C0NC	15
-#define TEGRA_POWERGATE_C1NC	16
-#define TEGRA_POWERGATE_SOR	17
-#define TEGRA_POWERGATE_DIS	18
-#define TEGRA_POWERGATE_DISB	19
-#define TEGRA_POWERGATE_XUSBA	20
-#define TEGRA_POWERGATE_XUSBB	21
-#define TEGRA_POWERGATE_XUSBC	22
-#define TEGRA_POWERGATE_VIC	23
-#define TEGRA_POWERGATE_IRAM	24
-#define TEGRA_POWERGATE_NVDEC	25
-#define TEGRA_POWERGATE_NVJPG	26
-#define TEGRA_POWERGATE_AUD	27
-#define TEGRA_POWERGATE_DFD	28
-#define TEGRA_POWERGATE_VE2	29
-
-#define TEGRA_POWERGATE_3D0	TEGRA_POWERGATE_3D
-
 #define TEGRA_IO_RAIL_CSIA	0
 #define TEGRA_IO_RAIL_CSIB	1
 #define TEGRA_IO_RAIL_DSI	2
@@ -119,18 +87,8 @@ int tegra_powergate_remove_clamping(int id);
 int tegra_powergate_sequence_power_up(int id, struct clk *clk,
 				      struct reset_control *rst);
 
-static inline int tegra_powergate_power_on_legacy(int id, struct clk *clk,
-						  struct reset_control *rst)
-{
-	int err = tegra_powergate_sequence_power_up(id, clk, rst);
-
-	if (!err) {
-		usleep_range(10, 20);
-		clk_disable_unprepare(clk);
-	}
-
-	return err;
-}
+int tegra_powergate_power_on_legacy(int id, struct clk *clk,
+				    struct reset_control *rst);
 
 int tegra_powergate_power_off_legacy(int id, struct clk *clk,
 				     struct reset_control *rst);
-- 
2.1.4




More information about the linux-arm-kernel mailing list