Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner:
"Three fixes for irq core and irq chip drivers:

- Do not set the irq type if type is NONE. Fixes a boot regression
on various SoCs

- Use the proper cpu for setting up the GIC target list. Discovered
by the cpumask debugging code.

- A rather large fix for the MIPS-GIC so per cpu local interrupts
work again. This was discovered late because the code falls back
to slower timers which use normal device interrupts"

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
irqchip/mips-gic: Fix local interrupts
irqchip/gicv3: Silence noisy DEBUG_PER_CPU_MAPS warning
genirq: Skip chained interrupt trigger setup if type is IRQ_TYPE_NONE

+60 -60
+4 -3
drivers/irqchip/irq-gic-v3.c
··· 548 548 static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, 549 549 unsigned long cluster_id) 550 550 { 551 - int cpu = *base_cpu; 551 + int next_cpu, cpu = *base_cpu; 552 552 unsigned long mpidr = cpu_logical_map(cpu); 553 553 u16 tlist = 0; 554 554 ··· 562 562 563 563 tlist |= 1 << (mpidr & 0xf); 564 564 565 - cpu = cpumask_next(cpu, mask); 566 - if (cpu >= nr_cpu_ids) 565 + next_cpu = cpumask_next(cpu, mask); 566 + if (next_cpu >= nr_cpu_ids) 567 567 goto out; 568 + cpu = next_cpu; 568 569 569 570 mpidr = cpu_logical_map(cpu); 570 571
+50 -55
drivers/irqchip/irq-mips-gic.c
··· 638 638 if (!gic_local_irq_is_routable(intr)) 639 639 return -EPERM; 640 640 641 - /* 642 - * HACK: These are all really percpu interrupts, but the rest 643 - * of the MIPS kernel code does not use the percpu IRQ API for 644 - * the CP0 timer and performance counter interrupts. 645 - */ 646 - switch (intr) { 647 - case GIC_LOCAL_INT_TIMER: 648 - case GIC_LOCAL_INT_PERFCTR: 649 - case GIC_LOCAL_INT_FDC: 650 - irq_set_chip_and_handler(virq, 651 - &gic_all_vpes_local_irq_controller, 652 - handle_percpu_irq); 653 - break; 654 - default: 655 - irq_set_chip_and_handler(virq, 656 - &gic_local_irq_controller, 657 - handle_percpu_devid_irq); 658 - irq_set_percpu_devid(virq); 659 - break; 660 - } 661 - 662 641 spin_lock_irqsave(&gic_lock, flags); 663 642 for (i = 0; i < gic_vpes; i++) { 664 643 u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; ··· 703 724 return 0; 704 725 } 705 726 706 - static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, 707 - irq_hw_number_t hw) 727 + static int gic_setup_dev_chip(struct irq_domain *d, unsigned int virq, 728 + unsigned int hwirq) 708 729 { 709 - if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) 710 - return gic_local_irq_domain_map(d, virq, hw); 730 + struct irq_chip *chip; 731 + int err; 711 732 712 - irq_set_chip_and_handler(virq, &gic_level_irq_controller, 713 - handle_level_irq); 733 + if (hwirq >= GIC_SHARED_HWIRQ_BASE) { 734 + err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, 735 + &gic_level_irq_controller, 736 + NULL); 737 + } else { 738 + switch (GIC_HWIRQ_TO_LOCAL(hwirq)) { 739 + case GIC_LOCAL_INT_TIMER: 740 + case GIC_LOCAL_INT_PERFCTR: 741 + case GIC_LOCAL_INT_FDC: 742 + /* 743 + * HACK: These are all really percpu interrupts, but 744 + * the rest of the MIPS kernel code does not use the 745 + * percpu IRQ API for them. 746 + */ 747 + chip = &gic_all_vpes_local_irq_controller; 748 + irq_set_handler(virq, handle_percpu_irq); 749 + break; 714 750 715 - return gic_shared_irq_domain_map(d, virq, hw, 0); 751 + default: 752 + chip = &gic_local_irq_controller; 753 + irq_set_handler(virq, handle_percpu_devid_irq); 754 + irq_set_percpu_devid(virq); 755 + break; 756 + } 757 + 758 + err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, 759 + chip, NULL); 760 + } 761 + 762 + return err; 716 763 } 717 764 718 765 static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, ··· 749 744 int cpu, ret, i; 750 745 751 746 if (spec->type == GIC_DEVICE) { 752 - /* verify that it doesn't conflict with an IPI irq */ 753 - if (test_bit(spec->hwirq, ipi_resrv)) 747 + /* verify that shared irqs don't conflict with an IPI irq */ 748 + if ((spec->hwirq >= GIC_SHARED_HWIRQ_BASE) && 749 + test_bit(GIC_HWIRQ_TO_SHARED(spec->hwirq), ipi_resrv)) 754 750 return -EBUSY; 755 751 756 - hwirq = GIC_SHARED_TO_HWIRQ(spec->hwirq); 757 - 758 - return irq_domain_set_hwirq_and_chip(d, virq, hwirq, 759 - &gic_level_irq_controller, 760 - NULL); 752 + return gic_setup_dev_chip(d, virq, spec->hwirq); 761 753 } else { 762 754 base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs); 763 755 if (base_hwirq == gic_shared_intrs) { ··· 823 821 } 824 822 825 823 static const struct irq_domain_ops gic_irq_domain_ops = { 826 - .map = gic_irq_domain_map, 827 824 .alloc = gic_irq_domain_alloc, 828 825 .free = gic_irq_domain_free, 829 826 .match = gic_irq_domain_match, ··· 853 852 struct irq_fwspec *fwspec = arg; 854 853 struct gic_irq_spec spec = { 855 854 .type = GIC_DEVICE, 856 - .hwirq = fwspec->param[1], 857 855 }; 858 856 int i, ret; 859 - bool is_shared = fwspec->param[0] == GIC_SHARED; 860 857 861 - if (is_shared) { 862 - ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec); 863 - if (ret) 864 - return ret; 865 - } 858 + if (fwspec->param[0] == GIC_SHARED) 859 + spec.hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]); 860 + else 861 + spec.hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]); 862 + 863 + ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec); 864 + if (ret) 865 + return ret; 866 866 867 867 for (i = 0; i < nr_irqs; i++) { 868 - irq_hw_number_t hwirq; 869 - 870 - if (is_shared) 871 - hwirq = GIC_SHARED_TO_HWIRQ(spec.hwirq + i); 872 - else 873 - hwirq = GIC_LOCAL_TO_HWIRQ(spec.hwirq + i); 874 - 875 - ret = irq_domain_set_hwirq_and_chip(d, virq + i, 876 - hwirq, 877 - &gic_level_irq_controller, 878 - NULL); 868 + ret = gic_setup_dev_chip(d, virq + i, spec.hwirq + i); 879 869 if (ret) 880 870 goto error; 881 871 } ··· 888 896 static void gic_dev_domain_activate(struct irq_domain *domain, 889 897 struct irq_data *d) 890 898 { 891 - gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0); 899 + if (GIC_HWIRQ_TO_LOCAL(d->hwirq) < GIC_NUM_LOCAL_INTRS) 900 + gic_local_irq_domain_map(domain, d->irq, d->hwirq); 901 + else 902 + gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0); 892 903 } 893 904 894 905 static struct irq_domain_ops gic_dev_domain_ops = {
+6 -2
kernel/irq/chip.c
··· 820 820 desc->name = name; 821 821 822 822 if (handle != handle_bad_irq && is_chained) { 823 + unsigned int type = irqd_get_trigger_type(&desc->irq_data); 824 + 823 825 /* 824 826 * We're about to start this interrupt immediately, 825 827 * hence the need to set the trigger configuration. ··· 830 828 * chained interrupt. Reset it immediately because we 831 829 * do know better. 832 830 */ 833 - __irq_set_trigger(desc, irqd_get_trigger_type(&desc->irq_data)); 834 - desc->handle_irq = handle; 831 + if (type != IRQ_TYPE_NONE) { 832 + __irq_set_trigger(desc, type); 833 + desc->handle_irq = handle; 834 + } 835 835 836 836 irq_settings_set_noprobe(desc); 837 837 irq_settings_set_norequest(desc);