lkml.org 
[lkml]   [2017]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/2] uio: Prefer MSI(X) interrupts in PCI drivers
    Date

    Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
    ---
     drivers/uio/uio_pci_dmem_genirq.c | 27 ++++++++++++++++++++-------
     drivers/uio/uio_pci_generic.c     | 24 ++++++++++++++++++------
     2 files changed, 38 insertions(+), 13 deletions(-)

    diff --git a/drivers/uio/uio_pci_dmem_genirq.c b/drivers/uio/uio_pci_dmem_genirq.c
    index d1dfd8002c6d..ebb3f9012cd8 100644
    --- a/drivers/uio/uio_pci_dmem_genirq.c
    +++ b/drivers/uio/uio_pci_dmem_genirq.c
    @@ -173,11 +173,13 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
     {
      struct uio_pci_dmem_dev *gdev = to_uio_pci_dmem_dev(info);
     
    - if (!pci_check_and_mask_intx(gdev->pdev))
    - return IRQ_NONE;
    + if (gdev->pdev->msi_enabled || gdev->pdev->msix_enabled)
    + return IRQ_HANDLED;
     
    - /* UIO core will signal the user process. */
    - return IRQ_HANDLED;
    + if (pci_check_and_mask_intx(gdev->pdev))
    + return IRQ_HANDLED;
    +
    + return IRQ_NONE;
     }
     
     static unsigned int uio_dmem_dma_bits = 32;
    @@ -269,11 +271,19 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
      }
      pci_set_master(pdev);
     
    - dev_info(&pdev->dev, "Legacy IRQ: %i", pdev->irq);
    - if (pdev->irq && !pci_intx_mask_supported(pdev)) {
    - err = -ENODEV;
    + /* Try to use MSI interrupts */
    + err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
    + if (err) {
    + dev_err(&pdev->dev, "%s: pci_alloc_irq_vectors failed: %d\n",
    + __func__, err);
      goto err_disable_pci;
      }
    + if (!pdev->msi_enabled && !pdev->msix_enabled &&
    +     !pci_intx_mask_supported(pdev)) {
    + err = -ENODEV;
    + goto err_free_irq_vectors;
    + }
    + dev_info(&pdev->dev, "IRQ: %i", pdev->irq);
     
      gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
      if (!gdev) {
    @@ -316,6 +326,8 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
      return 0;
     err_free_gdev:
      kfree(gdev);
    +err_free_irq_vectors:
    + pci_free_irq_vectors(pdev);
     err_disable_pci:
      pci_clear_master(pdev);
      pci_disable_device(pdev);
    @@ -327,6 +339,7 @@ static void remove(struct pci_dev *pdev)
      struct uio_pci_dmem_dev *gdev = pci_get_drvdata(pdev);
     
      uio_unregister_device(&gdev->info);
    + pci_free_irq_vectors(pdev);
      pci_clear_master(pdev);
      pci_disable_device(pdev);
      kfree(gdev);
    diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
    index a56fdf972dbe..23a800e76303 100644
    --- a/drivers/uio/uio_pci_generic.c
    +++ b/drivers/uio/uio_pci_generic.c
    @@ -46,11 +46,13 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
     {
      struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
     
    - if (!pci_check_and_mask_intx(gdev->pdev))
    - return IRQ_NONE;
    + if (gdev->pdev->msi_enabled || gdev->pdev->msix_enabled)
    + return IRQ_HANDLED;
     
    - /* UIO core will signal the user process. */
    - return IRQ_HANDLED;
    + if (pci_check_and_mask_intx(gdev->pdev))
    + return IRQ_HANDLED;
    +
    + return IRQ_NONE;
     }
     
     static int probe(struct pci_dev *pdev,
    @@ -66,10 +68,18 @@ static int probe(struct pci_dev *pdev,
      return err;
      }
     
    - if (pdev->irq && !pci_intx_mask_supported(pdev)) {
    - err = -ENODEV;
    + /* Try to use MSI interrupts */
    + err = pci_alloc_irq_vectors(pdev, 0, 1, PCI_IRQ_ALL_TYPES);
    + if (err) {
    + dev_err(&pdev->dev, "%s: pci_alloc_irq_vectors failed: %d\n",
    + __func__, err);
      goto err_verify;
      }
    + if (pdev->irq && !pdev->msi_enabled && !pdev->msix_enabled &&
    +     !pci_intx_mask_supported(pdev)) {
    + err = -ENODEV;
    + goto err_alloc;
    + }
     
      gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
      if (!gdev) {
    @@ -98,6 +108,7 @@ static int probe(struct pci_dev *pdev,
     err_register:
      kfree(gdev);
     err_alloc:
    + pci_free_irq_vectors(pdev);
     err_verify:
      pci_disable_device(pdev);
      return err;
    @@ -108,6 +119,7 @@ static void remove(struct pci_dev *pdev)
      struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
     
      uio_unregister_device(&gdev->info);
    + pci_free_irq_vectors(pdev);
      pci_disable_device(pdev);
      kfree(gdev);
     }
    -- 
    2.11.0
    \
     
     \ /
      Last update: 2017-10-06 15:33    [W:4.542 / U:3.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site