[PATCH 01/15] MIPS: lantiq: add locking for PMU register and check status afterwards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hauke Mehrtens <hauke.mehrtens@xxxxxxxxxx>

From: Hauke Mehrtens <hauke.mehrtens@xxxxxxxxxx>

The PMU register are accesses in a non atomic way and they could be
accesses by different threads simultaneously, which could cause
problems this patch adds locking around the PMU registers. In
addition it is now also waited till the PMU is actually deactivated.

Signed-off-by: Hauke Mehrtens <hauke.mehrtens@xxxxxxxxxx>
---
 arch/mips/lantiq/xway/sysctrl.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 2b15491..9965731 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -85,15 +85,19 @@ void __iomem *ltq_ebu_membase;
 static u32 ifccr = CGU_IFCCR;
 static u32 pcicr = CGU_PCICR;
 
+static DEFINE_SPINLOCK(g_pmu_lock);
+
 /* legacy function kept alive to ease clkdev transition */
 void ltq_pmu_enable(unsigned int module)
 {
-	int err = 1000000;
+	int retry = 1000000;
 
+	spin_lock(&g_pmu_lock);
 	pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR);
-	do {} while (--err && (pmu_r32(PMU_PWDSR) & module));
+	do {} while (--retry && (pmu_r32(PMU_PWDSR) & module));
+	spin_unlock(&g_pmu_lock);
 
-	if (!err)
+	if (!retry)
 		panic("activating PMU module failed!");
 }
 EXPORT_SYMBOL(ltq_pmu_enable);
@@ -101,7 +105,15 @@ EXPORT_SYMBOL(ltq_pmu_enable);
 /* legacy function kept alive to ease clkdev transition */
 void ltq_pmu_disable(unsigned int module)
 {
+	int retry = 1000000;
+
+	spin_lock(&g_pmu_lock);
 	pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR);
+	do {} while (--retry && (!(pmu_r32(PMU_PWDSR) & module)));
+	spin_unlock(&g_pmu_lock);
+
+	if (!retry)
+		pr_warn("deactivating PMU module failed!");
 }
 EXPORT_SYMBOL(ltq_pmu_disable);
 
@@ -123,9 +135,11 @@ static int pmu_enable(struct clk *clk)
 {
 	int retry = 1000000;
 
+	spin_lock(&g_pmu_lock);
 	pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
 		PWDCR(clk->module));
 	do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits));
+	spin_unlock(&g_pmu_lock);
 
 	if (!retry)
 		panic("activating PMU module failed!");
@@ -136,8 +150,15 @@ static int pmu_enable(struct clk *clk)
 /* disable a clock gate */
 static void pmu_disable(struct clk *clk)
 {
-	pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
-		PWDCR(clk->module));
+	int retry = 1000000;
+
+	spin_lock(&g_pmu_lock);
+	pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits, PWDCR(clk->module));
+	do {} while (--retry && (!(pmu_r32(PWDSR(clk->module)) & clk->bits)));
+	spin_unlock(&g_pmu_lock);
+
+	if (!retry)
+		pr_warn("deactivating PMU module failed!");
 }
 
 /* the pci enable helper */
-- 
2.6.1





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux