Lines Matching refs: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);
137 struct irq_domain *domain; in __irq_domain_create() local
146 domain = kzalloc_node(struct_size(domain, revmap, size), in __irq_domain_create()
148 if (!domain) in __irq_domain_create()
157 domain->fwnode = fwnode; in __irq_domain_create()
158 domain->name = kstrdup(fwid->name, GFP_KERNEL); in __irq_domain_create()
159 if (!domain->name) { in __irq_domain_create()
160 kfree(domain); in __irq_domain_create()
163 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in __irq_domain_create()
166 domain->fwnode = fwnode; in __irq_domain_create()
167 domain->name = fwid->name; in __irq_domain_create()
181 kfree(domain); in __irq_domain_create()
187 domain->name = name; in __irq_domain_create()
188 domain->fwnode = fwnode; in __irq_domain_create()
189 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in __irq_domain_create()
192 if (!domain->name) { in __irq_domain_create()
195 domain->name = kasprintf(GFP_KERNEL, "unknown-%d", in __irq_domain_create()
197 if (!domain->name) { in __irq_domain_create()
198 kfree(domain); in __irq_domain_create()
201 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in __irq_domain_create()
208 INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL); in __irq_domain_create()
209 domain->ops = ops; in __irq_domain_create()
210 domain->host_data = host_data; in __irq_domain_create()
211 domain->hwirq_max = hwirq_max; in __irq_domain_create()
214 domain->flags |= IRQ_DOMAIN_FLAG_NO_MAP; in __irq_domain_create()
216 domain->revmap_size = size; in __irq_domain_create()
226 mutex_init(&domain->mutex); in __irq_domain_create()
227 domain->root = domain; in __irq_domain_create()
229 irq_domain_check_hierarchy(domain); in __irq_domain_create()
231 return domain; in __irq_domain_create()
234 static void __irq_domain_publish(struct irq_domain *domain) in __irq_domain_publish() argument
237 debugfs_add_domain_dir(domain); in __irq_domain_publish()
238 list_add(&domain->link, &irq_domain_list); in __irq_domain_publish()
241 pr_debug("Added domain %s\n", domain->name); in __irq_domain_publish()
262 struct irq_domain *domain; in __irq_domain_add() local
264 domain = __irq_domain_create(fwnode, size, hwirq_max, direct_max, in __irq_domain_add()
266 if (domain) in __irq_domain_add()
267 __irq_domain_publish(domain); in __irq_domain_add()
269 return domain; in __irq_domain_add()
281 void irq_domain_remove(struct irq_domain *domain) in irq_domain_remove() argument
284 debugfs_remove_domain_dir(domain); in irq_domain_remove()
286 WARN_ON(!radix_tree_empty(&domain->revmap_tree)); in irq_domain_remove()
288 list_del(&domain->link); in irq_domain_remove()
293 if (unlikely(irq_default_domain == domain)) in irq_domain_remove()
298 pr_debug("Removed domain %s\n", domain->name); in irq_domain_remove()
300 fwnode_dev_initialized(domain->fwnode, false); in irq_domain_remove()
301 fwnode_handle_put(domain->fwnode); in irq_domain_remove()
302 if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED) in irq_domain_remove()
303 kfree(domain->name); in irq_domain_remove()
304 kfree(domain); in irq_domain_remove()
308 void irq_domain_update_bus_token(struct irq_domain *domain, in irq_domain_update_bus_token() argument
313 if (domain->bus_token == bus_token) in irq_domain_update_bus_token()
318 domain->bus_token = bus_token; in irq_domain_update_bus_token()
320 name = kasprintf(GFP_KERNEL, "%s-%d", domain->name, bus_token); in irq_domain_update_bus_token()
326 debugfs_remove_domain_dir(domain); in irq_domain_update_bus_token()
328 if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED) in irq_domain_update_bus_token()
329 kfree(domain->name); in irq_domain_update_bus_token()
331 domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; in irq_domain_update_bus_token()
333 domain->name = name; in irq_domain_update_bus_token()
334 debugfs_add_domain_dir(domain); in irq_domain_update_bus_token()
364 struct irq_domain *domain; in irq_domain_create_simple() local
366 domain = __irq_domain_add(fwnode, size, size, 0, ops, host_data); in irq_domain_create_simple()
367 if (!domain) in irq_domain_create_simple()
379 irq_domain_associate_many(domain, first_irq, 0, size); in irq_domain_create_simple()
382 return domain; in irq_domain_create_simple()
420 struct irq_domain *domain; in irq_domain_create_legacy() local
422 domain = __irq_domain_add(fwnode, first_hwirq + size, first_hwirq + size, 0, ops, host_data); in irq_domain_create_legacy()
423 if (domain) in irq_domain_create_legacy()
424 irq_domain_associate_many(domain, first_irq, first_hwirq, size); in irq_domain_create_legacy()
426 return domain; in irq_domain_create_legacy()
481 void irq_set_default_host(struct irq_domain *domain) in irq_set_default_host() argument
483 pr_debug("Default domain set to @0x%p\n", domain); in irq_set_default_host()
485 irq_default_domain = domain; in irq_set_default_host()
504 static bool irq_domain_is_nomap(struct irq_domain *domain) in irq_domain_is_nomap() argument
507 (domain->flags & IRQ_DOMAIN_FLAG_NO_MAP); in irq_domain_is_nomap()
510 static void irq_domain_clear_mapping(struct irq_domain *domain, in irq_domain_clear_mapping() argument
513 lockdep_assert_held(&domain->root->mutex); in irq_domain_clear_mapping()
515 if (irq_domain_is_nomap(domain)) in irq_domain_clear_mapping()
518 if (hwirq < domain->revmap_size) in irq_domain_clear_mapping()
519 rcu_assign_pointer(domain->revmap[hwirq], NULL); in irq_domain_clear_mapping()
521 radix_tree_delete(&domain->revmap_tree, hwirq); in irq_domain_clear_mapping()
524 static void irq_domain_set_mapping(struct irq_domain *domain, in irq_domain_set_mapping() argument
532 lockdep_assert_held(&domain->root->mutex); in irq_domain_set_mapping()
534 if (irq_domain_is_nomap(domain)) in irq_domain_set_mapping()
537 if (hwirq < domain->revmap_size) in irq_domain_set_mapping()
538 rcu_assign_pointer(domain->revmap[hwirq], irq_data); in irq_domain_set_mapping()
540 radix_tree_insert(&domain->revmap_tree, hwirq, irq_data); in irq_domain_set_mapping()
543 static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) in irq_domain_disassociate() argument
548 if (WARN(!irq_data || irq_data->domain != domain, in irq_domain_disassociate()
554 mutex_lock(&domain->root->mutex); in irq_domain_disassociate()
565 if (domain->ops->unmap) in irq_domain_disassociate()
566 domain->ops->unmap(domain, irq); in irq_domain_disassociate()
569 irq_data->domain = NULL; in irq_domain_disassociate()
571 domain->mapcount--; in irq_domain_disassociate()
574 irq_domain_clear_mapping(domain, hwirq); in irq_domain_disassociate()
576 mutex_unlock(&domain->root->mutex); in irq_domain_disassociate()
579 static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq, in irq_domain_associate_locked() argument
585 if (WARN(hwirq >= domain->hwirq_max, in irq_domain_associate_locked()
586 "error: hwirq 0x%x is too large for %s\n", (int)hwirq, domain->name)) in irq_domain_associate_locked()
590 if (WARN(irq_data->domain, "error: virq%i is already associated", virq)) in irq_domain_associate_locked()
594 irq_data->domain = domain; in irq_domain_associate_locked()
595 if (domain->ops->map) { in irq_domain_associate_locked()
596 ret = domain->ops->map(domain, virq, hwirq); in irq_domain_associate_locked()
605 domain->name, hwirq, virq, ret); in irq_domain_associate_locked()
607 irq_data->domain = NULL; in irq_domain_associate_locked()
613 domain->mapcount++; in irq_domain_associate_locked()
614 irq_domain_set_mapping(domain, hwirq, irq_data); in irq_domain_associate_locked()
621 int irq_domain_associate(struct irq_domain *domain, unsigned int virq, in irq_domain_associate() argument
626 mutex_lock(&domain->root->mutex); in irq_domain_associate()
627 ret = irq_domain_associate_locked(domain, virq, hwirq); in irq_domain_associate()
628 mutex_unlock(&domain->root->mutex); in irq_domain_associate()
634 void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base, in irq_domain_associate_many() argument
640 of_node = irq_domain_get_of_node(domain); in irq_domain_associate_many()
645 irq_domain_associate(domain, irq_base + i, hwirq_base + i); in irq_domain_associate_many()
660 unsigned int irq_create_direct_mapping(struct irq_domain *domain) in irq_create_direct_mapping() argument
665 if (domain == NULL) in irq_create_direct_mapping()
666 domain = irq_default_domain; in irq_create_direct_mapping()
668 of_node = irq_domain_get_of_node(domain); in irq_create_direct_mapping()
674 if (virq >= domain->hwirq_max) { in irq_create_direct_mapping()
676 domain->hwirq_max); in irq_create_direct_mapping()
682 if (irq_domain_associate(domain, virq, virq)) { in irq_create_direct_mapping()
692 static unsigned int irq_create_mapping_affinity_locked(struct irq_domain *domain, in irq_create_mapping_affinity_locked() argument
696 struct device_node *of_node = irq_domain_get_of_node(domain); in irq_create_mapping_affinity_locked()
699 pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); in irq_create_mapping_affinity_locked()
709 if (irq_domain_associate_locked(domain, virq, hwirq)) { in irq_create_mapping_affinity_locked()
731 unsigned int irq_create_mapping_affinity(struct irq_domain *domain, in irq_create_mapping_affinity() argument
738 if (domain == NULL) in irq_create_mapping_affinity()
739 domain = irq_default_domain; in irq_create_mapping_affinity()
740 if (domain == NULL) { in irq_create_mapping_affinity()
745 mutex_lock(&domain->root->mutex); in irq_create_mapping_affinity()
748 virq = irq_find_mapping(domain, hwirq); in irq_create_mapping_affinity()
754 virq = irq_create_mapping_affinity_locked(domain, hwirq, affinity); in irq_create_mapping_affinity()
756 mutex_unlock(&domain->root->mutex); in irq_create_mapping_affinity()
795 struct irq_domain *domain; in irq_create_fwspec_mapping() local
802 domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_WIRED); in irq_create_fwspec_mapping()
803 if (!domain) in irq_create_fwspec_mapping()
804 domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_ANY); in irq_create_fwspec_mapping()
806 domain = irq_default_domain; in irq_create_fwspec_mapping()
809 if (!domain) { in irq_create_fwspec_mapping()
815 if (irq_domain_translate(domain, fwspec, &hwirq, &type)) in irq_create_fwspec_mapping()
825 mutex_lock(&domain->root->mutex); in irq_create_fwspec_mapping()
831 virq = irq_find_mapping(domain, hwirq); in irq_create_fwspec_mapping()
862 if (irq_domain_is_hierarchy(domain)) { in irq_create_fwspec_mapping()
863 virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE, in irq_create_fwspec_mapping()
871 virq = irq_create_mapping_affinity_locked(domain, hwirq, NULL); in irq_create_fwspec_mapping()
885 mutex_unlock(&domain->root->mutex); in irq_create_fwspec_mapping()
909 struct irq_domain *domain; in irq_dispose_mapping() local
914 domain = irq_data->domain; in irq_dispose_mapping()
915 if (WARN_ON(domain == NULL)) in irq_dispose_mapping()
918 if (irq_domain_is_hierarchy(domain)) { in irq_dispose_mapping()
921 irq_domain_disassociate(domain, virq); in irq_dispose_mapping()
935 struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain, in __irq_resolve_mapping() argument
943 if (domain == NULL) in __irq_resolve_mapping()
944 domain = irq_default_domain; in __irq_resolve_mapping()
945 if (domain == NULL) in __irq_resolve_mapping()
948 if (irq_domain_is_nomap(domain)) { in __irq_resolve_mapping()
949 if (hwirq < domain->hwirq_max) { in __irq_resolve_mapping()
950 data = irq_domain_get_irq_data(domain, hwirq); in __irq_resolve_mapping()
962 if (hwirq < domain->revmap_size) in __irq_resolve_mapping()
963 data = rcu_dereference(domain->revmap[hwirq]); in __irq_resolve_mapping()
965 data = radix_tree_lookup(&domain->revmap_tree, hwirq); in __irq_resolve_mapping()
1142 struct irq_domain *domain; in irq_domain_create_hierarchy() local
1145 domain = __irq_domain_create(fwnode, size, size, 0, ops, host_data); in irq_domain_create_hierarchy()
1147 domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data); in irq_domain_create_hierarchy()
1149 if (domain) { in irq_domain_create_hierarchy()
1151 domain->root = parent->root; in irq_domain_create_hierarchy()
1152 domain->parent = parent; in irq_domain_create_hierarchy()
1153 domain->flags |= flags; in irq_domain_create_hierarchy()
1155 __irq_domain_publish(domain); in irq_domain_create_hierarchy()
1158 return domain; in irq_domain_create_hierarchy()
1167 struct irq_domain *domain = data->domain; in irq_domain_insert_irq() local
1169 domain->mapcount++; in irq_domain_insert_irq()
1170 irq_domain_set_mapping(domain, data->hwirq, data); in irq_domain_insert_irq()
1186 struct irq_domain *domain = data->domain; in irq_domain_remove_irq() local
1189 domain->mapcount--; in irq_domain_remove_irq()
1190 irq_domain_clear_mapping(domain, hwirq); in irq_domain_remove_irq()
1194 static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain, in irq_domain_insert_irq_data() argument
1205 irq_data->domain = domain; in irq_domain_insert_irq_data()
1231 irq_data->domain = NULL; in irq_domain_free_irq_data()
1250 int irq_domain_disconnect_hierarchy(struct irq_domain *domain, in irq_domain_disconnect_hierarchy() argument
1255 irqd = irq_domain_get_irq_data(domain, virq); in irq_domain_disconnect_hierarchy()
1302 virq, tail->parent_data->domain->name); in irq_domain_trim_hierarchy()
1313 static int irq_domain_alloc_irq_data(struct irq_domain *domain, in irq_domain_alloc_irq_data() argument
1323 irq_data->domain = domain; in irq_domain_alloc_irq_data()
1325 for (parent = domain->parent; parent; parent = parent->parent) { in irq_domain_alloc_irq_data()
1342 struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, in irq_domain_get_irq_data() argument
1349 if (irq_data->domain == domain) in irq_domain_get_irq_data()
1364 int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, unsigned int virq, in irq_domain_set_hwirq_and_chip() argument
1369 struct irq_data *irq_data = irq_domain_get_irq_data(domain, virq); in irq_domain_set_hwirq_and_chip()
1393 void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, in irq_domain_set_info() argument
1398 irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, chip_data); in irq_domain_set_info()
1410 void irq_domain_free_irqs_common(struct irq_domain *domain, unsigned int virq, in irq_domain_free_irqs_common() argument
1417 irq_data = irq_domain_get_irq_data(domain, virq + i); in irq_domain_free_irqs_common()
1421 irq_domain_free_irqs_parent(domain, virq, nr_irqs); in irq_domain_free_irqs_common()
1431 void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq, in irq_domain_free_irqs_top() argument
1440 irq_domain_free_irqs_common(domain, virq, nr_irqs); in irq_domain_free_irqs_top()
1443 static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain, in irq_domain_free_irqs_hierarchy() argument
1449 if (!domain->ops->free) in irq_domain_free_irqs_hierarchy()
1453 if (irq_domain_get_irq_data(domain, irq_base + i)) in irq_domain_free_irqs_hierarchy()
1454 domain->ops->free(domain, irq_base + i, 1); in irq_domain_free_irqs_hierarchy()
1458 int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, in irq_domain_alloc_irqs_hierarchy() argument
1462 if (!domain->ops->alloc) { in irq_domain_alloc_irqs_hierarchy()
1467 return domain->ops->alloc(domain, irq_base, nr_irqs, arg); in irq_domain_alloc_irqs_hierarchy()
1470 static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, in irq_domain_alloc_irqs_locked() argument
1488 if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) { in irq_domain_alloc_irqs_locked()
1494 ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg); in irq_domain_alloc_irqs_locked()
1538 int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, in __irq_domain_alloc_irqs() argument
1544 if (domain == NULL) { in __irq_domain_alloc_irqs()
1545 domain = irq_default_domain; in __irq_domain_alloc_irqs()
1546 if (WARN(!domain, "domain is NULL; cannot allocate IRQ\n")) in __irq_domain_alloc_irqs()
1550 mutex_lock(&domain->root->mutex); in __irq_domain_alloc_irqs()
1551 ret = irq_domain_alloc_irqs_locked(domain, irq_base, nr_irqs, node, arg, in __irq_domain_alloc_irqs()
1553 mutex_unlock(&domain->root->mutex); in __irq_domain_alloc_irqs()
1564 lockdep_assert_held(&d->domain->root->mutex); in irq_domain_fix_revmap()
1566 if (irq_domain_is_nomap(d->domain)) in irq_domain_fix_revmap()
1570 if (d->hwirq < d->domain->revmap_size) { in irq_domain_fix_revmap()
1572 rcu_assign_pointer(d->domain->revmap[d->hwirq], d); in irq_domain_fix_revmap()
1574 slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq); in irq_domain_fix_revmap()
1576 radix_tree_replace_slot(&d->domain->revmap_tree, slot, d); in irq_domain_fix_revmap()
1591 int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg) in irq_domain_push_irq() argument
1613 if (domain == NULL) in irq_domain_push_irq()
1616 if (WARN_ON(!irq_domain_is_hierarchy(domain))) in irq_domain_push_irq()
1622 if (domain->parent != irq_data->domain) in irq_domain_push_irq()
1630 mutex_lock(&domain->root->mutex); in irq_domain_push_irq()
1640 irq_data->domain = domain; in irq_domain_push_irq()
1647 rv = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); in irq_domain_push_irq()
1656 irq_domain_set_mapping(domain, irq_data->hwirq, irq_data); in irq_domain_push_irq()
1658 mutex_unlock(&domain->root->mutex); in irq_domain_push_irq()
1672 int irq_domain_pop_irq(struct irq_domain *domain, int virq) in irq_domain_pop_irq() argument
1694 if (domain == NULL) in irq_domain_pop_irq()
1700 tmp_irq_data = irq_domain_get_irq_data(domain, virq); in irq_domain_pop_irq()
1706 if (WARN_ON(irq_data->domain != domain)) in irq_domain_pop_irq()
1713 mutex_lock(&domain->root->mutex); in irq_domain_pop_irq()
1717 irq_domain_clear_mapping(domain, irq_data->hwirq); in irq_domain_pop_irq()
1718 irq_domain_free_irqs_hierarchy(domain, virq, 1); in irq_domain_pop_irq()
1725 mutex_unlock(&domain->root->mutex); in irq_domain_pop_irq()
1741 struct irq_domain *domain; in irq_domain_free_irqs() local
1744 if (WARN(!data || !data->domain || !data->domain->ops->free, in irq_domain_free_irqs()
1748 domain = data->domain; in irq_domain_free_irqs()
1750 mutex_lock(&domain->root->mutex); in irq_domain_free_irqs()
1753 irq_domain_free_irqs_hierarchy(domain, virq, nr_irqs); in irq_domain_free_irqs()
1754 mutex_unlock(&domain->root->mutex); in irq_domain_free_irqs()
1767 int irq_domain_alloc_irqs_parent(struct irq_domain *domain, in irq_domain_alloc_irqs_parent() argument
1771 if (!domain->parent) in irq_domain_alloc_irqs_parent()
1774 return irq_domain_alloc_irqs_hierarchy(domain->parent, irq_base, in irq_domain_alloc_irqs_parent()
1785 void irq_domain_free_irqs_parent(struct irq_domain *domain, in irq_domain_free_irqs_parent() argument
1788 if (!domain->parent) in irq_domain_free_irqs_parent()
1791 irq_domain_free_irqs_hierarchy(domain->parent, irq_base, nr_irqs); in irq_domain_free_irqs_parent()
1797 if (irq_data && irq_data->domain) { in __irq_domain_deactivate_irq()
1798 struct irq_domain *domain = irq_data->domain; in __irq_domain_deactivate_irq() local
1800 if (domain->ops->deactivate) in __irq_domain_deactivate_irq()
1801 domain->ops->deactivate(domain, irq_data); in __irq_domain_deactivate_irq()
1811 if (irqd && irqd->domain) { in __irq_domain_activate_irq()
1812 struct irq_domain *domain = irqd->domain; in __irq_domain_activate_irq() local
1817 if (!ret && domain->ops->activate) { in __irq_domain_activate_irq()
1818 ret = domain->ops->activate(domain, irqd, reserve); in __irq_domain_activate_irq()
1863 static void irq_domain_check_hierarchy(struct irq_domain *domain) in irq_domain_check_hierarchy() argument
1866 if (domain->ops->alloc) in irq_domain_check_hierarchy()
1867 domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY; in irq_domain_check_hierarchy()
1875 struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, in irq_domain_get_irq_data() argument
1880 return (irq_data && irq_data->domain == domain) ? irq_data : NULL; in irq_domain_get_irq_data()
1895 void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, in irq_domain_set_info() argument
1905 static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, in irq_domain_alloc_irqs_locked() argument
1912 static void irq_domain_check_hierarchy(struct irq_domain *domain) in irq_domain_check_hierarchy() argument