Commit 5c0c1f08 authored by Rabin Vincent's avatar Rabin Vincent Committed by Russell King

ARM: 6150/1: gic: implement set_type

Implement set_type() to allow configuration of the trigger type.

Cc: Abhijeet Dharmapurikar <adharmap@quicinc.com>
Acked-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarRabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 7e27d6e7
...@@ -108,6 +108,51 @@ static void gic_unmask_irq(unsigned int irq) ...@@ -108,6 +108,51 @@ static void gic_unmask_irq(unsigned int irq)
spin_unlock(&irq_controller_lock); spin_unlock(&irq_controller_lock);
} }
static int gic_set_type(unsigned int irq, unsigned int type)
{
void __iomem *base = gic_dist_base(irq);
unsigned int gicirq = gic_irq(irq);
u32 enablemask = 1 << (gicirq % 32);
u32 enableoff = (gicirq / 32) * 4;
u32 confmask = 0x2 << ((gicirq % 16) * 2);
u32 confoff = (gicirq / 16) * 4;
bool enabled = false;
u32 val;
/* Interrupt configuration for SGIs can't be changed */
if (gicirq < 16)
return -EINVAL;
if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
return -EINVAL;
spin_lock(&irq_controller_lock);
val = readl(base + GIC_DIST_CONFIG + confoff);
if (type == IRQ_TYPE_LEVEL_HIGH)
val &= ~confmask;
else if (type == IRQ_TYPE_EDGE_RISING)
val |= confmask;
/*
* As recommended by the spec, disable the interrupt before changing
* the configuration
*/
if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
enabled = true;
}
writel(val, base + GIC_DIST_CONFIG + confoff);
if (enabled)
writel(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
spin_unlock(&irq_controller_lock);
return 0;
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val) static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
{ {
...@@ -161,6 +206,7 @@ static struct irq_chip gic_chip = { ...@@ -161,6 +206,7 @@ static struct irq_chip gic_chip = {
.ack = gic_ack_irq, .ack = gic_ack_irq,
.mask = gic_mask_irq, .mask = gic_mask_irq,
.unmask = gic_unmask_irq, .unmask = gic_unmask_irq,
.set_type = gic_set_type,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = gic_set_cpu, .set_affinity = gic_set_cpu,
#endif #endif
......
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