diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hv/vmbus_drv.c | 57 | ||||
-rw-r--r-- | drivers/irqchip/Makefile | 1 | ||||
-rw-r--r-- | drivers/irqchip/irq-armada-370-xp.c | 98 | ||||
-rw-r--r-- | drivers/irqchip/irq-bcm2835.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 11 | ||||
-rw-r--r-- | drivers/irqchip/irq-mmp.c | 6 | ||||
-rw-r--r-- | drivers/irqchip/irq-moxart.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-orion.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-sirfsoc.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-sun4i.c | 42 | ||||
-rw-r--r-- | drivers/irqchip/irq-sunxi-nmi.c | 208 | ||||
-rw-r--r-- | drivers/irqchip/irq-vic.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-vt8500.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-xtensa-mx.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-zevio.c | 2 | ||||
-rw-r--r-- | drivers/irqchip/irqchip.c | 3 | ||||
-rw-r--r-- | drivers/pci/host/pcie-designware.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 6 | ||||
-rw-r--r-- | drivers/xen/events/events_2l.c | 15 | ||||
-rw-r--r-- | drivers/xen/events/events_base.c | 25 | ||||
-rw-r--r-- | drivers/xen/events/events_fifo.c | 8 |
21 files changed, 344 insertions, 159 deletions
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 077bb1bdac34..3f0a95290e14 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/irq.h> | ||
29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
30 | #include <linux/sysctl.h> | 29 | #include <linux/sysctl.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
@@ -558,9 +557,6 @@ static struct bus_type hv_bus = { | |||
558 | .dev_groups = vmbus_groups, | 557 | .dev_groups = vmbus_groups, |
559 | }; | 558 | }; |
560 | 559 | ||
561 | static const char *driver_name = "hyperv"; | ||
562 | |||
563 | |||
564 | struct onmessage_work_context { | 560 | struct onmessage_work_context { |
565 | struct work_struct work; | 561 | struct work_struct work; |
566 | struct hv_message msg; | 562 | struct hv_message msg; |
@@ -619,7 +615,7 @@ static void vmbus_on_msg_dpc(unsigned long data) | |||
619 | } | 615 | } |
620 | } | 616 | } |
621 | 617 | ||
622 | static irqreturn_t vmbus_isr(int irq, void *dev_id) | 618 | static void vmbus_isr(void) |
623 | { | 619 | { |
624 | int cpu = smp_processor_id(); | 620 | int cpu = smp_processor_id(); |
625 | void *page_addr; | 621 | void *page_addr; |
@@ -629,7 +625,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) | |||
629 | 625 | ||
630 | page_addr = hv_context.synic_event_page[cpu]; | 626 | page_addr = hv_context.synic_event_page[cpu]; |
631 | if (page_addr == NULL) | 627 | if (page_addr == NULL) |
632 | return IRQ_NONE; | 628 | return; |
633 | 629 | ||
634 | event = (union hv_synic_event_flags *)page_addr + | 630 | event = (union hv_synic_event_flags *)page_addr + |
635 | VMBUS_MESSAGE_SINT; | 631 | VMBUS_MESSAGE_SINT; |
@@ -665,28 +661,8 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) | |||
665 | msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; | 661 | msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; |
666 | 662 | ||
667 | /* Check if there are actual msgs to be processed */ | 663 | /* Check if there are actual msgs to be processed */ |
668 | if (msg->header.message_type != HVMSG_NONE) { | 664 | if (msg->header.message_type != HVMSG_NONE) |
669 | handled = true; | ||
670 | tasklet_schedule(&msg_dpc); | 665 | tasklet_schedule(&msg_dpc); |
671 | } | ||
672 | |||
673 | if (handled) | ||
674 | return IRQ_HANDLED; | ||
675 | else | ||
676 | return IRQ_NONE; | ||
677 | } | ||
678 | |||
679 | /* | ||
680 | * vmbus interrupt flow handler: | ||
681 | * vmbus interrupts can concurrently occur on multiple CPUs and | ||
682 | * can be handled concurrently. | ||
683 | */ | ||
684 | |||
685 | static void vmbus_flow_handler(unsigned int irq, struct irq_desc *desc) | ||
686 | { | ||
687 | kstat_incr_irqs_this_cpu(irq, desc); | ||
688 | |||
689 | desc->action->handler(irq, desc->action->dev_id); | ||
690 | } | 666 | } |
691 | 667 | ||
692 | /* | 668 | /* |
@@ -715,25 +691,7 @@ static int vmbus_bus_init(int irq) | |||
715 | if (ret) | 691 | if (ret) |
716 | goto err_cleanup; | 692 | goto err_cleanup; |
717 | 693 | ||
718 | ret = request_irq(irq, vmbus_isr, 0, driver_name, hv_acpi_dev); | 694 | hv_setup_vmbus_irq(vmbus_isr); |
719 | |||
720 | if (ret != 0) { | ||
721 | pr_err("Unable to request IRQ %d\n", | ||
722 | irq); | ||
723 | goto err_unregister; | ||
724 | } | ||
725 | |||
726 | /* | ||
727 | * Vmbus interrupts can be handled concurrently on | ||
728 | * different CPUs. Establish an appropriate interrupt flow | ||
729 | * handler that can support this model. | ||
730 | */ | ||
731 | irq_set_handler(irq, vmbus_flow_handler); | ||
732 | |||
733 | /* | ||
734 | * Register our interrupt handler. | ||
735 | */ | ||
736 | hv_register_vmbus_handler(irq, vmbus_isr); | ||
737 | 695 | ||
738 | ret = hv_synic_alloc(); | 696 | ret = hv_synic_alloc(); |
739 | if (ret) | 697 | if (ret) |
@@ -753,9 +711,8 @@ static int vmbus_bus_init(int irq) | |||
753 | 711 | ||
754 | err_alloc: | 712 | err_alloc: |
755 | hv_synic_free(); | 713 | hv_synic_free(); |
756 | free_irq(irq, hv_acpi_dev); | 714 | hv_remove_vmbus_irq(); |
757 | 715 | ||
758 | err_unregister: | ||
759 | bus_unregister(&hv_bus); | 716 | bus_unregister(&hv_bus); |
760 | 717 | ||
761 | err_cleanup: | 718 | err_cleanup: |
@@ -947,7 +904,6 @@ static int __init hv_acpi_init(void) | |||
947 | /* | 904 | /* |
948 | * Get irq resources first. | 905 | * Get irq resources first. |
949 | */ | 906 | */ |
950 | |||
951 | ret = acpi_bus_register_driver(&vmbus_acpi_driver); | 907 | ret = acpi_bus_register_driver(&vmbus_acpi_driver); |
952 | 908 | ||
953 | if (ret) | 909 | if (ret) |
@@ -978,8 +934,7 @@ cleanup: | |||
978 | 934 | ||
979 | static void __exit vmbus_exit(void) | 935 | static void __exit vmbus_exit(void) |
980 | { | 936 | { |
981 | 937 | hv_remove_vmbus_irq(); | |
982 | free_irq(irq, hv_acpi_dev); | ||
983 | vmbus_free_channels(); | 938 | vmbus_free_channels(); |
984 | bus_unregister(&hv_bus); | 939 | bus_unregister(&hv_bus); |
985 | hv_cleanup(); | 940 | hv_cleanup(); |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 5194afb39e78..1c0c151d108c 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o | |||
12 | obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o | 12 | obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o |
13 | obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o | 13 | obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o |
14 | obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o | 14 | obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o |
15 | obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o | ||
15 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o | 16 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o |
16 | obj-$(CONFIG_ARM_GIC) += irq-gic.o | 17 | obj-$(CONFIG_ARM_GIC) += irq-gic.o |
17 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o | 18 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o |
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 540956465ed2..41be897df8d5 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/irqchip/chained_irq.h> | ||
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
23 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
@@ -42,6 +43,7 @@ | |||
42 | #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) | 43 | #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) |
43 | 44 | ||
44 | #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) | 45 | #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) |
46 | #define ARMADA_375_PPI_CAUSE (0x10) | ||
45 | 47 | ||
46 | #define ARMADA_370_XP_SW_TRIG_INT_OFFS (0x4) | 48 | #define ARMADA_370_XP_SW_TRIG_INT_OFFS (0x4) |
47 | #define ARMADA_370_XP_IN_DRBEL_MSK_OFFS (0xc) | 49 | #define ARMADA_370_XP_IN_DRBEL_MSK_OFFS (0xc) |
@@ -352,7 +354,63 @@ static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { | |||
352 | .xlate = irq_domain_xlate_onecell, | 354 | .xlate = irq_domain_xlate_onecell, |
353 | }; | 355 | }; |
354 | 356 | ||
355 | static asmlinkage void __exception_irq_entry | 357 | #ifdef CONFIG_PCI_MSI |
358 | static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained) | ||
359 | { | ||
360 | u32 msimask, msinr; | ||
361 | |||
362 | msimask = readl_relaxed(per_cpu_int_base + | ||
363 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) | ||
364 | & PCI_MSI_DOORBELL_MASK; | ||
365 | |||
366 | writel(~msimask, per_cpu_int_base + | ||
367 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); | ||
368 | |||
369 | for (msinr = PCI_MSI_DOORBELL_START; | ||
370 | msinr < PCI_MSI_DOORBELL_END; msinr++) { | ||
371 | int irq; | ||
372 | |||
373 | if (!(msimask & BIT(msinr))) | ||
374 | continue; | ||
375 | |||
376 | irq = irq_find_mapping(armada_370_xp_msi_domain, | ||
377 | msinr - 16); | ||
378 | |||
379 | if (is_chained) | ||
380 | generic_handle_irq(irq); | ||
381 | else | ||
382 | handle_IRQ(irq, regs); | ||
383 | } | ||
384 | } | ||
385 | #else | ||
386 | static void armada_370_xp_handle_msi_irq(struct pt_regs *r, bool b) {} | ||
387 | #endif | ||
388 | |||
389 | static void armada_370_xp_mpic_handle_cascade_irq(unsigned int irq, | ||
390 | struct irq_desc *desc) | ||
391 | { | ||
392 | struct irq_chip *chip = irq_get_chip(irq); | ||
393 | unsigned long irqmap, irqn; | ||
394 | unsigned int cascade_irq; | ||
395 | |||
396 | chained_irq_enter(chip, desc); | ||
397 | |||
398 | irqmap = readl_relaxed(per_cpu_int_base + ARMADA_375_PPI_CAUSE); | ||
399 | |||
400 | if (irqmap & BIT(0)) { | ||
401 | armada_370_xp_handle_msi_irq(NULL, true); | ||
402 | irqmap &= ~BIT(0); | ||
403 | } | ||
404 | |||
405 | for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) { | ||
406 | cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn); | ||
407 | generic_handle_irq(cascade_irq); | ||
408 | } | ||
409 | |||
410 | chained_irq_exit(chip, desc); | ||
411 | } | ||
412 | |||
413 | static void __exception_irq_entry | ||
356 | armada_370_xp_handle_irq(struct pt_regs *regs) | 414 | armada_370_xp_handle_irq(struct pt_regs *regs) |
357 | { | 415 | { |
358 | u32 irqstat, irqnr; | 416 | u32 irqstat, irqnr; |
@@ -372,31 +430,9 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | |||
372 | continue; | 430 | continue; |
373 | } | 431 | } |
374 | 432 | ||
375 | #ifdef CONFIG_PCI_MSI | ||
376 | /* MSI handling */ | 433 | /* MSI handling */ |
377 | if (irqnr == 1) { | 434 | if (irqnr == 1) |
378 | u32 msimask, msinr; | 435 | armada_370_xp_handle_msi_irq(regs, false); |
379 | |||
380 | msimask = readl_relaxed(per_cpu_int_base + | ||
381 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) | ||
382 | & PCI_MSI_DOORBELL_MASK; | ||
383 | |||
384 | writel(~msimask, per_cpu_int_base + | ||
385 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); | ||
386 | |||
387 | for (msinr = PCI_MSI_DOORBELL_START; | ||
388 | msinr < PCI_MSI_DOORBELL_END; msinr++) { | ||
389 | int irq; | ||
390 | |||
391 | if (!(msimask & BIT(msinr))) | ||
392 | continue; | ||
393 | |||
394 | irq = irq_find_mapping(armada_370_xp_msi_domain, | ||
395 | msinr - 16); | ||
396 | handle_IRQ(irq, regs); | ||
397 | } | ||
398 | } | ||
399 | #endif | ||
400 | 436 | ||
401 | #ifdef CONFIG_SMP | 437 | #ifdef CONFIG_SMP |
402 | /* IPI Handling */ | 438 | /* IPI Handling */ |
@@ -427,6 +463,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, | |||
427 | struct device_node *parent) | 463 | struct device_node *parent) |
428 | { | 464 | { |
429 | struct resource main_int_res, per_cpu_int_res; | 465 | struct resource main_int_res, per_cpu_int_res; |
466 | int parent_irq; | ||
430 | u32 control; | 467 | u32 control; |
431 | 468 | ||
432 | BUG_ON(of_address_to_resource(node, 0, &main_int_res)); | 469 | BUG_ON(of_address_to_resource(node, 0, &main_int_res)); |
@@ -455,8 +492,6 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, | |||
455 | 492 | ||
456 | BUG_ON(!armada_370_xp_mpic_domain); | 493 | BUG_ON(!armada_370_xp_mpic_domain); |
457 | 494 | ||
458 | irq_set_default_host(armada_370_xp_mpic_domain); | ||
459 | |||
460 | #ifdef CONFIG_SMP | 495 | #ifdef CONFIG_SMP |
461 | armada_xp_mpic_smp_cpu_init(); | 496 | armada_xp_mpic_smp_cpu_init(); |
462 | 497 | ||
@@ -472,7 +507,14 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, | |||
472 | 507 | ||
473 | armada_370_xp_msi_init(node, main_int_res.start); | 508 | armada_370_xp_msi_init(node, main_int_res.start); |
474 | 509 | ||
475 | set_handle_irq(armada_370_xp_handle_irq); | 510 | parent_irq = irq_of_parse_and_map(node, 0); |
511 | if (parent_irq <= 0) { | ||
512 | irq_set_default_host(armada_370_xp_mpic_domain); | ||
513 | set_handle_irq(armada_370_xp_handle_irq); | ||
514 | } else { | ||
515 | irq_set_chained_handler(parent_irq, | ||
516 | armada_370_xp_mpic_handle_cascade_irq); | ||
517 | } | ||
476 | 518 | ||
477 | return 0; | 519 | return 0; |
478 | } | 520 | } |
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index 1693b8e7f26a..5916d6cdafa1 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c | |||
@@ -95,7 +95,7 @@ struct armctrl_ic { | |||
95 | }; | 95 | }; |
96 | 96 | ||
97 | static struct armctrl_ic intc __read_mostly; | 97 | static struct armctrl_ic intc __read_mostly; |
98 | static asmlinkage void __exception_irq_entry bcm2835_handle_irq( | 98 | static void __exception_irq_entry bcm2835_handle_irq( |
99 | struct pt_regs *regs); | 99 | struct pt_regs *regs); |
100 | 100 | ||
101 | static void armctrl_mask_irq(struct irq_data *d) | 101 | static void armctrl_mask_irq(struct irq_data *d) |
@@ -196,7 +196,7 @@ static void armctrl_handle_shortcut(int bank, struct pt_regs *regs, | |||
196 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | 196 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); |
197 | } | 197 | } |
198 | 198 | ||
199 | static asmlinkage void __exception_irq_entry bcm2835_handle_irq( | 199 | static void __exception_irq_entry bcm2835_handle_irq( |
200 | struct pt_regs *regs) | 200 | struct pt_regs *regs) |
201 | { | 201 | { |
202 | u32 stat, irq; | 202 | u32 stat, irq; |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 341c6016812d..531769b2433a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -50,7 +50,7 @@ | |||
50 | 50 | ||
51 | union gic_base { | 51 | union gic_base { |
52 | void __iomem *common_base; | 52 | void __iomem *common_base; |
53 | void __percpu __iomem **percpu_base; | 53 | void __percpu * __iomem *percpu_base; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct gic_chip_data { | 56 | struct gic_chip_data { |
@@ -279,7 +279,7 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) | |||
279 | #define gic_set_wake NULL | 279 | #define gic_set_wake NULL |
280 | #endif | 280 | #endif |
281 | 281 | ||
282 | static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | 282 | static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) |
283 | { | 283 | { |
284 | u32 irqstat, irqnr; | 284 | u32 irqstat, irqnr; |
285 | struct gic_chip_data *gic = &gic_data[0]; | 285 | struct gic_chip_data *gic = &gic_data[0]; |
@@ -648,7 +648,7 @@ static void __init gic_pm_init(struct gic_chip_data *gic) | |||
648 | #endif | 648 | #endif |
649 | 649 | ||
650 | #ifdef CONFIG_SMP | 650 | #ifdef CONFIG_SMP |
651 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | 651 | static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) |
652 | { | 652 | { |
653 | int cpu; | 653 | int cpu; |
654 | unsigned long flags, map = 0; | 654 | unsigned long flags, map = 0; |
@@ -869,7 +869,7 @@ static struct notifier_block gic_cpu_notifier = { | |||
869 | }; | 869 | }; |
870 | #endif | 870 | #endif |
871 | 871 | ||
872 | const struct irq_domain_ops gic_irq_domain_ops = { | 872 | static const struct irq_domain_ops gic_irq_domain_ops = { |
873 | .map = gic_irq_domain_map, | 873 | .map = gic_irq_domain_map, |
874 | .xlate = gic_irq_domain_xlate, | 874 | .xlate = gic_irq_domain_xlate, |
875 | }; | 875 | }; |
@@ -974,7 +974,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
974 | #ifdef CONFIG_OF | 974 | #ifdef CONFIG_OF |
975 | static int gic_cnt __initdata; | 975 | static int gic_cnt __initdata; |
976 | 976 | ||
977 | int __init gic_of_init(struct device_node *node, struct device_node *parent) | 977 | static int __init |
978 | gic_of_init(struct device_node *node, struct device_node *parent) | ||
978 | { | 979 | { |
979 | void __iomem *cpu_base; | 980 | void __iomem *cpu_base; |
980 | void __iomem *dist_base; | 981 | void __iomem *dist_base; |
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index 2cb7cd0bc2f5..3c8827fe83f3 100644 --- a/drivers/irqchip/irq-mmp.c +++ b/drivers/irqchip/irq-mmp.c | |||
@@ -194,8 +194,7 @@ static struct mmp_intc_conf mmp2_conf = { | |||
194 | .conf_mask = 0x7f, | 194 | .conf_mask = 0x7f, |
195 | }; | 195 | }; |
196 | 196 | ||
197 | static asmlinkage void __exception_irq_entry | 197 | static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs) |
198 | mmp_handle_irq(struct pt_regs *regs) | ||
199 | { | 198 | { |
200 | int irq, hwirq; | 199 | int irq, hwirq; |
201 | 200 | ||
@@ -207,8 +206,7 @@ mmp_handle_irq(struct pt_regs *regs) | |||
207 | handle_IRQ(irq, regs); | 206 | handle_IRQ(irq, regs); |
208 | } | 207 | } |
209 | 208 | ||
210 | static asmlinkage void __exception_irq_entry | 209 | static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs) |
211 | mmp2_handle_irq(struct pt_regs *regs) | ||
212 | { | 210 | { |
213 | int irq, hwirq; | 211 | int irq, hwirq; |
214 | 212 | ||
diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c index 5552fc2bf28a..00b3cc908f76 100644 --- a/drivers/irqchip/irq-moxart.c +++ b/drivers/irqchip/irq-moxart.c | |||
@@ -44,7 +44,7 @@ struct moxart_irq_data { | |||
44 | 44 | ||
45 | static struct moxart_irq_data intc; | 45 | static struct moxart_irq_data intc; |
46 | 46 | ||
47 | static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs) | 47 | static void __exception_irq_entry handle_irq(struct pt_regs *regs) |
48 | { | 48 | { |
49 | u32 irqstat; | 49 | u32 irqstat; |
50 | int hwirq; | 50 | int hwirq; |
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index 8e41be62812e..e25f246cd2fb 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static struct irq_domain *orion_irq_domain; | 31 | static struct irq_domain *orion_irq_domain; |
32 | 32 | ||
33 | static asmlinkage void | 33 | static void |
34 | __exception_irq_entry orion_handle_irq(struct pt_regs *regs) | 34 | __exception_irq_entry orion_handle_irq(struct pt_regs *regs) |
35 | { | 35 | { |
36 | struct irq_domain_chip_generic *dgc = orion_irq_domain->gc; | 36 | struct irq_domain_chip_generic *dgc = orion_irq_domain->gc; |
diff --git a/drivers/irqchip/irq-sirfsoc.c b/drivers/irqchip/irq-sirfsoc.c index 3a070c587ed9..581eefe331ae 100644 --- a/drivers/irqchip/irq-sirfsoc.c +++ b/drivers/irqchip/irq-sirfsoc.c | |||
@@ -47,7 +47,7 @@ sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) | |||
47 | ct->regs.mask = SIRFSOC_INT_RISC_MASK0; | 47 | ct->regs.mask = SIRFSOC_INT_RISC_MASK0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) | 50 | static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) |
51 | { | 51 | { |
52 | void __iomem *base = sirfsoc_irqdomain->host_data; | 52 | void __iomem *base = sirfsoc_irqdomain->host_data; |
53 | u32 irqstat, irqnr; | 53 | u32 irqstat, irqnr; |
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index a5438d889245..6fcef4a95a18 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c | |||
@@ -36,18 +36,16 @@ | |||
36 | static void __iomem *sun4i_irq_base; | 36 | static void __iomem *sun4i_irq_base; |
37 | static struct irq_domain *sun4i_irq_domain; | 37 | static struct irq_domain *sun4i_irq_domain; |
38 | 38 | ||
39 | static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs); | 39 | static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs); |
40 | 40 | ||
41 | static void sun4i_irq_ack(struct irq_data *irqd) | 41 | static void sun4i_irq_ack(struct irq_data *irqd) |
42 | { | 42 | { |
43 | unsigned int irq = irqd_to_hwirq(irqd); | 43 | unsigned int irq = irqd_to_hwirq(irqd); |
44 | unsigned int irq_off = irq % 32; | ||
45 | int reg = irq / 32; | ||
46 | u32 val; | ||
47 | 44 | ||
48 | val = readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); | 45 | if (irq != 0) |
49 | writel(val | (1 << irq_off), | 46 | return; /* Only IRQ 0 / the ENMI needs to be acked */ |
50 | sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); | 47 | |
48 | writel(BIT(0), sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)); | ||
51 | } | 49 | } |
52 | 50 | ||
53 | static void sun4i_irq_mask(struct irq_data *irqd) | 51 | static void sun4i_irq_mask(struct irq_data *irqd) |
@@ -76,16 +74,16 @@ static void sun4i_irq_unmask(struct irq_data *irqd) | |||
76 | 74 | ||
77 | static struct irq_chip sun4i_irq_chip = { | 75 | static struct irq_chip sun4i_irq_chip = { |
78 | .name = "sun4i_irq", | 76 | .name = "sun4i_irq", |
79 | .irq_ack = sun4i_irq_ack, | 77 | .irq_eoi = sun4i_irq_ack, |
80 | .irq_mask = sun4i_irq_mask, | 78 | .irq_mask = sun4i_irq_mask, |
81 | .irq_unmask = sun4i_irq_unmask, | 79 | .irq_unmask = sun4i_irq_unmask, |
80 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, | ||
82 | }; | 81 | }; |
83 | 82 | ||
84 | static int sun4i_irq_map(struct irq_domain *d, unsigned int virq, | 83 | static int sun4i_irq_map(struct irq_domain *d, unsigned int virq, |
85 | irq_hw_number_t hw) | 84 | irq_hw_number_t hw) |
86 | { | 85 | { |
87 | irq_set_chip_and_handler(virq, &sun4i_irq_chip, | 86 | irq_set_chip_and_handler(virq, &sun4i_irq_chip, handle_fasteoi_irq); |
88 | handle_level_irq); | ||
89 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); | 87 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); |
90 | 88 | ||
91 | return 0; | 89 | return 0; |
@@ -109,7 +107,7 @@ static int __init sun4i_of_init(struct device_node *node, | |||
109 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1)); | 107 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1)); |
110 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2)); | 108 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2)); |
111 | 109 | ||
112 | /* Mask all the interrupts */ | 110 | /* Unmask all the interrupts, ENABLE_REG(x) is used for masking */ |
113 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0)); | 111 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0)); |
114 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1)); | 112 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1)); |
115 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2)); | 113 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2)); |
@@ -134,16 +132,30 @@ static int __init sun4i_of_init(struct device_node *node, | |||
134 | 132 | ||
135 | return 0; | 133 | return 0; |
136 | } | 134 | } |
137 | IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-ic", sun4i_of_init); | 135 | IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-a10-ic", sun4i_of_init); |
138 | 136 | ||
139 | static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) | 137 | static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) |
140 | { | 138 | { |
141 | u32 irq, hwirq; | 139 | u32 irq, hwirq; |
142 | 140 | ||
141 | /* | ||
142 | * hwirq == 0 can mean one of 3 things: | ||
143 | * 1) no more irqs pending | ||
144 | * 2) irq 0 pending | ||
145 | * 3) spurious irq | ||
146 | * So if we immediately get a reading of 0, check the irq-pending reg | ||
147 | * to differentiate between 2 and 3. We only do this once to avoid | ||
148 | * the extra check in the common case of 1 hapening after having | ||
149 | * read the vector-reg once. | ||
150 | */ | ||
143 | hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; | 151 | hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; |
144 | while (hwirq != 0) { | 152 | if (hwirq == 0 && |
153 | !(readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)) & BIT(0))) | ||
154 | return; | ||
155 | |||
156 | do { | ||
145 | irq = irq_find_mapping(sun4i_irq_domain, hwirq); | 157 | irq = irq_find_mapping(sun4i_irq_domain, hwirq); |
146 | handle_IRQ(irq, regs); | 158 | handle_IRQ(irq, regs); |
147 | hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; | 159 | hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; |
148 | } | 160 | } while (hwirq != 0); |
149 | } | 161 | } |
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c new file mode 100644 index 000000000000..12f547a44ae4 --- /dev/null +++ b/drivers/irqchip/irq-sunxi-nmi.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * Allwinner A20/A31 SoCs NMI IRQ chip driver. | ||
3 | * | ||
4 | * Carlo Caione <carlo.caione@gmail.com> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/bitops.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irqdomain.h> | ||
17 | #include <linux/of_irq.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_platform.h> | ||
20 | #include <linux/irqchip/chained_irq.h> | ||
21 | #include "irqchip.h" | ||
22 | |||
23 | #define SUNXI_NMI_SRC_TYPE_MASK 0x00000003 | ||
24 | |||
25 | enum { | ||
26 | SUNXI_SRC_TYPE_LEVEL_LOW = 0, | ||
27 | SUNXI_SRC_TYPE_EDGE_FALLING, | ||
28 | SUNXI_SRC_TYPE_LEVEL_HIGH, | ||
29 | SUNXI_SRC_TYPE_EDGE_RISING, | ||
30 | }; | ||
31 | |||
32 | struct sunxi_sc_nmi_reg_offs { | ||
33 | u32 ctrl; | ||
34 | u32 pend; | ||
35 | u32 enable; | ||
36 | }; | ||
37 | |||
38 | static struct sunxi_sc_nmi_reg_offs sun7i_reg_offs = { | ||
39 | .ctrl = 0x00, | ||
40 | .pend = 0x04, | ||
41 | .enable = 0x08, | ||
42 | }; | ||
43 | |||
44 | static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = { | ||
45 | .ctrl = 0x00, | ||
46 | .pend = 0x04, | ||
47 | .enable = 0x34, | ||
48 | }; | ||
49 | |||
50 | static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off, | ||
51 | u32 val) | ||
52 | { | ||
53 | irq_reg_writel(val, gc->reg_base + off); | ||
54 | } | ||
55 | |||
56 | static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off) | ||
57 | { | ||
58 | return irq_reg_readl(gc->reg_base + off); | ||
59 | } | ||
60 | |||
61 | static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc) | ||
62 | { | ||
63 | struct irq_domain *domain = irq_desc_get_handler_data(desc); | ||
64 | struct irq_chip *chip = irq_get_chip(irq); | ||
65 | unsigned int virq = irq_find_mapping(domain, 0); | ||
66 | |||
67 | chained_irq_enter(chip, desc); | ||
68 | generic_handle_irq(virq); | ||
69 | chained_irq_exit(chip, desc); | ||
70 | } | ||
71 | |||
72 | static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type) | ||
73 | { | ||
74 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | ||
75 | struct irq_chip_type *ct = gc->chip_types; | ||
76 | u32 src_type_reg; | ||
77 | u32 ctrl_off = ct->regs.type; | ||
78 | unsigned int src_type; | ||
79 | unsigned int i; | ||
80 | |||
81 | irq_gc_lock(gc); | ||
82 | |||
83 | switch (flow_type & IRQF_TRIGGER_MASK) { | ||
84 | case IRQ_TYPE_EDGE_FALLING: | ||
85 | src_type = SUNXI_SRC_TYPE_EDGE_FALLING; | ||
86 | break; | ||
87 | case IRQ_TYPE_EDGE_RISING: | ||
88 | src_type = SUNXI_SRC_TYPE_EDGE_RISING; | ||
89 | break; | ||
90 | case IRQ_TYPE_LEVEL_HIGH: | ||
91 | src_type = SUNXI_SRC_TYPE_LEVEL_HIGH; | ||
92 | break; | ||
93 | case IRQ_TYPE_NONE: | ||
94 | case IRQ_TYPE_LEVEL_LOW: | ||
95 | src_type = SUNXI_SRC_TYPE_LEVEL_LOW; | ||
96 | break; | ||
97 | default: | ||
98 | irq_gc_unlock(gc); | ||
99 | pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n", | ||
100 | __func__, data->irq); | ||
101 | return -EBADR; | ||
102 | } | ||
103 | |||
104 | irqd_set_trigger_type(data, flow_type); | ||
105 | irq_setup_alt_chip(data, flow_type); | ||
106 | |||
107 | for (i = 0; i <= gc->num_ct; i++, ct++) | ||
108 | if (ct->type & flow_type) | ||
109 | ctrl_off = ct->regs.type; | ||
110 | |||
111 | src_type_reg = sunxi_sc_nmi_read(gc, ctrl_off); | ||
112 | src_type_reg &= ~SUNXI_NMI_SRC_TYPE_MASK; | ||
113 | src_type_reg |= src_type; | ||
114 | sunxi_sc_nmi_write(gc, ctrl_off, src_type_reg); | ||
115 | |||
116 | irq_gc_unlock(gc); | ||
117 | |||
118 | return IRQ_SET_MASK_OK; | ||
119 | } | ||
120 | |||
121 | static int __init sunxi_sc_nmi_irq_init(struct device_node *node, | ||
122 | struct sunxi_sc_nmi_reg_offs *reg_offs) | ||
123 | { | ||
124 | struct irq_domain *domain; | ||
125 | struct irq_chip_generic *gc; | ||
126 | unsigned int irq; | ||
127 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
128 | int ret; | ||
129 | |||
130 | |||
131 | domain = irq_domain_add_linear(node, 1, &irq_generic_chip_ops, NULL); | ||
132 | if (!domain) { | ||
133 | pr_err("%s: Could not register interrupt domain.\n", node->name); | ||
134 | return -ENOMEM; | ||
135 | } | ||
136 | |||
137 | ret = irq_alloc_domain_generic_chips(domain, 1, 2, node->name, | ||
138 | handle_fasteoi_irq, clr, 0, | ||
139 | IRQ_GC_INIT_MASK_CACHE); | ||
140 | if (ret) { | ||
141 | pr_err("%s: Could not allocate generic interrupt chip.\n", | ||
142 | node->name); | ||
143 | goto fail_irqd_remove; | ||
144 | } | ||
145 | |||
146 | irq = irq_of_parse_and_map(node, 0); | ||
147 | if (irq <= 0) { | ||
148 | pr_err("%s: unable to parse irq\n", node->name); | ||
149 | ret = -EINVAL; | ||
150 | goto fail_irqd_remove; | ||
151 | } | ||
152 | |||
153 | gc = irq_get_domain_generic_chip(domain, 0); | ||
154 | gc->reg_base = of_iomap(node, 0); | ||
155 | if (!gc->reg_base) { | ||
156 | pr_err("%s: unable to map resource\n", node->name); | ||
157 | ret = -ENOMEM; | ||
158 | goto fail_irqd_remove; | ||
159 | } | ||
160 | |||
161 | gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; | ||
162 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | ||
163 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | ||
164 | gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit; | ||
165 | gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type; | ||
166 | gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED; | ||
167 | gc->chip_types[0].regs.ack = reg_offs->pend; | ||
168 | gc->chip_types[0].regs.mask = reg_offs->enable; | ||
169 | gc->chip_types[0].regs.type = reg_offs->ctrl; | ||
170 | |||
171 | gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; | ||
172 | gc->chip_types[1].chip.name = gc->chip_types[0].chip.name; | ||
173 | gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit; | ||
174 | gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit; | ||
175 | gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit; | ||
176 | gc->chip_types[1].chip.irq_set_type = sunxi_sc_nmi_set_type; | ||
177 | gc->chip_types[1].regs.ack = reg_offs->pend; | ||
178 | gc->chip_types[1].regs.mask = reg_offs->enable; | ||
179 | gc->chip_types[1].regs.type = reg_offs->ctrl; | ||
180 | gc->chip_types[1].handler = handle_edge_irq; | ||
181 | |||
182 | sunxi_sc_nmi_write(gc, reg_offs->enable, 0); | ||
183 | sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1); | ||
184 | |||
185 | irq_set_handler_data(irq, domain); | ||
186 | irq_set_chained_handler(irq, sunxi_sc_nmi_handle_irq); | ||
187 | |||
188 | return 0; | ||
189 | |||
190 | fail_irqd_remove: | ||
191 | irq_domain_remove(domain); | ||
192 | |||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | static int __init sun6i_sc_nmi_irq_init(struct device_node *node, | ||
197 | struct device_node *parent) | ||
198 | { | ||
199 | return sunxi_sc_nmi_irq_init(node, &sun6i_reg_offs); | ||
200 | } | ||
201 | IRQCHIP_DECLARE(sun6i_sc_nmi, "allwinner,sun6i-a31-sc-nmi", sun6i_sc_nmi_irq_init); | ||
202 | |||
203 | static int __init sun7i_sc_nmi_irq_init(struct device_node *node, | ||
204 | struct device_node *parent) | ||
205 | { | ||
206 | return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs); | ||
207 | } | ||
208 | IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-a20-sc-nmi", sun7i_sc_nmi_irq_init); | ||
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 8e21ae0bab46..473f09a74d4d 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c | |||
@@ -228,7 +228,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) | |||
228 | * Keep iterating over all registered VIC's until there are no pending | 228 | * Keep iterating over all registered VIC's until there are no pending |
229 | * interrupts. | 229 | * interrupts. |
230 | */ | 230 | */ |
231 | static asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs) | 231 | static void __exception_irq_entry vic_handle_irq(struct pt_regs *regs) |
232 | { | 232 | { |
233 | int i, handled; | 233 | int i, handled; |
234 | 234 | ||
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c index 1846e7d66681..eb6e91efdec8 100644 --- a/drivers/irqchip/irq-vt8500.c +++ b/drivers/irqchip/irq-vt8500.c | |||
@@ -178,8 +178,7 @@ static struct irq_domain_ops vt8500_irq_domain_ops = { | |||
178 | .xlate = irq_domain_xlate_onecell, | 178 | .xlate = irq_domain_xlate_onecell, |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static asmlinkage | 181 | static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) |
182 | void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) | ||
183 | { | 182 | { |
184 | u32 stat, i; | 183 | u32 stat, i; |
185 | int irqnr, virq; | 184 | int irqnr, virq; |
diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c index f693f1bc1348..e1c2f9632893 100644 --- a/drivers/irqchip/irq-xtensa-mx.c +++ b/drivers/irqchip/irq-xtensa-mx.c | |||
@@ -122,7 +122,7 @@ static int xtensa_mx_irq_retrigger(struct irq_data *d) | |||
122 | static int xtensa_mx_irq_set_affinity(struct irq_data *d, | 122 | static int xtensa_mx_irq_set_affinity(struct irq_data *d, |
123 | const struct cpumask *dest, bool force) | 123 | const struct cpumask *dest, bool force) |
124 | { | 124 | { |
125 | unsigned mask = 1u << cpumask_any(dest); | 125 | unsigned mask = 1u << cpumask_any_and(dest, cpu_online_mask); |
126 | 126 | ||
127 | set_er(mask, MIROUT(d->hwirq - HW_IRQ_MX_BASE)); | 127 | set_er(mask, MIROUT(d->hwirq - HW_IRQ_MX_BASE)); |
128 | return 0; | 128 | return 0; |
diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c index 8ed04c4a43ee..ceb3a4318f73 100644 --- a/drivers/irqchip/irq-zevio.c +++ b/drivers/irqchip/irq-zevio.c | |||
@@ -50,7 +50,7 @@ static void zevio_irq_ack(struct irq_data *irqd) | |||
50 | readl(gc->reg_base + regs->ack); | 50 | readl(gc->reg_base + regs->ack); |
51 | } | 51 | } |
52 | 52 | ||
53 | static asmlinkage void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) | 53 | static void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) |
54 | { | 54 | { |
55 | int irqnr; | 55 | int irqnr; |
56 | 56 | ||
diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index f496afce29de..cad3e2495552 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c | |||
@@ -10,8 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/of_irq.h> | 12 | #include <linux/of_irq.h> |
13 | 13 | #include <linux/irqchip.h> | |
14 | #include "irqchip.h" | ||
15 | 14 | ||
16 | /* | 15 | /* |
17 | * This special of_device_id is the sentinel at the end of the | 16 | * This special of_device_id is the sentinel at the end of the |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 17ce88f79d2b..2e48ecf09e2c 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -294,14 +294,12 @@ no_valid_irq: | |||
294 | static void clear_irq(unsigned int irq) | 294 | static void clear_irq(unsigned int irq) |
295 | { | 295 | { |
296 | unsigned int pos, nvec; | 296 | unsigned int pos, nvec; |
297 | struct irq_desc *desc; | ||
298 | struct msi_desc *msi; | 297 | struct msi_desc *msi; |
299 | struct pcie_port *pp; | 298 | struct pcie_port *pp; |
300 | struct irq_data *data = irq_get_irq_data(irq); | 299 | struct irq_data *data = irq_get_irq_data(irq); |
301 | 300 | ||
302 | /* get the port structure */ | 301 | /* get the port structure */ |
303 | desc = irq_to_desc(irq); | 302 | msi = irq_data_get_msi(data); |
304 | msi = irq_desc_get_msi_desc(desc); | ||
305 | pp = sys_to_pcie(msi->dev->bus->sysdata); | 303 | pp = sys_to_pcie(msi->dev->bus->sysdata); |
306 | if (!pp) { | 304 | if (!pp) { |
307 | BUG(); | 305 | BUG(); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index d691e6a13aae..9e058c4657a3 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/kernel_stat.h> | 19 | #include <linux/kernel_stat.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/irq.h> | ||
21 | #include <asm/cio.h> | 22 | #include <asm/cio.h> |
22 | #include <asm/delay.h> | 23 | #include <asm/delay.h> |
23 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
@@ -584,8 +585,6 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) | |||
584 | return IRQ_HANDLED; | 585 | return IRQ_HANDLED; |
585 | } | 586 | } |
586 | 587 | ||
587 | static struct irq_desc *irq_desc_io; | ||
588 | |||
589 | static struct irqaction io_interrupt = { | 588 | static struct irqaction io_interrupt = { |
590 | .name = "IO", | 589 | .name = "IO", |
591 | .handler = do_cio_interrupt, | 590 | .handler = do_cio_interrupt, |
@@ -596,7 +595,6 @@ void __init init_cio_interrupts(void) | |||
596 | irq_set_chip_and_handler(IO_INTERRUPT, | 595 | irq_set_chip_and_handler(IO_INTERRUPT, |
597 | &dummy_irq_chip, handle_percpu_irq); | 596 | &dummy_irq_chip, handle_percpu_irq); |
598 | setup_irq(IO_INTERRUPT, &io_interrupt); | 597 | setup_irq(IO_INTERRUPT, &io_interrupt); |
599 | irq_desc_io = irq_to_desc(IO_INTERRUPT); | ||
600 | } | 598 | } |
601 | 599 | ||
602 | #ifdef CONFIG_CCW_CONSOLE | 600 | #ifdef CONFIG_CCW_CONSOLE |
@@ -623,7 +621,7 @@ void cio_tsch(struct subchannel *sch) | |||
623 | local_bh_disable(); | 621 | local_bh_disable(); |
624 | irq_enter(); | 622 | irq_enter(); |
625 | } | 623 | } |
626 | kstat_incr_irqs_this_cpu(IO_INTERRUPT, irq_desc_io); | 624 | kstat_incr_irq_this_cpu(IO_INTERRUPT); |
627 | if (sch->driver && sch->driver->irq) | 625 | if (sch->driver && sch->driver->irq) |
628 | sch->driver->irq(sch); | 626 | sch->driver->irq(sch); |
629 | else | 627 | else |
diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c index d7ff91757307..5db43fc100a4 100644 --- a/drivers/xen/events/events_2l.c +++ b/drivers/xen/events/events_2l.c | |||
@@ -166,7 +166,6 @@ static void evtchn_2l_handle_events(unsigned cpu) | |||
166 | int start_word_idx, start_bit_idx; | 166 | int start_word_idx, start_bit_idx; |
167 | int word_idx, bit_idx; | 167 | int word_idx, bit_idx; |
168 | int i; | 168 | int i; |
169 | struct irq_desc *desc; | ||
170 | struct shared_info *s = HYPERVISOR_shared_info; | 169 | struct shared_info *s = HYPERVISOR_shared_info; |
171 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); | 170 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); |
172 | 171 | ||
@@ -176,11 +175,8 @@ static void evtchn_2l_handle_events(unsigned cpu) | |||
176 | unsigned int evtchn = evtchn_from_irq(irq); | 175 | unsigned int evtchn = evtchn_from_irq(irq); |
177 | word_idx = evtchn / BITS_PER_LONG; | 176 | word_idx = evtchn / BITS_PER_LONG; |
178 | bit_idx = evtchn % BITS_PER_LONG; | 177 | bit_idx = evtchn % BITS_PER_LONG; |
179 | if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx)) { | 178 | if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx)) |
180 | desc = irq_to_desc(irq); | 179 | generic_handle_irq(irq); |
181 | if (desc) | ||
182 | generic_handle_irq_desc(irq, desc); | ||
183 | } | ||
184 | } | 180 | } |
185 | 181 | ||
186 | /* | 182 | /* |
@@ -245,11 +241,8 @@ static void evtchn_2l_handle_events(unsigned cpu) | |||
245 | port = (word_idx * BITS_PER_EVTCHN_WORD) + bit_idx; | 241 | port = (word_idx * BITS_PER_EVTCHN_WORD) + bit_idx; |
246 | irq = get_evtchn_to_irq(port); | 242 | irq = get_evtchn_to_irq(port); |
247 | 243 | ||
248 | if (irq != -1) { | 244 | if (irq != -1) |
249 | desc = irq_to_desc(irq); | 245 | generic_handle_irq(irq); |
250 | if (desc) | ||
251 | generic_handle_irq_desc(irq, desc); | ||
252 | } | ||
253 | 246 | ||
254 | bit_idx = (bit_idx + 1) % BITS_PER_EVTCHN_WORD; | 247 | bit_idx = (bit_idx + 1) % BITS_PER_EVTCHN_WORD; |
255 | 248 | ||
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index f4a9e3311297..c3458f58de90 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c | |||
@@ -336,9 +336,8 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
336 | 336 | ||
337 | BUG_ON(irq == -1); | 337 | BUG_ON(irq == -1); |
338 | #ifdef CONFIG_SMP | 338 | #ifdef CONFIG_SMP |
339 | cpumask_copy(irq_to_desc(irq)->irq_data.affinity, cpumask_of(cpu)); | 339 | cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(cpu)); |
340 | #endif | 340 | #endif |
341 | |||
342 | xen_evtchn_port_bind_to_cpu(info, cpu); | 341 | xen_evtchn_port_bind_to_cpu(info, cpu); |
343 | 342 | ||
344 | info->cpu = cpu; | 343 | info->cpu = cpu; |
@@ -373,10 +372,8 @@ static void xen_irq_init(unsigned irq) | |||
373 | { | 372 | { |
374 | struct irq_info *info; | 373 | struct irq_info *info; |
375 | #ifdef CONFIG_SMP | 374 | #ifdef CONFIG_SMP |
376 | struct irq_desc *desc = irq_to_desc(irq); | ||
377 | |||
378 | /* By default all event channels notify CPU#0. */ | 375 | /* By default all event channels notify CPU#0. */ |
379 | cpumask_copy(desc->irq_data.affinity, cpumask_of(0)); | 376 | cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(0)); |
380 | #endif | 377 | #endif |
381 | 378 | ||
382 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 379 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
@@ -490,13 +487,6 @@ static void pirq_query_unmask(int irq) | |||
490 | info->u.pirq.flags |= PIRQ_NEEDS_EOI; | 487 | info->u.pirq.flags |= PIRQ_NEEDS_EOI; |
491 | } | 488 | } |
492 | 489 | ||
493 | static bool probing_irq(int irq) | ||
494 | { | ||
495 | struct irq_desc *desc = irq_to_desc(irq); | ||
496 | |||
497 | return desc && desc->action == NULL; | ||
498 | } | ||
499 | |||
500 | static void eoi_pirq(struct irq_data *data) | 490 | static void eoi_pirq(struct irq_data *data) |
501 | { | 491 | { |
502 | int evtchn = evtchn_from_irq(data->irq); | 492 | int evtchn = evtchn_from_irq(data->irq); |
@@ -538,8 +528,7 @@ static unsigned int __startup_pirq(unsigned int irq) | |||
538 | BIND_PIRQ__WILL_SHARE : 0; | 528 | BIND_PIRQ__WILL_SHARE : 0; |
539 | rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq); | 529 | rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq); |
540 | if (rc != 0) { | 530 | if (rc != 0) { |
541 | if (!probing_irq(irq)) | 531 | pr_warn("Failed to obtain physical IRQ %d\n", irq); |
542 | pr_info("Failed to obtain physical IRQ %d\n", irq); | ||
543 | return 0; | 532 | return 0; |
544 | } | 533 | } |
545 | evtchn = bind_pirq.port; | 534 | evtchn = bind_pirq.port; |
@@ -772,17 +761,12 @@ error_irq: | |||
772 | 761 | ||
773 | int xen_destroy_irq(int irq) | 762 | int xen_destroy_irq(int irq) |
774 | { | 763 | { |
775 | struct irq_desc *desc; | ||
776 | struct physdev_unmap_pirq unmap_irq; | 764 | struct physdev_unmap_pirq unmap_irq; |
777 | struct irq_info *info = info_for_irq(irq); | 765 | struct irq_info *info = info_for_irq(irq); |
778 | int rc = -ENOENT; | 766 | int rc = -ENOENT; |
779 | 767 | ||
780 | mutex_lock(&irq_mapping_update_lock); | 768 | mutex_lock(&irq_mapping_update_lock); |
781 | 769 | ||
782 | desc = irq_to_desc(irq); | ||
783 | if (!desc) | ||
784 | goto out; | ||
785 | |||
786 | if (xen_initial_domain()) { | 770 | if (xen_initial_domain()) { |
787 | unmap_irq.pirq = info->u.pirq.pirq; | 771 | unmap_irq.pirq = info->u.pirq.pirq; |
788 | unmap_irq.domid = info->u.pirq.domid; | 772 | unmap_irq.domid = info->u.pirq.domid; |
@@ -1251,6 +1235,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) | |||
1251 | #ifdef CONFIG_X86 | 1235 | #ifdef CONFIG_X86 |
1252 | exit_idle(); | 1236 | exit_idle(); |
1253 | #endif | 1237 | #endif |
1238 | inc_irq_stat(irq_hv_callback_count); | ||
1254 | 1239 | ||
1255 | __xen_evtchn_do_upcall(); | 1240 | __xen_evtchn_do_upcall(); |
1256 | 1241 | ||
@@ -1339,7 +1324,7 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) | |||
1339 | static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, | 1324 | static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, |
1340 | bool force) | 1325 | bool force) |
1341 | { | 1326 | { |
1342 | unsigned tcpu = cpumask_first(dest); | 1327 | unsigned tcpu = cpumask_first_and(dest, cpu_online_mask); |
1343 | 1328 | ||
1344 | return rebind_irq_to_cpu(data->irq, tcpu); | 1329 | return rebind_irq_to_cpu(data->irq, tcpu); |
1345 | } | 1330 | } |
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c index 1de2a191b395..96109a9972b6 100644 --- a/drivers/xen/events/events_fifo.c +++ b/drivers/xen/events/events_fifo.c | |||
@@ -235,14 +235,10 @@ static uint32_t clear_linked(volatile event_word_t *word) | |||
235 | static void handle_irq_for_port(unsigned port) | 235 | static void handle_irq_for_port(unsigned port) |
236 | { | 236 | { |
237 | int irq; | 237 | int irq; |
238 | struct irq_desc *desc; | ||
239 | 238 | ||
240 | irq = get_evtchn_to_irq(port); | 239 | irq = get_evtchn_to_irq(port); |
241 | if (irq != -1) { | 240 | if (irq != -1) |
242 | desc = irq_to_desc(irq); | 241 | generic_handle_irq(irq); |
243 | if (desc) | ||
244 | generic_handle_irq_desc(irq, desc); | ||
245 | } | ||
246 | } | 242 | } |
247 | 243 | ||
248 | static void consume_one_event(unsigned cpu, | 244 | static void consume_one_event(unsigned cpu, |