--- /dev/null
+From 852a88f35f4b7e5ebb717fed3c3a3330d5ad4336 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
+Date: Wed, 10 Apr 2019 16:43:27 +0200
+Subject: [PATCH v2] MIPS: perf: ath79: Fix perfcount IRQ assignment
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently it's not possible to use perf on ath79 due to genirq flags
+mismatch happening on static virtual IRQ 13 which is used for
+performance counters hardware IRQ 5.
+
+On TP-Link Archer C7v5:
+
+ CPU0
+ 2: 0 MIPS 2 ath9k
+ 4: 318 MIPS 4 19000000.eth
+ 7: 55034 MIPS 7 timer
+ 8: 1236 MISC 3 ttyS0
+ 12: 0 INTC 1 ehci_hcd:usb1
+ 13: 0 gpio-ath79 2 keys
+ 14: 0 gpio-ath79 5 keys
+ 15: 31 AR724X PCI 1 ath10k_pci
+
+ $ perf top
+ genirq: Flags mismatch irq 13. 00014c83 (mips_perf_pmu) vs. 00002003 (keys)
+
+On TP-Link Archer C7v4:
+
+ CPU0
+ 4: 0 MIPS 4 19000000.eth
+ 5: 7135 MIPS 5 1a000000.eth
+ 7: 98379 MIPS 7 timer
+ 8: 30 MISC 3 ttyS0
+ 12: 90028 INTC 0 ath9k
+ 13: 5520 INTC 1 ehci_hcd:usb1
+ 14: 4623 INTC 2 ehci_hcd:usb2
+ 15: 32844 AR724X PCI 1 ath10k_pci
+ 16: 0 gpio-ath79 16 keys
+ 23: 0 gpio-ath79 23 keys
+
+ $ perf top
+ genirq: Flags mismatch irq 13. 00014c80 (mips_perf_pmu) vs. 00000080 (ehci_hcd:usb1)
+
+This problem is happening, because currently statically assigned virtual
+IRQ 13 for performance counters is not claimed during the initialization
+of MIPS PMU during the bootup, so the IRQ subsystem doesn't know, that
+this interrupt isn't available for further use.
+
+So this patch fixes the issue by simply booking hardware IRQ 5 for MIPS PMU.
+
+Tested-by: Kevin 'ldir' Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+Signed-off-by: Petr Štetiar <ynezz@true.cz>
+---
+
+Changes since v1:
+
+ I've incorporated two comments which I've received on IRC from blogic and
+ I've also reworded the commit message to match the changes in v2 of this
+ patch.
+
+ * use actual hardware perfcount IRQ 5 instead of the virtual IRQ 13
+ * dropped the CONFIG_PERF_EVENTS ifdef around irq_create_mapping
+
+ arch/mips/ath79/setup.c | 6 ------
+ drivers/irqchip/irq-ath79-misc.c | 11 +++++++++++
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+--- a/arch/mips/ath79/setup.c
++++ b/arch/mips/ath79/setup.c
+@@ -183,12 +183,6 @@ const char *get_system_type(void)
+ return ath79_sys_type;
+ }
+
+-int get_c0_perfcount_int(void)
+-{
+- return ATH79_MISC_IRQ(5);
+-}
+-EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+-
+ unsigned int get_c0_compare_int(void)
+ {
+ return CP0_LEGACY_COMPARE_IRQ;
+--- a/drivers/irqchip/irq-ath79-misc.c
++++ b/drivers/irqchip/irq-ath79-misc.c
+@@ -22,6 +22,15 @@
+ #define AR71XX_RESET_REG_MISC_INT_ENABLE 4
+
+ #define ATH79_MISC_IRQ_COUNT 32
++#define ATH79_MISC_PERF_IRQ 5
++
++static int ath79_perfcount_irq;
++
++int get_c0_perfcount_int(void)
++{
++ return ath79_perfcount_irq;
++}
++EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+
+ static void ath79_misc_irq_handler(struct irq_desc *desc)
+ {
+@@ -113,6 +122,8 @@ static void __init ath79_misc_intc_domai
+ {
+ void __iomem *base = domain->host_data;
+
++ ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ);
++
+ /* Disable and clear all interrupts */
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
int id;
char name[20];
enum pci_barno bar;
-@@ -476,11 +656,14 @@ static int pci_endpoint_test_probe(struc
+@@ -476,12 +656,15 @@ static int pci_endpoint_test_probe(struc
test->alignment = 0;
test->pdev = pdev;
data = (struct pci_endpoint_test_data *)ent->driver_data;
if (data) {
test_reg_bar = data->test_reg_bar;
+ test->test_reg_bar = test_reg_bar;
test->alignment = data->alignment;
- no_msi = data->no_msi;
+ irq_type = data->irq_type;
}
init_completion(&test->irq_raised);
-@@ -500,35 +683,21 @@ static int pci_endpoint_test_probe(struc
+@@ -501,35 +684,21 @@ static int pci_endpoint_test_probe(struc
pci_set_master(pdev);
}
test->base = test->bar[test_reg_bar];
-@@ -544,24 +713,31 @@ static int pci_endpoint_test_probe(struc
+@@ -545,24 +714,31 @@ static int pci_endpoint_test_probe(struc
id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
err_ida_remove:
ida_simple_remove(&pci_endpoint_test_ida, id);
-@@ -570,9 +746,10 @@ err_iounmap:
+@@ -571,9 +747,10 @@ err_iounmap:
if (test->bar[bar])
pci_iounmap(pdev, test->bar[bar]);
}
pci_release_regions(pdev);
err_disable_pdev:
-@@ -594,12 +771,16 @@ static void pci_endpoint_test_remove(str
+@@ -595,12 +772,16 @@ static void pci_endpoint_test_remove(str
return;
misc_deregister(&test->miscdev);
pci_release_regions(pdev);
pci_disable_device(pdev);
}
-@@ -607,6 +788,7 @@ static void pci_endpoint_test_remove(str
+@@ -608,6 +789,7 @@ static void pci_endpoint_test_remove(str
static const struct pci_device_id pci_endpoint_test_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
pcie->breg_base = devm_ioremap_resource(dev, res);
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
-@@ -576,15 +576,8 @@ static int xilinx_pcie_parse_dt(struct x
+@@ -584,15 +584,8 @@ static int xilinx_pcie_parse_dt(struct x
struct device *dev = port->dev;
struct device_node *node = dev->of_node;
struct resource regs;