From db73a059de00eed721f13051c0d6ff3e7de90fe8 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 3 May 2019 11:44:36 +0300 Subject: intel_th: Rework resource passing between glue layers and core Currently, MMIO resource numbers in the TH driver core correspond to PCI BAR numbers, because in the beginning there was only the PCI glue layer. This created some confusion when the ACPI glue layer was added. To avoid confusion and remove glue-specific code from the driver core, split the resource indices between core and glue layers and change the API so that the driver core receives the MMIO resources in the same fixed order. At the same time, make the IRQ always be a parameter to intel_th_alloc() instead of sometimes passing it as a resource. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing/intel_th/pci.c') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 1cf6290d6435..9dd2d75bd539 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -17,7 +17,12 @@ #define DRIVER_NAME "intel_th_pci" -#define BAR_MASK (BIT(TH_MMIO_CONFIG) | BIT(TH_MMIO_SW)) +enum { + TH_PCI_CONFIG_BAR = 0, + TH_PCI_STH_SW_BAR = 2, +}; + +#define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR)) #define PCI_REG_NPKDSC 0x80 #define NPKDSC_TSACT BIT(5) @@ -66,6 +71,10 @@ 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] = { + [TH_MMIO_CONFIG] = pdev->resource[TH_PCI_CONFIG_BAR], + [TH_MMIO_SW] = pdev->resource[TH_PCI_STH_SW_BAR], + }; struct intel_th *th; int err; @@ -77,8 +86,8 @@ static int intel_th_pci_probe(struct pci_dev *pdev, if (err) return err; - th = intel_th_alloc(&pdev->dev, drvdata, pdev->resource, - DEVICE_COUNT_RESOURCE, pdev->irq); + th = intel_th_alloc(&pdev->dev, drvdata, resource, TH_MMIO_END, + pdev->irq); if (IS_ERR(th)) return PTR_ERR(th); -- cgit v1.2.3 From fc027f4ce7c718660e046c3269b303bdbe692fda Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 3 May 2019 11:44:38 +0300 Subject: intel_th: Add "rtit" source device In some versions of Intel TH, the Software Trace Hub (STH) has a second MMIO BAR dedicated to the input from Intel PT. This calls for a new subdevice that will be enumerated if the corresponding BAR is present. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing/intel_th/pci.c') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 9dd2d75bd539..fd8267bbaf2c 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -20,6 +20,7 @@ enum { TH_PCI_CONFIG_BAR = 0, TH_PCI_STH_SW_BAR = 2, + TH_PCI_RTIT_BAR = 4, }; #define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR)) @@ -75,8 +76,8 @@ static int intel_th_pci_probe(struct pci_dev *pdev, [TH_MMIO_CONFIG] = pdev->resource[TH_PCI_CONFIG_BAR], [TH_MMIO_SW] = pdev->resource[TH_PCI_STH_SW_BAR], }; + int err, r = TH_MMIO_SW + 1; struct intel_th *th; - int err; err = pcim_enable_device(pdev); if (err) @@ -86,8 +87,12 @@ static int intel_th_pci_probe(struct pci_dev *pdev, if (err) return err; - th = intel_th_alloc(&pdev->dev, drvdata, resource, TH_MMIO_END, - pdev->irq); + if (pdev->resource[TH_PCI_RTIT_BAR].start) { + resource[TH_MMIO_RTIT] = pdev->resource[TH_PCI_RTIT_BAR]; + r++; + } + + th = intel_th_alloc(&pdev->dev, drvdata, resource, r, pdev->irq); if (IS_ERR(th)) return PTR_ERR(th); -- cgit v1.2.3 From 62a593022c32380d040303a5e3d6b67fd9c415bc Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 3 May 2019 11:44:39 +0300 Subject: intel_th: Communicate IRQ via resource 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 Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/hwtracing/intel_th/pci.c') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index fd8267bbaf2c..03d6894cd9c9 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -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); -- cgit v1.2.3 From 7b7036d47c356a40818e516a69ac81a5dcc1613f Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 3 May 2019 11:44:40 +0300 Subject: intel_th: pci: Use MSI interrupt signalling Since Intel TH is capable of MSI interrupt signalling, make use of it. The way it works is, each of the 7 interrupt triggering events has its own vector in this mode, as opposed to interrupt line delivery, where all events are signalled via the same line. Failing to enable MSI, the driver falls back to using an interrupt line. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/hwtracing/intel_th/pci.c') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 03d6894cd9c9..f5643444481b 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -72,11 +72,11 @@ 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 + 1] = { + struct resource resource[TH_MMIO_END + TH_NVEC_MAX] = { [TH_MMIO_CONFIG] = pdev->resource[TH_PCI_CONFIG_BAR], [TH_MMIO_SW] = pdev->resource[TH_PCI_STH_SW_BAR], }; - int err, r = TH_MMIO_SW + 1; + int err, r = TH_MMIO_SW + 1, i; struct intel_th *th; err = pcim_enable_device(pdev); @@ -92,10 +92,12 @@ static int intel_th_pci_probe(struct pci_dev *pdev, r++; } - if (pdev->irq > 0) { - resource[r].flags = IORESOURCE_IRQ; - resource[r++].start = pdev->irq; - } + err = pci_alloc_irq_vectors(pdev, 1, 8, PCI_IRQ_ALL_TYPES); + if (err > 0) + for (i = 0; i < err; i++, r++) { + resource[r].flags = IORESOURCE_IRQ; + resource[r].start = pci_irq_vector(pdev, i); + } th = intel_th_alloc(&pdev->dev, drvdata, resource, r); if (IS_ERR(th)) @@ -114,6 +116,8 @@ static void intel_th_pci_remove(struct pci_dev *pdev) struct intel_th *th = pci_get_drvdata(pdev); intel_th_free(th); + + pci_free_irq_vectors(pdev); } static const struct intel_th_drvdata intel_th_2x = { -- cgit v1.2.3 From 4c5bb6eb4055adcefaeb5da56dfbecf7df3695d7 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 3 May 2019 11:44:42 +0300 Subject: intel_th: Only report useful IRQs to subdevices The only type of IRQ triggering event that is useful to us at the moment is the "last block" interrupt of the MSU. This interrupt can only be enabled via "MINTCTL" register that doesn't exist in earlier version of the Intel TH. Enumerate the presence of MINTCTL via per-device driver data structure and only instantiate the IRQ resource for subdevices if this capability is present. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/hwtracing/intel_th/pci.c') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index f5643444481b..5808dd4c104c 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -122,6 +122,7 @@ static void intel_th_pci_remove(struct pci_dev *pdev) static const struct intel_th_drvdata intel_th_2x = { .tscu_enable = 1, + .has_mintctl = 1, }; static const struct pci_device_id intel_th_pci_id_table[] = { -- cgit v1.2.3