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

Merge tag 'irqchip-core-4.6' of git://git.infradead.org/users/jcooper/linux into irq/core

Pull irqchip core changes for v4.6 from Jason Cooper:

- mvebu (armada-370-xp)
- MSI support
- Deconflict with mvebu's arm64 code

- ts4800
- Restrict when ts4800 driver can be built
- Make ts4800_ic_ops static const

- bcm2836: Drop superfluous memory barrier

+91 -106
+5 -1
arch/arm/mach-mvebu/Kconfig
··· 3 3 depends on ARCH_MULTI_V7 || ARCH_MULTI_V5 4 4 select ARCH_SUPPORTS_BIG_ENDIAN 5 5 select CLKSRC_MMIO 6 - select GENERIC_IRQ_CHIP 7 6 select PINCTRL 8 7 select PLAT_ORION 9 8 select SOC_BUS ··· 28 29 bool "Marvell Armada 370 boards" 29 30 depends on ARCH_MULTI_V7 30 31 select ARMADA_370_CLK 32 + select ARMADA_370_XP_IRQ 31 33 select CPU_PJ4B 32 34 select MACH_MVEBU_V7 33 35 select PINCTRL_ARMADA_370 ··· 39 39 config MACH_ARMADA_375 40 40 bool "Marvell Armada 375 boards" 41 41 depends on ARCH_MULTI_V7 42 + select ARMADA_370_XP_IRQ 42 43 select ARM_ERRATA_720789 43 44 select ARM_ERRATA_753970 44 45 select ARM_GIC ··· 59 58 select ARM_ERRATA_720789 60 59 select ARM_ERRATA_753970 61 60 select ARM_GIC 61 + select ARMADA_370_XP_IRQ 62 62 select ARMADA_38X_CLK 63 63 select HAVE_ARM_SCU 64 64 select HAVE_ARM_TWD if SMP ··· 74 72 bool "Marvell Armada 39x boards" 75 73 depends on ARCH_MULTI_V7 76 74 select ARM_GIC 75 + select ARMADA_370_XP_IRQ 77 76 select ARMADA_39X_CLK 78 77 select CACHE_L2X0 79 78 select HAVE_ARM_SCU ··· 89 86 config MACH_ARMADA_XP 90 87 bool "Marvell Armada XP boards" 91 88 depends on ARCH_MULTI_V7 89 + select ARMADA_370_XP_IRQ 92 90 select ARMADA_XP_CLK 93 91 select CPU_PJ4B 94 92 select MACH_MVEBU_V7
+6
drivers/irqchip/Kconfig
··· 60 60 The maximum number of VICs available in the system, for 61 61 power management. 62 62 63 + config ARMADA_370_XP_IRQ 64 + bool 65 + select GENERIC_IRQ_CHIP 66 + select PCI_MSI_IRQ_DOMAIN if PCI_MSI 67 + 63 68 config ATMEL_AIC_IRQ 64 69 bool 65 70 select GENERIC_IRQ_CHIP ··· 170 165 tristate "TS-4800 IRQ controller" 171 166 select IRQ_DOMAIN 172 167 depends on HAS_IOMEM 168 + depends on SOC_IMX51 || COMPILE_TEST 173 169 help 174 170 Support for the TS-4800 FPGA IRQ controller 175 171
+1 -1
drivers/irqchip/Makefile
··· 5 5 obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o 6 6 obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o 7 7 obj-$(CONFIG_ARCH_MMP) += irq-mmp.o 8 - obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o 9 8 obj-$(CONFIG_IRQ_MXS) += irq-mxs.o 10 9 obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o 11 10 obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o ··· 27 28 obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o 28 29 obj-$(CONFIG_ARM_NVIC) += irq-nvic.o 29 30 obj-$(CONFIG_ARM_VIC) += irq-vic.o 31 + obj-$(CONFIG_ARMADA_370_XP_IRQ) += irq-armada-370-xp.o 30 32 obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o 31 33 obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o 32 34 obj-$(CONFIG_I8259) += irq-i8259.o
+78 -102
drivers/irqchip/irq-armada-370-xp.c
··· 71 71 static int parent_irq; 72 72 #ifdef CONFIG_PCI_MSI 73 73 static struct irq_domain *armada_370_xp_msi_domain; 74 + static struct irq_domain *armada_370_xp_msi_inner_domain; 74 75 static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); 75 76 static DEFINE_MUTEX(msi_used_lock); 76 77 static phys_addr_t msi_doorbell_addr; ··· 116 115 117 116 #ifdef CONFIG_PCI_MSI 118 117 119 - static int armada_370_xp_alloc_msi(void) 120 - { 121 - int hwirq; 122 - 123 - mutex_lock(&msi_used_lock); 124 - hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR); 125 - if (hwirq >= PCI_MSI_DOORBELL_NR) 126 - hwirq = -ENOSPC; 127 - else 128 - set_bit(hwirq, msi_used); 129 - mutex_unlock(&msi_used_lock); 130 - 131 - return hwirq; 132 - } 133 - 134 - static void armada_370_xp_free_msi(int hwirq) 135 - { 136 - mutex_lock(&msi_used_lock); 137 - if (!test_bit(hwirq, msi_used)) 138 - pr_err("trying to free unused MSI#%d\n", hwirq); 139 - else 140 - clear_bit(hwirq, msi_used); 141 - mutex_unlock(&msi_used_lock); 142 - } 143 - 144 - static int armada_370_xp_setup_msi_irq(struct msi_controller *chip, 145 - struct pci_dev *pdev, 146 - struct msi_desc *desc) 147 - { 148 - struct msi_msg msg; 149 - int virq, hwirq; 150 - 151 - /* We support MSI, but not MSI-X */ 152 - if (desc->msi_attrib.is_msix) 153 - return -EINVAL; 154 - 155 - hwirq = armada_370_xp_alloc_msi(); 156 - if (hwirq < 0) 157 - return hwirq; 158 - 159 - virq = irq_create_mapping(armada_370_xp_msi_domain, hwirq); 160 - if (!virq) { 161 - armada_370_xp_free_msi(hwirq); 162 - return -EINVAL; 163 - } 164 - 165 - irq_set_msi_desc(virq, desc); 166 - 167 - msg.address_lo = msi_doorbell_addr; 168 - msg.address_hi = 0; 169 - msg.data = 0xf00 | (hwirq + 16); 170 - 171 - pci_write_msi_msg(virq, &msg); 172 - return 0; 173 - } 174 - 175 - static void armada_370_xp_teardown_msi_irq(struct msi_controller *chip, 176 - unsigned int irq) 177 - { 178 - struct irq_data *d = irq_get_irq_data(irq); 179 - unsigned long hwirq = d->hwirq; 180 - 181 - irq_dispose_mapping(irq); 182 - armada_370_xp_free_msi(hwirq); 183 - } 184 - 185 118 static struct irq_chip armada_370_xp_msi_irq_chip = { 186 - .name = "armada_370_xp_msi_irq", 187 - .irq_enable = pci_msi_unmask_irq, 188 - .irq_disable = pci_msi_mask_irq, 119 + .name = "MPIC MSI", 189 120 .irq_mask = pci_msi_mask_irq, 190 121 .irq_unmask = pci_msi_unmask_irq, 191 122 }; 192 123 193 - static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq, 194 - irq_hw_number_t hw) 195 - { 196 - irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip, 197 - handle_simple_irq); 124 + static struct msi_domain_info armada_370_xp_msi_domain_info = { 125 + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 126 + MSI_FLAG_MULTI_PCI_MSI), 127 + .chip = &armada_370_xp_msi_irq_chip, 128 + }; 198 129 199 - return 0; 130 + static void armada_370_xp_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 131 + { 132 + msg->address_lo = lower_32_bits(msi_doorbell_addr); 133 + msg->address_hi = upper_32_bits(msi_doorbell_addr); 134 + msg->data = 0xf00 | (data->hwirq + PCI_MSI_DOORBELL_START); 200 135 } 201 136 202 - static const struct irq_domain_ops armada_370_xp_msi_irq_ops = { 203 - .map = armada_370_xp_msi_map, 137 + static int armada_370_xp_msi_set_affinity(struct irq_data *irq_data, 138 + const struct cpumask *mask, bool force) 139 + { 140 + return -EINVAL; 141 + } 142 + 143 + static struct irq_chip armada_370_xp_msi_bottom_irq_chip = { 144 + .name = "MPIC MSI", 145 + .irq_compose_msi_msg = armada_370_xp_compose_msi_msg, 146 + .irq_set_affinity = armada_370_xp_msi_set_affinity, 147 + }; 148 + 149 + static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq, 150 + unsigned int nr_irqs, void *args) 151 + { 152 + int hwirq, i; 153 + 154 + mutex_lock(&msi_used_lock); 155 + 156 + hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR, 157 + 0, nr_irqs, 0); 158 + if (hwirq >= PCI_MSI_DOORBELL_NR) { 159 + mutex_unlock(&msi_used_lock); 160 + return -ENOSPC; 161 + } 162 + 163 + bitmap_set(msi_used, hwirq, nr_irqs); 164 + mutex_unlock(&msi_used_lock); 165 + 166 + for (i = 0; i < nr_irqs; i++) { 167 + irq_domain_set_info(domain, virq + i, hwirq + i, 168 + &armada_370_xp_msi_bottom_irq_chip, 169 + domain->host_data, handle_simple_irq, 170 + NULL, NULL); 171 + } 172 + 173 + return hwirq; 174 + } 175 + 176 + static void armada_370_xp_msi_free(struct irq_domain *domain, 177 + unsigned int virq, unsigned int nr_irqs) 178 + { 179 + struct irq_data *d = irq_domain_get_irq_data(domain, virq); 180 + 181 + mutex_lock(&msi_used_lock); 182 + bitmap_clear(msi_used, d->hwirq, nr_irqs); 183 + mutex_unlock(&msi_used_lock); 184 + } 185 + 186 + static const struct irq_domain_ops armada_370_xp_msi_domain_ops = { 187 + .alloc = armada_370_xp_msi_alloc, 188 + .free = armada_370_xp_msi_free, 204 189 }; 205 190 206 191 static int armada_370_xp_msi_init(struct device_node *node, 207 192 phys_addr_t main_int_phys_base) 208 193 { 209 - struct msi_controller *msi_chip; 210 194 u32 reg; 211 - int ret; 212 195 213 196 msi_doorbell_addr = main_int_phys_base + 214 197 ARMADA_370_XP_SW_TRIG_INT_OFFS; 215 198 216 - msi_chip = kzalloc(sizeof(*msi_chip), GFP_KERNEL); 217 - if (!msi_chip) 199 + armada_370_xp_msi_inner_domain = 200 + irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR, 201 + &armada_370_xp_msi_domain_ops, NULL); 202 + if (!armada_370_xp_msi_inner_domain) 218 203 return -ENOMEM; 219 - 220 - msi_chip->setup_irq = armada_370_xp_setup_msi_irq; 221 - msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq; 222 - msi_chip->of_node = node; 223 204 224 205 armada_370_xp_msi_domain = 225 - irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR, 226 - &armada_370_xp_msi_irq_ops, 227 - NULL); 206 + pci_msi_create_irq_domain(of_node_to_fwnode(node), 207 + &armada_370_xp_msi_domain_info, 208 + armada_370_xp_msi_inner_domain); 228 209 if (!armada_370_xp_msi_domain) { 229 - kfree(msi_chip); 210 + irq_domain_remove(armada_370_xp_msi_inner_domain); 230 211 return -ENOMEM; 231 - } 232 - 233 - ret = of_pci_msi_chip_add(msi_chip); 234 - if (ret < 0) { 235 - irq_domain_remove(armada_370_xp_msi_domain); 236 - kfree(msi_chip); 237 - return ret; 238 212 } 239 213 240 214 reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS) ··· 256 280 #endif 257 281 258 282 static struct irq_chip armada_370_xp_irq_chip = { 259 - .name = "armada_370_xp_irq", 283 + .name = "MPIC", 260 284 .irq_mask = armada_370_xp_irq_mask, 261 285 .irq_mask_ack = armada_370_xp_irq_mask, 262 286 .irq_unmask = armada_370_xp_irq_unmask, ··· 403 427 continue; 404 428 405 429 if (is_chained) { 406 - irq = irq_find_mapping(armada_370_xp_msi_domain, 407 - msinr - 16); 430 + irq = irq_find_mapping(armada_370_xp_msi_inner_domain, 431 + msinr - PCI_MSI_DOORBELL_START); 408 432 generic_handle_irq(irq); 409 433 } else { 410 - irq = msinr - 16; 411 - handle_domain_irq(armada_370_xp_msi_domain, 434 + irq = msinr - PCI_MSI_DOORBELL_START; 435 + handle_domain_irq(armada_370_xp_msi_inner_domain, 412 436 irq, regs); 413 437 } 414 438 } ··· 580 604 armada_370_xp_mpic_domain = 581 605 irq_domain_add_linear(node, nr_irqs, 582 606 &armada_370_xp_mpic_irq_ops, NULL); 583 - 584 607 BUG_ON(!armada_370_xp_mpic_domain); 608 + armada_370_xp_mpic_domain->bus_token = DOMAIN_BUS_WIRED; 585 609 586 610 /* Setup for the boot CPU */ 587 611 armada_xp_mpic_perf_init();
-1
drivers/irqchip/irq-bcm2836.c
··· 229 229 unsigned long secondary_startup_phys = 230 230 (unsigned long)virt_to_phys((void *)secondary_startup); 231 231 232 - dsb(); 233 232 writel(secondary_startup_phys, 234 233 intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu); 235 234
+1 -1
drivers/irqchip/irq-ts4800.c
··· 59 59 return 0; 60 60 } 61 61 62 - struct irq_domain_ops ts4800_ic_ops = { 62 + static const struct irq_domain_ops ts4800_ic_ops = { 63 63 .map = ts4800_irqdomain_map, 64 64 .xlate = irq_domain_xlate_onecell, 65 65 };