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

1 // SPDX-License-Identifier: GPL-2.0
3 * MSI framework for platform devices
13 #include <linux/msi.h>
17 #define MAX_DEV_MSIS (1 << (32 - DEV_ID_SHIFT))
21 * and the callback to write the MSI message.
36 * Convert an msi_desc to a globaly unique identifier (per-device
41 u32 devid = desc->dev->msi.data->platform_data->devid; in platform_msi_calc_hwirq()
43 return (devid << (32 - DEV_ID_SHIFT)) | desc->msi_index; in platform_msi_calc_hwirq()
48 arg->desc = desc; in platform_msi_set_desc()
49 arg->hwirq = platform_msi_calc_hwirq(desc); in platform_msi_set_desc()
58 info->chip, info->chip_data); in platform_msi_init()
63 arg->flags |= MSI_ALLOC_FLAGS_PROXY_DEVICE; in platform_msi_set_proxy_dev()
73 struct msi_domain_ops *ops = info->ops; in platform_msi_update_dom_ops()
77 if (ops->msi_init == NULL) in platform_msi_update_dom_ops()
78 ops->msi_init = platform_msi_init; in platform_msi_update_dom_ops()
79 if (ops->set_desc == NULL) in platform_msi_update_dom_ops()
80 ops->set_desc = platform_msi_set_desc; in platform_msi_update_dom_ops()
87 desc->dev->msi.data->platform_data->write_msg(desc, msg); in platform_msi_write_msg()
92 struct irq_chip *chip = info->chip; in platform_msi_update_chip_ops()
95 if (!chip->irq_mask) in platform_msi_update_chip_ops()
96 chip->irq_mask = irq_chip_mask_parent; in platform_msi_update_chip_ops()
97 if (!chip->irq_unmask) in platform_msi_update_chip_ops()
98 chip->irq_unmask = irq_chip_unmask_parent; in platform_msi_update_chip_ops()
99 if (!chip->irq_eoi) in platform_msi_update_chip_ops()
100 chip->irq_eoi = irq_chip_eoi_parent; in platform_msi_update_chip_ops()
101 if (!chip->irq_set_affinity) in platform_msi_update_chip_ops()
102 chip->irq_set_affinity = msi_domain_set_affinity; in platform_msi_update_chip_ops()
103 if (!chip->irq_write_msi_msg) in platform_msi_update_chip_ops()
104 chip->irq_write_msi_msg = platform_msi_write_msg; in platform_msi_update_chip_ops()
105 if (WARN_ON((info->flags & MSI_FLAG_LEVEL_CAPABLE) && in platform_msi_update_chip_ops()
106 !(chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI))) in platform_msi_update_chip_ops()
107 info->flags &= ~MSI_FLAG_LEVEL_CAPABLE; in platform_msi_update_chip_ops()
111 * platform_msi_create_irq_domain - Create a platform MSI interrupt domain
113 * @info: MSI domain info
114 * @parent: Parent irq domain
116 * Updates the domain and chip ops and creates a platform MSI
124 struct irq_domain *parent) in platform_msi_create_irq_domain() argument
128 if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) in platform_msi_create_irq_domain()
130 if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) in platform_msi_create_irq_domain()
132 info->flags |= MSI_FLAG_DEV_SYSFS | MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | in platform_msi_create_irq_domain()
135 domain = msi_create_irq_domain(fwnode, info, parent); in platform_msi_create_irq_domain()
152 * accordingly (which would impact the max number of MSI in platform_msi_alloc_priv_data()
155 if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS) in platform_msi_alloc_priv_data()
156 return -EINVAL; in platform_msi_alloc_priv_data()
158 if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) { in platform_msi_alloc_priv_data()
160 return -EINVAL; in platform_msi_alloc_priv_data()
168 if (dev->msi.data->platform_data) in platform_msi_alloc_priv_data()
169 return -EBUSY; in platform_msi_alloc_priv_data()
173 return -ENOMEM; in platform_msi_alloc_priv_data()
175 datap->devid = ida_simple_get(&platform_msi_devid_ida, in platform_msi_alloc_priv_data()
177 if (datap->devid < 0) { in platform_msi_alloc_priv_data()
178 err = datap->devid; in platform_msi_alloc_priv_data()
183 datap->write_msg = write_msi_msg; in platform_msi_alloc_priv_data()
184 datap->dev = dev; in platform_msi_alloc_priv_data()
185 dev->msi.data->platform_data = datap; in platform_msi_alloc_priv_data()
191 struct platform_msi_priv_data *data = dev->msi.data->platform_data; in platform_msi_free_priv_data()
193 dev->msi.data->platform_data = NULL; in platform_msi_free_priv_data()
194 ida_simple_remove(&platform_msi_devid_ida, data->devid); in platform_msi_free_priv_data()
199 * platform_msi_domain_alloc_irqs - Allocate MSI interrupts for @dev
216 err = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1); in platform_msi_domain_alloc_irqs()
225 * platform_msi_domain_free_irqs - Free MSI interrupts for @dev
236 * platform_msi_get_host_data - Query the private data associated with
237 * a platform-msi domain
238 * @domain: The platform-msi domain
245 struct platform_msi_priv_data *data = domain->host_data; in platform_msi_get_host_data()
247 return data->host_data; in platform_msi_get_host_data()
253 * __platform_msi_create_device_domain - Create a platform-msi device domain
264 * This is for interrupt domains which stack on a platform-msi domain
265 * created by platform_msi_create_irq_domain(). @dev->msi.domain points to
266 * that platform-msi domain which is the parent for the new domain.
285 * Use a separate lock class for the MSI descriptor mutex on in __platform_msi_create_device_domain()
286 * platform MSI device domains because the descriptor mutex nests in __platform_msi_create_device_domain()
289 lockdep_set_class(&dev->msi.data->mutex, &platform_device_msi_lock_class); in __platform_msi_create_device_domain()
291 data = dev->msi.data->platform_data; in __platform_msi_create_device_domain()
292 data->host_data = host_data; in __platform_msi_create_device_domain()
293 domain = irq_domain_create_hierarchy(dev->msi.domain, 0, in __platform_msi_create_device_domain()
295 dev->fwnode, ops, data); in __platform_msi_create_device_domain()
299 platform_msi_set_proxy_dev(&data->arg); in __platform_msi_create_device_domain()
300 err = msi_domain_prepare_irqs(domain->parent, dev, nvec, &data->arg); in __platform_msi_create_device_domain()
314 * platform_msi_device_domain_free - Free interrupts associated with a platform-msi
317 * @domain: The platform-msi device domain
324 struct platform_msi_priv_data *data = domain->host_data; in platform_msi_device_domain_free()
326 msi_lock_descs(data->dev); in platform_msi_device_domain_free()
327 msi_domain_depopulate_descs(data->dev, virq, nr_irqs); in platform_msi_device_domain_free()
329 msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1); in platform_msi_device_domain_free()
330 msi_unlock_descs(data->dev); in platform_msi_device_domain_free()
334 * platform_msi_device_domain_alloc - Allocate interrupts associated with
335 * a platform-msi device domain
337 * @domain: The platform-msi device domain
343 * top-level interrupt allocation).
348 struct platform_msi_priv_data *data = domain->host_data; in platform_msi_device_domain_alloc()
349 struct device *dev = data->dev; in platform_msi_device_domain_alloc()
351 return msi_domain_populate_irqs(domain->parent, dev, virq, nr_irqs, &data->arg); in platform_msi_device_domain_alloc()