The powergate status register has PCIE and VDEC bits swapped. Using decicated tegra_powergate_get_status function instead of reading the PWRGATE_STATUS register allows to workaround this problem. Signed-off-by: Mike Rapoport <mike@xxxxxxxxxxxxxx> --- v2 changes: incorporated feedback from Erik Gilling --- arch/arm/mach-tegra/powergate.c | 28 +++++++++++++++++++++++----- 1 files changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index c286dad..863c8f5 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -52,6 +52,27 @@ static void pmc_write(u32 val, unsigned long reg) writel(val, pmc + reg); } +static bool tegra_powergate_get_status(int id) +{ + u32 mask; + u32 val; + + /* + * Tegra 2 has a bug where PCIE and VDE clamping masks are + * swapped relatively to the partition ids + */ + if (id == TEGRA_POWERGATE_VDEC) + mask = (1 << TEGRA_POWERGATE_PCIE); + else if (id == TEGRA_POWERGATE_PCIE) + mask = (1 << TEGRA_POWERGATE_VDEC); + else + mask = (1 << id); + + val = pmc_read(PWRGATE_STATUS); + + return !!(val & mask); +} + static int tegra_powergate_set(int id, bool new_state) { bool status; @@ -59,7 +80,7 @@ static int tegra_powergate_set(int id, bool new_state) spin_lock_irqsave(&tegra_powergate_lock, flags); - status = pmc_read(PWRGATE_STATUS) & (1 << id); + status = tegra_powergate_get_status(id); if (status == new_state) { spin_unlock_irqrestore(&tegra_powergate_lock, flags); @@ -91,13 +112,10 @@ int tegra_powergate_power_off(int id) bool tegra_powergate_is_powered(int id) { - u32 status; - if (id < 0 || id >= TEGRA_NUM_POWERGATE) return -EINVAL; - status = pmc_read(PWRGATE_STATUS) & (1 << id); - return !!status; + return tegra_powergate_get_status(id); } int tegra_powergate_remove_clamping(int id) -- 1.6.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html