[PATCH 01/16] ARM: scu: Provide support for parsing SCU device node to enable SCU

Pankaj Dubey pankaj.dubey at samsung.com
Sun Nov 13 21:01:56 PST 2016


Many platforms are duplicating code for enabling SCU, lets add
common code to enable SCU by parsing SCU device node so the duplication
in each platform can be avoided.

CC: Krzysztof Kozlowski <krzk at kernel.org>
CC: Jisheng Zhang <jszhang at marvell.com>
CC: Russell King <linux at armlinux.org.uk>
CC: Dinh Nguyen <dinguyen at opensource.altera.com>
CC: Patrice Chotard <patrice.chotard at st.com>
CC: Linus Walleij <linus.walleij at linaro.org>
CC: Liviu Dudau <liviu.dudau at arm.com>
CC: Ray Jui <rjui at broadcom.com>
CC: Stephen Warren <swarren at wwwdotorg.org>
CC: Heiko Stuebner <heiko at sntech.de>
CC: Shawn Guo <shawnguo at kernel.org>
CC: Michal Simek <michal.simek at xilinx.com>
CC: Wei Xu <xuwei5 at hisilicon.com>
CC: Andrew Lunn <andrew at lunn.ch>
CC: Jun Nie <jun.nie at linaro.org> 
Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
 arch/arm/include/asm/smp_scu.h |  4 +++
 arch/arm/kernel/smp_scu.c      | 56 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index bfe163c..fdeec07 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -39,8 +39,12 @@ static inline int scu_power_mode(void __iomem *scu_base, unsigned int mode)
 
 #if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
 void scu_enable(void __iomem *scu_base);
+void __iomem *of_scu_get_base(void);
+int of_scu_enable(void);
 #else
 static inline void scu_enable(void __iomem *scu_base) {}
+static inline void __iomem *of_scu_get_base(void) {return NULL; }
+static inline int of_scu_enable(void) {return 0; }
 #endif
 
 #endif
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 72f9241..d0ac3ed 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -10,6 +10,7 @@
  */
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/of_address.h>
 
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
@@ -70,6 +71,61 @@ void scu_enable(void __iomem *scu_base)
 	 */
 	flush_cache_all();
 }
+
+static const struct of_device_id scu_match[] = {
+	{ .compatible = "arm,cortex-a9-scu", },
+	{ .compatible = "arm,cortex-a5-scu", },
+	{ }
+};
+
+/*
+ * Helper API to get SCU base address
+ * In case platform DT do not have SCU node, or iomap fails
+ * this call will fallback and will try to map via call to
+ * scu_a9_get_base.
+ * This will return ownership of scu_base to the caller
+ */
+void __iomem *of_scu_get_base(void)
+{
+	unsigned long base = 0;
+	struct device_node *np;
+	void __iomem *scu_base;
+
+	np = of_find_matching_node(NULL, scu_match);
+	scu_base = of_iomap(np, 0);
+	of_node_put(np);
+	if (!scu_base) {
+		pr_err("%s failed to map scu_base via DT\n", __func__);
+		if (scu_a9_has_base()) {
+			base = scu_a9_get_base();
+			scu_base = ioremap(base, SZ_4K);
+		}
+		if (!scu_base) {
+			pr_err("%s failed to map scu_base\n", __func__);
+			return IOMEM_ERR_PTR(-ENOMEM);
+		}
+	}
+	return scu_base;
+}
+
+/*
+ * Enable SCU via mapping scu_base DT
+ * If scu_base mapped successfully scu will be enabled and in case of
+ * failure if will return non-zero error code
+ */
+int of_scu_enable(void)
+{
+	void __iomem *scu_base;
+
+	scu_base = of_scu_get_base();
+	if (!IS_ERR(scu_base)) {
+		scu_enable(scu_base);
+		iounmap(scu_base);
+		return 0;
+	}
+	return PTR_ERR(scu_base);
+}
+
 #endif
 
 /*
-- 
2.7.4




More information about the linux-arm-kernel mailing list