Skip to content

Commit

Permalink
x86: dtb: Add irq domain abstraction
Browse files Browse the repository at this point in the history
The here introduced irq_domain abstraction represents a generic irq
controller. It is a subset of powerpc's irq_host which is going to be
renamed to irq_domain and then become generic. This implementation will
be removed once it is generic.

The xlate callback is resposible to parse irq informations like irq type
and number and returns the hardware irq number which is reported by the
hardware as active.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Cc: sodaville@linutronix.de
Cc: devicetree-discuss@lists.ozlabs.org
LKML-Reference: <1298405266-1624-5-git-send-email-bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Sebastian Andrzej Siewior authored and Thomas Gleixner committed Feb 23, 2011
1 parent df2634f commit 19c4f5f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
12 changes: 12 additions & 0 deletions arch/x86/include/asm/irq_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef __IRQ_CONTROLLER__
#define __IRQ_CONTROLLER__

struct irq_domain {
int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
u32 *out_hwirq, u32 *out_type);
void *priv;
struct device_node *controller;
struct list_head l;
};

#endif
2 changes: 2 additions & 0 deletions arch/x86/include/asm/prom.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/setup.h>
#include <asm/irq_controller.h>

#ifdef CONFIG_OF
extern void add_dtb(u64 data);
void add_interrupt_host(struct irq_domain *ih);
#else
static inline void add_dtb(u64 data) { }
#endif
Expand Down
46 changes: 45 additions & 1 deletion arch/x86/kernel/devicetree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,63 @@
*/
#include <linux/bootmem.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/slab.h>

#include <asm/irq_controller.h>

char __initdata cmd_line[COMMAND_LINE_SIZE];
static LIST_HEAD(irq_domains);
static DEFINE_RAW_SPINLOCK(big_irq_lock);

void add_interrupt_host(struct irq_domain *ih)
{
unsigned long flags;

raw_spin_lock_irqsave(&big_irq_lock, flags);
list_add(&ih->l, &irq_domains);
raw_spin_unlock_irqrestore(&big_irq_lock, flags);
}

static struct irq_domain *get_ih_from_node(struct device_node *controller)
{
struct irq_domain *ih, *found = NULL;
unsigned long flags;

raw_spin_lock_irqsave(&big_irq_lock, flags);
list_for_each_entry(ih, &irq_domains, l) {
if (ih->controller == controller) {
found = ih;
break;
}
}
raw_spin_unlock_irqrestore(&big_irq_lock, flags);
return found;
}

unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec, unsigned int intsize)
{
return intspec[0];
struct irq_domain *ih;
u32 virq, type;
int ret;

ih = get_ih_from_node(controller);
if (!ih)
return 0;
ret = ih->xlate(ih, intspec, intsize, &virq, &type);
if (ret)
return ret;
if (type == IRQ_TYPE_NONE)
return virq;
/* set the mask if it is different from current */
if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
set_irq_type(virq, type);
return virq;
}
EXPORT_SYMBOL_GPL(irq_create_of_mapping);

Expand Down

0 comments on commit 19c4f5f

Please sign in to comment.