lkml.org 
[lkml]   [2021]   [Nov]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[patch 28/37] genirq/msi: Provide interface to retrieve Linux interrupt number
    Date
    This allows drivers to retrieve the Linux interrupt number instead of
    fiddling with MSI descriptors.

    msi_get_virq() returns the Linux interrupt number or 0, __msi_get_virq()
    has more detailed return codes so pci_irq_vector() can use it as well.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
    include/linux/msi.h | 16 ++++++++++++++++
    kernel/irq/msi.c | 38 ++++++++++++++++++++++++++++++++++++++
    2 files changed, 54 insertions(+)

    --- a/include/linux/msi.h
    +++ b/include/linux/msi.h
    @@ -169,6 +169,22 @@ static inline bool msi_device_has_proper
    }
    #endif

    +int __msi_get_virq(struct device *dev, unsigned int index);
    +
    +/**
    + * msi_get_virq - Return Linux interrupt number of a MSI interrupt
    + * @dev: Device to operate on
    + * @index: MSI interrupt index to look for (0-based)
    + *
    + * Return: The Linux interrupt number on success (> 0), 0 if not found
    + */
    +static inline unsigned int msi_get_virq(struct device *dev, unsigned int index)
    +{
    + int ret = __msi_get_virq(dev, index);
    +
    + return ret < 0 ? 0 : ret;
    +}
    +
    /* Helpers to hide struct msi_desc implementation details */
    #define msi_desc_to_dev(desc) ((desc)->dev)
    #define dev_to_msi_list(dev) (&(dev)->msi_list)
    --- a/kernel/irq/msi.c
    +++ b/kernel/irq/msi.c
    @@ -120,6 +120,44 @@ int msi_setup_device_data(struct device
    return 0;
    }

    +/**
    + * __msi_get_virq - Return Linux interrupt number of a MSI interrupt
    + * @dev: Device to operate on
    + * @index: MSI interrupt index to look for (0-based)
    + *
    + * Return: The Linux interrupt number on success (> 0)
    + * -ENODEV when the device is not using MSI
    + * -ENOENT if no such entry exists
    + */
    +int __msi_get_virq(struct device *dev, unsigned int index)
    +{
    + struct msi_desc *desc;
    + bool pcimsi;
    +
    + if (!dev->msi.data)
    + return -ENODEV;
    +
    + pcimsi = msi_device_has_property(dev, MSI_PROP_PCI_MSI);
    +
    + for_each_msi_entry(desc, dev) {
    + /* PCI-MSI has only one descriptor for multiple interrupts. */
    + if (pcimsi) {
    + if (desc->irq && index < desc->nvec_used)
    + return desc->irq + index;
    + break;
    + }
    +
    + /*
    + * PCI-MSIX and platform MSI use a descriptor per
    + * interrupt.
    + */
    + if (desc->msi_index == index)
    + return desc->irq;
    + }
    + return -ENOENT;
    +}
    +EXPORT_SYMBOL_GPL(__msi_get_virq);
    +
    #ifdef CONFIG_SYSFS
    static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
    char *buf)
    \
     
     \ /
      Last update: 2021-11-27 02:26    [W:8.818 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site