@@ -317,6 +317,10 @@ struct msi_domain_info;
* function.
* @domain_free_irqs: Optional function to override the default free
* function.
+ * @msi_alloc_store: Optional callback to allocate storage in a device
+ * specific non-standard MSI store
+ * @msi_alloc_free: Optional callback to free storage in a device
+ * specific non-standard MSI store
*
* @get_hwirq, @msi_init and @msi_free are callbacks used by
* msi_create_irq_domain() and related interfaces
@@ -366,6 +370,10 @@ struct msi_domain_ops {
struct device *dev, int nvec);
void (*domain_free_irqs)(struct irq_domain *domain,
struct device *dev);
+ int (*msi_alloc_store)(struct irq_domain *domain,
+ struct device *dev, int nvec);
+ void (*msi_free_store)(struct irq_domain *domain,
+ struct device *dev);
};
/**
@@ -434,6 +434,12 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
if (ret)
return ret;
+ if (ops->msi_alloc_store) {
+ ret = ops->msi_alloc_store(domain, dev, nvec);
+ if (ret)
+ return ret;
+ }
+
for_each_msi_entry(desc, dev) {
ops->set_desc(&arg, desc);
@@ -533,6 +539,8 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
{
+ struct msi_domain_info *info = domain->host_data;
+ struct msi_domain_ops *ops = info->ops;
struct msi_desc *desc;
for_each_msi_entry(desc, dev) {
@@ -546,6 +554,9 @@ void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
desc->irq = 0;
}
}
+
+ if (ops->msi_free_store)
+ ops->msi_free_store(domain, dev);
}
/**