History

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 ...

Linus Torvalds committed 6 years ago

Commit f8b036a2 parents 2ed90db 3d5128c36 files · +346 −244Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t