Commit a21c3f17 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'tegra-for-5.1-soc' of...

Merge tag 'tegra-for-5.1-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/drivers

soc/tegra: Changes for v5.1-rc1

This contains a couple of miscellaneous fixes for minor issues and a
largish rework of the PMC driver to make it work on systems where the
PMC has been locked down and can only be accessed from secure firmware.

* tag 'tegra-for-5.1-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  soc/tegra: pmc: Support systems where PMC is marked secure
  soc/tegra: pmc: Explicitly initialize all fields
  soc/tegra: pmc: Make alignment consistent
  soc/tegra: pmc: Pass struct tegra_pmc * where possible
  soc/tegra: pmc: Make tegra_powergate_is_powered() a local function
  soc/tegra: pmc: Add missing kerneldoc
  soc/tegra: pmc: Sort includes alphabetically
  soc/tegra: pmc: Use TEGRA186_ prefix for GPIO names
  soc/tegra: fuse: Fix typo in tegra210_init_speedo_data
  soc/tegra: fuse: Fix illegal free of IO base address
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents f73e22d6 e247deae
...@@ -137,13 +137,17 @@ static int tegra_fuse_probe(struct platform_device *pdev) ...@@ -137,13 +137,17 @@ static int tegra_fuse_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
fuse->phys = res->start; fuse->phys = res->start;
fuse->base = devm_ioremap_resource(&pdev->dev, res); fuse->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(fuse->base)) if (IS_ERR(fuse->base)) {
return PTR_ERR(fuse->base); err = PTR_ERR(fuse->base);
fuse->base = base;
return err;
}
fuse->clk = devm_clk_get(&pdev->dev, "fuse"); fuse->clk = devm_clk_get(&pdev->dev, "fuse");
if (IS_ERR(fuse->clk)) { if (IS_ERR(fuse->clk)) {
dev_err(&pdev->dev, "failed to get FUSE clock: %ld", dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
PTR_ERR(fuse->clk)); PTR_ERR(fuse->clk));
fuse->base = base;
return PTR_ERR(fuse->clk); return PTR_ERR(fuse->clk);
} }
...@@ -152,8 +156,10 @@ static int tegra_fuse_probe(struct platform_device *pdev) ...@@ -152,8 +156,10 @@ static int tegra_fuse_probe(struct platform_device *pdev)
if (fuse->soc->probe) { if (fuse->soc->probe) {
err = fuse->soc->probe(fuse); err = fuse->soc->probe(fuse);
if (err < 0) if (err < 0) {
fuse->base = base;
return err; return err;
}
} }
if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size, if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size,
......
...@@ -131,7 +131,7 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info) ...@@ -131,7 +131,7 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info)
soc_speedo[0] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0); soc_speedo[0] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
soc_speedo[1] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_1); soc_speedo[1] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_1);
soc_speedo[2] = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2); soc_speedo[2] = tegra_fuse_read_early(FUSE_SOC_SPEEDO_2);
cpu_iddq = tegra_fuse_read_early(FUSE_CPU_IDDQ) * 4; cpu_iddq = tegra_fuse_read_early(FUSE_CPU_IDDQ) * 4;
soc_iddq = tegra_fuse_read_early(FUSE_SOC_IDDQ) * 4; soc_iddq = tegra_fuse_read_early(FUSE_SOC_IDDQ) * 4;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#define pr_fmt(fmt) "tegra-pmc: " fmt #define pr_fmt(fmt) "tegra-pmc: " fmt
#include <linux/kernel.h> #include <linux/arm-smccc.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/tegra.h> #include <linux/clk/tegra.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
...@@ -30,16 +30,17 @@ ...@@ -30,16 +30,17 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_clk.h> #include <linux/of_clk.h>
#include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
#include <linux/reboot.h> #include <linux/reboot.h>
...@@ -145,6 +146,11 @@ ...@@ -145,6 +146,11 @@
#define WAKE_AOWAKE_CTRL 0x4f4 #define WAKE_AOWAKE_CTRL 0x4f4
#define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0) #define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
/* for secure PMC */
#define TEGRA_SMC_PMC 0xc2fffe00
#define TEGRA_SMC_PMC_READ 0xaa
#define TEGRA_SMC_PMC_WRITE 0xbb
struct tegra_powergate { struct tegra_powergate {
struct generic_pm_domain genpd; struct generic_pm_domain genpd;
struct tegra_pmc *pmc; struct tegra_pmc *pmc;
...@@ -216,6 +222,7 @@ struct tegra_pmc_soc { ...@@ -216,6 +222,7 @@ struct tegra_pmc_soc {
bool has_gpu_clamps; bool has_gpu_clamps;
bool needs_mbist_war; bool needs_mbist_war;
bool has_impl_33v_pwr; bool has_impl_33v_pwr;
bool maybe_tz_only;
const struct tegra_io_pad_soc *io_pads; const struct tegra_io_pad_soc *io_pads;
unsigned int num_io_pads; unsigned int num_io_pads;
...@@ -273,8 +280,12 @@ static const char * const tegra30_reset_sources[] = { ...@@ -273,8 +280,12 @@ static const char * const tegra30_reset_sources[] = {
* struct tegra_pmc - NVIDIA Tegra PMC * struct tegra_pmc - NVIDIA Tegra PMC
* @dev: pointer to PMC device structure * @dev: pointer to PMC device structure
* @base: pointer to I/O remapped register region * @base: pointer to I/O remapped register region
* @wake: pointer to I/O remapped region for WAKE registers
* @aotag: pointer to I/O remapped region for AOTAG registers
* @scratch: pointer to I/O remapped region for scratch registers
* @clk: pointer to pclk clock * @clk: pointer to pclk clock
* @soc: pointer to SoC data structure * @soc: pointer to SoC data structure
* @tz_only: flag specifying if the PMC can only be accessed via TrustZone
* @debugfs: pointer to debugfs entry * @debugfs: pointer to debugfs entry
* @rate: currently configured rate of pclk * @rate: currently configured rate of pclk
* @suspend_mode: lowest suspend mode available * @suspend_mode: lowest suspend mode available
...@@ -291,6 +302,9 @@ static const char * const tegra30_reset_sources[] = { ...@@ -291,6 +302,9 @@ static const char * const tegra30_reset_sources[] = {
* @lp0_vec_size: size of the LP0 warm boot code * @lp0_vec_size: size of the LP0 warm boot code
* @powergates_available: Bitmap of available power gates * @powergates_available: Bitmap of available power gates
* @powergates_lock: mutex for power gate register access * @powergates_lock: mutex for power gate register access
* @pctl_dev: pin controller exposed by the PMC
* @domain: IRQ domain provided by the PMC
* @irq: chip implementation for the IRQ domain
*/ */
struct tegra_pmc { struct tegra_pmc {
struct device *dev; struct device *dev;
...@@ -302,6 +316,7 @@ struct tegra_pmc { ...@@ -302,6 +316,7 @@ struct tegra_pmc {
struct dentry *debugfs; struct dentry *debugfs;
const struct tegra_pmc_soc *soc; const struct tegra_pmc_soc *soc;
bool tz_only;
unsigned long rate; unsigned long rate;
...@@ -338,30 +353,85 @@ to_powergate(struct generic_pm_domain *domain) ...@@ -338,30 +353,85 @@ to_powergate(struct generic_pm_domain *domain)
return container_of(domain, struct tegra_powergate, genpd); return container_of(domain, struct tegra_powergate, genpd);
} }
static u32 tegra_pmc_readl(unsigned long offset) static u32 tegra_pmc_readl(struct tegra_pmc *pmc, unsigned long offset)
{ {
struct arm_smccc_res res;
if (pmc->tz_only) {
arm_smccc_smc(TEGRA_SMC_PMC, TEGRA_SMC_PMC_READ, offset, 0, 0,
0, 0, 0, &res);
if (res.a0) {
if (pmc->dev)
dev_warn(pmc->dev, "%s(): SMC failed: %lu\n",
__func__, res.a0);
else
pr_warn("%s(): SMC failed: %lu\n", __func__,
res.a0);
}
return res.a1;
}
return readl(pmc->base + offset); return readl(pmc->base + offset);
} }
static void tegra_pmc_writel(u32 value, unsigned long offset) static void tegra_pmc_writel(struct tegra_pmc *pmc, u32 value,
unsigned long offset)
{ {
writel(value, pmc->base + offset); struct arm_smccc_res res;
if (pmc->tz_only) {
arm_smccc_smc(TEGRA_SMC_PMC, TEGRA_SMC_PMC_WRITE, offset,
value, 0, 0, 0, 0, &res);
if (res.a0) {
if (pmc->dev)
dev_warn(pmc->dev, "%s(): SMC failed: %lu\n",
__func__, res.a0);
else
pr_warn("%s(): SMC failed: %lu\n", __func__,
res.a0);
}
} else {
writel(value, pmc->base + offset);
}
} }
static u32 tegra_pmc_scratch_readl(struct tegra_pmc *pmc, unsigned long offset)
{
if (pmc->tz_only)
return tegra_pmc_readl(pmc, offset);
return readl(pmc->scratch + offset);
}
static void tegra_pmc_scratch_writel(struct tegra_pmc *pmc, u32 value,
unsigned long offset)
{
if (pmc->tz_only)
tegra_pmc_writel(pmc, value, offset);
else
writel(value, pmc->scratch + offset);
}
/*
* TODO Figure out a way to call this with the struct tegra_pmc * passed in.
* This currently doesn't work because readx_poll_timeout() can only operate
* on functions that take a single argument.
*/
static inline bool tegra_powergate_state(int id) static inline bool tegra_powergate_state(int id)
{ {
if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps) if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
return (tegra_pmc_readl(GPU_RG_CNTRL) & 0x1) == 0; return (tegra_pmc_readl(pmc, GPU_RG_CNTRL) & 0x1) == 0;
else else
return (tegra_pmc_readl(PWRGATE_STATUS) & BIT(id)) != 0; return (tegra_pmc_readl(pmc, PWRGATE_STATUS) & BIT(id)) != 0;
} }
static inline bool tegra_powergate_is_valid(int id) static inline bool tegra_powergate_is_valid(struct tegra_pmc *pmc, int id)
{ {
return (pmc->soc && pmc->soc->powergates[id]); return (pmc->soc && pmc->soc->powergates[id]);
} }
static inline bool tegra_powergate_is_available(int id) static inline bool tegra_powergate_is_available(struct tegra_pmc *pmc, int id)
{ {
return test_bit(id, pmc->powergates_available); return test_bit(id, pmc->powergates_available);
} }
...@@ -374,7 +444,7 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name) ...@@ -374,7 +444,7 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
return -EINVAL; return -EINVAL;
for (i = 0; i < pmc->soc->num_powergates; i++) { for (i = 0; i < pmc->soc->num_powergates; i++) {
if (!tegra_powergate_is_valid(i)) if (!tegra_powergate_is_valid(pmc, i))
continue; continue;
if (!strcmp(name, pmc->soc->powergates[i])) if (!strcmp(name, pmc->soc->powergates[i]))
...@@ -386,10 +456,12 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name) ...@@ -386,10 +456,12 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
/** /**
* tegra_powergate_set() - set the state of a partition * tegra_powergate_set() - set the state of a partition
* @pmc: power management controller
* @id: partition ID * @id: partition ID
* @new_state: new state of the partition * @new_state: new state of the partition
*/ */
static int tegra_powergate_set(unsigned int id, bool new_state) static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
bool new_state)
{ {
bool status; bool status;
int err; int err;
...@@ -404,7 +476,7 @@ static int tegra_powergate_set(unsigned int id, bool new_state) ...@@ -404,7 +476,7 @@ static int tegra_powergate_set(unsigned int id, bool new_state)
return 0; return 0;
} }
tegra_pmc_writel(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
err = readx_poll_timeout(tegra_powergate_state, id, status, err = readx_poll_timeout(tegra_powergate_state, id, status,
status == new_state, 10, 100000); status == new_state, 10, 100000);
...@@ -414,7 +486,8 @@ static int tegra_powergate_set(unsigned int id, bool new_state) ...@@ -414,7 +486,8 @@ static int tegra_powergate_set(unsigned int id, bool new_state)
return err; return err;
} }
static int __tegra_powergate_remove_clamping(unsigned int id) static int __tegra_powergate_remove_clamping(struct tegra_pmc *pmc,
unsigned int id)
{ {
u32 mask; u32 mask;
...@@ -426,7 +499,7 @@ static int __tegra_powergate_remove_clamping(unsigned int id) ...@@ -426,7 +499,7 @@ static int __tegra_powergate_remove_clamping(unsigned int id)
*/ */
if (id == TEGRA_POWERGATE_3D) { if (id == TEGRA_POWERGATE_3D) {
if (pmc->soc->has_gpu_clamps) { if (pmc->soc->has_gpu_clamps) {
tegra_pmc_writel(0, GPU_RG_CNTRL); tegra_pmc_writel(pmc, 0, GPU_RG_CNTRL);
goto out; goto out;
} }
} }
...@@ -442,7 +515,7 @@ static int __tegra_powergate_remove_clamping(unsigned int id) ...@@ -442,7 +515,7 @@ static int __tegra_powergate_remove_clamping(unsigned int id)
else else
mask = (1 << id); mask = (1 << id);
tegra_pmc_writel(mask, REMOVE_CLAMPING); tegra_pmc_writel(pmc, mask, REMOVE_CLAMPING);
out: out:
mutex_unlock(&pmc->powergates_lock); mutex_unlock(&pmc->powergates_lock);
...@@ -494,7 +567,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg, ...@@ -494,7 +567,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
usleep_range(10, 20); usleep_range(10, 20);
err = tegra_powergate_set(pg->id, true); err = tegra_powergate_set(pg->pmc, pg->id, true);
if (err < 0) if (err < 0)
return err; return err;
...@@ -506,7 +579,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg, ...@@ -506,7 +579,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
usleep_range(10, 20); usleep_range(10, 20);
err = __tegra_powergate_remove_clamping(pg->id); err = __tegra_powergate_remove_clamping(pg->pmc, pg->id);
if (err) if (err)
goto disable_clks; goto disable_clks;
...@@ -533,7 +606,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg, ...@@ -533,7 +606,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
usleep_range(10, 20); usleep_range(10, 20);
powergate_off: powergate_off:
tegra_powergate_set(pg->id, false); tegra_powergate_set(pg->pmc, pg->id, false);
return err; return err;
} }
...@@ -558,7 +631,7 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg) ...@@ -558,7 +631,7 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
usleep_range(10, 20); usleep_range(10, 20);
err = tegra_powergate_set(pg->id, false); err = tegra_powergate_set(pg->pmc, pg->id, false);
if (err) if (err)
goto assert_resets; goto assert_resets;
...@@ -579,12 +652,13 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg) ...@@ -579,12 +652,13 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
static int tegra_genpd_power_on(struct generic_pm_domain *domain) static int tegra_genpd_power_on(struct generic_pm_domain *domain)
{ {
struct tegra_powergate *pg = to_powergate(domain); struct tegra_powergate *pg = to_powergate(domain);
struct device *dev = pg->pmc->dev;
int err; int err;
err = tegra_powergate_power_up(pg, true); err = tegra_powergate_power_up(pg, true);
if (err) if (err)
pr_err("failed to turn on PM domain %s: %d\n", pg->genpd.name, dev_err(dev, "failed to turn on PM domain %s: %d\n",
err); pg->genpd.name, err);
return err; return err;
} }
...@@ -592,12 +666,13 @@ static int tegra_genpd_power_on(struct generic_pm_domain *domain) ...@@ -592,12 +666,13 @@ static int tegra_genpd_power_on(struct generic_pm_domain *domain)
static int tegra_genpd_power_off(struct generic_pm_domain *domain) static int tegra_genpd_power_off(struct generic_pm_domain *domain)
{ {
struct tegra_powergate *pg = to_powergate(domain); struct tegra_powergate *pg = to_powergate(domain);
struct device *dev = pg->pmc->dev;
int err; int err;
err = tegra_powergate_power_down(pg); err = tegra_powergate_power_down(pg);
if (err) if (err)
pr_err("failed to turn off PM domain %s: %d\n", dev_err(dev, "failed to turn off PM domain %s: %d\n",
pg->genpd.name, err); pg->genpd.name, err);
return err; return err;
} }
...@@ -608,10 +683,10 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain) ...@@ -608,10 +683,10 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
*/ */
int tegra_powergate_power_on(unsigned int id) int tegra_powergate_power_on(unsigned int id)
{ {
if (!tegra_powergate_is_available(id)) if (!tegra_powergate_is_available(pmc, id))
return -EINVAL; return -EINVAL;
return tegra_powergate_set(id, true); return tegra_powergate_set(pmc, id, true);
} }
/** /**
...@@ -620,20 +695,21 @@ int tegra_powergate_power_on(unsigned int id) ...@@ -620,20 +695,21 @@ int tegra_powergate_power_on(unsigned int id)
*/ */
int tegra_powergate_power_off(unsigned int id) int tegra_powergate_power_off(unsigned int id)
{ {
if (!tegra_powergate_is_available(id)) if (!tegra_powergate_is_available(pmc, id))
return -EINVAL; return -EINVAL;
return tegra_powergate_set(id, false); return tegra_powergate_set(pmc, id, false);
} }
EXPORT_SYMBOL(tegra_powergate_power_off); EXPORT_SYMBOL(tegra_powergate_power_off);
/** /**
* tegra_powergate_is_powered() - check if partition is powered * tegra_powergate_is_powered() - check if partition is powered
* @pmc: power management controller
* @id: partition ID * @id: partition ID
*/ */
int tegra_powergate_is_powered(unsigned int id) static int tegra_powergate_is_powered(struct tegra_pmc *pmc, unsigned int id)
{ {
if (!tegra_powergate_is_valid(id)) if (!tegra_powergate_is_valid(pmc, id))
return -EINVAL; return -EINVAL;
return tegra_powergate_state(id); return tegra_powergate_state(id);
...@@ -645,10 +721,10 @@ int tegra_powergate_is_powered(unsigned int id) ...@@ -645,10 +721,10 @@ int tegra_powergate_is_powered(unsigned int id)
*/ */
int tegra_powergate_remove_clamping(unsigned int id) int tegra_powergate_remove_clamping(unsigned int id)
{ {
if (!tegra_powergate_is_available(id)) if (!tegra_powergate_is_available(pmc, id))
return -EINVAL; return -EINVAL;
return __tegra_powergate_remove_clamping(id); return __tegra_powergate_remove_clamping(pmc, id);
} }
EXPORT_SYMBOL(tegra_powergate_remove_clamping); EXPORT_SYMBOL(tegra_powergate_remove_clamping);
...@@ -666,7 +742,7 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, ...@@ -666,7 +742,7 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
struct tegra_powergate *pg; struct tegra_powergate *pg;
int err; int err;
if (!tegra_powergate_is_available(id)) if (!tegra_powergate_is_available(pmc, id))
return -EINVAL; return -EINVAL;
pg = kzalloc(sizeof(*pg), GFP_KERNEL); pg = kzalloc(sizeof(*pg), GFP_KERNEL);
...@@ -681,7 +757,8 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, ...@@ -681,7 +757,8 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
err = tegra_powergate_power_up(pg, false); err = tegra_powergate_power_up(pg, false);
if (err) if (err)
pr_err("failed to turn on partition %d: %d\n", id, err); dev_err(pmc->dev, "failed to turn on partition %d: %d\n", id,
err);
kfree(pg); kfree(pg);
...@@ -691,12 +768,14 @@ EXPORT_SYMBOL(tegra_powergate_sequence_power_up); ...@@ -691,12 +768,14 @@ EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
/** /**
* tegra_get_cpu_powergate_id() - convert from CPU ID to partition ID * tegra_get_cpu_powergate_id() - convert from CPU ID to partition ID
* @pmc: power management controller
* @cpuid: CPU partition ID * @cpuid: CPU partition ID
* *
* Returns the partition ID corresponding to the CPU partition ID or a * Returns the partition ID corresponding to the CPU partition ID or a
* negative error code on failure. * negative error code on failure.
*/ */
static int tegra_get_cpu_powergate_id(unsigned int cpuid) static int tegra_get_cpu_powergate_id(struct tegra_pmc *pmc,
unsigned int cpuid)
{ {
if (pmc->soc && cpuid < pmc->soc->num_cpu_powergates) if (pmc->soc && cpuid < pmc->soc->num_cpu_powergates)
return pmc->soc->cpu_powergates[cpuid]; return pmc->soc->cpu_powergates[cpuid];
...@@ -712,11 +791,11 @@ bool tegra_pmc_cpu_is_powered(unsigned int cpuid) ...@@ -712,11 +791,11 @@ bool tegra_pmc_cpu_is_powered(unsigned int cpuid)
{ {
int id; int id;
id = tegra_get_cpu_powergate_id(cpuid); id = tegra_get_cpu_powergate_id(pmc, cpuid);
if (id < 0) if (id < 0)
return false; return false;
return tegra_powergate_is_powered(id); return tegra_powergate_is_powered(pmc, id);
} }
/** /**
...@@ -727,11 +806,11 @@ int tegra_pmc_cpu_power_on(unsigned int cpuid) ...@@ -727,11 +806,11 @@ int tegra_pmc_cpu_power_on(unsigned int cpuid)
{ {
int id; int id;
id = tegra_get_cpu_powergate_id(cpuid); id = tegra_get_cpu_powergate_id(pmc, cpuid);
if (id < 0) if (id < 0)
return id; return id;
return tegra_powergate_set(id, true); return tegra_powergate_set(pmc, id, true);
} }
/** /**
...@@ -742,7 +821,7 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid) ...@@ -742,7 +821,7 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid)
{ {
int id; int id;
id = tegra_get_cpu_powergate_id(cpuid); id = tegra_get_cpu_powergate_id(pmc, cpuid);
if (id < 0) if (id < 0)
return id; return id;
...@@ -755,7 +834,7 @@ static int tegra_pmc_restart_notify(struct notifier_block *this, ...@@ -755,7 +834,7 @@ static int tegra_pmc_restart_notify(struct notifier_block *this,
const char *cmd = data; const char *cmd = data;
u32 value; u32 value;
value = readl(pmc->scratch + pmc->soc->regs->scratch0); value = tegra_pmc_scratch_readl(pmc, pmc->soc->regs->scratch0);
value &= ~PMC_SCRATCH0_MODE_MASK; value &= ~PMC_SCRATCH0_MODE_MASK;
if (cmd) { if (cmd) {
...@@ -769,12 +848,12 @@ static int tegra_pmc_restart_notify(struct notifier_block *this, ...@@ -769,12 +848,12 @@ static int tegra_pmc_restart_notify(struct notifier_block *this,
value |= PMC_SCRATCH0_MODE_RCM; value |= PMC_SCRATCH0_MODE_RCM;
} }
writel(value, pmc->scratch + pmc->soc->regs->scratch0); tegra_pmc_scratch_writel(pmc, value, pmc->soc->regs->scratch0);
/* reset everything but PMC_SCRATCH0 and PMC_RST_STATUS */ /* reset everything but PMC_SCRATCH0 and PMC_RST_STATUS */
value = tegra_pmc_readl(PMC_CNTRL); value = tegra_pmc_readl(pmc, PMC_CNTRL);
value |= PMC_CNTRL_MAIN_RST; value |= PMC_CNTRL_MAIN_RST;
tegra_pmc_writel(value, PMC_CNTRL); tegra_pmc_writel(pmc, value, PMC_CNTRL);
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -793,7 +872,7 @@ static int powergate_show(struct seq_file *s, void *data) ...@@ -793,7 +872,7 @@ static int powergate_show(struct seq_file *s, void *data)
seq_printf(s, "------------------\n"); seq_printf(s, "------------------\n");
for (i = 0; i < pmc->soc->num_powergates; i++) { for (i = 0; i < pmc->soc->num_powergates; i++) {
status = tegra_powergate_is_powered(i); status = tegra_powergate_is_powered(pmc, i);
if (status < 0) if (status < 0)
continue; continue;
...@@ -855,12 +934,13 @@ static int tegra_powergate_of_get_clks(struct tegra_powergate *pg, ...@@ -855,12 +934,13 @@ static int tegra_powergate_of_get_clks(struct tegra_powergate *pg,
static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
struct device_node *np, bool off) struct device_node *np, bool off)
{ {
struct device *dev = pg->pmc->dev;
int err; int err;
pg->reset = of_reset_control_array_get_exclusive(np); pg->reset = of_reset_control_array_get_exclusive(np);
if (IS_ERR(pg->reset)) { if (IS_ERR(pg->reset)) {
err = PTR_ERR(pg->reset); err = PTR_ERR(pg->reset);
pr_err("failed to get device resets: %d\n", err); dev_err(dev, "failed to get device resets: %d\n", err);
return err; return err;
} }
...@@ -877,6 +957,7 @@ static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, ...@@ -877,6 +957,7 @@ static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
{ {
struct device *dev = pmc->dev;
struct tegra_powergate *pg; struct tegra_powergate *pg;
int id, err; int id, err;
bool off; bool off;
...@@ -887,7 +968,7 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) ...@@ -887,7 +968,7 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
id = tegra_powergate_lookup(pmc, np->name); id = tegra_powergate_lookup(pmc, np->name);
if (id < 0) { if (id < 0) {
pr_err("powergate lookup failed for %pOFn: %d\n", np, id); dev_err(dev, "powergate lookup failed for %pOFn: %d\n", np, id);
goto free_mem; goto free_mem;
} }
...@@ -903,17 +984,17 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) ...@@ -903,17 +984,17 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
pg->genpd.power_on = tegra_genpd_power_on; pg->genpd.power_on = tegra_genpd_power_on;
pg->pmc = pmc; pg->pmc = pmc;
off = !tegra_powergate_is_powered(pg->id); off = !tegra_powergate_is_powered(pmc, pg->id);
err = tegra_powergate_of_get_clks(pg, np); err = tegra_powergate_of_get_clks(pg, np);
if (err < 0) { if (err < 0) {
pr_err("failed to get clocks for %pOFn: %d\n", np, err); dev_err(dev, "failed to get clocks for %pOFn: %d\n", np, err);
goto set_available; goto set_available;
} }
err = tegra_powergate_of_get_resets(pg, np, off); err = tegra_powergate_of_get_resets(pg, np, off);
if (err < 0) { if (err < 0) {
pr_err("failed to get resets for %pOFn: %d\n", np, err); dev_err(dev, "failed to get resets for %pOFn: %d\n", np, err);
goto remove_clks; goto remove_clks;
} }
...@@ -926,19 +1007,19 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) ...@@ -926,19 +1007,19 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
err = pm_genpd_init(&pg->genpd, NULL, off); err = pm_genpd_init(&pg->genpd, NULL, off);
if (err < 0) { if (err < 0) {
pr_err("failed to initialise PM domain %pOFn: %d\n", np, dev_err(dev, "failed to initialise PM domain %pOFn: %d\n", np,
err); err);
goto remove_resets; goto remove_resets;
} }
err = of_genpd_add_provider_simple(np, &pg->genpd); err = of_genpd_add_provider_simple(np, &pg->genpd);
if (err < 0) { if (err < 0) {
pr_err("failed to add PM domain provider for %pOFn: %d\n", dev_err(dev, "failed to add PM domain provider for %pOFn: %d\n",
np, err); np, err);
goto remove_genpd; goto remove_genpd;
} }
pr_debug("added PM domain %s\n", pg->genpd.name); dev_dbg(dev, "added PM domain %s\n", pg->genpd.name);
return; return;
...@@ -994,7 +1075,8 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id) ...@@ -994,7 +1075,8 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
return NULL; return NULL;
} }
static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id, static int tegra_io_pad_get_dpd_register_bit(struct tegra_pmc *pmc,
enum tegra_io_pad id,
unsigned long *request, unsigned long *request,
unsigned long *status, unsigned long *status,
u32 *mask) u32 *mask)
...@@ -1003,7 +1085,7 @@ static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id, ...@@ -1003,7 +1085,7 @@ static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id,
pad = tegra_io_pad_find(pmc, id); pad = tegra_io_pad_find(pmc, id);
if (!pad) { if (!pad) {
pr_err("invalid I/O pad ID %u\n", id); dev_err(pmc->dev, "invalid I/O pad ID %u\n", id);
return -ENOENT; return -ENOENT;
} }
...@@ -1023,43 +1105,44 @@ static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id, ...@@ -1023,43 +1105,44 @@ static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id,
return 0; return 0;
} }
static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request, static int tegra_io_pad_prepare(struct tegra_pmc *pmc, enum tegra_io_pad id,
unsigned long *status, u32 *mask) unsigned long *request, unsigned long *status,
u32 *mask)
{ {
unsigned long rate, value; unsigned long rate, value;
int err; int err;
err = tegra_io_pad_get_dpd_register_bit(id, request, status, mask); err = tegra_io_pad_get_dpd_register_bit(pmc, id, request, status, mask);
if (err) if (err)
return err; return err;
if (pmc->clk) { if (pmc->clk) {
rate = clk_get_rate(pmc->clk); rate = clk_get_rate(pmc->clk);
if (!rate) { if (!rate) {
pr_err("failed to get clock rate\n"); dev_err(pmc->dev, "failed to get clock rate\n");
return -ENODEV; return -ENODEV;
} }
tegra_pmc_writel(DPD_SAMPLE_ENABLE, DPD_SAMPLE); tegra_pmc_writel(pmc, DPD_SAMPLE_ENABLE, DPD_SAMPLE);
/* must be at least 200 ns, in APB (PCLK) clock cycles */ /* must be at least 200 ns, in APB (PCLK) clock cycles */
value = DIV_ROUND_UP(1000000000, rate); value = DIV_ROUND_UP(1000000000, rate);
value = DIV_ROUND_UP(200, value); value = DIV_ROUND_UP(200, value);
tegra_pmc_writel(value, SEL_DPD_TIM); tegra_pmc_writel(pmc, value, SEL_DPD_TIM);
} }
return 0; return 0;
} }
static int tegra_io_pad_poll(unsigned long offset, u32 mask, static int tegra_io_pad_poll(struct tegra_pmc *pmc, unsigned long offset,
u32 val, unsigned long timeout) u32 mask, u32 val, unsigned long timeout)
{ {
u32 value; u32 value;
timeout = jiffies + msecs_to_jiffies(timeout); timeout = jiffies + msecs_to_jiffies(timeout);
while (time_after(timeout, jiffies)) { while (time_after(timeout, jiffies)) {
value = tegra_pmc_readl(offset); value = tegra_pmc_readl(pmc, offset);
if ((value & mask) == val) if ((value & mask) == val)
return 0; return 0;
...@@ -1069,10 +1152,10 @@ static int tegra_io_pad_poll(unsigned long offset, u32 mask, ...@@ -1069,10 +1152,10 @@ static int tegra_io_pad_poll(unsigned long offset, u32 mask,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
static void tegra_io_pad_unprepare(void) static void tegra_io_pad_unprepare(struct tegra_pmc *pmc)
{ {
if (pmc->clk) if (pmc->clk)
tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE); tegra_pmc_writel(pmc, DPD_SAMPLE_DISABLE, DPD_SAMPLE);
} }
/** /**
...@@ -1089,21 +1172,21 @@ int tegra_io_pad_power_enable(enum tegra_io_pad id) ...@@ -1089,21 +1172,21 @@ int tegra_io_pad_power_enable(enum tegra_io_pad id)
mutex_lock(&pmc->powergates_lock); mutex_lock(&pmc->powergates_lock);
err = tegra_io_pad_prepare(id, &request, &status, &mask); err = tegra_io_pad_prepare(pmc, id, &request, &status, &mask);
if (err < 0) { if (err < 0) {
pr_err("failed to prepare I/O pad: %d\n", err); dev_err(pmc->dev, "failed to prepare I/O pad: %d\n", err);
goto unlock; goto unlock;
} }
tegra_pmc_writel(IO_DPD_REQ_CODE_OFF | mask, request); tegra_pmc_writel(pmc, IO_DPD_REQ_CODE_OFF | mask, request);
err = tegra_io_pad_poll(status, mask, 0, 250); err = tegra_io_pad_poll(pmc, status, mask, 0, 250);
if (err < 0) { if (err < 0) {
pr_err("failed to enable I/O pad: %d\n", err); dev_err(pmc->dev, "failed to enable I/O pad: %d\n", err);
goto unlock; goto unlock;
} }
tegra_io_pad_unprepare(); tegra_io_pad_unprepare(pmc);
unlock: unlock:
mutex_unlock(&pmc->powergates_lock); mutex_unlock(&pmc->powergates_lock);
...@@ -1125,21 +1208,21 @@ int tegra_io_pad_power_disable(enum tegra_io_pad id) ...@@ -1125,21 +1208,21 @@ int tegra_io_pad_power_disable(enum tegra_io_pad id)
mutex_lock(&pmc->powergates_lock); mutex_lock(&pmc->powergates_lock);
err = tegra_io_pad_prepare(id, &request, &status, &mask); err = tegra_io_pad_prepare(pmc, id, &request, &status, &mask);
if (err < 0) { if (err < 0) {
pr_err("failed to prepare I/O pad: %d\n", err); dev_err(pmc->dev, "failed to prepare I/O pad: %d\n", err);
goto unlock; goto unlock;
} }
tegra_pmc_writel(IO_DPD_REQ_CODE_ON | mask, request); tegra_pmc_writel(pmc, IO_DPD_REQ_CODE_ON | mask, request);
err = tegra_io_pad_poll(status, mask, mask, 250); err = tegra_io_pad_poll(pmc, status, mask, mask, 250);
if (err < 0) { if (err < 0) {
pr_err("failed to disable I/O pad: %d\n", err); dev_err(pmc->dev, "failed to disable I/O pad: %d\n", err);
goto unlock; goto unlock;
} }
tegra_io_pad_unprepare(); tegra_io_pad_unprepare(pmc);
unlock: unlock:
mutex_unlock(&pmc->powergates_lock); mutex_unlock(&pmc->powergates_lock);
...@@ -1147,22 +1230,24 @@ int tegra_io_pad_power_disable(enum tegra_io_pad id) ...@@ -1147,22 +1230,24 @@ int tegra_io_pad_power_disable(enum tegra_io_pad id)
} }
EXPORT_SYMBOL(tegra_io_pad_power_disable); EXPORT_SYMBOL(tegra_io_pad_power_disable);
static int tegra_io_pad_is_powered(enum tegra_io_pad id) static int tegra_io_pad_is_powered(struct tegra_pmc *pmc, enum tegra_io_pad id)
{ {
unsigned long request, status; unsigned long request, status;
u32 mask, value; u32 mask, value;
int err; int err;
err = tegra_io_pad_get_dpd_register_bit(id, &request, &status, &mask); err = tegra_io_pad_get_dpd_register_bit(pmc, id, &request, &status,
&mask);
if (err) if (err)
return err; return err;
value = tegra_pmc_readl(status); value = tegra_pmc_readl(pmc, status);
return !(value & mask); return !(value & mask);
} }
static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage) static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
int voltage)
{ {
const struct tegra_io_pad_soc *pad; const struct tegra_io_pad_soc *pad;
u32 value; u32 value;
...@@ -1177,29 +1262,29 @@ static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage) ...@@ -1177,29 +1262,29 @@ static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage)
mutex_lock(&pmc->powergates_lock); mutex_lock(&pmc->powergates_lock);
if (pmc->soc->has_impl_33v_pwr) { if (pmc->soc->has_impl_33v_pwr) {
value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR); value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8) if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
value &= ~BIT(pad->voltage); value &= ~BIT(pad->voltage);
else else
value |= BIT(pad->voltage); value |= BIT(pad->voltage);
tegra_pmc_writel(value, PMC_IMPL_E_33V_PWR); tegra_pmc_writel(pmc, value, PMC_IMPL_E_33V_PWR);
} else { } else {
/* write-enable PMC_PWR_DET_VALUE[pad->voltage] */ /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
value = tegra_pmc_readl(PMC_PWR_DET); value = tegra_pmc_readl(pmc, PMC_PWR_DET);
value |= BIT(pad->voltage); value |= BIT(pad->voltage);
tegra_pmc_writel(value, PMC_PWR_DET); tegra_pmc_writel(pmc, value, PMC_PWR_DET);
/* update I/O voltage */ /* update I/O voltage */
value = tegra_pmc_readl(PMC_PWR_DET_VALUE); value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8) if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
value &= ~BIT(pad->voltage); value &= ~BIT(pad->voltage);
else else
value |= BIT(pad->voltage); value |= BIT(pad->voltage);
tegra_pmc_writel(value, PMC_PWR_DET_VALUE); tegra_pmc_writel(pmc, value, PMC_PWR_DET_VALUE);
} }
mutex_unlock(&pmc->powergates_lock); mutex_unlock(&pmc->powergates_lock);
...@@ -1209,7 +1294,7 @@ static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage) ...@@ -1209,7 +1294,7 @@ static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage)
return 0; return 0;
} }
static int tegra_io_pad_get_voltage(enum tegra_io_pad id) static int tegra_io_pad_get_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id)
{ {
const struct tegra_io_pad_soc *pad; const struct tegra_io_pad_soc *pad;
u32 value; u32 value;
...@@ -1222,9 +1307,9 @@ static int tegra_io_pad_get_voltage(enum tegra_io_pad id) ...@@ -1222,9 +1307,9 @@ static int tegra_io_pad_get_voltage(enum tegra_io_pad id)
return -ENOTSUPP; return -ENOTSUPP;
if (pmc->soc->has_impl_33v_pwr) if (pmc->soc->has_impl_33v_pwr)
value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR); value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
else else
value = tegra_pmc_readl(PMC_PWR_DET_VALUE); value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
if ((value & BIT(pad->voltage)) == 0) if ((value & BIT(pad->voltage)) == 0)
return TEGRA_IO_PAD_VOLTAGE_1V8; return TEGRA_IO_PAD_VOLTAGE_1V8;
...@@ -1296,21 +1381,21 @@ void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode) ...@@ -1296,21 +1381,21 @@ void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
ticks = pmc->cpu_good_time * rate + USEC_PER_SEC - 1; ticks = pmc->cpu_good_time * rate + USEC_PER_SEC - 1;
do_div(ticks, USEC_PER_SEC); do_div(ticks, USEC_PER_SEC);
tegra_pmc_writel(ticks, PMC_CPUPWRGOOD_TIMER); tegra_pmc_writel(pmc, ticks, PMC_CPUPWRGOOD_TIMER);
ticks = pmc->cpu_off_time * rate + USEC_PER_SEC - 1; ticks = pmc->cpu_off_time * rate + USEC_PER_SEC - 1;
do_div(ticks, USEC_PER_SEC); do_div(ticks, USEC_PER_SEC);
tegra_pmc_writel(ticks, PMC_CPUPWROFF_TIMER); tegra_pmc_writel(pmc, ticks, PMC_CPUPWROFF_TIMER);
wmb(); wmb();
pmc->rate = rate; pmc->rate = rate;
} }
value = tegra_pmc_readl(PMC_CNTRL); value = tegra_pmc_readl(pmc, PMC_CNTRL);
value &= ~PMC_CNTRL_SIDE_EFFECT_LP0; value &= ~PMC_CNTRL_SIDE_EFFECT_LP0;
value |= PMC_CNTRL_CPU_PWRREQ_OE; value |= PMC_CNTRL_CPU_PWRREQ_OE;
tegra_pmc_writel(value, PMC_CNTRL); tegra_pmc_writel(pmc, value, PMC_CNTRL);
} }
#endif #endif
...@@ -1432,13 +1517,13 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) ...@@ -1432,13 +1517,13 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux)) if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux))
pinmux = 0; pinmux = 0;
value = tegra_pmc_readl(PMC_SENSOR_CTRL); value = tegra_pmc_readl(pmc, PMC_SENSOR_CTRL);
value |= PMC_SENSOR_CTRL_SCRATCH_WRITE; value |= PMC_SENSOR_CTRL_SCRATCH_WRITE;
tegra_pmc_writel(value, PMC_SENSOR_CTRL); tegra_pmc_writel(pmc, value, PMC_SENSOR_CTRL);
value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) | value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) |
(reg_addr << PMC_SCRATCH54_ADDR_SHIFT); (reg_addr << PMC_SCRATCH54_ADDR_SHIFT);
tegra_pmc_writel(value, PMC_SCRATCH54); tegra_pmc_writel(pmc, value, PMC_SCRATCH54);
value = PMC_SCRATCH55_RESET_TEGRA; value = PMC_SCRATCH55_RESET_TEGRA;
value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT; value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT;
...@@ -1456,11 +1541,11 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) ...@@ -1456,11 +1541,11 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT; value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT;
tegra_pmc_writel(value, PMC_SCRATCH55); tegra_pmc_writel(pmc, value, PMC_SCRATCH55);
value = tegra_pmc_readl(PMC_SENSOR_CTRL); value = tegra_pmc_readl(pmc, PMC_SENSOR_CTRL);
value |= PMC_SENSOR_CTRL_ENABLE_RST; value |= PMC_SENSOR_CTRL_ENABLE_RST;
tegra_pmc_writel(value, PMC_SENSOR_CTRL); tegra_pmc_writel(pmc, value, PMC_SENSOR_CTRL);
dev_info(pmc->dev, "emergency thermal reset enabled\n"); dev_info(pmc->dev, "emergency thermal reset enabled\n");
...@@ -1470,12 +1555,16 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) ...@@ -1470,12 +1555,16 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev) static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev)
{ {
struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
return pmc->soc->num_io_pads; return pmc->soc->num_io_pads;
} }
static const char *tegra_io_pad_pinctrl_get_group_name( static const char *tegra_io_pad_pinctrl_get_group_name(struct pinctrl_dev *pctl,
struct pinctrl_dev *pctl, unsigned int group) unsigned int group)
{ {
struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl);
return pmc->soc->io_pads[group].name; return pmc->soc->io_pads[group].name;
} }
...@@ -1484,8 +1573,11 @@ static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev, ...@@ -1484,8 +1573,11 @@ static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev,
const unsigned int **pins, const unsigned int **pins,
unsigned int *num_pins) unsigned int *num_pins)
{ {
struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
*pins = &pmc->soc->io_pads[group].id; *pins = &pmc->soc->io_pads[group].id;
*num_pins = 1; *num_pins = 1;
return 0; return 0;
} }
...@@ -1500,27 +1592,33 @@ static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = { ...@@ -1500,27 +1592,33 @@ static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = {
static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev, static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev,
unsigned int pin, unsigned long *config) unsigned int pin, unsigned long *config)
{ {
const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin);
enum pin_config_param param = pinconf_to_config_param(*config); enum pin_config_param param = pinconf_to_config_param(*config);
struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
const struct tegra_io_pad_soc *pad;
int ret; int ret;
u32 arg; u32 arg;
pad = tegra_io_pad_find(pmc, pin);
if (!pad) if (!pad)
return -EINVAL; return -EINVAL;
switch (param) { switch (param) {
case PIN_CONFIG_POWER_SOURCE: case PIN_CONFIG_POWER_SOURCE:
ret = tegra_io_pad_get_voltage(pad->id); ret = tegra_io_pad_get_voltage(pmc, pad->id);
if (ret < 0) if (ret < 0)
return ret; return ret;
arg = ret; arg = ret;
break; break;
case PIN_CONFIG_LOW_POWER_MODE: case PIN_CONFIG_LOW_POWER_MODE:
ret = tegra_io_pad_is_powered(pad->id); ret = tegra_io_pad_is_powered(pmc, pad->id);
if (ret < 0) if (ret < 0)
return ret; return ret;
arg = !ret; arg = !ret;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -1534,12 +1632,14 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev, ...@@ -1534,12 +1632,14 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev,
unsigned int pin, unsigned long *configs, unsigned int pin, unsigned long *configs,
unsigned int num_configs) unsigned int num_configs)
{ {
const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin); struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
const struct tegra_io_pad_soc *pad;
enum pin_config_param param; enum pin_config_param param;
unsigned int i; unsigned int i;
int err; int err;
u32 arg; u32 arg;
pad = tegra_io_pad_find(pmc, pin);
if (!pad) if (!pad)
return -EINVAL; return -EINVAL;
...@@ -1560,7 +1660,7 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev, ...@@ -1560,7 +1660,7 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev,
if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 && if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 &&
arg != TEGRA_IO_PAD_VOLTAGE_3V3) arg != TEGRA_IO_PAD_VOLTAGE_3V3)
return -EINVAL; return -EINVAL;
err = tegra_io_pad_set_voltage(pad->id, arg); err = tegra_io_pad_set_voltage(pmc, pad->id, arg);
if (err) if (err)
return err; return err;
break; break;
...@@ -1585,7 +1685,7 @@ static struct pinctrl_desc tegra_pmc_pctl_desc = { ...@@ -1585,7 +1685,7 @@ static struct pinctrl_desc tegra_pmc_pctl_desc = {
static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc) static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
{ {
int err = 0; int err;
if (!pmc->soc->num_pin_descs) if (!pmc->soc->num_pin_descs)
return 0; return 0;
...@@ -1598,18 +1698,20 @@ static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc) ...@@ -1598,18 +1698,20 @@ static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
pmc); pmc);
if (IS_ERR(pmc->pctl_dev)) { if (IS_ERR(pmc->pctl_dev)) {
err = PTR_ERR(pmc->pctl_dev); err = PTR_ERR(pmc->pctl_dev);
dev_err(pmc->dev, "unable to register pinctrl, %d\n", err); dev_err(pmc->dev, "failed to register pin controller: %d\n",
err);
return err;
} }
return err; return 0;
} }
static ssize_t reset_reason_show(struct device *dev, static ssize_t reset_reason_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
u32 value, rst_src; u32 value, rst_src;
value = tegra_pmc_readl(pmc->soc->regs->rst_status); value = tegra_pmc_readl(pmc, pmc->soc->regs->rst_status);
rst_src = (value & pmc->soc->regs->rst_source_mask) >> rst_src = (value & pmc->soc->regs->rst_source_mask) >>
pmc->soc->regs->rst_source_shift; pmc->soc->regs->rst_source_shift;
...@@ -1619,11 +1721,11 @@ static ssize_t reset_reason_show(struct device *dev, ...@@ -1619,11 +1721,11 @@ static ssize_t reset_reason_show(struct device *dev,
static DEVICE_ATTR_RO(reset_reason); static DEVICE_ATTR_RO(reset_reason);
static ssize_t reset_level_show(struct device *dev, static ssize_t reset_level_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
u32 value, rst_lvl; u32 value, rst_lvl;
value = tegra_pmc_readl(pmc->soc->regs->rst_status); value = tegra_pmc_readl(pmc, pmc->soc->regs->rst_status);
rst_lvl = (value & pmc->soc->regs->rst_level_mask) >> rst_lvl = (value & pmc->soc->regs->rst_level_mask) >>
pmc->soc->regs->rst_level_shift; pmc->soc->regs->rst_level_shift;
...@@ -1641,16 +1743,16 @@ static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc) ...@@ -1641,16 +1743,16 @@ static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc)
err = device_create_file(dev, &dev_attr_reset_reason); err = device_create_file(dev, &dev_attr_reset_reason);
if (err < 0) if (err < 0)
dev_warn(dev, dev_warn(dev,
"failed to create attr \"reset_reason\": %d\n", "failed to create attr \"reset_reason\": %d\n",
err); err);
} }
if (pmc->soc->reset_levels) { if (pmc->soc->reset_levels) {
err = device_create_file(dev, &dev_attr_reset_level); err = device_create_file(dev, &dev_attr_reset_level);
if (err < 0) if (err < 0)
dev_warn(dev, dev_warn(dev,
"failed to create attr \"reset_level\": %d\n", "failed to create attr \"reset_level\": %d\n",
err); err);
} }
} }
...@@ -1920,6 +2022,8 @@ static int tegra_pmc_probe(struct platform_device *pdev) ...@@ -1920,6 +2022,8 @@ static int tegra_pmc_probe(struct platform_device *pdev)
pmc->base = base; pmc->base = base;
mutex_unlock(&pmc->powergates_lock); mutex_unlock(&pmc->powergates_lock);
platform_set_drvdata(pdev, pmc);
return 0; return 0;
cleanup_restart_handler: cleanup_restart_handler:
...@@ -1932,14 +2036,18 @@ static int tegra_pmc_probe(struct platform_device *pdev) ...@@ -1932,14 +2036,18 @@ static int tegra_pmc_probe(struct platform_device *pdev)
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
static int tegra_pmc_suspend(struct device *dev) static int tegra_pmc_suspend(struct device *dev)
{ {
tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41); struct tegra_pmc *pmc = dev_get_drvdata(dev);
tegra_pmc_writel(pmc, virt_to_phys(tegra_resume), PMC_SCRATCH41);
return 0; return 0;
} }
static int tegra_pmc_resume(struct device *dev) static int tegra_pmc_resume(struct device *dev)
{ {
tegra_pmc_writel(0x0, PMC_SCRATCH41); struct tegra_pmc *pmc = dev_get_drvdata(dev);
tegra_pmc_writel(pmc, 0x0, PMC_SCRATCH41);
return 0; return 0;
} }
...@@ -1976,11 +2084,11 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc) ...@@ -1976,11 +2084,11 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc)
u32 value; u32 value;
/* Always enable CPU power request */ /* Always enable CPU power request */
value = tegra_pmc_readl(PMC_CNTRL); value = tegra_pmc_readl(pmc, PMC_CNTRL);
value |= PMC_CNTRL_CPU_PWRREQ_OE; value |= PMC_CNTRL_CPU_PWRREQ_OE;
tegra_pmc_writel(value, PMC_CNTRL); tegra_pmc_writel(pmc, value, PMC_CNTRL);
value = tegra_pmc_readl(PMC_CNTRL); value = tegra_pmc_readl(pmc, PMC_CNTRL);
if (pmc->sysclkreq_high) if (pmc->sysclkreq_high)
value &= ~PMC_CNTRL_SYSCLK_POLARITY; value &= ~PMC_CNTRL_SYSCLK_POLARITY;
...@@ -1988,12 +2096,12 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc) ...@@ -1988,12 +2096,12 @@ static void tegra20_pmc_init(struct tegra_pmc *pmc)
value |= PMC_CNTRL_SYSCLK_POLARITY; value |= PMC_CNTRL_SYSCLK_POLARITY;
/* configure the output polarity while the request is tristated */ /* configure the output polarity while the request is tristated */
tegra_pmc_writel(value, PMC_CNTRL); tegra_pmc_writel(pmc, value, PMC_CNTRL);
/* now enable the request */ /* now enable the request */
value = tegra_pmc_readl(PMC_CNTRL); value = tegra_pmc_readl(pmc, PMC_CNTRL);
value |= PMC_CNTRL_SYSCLK_OE; value |= PMC_CNTRL_SYSCLK_OE;
tegra_pmc_writel(value, PMC_CNTRL); tegra_pmc_writel(pmc, value, PMC_CNTRL);
} }
static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc, static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
...@@ -2002,14 +2110,14 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc, ...@@ -2002,14 +2110,14 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
{ {
u32 value; u32 value;
value = tegra_pmc_readl(PMC_CNTRL); value = tegra_pmc_readl(pmc, PMC_CNTRL);
if (invert) if (invert)
value |= PMC_CNTRL_INTR_POLARITY; value |= PMC_CNTRL_INTR_POLARITY;
else else
value &= ~PMC_CNTRL_INTR_POLARITY; value &= ~PMC_CNTRL_INTR_POLARITY;
tegra_pmc_writel(value, PMC_CNTRL); tegra_pmc_writel(pmc, value, PMC_CNTRL);
} }
static const struct tegra_pmc_soc tegra20_pmc_soc = { static const struct tegra_pmc_soc tegra20_pmc_soc = {
...@@ -2019,6 +2127,9 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { ...@@ -2019,6 +2127,9 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.cpu_powergates = NULL, .cpu_powergates = NULL,
.has_tsense_reset = false, .has_tsense_reset = false,
.has_gpu_clamps = false, .has_gpu_clamps = false,
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
.num_io_pads = 0, .num_io_pads = 0,
.io_pads = NULL, .io_pads = NULL,
.num_pin_descs = 0, .num_pin_descs = 0,
...@@ -2063,7 +2174,9 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { ...@@ -2063,7 +2174,9 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.cpu_powergates = tegra30_cpu_powergates, .cpu_powergates = tegra30_cpu_powergates,
.has_tsense_reset = true, .has_tsense_reset = true,
.has_gpu_clamps = false, .has_gpu_clamps = false,
.needs_mbist_war = false,
.has_impl_33v_pwr = false, .has_impl_33v_pwr = false,
.maybe_tz_only = false,
.num_io_pads = 0, .num_io_pads = 0,
.io_pads = NULL, .io_pads = NULL,
.num_pin_descs = 0, .num_pin_descs = 0,
...@@ -2112,7 +2225,9 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { ...@@ -2112,7 +2225,9 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.cpu_powergates = tegra114_cpu_powergates, .cpu_powergates = tegra114_cpu_powergates,
.has_tsense_reset = true, .has_tsense_reset = true,
.has_gpu_clamps = false, .has_gpu_clamps = false,
.needs_mbist_war = false,
.has_impl_33v_pwr = false, .has_impl_33v_pwr = false,
.maybe_tz_only = false,
.num_io_pads = 0, .num_io_pads = 0,
.io_pads = NULL, .io_pads = NULL,
.num_pin_descs = 0, .num_pin_descs = 0,
...@@ -2221,7 +2336,9 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { ...@@ -2221,7 +2336,9 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.cpu_powergates = tegra124_cpu_powergates, .cpu_powergates = tegra124_cpu_powergates,
.has_tsense_reset = true, .has_tsense_reset = true,
.has_gpu_clamps = true, .has_gpu_clamps = true,
.needs_mbist_war = false,
.has_impl_33v_pwr = false, .has_impl_33v_pwr = false,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra124_io_pads), .num_io_pads = ARRAY_SIZE(tegra124_io_pads),
.io_pads = tegra124_io_pads, .io_pads = tegra124_io_pads,
.num_pin_descs = ARRAY_SIZE(tegra124_pin_descs), .num_pin_descs = ARRAY_SIZE(tegra124_pin_descs),
...@@ -2325,8 +2442,9 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { ...@@ -2325,8 +2442,9 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.cpu_powergates = tegra210_cpu_powergates, .cpu_powergates = tegra210_cpu_powergates,
.has_tsense_reset = true, .has_tsense_reset = true,
.has_gpu_clamps = true, .has_gpu_clamps = true,
.has_impl_33v_pwr = false,
.needs_mbist_war = true, .needs_mbist_war = true,
.has_impl_33v_pwr = false,
.maybe_tz_only = true,
.num_io_pads = ARRAY_SIZE(tegra210_io_pads), .num_io_pads = ARRAY_SIZE(tegra210_io_pads),
.io_pads = tegra210_io_pads, .io_pads = tegra210_io_pads,
.num_pin_descs = ARRAY_SIZE(tegra210_pin_descs), .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
...@@ -2413,7 +2531,7 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc, ...@@ -2413,7 +2531,7 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
index = of_property_match_string(np, "reg-names", "wake"); index = of_property_match_string(np, "reg-names", "wake");
if (index < 0) { if (index < 0) {
pr_err("failed to find PMC wake registers\n"); dev_err(pmc->dev, "failed to find PMC wake registers\n");
return; return;
} }
...@@ -2421,7 +2539,7 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc, ...@@ -2421,7 +2539,7 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
wake = ioremap_nocache(regs.start, resource_size(&regs)); wake = ioremap_nocache(regs.start, resource_size(&regs));
if (!wake) { if (!wake) {
pr_err("failed to map PMC wake registers\n"); dev_err(pmc->dev, "failed to map PMC wake registers\n");
return; return;
} }
...@@ -2438,7 +2556,7 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc, ...@@ -2438,7 +2556,7 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
} }
static const struct tegra_wake_event tegra186_wake_events[] = { static const struct tegra_wake_event tegra186_wake_events[] = {
TEGRA_WAKE_GPIO("power", 29, 1, TEGRA_AON_GPIO(FF, 0)), TEGRA_WAKE_GPIO("power", 29, 1, TEGRA186_AON_GPIO(FF, 0)),
TEGRA_WAKE_IRQ("rtc", 73, 10), TEGRA_WAKE_IRQ("rtc", 73, 10),
}; };
...@@ -2449,7 +2567,9 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = { ...@@ -2449,7 +2567,9 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.cpu_powergates = NULL, .cpu_powergates = NULL,
.has_tsense_reset = false, .has_tsense_reset = false,
.has_gpu_clamps = false, .has_gpu_clamps = false,
.needs_mbist_war = false,
.has_impl_33v_pwr = true, .has_impl_33v_pwr = true,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra186_io_pads), .num_io_pads = ARRAY_SIZE(tegra186_io_pads),
.io_pads = tegra186_io_pads, .io_pads = tegra186_io_pads,
.num_pin_descs = ARRAY_SIZE(tegra186_pin_descs), .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
...@@ -2527,6 +2647,9 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = { ...@@ -2527,6 +2647,9 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
.cpu_powergates = NULL, .cpu_powergates = NULL,
.has_tsense_reset = false, .has_tsense_reset = false,
.has_gpu_clamps = false, .has_gpu_clamps = false,
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra194_io_pads), .num_io_pads = ARRAY_SIZE(tegra194_io_pads),
.io_pads = tegra194_io_pads, .io_pads = tegra194_io_pads,
.regs = &tegra186_pmc_regs, .regs = &tegra186_pmc_regs,
...@@ -2561,6 +2684,32 @@ static struct platform_driver tegra_pmc_driver = { ...@@ -2561,6 +2684,32 @@ static struct platform_driver tegra_pmc_driver = {
}; };
builtin_platform_driver(tegra_pmc_driver); builtin_platform_driver(tegra_pmc_driver);
static bool __init tegra_pmc_detect_tz_only(struct tegra_pmc *pmc)
{
u32 value, saved;
saved = readl(pmc->base + pmc->soc->regs->scratch0);
value = saved ^ 0xffffffff;
if (value == 0xffffffff)
value = 0xdeadbeef;
/* write pattern and read it back */
writel(value, pmc->base + pmc->soc->regs->scratch0);
value = readl(pmc->base + pmc->soc->regs->scratch0);
/* if we read all-zeroes, access is restricted to TZ only */
if (value == 0) {
pr_info("access to PMC is restricted to TZ\n");
return true;
}
/* restore original value */
writel(saved, pmc->base + pmc->soc->regs->scratch0);
return false;
}
/* /*
* Early initialization to allow access to registers in the very early boot * Early initialization to allow access to registers in the very early boot
* process. * process.
...@@ -2623,6 +2772,9 @@ static int __init tegra_pmc_early_init(void) ...@@ -2623,6 +2772,9 @@ static int __init tegra_pmc_early_init(void)
if (np) { if (np) {
pmc->soc = match->data; pmc->soc = match->data;
if (pmc->soc->maybe_tz_only)
pmc->tz_only = tegra_pmc_detect_tz_only(pmc);
tegra_powergate_init(pmc, np); tegra_powergate_init(pmc, np);
/* /*
......
...@@ -161,7 +161,6 @@ enum tegra_io_pad { ...@@ -161,7 +161,6 @@ enum tegra_io_pad {
#define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS #define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS
#ifdef CONFIG_SOC_TEGRA_PMC #ifdef CONFIG_SOC_TEGRA_PMC
int tegra_powergate_is_powered(unsigned int id);
int tegra_powergate_power_on(unsigned int id); int tegra_powergate_power_on(unsigned int id);
int tegra_powergate_power_off(unsigned int id); int tegra_powergate_power_off(unsigned int id);
int tegra_powergate_remove_clamping(unsigned int id); int tegra_powergate_remove_clamping(unsigned int id);
...@@ -182,11 +181,6 @@ void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); ...@@ -182,11 +181,6 @@ void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode);
#else #else
static inline int tegra_powergate_is_powered(unsigned int id)
{
return -ENOSYS;
}
static inline int tegra_powergate_power_on(unsigned int id) static inline int tegra_powergate_power_on(unsigned int id)
{ {
return -ENOSYS; return -ENOSYS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment