Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / arch / arm / mach-shmobile / pm-r8a7779.c
index d50a8e9..82fe3d7 100644 (file)
 #include <linux/suspend.h>
 #include <linux/err.h>
 #include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/console.h>
+
 #include <asm/io.h>
-#include <mach/common.h>
-#include <mach/r8a7779.h>
 
-static void __iomem *r8a7779_sysc_base;
+#include "common.h"
+#include "pm-rcar.h"
+#include "r8a7779.h"
 
 /* SYSC */
-#define SYSCSR 0x00
-#define SYSCISR 0x04
-#define SYSCISCR 0x08
 #define SYSCIER 0x0c
 #define SYSCIMR 0x10
-#define PWRSR0 0x40
-#define PWRSR1 0x80
-#define PWRSR2 0xc0
-#define PWRSR3 0x100
-#define PWRSR4 0x140
-
-#define PWRSR_OFFS 0x00
-#define PWROFFCR_OFFS 0x04
-#define PWRONCR_OFFS 0x0c
-#define PWRER_OFFS 0x14
-
-#define SYSCSR_RETRIES 100
-#define SYSCSR_DELAY_US 1
-
-#define SYSCISR_RETRIES 1000
-#define SYSCISR_DELAY_US 1
-
-#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)
-{
-       int k;
-
-       for (k = 0; k < SYSCSR_RETRIES; k++) {
-               if (ioread32(r8a7779_sysc_base + SYSCSR) & (1 << sr_bit))
-                       break;
-               udelay(SYSCSR_DELAY_US);
-       }
-
-       if (k == SYSCSR_RETRIES)
-               return -EAGAIN;
-
-       iowrite32(1 << r8a7779_ch->chan_bit,
-                 r8a7779_sysc_base + r8a7779_ch->chan_offs + reg_offs);
-
-       return 0;
-}
 
-static int r8a7779_sysc_pwr_off(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_pwr_on_off(r8a7779_ch, 0, PWROFFCR_OFFS);
-}
-
-static int r8a7779_sysc_pwr_on(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_pwr_on_off(r8a7779_ch, 1, PWRONCR_OFFS);
-}
-
-static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
-                              int (*on_off_fn)(struct r8a7779_pm_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 {
-               ret = on_off_fn(r8a7779_ch);
-               if (ret)
-                       goto out;
-
-               status = ioread32(r8a7779_sysc_base +
-                                 r8a7779_ch->chan_offs + PWRER_OFFS);
-       } while (status & chan_mask);
-
-       for (k = 0; k < SYSCISR_RETRIES; k++) {
-               if (ioread32(r8a7779_sysc_base + SYSCISR) & isr_mask)
-                       break;
-               udelay(SYSCISR_DELAY_US);
-       }
-
-       if (k == SYSCISR_RETRIES)
-               ret = -EIO;
-
-       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),
-                ioread32(r8a7779_sysc_base + PWRSR2),
-                ioread32(r8a7779_sysc_base + PWRSR3),
-                ioread32(r8a7779_sysc_base + PWRSR4), ret);
-       return ret;
-}
+struct r8a7779_pm_domain {
+       struct generic_pm_domain genpd;
+       struct rcar_sysc_ch ch;
+};
 
-int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
+static inline struct rcar_sysc_ch *to_r8a7779_ch(struct generic_pm_domain *d)
 {
-       return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off);
+       return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
 }
 
-int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
-{
-       return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on);
-}
+#if defined(CONFIG_PM) || defined(CONFIG_SMP)
 
 static void __init r8a7779_sysc_init(void)
 {
-       r8a7779_sysc_base = ioremap_nocache(0xffd85000, PAGE_SIZE);
-       if (!r8a7779_sysc_base)
-               panic("unable to ioremap r8a7779 SYSC hardware block\n");
+       void __iomem *base = rcar_sysc_init(0xffd85000);
 
        /* enable all interrupt sources, but do not use interrupt handler */
-       iowrite32(0x0131000e, r8a7779_sysc_base + SYSCIER);
-       iowrite32(0, r8a7779_sysc_base + SYSCIMR);
+       iowrite32(0x0131000e, base + SYSCIER);
+       iowrite32(0, base + SYSCIMR);
 }
 
 #else /* CONFIG_PM || CONFIG_SMP */
@@ -158,24 +61,17 @@ static inline void r8a7779_sysc_init(void) {}
 
 static int pd_power_down(struct generic_pm_domain *genpd)
 {
-       return r8a7779_sysc_power_down(to_r8a7779_ch(genpd));
+       return rcar_sysc_power_down(to_r8a7779_ch(genpd));
 }
 
 static int pd_power_up(struct generic_pm_domain *genpd)
 {
-       return r8a7779_sysc_power_up(to_r8a7779_ch(genpd));
+       return rcar_sysc_power_up(to_r8a7779_ch(genpd));
 }
 
 static bool pd_is_off(struct generic_pm_domain *genpd)
 {
-       struct r8a7779_pm_ch *r8a7779_ch = to_r8a7779_ch(genpd);
-       unsigned int st;
-
-       st = ioread32(r8a7779_sysc_base + r8a7779_ch->chan_offs + PWRSR_OFFS);
-       if (st & (1 << r8a7779_ch->chan_bit))
-               return true;
-
-       return false;
+       return rcar_sysc_power_is_off(to_r8a7779_ch(genpd));
 }
 
 static bool pd_active_wakeup(struct device *dev)
@@ -191,7 +87,6 @@ static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
        genpd->dev_ops.stop = pm_clk_suspend;
        genpd->dev_ops.start = pm_clk_resume;
        genpd->dev_ops.active_wakeup = pd_active_wakeup;
-       genpd->dev_irq_safe = true;
        genpd->power_off = pd_power_down;
        genpd->power_on = pd_power_up;