X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Far71xx%2Firq.c;h=6d744daefab02f0721d0d13823e20eb14ab2b9b3;hb=b66dee35c331cdcfc0ac2e61699abe1e9191e8d0;hp=90e06817df79c122c70f571ff1ca93d164104206;hpb=48cf86296e5ef56531898398563cde678e11173c;p=openwrt.git diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c b/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c index 90e06817df..6d744daefa 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c @@ -28,8 +28,8 @@ static void ar71xx_gpio_irq_dispatch(void) void __iomem *base = ar71xx_gpio_base; u32 pending; - pending = __raw_readl(base + GPIO_REG_INT_PENDING) & - __raw_readl(base + GPIO_REG_INT_ENABLE); + pending = __raw_readl(base + AR71XX_GPIO_REG_INT_PENDING) & + __raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE); if (pending) do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1); @@ -37,39 +37,37 @@ 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); + t = __raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE); + __raw_writel(t | (1 << irq), base + AR71XX_GPIO_REG_INT_ENABLE); /* flush write */ - (void) __raw_readl(base + GPIO_REG_INT_ENABLE); + (void) __raw_readl(base + AR71XX_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); + t = __raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE); + __raw_writel(t & ~(1 << irq), base + AR71XX_GPIO_REG_INT_ENABLE); /* flush write */ - (void) __raw_readl(base + GPIO_REG_INT_ENABLE); + (void) __raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE); } 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, + .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 = { @@ -84,18 +82,18 @@ static void __init ar71xx_gpio_irq_init(void) void __iomem *base = ar71xx_gpio_base; int i; - __raw_writel(0, base + GPIO_REG_INT_ENABLE); - __raw_writel(0, base + GPIO_REG_INT_PENDING); + __raw_writel(0, base + AR71XX_GPIO_REG_INT_ENABLE); + __raw_writel(0, base + AR71XX_GPIO_REG_INT_PENDING); /* setup type of all GPIO interrupts to level sensitive */ - __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_TYPE); + __raw_writel(GPIO_INT_ALL, base + AR71XX_GPIO_REG_INT_TYPE); /* setup polarity of all GPIO interrupts to active high */ - __raw_writel(GPIO_INT_ALL, base + GPIO_REG_INT_POLARITY); + __raw_writel(GPIO_INT_ALL, base + AR71XX_GPIO_REG_INT_POLARITY); 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); @@ -151,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); @@ -165,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); @@ -179,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); @@ -195,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 = { @@ -221,21 +216,55 @@ 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); } +static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) +{ + u32 status; + + disable_irq_nosync(irq); + + status = ar71xx_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); + + if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { + ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); + generic_handle_irq(AR934X_IP2_IRQ_PCIE); + } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { + ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_WMAC); + generic_handle_irq(AR934X_IP2_IRQ_WMAC); + } else { + spurious_interrupt(); + } + + enable_irq(irq); +} + +static void ar934x_ip2_irq_init(void) +{ + int i; + + for (i = AR934X_IP2_IRQ_BASE; + i < AR934X_IP2_IRQ_BASE + AR934X_IP2_IRQ_COUNT; i++) + irq_set_chip_and_handler(i, &dummy_irq_chip, + handle_level_irq); + + irq_set_chained_handler(AR71XX_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); +} + + /* * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for * these devices typically allocate coherent DMA memory, however the @@ -269,7 +298,6 @@ static void ar933x_ip2_handler(void) static void ar934x_ip2_handler(void) { - ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE); do_IRQ(AR71XX_CPU_IRQ_IP2); } @@ -329,7 +357,8 @@ asmlinkage void plat_irq_dispatch(void) else if (pending & STATUSF_IP6) ar71xx_misc_irq_dispatch(); - spurious_interrupt(); + else + spurious_interrupt(); } void __init arch_init_irq(void) @@ -376,6 +405,11 @@ void __init arch_init_irq(void) ar71xx_misc_irq_init(); + if (ar71xx_soc == AR71XX_SOC_AR9341 || + ar71xx_soc == AR71XX_SOC_AR9342 || + ar71xx_soc == AR71XX_SOC_AR9344) + ar934x_ip2_irq_init(); + cp0_perfcount_irq = AR71XX_MISC_IRQ_PERFC; ar71xx_gpio_irq_init();