diff options
Diffstat (limited to 'arch/mips/ath79/irq.c')
| -rw-r--r-- | arch/mips/ath79/irq.c | 61 |
1 files changed, 28 insertions, 33 deletions
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index eeb3953ed8ac..511c06560dc1 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
| @@ -26,9 +26,13 @@ | |||
| 26 | #include "common.h" | 26 | #include "common.h" |
| 27 | #include "machtypes.h" | 27 | #include "machtypes.h" |
| 28 | 28 | ||
| 29 | static void __init ath79_misc_intc_domain_init( | ||
| 30 | struct device_node *node, int irq); | ||
| 31 | |||
| 29 | static void ath79_misc_irq_handler(struct irq_desc *desc) | 32 | static void ath79_misc_irq_handler(struct irq_desc *desc) |
| 30 | { | 33 | { |
| 31 | void __iomem *base = ath79_reset_base; | 34 | struct irq_domain *domain = irq_desc_get_handler_data(desc); |
| 35 | void __iomem *base = domain->host_data; | ||
| 32 | u32 pending; | 36 | u32 pending; |
| 33 | 37 | ||
| 34 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & | 38 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & |
| @@ -42,15 +46,15 @@ static void ath79_misc_irq_handler(struct irq_desc *desc) | |||
| 42 | while (pending) { | 46 | while (pending) { |
| 43 | int bit = __ffs(pending); | 47 | int bit = __ffs(pending); |
| 44 | 48 | ||
| 45 | generic_handle_irq(ATH79_MISC_IRQ(bit)); | 49 | generic_handle_irq(irq_linear_revmap(domain, bit)); |
| 46 | pending &= ~BIT(bit); | 50 | pending &= ~BIT(bit); |
| 47 | } | 51 | } |
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | static void ar71xx_misc_irq_unmask(struct irq_data *d) | 54 | static void ar71xx_misc_irq_unmask(struct irq_data *d) |
| 51 | { | 55 | { |
| 52 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | 56 | void __iomem *base = irq_data_get_irq_chip_data(d); |
| 53 | void __iomem *base = ath79_reset_base; | 57 | unsigned int irq = d->hwirq; |
| 54 | u32 t; | 58 | u32 t; |
| 55 | 59 | ||
| 56 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 60 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
| @@ -62,8 +66,8 @@ static void ar71xx_misc_irq_unmask(struct irq_data *d) | |||
| 62 | 66 | ||
| 63 | static void ar71xx_misc_irq_mask(struct irq_data *d) | 67 | static void ar71xx_misc_irq_mask(struct irq_data *d) |
| 64 | { | 68 | { |
| 65 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | 69 | void __iomem *base = irq_data_get_irq_chip_data(d); |
| 66 | void __iomem *base = ath79_reset_base; | 70 | unsigned int irq = d->hwirq; |
| 67 | u32 t; | 71 | u32 t; |
| 68 | 72 | ||
| 69 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 73 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
| @@ -75,8 +79,8 @@ static void ar71xx_misc_irq_mask(struct irq_data *d) | |||
| 75 | 79 | ||
| 76 | static void ar724x_misc_irq_ack(struct irq_data *d) | 80 | static void ar724x_misc_irq_ack(struct irq_data *d) |
| 77 | { | 81 | { |
| 78 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | 82 | void __iomem *base = irq_data_get_irq_chip_data(d); |
| 79 | void __iomem *base = ath79_reset_base; | 83 | unsigned int irq = d->hwirq; |
| 80 | u32 t; | 84 | u32 t; |
| 81 | 85 | ||
| 82 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); | 86 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); |
| @@ -94,12 +98,6 @@ static struct irq_chip ath79_misc_irq_chip = { | |||
| 94 | 98 | ||
| 95 | static void __init ath79_misc_irq_init(void) | 99 | static void __init ath79_misc_irq_init(void) |
| 96 | { | 100 | { |
| 97 | void __iomem *base = ath79_reset_base; | ||
| 98 | int i; | ||
| 99 | |||
| 100 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
| 101 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); | ||
| 102 | |||
| 103 | if (soc_is_ar71xx() || soc_is_ar913x()) | 101 | if (soc_is_ar71xx() || soc_is_ar913x()) |
| 104 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; | 102 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; |
| 105 | else if (soc_is_ar724x() || | 103 | else if (soc_is_ar724x() || |
| @@ -110,13 +108,7 @@ static void __init ath79_misc_irq_init(void) | |||
| 110 | else | 108 | else |
| 111 | BUG(); | 109 | BUG(); |
| 112 | 110 | ||
| 113 | for (i = ATH79_MISC_IRQ_BASE; | 111 | ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6)); |
| 114 | i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { | ||
| 115 | irq_set_chip_and_handler(i, &ath79_misc_irq_chip, | ||
| 116 | handle_level_irq); | ||
| 117 | } | ||
| 118 | |||
| 119 | irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler); | ||
| 120 | } | 112 | } |
| 121 | 113 | ||
| 122 | static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) | 114 | static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) |
| @@ -256,10 +248,10 @@ asmlinkage void plat_irq_dispatch(void) | |||
| 256 | } | 248 | } |
| 257 | } | 249 | } |
| 258 | 250 | ||
| 259 | #ifdef CONFIG_IRQCHIP | ||
| 260 | static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | 251 | static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) |
| 261 | { | 252 | { |
| 262 | irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); | 253 | irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); |
| 254 | irq_set_chip_data(irq, d->host_data); | ||
| 263 | return 0; | 255 | return 0; |
| 264 | } | 256 | } |
| 265 | 257 | ||
| @@ -268,19 +260,14 @@ static const struct irq_domain_ops misc_irq_domain_ops = { | |||
| 268 | .map = misc_map, | 260 | .map = misc_map, |
| 269 | }; | 261 | }; |
| 270 | 262 | ||
| 271 | static int __init ath79_misc_intc_of_init( | 263 | static void __init ath79_misc_intc_domain_init( |
| 272 | struct device_node *node, struct device_node *parent) | 264 | struct device_node *node, int irq) |
| 273 | { | 265 | { |
| 274 | void __iomem *base = ath79_reset_base; | 266 | void __iomem *base = ath79_reset_base; |
| 275 | struct irq_domain *domain; | 267 | struct irq_domain *domain; |
| 276 | int irq; | ||
| 277 | |||
| 278 | irq = irq_of_parse_and_map(node, 0); | ||
| 279 | if (!irq) | ||
| 280 | panic("Failed to get MISC IRQ"); | ||
| 281 | 268 | ||
| 282 | domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, | 269 | domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, |
| 283 | ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL); | 270 | ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base); |
| 284 | if (!domain) | 271 | if (!domain) |
| 285 | panic("Failed to add MISC irqdomain"); | 272 | panic("Failed to add MISC irqdomain"); |
| 286 | 273 | ||
| @@ -288,9 +275,19 @@ static int __init ath79_misc_intc_of_init( | |||
| 288 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 275 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
| 289 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); | 276 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); |
| 290 | 277 | ||
| 278 | irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain); | ||
| 279 | } | ||
| 291 | 280 | ||
| 292 | irq_set_chained_handler(irq, ath79_misc_irq_handler); | 281 | static int __init ath79_misc_intc_of_init( |
| 282 | struct device_node *node, struct device_node *parent) | ||
| 283 | { | ||
| 284 | int irq; | ||
| 293 | 285 | ||
| 286 | irq = irq_of_parse_and_map(node, 0); | ||
| 287 | if (!irq) | ||
| 288 | panic("Failed to get MISC IRQ"); | ||
| 289 | |||
| 290 | ath79_misc_intc_domain_init(node, irq); | ||
| 294 | return 0; | 291 | return 0; |
| 295 | } | 292 | } |
| 296 | 293 | ||
| @@ -349,8 +346,6 @@ static int __init ar79_cpu_intc_of_init( | |||
| 349 | IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", | 346 | IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc", |
| 350 | ar79_cpu_intc_of_init); | 347 | ar79_cpu_intc_of_init); |
| 351 | 348 | ||
| 352 | #endif | ||
| 353 | |||
| 354 | void __init arch_init_irq(void) | 349 | void __init arch_init_irq(void) |
| 355 | { | 350 | { |
| 356 | if (mips_machtype == ATH79_MACH_GENERIC_OF) { | 351 | if (mips_machtype == ATH79_MACH_GENERIC_OF) { |
