summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/sh/intc/virq.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/sh/intc/virq.c')
-rw-r--r--kernel/drivers/sh/intc/virq.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/kernel/drivers/sh/intc/virq.c b/kernel/drivers/sh/intc/virq.c
index f30ac9354..e7899624a 100644
--- a/kernel/drivers/sh/intc/virq.c
+++ b/kernel/drivers/sh/intc/virq.c
@@ -83,12 +83,11 @@ EXPORT_SYMBOL_GPL(intc_irq_lookup);
static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
{
- struct intc_virq_list **last, *entry;
- struct irq_data *data = irq_get_irq_data(irq);
+ struct intc_virq_list *entry;
+ struct intc_virq_list **last = NULL;
/* scan for duplicates */
- last = (struct intc_virq_list **)&data->handler_data;
- for_each_virq(entry, data->handler_data) {
+ for_each_virq(entry, irq_get_handler_data(irq)) {
if (entry->irq == virq)
return 0;
last = &entry->next;
@@ -102,14 +101,18 @@ static int add_virq_to_pirq(unsigned int irq, unsigned int virq)
entry->irq = virq;
- *last = entry;
+ if (last)
+ *last = entry;
+ else
+ irq_set_handler_data(irq, entry);
return 0;
}
-static void intc_virq_handler(unsigned int irq, struct irq_desc *desc)
+static void intc_virq_handler(struct irq_desc *desc)
{
- struct irq_data *data = irq_get_irq_data(irq);
+ unsigned int irq = irq_desc_get_irq(desc);
+ struct irq_data *data = irq_desc_get_irq_data(desc);
struct irq_chip *chip = irq_data_get_irq_chip(data);
struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data);
struct intc_desc_int *d = get_intc_desc(irq);
@@ -118,12 +121,14 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc)
for_each_virq(entry, vlist) {
unsigned long addr, handle;
+ struct irq_desc *vdesc = irq_to_desc(entry->irq);
- handle = (unsigned long)irq_get_handler_data(entry->irq);
- addr = INTC_REG(d, _INTC_ADDR_E(handle), 0);
-
- if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0))
- generic_handle_irq(entry->irq);
+ if (vdesc) {
+ handle = (unsigned long)irq_desc_get_handler_data(vdesc);
+ addr = INTC_REG(d, _INTC_ADDR_E(handle), 0);
+ if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0))
+ generic_handle_irq_desc(vdesc);
+ }
}
chip->irq_unmask(data);
@@ -243,8 +248,9 @@ restart:
*/
irq_set_nothread(irq);
- irq_set_chained_handler(entry->pirq, intc_virq_handler);
+ /* Set handler data before installing the handler */
add_virq_to_pirq(entry->pirq, irq);
+ irq_set_chained_handler(entry->pirq, intc_virq_handler);
radix_tree_tag_clear(&d->tree, entry->enum_id,
INTC_TAG_VIRQ_NEEDS_ALLOC);