diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-03-25 11:20:15 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-03-29 08:48:10 -0400 |
commit | 24a3f2e82bc8cf7ed05294008794f842cf170ea2 (patch) | |
tree | a0fb6efba75b1c61ce801f0965037cc2a0c8d9b0 /arch/powerpc/sysdev | |
parent | 5fed97a9fdc0bc76ea2e220cf3aac0e8c7cf4b2b (diff) |
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>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 0f7c6718d261..edf1f37eaca3 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -361,7 +361,7 @@ static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source) | |||
361 | } | 361 | } |
362 | 362 | ||
363 | static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, | 363 | static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, |
364 | unsigned int irqflags) | 364 | bool level) |
365 | { | 365 | { |
366 | struct mpic_irq_fixup *fixup = &mpic->fixups[source]; | 366 | struct mpic_irq_fixup *fixup = &mpic->fixups[source]; |
367 | unsigned long flags; | 367 | unsigned long flags; |
@@ -370,14 +370,14 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, | |||
370 | if (fixup->base == NULL) | 370 | if (fixup->base == NULL) |
371 | return; | 371 | return; |
372 | 372 | ||
373 | DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n", | 373 | DBG("startup_ht_interrupt(0x%x) index: %d\n", |
374 | source, irqflags, fixup->index); | 374 | source, fixup->index); |
375 | raw_spin_lock_irqsave(&mpic->fixup_lock, flags); | 375 | raw_spin_lock_irqsave(&mpic->fixup_lock, flags); |
376 | /* Enable and configure */ | 376 | /* Enable and configure */ |
377 | writeb(0x10 + 2 * fixup->index, fixup->base + 2); | 377 | writeb(0x10 + 2 * fixup->index, fixup->base + 2); |
378 | tmp = readl(fixup->base + 4); | 378 | tmp = readl(fixup->base + 4); |
379 | tmp &= ~(0x23U); | 379 | tmp &= ~(0x23U); |
380 | if (irqflags & IRQ_LEVEL) | 380 | if (level) |
381 | tmp |= 0x22; | 381 | tmp |= 0x22; |
382 | writel(tmp, fixup->base + 4); | 382 | writel(tmp, fixup->base + 4); |
383 | raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags); | 383 | raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags); |
@@ -389,8 +389,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, | |||
389 | #endif | 389 | #endif |
390 | } | 390 | } |
391 | 391 | ||
392 | static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, | 392 | static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source) |
393 | unsigned int irqflags) | ||
394 | { | 393 | { |
395 | struct mpic_irq_fixup *fixup = &mpic->fixups[source]; | 394 | struct mpic_irq_fixup *fixup = &mpic->fixups[source]; |
396 | unsigned long flags; | 395 | unsigned long flags; |
@@ -399,7 +398,7 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, | |||
399 | if (fixup->base == NULL) | 398 | if (fixup->base == NULL) |
400 | return; | 399 | return; |
401 | 400 | ||
402 | DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags); | 401 | DBG("shutdown_ht_interrupt(0x%x)\n", source); |
403 | 402 | ||
404 | /* Disable */ | 403 | /* Disable */ |
405 | raw_spin_lock_irqsave(&mpic->fixup_lock, flags); | 404 | raw_spin_lock_irqsave(&mpic->fixup_lock, flags); |
@@ -738,7 +737,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d) | |||
738 | 737 | ||
739 | mpic_unmask_irq(d); | 738 | mpic_unmask_irq(d); |
740 | 739 | ||
741 | if (irq_to_desc(d->irq)->status & IRQ_LEVEL) | 740 | if (irqd_is_level_type(d)) |
742 | mpic_ht_end_irq(mpic, src); | 741 | mpic_ht_end_irq(mpic, src); |
743 | } | 742 | } |
744 | 743 | ||
@@ -748,7 +747,7 @@ static unsigned int mpic_startup_ht_irq(struct irq_data *d) | |||
748 | unsigned int src = mpic_irq_to_hw(d->irq); | 747 | unsigned int src = mpic_irq_to_hw(d->irq); |
749 | 748 | ||
750 | mpic_unmask_irq(d); | 749 | mpic_unmask_irq(d); |
751 | mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status); | 750 | mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d)); |
752 | 751 | ||
753 | return 0; | 752 | return 0; |
754 | } | 753 | } |
@@ -758,7 +757,7 @@ static void mpic_shutdown_ht_irq(struct irq_data *d) | |||
758 | struct mpic *mpic = mpic_from_irq_data(d); | 757 | struct mpic *mpic = mpic_from_irq_data(d); |
759 | unsigned int src = mpic_irq_to_hw(d->irq); | 758 | unsigned int src = mpic_irq_to_hw(d->irq); |
760 | 759 | ||
761 | mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status); | 760 | mpic_shutdown_ht_interrupt(mpic, src); |
762 | mpic_mask_irq(d); | 761 | mpic_mask_irq(d); |
763 | } | 762 | } |
764 | 763 | ||
@@ -775,7 +774,7 @@ static void mpic_end_ht_irq(struct irq_data *d) | |||
775 | * latched another edge interrupt coming in anyway | 774 | * latched another edge interrupt coming in anyway |
776 | */ | 775 | */ |
777 | 776 | ||
778 | if (irq_to_desc(d->irq)->status & IRQ_LEVEL) | 777 | if (irqd_is_level_type(d)) |
779 | mpic_ht_end_irq(mpic, src); | 778 | mpic_ht_end_irq(mpic, src); |
780 | mpic_eoi(mpic); | 779 | mpic_eoi(mpic); |
781 | } | 780 | } |
@@ -864,7 +863,6 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) | |||
864 | { | 863 | { |
865 | struct mpic *mpic = mpic_from_irq_data(d); | 864 | struct mpic *mpic = mpic_from_irq_data(d); |
866 | unsigned int src = mpic_irq_to_hw(d->irq); | 865 | unsigned int src = mpic_irq_to_hw(d->irq); |
867 | struct irq_desc *desc = irq_to_desc(d->irq); | ||
868 | unsigned int vecpri, vold, vnew; | 866 | unsigned int vecpri, vold, vnew; |
869 | 867 | ||
870 | DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n", | 868 | 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) | |||
879 | if (flow_type == IRQ_TYPE_NONE) | 877 | if (flow_type == IRQ_TYPE_NONE) |
880 | flow_type = IRQ_TYPE_LEVEL_LOW; | 878 | flow_type = IRQ_TYPE_LEVEL_LOW; |
881 | 879 | ||
882 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | 880 | irqd_set_trigger_type(d, flow_type); |
883 | desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; | ||
884 | if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) | ||
885 | desc->status |= IRQ_LEVEL; | ||
886 | 881 | ||
887 | if (mpic_is_ht_interrupt(mpic, src)) | 882 | if (mpic_is_ht_interrupt(mpic, src)) |
888 | vecpri = MPIC_VECPRI_POLARITY_POSITIVE | | 883 | vecpri = MPIC_VECPRI_POLARITY_POSITIVE | |
@@ -897,7 +892,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) | |||
897 | if (vold != vnew) | 892 | if (vold != vnew) |
898 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew); | 893 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew); |
899 | 894 | ||
900 | return 0; | 895 | return IRQ_SET_MASK_OK_NOCOPY;; |
901 | } | 896 | } |
902 | 897 | ||
903 | void mpic_set_vector(unsigned int virq, unsigned int vector) | 898 | void mpic_set_vector(unsigned int virq, unsigned int vector) |