summaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2016-02-11 18:03:23 +0000
committerThierry Reding <treding@nvidia.com>2016-04-05 15:22:48 +0200
commit0ecf2d33bb4686b5d8f06b3b18877de0d88d3af4 (patch)
tree75571f01a830109081ffaa00880e8193a227bca9 /drivers/soc
parent70293ed09decd1ec4ae5632af27cab73c16a50ba (diff)
downloadlinux-stable-0ecf2d33bb4686b5d8f06b3b18877de0d88d3af4.tar.gz
linux-stable-0ecf2d33bb4686b5d8f06b3b18877de0d88d3af4.tar.bz2
linux-stable-0ecf2d33bb4686b5d8f06b3b18877de0d88d3af4.zip
soc/tegra: pmc: Fix testing of powergate state
In tegra_powergate_set() the state of the powergates is read and OR'ed with the bit for the powergate of interest. This unsigned 32-bit value is then compared with a boolean value to test if the powergate is already in the desired state. When turning on a powergate, apart from the powergate that is represented by bit 0, this test will always return false and so we may attempt to turn on the powergate when it is already on. After OR'ing the bit for the powergate, check if the result is not equal to zero before comparing with the boolean value. Add a helper function to return the current state of a powergate and use this in both tegra_powergate_set() and tegra_powergate_is_powered() where we check the powergate status. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/tegra/pmc.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 5f32a3e34476..9e8d359baf0e 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -174,6 +174,11 @@ static void tegra_pmc_writel(u32 value, unsigned long offset)
writel(value, pmc->base + offset);
}
+static inline bool tegra_powergate_state(int id)
+{
+ return (tegra_pmc_readl(PWRGATE_STATUS) & BIT(id)) != 0;
+}
+
/**
* tegra_powergate_set() - set the state of a partition
* @id: partition ID
@@ -181,13 +186,9 @@ static void tegra_pmc_writel(u32 value, unsigned long offset)
*/
static int tegra_powergate_set(unsigned int id, bool new_state)
{
- bool status;
-
mutex_lock(&pmc->powergates_lock);
- status = tegra_pmc_readl(PWRGATE_STATUS) & (1 << id);
-
- if (status == new_state) {
+ if (tegra_powergate_state(id) == new_state) {
mutex_unlock(&pmc->powergates_lock);
return 0;
}
@@ -230,16 +231,16 @@ EXPORT_SYMBOL(tegra_powergate_power_off);
*/
int tegra_powergate_is_powered(unsigned int id)
{
- u32 status;
+ int status;
if (!pmc->soc || id >= pmc->soc->num_powergates)
return -EINVAL;
mutex_lock(&pmc->powergates_lock);
- status = tegra_pmc_readl(PWRGATE_STATUS) & (1 << id);
+ status = tegra_powergate_state(id);
mutex_unlock(&pmc->powergates_lock);
- return !!status;
+ return status;
}
/**