Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/ath79-misc: Move the MISC driver from arch/mips/ath79/

The driver stays the same but the initialization changes a bit.
For OF boards we now get the memory map from the OF node and use
a linear mapping instead of the legacy mapping. For legacy boards
we still use a legacy mapping and just pass down all the parameters
from the board init code.

Signed-off-by: Alban Bedel <albeu@free.fr>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Link: https://lkml.kernel.org/r/1453553867-27003-1-git-send-email-albeu@free.fr
Signed-off-by: Jason Cooper <jason@lakedaemon.net>

authored by

Alban Bedel and committed by
Jason Cooper
07ba4b06 92e963f5

+208 -148
+15 -148
arch/mips/ath79/irq.c
··· 26 26 #include "common.h" 27 27 #include "machtypes.h" 28 28 29 - static void __init ath79_misc_intc_domain_init( 30 - struct device_node *node, int irq); 31 - 32 - static void ath79_misc_irq_handler(struct irq_desc *desc) 33 - { 34 - struct irq_domain *domain = irq_desc_get_handler_data(desc); 35 - void __iomem *base = domain->host_data; 36 - u32 pending; 37 - 38 - pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & 39 - __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 40 - 41 - if (!pending) { 42 - spurious_interrupt(); 43 - return; 44 - } 45 - 46 - while (pending) { 47 - int bit = __ffs(pending); 48 - 49 - generic_handle_irq(irq_linear_revmap(domain, bit)); 50 - pending &= ~BIT(bit); 51 - } 52 - } 53 - 54 - static void ar71xx_misc_irq_unmask(struct irq_data *d) 55 - { 56 - void __iomem *base = irq_data_get_irq_chip_data(d); 57 - unsigned int irq = d->hwirq; 58 - u32 t; 59 - 60 - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 61 - __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); 62 - 63 - /* flush write */ 64 - __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 65 - } 66 - 67 - static void ar71xx_misc_irq_mask(struct irq_data *d) 68 - { 69 - void __iomem *base = irq_data_get_irq_chip_data(d); 70 - unsigned int irq = d->hwirq; 71 - u32 t; 72 - 73 - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 74 - __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); 75 - 76 - /* flush write */ 77 - __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 78 - } 79 - 80 - static void ar724x_misc_irq_ack(struct irq_data *d) 81 - { 82 - void __iomem *base = irq_data_get_irq_chip_data(d); 83 - unsigned int irq = d->hwirq; 84 - u32 t; 85 - 86 - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); 87 - __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); 88 - 89 - /* flush write */ 90 - __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); 91 - } 92 - 93 - static struct irq_chip ath79_misc_irq_chip = { 94 - .name = "MISC", 95 - .irq_unmask = ar71xx_misc_irq_unmask, 96 - .irq_mask = ar71xx_misc_irq_mask, 97 - }; 98 - 99 - static void __init ath79_misc_irq_init(void) 100 - { 101 - if (soc_is_ar71xx() || soc_is_ar913x()) 102 - ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 103 - else if (soc_is_ar724x() || 104 - soc_is_ar933x() || 105 - soc_is_ar934x() || 106 - soc_is_qca955x()) 107 - ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 108 - else 109 - BUG(); 110 - 111 - ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6)); 112 - } 113 29 114 30 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) 115 31 { ··· 164 248 } 165 249 } 166 250 167 - static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) 168 - { 169 - irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); 170 - irq_set_chip_data(irq, d->host_data); 171 - return 0; 172 - } 173 - 174 - static const struct irq_domain_ops misc_irq_domain_ops = { 175 - .xlate = irq_domain_xlate_onecell, 176 - .map = misc_map, 177 - }; 178 - 179 - static void __init ath79_misc_intc_domain_init( 180 - struct device_node *node, int irq) 181 - { 182 - void __iomem *base = ath79_reset_base; 183 - struct irq_domain *domain; 184 - 185 - domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT, 186 - ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base); 187 - if (!domain) 188 - panic("Failed to add MISC irqdomain"); 189 - 190 - /* Disable and clear all interrupts */ 191 - __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); 192 - __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); 193 - 194 - irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain); 195 - } 196 - 197 - static int __init ath79_misc_intc_of_init( 198 - struct device_node *node, struct device_node *parent) 199 - { 200 - int irq; 201 - 202 - irq = irq_of_parse_and_map(node, 0); 203 - if (!irq) 204 - panic("Failed to get MISC IRQ"); 205 - 206 - ath79_misc_intc_domain_init(node, irq); 207 - return 0; 208 - } 209 - 210 - static int __init ar7100_misc_intc_of_init( 211 - struct device_node *node, struct device_node *parent) 212 - { 213 - ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 214 - return ath79_misc_intc_of_init(node, parent); 215 - } 216 - 217 - IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc", 218 - ar7100_misc_intc_of_init); 219 - 220 - static int __init ar7240_misc_intc_of_init( 221 - struct device_node *node, struct device_node *parent) 222 - { 223 - ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 224 - return ath79_misc_intc_of_init(node, parent); 225 - } 226 - 227 - IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc", 228 - ar7240_misc_intc_of_init); 229 - 230 251 static int __init ar79_cpu_intc_of_init( 231 252 struct device_node *node, struct device_node *parent) 232 253 { ··· 201 348 202 349 void __init arch_init_irq(void) 203 350 { 351 + bool misc_is_ar71xx; 352 + 204 353 if (mips_machtype == ATH79_MACH_GENERIC_OF) { 205 354 irqchip_init(); 206 355 return; ··· 217 362 } 218 363 219 364 mips_cpu_irq_init(); 220 - ath79_misc_irq_init(); 365 + 366 + if (soc_is_ar71xx() || soc_is_ar913x()) 367 + misc_is_ar71xx = true; 368 + else if (soc_is_ar724x() || 369 + soc_is_ar933x() || 370 + soc_is_ar934x() || 371 + soc_is_qca955x()) 372 + misc_is_ar71xx = false; 373 + else 374 + BUG(); 375 + ath79_misc_irq_init( 376 + ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS, 377 + ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx); 221 378 222 379 if (soc_is_ar934x()) 223 380 ar934x_ip2_irq_init();
+3
arch/mips/include/asm/mach-ath79/ath79.h
··· 144 144 void ath79_device_reset_set(u32 mask); 145 145 void ath79_device_reset_clear(u32 mask); 146 146 147 + void ath79_misc_irq_init(void __iomem *regs, int irq, 148 + int irq_base, bool is_ar71xx); 149 + 147 150 #endif /* __ASM_MACH_ATH79_H */
+1
drivers/irqchip/Makefile
··· 1 1 obj-$(CONFIG_IRQCHIP) += irqchip.o 2 2 3 + obj-$(CONFIG_ATH79) += irq-ath79-misc.o 3 4 obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o 4 5 obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o 5 6 obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o
+189
drivers/irqchip/irq-ath79-misc.c
··· 1 + /* 2 + * Atheros AR71xx/AR724x/AR913x MISC interrupt controller 3 + * 4 + * Copyright (C) 2015 Alban Bedel <albeu@free.fr> 5 + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 6 + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 7 + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 8 + * 9 + * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 10 + * 11 + * This program is free software; you can redistribute it and/or modify it 12 + * under the terms of the GNU General Public License version 2 as published 13 + * by the Free Software Foundation. 14 + */ 15 + 16 + #include <linux/irqchip.h> 17 + #include <linux/irqchip/chained_irq.h> 18 + #include <linux/of_address.h> 19 + #include <linux/of_irq.h> 20 + 21 + #define AR71XX_RESET_REG_MISC_INT_STATUS 0 22 + #define AR71XX_RESET_REG_MISC_INT_ENABLE 4 23 + 24 + #define ATH79_MISC_IRQ_COUNT 32 25 + 26 + static void ath79_misc_irq_handler(struct irq_desc *desc) 27 + { 28 + struct irq_domain *domain = irq_desc_get_handler_data(desc); 29 + struct irq_chip *chip = irq_desc_get_chip(desc); 30 + void __iomem *base = domain->host_data; 31 + u32 pending; 32 + 33 + chained_irq_enter(chip, desc); 34 + 35 + pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & 36 + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 37 + 38 + if (!pending) { 39 + spurious_interrupt(); 40 + chained_irq_exit(chip, desc); 41 + return; 42 + } 43 + 44 + while (pending) { 45 + int bit = __ffs(pending); 46 + 47 + generic_handle_irq(irq_linear_revmap(domain, bit)); 48 + pending &= ~BIT(bit); 49 + } 50 + 51 + chained_irq_exit(chip, desc); 52 + } 53 + 54 + static void ar71xx_misc_irq_unmask(struct irq_data *d) 55 + { 56 + void __iomem *base = irq_data_get_irq_chip_data(d); 57 + unsigned int irq = d->hwirq; 58 + u32 t; 59 + 60 + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 61 + __raw_writel(t | BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); 62 + 63 + /* flush write */ 64 + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 65 + } 66 + 67 + static void ar71xx_misc_irq_mask(struct irq_data *d) 68 + { 69 + void __iomem *base = irq_data_get_irq_chip_data(d); 70 + unsigned int irq = d->hwirq; 71 + u32 t; 72 + 73 + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 74 + __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); 75 + 76 + /* flush write */ 77 + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); 78 + } 79 + 80 + static void ar724x_misc_irq_ack(struct irq_data *d) 81 + { 82 + void __iomem *base = irq_data_get_irq_chip_data(d); 83 + unsigned int irq = d->hwirq; 84 + u32 t; 85 + 86 + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); 87 + __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); 88 + 89 + /* flush write */ 90 + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); 91 + } 92 + 93 + static struct irq_chip ath79_misc_irq_chip = { 94 + .name = "MISC", 95 + .irq_unmask = ar71xx_misc_irq_unmask, 96 + .irq_mask = ar71xx_misc_irq_mask, 97 + }; 98 + 99 + static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) 100 + { 101 + irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq); 102 + irq_set_chip_data(irq, d->host_data); 103 + return 0; 104 + } 105 + 106 + static const struct irq_domain_ops misc_irq_domain_ops = { 107 + .xlate = irq_domain_xlate_onecell, 108 + .map = misc_map, 109 + }; 110 + 111 + static void __init ath79_misc_intc_domain_init( 112 + struct irq_domain *domain, int irq) 113 + { 114 + void __iomem *base = domain->host_data; 115 + 116 + /* Disable and clear all interrupts */ 117 + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); 118 + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); 119 + 120 + irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain); 121 + } 122 + 123 + static int __init ath79_misc_intc_of_init( 124 + struct device_node *node, struct device_node *parent) 125 + { 126 + struct irq_domain *domain; 127 + void __iomem *base; 128 + int irq; 129 + 130 + irq = irq_of_parse_and_map(node, 0); 131 + if (!irq) { 132 + pr_err("Failed to get MISC IRQ\n"); 133 + return -EINVAL; 134 + } 135 + 136 + base = of_iomap(node, 0); 137 + if (!base) { 138 + pr_err("Failed to get MISC IRQ registers\n"); 139 + return -ENOMEM; 140 + } 141 + 142 + domain = irq_domain_add_linear(node, ATH79_MISC_IRQ_COUNT, 143 + &misc_irq_domain_ops, base); 144 + if (!domain) { 145 + pr_err("Failed to add MISC irqdomain\n"); 146 + return -EINVAL; 147 + } 148 + 149 + ath79_misc_intc_domain_init(domain, irq); 150 + return 0; 151 + } 152 + 153 + static int __init ar7100_misc_intc_of_init( 154 + struct device_node *node, struct device_node *parent) 155 + { 156 + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 157 + return ath79_misc_intc_of_init(node, parent); 158 + } 159 + 160 + IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc", 161 + ar7100_misc_intc_of_init); 162 + 163 + static int __init ar7240_misc_intc_of_init( 164 + struct device_node *node, struct device_node *parent) 165 + { 166 + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 167 + return ath79_misc_intc_of_init(node, parent); 168 + } 169 + 170 + IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc", 171 + ar7240_misc_intc_of_init); 172 + 173 + void __init ath79_misc_irq_init(void __iomem *regs, int irq, 174 + int irq_base, bool is_ar71xx) 175 + { 176 + struct irq_domain *domain; 177 + 178 + if (is_ar71xx) 179 + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 180 + else 181 + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 182 + 183 + domain = irq_domain_add_legacy(NULL, ATH79_MISC_IRQ_COUNT, 184 + irq_base, 0, &misc_irq_domain_ops, regs); 185 + if (!domain) 186 + panic("Failed to create MISC irqdomain"); 187 + 188 + ath79_misc_intc_domain_init(domain, irq); 189 + }