Lines Matching +full:msi +full:- +full:base +full:- +full:vec
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>
18 #include <linux/irqchip/irq-msi-lib.h>
19 #include "irq-loongson.h"
37 mutex_lock(&priv->msi_map_lock); in pch_msi_allocate_hwirq()
39 first = bitmap_find_free_region(priv->msi_map, priv->num_irqs, in pch_msi_allocate_hwirq()
42 mutex_unlock(&priv->msi_map_lock); in pch_msi_allocate_hwirq()
43 return -ENOSPC; in pch_msi_allocate_hwirq()
46 mutex_unlock(&priv->msi_map_lock); in pch_msi_allocate_hwirq()
48 return priv->irq_first + first; in pch_msi_allocate_hwirq()
54 int first = hwirq - priv->irq_first; in pch_msi_free_hwirq()
56 mutex_lock(&priv->msi_map_lock); in pch_msi_free_hwirq()
57 bitmap_release_region(priv->msi_map, first, get_count_order(num_req)); in pch_msi_free_hwirq()
58 mutex_unlock(&priv->msi_map_lock); in pch_msi_free_hwirq()
66 msg->address_hi = upper_32_bits(priv->doorbell); in pch_msi_compose_msi_msg()
67 msg->address_lo = lower_32_bits(priv->doorbell); in pch_msi_compose_msi_msg()
68 msg->data = data->hwirq; in pch_msi_compose_msi_msg()
72 .name = "PCH MSI",
85 fwspec.fwnode = domain->parent->fwnode; in pch_msi_parent_domain_alloc()
96 struct pch_msi_data *priv = domain->host_data; in pch_msi_middle_domain_alloc()
129 pch_msi_free_hwirq(priv, d->hwirq, nr_irqs); in pch_msi_middle_domain_free()
152 .prefix = "PCH-",
161 .size = priv->num_irqs, in pch_msi_init_domains()
168 pr_err("Failed to create the MSI middle domain\n"); in pch_msi_init_domains()
169 return -ENOMEM; in pch_msi_init_domains()
182 return -ENOMEM; in pch_msi_init()
184 mutex_init(&priv->msi_map_lock); in pch_msi_init()
186 priv->doorbell = msg_address; in pch_msi_init()
187 priv->irq_first = irq_base; in pch_msi_init()
188 priv->num_irqs = irq_count; in pch_msi_init()
190 priv->msi_map = bitmap_zalloc(priv->num_irqs, GFP_KERNEL); in pch_msi_init()
191 if (!priv->msi_map) in pch_msi_init()
195 priv->num_irqs, priv->irq_first); in pch_msi_init()
205 bitmap_free(priv->msi_map); in pch_msi_init()
209 return -EINVAL; in pch_msi_init()
223 return -ENXIO; in pch_msi_of_init()
228 return -EINVAL; in pch_msi_of_init()
231 if (of_property_read_u32(node, "loongson,msi-base-vec", &irq_base)) { in pch_msi_of_init()
232 pr_err("Unable to parse MSI vec base\n"); in pch_msi_of_init()
233 return -EINVAL; in pch_msi_of_init()
236 if (of_property_read_u32(node, "loongson,msi-num-vecs", &irq_count)) { in pch_msi_of_init()
237 pr_err("Unable to parse MSI vec number\n"); in pch_msi_of_init()
238 return -EINVAL; in pch_msi_of_init()
248 IRQCHIP_DECLARE(pch_msi, "loongson,pch-msi-1.0", pch_msi_of_init);
269 domain_handle = irq_domain_alloc_fwnode(&acpi_pchmsi->msg_address); in pch_msi_acpi_init()
270 ret = pch_msi_init(acpi_pchmsi->msg_address, acpi_pchmsi->start, in pch_msi_acpi_init()
271 acpi_pchmsi->count, parent, domain_handle); in pch_msi_acpi_init()
283 pch_msi_handle[0] = parent->fwnode; in pch_msi_acpi_init_avec()
286 parent->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; in pch_msi_acpi_init_avec()
287 parent->msi_parent_ops = &pch_msi_parent_ops; in pch_msi_acpi_init_avec()