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

Merge tag 'irq-core-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
"The usual boring updates from the interrupt subsystem:

- Infrastructure to allow building irqchip drivers as modules

- Consolidation of irqchip ACPI probing

- Removal of the EOI-preflow interrupt handler which was required for
SPARC support and became obsolete after SPARC was converted to use
sparse interrupts.

- Cleanups, fixes and improvements all over the place"

* tag 'irq-core-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (51 commits)
irqchip/loongson-pch-pic: Fix the misused irq flow handler
irqchip/loongson-htvec: Support 8 groups of HT vectors
irqchip/loongson-liointc: Fix misuse of gc->mask_cache
dt-bindings: interrupt-controller: Update Loongson HTVEC description
irqchip/imx-intmux: Fix irqdata regs save in imx_intmux_runtime_suspend()
irqchip/imx-intmux: Implement intmux runtime power management
irqchip/gic-v4.1: Use GFP_ATOMIC flag in allocate_vpe_l1_table()
irqchip: Fix IRQCHIP_PLATFORM_DRIVER_* compilation by including module.h
irqchip/stm32-exti: Map direct event to irq parent
irqchip/mtk-cirq: Convert to a platform driver
irqchip/mtk-sysirq: Convert to a platform driver
irqchip/qcom-pdc: Switch to using IRQCHIP_PLATFORM_DRIVER helper macros
irqchip: Add IRQCHIP_PLATFORM_DRIVER_BEGIN/END and IRQCHIP_MATCH helper macros
irqchip: irq-bcm2836.h: drop a duplicated word
irqchip/gic-v4.1: Ensure accessing the correct RD when writing INVALLR
irqchip/irq-bcm7038-l1: Guard uses of cpu_logical_map
irqchip/gic-v3: Remove unused register definition
irqchip/qcom-pdc: Allow QCOM_PDC to be loadable as a permanent module
genirq: Export irq_chip_retrigger_hierarchy and irq_chip_set_vcpu_affinity_parent
irqdomain: Export irq_domain_update_bus_token
...

+346 -244
+4 -1
Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt
··· 2 2 3 3 Required properties: 4 4 5 - - compatible: should be "brcm,l2-intc" for latched interrupt controllers 5 + - compatible: should be one of: 6 + "brcm,hif-spi-l2-intc" or 7 + "brcm,upg-aux-aon-l2-intc" or 8 + "brcm,l2-intc" for latched interrupt controllers 6 9 should be "brcm,bcm7271-l2-intc" for level interrupt controllers 7 10 - reg: specifies the base physical address and size of the registers 8 11 - interrupt-controller: identifies the node as an interrupt controller
+2 -2
Documentation/devicetree/bindings/interrupt-controller/loongson,htvec.yaml
··· 22 22 23 23 interrupts: 24 24 minItems: 1 25 - maxItems: 4 26 - description: Four parent interrupts that receive chained interrupts. 25 + maxItems: 8 26 + description: Eight parent interrupts that receive chained interrupts. 27 27 28 28 interrupt-controller: true 29 29
-1
arch/sparc/Kconfig
··· 81 81 select RTC_DRV_STARFIRE 82 82 select HAVE_PERF_EVENTS 83 83 select PERF_USE_VMALLOC 84 - select IRQ_PREFLOW_FASTEOI 85 84 select ARCH_HAVE_NMI_SAFE_CMPXCHG 86 85 select HAVE_C_RECORDMCOUNT 87 86 select HAVE_ARCH_AUDITSYSCALL
+1 -2
drivers/irqchip/Kconfig
··· 425 425 for Goldfish based virtual platforms. 426 426 427 427 config QCOM_PDC 428 - bool "QCOM PDC" 428 + tristate "QCOM PDC" 429 429 depends on ARCH_QCOM 430 430 select IRQ_DOMAIN_HIERARCHY 431 431 help ··· 541 541 default y 542 542 select IRQ_DOMAIN 543 543 select GENERIC_IRQ_CHIP 544 - select I8259 545 544 help 546 545 Support for the Loongson-3 HyperTransport PIC Controller. 547 546
+1 -1
drivers/irqchip/irq-ativic32.c
··· 92 92 return 0; 93 93 } 94 94 95 - static struct irq_domain_ops ativic32_ops = { 95 + static const struct irq_domain_ops ativic32_ops = { 96 96 .map = ativic32_irq_domain_map, 97 97 .xlate = irq_domain_xlate_onecell 98 98 };
+7 -1
drivers/irqchip/irq-atmel-aic5.c
··· 310 310 aic_common_rtc_irq_fixup(); 311 311 } 312 312 313 + static void __init sam9x60_aic_irq_fixup(void) 314 + { 315 + aic_common_rtc_irq_fixup(); 316 + aic_common_rtt_irq_fixup(); 317 + } 318 + 313 319 static const struct of_device_id aic5_irq_fixups[] __initconst = { 314 320 { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, 315 321 { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, 316 - { .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup }, 322 + { .compatible = "microchip,sam9x60", .data = sam9x60_aic_irq_fixup }, 317 323 { /* sentinel */ }, 318 324 }; 319 325
+11
drivers/irqchip/irq-bcm7038-l1.c
··· 28 28 #include <linux/irqchip.h> 29 29 #include <linux/irqchip/chained_irq.h> 30 30 #include <linux/syscore_ops.h> 31 + #ifdef CONFIG_ARM 32 + #include <asm/smp_plat.h> 33 + #endif 31 34 32 35 #define IRQS_PER_WORD 32 33 36 #define REG_BYTES_PER_IRQ_WORD (sizeof(u32) * 4) ··· 330 327 u32 val; 331 328 332 329 /* Wakeup interrupt should only come from the boot cpu */ 330 + #ifdef CONFIG_SMP 333 331 boot_cpu = cpu_logical_map(0); 332 + #else 333 + boot_cpu = 0; 334 + #endif 334 335 335 336 list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) { 336 337 for (word = 0; word < intc->n_words; word++) { ··· 354 347 struct bcm7038_l1_chip *intc; 355 348 int boot_cpu, word; 356 349 350 + #ifdef CONFIG_SMP 357 351 boot_cpu = cpu_logical_map(0); 352 + #else 353 + boot_cpu = 0; 354 + #endif 358 355 359 356 list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) { 360 357 for (word = 0; word < intc->n_words; word++) {
+5 -3
drivers/irqchip/irq-bcm7120-l2.c
··· 143 143 144 144 irq_set_chained_handler_and_data(parent_irq, 145 145 bcm7120_l2_intc_irq_handle, l1_data); 146 + if (data->can_wake) 147 + enable_irq_wake(parent_irq); 148 + 146 149 return 0; 147 150 } 148 151 ··· 250 247 if (ret < 0) 251 248 goto out_free_l1_data; 252 249 250 + data->can_wake = of_property_read_bool(dn, "brcm,irq-can-wake"); 251 + 253 252 for (irq = 0; irq < data->num_parent_irqs; irq++) { 254 253 ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask); 255 254 if (ret) ··· 278 273 pr_err("failed to allocate generic irq chip\n"); 279 274 goto out_free_domain; 280 275 } 281 - 282 - if (of_property_read_bool(dn, "brcm,irq-can-wake")) 283 - data->can_wake = true; 284 276 285 277 for (idx = 0; idx < data->n_words; idx++) { 286 278 irq = idx * IRQS_PER_WORD;
+5
drivers/irqchip/irq-brcmstb-l2.c
··· 254 254 */ 255 255 data->gc->wake_enabled = 0xffffffff; 256 256 ct->chip.irq_set_wake = irq_gc_set_wake; 257 + enable_irq_wake(parent_irq); 257 258 } 258 259 259 260 pr_info("registered L2 intc (%pOF, parent irq: %d)\n", np, parent_irq); ··· 276 275 return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); 277 276 } 278 277 IRQCHIP_DECLARE(brcmstb_l2_intc, "brcm,l2-intc", brcmstb_l2_edge_intc_of_init); 278 + IRQCHIP_DECLARE(brcmstb_hif_spi_l2_intc, "brcm,hif-spi-l2-intc", 279 + brcmstb_l2_edge_intc_of_init); 280 + IRQCHIP_DECLARE(brcmstb_upg_aux_aon_l2_intc, "brcm,upg-aux-aon-l2-intc", 281 + brcmstb_l2_edge_intc_of_init); 279 282 280 283 static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, 281 284 struct device_node *parent)
+9 -5
drivers/irqchip/irq-gic-v3-its.c
··· 2814 2814 if (val & GICR_VPROPBASER_4_1_VALID) 2815 2815 goto out; 2816 2816 2817 - gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_KERNEL); 2817 + gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC); 2818 2818 if (!gic_data_rdist()->vpe_table_mask) 2819 2819 return -ENOMEM; 2820 2820 ··· 2881 2881 2882 2882 pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n", 2883 2883 np, npg, psz, epp, esz); 2884 - page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(np * PAGE_SIZE)); 2884 + page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE)); 2885 2885 if (!page) 2886 2886 return -ENOMEM; 2887 2887 ··· 4090 4090 static void its_vpe_4_1_invall(struct its_vpe *vpe) 4091 4091 { 4092 4092 void __iomem *rdbase; 4093 + unsigned long flags; 4093 4094 u64 val; 4095 + int cpu; 4094 4096 4095 4097 val = GICR_INVALLR_V; 4096 4098 val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id); 4097 4099 4098 4100 /* Target the redistributor this vPE is currently known on */ 4099 - raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); 4100 - rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base; 4101 + cpu = vpe_to_cpuid_lock(vpe, &flags); 4102 + raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); 4103 + rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; 4101 4104 gic_write_lpir(val, rdbase + GICR_INVALLR); 4102 4105 4103 4106 wait_for_syncr(rdbase); 4104 - raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); 4107 + raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); 4108 + vpe_to_cpuid_unlock(vpe, flags); 4105 4109 } 4106 4110 4107 4111 static int its_vpe_4_1_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
+1 -1
drivers/irqchip/irq-gic-v3.c
··· 2116 2116 } 2117 2117 2118 2118 static int __init 2119 - gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end) 2119 + gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end) 2120 2120 { 2121 2121 struct acpi_madt_generic_distributor *dist; 2122 2122 struct fwnode_handle *domain_handle;
+1 -1
drivers/irqchip/irq-gic.c
··· 1584 1584 gic_set_kvm_info(&gic_v2_kvm_info); 1585 1585 } 1586 1586 1587 - static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, 1587 + static int __init gic_v2_acpi_init(union acpi_subtable_headers *header, 1588 1588 const unsigned long end) 1589 1589 { 1590 1590 struct acpi_madt_generic_distributor *dist;
+66 -4
drivers/irqchip/irq-imx-intmux.c
··· 53 53 #include <linux/of_irq.h> 54 54 #include <linux/of_platform.h> 55 55 #include <linux/spinlock.h> 56 + #include <linux/pm_runtime.h> 56 57 57 58 #define CHANIER(n) (0x10 + (0x40 * n)) 58 59 #define CHANIPR(n) (0x20 + (0x40 * n)) ··· 61 60 #define CHAN_MAX_NUM 0x8 62 61 63 62 struct intmux_irqchip_data { 63 + struct irq_chip chip; 64 + u32 saved_reg; 64 65 int chanidx; 65 66 int irq; 66 67 struct irq_domain *domain; ··· 123 120 static int imx_intmux_irq_map(struct irq_domain *h, unsigned int irq, 124 121 irq_hw_number_t hwirq) 125 122 { 126 - irq_set_chip_data(irq, h->host_data); 127 - irq_set_chip_and_handler(irq, &imx_intmux_irq_chip, handle_level_irq); 123 + struct intmux_irqchip_data *data = h->host_data; 124 + 125 + irq_set_chip_data(irq, data); 126 + irq_set_chip_and_handler(irq, &data->chip, handle_level_irq); 128 127 129 128 return 0; 130 129 } ··· 215 210 return -EINVAL; 216 211 } 217 212 218 - data = devm_kzalloc(&pdev->dev, sizeof(*data) + 219 - channum * sizeof(data->irqchip_data[0]), GFP_KERNEL); 213 + data = devm_kzalloc(&pdev->dev, struct_size(data, irqchip_data, channum), GFP_KERNEL); 220 214 if (!data) 221 215 return -ENOMEM; 222 216 ··· 236 232 data->channum = channum; 237 233 raw_spin_lock_init(&data->lock); 238 234 235 + pm_runtime_get_noresume(&pdev->dev); 236 + pm_runtime_set_active(&pdev->dev); 237 + pm_runtime_enable(&pdev->dev); 238 + 239 239 ret = clk_prepare_enable(data->ipg_clk); 240 240 if (ret) { 241 241 dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret); ··· 247 239 } 248 240 249 241 for (i = 0; i < channum; i++) { 242 + data->irqchip_data[i].chip = imx_intmux_irq_chip; 243 + data->irqchip_data[i].chip.parent_device = &pdev->dev; 250 244 data->irqchip_data[i].chanidx = i; 251 245 252 246 data->irqchip_data[i].irq = irq_of_parse_and_map(np, i); ··· 277 267 278 268 platform_set_drvdata(pdev, data); 279 269 270 + /* 271 + * Let pm_runtime_put() disable clock. 272 + * If CONFIG_PM is not enabled, the clock will stay powered. 273 + */ 274 + pm_runtime_put(&pdev->dev); 275 + 280 276 return 0; 281 277 out: 282 278 clk_disable_unprepare(data->ipg_clk); ··· 304 288 irq_domain_remove(data->irqchip_data[i].domain); 305 289 } 306 290 291 + pm_runtime_disable(&pdev->dev); 292 + 293 + return 0; 294 + } 295 + 296 + #ifdef CONFIG_PM 297 + static int imx_intmux_runtime_suspend(struct device *dev) 298 + { 299 + struct intmux_data *data = dev_get_drvdata(dev); 300 + struct intmux_irqchip_data *irqchip_data; 301 + int i; 302 + 303 + for (i = 0; i < data->channum; i++) { 304 + irqchip_data = &data->irqchip_data[i]; 305 + irqchip_data->saved_reg = readl_relaxed(data->regs + CHANIER(i)); 306 + } 307 + 307 308 clk_disable_unprepare(data->ipg_clk); 308 309 309 310 return 0; 310 311 } 312 + 313 + static int imx_intmux_runtime_resume(struct device *dev) 314 + { 315 + struct intmux_data *data = dev_get_drvdata(dev); 316 + struct intmux_irqchip_data *irqchip_data; 317 + int ret, i; 318 + 319 + ret = clk_prepare_enable(data->ipg_clk); 320 + if (ret) { 321 + dev_err(dev, "failed to enable ipg clk: %d\n", ret); 322 + return ret; 323 + } 324 + 325 + for (i = 0; i < data->channum; i++) { 326 + irqchip_data = &data->irqchip_data[i]; 327 + writel_relaxed(irqchip_data->saved_reg, data->regs + CHANIER(i)); 328 + } 329 + 330 + return 0; 331 + } 332 + #endif 333 + 334 + static const struct dev_pm_ops imx_intmux_pm_ops = { 335 + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 336 + pm_runtime_force_resume) 337 + SET_RUNTIME_PM_OPS(imx_intmux_runtime_suspend, 338 + imx_intmux_runtime_resume, NULL) 339 + }; 311 340 312 341 static const struct of_device_id imx_intmux_id[] = { 313 342 { .compatible = "fsl,imx-intmux", }, ··· 363 302 .driver = { 364 303 .name = "imx-intmux", 365 304 .of_match_table = imx_intmux_id, 305 + .pm = &imx_intmux_pm_ops, 366 306 }, 367 307 .probe = imx_intmux_probe, 368 308 .remove = imx_intmux_remove,
+2 -4
drivers/irqchip/irq-loongson-htpic.c
··· 93 93 } 94 94 95 95 htpic = kzalloc(sizeof(*htpic), GFP_KERNEL); 96 - if (!htpic) { 97 - err = -ENOMEM; 98 - goto out_free; 99 - } 96 + if (!htpic) 97 + return -ENOMEM; 100 98 101 99 htpic->base = of_iomap(node, 0); 102 100 if (!htpic->base) {
+18 -14
drivers/irqchip/irq-loongson-htvec.c
··· 19 19 20 20 /* Registers */ 21 21 #define HTVEC_EN_OFF 0x20 22 - #define HTVEC_MAX_PARENT_IRQ 4 22 + #define HTVEC_MAX_PARENT_IRQ 8 23 23 24 24 #define VEC_COUNT_PER_REG 32 25 - #define VEC_REG_COUNT 4 26 - #define VEC_COUNT (VEC_COUNT_PER_REG * VEC_REG_COUNT) 27 25 #define VEC_REG_IDX(irq_id) ((irq_id) / VEC_COUNT_PER_REG) 28 26 #define VEC_REG_BIT(irq_id) ((irq_id) % VEC_COUNT_PER_REG) 29 27 30 28 struct htvec { 29 + int num_parents; 31 30 void __iomem *base; 32 31 struct irq_domain *htvec_domain; 33 32 raw_spinlock_t htvec_lock; ··· 42 43 43 44 chained_irq_enter(chip, desc); 44 45 45 - for (i = 0; i < VEC_REG_COUNT; i++) { 46 + for (i = 0; i < priv->num_parents; i++) { 46 47 pending = readl(priv->base + 4 * i); 47 48 while (pending) { 48 49 int bit = __ffs(pending); ··· 108 109 static int htvec_domain_alloc(struct irq_domain *domain, unsigned int virq, 109 110 unsigned int nr_irqs, void *arg) 110 111 { 112 + int ret; 111 113 unsigned long hwirq; 112 114 unsigned int type, i; 113 115 struct htvec *priv = domain->host_data; 114 116 115 - irq_domain_translate_onecell(domain, arg, &hwirq, &type); 117 + ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); 118 + if (ret) 119 + return ret; 116 120 117 121 for (i = 0; i < nr_irqs; i++) { 118 122 irq_domain_set_info(domain, virq + i, hwirq + i, &htvec_irq_chip, ··· 149 147 u32 idx; 150 148 151 149 /* Clear IRQ cause registers, mask all interrupts */ 152 - for (idx = 0; idx < VEC_REG_COUNT; idx++) { 150 + for (idx = 0; idx < priv->num_parents; idx++) { 153 151 writel_relaxed(0x0, priv->base + HTVEC_EN_OFF + 4 * idx); 154 152 writel_relaxed(0xFFFFFFFF, priv->base); 155 153 } ··· 159 157 struct device_node *parent) 160 158 { 161 159 struct htvec *priv; 162 - int err, parent_irq[4], num_parents = 0, i; 160 + int err, parent_irq[8], i; 163 161 164 162 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 165 163 if (!priv) ··· 178 176 if (parent_irq[i] <= 0) 179 177 break; 180 178 181 - num_parents++; 179 + priv->num_parents++; 182 180 } 183 181 184 - if (!num_parents) { 182 + if (!priv->num_parents) { 185 183 pr_err("Failed to get parent irqs\n"); 186 184 err = -ENODEV; 187 185 goto iounmap_base; 188 186 } 189 187 190 188 priv->htvec_domain = irq_domain_create_linear(of_node_to_fwnode(node), 191 - VEC_COUNT, 192 - &htvec_domain_ops, 193 - priv); 189 + (VEC_COUNT_PER_REG * priv->num_parents), 190 + &htvec_domain_ops, priv); 194 191 if (!priv->htvec_domain) { 195 192 pr_err("Failed to create IRQ domain\n"); 196 193 err = -ENOMEM; 197 - goto iounmap_base; 194 + goto irq_dispose; 198 195 } 199 196 200 197 htvec_reset(priv); 201 198 202 - for (i = 0; i < num_parents; i++) 199 + for (i = 0; i < priv->num_parents; i++) 203 200 irq_set_chained_handler_and_data(parent_irq[i], 204 201 htvec_irq_dispatch, priv); 205 202 206 203 return 0; 207 204 205 + irq_dispose: 206 + for (; i > 0; i--) 207 + irq_dispose_mapping(parent_irq[i - 1]); 208 208 iounmap_base: 209 209 iounmap(priv->base); 210 210 free_priv:
+6 -5
drivers/irqchip/irq-loongson-liointc.c
··· 60 60 if (!pending) { 61 61 /* Always blame LPC IRQ if we have that bug */ 62 62 if (handler->priv->has_lpc_irq_errata && 63 - (handler->parent_int_map & ~gc->mask_cache & 63 + (handler->parent_int_map & gc->mask_cache & 64 64 BIT(LIOINTC_ERRATA_IRQ))) 65 65 pending = BIT(LIOINTC_ERRATA_IRQ); 66 66 else ··· 114 114 liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, false); 115 115 break; 116 116 default: 117 + irq_gc_unlock_irqrestore(gc, flags); 117 118 return -EINVAL; 118 119 } 119 120 irq_gc_unlock_irqrestore(gc, flags); ··· 132 131 irq_gc_lock_irqsave(gc, flags); 133 132 /* Disable all at first */ 134 133 writel(0xffffffff, gc->reg_base + LIOINTC_REG_INTC_DISABLE); 135 - /* Revert map cache */ 134 + /* Restore map cache */ 136 135 for (i = 0; i < LIOINTC_CHIP_IRQ; i++) 137 136 writeb(priv->map_cache[i], gc->reg_base + i); 138 - /* Revert mask cache */ 139 - writel(~gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE); 137 + /* Restore mask cache */ 138 + writel(gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE); 140 139 irq_gc_unlock_irqrestore(gc, flags); 141 140 } 142 141 ··· 244 243 ct->chip.irq_mask_ack = irq_gc_mask_disable_reg; 245 244 ct->chip.irq_set_type = liointc_set_type; 246 245 247 - gc->mask_cache = 0xffffffff; 246 + gc->mask_cache = 0; 248 247 priv->gc = gc; 249 248 250 249 for (i = 0; i < LIOINTC_NUM_PARENT; i++) {
+1 -6
drivers/irqchip/irq-loongson-pch-msi.c
··· 100 100 unsigned int virq, int hwirq) 101 101 { 102 102 struct irq_fwspec fwspec; 103 - int ret; 104 103 105 104 fwspec.fwnode = domain->parent->fwnode; 106 105 fwspec.param_count = 1; 107 106 fwspec.param[0] = hwirq; 108 107 109 - ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 110 - if (ret) 111 - return ret; 112 - 113 - return 0; 108 + return irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 114 109 } 115 110 116 111 static int pch_msi_middle_domain_alloc(struct irq_domain *domain,
+13 -17
drivers/irqchip/irq-loongson-pch-pic.c
··· 64 64 raw_spin_unlock(&priv->pic_lock); 65 65 } 66 66 67 - static void pch_pic_eoi_irq(struct irq_data *d) 68 - { 69 - u32 idx = PIC_REG_IDX(d->hwirq); 70 - struct pch_pic *priv = irq_data_get_irq_chip_data(d); 71 - 72 - writel(BIT(PIC_REG_BIT(d->hwirq)), 73 - priv->base + PCH_PIC_CLR + idx * 4); 74 - } 75 - 76 67 static void pch_pic_mask_irq(struct irq_data *d) 77 68 { 78 69 struct pch_pic *priv = irq_data_get_irq_chip_data(d); ··· 75 84 static void pch_pic_unmask_irq(struct irq_data *d) 76 85 { 77 86 struct pch_pic *priv = irq_data_get_irq_chip_data(d); 87 + 88 + writel(BIT(PIC_REG_BIT(d->hwirq)), 89 + priv->base + PCH_PIC_CLR + PIC_REG_IDX(d->hwirq) * 4); 78 90 79 91 irq_chip_unmask_parent(d); 80 92 pch_pic_bitclr(priv, PCH_PIC_MASK, d->hwirq); ··· 118 124 .irq_mask = pch_pic_mask_irq, 119 125 .irq_unmask = pch_pic_unmask_irq, 120 126 .irq_ack = irq_chip_ack_parent, 121 - .irq_eoi = pch_pic_eoi_irq, 122 127 .irq_set_affinity = irq_chip_set_affinity_parent, 123 128 .irq_set_type = pch_pic_set_type, 124 129 }; ··· 128 135 int err; 129 136 unsigned int type; 130 137 unsigned long hwirq; 131 - struct irq_fwspec fwspec; 138 + struct irq_fwspec *fwspec = arg; 139 + struct irq_fwspec parent_fwspec; 132 140 struct pch_pic *priv = domain->host_data; 133 141 134 - irq_domain_translate_twocell(domain, arg, &hwirq, &type); 142 + err = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type); 143 + if (err) 144 + return err; 135 145 136 - fwspec.fwnode = domain->parent->fwnode; 137 - fwspec.param_count = 1; 138 - fwspec.param[0] = hwirq + priv->ht_vec_base; 146 + parent_fwspec.fwnode = domain->parent->fwnode; 147 + parent_fwspec.param_count = 1; 148 + parent_fwspec.param[0] = hwirq + priv->ht_vec_base; 139 149 140 - err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 150 + err = irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec); 141 151 if (err) 142 152 return err; 143 153 144 154 irq_domain_set_info(domain, virq, hwirq, 145 155 &pch_pic_irq_chip, priv, 146 - handle_fasteoi_ack_irq, NULL, NULL); 156 + handle_level_irq, NULL, NULL); 147 157 irq_set_probe(virq); 148 158 149 159 return 0;
+5 -5
drivers/irqchip/irq-mips-gic.c
··· 46 46 47 47 void __iomem *mips_gic_base; 48 48 49 - DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks); 49 + static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks); 50 50 51 51 static DEFINE_SPINLOCK(gic_lock); 52 52 static struct irq_domain *gic_irq_domain; ··· 617 617 return ret; 618 618 } 619 619 620 - void gic_ipi_domain_free(struct irq_domain *d, unsigned int virq, 621 - unsigned int nr_irqs) 620 + static void gic_ipi_domain_free(struct irq_domain *d, unsigned int virq, 621 + unsigned int nr_irqs) 622 622 { 623 623 irq_hw_number_t base_hwirq; 624 624 struct irq_data *data; ··· 631 631 bitmap_set(ipi_available, base_hwirq, nr_irqs); 632 632 } 633 633 634 - int gic_ipi_domain_match(struct irq_domain *d, struct device_node *node, 635 - enum irq_domain_bus_token bus_token) 634 + static int gic_ipi_domain_match(struct irq_domain *d, struct device_node *node, 635 + enum irq_domain_bus_token bus_token) 636 636 { 637 637 bool is_ipi; 638 638
+3 -1
drivers/irqchip/irq-mtk-cirq.c
··· 295 295 return ret; 296 296 } 297 297 298 - IRQCHIP_DECLARE(mtk_cirq, "mediatek,mtk-cirq", mtk_cirq_of_init); 298 + IRQCHIP_PLATFORM_DRIVER_BEGIN(mtk_cirq) 299 + IRQCHIP_MATCH("mediatek,mtk-cirq", mtk_cirq_of_init) 300 + IRQCHIP_PLATFORM_DRIVER_END(mtk_cirq)
+7 -5
drivers/irqchip/irq-mtk-sysirq.c
··· 15 15 #include <linux/spinlock.h> 16 16 17 17 struct mtk_sysirq_chip_data { 18 - spinlock_t lock; 18 + raw_spinlock_t lock; 19 19 u32 nr_intpol_bases; 20 20 void __iomem **intpol_bases; 21 21 u32 *intpol_words; ··· 37 37 reg_index = chip_data->which_word[hwirq]; 38 38 offset = hwirq & 0x1f; 39 39 40 - spin_lock_irqsave(&chip_data->lock, flags); 40 + raw_spin_lock_irqsave(&chip_data->lock, flags); 41 41 value = readl_relaxed(base + reg_index * 4); 42 42 if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) { 43 43 if (type == IRQ_TYPE_LEVEL_LOW) ··· 53 53 54 54 data = data->parent_data; 55 55 ret = data->chip->irq_set_type(data, type); 56 - spin_unlock_irqrestore(&chip_data->lock, flags); 56 + raw_spin_unlock_irqrestore(&chip_data->lock, flags); 57 57 return ret; 58 58 } 59 59 ··· 212 212 ret = -ENOMEM; 213 213 goto out_free_which_word; 214 214 } 215 - spin_lock_init(&chip_data->lock); 215 + raw_spin_lock_init(&chip_data->lock); 216 216 217 217 return 0; 218 218 ··· 231 231 kfree(chip_data); 232 232 return ret; 233 233 } 234 - IRQCHIP_DECLARE(mtk_sysirq, "mediatek,mt6577-sysirq", mtk_sysirq_of_init); 234 + IRQCHIP_PLATFORM_DRIVER_BEGIN(mtk_sysirq) 235 + IRQCHIP_MATCH("mediatek,mt6577-sysirq", mtk_sysirq_of_init) 236 + IRQCHIP_PLATFORM_DRIVER_END(mtk_sysirq)
+87 -79
drivers/irqchip/irq-stm32-exti.c
··· 25 25 #define IRQS_PER_BANK 32 26 26 27 27 #define HWSPNLCK_TIMEOUT 1000 /* usec */ 28 - #define HWSPNLCK_RETRY_DELAY 100 /* usec */ 29 28 30 29 struct stm32_exti_bank { 31 30 u32 imr_ofst; ··· 41 42 struct stm32_desc_irq { 42 43 u32 exti; 43 44 u32 irq_parent; 45 + struct irq_chip *chip; 44 46 }; 45 47 46 48 struct stm32_exti_drv_data { ··· 166 166 &stm32mp1_exti_b3, 167 167 }; 168 168 169 + static struct irq_chip stm32_exti_h_chip; 170 + static struct irq_chip stm32_exti_h_chip_direct; 171 + 169 172 static const struct stm32_desc_irq stm32mp1_desc_irq[] = { 170 - { .exti = 0, .irq_parent = 6 }, 171 - { .exti = 1, .irq_parent = 7 }, 172 - { .exti = 2, .irq_parent = 8 }, 173 - { .exti = 3, .irq_parent = 9 }, 174 - { .exti = 4, .irq_parent = 10 }, 175 - { .exti = 5, .irq_parent = 23 }, 176 - { .exti = 6, .irq_parent = 64 }, 177 - { .exti = 7, .irq_parent = 65 }, 178 - { .exti = 8, .irq_parent = 66 }, 179 - { .exti = 9, .irq_parent = 67 }, 180 - { .exti = 10, .irq_parent = 40 }, 181 - { .exti = 11, .irq_parent = 42 }, 182 - { .exti = 12, .irq_parent = 76 }, 183 - { .exti = 13, .irq_parent = 77 }, 184 - { .exti = 14, .irq_parent = 121 }, 185 - { .exti = 15, .irq_parent = 127 }, 186 - { .exti = 16, .irq_parent = 1 }, 187 - { .exti = 65, .irq_parent = 144 }, 188 - { .exti = 68, .irq_parent = 143 }, 189 - { .exti = 73, .irq_parent = 129 }, 173 + { .exti = 0, .irq_parent = 6, .chip = &stm32_exti_h_chip }, 174 + { .exti = 1, .irq_parent = 7, .chip = &stm32_exti_h_chip }, 175 + { .exti = 2, .irq_parent = 8, .chip = &stm32_exti_h_chip }, 176 + { .exti = 3, .irq_parent = 9, .chip = &stm32_exti_h_chip }, 177 + { .exti = 4, .irq_parent = 10, .chip = &stm32_exti_h_chip }, 178 + { .exti = 5, .irq_parent = 23, .chip = &stm32_exti_h_chip }, 179 + { .exti = 6, .irq_parent = 64, .chip = &stm32_exti_h_chip }, 180 + { .exti = 7, .irq_parent = 65, .chip = &stm32_exti_h_chip }, 181 + { .exti = 8, .irq_parent = 66, .chip = &stm32_exti_h_chip }, 182 + { .exti = 9, .irq_parent = 67, .chip = &stm32_exti_h_chip }, 183 + { .exti = 10, .irq_parent = 40, .chip = &stm32_exti_h_chip }, 184 + { .exti = 11, .irq_parent = 42, .chip = &stm32_exti_h_chip }, 185 + { .exti = 12, .irq_parent = 76, .chip = &stm32_exti_h_chip }, 186 + { .exti = 13, .irq_parent = 77, .chip = &stm32_exti_h_chip }, 187 + { .exti = 14, .irq_parent = 121, .chip = &stm32_exti_h_chip }, 188 + { .exti = 15, .irq_parent = 127, .chip = &stm32_exti_h_chip }, 189 + { .exti = 16, .irq_parent = 1, .chip = &stm32_exti_h_chip }, 190 + { .exti = 19, .irq_parent = 3, .chip = &stm32_exti_h_chip_direct }, 191 + { .exti = 21, .irq_parent = 31, .chip = &stm32_exti_h_chip_direct }, 192 + { .exti = 22, .irq_parent = 33, .chip = &stm32_exti_h_chip_direct }, 193 + { .exti = 23, .irq_parent = 72, .chip = &stm32_exti_h_chip_direct }, 194 + { .exti = 24, .irq_parent = 95, .chip = &stm32_exti_h_chip_direct }, 195 + { .exti = 25, .irq_parent = 107, .chip = &stm32_exti_h_chip_direct }, 196 + { .exti = 30, .irq_parent = 52, .chip = &stm32_exti_h_chip_direct }, 197 + { .exti = 47, .irq_parent = 93, .chip = &stm32_exti_h_chip_direct }, 198 + { .exti = 54, .irq_parent = 135, .chip = &stm32_exti_h_chip_direct }, 199 + { .exti = 61, .irq_parent = 100, .chip = &stm32_exti_h_chip_direct }, 200 + { .exti = 65, .irq_parent = 144, .chip = &stm32_exti_h_chip }, 201 + { .exti = 68, .irq_parent = 143, .chip = &stm32_exti_h_chip }, 202 + { .exti = 70, .irq_parent = 62, .chip = &stm32_exti_h_chip_direct }, 203 + { .exti = 73, .irq_parent = 129, .chip = &stm32_exti_h_chip }, 190 204 }; 191 205 192 206 static const struct stm32_exti_drv_data stm32mp1_drv_data = { ··· 210 196 .irq_nr = ARRAY_SIZE(stm32mp1_desc_irq), 211 197 }; 212 198 213 - static int stm32_exti_to_irq(const struct stm32_exti_drv_data *drv_data, 214 - irq_hw_number_t hwirq) 199 + static const struct 200 + stm32_desc_irq *stm32_exti_get_desc(const struct stm32_exti_drv_data *drv_data, 201 + irq_hw_number_t hwirq) 215 202 { 216 - const struct stm32_desc_irq *desc_irq; 203 + const struct stm32_desc_irq *desc = NULL; 217 204 int i; 218 205 219 206 if (!drv_data->desc_irqs) 220 - return -EINVAL; 207 + return NULL; 221 208 222 209 for (i = 0; i < drv_data->irq_nr; i++) { 223 - desc_irq = &drv_data->desc_irqs[i]; 224 - if (desc_irq->exti == hwirq) 225 - return desc_irq->irq_parent; 210 + desc = &drv_data->desc_irqs[i]; 211 + if (desc->exti == hwirq) 212 + break; 226 213 } 227 214 228 - return -EINVAL; 215 + return desc; 229 216 } 230 217 231 218 static unsigned long stm32_exti_pending(struct irq_chip_generic *gc) ··· 292 277 return 0; 293 278 } 294 279 295 - static int stm32_exti_hwspin_lock(struct stm32_exti_chip_data *chip_data) 296 - { 297 - int ret, timeout = 0; 298 - 299 - if (!chip_data->host_data->hwlock) 300 - return 0; 301 - 302 - /* 303 - * Use the x_raw API since we are under spin_lock protection. 304 - * Do not use the x_timeout API because we are under irq_disable 305 - * mode (see __setup_irq()) 306 - */ 307 - do { 308 - ret = hwspin_trylock_raw(chip_data->host_data->hwlock); 309 - if (!ret) 310 - return 0; 311 - 312 - udelay(HWSPNLCK_RETRY_DELAY); 313 - timeout += HWSPNLCK_RETRY_DELAY; 314 - } while (timeout < HWSPNLCK_TIMEOUT); 315 - 316 - if (ret == -EBUSY) 317 - ret = -ETIMEDOUT; 318 - 319 - if (ret) 320 - pr_err("%s can't get hwspinlock (%d)\n", __func__, ret); 321 - 322 - return ret; 323 - } 324 - 325 - static void stm32_exti_hwspin_unlock(struct stm32_exti_chip_data *chip_data) 326 - { 327 - if (chip_data->host_data->hwlock) 328 - hwspin_unlock_raw(chip_data->host_data->hwlock); 329 - } 330 - 331 280 static int stm32_irq_set_type(struct irq_data *d, unsigned int type) 332 281 { 333 282 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 334 283 struct stm32_exti_chip_data *chip_data = gc->private; 335 284 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 285 + struct hwspinlock *hwlock = chip_data->host_data->hwlock; 336 286 u32 rtsr, ftsr; 337 287 int err; 338 288 339 289 irq_gc_lock(gc); 340 290 341 - err = stm32_exti_hwspin_lock(chip_data); 342 - if (err) 343 - goto unlock; 291 + if (hwlock) { 292 + err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT); 293 + if (err) { 294 + pr_err("%s can't get hwspinlock (%d)\n", __func__, err); 295 + goto unlock; 296 + } 297 + } 344 298 345 299 rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst); 346 300 ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst); ··· 322 338 irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst); 323 339 324 340 unspinlock: 325 - stm32_exti_hwspin_unlock(chip_data); 341 + if (hwlock) 342 + hwspin_unlock_in_atomic(hwlock); 326 343 unlock: 327 344 irq_gc_unlock(gc); 328 345 ··· 489 504 { 490 505 struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d); 491 506 const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; 507 + struct hwspinlock *hwlock = chip_data->host_data->hwlock; 492 508 void __iomem *base = chip_data->host_data->base; 493 509 u32 rtsr, ftsr; 494 510 int err; 495 511 496 512 raw_spin_lock(&chip_data->rlock); 497 513 498 - err = stm32_exti_hwspin_lock(chip_data); 499 - if (err) 500 - goto unlock; 514 + if (hwlock) { 515 + err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT); 516 + if (err) { 517 + pr_err("%s can't get hwspinlock (%d)\n", __func__, err); 518 + goto unlock; 519 + } 520 + } 501 521 502 522 rtsr = readl_relaxed(base + stm32_bank->rtsr_ofst); 503 523 ftsr = readl_relaxed(base + stm32_bank->ftsr_ofst); ··· 515 525 writel_relaxed(ftsr, base + stm32_bank->ftsr_ofst); 516 526 517 527 unspinlock: 518 - stm32_exti_hwspin_unlock(chip_data); 528 + if (hwlock) 529 + hwspin_unlock_in_atomic(hwlock); 519 530 unlock: 520 531 raw_spin_unlock(&chip_data->rlock); 521 532 ··· 619 628 .irq_set_affinity = IS_ENABLED(CONFIG_SMP) ? stm32_exti_h_set_affinity : NULL, 620 629 }; 621 630 631 + static struct irq_chip stm32_exti_h_chip_direct = { 632 + .name = "stm32-exti-h-direct", 633 + .irq_eoi = irq_chip_eoi_parent, 634 + .irq_ack = irq_chip_ack_parent, 635 + .irq_mask = irq_chip_mask_parent, 636 + .irq_unmask = irq_chip_unmask_parent, 637 + .irq_retrigger = irq_chip_retrigger_hierarchy, 638 + .irq_set_type = irq_chip_set_type_parent, 639 + .irq_set_wake = stm32_exti_h_set_wake, 640 + .flags = IRQCHIP_MASK_ON_SUSPEND, 641 + .irq_set_affinity = IS_ENABLED(CONFIG_SMP) ? irq_chip_set_affinity_parent : NULL, 642 + }; 643 + 622 644 static int stm32_exti_h_domain_alloc(struct irq_domain *dm, 623 645 unsigned int virq, 624 646 unsigned int nr_irqs, void *data) 625 647 { 626 648 struct stm32_exti_host_data *host_data = dm->host_data; 627 649 struct stm32_exti_chip_data *chip_data; 650 + const struct stm32_desc_irq *desc; 628 651 struct irq_fwspec *fwspec = data; 629 652 struct irq_fwspec p_fwspec; 630 653 irq_hw_number_t hwirq; 631 - int p_irq, bank; 654 + int bank; 632 655 633 656 hwirq = fwspec->param[0]; 634 657 bank = hwirq / IRQS_PER_BANK; 635 658 chip_data = &host_data->chips_data[bank]; 636 659 637 - irq_domain_set_hwirq_and_chip(dm, virq, hwirq, 638 - &stm32_exti_h_chip, chip_data); 639 660 640 - p_irq = stm32_exti_to_irq(host_data->drv_data, hwirq); 641 - if (p_irq >= 0) { 661 + desc = stm32_exti_get_desc(host_data->drv_data, hwirq); 662 + if (!desc) 663 + return -EINVAL; 664 + 665 + irq_domain_set_hwirq_and_chip(dm, virq, hwirq, desc->chip, 666 + chip_data); 667 + if (desc->irq_parent) { 642 668 p_fwspec.fwnode = dm->parent->fwnode; 643 669 p_fwspec.param_count = 3; 644 670 p_fwspec.param[0] = GIC_SPI; 645 - p_fwspec.param[1] = p_irq; 671 + p_fwspec.param[1] = desc->irq_parent; 646 672 p_fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH; 647 673 648 674 return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec);
+2 -4
drivers/irqchip/irq-ti-sci-inta.c
··· 433 433 default: 434 434 return -EINVAL; 435 435 } 436 - 437 - return -EINVAL; 438 436 } 439 437 440 438 static struct irq_chip ti_sci_inta_irq_chip = { ··· 570 572 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 571 573 inta->base = devm_ioremap_resource(dev, res); 572 574 if (IS_ERR(inta->base)) 573 - return -ENODEV; 575 + return PTR_ERR(inta->base); 574 576 575 577 domain = irq_domain_add_linear(dev_of_node(dev), 576 578 ti_sci_get_num_resources(inta->vint), ··· 610 612 }; 611 613 module_platform_driver(ti_sci_inta_irq_domain_driver); 612 614 613 - MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>"); 615 + MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ti.com>"); 614 616 MODULE_DESCRIPTION("K3 Interrupt Aggregator driver over TI SCI protocol"); 615 617 MODULE_LICENSE("GPL v2");
+4 -22
drivers/irqchip/irq-vic.c
··· 27 27 28 28 #define VIC_IRQ_STATUS 0x00 29 29 #define VIC_FIQ_STATUS 0x04 30 + #define VIC_RAW_STATUS 0x08 30 31 #define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */ 32 + #define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */ 33 + #define VIC_INT_ENABLE_CLEAR 0x14 31 34 #define VIC_INT_SOFT 0x18 32 35 #define VIC_INT_SOFT_CLEAR 0x1c 33 36 #define VIC_PROTECT 0x20 ··· 431 428 vic_register(base, 0, irq_start, vic_sources, 0, node); 432 429 } 433 430 434 - void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, 431 + static void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, 435 432 u32 vic_sources, u32 resume_sources, 436 433 struct device_node *node) 437 434 { ··· 483 480 { 484 481 __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL); 485 482 } 486 - 487 - /** 488 - * vic_init_cascaded() - initialise a cascaded vectored interrupt controller 489 - * @base: iomem base address 490 - * @parent_irq: the parent IRQ we're cascaded off 491 - * @vic_sources: bitmask of interrupt sources to allow 492 - * @resume_sources: bitmask of interrupt sources to allow for resume 493 - * 494 - * This returns the base for the new interrupts or negative on error. 495 - */ 496 - int __init vic_init_cascaded(void __iomem *base, unsigned int parent_irq, 497 - u32 vic_sources, u32 resume_sources) 498 - { 499 - struct vic_device *v; 500 - 501 - v = &vic_devices[vic_id]; 502 - __vic_init(base, parent_irq, 0, vic_sources, resume_sources, NULL); 503 - /* Return out acquired base */ 504 - return v->irq; 505 - } 506 - EXPORT_SYMBOL_GPL(vic_init_cascaded); 507 483 508 484 #ifdef CONFIG_OF 509 485 static int __init vic_of_init(struct device_node *node,
+29
drivers/irqchip/irqchip.c
··· 10 10 11 11 #include <linux/acpi.h> 12 12 #include <linux/init.h> 13 + #include <linux/of_device.h> 13 14 #include <linux/of_irq.h> 14 15 #include <linux/irqchip.h> 16 + #include <linux/platform_device.h> 15 17 16 18 /* 17 19 * This special of_device_id is the sentinel at the end of the ··· 31 29 of_irq_init(__irqchip_of_table); 32 30 acpi_probe_device_table(irqchip); 33 31 } 32 + 33 + int platform_irqchip_probe(struct platform_device *pdev) 34 + { 35 + struct device_node *np = pdev->dev.of_node; 36 + struct device_node *par_np = of_irq_find_parent(np); 37 + of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); 38 + 39 + if (!irq_init_cb) 40 + return -EINVAL; 41 + 42 + if (par_np == np) 43 + par_np = NULL; 44 + 45 + /* 46 + * If there's a parent interrupt controller and none of the parent irq 47 + * domains have been registered, that means the parent interrupt 48 + * controller has not been initialized yet. it's not time for this 49 + * interrupt controller to initialize. So, defer probe of this 50 + * interrupt controller. The actual initialization callback of this 51 + * interrupt controller can check for specific domains as necessary. 52 + */ 53 + if (par_np && !irq_find_matching_host(np, DOMAIN_BUS_ANY)) 54 + return -EPROBE_DEFER; 55 + 56 + return irq_init_cb(np, par_np); 57 + } 58 + EXPORT_SYMBOL_GPL(platform_irqchip_probe);
+7 -1
drivers/irqchip/qcom-pdc.c
··· 11 11 #include <linux/irqdomain.h> 12 12 #include <linux/io.h> 13 13 #include <linux/kernel.h> 14 + #include <linux/module.h> 14 15 #include <linux/of.h> 15 16 #include <linux/of_address.h> 16 17 #include <linux/of_device.h> 18 + #include <linux/of_irq.h> 17 19 #include <linux/soc/qcom/irq.h> 18 20 #include <linux/spinlock.h> 19 21 #include <linux/slab.h> ··· 432 430 return ret; 433 431 } 434 432 435 - IRQCHIP_DECLARE(qcom_pdc, "qcom,pdc", qcom_pdc_init); 433 + IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc) 434 + IRQCHIP_MATCH("qcom,pdc", qcom_pdc_init) 435 + IRQCHIP_PLATFORM_DRIVER_END(qcom_pdc) 436 + MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller"); 437 + MODULE_LICENSE("GPL v2");
+17 -6
include/linux/acpi.h
··· 1150 1150 kernel_ulong_t driver_data; 1151 1151 }; 1152 1152 1153 - #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn) \ 1153 + #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, \ 1154 + valid, data, fn) \ 1154 1155 static const struct acpi_probe_entry __acpi_probe_##name \ 1155 - __used __section(__##table##_acpi_probe_table) \ 1156 - = { \ 1156 + __used __section(__##table##_acpi_probe_table) = { \ 1157 1157 .id = table_id, \ 1158 1158 .type = subtable, \ 1159 1159 .subtable_valid = valid, \ 1160 - .probe_table = (acpi_tbl_table_handler)fn, \ 1161 - .driver_data = data, \ 1162 - } 1160 + .probe_table = fn, \ 1161 + .driver_data = data, \ 1162 + } 1163 + 1164 + #define ACPI_DECLARE_SUBTABLE_PROBE_ENTRY(table, name, table_id, \ 1165 + subtable, valid, data, fn) \ 1166 + static const struct acpi_probe_entry __acpi_probe_##name \ 1167 + __used __section(__##table##_acpi_probe_table) = { \ 1168 + .id = table_id, \ 1169 + .type = subtable, \ 1170 + .subtable_valid = valid, \ 1171 + .probe_subtbl = fn, \ 1172 + .driver_data = data, \ 1173 + } 1163 1174 1164 1175 #define ACPI_PROBE_TABLE(name) __##name##_acpi_probe_table 1165 1176 #define ACPI_PROBE_TABLE_END(name) __##name##_acpi_probe_table_end
+27 -2
include/linux/irqchip.h
··· 12 12 #define _LINUX_IRQCHIP_H 13 13 14 14 #include <linux/acpi.h> 15 + #include <linux/module.h> 15 16 #include <linux/of.h> 17 + #include <linux/platform_device.h> 16 18 17 19 /* 18 20 * This macro must be used by the different irqchip drivers to declare ··· 27 25 * @fn: initialization function 28 26 */ 29 27 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn) 28 + 29 + extern int platform_irqchip_probe(struct platform_device *pdev); 30 + 31 + #define IRQCHIP_PLATFORM_DRIVER_BEGIN(drv_name) \ 32 + static const struct of_device_id drv_name##_irqchip_match_table[] = { 33 + 34 + #define IRQCHIP_MATCH(compat, fn) { .compatible = compat, .data = fn }, 35 + 36 + #define IRQCHIP_PLATFORM_DRIVER_END(drv_name) \ 37 + {}, \ 38 + }; \ 39 + MODULE_DEVICE_TABLE(of, drv_name##_irqchip_match_table); \ 40 + static struct platform_driver drv_name##_driver = { \ 41 + .probe = platform_irqchip_probe, \ 42 + .driver = { \ 43 + .name = #drv_name, \ 44 + .owner = THIS_MODULE, \ 45 + .of_match_table = drv_name##_irqchip_match_table, \ 46 + .suppress_bind_attrs = true, \ 47 + }, \ 48 + }; \ 49 + builtin_platform_driver(drv_name##_driver) 30 50 31 51 /* 32 52 * This macro must be used by the different irqchip drivers to declare ··· 63 39 * @fn: initialization function 64 40 */ 65 41 #define IRQCHIP_ACPI_DECLARE(name, subtable, validate, data, fn) \ 66 - ACPI_DECLARE_PROBE_ENTRY(irqchip, name, ACPI_SIG_MADT, \ 67 - subtable, validate, data, fn) 42 + ACPI_DECLARE_SUBTABLE_PROBE_ENTRY(irqchip, name, \ 43 + ACPI_SIG_MADT, subtable, \ 44 + validate, data, fn) 68 45 69 46 #ifdef CONFIG_IRQCHIP 70 47 void irqchip_init(void);
-4
include/linux/irqchip/arm-gic-v3.h
··· 19 19 #define GICD_CLRSPI_NSR 0x0048 20 20 #define GICD_SETSPI_SR 0x0050 21 21 #define GICD_CLRSPI_SR 0x0058 22 - #define GICD_SEIR 0x0068 23 22 #define GICD_IGROUPR 0x0080 24 23 #define GICD_ISENABLER 0x0100 25 24 #define GICD_ICENABLER 0x0180 ··· 118 119 #define GICR_WAKER 0x0014 119 120 #define GICR_SETLPIR 0x0040 120 121 #define GICR_CLRLPIR 0x0048 121 - #define GICR_SEIR GICD_SEIR 122 122 #define GICR_PROPBASER 0x0070 123 123 #define GICR_PENDBASER 0x0078 124 124 #define GICR_INVLPIR 0x00A0 125 125 #define GICR_INVALLR 0x00B0 126 126 #define GICR_SYNCR 0x00C0 127 - #define GICR_MOVLPIR 0x0100 128 - #define GICR_MOVALLR 0x0110 129 127 #define GICR_IDREGS GICD_IDREGS 130 128 #define GICR_PIDR2 GICD_PIDR2 131 129
-11
include/linux/irqchip/arm-vic.h
··· 9 9 10 10 #include <linux/types.h> 11 11 12 - #define VIC_RAW_STATUS 0x08 13 - #define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */ 14 - #define VIC_INT_ENABLE_CLEAR 0x14 15 - 16 - struct device_node; 17 - struct pt_regs; 18 - 19 - void __vic_init(void __iomem *base, int parent_irq, int irq_start, 20 - u32 vic_sources, u32 resume_sources, struct device_node *node); 21 12 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); 22 - int vic_init_cascaded(void __iomem *base, unsigned int parent_irq, 23 - u32 vic_sources, u32 resume_sources); 24 13 25 14 #endif
+1 -1
include/linux/irqchip/irq-bcm2836.h
··· 30 30 */ 31 31 #define LOCAL_MAILBOX_INT_CONTROL0 0x050 32 32 /* 33 - * The CPU's interrupt status register. Bits are defined by the the 33 + * The CPU's interrupt status register. Bits are defined by the 34 34 * LOCAL_IRQ_* bits below. 35 35 */ 36 36 #define LOCAL_IRQ_PENDING0 0x060
-15
include/linux/irqdesc.h
··· 22 22 * @irq_common_data: per irq and chip data passed down to chip functions 23 23 * @kstat_irqs: irq stats per cpu 24 24 * @handle_irq: highlevel irq-events handler 25 - * @preflow_handler: handler called before the flow handler (currently used by sparc) 26 25 * @action: the irq action chain 27 26 * @status_use_accessors: status information 28 27 * @core_internal_state__do_not_mess_with_it: core internal status information ··· 57 58 struct irq_data irq_data; 58 59 unsigned int __percpu *kstat_irqs; 59 60 irq_flow_handler_t handle_irq; 60 - #ifdef CONFIG_IRQ_PREFLOW_FASTEOI 61 - irq_preflow_handler_t preflow_handler; 62 - #endif 63 61 struct irqaction *action; /* IRQ action list */ 64 62 unsigned int status_use_accessors; 65 63 unsigned int core_internal_state__do_not_mess_with_it; ··· 263 267 lockdep_set_class(&desc->request_mutex, request_class); 264 268 } 265 269 } 266 - 267 - #ifdef CONFIG_IRQ_PREFLOW_FASTEOI 268 - static inline void 269 - __irq_set_preflow_handler(unsigned int irq, irq_preflow_handler_t handler) 270 - { 271 - struct irq_desc *desc; 272 - 273 - desc = irq_to_desc(irq); 274 - desc->preflow_handler = handler; 275 - } 276 - #endif 277 270 278 271 #endif
-1
include/linux/irqhandler.h
··· 10 10 struct irq_desc; 11 11 struct irq_data; 12 12 typedef void (*irq_flow_handler_t)(struct irq_desc *desc); 13 - typedef void (*irq_preflow_handler_t)(struct irq_data *data); 14 13 15 14 #endif
-4
kernel/irq/Kconfig
··· 51 51 config HARDIRQS_SW_RESEND 52 52 bool 53 53 54 - # Preflow handler support for fasteoi (sparc64) 55 - config IRQ_PREFLOW_FASTEOI 56 - bool 57 - 58 54 # Edge style eoi based handler (cell) 59 55 config IRQ_EDGE_EOI_HANDLER 60 56 bool
+2 -14
kernel/irq/chip.c
··· 656 656 } 657 657 EXPORT_SYMBOL_GPL(handle_level_irq); 658 658 659 - #ifdef CONFIG_IRQ_PREFLOW_FASTEOI 660 - static inline void preflow_handler(struct irq_desc *desc) 661 - { 662 - if (desc->preflow_handler) 663 - desc->preflow_handler(&desc->irq_data); 664 - } 665 - #else 666 - static inline void preflow_handler(struct irq_desc *desc) { } 667 - #endif 668 - 669 659 static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip) 670 660 { 671 661 if (!(desc->istate & IRQS_ONESHOT)) { ··· 711 721 if (desc->istate & IRQS_ONESHOT) 712 722 mask_irq(desc); 713 723 714 - preflow_handler(desc); 715 724 handle_irq_event(desc); 716 725 717 726 cond_unmask_eoi_irq(desc, chip); ··· 1220 1231 /* Start handling the irq */ 1221 1232 desc->irq_data.chip->irq_ack(&desc->irq_data); 1222 1233 1223 - preflow_handler(desc); 1224 1234 handle_irq_event(desc); 1225 1235 1226 1236 cond_unmask_eoi_irq(desc, chip); ··· 1269 1281 if (desc->istate & IRQS_ONESHOT) 1270 1282 mask_irq(desc); 1271 1283 1272 - preflow_handler(desc); 1273 1284 handle_irq_event(desc); 1274 1285 1275 1286 cond_unmask_eoi_irq(desc, chip); ··· 1465 1478 1466 1479 return 0; 1467 1480 } 1481 + EXPORT_SYMBOL_GPL(irq_chip_retrigger_hierarchy); 1468 1482 1469 1483 /** 1470 1484 * irq_chip_set_vcpu_affinity_parent - Set vcpu affinity on the parent interrupt ··· 1480 1492 1481 1493 return -ENOSYS; 1482 1494 } 1483 - 1495 + EXPORT_SYMBOL_GPL(irq_chip_set_vcpu_affinity_parent); 1484 1496 /** 1485 1497 * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt 1486 1498 * @data: Pointer to interrupt specific data
+2 -1
kernel/irq/irqdomain.c
··· 142 142 if (!domain) 143 143 return NULL; 144 144 145 - if (fwnode && is_fwnode_irqchip(fwnode)) { 145 + if (is_fwnode_irqchip(fwnode)) { 146 146 fwid = container_of(fwnode, struct irqchip_fwid, fwnode); 147 147 148 148 switch (fwid->type) { ··· 281 281 282 282 mutex_unlock(&irq_domain_mutex); 283 283 } 284 + EXPORT_SYMBOL_GPL(irq_domain_update_bus_token); 284 285 285 286 /** 286 287 * irq_domain_add_simple() - Register an irq_domain and optionally map a range of irqs