linux-snps-arc.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/3] ARCv2: IDU-intc: Add support for edge-triggered interrupts
       [not found] <CY4PR1201MB0120EDD4173511912A9FC99EA1C60@CYPR1201MB0120.namprd12.prod.outlook.com>
@ 2019-07-24 12:04 ` Mischa Jonker
  2019-07-24 12:04   ` [PATCH v2 2/3] dt-bindings: IDU-intc: Clean up documentation Mischa Jonker
  2019-07-24 12:04   ` [PATCH v2 3/3] dt-bindings: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
  0 siblings, 2 replies; 5+ messages in thread
From: Mischa Jonker @ 2019-07-24 12:04 UTC (permalink / raw)
  To: linux-snps-arc

This adds support for an optional extra interrupt cell to specify edge
vs level triggered. It is backward compatible with dts files with only
one cell, and will default to level-triggered in such a case.

Note that I had to make a change to idu_irq_set_affinity as well, as
this function was setting the interrupt type to "level" unconditionally,
since this was the only type supported previously.

Signed-off-by: Mischa Jonker <mischa.jonker at synopsys.com>
---
 arch/arc/kernel/mcip.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-----
 include/soc/arc/mcip.h | 11 +++++++++
 2 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 18b493d..abf9398 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -202,8 +202,8 @@ static void idu_set_dest(unsigned int cmn_irq, unsigned int cpu_mask)
 	__mcip_cmd_data(CMD_IDU_SET_DEST, cmn_irq, cpu_mask);
 }
 
-static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl,
-			   unsigned int distr)
+static void idu_set_mode(unsigned int cmn_irq, bool set_lvl, unsigned int lvl,
+			 bool set_distr, unsigned int distr)
 {
 	union {
 		unsigned int word;
@@ -212,8 +212,11 @@ static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl,
 		};
 	} data;
 
-	data.distr = distr;
-	data.lvl = lvl;
+	data.word = __mcip_cmd_read(CMD_IDU_READ_MODE, cmn_irq);
+	if (set_distr)
+		data.distr = distr;
+	if (set_lvl)
+		data.lvl = lvl;
 	__mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word);
 }
 
@@ -240,6 +243,25 @@ static void idu_irq_unmask(struct irq_data *data)
 	raw_spin_unlock_irqrestore(&mcip_lock, flags);
 }
 
+static void idu_irq_ack(struct irq_data *data)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&mcip_lock, flags);
+	__mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq);
+	raw_spin_unlock_irqrestore(&mcip_lock, flags);
+}
+
+static void idu_irq_mask_ack(struct irq_data *data)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&mcip_lock, flags);
+	__mcip_cmd_data(CMD_IDU_SET_MASK, data->hwirq, 1);
+	__mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq);
+	raw_spin_unlock_irqrestore(&mcip_lock, flags);
+}
+
 static int
 idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
 		     bool force)
@@ -263,13 +285,36 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
 	else
 		distribution_mode = IDU_M_DISTRI_RR;
 
-	idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode);
+	idu_set_mode(data->hwirq, false, 0, true, distribution_mode);
 
 	raw_spin_unlock_irqrestore(&mcip_lock, flags);
 
 	return IRQ_SET_MASK_OK;
 }
 
+static int idu_irq_set_type(struct irq_data *data, u32 type)
+{
+	unsigned long flags;
+
+	/*
+	 * ARCv2 IDU HW does not support inverse polarity, so these are the
+	 * only interrupt types supported.
+	 */
+	if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&mcip_lock, flags);
+
+	idu_set_mode(data->hwirq, true,
+		     type & IRQ_TYPE_EDGE_RISING ? IDU_M_TRIG_EDGE :
+						   IDU_M_TRIG_LEVEL,
+		     false, 0);
+
+	raw_spin_unlock_irqrestore(&mcip_lock, flags);
+
+	return 0;
+}
+
 static void idu_irq_enable(struct irq_data *data)
 {
 	/*
@@ -289,7 +334,10 @@ static struct irq_chip idu_irq_chip = {
 	.name			= "MCIP IDU Intc",
 	.irq_mask		= idu_irq_mask,
 	.irq_unmask		= idu_irq_unmask,
+	.irq_ack		= idu_irq_ack,
+	.irq_mask_ack		= idu_irq_mask_ack,
 	.irq_enable		= idu_irq_enable,
+	.irq_set_type		= idu_irq_set_type,
 #ifdef CONFIG_SMP
 	.irq_set_affinity       = idu_irq_set_affinity,
 #endif
@@ -317,7 +365,7 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t
 }
 
 static const struct irq_domain_ops idu_irq_ops = {
-	.xlate	= irq_domain_xlate_onecell,
+	.xlate	= irq_domain_xlate_onetwocell,
 	.map	= idu_irq_map,
 };
 
diff --git a/include/soc/arc/mcip.h b/include/soc/arc/mcip.h
index 50f49e0..d1a93c7 100644
--- a/include/soc/arc/mcip.h
+++ b/include/soc/arc/mcip.h
@@ -46,7 +46,9 @@ struct mcip_cmd {
 #define CMD_IDU_ENABLE			0x71
 #define CMD_IDU_DISABLE			0x72
 #define CMD_IDU_SET_MODE		0x74
+#define CMD_IDU_READ_MODE		0x75
 #define CMD_IDU_SET_DEST		0x76
+#define CMD_IDU_ACK_CIRQ		0x79
 #define CMD_IDU_SET_MASK		0x7C
 
 #define IDU_M_TRIG_LEVEL		0x0
@@ -119,4 +121,13 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
 	__mcip_cmd(cmd, param);
 }
 
+/*
+ * Read MCIP register
+ */
+static inline unsigned int __mcip_cmd_read(unsigned int cmd, unsigned int param)
+{
+	__mcip_cmd(cmd, param);
+	return read_aux_reg(ARC_REG_MCIP_READBACK);
+}
+
 #endif
-- 
2.8.3

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

* [PATCH v2 2/3] dt-bindings: IDU-intc: Clean up documentation
  2019-07-24 12:04 ` [PATCH v2 1/3] ARCv2: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
