[RFC] ARM: l2x0: suspend/resume entries

From: Barry Song <hidden>
Date: 2011-08-17 05:11:49
Also in: linux-arm-kernel, lkml
Subsystem: arm port, the rest · Maintainers: Russell King, Linus Torvalds

2011/7/7 Rob Herring [off-list ref]:
From: Rob Herring <redacted>

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 <redacted>
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 <redacted>
Subject: [RFC][PATCH] ARM: L2X0: add suspend/resume syscore ops

Signed-off-by: Barry Song <redacted>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help