Skip to content

Commit

Permalink
Merge tag 'irq-core-2020-08-04' 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:
 "The usual boring updates from the interrupt subsystem:

   - Infrastructure to allow building irqchip drivers as modules

   - Consolidation of irqchip ACPI probing

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

   - Cleanups, fixes and improvements all over the place"

* tag 'irq-core-2020-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (51 commits)
  irqchip/loongson-pch-pic: Fix the misused irq flow handler
  irqchip/loongson-htvec: Support 8 groups of HT vectors
  irqchip/loongson-liointc: Fix misuse of gc->mask_cache
  dt-bindings: interrupt-controller: Update Loongson HTVEC description
  irqchip/imx-intmux: Fix irqdata regs save in imx_intmux_runtime_suspend()
  irqchip/imx-intmux: Implement intmux runtime power management
  irqchip/gic-v4.1: Use GFP_ATOMIC flag in allocate_vpe_l1_table()
  irqchip: Fix IRQCHIP_PLATFORM_DRIVER_* compilation by including module.h
  irqchip/stm32-exti: Map direct event to irq parent
  irqchip/mtk-cirq: Convert to a platform driver
  irqchip/mtk-sysirq: Convert to a platform driver
  irqchip/qcom-pdc: Switch to using IRQCHIP_PLATFORM_DRIVER helper macros
  irqchip: Add IRQCHIP_PLATFORM_DRIVER_BEGIN/END and IRQCHIP_MATCH helper macros
  irqchip: irq-bcm2836.h: drop a duplicated word
  irqchip/gic-v4.1: Ensure accessing the correct RD when writing INVALLR
  irqchip/irq-bcm7038-l1: Guard uses of cpu_logical_map
  irqchip/gic-v3: Remove unused register definition
  irqchip/qcom-pdc: Allow QCOM_PDC to be loadable as a permanent module
  genirq: Export irq_chip_retrigger_hierarchy and irq_chip_set_vcpu_affinity_parent
  irqdomain: Export irq_domain_update_bus_token
  ...
  • Loading branch information
Linus Torvalds committed Aug 5, 2020
2 parents 2ed90db + 3d5128c commit f8b036a
Showing 36 changed files with 346 additions and 244 deletions.
Original file line number Diff line number Diff line change
@@ -2,7 +2,10 @@ Broadcom Generic Level 2 Interrupt Controller

Required properties:

- compatible: should be "brcm,l2-intc" for latched interrupt controllers
- compatible: should be one of:
"brcm,hif-spi-l2-intc" or
"brcm,upg-aux-aon-l2-intc" or
"brcm,l2-intc" for latched interrupt controllers
should be "brcm,bcm7271-l2-intc" for level interrupt controllers
- reg: specifies the base physical address and size of the registers
- interrupt-controller: identifies the node as an interrupt controller
Original file line number Diff line number Diff line change
@@ -22,8 +22,8 @@ properties:

interrupts:
minItems: 1
maxItems: 4
description: Four parent interrupts that receive chained interrupts.
maxItems: 8
description: Eight parent interrupts that receive chained interrupts.

interrupt-controller: true

1 change: 0 additions & 1 deletion arch/sparc/Kconfig
Original file line number Diff line number Diff line change
@@ -81,7 +81,6 @@ config SPARC64
select RTC_DRV_STARFIRE
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select IRQ_PREFLOW_FASTEOI
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select HAVE_C_RECORDMCOUNT
select HAVE_ARCH_AUDITSYSCALL
3 changes: 1 addition & 2 deletions drivers/irqchip/Kconfig
Original file line number Diff line number Diff line change
@@ -425,7 +425,7 @@ config GOLDFISH_PIC
for Goldfish based virtual platforms.

config QCOM_PDC
bool "QCOM PDC"
tristate "QCOM PDC"
depends on ARCH_QCOM
select IRQ_DOMAIN_HIERARCHY
help
@@ -541,7 +541,6 @@ config LOONGSON_HTPIC
default y
select IRQ_DOMAIN
select GENERIC_IRQ_CHIP
select I8259
help
Support for the Loongson-3 HyperTransport PIC Controller.

2 changes: 1 addition & 1 deletion drivers/irqchip/irq-ativic32.c
Original file line number Diff line number Diff line change
@@ -92,7 +92,7 @@ static int ativic32_irq_domain_map(struct irq_domain *id, unsigned int virq,
return 0;
}

static struct irq_domain_ops ativic32_ops = {
static const struct irq_domain_ops ativic32_ops = {
.map = ativic32_irq_domain_map,
.xlate = irq_domain_xlate_onecell
};
8 changes: 7 additions & 1 deletion drivers/irqchip/irq-atmel-aic5.c
Original file line number Diff line number Diff line change
@@ -310,10 +310,16 @@ static void __init sama5d3_aic_irq_fixup(void)
aic_common_rtc_irq_fixup();
}

static void __init sam9x60_aic_irq_fixup(void)
{
aic_common_rtc_irq_fixup();
aic_common_rtt_irq_fixup();
}

