aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/xen
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@linaro.org>2014-01-30 07:52:59 -0500
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2014-01-30 07:52:59 -0500
commit8b271d57b57585a3e3e8cd7abc5f4d7710a0e62d (patch)
treefbe7d6e06d932a75f038e0dc760d9c6836a6657d /arch/arm/xen
parentc9f6e9977e38de15da96b732a8dec0ef56cbf977 (diff)
arm/xen: Initialize event channels earlier
Event channels driver needs to be initialized very early. Until now, Xen initialization was done after all CPUs was bring up. We can safely move the initialization to an early initcall. Also use a cpu notifier to: - Register the VCPU when the CPU is prepared - Enable event channel IRQ when the CPU is running Signed-off-by: Julien Grall <julien.grall@linaro.org> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'arch/arm/xen')
-rw-r--r--arch/arm/xen/enlighten.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 2162172c0ddc..3465f25d7702 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}
155EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); 156EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
156 157
157static void __init xen_percpu_init(void *unused) 158static 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
197static 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
212static struct notifier_block xen_cpu_notifier = {
213 .notifier_call = xen_cpu_notification,
214};
215
216static 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.
@@ -229,6 +255,10 @@ static int __init xen_guest_init(void)
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_pfn=%lx\n",
231 version, xen_events_irq, (grant_frames >> PAGE_SHIFT)); 257 version, xen_events_irq, (grant_frames >> PAGE_SHIFT));
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}
286core_initcall(xen_guest_init); 328early_initcall(xen_guest_init);
287 329
288static int __init xen_pm_init(void) 330static int __init xen_pm_init(void)
289{ 331{
@@ -297,31 +339,6 @@ static int __init xen_pm_init(void)
297} 339}
298late_initcall(xen_pm_init); 340late_initcall(xen_pm_init);
299 341
300static irqreturn_t xen_arm_callback(int irq, void *arg)
301{
302 xen_hvm_evtchn_do_upcall();
303 return IRQ_HANDLED;
304}
305
306static 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}
323postcore_initcall(xen_init_events);
324
325/* In the hypervisor.S file. */ 342/* In the hypervisor.S file. */
326EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); 343EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
327EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); 344EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);