[backfire] ar71xx: backport pci/dma fix from r21143
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Tue, 27 Apr 2010 18:50:56 +0000 (18:50 +0000)
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Tue, 27 Apr 2010 18:50:56 +0000 (18:50 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/branches/backfire@21207 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/ar71xx/files/arch/mips/ar71xx/irq.c

index eecdd9f714b81a6bfb6de3ee62b553748fbc15f7..4e1da167dd03181030217df3fb6474237ac74725 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <asm/mach-ar71xx/ar71xx.h>
 
+static int ip2_flush_reg;
+
 static void ar71xx_gpio_irq_dispatch(void)
 {
        void __iomem *base = ar71xx_gpio_base;
@@ -239,8 +241,17 @@ asmlinkage void plat_irq_dispatch(void)
        if (pending & STATUSF_IP7)
                do_IRQ(AR71XX_CPU_IRQ_TIMER);
 
-       else if (pending & STATUSF_IP2)
+       else if (pending & STATUSF_IP2) {
+               /*
+                * This IRQ is meant for a PCI device. Drivers for PCI devices
+                * typically allocate coherent DMA memory for the descriptor
+                * ring, however the DMA controller may still have some
+                * unsynchronized data in the FIFO.
+                * Issue a flush here to ensure that the driver sees the update.
+                */
+               ar71xx_ddr_flush(ip2_flush_reg);
                do_IRQ(AR71XX_CPU_IRQ_IP2);
+       }
 
        else if (pending & STATUSF_IP4)
                do_IRQ(AR71XX_CPU_IRQ_GE0);
@@ -260,6 +271,20 @@ asmlinkage void plat_irq_dispatch(void)
 
 void __init arch_init_irq(void)
 {
+       switch(ar71xx_soc) {
+       case AR71XX_SOC_AR7240:
+       case AR71XX_SOC_AR7241:
+       case AR71XX_SOC_AR7242:
+               ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
+               break;
+       case AR71XX_SOC_AR9130:
+       case AR71XX_SOC_AR9132:
+               ip2_flush_reg = AR91XX_DDR_REG_FLUSH_WMAC;
+               break;
+       default:
+               ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
+               break;
+       }
        mips_cpu_irq_init();
 
        ar71xx_misc_irq_init();