static const struct of_device_id aic5_irq_fixups[] __initconst = {
{ .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
{ .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup },
{ .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup },
{ .compatible = "microchip,sam9x60", .data = sam9x60_aic_irq_fixup },
{ /* sentinel */ },
};

11 changes: 11 additions & 0 deletions drivers/irqchip/irq-bcm7038-l1.c
Original file line number Diff line number Diff line change
@@ -28,6 +28,9 @@
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/syscore_ops.h>
#ifdef CONFIG_ARM
#include <asm/smp_plat.h>
#endif

#define IRQS_PER_WORD 32
#define REG_BYTES_PER_IRQ_WORD (sizeof(u32) * 4)
@@ -327,7 +330,11 @@ static int bcm7038_l1_suspend(void)
u32 val;

/* Wakeup interrupt should only come from the boot cpu */
#ifdef CONFIG_SMP
boot_cpu = cpu_logical_map(0);
#else
boot_cpu = 0;
#endif

list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) {
for (word = 0; word < intc->n_words; word++) {
@@ -347,7 +354,11 @@ static void bcm7038_l1_resume(void)
struct bcm7038_l1_chip *intc;
int boot_cpu, word;

#ifdef CONFIG_SMP
boot_cpu = cpu_logical_map(0);
#else
boot_cpu = 0;
#endif

list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) {
for (word = 0; word < intc->n_words; word++) {
8 changes: 5 additions & 3 deletions drivers/irqchip/irq-bcm7120-l2.c
Original file line number Diff line number Diff line change
@@ -143,6 +143,9 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,

irq_set_chained_handler_and_data(parent_irq,
bcm7120_l2_intc_irq_handle, l1_data);
if (data->can_wake)
enable_irq_wake(parent_irq);

return 0;
}

@@ -247,6 +250,8 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
if (ret < 0)
goto out_free_l1_data;

data->can_wake = of_property_read_bool(dn, "brcm,irq-can-wake");

for (irq = 0; irq < data->num_parent_irqs; irq++) {
ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask);
if (ret)
@@ -274,9 +279,6 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
goto out_free_domain;
}

if (of_property_read_bool(dn, "brcm,irq-can-wake"))
data->can_wake = true;

for (idx = 0; idx < data->n_words; idx++) {
irq = idx * IRQS_PER_WORD;
gc = irq_get_domain_generic_chip(data->domain, irq);
5 changes: 5 additions & 0 deletions drivers/irqchip/irq-brcmstb-l2.c
Original file line number Diff line number Diff line change
@@ -254,6 +254,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
*/
data->gc->wake_enabled = 0xffffffff;
ct->chip.irq_set_wake = irq_gc_set_wake;
enable_irq_wake(parent_irq);
}

pr_info("registered L2 intc (%pOF, parent irq: %d)\n", np, parent_irq);
@@ -275,6 +276,10 @@ static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np,
return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init);
}
IRQCHIP_DECLARE(brcmstb_l2_intc, "brcm,l2-intc", brcmstb_l2_edge_intc_of_init);
IRQCHIP_DECLARE(brcmstb_hif_spi_l2_intc, "brcm,hif-spi-l2-intc",
brcmstb_l2_edge_intc_of_init);
IRQCHIP_DECLARE(brcmstb_upg_aux_aon_l2_intc, "brcm,upg-aux-aon-l2-intc",
brcmstb_l2_edge_intc_of_init);

static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np,
struct device_node *parent)
14 changes: 9 additions & 5 deletions drivers/irqchip/irq-gic-v3-its.c
Original file line number Diff line number Diff line change
@@ -2814,7 +2814,7 @@ static int allocate_vpe_l1_table(void)
if (val & GICR_VPROPBASER_4_1_VALID)
goto out;

gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_KERNEL);
gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC);
if (!gic_data_rdist()->vpe_table_mask)
return -ENOMEM;

@@ -2881,7 +2881,7 @@ static int allocate_vpe_l1_table(void)

pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
np, npg, psz, epp, esz);
page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(np * PAGE_SIZE));
page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
if (!page)
return -ENOMEM;

@@ -4090,18 +4090,22 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
static void its_vpe_4_1_invall(struct its_vpe *vpe)
{
void __iomem *rdbase;
unsigned long flags;
u64 val;
int cpu;

val = GICR_INVALLR_V;
val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);

/* Target the redistributor this vPE is currently known on */
raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock);
rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
cpu = vpe_to_cpuid_lock(vpe, &flags);
raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
gic_write_lpir(val, rdbase + GICR_INVALLR);

wait_for_syncr(rdbase);
raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock);
raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
vpe_to_cpuid_unlock(vpe, flags);
}

static int its_vpe_4_1_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
@@ -2116,7 +2116,7 @@ static void __init gic_acpi_setup_kvm_info(void)
}

static int __init
gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end)
{
struct acpi_madt_generic_distributor *dist;
struct fwnode_handle *domain_handle;
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-gic.c
Original file line number Diff line number Diff line change
@@ -1584,7 +1584,7 @@ static void __init gic_acpi_setup_kvm_info(void)
gic_set_kvm_info(&gic_v2_kvm_info);
}

static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
static int __init gic_v2_acpi_init(union acpi_subtable_headers *header,
const unsigned long end)
{
struct acpi_madt_generic_distributor *dist;
70 changes: 66 additions & 4 deletions drivers/irqchip/irq-imx-intmux.c
Original file line number Diff line number Diff line change
@@ -53,13 +53,16 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/spinlock.h>
#include <linux/pm_runtime.h>

#define CHANIER(n) (0x10 + (0x40 * n))
#define CHANIPR(n) (0x20 + (0x40 * n))

#define CHAN_MAX_NUM 0x8

struct intmux_irqchip_data {
struct irq_chip chip;
u32 saved_reg;
int chanidx;
int irq;
struct irq_domain *domain;
@@ -120,8 +123,10 @@ static struct irq_chip imx_intmux_irq_chip = {
static int imx_intmux_irq_map(struct irq_domain *h, unsigned int irq,
irq_hw_number_t hwirq)
{
irq_set_chip_data(irq, h->host_data);
irq_set_chip_and_handler(irq, &imx_intmux_irq_chip, handle_level_irq);
struct intmux_irqchip_data *data = h->host_data;

irq_set_chip_data(irq, data);
irq_set_chip_and_handler(irq, &data->chip, handle_level_irq);

return 0;
}
@@ -210,8 +215,7 @@ static int imx_intmux_probe(struct platform_device *pdev)
return -EINVAL;
}

data = devm_kzalloc(&pdev->dev, sizeof(*data) +
channum * sizeof(data->irqchip_data[0]), GFP_KERNEL);
data = devm_kzalloc(&pdev->dev, struct_size(data, irqchip_data, channum), GFP_KERNEL);
if (!data)
return -ENOMEM;

@@ -232,13 +236,19 @@ static int imx_intmux_probe(struct platform_device *pdev)
data->channum = channum;
raw_spin_lock_init(&data->lock);

pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);

ret = clk_prepare_enable(data->ipg_clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret);
return ret;
}

for (i = 0; i < channum; i++) {
data->irqchip_data[i].chip = imx_intmux_irq_chip;
data->irqchip_data[i].chip.parent_device = &pdev->dev;
data->irqchip_data[i].chanidx = i;

data->irqchip_data[i].irq = irq_of_parse_and_map(np, i);
@@ -267,6 +277,12 @@ static int imx_intmux_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, data);

/*
* Let pm_runtime_put() disable clock.
* If CONFIG_PM is not enabled, the clock will stay powered.
*/
pm_runtime_put(&pdev->dev);

return 0;
out:
clk_disable_unprepare(data->ipg_clk);
@@ -288,11 +304,56 @@ static int imx_intmux_remove(struct platform_device *pdev)
irq_domain_remove(data->irqchip_data[i].domain);
}

pm_runtime_disable(&pdev->dev);

return 0;
}

#ifdef CONFIG_PM
static int imx_intmux_runtime_suspend(struct device *dev)
{
struct intmux_data *data = dev_get_drvdata(dev);
struct intmux_irqchip_data *irqchip_data;
int i;

for (i = 0; i < data->channum; i++) {
irqchip_data = &data->irqchip_data[i];
irqchip_data->saved_reg = readl_relaxed(data->regs + CHANIER(i));
}

clk_disable_unprepare(data->ipg_clk);

return 0;
}

static int imx_intmux_runtime_resume(struct device *dev)
{
struct intmux_data *data = dev_get_drvdata(dev);
struct intmux_irqchip_data *irqchip_data;
int ret, i;

ret = clk_prepare_enable(data->ipg_clk);
if (ret) {
dev_err(dev, "failed to enable ipg clk: %d\n", ret);
return ret;
}

for (i = 0; i < data->channum; i++) {
irqchip_data = &data->irqchip_data[i];
writel_relaxed(irqchip_data->saved_reg, data->regs + CHANIER(i));
}

return 0;
}
#endif

static const struct dev_pm_ops imx_intmux_pm_ops = {
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(imx_intmux_runtime_suspend,
imx_intmux_runtime_resume, NULL)
};

static const struct of_device_id imx_intmux_id[] = {
{ .compatible = "fsl,imx-intmux", },
{ /* sentinel */ },
@@ -302,6 +363,7 @@ static struct platform_driver imx_intmux_driver = {
.driver = {
.name = "imx-intmux",
.of_match_table = imx_intmux_id,
.pm = &imx_intmux_pm_ops,
},
.probe = imx_intmux_probe,
.remove = imx_intmux_remove,
6 changes: 2 additions & 4 deletions drivers/irqchip/irq-loongson-htpic.c
Original file line number Diff line number Diff line change
@@ -93,10 +93,8 @@ int __init htpic_of_init(struct device_node *node, struct device_node *parent)
}

htpic = kzalloc(sizeof(*htpic), GFP_KERNEL);
if (!htpic) {
err = -ENOMEM;
goto out_free;
}
if (!htpic)
return -ENOMEM;

htpic->base = of_iomap(node, 0);
if (!htpic->base) {
Loading

0 comments on commit f8b036a

Please sign in to comment.