Updates for the interrupt subsystem:

Core changes:
 
   - Cleanup and simplification of common code to invoke the low level
     interrupt flow handlers when this invocation requires irqdomain
     resolution. Add the necessary core infrastructure.
 
   - Provide a proper interface for modular PMU drivers to set the
     interrupt affinity.
 
   - Add a request flag which allows to exclude interrupts from spurious
     interrupt detection. Useful especially for IPI handlers which always
     return IRQ_HANDLED which turns the spurious interrupt detection into a
     pointless waste of CPU cycles.
 
 Driver changes:
 
   - Bulk convert interrupt chip drivers to the new irqdomain low level flow
     handler invocation mechanism.
 
   - Add device tree bindings for the Renesas R-Car M3-W+ SoC
 
   - Enable modular build of the Qualcomm PDC driver
 
   - The usual small fixes and improvements.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmDbIg8THHRnbHhAbGlu
 dXRyb25peC5kZQAKCRCmGPVMDXSYobZNEAC2wTq3Ishk026va7g5mbQVSvAQyf8G
 0msmgJ48lJWVL9a6JUogNcCO7sZCTcAy4CYbuHI6kz1fGZZnNWSCrtEz0rFNAdWE
 WVR2k8ExR2R73vJm+K50WUMMj8YsefRnIFXWlJdTp+pksr3TZ7Lo70taGUK/6tMo
 aL0dqvnf7Vb3LG0iIkaHWLF4HnyK/UGqB+121rlL4UhI1/g+3EUxNWNcY5eg/dmc
 Ym73U1uDsjydp3/3jm8v8NYNtwCDGpujZZc/88RFLjP6PMpF1S9JUvDEt+LHJi0a
 cdS3RreB78HYXpLg5NtDFJwIegRMLSitvCGPBjHvWBzbifkMsA2zWIb6Cs8VkYys
 vuPoEGZ0ol+SWvcnSh5Xy36nyr4iGIBhQql47UAaqelSxsYPjvCCSD4yJV3k8hnC
 ZuDscOekXUMn75qZR0quNdi1SkgKpGZxK73QFbuW3Apl5EgArVai6kq0rbl6zlx6
 ACy0SEcevhOcpU6WpqDgrmUBgFr+M8zina8edRELgiFEuWT6pYxKwrN3pT4U5djO
 e5V3YuNzzwzvtUoXN4AiTlT8gwRiGfgeiEvHpvZBXPNvk5ffS6XzPiV81ZMWiBkb
 ReoCbqME3PKoxj1VAHJvVXHbcjiPIJeCRdV+5vQSNh1SPSQOmEdWyJtNUDrSkoym
 QkKKY5jrOhPhlQ==
 =FIKh
 -----END PGP SIGNATURE-----

Merge tag 'irq-core-2021-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "Updates for the interrupt subsystem:

  Core changes:

   - Cleanup and simplification of common code to invoke the low level
     interrupt flow handlers when this invocation requires irqdomain
     resolution. Add the necessary core infrastructure.

   - Provide a proper interface for modular PMU drivers to set the
     interrupt affinity.

   - Add a request flag which allows to exclude interrupts from spurious
     interrupt detection. Useful especially for IPI handlers which
     always return IRQ_HANDLED which turns the spurious interrupt
     detection into a pointless waste of CPU cycles.

  Driver changes:

   - Bulk convert interrupt chip drivers to the new irqdomain low level
     flow handler invocation mechanism.

   - Add device tree bindings for the Renesas R-Car M3-W+ SoC

   - Enable modular build of the Qualcomm PDC driver

   - The usual small fixes and improvements"

* tag 'irq-core-2021-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (38 commits)
  dt-bindings: interrupt-controller: arm,gic-v3: Describe GICv3 optional properties
  irqchip: gic-pm: Remove redundant error log of clock bulk
  irqchip/sun4i: Remove unnecessary oom message
  irqchip/irq-imx-gpcv2: Remove unnecessary oom message
  irqchip/imgpdc: Remove unnecessary oom message
  irqchip/gic-v3-its: Remove unnecessary oom message
  irqchip/gic-v2m: Remove unnecessary oom message
  irqchip/exynos-combiner: Remove unnecessary oom message
  irqchip: Bulk conversion to generic_handle_domain_irq()
  genirq: Move non-irqdomain handle_domain_irq() handling into ARM's handle_IRQ()
  genirq: Add generic_handle_domain_irq() helper
  irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq()
  irqdesc: Fix __handle_domain_irq() comment
  genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co
  irqdomain: Introduce irq_resolve_mapping()
  irqdomain: Protect the linear revmap with RCU
  irqdomain: Cache irq_data instead of a virq number in the revmap
  irqdomain: Use struct_size() helper when allocating irqdomain
  irqdomain: Make normal and nomap irqdomains exclusive
  powerpc: Move the use of irq_domain_add_nomap() behind a config option
  ...
This commit is contained in:
Linus Torvalds 2021-06-29 12:25:04 -07:00
commit 21edf50948
106 changed files with 408 additions and 354 deletions

View file

@ -146,7 +146,6 @@ Legacy
irq_domain_add_simple() irq_domain_add_simple()
irq_domain_add_legacy() irq_domain_add_legacy()
irq_domain_add_legacy_isa()
irq_domain_create_simple() irq_domain_create_simple()
irq_domain_create_legacy() irq_domain_create_legacy()

View file

@ -145,6 +145,19 @@ properties:
required: required:
- affinity - affinity
clocks:
maxItems: 1
clock-names:
items:
- const: aclk
power-domains:
maxItems: 1
resets:
maxItems: 1
dependencies: dependencies:
mbi-ranges: [ msi-controller ] mbi-ranges: [ msi-controller ]
msi-controller: [ mbi-ranges ] msi-controller: [ mbi-ranges ]

View file

@ -29,6 +29,7 @@ properties:
- renesas,intc-ex-r8a774c0 # RZ/G2E - renesas,intc-ex-r8a774c0 # RZ/G2E
- renesas,intc-ex-r8a7795 # R-Car H3 - renesas,intc-ex-r8a7795 # R-Car H3
- renesas,intc-ex-r8a7796 # R-Car M3-W - renesas,intc-ex-r8a7796 # R-Car M3-W
- renesas,intc-ex-r8a77961 # R-Car M3-W+
- renesas,intc-ex-r8a77965 # R-Car M3-N - renesas,intc-ex-r8a77965 # R-Car M3-N
- renesas,intc-ex-r8a77970 # R-Car V3M - renesas,intc-ex-r8a77970 # R-Car V3M
- renesas,intc-ex-r8a77980 # R-Car V3H - renesas,intc-ex-r8a77980 # R-Car V3H

View file

@ -63,7 +63,27 @@ int arch_show_interrupts(struct seq_file *p, int prec)
*/ */
void handle_IRQ(unsigned int irq, struct pt_regs *regs) void handle_IRQ(unsigned int irq, struct pt_regs *regs)
{ {
__handle_domain_irq(NULL, irq, false, regs); struct pt_regs *old_regs = set_irq_regs(regs);
struct irq_desc *desc;
irq_enter();
/*
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
*/
if (unlikely(!irq || irq >= nr_irqs))
desc = NULL;
else
desc = irq_to_desc(irq);
if (likely(desc))
handle_irq_desc(desc);
else
ack_bad_irq(irq);
irq_exit();
set_irq_regs(old_regs);
} }
/* /*

View file

@ -11,7 +11,6 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/irqdomain.h>
#include <asm/mipsmtregs.h> #include <asm/mipsmtregs.h>

View file

@ -12,6 +12,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h>
#include <lantiq_soc.h> #include <lantiq_soc.h>
#include <xway_dma.h> #include <xway_dma.h>

View file

@ -13,6 +13,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_pci.h> #include <linux/of_pci.h>

View file

@ -13,6 +13,7 @@
#include <linux/platform_data/xtalk-bridge.h> #include <linux/platform_data/xtalk-bridge.h>
#include <linux/nvmem-consumer.h> #include <linux/nvmem-consumer.h>
#include <linux/crc16.h> #include <linux/crc16.h>
#include <linux/irqdomain.h>
#include <asm/pci/bridge.h> #include <asm/pci/bridge.h>
#include <asm/paccess.h> #include <asm/paccess.h>

View file

@ -9,6 +9,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bitops.h> #include <linux/bitops.h>

View file

@ -6,6 +6,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/tick.h> #include <linux/tick.h>

View file

@ -10,6 +10,5 @@
#define NIOS2_CPU_NR_IRQS 32 #define NIOS2_CPU_NR_IRQS 32
#include <asm-generic/irq.h> #include <asm-generic/irq.h>
#include <linux/irqdomain.h>
#endif #endif

View file

@ -11,6 +11,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/of.h>
static u32 ienable; static u32 ienable;

View file

@ -6,7 +6,6 @@
/* /*
*/ */
#include <linux/irqdomain.h>
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/radix-tree.h> #include <linux/radix-tree.h>
@ -23,8 +22,8 @@ extern atomic_t ppc_n_lost_interrupts;
/* Total number of virq in the platform */ /* Total number of virq in the platform */
#define NR_IRQS CONFIG_NR_IRQS #define NR_IRQS CONFIG_NR_IRQS
/* Same thing, used by the generic IRQ code */ /* Number of irqs reserved for a legacy isa controller */
#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS #define NR_IRQS_LEGACY 16
extern irq_hw_number_t virq_to_hw(unsigned int virq); extern irq_hw_number_t virq_to_hw(unsigned int virq);

View file

@ -18,6 +18,7 @@
#include <linux/extable.h> #include <linux/extable.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/of.h>
#include <asm/interrupt.h> #include <asm/interrupt.h>
#include <asm/machdep.h> #include <asm/machdep.h>

View file

@ -90,6 +90,7 @@
#include <linux/migrate.h> #include <linux/migrate.h>
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include <linux/ksm.h> #include <linux/ksm.h>
#include <linux/of.h>
#include <asm/ultravisor.h> #include <asm/ultravisor.h>
#include <asm/mman.h> #include <asm/mman.h>
#include <asm/kvm_ppc.h> #include <asm/kvm_ppc.h>

View file

@ -14,6 +14,7 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/irqdomain.h>
#include <asm/kvm_book3s.h> #include <asm/kvm_book3s.h>
#include <asm/kvm_ppc.h> #include <asm/kvm_ppc.h>
#include <asm/hvcall.h> #include <asm/hvcall.h>

View file

@ -12,6 +12,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/irqdomain.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/kvm_book3s.h> #include <asm/kvm_book3s.h>
#include <asm/kvm_ppc.h> #include <asm/kvm_ppc.h>

View file

@ -11,6 +11,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>

View file

@ -35,6 +35,7 @@ config PPC_IBM_CELL_BLADE
config AXON_MSI config AXON_MSI
bool bool
depends on PPC_IBM_CELL_BLADE && PCI_MSI depends on PPC_IBM_CELL_BLADE && PCI_MSI
select IRQ_DOMAIN_NOMAP
default y default y
menu "Cell Broadband Engine options" menu "Cell Broadband Engine options"

View file

@ -10,6 +10,7 @@
*/ */
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/export.h> #include <linux/export.h>
#include <asm/io.h> #include <asm/io.h>

View file

@ -12,6 +12,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <asm/io.h> #include <asm/io.h>

View file

@ -24,6 +24,7 @@ config PPC_PMAC32_PSURGE
bool "Support for powersurge upgrade cards" if EXPERT bool "Support for powersurge upgrade cards" if EXPERT
depends on SMP && PPC32 && PPC_PMAC depends on SMP && PPC32 && PPC_PMAC
select PPC_SMP_MUXED_IPI select PPC_SMP_MUXED_IPI
select IRQ_DOMAIN_NOMAP
default y default y
help help
The powersurge cpu boards can be used in the generation The powersurge cpu boards can be used in the generation

View file

@ -7,6 +7,7 @@ config PPC_PS3
select USB_OHCI_BIG_ENDIAN_MMIO select USB_OHCI_BIG_ENDIAN_MMIO
select USB_EHCI_BIG_ENDIAN_MMIO select USB_EHCI_BIG_ENDIAN_MMIO
select HAVE_PCI select HAVE_PCI
select IRQ_DOMAIN_NOMAP
help help
This option enables support for the Sony PS3 game console This option enables support for the Sony PS3 game console
and other platforms using the PS3 hypervisor. Enabling this and other platforms using the PS3 hypervisor. Enabling this

View file

@ -9,6 +9,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/udbg.h> #include <asm/udbg.h>
@ -45,7 +46,7 @@
* implementation equates HV plug value to Linux virq value, constrains each * implementation equates HV plug value to Linux virq value, constrains each
* interrupt to have a system wide unique plug number, and limits the range * interrupt to have a system wide unique plug number, and limits the range
* of the plug values to map into the first dword of the bitmaps. This * of the plug values to map into the first dword of the bitmaps. This
* gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note * gives a usable range of plug values of {NR_IRQS_LEGACY..63}. Note
* that there is no constraint on how many in this set an individual thread * that there is no constraint on how many in this set an individual thread
* can acquire. * can acquire.
* *
@ -721,7 +722,7 @@ static unsigned int ps3_get_irq(void)
} }
#if defined(DEBUG) #if defined(DEBUG)
if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) { if (unlikely(plug < NR_IRQS_LEGACY || plug > PS3_PLUG_MAX)) {
dump_bmp(&per_cpu(ps3_private, 0)); dump_bmp(&per_cpu(ps3_private, 0));
dump_bmp(&per_cpu(ps3_private, 1)); dump_bmp(&per_cpu(ps3_private, 1));
BUG(); BUG();

View file

@ -42,6 +42,7 @@
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/dma-map-ops.h> #include <linux/dma-map-ops.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/stat.h> #include <linux/stat.h>

View file

@ -14,6 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/slab.h> #include <linux/slab.h>

View file

@ -8,6 +8,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>

View file

@ -260,7 +260,8 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
raw_spin_unlock_irqrestore(&i8259_lock, flags); raw_spin_unlock_irqrestore(&i8259_lock, flags);
/* create a legacy host */ /* create a legacy host */
i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL); i8259_host = irq_domain_add_legacy(node, NR_IRQS_LEGACY, 0, 0,
&i8259_host_ops, NULL);
if (i8259_host == NULL) { if (i8259_host == NULL) {
printk(KERN_ERR "i8259: failed to allocate irq host !\n"); printk(KERN_ERR "i8259: failed to allocate irq host !\n");
return; return;

View file

@ -602,7 +602,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
/* Find an mpic associated with a given linux interrupt */ /* Find an mpic associated with a given linux interrupt */
static struct mpic *mpic_find(unsigned int irq) static struct mpic *mpic_find(unsigned int irq)
{ {
if (irq < NUM_ISA_INTERRUPTS) if (irq < NR_IRQS_LEGACY)
return NULL; return NULL;
return irq_get_chip_data(irq); return irq_get_chip_data(irq);

View file

@ -404,7 +404,8 @@ void __init tsi108_pci_int_init(struct device_node *node)
{ {
DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL); pci_irq_host = irq_domain_add_legacy(node, NR_IRQS_LEGACY, 0, 0,
&pci_irq_domain_ops, NULL);
if (pci_irq_host == NULL) { if (pci_irq_host == NULL) {
printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n"); printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
return; return;

View file

@ -7,6 +7,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/of.h> #include <linux/of.h>

View file

@ -7,6 +7,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/of.h> #include <linux/of.h>

View file

@ -201,7 +201,7 @@ void xics_migrate_irqs_away(void)
struct ics *ics; struct ics *ics;
/* We can't set affinity on ISA interrupts */ /* We can't set affinity on ISA interrupts */
if (virq < NUM_ISA_INTERRUPTS) if (virq < NR_IRQS_LEGACY)
continue; continue;
/* We only need to migrate enabled IRQS */ /* We only need to migrate enabled IRQS */
if (!desc->action) if (!desc->action)

View file

@ -3,6 +3,7 @@ config PPC_XIVE
bool bool
select PPC_SMP_MUXED_IPI select PPC_SMP_MUXED_IPI
select HARDIRQS_SW_RESEND select HARDIRQS_SW_RESEND
select IRQ_DOMAIN_NOMAP
config PPC_XIVE_NATIVE config PPC_XIVE_NATIVE
bool bool

View file

@ -415,7 +415,7 @@ config GOLDFISH_PIC
for Goldfish based virtual platforms. for Goldfish based virtual platforms.
config QCOM_PDC config QCOM_PDC
bool "QCOM PDC" tristate "QCOM PDC"
depends on ARCH_QCOM depends on ARCH_QCOM
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
help help

View file

@ -66,8 +66,9 @@ static void combiner_handle_cascade_irq(struct irq_desc *desc)
{ {
struct combiner_chip_data *chip_data = irq_desc_get_handler_data(desc); struct combiner_chip_data *chip_data = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq, combiner_irq; unsigned int combiner_irq;
unsigned long status; unsigned long status;
int ret;
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
@ -80,12 +81,9 @@ static void combiner_handle_cascade_irq(struct irq_desc *desc)
goto out; goto out;
combiner_irq = chip_data->hwirq_offset + __ffs(status); combiner_irq = chip_data->hwirq_offset + __ffs(status);
cascade_irq = irq_find_mapping(combiner_irq_domain, combiner_irq); ret = generic_handle_domain_irq(combiner_irq_domain, combiner_irq);
if (unlikely(ret))
if (unlikely(!cascade_irq))
handle_bad_irq(desc); handle_bad_irq(desc);
else
generic_handle_irq(cascade_irq);
out: out:
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
@ -179,10 +177,8 @@ static void __init combiner_init(void __iomem *combiner_base,
nr_irq = max_nr * IRQ_IN_COMBINER; nr_irq = max_nr * IRQ_IN_COMBINER;
combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL); combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL);
if (!combiner_data) { if (!combiner_data)
pr_warn("%s: could not allocate combiner data\n", __func__);
return; return;
}
combiner_irq_domain = irq_domain_add_linear(np, nr_irq, combiner_irq_domain = irq_domain_add_linear(np, nr_irq,
&combiner_irq_domain_ops, combiner_data); &combiner_irq_domain_ops, combiner_data);

View file

@ -111,7 +111,6 @@ static void al_fic_irq_handler(struct irq_desc *desc)
struct irq_chip *irqchip = irq_desc_get_chip(desc); struct irq_chip *irqchip = irq_desc_get_chip(desc);
struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0); struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
unsigned long pending; unsigned long pending;
unsigned int irq;
u32 hwirq; u32 hwirq;
chained_irq_enter(irqchip, desc); chained_irq_enter(irqchip, desc);
@ -119,10 +118,8 @@ static void al_fic_irq_handler(struct irq_desc *desc)
pending = readl_relaxed(fic->base + AL_FIC_CAUSE); pending = readl_relaxed(fic->base + AL_FIC_CAUSE);
pending &= ~gc->mask_cache; pending &= ~gc->mask_cache;
for_each_set_bit(hwirq, &pending, NR_FIC_IRQS) { for_each_set_bit(hwirq, &pending, NR_FIC_IRQS)
irq = irq_find_mapping(domain, hwirq); generic_handle_domain_irq(domain, hwirq);
generic_handle_irq(irq);
}
chained_irq_exit(irqchip, desc); chained_irq_exit(irqchip, desc);
} }

View file

@ -582,22 +582,21 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
for (msinr = PCI_MSI_DOORBELL_START; for (msinr = PCI_MSI_DOORBELL_START;
msinr < PCI_MSI_DOORBELL_END; msinr++) { msinr < PCI_MSI_DOORBELL_END; msinr++) {
int irq; unsigned int irq;
if (!(msimask & BIT(msinr))) if (!(msimask & BIT(msinr)))
continue; continue;
if (is_chained) {
irq = irq_find_mapping(armada_370_xp_msi_inner_domain,
msinr - PCI_MSI_DOORBELL_START);
generic_handle_irq(irq);
} else {
irq = msinr - PCI_MSI_DOORBELL_START; irq = msinr - PCI_MSI_DOORBELL_START;
if (is_chained)
generic_handle_domain_irq(armada_370_xp_msi_inner_domain,
irq);
else
handle_domain_irq(armada_370_xp_msi_inner_domain, handle_domain_irq(armada_370_xp_msi_inner_domain,
irq, regs); irq, regs);
} }
} }
}
#else #else
static void armada_370_xp_handle_msi_irq(struct pt_regs *r, bool b) {} static void armada_370_xp_handle_msi_irq(struct pt_regs *r, bool b) {}
#endif #endif
@ -606,7 +605,6 @@ static void armada_370_xp_mpic_handle_cascade_irq(struct irq_desc *desc)
{ {
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned long irqmap, irqn, irqsrc, cpuid; unsigned long irqmap, irqn, irqsrc, cpuid;
unsigned int cascade_irq;
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
@ -628,8 +626,7 @@ static void armada_370_xp_mpic_handle_cascade_irq(struct irq_desc *desc)
continue; continue;
} }
cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn); generic_handle_domain_irq(armada_370_xp_mpic_domain, irqn);
generic_handle_irq(cascade_irq);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -34,14 +34,12 @@ static void aspeed_i2c_ic_irq_handler(struct irq_desc *desc)
struct aspeed_i2c_ic *i2c_ic = irq_desc_get_handler_data(desc); struct aspeed_i2c_ic *i2c_ic = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned long bit, status; unsigned long bit, status;
unsigned int bus_irq;
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
status = readl(i2c_ic->base); status = readl(i2c_ic->base);
for_each_set_bit(bit, &status, ASPEED_I2C_IC_NUM_BUS) { for_each_set_bit(bit, &status, ASPEED_I2C_IC_NUM_BUS)
bus_irq = irq_find_mapping(i2c_ic->irq_domain, bit); generic_handle_domain_irq(i2c_ic->irq_domain, bit);
generic_handle_irq(bus_irq);
}
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }

View file

@ -44,7 +44,6 @@ struct aspeed_scu_ic {
static void aspeed_scu_ic_irq_handler(struct irq_desc *desc) static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
{ {
unsigned int irq;
unsigned int sts; unsigned int sts;
unsigned long bit; unsigned long bit;
unsigned long enabled; unsigned long enabled;
@ -74,9 +73,8 @@ static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
max = scu_ic->num_irqs + bit; max = scu_ic->num_irqs + bit;
for_each_set_bit_from(bit, &status, max) { for_each_set_bit_from(bit, &status, max) {
irq = irq_find_mapping(scu_ic->irq_domain, generic_handle_domain_irq(scu_ic->irq_domain,
bit - scu_ic->irq_shift); bit - scu_ic->irq_shift);
generic_handle_irq(irq);
regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, regmap_update_bits(scu_ic->scu, scu_ic->reg, mask,
BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT)); BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT));

View file

@ -50,7 +50,7 @@ static void ath79_misc_irq_handler(struct irq_desc *desc)
while (pending) { while (pending) {
int bit = __ffs(pending); int bit = __ffs(pending);
generic_handle_irq(irq_linear_revmap(domain, bit)); generic_handle_domain_irq(domain, bit);
pending &= ~BIT(bit); pending &= ~BIT(bit);
} }

View file

@ -254,7 +254,7 @@ static void bcm2836_chained_handle_irq(struct irq_desc *desc)
u32 hwirq; u32 hwirq;
while ((hwirq = get_next_armctrl_hwirq()) != ~0) while ((hwirq = get_next_armctrl_hwirq()) != ~0)
generic_handle_irq(irq_linear_revmap(intc.domain, hwirq)); generic_handle_domain_irq(intc.domain, hwirq);
} }
IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic", IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic",

View file

@ -161,7 +161,7 @@ static void bcm2836_arm_irqchip_handle_ipi(struct irq_desc *desc)
mbox_val = readl_relaxed(intc.base + LOCAL_MAILBOX0_CLR0 + 16 * cpu); mbox_val = readl_relaxed(intc.base + LOCAL_MAILBOX0_CLR0 + 16 * cpu);
if (mbox_val) { if (mbox_val) {
int hwirq = ffs(mbox_val) - 1; int hwirq = ffs(mbox_val) - 1;
generic_handle_irq(irq_find_mapping(ipi_domain, hwirq)); generic_handle_domain_irq(ipi_domain, hwirq);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -145,10 +145,8 @@ static void bcm7038_l1_irq_handle(struct irq_desc *desc)
~cpu->mask_cache[idx]; ~cpu->mask_cache[idx];
raw_spin_unlock_irqrestore(&intc->lock, flags); raw_spin_unlock_irqrestore(&intc->lock, flags);
for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { for_each_set_bit(hwirq, &pending, IRQS_PER_WORD)
generic_handle_irq(irq_find_mapping(intc->domain, generic_handle_domain_irq(intc->domain, base + hwirq);
base + hwirq));
}
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -74,10 +74,8 @@ static void bcm7120_l2_intc_irq_handle(struct irq_desc *desc)
data->irq_map_mask[idx]; data->irq_map_mask[idx];
irq_gc_unlock(gc); irq_gc_unlock(gc);
for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { for_each_set_bit(hwirq, &pending, IRQS_PER_WORD)
generic_handle_irq(irq_find_mapping(b->domain, generic_handle_domain_irq(b->domain, base + hwirq);
base + hwirq));
}
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -110,7 +110,7 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc)
do { do {
irq = ffs(status) - 1; irq = ffs(status) - 1;
status &= ~(1 << irq); status &= ~(1 << irq);
generic_handle_irq(irq_linear_revmap(b->domain, irq)); generic_handle_domain_irq(b->domain, irq);
} while (status); } while (status);
out: out:
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -62,9 +62,8 @@ static void dw_apb_ictl_handle_irq_cascaded(struct irq_desc *desc)
while (stat) { while (stat) {
u32 hwirq = ffs(stat) - 1; u32 hwirq = ffs(stat) - 1;
u32 virq = irq_find_mapping(d, gc->irq_base + hwirq); generic_handle_domain_irq(d, gc->irq_base + hwirq);
generic_handle_irq(virq);
stat &= ~BIT(hwirq); stat &= ~BIT(hwirq);
} }
} }

View file

@ -30,10 +30,8 @@ static int gic_runtime_resume(struct device *dev)
int ret; int ret;
ret = clk_bulk_prepare_enable(data->num_clocks, chip_pm->clks); ret = clk_bulk_prepare_enable(data->num_clocks, chip_pm->clks);
if (ret) { if (ret)
dev_err(dev, "clk_enable failed: %d\n", ret);
return ret; return ret;
}
/* /*
* On the very first resume, the pointer to chip_pm->chip_data * On the very first resume, the pointer to chip_pm->chip_data

View file

@ -323,10 +323,8 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
struct v2m_data *v2m; struct v2m_data *v2m;
v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL); v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL);
if (!v2m) { if (!v2m)
pr_err("Failed to allocate struct v2m_data.\n");
return -ENOMEM; return -ENOMEM;
}
INIT_LIST_HEAD(&v2m->entry); INIT_LIST_HEAD(&v2m->entry);
v2m->fwnode = fwnode; v2m->fwnode = fwnode;

View file

@ -4895,10 +4895,8 @@ static int its_init_vpe_domain(void)
entries = roundup_pow_of_two(nr_cpu_ids); entries = roundup_pow_of_two(nr_cpu_ids);
vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes), vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes),
GFP_KERNEL); GFP_KERNEL);
if (!vpe_proxy.vpes) { if (!vpe_proxy.vpes)
pr_err("ITS: Can't allocate GICv4 proxy device array\n");
return -ENOMEM; return -ENOMEM;
}
/* Use the last possible DevID */ /* Use the last possible DevID */
devid = GENMASK(device_ids(its) - 1, 0); devid = GENMASK(device_ids(its) - 1, 0);
@ -5314,10 +5312,8 @@ static void __init acpi_table_parse_srat_its(void)
its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map), its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map),
GFP_KERNEL); GFP_KERNEL);
if (!its_srat_maps) { if (!its_srat_maps)
pr_warn("SRAT: Failed to allocate memory for its_srat_maps!\n");
return; return;
}
acpi_table_parse_entries(ACPI_SIG_SRAT, acpi_table_parse_entries(ACPI_SIG_SRAT,
sizeof(struct acpi_table_srat), sizeof(struct acpi_table_srat),

View file

@ -375,8 +375,9 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
{ {
struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc); struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq, gic_irq; unsigned int gic_irq;
unsigned long status; unsigned long status;
int ret;
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
@ -386,14 +387,10 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
if (gic_irq == GICC_INT_SPURIOUS) if (gic_irq == GICC_INT_SPURIOUS)
goto out; goto out;
cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
if (unlikely(gic_irq < 32 || gic_irq > 1020)) {
handle_bad_irq(desc);
} else {
isb(); isb();
generic_handle_irq(cascade_irq); ret = generic_handle_domain_irq(chip_data->domain, gic_irq);
} if (unlikely(ret))
handle_bad_irq(desc);
out: out:
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }

View file

@ -34,15 +34,14 @@ static void goldfish_pic_cascade(struct irq_desc *desc)
{ {
struct goldfish_pic_data *gfpic = irq_desc_get_handler_data(desc); struct goldfish_pic_data *gfpic = irq_desc_get_handler_data(desc);
struct irq_chip *host_chip = irq_desc_get_chip(desc); struct irq_chip *host_chip = irq_desc_get_chip(desc);
u32 pending, hwirq, virq; u32 pending, hwirq;
chained_irq_enter(host_chip, desc); chained_irq_enter(host_chip, desc);
pending = readl(gfpic->base + GFPIC_REG_IRQ_PENDING); pending = readl(gfpic->base + GFPIC_REG_IRQ_PENDING);
while (pending) { while (pending) {
hwirq = __fls(pending); hwirq = __fls(pending);
virq = irq_linear_revmap(gfpic->irq_domain, hwirq); generic_handle_domain_irq(gfpic->irq_domain, hwirq);
generic_handle_irq(virq);
pending &= ~(1 << hwirq); pending &= ~(1 << hwirq);
} }

View file

@ -333,13 +333,11 @@ static void i8259_irq_dispatch(struct irq_desc *desc)
{ {
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *domain = irq_desc_get_handler_data(desc);
int hwirq = i8259_poll(); int hwirq = i8259_poll();
unsigned int irq;
if (hwirq < 0) if (hwirq < 0)
return; return;
irq = irq_linear_revmap(domain, hwirq); generic_handle_domain_irq(domain, hwirq);
generic_handle_irq(irq);
} }
int __init i8259_of_init(struct device_node *node, struct device_node *parent) int __init i8259_of_init(struct device_node *node, struct device_node *parent)

View file

@ -28,7 +28,7 @@ static void idt_irq_dispatch(struct irq_desc *desc)
{ {
struct idt_pic_data *idtpic = irq_desc_get_handler_data(desc); struct idt_pic_data *idtpic = irq_desc_get_handler_data(desc);
struct irq_chip *host_chip = irq_desc_get_chip(desc); struct irq_chip *host_chip = irq_desc_get_chip(desc);
u32 pending, hwirq, virq; u32 pending, hwirq;
chained_irq_enter(host_chip, desc); chained_irq_enter(host_chip, desc);
@ -36,9 +36,7 @@ static void idt_irq_dispatch(struct irq_desc *desc)
pending &= ~idtpic->gc->mask_cache; pending &= ~idtpic->gc->mask_cache;
while (pending) { while (pending) {
hwirq = __fls(pending); hwirq = __fls(pending);
virq = irq_linear_revmap(idtpic->irq_domain, hwirq); generic_handle_domain_irq(idtpic->irq_domain, hwirq);
if (virq)
generic_handle_irq(virq);
pending &= ~(1 << hwirq); pending &= ~(1 << hwirq);
} }

View file

@ -223,7 +223,7 @@ static void pdc_intc_perip_isr(struct irq_desc *desc)
{ {
unsigned int irq = irq_desc_get_irq(desc); unsigned int irq = irq_desc_get_irq(desc);
struct pdc_intc_priv *priv; struct pdc_intc_priv *priv;
unsigned int i, irq_no; unsigned int i;
priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc); priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
@ -237,14 +237,13 @@ static void pdc_intc_perip_isr(struct irq_desc *desc)
found: found:
/* pass on the interrupt */ /* pass on the interrupt */
irq_no = irq_linear_revmap(priv->domain, i); generic_handle_domain_irq(priv->domain, i);
generic_handle_irq(irq_no);
} }
static void pdc_intc_syswake_isr(struct irq_desc *desc) static void pdc_intc_syswake_isr(struct irq_desc *desc)
{ {
struct pdc_intc_priv *priv; struct pdc_intc_priv *priv;
unsigned int syswake, irq_no; unsigned int syswake;
unsigned int status; unsigned int status;
priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc); priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
@ -258,9 +257,7 @@ static void pdc_intc_syswake_isr(struct irq_desc *desc)
if (!(status & 1)) if (!(status & 1))
continue; continue;
irq_no = irq_linear_revmap(priv->domain, generic_handle_domain_irq(priv->domain, syswake_to_hwirq(syswake));
syswake_to_hwirq(syswake));
generic_handle_irq(irq_no);
} }
} }
@ -316,10 +313,8 @@ static int pdc_intc_probe(struct platform_device *pdev)
/* Allocate driver data */ /* Allocate driver data */
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) { if (!priv)
dev_err(&pdev->dev, "cannot allocate device data\n");
return -ENOMEM; return -ENOMEM;
}
raw_spin_lock_init(&priv->lock); raw_spin_lock_init(&priv->lock);
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
@ -356,10 +351,8 @@ static int pdc_intc_probe(struct platform_device *pdev)
/* Get peripheral IRQ numbers */ /* Get peripheral IRQ numbers */
priv->perip_irqs = devm_kcalloc(&pdev->dev, 4, priv->nr_perips, priv->perip_irqs = devm_kcalloc(&pdev->dev, 4, priv->nr_perips,
GFP_KERNEL); GFP_KERNEL);
if (!priv->perip_irqs) { if (!priv->perip_irqs)
dev_err(&pdev->dev, "cannot allocate perip IRQ list\n");
return -ENOMEM; return -ENOMEM;
}
for (i = 0; i < priv->nr_perips; ++i) { for (i = 0; i < priv->nr_perips; ++i) {
irq = platform_get_irq(pdev, 1 + i); irq = platform_get_irq(pdev, 1 + i);
if (irq < 0) if (irq < 0)

View file

@ -228,10 +228,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
} }
cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL); cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL);
if (!cd) { if (!cd)
pr_err("%pOF: kzalloc failed!\n", node);
return -ENOMEM; return -ENOMEM;
}
raw_spin_lock_init(&cd->rlock); raw_spin_lock_init(&cd->rlock);

View file

@ -182,18 +182,15 @@ static void imx_intmux_irq_handler(struct irq_desc *desc)
struct intmux_data *data = container_of(irqchip_data, struct intmux_data, struct intmux_data *data = container_of(irqchip_data, struct intmux_data,
irqchip_data[idx]); irqchip_data[idx]);
unsigned long irqstat; unsigned long irqstat;
int pos, virq; int pos;
chained_irq_enter(irq_desc_get_chip(desc), desc); chained_irq_enter(irq_desc_get_chip(desc), desc);
/* read the interrupt source pending status of this channel */ /* read the interrupt source pending status of this channel */
irqstat = readl_relaxed(data->regs + CHANIPR(idx)); irqstat = readl_relaxed(data->regs + CHANIPR(idx));
for_each_set_bit(pos, &irqstat, 32) { for_each_set_bit(pos, &irqstat, 32)
virq = irq_find_mapping(irqchip_data->domain, pos); generic_handle_domain_irq(irqchip_data->domain, pos);
if (virq)
generic_handle_irq(virq);
}
chained_irq_exit(irq_desc_get_chip(desc), desc); chained_irq_exit(irq_desc_get_chip(desc), desc);
} }

View file

@ -122,7 +122,7 @@ static void imx_irqsteer_irq_handler(struct irq_desc *desc)
for (i = 0; i < 2; i++, hwirq += 32) { for (i = 0; i < 2; i++, hwirq += 32) {
int idx = imx_irqsteer_get_reg_index(data, hwirq); int idx = imx_irqsteer_get_reg_index(data, hwirq);
unsigned long irqmap; unsigned long irqmap;
int pos, virq; int pos;
if (hwirq >= data->reg_num * 32) if (hwirq >= data->reg_num * 32)
break; break;
@ -130,11 +130,8 @@ static void imx_irqsteer_irq_handler(struct irq_desc *desc)
irqmap = readl_relaxed(data->regs + irqmap = readl_relaxed(data->regs +
CHANSTATUS(idx, data->reg_num)); CHANSTATUS(idx, data->reg_num));
for_each_set_bit(pos, &irqmap, 32) { for_each_set_bit(pos, &irqmap, 32)
virq = irq_find_mapping(data->domain, pos + hwirq); generic_handle_domain_irq(data->domain, pos + hwirq);
if (virq)
generic_handle_irq(virq);
}
} }
chained_irq_exit(irq_desc_get_chip(desc), desc); chained_irq_exit(irq_desc_get_chip(desc), desc);

View file

@ -38,7 +38,7 @@ static void ingenic_tcu_intc_cascade(struct irq_desc *desc)
irq_reg &= ~irq_mask; irq_reg &= ~irq_mask;
for_each_set_bit(i, (unsigned long *)&irq_reg, 32) for_each_set_bit(i, (unsigned long *)&irq_reg, 32)
generic_handle_irq(irq_linear_revmap(domain, i)); generic_handle_domain_irq(domain, i);
chained_irq_exit(irq_chip, desc); chained_irq_exit(irq_chip, desc);
} }

View file

@ -49,8 +49,7 @@ static irqreturn_t intc_cascade(int irq, void *data)
while (pending) { while (pending) {
int bit = __fls(pending); int bit = __fls(pending);
irq = irq_linear_revmap(domain, bit + (i * 32)); generic_handle_domain_irq(domain, bit + (i * 32));
generic_handle_irq(irq);
pending &= ~BIT(bit); pending &= ~BIT(bit);
} }
} }

View file

@ -89,7 +89,7 @@ static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq)
struct keystone_irq_device *kirq = keystone_irq; struct keystone_irq_device *kirq = keystone_irq;
unsigned long wa_lock_flags; unsigned long wa_lock_flags;
unsigned long pending; unsigned long pending;
int src, virq; int src, err;
dev_dbg(kirq->dev, "start irq %d\n", irq); dev_dbg(kirq->dev, "start irq %d\n", irq);
@ -104,16 +104,14 @@ static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq)
for (src = 0; src < KEYSTONE_N_IRQ; src++) { for (src = 0; src < KEYSTONE_N_IRQ; src++) {
if (BIT(src) & pending) { if (BIT(src) & pending) {
virq = irq_find_mapping(kirq->irqd, src);
dev_dbg(kirq->dev, "dispatch bit %d, virq %d\n",
src, virq);
if (!virq)
dev_warn(kirq->dev, "spurious irq detected hwirq %d, virq %d\n",
src, virq);
raw_spin_lock_irqsave(&kirq->wa_lock, wa_lock_flags); raw_spin_lock_irqsave(&kirq->wa_lock, wa_lock_flags);
generic_handle_irq(virq); err = generic_handle_domain_irq(kirq->irqd, src);
raw_spin_unlock_irqrestore(&kirq->wa_lock, raw_spin_unlock_irqrestore(&kirq->wa_lock,
wa_lock_flags); wa_lock_flags);
if (err)
dev_warn_ratelimited(kirq->dev, "spurious irq detected hwirq %d\n",
src);
} }
} }

View file

@ -48,7 +48,7 @@ static void htpic_irq_dispatch(struct irq_desc *desc)
break; break;
} }
generic_handle_irq(irq_linear_revmap(priv->domain, bit)); generic_handle_domain_irq(priv->domain, bit);
pending &= ~BIT(bit); pending &= ~BIT(bit);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -47,8 +47,8 @@ static void htvec_irq_dispatch(struct irq_desc *desc)
while (pending) { while (pending) {
int bit = __ffs(pending); int bit = __ffs(pending);
generic_handle_irq(irq_linear_revmap(priv->htvec_domain, bit + generic_handle_domain_irq(priv->htvec_domain,
VEC_COUNT_PER_REG * i)); bit + VEC_COUNT_PER_REG * i);
pending &= ~BIT(bit); pending &= ~BIT(bit);
handled = true; handled = true;
} }

View file

@ -73,7 +73,7 @@ static void liointc_chained_handle_irq(struct irq_desc *desc)
while (pending) { while (pending) {
int bit = __ffs(pending); int bit = __ffs(pending);
generic_handle_irq(irq_find_mapping(gc->domain, bit)); generic_handle_domain_irq(gc->domain, bit);
pending &= ~BIT(bit); pending &= ~BIT(bit);
} }

View file

@ -141,7 +141,7 @@ static void lpc32xx_sic_handler(struct irq_desc *desc)
while (hwirq) { while (hwirq) {
irq = __ffs(hwirq); irq = __ffs(hwirq);
hwirq &= ~BIT(irq); hwirq &= ~BIT(irq);
generic_handle_irq(irq_find_mapping(ic->domain, irq)); generic_handle_domain_irq(ic->domain, irq);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -194,7 +194,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc); struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
struct ls_scfg_msi *msi_data = msir->msi_data; struct ls_scfg_msi *msi_data = msir->msi_data;
unsigned long val; unsigned long val;
int pos, size, virq, hwirq; int pos, size, hwirq;
chained_irq_enter(irq_desc_get_chip(desc), desc); chained_irq_enter(irq_desc_get_chip(desc), desc);
@ -206,9 +206,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
for_each_set_bit_from(pos, &val, size) { for_each_set_bit_from(pos, &val, size) {
hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) | hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
msir->srs; msir->srs;
virq = irq_find_mapping(msi_data->parent, hwirq); generic_handle_domain_irq(msi_data->parent, hwirq);
if (virq)
generic_handle_irq(virq);
} }
chained_irq_exit(irq_desc_get_chip(desc), desc); chained_irq_exit(irq_desc_get_chip(desc), desc);

View file

@ -50,7 +50,7 @@ static void ls1x_chained_handle_irq(struct irq_desc *desc)
while (pending) { while (pending) {
int bit = __ffs(pending); int bit = __ffs(pending);
generic_handle_irq(irq_find_mapping(priv->domain, bit)); generic_handle_domain_irq(priv->domain, bit);
pending &= ~BIT(bit); pending &= ~BIT(bit);
} }

View file

@ -273,6 +273,12 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
} }
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static const struct acpi_device_id mbigen_acpi_match[] = {
{ "HISI0152", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
static int mbigen_acpi_create_domain(struct platform_device *pdev, static int mbigen_acpi_create_domain(struct platform_device *pdev,
struct mbigen_device *mgn_chip) struct mbigen_device *mgn_chip)
{ {
@ -369,12 +375,6 @@ static const struct of_device_id mbigen_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, mbigen_of_match); MODULE_DEVICE_TABLE(of, mbigen_of_match);
static const struct acpi_device_id mbigen_acpi_match[] = {
{ "HISI0152", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
static struct platform_driver mbigen_platform_driver = { static struct platform_driver mbigen_platform_driver = {
.driver = { .driver = {
.name = "Hisilicon MBIGEN-V2", .name = "Hisilicon MBIGEN-V2",

View file

@ -16,6 +16,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/sched.h> #include <linux/sched.h>
@ -147,7 +148,7 @@ int gic_get_c0_fdc_int(void)
static void gic_handle_shared_int(bool chained) static void gic_handle_shared_int(bool chained)
{ {
unsigned int intr, virq; unsigned int intr;
unsigned long *pcpu_mask; unsigned long *pcpu_mask;
DECLARE_BITMAP(pending, GIC_MAX_INTRS); DECLARE_BITMAP(pending, GIC_MAX_INTRS);
@ -164,12 +165,12 @@ static void gic_handle_shared_int(bool chained)
bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
for_each_set_bit(intr, pending, gic_shared_intrs) { for_each_set_bit(intr, pending, gic_shared_intrs) {
virq = irq_linear_revmap(gic_irq_domain,
GIC_SHARED_TO_HWIRQ(intr));
if (chained) if (chained)
generic_handle_irq(virq); generic_handle_domain_irq(gic_irq_domain,
GIC_SHARED_TO_HWIRQ(intr));
else else
do_IRQ(virq); do_IRQ(irq_find_mapping(gic_irq_domain,
GIC_SHARED_TO_HWIRQ(intr)));
} }
} }
@ -307,7 +308,7 @@ static struct irq_chip gic_edge_irq_controller = {
static void gic_handle_local_int(bool chained) static void gic_handle_local_int(bool chained)
{ {
unsigned long pending, masked; unsigned long pending, masked;
unsigned int intr, virq; unsigned int intr;
pending = read_gic_vl_pend(); pending = read_gic_vl_pend();
masked = read_gic_vl_mask(); masked = read_gic_vl_mask();
@ -315,12 +316,12 @@ static void gic_handle_local_int(bool chained)
bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
for_each_set_bit(intr, &pending, GIC_NUM_LOCAL_INTRS) { for_each_set_bit(intr, &pending, GIC_NUM_LOCAL_INTRS) {
virq = irq_linear_revmap(gic_irq_domain,
GIC_LOCAL_TO_HWIRQ(intr));
if (chained) if (chained)
generic_handle_irq(virq); generic_handle_domain_irq(gic_irq_domain,
GIC_LOCAL_TO_HWIRQ(intr));
else else
do_IRQ(virq); do_IRQ(irq_find_mapping(gic_irq_domain,
GIC_LOCAL_TO_HWIRQ(intr)));
} }
} }

View file

@ -107,7 +107,7 @@ static void ocelot_irq_handler(struct irq_desc *desc)
while (reg) { while (reg) {
u32 hwirq = __fls(reg); u32 hwirq = __fls(reg);
generic_handle_irq(irq_find_mapping(d, hwirq)); generic_handle_domain_irq(d, hwirq);
reg &= ~(BIT(hwirq)); reg &= ~(BIT(hwirq));
} }

View file

@ -91,15 +91,12 @@ static void mvebu_pic_handle_cascade_irq(struct irq_desc *desc)
struct mvebu_pic *pic = irq_desc_get_handler_data(desc); struct mvebu_pic *pic = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned long irqmap, irqn; unsigned long irqmap, irqn;
unsigned int cascade_irq;
irqmap = readl_relaxed(pic->base + PIC_CAUSE); irqmap = readl_relaxed(pic->base + PIC_CAUSE);
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) { for_each_set_bit(irqn, &irqmap, BITS_PER_LONG)
cascade_irq = irq_find_mapping(pic->domain, irqn); generic_handle_domain_irq(pic->domain, irqn);
generic_handle_irq(cascade_irq);
}
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }

View file

@ -337,17 +337,12 @@ static void mvebu_sei_handle_cascade_irq(struct irq_desc *desc)
irqmap = readl_relaxed(sei->base + GICP_SECR(idx)); irqmap = readl_relaxed(sei->base + GICP_SECR(idx));
for_each_set_bit(bit, &irqmap, SEI_IRQ_COUNT_PER_REG) { for_each_set_bit(bit, &irqmap, SEI_IRQ_COUNT_PER_REG) {
unsigned long hwirq; unsigned long hwirq;
unsigned int virq; int err;
hwirq = idx * SEI_IRQ_COUNT_PER_REG + bit; hwirq = idx * SEI_IRQ_COUNT_PER_REG + bit;
virq = irq_find_mapping(sei->sei_domain, hwirq); err = generic_handle_domain_irq(sei->sei_domain, hwirq);
if (likely(virq)) { if (unlikely(err))
generic_handle_irq(virq); dev_warn(sei->dev, "Spurious IRQ detected (hwirq %lu)\n", hwirq);
continue;
}
dev_warn(sei->dev,
"Spurious IRQ detected (hwirq %lu)\n", hwirq);
} }
} }

View file

@ -40,9 +40,7 @@ static struct irq_domain *nvic_irq_domain;
asmlinkage void __exception_irq_entry asmlinkage void __exception_irq_entry
nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
{ {
unsigned int irq = irq_linear_revmap(nvic_irq_domain, hwirq); handle_domain_irq(nvic_irq_domain, hwirq, regs);
handle_IRQ(irq, regs);
} }
static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,

View file

@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(struct irq_desc *desc)
while (stat) { while (stat) {
u32 hwirq = __fls(stat); u32 hwirq = __fls(stat);
generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq)); generic_handle_domain_irq(d, gc->irq_base + hwirq);
stat &= ~(1 << hwirq); stat &= ~(1 << hwirq);
} }
} }

View file

@ -124,13 +124,10 @@ static void partition_handle_irq(struct irq_desc *desc)
break; break;
} }
if (unlikely(hwirq == part->nr_parts)) { if (unlikely(hwirq == part->nr_parts))
handle_bad_irq(desc); handle_bad_irq(desc);
} else { else
unsigned int irq; generic_handle_domain_irq(part->domain, hwirq);
irq = irq_find_mapping(part->domain, hwirq);
generic_handle_irq(irq);
}
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }

View file

@ -488,8 +488,7 @@ static void pruss_intc_irq_handler(struct irq_desc *desc)
while (true) { while (true) {
u32 hipir; u32 hipir;
unsigned int virq; int hwirq, err;
int hwirq;
/* get highest priority pending PRUSS system event */ /* get highest priority pending PRUSS system event */
hipir = pruss_intc_read_reg(intc, PRU_INTC_HIPIR(host_irq)); hipir = pruss_intc_read_reg(intc, PRU_INTC_HIPIR(host_irq));
@ -497,16 +496,14 @@ static void pruss_intc_irq_handler(struct irq_desc *desc)
break; break;
hwirq = hipir & GENMASK(9, 0); hwirq = hipir & GENMASK(9, 0);
virq = irq_find_mapping(intc->domain, hwirq); err = generic_handle_domain_irq(intc->domain, hwirq);
/* /*
* NOTE: manually ACK any system events that do not have a * NOTE: manually ACK any system events that do not have a
* handler mapped yet * handler mapped yet
*/ */
if (WARN_ON_ONCE(!virq)) if (WARN_ON_ONCE(err))
pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq);
else
generic_handle_irq(virq);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -85,7 +85,7 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
goto out; goto out;
} }
domain = irq_desc_get_handler_data(desc); domain = irq_desc_get_handler_data(desc);
generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); generic_handle_domain_irq(domain, __ffs(pending));
out: out:
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -115,7 +115,7 @@ static irqreturn_t irqc_irq_handler(int irq, void *dev_id)
if (ioread32(p->iomem + DETECT_STATUS) & bit) { if (ioread32(p->iomem + DETECT_STATUS) & bit) {
iowrite32(bit, p->iomem + DETECT_STATUS); iowrite32(bit, p->iomem + DETECT_STATUS);
irqc_dbg(i, "demux2"); irqc_dbg(i, "demux2");
generic_handle_irq(irq_find_mapping(p->irq_domain, i->hw_irq)); generic_handle_domain_irq(p->irq_domain, i->hw_irq);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
return IRQ_NONE; return IRQ_NONE;

View file

@ -233,13 +233,11 @@ static void plic_handle_irq(struct irq_desc *desc)
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
while ((hwirq = readl(claim))) { while ((hwirq = readl(claim))) {
int irq = irq_find_mapping(handler->priv->irqdomain, hwirq); int err = generic_handle_domain_irq(handler->priv->irqdomain,
hwirq);
if (unlikely(irq <= 0)) if (unlikely(err))
pr_warn_ratelimited("can't find mapping for hwirq %lu\n", pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
hwirq); hwirq);
else
generic_handle_irq(irq);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);

View file

@ -257,7 +257,7 @@ static void stm32_irq_handler(struct irq_desc *desc)
{ {
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *domain = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int virq, nbanks = domain->gc->num_chips; unsigned int nbanks = domain->gc->num_chips;
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
unsigned long pending; unsigned long pending;
int n, i, irq_base = 0; int n, i, irq_base = 0;
@ -268,10 +268,8 @@ static void stm32_irq_handler(struct irq_desc *desc)
gc = irq_get_domain_generic_chip(domain, irq_base); gc = irq_get_domain_generic_chip(domain, irq_base);
while ((pending = stm32_exti_pending(gc))) { while ((pending = stm32_exti_pending(gc))) {
for_each_set_bit(n, &pending, IRQS_PER_BANK) { for_each_set_bit(n, &pending, IRQS_PER_BANK)
virq = irq_find_mapping(domain, irq_base + n); generic_handle_domain_irq(domain, irq_base + n);
generic_handle_irq(virq);
}
} }
} }

View file

@ -147,10 +147,8 @@ static int __init sun4i_ic_of_init(struct device_node *node,
struct device_node *parent) struct device_node *parent)
{ {
irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL); irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL);
if (!irq_ic_data) { if (!irq_ic_data)
pr_err("kzalloc failed!\n");
return -ENOMEM; return -ENOMEM;
}
irq_ic_data->enable_reg_offset = SUN4I_IRQ_ENABLE_REG_OFFSET; irq_ic_data->enable_reg_offset = SUN4I_IRQ_ENABLE_REG_OFFSET;
irq_ic_data->mask_reg_offset = SUN4I_IRQ_MASK_REG_OFFSET; irq_ic_data->mask_reg_offset = SUN4I_IRQ_MASK_REG_OFFSET;
@ -164,10 +162,8 @@ static int __init suniv_ic_of_init(struct device_node *node,
struct device_node *parent) struct device_node *parent)
{ {
irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL); irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL);
if (!irq_ic_data) { if (!irq_ic_data)
pr_err("kzalloc failed!\n");
return -ENOMEM; return -ENOMEM;
}
irq_ic_data->enable_reg_offset = SUNIV_IRQ_ENABLE_REG_OFFSET; irq_ic_data->enable_reg_offset = SUNIV_IRQ_ENABLE_REG_OFFSET;
irq_ic_data->mask_reg_offset = SUNIV_IRQ_MASK_REG_OFFSET; irq_ic_data->mask_reg_offset = SUNIV_IRQ_MASK_REG_OFFSET;

View file

@ -88,10 +88,9 @@ static void sunxi_sc_nmi_handle_irq(struct irq_desc *desc)
{ {
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *domain = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int virq = irq_find_mapping(domain, 0);
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
generic_handle_irq(virq); generic_handle_domain_irq(domain, 0);
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }

View file

@ -91,7 +91,7 @@ static void tb10x_irq_cascade(struct irq_desc *desc)
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *domain = irq_desc_get_handler_data(desc);
unsigned int irq = irq_desc_get_irq(desc); unsigned int irq = irq_desc_get_irq(desc);
generic_handle_irq(irq_find_mapping(domain, irq)); generic_handle_domain_irq(domain, irq);
} }
static int __init of_tb10x_init_irq(struct device_node *ictl, static int __init of_tb10x_init_irq(struct device_node *ictl,

View file

@ -147,7 +147,7 @@ static void ti_sci_inta_irq_handler(struct irq_desc *desc)
struct ti_sci_inta_vint_desc *vint_desc; struct ti_sci_inta_vint_desc *vint_desc;
struct ti_sci_inta_irq_domain *inta; struct ti_sci_inta_irq_domain *inta;
struct irq_domain *domain; struct irq_domain *domain;
unsigned int virq, bit; unsigned int bit;
unsigned long val; unsigned long val;
vint_desc = irq_desc_get_handler_data(desc); vint_desc = irq_desc_get_handler_data(desc);
@ -159,11 +159,8 @@ static void ti_sci_inta_irq_handler(struct irq_desc *desc)
val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 + val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 +
VINT_STATUS_MASKED_OFFSET); VINT_STATUS_MASKED_OFFSET);
for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT) { for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT)
virq = irq_find_mapping(domain, vint_desc->events[bit].hwirq); generic_handle_domain_irq(domain, vint_desc->events[bit].hwirq);
if (virq)
generic_handle_irq(virq);
}
chained_irq_exit(irq_desc_get_chip(desc), desc); chained_irq_exit(irq_desc_get_chip(desc), desc);
} }

View file

@ -79,10 +79,9 @@ static void ts4800_ic_chained_handle_irq(struct irq_desc *desc)
do { do {
unsigned int bit = __ffs(status); unsigned int bit = __ffs(status);
int irq = irq_find_mapping(data->domain, bit);
generic_handle_domain_irq(data->domain, bit);
status &= ~(1 << bit); status &= ~(1 << bit);
generic_handle_irq(irq);
} while (status); } while (status);
out: out:

View file

@ -85,7 +85,7 @@ static void fpga_irq_handle(struct irq_desc *desc)
unsigned int irq = ffs(status) - 1; unsigned int irq = ffs(status) - 1;
status &= ~(1 << irq); status &= ~(1 << irq);
generic_handle_irq(irq_find_mapping(f->domain, irq)); generic_handle_domain_irq(f->domain, irq);
} while (status); } while (status);
out: out:

View file

@ -225,7 +225,7 @@ static void vic_handle_irq_cascaded(struct irq_desc *desc)
while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
hwirq = ffs(stat) - 1; hwirq = ffs(stat) - 1;
generic_handle_irq(irq_find_mapping(vic->domain, hwirq)); generic_handle_domain_irq(vic->domain, hwirq);
} }
chained_irq_exit(host_chip, desc); chained_irq_exit(host_chip, desc);

View file

@ -110,20 +110,6 @@ static struct irq_chip intc_dev = {
.irq_mask_ack = intc_mask_ack, .irq_mask_ack = intc_mask_ack,
}; };
static unsigned int xintc_get_irq_local(struct xintc_irq_chip *irqc)
{
unsigned int irq = 0;
u32 hwirq;
hwirq = xintc_read(irqc, IVR);
if (hwirq != -1U)
irq = irq_find_mapping(irqc->root_domain, hwirq);
pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
return irq;
}
unsigned int xintc_get_irq(void) unsigned int xintc_get_irq(void)
{ {
unsigned int irq = -1; unsigned int irq = -1;
@ -164,15 +150,16 @@ static void xil_intc_irq_handler(struct irq_desc *desc)
{ {
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
struct xintc_irq_chip *irqc; struct xintc_irq_chip *irqc;
u32 pending;
irqc = irq_data_get_irq_handler_data(&desc->irq_data); irqc = irq_data_get_irq_handler_data(&desc->irq_data);
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
do { do {
pending = xintc_get_irq_local(irqc); u32 hwirq = xintc_read(irqc, IVR);
if (pending == 0)
if (hwirq == -1U)
break; break;
generic_handle_irq(pending);
generic_handle_domain_irq(irqc->root_domain, hwirq);
} while (true); } while (true);
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }

View file

@ -53,7 +53,6 @@ static void combiner_handle_irq(struct irq_desc *desc)
chained_irq_enter(chip, desc); chained_irq_enter(chip, desc);
for (reg = 0; reg < combiner->nregs; reg++) { for (reg = 0; reg < combiner->nregs; reg++) {
int virq;
int hwirq; int hwirq;
u32 bit; u32 bit;
u32 status; u32 status;
@ -70,10 +69,7 @@ static void combiner_handle_irq(struct irq_desc *desc)
bit = __ffs(status); bit = __ffs(status);
status &= ~(1 << bit); status &= ~(1 << bit);
hwirq = irq_nr(reg, bit); hwirq = irq_nr(reg, bit);
virq = irq_find_mapping(combiner->domain, hwirq); generic_handle_domain_irq(combiner->domain, hwirq);
if (virq > 0)
generic_handle_irq(virq);
} }
} }

View file

@ -11,9 +11,11 @@
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/soc/qcom/irq.h> #include <linux/soc/qcom/irq.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -459,4 +461,8 @@ fail:
return ret; return ret;
} }
IRQCHIP_DECLARE(qcom_pdc, "qcom,pdc", qcom_pdc_init); IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc)
IRQCHIP_MATCH("qcom,pdc", qcom_pdc_init)
IRQCHIP_PLATFORM_DRIVER_END(qcom_pdc)
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller");
MODULE_LICENSE("GPL v2");

View file

@ -14,6 +14,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>

View file

@ -13,6 +13,7 @@
#include <linux/dmapool.h> #include <linux/dmapool.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>

View file

@ -22,6 +22,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of.h>
#include <target/target_core_base.h> #include <target/target_core_base.h>
#include <target/target_core_fabric.h> #include <target/target_core_fabric.h>

View file

@ -50,8 +50,10 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/usb/hcd.h> #include <linux/usb/hcd.h>
#include <linux/prefetch.h> #include <linux/prefetch.h>
#include <linux/irqdomain.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of.h>
#include <asm/octeon/octeon.h> #include <asm/octeon/octeon.h>

View file

@ -54,6 +54,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/uasm.h> #include <asm/uasm.h>

View file

@ -64,6 +64,8 @@
* IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it. * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
* Users will enable it explicitly by enable_irq() or enable_nmi() * Users will enable it explicitly by enable_irq() or enable_nmi()
* later. * later.
* IRQF_NO_DEBUG - Exclude from runnaway detection for IPI and similar handlers,
* depends on IRQF_PERCPU.
*/ */
#define IRQF_SHARED 0x00000080 #define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100 #define IRQF_PROBE_SHARED 0x00000100
@ -78,6 +80,7 @@
#define IRQF_EARLY_RESUME 0x00020000 #define IRQF_EARLY_RESUME 0x00020000
#define IRQF_COND_SUSPEND 0x00040000 #define IRQF_COND_SUSPEND 0x00040000
#define IRQF_NO_AUTOEN 0x00080000 #define IRQF_NO_AUTOEN 0x00080000
#define IRQF_NO_DEBUG 0x00100000
#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)

View file

@ -72,6 +72,7 @@ enum irqchip_irq_state;
* mechanism and from core side polling. * mechanism and from core side polling.
* IRQ_DISABLE_UNLAZY - Disable lazy irq disable * IRQ_DISABLE_UNLAZY - Disable lazy irq disable
* IRQ_HIDDEN - Don't show up in /proc/interrupts * IRQ_HIDDEN - Don't show up in /proc/interrupts
* IRQ_NO_DEBUG - Exclude from note_interrupt() debugging
*/ */
enum { enum {
IRQ_TYPE_NONE = 0x00000000, IRQ_TYPE_NONE = 0x00000000,
@ -99,6 +100,7 @@ enum {
IRQ_IS_POLLED = (1 << 18), IRQ_IS_POLLED = (1 << 18),
IRQ_DISABLE_UNLAZY = (1 << 19), IRQ_DISABLE_UNLAZY = (1 << 19),
IRQ_HIDDEN = (1 << 20), IRQ_HIDDEN = (1 << 20),
IRQ_NO_DEBUG = (1 << 21),
}; };
#define IRQF_MODIFY_MASK \ #define IRQF_MODIFY_MASK \

View file

@ -158,25 +158,21 @@ static inline void generic_handle_irq_desc(struct irq_desc *desc)
desc->handle_irq(desc); desc->handle_irq(desc);
} }
int handle_irq_desc(struct irq_desc *desc);
int generic_handle_irq(unsigned int irq); int generic_handle_irq(unsigned int irq);
#ifdef CONFIG_HANDLE_DOMAIN_IRQ #ifdef CONFIG_IRQ_DOMAIN
/* /*
* Convert a HW interrupt number to a logical one using a IRQ domain, * Convert a HW interrupt number to a logical one using a IRQ domain,
* and handle the result interrupt number. Return -EINVAL if * and handle the result interrupt number. Return -EINVAL if
* conversion failed. Providing a NULL domain indicates that the * conversion failed.
* conversion has already been done.
*/ */
int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq);
bool lookup, struct pt_regs *regs);
static inline int handle_domain_irq(struct irq_domain *domain, #ifdef CONFIG_HANDLE_DOMAIN_IRQ
unsigned int hwirq, struct pt_regs *regs) int handle_domain_irq(struct irq_domain *domain,
{ unsigned int hwirq, struct pt_regs *regs);
return __handle_domain_irq(domain, hwirq, true, regs);
}
#ifdef CONFIG_IRQ_DOMAIN
int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
struct pt_regs *regs); struct pt_regs *regs);
#endif #endif

View file

@ -41,13 +41,11 @@ struct fwnode_handle;
struct irq_domain; struct irq_domain;
struct irq_chip; struct irq_chip;
struct irq_data; struct irq_data;
struct irq_desc;
struct cpumask; struct cpumask;
struct seq_file; struct seq_file;
struct irq_affinity_desc; struct irq_affinity_desc;
/* Number of irqs reserved for a legacy isa controller */
#define NUM_ISA_INTERRUPTS 16
#define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16 #define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
/** /**
@ -152,11 +150,10 @@ struct irq_domain_chip_generic;
* @parent: Pointer to parent irq_domain to support hierarchy irq_domains * @parent: Pointer to parent irq_domain to support hierarchy irq_domains
* *
* Revmap data, used internally by irq_domain * Revmap data, used internally by irq_domain
* @revmap_direct_max_irq: The largest hwirq that can be set for controllers that * @revmap_size: Size of the linear map table @revmap[]
* support direct mapping
* @revmap_size: Size of the linear map table @linear_revmap[]
* @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
* @linear_revmap: Linear table of hwirq->virq reverse mappings * @revmap_mutex: Lock for the revmap
* @revmap: Linear table of irq_data pointers
*/ */
struct irq_domain { struct irq_domain {
struct list_head link; struct list_head link;
@ -176,11 +173,10 @@ struct irq_domain {
/* reverse map data. The linear map gets appended to the irq_domain */ /* reverse map data. The linear map gets appended to the irq_domain */
irq_hw_number_t hwirq_max; irq_hw_number_t hwirq_max;
unsigned int revmap_direct_max_irq;
unsigned int revmap_size; unsigned int revmap_size;
struct radix_tree_root revmap_tree; struct radix_tree_root revmap_tree;
struct mutex revmap_tree_mutex; struct mutex revmap_mutex;
unsigned int linear_revmap[]; struct irq_data __rcu *revmap[];
}; };
/* Irq domain flags */ /* Irq domain flags */
@ -210,6 +206,9 @@ enum {
*/ */
IRQ_DOMAIN_MSI_NOMASK_QUIRK = (1 << 6), IRQ_DOMAIN_MSI_NOMASK_QUIRK = (1 << 6),
/* Irq domain doesn't translate anything */
IRQ_DOMAIN_FLAG_NO_MAP = (1 << 7),
/* /*
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
* for implementation specific purposes and ignored by the * for implementation specific purposes and ignored by the
@ -348,6 +347,8 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
{ {
return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data); return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
} }
#ifdef CONFIG_IRQ_DOMAIN_NOMAP
static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
unsigned int max_irq, unsigned int max_irq,
const struct irq_domain_ops *ops, const struct irq_domain_ops *ops,
@ -355,14 +356,10 @@ static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_nod
{ {
return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data); return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
} }
static inline struct irq_domain *irq_domain_add_legacy_isa(
struct device_node *of_node, extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
const struct irq_domain_ops *ops, #endif
void *host_data)
{
return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
host_data);
}
static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node, static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
const struct irq_domain_ops *ops, const struct irq_domain_ops *ops,
void *host_data) void *host_data)
@ -405,25 +402,37 @@ static inline unsigned int irq_create_mapping(struct irq_domain *host,
return irq_create_mapping_affinity(host, hwirq, NULL); return irq_create_mapping_affinity(host, hwirq, NULL);
} }
extern struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq,
unsigned int *irq);
static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
{
return __irq_resolve_mapping(domain, hwirq, NULL);
}
/** /**
* irq_linear_revmap() - Find a linux irq from a hw irq number. * irq_find_mapping() - Find a linux irq from a hw irq number.
* @domain: domain owning this hardware interrupt * @domain: domain owning this hardware interrupt
* @hwirq: hardware irq number in that domain space * @hwirq: hardware irq number in that domain space
*
* This is a fast path alternative to irq_find_mapping() that can be
* called directly by irq controller code to save a handful of
* instructions. It is always safe to call, but won't find irqs mapped
* using the radix tree.
*/ */
static inline unsigned int irq_find_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
{
unsigned int irq;
if (__irq_resolve_mapping(domain, hwirq, &irq))
return irq;
return 0;
}
static inline unsigned int irq_linear_revmap(struct irq_domain *domain, static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
irq_hw_number_t hwirq) irq_hw_number_t hwirq)
{ {
return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0; return irq_find_mapping(domain, hwirq);
} }
extern unsigned int irq_find_mapping(struct irq_domain *host,
irq_hw_number_t hwirq);
extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
extern const struct irq_domain_ops irq_domain_simple_ops; extern const struct irq_domain_ops irq_domain_simple_ops;

View file

@ -70,6 +70,11 @@ config IRQ_DOMAIN_HIERARCHY
bool bool
select IRQ_DOMAIN select IRQ_DOMAIN
# Support for obsolete non-mapping irq domains
config IRQ_DOMAIN_NOMAP
bool
select IRQ_DOMAIN
# Support for hierarchical fasteoi+edge and fasteoi+level handlers # Support for hierarchical fasteoi+edge and fasteoi+level handlers
config IRQ_FASTEOI_HIERARCHY_HANDLERS config IRQ_FASTEOI_HIERARCHY_HANDLERS
bool bool

Some files were not shown because too many files have changed in this diff Show more