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: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
7e27d6e778
commit
5c0c1f08ab
|
@ -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 = {
|
||||||
.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
|
||||||
|
|
Loading…
Reference in New Issue