diff options
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/balloon.c | 2 | ||||
-rw-r--r-- | drivers/xen/events.c | 342 |
2 files changed, 128 insertions, 216 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 43f9f02c7db0..b1661cd416b0 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -296,7 +296,7 @@ static int decrease_reservation(unsigned long nr_pages) | |||
296 | /* No more mappings: invalidate P2M and add to balloon. */ | 296 | /* No more mappings: invalidate P2M and add to balloon. */ |
297 | for (i = 0; i < nr_pages; i++) { | 297 | for (i = 0; i < nr_pages; i++) { |
298 | pfn = mfn_to_pfn(frame_list[i]); | 298 | pfn = mfn_to_pfn(frame_list[i]); |
299 | set_phys_to_machine(pfn, INVALID_P2M_ENTRY); | 299 | __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); |
300 | balloon_append(pfn_to_page(pfn)); | 300 | balloon_append(pfn_to_page(pfn)); |
301 | } | 301 | } |
302 | 302 | ||
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 74681478100a..149fa875e396 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -114,7 +114,7 @@ struct cpu_evtchn_s { | |||
114 | static __initdata struct cpu_evtchn_s init_evtchn_mask = { | 114 | static __initdata struct cpu_evtchn_s init_evtchn_mask = { |
115 | .bits[0 ... (NR_EVENT_CHANNELS/BITS_PER_LONG)-1] = ~0ul, | 115 | .bits[0 ... (NR_EVENT_CHANNELS/BITS_PER_LONG)-1] = ~0ul, |
116 | }; | 116 | }; |
117 | static struct cpu_evtchn_s *cpu_evtchn_mask_p = &init_evtchn_mask; | 117 | static struct cpu_evtchn_s __refdata *cpu_evtchn_mask_p = &init_evtchn_mask; |
118 | 118 | ||
119 | static inline unsigned long *cpu_evtchn_mask(int cpu) | 119 | static inline unsigned long *cpu_evtchn_mask(int cpu) |
120 | { | 120 | { |
@@ -277,7 +277,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
277 | 277 | ||
278 | BUG_ON(irq == -1); | 278 | BUG_ON(irq == -1); |
279 | #ifdef CONFIG_SMP | 279 | #ifdef CONFIG_SMP |
280 | cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu)); | 280 | cpumask_copy(irq_to_desc(irq)->irq_data.affinity, cpumask_of(cpu)); |
281 | #endif | 281 | #endif |
282 | 282 | ||
283 | clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); | 283 | clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); |
@@ -294,7 +294,7 @@ static void init_evtchn_cpu_bindings(void) | |||
294 | 294 | ||
295 | /* By default all event channels notify CPU#0. */ | 295 | /* By default all event channels notify CPU#0. */ |
296 | for_each_irq_desc(i, desc) { | 296 | for_each_irq_desc(i, desc) { |
297 | cpumask_copy(desc->affinity, cpumask_of(0)); | 297 | cpumask_copy(desc->irq_data.affinity, cpumask_of(0)); |
298 | } | 298 | } |
299 | #endif | 299 | #endif |
300 | 300 | ||
@@ -376,81 +376,69 @@ static void unmask_evtchn(int port) | |||
376 | put_cpu(); | 376 | put_cpu(); |
377 | } | 377 | } |
378 | 378 | ||
379 | static int get_nr_hw_irqs(void) | 379 | static int xen_allocate_irq_dynamic(void) |
380 | { | 380 | { |
381 | int ret = 1; | 381 | int first = 0; |
382 | int irq; | ||
382 | 383 | ||
383 | #ifdef CONFIG_X86_IO_APIC | 384 | #ifdef CONFIG_X86_IO_APIC |
384 | ret = get_nr_irqs_gsi(); | 385 | /* |
386 | * For an HVM guest or domain 0 which see "real" (emulated or | ||
387 | * actual repectively) GSIs we allocate dynamic IRQs | ||
388 | * e.g. those corresponding to event channels or MSIs | ||
389 | * etc. from the range above those "real" GSIs to avoid | ||
390 | * collisions. | ||
391 | */ | ||
392 | if (xen_initial_domain() || xen_hvm_domain()) | ||
393 | first = get_nr_irqs_gsi(); | ||
385 | #endif | 394 | #endif |
386 | 395 | ||
387 | return ret; | 396 | retry: |
388 | } | 397 | irq = irq_alloc_desc_from(first, -1); |
389 | 398 | ||
390 | static int find_unbound_pirq(int type) | 399 | if (irq == -ENOMEM && first > NR_IRQS_LEGACY) { |
391 | { | 400 | printk(KERN_ERR "Out of dynamic IRQ space and eating into GSI space. You should increase nr_irqs\n"); |
392 | int rc, i; | 401 | first = max(NR_IRQS_LEGACY, first - NR_IRQS_LEGACY); |
393 | struct physdev_get_free_pirq op_get_free_pirq; | 402 | goto retry; |
394 | op_get_free_pirq.type = type; | 403 | } |
395 | 404 | ||
396 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); | 405 | if (irq < 0) |
397 | if (!rc) | 406 | panic("No available IRQ to bind to: increase nr_irqs!\n"); |
398 | return op_get_free_pirq.pirq; | ||
399 | 407 | ||
400 | for (i = 0; i < nr_irqs; i++) { | 408 | return irq; |
401 | if (pirq_to_irq[i] < 0) | ||
402 | return i; | ||
403 | } | ||
404 | return -1; | ||
405 | } | 409 | } |
406 | 410 | ||
407 | static int find_unbound_irq(void) | 411 | static int xen_allocate_irq_gsi(unsigned gsi) |
408 | { | 412 | { |
409 | struct irq_data *data; | 413 | int irq; |
410 | int irq, res; | ||
411 | int bottom = get_nr_hw_irqs(); | ||
412 | int top = nr_irqs-1; | ||
413 | |||
414 | if (bottom == nr_irqs) | ||
415 | goto no_irqs; | ||
416 | 414 | ||
417 | /* This loop starts from the top of IRQ space and goes down. | 415 | /* |
418 | * We need this b/c if we have a PCI device in a Xen PV guest | 416 | * A PV guest has no concept of a GSI (since it has no ACPI |
419 | * we do not have an IO-APIC (though the backend might have them) | 417 | * nor access to/knowledge of the physical APICs). Therefore |
420 | * mapped in. To not have a collision of physical IRQs with the Xen | 418 | * all IRQs are dynamically allocated from the entire IRQ |
421 | * event channels start at the top of the IRQ space for virtual IRQs. | 419 | * space. |
422 | */ | 420 | */ |
423 | for (irq = top; irq > bottom; irq--) { | 421 | if (xen_pv_domain() && !xen_initial_domain()) |
424 | data = irq_get_irq_data(irq); | 422 | return xen_allocate_irq_dynamic(); |
425 | /* only 15->0 have init'd desc; handle irq > 16 */ | ||
426 | if (!data) | ||
427 | break; | ||
428 | if (data->chip == &no_irq_chip) | ||
429 | break; | ||
430 | if (data->chip != &xen_dynamic_chip) | ||
431 | continue; | ||
432 | if (irq_info[irq].type == IRQT_UNBOUND) | ||
433 | return irq; | ||
434 | } | ||
435 | |||
436 | if (irq == bottom) | ||
437 | goto no_irqs; | ||
438 | 423 | ||
439 | res = irq_alloc_desc_at(irq, -1); | 424 | /* Legacy IRQ descriptors are already allocated by the arch. */ |
425 | if (gsi < NR_IRQS_LEGACY) | ||
426 | return gsi; | ||
440 | 427 | ||
441 | if (WARN_ON(res != irq)) | 428 | irq = irq_alloc_desc_at(gsi, -1); |
442 | return -1; | 429 | if (irq < 0) |
430 | panic("Unable to allocate to IRQ%d (%d)\n", gsi, irq); | ||
443 | 431 | ||
444 | return irq; | 432 | return irq; |
445 | |||
446 | no_irqs: | ||
447 | panic("No available IRQ to bind to: increase nr_irqs!\n"); | ||
448 | } | 433 | } |
449 | 434 | ||
450 | static bool identity_mapped_irq(unsigned irq) | 435 | static void xen_free_irq(unsigned irq) |
451 | { | 436 | { |
452 | /* identity map all the hardware irqs */ | 437 | /* Legacy IRQ descriptors are managed by the arch. */ |
453 | return irq < get_nr_hw_irqs(); | 438 | if (irq < NR_IRQS_LEGACY) |
439 | return; | ||
440 | |||
441 | irq_free_desc(irq); | ||
454 | } | 442 | } |
455 | 443 | ||
456 | static void pirq_unmask_notify(int irq) | 444 | static void pirq_unmask_notify(int irq) |
@@ -486,7 +474,7 @@ static bool probing_irq(int irq) | |||
486 | return desc && desc->action == NULL; | 474 | return desc && desc->action == NULL; |
487 | } | 475 | } |
488 | 476 | ||
489 | static unsigned int startup_pirq(unsigned int irq) | 477 | static unsigned int __startup_pirq(unsigned int irq) |
490 | { | 478 | { |
491 | struct evtchn_bind_pirq bind_pirq; | 479 | struct evtchn_bind_pirq bind_pirq; |
492 | struct irq_info *info = info_for_irq(irq); | 480 | struct irq_info *info = info_for_irq(irq); |
@@ -524,9 +512,15 @@ out: | |||
524 | return 0; | 512 | return 0; |
525 | } | 513 | } |
526 | 514 | ||
527 | static void shutdown_pirq(unsigned int irq) | 515 | static unsigned int startup_pirq(struct irq_data *data) |
516 | { | ||
517 | return __startup_pirq(data->irq); | ||
518 | } | ||
519 | |||
520 | static void shutdown_pirq(struct irq_data *data) | ||
528 | { | 521 | { |
529 | struct evtchn_close close; | 522 | struct evtchn_close close; |
523 | unsigned int irq = data->irq; | ||
530 | struct irq_info *info = info_for_irq(irq); | 524 | struct irq_info *info = info_for_irq(irq); |
531 | int evtchn = evtchn_from_irq(irq); | 525 | int evtchn = evtchn_from_irq(irq); |
532 | 526 | ||
@@ -546,20 +540,20 @@ static void shutdown_pirq(unsigned int irq) | |||
546 | info->evtchn = 0; | 540 | info->evtchn = 0; |
547 | } | 541 | } |
548 | 542 | ||
549 | static void enable_pirq(unsigned int irq) | 543 | static void enable_pirq(struct irq_data *data) |
550 | { | 544 | { |
551 | startup_pirq(irq); | 545 | startup_pirq(data); |
552 | } | 546 | } |
553 | 547 | ||
554 | static void disable_pirq(unsigned int irq) | 548 | static void disable_pirq(struct irq_data *data) |
555 | { | 549 | { |
556 | } | 550 | } |
557 | 551 | ||
558 | static void ack_pirq(unsigned int irq) | 552 | static void ack_pirq(struct irq_data *data) |
559 | { | 553 | { |
560 | int evtchn = evtchn_from_irq(irq); | 554 | int evtchn = evtchn_from_irq(data->irq); |
561 | 555 | ||
562 | move_native_irq(irq); | 556 | move_native_irq(data->irq); |
563 | 557 | ||
564 | if (VALID_EVTCHN(evtchn)) { | 558 | if (VALID_EVTCHN(evtchn)) { |
565 | mask_evtchn(evtchn); | 559 | mask_evtchn(evtchn); |
@@ -567,23 +561,6 @@ static void ack_pirq(unsigned int irq) | |||
567 | } | 561 | } |
568 | } | 562 | } |
569 | 563 | ||
570 | static void end_pirq(unsigned int irq) | ||
571 | { | ||
572 | int evtchn = evtchn_from_irq(irq); | ||
573 | struct irq_desc *desc = irq_to_desc(irq); | ||
574 | |||
575 | if (WARN_ON(!desc)) | ||
576 | return; | ||
577 | |||
578 | if ((desc->status & (IRQ_DISABLED|IRQ_PENDING)) == | ||
579 | (IRQ_DISABLED|IRQ_PENDING)) { | ||
580 | shutdown_pirq(irq); | ||
581 | } else if (VALID_EVTCHN(evtchn)) { | ||
582 | unmask_evtchn(evtchn); | ||
583 | pirq_unmask_notify(irq); | ||
584 | } | ||
585 | } | ||
586 | |||
587 | static int find_irq_by_gsi(unsigned gsi) | 564 | static int find_irq_by_gsi(unsigned gsi) |
588 | { | 565 | { |
589 | int irq; | 566 | int irq; |
@@ -638,14 +615,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name) | |||
638 | goto out; /* XXX need refcount? */ | 615 | goto out; /* XXX need refcount? */ |
639 | } | 616 | } |
640 | 617 | ||
641 | /* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore | 618 | irq = xen_allocate_irq_gsi(gsi); |
642 | * we are using the !xen_initial_domain() to drop in the function.*/ | ||
643 | if (identity_mapped_irq(gsi) || (!xen_initial_domain() && | ||
644 | xen_pv_domain())) { | ||
645 | irq = gsi; | ||
646 | irq_alloc_desc_at(irq, -1); | ||
647 | } else | ||
648 | irq = find_unbound_irq(); | ||
649 | 619 | ||
650 | set_irq_chip_and_handler_name(irq, &xen_pirq_chip, | 620 | set_irq_chip_and_handler_name(irq, &xen_pirq_chip, |
651 | handle_level_irq, name); | 621 | handle_level_irq, name); |
@@ -658,7 +628,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name) | |||
658 | * this in the priv domain. */ | 628 | * this in the priv domain. */ |
659 | if (xen_initial_domain() && | 629 | if (xen_initial_domain() && |
660 | HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) { | 630 | HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) { |
661 | irq_free_desc(irq); | 631 | xen_free_irq(irq); |
662 | irq = -ENOSPC; | 632 | irq = -ENOSPC; |
663 | goto out; | 633 | goto out; |
664 | } | 634 | } |
@@ -674,87 +644,46 @@ out: | |||
674 | } | 644 | } |
675 | 645 | ||
676 | #ifdef CONFIG_PCI_MSI | 646 | #ifdef CONFIG_PCI_MSI |
677 | #include <linux/msi.h> | 647 | int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) |
678 | #include "../pci/msi.h" | ||
679 | |||
680 | void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc) | ||
681 | { | 648 | { |
682 | spin_lock(&irq_mapping_update_lock); | 649 | int rc; |
683 | 650 | struct physdev_get_free_pirq op_get_free_pirq; | |
684 | if (alloc & XEN_ALLOC_IRQ) { | ||
685 | *irq = find_unbound_irq(); | ||
686 | if (*irq == -1) | ||
687 | goto out; | ||
688 | } | ||
689 | |||
690 | if (alloc & XEN_ALLOC_PIRQ) { | ||
691 | *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI); | ||
692 | if (*pirq == -1) | ||
693 | goto out; | ||
694 | } | ||
695 | 651 | ||
696 | set_irq_chip_and_handler_name(*irq, &xen_pirq_chip, | 652 | op_get_free_pirq.type = MAP_PIRQ_TYPE_MSI; |
697 | handle_level_irq, name); | 653 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); |
698 | 654 | ||
699 | irq_info[*irq] = mk_pirq_info(0, *pirq, 0, 0); | 655 | WARN_ONCE(rc == -ENOSYS, |
700 | pirq_to_irq[*pirq] = *irq; | 656 | "hypervisor does not support the PHYSDEVOP_get_free_pirq interface\n"); |
701 | 657 | ||
702 | out: | 658 | return rc ? -1 : op_get_free_pirq.pirq; |
703 | spin_unlock(&irq_mapping_update_lock); | ||
704 | } | 659 | } |
705 | 660 | ||
706 | int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) | 661 | int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, |
662 | int pirq, int vector, const char *name) | ||
707 | { | 663 | { |
708 | int irq = -1; | 664 | int irq, ret; |
709 | struct physdev_map_pirq map_irq; | ||
710 | int rc; | ||
711 | int pos; | ||
712 | u32 table_offset, bir; | ||
713 | |||
714 | memset(&map_irq, 0, sizeof(map_irq)); | ||
715 | map_irq.domid = DOMID_SELF; | ||
716 | map_irq.type = MAP_PIRQ_TYPE_MSI; | ||
717 | map_irq.index = -1; | ||
718 | map_irq.pirq = -1; | ||
719 | map_irq.bus = dev->bus->number; | ||
720 | map_irq.devfn = dev->devfn; | ||
721 | |||
722 | if (type == PCI_CAP_ID_MSIX) { | ||
723 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
724 | |||
725 | pci_read_config_dword(dev, msix_table_offset_reg(pos), | ||
726 | &table_offset); | ||
727 | bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); | ||
728 | |||
729 | map_irq.table_base = pci_resource_start(dev, bir); | ||
730 | map_irq.entry_nr = msidesc->msi_attrib.entry_nr; | ||
731 | } | ||
732 | 665 | ||
733 | spin_lock(&irq_mapping_update_lock); | 666 | spin_lock(&irq_mapping_update_lock); |
734 | 667 | ||
735 | irq = find_unbound_irq(); | 668 | irq = xen_allocate_irq_dynamic(); |
736 | |||
737 | if (irq == -1) | 669 | if (irq == -1) |
738 | goto out; | 670 | goto out; |
739 | 671 | ||
740 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); | ||
741 | if (rc) { | ||
742 | printk(KERN_WARNING "xen map irq failed %d\n", rc); | ||
743 | |||
744 | irq_free_desc(irq); | ||
745 | |||
746 | irq = -1; | ||
747 | goto out; | ||
748 | } | ||
749 | irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); | ||
750 | |||
751 | set_irq_chip_and_handler_name(irq, &xen_pirq_chip, | 672 | set_irq_chip_and_handler_name(irq, &xen_pirq_chip, |
752 | handle_level_irq, | 673 | handle_level_irq, name); |
753 | (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi"); | ||
754 | 674 | ||
675 | irq_info[irq] = mk_pirq_info(0, pirq, 0, vector); | ||
676 | pirq_to_irq[pirq] = irq; | ||
677 | ret = set_irq_msi(irq, msidesc); | ||
678 | if (ret < 0) | ||
679 | goto error_irq; | ||
755 | out: | 680 | out: |
756 | spin_unlock(&irq_mapping_update_lock); | 681 | spin_unlock(&irq_mapping_update_lock); |
757 | return irq; | 682 | return irq; |
683 | error_irq: | ||
684 | spin_unlock(&irq_mapping_update_lock); | ||
685 | xen_free_irq(irq); | ||
686 | return -1; | ||
758 | } | 687 | } |
759 | #endif | 688 | #endif |
760 | 689 | ||
@@ -779,11 +708,12 @@ int xen_destroy_irq(int irq) | |||
779 | printk(KERN_WARNING "unmap irq failed %d\n", rc); | 708 | printk(KERN_WARNING "unmap irq failed %d\n", rc); |
780 | goto out; | 709 | goto out; |
781 | } | 710 | } |
782 | pirq_to_irq[info->u.pirq.pirq] = -1; | ||
783 | } | 711 | } |
712 | pirq_to_irq[info->u.pirq.pirq] = -1; | ||
713 | |||
784 | irq_info[irq] = mk_unbound_info(); | 714 | irq_info[irq] = mk_unbound_info(); |
785 | 715 | ||
786 | irq_free_desc(irq); | 716 | xen_free_irq(irq); |
787 | 717 | ||
788 | out: | 718 | out: |
789 | spin_unlock(&irq_mapping_update_lock); | 719 | spin_unlock(&irq_mapping_update_lock); |
@@ -814,7 +744,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
814 | irq = evtchn_to_irq[evtchn]; | 744 | irq = evtchn_to_irq[evtchn]; |
815 | 745 | ||
816 | if (irq == -1) { | 746 | if (irq == -1) { |
817 | irq = find_unbound_irq(); | 747 | irq = xen_allocate_irq_dynamic(); |
818 | 748 | ||
819 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 749 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, |
820 | handle_fasteoi_irq, "event"); | 750 | handle_fasteoi_irq, "event"); |
@@ -839,7 +769,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) | |||
839 | irq = per_cpu(ipi_to_irq, cpu)[ipi]; | 769 | irq = per_cpu(ipi_to_irq, cpu)[ipi]; |
840 | 770 | ||
841 | if (irq == -1) { | 771 | if (irq == -1) { |
842 | irq = find_unbound_irq(); | 772 | irq = xen_allocate_irq_dynamic(); |
843 | if (irq < 0) | 773 | if (irq < 0) |
844 | goto out; | 774 | goto out; |
845 | 775 | ||
@@ -875,7 +805,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
875 | irq = per_cpu(virq_to_irq, cpu)[virq]; | 805 | irq = per_cpu(virq_to_irq, cpu)[virq]; |
876 | 806 | ||
877 | if (irq == -1) { | 807 | if (irq == -1) { |
878 | irq = find_unbound_irq(); | 808 | irq = xen_allocate_irq_dynamic(); |
879 | 809 | ||
880 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, | 810 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
881 | handle_percpu_irq, "virq"); | 811 | handle_percpu_irq, "virq"); |
@@ -934,7 +864,7 @@ static void unbind_from_irq(unsigned int irq) | |||
934 | if (irq_info[irq].type != IRQT_UNBOUND) { | 864 | if (irq_info[irq].type != IRQT_UNBOUND) { |
935 | irq_info[irq] = mk_unbound_info(); | 865 | irq_info[irq] = mk_unbound_info(); |
936 | 866 | ||
937 | irq_free_desc(irq); | 867 | xen_free_irq(irq); |
938 | } | 868 | } |
939 | 869 | ||
940 | spin_unlock(&irq_mapping_update_lock); | 870 | spin_unlock(&irq_mapping_update_lock); |
@@ -990,7 +920,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi, | |||
990 | if (irq < 0) | 920 | if (irq < 0) |
991 | return irq; | 921 | return irq; |
992 | 922 | ||
993 | irqflags |= IRQF_NO_SUSPEND; | 923 | irqflags |= IRQF_NO_SUSPEND | IRQF_FORCE_RESUME; |
994 | retval = request_irq(irq, handler, irqflags, devname, dev_id); | 924 | retval = request_irq(irq, handler, irqflags, devname, dev_id); |
995 | if (retval != 0) { | 925 | if (retval != 0) { |
996 | unbind_from_irq(irq); | 926 | unbind_from_irq(irq); |
@@ -1234,11 +1164,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
1234 | return 0; | 1164 | return 0; |
1235 | } | 1165 | } |
1236 | 1166 | ||
1237 | static int set_affinity_irq(unsigned irq, const struct cpumask *dest) | 1167 | static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, |
1168 | bool force) | ||
1238 | { | 1169 | { |
1239 | unsigned tcpu = cpumask_first(dest); | 1170 | unsigned tcpu = cpumask_first(dest); |
1240 | 1171 | ||
1241 | return rebind_irq_to_cpu(irq, tcpu); | 1172 | return rebind_irq_to_cpu(data->irq, tcpu); |
1242 | } | 1173 | } |
1243 | 1174 | ||
1244 | int resend_irq_on_evtchn(unsigned int irq) | 1175 | int resend_irq_on_evtchn(unsigned int irq) |
@@ -1257,35 +1188,35 @@ int resend_irq_on_evtchn(unsigned int irq) | |||
1257 | return 1; | 1188 | return 1; |
1258 | } | 1189 | } |
1259 | 1190 | ||
1260 | static void enable_dynirq(unsigned int irq) | 1191 | static void enable_dynirq(struct irq_data *data) |
1261 | { | 1192 | { |
1262 | int evtchn = evtchn_from_irq(irq); | 1193 | int evtchn = evtchn_from_irq(data->irq); |
1263 | 1194 | ||
1264 | if (VALID_EVTCHN(evtchn)) | 1195 | if (VALID_EVTCHN(evtchn)) |
1265 | unmask_evtchn(evtchn); | 1196 | unmask_evtchn(evtchn); |
1266 | } | 1197 | } |
1267 | 1198 | ||
1268 | static void disable_dynirq(unsigned int irq) | 1199 | static void disable_dynirq(struct irq_data *data) |
1269 | { | 1200 | { |
1270 | int evtchn = evtchn_from_irq(irq); | 1201 | int evtchn = evtchn_from_irq(data->irq); |
1271 | 1202 | ||
1272 | if (VALID_EVTCHN(evtchn)) | 1203 | if (VALID_EVTCHN(evtchn)) |
1273 | mask_evtchn(evtchn); | 1204 | mask_evtchn(evtchn); |
1274 | } | 1205 | } |
1275 | 1206 | ||
1276 | static void ack_dynirq(unsigned int irq) | 1207 | static void ack_dynirq(struct irq_data *data) |
1277 | { | 1208 | { |
1278 | int evtchn = evtchn_from_irq(irq); | 1209 | int evtchn = evtchn_from_irq(data->irq); |
1279 | 1210 | ||
1280 | move_masked_irq(irq); | 1211 | move_masked_irq(data->irq); |
1281 | 1212 | ||
1282 | if (VALID_EVTCHN(evtchn)) | 1213 | if (VALID_EVTCHN(evtchn)) |
1283 | unmask_evtchn(evtchn); | 1214 | unmask_evtchn(evtchn); |
1284 | } | 1215 | } |
1285 | 1216 | ||
1286 | static int retrigger_dynirq(unsigned int irq) | 1217 | static int retrigger_dynirq(struct irq_data *data) |
1287 | { | 1218 | { |
1288 | int evtchn = evtchn_from_irq(irq); | 1219 | int evtchn = evtchn_from_irq(data->irq); |
1289 | struct shared_info *sh = HYPERVISOR_shared_info; | 1220 | struct shared_info *sh = HYPERVISOR_shared_info; |
1290 | int ret = 0; | 1221 | int ret = 0; |
1291 | 1222 | ||
@@ -1334,7 +1265,7 @@ static void restore_cpu_pirqs(void) | |||
1334 | 1265 | ||
1335 | printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); | 1266 | printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); |
1336 | 1267 | ||
1337 | startup_pirq(irq); | 1268 | __startup_pirq(irq); |
1338 | } | 1269 | } |
1339 | } | 1270 | } |
1340 | 1271 | ||
@@ -1445,7 +1376,6 @@ void xen_poll_irq(int irq) | |||
1445 | void xen_irq_resume(void) | 1376 | void xen_irq_resume(void) |
1446 | { | 1377 | { |
1447 | unsigned int cpu, irq, evtchn; | 1378 | unsigned int cpu, irq, evtchn; |
1448 | struct irq_desc *desc; | ||
1449 | 1379 | ||
1450 | init_evtchn_cpu_bindings(); | 1380 | init_evtchn_cpu_bindings(); |
1451 | 1381 | ||
@@ -1465,66 +1395,48 @@ void xen_irq_resume(void) | |||
1465 | restore_cpu_ipis(cpu); | 1395 | restore_cpu_ipis(cpu); |
1466 | } | 1396 | } |
1467 | 1397 | ||
1468 | /* | ||
1469 | * Unmask any IRQF_NO_SUSPEND IRQs which are enabled. These | ||
1470 | * are not handled by the IRQ core. | ||
1471 | */ | ||
1472 | for_each_irq_desc(irq, desc) { | ||
1473 | if (!desc->action || !(desc->action->flags & IRQF_NO_SUSPEND)) | ||
1474 | continue; | ||
1475 | if (desc->status & IRQ_DISABLED) | ||
1476 | continue; | ||
1477 | |||
1478 | evtchn = evtchn_from_irq(irq); | ||
1479 | if (evtchn == -1) | ||
1480 | continue; | ||
1481 | |||
1482 | unmask_evtchn(evtchn); | ||
1483 | } | ||
1484 | |||
1485 | restore_cpu_pirqs(); | 1398 | restore_cpu_pirqs(); |
1486 | } | 1399 | } |
1487 | 1400 | ||
1488 | static struct irq_chip xen_dynamic_chip __read_mostly = { | 1401 | static struct irq_chip xen_dynamic_chip __read_mostly = { |
1489 | .name = "xen-dyn", | 1402 | .name = "xen-dyn", |
1490 | 1403 | ||
1491 | .disable = disable_dynirq, | 1404 | .irq_disable = disable_dynirq, |
1492 | .mask = disable_dynirq, | 1405 | .irq_mask = disable_dynirq, |
1493 | .unmask = enable_dynirq, | 1406 | .irq_unmask = enable_dynirq, |
1494 | 1407 | ||
1495 | .eoi = ack_dynirq, | 1408 | .irq_eoi = ack_dynirq, |
1496 | .set_affinity = set_affinity_irq, | 1409 | .irq_set_affinity = set_affinity_irq, |
1497 | .retrigger = retrigger_dynirq, | 1410 | .irq_retrigger = retrigger_dynirq, |
1498 | }; | 1411 | }; |
1499 | 1412 | ||
1500 | static struct irq_chip xen_pirq_chip __read_mostly = { | 1413 | static struct irq_chip xen_pirq_chip __read_mostly = { |
1501 | .name = "xen-pirq", | 1414 | .name = "xen-pirq", |
1502 | 1415 | ||
1503 | .startup = startup_pirq, | 1416 | .irq_startup = startup_pirq, |
1504 | .shutdown = shutdown_pirq, | 1417 | .irq_shutdown = shutdown_pirq, |
1505 | 1418 | ||
1506 | .enable = enable_pirq, | 1419 | .irq_enable = enable_pirq, |
1507 | .unmask = enable_pirq, | 1420 | .irq_unmask = enable_pirq, |
1508 | 1421 | ||
1509 | .disable = disable_pirq, | 1422 | .irq_disable = disable_pirq, |
1510 | .mask = disable_pirq, | 1423 | .irq_mask = disable_pirq, |
1511 | 1424 | ||
1512 | .ack = ack_pirq, | 1425 | .irq_ack = ack_pirq, |
1513 | .end = end_pirq, | ||
1514 | 1426 | ||
1515 | .set_affinity = set_affinity_irq, | 1427 | .irq_set_affinity = set_affinity_irq, |
1516 | 1428 | ||
1517 | .retrigger = retrigger_dynirq, | 1429 | .irq_retrigger = retrigger_dynirq, |
1518 | }; | 1430 | }; |
1519 | 1431 | ||
1520 | static struct irq_chip xen_percpu_chip __read_mostly = { | 1432 | static struct irq_chip xen_percpu_chip __read_mostly = { |
1521 | .name = "xen-percpu", | 1433 | .name = "xen-percpu", |
1522 | 1434 | ||
1523 | .disable = disable_dynirq, | 1435 | .irq_disable = disable_dynirq, |
1524 | .mask = disable_dynirq, | 1436 | .irq_mask = disable_dynirq, |
1525 | .unmask = enable_dynirq, | 1437 | .irq_unmask = enable_dynirq, |
1526 | 1438 | ||
1527 | .ack = ack_dynirq, | 1439 | .irq_ack = ack_dynirq, |
1528 | }; | 1440 | }; |
1529 | 1441 | ||
1530 | int xen_set_callback_via(uint64_t via) | 1442 | int xen_set_callback_via(uint64_t via) |