lkml.org 
[lkml]   [2011]   [Feb]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH TIP 10/14] x86/ioapic: Add OF bindings for IO-APIC
    On Mon, Jan 24, 2011 at 09:58:58AM +0530, Sebastian Andrzej Siewior wrote:
    > ioapic_xlate provides a translation from the information in device tree
    > to ioapic related informations. This includes
    > - obtaining hw irq which is the vector number "=> pin number + gsi"
    > - obtaining type (level/edge/..)
    > - programming this information into ioapic
    >
    > ioapic_add_ofnode adds an irq_domain based on informations from the device
    > tree. This information (irq_domain) is required in order to map a device to
    > its proper interrupt controller.
    >
    > Cc: devicetree-discuss@lists.ozlabs.org
    > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    > Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>

    Looks fine to me.

    g.

    > ---
    > arch/x86/include/asm/io_apic.h | 7 +++
    > arch/x86/include/asm/prom.h | 2 +
    > arch/x86/kernel/apic/io_apic.c | 99 ++++++++++++++++++++++++++++++++++++++++
    > arch/x86/kernel/irqinit.c | 6 ++
    > arch/x86/kernel/prom.c | 15 ++++++
    > 5 files changed, 129 insertions(+), 0 deletions(-)
    >
    > diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
    > index f327d38..5a8b950 100644
    > --- a/arch/x86/include/asm/io_apic.h
    > +++ b/arch/x86/include/asm/io_apic.h
    > @@ -177,6 +177,13 @@ struct mp_ioapic_gsi{
    > u32 gsi_base;
    > u32 gsi_end;
    > };
    > +#ifdef CONFIG_X86_OF
    > +struct mp_of_ioapic {
    > + struct device_node *node;
    > +};
    > +extern struct mp_of_ioapic mp_of_ioapic[MAX_IO_APICS];
    > +void __init ioapic_add_ofnode(struct device_node *np);
    > +#endif
    > extern struct mp_ioapic_gsi mp_gsi_routing[];
    > extern u32 gsi_top;
    > int mp_find_ioapic(u32 gsi);
    > diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
    > index 3ed0bd6..eea2839 100644
    > --- a/arch/x86/include/asm/prom.h
    > +++ b/arch/x86/include/asm/prom.h
    > @@ -26,6 +26,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);
    > @@ -46,6 +47,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
    > diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
    > index 697dc34..be7417f 100644
    > --- a/arch/x86/kernel/apic/io_apic.c
    > +++ b/arch/x86/kernel/apic/io_apic.c
    > @@ -43,6 +43,7 @@
    > #include <linux/bootmem.h>
    > #include <linux/dmar.h>
    > #include <linux/hpet.h>
    > +#include <linux/of_address.h>
    >
    > #include <asm/idle.h>
    > #include <asm/io.h>
    > @@ -60,6 +61,7 @@
    > #include <asm/irq_remapping.h>
    > #include <asm/hpet.h>
    > #include <asm/hw_irq.h>
    > +#include <asm/irq_controller.h>
    >
    > #include <asm/apic.h>
    >
    > @@ -88,6 +90,10 @@ int nr_ioapics;
    > /* IO APIC gsi routing info */
    > struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
    >
    > +#ifdef CONFIG_X86_OF
    > +/* OF -> IO APIC lookup */
    > +struct mp_of_ioapic mp_of_ioapic[MAX_IO_APICS];
    > +#endif
    > /* The one past the highest gsi number used */
    > u32 gsi_top;
    >
    > @@ -4080,6 +4086,99 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
    > nr_ioapics++;
    > }
    >
    > +#ifdef CONFIG_X86_OF
    > +static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
    > + u32 *out_hwirq, u32 *out_type)
    > +{
    > + u32 line;
    > + u32 idx;
    > + u32 type;
    > + u32 trigger;
    > + u32 polarity;
    > + struct irq_cfg *cfg;
    > + struct irq_desc *desc;
    > +
    > + if (intsize < 1)
    > + return -EINVAL;
    > +
    > + line = *intspec;
    > + idx = (u32) id->priv;
    > + *out_hwirq = line + mp_gsi_routing[idx].gsi_base;
    > + if (intsize > 1) {
    > + intspec++;
    > + type = *intspec;
    > + switch (type) {
    > + case 0:
    > + *out_type = IRQ_TYPE_EDGE_RISING;
    > + trigger = IOAPIC_EDGE;
    > + polarity = 1;
    > + break;
    > + case 1:
    > + *out_type = IRQ_TYPE_LEVEL_LOW;
    > + trigger = IOAPIC_LEVEL;
    > + polarity = 0;
    > + break;
    > + case 2:
    > + *out_type = IRQ_TYPE_LEVEL_HIGH;
    > + trigger = IOAPIC_LEVEL;
    > + polarity = 1;
    > + break;
    > + case 3:
    > + *out_type = IRQ_TYPE_EDGE_FALLING;
    > + trigger = IOAPIC_EDGE;
    > + polarity = 0;
    > + break;
    > + default:
    > + *out_type = IRQ_TYPE_NONE;
    > + trigger = IOAPIC_AUTO;
    > + polarity = 0;
    > + break;
    > + };
    > + } else {
    > + *out_type = IRQ_TYPE_NONE;
    > + trigger = IOAPIC_AUTO;
    > + polarity = 0;
    > + }
    > + /* And now tell the IO APIC to make the line ready */
    > + desc = irq_to_desc_alloc_node(*out_hwirq, 0);
    > + cfg = irq_cfg(*out_hwirq);
    > + add_pin_to_irq_node(cfg, 0, idx, line);
    > + /* make it edge by default, settype will update it */
    > + setup_ioapic_irq(idx, line, *out_hwirq, cfg, trigger, polarity);
    > + return 0;
    > +}
    > +
    > +void __init ioapic_add_ofnode(struct device_node *np)
    > +{
    > + int i;
    > + int ret;
    > + struct resource r;
    > +
    > + 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;
    > +
    > + mp_of_ioapic[i].node = np;
    > + 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);
    > +}
    > +#endif
    > +
    > /* Enable IOAPIC early just for system timer */
    > void __init pre_init_apic_IRQ0(void)
    > {
    > diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
    > index 4cadf86..9f76f89 100644
    > --- a/arch/x86/kernel/irqinit.c
    > +++ b/arch/x86/kernel/irqinit.c
    > @@ -119,6 +119,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,
    > * then this configuration will likely be static after the boot. If
    > diff --git a/arch/x86/kernel/prom.c b/arch/x86/kernel/prom.c
    > index 8215e8a..83ab00a 100644
    > --- a/arch/x86/kernel/prom.c
    > +++ b/arch/x86/kernel/prom.c
    > @@ -11,9 +11,11 @@
    > #include <linux/slab.h>
    > #include <linux/pci.h>
    > #include <linux/of_pci.h>
    > +#include <linux/of_fdt.h>
    >
    > #include <asm/hpet.h>
    > #include <asm/irq_controller.h>
    > +#include <asm/apic.h>
    > #include <asm/io_apic.h>
    > #include <asm/pci_x86.h>
    >
    > @@ -320,3 +322,16 @@ void __init x86_dtb_get_config(unsigned int unused)
    > dtb_setup_hpet();
    > dtb_apic_setup();
    > }
    > +
    > +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,ioapic"))
    > + ioapic_add_ofnode(dp);
    > + }
    > +}
    > --
    > 1.7.3.2
    >
    > _______________________________________________
    > devicetree-discuss mailing list
    > devicetree-discuss@lists.ozlabs.org
    > https://lists.ozlabs.org/listinfo/devicetree-discuss


    \
     
     \ /
      Last update: 2011-02-16 23:07    [W:0.077 / U:0.300 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site