X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Far71xx%2Firq.c;h=77acdfd635e85f2a454d0feadd5aac6dcaa11477;hb=8a8b1629fc9f836758b14633277208e6a09251ac;hp=9758f63f30da6a9a2bcaaed2105cd4805b5d4436;hpb=7e2da7ec232b0b78b5c582e22861bccd69b42730;p=openwrt%2Fsvn-archive%2Farchive.git diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c b/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c index 9758f63f30..77acdfd635 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c @@ -37,13 +37,12 @@ static void ar71xx_gpio_irq_dispatch(void) spurious_interrupt(); } -static void ar71xx_gpio_irq_unmask(unsigned int irq) +static void ar71xx_gpio_irq_unmask(struct irq_data *d) { + unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; void __iomem *base = ar71xx_gpio_base; u32 t; - irq -= AR71XX_GPIO_IRQ_BASE; - t = __raw_readl(base + GPIO_REG_INT_ENABLE); __raw_writel(t | (1 << irq), base + GPIO_REG_INT_ENABLE); @@ -51,13 +50,12 @@ static void ar71xx_gpio_irq_unmask(unsigned int irq) (void) __raw_readl(base + GPIO_REG_INT_ENABLE); } -static void ar71xx_gpio_irq_mask(unsigned int irq) +static void ar71xx_gpio_irq_mask(struct irq_data *d) { + unsigned int irq = d->irq - AR71XX_GPIO_IRQ_BASE; void __iomem *base = ar71xx_gpio_base; u32 t; - irq -= AR71XX_GPIO_IRQ_BASE; - t = __raw_readl(base + GPIO_REG_INT_ENABLE); __raw_writel(t & ~(1 << irq), base + GPIO_REG_INT_ENABLE); @@ -65,22 +63,11 @@ static void ar71xx_gpio_irq_mask(unsigned int irq) (void) __raw_readl(base + GPIO_REG_INT_ENABLE); } -#if 0 -static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) -{ - /* TODO: implement */ - return 0; -} -#else -#define ar71xx_gpio_irq_set_type NULL -#endif - static struct irq_chip ar71xx_gpio_irq_chip = { .name = "AR71XX GPIO", - .unmask = ar71xx_gpio_irq_unmask, - .mask = ar71xx_gpio_irq_mask, - .mask_ack = ar71xx_gpio_irq_mask, - .set_type = ar71xx_gpio_irq_set_type, + .irq_unmask = ar71xx_gpio_irq_unmask, + .irq_mask = ar71xx_gpio_irq_mask, + .irq_mask_ack = ar71xx_gpio_irq_mask, }; static struct irqaction ar71xx_gpio_irqaction = { @@ -106,7 +93,7 @@ static void __init ar71xx_gpio_irq_init(void) for (i = AR71XX_GPIO_IRQ_BASE; i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) - set_irq_chip_and_handler(i, &ar71xx_gpio_irq_chip, + irq_set_chip_and_handler(i, &ar71xx_gpio_irq_chip, handle_level_irq); setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction); @@ -162,13 +149,12 @@ static void ar71xx_misc_irq_dispatch(void) spurious_interrupt(); } -static void ar71xx_misc_irq_unmask(unsigned int irq) +static void ar71xx_misc_irq_unmask(struct irq_data *d) { + unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; void __iomem *base = ar71xx_reset_base; u32 t; - irq -= AR71XX_MISC_IRQ_BASE; - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); @@ -176,13 +162,12 @@ static void ar71xx_misc_irq_unmask(unsigned int irq) (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); } -static void ar71xx_misc_irq_mask(unsigned int irq) +static void ar71xx_misc_irq_mask(struct irq_data *d) { + unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; void __iomem *base = ar71xx_reset_base; u32 t; - irq -= AR71XX_MISC_IRQ_BASE; - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); @@ -190,13 +175,12 @@ static void ar71xx_misc_irq_mask(unsigned int irq) (void) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); } -static void ar724x_misc_irq_ack(unsigned int irq) +static void ar724x_misc_irq_ack(struct irq_data *d) { + unsigned int irq = d->irq - AR71XX_MISC_IRQ_BASE; void __iomem *base = ar71xx_reset_base; u32 t; - irq -= AR71XX_MISC_IRQ_BASE; - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); @@ -206,8 +190,8 @@ static void ar724x_misc_irq_ack(unsigned int irq) static struct irq_chip ar71xx_misc_irq_chip = { .name = "AR71XX MISC", - .unmask = ar71xx_misc_irq_unmask, - .mask = ar71xx_misc_irq_mask, + .irq_unmask = ar71xx_misc_irq_unmask, + .irq_mask = ar71xx_misc_irq_mask, }; static struct irqaction ar71xx_misc_irqaction = { @@ -232,26 +216,25 @@ static void __init ar71xx_misc_irq_init(void) case AR71XX_SOC_AR9341: case AR71XX_SOC_AR9342: case AR71XX_SOC_AR9344: - ar71xx_misc_irq_chip.ack = ar724x_misc_irq_ack; + ar71xx_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; break; default: - ar71xx_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask; + ar71xx_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; break; } for (i = AR71XX_MISC_IRQ_BASE; i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) - set_irq_chip_and_handler(i, &ar71xx_misc_irq_chip, + irq_set_chip_and_handler(i, &ar71xx_misc_irq_chip, handle_level_irq); setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction); } /* - * The IP2 line is tied to a PCI/WMAC device. Drivers for these - * devices typically allocate coherent DMA memory for the descriptor - * ring, however the DMA controller may still have some unsynchronized - * data in the FIFO. + * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for + * these devices typically allocate coherent DMA memory, however the + * DMA controller may still have some unsynchronized data in the FIFO. * Issue a flush in the handlers to ensure that the driver sees * the update. */ @@ -285,7 +268,37 @@ static void ar934x_ip2_handler(void) do_IRQ(AR71XX_CPU_IRQ_IP2); } +static void ar71xx_ip3_handler(void) +{ + ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_USB); + do_IRQ(AR71XX_CPU_IRQ_USB); +} + +static void ar724x_ip3_handler(void) +{ + ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_USB); + do_IRQ(AR71XX_CPU_IRQ_USB); +} + +static void ar913x_ip3_handler(void) +{ + ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_USB); + do_IRQ(AR71XX_CPU_IRQ_USB); +} + +static void ar933x_ip3_handler(void) +{ + ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB); + do_IRQ(AR71XX_CPU_IRQ_USB); +} + +static void ar934x_ip3_handler(void) +{ + do_IRQ(AR71XX_CPU_IRQ_USB); +} + static void (*ip2_handler)(void); +static void (*ip3_handler)(void); asmlinkage void plat_irq_dispatch(void) { @@ -306,7 +319,7 @@ asmlinkage void plat_irq_dispatch(void) do_IRQ(AR71XX_CPU_IRQ_GE1); else if (pending & STATUSF_IP3) - do_IRQ(AR71XX_CPU_IRQ_USB); + ip3_handler(); else if (pending & STATUSF_IP6) ar71xx_misc_irq_dispatch(); @@ -321,28 +334,33 @@ void __init arch_init_irq(void) case AR71XX_SOC_AR7141: case AR71XX_SOC_AR7161: ip2_handler = ar71xx_ip2_handler; + ip3_handler = ar71xx_ip3_handler; break; case AR71XX_SOC_AR7240: case AR71XX_SOC_AR7241: case AR71XX_SOC_AR7242: ip2_handler = ar724x_ip2_handler; + ip3_handler = ar724x_ip3_handler; break; case AR71XX_SOC_AR9130: case AR71XX_SOC_AR9132: ip2_handler = ar913x_ip2_handler; + ip3_handler = ar913x_ip3_handler; break; case AR71XX_SOC_AR9330: case AR71XX_SOC_AR9331: ip2_handler = ar933x_ip2_handler; + ip3_handler = ar933x_ip3_handler; break; case AR71XX_SOC_AR9341: case AR71XX_SOC_AR9342: case AR71XX_SOC_AR9344: ip2_handler = ar934x_ip2_handler; + ip3_handler = ar934x_ip3_handler; break; default: