Skip to content

Commit

Permalink
Merge tag 'irq-core-2021-08-30' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "Updates to the interrupt core and driver subsystems:

  Core changes:

   - The usual set of small fixes and improvements all over the place,
     but nothing stands out

  MSI changes:

   - Further consolidation of the PCI/MSI interrupt chip code

   - Make MSI sysfs code independent of PCI/MSI and expose the MSI
     interrupts of platform devices in the same way as PCI exposes them.

  Driver changes:

   - Support for ARM GICv3 EPPI partitions

   - Treewide conversion to generic_handle_domain_irq() for all chained
     interrupt controllers

   - Conversion to bitmap_zalloc() throughout the irq chip drivers

   - The usual set of small fixes and improvements"

* tag 'irq-core-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (57 commits)
  platform-msi: Add ABI to show msi_irqs of platform devices
  genirq/msi: Move MSI sysfs handling from PCI to MSI core
  genirq/cpuhotplug: Demote debug printk to KERN_DEBUG
  irqchip/qcom-pdc: Trim unused levels of the interrupt hierarchy
  irqdomain: Export irq_domain_disconnect_hierarchy()
  irqchip/gic-v3: Fix priority comparison when non-secure priorities are used
  irqchip/apple-aic: Fix irq_disable from within irq handlers
  pinctrl/rockchip: drop the gpio related codes
  gpio/rockchip: drop irq_gc_lock/irq_gc_unlock for irq set type
  gpio/rockchip: support next version gpio controller
  gpio/rockchip: use struct rockchip_gpio_regs for gpio controller
  gpio/rockchip: add driver for rockchip gpio
  dt-bindings: gpio: change items restriction of clock for rockchip,gpio-bank
  pinctrl/rockchip: add pinctrl device to gpio bank struct
  pinctrl/rockchip: separate struct rockchip_pin_bank to a head file
  pinctrl/rockchip: always enable clock for gpio controller
  genirq: Fix kernel doc indentation
  EDAC/altera: Convert to generic_handle_domain_irq()
  powerpc: Bulk conversion to generic_handle_domain_irq()
  nios2: Bulk conversion to generic_handle_domain_irq()
  ...
  • Loading branch information
torvalds committed Aug 30, 2021
2 parents e5e726f + 47fb0cf commit 7d6e3fa
Show file tree
Hide file tree
Showing 147 changed files with 1,826 additions and 1,677 deletions.
14 changes: 14 additions & 0 deletions Documentation/ABI/testing/sysfs-bus-platform
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,17 @@ Description:
value comes from an ACPI _PXM method or a similar firmware
source. Initial users for this file would be devices like
arm smmu which are populated by arm64 acpi_iort.

What: /sys/bus/platform/devices/.../msi_irqs/
Date: August 2021
Contact: Barry Song <[email protected]>
Description:
The /sys/devices/.../msi_irqs directory contains a variable set
of files, with each file being named after a corresponding msi
irq vector allocated to that device.

What: /sys/bus/platform/devices/.../msi_irqs/<N>
Date: August 2021
Contact: Barry Song <[email protected]>
Description:
This attribute will show "msi" if <N> is a valid msi irq
28 changes: 25 additions & 3 deletions Documentation/core-api/irq/irq-domain.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,24 @@ exist then it will allocate a new Linux irq_desc, associate it with
the hwirq, and call the .map() callback so the driver can perform any
required hardware setup.

When an interrupt is received, irq_find_mapping() function should
be used to find the Linux IRQ number from the hwirq number.
Once a mapping has been established, it can be retrieved or used via a
variety of methods:

- irq_resolve_mapping() returns a pointer to the irq_desc structure
for a given domain and hwirq number, and NULL if there was no
mapping.
- irq_find_mapping() returns a Linux IRQ number for a given domain and
hwirq number, and 0 if there was no mapping
- irq_linear_revmap() is now identical to irq_find_mapping(), and is
deprecated
- generic_handle_domain_irq() handles an interrupt described by a
domain and a hwirq number
- handle_domain_irq() does the same thing for root interrupt
controllers and deals with the set_irq_reg()/irq_enter() sequences
that most architecture requires

Note that irq domain lookups must happen in contexts that are
compatible with a RCU read-side critical section.

The irq_create_mapping() function must be called *atleast once*
before any call to irq_find_mapping(), lest the descriptor will not
Expand Down Expand Up @@ -137,7 +153,9 @@ required. Calling irq_create_direct_mapping() will allocate a Linux
IRQ number and call the .map() callback so that driver can program the
Linux IRQ number into the hardware.

Most drivers cannot use this mapping.
Most drivers cannot use this mapping, and it is now gated on the
CONFIG_IRQ_DOMAIN_NOMAP option. Please refrain from introducing new
users of this API.

Legacy
------
Expand All @@ -157,6 +175,10 @@ for IRQ numbers that are passed to struct device registrations. In that
case the Linux IRQ numbers cannot be dynamically assigned and the legacy
mapping should be used.

As the name implies, the *_legacy() functions are deprecated and only
exist to ease the support of ancient platforms. No new users should be
added.
The legacy map assumes a contiguous range of IRQ numbers has already
been allocated for the controller and that the IRQ number can be
calculated by adding a fixed offset to the hwirq number, and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ properties:
maxItems: 1

clocks:
maxItems: 1
minItems: 1
items:
- description: APB interface clock source
- description: GPIO debounce reference clock source

gpio-controller: true

Expand Down
2 changes: 1 addition & 1 deletion arch/arc/kernel/mcip.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ static void idu_cascade_isr(struct irq_desc *desc)
irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ;

chained_irq_enter(core_chip, desc);
generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
generic_handle_domain_irq(idu_domain, idu_hwirq);
chained_irq_exit(core_chip, desc);
}

Expand Down
12 changes: 2 additions & 10 deletions arch/arm/common/sa1111.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,6 @@ static int sa1111_map_irq(struct sa1111 *sachip, irq_hw_number_t hwirq)
return irq_create_mapping(sachip->irqdomain, hwirq);
}

static void sa1111_handle_irqdomain(struct irq_domain *irqdomain, int irq)
{
struct irq_desc *d = irq_to_desc(irq_linear_revmap(irqdomain, irq));

if (d)
generic_handle_irq_desc(d);
}

/*
* SA1111 interrupt support. Since clearing an IRQ while there are
* active IRQs causes the interrupt output to pulse, the upper levels
Expand Down Expand Up @@ -234,11 +226,11 @@ static void sa1111_irq_handler(struct irq_desc *desc)

for (i = 0; stat0; i++, stat0 >>= 1)
if (stat0 & 1)
sa1111_handle_irqdomain(irqdomain, i);
generic_handle_domain_irq(irqdomain, i);

for (i = 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1)
sa1111_handle_irqdomain(irqdomain, i);
generic_handle_domain_irq(irqdomain, i);

/* For level-based interrupts */
desc->irq_data.chip->irq_unmask(&desc->irq_data);
Expand Down
6 changes: 2 additions & 4 deletions arch/arm/mach-pxa/pxa_cplds_irqs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)

do {
pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
generic_handle_irq(irq_find_mapping(fpga->irqdomain,
bit));
}
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
generic_handle_domain_irq(fpga->irqdomain, bit);
} while (pending);

return IRQ_HANDLED;
Expand Down
5 changes: 2 additions & 3 deletions arch/arm/mach-s3c/irq-s3c24xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ static void s3c_irq_demux(struct irq_desc *desc)
struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
struct s3c_irq_intc *intc = irq_data->intc;
struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
unsigned int n, offset, irq;
unsigned int n, offset;
unsigned long src, msk;

/* we're using individual domains for the non-dt case
Expand All @@ -318,8 +318,7 @@ static void s3c_irq_demux(struct irq_desc *desc)
while (src) {
n = __ffs(src);
src &= ~(1 << n);
irq = irq_find_mapping(sub_intc->domain, offset + n);
generic_handle_irq(irq);
generic_handle_domain_irq(sub_intc->domain, offset + n);
}

chained_irq_exit(chip, desc);
Expand Down
14 changes: 7 additions & 7 deletions arch/mips/ath25/ar2315.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,24 @@ static void ar2315_misc_irq_handler(struct irq_desc *desc)
{
u32 pending = ar2315_rst_reg_read(AR2315_ISR) &
ar2315_rst_reg_read(AR2315_IMR);
unsigned nr, misc_irq = 0;
unsigned nr;
int ret = 0;

if (pending) {
struct irq_domain *domain = irq_desc_get_handler_data(desc);

nr = __ffs(pending);
misc_irq = irq_find_mapping(domain, nr);
}

if (misc_irq) {
if (nr == AR2315_MISC_IRQ_GPIO)
ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO);
else if (nr == AR2315_MISC_IRQ_WATCHDOG)
ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD);
generic_handle_irq(misc_irq);
} else {
spurious_interrupt();

ret = generic_handle_domain_irq(domain, nr);
}

if (!pending || ret)
spurious_interrupt();
}

static void ar2315_misc_irq_unmask(struct irq_data *d)
Expand Down
13 changes: 6 additions & 7 deletions arch/mips/ath25/ar5312.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,21 @@ static void ar5312_misc_irq_handler(struct irq_desc *desc)
{
u32 pending = ar5312_rst_reg_read(AR5312_ISR) &
ar5312_rst_reg_read(AR5312_IMR);
unsigned nr, misc_irq = 0;
unsigned nr;
int ret = 0;

if (pending) {
struct irq_domain *domain = irq_desc_get_handler_data(desc);

nr = __ffs(pending);
misc_irq = irq_find_mapping(domain, nr);
}

if (misc_irq) {
generic_handle_irq(misc_irq);
ret = generic_handle_domain_irq(domain, nr);
if (nr == AR5312_MISC_IRQ_TIMER)
ar5312_rst_reg_read(AR5312_TIMER);
} else {
spurious_interrupt();
}

if (!pending || ret)
spurious_interrupt();
}

/* Enable the specified AR5312_MISC_IRQ interrupt */
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/lantiq/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ static void ltq_hw_irq_handler(struct irq_desc *desc)
*/
irq = __fls(irq);
hwirq = irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module);
generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq));
generic_handle_domain_irq(ltq_domain, hwirq);

/* if this is a EBU irq, we need to ack it or get a deadlock */
if (irq == LTQ_ICU_EBU_IRQ && !module && LTQ_EBU_PCC_ISTAT != 0)
Expand Down
8 changes: 3 additions & 5 deletions arch/mips/pci/pci-ar2315.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,14 +337,12 @@ static void ar2315_pci_irq_handler(struct irq_desc *desc)
struct ar2315_pci_ctrl *apc = irq_desc_get_handler_data(desc);
u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) &
ar2315_pci_reg_read(apc, AR2315_PCI_IMR);
unsigned pci_irq = 0;
int ret = 0;

if (pending)
pci_irq = irq_find_mapping(apc->domain, __ffs(pending));
ret = generic_handle_domain_irq(apc->domain, __ffs(pending));

if (pci_irq)
generic_handle_irq(pci_irq);
else
if (!pending || ret)
spurious_interrupt();
}

Expand Down
5 changes: 2 additions & 3 deletions arch/mips/pci/pci-rt3883.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,9 @@ static void rt3883_pci_irq_handler(struct irq_desc *desc)
}

while (pending) {
unsigned irq, bit = __ffs(pending);
unsigned bit = __ffs(pending);

irq = irq_find_mapping(rpc->irq_domain, bit);
generic_handle_irq(irq);
generic_handle_domain_irq(rpc->irq_domain, bit);

pending &= ~BIT(bit);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/ralink/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static void ralink_intc_irq_handler(struct irq_desc *desc)

if (pending) {
struct irq_domain *domain = irq_desc_get_handler_data(desc);
generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
generic_handle_domain_irq(domain, __ffs(pending));
} else {
spurious_interrupt();
}
Expand Down
16 changes: 6 additions & 10 deletions arch/mips/sgi-ip27/ip27-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
unsigned long *mask = per_cpu(irq_enable_mask, cpu);
struct irq_domain *domain;
u64 pend0;
int irq;
int ret;

/* copied from Irix intpend0() */
pend0 = LOCAL_HUB_L(PI_INT_PEND0);
Expand All @@ -216,10 +216,8 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
#endif
{
domain = irq_desc_get_handler_data(desc);
irq = irq_linear_revmap(domain, __ffs(pend0));
if (irq)
generic_handle_irq(irq);
else
ret = generic_handle_domain_irq(domain, __ffs(pend0));
if (ret)
spurious_interrupt();
}

Expand All @@ -232,7 +230,7 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
unsigned long *mask = per_cpu(irq_enable_mask, cpu);
struct irq_domain *domain;
u64 pend1;
int irq;
int ret;

/* copied from Irix intpend0() */
pend1 = LOCAL_HUB_L(PI_INT_PEND1);
Expand All @@ -242,10 +240,8 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
return;

domain = irq_desc_get_handler_data(desc);
irq = irq_linear_revmap(domain, __ffs(pend1) + 64);
if (irq)
generic_handle_irq(irq);
else
ret = generic_handle_domain_irq(domain, __ffs(pend1) + 64);
if (ret)
spurious_interrupt();

LOCAL_HUB_L(PI_INT_PEND1);
Expand Down
8 changes: 3 additions & 5 deletions arch/mips/sgi-ip30/ip30-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void ip30_normal_irq(struct irq_desc *desc)
int cpu = smp_processor_id();
struct irq_domain *domain;
u64 pend, mask;
int irq;
int ret;

pend = heart_read(&heart_regs->isr);
mask = (heart_read(&heart_regs->imr[cpu]) &
Expand Down Expand Up @@ -130,10 +130,8 @@ static void ip30_normal_irq(struct irq_desc *desc)
#endif
{
domain = irq_desc_get_handler_data(desc);
irq = irq_linear_revmap(domain, __ffs(pend));
if (irq)
generic_handle_irq(irq);
else
ret = generic_handle_domain_irq(domain, __ffs(pend));
if (ret)
spurious_interrupt();
}
}
Expand Down
4 changes: 1 addition & 3 deletions arch/nios2/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ static u32 ienable;
asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
{
struct pt_regs *oldregs = set_irq_regs(regs);
int irq;

irq_enter();
irq = irq_find_mapping(NULL, hwirq);
generic_handle_irq(irq);
generic_handle_domain_irq(NULL, hwirq);
irq_exit();

set_irq_regs(oldregs);
Expand Down
4 changes: 1 addition & 3 deletions arch/powerpc/platforms/4xx/uic.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ static void uic_irq_cascade(struct irq_desc *desc)
struct uic *uic = irq_desc_get_handler_data(desc);
u32 msr;
int src;
int subvirq;

raw_spin_lock(&desc->lock);
if (irqd_is_level_type(idata))
Expand All @@ -213,8 +212,7 @@ static void uic_irq_cascade(struct irq_desc *desc)

src = 32 - ffs(msr);

subvirq = irq_linear_revmap(uic->irqhost, src);
generic_handle_irq(subvirq);
generic_handle_domain_irq(uic->irqhost, src);

uic_irq_ret:
raw_spin_lock(&desc->lock);
Expand Down
Loading

0 comments on commit 7d6e3fa

Please sign in to comment.