summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 19:42:56 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 19:42:56 -0700
commit407a2c720556e8e340e06f6a7174f5d6d80cf9ea (patch)
treeb78ba543dbef195909611448ca833348581b63a6 /drivers/irqchip
parent3a95398f54cbd664c749fe9f1bfc7e7dbace92d0 (diff)
parentf05218651be1ac6a6088e226bd7350fb6c154414 (diff)
downloadlinux-407a2c720556e8e340e06f6a7174f5d6d80cf9ea.tar.bz2
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "The irq departement delivers: - plug a potential race related to chained interrupt handlers - core updates which address the needs of the x86 irqdomain conversion - new irqchip callback to support affinity settings for VCPUs - the usual pile of updates to interrupt chip drivers - a few helper functions to allow further cleanups and simplifications I have a largish pile of coccinelle scripted/verified cleanups and simplifications pending on top of that, but I prefer to send that towards the end of the merge window when the arch/driver changes have hit your tree to avoid API change wreckage as far as possible" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (34 commits) genirq: Remove bogus restriction in irq_move_mask_irq() irqchip: atmel-aic5: Add sama5d2 support irq: spear-shirq: Fix race in installing chained IRQ handler irq: irq-keystone: Fix race in installing chained IRQ handler gpio: gpio-tegra: Fix race in installing chained IRQ handler gpio: gpio-mxs: Fix race in installing chained IRQ handler gpio: gpio-mxc: Fix race in installing chained IRQ handler ARM: gemini: Fix race in installing GPIO chained IRQ handler GPU: ipu: Fix race in installing IPU chained IRQ handler ARM: sa1100: convert SA11x0 related code to use new chained handler helper irq: Add irq_set_chained_handler_and_data() irqchip: exynos-combiner: Save IRQ enable set on suspend genirq: Introduce helper function irq_data_get_affinity_mask() genirq: Introduce helper function irq_data_get_node() genirq: Introduce struct irq_common_data to host shared irq data genirq: Prevent crash in irq_move_irq() genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain irqchip: gic: Simplify gic_configure_irq by using IRQCHIP_SET_TYPE_MASKED irqchip: renesas: intc-irqpin: Improve binding documentation genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip ...
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/Kconfig1
-rw-r--r--drivers/irqchip/exynos-combiner.c66
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c2
-rw-r--r--drivers/irqchip/irq-atmel-aic5.c9
-rw-r--r--drivers/irqchip/irq-bcm2835.c2
-rw-r--r--drivers/irqchip/irq-gic-common.c17
-rw-r--r--drivers/irqchip/irq-gic-v3.c1
-rw-r--r--drivers/irqchip/irq-gic.c1
-rw-r--r--drivers/irqchip/irq-hip04.c1
-rw-r--r--drivers/irqchip/irq-keystone.c5
-rw-r--r--drivers/irqchip/irq-mips-gic.c2
-rw-r--r--drivers/irqchip/irq-mtk-sysirq.c4
-rw-r--r--drivers/irqchip/irq-mxs.c2
-rw-r--r--drivers/irqchip/irq-nvic.c28
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c2
-rw-r--r--drivers/irqchip/irq-renesas-irqc.c19
-rw-r--r--drivers/irqchip/irq-s3c24xx.c4
-rw-r--r--drivers/irqchip/irq-sun4i.c2
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c2
-rw-r--r--drivers/irqchip/irq-vf610-mscm-ir.c28
-rw-r--r--drivers/irqchip/irq-vic.c2
-rw-r--r--drivers/irqchip/irq-vt8500.c2
-rw-r--r--drivers/irqchip/spear-shirq.c3
23 files changed, 137 insertions, 68 deletions
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 6de62a96e79c..99b9a9792975 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -30,6 +30,7 @@ config ARM_GIC_V3_ITS
config ARM_NVIC
bool
select IRQ_DOMAIN
+ select IRQ_DOMAIN_HIERARCHY
select GENERIC_IRQ_CHIP
config ARM_VIC
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 5945223b73fa..5c82e3bdafdf 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/syscore_ops.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/interrupt.h>
@@ -34,9 +35,14 @@ struct combiner_chip_data {
unsigned int irq_mask;
void __iomem *base;
unsigned int parent_irq;
+#ifdef CONFIG_PM
+ u32 pm_save;
+#endif
};
+static struct combiner_chip_data *combiner_data;
static struct irq_domain *combiner_irq_domain;
+static unsigned int max_nr = 20;
static inline void __iomem *combiner_base(struct irq_data *data)
{
@@ -164,18 +170,16 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
return 0;
}
-static struct irq_domain_ops combiner_irq_domain_ops = {
+static const struct irq_domain_ops combiner_irq_domain_ops = {
.xlate = combiner_irq_domain_xlate,
.map = combiner_irq_domain_map,
};
static void __init combiner_init(void __iomem *combiner_base,
- struct device_node *np,
- unsigned int max_nr)
+ struct device_node *np)
{
int i, irq;
unsigned int nr_irq;
- struct combiner_chip_data *combiner_data;
nr_irq = max_nr * IRQ_IN_COMBINER;
@@ -201,11 +205,59 @@ static void __init combiner_init(void __iomem *combiner_base,
}
}
+#ifdef CONFIG_PM
+
+/**
+ * combiner_suspend - save interrupt combiner state before suspend
+ *
+ * Save the interrupt enable set register for all combiner groups since
+ * the state is lost when the system enters into a sleep state.
+ *
+ */
+static int combiner_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < max_nr; i++)
+ combiner_data[i].pm_save =
+ __raw_readl(combiner_data[i].base + COMBINER_ENABLE_SET);
+
+ return 0;
+}
+
+/**
+ * combiner_resume - restore interrupt combiner state after resume
+ *
+ * Restore the interrupt enable set register for all combiner groups since
+ * the state is lost when the system enters into a sleep state on suspend.
+ *
+ */
+static void combiner_resume(void)
+{
+ int i;
+
+ for (i = 0; i < max_nr; i++) {
+ __raw_writel(combiner_data[i].irq_mask,
+ combiner_data[i].base + COMBINER_ENABLE_CLEAR);
+ __raw_writel(combiner_data[i].pm_save,
+ combiner_data[i].base + COMBINER_ENABLE_SET);
+ }
+}
+
+#else
+#define combiner_suspend NULL
+#define combiner_resume NULL
+#endif
+
+static struct syscore_ops combiner_syscore_ops = {
+ .suspend = combiner_suspend,
+ .resume = combiner_resume,
+};
+
static int __init combiner_of_init(struct device_node *np,
struct device_node *parent)
{
void __iomem *combiner_base;
- unsigned int max_nr = 20;
combiner_base = of_iomap(np, 0);
if (!combiner_base) {
@@ -219,7 +271,9 @@ static int __init combiner_of_init(struct device_node *np,
__func__, max_nr);
}
- combiner_init(combiner_base, np, max_nr);
+ combiner_init(combiner_base, np);
+
+ register_syscore_ops(&combiner_syscore_ops);
return 0;
}
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index daccc8bdbb42..0d3b0fe2f175 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -409,7 +409,7 @@ static struct notifier_block mpic_cascaded_cpu_notifier = {
};
#endif /* CONFIG_SMP */
-static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
+static const struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
.map = armada_370_xp_mpic_irq_map,
.xlate = irq_domain_xlate_onecell,
};
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c
index a2e8c3f876cb..459bf4429d36 100644
--- a/drivers/irqchip/irq-atmel-aic5.c
+++ b/drivers/irqchip/irq-atmel-aic5.c
@@ -339,6 +339,15 @@ static int __init aic5_of_init(struct device_node *node,
return 0;
}
+#define NR_SAMA5D2_IRQS 77
+
+static int __init sama5d2_aic5_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return aic5_of_init(node, parent, NR_SAMA5D2_IRQS);
+}
+IRQCHIP_DECLARE(sama5d2_aic5, "atmel,sama5d2-aic", sama5d2_aic5_of_init);
+
#define NR_SAMA5D3_IRQS 48
static int __init sama5d3_aic5_of_init(struct device_node *node,
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index 5916d6cdafa1..e68c3b60a681 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -135,7 +135,7 @@ static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
return 0;
}
-static struct irq_domain_ops armctrl_ops = {
+static const struct irq_domain_ops armctrl_ops = {
.xlate = armctrl_xlate
};
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index ad96ebb0c7ab..9448e391cb71 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -24,11 +24,8 @@
int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void))
{
- u32 enablemask = 1 << (irq % 32);
- u32 enableoff = (irq / 32) * 4;
u32 confmask = 0x2 << ((irq % 16) * 2);
u32 confoff = (irq / 16) * 4;
- bool enabled = false;
u32 val, oldval;
int ret = 0;
@@ -43,17 +40,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
val |= confmask;
/*
- * As recommended by the spec, disable the interrupt before changing
- * the configuration
- */
- if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
- writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
- if (sync_access)
- sync_access();
- enabled = true;
- }
-
- /*
* Write back the new configuration, and possibly re-enable
* the interrupt. If we tried to write a new configuration and failed,
* return an error.
@@ -62,9 +48,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval)
ret = -EINVAL;
- if (enabled)
- writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
-
if (sync_access)
sync_access();
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 49875adb6b44..c52f7ba205b4 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -658,6 +658,7 @@ static struct irq_chip gic_chip = {
.irq_set_affinity = gic_set_affinity,
.irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
};
#define GIC_ID_NR (1U << gic_data.rdists.id_bits)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 01999d74bd3a..8d7e1c8b6d56 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -324,6 +324,7 @@ static struct irq_chip gic_chip = {
#endif
.irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
};
void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 7d6ffb5de84f..0cae45d10695 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -202,6 +202,7 @@ static struct irq_chip hip04_irq_chip = {
#ifdef CONFIG_SMP
.irq_set_affinity = hip04_irq_set_affinity,
#endif
+ .flags = IRQCHIP_SET_TYPE_MASKED,
};
static u16 hip04_get_cpumask(struct hip04_irq_data *intc)
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c
index 78e8b3ce5252..81e3cf5b9a1f 100644
--- a/drivers/irqchip/irq-keystone.c
+++ b/drivers/irqchip/irq-keystone.c
@@ -131,7 +131,7 @@ static int keystone_irq_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops keystone_irq_ops = {
+static const struct irq_domain_ops keystone_irq_ops = {
.map = keystone_irq_map,
.xlate = irq_domain_xlate_onecell,
};
@@ -184,8 +184,7 @@ static int keystone_irq_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, kirq);
- irq_set_chained_handler(kirq->irq, keystone_irq_handler);
- irq_set_handler_data(kirq->irq, kirq);
+ irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq);
/* clear all source bits */
keystone_irq_writel(kirq, ~0x0);
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 269c2354c431..4400edd1a6c7 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -746,7 +746,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
return 0;
}
-static struct irq_domain_ops gic_irq_domain_ops = {
+static const struct irq_domain_ops gic_irq_domain_ops = {
.map = gic_irq_domain_map,
.xlate = gic_irq_domain_xlate,
};
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index eaf0a710e98a..15c13039bba2 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -111,7 +111,7 @@ static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
}
-static struct irq_domain_ops sysirq_domain_ops = {
+static const struct irq_domain_ops sysirq_domain_ops = {
.xlate = mtk_sysirq_domain_xlate,
.alloc = mtk_sysirq_domain_alloc,
.free = irq_domain_free_irqs_common,
@@ -144,7 +144,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
chip_data->intpol_base = ioremap(res.start, size);
if (!chip_data->intpol_base) {
pr_err("mtk_sysirq: unable to map sysirq register\n");
- ret = PTR_ERR(chip_data->intpol_base);
+ ret = -ENXIO;
goto out_free;
}
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index e4acf1e3f8e3..04bf97b289cf 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -90,7 +90,7 @@ static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
return 0;
}
-static struct irq_domain_ops icoll_irq_domain_ops = {
+static const struct irq_domain_ops icoll_irq_domain_ops = {
.map = icoll_irq_domain_map,
.xlate = irq_domain_xlate_onecell,
};
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index 4ff0805fca01..5fac9100f6cb 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -49,6 +49,31 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
handle_IRQ(irq, regs);
}
+static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs, void *arg)
+{
+ int i, ret;
+ irq_hw_number_t hwirq;
+ unsigned int type = IRQ_TYPE_NONE;
+ struct of_phandle_args *irq_data = arg;
+
+ ret = irq_domain_xlate_onecell(domain, irq_data->np, irq_data->args,
+ irq_data->args_count, &hwirq, &type);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < nr_irqs; i++)
+ irq_map_generic_chip(domain, virq + i, hwirq + i);
+
+ return 0;
+}
+
+static const struct irq_domain_ops nvic_irq_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .alloc = nvic_irq_domain_alloc,
+ .free = irq_domain_free_irqs_top,
+};
+
static int __init nvic_of_init(struct device_node *node,
struct device_node *parent)
{
@@ -70,7 +95,8 @@ static int __init nvic_of_init(struct device_node *node,
irqs = NVIC_MAX_IRQ;
nvic_irq_domain =
- irq_domain_add_linear(node, irqs, &irq_generic_chip_ops, NULL);
+ irq_domain_add_linear(node, irqs, &nvic_irq_domain_ops, NULL);
+
if (!nvic_irq_domain) {
pr_warn("Failed to allocate irq domain\n");
return -ENOMEM;
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 9a0767b9c89d..0670ab4e3897 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -347,7 +347,7 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops intc_irqpin_irq_domain_ops = {
+static const struct irq_domain_ops intc_irqpin_irq_domain_ops = {
.map = intc_irqpin_irq_domain_map,
.xlate = irq_domain_xlate_twocell,
};
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index cdf80b7794cd..778bd076aeea 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -29,7 +29,6 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/platform_data/irq-renesas-irqc.h>
#include <linux/pm_runtime.h>
#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */
@@ -62,7 +61,6 @@ struct irqc_priv {
void __iomem *iomem;
void __iomem *cpu_int_base;
struct irqc_irq irq[IRQC_IRQ_MAX];
- struct renesas_irqc_config config;
unsigned int number_of_irqs;
struct platform_device *pdev;
struct irq_chip irq_chip;
@@ -168,14 +166,13 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops irqc_irq_domain_ops = {
+static const struct irq_domain_ops irqc_irq_domain_ops = {
.map = irqc_irq_domain_map,
.xlate = irq_domain_xlate_twocell,
};
static int irqc_probe(struct platform_device *pdev)
{
- struct renesas_irqc_config *pdata = pdev->dev.platform_data;
struct irqc_priv *p;
struct resource *io;
struct resource *irq;
@@ -191,10 +188,6 @@ static int irqc_probe(struct platform_device *pdev)
goto err0;
}
- /* deal with driver instance configuration */
- if (pdata)
- memcpy(&p->config, pdata, sizeof(*pdata));
-
p->pdev = pdev;
platform_set_drvdata(pdev, p);
@@ -251,8 +244,7 @@ static int irqc_probe(struct platform_device *pdev)
irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
- p->number_of_irqs,
- p->config.irq_base,
+ p->number_of_irqs, 0,
&irqc_irq_domain_ops, p);
if (!p->irq_domain) {
ret = -ENXIO;
@@ -272,13 +264,6 @@ static int irqc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs);
- /* warn in case of mismatch if irq base is specified */
- if (p->config.irq_base) {
- if (p->config.irq_base != p->irq[0].domain_irq)
- dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n",
- p->config.irq_base, p->irq[0].domain_irq);
- }
-
return 0;
err3:
while (--k >= 0)
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index c8d373fcd823..e96717f45ea1 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -502,7 +502,7 @@ err:
return -EINVAL;
}
-static struct irq_domain_ops s3c24xx_irq_ops = {
+static const struct irq_domain_ops s3c24xx_irq_ops = {
.map = s3c24xx_irq_map,
.xlate = irq_domain_xlate_twocell,
};
@@ -1228,7 +1228,7 @@ static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
return 0;
}
-static struct irq_domain_ops s3c24xx_irq_ops_of = {
+static const struct irq_domain_ops s3c24xx_irq_ops_of = {
.map = s3c24xx_irq_map_of,
.xlate = s3c24xx_irq_xlate_of,
};
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c
index 64155b686081..83d6aa6464ee 100644
--- a/drivers/irqchip/irq-sun4i.c
+++ b/drivers/irqchip/irq-sun4i.c
@@ -89,7 +89,7 @@ static int sun4i_irq_map(struct irq_domain *d, unsigned int virq,
return 0;
}
-static struct irq_domain_ops sun4i_irq_ops = {
+static const struct irq_domain_ops sun4i_irq_ops = {
.map = sun4i_irq_map,
.xlate = irq_domain_xlate_onecell,
};
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 1ab451729a5c..888111b76ea0 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -132,7 +132,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
return 0;
}
-static struct irq_domain_ops fpga_irqdomain_ops = {
+static const struct irq_domain_ops fpga_irqdomain_ops = {
.map = fpga_irqdomain_map,
.xlate = irq_domain_xlate_onetwocell,
};
diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c
index 9521057d4744..f5c01cbcc73a 100644
--- a/drivers/irqchip/irq-vf610-mscm-ir.c
+++ b/drivers/irqchip/irq-vf610-mscm-ir.c
@@ -47,6 +47,7 @@ struct vf610_mscm_ir_chip_data {
void __iomem *mscm_ir_base;
u16 cpu_mask;
u16 saved_irsprc[MSCM_IRSPRC_NUM];
+ bool is_nvic;
};
static struct vf610_mscm_ir_chip_data *mscm_ir_data;
@@ -101,7 +102,7 @@ static void vf610_mscm_ir_enable(struct irq_data *data)
writew_relaxed(chip_data->cpu_mask,
chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
- irq_chip_unmask_parent(data);
+ irq_chip_enable_parent(data);
}
static void vf610_mscm_ir_disable(struct irq_data *data)
@@ -111,7 +112,7 @@ static void vf610_mscm_ir_disable(struct irq_data *data)
writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
- irq_chip_mask_parent(data);
+ irq_chip_disable_parent(data);
}
static struct irq_chip vf610_mscm_ir_irq_chip = {
@@ -143,10 +144,17 @@ static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi
domain->host_data);
gic_data.np = domain->parent->of_node;
- gic_data.args_count = 3;
- gic_data.args[0] = GIC_SPI;
- gic_data.args[1] = irq_data->args[0];
- gic_data.args[2] = irq_data->args[1];
+
+ if (mscm_ir_data->is_nvic) {
+ gic_data.args_count = 1;
+ gic_data.args[0] = irq_data->args[0];
+ } else {
+ gic_data.args_count = 3;
+ gic_data.args[0] = GIC_SPI;
+ gic_data.args[1] = irq_data->args[0];
+ gic_data.args[2] = irq_data->args[1];
+ }
+
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
}
@@ -174,10 +182,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
return -ENOMEM;
mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir");
-
- if (!mscm_ir_data->mscm_ir_base) {
+ if (IS_ERR(mscm_ir_data->mscm_ir_base)) {
pr_err("vf610_mscm_ir: unable to map mscm register\n");
- ret = -ENOMEM;
+ ret = PTR_ERR(mscm_ir_data->mscm_ir_base);
goto out_free;
}
@@ -199,6 +206,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
goto out_unmap;
}
+ if (of_device_is_compatible(domain->parent->of_node, "arm,armv7m-nvic"))
+ mscm_ir_data->is_nvic = true;
+
cpu_pm_register_notifier(&mscm_ir_notifier_block);
return 0;
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 54089debf2dc..d4ce331ea4a0 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -256,7 +256,7 @@ static void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
} while (handled);
}
-static struct irq_domain_ops vic_irqdomain_ops = {
+static const struct irq_domain_ops vic_irqdomain_ops = {
.map = vic_irqdomain_map,
.xlate = irq_domain_xlate_onetwocell,
};
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c
index b7af816f2769..0b297009b856 100644
--- a/drivers/irqchip/irq-vt8500.c
+++ b/drivers/irqchip/irq-vt8500.c
@@ -173,7 +173,7 @@ static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops vt8500_irq_domain_ops = {
+static const struct irq_domain_ops vt8500_irq_domain_ops = {
.map = vt8500_irq_map,
.xlate = irq_domain_xlate_onecell,
};
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index 9c145a7cb056..a45121546caf 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -207,8 +207,7 @@ static void __init spear_shirq_register(struct spear_shirq *shirq,
if (!shirq->irq_chip)
return;
- irq_set_chained_handler(parent_irq, shirq_handler);
- irq_set_handler_data(parent_irq, shirq);
+ irq_set_chained_handler_and_data(parent_irq, shirq_handler, shirq);
for (i = 0; i < shirq->nr_irqs; i++) {
irq_set_chip_and_handler(shirq->virq_base + i,