forked from mirrors/linux
		
	PCI/MSI: Provide pci_ims_alloc/free_irq()
Single vector allocation which allocates the next free index in the IMS space. The free function releases. All allocated vectors are released also via pci_free_vectors() which is also releasing MSI/MSI-X vectors. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20221124232326.961711347@linutronix.de
This commit is contained in:
		
							parent
							
								
									0194425af0
								
							
						
					
					
						commit
						c9e5bea273
					
				
					 2 changed files with 53 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -365,6 +365,56 @@ const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr)
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(pci_irq_get_affinity);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pci_ims_alloc_irq - Allocate an interrupt on a PCI/IMS interrupt domain
 | 
			
		||||
 * @dev:	The PCI device to operate on
 | 
			
		||||
 * @icookie:	Pointer to an IMS implementation specific cookie for this
 | 
			
		||||
 *		IMS instance (PASID, queue ID, pointer...).
 | 
			
		||||
 *		The cookie content is copied into the MSI descriptor for the
 | 
			
		||||
 *		interrupt chip callbacks or domain specific setup functions.
 | 
			
		||||
 * @affdesc:	Optional pointer to an interrupt affinity descriptor
 | 
			
		||||
 *
 | 
			
		||||
 * There is no index for IMS allocations as IMS is an implementation
 | 
			
		||||
 * specific storage and does not have any direct associations between
 | 
			
		||||
 * index, which might be a pure software construct, and device
 | 
			
		||||
 * functionality. This association is established by the driver either via
 | 
			
		||||
 * the index - if there is a hardware table - or in case of purely software
 | 
			
		||||
 * managed IMS implementation the association happens via the
 | 
			
		||||
 * irq_write_msi_msg() callback of the implementation specific interrupt
 | 
			
		||||
 * chip, which utilizes the provided @icookie to store the MSI message in
 | 
			
		||||
 * the appropriate place.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: A struct msi_map
 | 
			
		||||
 *
 | 
			
		||||
 *	On success msi_map::index contains the allocated index (>= 0) and
 | 
			
		||||
 *	msi_map::virq the allocated Linux interrupt number (> 0).
 | 
			
		||||
 *
 | 
			
		||||
 *	On fail msi_map::index contains the error code and msi_map::virq
 | 
			
		||||
 *	is set to 0.
 | 
			
		||||
 */
 | 
			
		||||
struct msi_map pci_ims_alloc_irq(struct pci_dev *dev, union msi_instance_cookie *icookie,
 | 
			
		||||
				 const struct irq_affinity_desc *affdesc)
 | 
			
		||||
{
 | 
			
		||||
	return msi_domain_alloc_irq_at(&dev->dev, MSI_SECONDARY_DOMAIN, MSI_ANY_INDEX,
 | 
			
		||||
				       affdesc, icookie);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(pci_ims_alloc_irq);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pci_ims_free_irq - Allocate an interrupt on a PCI/IMS interrupt domain
 | 
			
		||||
 *		      which was allocated via pci_ims_alloc_irq()
 | 
			
		||||
 * @dev:	The PCI device to operate on
 | 
			
		||||
 * @map:	A struct msi_map describing the interrupt to free as
 | 
			
		||||
 *		returned from pci_ims_alloc_irq()
 | 
			
		||||
 */
 | 
			
		||||
void pci_ims_free_irq(struct pci_dev *dev, struct msi_map map)
 | 
			
		||||
{
 | 
			
		||||
	if (WARN_ON_ONCE(map.index < 0 || map.virq <= 0))
 | 
			
		||||
		return;
 | 
			
		||||
	msi_domain_free_irqs_range(&dev->dev, MSI_SECONDARY_DOMAIN, map.index, map.index);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(pci_ims_free_irq);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pci_free_irq_vectors() - Free previously allocated IRQs for a device
 | 
			
		||||
 * @dev: the PCI device to operate on
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2491,6 +2491,9 @@ struct msi_domain_template;
 | 
			
		|||
 | 
			
		||||
bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template,
 | 
			
		||||
			   unsigned int hwsize, void *data);
 | 
			
		||||
struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie,
 | 
			
		||||
				 const struct irq_affinity_desc *affdesc);
 | 
			
		||||
void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map);
 | 
			
		||||
 | 
			
		||||
#include <linux/dma-mapping.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue