1 #define pr_fmt(fmt) "irq: " fmt 2 3 #include <linux/debugfs.h> 4 #include <linux/hardirq.h> 5 #include <linux/interrupt.h> 6 #include <linux/irq.h> 7 #include <linux/irqdesc.h> 8 #include <linux/irqdomain.h> 9 #include <linux/module.h> 10 #include <linux/mutex.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/seq_file.h> 14 #include <linux/slab.h> 15 #include <linux/smp.h> 16 #include <linux/fs.h> 17 18 #define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs. 19 * ie. legacy 8259, gets irqs 1..15 */ 20 #define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */ 21 #define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */ 22 #define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */ 23 24 static LIST_HEAD(irq_domain_list); 25 static DEFINE_MUTEX(irq_domain_mutex); 26 27 static DEFINE_MUTEX(revmap_trees_mutex); 28 static struct irq_domain *irq_default_domain; 29 30 /** 31 * irq_domain_alloc() - Allocate a new irq_domain data structure 32 * @of_node: optional device-tree node of the interrupt controller 33 * @revmap_type: type of reverse mapping to use 34 * @ops: map/unmap domain callbacks 35 * @host_data: Controller private data pointer 36 * 37 * Allocates and initialize and irq_domain structure. Caller is expected to 38 * register allocated irq_domain with irq_domain_register(). Returns pointer 39 * to IRQ domain, or NULL on failure. 40 */ 41 static struct irq_domain *irq_domain_alloc(struct device_node *of_node, 42 unsigned int revmap_type, 43 const struct irq_domain_ops *ops, 44 void *host_data) 45 { 46 struct irq_domain *domain; 47 48 domain = kzalloc(sizeof(*domain), GFP_KERNEL); 49 if (WARN_ON(!domain)) 50 return NULL; 51 52 /* Fill structure */ 53 domain->revmap_type = revmap_type; 54 domain->ops = ops; 55 domain->host_data = host_data; 56 domain->of_node = of_node_get(of_node); 57 58 return domain; 59 } 60 61 static void irq_domain_free(struct irq_domain *domain) 62 { 63 of_node_put(domain->of_node); 64 kfree(domain); 65 } 66 67 static void irq_domain_add(struct irq_domain *domain) 68 { 69 mutex_lock(&irq_domain_mutex); 70 list_add(&domain->link, &irq_domain_list); 71 mutex_unlock(&irq_domain_mutex); 72 pr_debug("Allocated domain of type %d @0x%p\n", 73 domain->revmap_type, domain); 74 } 75 76 /** 77 * irq_domain_remove() - Remove an irq domain. 78 * @domain: domain to remove 79 * 80 * This routine is used to remove an irq domain. The caller must ensure 81 * that all mappings within the domain have been disposed of prior to 82 * use, depending on the revmap type. 83 */ 84 void irq_domain_remove(struct irq_domain *domain) 85 { 86 mutex_lock(&irq_domain_mutex); 87 88 switch (domain->revmap_type) { 89 case IRQ_DOMAIN_MAP_LEGACY: 90 /* 91 * Legacy domains don't manage their own irq_desc 92 * allocations, we expect the caller to handle irq_desc 93 * freeing on their own. 94 */ 95 break; 96 case IRQ_DOMAIN_MAP_TREE: 97 /* 98 * radix_tree_delete() takes care of destroying the root 99 * node when all entries are removed. Shout if there are 100 * any mappings left. 101 */ 102 WARN_ON(domain->revmap_data.tree.height); 103 break; 104 case IRQ_DOMAIN_MAP_LINEAR: 105 kfree(domain->revmap_data.linear.revmap); 106 domain->revmap_data.linear.size = 0; 107 break; 108 case IRQ_DOMAIN_MAP_NOMAP: 109 break; 110 } 111 112 list_del(&domain->link); 113 114 /* 115 * If the going away domain is the default one, reset it. 116 */ 117 if (unlikely(irq_default_domain == domain)) 118 irq_set_default_host(NULL); 119 120 mutex_unlock(&irq_domain_mutex); 121 122 pr_debug("Removed domain of type %d @0x%p\n", 123 domain->revmap_type, domain); 124 125 irq_domain_free(domain); 126 } 127 EXPORT_SYMBOL_GPL(irq_domain_remove); 128 129 static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain, 130 irq_hw_number_t hwirq) 131 { 132 irq_hw_number_t first_hwirq = domain->revmap_data.legacy.first_hwirq; 133 int size = domain->revmap_data.legacy.size; 134 135 if (WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size)) 136 return 0; 137 return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq; 138 } 139 140 /** 141 * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain. 142 * @of_node: pointer to interrupt controller's device tree node. 143 * @size: total number of irqs in legacy mapping 144 * @first_irq: first number of irq block assigned to the domain 145 * @first_hwirq: first hwirq number to use for the translation. Should normally 146 * be '0', but a positive integer can be used if the effective 147 * hwirqs numbering does not begin at zero. 148 * @ops: map/unmap domain callbacks 149 * @host_data: Controller private data pointer 150 * 151 * Note: the map() callback will be called before this function returns 152 * for all legacy interrupts except 0 (which is always the invalid irq for 153 * a legacy controller). 154 */ 155 struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, 156 unsigned int size, 157 unsigned int first_irq, 158 irq_hw_number_t first_hwirq, 159 const struct irq_domain_ops *ops, 160 void *host_data) 161 { 162 struct irq_domain *domain; 163 unsigned int i; 164 165 domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data); 166 if (!domain) 167 return NULL; 168 169 domain->revmap_data.legacy.first_irq = first_irq; 170 domain->revmap_data.legacy.first_hwirq = first_hwirq; 171 domain->revmap_data.legacy.size = size; 172 173 mutex_lock(&irq_domain_mutex); 174 /* Verify that all the irqs are available */ 175 for (i = 0; i < size; i++) { 176 int irq = first_irq + i; 177 struct irq_data *irq_data = irq_get_irq_data(irq); 178 179 if (WARN_ON(!irq_data || irq_data->domain)) { 180 mutex_unlock(&irq_domain_mutex); 181 irq_domain_free(domain); 182 return NULL; 183 } 184 } 185 186 /* Claim all of the irqs before registering a legacy domain */ 187 for (i = 0; i < size; i++) { 188 struct irq_data *irq_data = irq_get_irq_data(first_irq + i); 189 irq_data->hwirq = first_hwirq + i; 190 irq_data->domain = domain; 191 } 192 mutex_unlock(&irq_domain_mutex); 193 194 for (i = 0; i < size; i++) { 195 int irq = first_irq + i; 196 int hwirq = first_hwirq + i; 197 198 /* IRQ0 gets ignored */ 199 if (!irq) 200 continue; 201 202 /* Legacy flags are left to default at this point, 203 * one can then use irq_create_mapping() to 204 * explicitly change them 205 */ 206 ops->map(domain, irq, hwirq); 207 208 /* Clear norequest flags */ 209 irq_clear_status_flags(irq, IRQ_NOREQUEST); 210 } 211 212 irq_domain_add(domain); 213 return domain; 214 } 215 EXPORT_SYMBOL_GPL(irq_domain_add_legacy); 216 217 /** 218 * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain. 219 * @of_node: pointer to interrupt controller's device tree node. 220 * @size: Number of interrupts in the domain. 221 * @ops: map/unmap domain callbacks 222 * @host_data: Controller private data pointer 223 */ 224 struct irq_domain *irq_domain_add_linear(struct device_node *of_node, 225 unsigned int size, 226 const struct irq_domain_ops *ops, 227 void *host_data) 228 { 229 struct irq_domain *domain; 230 unsigned int *revmap; 231 232 revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL); 233 if (WARN_ON(!revmap)) 234 return NULL; 235 236 domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data); 237 if (!domain) { 238 kfree(revmap); 239 return NULL; 240 } 241 domain->revmap_data.linear.size = size; 242 domain->revmap_data.linear.revmap = revmap; 243 irq_domain_add(domain); 244 return domain; 245 } 246 EXPORT_SYMBOL_GPL(irq_domain_add_linear); 247 248 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 249 unsigned int max_irq, 250 const struct irq_domain_ops *ops, 251 void *host_data) 252 { 253 struct irq_domain *domain = irq_domain_alloc(of_node, 254 IRQ_DOMAIN_MAP_NOMAP, ops, host_data); 255 if (domain) { 256 domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0; 257 irq_domain_add(domain); 258 } 259 return domain; 260 } 261 EXPORT_SYMBOL_GPL(irq_domain_add_nomap); 262 263 /** 264 * irq_domain_add_tree() 265 * @of_node: pointer to interrupt controller's device tree node. 266 * @ops: map/unmap domain callbacks 267 * 268 * Note: The radix tree will be allocated later during boot automatically 269 * (the reverse mapping will use the slow path until that happens). 270 */ 271 struct irq_domain *irq_domain_add_tree(struct device_node *of_node, 272 const struct irq_domain_ops *ops, 273 void *host_data) 274 { 275 struct irq_domain *domain = irq_domain_alloc(of_node, 276 IRQ_DOMAIN_MAP_TREE, ops, host_data); 277 if (domain) { 278 INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL); 279 irq_domain_add(domain); 280 } 281 return domain; 282 } 283 EXPORT_SYMBOL_GPL(irq_domain_add_tree); 284 285 /** 286 * irq_find_host() - Locates a domain for a given device node 287 * @node: device-tree node of the interrupt controller 288 */ 289 struct irq_domain *irq_find_host(struct device_node *node) 290 { 291 struct irq_domain *h, *found = NULL; 292 int rc; 293 294 /* We might want to match the legacy controller last since 295 * it might potentially be set to match all interrupts in 296 * the absence of a device node. This isn't a problem so far 297 * yet though... 298 */ 299 mutex_lock(&irq_domain_mutex); 300 list_for_each_entry(h, &irq_domain_list, link) { 301 if (h->ops->match) 302 rc = h->ops->match(h, node); 303 else 304 rc = (h->of_node != NULL) && (h->of_node == node); 305 306 if (rc) { 307 found = h; 308 break; 309 } 310 } 311 mutex_unlock(&irq_domain_mutex); 312 return found; 313 } 314 EXPORT_SYMBOL_GPL(irq_find_host); 315 316 /** 317 * irq_set_default_host() - Set a "default" irq domain 318 * @domain: default domain pointer 319 * 320 * For convenience, it's possible to set a "default" domain that will be used 321 * whenever NULL is passed to irq_create_mapping(). It makes life easier for 322 * platforms that want to manipulate a few hard coded interrupt numbers that 323 * aren't properly represented in the device-tree. 324 */ 325 void irq_set_default_host(struct irq_domain *domain) 326 { 327 pr_debug("Default domain set to @0x%p\n", domain); 328 329 irq_default_domain = domain; 330 } 331 EXPORT_SYMBOL_GPL(irq_set_default_host); 332 333 static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, 334 irq_hw_number_t hwirq) 335 { 336 struct irq_data *irq_data = irq_get_irq_data(virq); 337 338 irq_data->hwirq = hwirq; 339 irq_data->domain = domain; 340 if (domain->ops->map(domain, virq, hwirq)) { 341 pr_debug("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq); 342 irq_data->domain = NULL; 343 irq_data->hwirq = 0; 344 return -1; 345 } 346 347 irq_clear_status_flags(virq, IRQ_NOREQUEST); 348 349 return 0; 350 } 351 352 /** 353 * irq_create_direct_mapping() - Allocate an irq for direct mapping 354 * @domain: domain to allocate the irq for or NULL for default domain 355 * 356 * This routine is used for irq controllers which can choose the hardware 357 * interrupt numbers they generate. In such a case it's simplest to use 358 * the linux irq as the hardware interrupt number. 359 */ 360 unsigned int irq_create_direct_mapping(struct irq_domain *domain) 361 { 362 unsigned int virq; 363 364 if (domain == NULL) 365 domain = irq_default_domain; 366 367 BUG_ON(domain == NULL); 368 WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP); 369 370 virq = irq_alloc_desc_from(1, 0); 371 if (!virq) { 372 pr_debug("create_direct virq allocation failed\n"); 373 return 0; 374 } 375 if (virq >= domain->revmap_data.nomap.max_irq) { 376 pr_err("ERROR: no free irqs available below %i maximum\n", 377 domain->revmap_data.nomap.max_irq); 378 irq_free_desc(virq); 379 return 0; 380 } 381 pr_debug("create_direct obtained virq %d\n", virq); 382 383 if (irq_setup_virq(domain, virq, virq)) { 384 irq_free_desc(virq); 385 return 0; 386 } 387 388 return virq; 389 } 390 EXPORT_SYMBOL_GPL(irq_create_direct_mapping); 391 392 /** 393 * irq_create_mapping() - Map a hardware interrupt into linux irq space 394 * @domain: domain owning this hardware interrupt or NULL for default domain 395 * @hwirq: hardware irq number in that domain space 396 * 397 * Only one mapping per hardware interrupt is permitted. Returns a linux 398 * irq number. 399 * If the sense/trigger is to be specified, set_irq_type() should be called 400 * on the number returned from that call. 401 */ 402 unsigned int irq_create_mapping(struct irq_domain *domain, 403 irq_hw_number_t hwirq) 404 { 405 unsigned int hint; 406 int virq; 407 408 pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); 409 410 /* Look for default domain if nececssary */ 411 if (domain == NULL) 412 domain = irq_default_domain; 413 if (domain == NULL) { 414 pr_warning("irq_create_mapping called for" 415 " NULL domain, hwirq=%lx\n", hwirq); 416 WARN_ON(1); 417 return 0; 418 } 419 pr_debug("-> using domain @%p\n", domain); 420 421 /* Check if mapping already exists */ 422 virq = irq_find_mapping(domain, hwirq); 423 if (virq) { 424 pr_debug("-> existing mapping on virq %d\n", virq); 425 return virq; 426 } 427 428 /* Get a virtual interrupt number */ 429 if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) 430 return irq_domain_legacy_revmap(domain, hwirq); 431 432 /* Allocate a virtual interrupt number */ 433 hint = hwirq % nr_irqs; 434 if (hint == 0) 435 hint++; 436 virq = irq_alloc_desc_from(hint, 0); 437 if (virq <= 0) 438 virq = irq_alloc_desc_from(1, 0); 439 if (virq <= 0) { 440 pr_debug("-> virq allocation failed\n"); 441 return 0; 442 } 443 444 if (irq_setup_virq(domain, virq, hwirq)) { 445 if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY) 446 irq_free_desc(virq); 447 return 0; 448 } 449 450 pr_debug("irq %lu on domain %s mapped to virtual irq %u\n", 451 hwirq, domain->of_node ? domain->of_node->full_name : "null", virq); 452 453 return virq; 454 } 455 EXPORT_SYMBOL_GPL(irq_create_mapping); 456 457 unsigned int irq_create_of_mapping(struct device_node *controller, 458 const u32 *intspec, unsigned int intsize) 459 { 460 struct irq_domain *domain; 461 irq_hw_number_t hwirq; 462 unsigned int type = IRQ_TYPE_NONE; 463 unsigned int virq; 464 465 domain = controller ? irq_find_host(controller) : irq_default_domain; 466 if (!domain) { 467 #ifdef CONFIG_MIPS 468 /* 469 * Workaround to avoid breaking interrupt controller drivers 470 * that don't yet register an irq_domain. This is temporary 471 * code. ~~~gcl, Feb 24, 2012 472 * 473 * Scheduled for removal in Linux v3.6. That should be enough 474 * time. 475 */ 476 if (intsize > 0) 477 return intspec[0]; 478 #endif 479 pr_warning("no irq domain found for %s !\n", 480 controller->full_name); 481 return 0; 482 } 483 484 /* If domain has no translation, then we assume interrupt line */ 485 if (domain->ops->xlate == NULL) 486 hwirq = intspec[0]; 487 else { 488 if (domain->ops->xlate(domain, controller, intspec, intsize, 489 &hwirq, &type)) 490 return 0; 491 } 492 493 /* Create mapping */ 494 virq = irq_create_mapping(domain, hwirq); 495 if (!virq) 496 return virq; 497 498 /* Set type if specified and different than the current one */ 499 if (type != IRQ_TYPE_NONE && 500 type != (irqd_get_trigger_type(irq_get_irq_data(virq)))) 501 irq_set_irq_type(virq, type); 502 return virq; 503 } 504 EXPORT_SYMBOL_GPL(irq_create_of_mapping); 505 506 /** 507 * irq_dispose_mapping() - Unmap an interrupt 508 * @virq: linux irq number of the interrupt to unmap 509 */ 510 void irq_dispose_mapping(unsigned int virq) 511 { 512 struct irq_data *irq_data = irq_get_irq_data(virq); 513 struct irq_domain *domain; 514 irq_hw_number_t hwirq; 515 516 if (!virq || !irq_data) 517 return; 518 519 domain = irq_data->domain; 520 if (WARN_ON(domain == NULL)) 521 return; 522 523 /* Never unmap legacy interrupts */ 524 if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) 525 return; 526 527 irq_set_status_flags(virq, IRQ_NOREQUEST); 528 529 /* remove chip and handler */ 530 irq_set_chip_and_handler(virq, NULL, NULL); 531 532 /* Make sure it's completed */ 533 synchronize_irq(virq); 534 535 /* Tell the PIC about it */ 536 if (domain->ops->unmap) 537 domain->ops->unmap(domain, virq); 538 smp_mb(); 539 540 /* Clear reverse map */ 541 hwirq = irq_data->hwirq; 542 switch(domain->revmap_type) { 543 case IRQ_DOMAIN_MAP_LINEAR: 544 if (hwirq < domain->revmap_data.linear.size) 545 domain->revmap_data.linear.revmap[hwirq] = 0; 546 break; 547 case IRQ_DOMAIN_MAP_TREE: 548 mutex_lock(&revmap_trees_mutex); 549 radix_tree_delete(&domain->revmap_data.tree, hwirq); 550 mutex_unlock(&revmap_trees_mutex); 551 break; 552 } 553 554 irq_free_desc(virq); 555 } 556 EXPORT_SYMBOL_GPL(irq_dispose_mapping); 557 558 /** 559 * irq_find_mapping() - Find a linux irq from an hw irq number. 560 * @domain: domain owning this hardware interrupt 561 * @hwirq: hardware irq number in that domain space 562 * 563 * This is a slow path, for use by generic code. It's expected that an 564 * irq controller implementation directly calls the appropriate low level 565 * mapping function. 566 */ 567 unsigned int irq_find_mapping(struct irq_domain *domain, 568 irq_hw_number_t hwirq) 569 { 570 unsigned int i; 571 unsigned int hint = hwirq % nr_irqs; 572 573 /* Look for default domain if nececssary */ 574 if (domain == NULL) 575 domain = irq_default_domain; 576 if (domain == NULL) 577 return 0; 578 579 /* legacy -> bail early */ 580 if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) 581 return irq_domain_legacy_revmap(domain, hwirq); 582 583 /* Slow path does a linear search of the map */ 584 if (hint == 0) 585 hint = 1; 586 i = hint; 587 do { 588 struct irq_data *data = irq_get_irq_data(i); 589 if (data && (data->domain == domain) && (data->hwirq == hwirq)) 590 return i; 591 i++; 592 if (i >= nr_irqs) 593 i = 1; 594 } while(i != hint); 595 return 0; 596 } 597 EXPORT_SYMBOL_GPL(irq_find_mapping); 598 599 /** 600 * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number. 601 * @domain: domain owning this hardware interrupt 602 * @hwirq: hardware irq number in that domain space 603 * 604 * This is a fast path, for use by irq controller code that uses radix tree 605 * revmaps 606 */ 607 unsigned int irq_radix_revmap_lookup(struct irq_domain *domain, 608 irq_hw_number_t hwirq) 609 { 610 struct irq_data *irq_data; 611 612 if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE)) 613 return irq_find_mapping(domain, hwirq); 614 615 /* 616 * Freeing an irq can delete nodes along the path to 617 * do the lookup via call_rcu. 618 */ 619 rcu_read_lock(); 620 irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq); 621 rcu_read_unlock(); 622 623 /* 624 * If found in radix tree, then fine. 625 * Else fallback to linear lookup - this should not happen in practice 626 * as it means that we failed to insert the node in the radix tree. 627 */ 628 return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq); 629 } 630 EXPORT_SYMBOL_GPL(irq_radix_revmap_lookup); 631 632 /** 633 * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping. 634 * @domain: domain owning this hardware interrupt 635 * @virq: linux irq number 636 * @hwirq: hardware irq number in that domain space 637 * 638 * This is for use by irq controllers that use a radix tree reverse 639 * mapping for fast lookup. 640 */ 641 void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq, 642 irq_hw_number_t hwirq) 643 { 644 struct irq_data *irq_data = irq_get_irq_data(virq); 645 646 if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE)) 647 return; 648 649 if (virq) { 650 mutex_lock(&revmap_trees_mutex); 651 radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data); 652 mutex_unlock(&revmap_trees_mutex); 653 } 654 } 655 EXPORT_SYMBOL_GPL(irq_radix_revmap_insert); 656 657 /** 658 * irq_linear_revmap() - Find a linux irq from a hw irq number. 659 * @domain: domain owning this hardware interrupt 660 * @hwirq: hardware irq number in that domain space 661 * 662 * This is a fast path, for use by irq controller code that uses linear 663 * revmaps. It does fallback to the slow path if the revmap doesn't exist 664 * yet and will create the revmap entry with appropriate locking 665 */ 666 unsigned int irq_linear_revmap(struct irq_domain *domain, 667 irq_hw_number_t hwirq) 668 { 669 unsigned int *revmap; 670 671 if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR)) 672 return irq_find_mapping(domain, hwirq); 673 674 /* Check revmap bounds */ 675 if (unlikely(hwirq >= domain->revmap_data.linear.size)) 676 return irq_find_mapping(domain, hwirq); 677 678 /* Check if revmap was allocated */ 679 revmap = domain->revmap_data.linear.revmap; 680 if (unlikely(revmap == NULL)) 681 return irq_find_mapping(domain, hwirq); 682 683 /* Fill up revmap with slow path if no mapping found */ 684 if (unlikely(!revmap[hwirq])) 685 revmap[hwirq] = irq_find_mapping(domain, hwirq); 686 687 return revmap[hwirq]; 688 } 689 EXPORT_SYMBOL_GPL(irq_linear_revmap); 690 691 #ifdef CONFIG_IRQ_DOMAIN_DEBUG 692 static int virq_debug_show(struct seq_file *m, void *private) 693 { 694 unsigned long flags; 695 struct irq_desc *desc; 696 const char *p; 697 static const char none[] = "none"; 698 void *data; 699 int i; 700 701 seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq", 702 "chip name", (int)(2 * sizeof(void *) + 2), "chip data", 703 "domain name"); 704 705 for (i = 1; i < nr_irqs; i++) { 706 desc = irq_to_desc(i); 707 if (!desc) 708 continue; 709 710 raw_spin_lock_irqsave(&desc->lock, flags); 711 712 if (desc->action && desc->action->handler) { 713 struct irq_chip *chip; 714 715 seq_printf(m, "%5d ", i); 716 seq_printf(m, "0x%05lx ", desc->irq_data.hwirq); 717 718 chip = irq_desc_get_chip(desc); 719 if (chip && chip->name) 720 p = chip->name; 721 else 722 p = none; 723 seq_printf(m, "%-15s ", p); 724 725 data = irq_desc_get_chip_data(desc); 726 seq_printf(m, data ? "0x%p " : " %p ", data); 727 728 if (desc->irq_data.domain && desc->irq_data.domain->of_node) 729 p = desc->irq_data.domain->of_node->full_name; 730 else 731 p = none; 732 seq_printf(m, "%s\n", p); 733 } 734 735 raw_spin_unlock_irqrestore(&desc->lock, flags); 736 } 737 738 return 0; 739 } 740 741 static int virq_debug_open(struct inode *inode, struct file *file) 742 { 743 return single_open(file, virq_debug_show, inode->i_private); 744 } 745 746 static const struct file_operations virq_debug_fops = { 747 .open = virq_debug_open, 748 .read = seq_read, 749 .llseek = seq_lseek, 750 .release = single_release, 751 }; 752 753 static int __init irq_debugfs_init(void) 754 { 755 if (debugfs_create_file("irq_domain_mapping", S_IRUGO, NULL, 756 NULL, &virq_debug_fops) == NULL) 757 return -ENOMEM; 758 759 return 0; 760 } 761 __initcall(irq_debugfs_init); 762 #endif /* CONFIG_IRQ_DOMAIN_DEBUG */ 763 764 static int irq_domain_simple_map(struct irq_domain *d, unsigned int irq, 765 irq_hw_number_t hwirq) 766 { 767 return 0; 768 } 769 770 /** 771 * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings 772 * 773 * Device Tree IRQ specifier translation function which works with one cell 774 * bindings where the cell value maps directly to the hwirq number. 775 */ 776 int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr, 777 const u32 *intspec, unsigned int intsize, 778 unsigned long *out_hwirq, unsigned int *out_type) 779 { 780 if (WARN_ON(intsize < 1)) 781 return -EINVAL; 782 *out_hwirq = intspec[0]; 783 *out_type = IRQ_TYPE_NONE; 784 return 0; 785 } 786 EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell); 787 788 /** 789 * irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings 790 * 791 * Device Tree IRQ specifier translation function which works with two cell 792 * bindings where the cell values map directly to the hwirq number 793 * and linux irq flags. 794 */ 795 int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr, 796 const u32 *intspec, unsigned int intsize, 797 irq_hw_number_t *out_hwirq, unsigned int *out_type) 798 { 799 if (WARN_ON(intsize < 2)) 800 return -EINVAL; 801 *out_hwirq = intspec[0]; 802 *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; 803 return 0; 804 } 805 EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell); 806 807 /** 808 * irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings 809 * 810 * Device Tree IRQ specifier translation function which works with either one 811 * or two cell bindings where the cell values map directly to the hwirq number 812 * and linux irq flags. 813 * 814 * Note: don't use this function unless your interrupt controller explicitly 815 * supports both one and two cell bindings. For the majority of controllers 816 * the _onecell() or _twocell() variants above should be used. 817 */ 818 int irq_domain_xlate_onetwocell(struct irq_domain *d, 819 struct device_node *ctrlr, 820 const u32 *intspec, unsigned int intsize, 821 unsigned long *out_hwirq, unsigned int *out_type) 822 { 823 if (WARN_ON(intsize < 1)) 824 return -EINVAL; 825 *out_hwirq = intspec[0]; 826 *out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE; 827 return 0; 828 } 829 EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell); 830 831 const struct irq_domain_ops irq_domain_simple_ops = { 832 .map = irq_domain_simple_map, 833 .xlate = irq_domain_xlate_onetwocell, 834 }; 835 EXPORT_SYMBOL_GPL(irq_domain_simple_ops); 836 837 #ifdef CONFIG_OF_IRQ 838 void irq_domain_generate_simple(const struct of_device_id *match, 839 u64 phys_base, unsigned int irq_start) 840 { 841 struct device_node *node; 842 pr_debug("looking for phys_base=%llx, irq_start=%i\n", 843 (unsigned long long) phys_base, (int) irq_start); 844 node = of_find_matching_node_by_address(NULL, match, phys_base); 845 if (node) 846 irq_domain_add_legacy(node, 32, irq_start, 0, 847 &irq_domain_simple_ops, NULL); 848 } 849 EXPORT_SYMBOL_GPL(irq_domain_generate_simple); 850 #endif 851