@ 2019-07-24 12:04   ` Mischa Jonker
  2019-08-16 21:04     ` Rob Herring
  2019-07-24 12:04   ` [PATCH v2 3/3] dt-bindings: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
  1 sibling, 1 reply; 5+ messages in thread
From: Mischa Jonker @ 2019-07-24 12:04 UTC (permalink / raw)
  To: linux-snps-arc

* Some lines exceeded 80 characters.
* Clarified statement about AUX register interface

Signed-off-by: Mischa Jonker <mischa.jonker at synopsys.com>
---
 .../bindings/interrupt-controller/snps,archs-idu-intc.txt        | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
index 09fc02b..c5a1c7b 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
@@ -1,7 +1,8 @@
 * ARC-HS Interrupt Distribution Unit
 
-  This optional 2nd level interrupt controller can be used in SMP configurations for
-  dynamic IRQ routing, load balancing of common/external IRQs towards core intc.
+  This optional 2nd level interrupt controller can be used in SMP configurations
+  for dynamic IRQ routing, load balancing of common/external IRQs towards core
+  intc.
 
 Properties:
 
@@ -13,8 +14,8 @@ Properties:
   of the particular interrupt line of IDU corresponds to the line N+24 of the
   core interrupt controller.
 
-  intc accessed via the special ARC AUX register interface, hence "reg" property
-  is not specified.
+  The interrupt controller is accessed via the special ARC AUX register
+  interface, hence "reg" property is not specified.
 
 Example:
 	core_intc: core-interrupt-controller {
-- 
2.8.3

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

* [PATCH v2 3/3] dt-bindings: IDU-intc: Add support for edge-triggered interrupts
  2019-07-24 12:04 ` [PATCH v2 1/3] ARCv2: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
  2019-07-24 12:04   ` [PATCH v2 2/3] dt-bindings: IDU-intc: Clean up documentation Mischa Jonker
@ 2019-07-24 12:04   ` Mischa Jonker
  2019-08-16 21:05     ` Rob Herring
  1 sibling, 1 reply; 5+ messages in thread
From: Mischa Jonker @ 2019-07-24 12:04 UTC (permalink / raw)
  To: linux-snps-arc

This updates the documentation for supporting an optional extra interrupt
cell to specify edge vs level triggered.

Signed-off-by: Mischa Jonker <mischa.jonker at synopsys.com>
---
 .../interrupt-controller/snps,archs-idu-intc.txt      | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
index c5a1c7b..a5c1db9 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
@@ -8,11 +8,20 @@ Properties:
 
 - compatible: "snps,archs-idu-intc"
 - interrupt-controller: This is an interrupt controller.
-- #interrupt-cells: Must be <1>.
-
-  Value of the cell specifies the "common" IRQ from peripheral to IDU. Number N
-  of the particular interrupt line of IDU corresponds to the line N+24 of the
-  core interrupt controller.
+- #interrupt-cells: Must be <1> or <2>.
+
+  Value of the first cell specifies the "common" IRQ from peripheral to IDU.
+  Number N of the particular interrupt line of IDU corresponds to the line N+24
+  of the core interrupt controller.
+
+  The (optional) second cell specifies any of the following flags:
+    - bits[3:0] trigger type and level flags
+        1 = low-to-high edge triggered
+        2 = NOT SUPPORTED (high-to-low edge triggered)
+        4 = active high level-sensitive <<< DEFAULT
+        8 = NOT SUPPORTED (active low level-sensitive)
+  When no second cell is specified, the interrupt is assumed to be level
+  sensitive.
 
   The interrupt controller is accessed via the special ARC AUX register
   interface, hence "reg" property is not specified.
-- 
2.8.3

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

* [PATCH v2 2/3] dt-bindings: IDU-intc: Clean up documentation
  2019-07-24 12:04   ` [PATCH v2 2/3] dt-bindings: IDU-intc: Clean up documentation Mischa Jonker
@ 2019-08-16 21:04     ` Rob Herring
  0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2019-08-16 21:04 UTC (permalink / raw)
  To: linux-snps-arc

On Wed, 24 Jul 2019 14:04:35 +0200, Mischa Jonker wrote:
> * Some lines exceeded 80 characters.
> * Clarified statement about AUX register interface
> 
> Signed-off-by: Mischa Jonker <mischa.jonker at synopsys.com>
> ---
>  .../bindings/interrupt-controller/snps,archs-idu-intc.txt        | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>

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

* [PATCH v2 3/3] dt-bindings: IDU-intc: Add support for edge-triggered interrupts
  2019-07-24 12:04   ` [PATCH v2 3/3] dt-bindings: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
@ 2019-08-16 21:05     ` Rob Herring
  0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2019-08-16 21:05 UTC (permalink / raw)
  To: linux-snps-arc

On Wed, 24 Jul 2019 14:04:36 +0200, Mischa Jonker wrote:
> This updates the documentation for supporting an optional extra interrupt
> cell to specify edge vs level triggered.
> 
> Signed-off-by: Mischa Jonker <mischa.jonker at synopsys.com>
> ---
>  .../interrupt-controller/snps,archs-idu-intc.txt      | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>

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

end of thread, other threads:[~2019-08-16 21:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CY4PR1201MB0120EDD4173511912A9FC99EA1C60@CYPR1201MB0120.namprd12.prod.outlook.com>
2019-07-24 12:04 ` [PATCH v2 1/3] ARCv2: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
2019-07-24 12:04   ` [PATCH v2 2/3] dt-bindings: IDU-intc: Clean up documentation Mischa Jonker
2019-08-16 21:04     ` Rob Herring
2019-07-24 12:04   ` [PATCH v2 3/3] dt-bindings: IDU-intc: Add support for edge-triggered interrupts Mischa Jonker
2019-08-16 21:05     ` Rob Herring

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).