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 "irq-msi-lib.h"
40 guard(mutex)(&data->msi_map_lock); in sg2042_msi_allocate_hwirq()
41 first = bitmap_find_free_region(data->msi_map, data->num_irqs, in sg2042_msi_allocate_hwirq()
43 return first >= 0 ? first : -ENOSPC; in sg2042_msi_allocate_hwirq()
48 guard(mutex)(&data->msi_map_lock); in sg2042_msi_free_hwirq()
49 bitmap_release_region(data->msi_map, hwirq, get_count_order(num_req)); in sg2042_msi_free_hwirq()
55 int bit_off = d->hwirq; in sg2042_msi_irq_ack()
57 writel(1 << bit_off, data->reg_clr); in sg2042_msi_irq_ack()
66 msg->address_hi = upper_32_bits(data->doorbell_addr); in sg2042_msi_irq_compose_msi_msg()
67 msg->address_lo = lower_32_bits(data->doorbell_addr); in sg2042_msi_irq_compose_msi_msg()
68 msg->data = 1 << d->hwirq; in sg2042_msi_irq_compose_msi_msg()
72 .name = "SG2042 MSI",
84 struct sg2042_msi_chipdata *data = domain->host_data; in sg2042_msi_parent_domain_alloc()
89 fwspec.fwnode = domain->parent->fwnode; in sg2042_msi_parent_domain_alloc()
91 fwspec.param[0] = data->irq_first + hwirq; in sg2042_msi_parent_domain_alloc()
98 d = irq_domain_get_irq_data(domain->parent, virq); in sg2042_msi_parent_domain_alloc()
99 return d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING); in sg2042_msi_parent_domain_alloc()
105 struct sg2042_msi_chipdata *data = domain->host_data; in sg2042_msi_middle_domain_alloc()
137 sg2042_msi_free_hwirq(data, d->hwirq, nr_irqs); in sg2042_msi_middle_domain_free()
157 .prefix = "SG2042-",
167 middle_domain = irq_domain_create_hierarchy(plic_domain, 0, data->num_irqs, fwnode, in sg2042_msi_init_domains()
170 pr_err("Failed to create the MSI middle domain\n"); in sg2042_msi_init_domains()
171 return -ENOMEM; in sg2042_msi_init_domains()
176 middle_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; in sg2042_msi_init_domains()
177 middle_domain->msi_parent_ops = &sg2042_msi_parent_ops; in sg2042_msi_init_domains()
186 struct device *dev = &pdev->dev; in sg2042_msi_probe()
193 return -ENOMEM; in sg2042_msi_probe()
195 data->reg_clr = devm_platform_ioremap_resource_byname(pdev, "clr"); in sg2042_msi_probe()
196 if (IS_ERR(data->reg_clr)) { in sg2042_msi_probe()
198 return PTR_ERR(data->reg_clr); in sg2042_msi_probe()
204 return -EINVAL; in sg2042_msi_probe()
206 data->doorbell_addr = res->start; in sg2042_msi_probe()
208 ret = fwnode_property_get_reference_args(dev_fwnode(dev), "msi-ranges", in sg2042_msi_probe()
209 "#interrupt-cells", 0, 0, &args); in sg2042_msi_probe()
211 dev_err(dev, "Unable to parse MSI vec base\n"); in sg2042_msi_probe()
216 ret = fwnode_property_get_reference_args(dev_fwnode(dev), "msi-ranges", NULL, in sg2042_msi_probe()
219 dev_err(dev, "Unable to parse MSI vec number\n"); in sg2042_msi_probe()
227 return -ENXIO; in sg2042_msi_probe()
230 data->irq_first = (u32)args.args[0]; in sg2042_msi_probe()
231 data->num_irqs = (u32)args.args[args.nargs - 1]; in sg2042_msi_probe()
233 mutex_init(&data->msi_map_lock); in sg2042_msi_probe()
239 { .compatible = "sophgo,sg2042-msi" },
245 .name = "sg2042-msi",