/*
- * arch/ppc/kernel/mv64360_pic.c
- *
* Interrupt controller support for Marvell's MV64360.
*
* Author: Rabeeh Khoury <rabeeh@galileo.co.il>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mv64x60.h>
+#include <asm/machdep.h>
#ifdef CONFIG_IRQ_ALL_CPUS
#error "The mv64360 does not support distribution of IRQs on all CPUs"
/* ========================== local declarations =========================== */
struct hw_interrupt_type mv64360_pic = {
- .typename = " mv64360_pic ",
+ .typename = " mv64360 ",
.enable = mv64360_unmask_irq,
.disable = mv64360_mask_irq,
.ack = mv64360_mask_irq,
*/
int cpu_nr = smp_processor_id();
if (cpu_nr == 1) {
- if (!(mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO) & (1 << 28)))
+ if (!(mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO) &
+ (1 << MV64x60_IRQ_DOORBELL)))
return -1;
- return 28;
+ return mv64360_irq_base + MV64x60_IRQ_DOORBELL;
}
#endif
if (irq == -1)
irq = -2; /* bogus interrupt, should never happen */
else {
- if ((irq >= 24) && (irq < 28)) {
+ if ((irq >= 24) && (irq < MV64x60_IRQ_DOORBELL)) {
irq_gpp = mv64x60_read(&bh,
MV64x60_GPP_INTR_CAUSE);
irq_gpp = __ilog2(irq_gpp &
{
#ifdef CONFIG_SMP
/* second CPU gets only doorbell interrupts */
- if ((irq - mv64360_irq_base) == 28) {
- mv64x60_set_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO, (1 << 28));
+ if ((irq - mv64360_irq_base) == MV64x60_IRQ_DOORBELL) {
+ mv64x60_set_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO,
+ (1 << MV64x60_IRQ_DOORBELL));
return;
}
#endif
mv64360_mask_irq(unsigned int irq)
{
#ifdef CONFIG_SMP
- if ((irq - mv64360_irq_base) == 28) {
- mv64x60_clr_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO, (1 << 28));
+ if ((irq - mv64360_irq_base) == MV64x60_IRQ_DOORBELL) {
+ mv64x60_clr_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO,
+ (1 << MV64x60_IRQ_DOORBELL));
return;
}
#endif
return IRQ_HANDLED;
}
+/*
+ * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of
+ * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as
+ * well. IOW, don't set bit 0.
+ */
+#define MV64360_PCI0_ERR_MASK_VAL 0x00a50c24
+
static int __init
mv64360_register_hdlrs(void)
{
- u32 mask;
int rc;
/* Clear old errors and register CPU interface error intr handler */
mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
- if ((rc = request_irq(MV64x60_IRQ_CPU_ERR,
+ if ((rc = request_irq(MV64x60_IRQ_CPU_ERR + mv64360_irq_base,
mv64360_cpu_error_int_handler, SA_INTERRUPT, CPU_INTR_STR, 0)))
printk(KERN_WARNING "Can't register cpu error handler: %d", rc);
/* Clear old errors and register internal SRAM error intr handler */
mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
- if ((rc = request_irq(MV64360_IRQ_SRAM_PAR_ERR,
+ if ((rc = request_irq(MV64360_IRQ_SRAM_PAR_ERR + mv64360_irq_base,
mv64360_sram_error_int_handler,SA_INTERRUPT,SRAM_INTR_STR, 0)))
printk(KERN_WARNING "Can't register SRAM error handler: %d",rc);
- /*
- * Bit 0 reserved on 64360 and erratum FEr PCI-#11 (PCI internal
- * data parity error set incorrectly) on rev 0 & 1 of 64460 requires
- * bit 0 to be cleared.
- */
- mask = 0x00a50c24;
-
- if ((mv64x60_get_bridge_type() == MV64x60_TYPE_MV64460) &&
- (mv64x60_get_bridge_rev() > 1))
- mask |= 0x1; /* enable DPErr on 64460 */
-
/* Clear old errors and register PCI 0 error intr handler */
mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, 0);
- if ((rc = request_irq(MV64360_IRQ_PCI0, mv64360_pci_error_int_handler,
+ if ((rc = request_irq(MV64360_IRQ_PCI0 + mv64360_irq_base,
+ mv64360_pci_error_int_handler,
SA_INTERRUPT, PCI0_INTR_STR, (void *)0)))
printk(KERN_WARNING "Can't register pci 0 error handler: %d",
rc);
mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
- mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, mask);
+ mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, MV64360_PCI0_ERR_MASK_VAL);
+
+ /* Erratum FEr PCI-#16 says to clear bit 0 of PCI SERRn Mask reg. */
+ mv64x60_write(&bh, MV64x60_PCI0_ERR_SERR_MASK,
+ mv64x60_read(&bh, MV64x60_PCI0_ERR_SERR_MASK) & ~0x1UL);
/* Clear old errors and register PCI 1 error intr handler */
mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, 0);
- if ((rc = request_irq(MV64360_IRQ_PCI1, mv64360_pci_error_int_handler,
+ if ((rc = request_irq(MV64360_IRQ_PCI1 + mv64360_irq_base,
+ mv64360_pci_error_int_handler,
SA_INTERRUPT, PCI1_INTR_STR, (void *)1)))
printk(KERN_WARNING "Can't register pci 1 error handler: %d",
rc);
mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
- mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, mask);
+ mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, MV64360_PCI0_ERR_MASK_VAL);
+
+ /* Erratum FEr PCI-#16 says to clear bit 0 of PCI Intr Mask reg. */
+ mv64x60_write(&bh, MV64x60_PCI1_ERR_SERR_MASK,
+ mv64x60_read(&bh, MV64x60_PCI1_ERR_SERR_MASK) & ~0x1UL);
return 0;
}