aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Schaefer <gerald.schaefer@de.ibm.com>2009-06-16 04:30:48 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-06-16 04:31:20 -0400
commit039979049834bde56f67f8078c802b416bd4763c (patch)
treea7fe7b8b8912d4137fd026db3286100faac097fb
parent4b214a0c7720bfcfaca936047a359f8859fc8424 (diff)
[S390] pm: memory hotplug power management callbacks
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/char/sclp_cmd.c42
-rw-r--r--mm/Kconfig4
2 files changed, 40 insertions, 6 deletions
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 77ab6e34a100..5cc11c636d38 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * drivers/s390/char/sclp_cmd.c 2 * Copyright IBM Corp. 2007, 2009
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, 5 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
7 */ 6 */
8 7
9#define KMSG_COMPONENT "sclp_cmd" 8#define KMSG_COMPONENT "sclp_cmd"
@@ -12,11 +11,13 @@
12#include <linux/completion.h> 11#include <linux/completion.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/err.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/mmzone.h> 18#include <linux/mmzone.h>
19#include <linux/memory.h> 19#include <linux/memory.h>
20#include <linux/platform_device.h>
20#include <asm/chpid.h> 21#include <asm/chpid.h>
21#include <asm/sclp.h> 22#include <asm/sclp.h>
22#include <asm/setup.h> 23#include <asm/setup.h>
@@ -292,6 +293,7 @@ static DEFINE_MUTEX(sclp_mem_mutex);
292static LIST_HEAD(sclp_mem_list); 293static LIST_HEAD(sclp_mem_list);
293static u8 sclp_max_storage_id; 294static u8 sclp_max_storage_id;
294static unsigned long sclp_storage_ids[256 / BITS_PER_LONG]; 295static unsigned long sclp_storage_ids[256 / BITS_PER_LONG];
296static int sclp_mem_state_changed;
295 297
296struct memory_increment { 298struct memory_increment {
297 struct list_head list; 299 struct list_head list;
@@ -450,6 +452,8 @@ static int sclp_mem_notifier(struct notifier_block *nb,
450 rc = -EINVAL; 452 rc = -EINVAL;
451 break; 453 break;
452 } 454 }
455 if (!rc)
456 sclp_mem_state_changed = 1;
453 mutex_unlock(&sclp_mem_mutex); 457 mutex_unlock(&sclp_mem_mutex);
454 return rc ? NOTIFY_BAD : NOTIFY_OK; 458 return rc ? NOTIFY_BAD : NOTIFY_OK;
455} 459}
@@ -525,6 +529,14 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
525 list_add(&new_incr->list, prev); 529 list_add(&new_incr->list, prev);
526} 530}
527 531
532static int sclp_mem_freeze(struct device *dev)
533{
534 if (!sclp_mem_state_changed)
535 return 0;
536 pr_err("Memory hotplug state changed, suspend refused.\n");
537 return -EPERM;
538}
539
528struct read_storage_sccb { 540struct read_storage_sccb {
529 struct sccb_header header; 541 struct sccb_header header;
530 u16 max_id; 542 u16 max_id;
@@ -534,8 +546,20 @@ struct read_storage_sccb {
534 u32 entries[0]; 546 u32 entries[0];
535} __packed; 547} __packed;
536 548
549static struct dev_pm_ops sclp_mem_pm_ops = {
550 .freeze = sclp_mem_freeze,
551};
552
553static struct platform_driver sclp_mem_pdrv = {
554 .driver = {
555 .name = "sclp_mem",
556 .pm = &sclp_mem_pm_ops,
557 },
558};
559
537static int __init sclp_detect_standby_memory(void) 560static int __init sclp_detect_standby_memory(void)
538{ 561{
562 struct platform_device *sclp_pdev;
539 struct read_storage_sccb *sccb; 563 struct read_storage_sccb *sccb;
540 int i, id, assigned, rc; 564 int i, id, assigned, rc;
541 565
@@ -588,7 +612,17 @@ static int __init sclp_detect_standby_memory(void)
588 rc = register_memory_notifier(&sclp_mem_nb); 612 rc = register_memory_notifier(&sclp_mem_nb);
589 if (rc) 613 if (rc)
590 goto out; 614 goto out;
615 rc = platform_driver_register(&sclp_mem_pdrv);
616 if (rc)
617 goto out;
618 sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
619 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
620 if (rc)
621 goto out_driver;
591 sclp_add_standby_memory(); 622 sclp_add_standby_memory();
623 goto out;
624out_driver:
625 platform_driver_unregister(&sclp_mem_pdrv);
592out: 626out:
593 free_page((unsigned long) sccb); 627 free_page((unsigned long) sccb);
594 return rc; 628 return rc;
diff --git a/mm/Kconfig b/mm/Kconfig
index 71830ba7b986..6f4610a9ce55 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -128,11 +128,11 @@ config SPARSEMEM_VMEMMAP
128config MEMORY_HOTPLUG 128config MEMORY_HOTPLUG
129 bool "Allow for memory hot-add" 129 bool "Allow for memory hot-add"
130 depends on SPARSEMEM || X86_64_ACPI_NUMA 130 depends on SPARSEMEM || X86_64_ACPI_NUMA
131 depends on HOTPLUG && !HIBERNATION && ARCH_ENABLE_MEMORY_HOTPLUG 131 depends on HOTPLUG && !(HIBERNATION && !S390) && ARCH_ENABLE_MEMORY_HOTPLUG
132 depends on (IA64 || X86 || PPC64 || SUPERH || S390) 132 depends on (IA64 || X86 || PPC64 || SUPERH || S390)
133 133
134comment "Memory hotplug is currently incompatible with Software Suspend" 134comment "Memory hotplug is currently incompatible with Software Suspend"
135 depends on SPARSEMEM && HOTPLUG && HIBERNATION 135 depends on SPARSEMEM && HOTPLUG && HIBERNATION && !S390
136 136
137config MEMORY_HOTPLUG_SPARSE 137config MEMORY_HOTPLUG_SPARSE
138 def_bool y 138 def_bool y