mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	irq: remove handle_domain_{irq,nmi}()
Now that entry code handles IRQ entry (including setting the IRQ regs)
before calling irqchip code, irqchip code can safely call
generic_handle_domain_irq(), and there's no functional reason for it to
call handle_domain_irq().
Let's cement this split of responsibility and remove handle_domain_irq()
entirely, updating irqchip drivers to call generic_handle_domain_irq().
For consistency, handle_domain_nmi() is similarly removed and replaced
with a generic_handle_domain_nmi() function which also does not perform
any entry logic.
Previously handle_domain_{irq,nmi}() had a WARN_ON() which would fire
when they were called in an inappropriate context. So that we can
identify similar issues going forward, similar WARN_ON_ONCE() logic is
added to the generic_handle_*() functions, and comments are updated for
clarity and consistency.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
			
			
This commit is contained in:
		
							parent
							
								
									5aecc24377
								
							
						
					
					
						commit
						0953fb2637
					
				
					 48 changed files with 80 additions and 141 deletions
				
			
		|  | @ -67,9 +67,6 @@ variety of methods: | ||||||
|   deprecated |   deprecated | ||||||
| - generic_handle_domain_irq() handles an interrupt described by a | - generic_handle_domain_irq() handles an interrupt described by a | ||||||
|   domain and a hwirq number |   domain and a hwirq number | ||||||
| - handle_domain_irq() does the same thing for root interrupt |  | ||||||
|   controllers and deals with the set_irq_reg()/irq_enter() sequences |  | ||||||
|   that most architecture requires |  | ||||||
| 
 | 
 | ||||||
| Note that irq domain lookups must happen in contexts that are | Note that irq domain lookups must happen in contexts that are | ||||||
| compatible with a RCU read-side critical section. | compatible with a RCU read-side critical section. | ||||||
|  |  | ||||||
|  | @ -64,7 +64,6 @@ config ARM | ||||||
| 	select GENERIC_PCI_IOMAP | 	select GENERIC_PCI_IOMAP | ||||||
| 	select GENERIC_SCHED_CLOCK | 	select GENERIC_SCHED_CLOCK | ||||||
| 	select GENERIC_SMP_IDLE_THREAD | 	select GENERIC_SMP_IDLE_THREAD | ||||||
| 	select HANDLE_DOMAIN_IRQ |  | ||||||
| 	select HARDIRQS_SW_RESEND | 	select HARDIRQS_SW_RESEND | ||||||
| 	select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT | 	select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT | ||||||
| 	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 | 	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 | ||||||
|  |  | ||||||
|  | @ -154,7 +154,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) | ||||||
| 		if (nivector == 0xffff) | 		if (nivector == 0xffff) | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		handle_domain_irq(domain, nivector, regs); | 		generic_handle_domain_irq(domain, nivector); | ||||||
| 	} while (1); | 	} while (1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -134,7 +134,7 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) | ||||||
| 			while (stat) { | 			while (stat) { | ||||||
| 				handled = 1; | 				handled = 1; | ||||||
| 				irqofs = fls(stat) - 1; | 				irqofs = fls(stat) - 1; | ||||||
| 				handle_domain_irq(domain, irqofs + i * 32, regs); | 				generic_handle_domain_irq(domain, irqofs + i * 32); | ||||||
| 				stat &= ~(1 << irqofs); | 				stat &= ~(1 << irqofs); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -165,7 +165,7 @@ asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs) | ||||||
| 		} | 		} | ||||||
| irq: | irq: | ||||||
| 		if (irqnr) | 		if (irqnr) | ||||||
| 			handle_domain_irq(domain, irqnr, regs); | 			generic_handle_domain_irq(domain, irqnr); | ||||||
| 		else | 		else | ||||||
| 			break; | 			break; | ||||||
| 	} while (irqnr); | 	} while (irqnr); | ||||||
|  |  | ||||||
|  | @ -354,7 +354,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, | ||||||
| 	if (!(pnd & (1 << offset))) | 	if (!(pnd & (1 << offset))) | ||||||
| 		offset =  __ffs(pnd); | 		offset =  __ffs(pnd); | ||||||
| 
 | 
 | ||||||
