Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234928
b: refs/heads/master
c: bcc7c12
h: refs/heads/master
v: v3
  • Loading branch information
Sebastian Andrzej Siewior authored and Thomas Gleixner committed Feb 23, 2011
1 parent 368e247 commit 18e54df
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9079b35364e75ce6b968a179f861d2f819f33e61
refs/heads/master: bcc7c1244fcfd852b9f4590935491057e1cab9dd
2 changes: 2 additions & 0 deletions trunk/arch/x86/include/asm/prom.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
extern int of_ioapic;
extern u64 initial_dtb;
extern void add_dtb(u64 data);
extern void x86_add_irq_domains(void);
void x86_dtb_find_config(void);
void x86_dtb_get_config(unsigned int unused);
void add_interrupt_host(struct irq_domain *ih);
Expand All @@ -44,6 +45,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)

#else
static inline void add_dtb(u64 data) { }
static inline void x86_add_irq_domains(void) { }
static inline void x86_of_pci_init(void) { }
#define x86_dtb_find_config x86_init_noop
#define x86_dtb_get_config x86_init_uint_noop
Expand Down
104 changes: 104 additions & 0 deletions trunk/arch/x86/kernel/devicetree.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,107 @@ void __init x86_dtb_get_config(unsigned int unused)
dtb_setup_hpet();
dtb_apic_setup();
}

#ifdef CONFIG_X86_IO_APIC

struct of_ioapic_type {
u32 out_type;
u32 trigger;
u32 polarity;
};

static struct of_ioapic_type of_ioapic_type[] =
{
{
.out_type = IRQ_TYPE_EDGE_RISING,
.trigger = IOAPIC_EDGE,
.polarity = 1,
},
{
.out_type = IRQ_TYPE_LEVEL_LOW,
.trigger = IOAPIC_LEVEL,
.polarity = 0,
},
{
.out_type = IRQ_TYPE_LEVEL_HIGH,
.trigger = IOAPIC_LEVEL,
.polarity = 1,
},
{
.out_type = IRQ_TYPE_EDGE_FALLING,
.trigger = IOAPIC_EDGE,
.polarity = 0,
},
};

static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
u32 *out_hwirq, u32 *out_type)
{
struct io_apic_irq_attr attr;
struct of_ioapic_type *it;
u32 line, idx, type;

if (intsize < 2)
return -EINVAL;

line = *intspec;
idx = (u32) id->priv;
*out_hwirq = line + mp_gsi_routing[idx].gsi_base;

intspec++;
type = *intspec;

if (type >= ARRAY_SIZE(of_ioapic_type))
return -EINVAL;

it = of_ioapic_type + type;
*out_type = it->out_type;

set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);

return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr);
}

static void __init ioapic_add_ofnode(struct device_node *np)
{
struct resource r;
int i, ret;

ret = of_address_to_resource(np, 0, &r);
if (ret) {
printk(KERN_ERR "Failed to obtain address for %s\n",
np->full_name);
return;
}

for (i = 0; i < nr_ioapics; i++) {
if (r.start == mp_ioapics[i].apicaddr) {
struct irq_domain *id;

id = kzalloc(sizeof(*id), GFP_KERNEL);
BUG_ON(!id);
id->controller = np;
id->xlate = ioapic_xlate;
id->priv = (void *)i;
add_interrupt_host(id);
return;
}
}
printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
}

void __init x86_add_irq_domains(void)
{
struct device_node *dp;

if (!initial_boot_params)
return;

for_each_node_with_property(dp, "interrupt-controller") {
if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
ioapic_add_ofnode(dp);
}
}
#else
void __init x86_add_irq_domains(void) { }
#endif
6 changes: 6 additions & 0 deletions trunk/arch/x86/kernel/irqinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ void __init init_IRQ(void)
{
int i;

/*
* We probably need a better place for this, but it works for
* now ...
*/
x86_add_irq_domains();

/*
* On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
* If these IRQ's are handled by legacy interrupt-controllers like PIC,
Expand Down

0 comments on commit 18e54df

Please sign in to comment.