summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/pm-r8a7779.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile/pm-r8a7779.c')
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7779.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
index d9c56fe067a5..c38ba7b43ef8 100644
--- a/arch/arm/mach-shmobile/pm-r8a7779.c
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -48,7 +48,9 @@ static void __iomem *r8a7779_sysc_base;
#define SYSCISR_RETRIES 1000
#define SYSCISR_DELAY_US 1
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) || defined(CONFIG_SMP)
+
+static DEFINE_SPINLOCK(r8a7779_sysc_lock); /* SMP CPUs + I/O devices */
static int r8a7779_sysc_pwr_on_off(struct r8a7779_pm_ch *r8a7779_ch,
int sr_bit, int reg_offs)
@@ -86,9 +88,12 @@ static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
unsigned int isr_mask = 1 << r8a7779_ch->isr_bit;
unsigned int chan_mask = 1 << r8a7779_ch->chan_bit;
unsigned int status;
+ unsigned long flags;
int ret = 0;
int k;
+ spin_lock_irqsave(&r8a7779_sysc_lock, flags);
+
iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
do {
@@ -112,6 +117,8 @@ static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
out:
+ spin_unlock_irqrestore(&r8a7779_sysc_lock, flags);
+
pr_debug("r8a7779 power domain %d: %02x %02x %02x %02x %02x -> %d\n",
r8a7779_ch->isr_bit, ioread32(r8a7779_sysc_base + PWRSR0),
ioread32(r8a7779_sysc_base + PWRSR1),
@@ -121,12 +128,12 @@ static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
return ret;
}
-static int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
+int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
{
return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off);
}
-static int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
+int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
{
return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on);
}
@@ -142,6 +149,14 @@ static void __init r8a7779_sysc_init(void)
iowrite32(0, r8a7779_sysc_base + SYSCIMR);
}
+#else /* CONFIG_PM || CONFIG_SMP */
+
+static inline void r8a7779_sysc_init(void) {}
+
+#endif /* CONFIG_PM || CONFIG_SMP */
+
+#ifdef CONFIG_PM
+
static int pd_power_down(struct generic_pm_domain *genpd)
{
return r8a7779_sysc_power_down(to_r8a7779_ch(genpd));
@@ -223,13 +238,12 @@ struct r8a7779_pm_domain r8a7779_impx3 = {
}
};
-#else /* CONFIG_PM */
-
-static inline void r8a7779_sysc_init(void) {}
-
#endif /* CONFIG_PM */
void __init r8a7779_pm_init(void)
{
- r8a7779_sysc_init();
+ static int once;
+
+ if (!once++)
+ r8a7779_sysc_init();
}
OpenPOWER on IntegriCloud