soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating
authorAndreas Färber <afaerber@suse.de>
Mon, 5 Jun 2017 19:04:21 +0000 (21:04 +0200)
committerAndreas Färber <afaerber@suse.de>
Fri, 23 Jun 2017 15:43:27 +0000 (17:43 +0200)
Allow the SMP code to reuse PM domain code for CPU2/CPU3 wakeup.

Signed-off-by: Andreas Färber <afaerber@suse.de>
drivers/soc/actions/Kconfig
drivers/soc/actions/Makefile
drivers/soc/actions/owl-sps-helper.c [new file with mode: 0644]
drivers/soc/actions/owl-sps.c
include/linux/soc/actions/owl-sps.h [new file with mode: 0644]

index bdf827d5ce78ed4f165235d362014cfbb1c8bd38..9d68b5a771c330ff1107eee5abdb7f8ebebf5bb9 100644 (file)
@@ -1,8 +1,12 @@
 if ARCH_ACTIONS || COMPILE_TEST
 
+config OWL_PM_DOMAINS_HELPER
+       bool
+
 config OWL_PM_DOMAINS
        bool "Actions Semi SPS power domains"
        depends on PM
+       select OWL_PM_DOMAINS_HELPER
        select PM_GENERIC_DOMAINS
        help
          Say 'y' here to enable support for Smart Power System (SPS)
index 720c34ed16e467db56fc41059c61ef1c468d35fc..1e101b06bab1e22ba838933870459f81627a4f66 100644 (file)
@@ -1 +1,2 @@
+obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o
 obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
diff --git a/drivers/soc/actions/owl-sps-helper.c b/drivers/soc/actions/owl-sps-helper.c
new file mode 100644 (file)
index 0000000..9d7a2c2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Actions Semi Owl Smart Power System (SPS) shared helpers
+ *
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#define OWL_SPS_PG_CTL 0x0
+
+int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable)
+{
+       u32 val;
+       bool ack;
+       int timeout;
+
+       val = readl(base + OWL_SPS_PG_CTL);
+       ack = val & ack_mask;
+       if (ack == enable)
+               return 0;
+
+       if (enable)
+               val |= pwr_mask;
+       else
+               val &= ~pwr_mask;
+
+       writel(val, base + OWL_SPS_PG_CTL);
+
+       for (timeout = 5000; timeout > 0; timeout -= 50) {
+               val = readl(base + OWL_SPS_PG_CTL);
+               if ((val & ack_mask) == (enable ? ack_mask : 0))
+                       break;
+               udelay(50);
+       }
+       if (timeout <= 0)
+               return -ETIMEDOUT;
+
+       udelay(10);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(owl_sps_set_pg);
index 8abb72f01929ec23bb741a89a01e08f7cfd4f50b..875225bfa21c2e77fd0d791a24a921c6b1469c34 100644 (file)
  * option) any later version.
  */
 
-#include <linux/delay.h>
-#include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_domain.h>
+#include <linux/soc/actions/owl-sps.h>
 #include <dt-bindings/power/owl-s500-powergate.h>
 
-#define OWL_SPS_PG_CTL 0x0
-
 struct owl_sps_domain_info {
        const char *name;
        int pwr_bit;
@@ -51,37 +48,12 @@ struct owl_sps_domain {
 
 static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable)
 {
-       u32 val, pwr_mask, ack_mask;
-       int timeout;
-       bool ack;
+       u32 pwr_mask, ack_mask;
 
        ack_mask = BIT(pd->info->ack_bit);
        pwr_mask = BIT(pd->info->pwr_bit);
-       val = readl(pd->sps->base + OWL_SPS_PG_CTL);
-       ack = val & ack_mask;
-
-       if (ack == enable)
-               return 0;
-
-       if (enable)
-               val |= pwr_mask;
-       else
-               val &= ~pwr_mask;
-
-       writel(val, pd->sps->base + OWL_SPS_PG_CTL);
 
-       for (timeout = 5000; timeout > 0; timeout -= 50) {
-               val = readl(pd->sps->base + OWL_SPS_PG_CTL);
-               if ((val & ack_mask) == (enable ? ack_mask : 0))
-                       break;
-               udelay(50);
-       }
-       if (timeout <= 0)
-               return -ETIMEDOUT;
-
-       udelay(10);
-
-       return 0;
+       return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable);
 }
 
 static int owl_sps_power_on(struct generic_pm_domain *domain)
diff --git a/include/linux/soc/actions/owl-sps.h b/include/linux/soc/actions/owl-sps.h
new file mode 100644 (file)
index 0000000..33d0dbe
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef SOC_ACTIONS_OWL_SPS_H
+#define SOC_ACTIONS_OWL_SPS_H
+
+int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable);
+
+#endif