diff options
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.patch | 139 |
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 + |