diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-01-26 08:10:56 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-01-26 08:11:09 -0500 |
commit | 08d07968277cd898c88bf12b7720d89c02c4f139 (patch) | |
tree | 1c91768976c389883842eb7650141e93b7dbe334 /drivers/s390/char/sclp_info.c | |
parent | c05ffc4f2b208da8ba7d3a9b5ab886c76f8939b5 (diff) |
[S390] Standby cpu activation/deactivation.
Add a new interface so that cpus can be put into standby state and
configured state.
Only offline cpus can be put into standby state or configured state.
For that the new percpu sysfs attribute "configure" must be used.
To put a cpu in standby state a "0" must be written to the attribute.
In order to switch it into configured state a "1" must be written to
the attribute.
Only cpus in configured state can be brought online.
In addition this patch introduces a static mapping of physical to
logical cpus. As a result only the sysfs directories of present cpus
will be created. To scan for new cpus the new sysfs attribute "rescan"
must be used.
Writing to /sys/devices/system/cpu/rescan will trigger a rescan of
cpus and will create directories for new cpus.
On IPL only configured cpus will be used. And on reboot/shutdown all
cpus will remain in their current state (configured/standby).
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp_info.c')
-rw-r--r-- | drivers/s390/char/sclp_info.c | 116 |
1 files changed, 0 insertions, 116 deletions
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c deleted file mode 100644 index a1136e052750..000000000000 --- a/drivers/s390/char/sclp_info.c +++ /dev/null | |||
@@ -1,116 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_info.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/init.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <asm/sclp.h> | ||
12 | #include "sclp.h" | ||
13 | |||
14 | struct sclp_readinfo_sccb { | ||
15 | struct sccb_header header; /* 0-7 */ | ||
16 | u16 rnmax; /* 8-9 */ | ||
17 | u8 rnsize; /* 10 */ | ||
18 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
19 | u8 loadparm[8]; /* 24-31 */ | ||
20 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
21 | u64 facilities; /* 48-55 */ | ||
22 | u8 _reserved2[91 - 56]; /* 56-90 */ | ||
23 | u8 flags; /* 91 */ | ||
24 | u8 _reserved3[100 - 92]; /* 92-99 */ | ||
25 | u32 rnsize2; /* 100-103 */ | ||
26 | u64 rnmax2; /* 104-111 */ | ||
27 | u8 _reserved4[4096 - 112]; /* 112-4095 */ | ||
28 | } __attribute__((packed, aligned(4096))); | ||
29 | |||
30 | static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; | ||
31 | static int __initdata early_readinfo_sccb_valid; | ||
32 | |||
33 | u64 sclp_facilities; | ||
34 | |||
35 | void __init sclp_readinfo_early(void) | ||
36 | { | ||
37 | int ret; | ||
38 | int i; | ||
39 | struct sclp_readinfo_sccb *sccb; | ||
40 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
41 | SCLP_CMDW_READ_SCP_INFO}; | ||
42 | |||
43 | /* Enable service signal subclass mask. */ | ||
44 | __ctl_set_bit(0, 9); | ||
45 | sccb = &early_readinfo_sccb; | ||
46 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
47 | do { | ||
48 | memset(sccb, 0, sizeof(*sccb)); | ||
49 | sccb->header.length = sizeof(*sccb); | ||
50 | sccb->header.control_mask[2] = 0x80; | ||
51 | ret = sclp_service_call(commands[i], sccb); | ||
52 | } while (ret == -EBUSY); | ||
53 | |||
54 | if (ret) | ||
55 | break; | ||
56 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | ||
57 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | ||
58 | local_irq_disable(); | ||
59 | /* | ||
60 | * Contents of the sccb might have changed | ||
61 | * therefore a barrier is needed. | ||
62 | */ | ||
63 | barrier(); | ||
64 | if (sccb->header.response_code == 0x10) { | ||
65 | early_readinfo_sccb_valid = 1; | ||
66 | break; | ||
67 | } | ||
68 | if (sccb->header.response_code != 0x1f0) | ||
69 | break; | ||
70 | } | ||
71 | /* Disable service signal subclass mask again. */ | ||
72 | __ctl_clear_bit(0, 9); | ||
73 | } | ||
74 | |||
75 | void __init sclp_facilities_detect(void) | ||
76 | { | ||
77 | if (!early_readinfo_sccb_valid) | ||
78 | return; | ||
79 | sclp_facilities = early_readinfo_sccb.facilities; | ||
80 | } | ||
81 | |||
82 | unsigned long long __init sclp_memory_detect(void) | ||
83 | { | ||
84 | unsigned long long memsize; | ||
85 | struct sclp_readinfo_sccb *sccb; | ||
86 | |||
87 | if (!early_readinfo_sccb_valid) | ||
88 | return 0; | ||
89 | sccb = &early_readinfo_sccb; | ||
90 | if (sccb->rnsize) | ||
91 | memsize = sccb->rnsize << 20; | ||
92 | else | ||
93 | memsize = sccb->rnsize2 << 20; | ||
94 | if (sccb->rnmax) | ||
95 | memsize *= sccb->rnmax; | ||
96 | else | ||
97 | memsize *= sccb->rnmax2; | ||
98 | return memsize; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * This function will be called after sclp_memory_detect(), which gets called | ||
103 | * early from early.c code. Therefore the sccb should have valid contents. | ||
104 | */ | ||
105 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
106 | { | ||
107 | struct sclp_readinfo_sccb *sccb; | ||
108 | |||
109 | if (!early_readinfo_sccb_valid) | ||
110 | return; | ||
111 | sccb = &early_readinfo_sccb; | ||
112 | info->is_valid = 1; | ||
113 | if (sccb->flags & 0x2) | ||
114 | info->has_dump = 1; | ||
115 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
116 | } | ||