[PATCH 1/5] ARM: gic: Add hooks for architecture specific extensions

Colin Cross ccross at android.com
Tue Jan 25 15:54:55 EST 2011


On Mon, Jan 24, 2011 at 7:03 PM, Colin Cross <ccross at android.com> wrote:
> On Mon, Jan 24, 2011 at 12:51 AM, Santosh Shilimkar
> <santosh.shilimkar at ti.com> wrote:
>> Few architectures combine the GIC with an external interrupt controller.
>> On such systems it may be necessary to update both the GIC registers
>> and the external controller's registers to control IRQ behavior.
>>
>> This can be addressed in couple of possible methods.
>>  1.     Export common GIC routines along with 'struct irq_chip gic_chip'
>>        and allow architectures to have custom function by override.
>>
>>  2.     Provide architecture specific function pointer hooks
>>        within GIC library and leave platforms to add the necessary
>>        code as part of these hooks.
>>
>> First one might be non-intrusive but have few shortcomings like arch needs
>> to have there own custom gic library. Locks used should be common since it
>> caters to same IRQs etc. Maintenance point of view also it leads to
>> multiple file fixes.
>>
>> The second probably is cleaner and portable. It ensures that all the
>> common GIC infrastructure is not touched and also provides archs to
>> address their specific issue.
>
> This method would work for most of Tegra's needs, although we would
> need gic_set_type and gic_ack_irq to have arch extensions as well.
> However, it does not allow for irq_retrigger, which can be implemented
> on Tegra.

irq_retrigger does work with this method, the core IRQ code checks for
a return value if the retrigger was successful.  Tegra works with your
patch along with these changes:

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 0b6c043..7993f07 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -90,6 +90,8 @@ static inline unsigned int gic_irq(struct irq_data *d)
 static void gic_ack_irq(struct irq_data *d)
 {
 	spin_lock(&irq_controller_lock);
+	if (gic_arch_extn.irq_ack)
+		gic_arch_extn.irq_ack(d);
 	writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
 	spin_unlock(&irq_controller_lock);
 }
@@ -161,6 +163,14 @@ static int gic_set_type(struct irq_data *d,
unsigned int type)
 	return 0;
 }

+static int gic_retrigger(struct irq_data *d)
+{
+	if (gic_arch_extn.irq_retrigger)
+		return gic_arch_extn.irq_retrigger(d);
+
+	return 0;
+}
+
 #ifdef CONFIG_SMP
 static int
 gic_set_cpu(struct irq_data *d, const struct cpumask *mask_val, bool force)
@@ -234,6 +244,7 @@ static struct irq_chip gic_chip = {
 	.irq_mask		= gic_mask_irq,
 	.irq_unmask		= gic_unmask_irq,
 	.irq_set_type		= gic_set_type,
+	.irq_retrigger		= gic_retrigger,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= gic_set_cpu,
 #endif



More information about the linux-arm-kernel mailing list