Commit facd8fdb authored by Jiang Liu's avatar Jiang Liu Committed by Thomas Gleixner

x86, devicetree, irq: Use common mechanism to support irqdomain

Now the ioapic driver provides a common interface to create irqdomain,
so replace the private implementation.
Signed-off-by: default avatarJiang Liu <jiang.liu@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Tony Lindgren <tony@atomide.com>
Link: http://lkml.kernel.org/r/1402302011-23642-29-git-send-email-jiang.liu@linux.intel.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 1b5d3e00
...@@ -26,12 +26,10 @@ ...@@ -26,12 +26,10 @@
extern int of_ioapic; extern int of_ioapic;
extern u64 initial_dtb; extern u64 initial_dtb;
extern void add_dtb(u64 data); extern void add_dtb(u64 data);
extern void x86_add_irq_domains(void);
void x86_of_pci_init(void); void x86_of_pci_init(void);
void x86_dtb_init(void); void x86_dtb_init(void);
#else #else
static inline void add_dtb(u64 data) { } static inline void add_dtb(u64 data) { }
static inline void x86_add_irq_domains(void) { }
static inline void x86_of_pci_init(void) { } static inline void x86_of_pci_init(void) { }
static inline void x86_dtb_init(void) { } static inline void x86_dtb_init(void) { }
#define of_ioapic 0 #define of_ioapic 0
......
...@@ -166,82 +166,6 @@ static void __init dtb_lapic_setup(void) ...@@ -166,82 +166,6 @@ static void __init dtb_lapic_setup(void)
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
static unsigned int ioapic_id; static unsigned int ioapic_id;
static void __init dtb_add_ioapic(struct device_node *dn)
{
struct resource r;
int ret;
ret = of_address_to_resource(dn, 0, &r);
if (ret) {
printk(KERN_ERR "Can't obtain address from node %s.\n",
dn->full_name);
return;
}
mp_register_ioapic(++ioapic_id, r.start, gsi_top, NULL);
}
static void __init dtb_ioapic_setup(void)
{
struct device_node *dn;
for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
dtb_add_ioapic(dn);
if (nr_ioapics) {
of_ioapic = 1;
return;
}
printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
}
#else
static void __init dtb_ioapic_setup(void) {}
#endif
static void __init dtb_apic_setup(void)
{
dtb_lapic_setup();
dtb_ioapic_setup();
}
#ifdef CONFIG_OF_FLATTREE
static void __init x86_flattree_get_config(void)
{
u32 size, map_len;
void *dt;
if (!initial_dtb)
return;
map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
initial_boot_params = dt = early_memremap(initial_dtb, map_len);
size = of_get_flat_dt_size();
if (map_len < size) {
early_iounmap(dt, map_len);
initial_boot_params = dt = early_memremap(initial_dtb, size);
map_len = size;
}
unflatten_and_copy_device_tree();
early_iounmap(dt, map_len);
}
#else
static inline void x86_flattree_get_config(void) { }
#endif
void __init x86_dtb_init(void)
{
x86_flattree_get_config();
if (!of_have_populated_dt())
return;
dtb_setup_hpet();
dtb_apic_setup();
}
#ifdef CONFIG_X86_IO_APIC
struct of_ioapic_type { struct of_ioapic_type {
u32 out_type; u32 out_type;
u32 trigger; u32 trigger;
...@@ -292,7 +216,7 @@ static int ioapic_xlate(struct irq_domain *domain, ...@@ -292,7 +216,7 @@ static int ioapic_xlate(struct irq_domain *domain,
it = &of_ioapic_type[intspec[1]]; it = &of_ioapic_type[intspec[1]];
idx = (u32) domain->host_data; idx = (u32)(long)domain->host_data;
set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line),
...@@ -309,78 +233,81 @@ const struct irq_domain_ops ioapic_irq_domain_ops = { ...@@ -309,78 +233,81 @@ const struct irq_domain_ops ioapic_irq_domain_ops = {
.xlate = ioapic_xlate, .xlate = ioapic_xlate,
}; };
static void dt_add_ioapic_domain(unsigned int ioapic_num, static void __init dtb_add_ioapic(struct device_node *dn)
struct device_node *np)
{ {
struct irq_domain *id; struct resource r;
struct mp_ioapic_gsi *gsi_cfg;
int ret; int ret;
int num, legacy_irqs = nr_legacy_irqs(); struct ioapic_domain_cfg cfg = {
.type = IOAPIC_DOMAIN_DYNAMIC,
gsi_cfg = mp_ioapic_gsi_routing(ioapic_num); .ops = &ioapic_irq_domain_ops,
num = gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1; .dev = dn,
};
id = irq_domain_add_linear(np, num, &ioapic_irq_domain_ops,
(void *)ioapic_num); ret = of_address_to_resource(dn, 0, &r);
BUG_ON(!id); if (ret) {
if (gsi_cfg->gsi_base == 0) { printk(KERN_ERR "Can't obtain address from node %s.\n",
/* dn->full_name);
* The first nr_legacy_irqs() irq descs are allocated in return;
* early_irq_init() and need just a mapping. The
* remaining irqs need both. All of them are preallocated
* and assigned so we can keep the 1:1 mapping which the ioapic
* is having.
*/
irq_domain_associate_many(id, 0, 0, legacy_irqs);
if (num > legacy_irqs) {
ret = irq_create_strict_mappings(id, legacy_irqs,
legacy_irqs, num - legacy_irqs);
if (ret)
pr_err("Error creating mapping for the "
"remaining IRQs: %d\n", ret);
}
irq_set_default_host(id);
} else {
ret = irq_create_strict_mappings(id, gsi_cfg->gsi_base, 0, num);
if (ret)
pr_err("Error creating IRQ mapping: %d\n", ret);
} }
mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg);
} }
static void __init ioapic_add_ofnode(struct device_node *np) static void __init dtb_ioapic_setup(void)
{ {
struct resource r; struct device_node *dn;
int i, ret;
ret = of_address_to_resource(np, 0, &r); for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
if (ret) { dtb_add_ioapic(dn);
printk(KERN_ERR "Failed to obtain address for %s\n",
np->full_name); if (nr_ioapics) {
of_ioapic = 1;
return; return;
} }
printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
}
#else
static void __init dtb_ioapic_setup(void) {}
#endif
for (i = 0; i < nr_ioapics; i++) { static void __init dtb_apic_setup(void)
if (r.start == mpc_ioapic_addr(i)) { {
dt_add_ioapic_domain(i, np); dtb_lapic_setup();
return; dtb_ioapic_setup();
}
}
printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
} }
void __init x86_add_irq_domains(void) #ifdef CONFIG_OF_FLATTREE
static void __init x86_flattree_get_config(void)
{ {
struct device_node *dp; u32 size, map_len;
void *dt;
if (!of_have_populated_dt()) if (!initial_dtb)
return; return;
for_each_node_with_property(dp, "interrupt-controller") { map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
if (of_device_is_compatible(dp, "intel,ce4100-ioapic"))
ioapic_add_ofnode(dp); initial_boot_params = dt = early_memremap(initial_dtb, map_len);
size = of_get_flat_dt_size();
if (map_len < size) {
early_iounmap(dt, map_len);
initial_boot_params = dt = early_memremap(initial_dtb, size);
map_len = size;
} }
unflatten_and_copy_device_tree();
early_iounmap(dt, map_len);
} }
#else #else
void __init x86_add_irq_domains(void) { } static inline void x86_flattree_get_config(void) { }
#endif #endif
void __init x86_dtb_init(void)
{
x86_flattree_get_config();
if (!of_have_populated_dt())
return;
dtb_setup_hpet();
dtb_apic_setup();
}
...@@ -86,12 +86,6 @@ void __init init_IRQ(void) ...@@ -86,12 +86,6 @@ void __init init_IRQ(void)
{ {
int i; 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. * 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, * If these IRQ's are handled by legacy interrupt-controllers like PIC,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment