irqchip/ls-scfg-msi: Add LS1043a v1.1 MSI support

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.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Minghuan Lian <Minghuan.Lian@nxp.com>
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

authored by

Minghuan Lian and committed by
Marc Zyngier
fd100dab 4dd5da65

+40 -6
+1
Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
··· 7 7 "fsl,ls1021a-msi" 8 8 "fsl,ls1043a-msi" 9 9 "fsl,ls1046a-msi" 10 + "fsl,ls1043a-v1.1-msi" 10 11 - msi-controller: indicates that this is a PCIe MSI controller node 11 12 - reg: physical base address of the controller and length of memory mapped. 12 13 - interrupts: an interrupt to the parent interrupt controller.
+39 -6
drivers/irqchip/irq-ls-scfg-msi.c
··· 25 25 #define MSI_IRQS_PER_MSIR 32 26 26 #define MSI_MSIR_OFFSET 4 27 27 28 + #define MSI_LS1043V1_1_IRQS_PER_MSIR 8 29 + #define MSI_LS1043V1_1_MSIR_OFFSET 0x10 30 + 28 31 struct ls_scfg_msi_cfg { 29 32 u32 ibs_shift; /* Shift of interrupt bit select */ 33 + u32 msir_irqs; /* The irq number per MSIR */ 34 + u32 msir_base; /* The base address of MSIR */ 30 35 }; 31 36 32 37 struct ls_scfg_msir { 33 38 struct ls_scfg_msi *msi_data; 34 39 unsigned int index; 35 40 unsigned int gic_irq; 41 + unsigned int bit_start; 42 + unsigned int bit_end; 36 43 void __iomem *reg; 37 44 }; 38 45 ··· 147 140 struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc); 148 141 struct ls_scfg_msi *msi_data = msir->msi_data; 149 142 unsigned long val; 150 - int pos, virq, hwirq; 143 + int pos, size, virq, hwirq; 151 144 152 145 chained_irq_enter(irq_desc_get_chip(desc), desc); 153 146 154 147 val = ioread32be(msir->reg); 155 - for_each_set_bit(pos, &val, MSI_IRQS_PER_MSIR) { 156 - hwirq = ((31 - pos) << msi_data->cfg->ibs_shift) | msir->index; 148 + 149 + pos = msir->bit_start; 150 + size = msir->bit_end + 1; 151 + 152 + for_each_set_bit_from(pos, &val, size) { 153 + hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) | 154 + msir->index; 157 155 virq = irq_find_mapping(msi_data->parent, hwirq); 158 156 if (virq) 159 157 generic_handle_irq(virq); ··· 205 193 msir->index = index; 206 194 msir->msi_data = msi_data; 207 195 msir->gic_irq = virq; 208 - msir->reg = msi_data->regs + MSI_MSIR_OFFSET + 4 * index; 196 + msir->reg = msi_data->regs + msi_data->cfg->msir_base + 4 * index; 197 + 198 + if (msi_data->cfg->msir_irqs == MSI_LS1043V1_1_IRQS_PER_MSIR) { 199 + msir->bit_start = 32 - ((msir->index + 1) * 200 + MSI_LS1043V1_1_IRQS_PER_MSIR); 201 + msir->bit_end = msir->bit_start + 202 + MSI_LS1043V1_1_IRQS_PER_MSIR - 1; 203 + } else { 204 + msir->bit_start = 0; 205 + msir->bit_end = msi_data->cfg->msir_irqs - 1; 206 + } 209 207 210 208 irq_set_chained_handler_and_data(msir->gic_irq, 211 209 ls_scfg_msi_irq_handler, 212 210 msir); 213 211 214 212 /* Release the hwirqs corresponding to this MSIR */ 215 - for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { 213 + for (i = 0; i < msi_data->cfg->msir_irqs; i++) { 216 214 hwirq = i << msi_data->cfg->ibs_shift | msir->index; 217 215 bitmap_clear(msi_data->used, hwirq, 1); 218 216 } ··· 238 216 if (msir->gic_irq > 0) 239 217 irq_set_chained_handler_and_data(msir->gic_irq, NULL, NULL); 240 218 241 - for (i = 0; i < MSI_IRQS_PER_MSIR; i++) { 219 + for (i = 0; i < msi_data->cfg->msir_irqs; i++) { 242 220 hwirq = i << msi_data->cfg->ibs_shift | msir->index; 243 221 bitmap_set(msi_data->used, hwirq, 1); 244 222 } ··· 248 226 249 227 static struct ls_scfg_msi_cfg ls1021_msi_cfg = { 250 228 .ibs_shift = 3, 229 + .msir_irqs = MSI_IRQS_PER_MSIR, 230 + .msir_base = MSI_MSIR_OFFSET, 251 231 }; 252 232 253 233 static struct ls_scfg_msi_cfg ls1046_msi_cfg = { 254 234 .ibs_shift = 2, 235 + .msir_irqs = MSI_IRQS_PER_MSIR, 236 + .msir_base = MSI_MSIR_OFFSET, 237 + }; 238 + 239 + static struct ls_scfg_msi_cfg ls1043_v1_1_msi_cfg = { 240 + .ibs_shift = 2, 241 + .msir_irqs = MSI_LS1043V1_1_IRQS_PER_MSIR, 242 + .msir_base = MSI_LS1043V1_1_MSIR_OFFSET, 255 243 }; 256 244 257 245 static const struct of_device_id ls_scfg_msi_id[] = { ··· 271 239 272 240 { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, 273 241 { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, 242 + { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg }, 274 243 { .compatible = "fsl,ls1046a-msi", .data = &ls1046_msi_cfg }, 275 244 {}, 276 245 };