linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem
@ 2016-11-08  7:08 Yuriy Kolerov
  2016-11-08  7:08 ` [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa Yuriy Kolerov
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Yuriy Kolerov @ 2016-11-08  7:08 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: Vineet.Gupta1, Alexey.Brodkin, tglx, linux-kernel, Yuriy Kolerov

The first patch fixes misuse of IRQ numbers. In some places of the
Linux kernel for ARC hardware IRQ numbers are used as virtual IRQ
numbers and obviously it is wrong.

The second patch forces the kernel to set a simple distribution mode
for common interrupts in cases when such interrupts are routed to a
single core.

Yuriy Kolerov (2):
  ARC: IRQ: Do not use hwirq as virq and vice versa
  ARCv2: MCIP: Use IDU_M_DISTRI_DEST mode if there is only 1 destination
    core

 arch/arc/include/asm/smp.h |  4 ++--
 arch/arc/kernel/mcip.c     | 33 ++++++++++++++++++++-------------
 arch/arc/kernel/smp.c      | 13 +++++++++----
 3 files changed, 31 insertions(+), 19 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa
  2016-11-08  7:08 [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Yuriy Kolerov
@ 2016-11-08  7:08 ` Yuriy Kolerov
  2016-11-08  7:20   ` Vineet Gupta
  2016-11-08 20:23   ` Vineet Gupta
  2016-11-08  7:08 ` [PATCH v4 2/2] ARCv2: MCIP: Use IDU_M_DISTRI_DEST mode if there is only 1 destination core Yuriy Kolerov
  2016-11-08 20:25 ` [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Vineet Gupta
  2 siblings, 2 replies; 7+ messages in thread
From: Yuriy Kolerov @ 2016-11-08  7:08 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: Vineet.Gupta1, Alexey.Brodkin, tglx, linux-kernel, Yuriy Kolerov

At first smp_ipi_irq_setup() takes a cpu number and a hwirq number for
the per core local interrupt line in the root interrupt controller and
registers an appropriate IPI handler per cpu. However this function tries
to bind a handler to the hwirq as virtual IRQ number and it is a wrong
behavior. It is necessary to find a mapping of hwirq in the root IRQ
domain to the actual virq using irq_find_mapping(). Also a declaration
of smp_ipi_irq_setup() is corrected to denote that this function takes
a hardware IRQ number but not a virtual IRQ number.

Also there is one more problem related to usage of IRQ numbers. Multicore
ARC configurations use IDU (Interrupt Distribution Unit) for distributing
of common interrupts. In fact IDU is a interrupt controller on top of
main per core interrupt controller.

All common IRQs are physically and linearly mapped to per core
interrupts. E.g. <0, 1, 2, 3> common IDU interrupts may be mapped to per
core <24, 25, 26, 27> interrupts. An initialization code of IDU
controller (idu_of_init()) creates mappings for all parent interrupts
<24, 25, ...> and sets a chained IDU handler for them. In the same
time idu_of_init() must save the first met parent hwirq (idu_first_irq)
thus in future it is possible to figure out what common hwirq has come
by subtracting of idu_first_irq from the current parent hwirq (see
idu_cascade_isr()).

The problem is that idu_of_init() and idu_cascade_isr() use parent virtual
IRQs as hardware IRQs and perform all the above-described manipulations
on virtual IRQs. But it is wrong and hardware IRQs must be used instead.

Signed-off-by: Yuriy Kolerov <yuriy.kolerov@synopsys.com>
---
 arch/arc/include/asm/smp.h |  4 ++--
 arch/arc/kernel/mcip.c     | 20 +++++++++-----------
 arch/arc/kernel/smp.c      | 13 +++++++++----
 3 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 89fdd1b..0861007 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -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
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 72f9179..4f4f04b 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -219,16 +219,14 @@ 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;
-
-	idu_irq = core_irq - idu_first_irq;
-	generic_handle_irq(irq_find_mapping(domain, 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;
+	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)
@@ -294,7 +292,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;
 
 	if (!idu_detected)
 		panic("IDU not detected, but DeviceTree using it");
@@ -312,11 +310,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);
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index f183cc6..692ca51 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -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>
@@ -351,20 +352,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;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 2/2] ARCv2: MCIP: Use IDU_M_DISTRI_DEST mode if there is only 1 destination core
  2016-11-08  7:08 [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Yuriy Kolerov
  2016-11-08  7:08 ` [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa Yuriy Kolerov
@ 2016-11-08  7:08 ` Yuriy Kolerov
  2016-11-08 20:25 ` [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Vineet Gupta
  2 siblings, 0 replies; 7+ messages in thread
From: Yuriy Kolerov @ 2016-11-08  7:08 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: Vineet.Gupta1, Alexey.Brodkin, tglx, linux-kernel, Yuriy Kolerov

ARC linux uses 2 distribution modes for common interrupts: round robin
mode (IDU_M_DISTRI_RR) and a simple destination mode (IDU_M_DISTRI_DEST).
The first one is used when more than 1 cores may handle a common interrupt
and the second one is used when only 1 core may handle a common interrupt.

However idu_irq_set_affinity() always sets IDU_M_DISTRI_RR for all affinity
values. But there is no sense in setting of such mode if only 1 core must
handle a common interrupt.

Signed-off-by: Yuriy Kolerov <yuriy.kolerov@synopsys.com>
---
 arch/arc/kernel/mcip.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 4f4f04b..90f9934 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -193,6 +193,8 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
 {
 	unsigned long flags;
 	cpumask_t online;
+	unsigned int destination_bits;
+	unsigned int distribution_mode;
 
 	/* errout if no online cpu per @cpumask */
 	if (!cpumask_and(&online, cpumask, cpu_online_mask))
@@ -200,8 +202,15 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
 
 	raw_spin_lock_irqsave(&mcip_lock, flags);
 
-	idu_set_dest(data->hwirq, cpumask_bits(&online)[0]);
-	idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR);
+	destination_bits = cpumask_bits(&online)[0];
+	idu_set_dest(data->hwirq, destination_bits);
+
+	if (ffs(destination_bits) == fls(destination_bits))
+		distribution_mode = IDU_M_DISTRI_DEST;
+	else
+		distribution_mode = IDU_M_DISTRI_RR;
+
+	idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode);
 
 	raw_spin_unlock_irqrestore(&mcip_lock, flags);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa
  2016-11-08  7:08 ` [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa Yuriy Kolerov
@ 2016-11-08  7:20   ` Vineet Gupta
  2016-11-08  9:30     ` Noam Camus
  2016-11-08 20:23   ` Vineet Gupta
  1 sibling, 1 reply; 7+ messages in thread
From: Vineet Gupta @ 2016-11-08  7:20 UTC (permalink / raw)
  To: Noam Camus; +Cc: Yuriy Kolerov, linux-snps-arc, Alexey.Brodkin, linux-kernel

Hi Noam,

I'm planning to merge this valid patch. Please look at arc mailing list for more
context !

Can you please check if this doesn't break ur platform and/or requires a fixup.

Thx,
-Vineet


On 11/07/2016 11:08 PM, Yuriy Kolerov wrote:
> At first smp_ipi_irq_setup() takes a cpu number and a hwirq number for
> the per core local interrupt line in the root interrupt controller and
> registers an appropriate IPI handler per cpu. However this function tries
> to bind a handler to the hwirq as virtual IRQ number and it is a wrong
> behavior. It is necessary to find a mapping of hwirq in the root IRQ
> domain to the actual virq using irq_find_mapping(). Also a declaration
> of smp_ipi_irq_setup() is corrected to denote that this function takes
> a hardware IRQ number but not a virtual IRQ number.
> 
> Also there is one more problem related to usage of IRQ numbers. Multicore
> ARC configurations use IDU (Interrupt Distribution Unit) for distributing
> of common interrupts. In fact IDU is a interrupt controller on top of
> main per core interrupt controller.
> 
> All common IRQs are physically and linearly mapped to per core
> interrupts. E.g. <0, 1, 2, 3> common IDU interrupts may be mapped to per
> core <24, 25, 26, 27> interrupts. An initialization code of IDU
> controller (idu_of_init()) creates mappings for all parent interrupts
> <24, 25, ...> and sets a chained IDU handler for them. In the same
> time idu_of_init() must save the first met parent hwirq (idu_first_irq)
> thus in future it is possible to figure out what common hwirq has come
> by subtracting of idu_first_irq from the current parent hwirq (see
> idu_cascade_isr()).
> 
> The problem is that idu_of_init() and idu_cascade_isr() use parent virtual
> IRQs as hardware IRQs and perform all the above-described manipulations
> on virtual IRQs. But it is wrong and hardware IRQs must be used instead.
> 
> Signed-off-by: Yuriy Kolerov <yuriy.kolerov@synopsys.com>
> ---
>  arch/arc/include/asm/smp.h |  4 ++--
>  arch/arc/kernel/mcip.c     | 20 +++++++++-----------
>  arch/arc/kernel/smp.c      | 13 +++++++++----
>  3 files changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 89fdd1b..0861007 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -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
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index 72f9179..4f4f04b 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -219,16 +219,14 @@ 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;
> -
> -	idu_irq = core_irq - idu_first_irq;
> -	generic_handle_irq(irq_find_mapping(domain, 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;
> +	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)
> @@ -294,7 +292,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;
>  
>  	if (!idu_detected)
>  		panic("IDU not detected, but DeviceTree using it");
> @@ -312,11 +310,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);
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index f183cc6..692ca51 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -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>
> @@ -351,20 +352,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;
>  }
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa
  2016-11-08  7:20   ` Vineet Gupta
@ 2016-11-08  9:30     ` Noam Camus
  0 siblings, 0 replies; 7+ messages in thread
From: Noam Camus @ 2016-11-08  9:30 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: Yuriy Kolerov, linux-snps-arc, Alexey.Brodkin, linux-kernel

> From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
> Sent: Tuesday, November 8, 2016 9:21 AM

>I'm planning to merge this valid patch. Please look at arc mailing list for more context !

>Can you please check if this doesn't break ur platform and/or requires a fixup.
Ack by me

-Noam 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa
  2016-11-08  7:08 ` [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa Yuriy Kolerov
  2016-11-08  7:20   ` Vineet Gupta
@ 2016-11-08 20:23   ` Vineet Gupta
  1 sibling, 0 replies; 7+ messages in thread
From: Vineet Gupta @ 2016-11-08 20:23 UTC (permalink / raw)
  To: Yuriy Kolerov, linux-snps-arc; +Cc: Alexey.Brodkin, tglx, linux-kernel

On 11/07/2016 11:08 PM, Yuriy Kolerov wrote:
> At first smp_ipi_irq_setup() takes a cpu number and a hwirq number for
> the per core local interrupt line in the root interrupt controller and
> registers an appropriate IPI handler per cpu. However this function tries
> to bind a handler to the hwirq as virtual IRQ number and it is a wrong
> behavior. It is necessary to find a mapping of hwirq in the root IRQ
> domain to the actual virq using irq_find_mapping(). Also a declaration
> of smp_ipi_irq_setup() is corrected to denote that this function takes
> a hardware IRQ number but not a virtual IRQ number.
>
> Also there is one more problem related to usage of IRQ numbers. Multicore
> ARC configurations use IDU (Interrupt Distribution Unit) for distributing
> of common interrupts. In fact IDU is a interrupt controller on top of
> main per core interrupt controller.
>
> All common IRQs are physically and linearly mapped to per core
> interrupts. E.g. <0, 1, 2, 3> common IDU interrupts may be mapped to per
> core <24, 25, 26, 27> interrupts. An initialization code of IDU
> controller (idu_of_init()) creates mappings for all parent interrupts
> <24, 25, ...> and sets a chained IDU handler for them. In the same
> time idu_of_init() must save the first met parent hwirq (idu_first_irq)
> thus in future it is possible to figure out what common hwirq has come
> by subtracting of idu_first_irq from the current parent hwirq (see
> idu_cascade_isr()).
>
> The problem is that idu_of_init() and idu_cascade_isr() use parent virtual
> IRQs as hardware IRQs and perform all the above-described manipulations
> on virtual IRQs. But it is wrong and hardware IRQs must be used instead.

I rephrased the changelog to below

---->
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: Yuriy Kolerov <yuriy.kolerov@synopsys.com>
> ---
>  arch/arc/include/asm/smp.h |  4 ++--
>  arch/arc/kernel/mcip.c     | 20 +++++++++-----------
>  arch/arc/kernel/smp.c      | 13 +++++++++----
>  3 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 89fdd1b..0861007 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -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
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index 72f9179..4f4f04b 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -219,16 +219,14 @@ 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;
> -
> -	idu_irq = core_irq - idu_first_irq;
> -	generic_handle_irq(irq_find_mapping(domain, 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;
> +	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)
> @@ -294,7 +292,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;
>  
>  	if (!idu_detected)
>  		panic("IDU not detected, but DeviceTree using it");
> @@ -312,11 +310,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);
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index f183cc6..692ca51 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -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>
> @@ -351,20 +352,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;
>  }

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem
  2016-11-08  7:08 [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Yuriy Kolerov
  2016-11-08  7:08 ` [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa Yuriy Kolerov
  2016-11-08  7:08 ` [PATCH v4 2/2] ARCv2: MCIP: Use IDU_M_DISTRI_DEST mode if there is only 1 destination core Yuriy Kolerov
@ 2016-11-08 20:25 ` Vineet Gupta
  2 siblings, 0 replies; 7+ messages in thread
From: Vineet Gupta @ 2016-11-08 20:25 UTC (permalink / raw)
  To: Yuriy Kolerov, linux-snps-arc; +Cc: Alexey.Brodkin, tglx, linux-kernel

On 11/07/2016 11:08 PM, Yuriy Kolerov wrote:
> The first patch fixes misuse of IRQ numbers. In some places of the
> Linux kernel for ARC hardware IRQ numbers are used as virtual IRQ
> numbers and obviously it is wrong.
>
> The second patch forces the kernel to set a simple distribution mode
> for common interrupts in cases when such interrupts are routed to a
> single core.
>
> Yuriy Kolerov (2):
>   ARC: IRQ: Do not use hwirq as virq and vice versa
>   ARCv2: MCIP: Use IDU_M_DISTRI_DEST mode if there is only 1 destination
>     core
>
>  arch/arc/include/asm/smp.h |  4 ++--
>  arch/arc/kernel/mcip.c     | 33 ++++++++++++++++++++-------------
>  arch/arc/kernel/smp.c      | 13 +++++++++----
>  3 files changed, 31 insertions(+), 19 deletions(-)

Thx Yuriy.

Added to for-curr !

-Vineet

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-11-08 20:25 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-08  7:08 [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Yuriy Kolerov
2016-11-08  7:08 ` [PATCH v4 1/2] ARC: IRQ: Do not use hwirq as virq and vice versa Yuriy Kolerov
2016-11-08  7:20   ` Vineet Gupta
2016-11-08  9:30     ` Noam Camus
2016-11-08 20:23   ` Vineet Gupta
2016-11-08  7:08 ` [PATCH v4 2/2] ARCv2: MCIP: Use IDU_M_DISTRI_DEST mode if there is only 1 destination core Yuriy Kolerov
2016-11-08 20:25 ` [PATCH v4 0/2] ARC: Set of patches for IRQ subsystem Vineet Gupta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).