mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-03 18:20:25 +02:00 
			
		
		
		
	ARC: [SMP] unify cpu private IRQ requests (TIMER/IPI)
The current cpu-private IRQ registration is ugly as it requires need to expose arch_unmask_irq() outside of intc code. So switch to percpu IRQ APIs: -request_percpu_irq [boot core] -enable_percpu_irq [all cores] Encapsulated in helper arc_request_percpu_irq() Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
		
							parent
							
								
									4c834452aa
								
							
						
					
					
						commit
						2b75c0f93e
					
				
					 4 changed files with 37 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -16,9 +16,13 @@
 | 
			
		|||
#define TIMER0_IRQ      3
 | 
			
		||||
#define TIMER1_IRQ      4
 | 
			
		||||
 | 
			
		||||
#include <linux/interrupt.h>
 | 
			
		||||
#include <asm-generic/irq.h>
 | 
			
		||||
 | 
			
		||||
extern void arc_init_IRQ(void);
 | 
			
		||||
void arc_local_timer_setup(void);
 | 
			
		||||
void arc_request_percpu_irq(int irq, int cpu,
 | 
			
		||||
                            irqreturn_t (*isr)(int irq, void *dev),
 | 
			
		||||
                            const char *irq_nm, void *percpu_dev);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,32 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
 | 
			
		|||
	set_irq_regs(old_regs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void arc_request_percpu_irq(int irq, int cpu,
 | 
			
		||||
                            irqreturn_t (*isr)(int irq, void *dev),
 | 
			
		||||
                            const char *irq_nm,
 | 
			
		||||
                            void *percpu_dev)
 | 
			
		||||
{
 | 
			
		||||
	/* Boot cpu calls request, all call enable */
 | 
			
		||||
	if (!cpu) {
 | 
			
		||||
		int rc;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * These 2 calls are essential to making percpu IRQ APIs work
 | 
			
		||||
		 * Ideally these details could be hidden in irq chip map function
 | 
			
		||||
		 * but the issue is IPIs IRQs being static (non-DT) and platform
 | 
			
		||||
		 * specific, so we can't identify them there.
 | 
			
		||||
		 */
 | 
			
		||||
		irq_set_percpu_devid(irq);
 | 
			
		||||
		irq_modify_status(irq, IRQ_NOAUTOEN, 0);  /* @irq, @clr, @set */
 | 
			
		||||
 | 
			
		||||
		rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
 | 
			
		||||
		if (rc)
 | 
			
		||||
			panic("Percpu IRQ request failed for %d\n", irq);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	enable_percpu_irq(irq, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * arch_local_irq_enable - Enable interrupts.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ void start_kernel_secondary(void)
 | 
			
		|||
	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 | 
			
		||||
 | 
			
		||||
	if (machine_desc->init_smp)
 | 
			
		||||
		machine_desc->init_smp(smp_processor_id());
 | 
			
		||||
		machine_desc->init_smp(cpu);
 | 
			
		||||
 | 
			
		||||
	arc_local_timer_setup();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -338,18 +338,11 @@ irqreturn_t do_IPI(int irq, void *dev_id)
 | 
			
		|||
 */
 | 
			
		||||
static DEFINE_PER_CPU(int, ipi_dev);
 | 
			
		||||
 | 
			
		||||
static struct irqaction arc_ipi_irq = {
 | 
			
		||||
        .name    = "IPI Interrupt",
 | 
			
		||||
        .flags   = IRQF_PERCPU,
 | 
			
		||||
        .handler = do_IPI,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int smp_ipi_irq_setup(int cpu, int irq)
 | 
			
		||||
{
 | 
			
		||||
	if (!cpu)
 | 
			
		||||
		return setup_irq(irq, &arc_ipi_irq);
 | 
			
		||||
	else
 | 
			
		||||
		arch_unmask_irq(irq);
 | 
			
		||||
	int *dev = per_cpu_ptr(&ipi_dev, cpu);
 | 
			
		||||
 | 
			
		||||
	arc_request_percpu_irq(irq, cpu, do_IPI, "IPI Interrupt", dev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -210,12 +210,6 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
 | 
			
		|||
	return IRQ_HANDLED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct irqaction arc_timer_irq = {
 | 
			
		||||
	.name    = "Timer0 (clock-evt-dev)",
 | 
			
		||||
	.flags   = IRQF_TIMER | IRQF_PERCPU,
 | 
			
		||||
	.handler = timer_irq_handler,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the local event timer for @cpu
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -228,15 +222,9 @@ void arc_local_timer_setup()
 | 
			
		|||
	clockevents_config_and_register(evt, arc_get_core_freq(),
 | 
			
		||||
					0, ARC_TIMER_MAX);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * setup the per-cpu timer IRQ handler - for all cpus
 | 
			
		||||
	 * For non boot CPU explicitly unmask at intc
 | 
			
		||||
	 * setup_irq() -> .. -> irq_startup() already does this on boot-cpu
 | 
			
		||||
	 */
 | 
			
		||||
	if (!cpu)
 | 
			
		||||
		setup_irq(TIMER0_IRQ, &arc_timer_irq);
 | 
			
		||||
	else
 | 
			
		||||
		arch_unmask_irq(TIMER0_IRQ);
 | 
			
		||||
	/* setup the per-cpu timer IRQ handler - for all cpus */
 | 
			
		||||
	arc_request_percpu_irq(TIMER0_IRQ, cpu, timer_irq_handler,
 | 
			
		||||
			       "Timer0 (per-cpu-tick)", evt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue