Skip to content

Commit

Permalink
Merge tag 'irq-core-2024-03-10' 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:
 "Core:

   - Make affinity changes take effect immediately for interrupt
     threads. This reduces the impact on isolated CPUs as it pulls over
     the thread right away instead of doing it after the next hardware
     interrupt arrived.

   - Cleanup and improvements for the interrupt chip simulator

   - Deduplication of the interrupt descriptor initialization code so
     the sparse and non-sparse mode share more code.

  Drivers:

   - A set of conversions to platform_drivers::remove_new() which gets
     rid of the pointless return value.

   - A new driver for the Starfive JH8100 SoC

   - Support for Amlogic-T7 SoCs

   - Improvement for the interrupt handling and EOI management for the
     loongson interrupt controller.

   - The usual fixes and improvements all over the place"

* tag 'irq-core-2024-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (33 commits)
  irqchip/ts4800: Convert to platform_driver::remove_new() callback
  irqchip/stm32-exti: Convert to platform_driver::remove_new() callback
  irqchip/renesas-rza1: Convert to platform_driver::remove_new() callback
  irqchip/renesas-irqc: Convert to platform_driver::remove_new() callback
  irqchip/renesas-intc-irqpin: Convert to platform_driver::remove_new() callback
  irqchip/pruss-intc: Convert to platform_driver::remove_new() callback
  irqchip/mvebu-pic: Convert to platform_driver::remove_new() callback
  irqchip/madera: Convert to platform_driver::remove_new() callback
  irqchip/ls-scfg-msi: Convert to platform_driver::remove_new() callback
  irqchip/keystone: Convert to platform_driver::remove_new() callback
  irqchip/imx-irqsteer: Convert to platform_driver::remove_new() callback
  irqchip/imx-intmux: Convert to platform_driver::remove_new() callback
  irqchip/imgpdc: Convert to platform_driver::remove_new() callback
  irqchip: Add StarFive external interrupt controller
  dt-bindings: interrupt-controller: Add starfive,jh8100-intc
  arm64: dts: Add gpio_intc node for Amlogic-T7 SoCs
  irqchip/meson-gpio: Add support for Amlogic-T7 SoCs
  dt-bindings: interrupt-controller: Add support for Amlogic-T7 SoCs
  irqchip/vic: Fix a kernel-doc warning
  genirq: Wake interrupt threads immediately when changing affinity
  ...
  • Loading branch information
Linus Torvalds committed Mar 11, 2024
2 parents 045395d + f7f56d5 commit 02d4df7
Show file tree
Hide file tree
Showing 34 changed files with 537 additions and 266 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ properties:
- amlogic,meson-a1-gpio-intc
- amlogic,meson-s4-gpio-intc
- amlogic,c3-gpio-intc
- amlogic,t7-gpio-intc
- const: amlogic,meson-gpio-intc

reg:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/interrupt-controller/starfive,jh8100-intc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: StarFive External Interrupt Controller

description:
StarFive SoC JH8100 contain a external interrupt controller. It can be used
to handle high-level input interrupt signals. It also send the output
interrupt signal to RISC-V PLIC.

maintainers:
- Changhuang Liang <changhuang.liang@starfivetech.com>

properties:
compatible:
const: starfive,jh8100-intc

reg:
maxItems: 1

clocks:
description: APB clock for the interrupt controller
maxItems: 1

resets:
description: APB reset for the interrupt controller
maxItems: 1

interrupts:
maxItems: 1

interrupt-controller: true

"#interrupt-cells":
const: 1

required:
- compatible
- reg
- clocks
- resets
- interrupts
- interrupt-controller
- "#interrupt-cells"

additionalProperties: false

examples:
- |
interrupt-controller@12260000 {
compatible = "starfive,jh8100-intc";
reg = <0x12260000 0x10000>;
clocks = <&syscrg_ne 76>;
resets = <&syscrg_ne 13>;
interrupts = <45>;
interrupt-controller;
#interrupt-cells = <1>;
};
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -20952,6 +20952,12 @@ F: Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
F: drivers/phy/starfive/phy-jh7110-pcie.c
F: drivers/phy/starfive/phy-jh7110-usb.c

STARFIVE JH8100 EXTERNAL INTERRUPT CONTROLLER DRIVER
M: Changhuang Liang <changhuang.liang@starfivetech.com>
S: Supported
F: Documentation/devicetree/bindings/interrupt-controller/starfive,jh8100-intc.yaml
F: drivers/irqchip/irq-starfive-jh8100-intc.c

STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org>
M: Josh Poimboeuf <jpoimboe@kernel.org>
Expand Down
10 changes: 10 additions & 0 deletions arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@
};
};

gpio_intc: interrupt-controller@4080 {
compatible = "amlogic,t7-gpio-intc",
"amlogic,meson-gpio-intc";
reg = <0x0 0x4080 0x0 0x20>;
interrupt-controller;
#interrupt-cells = <2>;
amlogic,channel-interrupts =
<10 11 12 13 14 15 16 17 18 19 20 21>;
};

uart_a: serial@78000 {
compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
reg = <0x0 0x78000 0x0 0x18>;
Expand Down
11 changes: 11 additions & 0 deletions drivers/irqchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,17 @@ config SIFIVE_PLIC
select IRQ_DOMAIN_HIERARCHY
select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP

config STARFIVE_JH8100_INTC
bool "StarFive JH8100 External Interrupt Controller"
depends on ARCH_STARFIVE || COMPILE_TEST
default ARCH_STARFIVE
select IRQ_DOMAIN_HIERARCHY
help
This enables support for the INTC chip found in StarFive JH8100
SoC.

If you don't know what to do here, say Y.

config EXYNOS_IRQ_COMBINER
bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
Expand Down
1 change: 1 addition & 0 deletions drivers/irqchip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ obj-$(CONFIG_CSKY_MPINTC) += irq-csky-mpintc.o
obj-$(CONFIG_CSKY_APB_INTC) += irq-csky-apb-intc.o
obj-$(CONFIG_RISCV_INTC) += irq-riscv-intc.o
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
obj-$(CONFIG_STARFIVE_JH8100_INTC) += irq-starfive-jh8100-intc.o
obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
obj-$(CONFIG_IMX_INTMUX) += irq-imx-intmux.o
obj-$(CONFIG_IMX_MU_MSI) += irq-imx-mu-msi.o
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-bcm6345-l1.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,
else if (intc->n_words != n_words)
return -EINVAL;

cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, enable_cache, n_words),
GFP_KERNEL);
if (!cpu)
return -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-bcm7038-l1.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
return -EINVAL;
}

cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, mask_cache, n_words),
GFP_KERNEL);
if (!cpu)
return -ENOMEM;
Expand Down
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-gic-v3-its.c
Original file line number Diff line number Diff line change
Expand Up @@ -4436,12 +4436,12 @@ static const struct irq_domain_ops its_sgi_domain_ops = {

static int its_vpe_id_alloc(void)
{
return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
return ida_alloc_max(&its_vpeid_ida, ITS_MAX_VPEID - 1, GFP_KERNEL);
}

static void its_vpe_id_free(u16 id)
{
ida_simple_remove(&its_vpeid_ida, id);
ida_free(&its_vpeid_ida, id);
}

static int its_vpe_init(struct its_vpe *vpe)
Expand Down
51 changes: 20 additions & 31 deletions drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/percpu.h>
#include <linux/refcount.h>
#include <linux/slab.h>
#include <linux/iopoll.h>

#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic-common.h>
Expand Down Expand Up @@ -180,11 +181,6 @@ static enum gic_intid_range get_intid_range(struct irq_data *d)
return __get_intid_range(d->hwirq);
}

static inline unsigned int gic_irq(struct irq_data *d)
{
return d->hwirq;
}

static inline bool gic_irq_in_rdist(struct irq_data *d)
{
switch (get_intid_range(d)) {
Expand Down Expand Up @@ -251,17 +247,13 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)

static void gic_do_wait_for_rwp(void __iomem *base, u32 bit)
{
u32 count = 1000000; /* 1s! */
u32 val;
int ret;

while (readl_relaxed(base + GICD_CTLR) & bit) {
count--;
if (!count) {
pr_err_ratelimited("RWP timeout, gone fishing\n");
return;
}
cpu_relax();
udelay(1);
}
ret = readl_relaxed_poll_timeout_atomic(base + GICD_CTLR, val, !(val & bit),
1, USEC_PER_SEC);
if (ret == -ETIMEDOUT)
pr_err_ratelimited("RWP timeout, gone fishing\n");
}

/* Wait for completion of a distributor change */
Expand All @@ -279,8 +271,8 @@ static void gic_redist_wait_for_rwp(void)
static void gic_enable_redist(bool enable)
{
void __iomem *rbase;
u32 count = 1000000; /* 1s! */
u32 val;
int ret;

if (gic_data.flags & FLAGS_WORKAROUND_GICR_WAKER_MSM8996)
return;
Expand All @@ -301,16 +293,13 @@ static void gic_enable_redist(bool enable)
return; /* No PM support in this redistributor */
}

while (--count) {
val = readl_relaxed(rbase + GICR_WAKER);
if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep))
break;
cpu_relax();
udelay(1);
}
if (!count)
ret = readl_relaxed_poll_timeout_atomic(rbase + GICR_WAKER, val,
enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep),
1, USEC_PER_SEC);
if (ret == -ETIMEDOUT) {
pr_err_ratelimited("redistributor failed to %s...\n",
enable ? "wakeup" : "sleep");
}
}

/*
Expand Down Expand Up @@ -548,7 +537,7 @@ static int gic_irq_nmi_setup(struct irq_data *d)
* A secondary irq_chip should be in charge of LPI request,
* it should not be possible to get there
*/
if (WARN_ON(gic_irq(d) >= 8192))
if (WARN_ON(irqd_to_hwirq(d) >= 8192))
return -EINVAL;

/* desc lock should already be held */
Expand Down Expand Up @@ -588,7 +577,7 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
* A secondary irq_chip should be in charge of LPI request,
* it should not be possible to get there
*/
if (WARN_ON(gic_irq(d) >= 8192))
if (WARN_ON(irqd_to_hwirq(d) >= 8192))
return;

/* desc lock should already be held */
Expand Down Expand Up @@ -626,7 +615,7 @@ static bool gic_arm64_erratum_2941627_needed(struct irq_data *d)

static void gic_eoi_irq(struct irq_data *d)
{
write_gicreg(gic_irq(d), ICC_EOIR1_EL1);
write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);
isb();

if (gic_arm64_erratum_2941627_needed(d)) {
Expand All @@ -646,19 +635,19 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d)
* No need to deactivate an LPI, or an interrupt that
* is is getting forwarded to a vcpu.
*/
if (gic_irq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d))
if (irqd_to_hwirq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d))
return;

if (!gic_arm64_erratum_2941627_needed(d))
gic_write_dir(gic_irq(d));
gic_write_dir(irqd_to_hwirq(d));
else
gic_poke_irq(d, GICD_ICACTIVER);
}

static int gic_set_type(struct irq_data *d, unsigned int type)
{
irq_hw_number_t irq = irqd_to_hwirq(d);
enum gic_intid_range range;
unsigned int irq = gic_irq(d);
void __iomem *base;
u32 offset, index;
int ret;
Expand All @@ -684,7 +673,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
ret = gic_configure_irq(index, type, base + offset, NULL);
if (ret && (range == PPI_RANGE || range == EPPI_RANGE)) {
/* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI INTID%d is secure or misconfigured\n", irq);
pr_warn("GIC: PPI INTID%ld is secure or misconfigured\n", irq);
ret = 0;
}

Expand Down
27 changes: 12 additions & 15 deletions drivers/irqchip/irq-gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,6 @@ static inline void __iomem *gic_cpu_base(struct irq_data *d)
return gic_data_cpu_base(gic_data);
}

static inline unsigned int gic_irq(struct irq_data *d)
{
return d->hwirq;
}

static inline bool cascading_gic_irq(struct irq_data *d)
{
void *data = irq_data_get_irq_handler_data(d);
Expand All @@ -183,14 +178,16 @@ static inline bool cascading_gic_irq(struct irq_data *d)
*/
static void gic_poke_irq(struct irq_data *d, u32 offset)
{
u32 mask = 1 << (gic_irq(d) % 32);
writel_relaxed(mask, gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4);
u32 mask = 1 << (irqd_to_hwirq(d) % 32);

writel_relaxed(mask, gic_dist_base(d) + offset + (irqd_to_hwirq(d) / 32) * 4);
}

static int gic_peek_irq(struct irq_data *d, u32 offset)
{
u32 mask = 1 << (gic_irq(d) % 32);
return !!(readl_relaxed(gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4) & mask);
u32 mask = 1 << (irqd_to_hwirq(d) % 32);

return !!(readl_relaxed(gic_dist_base(d) + offset + (irqd_to_hwirq(d) / 32) * 4) & mask);
}

static void gic_mask_irq(struct irq_data *d)
Expand Down Expand Up @@ -220,7 +217,7 @@ static void gic_unmask_irq(struct irq_data *d)

static void gic_eoi_irq(struct irq_data *d)
{
u32 hwirq = gic_irq(d);
irq_hw_number_t hwirq = irqd_to_hwirq(d);

if (hwirq < 16)
hwirq = this_cpu_read(sgi_intid);
Expand All @@ -230,7 +227,7 @@ static void gic_eoi_irq(struct irq_data *d)

static void gic_eoimode1_eoi_irq(struct irq_data *d)
{
u32 hwirq = gic_irq(d);
irq_hw_number_t hwirq = irqd_to_hwirq(d);

/* Do not deactivate an IRQ forwarded to a vcpu. */
if (irqd_is_forwarded_to_vcpu(d))
Expand Down Expand Up @@ -293,8 +290,8 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,

static int gic_set_type(struct irq_data *d, unsigned int type)
{
irq_hw_number_t gicirq = irqd_to_hwirq(d);
void __iomem *base = gic_dist_base(d);
unsigned int gicirq = gic_irq(d);
int ret;

/* Interrupt configuration for SGIs can't be changed */
Expand All @@ -309,7 +306,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL);
if (ret && gicirq < 32) {
/* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16);
pr_warn("GIC: PPI%ld is secure or misconfigured\n", gicirq - 16);
ret = 0;
}

Expand All @@ -319,7 +316,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
{
/* Only interrupts on the primary GIC can be forwarded to a vcpu. */
if (cascading_gic_irq(d) || gic_irq(d) < 16)
if (cascading_gic_irq(d) || irqd_to_hwirq(d) < 16)
return -EINVAL;

if (vcpu)
Expand Down Expand Up @@ -796,7 +793,7 @@ static void rmw_writeb(u8 bval, void __iomem *addr)
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force)
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d);
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + irqd_to_hwirq(d);
struct gic_chip_data *gic = irq_data_get_irq_chip_data(d);
unsigned int cpu;

Expand Down
Loading

0 comments on commit 02d4df7

Please sign in to comment.