| 	handle_domain_irq(intc->domain, intc_offset + offset, regs); | 	generic_handle_domain_irq(intc->domain, intc_offset + offset); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -133,7 +133,6 @@ config ARM64 | ||||||
| 	select GENERIC_TIME_VSYSCALL | 	select GENERIC_TIME_VSYSCALL | ||||||
| 	select GENERIC_GETTIMEOFDAY | 	select GENERIC_GETTIMEOFDAY | ||||||
| 	select GENERIC_VDSO_TIME_NS | 	select GENERIC_VDSO_TIME_NS | ||||||
| 	select HANDLE_DOMAIN_IRQ |  | ||||||
| 	select HARDIRQS_SW_RESEND | 	select HARDIRQS_SW_RESEND | ||||||
| 	select HAVE_MOVE_PMD | 	select HAVE_MOVE_PMD | ||||||
| 	select HAVE_MOVE_PUD | 	select HAVE_MOVE_PUD | ||||||
|  |  | ||||||
|  | @ -17,7 +17,6 @@ config CSKY | ||||||
| 	select CSKY_APB_INTC | 	select CSKY_APB_INTC | ||||||
| 	select DMA_DIRECT_REMAP | 	select DMA_DIRECT_REMAP | ||||||
| 	select IRQ_DOMAIN | 	select IRQ_DOMAIN | ||||||
| 	select HANDLE_DOMAIN_IRQ |  | ||||||
| 	select DW_APB_TIMER_OF | 	select DW_APB_TIMER_OF | ||||||
| 	select GENERIC_IOREMAP | 	select GENERIC_IOREMAP | ||||||
| 	select GENERIC_LIB_ASHLDI3 | 	select GENERIC_LIB_ASHLDI3 | ||||||
|  |  | ||||||
|  | @ -13,7 +13,6 @@ config OPENRISC | ||||||
| 	select OF | 	select OF | ||||||
| 	select OF_EARLY_FLATTREE | 	select OF_EARLY_FLATTREE | ||||||
| 	select IRQ_DOMAIN | 	select IRQ_DOMAIN | ||||||
| 	select HANDLE_DOMAIN_IRQ |  | ||||||
| 	select GPIOLIB | 	select GPIOLIB | ||||||
| 	select HAVE_ARCH_TRACEHOOK | 	select HAVE_ARCH_TRACEHOOK | ||||||
| 	select SPARSE_IRQ | 	select SPARSE_IRQ | ||||||
|  |  | ||||||
|  | @ -62,7 +62,6 @@ config RISCV | ||||||
| 	select GENERIC_SCHED_CLOCK | 	select GENERIC_SCHED_CLOCK | ||||||
| 	select GENERIC_SMP_IDLE_THREAD | 	select GENERIC_SMP_IDLE_THREAD | ||||||
| 	select GENERIC_TIME_VSYSCALL if MMU && 64BIT | 	select GENERIC_TIME_VSYSCALL if MMU && 64BIT | ||||||
| 	select HANDLE_DOMAIN_IRQ |  | ||||||
| 	select HAVE_ARCH_AUDITSYSCALL | 	select HAVE_ARCH_AUDITSYSCALL | ||||||
| 	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | 	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | ||||||
| 	select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL | 	select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL | ||||||
|  |  | ||||||
|  | @ -245,7 +245,7 @@ static void __exception_irq_entry aic_handle_irq(struct pt_regs *regs) | ||||||
| 		irq = FIELD_GET(AIC_EVENT_NUM, event); | 		irq = FIELD_GET(AIC_EVENT_NUM, event); | ||||||
| 
 | 
 | ||||||
| 		if (type == AIC_EVENT_TYPE_HW) | 		if (type == AIC_EVENT_TYPE_HW) | ||||||
| 			handle_domain_irq(aic_irqc->hw_domain, irq, regs); | 			generic_handle_domain_irq(aic_irqc->hw_domain, irq); | ||||||
| 		else if (type == AIC_EVENT_TYPE_IPI && irq == 1) | 		else if (type == AIC_EVENT_TYPE_IPI && irq == 1) | ||||||
| 			aic_handle_ipi(regs); | 			aic_handle_ipi(regs); | ||||||
| 		else if (event != 0) | 		else if (event != 0) | ||||||
|  | @ -392,25 +392,25 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (TIMER_FIRING(read_sysreg(cntp_ctl_el0))) | 	if (TIMER_FIRING(read_sysreg(cntp_ctl_el0))) | ||||||
| 		handle_domain_irq(aic_irqc->hw_domain, | 		generic_handle_domain_irq(aic_irqc->hw_domain, | ||||||
| 				  aic_irqc->nr_hw + AIC_TMR_EL0_PHYS, regs); | 					  aic_irqc->nr_hw + AIC_TMR_EL0_PHYS); | ||||||
| 
 | 
 | ||||||
| 	if (TIMER_FIRING(read_sysreg(cntv_ctl_el0))) | 	if (TIMER_FIRING(read_sysreg(cntv_ctl_el0))) | ||||||
| 		handle_domain_irq(aic_irqc->hw_domain, | 		generic_handle_domain_irq(aic_irqc->hw_domain, | ||||||
| 				  aic_irqc->nr_hw + AIC_TMR_EL0_VIRT, regs); | 					  aic_irqc->nr_hw + AIC_TMR_EL0_VIRT); | ||||||
| 
 | 
 | ||||||
| 	if (is_kernel_in_hyp_mode()) { | 	if (is_kernel_in_hyp_mode()) { | ||||||
| 		uint64_t enabled = read_sysreg_s(SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2); | 		uint64_t enabled = read_sysreg_s(SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2); | ||||||
| 
 | 
 | ||||||
| 		if ((enabled & VM_TMR_FIQ_ENABLE_P) && | 		if ((enabled & VM_TMR_FIQ_ENABLE_P) && | ||||||
| 		    TIMER_FIRING(read_sysreg_s(SYS_CNTP_CTL_EL02))) | 		    TIMER_FIRING(read_sysreg_s(SYS_CNTP_CTL_EL02))) | ||||||
| 			handle_domain_irq(aic_irqc->hw_domain, | 			generic_handle_domain_irq(aic_irqc->hw_domain, | ||||||
| 					  aic_irqc->nr_hw + AIC_TMR_EL02_PHYS, regs); | 						  aic_irqc->nr_hw + AIC_TMR_EL02_PHYS); | ||||||
| 
 | 
 | ||||||
| 		if ((enabled & VM_TMR_FIQ_ENABLE_V) && | 		if ((enabled & VM_TMR_FIQ_ENABLE_V) && | ||||||
| 		    TIMER_FIRING(read_sysreg_s(SYS_CNTV_CTL_EL02))) | 		    TIMER_FIRING(read_sysreg_s(SYS_CNTV_CTL_EL02))) | ||||||
| 			handle_domain_irq(aic_irqc->hw_domain, | 			generic_handle_domain_irq(aic_irqc->hw_domain, | ||||||
| 					  aic_irqc->nr_hw + AIC_TMR_EL02_VIRT, regs); | 						  aic_irqc->nr_hw + AIC_TMR_EL02_VIRT); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) == | 	if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) == | ||||||
|  | @ -674,7 +674,7 @@ static void aic_handle_ipi(struct pt_regs *regs) | ||||||
| 	firing = atomic_fetch_andnot(enabled, this_cpu_ptr(&aic_vipi_flag)) & enabled; | 	firing = atomic_fetch_andnot(enabled, this_cpu_ptr(&aic_vipi_flag)) & enabled; | ||||||
| 
 | 
 | ||||||
| 	for_each_set_bit(i, &firing, AIC_NR_SWIPI) | 	for_each_set_bit(i, &firing, AIC_NR_SWIPI) | ||||||
| 		handle_domain_irq(aic_irqc->ipi_domain, i, regs); | 		generic_handle_domain_irq(aic_irqc->ipi_domain, i); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * No ordering needed here; at worst this just changes the timing of | 	 * No ordering needed here; at worst this just changes the timing of | ||||||
|  |  | ||||||
|  | @ -589,12 +589,7 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained) | ||||||
| 
 | 
 | ||||||
| 		irq = msinr - PCI_MSI_DOORBELL_START; | 		irq = msinr - PCI_MSI_DOORBELL_START; | ||||||
| 
 | 
 | ||||||
