Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34e71e4c authored by Yuriy Kolerov's avatar Yuriy Kolerov Committed by Vineet Gupta
Browse files

ARC: IRQ: Do not use hwirq as virq and vice versa



This came up when reviewing code to address missing IRQ affinity
setting in AXS103 platform and/or implementing hierarchical IRQ domains

- smp_ipi_irq_setup() callers pass hwirq but in turn calls
  request_percpu_irq() which expects a linux virq. So invoke
  irq_find_mapping() to do the conversion
  (also explicitify this in code by renaming the args appropriately)

- idu_of_init()/idu_cascade_isr() were similarly using linux virq where
  hwirq is expected, so do the conversion using irqd_to_hwirq() helper

Signed-off-by: default avatarYuriy Kolerov <yuriy.kolerov@synopsys.com>
[vgupta: made changelog a bit concise a bit]
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 19dbc762
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void);
 * API expected BY platform smp code (FROM arch smp code)
 *
 * smp_ipi_irq_setup:
 *	Takes @cpu and @irq to which the arch-common ISR is hooked up
 *	Takes @cpu and @hwirq to which the arch-common ISR is hooked up
 */
extern int smp_ipi_irq_setup(int cpu, int irq);
extern int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq);

/*
 * struct plat_smp_ops	- SMP callbacks provided by platform to ARC SMP
+9 −10
Original line number Diff line number Diff line
@@ -207,16 +207,15 @@ static struct irq_chip idu_irq_chip = {

};

static int idu_first_irq;
static irq_hw_number_t idu_first_hwirq;

static void idu_cascade_isr(struct irq_desc *desc)
{
	struct irq_domain *domain = irq_desc_get_handler_data(desc);
	unsigned int core_irq = irq_desc_get_irq(desc);
	unsigned int idu_irq;
	struct irq_domain *idu_domain = irq_desc_get_handler_data(desc);
	irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc));
	irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq;

	idu_irq = core_irq - idu_first_irq;
	generic_handle_irq(irq_find_mapping(domain, idu_irq));
	generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
}

static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq)
@@ -282,7 +281,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
	struct irq_domain *domain;
	/* Read IDU BCR to confirm nr_irqs */
	int nr_irqs = of_irq_count(intc);
	int i, irq;
	int i, virq;
	struct mcip_bcr mp;

	READ_BCR(ARC_REG_MCIP_BCR, mp);
@@ -303,11 +302,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
		 * however we need it to get the parent virq and set IDU handler
		 * as first level isr
		 */
		irq = irq_of_parse_and_map(intc, i);
		virq = irq_of_parse_and_map(intc, i);
		if (!i)
			idu_first_irq = irq;
			idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq));

		irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain);
		irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain);
	}

	__mcip_cmd(CMD_IDU_ENABLE, 0);
+9 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/atomic.h>
#include <linux/cpumask.h>
#include <linux/reboot.h>
#include <linux/irqdomain.h>
#include <asm/processor.h>
#include <asm/setup.h>
#include <asm/mach_desc.h>
@@ -353,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id)
 */
static DEFINE_PER_CPU(int, ipi_dev);

int smp_ipi_irq_setup(int cpu, int irq)
int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq)
{
	int *dev = per_cpu_ptr(&ipi_dev, cpu);
	unsigned int virq = irq_find_mapping(NULL, hwirq);

	if (!virq)
		panic("Cannot find virq for root domain and hwirq=%lu", hwirq);

	/* Boot cpu calls request, all call enable */
	if (!cpu) {
		int rc;

		rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev);
		rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev);
		if (rc)
			panic("Percpu IRQ request failed for %d\n", irq);
			panic("Percpu IRQ request failed for %u\n", virq);
	}

	enable_percpu_irq(irq, 0);
	enable_percpu_irq(virq, 0);

	return 0;
}