aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/xen/enlighten.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/xen/enlighten.c')
-rw-r--r--arch/arm/xen/enlighten.c77
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}
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.
@@ -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}
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);