genirq/msi: Allow creation of a tree-based irqdomain for platform-msi
platform_msi_create_device_domain() always creates a revmap-based irqdomain, which has the drawback of requiring the number of MSIs that can be allocated ahead of time. This is not always possible, and we sometimes need to use a tree-based irqdomain instead. Add a new platform_msi_create_device_tree_domain() helper to that effect. Reported-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
parent
0c4cb97d4e
commit
1f83515beb
|
@ -321,11 +321,12 @@ void *platform_msi_get_host_data(struct irq_domain *domain)
|
||||||
* Returns an irqdomain for @nvec interrupts
|
* Returns an irqdomain for @nvec interrupts
|
||||||
*/
|
*/
|
||||||
struct irq_domain *
|
struct irq_domain *
|
||||||
platform_msi_create_device_domain(struct device *dev,
|
__platform_msi_create_device_domain(struct device *dev,
|
||||||
unsigned int nvec,
|
unsigned int nvec,
|
||||||
irq_write_msi_msg_t write_msi_msg,
|
bool is_tree,
|
||||||
const struct irq_domain_ops *ops,
|
irq_write_msi_msg_t write_msi_msg,
|
||||||
void *host_data)
|
const struct irq_domain_ops *ops,
|
||||||
|
void *host_data)
|
||||||
{
|
{
|
||||||
struct platform_msi_priv_data *data;
|
struct platform_msi_priv_data *data;
|
||||||
struct irq_domain *domain;
|
struct irq_domain *domain;
|
||||||
|
@ -336,7 +337,8 @@ platform_msi_create_device_domain(struct device *dev,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
data->host_data = host_data;
|
data->host_data = host_data;
|
||||||
domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
|
domain = irq_domain_create_hierarchy(dev->msi_domain, 0,
|
||||||
|
is_tree ? 0 : nvec,
|
||||||
dev->fwnode, ops, data);
|
dev->fwnode, ops, data);
|
||||||
if (!domain)
|
if (!domain)
|
||||||
goto free_priv;
|
goto free_priv;
|
||||||
|
|
|
@ -317,11 +317,18 @@ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
|
||||||
int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
|
int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
|
||||||
int virq, int nvec, msi_alloc_info_t *args);
|
int virq, int nvec, msi_alloc_info_t *args);
|
||||||
struct irq_domain *
|
struct irq_domain *
|
||||||
platform_msi_create_device_domain(struct device *dev,
|
__platform_msi_create_device_domain(struct device *dev,
|
||||||
unsigned int nvec,
|
unsigned int nvec,
|
||||||
irq_write_msi_msg_t write_msi_msg,
|
bool is_tree,
|
||||||
const struct irq_domain_ops *ops,
|
irq_write_msi_msg_t write_msi_msg,
|
||||||
void *host_data);
|
const struct irq_domain_ops *ops,
|
||||||
|
void *host_data);
|
||||||
|
|
||||||
|
#define platform_msi_create_device_domain(dev, nvec, write, ops, data) \
|
||||||
|
__platform_msi_create_device_domain(dev, nvec, false, write, ops, data)
|
||||||
|
#define platform_msi_create_device_tree_domain(dev, nvec, write, ops, data) \
|
||||||
|
__platform_msi_create_device_domain(dev, nvec, true, write, ops, data)
|
||||||
|
|
||||||
int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||||
unsigned int nr_irqs);
|
unsigned int nr_irqs);
|
||||||
void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
|
void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
|
||||||
|
|
Loading…
Reference in New Issue