powerpc/pseries: Update dynamic cache nodes for suspend/resume operation
authorHaren Myneni <hbabu@us.ibm.com>
Wed, 26 Feb 2014 04:02:18 +0000 (20:02 -0800)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 7 Mar 2014 04:54:49 +0000 (15:54 +1100)
pHyp can change cache nodes for suspend/resume operation. Currently the
device tree is updated by drmgr in userspace after all non boot CPUs are
enabled. Hence, we do not modify the cache list based on the latest cache
nodes. Also we do not remove cache entries for the primary CPU.

This patch removes the cache list for the boot CPU, updates the device tree
before enabling nonboot CPUs and adds cache list for the boot cpu.

This patch also has the side effect that older versions of drmgr will
perform a second device tree update from userspace. While this is a
redundant waste of a couple cycles it is harmless since firmware returns the
same data for the subsequent update-nodes/properties rtas calls.

Signed-off-by: Haren Myneni <hbabu@us.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/cacheinfo.c
arch/powerpc/platforms/pseries/suspend.c

index 9bd52c65e66f9800734b70fdf9f3d6b649c992ba..a0e1add01ef5804d00d105c5d3ba12e608be5f03 100644 (file)
@@ -283,6 +283,7 @@ extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
 
 #ifdef CONFIG_PPC_PSERIES
 extern int pseries_devicetree_update(s32 scope);
+extern void post_mobility_fixup(void);
 #endif
 
 #ifdef CONFIG_PPC_RTAS_DAEMON
index 2912b8787aa46b4b28b0e84a2e5c068afc2f5ea2..40198d50b4c24adb55da6db482d65098427b86b7 100644 (file)
@@ -756,7 +756,10 @@ void cacheinfo_cpu_online(unsigned int cpu_id)
        cacheinfo_sysfs_populate(cpu_id, cache);
 }
 
-#ifdef CONFIG_HOTPLUG_CPU /* functions needed for cpu offline */
+/* functions needed to remove cache entry for cpu offline or suspend/resume */
+
+#if (defined(CONFIG_PPC_PSERIES) && defined(CONFIG_SUSPEND)) || \
+    defined(CONFIG_HOTPLUG_CPU)
 
 static struct cache *cache_lookup_by_cpu(unsigned int cpu_id)
 {
@@ -843,4 +846,4 @@ void cacheinfo_cpu_offline(unsigned int cpu_id)
        if (cache)
                cache_cpu_clear(cache, cpu_id);
 }
-#endif /* CONFIG_HOTPLUG_CPU */
+#endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */
index 16a255255d3003c64ce8d517fe90bf8b9109552b..1d9c580ab7723771f1f0ff496c254261fa3a5fdc 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/mmu.h>
 #include <asm/rtas.h>
 #include <asm/topology.h>
+#include "../../kernel/cacheinfo.h"
 
 static u64 stream_id;
 static struct device suspend_dev;
@@ -78,6 +79,23 @@ static int pseries_suspend_cpu(void)
        return 0;
 }
 
+/**
+ * pseries_suspend_enable_irqs
+ *
+ * Post suspend configuration updates
+ *
+ **/
+static void pseries_suspend_enable_irqs(void)
+{
+       /*
+        * Update configuration which can be modified based on device tree
+        * changes during resume.
+        */
+       cacheinfo_cpu_offline(smp_processor_id());
+       post_mobility_fixup();
+       cacheinfo_cpu_online(smp_processor_id());
+}
+
 /**
  * pseries_suspend_enter - Final phase of hibernation
  *
@@ -235,6 +253,7 @@ static int __init pseries_suspend_init(void)
                return rc;
 
        ppc_md.suspend_disable_cpu = pseries_suspend_cpu;
+       ppc_md.suspend_enable_irqs = pseries_suspend_enable_irqs;
        suspend_set_ops(&pseries_suspend_ops);
        return 0;
 }
This page took 0.026752 seconds and 5 git commands to generate.