diff options
Diffstat (limited to 'arch/arm/xen/enlighten.c')
-rw-r--r-- | arch/arm/xen/enlighten.c | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 2162172c0ddc..b96723e258a0 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
24 | #include <linux/cpuidle.h> | 24 | #include <linux/cpuidle.h> |
25 | #include <linux/cpufreq.h> | 25 | #include <linux/cpufreq.h> |
26 | #include <linux/cpu.h> | ||
26 | 27 | ||
27 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
28 | 29 | ||
@@ -154,7 +155,7 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma, | |||
154 | } | 155 | } |
155 | EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); | 156 | EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); |
156 | 157 | ||
157 | static void __init xen_percpu_init(void *unused) | 158 | static void xen_percpu_init(void) |
158 | { | 159 | { |
159 | struct vcpu_register_vcpu_info info; | 160 | struct vcpu_register_vcpu_info info; |
160 | struct vcpu_info *vcpup; | 161 | struct vcpu_info *vcpup; |
@@ -193,6 +194,31 @@ static void xen_power_off(void) | |||
193 | BUG(); | 194 | BUG(); |
194 | } | 195 | } |
195 | 196 | ||
197 | static int xen_cpu_notification(struct notifier_block *self, | ||
198 | unsigned long action, | ||
199 | void *hcpu) | ||
200 | { | ||
201 | switch (action) { | ||
202 | case CPU_STARTING: | ||
203 | xen_percpu_init(); | ||
204 | break; | ||
205 | default: | ||
206 | break; | ||
207 | } | ||
208 | |||
209 | return NOTIFY_OK; | ||
210 | } | ||
211 | |||
212 | static struct notifier_block xen_cpu_notifier = { | ||
213 | .notifier_call = xen_cpu_notification, | ||
214 | }; | ||
215 | |||
216 | static irqreturn_t xen_arm_callback(int irq, void *arg) | ||
217 | { | ||
218 | xen_hvm_evtchn_do_upcall(); | ||
219 | return IRQ_HANDLED; | ||
220 | } | ||
221 | |||
196 | /* | 222 | /* |
197 | * see Documentation/devicetree/bindings/arm/xen.txt for the | 223 | * see Documentation/devicetree/bindings/arm/xen.txt for the |
198 | * documentation of the Xen Device Tree format. | 224 | * documentation of the Xen Device Tree format. |
@@ -208,7 +234,7 @@ static int __init xen_guest_init(void) | |||
208 | const char *version = NULL; | 234 | const char *version = NULL; |
209 | const char *xen_prefix = "xen,xen-"; | 235 | const char *xen_prefix = "xen,xen-"; |
210 | struct resource res; | 236 | struct resource res; |
211 | unsigned long grant_frames; | 237 | phys_addr_t grant_frames; |
212 | 238 | ||
213 | node = of_find_compatible_node(NULL, NULL, "xen,xen"); | 239 | node = of_find_compatible_node(NULL, NULL, "xen,xen"); |
214 | if (!node) { | 240 | if (!node) { |
@@ -227,8 +253,12 @@ static int __init xen_guest_init(void) | |||
227 | return 0; | 253 | return 0; |
228 | grant_frames = res.start; | 254 | grant_frames = res.start; |
229 | xen_events_irq = irq_of_parse_and_map(node, 0); | 255 | xen_events_irq = irq_of_parse_and_map(node, 0); |
230 | pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n", | 256 | pr_info("Xen %s support found, events_irq=%d gnttab_frame=%pa\n", |
231 | version, xen_events_irq, (grant_frames >> PAGE_SHIFT)); | 257 | version, xen_events_irq, &grant_frames); |
258 | |||
259 | if (xen_events_irq < 0) | ||
260 | return -ENODEV; | ||
261 | |||
232 | xen_domain_type = XEN_HVM_DOMAIN; | 262 | xen_domain_type = XEN_HVM_DOMAIN; |
233 | 263 | ||
234 | xen_setup_features(); | 264 | xen_setup_features(); |
@@ -281,9 +311,21 @@ static int __init xen_guest_init(void) | |||
281 | disable_cpuidle(); | 311 | disable_cpuidle(); |
282 | disable_cpufreq(); | 312 | disable_cpufreq(); |
283 | 313 | ||
314 | xen_init_IRQ(); | ||
315 | |||
316 | if (request_percpu_irq(xen_events_irq, xen_arm_callback, | ||
317 | "events", &xen_vcpu)) { | ||
318 | pr_err("Error request IRQ %d\n", xen_events_irq); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | xen_percpu_init(); | ||
323 | |||
324 | register_cpu_notifier(&xen_cpu_notifier); | ||
325 | |||
284 | return 0; | 326 | return 0; |
285 | } | 327 | } |
286 | core_initcall(xen_guest_init); | 328 | early_initcall(xen_guest_init); |
287 | 329 | ||
288 | static int __init xen_pm_init(void) | 330 | static int __init xen_pm_init(void) |
289 | { | 331 | { |
@@ -297,31 +339,6 @@ static int __init xen_pm_init(void) | |||
297 | } | 339 | } |
298 | late_initcall(xen_pm_init); | 340 | late_initcall(xen_pm_init); |
299 | 341 | ||
300 | static irqreturn_t xen_arm_callback(int irq, void *arg) | ||
301 | { | ||
302 | xen_hvm_evtchn_do_upcall(); | ||
303 | return IRQ_HANDLED; | ||
304 | } | ||
305 | |||
306 | static int __init xen_init_events(void) | ||
307 | { | ||
308 | if (!xen_domain() || xen_events_irq < 0) | ||
309 | return -ENODEV; | ||
310 | |||
311 | xen_init_IRQ(); | ||
312 | |||
313 | if (request_percpu_irq(xen_events_irq, xen_arm_callback, | ||
314 | "events", &xen_vcpu)) { | ||
315 | pr_err("Error requesting IRQ %d\n", xen_events_irq); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | on_each_cpu(xen_percpu_init, NULL, 0); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | postcore_initcall(xen_init_events); | ||
324 | |||
325 | /* In the hypervisor.S file. */ | 342 | /* In the hypervisor.S file. */ |
326 | EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); | 343 | EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); |
327 | EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); | 344 | EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); |