diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c index 67e9eb8fe329..c4795249719d 100644 --- a/drivers/net/ipa/gsi.c +++ b/drivers/net/ipa/gsi.c @@ -195,6 +195,8 @@ static void gsi_irq_type_disable(struct gsi *gsi, enum gsi_irq_type_id type_id) /* Turn off all GSI interrupts initially */ static void gsi_irq_setup(struct gsi *gsi) { + u32 adjust; + /* Disable all interrupt types */ gsi_irq_type_update(gsi, 0); @@ -203,8 +205,12 @@ static void gsi_irq_setup(struct gsi *gsi) iowrite32(0, gsi->virt + GSI_CNTXT_SRC_EV_CH_IRQ_MSK_OFFSET); iowrite32(0, gsi->virt + GSI_CNTXT_GLOB_IRQ_EN_OFFSET); iowrite32(0, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_MSK_OFFSET); - iowrite32(0, gsi->virt + GSI_INTER_EE_SRC_CH_IRQ_OFFSET); - iowrite32(0, gsi->virt + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET); + + /* Reverse the offset adjustment for inter-EE register offsets */ + adjust = gsi->version < IPA_VERSION_4_5 ? 0 : GSI_EE_REG_ADJUST; + iowrite32(0, gsi->virt + adjust + GSI_INTER_EE_SRC_CH_IRQ_OFFSET); + iowrite32(0, gsi->virt + adjust + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET); + iowrite32(0, gsi->virt + GSI_CNTXT_GSI_IRQ_EN_OFFSET); } @@ -2089,6 +2095,7 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, struct device *dev = &pdev->dev; struct resource *res; resource_size_t size; + u32 adjust; int ret; gsi_validate_build(); @@ -2115,11 +2122,21 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, return -EINVAL; } + /* Make sure we can make our pointer adjustment if necessary */ + adjust = gsi->version < IPA_VERSION_4_5 ? 0 : GSI_EE_REG_ADJUST; + if (res->start < adjust) { + dev_err(dev, "DT memory resource \"gsi\" too low (< %u)\n", + adjust); + return -EINVAL; + } + gsi->virt = ioremap(res->start, size); if (!gsi->virt) { dev_err(dev, "unable to remap \"gsi\" memory\n"); return -ENOMEM; } + /* Adjust register range pointer downward for newer IPA versions */ + gsi->virt -= adjust; init_completion(&gsi->completion); diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h index 2aea17f8f5c4..0e138bbd8205 100644 --- a/drivers/net/ipa/gsi_reg.h +++ b/drivers/net/ipa/gsi_reg.h @@ -38,6 +38,17 @@ * (though the actual limit is hardware-dependent). */ +/* GSI EE registers as a group are shifted downward by a fixed + * constant amount for IPA versions 4.5 and beyond. This applies + * to all GSI registers we use *except* the ones that disable + * inter-EE interrupts for channels and event channels. + * + * We handle this by adjusting the pointer to the mapped GSI memory + * region downward. Then in the one place we use them (gsi_irq_setup()) + * we undo that adjustment for the inter-EE interrupt registers. + */ +#define GSI_EE_REG_ADJUST 0x0000d000 /* IPA v4.5+ */ + #define GSI_INTER_EE_SRC_CH_IRQ_OFFSET \ GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(GSI_EE_AP) #define GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(ee) \