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

Merge remote-tracking branch 'origin/irq/ipi-as-irq' into irq/irqchip-next

Signed-off-by: Marc Zyngier <maz@kernel.org>

+794 -486
+1
arch/arm/Kconfig
··· 49 49 select GENERIC_ARCH_TOPOLOGY if ARM_CPU_TOPOLOGY 50 50 select GENERIC_ATOMIC64 if CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI 51 51 select GENERIC_CLOCKEVENTS_BROADCAST if SMP 52 + select GENERIC_IRQ_IPI if SMP 52 53 select GENERIC_CPU_AUTOPROBE 53 54 select GENERIC_EARLY_IOREMAP 54 55 select GENERIC_IDLE_POLL_SETUP
-17
arch/arm/include/asm/hardirq.h
··· 6 6 #include <linux/threads.h> 7 7 #include <asm/irq.h> 8 8 9 - /* number of IPIS _not_ including IPI_CPU_BACKTRACE */ 10 - #define NR_IPI 7 11 - 12 9 typedef struct { 13 10 unsigned int __softirq_pending; 14 - #ifdef CONFIG_SMP 15 - unsigned int ipi_irqs[NR_IPI]; 16 - #endif 17 11 } ____cacheline_aligned irq_cpustat_t; 18 12 19 13 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 20 - 21 - #define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++ 22 - #define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member) 23 - 24 - #ifdef CONFIG_SMP 25 - u64 smp_irq_stat_cpu(unsigned int cpu); 26 - #else 27 - #define smp_irq_stat_cpu(cpu) 0 28 - #endif 29 - 30 - #define arch_irq_stat_cpu smp_irq_stat_cpu 31 14 32 15 #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 33 16
+2 -3
arch/arm/include/asm/smp.h
··· 39 39 */ 40 40 extern void smp_init_cpus(void); 41 41 42 - 43 42 /* 44 - * Provide a function to raise an IPI cross call on CPUs in callmap. 43 + * Register IPI interrupts with the arch SMP code 45 44 */ 46 - extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); 45 + extern void set_smp_ipi_range(int ipi_base, int nr_ipi); 47 46 48 47 /* 49 48 * Called from platform specific assembly code, this is the
-1
arch/arm/kernel/irq.c
··· 18 18 * IRQ's are in fact implemented a bit like signal handlers for the kernel. 19 19 * Naturally it's not a 1:1 relation, but there are similarities. 20 20 */ 21 - #include <linux/kernel_stat.h> 22 21 #include <linux/signal.h> 23 22 #include <linux/ioport.h> 24 23 #include <linux/interrupt.h>
+90 -46
arch/arm/kernel/smp.c
··· 26 26 #include <linux/completion.h> 27 27 #include <linux/cpufreq.h> 28 28 #include <linux/irq_work.h> 29 + #include <linux/kernel_stat.h> 29 30 30 31 #include <linux/atomic.h> 31 32 #include <asm/bugs.h> ··· 66 65 IPI_CPU_STOP, 67 66 IPI_IRQ_WORK, 68 67 IPI_COMPLETION, 68 + NR_IPI, 69 69 /* 70 70 * CPU_BACKTRACE is special and not included in NR_IPI 71 71 * or tracable with trace_ipi_* 72 72 */ 73 - IPI_CPU_BACKTRACE, 73 + IPI_CPU_BACKTRACE = NR_IPI, 74 74 /* 75 75 * SGI8-15 can be reserved by secure firmware, and thus may 76 76 * not be usable by the kernel. Please keep the above limited 77 77 * to at most 8 entries. 78 78 */ 79 + MAX_IPI 79 80 }; 81 + 82 + static int ipi_irq_base __read_mostly; 83 + static int nr_ipi __read_mostly = NR_IPI; 84 + static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly; 85 + 86 + static void ipi_setup(int cpu); 87 + static void ipi_teardown(int cpu); 80 88 81 89 static DECLARE_COMPLETION(cpu_running); 82 90 ··· 257 247 * and we must not schedule until we're ready to give up the cpu. 258 248 */ 259 249 set_cpu_online(cpu, false); 250 + ipi_teardown(cpu); 260 251 261 252 /* 262 253 * OK - migrate IRQs away from this CPU ··· 433 422 434 423 notify_cpu_starting(cpu); 435 424 425 + ipi_setup(cpu); 426 + 436 427 calibrate_delay(); 437 428 438 429 smp_store_cpu_info(cpu); ··· 513 500 } 514 501 } 515 502 516 - static void (*__smp_cross_call)(const struct cpumask *, unsigned int); 517 - 518 - void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) 519 - { 520 - if (!__smp_cross_call) 521 - __smp_cross_call = fn; 522 - } 523 - 524 503 static const char *ipi_types[NR_IPI] __tracepoint_string = { 525 504 #define S(x,s) [x] = s 526 505 S(IPI_WAKEUP, "CPU wakeup interrupts"), ··· 524 519 S(IPI_COMPLETION, "completion interrupts"), 525 520 }; 526 521 527 - static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) 528 - { 529 - trace_ipi_raise_rcuidle(target, ipi_types[ipinr]); 530 - __smp_cross_call(target, ipinr); 531 - } 522 + static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); 532 523 533 524 void show_ipi_list(struct seq_file *p, int prec) 534 525 { 535 526 unsigned int cpu, i; 536 527 537 528 for (i = 0; i < NR_IPI; i++) { 529 + unsigned int irq = irq_desc_get_irq(ipi_desc[i]); 538 530 seq_printf(p, "%*s%u: ", prec - 1, "IPI", i); 539 531 540 532 for_each_online_cpu(cpu) 541 - seq_printf(p, "%10u ", 542 - __get_irq_stat(cpu, ipi_irqs[i])); 533 + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); 543 534 544 535 seq_printf(p, " %s\n", ipi_types[i]); 545 536 } 546 - } 547 - 548 - u64 smp_irq_stat_cpu(unsigned int cpu) 549 - { 550 - u64 sum = 0; 551 - int i; 552 - 553 - for (i = 0; i < NR_IPI; i++) 554 - sum += __get_irq_stat(cpu, ipi_irqs[i]); 555 - 556 - return sum; 557 537 } 558 538 559 539 void arch_send_call_function_ipi_mask(const struct cpumask *mask) ··· 617 627 handle_IPI(ipinr, regs); 618 628 } 619 629 620 - void handle_IPI(int ipinr, struct pt_regs *regs) 630 + static void do_handle_IPI(int ipinr) 621 631 { 622 632 unsigned int cpu = smp_processor_id(); 623 - struct pt_regs *old_regs = set_irq_regs(regs); 624 633 625 - if ((unsigned)ipinr < NR_IPI) { 634 + if ((unsigned)ipinr < NR_IPI) 626 635 trace_ipi_entry_rcuidle(ipi_types[ipinr]); 627 - __inc_irq_stat(cpu, ipi_irqs[ipinr]); 628 - } 629 636 630 637 switch (ipinr) { 631 638 case IPI_WAKEUP: ··· 630 643 631 644 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 632 645 case IPI_TIMER: 633 - irq_enter(); 634 646 tick_receive_broadcast(); 635 - irq_exit(); 636 647 break; 637 648 #endif 638 649 ··· 639 654 break; 640 655 641 656 case IPI_CALL_FUNC: 642 - irq_enter(); 643 657 generic_smp_call_function_interrupt(); 644 - irq_exit(); 645 658 break; 646 659 647 660 case IPI_CPU_STOP: 648 - irq_enter(); 649 661 ipi_cpu_stop(cpu); 650 - irq_exit(); 651 662 break; 652 663 653 664 #ifdef CONFIG_IRQ_WORK 654 665 case IPI_IRQ_WORK: 655 - irq_enter(); 656 666 irq_work_run(); 657 - irq_exit(); 658 667 break; 659 668 #endif 660 669 661 670 case IPI_COMPLETION: 662 - irq_enter(); 663 671 ipi_complete(cpu); 664 - irq_exit(); 665 672 break; 666 673 667 674 case IPI_CPU_BACKTRACE: 668 675 printk_nmi_enter(); 669 - irq_enter(); 670 - nmi_cpu_backtrace(regs); 671 - irq_exit(); 676 + nmi_cpu_backtrace(get_irq_regs()); 672 677 printk_nmi_exit(); 673 678 break; 674 679 ··· 670 695 671 696 if ((unsigned)ipinr < NR_IPI) 672 697 trace_ipi_exit_rcuidle(ipi_types[ipinr]); 698 + } 699 + 700 + /* Legacy version, should go away once all irqchips have been converted */ 701 + void handle_IPI(int ipinr, struct pt_regs *regs) 702 + { 703 + struct pt_regs *old_regs = set_irq_regs(regs); 704 + 705 + irq_enter(); 706 + do_handle_IPI(ipinr); 707 + irq_exit(); 708 + 673 709 set_irq_regs(old_regs); 710 + } 711 + 712 + static irqreturn_t ipi_handler(int irq, void *data) 713 + { 714 + do_handle_IPI(irq - ipi_irq_base); 715 + return IRQ_HANDLED; 716 + } 717 + 718 + static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) 719 + { 720 + trace_ipi_raise_rcuidle(target, ipi_types[ipinr]); 721 + __ipi_send_mask(ipi_desc[ipinr], target); 722 + } 723 + 724 + static void ipi_setup(int cpu) 725 + { 726 + int i; 727 + 728 + if (WARN_ON_ONCE(!ipi_irq_base)) 729 + return; 730 + 731 + for (i = 0; i < nr_ipi; i++) 732 + enable_percpu_irq(ipi_irq_base + i, 0); 733 + } 734 + 735 + static void ipi_teardown(int cpu) 736 + { 737 + int i; 738 + 739 + if (WARN_ON_ONCE(!ipi_irq_base)) 740 + return; 741 + 742 + for (i = 0; i < nr_ipi; i++) 743 + disable_percpu_irq(ipi_irq_base + i); 744 + } 745 + 746 + void __init set_smp_ipi_range(int ipi_base, int n) 747 + { 748 + int i; 749 + 750 + WARN_ON(n < MAX_IPI); 751 + nr_ipi = min(n, MAX_IPI); 752 + 753 + for (i = 0; i < nr_ipi; i++) { 754 + int err; 755 + 756 + err = request_percpu_irq(ipi_base + i, ipi_handler, 757 + "IPI", &irq_stat); 758 + WARN_ON(err); 759 + 760 + ipi_desc[i] = irq_to_desc(ipi_base + i); 761 + irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); 762 + } 763 + 764 + ipi_irq_base = ipi_base; 765 + 766 + /* Setup the boot CPU immediately */ 767 + ipi_setup(smp_processor_id()); 674 768 } 675 769 676 770 void smp_send_reschedule(int cpu) ··· 849 805 850 806 static void raise_nmi(cpumask_t *mask) 851 807 { 852 - __smp_cross_call(mask, IPI_CPU_BACKTRACE); 808 + __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask); 853 809 } 854 810 855 811 void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
+1
arch/arm64/Kconfig
··· 106 106 select GENERIC_CPU_VULNERABILITIES 107 107 select GENERIC_EARLY_IOREMAP 108 108 select GENERIC_IDLE_POLL_SETUP 109 + select GENERIC_IRQ_IPI 109 110 select GENERIC_IRQ_MULTI_HANDLER 110 111 select GENERIC_IRQ_PROBE 111 112 select GENERIC_IRQ_SHOW
-9
arch/arm64/include/asm/hardirq.h
··· 13 13 #include <asm/kvm_arm.h> 14 14 #include <asm/sysreg.h> 15 15 16 - #define NR_IPI 7 17 - 18 16 typedef struct { 19 17 unsigned int __softirq_pending; 20 - unsigned int ipi_irqs[NR_IPI]; 21 18 } ____cacheline_aligned irq_cpustat_t; 22 19 23 20 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 24 - 25 - #define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++ 26 - #define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member) 27 - 28 - u64 smp_irq_stat_cpu(unsigned int cpu); 29 - #define arch_irq_stat_cpu smp_irq_stat_cpu 30 21 31 22 #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 32 23
+1 -3
arch/arm64/include/asm/irq_work.h
··· 2 2 #ifndef __ASM_IRQ_WORK_H 3 3 #define __ASM_IRQ_WORK_H 4 4 5 - #include <asm/smp.h> 6 - 7 5 static inline bool arch_irq_work_has_interrupt(void) 8 6 { 9 - return !!__smp_cross_call; 7 + return true; 10 8 } 11 9 12 10 #endif /* __ASM_IRQ_WORK_H */
+2 -14
arch/arm64/include/asm/smp.h
··· 56 56 struct seq_file; 57 57 58 58 /* 59 - * generate IPI list text 60 - */ 61 - extern void show_ipi_list(struct seq_file *p, int prec); 62 - 63 - /* 64 - * Called from C code, this handles an IPI. 65 - */ 66 - extern void handle_IPI(int ipinr, struct pt_regs *regs); 67 - 68 - /* 69 59 * Discover the set of possible CPUs and determine their 70 60 * SMP operations. 71 61 */ 72 62 extern void smp_init_cpus(void); 73 63 74 64 /* 75 - * Provide a function to raise an IPI cross call on CPUs in callmap. 65 + * Register IPI interrupts with the arch SMP code 76 66 */ 77 - extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); 78 - 79 - extern void (*__smp_cross_call)(const struct cpumask *, unsigned int); 67 + extern void set_smp_ipi_range(int ipi_base, int nr_ipi); 80 68 81 69 /* 82 70 * Called from the secondary holding pen, this is the secondary CPU entry point.
+1 -10
arch/arm64/kernel/irq.c
··· 10 10 * Copyright (C) 2012 ARM Ltd. 11 11 */ 12 12 13 - #include <linux/kernel_stat.h> 14 13 #include <linux/irq.h> 15 14 #include <linux/memory.h> 16 15 #include <linux/smp.h> 16 + #include <linux/hardirq.h> 17 17 #include <linux/init.h> 18 18 #include <linux/irqchip.h> 19 19 #include <linux/kprobes.h> ··· 22 22 #include <asm/daifflags.h> 23 23 #include <asm/vmap_stack.h> 24 24 25 - unsigned long irq_err_count; 26 - 27 25 /* Only access this in an NMI enter/exit */ 28 26 DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts); 29 27 30 28 DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); 31 - 32 - int arch_show_interrupts(struct seq_file *p, int prec) 33 - { 34 - show_ipi_list(p, prec); 35 - seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); 36 - return 0; 37 - } 38 29 39 30 #ifdef CONFIG_VMAP_STACK 40 31 static void init_irq_stacks(void)
+83 -44
arch/arm64/kernel/smp.c
··· 30 30 #include <linux/completion.h> 31 31 #include <linux/of.h> 32 32 #include <linux/irq_work.h> 33 + #include <linux/kernel_stat.h> 33 34 #include <linux/kexec.h> 34 35 #include <linux/kvm_host.h> 35 36 ··· 73 72 IPI_CPU_CRASH_STOP, 74 73 IPI_TIMER, 75 74 IPI_IRQ_WORK, 76 - IPI_WAKEUP 75 + IPI_WAKEUP, 76 + NR_IPI 77 77 }; 78 + 79 + static int ipi_irq_base __read_mostly; 80 + static int nr_ipi __read_mostly = NR_IPI; 81 + static struct irq_desc *ipi_desc[NR_IPI] __read_mostly; 82 + 83 + static void ipi_setup(int cpu); 84 + static void ipi_teardown(int cpu); 78 85 79 86 #ifdef CONFIG_HOTPLUG_CPU 80 87 static int op_cpu_kill(unsigned int cpu); ··· 246 237 */ 247 238 notify_cpu_starting(cpu); 248 239 240 + ipi_setup(cpu); 241 + 249 242 store_cpu_topology(cpu); 250 243 numa_add_cpu(cpu); 251 244 ··· 313 302 * and we must not schedule until we're ready to give up the cpu. 314 303 */ 315 304 set_cpu_online(cpu, false); 305 + ipi_teardown(cpu); 316 306 317 307 /* 318 308 * OK - migrate IRQs away from this CPU ··· 784 772 } 785 773 } 786 774 787 - void (*__smp_cross_call)(const struct cpumask *, unsigned int); 788 - 789 - void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) 790 - { 791 - __smp_cross_call = fn; 792 - } 793 - 794 775 static const char *ipi_types[NR_IPI] __tracepoint_string = { 795 776 #define S(x,s) [x] = s 796 777 S(IPI_RESCHEDULE, "Rescheduling interrupts"), ··· 795 790 S(IPI_WAKEUP, "CPU wake-up interrupts"), 796 791 }; 797 792 798 - static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) 799 - { 800 - trace_ipi_raise(target, ipi_types[ipinr]); 801 - __smp_cross_call(target, ipinr); 802 - } 793 + static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); 803 794 804 - void show_ipi_list(struct seq_file *p, int prec) 795 + unsigned long irq_err_count; 796 + 797 + int arch_show_interrupts(struct seq_file *p, int prec) 805 798 { 806 799 unsigned int cpu, i; 807 800 808 801 for (i = 0; i < NR_IPI; i++) { 802 + unsigned int irq = irq_desc_get_irq(ipi_desc[i]); 809 803 seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, 810 804 prec >= 4 ? " " : ""); 811 805 for_each_online_cpu(cpu) 812 - seq_printf(p, "%10u ", 813 - __get_irq_stat(cpu, ipi_irqs[i])); 806 + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); 814 807 seq_printf(p, " %s\n", ipi_types[i]); 815 808 } 816 - } 817 809 818 - u64 smp_irq_stat_cpu(unsigned int cpu) 819 - { 820 - u64 sum = 0; 821 - int i; 822 - 823 - for (i = 0; i < NR_IPI; i++) 824 - sum += __get_irq_stat(cpu, ipi_irqs[i]); 825 - 826 - return sum; 810 + seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); 811 + return 0; 827 812 } 828 813 829 814 void arch_send_call_function_ipi_mask(const struct cpumask *mask) ··· 836 841 #ifdef CONFIG_IRQ_WORK 837 842 void arch_irq_work_raise(void) 838 843 { 839 - if (__smp_cross_call) 840 - smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); 844 + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); 841 845 } 842 846 #endif 843 847 ··· 884 890 /* 885 891 * Main handler for inter-processor interrupts 886 892 */ 887 - void handle_IPI(int ipinr, struct pt_regs *regs) 893 + static void do_handle_IPI(int ipinr) 888 894 { 889 895 unsigned int cpu = smp_processor_id(); 890 - struct pt_regs *old_regs = set_irq_regs(regs); 891 896 892 - if ((unsigned)ipinr < NR_IPI) { 897 + if ((unsigned)ipinr < NR_IPI) 893 898 trace_ipi_entry_rcuidle(ipi_types[ipinr]); 894 - __inc_irq_stat(cpu, ipi_irqs[ipinr]); 895 - } 896 899 897 900 switch (ipinr) { 898 901 case IPI_RESCHEDULE: ··· 897 906 break; 898 907 899 908 case IPI_CALL_FUNC: 900 - irq_enter(); 901 909 generic_smp_call_function_interrupt(); 902 - irq_exit(); 903 910 break; 904 911 905 912 case IPI_CPU_STOP: 906 - irq_enter(); 907 913 local_cpu_stop(); 908 - irq_exit(); 909 914 break; 910 915 911 916 case IPI_CPU_CRASH_STOP: 912 917 if (IS_ENABLED(CONFIG_KEXEC_CORE)) { 913 - irq_enter(); 914 - ipi_cpu_crash_stop(cpu, regs); 918 + ipi_cpu_crash_stop(cpu, get_irq_regs()); 915 919 916 920 unreachable(); 917 921 } ··· 914 928 915 929 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 916 930 case IPI_TIMER: 917 - irq_enter(); 918 931 tick_receive_broadcast(); 919 - irq_exit(); 920 932 break; 921 933 #endif 922 934 923 935 #ifdef CONFIG_IRQ_WORK 924 936 case IPI_IRQ_WORK: 925 - irq_enter(); 926 937 irq_work_run(); 927 - irq_exit(); 928 938 break; 929 939 #endif 930 940 ··· 939 957 940 958 if ((unsigned)ipinr < NR_IPI) 941 959 trace_ipi_exit_rcuidle(ipi_types[ipinr]); 942 - set_irq_regs(old_regs); 960 + } 961 + 962 + static irqreturn_t ipi_handler(int irq, void *data) 963 + { 964 + do_handle_IPI(irq - ipi_irq_base); 965 + return IRQ_HANDLED; 966 + } 967 + 968 + static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) 969 + { 970 + trace_ipi_raise(target, ipi_types[ipinr]); 971 + __ipi_send_mask(ipi_desc[ipinr], target); 972 + } 973 + 974 + static void ipi_setup(int cpu) 975 + { 976 + int i; 977 + 978 + if (WARN_ON_ONCE(!ipi_irq_base)) 979 + return; 980 + 981 + for (i = 0; i < nr_ipi; i++) 982 + enable_percpu_irq(ipi_irq_base + i, 0); 983 + } 984 + 985 + static void ipi_teardown(int cpu) 986 + { 987 + int i; 988 + 989 + if (WARN_ON_ONCE(!ipi_irq_base)) 990 + return; 991 + 992 + for (i = 0; i < nr_ipi; i++) 993 + disable_percpu_irq(ipi_irq_base + i); 994 + } 995 + 996 + void __init set_smp_ipi_range(int ipi_base, int n) 997 + { 998 + int i; 999 + 1000 + WARN_ON(n < NR_IPI); 1001 + nr_ipi = min(n, NR_IPI); 1002 + 1003 + for (i = 0; i < nr_ipi; i++) { 1004 + int err; 1005 + 1006 + err = request_percpu_irq(ipi_base + i, ipi_handler, 1007 + "IPI", &cpu_number); 1008 + WARN_ON(err); 1009 + 1010 + ipi_desc[i] = irq_to_desc(ipi_base + i); 1011 + irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); 1012 + } 1013 + 1014 + ipi_irq_base = ipi_base; 1015 + 1016 + /* Setup the boot CPU immediately */ 1017 + ipi_setup(smp_processor_id()); 943 1018 } 944 1019 945 1020 void smp_send_reschedule(int cpu)
+198 -104
drivers/irqchip/irq-armada-370-xp.c
··· 310 310 } 311 311 #endif 312 312 313 + static void armada_xp_mpic_perf_init(void) 314 + { 315 + unsigned long cpuid = cpu_logical_map(smp_processor_id()); 316 + 317 + /* Enable Performance Counter Overflow interrupts */ 318 + writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid), 319 + per_cpu_int_base + ARMADA_370_XP_INT_FABRIC_MASK_OFFS); 320 + } 321 + 313 322 #ifdef CONFIG_SMP 323 + static struct irq_domain *ipi_domain; 324 + 325 + static void armada_370_xp_ipi_mask(struct irq_data *d) 326 + { 327 + u32 reg; 328 + reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); 329 + reg &= ~BIT(d->hwirq); 330 + writel(reg, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); 331 + } 332 + 333 + static void armada_370_xp_ipi_unmask(struct irq_data *d) 334 + { 335 + u32 reg; 336 + reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); 337 + reg |= BIT(d->hwirq); 338 + writel(reg, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); 339 + } 340 + 341 + static void armada_370_xp_ipi_send_mask(struct irq_data *d, 342 + const struct cpumask *mask) 343 + { 344 + unsigned long map = 0; 345 + int cpu; 346 + 347 + /* Convert our logical CPU mask into a physical one. */ 348 + for_each_cpu(cpu, mask) 349 + map |= 1 << cpu_logical_map(cpu); 350 + 351 + /* 352 + * Ensure that stores to Normal memory are visible to the 353 + * other CPUs before issuing the IPI. 354 + */ 355 + dsb(); 356 + 357 + /* submit softirq */ 358 + writel((map << 8) | d->hwirq, main_int_base + 359 + ARMADA_370_XP_SW_TRIG_INT_OFFS); 360 + } 361 + 362 + static void armada_370_xp_ipi_eoi(struct irq_data *d) 363 + { 364 + writel(~BIT(d->hwirq), per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 365 + } 366 + 367 + static struct irq_chip ipi_irqchip = { 368 + .name = "IPI", 369 + .irq_mask = armada_370_xp_ipi_mask, 370 + .irq_unmask = armada_370_xp_ipi_unmask, 371 + .irq_eoi = armada_370_xp_ipi_eoi, 372 + .ipi_send_mask = armada_370_xp_ipi_send_mask, 373 + }; 374 + 375 + static int armada_370_xp_ipi_alloc(struct irq_domain *d, 376 + unsigned int virq, 377 + unsigned int nr_irqs, void *args) 378 + { 379 + int i; 380 + 381 + for (i = 0; i < nr_irqs; i++) { 382 + irq_set_percpu_devid(virq + i); 383 + irq_domain_set_info(d, virq + i, i, &ipi_irqchip, 384 + d->host_data, 385 + handle_percpu_devid_fasteoi_ipi, 386 + NULL, NULL); 387 + } 388 + 389 + return 0; 390 + } 391 + 392 + static void armada_370_xp_ipi_free(struct irq_domain *d, 393 + unsigned int virq, 394 + unsigned int nr_irqs) 395 + { 396 + /* Not freeing IPIs */ 397 + } 398 + 399 + static const struct irq_domain_ops ipi_domain_ops = { 400 + .alloc = armada_370_xp_ipi_alloc, 401 + .free = armada_370_xp_ipi_free, 402 + }; 403 + 404 + static void ipi_resume(void) 405 + { 406 + int i; 407 + 408 + for (i = 0; i < IPI_DOORBELL_END; i++) { 409 + int irq; 410 + 411 + irq = irq_find_mapping(ipi_domain, i); 412 + if (irq <= 0) 413 + continue; 414 + if (irq_percpu_is_enabled(irq)) { 415 + struct irq_data *d; 416 + d = irq_domain_get_irq_data(ipi_domain, irq); 417 + armada_370_xp_ipi_unmask(d); 418 + } 419 + } 420 + } 421 + 422 + static __init void armada_xp_ipi_init(struct device_node *node) 423 + { 424 + int base_ipi; 425 + 426 + ipi_domain = irq_domain_create_linear(of_node_to_fwnode(node), 427 + IPI_DOORBELL_END, 428 + &ipi_domain_ops, NULL); 429 + if (WARN_ON(!ipi_domain)) 430 + return; 431 + 432 + irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); 433 + base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, IPI_DOORBELL_END, 434 + NUMA_NO_NODE, NULL, false, NULL); 435 + if (WARN_ON(!base_ipi)) 436 + return; 437 + 438 + set_smp_ipi_range(base_ipi, IPI_DOORBELL_END); 439 + } 440 + 314 441 static DEFINE_RAW_SPINLOCK(irq_controller_lock); 315 442 316 443 static int armada_xp_set_affinity(struct irq_data *d, ··· 461 334 462 335 return IRQ_SET_MASK_OK; 463 336 } 337 + 338 + static void armada_xp_mpic_smp_cpu_init(void) 339 + { 340 + u32 control; 341 + int nr_irqs, i; 342 + 343 + control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); 344 + nr_irqs = (control >> 2) & 0x3ff; 345 + 346 + for (i = 0; i < nr_irqs; i++) 347 + writel(i, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); 348 + 349 + /* Disable all IPIs */ 350 + writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); 351 + 352 + /* Clear pending IPIs */ 353 + writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 354 + 355 + /* Unmask IPI interrupt */ 356 + writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 357 + } 358 + 359 + static void armada_xp_mpic_reenable_percpu(void) 360 + { 361 + unsigned int irq; 362 + 363 + /* Re-enable per-CPU interrupts that were enabled before suspend */ 364 + for (irq = 0; irq < ARMADA_370_XP_MAX_PER_CPU_IRQS; irq++) { 365 + struct irq_data *data; 366 + int virq; 367 + 368 + virq = irq_linear_revmap(armada_370_xp_mpic_domain, irq); 369 + if (virq == 0) 370 + continue; 371 + 372 + data = irq_get_irq_data(virq); 373 + 374 + if (!irq_percpu_is_enabled(virq)) 375 + continue; 376 + 377 + armada_370_xp_irq_unmask(data); 378 + } 379 + 380 + ipi_resume(); 381 + } 382 + 383 + static int armada_xp_mpic_starting_cpu(unsigned int cpu) 384 + { 385 + armada_xp_mpic_perf_init(); 386 + armada_xp_mpic_smp_cpu_init(); 387 + armada_xp_mpic_reenable_percpu(); 388 + return 0; 389 + } 390 + 391 + static int mpic_cascaded_starting_cpu(unsigned int cpu) 392 + { 393 + armada_xp_mpic_perf_init(); 394 + armada_xp_mpic_reenable_percpu(); 395 + enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); 396 + return 0; 397 + } 398 + #else 399 + static void armada_xp_mpic_smp_cpu_init(void) {} 400 + static void ipi_resume(void) {} 464 401 #endif 465 402 466 403 static struct irq_chip armada_370_xp_irq_chip = { ··· 562 371 563 372 return 0; 564 373 } 565 - 566 - static void armada_xp_mpic_smp_cpu_init(void) 567 - { 568 - u32 control; 569 - int nr_irqs, i; 570 - 571 - control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); 572 - nr_irqs = (control >> 2) & 0x3ff; 573 - 574 - for (i = 0; i < nr_irqs; i++) 575 - writel(i, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); 576 - 577 - /* Clear pending IPIs */ 578 - writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 579 - 580 - /* Enable first 8 IPIs */ 581 - writel(IPI_DOORBELL_MASK, per_cpu_int_base + 582 - ARMADA_370_XP_IN_DRBEL_MSK_OFFS); 583 - 584 - /* Unmask IPI interrupt */ 585 - writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 586 - } 587 - 588 - static void armada_xp_mpic_perf_init(void) 589 - { 590 - unsigned long cpuid = cpu_logical_map(smp_processor_id()); 591 - 592 - /* Enable Performance Counter Overflow interrupts */ 593 - writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid), 594 - per_cpu_int_base + ARMADA_370_XP_INT_FABRIC_MASK_OFFS); 595 - } 596 - 597 - #ifdef CONFIG_SMP 598 - static void armada_mpic_send_doorbell(const struct cpumask *mask, 599 - unsigned int irq) 600 - { 601 - int cpu; 602 - unsigned long map = 0; 603 - 604 - /* Convert our logical CPU mask into a physical one. */ 605 - for_each_cpu(cpu, mask) 606 - map |= 1 << cpu_logical_map(cpu); 607 - 608 - /* 609 - * Ensure that stores to Normal memory are visible to the 610 - * other CPUs before issuing the IPI. 611 - */ 612 - dsb(); 613 - 614 - /* submit softirq */ 615 - writel((map << 8) | irq, main_int_base + 616 - ARMADA_370_XP_SW_TRIG_INT_OFFS); 617 - } 618 - 619 - static void armada_xp_mpic_reenable_percpu(void) 620 - { 621 - unsigned int irq; 622 - 623 - /* Re-enable per-CPU interrupts that were enabled before suspend */ 624 - for (irq = 0; irq < ARMADA_370_XP_MAX_PER_CPU_IRQS; irq++) { 625 - struct irq_data *data; 626 - int virq; 627 - 628 - virq = irq_linear_revmap(armada_370_xp_mpic_domain, irq); 629 - if (virq == 0) 630 - continue; 631 - 632 - data = irq_get_irq_data(virq); 633 - 634 - if (!irq_percpu_is_enabled(virq)) 635 - continue; 636 - 637 - armada_370_xp_irq_unmask(data); 638 - } 639 - } 640 - 641 - static int armada_xp_mpic_starting_cpu(unsigned int cpu) 642 - { 643 - armada_xp_mpic_perf_init(); 644 - armada_xp_mpic_smp_cpu_init(); 645 - armada_xp_mpic_reenable_percpu(); 646 - return 0; 647 - } 648 - 649 - static int mpic_cascaded_starting_cpu(unsigned int cpu) 650 - { 651 - armada_xp_mpic_perf_init(); 652 - armada_xp_mpic_reenable_percpu(); 653 - enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); 654 - return 0; 655 - } 656 - #endif 657 374 658 375 static const struct irq_domain_ops armada_370_xp_mpic_irq_ops = { 659 376 .map = armada_370_xp_mpic_irq_map, ··· 661 562 #ifdef CONFIG_SMP 662 563 /* IPI Handling */ 663 564 if (irqnr == 0) { 664 - u32 ipimask, ipinr; 565 + unsigned long ipimask; 566 + int ipi; 665 567 666 568 ipimask = readl_relaxed(per_cpu_int_base + 667 569 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) 668 570 & IPI_DOORBELL_MASK; 669 571 670 - writel(~ipimask, per_cpu_int_base + 671 - ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); 672 - 673 - /* Handle all pending doorbells */ 674 - for (ipinr = IPI_DOORBELL_START; 675 - ipinr < IPI_DOORBELL_END; ipinr++) { 676 - if (ipimask & (0x1 << ipinr)) 677 - handle_IPI(ipinr, regs); 678 - } 679 - continue; 572 + for_each_set_bit(ipi, &ipimask, IPI_DOORBELL_END) 573 + handle_domain_irq(ipi_domain, ipi, regs); 680 574 } 681 575 #endif 682 576 ··· 728 636 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 729 637 if (doorbell_mask_reg & PCI_MSI_DOORBELL_MASK) 730 638 writel(1, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 639 + 640 + ipi_resume(); 731 641 } 732 642 733 643 static struct syscore_ops armada_370_xp_mpic_syscore_ops = { ··· 785 691 irq_set_default_host(armada_370_xp_mpic_domain); 786 692 set_handle_irq(armada_370_xp_handle_irq); 787 693 #ifdef CONFIG_SMP 788 - set_smp_cross_call(armada_mpic_send_doorbell); 694 + armada_xp_ipi_init(node); 789 695 cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_ARMADA_XP_STARTING, 790 696 "irqchip/armada/ipi:starting", 791 697 armada_xp_mpic_starting_cpu, NULL);
+130 -29
drivers/irqchip/irq-bcm2836.c
··· 10 10 #include <linux/of_irq.h> 11 11 #include <linux/irqchip.h> 12 12 #include <linux/irqdomain.h> 13 + #include <linux/irqchip/chained_irq.h> 13 14 #include <linux/irqchip/irq-bcm2836.h> 14 15 15 16 #include <asm/exception.h> ··· 90 89 .irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq, 91 90 }; 92 91 92 + static void bcm2836_arm_irqchip_dummy_op(struct irq_data *d) 93 + { 94 + } 95 + 96 + static struct irq_chip bcm2836_arm_irqchip_dummy = { 97 + .name = "bcm2836-dummy", 98 + .irq_eoi = bcm2836_arm_irqchip_dummy_op, 99 + }; 100 + 93 101 static int bcm2836_map(struct irq_domain *d, unsigned int irq, 94 102 irq_hw_number_t hw) 95 103 { 96 104 struct irq_chip *chip; 97 105 98 106 switch (hw) { 107 + case LOCAL_IRQ_MAILBOX0: 108 + chip = &bcm2836_arm_irqchip_dummy; 109 + break; 99 110 case LOCAL_IRQ_CNTPSIRQ: 100 111 case LOCAL_IRQ_CNTPNSIRQ: 101 112 case LOCAL_IRQ_CNTHPIRQ: ··· 140 127 u32 stat; 141 128 142 129 stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); 143 - if (stat & BIT(LOCAL_IRQ_MAILBOX0)) { 144 - #ifdef CONFIG_SMP 145 - void __iomem *mailbox0 = (intc.base + 146 - LOCAL_MAILBOX0_CLR0 + 16 * cpu); 147 - u32 mbox_val = readl(mailbox0); 148 - u32 ipi = ffs(mbox_val) - 1; 149 - 150 - writel(1 << ipi, mailbox0); 151 - handle_IPI(ipi, regs); 152 - #endif 153 - } else if (stat) { 130 + if (stat) { 154 131 u32 hwirq = ffs(stat) - 1; 155 132 156 133 handle_domain_irq(intc.domain, hwirq, regs); ··· 148 145 } 149 146 150 147 #ifdef CONFIG_SMP 151 - static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask, 152 - unsigned int ipi) 148 + static struct irq_domain *ipi_domain; 149 + 150 + static void bcm2836_arm_irqchip_handle_ipi(struct irq_desc *desc) 151 + { 152 + struct irq_chip *chip = irq_desc_get_chip(desc); 153 + int cpu = smp_processor_id(); 154 + u32 mbox_val; 155 + 156 + chained_irq_enter(chip, desc); 157 + 158 + mbox_val = readl_relaxed(intc.base + LOCAL_MAILBOX0_CLR0 + 16 * cpu); 159 + if (mbox_val) { 160 + int hwirq = ffs(mbox_val) - 1; 161 + generic_handle_irq(irq_find_mapping(ipi_domain, hwirq)); 162 + } 163 + 164 + chained_irq_exit(chip, desc); 165 + } 166 + 167 + static void bcm2836_arm_irqchip_ipi_eoi(struct irq_data *d) 168 + { 169 + int cpu = smp_processor_id(); 170 + 171 + writel_relaxed(BIT(d->hwirq), 172 + intc.base + LOCAL_MAILBOX0_CLR0 + 16 * cpu); 173 + } 174 + 175 + static void bcm2836_arm_irqchip_ipi_send_mask(struct irq_data *d, 176 + const struct cpumask *mask) 153 177 { 154 178 int cpu; 155 179 void __iomem *mailbox0_base = intc.base + LOCAL_MAILBOX0_SET0; ··· 187 157 */ 188 158 smp_wmb(); 189 159 190 - for_each_cpu(cpu, mask) { 191 - writel(1 << ipi, mailbox0_base + 16 * cpu); 192 - } 160 + for_each_cpu(cpu, mask) 161 + writel_relaxed(BIT(d->hwirq), mailbox0_base + 16 * cpu); 193 162 } 163 + 164 + static struct irq_chip bcm2836_arm_irqchip_ipi = { 165 + .name = "IPI", 166 + .irq_mask = bcm2836_arm_irqchip_dummy_op, 167 + .irq_unmask = bcm2836_arm_irqchip_dummy_op, 168 + .irq_eoi = bcm2836_arm_irqchip_ipi_eoi, 169 + .ipi_send_mask = bcm2836_arm_irqchip_ipi_send_mask, 170 + }; 171 + 172 + static int bcm2836_arm_irqchip_ipi_alloc(struct irq_domain *d, 173 + unsigned int virq, 174 + unsigned int nr_irqs, void *args) 175 + { 176 + int i; 177 + 178 + for (i = 0; i < nr_irqs; i++) { 179 + irq_set_percpu_devid(virq + i); 180 + irq_domain_set_info(d, virq + i, i, &bcm2836_arm_irqchip_ipi, 181 + d->host_data, 182 + handle_percpu_devid_fasteoi_ipi, 183 + NULL, NULL); 184 + } 185 + 186 + return 0; 187 + } 188 + 189 + static void bcm2836_arm_irqchip_ipi_free(struct irq_domain *d, 190 + unsigned int virq, 191 + unsigned int nr_irqs) 192 + { 193 + /* Not freeing IPIs */ 194 + } 195 + 196 + static const struct irq_domain_ops ipi_domain_ops = { 197 + .alloc = bcm2836_arm_irqchip_ipi_alloc, 198 + .free = bcm2836_arm_irqchip_ipi_free, 199 + }; 194 200 195 201 static int bcm2836_cpu_starting(unsigned int cpu) 196 202 { ··· 241 175 cpu); 242 176 return 0; 243 177 } 178 + 179 + #define BITS_PER_MBOX 32 180 + 181 + static void bcm2836_arm_irqchip_smp_init(void) 182 + { 183 + struct irq_fwspec ipi_fwspec = { 184 + .fwnode = intc.domain->fwnode, 185 + .param_count = 1, 186 + .param = { 187 + [0] = LOCAL_IRQ_MAILBOX0, 188 + }, 189 + }; 190 + int base_ipi, mux_irq; 191 + 192 + mux_irq = irq_create_fwspec_mapping(&ipi_fwspec); 193 + if (WARN_ON(mux_irq <= 0)) 194 + return; 195 + 196 + ipi_domain = irq_domain_create_linear(intc.domain->fwnode, 197 + BITS_PER_MBOX, &ipi_domain_ops, 198 + NULL); 199 + if (WARN_ON(!ipi_domain)) 200 + return; 201 + 202 + ipi_domain->flags |= IRQ_DOMAIN_FLAG_IPI_SINGLE; 203 + irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); 204 + 205 + base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, BITS_PER_MBOX, 206 + NUMA_NO_NODE, NULL, 207 + false, NULL); 208 + 209 + if (WARN_ON(!base_ipi)) 210 + return; 211 + 212 + set_smp_ipi_range(base_ipi, BITS_PER_MBOX); 213 + 214 + irq_set_chained_handler_and_data(mux_irq, 215 + bcm2836_arm_irqchip_handle_ipi, NULL); 216 + 217 + /* Unmask IPIs to the boot CPU. */ 218 + cpuhp_setup_state(CPUHP_AP_IRQ_BCM2836_STARTING, 219 + "irqchip/bcm2836:starting", bcm2836_cpu_starting, 220 + bcm2836_cpu_dying); 221 + } 222 + #else 223 + #define bcm2836_arm_irqchip_smp_init() do { } while(0) 244 224 #endif 245 225 246 226 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { 247 227 .xlate = irq_domain_xlate_onetwocell, 248 228 .map = bcm2836_map, 249 229 }; 250 - 251 - static void 252 - bcm2836_arm_irqchip_smp_init(void) 253 - { 254 - #ifdef CONFIG_SMP 255 - /* Unmask IPIs to the boot CPU. */ 256 - cpuhp_setup_state(CPUHP_AP_IRQ_BCM2836_STARTING, 257 - "irqchip/bcm2836:starting", bcm2836_cpu_starting, 258 - bcm2836_cpu_dying); 259 - 260 - set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); 261 - #endif 262 - } 263 230 264 231 /* 265 232 * The LOCAL_IRQ_CNT* timer firings are based off of the external ··· 330 231 NULL); 331 232 if (!intc.domain) 332 233 panic("%pOF: unable to create IRQ domain\n", node); 234 + 235 + irq_domain_update_bus_token(intc.domain, DOMAIN_BUS_WIRED); 333 236 334 237 bcm2836_arm_irqchip_smp_init(); 335 238
-3
drivers/irqchip/irq-gic-common.c
··· 152 152 writel_relaxed(GICD_INT_DEF_PRI_X4, 153 153 base + GIC_DIST_PRI + i * 4 / 4); 154 154 155 - /* Ensure all SGI interrupts are now enabled */ 156 - writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET); 157 - 158 155 if (sync_access) 159 156 sync_access(); 160 157 }
+66 -46
drivers/irqchip/irq-gic-v3.c
··· 36 36 #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) 37 37 #define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) 38 38 39 + #define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1) 40 + 39 41 struct redist_region { 40 42 void __iomem *redist_base; 41 43 phys_addr_t phys_base; ··· 115 113 #define DEFAULT_PMR_VALUE 0xf0 116 114 117 115 enum gic_intid_range { 116 + SGI_RANGE, 118 117 PPI_RANGE, 119 118 SPI_RANGE, 120 119 EPPI_RANGE, ··· 127 124 static enum gic_intid_range __get_intid_range(irq_hw_number_t hwirq) 128 125 { 129 126 switch (hwirq) { 127 + case 0 ... 15: 128 + return SGI_RANGE; 130 129 case 16 ... 31: 131 130 return PPI_RANGE; 132 131 case 32 ... 1019: ··· 154 149 return d->hwirq; 155 150 } 156 151 157 - static inline int gic_irq_in_rdist(struct irq_data *d) 152 + static inline bool gic_irq_in_rdist(struct irq_data *d) 158 153 { 159 - enum gic_intid_range range = get_intid_range(d); 160 - return range == PPI_RANGE || range == EPPI_RANGE; 154 + switch (get_intid_range(d)) { 155 + case SGI_RANGE: 156 + case PPI_RANGE: 157 + case EPPI_RANGE: 158 + return true; 159 + default: 160 + return false; 161 + } 161 162 } 162 163 163 164 static inline void __iomem *gic_dist_base(struct irq_data *d) 164 165 { 165 166 switch (get_intid_range(d)) { 167 + case SGI_RANGE: 166 168 case PPI_RANGE: 167 169 case EPPI_RANGE: 168 170 /* SGI+PPI -> SGI_base for this CPU */ ··· 266 254 static u32 convert_offset_index(struct irq_data *d, u32 offset, u32 *index) 267 255 { 268 256 switch (get_intid_range(d)) { 257 + case SGI_RANGE: 269 258 case PPI_RANGE: 270 259 case SPI_RANGE: 271 260 *index = d->hwirq; ··· 386 373 { 387 374 u32 reg; 388 375 389 - if (d->hwirq >= 8192) /* PPI/SPI only */ 376 + if (d->hwirq >= 8192) /* SGI/PPI/SPI only */ 390 377 return -EINVAL; 391 378 392 379 switch (which) { ··· 553 540 u32 offset, index; 554 541 int ret; 555 542 556 - /* Interrupt configuration for SGIs can't be changed */ 557 - if (irq < 16) 558 - return -EINVAL; 559 - 560 543 range = get_intid_range(d); 544 + 545 + /* Interrupt configuration for SGIs can't be changed */ 546 + if (range == SGI_RANGE) 547 + return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; 561 548 562 549 /* SPIs have restrictions on the supported types */ 563 550 if ((range == SPI_RANGE || range == ESPI_RANGE) && ··· 586 573 587 574 static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) 588 575 { 576 + if (get_intid_range(d) == SGI_RANGE) 577 + return -EINVAL; 578 + 589 579 if (vcpu) 590 580 irqd_set_forwarded_to_vcpu(d); 591 581 else ··· 663 647 if ((irqnr >= 1020 && irqnr <= 1023)) 664 648 return; 665 649 666 - /* Treat anything but SGIs in a uniform way */ 667 - if (likely(irqnr > 15)) { 668 - int err; 669 - 670 - if (static_branch_likely(&supports_deactivate_key)) 671 - gic_write_eoir(irqnr); 672 - else 673 - isb(); 674 - 675 - err = handle_domain_irq(gic_data.domain, irqnr, regs); 676 - if (err) { 677 - WARN_ONCE(true, "Unexpected interrupt received!\n"); 678 - gic_deactivate_unhandled(irqnr); 679 - } 680 - return; 681 - } 682 - if (irqnr < 16) { 650 + if (static_branch_likely(&supports_deactivate_key)) 683 651 gic_write_eoir(irqnr); 684 - if (static_branch_likely(&supports_deactivate_key)) 685 - gic_write_dir(irqnr); 686 - #ifdef CONFIG_SMP 687 - /* 688 - * Unlike GICv2, we don't need an smp_rmb() here. 689 - * The control dependency from gic_read_iar to 690 - * the ISB in gic_write_eoir is enough to ensure 691 - * that any shared data read by handle_IPI will 692 - * be read after the ACK. 693 - */ 694 - handle_IPI(irqnr, regs); 695 - #else 696 - WARN_ONCE(true, "Unexpected SGI received!\n"); 697 - #endif 652 + else 653 + isb(); 654 + 655 + if (handle_domain_irq(gic_data.domain, irqnr, regs)) { 656 + WARN_ONCE(true, "Unexpected interrupt received!\n"); 657 + gic_deactivate_unhandled(irqnr); 698 658 } 699 659 } 700 660 ··· 1124 1132 gic_write_sgi1r(val); 1125 1133 } 1126 1134 1127 - static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) 1135 + static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask) 1128 1136 { 1129 1137 int cpu; 1130 1138 1131 - if (WARN_ON(irq >= 16)) 1139 + if (WARN_ON(d->hwirq >= 16)) 1132 1140 return; 1133 1141 1134 1142 /* ··· 1142 1150 u16 tlist; 1143 1151 1144 1152 tlist = gic_compute_target_list(&cpu, mask, cluster_id); 1145 - gic_send_sgi(cluster_id, tlist, irq); 1153 + gic_send_sgi(cluster_id, tlist, d->hwirq); 1146 1154 } 1147 1155 1148 1156 /* Force the above writes to ICC_SGI1R_EL1 to be executed */ ··· 1151 1159 1152 1160 static void __init gic_smp_init(void) 1153 1161 { 1154 - set_smp_cross_call(gic_raise_softirq); 1162 + struct irq_fwspec sgi_fwspec = { 1163 + .fwnode = gic_data.fwnode, 1164 + .param_count = 1, 1165 + }; 1166 + int base_sgi; 1167 + 1155 1168 cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, 1156 1169 "irqchip/arm/gicv3:starting", 1157 1170 gic_starting_cpu, NULL); 1171 + 1172 + /* Register all 8 non-secure SGIs */ 1173 + base_sgi = __irq_domain_alloc_irqs(gic_data.domain, -1, 8, 1174 + NUMA_NO_NODE, &sgi_fwspec, 1175 + false, NULL); 1176 + if (WARN_ON(base_sgi <= 0)) 1177 + return; 1178 + 1179 + set_smp_ipi_range(base_sgi, 8); 1158 1180 } 1159 1181 1160 1182 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, ··· 1217 1211 } 1218 1212 #else 1219 1213 #define gic_set_affinity NULL 1214 + #define gic_ipi_send_mask NULL 1220 1215 #define gic_smp_init() do { } while(0) 1221 1216 #endif 1222 1217 ··· 1260 1253 .irq_set_irqchip_state = gic_irq_set_irqchip_state, 1261 1254 .irq_nmi_setup = gic_irq_nmi_setup, 1262 1255 .irq_nmi_teardown = gic_irq_nmi_teardown, 1256 + .ipi_send_mask = gic_ipi_send_mask, 1263 1257 .flags = IRQCHIP_SET_TYPE_MASKED | 1264 1258 IRQCHIP_SKIP_SET_WAKE | 1265 1259 IRQCHIP_MASK_ON_SUSPEND, ··· 1278 1270 .irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity, 1279 1271 .irq_nmi_setup = gic_irq_nmi_setup, 1280 1272 .irq_nmi_teardown = gic_irq_nmi_teardown, 1273 + .ipi_send_mask = gic_ipi_send_mask, 1281 1274 .flags = IRQCHIP_SET_TYPE_MASKED | 1282 1275 IRQCHIP_SKIP_SET_WAKE | 1283 1276 IRQCHIP_MASK_ON_SUSPEND, ··· 1293 1284 chip = &gic_eoimode1_chip; 1294 1285 1295 1286 switch (__get_intid_range(hw)) { 1287 + case SGI_RANGE: 1288 + irq_set_percpu_devid(irq); 1289 + irq_domain_set_info(d, irq, hw, chip, d->host_data, 1290 + handle_percpu_devid_fasteoi_ipi, 1291 + NULL, NULL); 1292 + break; 1293 + 1296 1294 case PPI_RANGE: 1297 1295 case EPPI_RANGE: 1298 1296 irq_set_percpu_devid(irq); ··· 1329 1313 return 0; 1330 1314 } 1331 1315 1332 - #define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1) 1333 - 1334 1316 static int gic_irq_domain_translate(struct irq_domain *d, 1335 1317 struct irq_fwspec *fwspec, 1336 1318 unsigned long *hwirq, 1337 1319 unsigned int *type) 1338 1320 { 1321 + if (fwspec->param_count == 1 && fwspec->param[0] < 16) { 1322 + *hwirq = fwspec->param[0]; 1323 + *type = IRQ_TYPE_EDGE_RISING; 1324 + return 0; 1325 + } 1326 + 1339 1327 if (is_of_node(fwspec->fwnode)) { 1340 1328 if (fwspec->param_count < 3) 1341 1329 return -EINVAL; ··· 1696 1676 1697 1677 gic_update_rdist_properties(); 1698 1678 1699 - gic_smp_init(); 1700 1679 gic_dist_init(); 1701 1680 gic_cpu_init(); 1681 + gic_smp_init(); 1702 1682 gic_cpu_pm_init(); 1703 1683 1704 1684 if (gic_dist_supports_lpis()) {
+139 -106
drivers/irqchip/irq-gic.c
··· 83 83 #endif 84 84 struct irq_domain *domain; 85 85 unsigned int gic_irqs; 86 - #ifdef CONFIG_GIC_NON_BANKED 87 - void __iomem *(*get_base)(union gic_base *); 88 - #endif 89 86 }; 90 87 91 88 #ifdef CONFIG_BL_SWITCHER ··· 121 124 122 125 static struct gic_kvm_info gic_v2_kvm_info; 123 126 127 + static DEFINE_PER_CPU(u32, sgi_intid); 128 + 124 129 #ifdef CONFIG_GIC_NON_BANKED 125 - static void __iomem *gic_get_percpu_base(union gic_base *base) 130 + static DEFINE_STATIC_KEY_FALSE(frankengic_key); 131 + 132 + static void enable_frankengic(void) 126 133 { 127 - return raw_cpu_read(*base->percpu_base); 134 + static_branch_enable(&frankengic_key); 128 135 } 129 136 130 - static void __iomem *gic_get_common_base(union gic_base *base) 137 + static inline void __iomem *__get_base(union gic_base *base) 131 138 { 139 + if (static_branch_unlikely(&frankengic_key)) 140 + return raw_cpu_read(*base->percpu_base); 141 + 132 142 return base->common_base; 133 143 } 134 144 135 - static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data) 136 - { 137 - return data->get_base(&data->dist_base); 138 - } 139 - 140 - static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data) 141 - { 142 - return data->get_base(&data->cpu_base); 143 - } 144 - 145 - static inline void gic_set_base_accessor(struct gic_chip_data *data, 146 - void __iomem *(*f)(union gic_base *)) 147 - { 148 - data->get_base = f; 149 - } 145 + #define gic_data_dist_base(d) __get_base(&(d)->dist_base) 146 + #define gic_data_cpu_base(d) __get_base(&(d)->cpu_base) 150 147 #else 151 148 #define gic_data_dist_base(d) ((d)->dist_base.common_base) 152 149 #define gic_data_cpu_base(d) ((d)->cpu_base.common_base) 153 - #define gic_set_base_accessor(d, f) 150 + #define enable_frankengic() do { } while(0) 154 151 #endif 155 152 156 153 static inline void __iomem *gic_dist_base(struct irq_data *d) ··· 217 226 218 227 static void gic_eoi_irq(struct irq_data *d) 219 228 { 220 - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); 229 + u32 hwirq = gic_irq(d); 230 + 231 + if (hwirq < 16) 232 + hwirq = this_cpu_read(sgi_intid); 233 + 234 + writel_relaxed(hwirq, gic_cpu_base(d) + GIC_CPU_EOI); 221 235 } 222 236 223 237 static void gic_eoimode1_eoi_irq(struct irq_data *d) 224 238 { 239 + u32 hwirq = gic_irq(d); 240 + 225 241 /* Do not deactivate an IRQ forwarded to a vcpu. */ 226 242 if (irqd_is_forwarded_to_vcpu(d)) 227 243 return; 228 244 229 - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE); 245 + if (hwirq < 16) 246 + hwirq = this_cpu_read(sgi_intid); 247 + 248 + writel_relaxed(hwirq, gic_cpu_base(d) + GIC_CPU_DEACTIVATE); 230 249 } 231 250 232 251 static int gic_irq_set_irqchip_state(struct irq_data *d, ··· 296 295 297 296 /* Interrupt configuration for SGIs can't be changed */ 298 297 if (gicirq < 16) 299 - return -EINVAL; 298 + return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; 300 299 301 300 /* SPIs have restrictions on the supported types */ 302 301 if (gicirq >= 32 && type != IRQ_TYPE_LEVEL_HIGH && ··· 316 315 static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) 317 316 { 318 317 /* Only interrupts on the primary GIC can be forwarded to a vcpu. */ 319 - if (cascading_gic_irq(d)) 318 + if (cascading_gic_irq(d) || gic_irq(d) < 16) 320 319 return -EINVAL; 321 320 322 321 if (vcpu) ··· 325 324 irqd_clr_forwarded_to_vcpu(d); 326 325 return 0; 327 326 } 328 - 329 - #ifdef CONFIG_SMP 330 - static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, 331 - bool force) 332 - { 333 - void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); 334 - unsigned int cpu; 335 - 336 - if (!force) 337 - cpu = cpumask_any_and(mask_val, cpu_online_mask); 338 - else 339 - cpu = cpumask_first(mask_val); 340 - 341 - if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) 342 - return -EINVAL; 343 - 344 - writeb_relaxed(gic_cpu_map[cpu], reg); 345 - irq_data_update_effective_affinity(d, cpumask_of(cpu)); 346 - 347 - return IRQ_SET_MASK_OK_DONE; 348 - } 349 - #endif 350 327 351 328 static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) 352 329 { ··· 336 357 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); 337 358 irqnr = irqstat & GICC_IAR_INT_ID_MASK; 338 359 339 - if (likely(irqnr > 15 && irqnr < 1020)) { 340 - if (static_branch_likely(&supports_deactivate_key)) 341 - writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); 342 - isb(); 343 - handle_domain_irq(gic->domain, irqnr, regs); 344 - continue; 345 - } 346 - if (irqnr < 16) { 360 + if (unlikely(irqnr >= 1020)) 361 + break; 362 + 363 + if (static_branch_likely(&supports_deactivate_key)) 347 364 writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); 348 - if (static_branch_likely(&supports_deactivate_key)) 349 - writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE); 350 - #ifdef CONFIG_SMP 351 - /* 352 - * Ensure any shared data written by the CPU sending 353 - * the IPI is read after we've read the ACK register 354 - * on the GIC. 355 - * 356 - * Pairs with the write barrier in gic_raise_softirq 357 - */ 365 + isb(); 366 + 367 + /* 368 + * Ensure any shared data written by the CPU sending the IPI 369 + * is read after we've read the ACK register on the GIC. 370 + * 371 + * Pairs with the write barrier in gic_ipi_send_mask 372 + */ 373 + if (irqnr <= 15) { 358 374 smp_rmb(); 359 - handle_IPI(irqnr, regs); 360 - #endif 361 - continue; 375 + 376 + /* 377 + * The GIC encodes the source CPU in GICC_IAR, 378 + * leading to the deactivation to fail if not 379 + * written back as is to GICC_EOI. Stash the INTID 380 + * away for gic_eoi_irq() to write back. This only 381 + * works because we don't nest SGIs... 382 + */ 383 + this_cpu_write(sgi_intid, irqstat); 362 384 } 363 - break; 385 + 386 + handle_domain_irq(gic->domain, irqnr, regs); 364 387 } while (1); 365 388 } 366 389 ··· 709 728 int i; 710 729 711 730 for (i = 0; i < CONFIG_ARM_GIC_MAX_NR; i++) { 712 - #ifdef CONFIG_GIC_NON_BANKED 713 - /* Skip over unused GICs */ 714 - if (!gic_data[i].get_base) 715 - continue; 716 - #endif 717 731 switch (cmd) { 718 732 case CPU_PM_ENTER: 719 733 gic_cpu_save(&gic_data[i]); ··· 771 795 #endif 772 796 773 797 #ifdef CONFIG_SMP 774 - static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) 798 + static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, 799 + bool force) 800 + { 801 + void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); 802 + unsigned int cpu; 803 + 804 + if (!force) 805 + cpu = cpumask_any_and(mask_val, cpu_online_mask); 806 + else 807 + cpu = cpumask_first(mask_val); 808 + 809 + if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) 810 + return -EINVAL; 811 + 812 + writeb_relaxed(gic_cpu_map[cpu], reg); 813 + irq_data_update_effective_affinity(d, cpumask_of(cpu)); 814 + 815 + return IRQ_SET_MASK_OK_DONE; 816 + } 817 + 818 + static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask) 775 819 { 776 820 int cpu; 777 821 unsigned long flags, map = 0; 778 822 779 823 if (unlikely(nr_cpu_ids == 1)) { 780 824 /* Only one CPU? let's do a self-IPI... */ 781 - writel_relaxed(2 << 24 | irq, 825 + writel_relaxed(2 << 24 | d->hwirq, 782 826 gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); 783 827 return; 784 828 } ··· 816 820 dmb(ishst); 817 821 818 822 /* this always happens on GIC0 */ 819 - writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); 823 + writel_relaxed(map << 16 | d->hwirq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); 820 824 821 825 gic_unlock_irqrestore(flags); 822 826 } 827 + 828 + static int gic_starting_cpu(unsigned int cpu) 829 + { 830 + gic_cpu_init(&gic_data[0]); 831 + return 0; 832 + } 833 + 834 + static __init void gic_smp_init(void) 835 + { 836 + struct irq_fwspec sgi_fwspec = { 837 + .fwnode = gic_data[0].domain->fwnode, 838 + .param_count = 1, 839 + }; 840 + int base_sgi; 841 + 842 + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, 843 + "irqchip/arm/gic:starting", 844 + gic_starting_cpu, NULL); 845 + 846 + base_sgi = __irq_domain_alloc_irqs(gic_data[0].domain, -1, 8, 847 + NUMA_NO_NODE, &sgi_fwspec, 848 + false, NULL); 849 + if (WARN_ON(base_sgi <= 0)) 850 + return; 851 + 852 + set_smp_ipi_range(base_sgi, 8); 853 + } 854 + #else 855 + #define gic_smp_init() do { } while(0) 856 + #define gic_set_affinity NULL 857 + #define gic_ipi_send_mask NULL 823 858 #endif 824 859 825 860 #ifdef CONFIG_BL_SWITCHER ··· 997 970 { 998 971 struct gic_chip_data *gic = d->host_data; 999 972 1000 - if (hw < 32) { 973 + switch (hw) { 974 + case 0 ... 15: 975 + irq_set_percpu_devid(irq); 976 + irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, 977 + handle_percpu_devid_fasteoi_ipi, 978 + NULL, NULL); 979 + break; 980 + case 16 ... 31: 1001 981 irq_set_percpu_devid(irq); 1002 982 irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, 1003 983 handle_percpu_devid_irq, NULL, NULL); 1004 - } else { 984 + break; 985 + default: 1005 986 irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data, 1006 987 handle_fasteoi_irq, NULL, NULL); 1007 988 irq_set_probe(irq); 1008 989 irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq))); 990 + break; 1009 991 } 1010 992 return 0; 1011 993 } ··· 1028 992 unsigned long *hwirq, 1029 993 unsigned int *type) 1030 994 { 995 + if (fwspec->param_count == 1 && fwspec->param[0] < 16) { 996 + *hwirq = fwspec->param[0]; 997 + *type = IRQ_TYPE_EDGE_RISING; 998 + return 0; 999 + } 1000 + 1031 1001 if (is_of_node(fwspec->fwnode)) { 1032 1002 if (fwspec->param_count < 3) 1033 1003 return -EINVAL; 1034 1004 1035 - /* Get the interrupt number and add 16 to skip over SGIs */ 1036 - *hwirq = fwspec->param[1] + 16; 1037 - 1038 - /* 1039 - * For SPIs, we need to add 16 more to get the GIC irq 1040 - * ID number 1041 - */ 1042 - if (!fwspec->param[0]) 1043 - *hwirq += 16; 1005 + switch (fwspec->param[0]) { 1006 + case 0: /* SPI */ 1007 + *hwirq = fwspec->param[1] + 32; 1008 + break; 1009 + case 1: /* PPI */ 1010 + *hwirq = fwspec->param[1] + 16; 1011 + break; 1012 + default: 1013 + return -EINVAL; 1014 + } 1044 1015 1045 1016 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; 1046 1017 ··· 1068 1025 } 1069 1026 1070 1027 return -EINVAL; 1071 - } 1072 - 1073 - static int gic_starting_cpu(unsigned int cpu) 1074 - { 1075 - gic_cpu_init(&gic_data[0]); 1076 - return 0; 1077 1028 } 1078 1029 1079 1030 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, ··· 1116 1079 gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity; 1117 1080 } 1118 1081 1119 - #ifdef CONFIG_SMP 1120 - if (gic == &gic_data[0]) 1082 + if (gic == &gic_data[0]) { 1121 1083 gic->chip.irq_set_affinity = gic_set_affinity; 1122 - #endif 1084 + gic->chip.ipi_send_mask = gic_ipi_send_mask; 1085 + } 1123 1086 } 1124 1087 1125 1088 static int gic_init_bases(struct gic_chip_data *gic, ··· 1149 1112 gic->raw_cpu_base + offset; 1150 1113 } 1151 1114 1152 - gic_set_base_accessor(gic, gic_get_percpu_base); 1115 + enable_frankengic(); 1153 1116 } else { 1154 1117 /* Normal, sane GIC... */ 1155 1118 WARN(gic->percpu_offset, ··· 1157 1120 gic->percpu_offset); 1158 1121 gic->dist_base.common_base = gic->raw_dist_base; 1159 1122 gic->cpu_base.common_base = gic->raw_cpu_base; 1160 - gic_set_base_accessor(gic, gic_get_common_base); 1161 1123 } 1162 1124 1163 1125 /* ··· 1235 1199 */ 1236 1200 for (i = 0; i < NR_GIC_CPU_IF; i++) 1237 1201 gic_cpu_map[i] = 0xff; 1238 - #ifdef CONFIG_SMP 1239 - set_smp_cross_call(gic_raise_softirq); 1240 - #endif 1241 - cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, 1242 - "irqchip/arm/gic:starting", 1243 - gic_starting_cpu, NULL); 1202 + 1244 1203 set_handle_irq(gic_handle_irq); 1245 1204 if (static_branch_likely(&supports_deactivate_key)) 1246 1205 pr_info("GIC: Using split EOI/Deactivate mode\n"); ··· 1252 1221 ret = gic_init_bases(gic, handle); 1253 1222 if (ret) 1254 1223 kfree(name); 1224 + else if (gic == &gic_data[0]) 1225 + gic_smp_init(); 1255 1226 1256 1227 return ret; 1257 1228 }
+40 -49
drivers/irqchip/irq-hip04.c
··· 171 171 172 172 return IRQ_SET_MASK_OK; 173 173 } 174 + 175 + static void hip04_ipi_send_mask(struct irq_data *d, const struct cpumask *mask) 176 + { 177 + int cpu; 178 + unsigned long flags, map = 0; 179 + 180 + raw_spin_lock_irqsave(&irq_controller_lock, flags); 181 + 182 + /* Convert our logical CPU mask into a physical one. */ 183 + for_each_cpu(cpu, mask) 184 + map |= hip04_cpu_map[cpu]; 185 + 186 + /* 187 + * Ensure that stores to Normal memory are visible to the 188 + * other CPUs before they observe us issuing the IPI. 189 + */ 190 + dmb(ishst); 191 + 192 + /* this always happens on GIC0 */ 193 + writel_relaxed(map << 8 | d->hwirq, hip04_data.dist_base + GIC_DIST_SOFTINT); 194 + 195 + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); 196 + } 174 197 #endif 175 198 176 199 static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs) ··· 205 182 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); 206 183 irqnr = irqstat & GICC_IAR_INT_ID_MASK; 207 184 208 - if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) { 185 + if (irqnr <= HIP04_MAX_IRQS) 209 186 handle_domain_irq(hip04_data.domain, irqnr, regs); 210 - continue; 211 - } 212 - if (irqnr < 16) { 213 - writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); 214 - #ifdef CONFIG_SMP 215 - handle_IPI(irqnr, regs); 216 - #endif 217 - continue; 218 - } 219 - break; 220 - } while (1); 187 + } while (irqnr > HIP04_MAX_IRQS); 221 188 } 222 189 223 190 static struct irq_chip hip04_irq_chip = { ··· 218 205 .irq_set_type = hip04_irq_set_type, 219 206 #ifdef CONFIG_SMP 220 207 .irq_set_affinity = hip04_irq_set_affinity, 208 + .ipi_send_mask = hip04_ipi_send_mask, 221 209 #endif 222 210 .flags = IRQCHIP_SET_TYPE_MASKED | 223 211 IRQCHIP_SKIP_SET_WAKE | ··· 293 279 writel_relaxed(1, base + GIC_CPU_CTRL); 294 280 } 295 281 296 - #ifdef CONFIG_SMP 297 - static void hip04_raise_softirq(const struct cpumask *mask, unsigned int irq) 298 - { 299 - int cpu; 300 - unsigned long flags, map = 0; 301 - 302 - raw_spin_lock_irqsave(&irq_controller_lock, flags); 303 - 304 - /* Convert our logical CPU mask into a physical one. */ 305 - for_each_cpu(cpu, mask) 306 - map |= hip04_cpu_map[cpu]; 307 - 308 - /* 309 - * Ensure that stores to Normal memory are visible to the 310 - * other CPUs before they observe us issuing the IPI. 311 - */ 312 - dmb(ishst); 313 - 314 - /* this always happens on GIC0 */ 315 - writel_relaxed(map << 8 | irq, hip04_data.dist_base + GIC_DIST_SOFTINT); 316 - 317 - raw_spin_unlock_irqrestore(&irq_controller_lock, flags); 318 - } 319 - #endif 320 - 321 282 static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq, 322 283 irq_hw_number_t hw) 323 284 { 324 - if (hw < 32) { 285 + if (hw < 16) { 286 + irq_set_percpu_devid(irq); 287 + irq_set_chip_and_handler(irq, &hip04_irq_chip, 288 + handle_percpu_devid_fasteoi_ipi); 289 + } else if (hw < 32) { 325 290 irq_set_percpu_devid(irq); 326 291 irq_set_chip_and_handler(irq, &hip04_irq_chip, 327 292 handle_percpu_devid_irq); 328 - irq_set_status_flags(irq, IRQ_NOAUTOEN); 329 293 } else { 330 294 irq_set_chip_and_handler(irq, &hip04_irq_chip, 331 295 handle_fasteoi_irq); ··· 320 328 unsigned long *out_hwirq, 321 329 unsigned int *out_type) 322 330 { 323 - unsigned long ret = 0; 324 - 325 331 if (irq_domain_get_of_node(d) != controller) 326 332 return -EINVAL; 333 + if (intsize == 1 && intspec[0] < 16) { 334 + *out_hwirq = intspec[0]; 335 + *out_type = IRQ_TYPE_EDGE_RISING; 336 + return 0; 337 + } 327 338 if (intsize < 3) 328 339 return -EINVAL; 329 340 ··· 339 344 340 345 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 341 346 342 - return ret; 347 + return 0; 343 348 } 344 349 345 350 static int hip04_irq_starting_cpu(unsigned int cpu) ··· 356 361 static int __init 357 362 hip04_of_init(struct device_node *node, struct device_node *parent) 358 363 { 359 - irq_hw_number_t hwirq_base = 16; 360 364 int nr_irqs, irq_base, i; 361 365 362 366 if (WARN_ON(!node)) ··· 384 390 nr_irqs = HIP04_MAX_IRQS; 385 391 hip04_data.nr_irqs = nr_irqs; 386 392 387 - nr_irqs -= hwirq_base; /* calculate # of irqs to allocate */ 388 - 389 - irq_base = irq_alloc_descs(-1, hwirq_base, nr_irqs, numa_node_id()); 393 + irq_base = irq_alloc_descs(-1, 0, nr_irqs, numa_node_id()); 390 394 if (irq_base < 0) { 391 395 pr_err("failed to allocate IRQ numbers\n"); 392 396 return -EINVAL; 393 397 } 394 398 395 399 hip04_data.domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 396 - hwirq_base, 400 + 0, 397 401 &hip04_irq_domain_ops, 398 402 &hip04_data); 399 - 400 403 if (WARN_ON(!hip04_data.domain)) 401 404 return -EINVAL; 402 405 403 406 #ifdef CONFIG_SMP 404 - set_smp_cross_call(hip04_raise_softirq); 407 + set_smp_ipi_range(irq_base, 16); 405 408 #endif 406 409 set_handle_irq(hip04_handle_irq); 407 410
+4 -1
include/linux/irq.h
··· 71 71 * it from the spurious interrupt detection 72 72 * mechanism and from core side polling. 73 73 * IRQ_DISABLE_UNLAZY - Disable lazy irq disable 74 + * IRQ_HIDDEN - Don't show up in /proc/interrupts 74 75 */ 75 76 enum { 76 77 IRQ_TYPE_NONE = 0x00000000, ··· 98 97 IRQ_PER_CPU_DEVID = (1 << 17), 99 98 IRQ_IS_POLLED = (1 << 18), 100 99 IRQ_DISABLE_UNLAZY = (1 << 19), 100 + IRQ_HIDDEN = (1 << 20), 101 101 }; 102 102 103 103 #define IRQF_MODIFY_MASK \ 104 104 (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ 105 105 IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ 106 106 IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \ 107 - IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY) 107 + IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_HIDDEN) 108 108 109 109 #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) 110 110 ··· 636 634 */ 637 635 extern void handle_level_irq(struct irq_desc *desc); 638 636 extern void handle_fasteoi_irq(struct irq_desc *desc); 637 + extern void handle_percpu_devid_fasteoi_ipi(struct irq_desc *desc); 639 638 extern void handle_edge_irq(struct irq_desc *desc); 640 639 extern void handle_edge_eoi_irq(struct irq_desc *desc); 641 640 extern void handle_simple_irq(struct irq_desc *desc);
+27
kernel/irq/chip.c
··· 945 945 } 946 946 947 947 /** 948 + * handle_percpu_devid_fasteoi_ipi - Per CPU local IPI handler with per cpu 949 + * dev ids 950 + * @desc: the interrupt description structure for this irq 951 + * 952 + * The biggest difference with the IRQ version is that the interrupt is 953 + * EOIed early, as the IPI could result in a context switch, and we need to 954 + * make sure the IPI can fire again. We also assume that the arch code has 955 + * registered an action. If not, we are positively doomed. 956 + */ 957 + void handle_percpu_devid_fasteoi_ipi(struct irq_desc *desc) 958 + { 959 + struct irq_chip *chip = irq_desc_get_chip(desc); 960 + struct irqaction *action = desc->action; 961 + unsigned int irq = irq_desc_get_irq(desc); 962 + irqreturn_t res; 963 + 964 + __kstat_incr_irqs_this_cpu(desc); 965 + 966 + if (chip->irq_eoi) 967 + chip->irq_eoi(&desc->irq_data); 968 + 969 + trace_irq_handler_entry(irq, action); 970 + res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id)); 971 + trace_irq_handler_exit(irq, action, res); 972 + } 973 + 974 + /** 948 975 * handle_percpu_devid_fasteoi_nmi - Per CPU local NMI handler with per cpu 949 976 * dev ids 950 977 * @desc: the interrupt description structure for this irq
+1
kernel/irq/debugfs.c
··· 136 136 BIT_MASK_DESCR(_IRQ_PER_CPU_DEVID), 137 137 BIT_MASK_DESCR(_IRQ_IS_POLLED), 138 138 BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY), 139 + BIT_MASK_DESCR(_IRQ_HIDDEN), 139 140 }; 140 141 141 142 static const struct irq_bit_descr irqdesc_istates[] = {
+1 -1
kernel/irq/proc.c
··· 485 485 486 486 rcu_read_lock(); 487 487 desc = irq_to_desc(i); 488 - if (!desc) 488 + if (!desc || irq_settings_is_hidden(desc)) 489 489 goto outsparse; 490 490 491 491 if (desc->kstat_irqs)
+7
kernel/irq/settings.h
··· 17 17 _IRQ_PER_CPU_DEVID = IRQ_PER_CPU_DEVID, 18 18 _IRQ_IS_POLLED = IRQ_IS_POLLED, 19 19 _IRQ_DISABLE_UNLAZY = IRQ_DISABLE_UNLAZY, 20 + _IRQ_HIDDEN = IRQ_HIDDEN, 20 21 _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK, 21 22 }; 22 23 ··· 32 31 #define IRQ_PER_CPU_DEVID GOT_YOU_MORON 33 32 #define IRQ_IS_POLLED GOT_YOU_MORON 34 33 #define IRQ_DISABLE_UNLAZY GOT_YOU_MORON 34 + #define IRQ_HIDDEN GOT_YOU_MORON 35 35 #undef IRQF_MODIFY_MASK 36 36 #define IRQF_MODIFY_MASK GOT_YOU_MORON 37 37 ··· 168 166 static inline void irq_settings_clr_disable_unlazy(struct irq_desc *desc) 169 167 { 170 168 desc->status_use_accessors &= ~_IRQ_DISABLE_UNLAZY; 169 + } 170 + 171 + static inline bool irq_settings_is_hidden(struct irq_desc *desc) 172 + { 173 + return desc->status_use_accessors & _IRQ_HIDDEN; 171 174 }