@@ -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;
}
+