Commit 1f83515b authored by Marc Zyngier's avatar Marc Zyngier

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: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 0c4cb97d
...@@ -321,11 +321,12 @@ void *platform_msi_get_host_data(struct irq_domain *domain) ...@@ -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, ...@@ -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, ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment