Lines Matching full:domain
28 static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
31 static void irq_domain_check_hierarchy(struct irq_domain *domain);
32 static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq);
63 * identifying an irq domain
66 * @name: Optional user provided domain name
75 * domain struct.
131 static int alloc_name(struct irq_domain *domain, char *base, enum irq_domain_bus_token bus_token) in alloc_name() argument
134 domain->name = kasprintf(GFP_KERNEL, "%s", base); in alloc_name()
136 domain->name = kasprintf(GFP_KERNEL, "%s-%d", base, bus_token); in alloc_name()
137 if (!domain->name) in alloc_name()
140 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in alloc_name()
144 static int alloc_fwnode_name(struct irq_domain *domain, const struct fwnode_handle *fwnode, in alloc_fwnode_name() argument
163 domain->name = strreplace(name, '/', ':'); in alloc_fwnode_name()
164 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in alloc_fwnode_name()
168 static int alloc_unknown_name(struct irq_domain *domain, enum irq_domain_bus_token bus_token) in alloc_unknown_name() argument
174 domain->name = kasprintf(GFP_KERNEL, "unknown-%d", id); in alloc_unknown_name()
176 domain->name = kasprintf(GFP_KERNEL, "unknown-%d-%d", id, bus_token); in alloc_unknown_name()
177 if (!domain->name) in alloc_unknown_name()
180 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in alloc_unknown_name()
184 static int irq_domain_set_name(struct irq_domain *domain, const struct irq_domain_info *info) in irq_domain_set_name() argument
206 return alloc_name(domain, fwid->name, bus_token); in irq_domain_set_name()
208 domain->name = fwid->name; in irq_domain_set_name()
210 return alloc_name(domain, fwid->name, bus_token); in irq_domain_set_name()
214 return alloc_fwnode_name(domain, fwnode, bus_token, info->name_suffix); in irq_domain_set_name()
217 if (domain->name) in irq_domain_set_name()
222 return alloc_unknown_name(domain, bus_token); in irq_domain_set_name()
227 struct irq_domain *domain; in __irq_domain_create() local
235 domain = kzalloc_node(struct_size(domain, revmap, info->size), in __irq_domain_create()
237 if (!domain) in __irq_domain_create()
240 err = irq_domain_set_name(domain, info); in __irq_domain_create()
242 kfree(domain); in __irq_domain_create()
246 domain->fwnode = fwnode_handle_get(info->fwnode); in __irq_domain_create()
247 fwnode_dev_initialized(domain->fwnode, true); in __irq_domain_create()
250 INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL); in __irq_domain_create()
251 domain->ops = info->ops; in __irq_domain_create()
252 domain->host_data = info->host_data; in __irq_domain_create()
253 domain->bus_token = info->bus_token; in __irq_domain_create()
254 domain->hwirq_max = info->hwirq_max; in __irq_domain_create()
257 domain->flags |= IRQ_DOMAIN_FLAG_NO_MAP; in __irq_domain_create()
259 domain->revmap_size = info->size; in __irq_domain_create()
262 * Hierarchical domains use the domain lock of the root domain in __irq_domain_create()
263 * (innermost domain). in __irq_domain_create()
266 * pointer is set to the domain itself so that &domain->root->mutex in __irq_domain_create()
269 mutex_init(&domain->mutex); in __irq_domain_create()
270 domain->root = domain; in __irq_domain_create()
272 irq_domain_check_hierarchy(domain); in __irq_domain_create()
274 return domain; in __irq_domain_create()
277 static void __irq_domain_publish(struct irq_domain *domain) in __irq_domain_publish() argument
280 debugfs_add_domain_dir(domain); in __irq_domain_publish()
281 list_add(&domain->link, &irq_domain_list); in __irq_domain_publish()
284 pr_debug("Added domain %s\n", domain->name); in __irq_domain_publish()
287 static void irq_domain_free(struct irq_domain *domain) in irq_domain_free() argument
289 fwnode_dev_initialized(domain->fwnode, false); in irq_domain_free()
290 fwnode_handle_put(domain->fwnode); in irq_domain_free()
291 if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED) in irq_domain_free()
292 kfree(domain->name); in irq_domain_free()
293 kfree(domain); in irq_domain_free()
311 struct irq_domain *domain; in __irq_domain_instantiate() local
314 domain = __irq_domain_create(info); in __irq_domain_instantiate()
315 if (IS_ERR(domain)) in __irq_domain_instantiate()
316 return domain; in __irq_domain_instantiate()
318 domain->flags |= info->domain_flags; in __irq_domain_instantiate()
319 domain->exit = info->exit; in __irq_domain_instantiate()
323 domain->root = info->parent->root; in __irq_domain_instantiate()
324 domain->parent = info->parent; in __irq_domain_instantiate()
329 err = irq_domain_alloc_generic_chips(domain, info->dgc_info); in __irq_domain_instantiate()
335 err = info->init(domain); in __irq_domain_instantiate()
340 __irq_domain_publish(domain); in __irq_domain_instantiate()
351 irq_domain_associate_many(domain, info->virq_base, info->hwirq_base, in __irq_domain_instantiate()
355 return domain; in __irq_domain_instantiate()
359 irq_domain_remove_generic_chips(domain); in __irq_domain_instantiate()
361 irq_domain_free(domain); in __irq_domain_instantiate()
366 * irq_domain_instantiate() - Instantiate a new irq domain data structure
367 * @info: Domain information pointer pointing to the information for this domain
369 * Return: A pointer to the instantiated irq domain or an ERR_PTR value.
378 * irq_domain_remove() - Remove an irq domain.
379 * @domain: domain to remove
381 * This routine is used to remove an irq domain. The caller must ensure
382 * that all mappings within the domain have been disposed of prior to
385 void irq_domain_remove(struct irq_domain *domain) in irq_domain_remove() argument
387 if (domain->exit) in irq_domain_remove()
388 domain->exit(domain); in irq_domain_remove()
391 debugfs_remove_domain_dir(domain); in irq_domain_remove()
393 WARN_ON(!radix_tree_empty(&domain->revmap_tree)); in irq_domain_remove()
395 list_del(&domain->link); in irq_domain_remove()
398 * If the going away domain is the default one, reset it. in irq_domain_remove()
400 if (unlikely(irq_default_domain == domain)) in irq_domain_remove()
405 if (domain->flags & IRQ_DOMAIN_FLAG_DESTROY_GC) in irq_domain_remove()
406 irq_domain_remove_generic_chips(domain); in irq_domain_remove()
408 pr_debug("Removed domain %s\n", domain->name); in irq_domain_remove()
409 irq_domain_free(domain); in irq_domain_remove()
413 void irq_domain_update_bus_token(struct irq_domain *domain, in irq_domain_update_bus_token() argument
418 if (domain->bus_token == bus_token) in irq_domain_update_bus_token()
423 domain->bus_token = bus_token; in irq_domain_update_bus_token()
425 name = kasprintf(GFP_KERNEL, "%s-%d", domain->name, bus_token); in irq_domain_update_bus_token()
431 debugfs_remove_domain_dir(domain); in irq_domain_update_bus_token()
433 if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED) in irq_domain_update_bus_token()
434 kfree(domain->name); in irq_domain_update_bus_token()
436 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in irq_domain_update_bus_token()
438 domain->name = name; in irq_domain_update_bus_token()
439 debugfs_add_domain_dir(domain); in irq_domain_update_bus_token()
449 * @first_irq: first number of irq block assigned to the domain,
451 * pre-map all of the irqs in the domain to virqs starting at first_irq.
452 * @ops: domain callbacks
477 struct irq_domain *domain = __irq_domain_instantiate(&info, true, false); in irq_domain_create_simple() local
479 return IS_ERR(domain) ? NULL : domain; in irq_domain_create_simple()
487 * @first_irq: first number of irq block assigned to the domain
491 * @ops: map/unmap domain callbacks
526 struct irq_domain *domain = __irq_domain_instantiate(&info, false, true); in irq_domain_create_legacy() local
528 return IS_ERR(domain) ? NULL : domain; in irq_domain_create_legacy()
533 * irq_find_matching_fwspec() - Locates a domain for a given fwspec
535 * @bus_token: domain-specific data
550 * bus_token == DOMAIN_BUS_ANY matches any domain, any other in irq_find_matching_fwspec()
551 * values must generate an exact match for the domain to be in irq_find_matching_fwspec()
576 * irq_set_default_host() - Set a "default" irq domain
577 * @domain: default domain pointer
579 * For convenience, it's possible to set a "default" domain that will be used
584 void irq_set_default_host(struct irq_domain *domain) in irq_set_default_host() argument
586 pr_debug("Default domain set to @0x%p\n", domain); in irq_set_default_host()
588 irq_default_domain = domain; in irq_set_default_host()
593 * irq_get_default_host() - Retrieve the "default" irq domain
595 * Returns: the default domain, if any.
607 static bool irq_domain_is_nomap(struct irq_domain *domain) in irq_domain_is_nomap() argument
610 (domain->flags & IRQ_DOMAIN_FLAG_NO_MAP); in irq_domain_is_nomap()
613 static void irq_domain_clear_mapping(struct irq_domain *domain, in irq_domain_clear_mapping() argument
616 lockdep_assert_held(&domain->root->mutex); in irq_domain_clear_mapping()
618 if (irq_domain_is_nomap(domain)) in irq_domain_clear_mapping()
621 if (hwirq < domain->revmap_size) in irq_domain_clear_mapping()
622 rcu_assign_pointer(domain->revmap[hwirq], NULL); in irq_domain_clear_mapping()
624 radix_tree_delete(&domain->revmap_tree, hwirq); in irq_domain_clear_mapping()
627 static void irq_domain_set_mapping(struct irq_domain *domain, in irq_domain_set_mapping() argument
633 * called from irq_domain_insert_irq() for each domain in a hierarchy. in irq_domain_set_mapping()
635 lockdep_assert_held(&domain->root->mutex); in irq_domain_set_mapping()
637 if (irq_domain_is_nomap(domain)) in irq_domain_set_mapping()
640 if (hwirq < domain->revmap_size) in irq_domain_set_mapping()
641 rcu_assign_pointer(domain->revmap[hwirq], irq_data); in irq_domain_set_mapping()
643 radix_tree_insert(&domain->revmap_tree, hwirq, irq_data); in irq_domain_set_mapping()
646 static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) in irq_domain_disassociate() argument
651 if (WARN(!irq_data || irq_data->domain != domain, in irq_domain_disassociate()
657 mutex_lock(&domain->root->mutex); in irq_domain_disassociate()
668 if (domain->ops->unmap) in irq_domain_disassociate()
669 domain->ops->unmap(domain, irq); in irq_domain_disassociate()
672 irq_data->domain = NULL; in irq_domain_disassociate()
674 domain->mapcount--; in irq_domain_disassociate()
677 irq_domain_clear_mapping(domain, hwirq); in irq_domain_disassociate()
679 mutex_unlock(&domain->root->mutex); in irq_domain_disassociate()
682 static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq, in irq_domain_associate_locked() argument
688 if (WARN(hwirq >= domain->hwirq_max, in irq_domain_associate_locked()
689 "error: hwirq 0x%x is too large for %s\n", (int)hwirq, domain->name)) in irq_domain_associate_locked()
693 if (WARN(irq_data->domain, "error: virq%i is already associated", virq)) in irq_domain_associate_locked()
697 irq_data->domain = domain; in irq_domain_associate_locked()
698 if (domain->ops->map) { in irq_domain_associate_locked()
699 ret = domain->ops->map(domain, virq, hwirq); in irq_domain_associate_locked()
708 domain->name, hwirq, virq, ret); in irq_domain_associate_locked()
710 irq_data->domain = NULL; in irq_domain_associate_locked()
716 domain->mapcount++; in irq_domain_associate_locked()
717 irq_domain_set_mapping(domain, hwirq, irq_data); in irq_domain_associate_locked()
724 int irq_domain_associate(struct irq_domain *domain, unsigned int virq, in irq_domain_associate() argument
729 mutex_lock(&domain->root->mutex); in irq_domain_associate()
730 ret = irq_domain_associate_locked(domain, virq, hwirq); in irq_domain_associate()
731 mutex_unlock(&domain->root->mutex); in irq_domain_associate()
737 void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base, in irq_domain_associate_many() argument
743 of_node = irq_domain_get_of_node(domain); in irq_domain_associate_many()
748 irq_domain_associate(domain, irq_base + i, hwirq_base + i); in irq_domain_associate_many()
755 * @domain: domain to allocate the irq for or NULL for default domain
763 unsigned int irq_create_direct_mapping(struct irq_domain *domain) in irq_create_direct_mapping() argument
768 if (domain == NULL) in irq_create_direct_mapping()
769 domain = irq_default_domain; in irq_create_direct_mapping()
771 of_node = irq_domain_get_of_node(domain); in irq_create_direct_mapping()
777 if (virq >= domain->hwirq_max) { in irq_create_direct_mapping()
779 domain->hwirq_max); in irq_create_direct_mapping()
785 if (irq_domain_associate(domain, virq, virq)) { in irq_create_direct_mapping()
795 static unsigned int irq_create_mapping_affinity_locked(struct irq_domain *domain, in irq_create_mapping_affinity_locked() argument
799 struct device_node *of_node = irq_domain_get_of_node(domain); in irq_create_mapping_affinity_locked()
802 pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); in irq_create_mapping_affinity_locked()
812 if (irq_domain_associate_locked(domain, virq, hwirq)) { in irq_create_mapping_affinity_locked()
817 pr_debug("irq %lu on domain %s mapped to virtual irq %u\n", in irq_create_mapping_affinity_locked()
825 * @domain: domain owning this hardware interrupt or NULL for default domain
826 * @hwirq: hardware irq number in that domain space
834 unsigned int irq_create_mapping_affinity(struct irq_domain *domain, in irq_create_mapping_affinity() argument
840 /* Look for default domain if necessary */ in irq_create_mapping_affinity()
841 if (domain == NULL) in irq_create_mapping_affinity()
842 domain = irq_default_domain; in irq_create_mapping_affinity()
843 if (domain == NULL) { in irq_create_mapping_affinity()
844 WARN(1, "%s(, %lx) called with NULL domain\n", __func__, hwirq); in irq_create_mapping_affinity()
848 mutex_lock(&domain->root->mutex); in irq_create_mapping_affinity()
851 virq = irq_find_mapping(domain, hwirq); in irq_create_mapping_affinity()
857 virq = irq_create_mapping_affinity_locked(domain, hwirq, affinity); in irq_create_mapping_affinity()
859 mutex_unlock(&domain->root->mutex); in irq_create_mapping_affinity()
878 /* If domain has no translation, then we assume interrupt line */ in irq_domain_translate()
898 struct irq_domain *domain; in irq_create_fwspec_mapping() local
905 domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_WIRED); in irq_create_fwspec_mapping()
906 if (!domain) in irq_create_fwspec_mapping()
907 domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_ANY); in irq_create_fwspec_mapping()
909 domain = irq_default_domain; in irq_create_fwspec_mapping()
912 if (!domain) { in irq_create_fwspec_mapping()
913 pr_warn("no irq domain found for %s !\n", in irq_create_fwspec_mapping()
918 if (irq_domain_translate(domain, fwspec, &hwirq, &type)) in irq_create_fwspec_mapping()
928 mutex_lock(&domain->root->mutex); in irq_create_fwspec_mapping()
934 virq = irq_find_mapping(domain, hwirq); in irq_create_fwspec_mapping()
965 if (irq_domain_is_hierarchy(domain)) { in irq_create_fwspec_mapping()
966 if (irq_domain_is_msi_device(domain)) { in irq_create_fwspec_mapping()
967 mutex_unlock(&domain->root->mutex); in irq_create_fwspec_mapping()
968 virq = msi_device_domain_alloc_wired(domain, hwirq, type); in irq_create_fwspec_mapping()
969 mutex_lock(&domain->root->mutex); in irq_create_fwspec_mapping()
971 virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE, in irq_create_fwspec_mapping()
979 virq = irq_create_mapping_affinity_locked(domain, hwirq, NULL); in irq_create_fwspec_mapping()
993 mutex_unlock(&domain->root->mutex); in irq_create_fwspec_mapping()
1017 struct irq_domain *domain; in irq_dispose_mapping() local
1023 domain = irq_data->domain; in irq_dispose_mapping()
1024 if (WARN_ON(domain == NULL)) in irq_dispose_mapping()
1027 if (irq_domain_is_hierarchy(domain)) { in irq_dispose_mapping()
1028 irq_domain_free_one_irq(domain, virq); in irq_dispose_mapping()
1030 irq_domain_disassociate(domain, virq); in irq_dispose_mapping()
1038 * @domain: domain owning this hardware interrupt
1039 * @hwirq: hardware irq number in that domain space
1044 struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain, in __irq_resolve_mapping() argument
1051 /* Look for default domain if necessary */ in __irq_resolve_mapping()
1052 if (domain == NULL) in __irq_resolve_mapping()
1053 domain = irq_default_domain; in __irq_resolve_mapping()
1054 if (domain == NULL) in __irq_resolve_mapping()
1057 if (irq_domain_is_nomap(domain)) { in __irq_resolve_mapping()
1058 if (hwirq < domain->hwirq_max) { in __irq_resolve_mapping()
1059 data = irq_domain_get_irq_data(domain, hwirq); in __irq_resolve_mapping()
1071 if (hwirq < domain->revmap_size) in __irq_resolve_mapping()
1072 data = rcu_dereference(domain->revmap[hwirq]); in __irq_resolve_mapping()
1074 data = radix_tree_lookup(&domain->revmap_tree, hwirq); in __irq_resolve_mapping()
1089 * @d: Interrupt domain involved in the translation
1113 * @d: Interrupt domain involved in the translation
1137 * @d: Interrupt domain involved in the translation
1176 * @d: Interrupt domain involved in the translation
1197 * @d: Interrupt domain involved in the translation
1257 * @parent: Parent irq domain to associate with the new domain
1258 * @flags: Irq domain flags associated to the domain
1259 * @size: Size of the domain. See below
1261 * @ops: Pointer to the interrupt domain callbacks
1264 * If @size is 0 a tree domain is created, otherwise a linear domain.
1266 * If successful the parent is associated to the new domain and the
1267 * domain flags are set.
1268 * Returns pointer to IRQ domain, or NULL on failure.
1301 struct irq_domain *domain = data->domain; in irq_domain_insert_irq() local
1303 domain->mapcount++; in irq_domain_insert_irq()
1304 irq_domain_set_mapping(domain, data->hwirq, data); in irq_domain_insert_irq()
1320 struct irq_domain *domain = data->domain; in irq_domain_remove_irq() local
1323 domain->mapcount--; in irq_domain_remove_irq()
1324 irq_domain_clear_mapping(domain, hwirq); in irq_domain_remove_irq()
1328 static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain, in irq_domain_insert_irq_data() argument
1339 irq_data->domain = domain; in irq_domain_insert_irq_data()
1365 irq_data->domain = NULL; in irq_domain_free_irq_data()
1373 * @domain: IRQ domain from which the hierarchy is to be disconnected
1376 * Marks the @virq level belonging to @domain as disconnected.
1378 * to @domain.
1384 int irq_domain_disconnect_hierarchy(struct irq_domain *domain, in irq_domain_disconnect_hierarchy() argument
1389 irqd = irq_domain_get_irq_data(domain, virq); in irq_domain_disconnect_hierarchy()
1436 virq, tail->parent_data->domain->name); in irq_domain_trim_hierarchy()
1447 static int irq_domain_alloc_irq_data(struct irq_domain *domain, in irq_domain_alloc_irq_data() argument
1457 irq_data->domain = domain; in irq_domain_alloc_irq_data()
1459 for (parent = domain->parent; parent; parent = parent->parent) { in irq_domain_alloc_irq_data()
1472 * irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
1473 * @domain: domain to match
1476 struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, in irq_domain_get_irq_data() argument
1483 if (irq_data->domain == domain) in irq_domain_get_irq_data()
1491 * irq_domain_set_hwirq_and_chip - Set hwirq and irqchip of @virq at @domain
1492 * @domain: Interrupt domain to match
1498 int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, unsigned int virq, in irq_domain_set_hwirq_and_chip() argument
1503 struct irq_data *irq_data = irq_domain_get_irq_data(domain, virq); in irq_domain_set_hwirq_and_chip()
1517 * irq_domain_set_info - Set the complete data for a @virq in @domain
1518 * @domain: Interrupt domain to match
1527 void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, in irq_domain_set_info() argument
1532 irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, chip_data); in irq_domain_set_info()
1540 * @domain: Interrupt domain to match
1544 void irq_domain_free_irqs_common(struct irq_domain *domain, unsigned int virq, in irq_domain_free_irqs_common() argument
1551 irq_data = irq_domain_get_irq_data(domain, virq + i); in irq_domain_free_irqs_common()
1555 irq_domain_free_irqs_parent(domain, virq, nr_irqs); in irq_domain_free_irqs_common()
1561 * @domain: Interrupt domain to match
1565 void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq, in irq_domain_free_irqs_top() argument
1574 irq_domain_free_irqs_common(domain, virq, nr_irqs); in irq_domain_free_irqs_top()
1577 static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain, in irq_domain_free_irqs_hierarchy() argument
1583 if (!domain->ops->free) in irq_domain_free_irqs_hierarchy()
1587 if (irq_domain_get_irq_data(domain, irq_base + i)) in irq_domain_free_irqs_hierarchy()
1588 domain->ops->free(domain, irq_base + i, 1); in irq_domain_free_irqs_hierarchy()
1592 int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, in irq_domain_alloc_irqs_hierarchy() argument
1596 if (!domain->ops->alloc) { in irq_domain_alloc_irqs_hierarchy()
1597 pr_debug("domain->ops->alloc() is NULL\n"); in irq_domain_alloc_irqs_hierarchy()
1601 return domain->ops->alloc(domain, irq_base, nr_irqs, arg); in irq_domain_alloc_irqs_hierarchy()
1604 static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, in irq_domain_alloc_irqs_locked() argument
1622 if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) { in irq_domain_alloc_irqs_locked()
1628 ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg); in irq_domain_alloc_irqs_locked()
1651 * __irq_domain_alloc_irqs - Allocate IRQs from domain
1652 * @domain: domain to allocate from
1656 * @arg: domain specific argument
1672 int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, in __irq_domain_alloc_irqs() argument
1678 if (domain == NULL) { in __irq_domain_alloc_irqs()
1679 domain = irq_default_domain; in __irq_domain_alloc_irqs()
1680 if (WARN(!domain, "domain is NULL; cannot allocate IRQ\n")) in __irq_domain_alloc_irqs()
1684 mutex_lock(&domain->root->mutex); in __irq_domain_alloc_irqs()
1685 ret = irq_domain_alloc_irqs_locked(domain, irq_base, nr_irqs, node, arg, in __irq_domain_alloc_irqs()
1687 mutex_unlock(&domain->root->mutex); in __irq_domain_alloc_irqs()
1698 lockdep_assert_held(&d->domain->root->mutex); in irq_domain_fix_revmap()
1700 if (irq_domain_is_nomap(d->domain)) in irq_domain_fix_revmap()
1704 if (d->hwirq < d->domain->revmap_size) { in irq_domain_fix_revmap()
1706 rcu_assign_pointer(d->domain->revmap[d->hwirq], d); in irq_domain_fix_revmap()
1708 slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq); in irq_domain_fix_revmap()
1710 radix_tree_replace_slot(&d->domain->revmap_tree, slot, d); in irq_domain_fix_revmap()
1715 * irq_domain_push_irq() - Push a domain in to the top of a hierarchy.
1716 * @domain: Domain to push.
1717 * @virq: Irq to push the domain in to.
1721 * via a call to pci_enable_msix(), add an additional domain to the
1725 int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg) in irq_domain_push_irq() argument
1747 if (domain == NULL) in irq_domain_push_irq()
1750 if (WARN_ON(!irq_domain_is_hierarchy(domain))) in irq_domain_push_irq()
1756 if (domain->parent != irq_data->domain) in irq_domain_push_irq()
1764 mutex_lock(&domain->root->mutex); in irq_domain_push_irq()
1771 * values for this domain. in irq_domain_push_irq()
1774 irq_data->domain = domain; in irq_domain_push_irq()
1781 rv = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); in irq_domain_push_irq()
1790 irq_domain_set_mapping(domain, irq_data->hwirq, irq_data); in irq_domain_push_irq()
1792 mutex_unlock(&domain->root->mutex); in irq_domain_push_irq()
1799 * irq_domain_pop_irq() - Remove a domain from the top of a hierarchy.
1800 * @domain: Domain to remove.
1801 * @virq: Irq to remove the domain from.
1806 int irq_domain_pop_irq(struct irq_domain *domain, int virq) in irq_domain_pop_irq() argument
1828 if (domain == NULL) in irq_domain_pop_irq()
1834 tmp_irq_data = irq_domain_get_irq_data(domain, virq); in irq_domain_pop_irq()
1836 /* We can only "pop" if this domain is at the top of the list */ in irq_domain_pop_irq()
1840 if (WARN_ON(irq_data->domain != domain)) in irq_domain_pop_irq()
1847 mutex_lock(&domain->root->mutex); in irq_domain_pop_irq()
1851 irq_domain_clear_mapping(domain, irq_data->hwirq); in irq_domain_pop_irq()
1852 irq_domain_free_irqs_hierarchy(domain, virq, 1); in irq_domain_pop_irq()
1859 mutex_unlock(&domain->root->mutex); in irq_domain_pop_irq()
1875 struct irq_domain *domain; in irq_domain_free_irqs() local
1878 if (WARN(!data || !data->domain || !data->domain->ops->free, in irq_domain_free_irqs()
1882 domain = data->domain; in irq_domain_free_irqs()
1884 mutex_lock(&domain->root->mutex); in irq_domain_free_irqs()
1887 irq_domain_free_irqs_hierarchy(domain, virq, nr_irqs); in irq_domain_free_irqs()
1888 mutex_unlock(&domain->root->mutex); in irq_domain_free_irqs()
1894 static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq) in irq_domain_free_one_irq() argument
1896 if (irq_domain_is_msi_device(domain)) in irq_domain_free_one_irq()
1897 msi_device_domain_free_wired(domain, virq); in irq_domain_free_one_irq()
1903 * irq_domain_alloc_irqs_parent - Allocate interrupts from parent domain
1904 * @domain: Domain below which interrupts must be allocated
1907 * @arg: Allocation data (arch/domain specific)
1909 int irq_domain_alloc_irqs_parent(struct irq_domain *domain, in irq_domain_alloc_irqs_parent() argument
1913 if (!domain->parent) in irq_domain_alloc_irqs_parent()
1916 return irq_domain_alloc_irqs_hierarchy(domain->parent, irq_base, in irq_domain_alloc_irqs_parent()
1922 * irq_domain_free_irqs_parent - Free interrupts from parent domain
1923 * @domain: Domain below which interrupts must be freed
1927 void irq_domain_free_irqs_parent(struct irq_domain *domain, in irq_domain_free_irqs_parent() argument
1930 if (!domain->parent) in irq_domain_free_irqs_parent()
1933 irq_domain_free_irqs_hierarchy(domain->parent, irq_base, nr_irqs); in irq_domain_free_irqs_parent()
1939 if (irq_data && irq_data->domain) { in __irq_domain_deactivate_irq()
1940 struct irq_domain *domain = irq_data->domain; in __irq_domain_deactivate_irq() local
1942 if (domain->ops->deactivate) in __irq_domain_deactivate_irq()
1943 domain->ops->deactivate(domain, irq_data); in __irq_domain_deactivate_irq()
1953 if (irqd && irqd->domain) { in __irq_domain_activate_irq()
1954 struct irq_domain *domain = irqd->domain; in __irq_domain_activate_irq() local
1959 if (!ret && domain->ops->activate) { in __irq_domain_activate_irq()
1960 ret = domain->ops->activate(domain, irqd, reserve); in __irq_domain_activate_irq()
2005 static void irq_domain_check_hierarchy(struct irq_domain *domain) in irq_domain_check_hierarchy() argument
2008 if (domain->ops->alloc) in irq_domain_check_hierarchy()
2009 domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY; in irq_domain_check_hierarchy()
2013 * irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
2014 * @domain: domain to match
2017 struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, in irq_domain_get_irq_data() argument
2022 return (irq_data && irq_data->domain == domain) ? irq_data : NULL; in irq_domain_get_irq_data()
2027 * irq_domain_set_info - Set the complete data for a @virq in @domain
2028 * @domain: Interrupt domain to match
2037 void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, in irq_domain_set_info() argument
2047 static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, in irq_domain_alloc_irqs_locked() argument
2054 static void irq_domain_check_hierarchy(struct irq_domain *domain) { } in irq_domain_check_hierarchy() argument
2055 static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq) { } in irq_domain_free_one_irq() argument
2098 /* Default domain? Might be NULL */ in irq_domain_debug_show()