++static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc)
++{
++ u32 pending = ar231x_read_reg(AR2315_PCI_ISR) &
++ ar231x_read_reg(AR2315_PCI_IMR);
++
++ if (pending & AR2315_PCI_INT_EXT)
++ generic_handle_irq(AR2315_PCI_IRQ_EXT);
++ else if (pending & AR2315_PCI_INT_ABORT)
++ generic_handle_irq(AR2315_PCI_IRQ_ABORT);
++ else
++ spurious_interrupt();
++}
++
++static void ar2315_pci_irq_mask(struct irq_data *d)
++{
++ u32 m = 1 << (d->irq - AR2315_PCI_IRQ_BASE + AR2315_PCI_IRQ_SHIFT);
++
++ ar231x_mask_reg(AR2315_PCI_IMR, m, 0);
++}
++
++static void ar2315_pci_irq_mask_ack(struct irq_data *d)
++{
++ u32 m = 1 << (d->irq - AR2315_PCI_IRQ_BASE + AR2315_PCI_IRQ_SHIFT);
++
++ ar231x_mask_reg(AR2315_PCI_IMR, m, 0);
++ ar231x_write_reg(AR2315_PCI_ISR, m);
++}
++
++static void ar2315_pci_irq_unmask(struct irq_data *d)
++{
++ u32 m = 1 << (d->irq - AR2315_PCI_IRQ_BASE + AR2315_PCI_IRQ_SHIFT);
++
++ ar231x_mask_reg(AR2315_PCI_IMR, 0, m);
++}
++
++static struct irq_chip ar2315_pci_irq_chip = {
++ .name = "AR2315-PCI",
++ .irq_mask = ar2315_pci_irq_mask,
++ .irq_mask_ack = ar2315_pci_irq_mask_ack,
++ .irq_unmask = ar2315_pci_irq_unmask,
++};
++
++static void ar2315_pci_irq_init(void)
++{
++ int i;
++
++ ar231x_mask_reg(AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0);
++ ar231x_mask_reg(AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT |
++ AR2315_PCI_INT_EXT), 0);
++
++ for (i = 0; i < AR2315_PCI_IRQ_COUNT; ++i) {
++ int irq = AR2315_PCI_IRQ_BASE + i;
++
++ irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip,
++ handle_level_irq);
++ }
++
++ irq_set_chained_handler(AR2315_IRQ_LCBUS_PCI, ar2315_pci_irq_handler);
++
++ /* Clear any pending Abort or external Interrupts
++ * and enable interrupt processing */
++ ar231x_write_reg(AR2315_PCI_ISR, (AR2315_PCI_INT_ABORT |
++ AR2315_PCI_INT_EXT));
++ ar231x_mask_reg(AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE);
++}
++