[RFC] ARM: l2x0: suspend/resume entries

Barry Song 21cnbao at gmail.com
Wed Aug 17 15:11:22 EST 2011


2011/7/7 Rob Herring <robherring2 at gmail.com>:
> From: Rob Herring <rob.herring at calxeda.com>
>
> This adds probing for ARM L2x0 cache controllers via device tree. Support
> includes the L210, L220, and PL310 controllers. The binding allows setting
> up cache RAM latencies and filter addresses (PL310 only).
>
> Signed-off-by: Rob Herring <rob.herring at calxeda.com>

Based on this patch, I simply modified some codes to add preliminary
suspend/resume entries for l2 cache and request for comments. it is
not a formal patch.

From: Barry Song <Baohua.Song at csr.com>
Subject: [RFC][PATCH] ARM: L2X0: add suspend/resume syscore ops

Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 arch/arm/mm/cache-l2x0.c |   74 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index c035b9a..8db89b5 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -32,6 +32,11 @@ static void __iomem *l2x0_base;
 static DEFINE_SPINLOCK(l2x0_lock);
 static uint32_t l2x0_way_mask;	/* Bitmask of active ways */
 static uint32_t l2x0_size;
+static uint32_t l2x0_aux_val;
+static uint32_t l2x0_aux_mask;
+static void (*l2x0_setup)(const struct device_node *np,
+                __u32 *aux_val, __u32 *aux_mask);
+static struct device_node *l2x0_np;

 static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
 {
@@ -280,7 +285,7 @@ static void l2x0_disable(void)
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }

-void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 {
 	__u32 aux;
 	__u32 cache_id;
@@ -431,26 +436,65 @@ static const struct of_device_id l2x0_ids[]
__initconst = {
 	{}
 };

-int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask)
+static void l2x0_arch_init(void)
 {
-	struct device_node *np;
-	void (*l2_setup)(const struct device_node *np,
-		__u32 *aux_val, __u32 *aux_mask);
+	/* L2 configuration can only be changed if the cache is disabled */
+	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+		if (l2x0_setup)
+			l2x0_setup(l2x0_np, &l2x0_aux_val, &l2x0_aux_mask);
+	}
+
+	l2x0_init(l2x0_base, l2x0_aux_val, l2x0_aux_mask);
+}
+
+#ifdef CONFIG_PM
+#include <linux/syscore_ops.h>
+
+static int l2x0_pm_suspend(void)
+{
+        l2x0_flush_all();
+        l2x0_clean_all();
+        l2x0_disable();
+        return 0;
+}
+
+static void l2x0_pm_resume(void)
+{
+	l2x0_arch_init();
+}
+
+static struct syscore_ops l2x0_pm_syscore_ops = {
+        .suspend        = l2x0_pm_suspend,
+        .resume         = l2x0_pm_resume,
+};

-	np = of_find_matching_node(NULL, l2x0_ids);
-	if (!np)
+static void __init l2x0_pm_init(void)
+{
+        register_syscore_ops(&l2x0_pm_syscore_ops);
+}
+
+#else
+static inline void l2x0_pm_init(void) { }
+#endif /* CONFIG_PM */
+
+
+int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask)
+{
+	l2x0_np = of_find_matching_node(NULL, l2x0_ids);
+	if (!l2x0_np)
 		return -ENODEV;
-	l2x0_base = of_iomap(np, 0);
+	l2x0_base = of_iomap(l2x0_np, 0);
 	if (!l2x0_base)
 		return -ENOMEM;

-	/* L2 configuration can only be changed if the cache is disabled */
-	if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
-		l2_setup = of_match_node(l2x0_ids, np)->data;
-		if (l2_setup)
-			l2_setup(np, &aux_val, &aux_mask);
-	}
-	l2x0_init(l2x0_base, aux_val, aux_mask);
+	l2x0_setup = of_match_node(l2x0_ids, l2x0_np)->data;
+
+	l2x0_aux_val = aux_val;
+	l2x0_aux_mask = aux_mask;
+
+	l2x0_arch_init();
+	l2x0_pm_init();
 	return 0;
 }
+
 #endif
-- 
1.7.1


More information about the devicetree-discuss mailing list