Lines Matching +full:msi +full:- +full:parent

1 // SPDX-License-Identifier: GPL-2.0
4 * Loongson PCH MSI support
7 #define pr_fmt(fmt) "pch-msi: " fmt
10 #include <linux/msi.h>
43 .name = "PCH PCI MSI",
54 mutex_lock(&priv->msi_map_lock); in pch_msi_allocate_hwirq()
56 first = bitmap_find_free_region(priv->msi_map, priv->num_irqs, in pch_msi_allocate_hwirq()
59 mutex_unlock(&priv->msi_map_lock); in pch_msi_allocate_hwirq()
60 return -ENOSPC; in pch_msi_allocate_hwirq()
63 mutex_unlock(&priv->msi_map_lock); in pch_msi_allocate_hwirq()
65 return priv->irq_first + first; in pch_msi_allocate_hwirq()
71 int first = hwirq - priv->irq_first; in pch_msi_free_hwirq()
73 mutex_lock(&priv->msi_map_lock); in pch_msi_free_hwirq()
74 bitmap_release_region(priv->msi_map, first, get_count_order(num_req)); in pch_msi_free_hwirq()
75 mutex_unlock(&priv->msi_map_lock); in pch_msi_free_hwirq()
83 msg->address_hi = upper_32_bits(priv->doorbell); in pch_msi_compose_msi_msg()
84 msg->address_lo = lower_32_bits(priv->doorbell); in pch_msi_compose_msi_msg()
85 msg->data = data->hwirq; in pch_msi_compose_msi_msg()
95 .name = "PCH MSI",
108 fwspec.fwnode = domain->parent->fwnode; in pch_msi_parent_domain_alloc()
119 struct pch_msi_data *priv = domain->host_data; in pch_msi_middle_domain_alloc()
152 pch_msi_free_hwirq(priv, d->hwirq, nr_irqs); in pch_msi_middle_domain_free()
161 struct irq_domain *parent, in pch_msi_init_domains() argument
166 middle_domain = irq_domain_create_hierarchy(parent, 0, priv->num_irqs, in pch_msi_init_domains()
171 pr_err("Failed to create the MSI middle domain\n"); in pch_msi_init_domains()
172 return -ENOMEM; in pch_msi_init_domains()
181 pr_err("Failed to create PCI MSI domain\n"); in pch_msi_init_domains()
183 return -ENOMEM; in pch_msi_init_domains()
197 return -ENOMEM; in pch_msi_init()
199 mutex_init(&priv->msi_map_lock); in pch_msi_init()
201 priv->doorbell = msg_address; in pch_msi_init()
202 priv->irq_first = irq_base; in pch_msi_init()
203 priv->num_irqs = irq_count; in pch_msi_init()
205 priv->msi_map = bitmap_zalloc(priv->num_irqs, GFP_KERNEL); in pch_msi_init()
206 if (!priv->msi_map) in pch_msi_init()
210 priv->num_irqs, priv->irq_first); in pch_msi_init()
220 bitmap_free(priv->msi_map); in pch_msi_init()
224 return -EINVAL; in pch_msi_init()
228 static int pch_msi_of_init(struct device_node *node, struct device_node *parent) in pch_msi_of_init() argument
235 parent_domain = irq_find_host(parent); in pch_msi_of_init()
237 pr_err("Failed to find the parent domain\n"); in pch_msi_of_init()
238 return -ENXIO; in pch_msi_of_init()
243 return -EINVAL; in pch_msi_of_init()
246 if (of_property_read_u32(node, "loongson,msi-base-vec", &irq_base)) { in pch_msi_of_init()
247 pr_err("Unable to parse MSI vec base\n"); in pch_msi_of_init()
248 return -EINVAL; in pch_msi_of_init()
251 if (of_property_read_u32(node, "loongson,msi-num-vecs", &irq_count)) { in pch_msi_of_init()
252 pr_err("Unable to parse MSI vec number\n"); in pch_msi_of_init()
253 return -EINVAL; in pch_msi_of_init()
263 IRQCHIP_DECLARE(pch_msi, "loongson,pch-msi-1.0", pch_msi_of_init);
278 int __init pch_msi_acpi_init(struct irq_domain *parent, in pch_msi_acpi_init() argument
284 domain_handle = irq_domain_alloc_fwnode(&acpi_pchmsi->msg_address); in pch_msi_acpi_init()
285 ret = pch_msi_init(acpi_pchmsi->msg_address, acpi_pchmsi->start, in pch_msi_acpi_init()
286 acpi_pchmsi->count, parent, domain_handle); in pch_msi_acpi_init()