diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/msr.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index df85c9c13601..e0d5e82e64b3 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
@@ -133,37 +133,42 @@ static const struct file_operations msr_fops = { | |||
133 | .open = msr_open, | 133 | .open = msr_open, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int __cpuinit msr_device_create(int i) | 136 | static int msr_device_create(int cpu) |
137 | { | 137 | { |
138 | int err = 0; | ||
139 | struct device *dev; | 138 | struct device *dev; |
140 | 139 | ||
141 | dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); | 140 | dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), |
142 | if (IS_ERR(dev)) | 141 | "msr%d", cpu); |
143 | err = PTR_ERR(dev); | 142 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; |
144 | return err; | 143 | } |
144 | |||
145 | static void msr_device_destroy(int cpu) | ||
146 | { | ||
147 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | ||
145 | } | 148 | } |
146 | 149 | ||
147 | static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb, | 150 | static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb, |
148 | unsigned long action, void *hcpu) | 151 | unsigned long action, void *hcpu) |
149 | { | 152 | { |
150 | unsigned int cpu = (unsigned long)hcpu; | 153 | unsigned int cpu = (unsigned long)hcpu; |
154 | int err = 0; | ||
151 | 155 | ||
152 | switch (action) { | 156 | switch (action) { |
153 | case CPU_ONLINE: | 157 | case CPU_UP_PREPARE: |
154 | case CPU_ONLINE_FROZEN: | 158 | case CPU_UP_PREPARE_FROZEN: |
155 | msr_device_create(cpu); | 159 | err = msr_device_create(cpu); |
156 | break; | 160 | break; |
161 | case CPU_UP_CANCELED: | ||
162 | case CPU_UP_CANCELED_FROZEN: | ||
157 | case CPU_DEAD: | 163 | case CPU_DEAD: |
158 | case CPU_DEAD_FROZEN: | 164 | case CPU_DEAD_FROZEN: |
159 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 165 | msr_device_destroy(cpu); |
160 | break; | 166 | break; |
161 | } | 167 | } |
162 | return NOTIFY_OK; | 168 | return err ? NOTIFY_BAD : NOTIFY_OK; |
163 | } | 169 | } |
164 | 170 | ||
165 | static struct notifier_block __cpuinitdata msr_class_cpu_notifier = | 171 | static struct notifier_block __cpuinitdata msr_class_cpu_notifier = { |
166 | { | ||
167 | .notifier_call = msr_class_cpu_callback, | 172 | .notifier_call = msr_class_cpu_callback, |
168 | }; | 173 | }; |
169 | 174 | ||
@@ -196,7 +201,7 @@ static int __init msr_init(void) | |||
196 | out_class: | 201 | out_class: |
197 | i = 0; | 202 | i = 0; |
198 | for_each_online_cpu(i) | 203 | for_each_online_cpu(i) |
199 | device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); | 204 | msr_device_destroy(i); |
200 | class_destroy(msr_class); | 205 | class_destroy(msr_class); |
201 | out_chrdev: | 206 | out_chrdev: |
202 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 207 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); |
@@ -208,7 +213,7 @@ static void __exit msr_exit(void) | |||
208 | { | 213 | { |
209 | int cpu = 0; | 214 | int cpu = 0; |
210 | for_each_online_cpu(cpu) | 215 | for_each_online_cpu(cpu) |
211 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 216 | msr_device_destroy(cpu); |
212 | class_destroy(msr_class); | 217 | class_destroy(msr_class); |
213 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 218 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); |
214 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); | 219 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); |