Lines Matching +full:parent +full:- +full:interrupt +full:- +full:base
1 // SPDX-License-Identifier: GPL-2.0-only
14 #include <linux/irqchip/irq-msi-lib.h>
30 * struct mip_priv - MSI-X interrupt controller data
32 * @base: Base address of MMIO area
33 * @msg_addr: PCIe MSI-X address
34 * @msi_base: MSI base
38 * @parent: Parent domain (GIC)
43 void __iomem *base; member
49 struct irq_domain *parent; member
57 msg->address_hi = upper_32_bits(mip->msg_addr); in mip_compose_msi_msg()
58 msg->address_lo = lower_32_bits(mip->msg_addr); in mip_compose_msi_msg()
59 msg->data = d->hwirq; in mip_compose_msi_msg()
74 guard(spinlock)(&mip->lock); in mip_alloc_hwirq()
75 return bitmap_find_free_region(mip->bitmap, mip->num_msis, ilog2(nr_irqs)); in mip_alloc_hwirq()
81 guard(spinlock)(&mip->lock); in mip_free_hwirq()
82 bitmap_release_region(mip->bitmap, hwirq, ilog2(nr_irqs)); in mip_free_hwirq()
88 struct mip_priv *mip = domain->host_data; in mip_middle_domain_alloc()
98 hwirq = irq + mip->msi_offset; in mip_middle_domain_alloc()
100 fwspec.fwnode = domain->parent->fwnode; in mip_middle_domain_alloc()
103 fwspec.param[1] = hwirq + mip->msi_base; in mip_middle_domain_alloc()
111 irqd = irq_domain_get_irq_data(domain->parent, virq + i); in mip_middle_domain_alloc()
112 irqd->chip->irq_set_type(irqd, IRQ_TYPE_EDGE_RISING); in mip_middle_domain_alloc()
146 mip_free_hwirq(mip, hwirq - mip->msi_offset, nr_irqs); in mip_middle_domain_free()
169 .prefix = "MIP-MSI-",
177 middle = irq_domain_create_hierarchy(mip->parent, 0, mip->num_msis, of_fwnode_handle(np), in mip_init_domains()
180 return -ENOMEM; in mip_init_domains()
183 middle->dev = mip->dev; in mip_init_domains()
184 middle->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; in mip_init_domains()
185 middle->msi_parent_ops = &mip_msi_parent_ops; in mip_init_domains()
188 * All MSI-X unmasked for the host, masked for the VPU, and edge-triggered. in mip_init_domains()
190 writel(0, mip->base + MIP_INT_MASKL_HOST); in mip_init_domains()
191 writel(0, mip->base + MIP_INT_MASKH_HOST); in mip_init_domains()
192 writel(~0, mip->base + MIP_INT_MASKL_VPU); in mip_init_domains()
193 writel(~0, mip->base + MIP_INT_MASKH_VPU); in mip_init_domains()
194 writel(~0, mip->base + MIP_INT_CFGL_HOST); in mip_init_domains()
195 writel(~0, mip->base + MIP_INT_CFGH_HOST); in mip_init_domains()
206 ret = of_property_read_u32(np, "brcm,msi-offset", &mip->msi_offset); in mip_parse_dt()
208 mip->msi_offset = 0; in mip_parse_dt()
210 ret = of_parse_phandle_with_args(np, "msi-ranges", "#interrupt-cells", in mip_parse_dt()
215 ret = of_property_read_u32_index(np, "msi-ranges", args.args_count + 1, in mip_parse_dt()
216 &mip->num_msis); in mip_parse_dt()
220 ret = of_property_read_reg(np, 1, &mip->msg_addr, &size); in mip_parse_dt()
224 mip->msi_base = args.args[1]; in mip_parse_dt()
226 mip->parent = irq_find_host(args.np); in mip_parse_dt()
227 if (!mip->parent) in mip_parse_dt()
228 ret = -EINVAL; in mip_parse_dt()
235 static int __init mip_of_msi_init(struct device_node *node, struct device_node *parent) in mip_of_msi_init() argument
244 return -EPROBE_DEFER; in mip_of_msi_init()
248 return -ENOMEM; in mip_of_msi_init()
250 spin_lock_init(&mip->lock); in mip_of_msi_init()
251 mip->dev = &pdev->dev; in mip_of_msi_init()
257 mip->base = of_iomap(node, 0); in mip_of_msi_init()
258 if (!mip->base) { in mip_of_msi_init()
259 ret = -ENXIO; in mip_of_msi_init()
263 mip->bitmap = bitmap_zalloc(mip->num_msis, GFP_KERNEL); in mip_of_msi_init()
264 if (!mip->bitmap) { in mip_of_msi_init()
265 ret = -ENOMEM; in mip_of_msi_init()
273 dev_dbg(&pdev->dev, "MIP: MSI-X count: %u, base: %u, offset: %u, msg_addr: %llx\n", in mip_of_msi_init()
274 mip->num_msis, mip->msi_base, mip->msi_offset, mip->msg_addr); in mip_of_msi_init()
279 bitmap_free(mip->bitmap); in mip_of_msi_init()
281 iounmap(mip->base); in mip_of_msi_init()
288 IRQCHIP_MATCH("brcm,bcm2712-mip", mip_of_msi_init)
290 MODULE_DESCRIPTION("Broadcom BCM2712 MSI-X interrupt controller");