void __init epxa10db_init_irq(void) { unsigned int i; request_resource(&iomem_resource, &irq_resource); /* * This bit sets up the interrupt controller using * the 6 PLD interrupts mode (the default) each * irqs is assigned a priority which is the same * as its interrupt number. This scheme is used because * its easy, but you may want to change it depending * on the contents of your PLD */ writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE))); for (i = 0; i < NR_IRQS; i++){ writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i)); set_irq_chip(i,&epxa_irq_chip); set_irq_handler(i,do_level_IRQ); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } /* Disable all interrupts */ writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); }
/* Test generation and receipt of interrupts */ static int efx_test_interrupts(struct efx_nic *efx, struct efx_self_tests *tests) { struct efx_channel *channel; EFX_LOG(efx, "testing interrupts\n"); tests->interrupt = -1; /* Reset interrupt flag */ efx->last_irq_cpu = -1; smp_wmb(); /* ACK each interrupting event queue. Receiving an interrupt due to * traffic before a test event is raised is considered a pass */ efx_for_each_channel(channel, efx) { if (channel->work_pending) efx_process_channel_now(channel); if (efx->last_irq_cpu >= 0) goto success; } efx_nic_generate_interrupt(efx); /* Wait for arrival of test interrupt. */ EFX_LOG(efx, "waiting for test interrupt\n"); schedule_timeout_uninterruptible(HZ / 10); if (efx->last_irq_cpu >= 0) goto success; EFX_ERR(efx, "timed out waiting for interrupt\n"); return -ETIMEDOUT; success: EFX_LOG(efx, "%s test interrupt seen on CPU%d\n", INT_MODE(efx), efx->last_irq_cpu); tests->interrupt = 1; return 0; }