Lines Matching +full:sg2042 +full:- +full:msi

1 // SPDX-License-Identifier: GPL-2.0
3 * SG2042 MSI Controller
15 #include <linux/msi.h>
20 #include <linux/irqchip/irq-msi-lib.h>
28 * struct sg204x_msi_chipdata - chip data for the SG204x MSI IRQ controller
34 * @msi_map: mapping for allocated MSI vectors.
57 guard(mutex)(&data->msi_map_lock); in sg204x_msi_allocate_hwirq()
58 first = bitmap_find_free_region(data->msi_map, data->num_irqs, in sg204x_msi_allocate_hwirq()
60 return first >= 0 ? first : -ENOSPC; in sg204x_msi_allocate_hwirq()
65 guard(mutex)(&data->msi_map_lock); in sg204x_msi_free_hwirq()
66 bitmap_release_region(data->msi_map, hwirq, get_count_order(num_req)); in sg204x_msi_free_hwirq()
72 int bit_off = d->hwirq; in sg2042_msi_irq_ack()
74 writel(1 << bit_off, data->reg_clr); in sg2042_msi_irq_ack()
83 msg->address_hi = upper_32_bits(data->doorbell_addr); in sg2042_msi_irq_compose_msi_msg()
84 msg->address_lo = lower_32_bits(data->doorbell_addr); in sg2042_msi_irq_compose_msi_msg()
85 msg->data = 1 << d->hwirq; in sg2042_msi_irq_compose_msi_msg()
89 .name = "SG2042 MSI",
105 writel(0, (u32 __iomem *)data->reg_clr + d->hwirq); in sg2044_msi_irq_ack()
112 phys_addr_t doorbell = data->doorbell_addr + 4 * (d->hwirq / 32); in sg2044_msi_irq_compose_msi_msg()
114 msg->address_lo = lower_32_bits(doorbell); in sg2044_msi_irq_compose_msi_msg()
115 msg->address_hi = upper_32_bits(doorbell); in sg2044_msi_irq_compose_msi_msg()
116 msg->data = d->hwirq % 32; in sg2044_msi_irq_compose_msi_msg()
120 .name = "SG2044 MSI",
134 struct sg204x_msi_chipdata *data = domain->host_data; in sg204x_msi_parent_domain_alloc()
139 fwspec.fwnode = domain->parent->fwnode; in sg204x_msi_parent_domain_alloc()
141 fwspec.param[0] = data->irq_first + hwirq; in sg204x_msi_parent_domain_alloc()
142 fwspec.param[1] = data->irq_type; in sg204x_msi_parent_domain_alloc()
148 d = irq_domain_get_irq_data(domain->parent, virq); in sg204x_msi_parent_domain_alloc()
149 return d->chip->irq_set_type(d, data->irq_type); in sg204x_msi_parent_domain_alloc()
155 struct sg204x_msi_chipdata *data = domain->host_data; in sg204x_msi_middle_domain_alloc()
168 data->chip_info->irqchip, data); in sg204x_msi_middle_domain_alloc()
185 sg204x_msi_free_hwirq(data, d->hwirq, nr_irqs); in sg204x_msi_middle_domain_free()
207 .prefix = "SG2042-",
226 .prefix = "SG2044-",
236 .size = data->num_irqs, in sg204x_msi_init_domains()
241 if (!msi_create_parent_irq_domain(&info, data->chip_info->parent_ops)) { in sg204x_msi_init_domains()
242 pr_err("Failed to create the MSI middle domain\n"); in sg204x_msi_init_domains()
243 return -ENOMEM; in sg204x_msi_init_domains()
252 struct device *dev = &pdev->dev; in sg2042_msi_probe()
259 return -ENOMEM; in sg2042_msi_probe()
261 data->chip_info = device_get_match_data(&pdev->dev); in sg2042_msi_probe()
262 if (!data->chip_info) { in sg2042_msi_probe()
263 dev_err(&pdev->dev, "Failed to get irqchip\n"); in sg2042_msi_probe()
264 return -EINVAL; in sg2042_msi_probe()
267 data->reg_clr = devm_platform_ioremap_resource_byname(pdev, "clr"); in sg2042_msi_probe()
268 if (IS_ERR(data->reg_clr)) { in sg2042_msi_probe()
270 return PTR_ERR(data->reg_clr); in sg2042_msi_probe()
276 return -EINVAL; in sg2042_msi_probe()
278 data->doorbell_addr = res->start; in sg2042_msi_probe()
280 ret = fwnode_property_get_reference_args(dev_fwnode(dev), "msi-ranges", in sg2042_msi_probe()
281 "#interrupt-cells", 0, 0, &args); in sg2042_msi_probe()
283 dev_err(dev, "Unable to parse MSI vec base\n"); in sg2042_msi_probe()
288 ret = fwnode_property_get_reference_args(dev_fwnode(dev), "msi-ranges", NULL, in sg2042_msi_probe()
291 dev_err(dev, "Unable to parse MSI vec number\n"); in sg2042_msi_probe()
299 return -ENXIO; in sg2042_msi_probe()
302 data->irq_first = (u32)args.args[0]; in sg2042_msi_probe()
303 data->irq_type = (unsigned int)args.args[1]; in sg2042_msi_probe()
304 data->num_irqs = (u32)args.args[args.nargs - 1]; in sg2042_msi_probe()
306 mutex_init(&data->msi_map_lock); in sg2042_msi_probe()
308 data->msi_map = devm_bitmap_zalloc(&pdev->dev, data->num_irqs, GFP_KERNEL); in sg2042_msi_probe()
309 if (!data->msi_map) { in sg2042_msi_probe()
310 dev_err(&pdev->dev, "Unable to allocate msi mapping\n"); in sg2042_msi_probe()
311 return -ENOMEM; in sg2042_msi_probe()
328 { .compatible = "sophgo,sg2042-msi", .data = &sg2042_chip_info },
329 { .compatible = "sophgo,sg2044-msi", .data = &sg2044_chip_info },
335 .name = "sg2042-msi",