| 		if (is_chained) | 		generic_handle_domain_irq(armada_370_xp_msi_inner_domain, irq); | ||||||
| 			generic_handle_domain_irq(armada_370_xp_msi_inner_domain, |  | ||||||
| 						  irq); |  | ||||||
| 		else |  | ||||||
| 			handle_domain_irq(armada_370_xp_msi_inner_domain, |  | ||||||
| 					  irq, regs); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| #else | #else | ||||||
|  | @ -646,8 +641,8 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		if (irqnr > 1) { | 		if (irqnr > 1) { | ||||||
| 			handle_domain_irq(armada_370_xp_mpic_domain, | 			generic_handle_domain_irq(armada_370_xp_mpic_domain, | ||||||
| 					  irqnr, regs); | 						  irqnr); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -666,7 +661,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | ||||||
| 				& IPI_DOORBELL_MASK; | 				& IPI_DOORBELL_MASK; | ||||||
| 
 | 
 | ||||||
| 			for_each_set_bit(ipi, &ipimask, IPI_DOORBELL_END) | 			for_each_set_bit(ipi, &ipimask, IPI_DOORBELL_END) | ||||||
| 				handle_domain_irq(ipi_domain, ipi, regs); | 				generic_handle_domain_irq(ipi_domain, ipi); | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -100,7 +100,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) | ||||||
| 		if (stat == 0) | 		if (stat == 0) | ||||||
| 			break; | 			break; | ||||||
| 		irq += ffs(stat) - 1; | 		irq += ffs(stat) - 1; | ||||||
| 		handle_domain_irq(vic->dom, irq, regs); | 		generic_handle_domain_irq(vic->dom, irq); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -71,7 +71,7 @@ aic_handle(struct pt_regs *regs) | ||||||
| 	if (!irqstat) | 	if (!irqstat) | ||||||
| 		irq_reg_writel(gc, 0, AT91_AIC_EOICR); | 		irq_reg_writel(gc, 0, AT91_AIC_EOICR); | ||||||
| 	else | 	else | ||||||
| 		handle_domain_irq(aic_domain, irqnr, regs); | 		generic_handle_domain_irq(aic_domain, irqnr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int aic_retrigger(struct irq_data *d) | static int aic_retrigger(struct irq_data *d) | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ aic5_handle(struct pt_regs *regs) | ||||||
| 	if (!irqstat) | 	if (!irqstat) | ||||||
| 		irq_reg_writel(bgc, 0, AT91_AIC5_EOICR); | 		irq_reg_writel(bgc, 0, AT91_AIC5_EOICR); | ||||||
| 	else | 	else | ||||||
| 		handle_domain_irq(aic5_domain, irqnr, regs); | 		generic_handle_domain_irq(aic5_domain, irqnr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void aic5_mask(struct irq_data *d) | static void aic5_mask(struct irq_data *d) | ||||||
|  |  | ||||||
|  | @ -246,7 +246,7 @@ static void __exception_irq_entry bcm2835_handle_irq( | ||||||
| 	u32 hwirq; | 	u32 hwirq; | ||||||
| 
 | 
 | ||||||
| 	while ((hwirq = get_next_armctrl_hwirq()) != ~0) | 	while ((hwirq = get_next_armctrl_hwirq()) != ~0) | ||||||
| 		handle_domain_irq(intc.domain, hwirq, regs); | 		generic_handle_domain_irq(intc.domain, hwirq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void bcm2836_chained_handle_irq(struct irq_desc *desc) | static void bcm2836_chained_handle_irq(struct irq_desc *desc) | ||||||
|  |  | ||||||
|  | @ -143,7 +143,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) | ||||||
| 	if (stat) { | 	if (stat) { | ||||||
| 		u32 hwirq = ffs(stat) - 1; | 		u32 hwirq = ffs(stat) - 1; | ||||||
| 
 | 
 | ||||||
| 		handle_domain_irq(intc.domain, hwirq, regs); | 		generic_handle_domain_irq(intc.domain, hwirq); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -77,14 +77,14 @@ static asmlinkage void __exception_irq_entry clps711x_irqh(struct pt_regs *regs) | ||||||
| 		irqstat = readw_relaxed(clps711x_intc->intmr[0]) & | 		irqstat = readw_relaxed(clps711x_intc->intmr[0]) & | ||||||
| 			  readw_relaxed(clps711x_intc->intsr[0]); | 			  readw_relaxed(clps711x_intc->intsr[0]); | ||||||
| 		if (irqstat) | 		if (irqstat) | ||||||
| 			handle_domain_irq(clps711x_intc->domain, | 			generic_handle_domain_irq(clps711x_intc->domain, | ||||||
| 					  fls(irqstat) - 1, regs); | 						  fls(irqstat) - 1); | ||||||
| 
 | 
 | ||||||
| 		irqstat = readw_relaxed(clps711x_intc->intmr[1]) & | 		irqstat = readw_relaxed(clps711x_intc->intmr[1]) & | ||||||
| 			  readw_relaxed(clps711x_intc->intsr[1]); | 			  readw_relaxed(clps711x_intc->intsr[1]); | ||||||
| 		if (irqstat) | 		if (irqstat) | ||||||
| 			handle_domain_irq(clps711x_intc->domain, | 			generic_handle_domain_irq(clps711x_intc->domain, | ||||||
| 					  fls(irqstat) - 1 + 16, regs); | 						  fls(irqstat) - 1 + 16); | ||||||
| 	} while (irqstat); | 	} while (irqstat); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -138,7 +138,7 @@ static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq, | ||||||
| 	if (hwirq == 0) | 	if (hwirq == 0) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	handle_domain_irq(root_domain, irq_base + __fls(hwirq), regs); | 	generic_handle_domain_irq(root_domain, irq_base + __fls(hwirq)); | ||||||
| 
 | 
 | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -74,8 +74,8 @@ static void csky_mpintc_handler(struct pt_regs *regs) | ||||||
| { | { | ||||||
| 	void __iomem *reg_base = this_cpu_read(intcl_reg); | 	void __iomem *reg_base = this_cpu_read(intcl_reg); | ||||||
| 
 | 
 | ||||||
| 	handle_domain_irq(root_domain, | 	generic_handle_domain_irq(root_domain, | ||||||
| 		readl_relaxed(reg_base + INTCL_RDYIR), regs); | 		readl_relaxed(reg_base + INTCL_RDYIR)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void csky_mpintc_enable(struct irq_data *d) | static void csky_mpintc_enable(struct irq_data *d) | ||||||
|  |  | ||||||
|  | @ -73,7 +73,7 @@ davinci_aintc_handle_irq(struct pt_regs *regs) | ||||||
| 	irqnr >>= 2; | 	irqnr >>= 2; | ||||||
| 	irqnr -= 1; | 	irqnr -= 1; | ||||||
| 
 | 
 | ||||||
| 	handle_domain_irq(davinci_aintc_irq_domain, irqnr, regs); | 	generic_handle_domain_irq(davinci_aintc_irq_domain, irqnr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ARM Interrupt Controller Initialization */ | /* ARM Interrupt Controller Initialization */ | ||||||
|  |  | ||||||
|  | @ -135,7 +135,7 @@ davinci_cp_intc_handle_irq(struct pt_regs *regs) | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	handle_domain_irq(davinci_cp_intc_irq_domain, irqnr, regs); | 	generic_handle_domain_irq(davinci_cp_intc_irq_domain, irqnr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int davinci_cp_intc_host_map(struct irq_domain *h, unsigned int virq, | static int davinci_cp_intc_host_map(struct irq_domain *h, unsigned int virq, | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs) | ||||||
| 				return; | 				return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		handle_domain_irq(digicolor_irq_domain, hwirq, regs); | 		generic_handle_domain_irq(digicolor_irq_domain, hwirq); | ||||||
| 	} while (1); | 	} while (1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ static void __irq_entry dw_apb_ictl_handle_irq(struct pt_regs *regs) | ||||||
| 		while (stat) { | 		while (stat) { | ||||||
| 			u32 hwirq = ffs(stat) - 1; | 			u32 hwirq = ffs(stat) - 1; | ||||||
| 
 | 
 | ||||||
| 			handle_domain_irq(d, hwirq, regs); | 			generic_handle_domain_irq(d, hwirq); | ||||||
| 			stat &= ~BIT(hwirq); | 			stat &= ~BIT(hwirq); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -134,7 +134,7 @@ asmlinkage void __exception_irq_entry ft010_irqchip_handle_irq(struct pt_regs *r | ||||||
| 
 | 
 | ||||||
| 	while ((status = readl(FT010_IRQ_STATUS(f->base)))) { | 	while ((status = readl(FT010_IRQ_STATUS(f->base)))) { | ||||||
| 		irq = ffs(status) - 1; | 		irq = ffs(status) - 1; | ||||||
| 		handle_domain_irq(f->domain, irq, regs); | 		generic_handle_domain_irq(f->domain, irq); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -660,7 +660,7 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) | ||||||
| 	 * PSR.I will be restored when we ERET to the | 	 * PSR.I will be restored when we ERET to the | ||||||
| 	 * interrupted context. | 	 * interrupted context. | ||||||
| 	 */ | 	 */ | ||||||
| 	err = handle_domain_nmi(gic_data.domain, irqnr, regs); | 	err = generic_handle_domain_nmi(gic_data.domain, irqnr); | ||||||
| 	if (err) | 	if (err) | ||||||
| 		gic_deactivate_unhandled(irqnr); | 		gic_deactivate_unhandled(irqnr); | ||||||
| 
 | 
 | ||||||
|  | @ -728,7 +728,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs | ||||||
| 	else | 	else | ||||||
| 		isb(); | 		isb(); | ||||||
| 
 | 
 | ||||||
| 	if (handle_domain_irq(gic_data.domain, irqnr, regs)) { | 	if (generic_handle_domain_irq(gic_data.domain, irqnr)) { | ||||||
| 		WARN_ONCE(true, "Unexpected interrupt received!\n"); | 		WARN_ONCE(true, "Unexpected interrupt received!\n"); | ||||||
| 		gic_deactivate_unhandled(irqnr); | 		gic_deactivate_unhandled(irqnr); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -369,7 +369,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | ||||||
| 			this_cpu_write(sgi_intid, irqstat); | 			this_cpu_write(sgi_intid, irqstat); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		handle_domain_irq(gic->domain, irqnr, regs); | 		generic_handle_domain_irq(gic->domain, irqnr); | ||||||
| 	} while (1); | 	} while (1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -206,7 +206,7 @@ static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs) | ||||||
| 		irqnr = irqstat & GICC_IAR_INT_ID_MASK; | 		irqnr = irqstat & GICC_IAR_INT_ID_MASK; | ||||||
| 
 | 
 | ||||||
| 		if (irqnr <= HIP04_MAX_IRQS) | 		if (irqnr <= HIP04_MAX_IRQS) | ||||||
| 			handle_domain_irq(hip04_data.domain, irqnr, regs); | 			generic_handle_domain_irq(hip04_data.domain, irqnr); | ||||||
| 	} while (irqnr > HIP04_MAX_IRQS); | 	} while (irqnr > HIP04_MAX_IRQS); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -114,7 +114,7 @@ asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	status = __raw_readl(ixi->irqbase + IXP4XX_ICIP); | 	status = __raw_readl(ixi->irqbase + IXP4XX_ICIP); | ||||||
| 	for_each_set_bit(i, &status, 32) | 	for_each_set_bit(i, &status, 32) | ||||||
| 		handle_domain_irq(ixi->domain, i, regs); | 		generic_handle_domain_irq(ixi->domain, i); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * IXP465/IXP435 has an upper IRQ status register | 	 * IXP465/IXP435 has an upper IRQ status register | ||||||
|  | @ -122,7 +122,7 @@ asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs) | ||||||
| 	if (ixi->is_356) { | 	if (ixi->is_356) { | ||||||
| 		status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2); | 		status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2); | ||||||
| 		for_each_set_bit(i, &status, 32) | 		for_each_set_bit(i, &status, 32) | ||||||
| 			handle_domain_irq(ixi->domain, i + 32, regs); | 			generic_handle_domain_irq(ixi->domain, i + 32); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -126,7 +126,7 @@ static void __exception_irq_entry lpc32xx_handle_irq(struct pt_regs *regs) | ||||||
| 	while (hwirq) { | 	while (hwirq) { | ||||||
| 		irq = __ffs(hwirq); | 		irq = __ffs(hwirq); | ||||||
| 		hwirq &= ~BIT(irq); | 		hwirq &= ~BIT(irq); | ||||||
| 		handle_domain_irq(lpc32xx_mic_irqc->domain, irq, regs); | 		generic_handle_domain_irq(lpc32xx_mic_irqc->domain, irq); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -230,7 +230,7 @@ static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs) | ||||||
| 	if (!(hwirq & SEL_INT_PENDING)) | 	if (!(hwirq & SEL_INT_PENDING)) | ||||||
| 		return; | 		return; | ||||||
| 	hwirq &= SEL_INT_NUM_MASK; | 	hwirq &= SEL_INT_NUM_MASK; | ||||||
| 	handle_domain_irq(icu_data[0].domain, hwirq, regs); | 	generic_handle_domain_irq(icu_data[0].domain, hwirq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs) | static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs) | ||||||
|  | @ -241,7 +241,7 @@ static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs) | ||||||
| 	if (!(hwirq & SEL_INT_PENDING)) | 	if (!(hwirq & SEL_INT_PENDING)) | ||||||
| 		return; | 		return; | ||||||
| 	hwirq &= SEL_INT_NUM_MASK; | 	hwirq &= SEL_INT_NUM_MASK; | ||||||
| 	handle_domain_irq(icu_data[0].domain, hwirq, regs); | 	generic_handle_domain_irq(icu_data[0].domain, hwirq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* MMP (ARMv5) */ | /* MMP (ARMv5) */ | ||||||
|  |  | ||||||
|  | @ -136,7 +136,7 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	irqnr = __raw_readl(icoll_priv.stat); | 	irqnr = __raw_readl(icoll_priv.stat); | ||||||
| 	__raw_writel(irqnr, icoll_priv.vector); | 	__raw_writel(irqnr, icoll_priv.vector); | ||||||
| 	handle_domain_irq(icoll_domain, irqnr, regs); | 	generic_handle_domain_irq(icoll_domain, irqnr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, | static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||||||
|  |  | ||||||
|  | @ -37,9 +37,9 @@ | ||||||
| 
 | 
 | ||||||
| static struct irq_domain *nvic_irq_domain; | static struct irq_domain *nvic_irq_domain; | ||||||
| 
 | 
 | ||||||
| static void __nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) | static void __nvic_handle_irq(irq_hw_number_t hwirq) | ||||||
| { | { | ||||||
| 	handle_domain_irq(nvic_irq_domain, hwirq, regs); | 	generic_handle_domain_irq(nvic_irq_domain, hwirq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -53,7 +53,7 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	irq_enter(); | 	irq_enter(); | ||||||
| 	old_regs = set_irq_regs(regs); | 	old_regs = set_irq_regs(regs); | ||||||
| 	__nvic_handle_irq(hwirq, regs); | 	__nvic_handle_irq(hwirq); | ||||||
| 	set_irq_regs(old_regs); | 	set_irq_regs(old_regs); | ||||||
| 	irq_exit(); | 	irq_exit(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -357,7 +357,7 @@ omap_intc_handle_irq(struct pt_regs *regs) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	irqnr &= ACTIVEIRQ_MASK; | 	irqnr &= ACTIVEIRQ_MASK; | ||||||
| 	handle_domain_irq(domain, irqnr, regs); | 	generic_handle_domain_irq(domain, irqnr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int __init intc_of_init(struct device_node *node, | static int __init intc_of_init(struct device_node *node, | ||||||
|  |  | ||||||
|  | @ -116,7 +116,7 @@ static void or1k_pic_handle_irq(struct pt_regs *regs) | ||||||
| 	int irq = -1; | 	int irq = -1; | ||||||
| 
 | 
 | ||||||
| 	while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) | 	while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) | ||||||
| 		handle_domain_irq(root_domain, irq, regs); | 		generic_handle_domain_irq(root_domain, irq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | ||||||
|  |  | ||||||
|  | @ -42,8 +42,8 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs) | ||||||
| 			gc->mask_cache; | 			gc->mask_cache; | ||||||
| 		while (stat) { | 		while (stat) { | ||||||
| 			u32 hwirq = __fls(stat); | 			u32 hwirq = __fls(stat); | ||||||
| 			handle_domain_irq(orion_irq_domain, | 			generic_handle_domain_irq(orion_irq_domain, | ||||||
| 					  gc->irq_base + hwirq, regs); | 						  gc->irq_base + hwirq); | ||||||
| 			stat &= ~(1 << hwirq); | 			stat &= ~(1 << hwirq); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ static void __exception_irq_entry rda_handle_irq(struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	while (stat) { | 	while (stat) { | ||||||
| 		hwirq = __fls(stat); | 		hwirq = __fls(stat); | ||||||
| 		handle_domain_irq(rda_irq_domain, hwirq, regs); | 		generic_handle_domain_irq(rda_irq_domain, hwirq); | ||||||
| 		stat &= ~BIT(hwirq); | 		stat &= ~BIT(hwirq); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs) | ||||||
| 		break; | 		break; | ||||||
| #endif | #endif | ||||||
| 	default: | 	default: | ||||||
| 		handle_domain_irq(intc_domain, cause, regs); | 		generic_handle_domain_irq(intc_domain, cause); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -140,8 +140,8 @@ sa1100_handle_irq(struct pt_regs *regs) | ||||||
| 		if (mask == 0) | 		if (mask == 0) | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		handle_domain_irq(sa1100_normal_irqdomain, | 		generic_handle_domain_irq(sa1100_normal_irqdomain, | ||||||
| 				ffs(mask) - 1, regs); | 					  ffs(mask) - 1); | ||||||
| 	} while (1); | 	} while (1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -195,7 +195,7 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	do { | 	do { | ||||||
| 		handle_domain_irq(irq_ic_data->irq_domain, hwirq, regs); | 		generic_handle_domain_irq(irq_ic_data->irq_domain, hwirq); | ||||||
| 		hwirq = readl(irq_ic_data->irq_base + | 		hwirq = readl(irq_ic_data->irq_base + | ||||||
| 				SUN4I_IRQ_VECTOR_REG) >> 2; | 				SUN4I_IRQ_VECTOR_REG) >> 2; | ||||||
| 	} while (hwirq != 0); | 	} while (hwirq != 0); | ||||||
|  |  | ||||||
|  | @ -105,7 +105,7 @@ static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	while ((status  = readl(f->base + IRQ_STATUS))) { | 	while ((status  = readl(f->base + IRQ_STATUS))) { | ||||||
| 		irq = ffs(status) - 1; | 		irq = ffs(status) - 1; | ||||||
| 		handle_domain_irq(f->domain, irq, regs); | 		generic_handle_domain_irq(f->domain, irq); | ||||||
| 		handled = 1; | 		handled = 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -208,7 +208,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { | 	while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { | ||||||
| 		irq = ffs(stat) - 1; | 		irq = ffs(stat) - 1; | ||||||
| 		handle_domain_irq(vic->domain, irq, regs); | 		generic_handle_domain_irq(vic->domain, irq); | ||||||
| 		handled = 1; | 		handled = 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -183,7 +183,7 @@ static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) | ||||||
| 				continue; | 				continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		handle_domain_irq(intc[i].domain, irqnr, regs); | 		generic_handle_domain_irq(intc[i].domain, irqnr); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ static void __exception_irq_entry wpcm450_aic_handle_irq(struct pt_regs *regs) | ||||||
| 	/* Read IPER to signal that nIRQ can be de-asserted */ | 	/* Read IPER to signal that nIRQ can be de-asserted */ | ||||||
| 	hwirq = readl(aic->regs + AIC_IPER) / 4; | 	hwirq = readl(aic->regs + AIC_IPER) / 4; | ||||||
| 
 | 
 | ||||||
| 	handle_domain_irq(aic->domain, hwirq, regs); | 	generic_handle_domain_irq(aic->domain, hwirq); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void wpcm450_aic_eoi(struct irq_data *d) | static void wpcm450_aic_eoi(struct irq_data *d) | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ static void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) | ||||||
| 
 | 
 | ||||||
| 	while (readl(zevio_irq_io + IO_STATUS)) { | 	while (readl(zevio_irq_io + IO_STATUS)) { | ||||||
| 		irqnr = readl(zevio_irq_io + IO_CURRENT); | 		irqnr = readl(zevio_irq_io + IO_CURRENT); | ||||||
| 		handle_domain_irq(zevio_irq_domain, irqnr, regs); | 		generic_handle_domain_irq(zevio_irq_domain, irqnr); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -168,14 +168,7 @@ int generic_handle_irq(unsigned int irq); | ||||||
|  * conversion failed. |  * conversion failed. | ||||||
|  */ |  */ | ||||||
| int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq); | int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq); | ||||||
| 
 | int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq); | ||||||
| #ifdef CONFIG_HANDLE_DOMAIN_IRQ |  | ||||||
| int handle_domain_irq(struct irq_domain *domain, |  | ||||||
| 		      unsigned int hwirq, struct pt_regs *regs); |  | ||||||
| 
 |  | ||||||
| int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, |  | ||||||
| 		      struct pt_regs *regs); |  | ||||||
| #endif |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /* Test to see if a driver has successfully requested an irq */ | /* Test to see if a driver has successfully requested an irq */ | ||||||
|  |  | ||||||
|  | @ -97,13 +97,6 @@ config GENERIC_MSI_IRQ_DOMAIN | ||||||
| config IRQ_MSI_IOMMU | config IRQ_MSI_IOMMU | ||||||
| 	bool | 	bool | ||||||
| 
 | 
 | ||||||
| config HANDLE_DOMAIN_IRQ |  | ||||||
| 	bool |  | ||||||
| 
 |  | ||||||
| # Legacy behaviour; architectures should call irq_{enter,exit}() themselves |  | ||||||
| config HANDLE_DOMAIN_IRQ_IRQENTRY |  | ||||||
| 	bool |  | ||||||
| 
 |  | ||||||
| config IRQ_TIMINGS | config IRQ_TIMINGS | ||||||
| 	bool | 	bool | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -651,7 +651,11 @@ int handle_irq_desc(struct irq_desc *desc) | ||||||
|  * generic_handle_irq - Invoke the handler for a particular irq |  * generic_handle_irq - Invoke the handler for a particular irq | ||||||
|  * @irq:	The irq number to handle |  * @irq:	The irq number to handle | ||||||
|  * |  * | ||||||
|  */ |  * Returns:	0 on success, or -EINVAL if conversion has failed | ||||||
|  |  * | ||||||
|  |  * 		This function must be called from an IRQ context with irq regs | ||||||
|  |  * 		initialized. | ||||||
|  |   */ | ||||||
| int generic_handle_irq(unsigned int irq) | int generic_handle_irq(unsigned int irq) | ||||||
| { | { | ||||||
| 	return handle_irq_desc(irq_to_desc(irq)); | 	return handle_irq_desc(irq_to_desc(irq)); | ||||||
|  | @ -661,77 +665,39 @@ EXPORT_SYMBOL_GPL(generic_handle_irq); | ||||||
| #ifdef CONFIG_IRQ_DOMAIN | #ifdef CONFIG_IRQ_DOMAIN | ||||||
| /**
 | /**
 | ||||||
|  * generic_handle_domain_irq - Invoke the handler for a HW irq belonging |  * generic_handle_domain_irq - Invoke the handler for a HW irq belonging | ||||||
|  *                             to a domain, usually for a non-root interrupt |  *                             to a domain. | ||||||
|  *                             controller |  | ||||||
|  * @domain:	The domain where to perform the lookup |  * @domain:	The domain where to perform the lookup | ||||||
|  * @hwirq:	The HW irq number to convert to a logical one |  * @hwirq:	The HW irq number to convert to a logical one | ||||||
|  * |  * | ||||||
|  * Returns:	0 on success, or -EINVAL if conversion has failed |  * Returns:	0 on success, or -EINVAL if conversion has failed | ||||||
|  * |  * | ||||||
|  |  * 		This function must be called from an IRQ context with irq regs | ||||||
|  |  * 		initialized. | ||||||
|  */ |  */ | ||||||
| int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq) | int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq) | ||||||
| { | { | ||||||
|  | 	WARN_ON_ONCE(!in_irq()); | ||||||
| 	return handle_irq_desc(irq_resolve_mapping(domain, hwirq)); | 	return handle_irq_desc(irq_resolve_mapping(domain, hwirq)); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(generic_handle_domain_irq); | EXPORT_SYMBOL_GPL(generic_handle_domain_irq); | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_HANDLE_DOMAIN_IRQ |  | ||||||
| /**
 | /**
 | ||||||
|  * handle_domain_irq - Invoke the handler for a HW irq belonging to a domain, |  * generic_handle_domain_nmi - Invoke the handler for a HW nmi belonging | ||||||
|  *                     usually for a root interrupt controller |  *                             to a domain. | ||||||
|  * @domain:	The domain where to perform the lookup |  * @domain:	The domain where to perform the lookup | ||||||
|  * @hwirq:	The HW irq number to convert to a logical one |  * @hwirq:	The HW irq number to convert to a logical one | ||||||
|  * @regs:	Register file coming from the low-level handling code |  | ||||||
|  * |  | ||||||
|  * 		This function must be called from an IRQ context. |  | ||||||
|  * |  * | ||||||
|  * Returns:	0 on success, or -EINVAL if conversion has failed |  * Returns:	0 on success, or -EINVAL if conversion has failed | ||||||
|  */ |  | ||||||
| int handle_domain_irq(struct irq_domain *domain, |  | ||||||
| 		      unsigned int hwirq, struct pt_regs *regs) |  | ||||||
| { |  | ||||||
| 	struct pt_regs *old_regs = set_irq_regs(regs); |  | ||||||
| 	int ret; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * IRQ context needs to be setup earlier. |  | ||||||
| 	 */ |  | ||||||
| 	WARN_ON(!in_irq()); |  | ||||||
| 
 |  | ||||||
| 	ret = generic_handle_domain_irq(domain, hwirq); |  | ||||||
| 
 |  | ||||||
| 	set_irq_regs(old_regs); |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain |  | ||||||
|  * @domain:	The domain where to perform the lookup |  | ||||||
|  * @hwirq:	The HW irq number to convert to a logical one |  | ||||||
|  * @regs:	Register file coming from the low-level handling code |  | ||||||
|  * |  * | ||||||
|  *		This function must be called from an NMI context. |  * 		This function must be called from an NMI context with irq regs | ||||||
|  * |  * 		initialized. | ||||||
|  * Returns:	0 on success, or -EINVAL if conversion has failed |  **/ | ||||||
|  */ | int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq) | ||||||
| int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, |  | ||||||
| 		      struct pt_regs *regs) |  | ||||||
| { | { | ||||||
| 	struct pt_regs *old_regs = set_irq_regs(regs); | 	WARN_ON_ONCE(!in_nmi()); | ||||||
| 	int ret; | 	return handle_irq_desc(irq_resolve_mapping(domain, hwirq)); | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * NMI context needs to be setup earlier in order to deal with tracing. |  | ||||||
| 	 */ |  | ||||||
| 	WARN_ON(!in_nmi()); |  | ||||||
| 
 |  | ||||||
| 	ret = generic_handle_domain_irq(domain, hwirq); |  | ||||||
| 
 |  | ||||||
| 	set_irq_regs(old_regs); |  | ||||||
| 	return ret; |  | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| /* Dynamic interrupt handling */ | /* Dynamic interrupt handling */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Mark Rutland
						Mark Rutland