Lines Matching +full:iommu +full:- +full:parent
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2024-2025, Ventana Micro Systems Inc
12 #include <linux/iommu.h>
34 * rimt_set_fwnode() - Create rimt_fwnode and use it to register
35 * iommu data in the rimt_fwnode_list
37 * @rimt_node: RIMT table node associated with the IOMMU
51 return -ENOMEM; in rimt_set_fwnode()
53 INIT_LIST_HEAD(&np->list); in rimt_set_fwnode()
54 np->rimt_node = rimt_node; in rimt_set_fwnode()
55 np->fwnode = fwnode; in rimt_set_fwnode()
58 list_add_tail(&np->list, &rimt_fwnode_list); in rimt_set_fwnode()
70 if (node->type == ACPI_RIMT_NODE_TYPE_IOMMU) { in rimt_match_node_callback()
71 struct acpi_rimt_iommu *iommu_node = (struct acpi_rimt_iommu *)&node->node_data; in rimt_match_node_callback()
78 bdf = PCI_DEVID(pdev->bus->number, pdev->devfn); in rimt_match_node_callback()
79 if ((pci_domain_nr(pdev->bus) == iommu_node->pcie_segment_number) && in rimt_match_node_callback()
80 bdf == iommu_node->pcie_bdf) { in rimt_match_node_callback()
90 if (res && res->start == iommu_node->base_address) in rimt_match_node_callback()
95 } else if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { in rimt_match_node_callback()
100 pci_rc = (struct acpi_rimt_pcie_rc *)node->node_data; in rimt_match_node_callback()
103 * It is assumed that PCI segment numbers maps one-to-one in rimt_match_node_callback()
107 status = pci_rc->pcie_segment_number == pci_domain_nr(bus) ? in rimt_match_node_callback()
109 } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { in rimt_match_node_callback()
127 plat_dev = plat_dev->parent; in rimt_match_node_callback()
133 status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); in rimt_match_node_callback()
139 ncomp = (struct acpi_rimt_platform_device *)node->node_data; in rimt_match_node_callback()
140 status = !strcmp(ncomp->device_name, buf.pointer) ? in rimt_match_node_callback()
161 rimt->node_offset); in rimt_scan_node()
163 rimt_table->length); in rimt_scan_node()
165 for (i = 0; i < rimt->num_nodes; i++) { in rimt_scan_node()
170 if (rimt_node->type == type && in rimt_scan_node()
175 rimt_node->length); in rimt_scan_node()
182 * RISC-V supports IOMMU as a PCI device or a platform device.
185 * the platform device, the IOMMU driver should register itself with the
186 * RIMT module. This is true for PCI based IOMMU as well.
195 pr_err("Could not find IOMMU node in RIMT\n"); in rimt_iommu_register()
196 return -ENODEV; in rimt_iommu_register()
202 return -ENOMEM; in rimt_iommu_register()
204 rimt_fwnode->dev = dev; in rimt_iommu_register()
205 if (!dev->fwnode) in rimt_iommu_register()
206 dev->fwnode = rimt_fwnode; in rimt_iommu_register()
210 rimt_set_fwnode(node, dev->fwnode); in rimt_iommu_register()
219 * rimt_get_fwnode() - Retrieve fwnode associated with an RIMT node
221 * @node: RIMT table node to be looked-up
232 if (curr->rimt_node == node) { in rimt_get_fwnode()
233 fwnode = curr->fwnode; in rimt_get_fwnode()
246 pci_rc = (struct acpi_rimt_pcie_rc *)node->node_data; in rimt_pcie_rc_supports_ats()
247 return pci_rc->flags & ACPI_RIMT_PCIE_ATS_SUPPORTED; in rimt_pcie_rc_supports_ats()
255 return -ENODEV; in rimt_iommu_xlate()
260 * The IOMMU drivers may not be probed yet. in rimt_iommu_xlate()
261 * Defer the IOMMU configuration in rimt_iommu_xlate()
264 return -EPROBE_DEFER; in rimt_iommu_xlate()
277 if (rid_in < map->source_id_base || in rimt_id_map()
278 (rid_in > map->source_id_base + map->num_ids)) in rimt_id_map()
279 return -ENXIO; in rimt_id_map()
281 *rid_out = map->dest_id_base + (rid_in - map->source_id_base); in rimt_id_map()
292 struct acpi_rimt_node *parent; in rimt_node_get_id() local
294 if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { in rimt_node_get_id()
295 pci_node = (struct acpi_rimt_pcie_rc *)&node->node_data; in rimt_node_get_id()
296 id_mapping_offset = pci_node->id_mapping_offset; in rimt_node_get_id()
297 num_id_mapping = pci_node->num_id_mappings; in rimt_node_get_id()
298 } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { in rimt_node_get_id()
299 plat_node = (struct acpi_rimt_platform_device *)&node->node_data; in rimt_node_get_id()
300 id_mapping_offset = plat_node->id_mapping_offset; in rimt_node_get_id()
301 num_id_mapping = plat_node->num_id_mappings; in rimt_node_get_id()
313 if (!map->dest_offset) { in rimt_node_get_id()
314 pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", in rimt_node_get_id()
315 node, node->type); in rimt_node_get_id()
319 parent = ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, map->dest_offset); in rimt_node_get_id()
321 if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE || in rimt_node_get_id()
322 node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { in rimt_node_get_id()
323 *id_out = map->dest_id_base; in rimt_node_get_id()
324 return parent; in rimt_node_get_id()
345 if (RIMT_TYPE_MASK(node->type) & type_mask) { in rimt_node_map_id()
351 if (node->type == ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { in rimt_node_map_id()
352 pci_node = (struct acpi_rimt_pcie_rc *)&node->node_data; in rimt_node_map_id()
353 id_mapping_offset = pci_node->id_mapping_offset; in rimt_node_map_id()
354 num_id_mapping = pci_node->num_id_mappings; in rimt_node_map_id()
355 } else if (node->type == ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { in rimt_node_map_id()
356 plat_node = (struct acpi_rimt_platform_device *)&node->node_data; in rimt_node_map_id()
357 id_mapping_offset = plat_node->id_mapping_offset; in rimt_node_map_id()
358 num_id_mapping = plat_node->num_id_mappings; in rimt_node_map_id()
370 if (!map->dest_offset) { in rimt_node_map_id()
371 pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", in rimt_node_map_id()
372 node, node->type); in rimt_node_map_id()
378 rc = rimt_id_map(map, node->type, map_id, &id); in rimt_node_map_id()
387 rc ? 0 : map->dest_offset); in rimt_node_map_id()
401 struct acpi_rimt_node *parent; in rimt_node_map_platform_id() local
404 parent = rimt_node_get_id(node, &id, index); in rimt_node_map_platform_id()
405 if (!parent) in rimt_node_map_platform_id()
408 if (!(RIMT_TYPE_MASK(parent->type) & type_mask)) in rimt_node_map_platform_id()
409 parent = rimt_node_map_id(parent, id, id_out, type_mask); in rimt_node_map_platform_id()
414 return parent; in rimt_node_map_platform_id()
420 struct acpi_rimt_node *parent; in rimt_pci_iommu_init() local
423 parent = rimt_node_map_id(info->node, alias, &deviceid, RIMT_IOMMU_TYPE); in rimt_pci_iommu_init()
424 return rimt_iommu_xlate(info->dev, parent, deviceid); in rimt_pci_iommu_init()
429 struct acpi_rimt_node *parent; in rimt_plat_iommu_map() local
430 int err = -ENODEV, i = 0; in rimt_plat_iommu_map()
434 parent = rimt_node_map_platform_id(node, &deviceid, in rimt_plat_iommu_map()
438 if (parent) in rimt_plat_iommu_map()
439 err = rimt_iommu_xlate(dev, parent, deviceid); in rimt_plat_iommu_map()
440 } while (parent && !err); in rimt_plat_iommu_map()
449 struct acpi_rimt_node *parent; in rimt_plat_iommu_map_id() local
452 parent = rimt_node_map_id(node, *in_id, &deviceid, RIMT_IOMMU_TYPE); in rimt_plat_iommu_map_id()
453 if (parent) in rimt_plat_iommu_map_id()
454 return rimt_iommu_xlate(dev, parent, deviceid); in rimt_plat_iommu_map_id()
456 return -ENODEV; in rimt_plat_iommu_map_id()
460 * rimt_iommu_configure_id - Set-up IOMMU configuration for a device.
470 int err = -ENODEV; in rimt_iommu_configure_id()
474 struct pci_bus *bus = to_pci_dev(dev)->bus; in rimt_iommu_configure_id()
477 node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX, &bus->dev); in rimt_iommu_configure_id()
479 return -ENODEV; in rimt_iommu_configure_id()
487 fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS; in rimt_iommu_configure_id()
491 return -ENODEV; in rimt_iommu_configure_id()