diff mbox

[v6,04/12] irqchip: vf610-mscm: support NVIC parent

Message ID 1431203982-13217-5-git-send-email-stefan@agner.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Agner May 9, 2015, 8:39 p.m. UTC
Support the NVIC interrupt controller as node parent of the MSCM
interrupt router. On the dual-core variants of Vybird (VF6xx), the
NVIC interrupt controller is used by the Cortex-M4. To support
running Linux on this core too, MSCM needs NVIC parent support too.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/irqchip/irq-vf610-mscm-ir.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

Comments

Thomas Gleixner May 15, 2015, 10:39 a.m. UTC | #1
On Sat, 9 May 2015, Stefan Agner wrote:
> -	irq_chip_unmask_parent(data);
> +	if (parent->chip->irq_enable)
> +		parent->chip->irq_enable(parent);
> +	else
> +		parent->chip->irq_unmask(parent);

Why are you not creating irq_chip_enable_parent() which would have
been the proper function anyway?

Thanks,

	tglx
Stefan Agner May 15, 2015, 4:01 p.m. UTC | #2
On 2015-05-15 12:39, Thomas Gleixner wrote:
> On Sat, 9 May 2015, Stefan Agner wrote:
>> -	irq_chip_unmask_parent(data);
>> +	if (parent->chip->irq_enable)
>> +		parent->chip->irq_enable(parent);
>> +	else
>> +		parent->chip->irq_unmask(parent);
> 
> Why are you not creating irq_chip_enable_parent() which would have
> been the proper function anyway?
> 

Will add that...

Btw, have you had a chance to look at 1/12? I added a helper there too
to allow make use of generic chip with IRQ domain hierarchy. In case you
are fine with that general appraoch I will send an updated version of
the patchset with the irq_chip_enable_parent helper soon. 

--
Stefan
Thomas Gleixner May 15, 2015, 8:29 p.m. UTC | #3
On Fri, 15 May 2015, Stefan Agner wrote:

> On 2015-05-15 12:39, Thomas Gleixner wrote:
> > On Sat, 9 May 2015, Stefan Agner wrote:
> >> -	irq_chip_unmask_parent(data);
> >> +	if (parent->chip->irq_enable)
> >> +		parent->chip->irq_enable(parent);
> >> +	else
> >> +		parent->chip->irq_unmask(parent);
> > 
> > Why are you not creating irq_chip_enable_parent() which would have
> > been the proper function anyway?
> > 
> 
> Will add that...
> 
> Btw, have you had a chance to look at 1/12? I added a helper there too

Yes 1/12 is fine ...
diff mbox

Patch

diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c
index 9521057..40b7d8d 100644
--- a/drivers/irqchip/irq-vf610-mscm-ir.c
+++ b/drivers/irqchip/irq-vf610-mscm-ir.c
@@ -47,6 +47,7 @@  struct vf610_mscm_ir_chip_data {
 	void __iomem *mscm_ir_base;
 	u16 cpu_mask;
 	u16 saved_irsprc[MSCM_IRSPRC_NUM];
+	bool is_nvic;
 };
 
 static struct vf610_mscm_ir_chip_data *mscm_ir_data;
@@ -91,6 +92,7 @@  static void vf610_mscm_ir_enable(struct irq_data *data)
 {
 	irq_hw_number_t hwirq = data->hwirq;
 	struct vf610_mscm_ir_chip_data *chip_data = data->chip_data;
+	struct irq_data *parent = data->parent_data;
 	u16 irsprc;
 
 	irsprc = readw_relaxed(chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
@@ -101,17 +103,25 @@  static void vf610_mscm_ir_enable(struct irq_data *data)
 	writew_relaxed(chip_data->cpu_mask,
 		       chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
 
-	irq_chip_unmask_parent(data);
+	if (parent->chip->irq_enable)
+		parent->chip->irq_enable(parent);
+	else
+		parent->chip->irq_unmask(parent);
+
 }
 
 static void vf610_mscm_ir_disable(struct irq_data *data)
 {
 	irq_hw_number_t hwirq = data->hwirq;
 	struct vf610_mscm_ir_chip_data *chip_data = data->chip_data;
+	struct irq_data *parent = data->parent_data;
 
 	writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
 
-	irq_chip_mask_parent(data);
+	if (parent->chip->irq_disable)
+		parent->chip->irq_disable(parent);
+	else
+		parent->chip->irq_mask(parent);
 }
 
 static struct irq_chip vf610_mscm_ir_irq_chip = {
@@ -143,10 +153,17 @@  static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi
 					      domain->host_data);
 
 	gic_data.np = domain->parent->of_node;
-	gic_data.args_count = 3;
-	gic_data.args[0] = GIC_SPI;
-	gic_data.args[1] = irq_data->args[0];
-	gic_data.args[2] = irq_data->args[1];
+
+	if (mscm_ir_data->is_nvic) {
+		gic_data.args_count = 1;
+		gic_data.args[0] = irq_data->args[0];
+	} else {
+		gic_data.args_count = 3;
+		gic_data.args[0] = GIC_SPI;
+		gic_data.args[1] = irq_data->args[0];
+		gic_data.args[2] = irq_data->args[1];
+	}
+
 	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
 }
 
@@ -199,6 +216,9 @@  static int __init vf610_mscm_ir_of_init(struct device_node *node,
 		goto out_unmap;
 	}
 
+	if (of_device_is_compatible(domain->parent->of_node, "arm,armv7m-nvic"))
+		mscm_ir_data->is_nvic = true;
+
 	cpu_pm_register_notifier(&mscm_ir_notifier_block);
 
 	return 0;