powerpc: mpic: Cleanup flow type handling
The core irq_set_type() function updates the flow type when the chip callback returns 0. So setting the type is bogus. The new core code allows to update the type in irq_data and return IRQ_SET_MASK_OK_NOCOPY, so the core code will not touch it, except for setting the IRQ_LEVEL flag. Retrieve the IRQ_LEVEL information from irq_data which avoids a redundant sparse irq lookup as well. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
5fed97a9fd
commit
24a3f2e82b
1 changed files with 12 additions and 17 deletions
|
@ -361,7 +361,7 @@ static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
|
static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
|
||||||
unsigned int irqflags)
|
bool level)
|
||||||
{
|
{
|
||||||
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
|
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -370,14 +370,14 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
|
||||||
if (fixup->base == NULL)
|
if (fixup->base == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
|
DBG("startup_ht_interrupt(0x%x) index: %d\n",
|
||||||
source, irqflags, fixup->index);
|
source, fixup->index);
|
||||||
raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
|
raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
|
||||||
/* Enable and configure */
|
/* Enable and configure */
|
||||||
writeb(0x10 + 2 * fixup->index, fixup->base + 2);
|
writeb(0x10 + 2 * fixup->index, fixup->base + 2);
|
||||||
tmp = readl(fixup->base + 4);
|
tmp = readl(fixup->base + 4);
|
||||||
tmp &= ~(0x23U);
|
tmp &= ~(0x23U);
|
||||||
if (irqflags & IRQ_LEVEL)
|
if (level)
|
||||||
tmp |= 0x22;
|
tmp |= 0x22;
|
||||||
writel(tmp, fixup->base + 4);
|
writel(tmp, fixup->base + 4);
|
||||||
raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
|
raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
|
||||||
|
@ -389,8 +389,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
|
static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source)
|
||||||
unsigned int irqflags)
|
|
||||||
{
|
{
|
||||||
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
|
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -399,7 +398,7 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
|
||||||
if (fixup->base == NULL)
|
if (fixup->base == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
|
DBG("shutdown_ht_interrupt(0x%x)\n", source);
|
||||||
|
|
||||||
/* Disable */
|
/* Disable */
|
||||||
raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
|
raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
|
||||||
|
@ -738,7 +737,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d)
|
||||||
|
|
||||||
mpic_unmask_irq(d);
|
mpic_unmask_irq(d);
|
||||||
|
|
||||||
if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
|
if (irqd_is_level_type(d))
|
||||||
mpic_ht_end_irq(mpic, src);
|
mpic_ht_end_irq(mpic, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +747,7 @@ static unsigned int mpic_startup_ht_irq(struct irq_data *d)
|
||||||
unsigned int src = mpic_irq_to_hw(d->irq);
|
unsigned int src = mpic_irq_to_hw(d->irq);
|
||||||
|
|
||||||
mpic_unmask_irq(d);
|
mpic_unmask_irq(d);
|
||||||
mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
|
mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -758,7 +757,7 @@ static void mpic_shutdown_ht_irq(struct irq_data *d)
|
||||||
struct mpic *mpic = mpic_from_irq_data(d);
|
struct mpic *mpic = mpic_from_irq_data(d);
|
||||||
unsigned int src = mpic_irq_to_hw(d->irq);
|
unsigned int src = mpic_irq_to_hw(d->irq);
|
||||||
|
|
||||||
mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
|
mpic_shutdown_ht_interrupt(mpic, src);
|
||||||
mpic_mask_irq(d);
|
mpic_mask_irq(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,7 +774,7 @@ static void mpic_end_ht_irq(struct irq_data *d)
|
||||||
* latched another edge interrupt coming in anyway
|
* latched another edge interrupt coming in anyway
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
|
if (irqd_is_level_type(d))
|
||||||
mpic_ht_end_irq(mpic, src);
|
mpic_ht_end_irq(mpic, src);
|
||||||
mpic_eoi(mpic);
|
mpic_eoi(mpic);
|
||||||
}
|
}
|
||||||
|
@ -864,7 +863,6 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
|
||||||
{
|
{
|
||||||
struct mpic *mpic = mpic_from_irq_data(d);
|
struct mpic *mpic = mpic_from_irq_data(d);
|
||||||
unsigned int src = mpic_irq_to_hw(d->irq);
|
unsigned int src = mpic_irq_to_hw(d->irq);
|
||||||
struct irq_desc *desc = irq_to_desc(d->irq);
|
|
||||||
unsigned int vecpri, vold, vnew;
|
unsigned int vecpri, vold, vnew;
|
||||||
|
|
||||||
DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
|
DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
|
||||||
|
@ -879,10 +877,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
|
||||||
if (flow_type == IRQ_TYPE_NONE)
|
if (flow_type == IRQ_TYPE_NONE)
|
||||||
flow_type = IRQ_TYPE_LEVEL_LOW;
|
flow_type = IRQ_TYPE_LEVEL_LOW;
|
||||||
|
|
||||||
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
|
irqd_set_trigger_type(d, flow_type);
|
||||||
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
|
|
||||||
if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
|
|
||||||
desc->status |= IRQ_LEVEL;
|
|
||||||
|
|
||||||
if (mpic_is_ht_interrupt(mpic, src))
|
if (mpic_is_ht_interrupt(mpic, src))
|
||||||
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
|
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
|
||||||
|
@ -897,7 +892,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
|
||||||
if (vold != vnew)
|
if (vold != vnew)
|
||||||
mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
|
mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
|
||||||
|
|
||||||
return 0;
|
return IRQ_SET_MASK_OK_NOCOPY;;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mpic_set_vector(unsigned int virq, unsigned int vector)
|
void mpic_set_vector(unsigned int virq, unsigned int vector)
|
||||||
|
|
Loading…
Reference in a new issue