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

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
...@@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void); ...@@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void);
* API expected BY platform smp code (FROM arch smp code) * API expected BY platform smp code (FROM arch smp code)
* *
* smp_ipi_irq_setup: * 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 * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP
......
...@@ -207,16 +207,15 @@ static struct irq_chip idu_irq_chip = { ...@@ -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) static void idu_cascade_isr(struct irq_desc *desc)
{ {
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *idu_domain = irq_desc_get_handler_data(desc);
unsigned int core_irq = irq_desc_get_irq(desc); irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc));
unsigned int idu_irq; irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq;
idu_irq = core_irq - idu_first_irq; generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
generic_handle_irq(irq_find_mapping(domain, idu_irq));
} }
static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t 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) ...@@ -282,7 +281,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
struct irq_domain *domain; struct irq_domain *domain;
/* Read IDU BCR to confirm nr_irqs */ /* Read IDU BCR to confirm nr_irqs */
int nr_irqs = of_irq_count(intc); int nr_irqs = of_irq_count(intc);
int i, irq; int i, virq;
struct mcip_bcr mp; struct mcip_bcr mp;
READ_BCR(ARC_REG_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) ...@@ -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 * however we need it to get the parent virq and set IDU handler
* as first level isr * as first level isr
*/ */
irq = irq_of_parse_and_map(intc, i); virq = irq_of_parse_and_map(intc, i);
if (!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); __mcip_cmd(CMD_IDU_ENABLE, 0);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/irqdomain.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach_desc.h> #include <asm/mach_desc.h>
...@@ -353,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id) ...@@ -353,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id)
*/ */
static DEFINE_PER_CPU(int, ipi_dev); 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); 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 */ /* Boot cpu calls request, all call enable */
if (!cpu) { if (!cpu) {
int rc; int rc;
rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev); rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev);
if (rc) 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; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment