Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jiang Liu and committed by
Thomas Gleixner
facd8fdb 1b5d3e00

+73 -154
-2
arch/x86/include/asm/prom.h
··· 26 26 extern int of_ioapic; 27 27 extern u64 initial_dtb; 28 28 extern void add_dtb(u64 data); 29 - extern void x86_add_irq_domains(void); 30 29 void x86_of_pci_init(void); 31 30 void x86_dtb_init(void); 32 31 #else 33 32 static inline void add_dtb(u64 data) { } 34 - static inline void x86_add_irq_domains(void) { } 35 33 static inline void x86_of_pci_init(void) { } 36 34 static inline void x86_dtb_init(void) { } 37 35 #define of_ioapic 0
+73 -146
arch/x86/kernel/devicetree.c
··· 166 166 #ifdef CONFIG_X86_IO_APIC 167 167 static unsigned int ioapic_id; 168 168 169 + struct of_ioapic_type { 170 + u32 out_type; 171 + u32 trigger; 172 + u32 polarity; 173 + }; 174 + 175 + static struct of_ioapic_type of_ioapic_type[] = 176 + { 177 + { 178 + .out_type = IRQ_TYPE_EDGE_RISING, 179 + .trigger = IOAPIC_EDGE, 180 + .polarity = 1, 181 + }, 182 + { 183 + .out_type = IRQ_TYPE_LEVEL_LOW, 184 + .trigger = IOAPIC_LEVEL, 185 + .polarity = 0, 186 + }, 187 + { 188 + .out_type = IRQ_TYPE_LEVEL_HIGH, 189 + .trigger = IOAPIC_LEVEL, 190 + .polarity = 1, 191 + }, 192 + { 193 + .out_type = IRQ_TYPE_EDGE_FALLING, 194 + .trigger = IOAPIC_EDGE, 195 + .polarity = 0, 196 + }, 197 + }; 198 + 199 + static int ioapic_xlate(struct irq_domain *domain, 200 + struct device_node *controller, 201 + const u32 *intspec, u32 intsize, 202 + irq_hw_number_t *out_hwirq, u32 *out_type) 203 + { 204 + struct io_apic_irq_attr attr; 205 + struct of_ioapic_type *it; 206 + u32 line, idx; 207 + int rc; 208 + 209 + if (WARN_ON(intsize < 2)) 210 + return -EINVAL; 211 + 212 + line = intspec[0]; 213 + 214 + if (intspec[1] >= ARRAY_SIZE(of_ioapic_type)) 215 + return -EINVAL; 216 + 217 + it = &of_ioapic_type[intspec[1]]; 218 + 219 + idx = (u32)(long)domain->host_data; 220 + set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); 221 + 222 + rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), 223 + cpu_to_node(0), &attr); 224 + if (rc) 225 + return rc; 226 + 227 + *out_hwirq = line; 228 + *out_type = it->out_type; 229 + return 0; 230 + } 231 + 232 + const struct irq_domain_ops ioapic_irq_domain_ops = { 233 + .xlate = ioapic_xlate, 234 + }; 235 + 169 236 static void __init dtb_add_ioapic(struct device_node *dn) 170 237 { 171 238 struct resource r; 172 239 int ret; 240 + struct ioapic_domain_cfg cfg = { 241 + .type = IOAPIC_DOMAIN_DYNAMIC, 242 + .ops = &ioapic_irq_domain_ops, 243 + .dev = dn, 244 + }; 173 245 174 246 ret = of_address_to_resource(dn, 0, &r); 175 247 if (ret) { ··· 249 177 dn->full_name); 250 178 return; 251 179 } 252 - mp_register_ioapic(++ioapic_id, r.start, gsi_top, NULL); 180 + mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg); 253 181 } 254 182 255 183 static void __init dtb_ioapic_setup(void) ··· 311 239 dtb_setup_hpet(); 312 240 dtb_apic_setup(); 313 241 } 314 - 315 - #ifdef CONFIG_X86_IO_APIC 316 - 317 - struct of_ioapic_type { 318 - u32 out_type; 319 - u32 trigger; 320 - u32 polarity; 321 - }; 322 - 323 - static struct of_ioapic_type of_ioapic_type[] = 324 - { 325 - { 326 - .out_type = IRQ_TYPE_EDGE_RISING, 327 - .trigger = IOAPIC_EDGE, 328 - .polarity = 1, 329 - }, 330 - { 331 - .out_type = IRQ_TYPE_LEVEL_LOW, 332 - .trigger = IOAPIC_LEVEL, 333 - .polarity = 0, 334 - }, 335 - { 336 - .out_type = IRQ_TYPE_LEVEL_HIGH, 337 - .trigger = IOAPIC_LEVEL, 338 - .polarity = 1, 339 - }, 340 - { 341 - .out_type = IRQ_TYPE_EDGE_FALLING, 342 - .trigger = IOAPIC_EDGE, 343 - .polarity = 0, 344 - }, 345 - }; 346 - 347 - static int ioapic_xlate(struct irq_domain *domain, 348 - struct device_node *controller, 349 - const u32 *intspec, u32 intsize, 350 - irq_hw_number_t *out_hwirq, u32 *out_type) 351 - { 352 - struct io_apic_irq_attr attr; 353 - struct of_ioapic_type *it; 354 - u32 line, idx; 355 - int rc; 356 - 357 - if (WARN_ON(intsize < 2)) 358 - return -EINVAL; 359 - 360 - line = intspec[0]; 361 - 362 - if (intspec[1] >= ARRAY_SIZE(of_ioapic_type)) 363 - return -EINVAL; 364 - 365 - it = &of_ioapic_type[intspec[1]]; 366 - 367 - idx = (u32) domain->host_data; 368 - set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); 369 - 370 - rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), 371 - cpu_to_node(0), &attr); 372 - if (rc) 373 - return rc; 374 - 375 - *out_hwirq = line; 376 - *out_type = it->out_type; 377 - return 0; 378 - } 379 - 380 - const struct irq_domain_ops ioapic_irq_domain_ops = { 381 - .xlate = ioapic_xlate, 382 - }; 383 - 384 - static void dt_add_ioapic_domain(unsigned int ioapic_num, 385 - struct device_node *np) 386 - { 387 - struct irq_domain *id; 388 - struct mp_ioapic_gsi *gsi_cfg; 389 - int ret; 390 - int num, legacy_irqs = nr_legacy_irqs(); 391 - 392 - gsi_cfg = mp_ioapic_gsi_routing(ioapic_num); 393 - num = gsi_cfg->gsi_end - gsi_cfg->gsi_base + 1; 394 - 395 - id = irq_domain_add_linear(np, num, &ioapic_irq_domain_ops, 396 - (void *)ioapic_num); 397 - BUG_ON(!id); 398 - if (gsi_cfg->gsi_base == 0) { 399 - /* 400 - * The first nr_legacy_irqs() irq descs are allocated in 401 - * early_irq_init() and need just a mapping. The 402 - * remaining irqs need both. All of them are preallocated 403 - * and assigned so we can keep the 1:1 mapping which the ioapic 404 - * is having. 405 - */ 406 - irq_domain_associate_many(id, 0, 0, legacy_irqs); 407 - 408 - if (num > legacy_irqs) { 409 - ret = irq_create_strict_mappings(id, legacy_irqs, 410 - legacy_irqs, num - legacy_irqs); 411 - if (ret) 412 - pr_err("Error creating mapping for the " 413 - "remaining IRQs: %d\n", ret); 414 - } 415 - irq_set_default_host(id); 416 - } else { 417 - ret = irq_create_strict_mappings(id, gsi_cfg->gsi_base, 0, num); 418 - if (ret) 419 - pr_err("Error creating IRQ mapping: %d\n", ret); 420 - } 421 - } 422 - 423 - static void __init ioapic_add_ofnode(struct device_node *np) 424 - { 425 - struct resource r; 426 - int i, ret; 427 - 428 - ret = of_address_to_resource(np, 0, &r); 429 - if (ret) { 430 - printk(KERN_ERR "Failed to obtain address for %s\n", 431 - np->full_name); 432 - return; 433 - } 434 - 435 - for (i = 0; i < nr_ioapics; i++) { 436 - if (r.start == mpc_ioapic_addr(i)) { 437 - dt_add_ioapic_domain(i, np); 438 - return; 439 - } 440 - } 441 - printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name); 442 - } 443 - 444 - void __init x86_add_irq_domains(void) 445 - { 446 - struct device_node *dp; 447 - 448 - if (!of_have_populated_dt()) 449 - return; 450 - 451 - for_each_node_with_property(dp, "interrupt-controller") { 452 - if (of_device_is_compatible(dp, "intel,ce4100-ioapic")) 453 - ioapic_add_ofnode(dp); 454 - } 455 - } 456 - #else 457 - void __init x86_add_irq_domains(void) { } 458 - #endif
-6
arch/x86/kernel/irqinit.c
··· 87 87 int i; 88 88 89 89 /* 90 - * We probably need a better place for this, but it works for 91 - * now ... 92 - */ 93 - x86_add_irq_domains(); 94 - 95 - /* 96 90 * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15. 97 91 * If these IRQ's are handled by legacy interrupt-controllers like PIC, 98 92 * then this configuration will likely be static after the boot. If