intel_th: Communicate IRQ via resource
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>
Fri, 3 May 2019 08:44:39 +0000 (11:44 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 May 2019 16:14:29 +0000 (18:14 +0200)
Currently, the IRQ is passed between the glue layers and the core as a
separate argument, while the MMIO resources are passed as resources.
This also limits the number of IRQs thus used to one, while the current
versions of Intel TH use a different MSI vector for each interrupt
triggering event, of which there are 7.

Change this to pass IRQ in the resources array.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hwtracing/intel_th/acpi.c
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/intel_th.h
drivers/hwtracing/intel_th/pci.c

index b528e5b..87f9024 100644 (file)
@@ -40,20 +40,18 @@ static int intel_th_acpi_probe(struct platform_device *pdev)
        struct resource resource[TH_MMIO_END];
        const struct acpi_device_id *id;
        struct intel_th *th;
-       int i, r, irq = -1;
+       int i, r;
 
        id = acpi_match_device(intel_th_acpi_ids, &pdev->dev);
        if (!id)
                return -ENODEV;
 
        for (i = 0, r = 0; i < pdev->num_resources && r < TH_MMIO_END; i++)
-               if (pdev->resource[i].flags & IORESOURCE_IRQ)
-                       irq = pdev->resource[i].start;
-               else if (pdev->resource[i].flags & IORESOURCE_MEM)
+               if (pdev->resource[i].flags &
+                   (IORESOURCE_IRQ | IORESOURCE_MEM))
                        resource[r++] = pdev->resource[i];
 
-       th = intel_th_alloc(&pdev->dev, (void *)id->driver_data, resource, r,
-                           irq);
+       th = intel_th_alloc(&pdev->dev, (void *)id->driver_data, resource, r);
        if (IS_ERR(th))
                return PTR_ERR(th);
 
index a0b8b01..0205fca 100644 (file)
@@ -834,10 +834,10 @@ static const struct file_operations intel_th_output_fops = {
  */
 struct intel_th *
 intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
-              struct resource *devres, unsigned int ndevres, int irq)
+              struct resource *devres, unsigned int ndevres)
 {
+       int err, r, nr_mmios = 0;
        struct intel_th *th;
-       int err, r;
 
        th = kzalloc(sizeof(*th), GFP_KERNEL);
        if (!th)
@@ -855,13 +855,26 @@ intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
                err = th->major;
                goto err_ida;
        }
+       th->irq = -1;
        th->dev = dev;
        th->drvdata = drvdata;
 
        for (r = 0; r < ndevres; r++)
-               th->resource[r] = devres[r];
-       th->num_resources = ndevres;
-       th->irq = irq;
+               switch (devres[r].flags & IORESOURCE_TYPE_BITS) {
+               case IORESOURCE_MEM:
+                       th->resource[nr_mmios++] = devres[r];
+                       break;
+               case IORESOURCE_IRQ:
+                       if (th->irq == -1)
+                               th->irq = devres[r].start;
+                       break;
+               default:
+                       dev_warn(dev, "Unknown resource type %lx\n",
+                                devres[r].flags);
+                       break;
+               }
+
+       th->num_resources = nr_mmios;
 
        dev_set_drvdata(dev, th);
 
index 3fca86d..6c6eb87 100644 (file)
@@ -213,7 +213,7 @@ static inline struct intel_th *to_intel_th(struct intel_th_device *thdev)
 
 struct intel_th *
 intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
-              struct resource *devres, unsigned int ndevres, int irq);
+              struct resource *devres, unsigned int ndevres);
 void intel_th_free(struct intel_th *th);
 
 int intel_th_driver_register(struct intel_th_driver *thdrv);
index fd8267b..03d6894 100644 (file)
@@ -72,7 +72,7 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
                              const struct pci_device_id *id)
 {
        struct intel_th_drvdata *drvdata = (void *)id->driver_data;
-       struct resource resource[TH_MMIO_END] = {
+       struct resource resource[TH_MMIO_END + 1] = {
                [TH_MMIO_CONFIG]        = pdev->resource[TH_PCI_CONFIG_BAR],
                [TH_MMIO_SW]            = pdev->resource[TH_PCI_STH_SW_BAR],
        };
@@ -92,7 +92,12 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
                r++;
        }
 
-       th = intel_th_alloc(&pdev->dev, drvdata, resource, r, pdev->irq);
+       if (pdev->irq > 0) {
+               resource[r].flags   = IORESOURCE_IRQ;
+               resource[r++].start = pdev->irq;
+       }
+
+       th = intel_th_alloc(&pdev->dev, drvdata, resource, r);
        if (IS_ERR(th))
                return PTR_ERR(th);