aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch')
-rw-r--r--target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch139
1 files changed, 139 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch b/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch
new file mode 100644
index 0000000000..02fc020338
--- /dev/null
+++ b/target/linux/layerscape/patches-4.4/8240-irqchip-ls-scfg-msi-add-LS1043a-v1.1-MSI-support.patch
@@ -0,0 +1,139 @@
+From ab9d5c5c767c17bf9526f84beb5667f2a50e1a4d Mon Sep 17 00:00:00 2001
+From: Minghuan Lian <Minghuan.Lian@nxp.com>
+Date: Tue, 17 Jan 2017 17:32:42 +0800
+Subject: [PATCH] irqchip/ls-scfg-msi: add LS1043a v1.1 MSI support
+
+Cherry-pick patchwork patch with context adjustment.
+
+A MSI controller of LS1043a v1.0 only includes one MSIR and
+is assigned one GIC interrupt. In order to support affinity,
+LS1043a v1.1 MSI is assigned 4 MSIRs and 4 GIC interrupts.
+But the MSIR has the different offset and only supports 8 MSIs.
+The bits between variable bit_start and bit_end in structure
+ls_scfg_msir are used to show 8 MSI interrupts. msir_irqs and
+msir_base are added to describe the difference of MSI between
+LS1043a v1.1 and other SoCs.
+
+Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+---
+ drivers/irqchip/irq-ls-scfg-msi.c | 45 +++++++++++++++++++++++++++++++++------
+ 1 file changed, 39 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
+index 6586076..71a2050 100644
+--- a/drivers/irqchip/irq-ls-scfg-msi.c
++++ b/drivers/irqchip/irq-ls-scfg-msi.c
+@@ -25,14 +25,21 @@
+ #define MSI_IRQS_PER_MSIR 32
+ #define MSI_MSIR_OFFSET 4
+
++#define MSI_LS1043V1_1_IRQS_PER_MSIR 8
++#define MSI_LS1043V1_1_MSIR_OFFSET 0x10
++
+ struct ls_scfg_msi_cfg {
+ u32 ibs_shift; /* Shift of interrupt bit select */
++ u32 msir_irqs; /* The irq number per MSIR */
++ u32 msir_base; /* The base address of MSIR */
+ };
+
+ struct ls_scfg_msir {
+ struct ls_scfg_msi *msi_data;
+ unsigned int index;
+ unsigned int gic_irq;
++ unsigned int bit_start;
++ unsigned int bit_end;
+ void __iomem *reg;
+ };
+
+@@ -140,13 +147,18 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
+ struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
+ struct ls_scfg_msi *msi_data = msir->msi_data;
+ unsigned long val;
+- int pos, virq, hwirq;
++ int pos, size, virq, hwirq;
+
+ chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+ val = ioread32be(msir->reg);
+- for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) {
+- hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index;
++
++ pos = msir->bit_start;
++ size = msir->bit_end + 1;
++
++ for_each_set_bit_from(pos, &val, size) {
++ hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
++ msir->index;
+ virq = irq_find_mapping(msi_data->parent, hwirq);
+ if (virq)
+ generic_handle_irq(virq);
+@@ -193,14 +205,24 @@ static int ls_scfg_msi_setup_hwirq(struct ls_scfg_msi *msi_data, int index)
+ msir->index = index;
+ msir->msi_data = msi_data;
+ msir->gic_irq = virq;
+- msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index;
++ msir->reg = msi_data->regs + msi_data->cfg->msir_base + 4 * index;
++
++ if (msi_data->cfg->msir_irqs == MSI_LS1043V1_1_IRQS_PER_MSIR) {
++ msir->bit_start = 32 - ((msir->index + 1) *
++ MSI_LS1043V1_1_IRQS_PER_MSIR);
++ msir->bit_end = msir->bit_start +
++ MSI_LS1043V1_1_IRQS_PER_MSIR - 1;
++ } else {
++ msir->bit_start = 0;
++ msir->bit_end = msi_data->cfg->msir_irqs - 1;
++ }
+
+ irq_set_chained_handler_and_data(msir->gic_irq,
+ ls_scfg_msi_irq_handler,
+ msir);
+
+ /* Release the hwirqs corresponding to this MSIR */
+- for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
++ for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
+ hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+ bitmap_clear(msi_data->used, hwirq, 1);
+ }
+@@ -216,7 +238,7 @@ static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
+ if (msir->gic_irq > 0)
+ irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL);
+
+- for (i = 0; i < MSI_IRQS_PER_MSIR; i++) {
++ for (i = 0; i < msi_data->cfg->msir_irqs; i++) {
+ hwirq = i << msi_data->cfg->ibs_shift | msir->index;
+ bitmap_set(msi_data->used, hwirq, 1);
+ }
+@@ -226,10 +248,20 @@ static int ls_scfg_msi_teardown_hwirq(struct ls_scfg_msir *msir)
+
+ static struct ls_scfg_msi_cfg ls1021_msi_cfg = {
+ .ibs_shift = 3,
++ .msir_irqs = MSI_IRQS_PER_MSIR,
++ .msir_base = MSI_MSIR_OFFSET,
+ };
+
+ static struct ls_scfg_msi_cfg ls1046_msi_cfg = {
+ .ibs_shift = 2,
++ .msir_irqs = MSI_IRQS_PER_MSIR,
++ .msir_base = MSI_MSIR_OFFSET,
++};
++
++static struct ls_scfg_msi_cfg ls1043_v1_1_msi_cfg = {
++ .ibs_shift = 2,
++ .msir_irqs = MSI_LS1043V1_1_IRQS_PER_MSIR,
++ .msir_base = MSI_LS1043V1_1_MSIR_OFFSET,
+ };
+
+ static const struct of_device_id ls_scfg_msi_id[] = {
+@@ -240,6 +272,7 @@ static const struct of_device_id ls_scfg_msi_id[] = {
+ { .compatible = "fsl,ls1012a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg },
+ { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg },
++ { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg },
+ { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg },
+ {},
+ };
+--
+2.1.0.27.g96db324
+