summaryrefslogtreecommitdiff
path: root/drivers/irqchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-bcm7038-l1.c4
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c4
-rw-r--r--drivers/irqchip/irq-gic-v3.c2
-rw-r--r--drivers/irqchip/irq-gic.c9
-rw-r--r--drivers/irqchip/irq-ingenic.c15
-rw-r--r--drivers/irqchip/irq-nvic.c2
-rw-r--r--drivers/irqchip/irq-s3c24xx.c22
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c18
-rw-r--r--drivers/irqchip/msm_show_resume_irq.c2
9 files changed, 57 insertions, 21 deletions
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 6fb34bf0f352..34e13623f29d 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -283,6 +283,10 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
pr_err("failed to map parent interrupt %d\n", parent_irq);
return -EINVAL;
}
+
+ if (of_property_read_bool(dn, "brcm,irq-can-wake"))
+ enable_irq_wake(parent_irq);
+
irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle,
intc);
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index cf11d43ce241..fee7c6f3e971 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -352,11 +352,11 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
struct its_cmd_desc *desc)
{
its_encode_cmd(cmd, GITS_CMD_INVALL);
- its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id);
+ its_encode_collection(cmd, desc->its_invall_cmd.col->col_id);
its_fixup_cmd(cmd);
- return NULL;
+ return desc->its_invall_cmd.col;
}
static u64 its_cmd_ptr_to_offset(struct its_node *its,
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 2b8b0e4036b5..058b65cbfdd0 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -25,6 +25,7 @@
#include <linux/percpu.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/wakeup_reason.h>
#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic-v3.h>
@@ -442,6 +443,7 @@ static void gic_show_resume_irq(struct gic_chip_data *gic)
else if (desc->action && desc->action->name)
name = desc->action->name;
+ log_base_wakeup_reason(irq);
pr_warn("%s: %d triggered %s\n", __func__, irq, name);
}
}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 25b5a2427705..db27aa9c7e8d 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -42,7 +42,7 @@
#include <linux/irqchip/chained_irq.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/syscore_ops.h>
-
+#include <linux/wakeup_reason.h>
#include <asm/cputype.h>
#include <asm/irq.h>
#include <asm/exception.h>
@@ -544,12 +544,13 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
} while (1);
}
-static void gic_handle_cascade_irq(struct irq_desc *desc)
+static bool gic_handle_cascade_irq(struct irq_desc *desc)
{
struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq, gic_irq;
unsigned long status;
+ int handled = false;
chained_irq_enter(chip, desc);
@@ -565,10 +566,12 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
if (unlikely(gic_irq < 32 || gic_irq > 1020))
handle_bad_irq(desc);
else
- generic_handle_irq(cascade_irq);
+ handled = generic_handle_irq(cascade_irq);
+
out:
chained_irq_exit(chip, desc);
+ return handled == true;
}
static struct irq_chip gic_chip = {
diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c
index fc5953dea509..b2e16dca76a6 100644
--- a/drivers/irqchip/irq-ingenic.c
+++ b/drivers/irqchip/irq-ingenic.c
@@ -117,6 +117,14 @@ static int __init ingenic_intc_of_init(struct device_node *node,
goto out_unmap_irq;
}
+ domain = irq_domain_add_legacy(node, num_chips * 32,
+ JZ4740_IRQ_BASE, 0,
+ &irq_domain_simple_ops, NULL);
+ if (!domain) {
+ err = -ENOMEM;
+ goto out_unmap_base;
+ }
+
for (i = 0; i < num_chips; i++) {
/* Mask all irqs */
writel(0xffffffff, intc->base + (i * CHIP_SIZE) +
@@ -143,14 +151,11 @@ static int __init ingenic_intc_of_init(struct device_node *node,
IRQ_NOPROBE | IRQ_LEVEL);
}
- domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
- &irq_domain_simple_ops, NULL);
- if (!domain)
- pr_warn("unable to register IRQ domain\n");
-
setup_irq(parent_irq, &intc_cascade_action);
return 0;
+out_unmap_base:
+ iounmap(intc->base);
out_unmap_irq:
irq_dispose_mapping(parent_irq);
out_free:
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index b1777104fd9f..9694529b709d 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -29,7 +29,7 @@
#define NVIC_ISER 0x000
#define NVIC_ICER 0x080
-#define NVIC_IPR 0x300
+#define NVIC_IPR 0x400
#define NVIC_MAX_BANKS 16
/*
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index c71914e8f596..cd7fdce98359 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -368,11 +368,25 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
{
do {
- if (likely(s3c_intc[0]))
- if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
- continue;
+ /*
+ * For platform based machines, neither ERR nor NULL can happen here.
+ * The s3c24xx_handle_irq() will be set as IRQ handler iff this succeeds:
+ *
+ * s3c_intc[0] = s3c24xx_init_intc()
+ *
+ * If this fails, the next calls to s3c24xx_init_intc() won't be executed.
+ *
+ * For DT machine, s3c_init_intc_of() could set the IRQ handler without
+ * setting s3c_intc[0] only if it was called with num_ctrl=0. There is no
+ * such code path, so again the s3c_intc[0] will have a valid pointer if
+ * set_handle_irq() is called.
+ *
+ * Therefore in s3c24xx_handle_irq(), the s3c_intc[0] is always something.
+ */
+ if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
+ continue;
- if (s3c_intc[2])
+ if (!IS_ERR_OR_NULL(s3c_intc[2]))
if (s3c24xx_handle_intc(s3c_intc[2], regs, 64))
continue;
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index cadf104e3074..08b66b25f845 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -5,6 +5,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/irqchip/versatile-fpga.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
@@ -67,12 +68,16 @@ static void fpga_irq_unmask(struct irq_data *d)
static void fpga_irq_handle(struct irq_desc *desc)
{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
- u32 status = readl(f->base + IRQ_STATUS);
+ u32 status;
+
+ chained_irq_enter(chip, desc);
+ status = readl(f->base + IRQ_STATUS);
if (status == 0) {
do_bad_IRQ(desc);
- return;
+ goto out;
}
do {
@@ -81,6 +86,9 @@ static void fpga_irq_handle(struct irq_desc *desc)
status &= ~(1 << irq);
generic_handle_irq(irq_find_mapping(f->domain, irq));
} while (status);
+
+out:
+ chained_irq_exit(chip, desc);
}
/*
@@ -203,6 +211,9 @@ int __init fpga_irq_of_init(struct device_node *node,
if (of_property_read_u32(node, "valid-mask", &valid_mask))
valid_mask = 0;
+ writel(clear_mask, base + IRQ_ENABLE_CLEAR);
+ writel(clear_mask, base + FIQ_ENABLE_CLEAR);
+
/* Some chips are cascaded from a parent IRQ */
parent_irq = irq_of_parse_and_map(node, 0);
if (!parent_irq) {
@@ -217,9 +228,6 @@ int __init fpga_irq_of_init(struct device_node *node,
fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
#endif
- writel(clear_mask, base + IRQ_ENABLE_CLEAR);
- writel(clear_mask, base + FIQ_ENABLE_CLEAR);
-
/*
* On Versatile AB/PB, some secondary interrupts have a direct
* pass-thru to the primary controller for IRQs 20 and 22-31 which need
diff --git a/drivers/irqchip/msm_show_resume_irq.c b/drivers/irqchip/msm_show_resume_irq.c
index 521149671fdf..cfadb7c2643d 100644
--- a/drivers/irqchip/msm_show_resume_irq.c
+++ b/drivers/irqchip/msm_show_resume_irq.c
@@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-int msm_show_resume_irq_mask;
+int msm_show_resume_irq_mask = 1;
module_param_named(
debug_mask, msm_show_resume_irq_mask, int, S_IRUGO | S_IWUSR | S_IWGRP