lkml.org 
[lkml]   [2022]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[patch 29/33] PCI/MSI: Provide pci_ims_alloc/free_irq()
    Date
    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>
    ---
    drivers/pci/msi/api.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
    include/linux/pci.h | 3 +++
    2 files changed, 53 insertions(+)

    --- a/drivers/pci/msi/api.c
    +++ b/drivers/pci/msi/api.c
    @@ -361,6 +361,56 @@ const struct cpumask *pci_irq_get_affini
    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
    + * @cookie: Pointer to an IMS implementation specific device cookie
    + * (PASID, queue id, pointer...). The cookie content is stored
    + * in the MSI descriptor for the interrupt chip callbacks or
    + * domain specific setup functions
    + * @affdesc: Optional pointer to an interrupt affinity descriptor
    + *
    + * 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.
    + *
    + * Note: 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 @cookie to store the MSI
    + * message in the appropriate place.
    + */
    +struct msi_map pci_ims_alloc_irq(struct pci_dev *dev, union msi_dev_cookie *cookie,
    + const struct irq_affinity_desc *affdesc)
    +{
    + return msi_domain_alloc_irq_at(&dev->dev, MSI_SECONDARY_DOMAIN, MSI_ANY_INDEX,
    + affdesc, cookie);
    +}
    +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))
    + 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
    *
    --- a/include/linux/pci.h
    +++ b/include/linux/pci.h
    @@ -2485,6 +2485,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_dev_cookie *cookie,
    + const struct irq_affinity_desc *affdesc);
    +void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map);

    #include <linux/dma-mapping.h>

    \
     
     \ /
      Last update: 2022-11-11 15:09    [W:4.036 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site