aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/devicetree.c
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2014-06-09 04:19:57 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-06-21 17:05:43 -0400
commitfacd8fdb25fc4d041a283446cfb040cbfe2c3723 (patch)
tree090f50218fca1de695eb7ebdf8ce5894971d8691 /arch/x86/kernel/devicetree.c
parent1b5d3e00d45e093fa0551c588034c3355b362f66 (diff)
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: Jiang 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.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/devicetree.c')
-rw-r--r--arch/x86/kernel/devicetree.c191
1 files changed, 59 insertions, 132 deletions
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index d2c53feacd77..ee26feca93d9 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -166,82 +166,6 @@ static void __init dtb_lapic_setup(void)
166#ifdef CONFIG_X86_IO_APIC 166#ifdef CONFIG_X86_IO_APIC
167static unsigned int ioapic_id; 167static unsigned int ioapic_id;
168 168
169static void __init dtb_add_ioapic(struct device_node *dn)
170{
171 struct resource r;
172 int ret;
173
174 ret = of_address_to_resource(dn, 0, &r);
175 if (ret) {
176 printk(KERN_ERR "Can't obtain address from node %s.\n",
177 dn->full_name);
178 return;
179 }
180 mp_register_ioapic(++ioapic_id, r.start, gsi_top, NULL);
181}
182
183static void __init dtb_ioapic_setup(void)
184{
185 struct device_node *dn;
186
187 for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
188 dtb_add_ioapic(dn);
189
190 if (nr_ioapics) {
191 of_ioapic = 1;
192 return;
193 }
194 printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
195}
196#else
197static void __init dtb_ioapic_setup(void) {}
198#endif
199
200static void __init dtb_apic_setup(void)
201{
202 dtb_lapic_setup();
203 dtb_ioapic_setup();
204}
205
206#ifdef CONFIG_OF_FLATTREE
207static void __init x86_flattree_get_config(void)
208{
209 u32 size, map_len;
210 void *dt;
211
212 if (!initial_dtb)
213 return;
214
215 map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
216
217 initial_boot_params = dt = early_memremap(initial_dtb, map_len);
218 size = of_get_flat_dt_size();
219 if (map_len < size) {
220 early_iounmap(dt, map_len);
221 initial_boot_params = dt = early_memremap(initial_dtb, size);
222 map_len = size;
223 }
224
225 unflatten_and_copy_device_tree();
226 early_iounmap(dt, map_len);
227}
228#else
229static inline void x86_flattree_get_config(void) { }
230#endif
231
232void __init x86_dtb_init(void)
233{
234 x86_flattree_get_config();
235
236 if (!of_have_populated_dt())
237 return;
238
239 dtb_setup_hpet();
240 dtb_apic_setup();
241}
242
243#ifdef CONFIG_X86_IO_APIC
244
245struct of_ioapic_type { 169struct of_ioapic_type {
246 u32 out_type; 170 u32 out_type;
247 u32 trigger; 171 u32 trigger;
@@ -292,7 +216,7 @@ static int ioapic_xlate(struct irq_domain *domain,
292 216
293 it = &of_ioapic_type[intspec[1]]; 217 it = &of_ioapic_type[intspec[1]];
294 218
295 idx = (u32) domain->host_data; 219 idx = (u32)(long)domain->host_data;
296 set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); 220 set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
297 221
298 rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), 222 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 .xlate = ioapic_xlate, 233 .xlate = ioapic_xlate,
310}; 234};
311 235
312static void dt_add_ioapic_domain(unsigned int ioapic_num, 236static void __init dtb_add_ioapic(struct device_node *dn)
313 struct device_node *np)
314{ 237{
315 struct irq_domain *id; 238 struct resource r;
316 struct mp_ioapic_gsi *gsi_cfg;
317 int ret; 239 int ret;
318 int num, legacy_irqs = nr_legacy_irqs(); 240 struct ioapic_domain_cfg cfg = {
319 241 .type = IOAPIC_DOMAIN_DYNAMIC,
320 gsi_cfg = mp_ioapic_gsi_routing(ioapic_num); 242 .ops = &ioapic_irq_domain_ops,
321 num = gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1; 243 .dev = dn,
322 244 };
323 id = irq_domain_add_linear(np, num, &ioapic_irq_domain_ops, 245
324 (void *)ioapic_num); 246 ret = of_address_to_resource(dn, 0, &r);
325 BUG_ON(!id); 247 if (ret) {
326 if (gsi_cfg->gsi_base == 0) { 248 printk(KERN_ERR "Can't obtain address from node %s.\n",
327 /* 249 dn->full_name);
328 * The first nr_legacy_irqs() irq descs are allocated in 250 return;
329 * early_irq_init() and need just a mapping. The
330 * remaining irqs need both. All of them are preallocated
331 * and assigned so we can keep the 1:1 mapping which the ioapic
332 * is having.
333 */
334 irq_domain_associate_many(id, 0, 0, legacy_irqs);
335
336 if (num > legacy_irqs) {
337 ret = irq_create_strict_mappings(id, legacy_irqs,
338 legacy_irqs, num - legacy_irqs);
339 if (ret)
340 pr_err("Error creating mapping for the "
341 "remaining IRQs: %d\n", ret);
342 }
343 irq_set_default_host(id);
344 } else {
345 ret = irq_create_strict_mappings(id, gsi_cfg->gsi_base, 0, num);
346 if (ret)
347 pr_err("Error creating IRQ mapping: %d\n", ret);
348 } 251 }
252 mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg);
349} 253}
350 254
351static void __init ioapic_add_ofnode(struct device_node *np) 255static void __init dtb_ioapic_setup(void)
352{ 256{
353 struct resource r; 257 struct device_node *dn;
354 int i, ret;
355 258
356 ret = of_address_to_resource(np, 0, &r); 259 for_each_compatible_node(dn, NULL, "intel,ce4100-ioapic")
357 if (ret) { 260 dtb_add_ioapic(dn);
358 printk(KERN_ERR "Failed to obtain address for %s\n", 261
359 np->full_name); 262 if (nr_ioapics) {
263 of_ioapic = 1;
360 return; 264 return;
361 } 265 }
266 printk(KERN_ERR "Error: No information about IO-APIC in OF.\n");
267}
268#else
269static void __init dtb_ioapic_setup(void) {}
270#endif
362 271
363 for (i = 0; i < nr_ioapics; i++) { 272static void __init dtb_apic_setup(void)
364 if (r.start == mpc_ioapic_addr(i)) { 273{
365 dt_add_ioapic_domain(i, np); 274 dtb_lapic_setup();
366 return; 275 dtb_ioapic_setup();
367 }
368 }
369 printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name);
370} 276}
371 277
372void __init x86_add_irq_domains(void) 278#ifdef CONFIG_OF_FLATTREE
279static void __init x86_flattree_get_config(void)
373{ 280{
374 struct device_node *dp; 281 u32 size, map_len;
282 void *dt;
375 283
376 if (!of_have_populated_dt()) 284 if (!initial_dtb)
377 return; 285 return;
378 286
379 for_each_node_with_property(dp, "interrupt-controller") { 287 map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
380 if (of_device_is_compatible(dp, "intel,ce4100-ioapic")) 288
381 ioapic_add_ofnode(dp); 289 initial_boot_params = dt = early_memremap(initial_dtb, map_len);
290 size = of_get_flat_dt_size();
291 if (map_len < size) {
292 early_iounmap(dt, map_len);
293 initial_boot_params = dt = early_memremap(initial_dtb, size);
294 map_len = size;
382 } 295 }
296
297 unflatten_and_copy_device_tree();
298 early_iounmap(dt, map_len);
383} 299}
384#else 300#else
385void __init x86_add_irq_domains(void) { } 301static inline void x86_flattree_get_config(void) { }
386#endif 302#endif
303
304void __init x86_dtb_init(void)
305{
306 x86_flattree_get_config();
307
308 if (!of_have_populated_dt())
309 return;
310
311 dtb_setup_hpet();
312 dtb_apic_setup();
313}