Skip to content

Commit

Permalink
platform-msi: Let core code handle MSI descriptors
Browse files Browse the repository at this point in the history
Use the core functionality for platform MSI interrupt domains. The platform
device MSI interrupt domains will be converted in a later step.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Nishanth Menon <nm@ti.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20211206210748.903173257@linutronix.de
  • Loading branch information
Thomas Gleixner committed Dec 16, 2021
1 parent e8604b1 commit 653b50c
Showing 1 changed file with 48 additions and 64 deletions.
112 changes: 48 additions & 64 deletions drivers/base/platform-msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,57 +107,6 @@ static void platform_msi_update_chip_ops(struct msi_domain_info *info)
info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
}

static void platform_msi_free_descs(struct device *dev, int base, int nvec)
{
struct msi_desc *desc, *tmp;

list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
if (desc->msi_index >= base &&
desc->msi_index < (base + nvec)) {
list_del(&desc->list);
free_msi_entry(desc);
}
}
}

static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
int nvec)
{
struct msi_desc *desc;
int i, base = 0;

if (!list_empty(dev_to_msi_list(dev))) {
desc = list_last_entry(dev_to_msi_list(dev),
struct msi_desc, list);
base = desc->msi_index + 1;
}

for (i = 0; i < nvec; i++) {
desc = alloc_msi_entry(dev, 1, NULL);
if (!desc)
break;

desc->msi_index = base + i;
desc->irq = virq ? virq + i : 0;

list_add_tail(&desc->list, dev_to_msi_list(dev));
}

if (i != nvec) {
/* Clean up the mess */
platform_msi_free_descs(dev, base, nvec);

return -ENOMEM;
}

return 0;
}

static int platform_msi_alloc_descs(struct device *dev, int nvec)
{
return platform_msi_alloc_descs_with_irq(dev, 0, nvec);
}

/**
* platform_msi_create_irq_domain - Create a platform MSI interrupt domain
* @fwnode: Optional fwnode of the interrupt controller
Expand All @@ -180,7 +129,8 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
platform_msi_update_dom_ops(info);
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
platform_msi_update_chip_ops(info);
info->flags |= MSI_FLAG_DEV_SYSFS;
info->flags |= MSI_FLAG_DEV_SYSFS | MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
MSI_FLAG_FREE_MSI_DESCS;

domain = msi_create_irq_domain(fwnode, info, parent);
if (domain)
Expand Down Expand Up @@ -262,20 +212,10 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
if (err)
return err;

err = platform_msi_alloc_descs(dev, nvec);
if (err)
goto out_free_priv_data;

err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec);
if (err)
goto out_free_desc;

return 0;
platform_msi_free_priv_data(dev);

out_free_desc:
platform_msi_free_descs(dev, 0, nvec);
out_free_priv_data:
platform_msi_free_priv_data(dev);
return err;
}
EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
Expand All @@ -287,7 +227,6 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
void platform_msi_domain_free_irqs(struct device *dev)
{
msi_domain_free_irqs(dev->msi.domain, dev);
platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
platform_msi_free_priv_data(dev);
}
EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
Expand Down Expand Up @@ -361,6 +300,51 @@ __platform_msi_create_device_domain(struct device *dev,
return NULL;
}

static void platform_msi_free_descs(struct device *dev, int base, int nvec)
{
struct msi_desc *desc, *tmp;

list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
if (desc->msi_index >= base &&
desc->msi_index < (base + nvec)) {
list_del(&desc->list);
free_msi_entry(desc);
}
}
}

static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq,
int nvec)
{
struct msi_desc *desc;
int i, base = 0;

if (!list_empty(dev_to_msi_list(dev))) {
desc = list_last_entry(dev_to_msi_list(dev),
struct msi_desc, list);
base = desc->msi_index + 1;
}

for (i = 0; i < nvec; i++) {
desc = alloc_msi_entry(dev, 1, NULL);
if (!desc)
break;

desc->msi_index = base + i;
desc->irq = virq + i;

list_add_tail(&desc->list, dev_to_msi_list(dev));
}

if (i != nvec) {
/* Clean up the mess */
platform_msi_free_descs(dev, base, nvec);
return -ENOMEM;
}

return 0;
}

/**
* platform_msi_device_domain_free - Free interrupts associated with a platform-msi
* device domain
Expand Down

0 comments on commit 653b50c

Please sign in to comment.