There are three different ways of retrieving the I/O-memory ranges for AST devices: either from PCI BAR 1, from PCI BAR 2 or from PCI BAR 1 by 'guessing'. Make the respective code more readable by making each case self- contained. Also add error checking against the length of the PCI BARs. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/ast/ast_main.c | 40 +++++++++++++++++++++++++--------- drivers/gpu/drm/ast/ast_reg.h | 1 + 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 445cf47871a43..2c2700256a966 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -444,22 +444,42 @@ struct ast_device *ast_device_create(const struct drm_driver *drv, if (!ast->regs) return ERR_PTR(-EIO); - /* - * After AST2500, MMIO is enabled by default, and it should be adopted - * to be compatible with Arm. - */ if (pdev->revision >= 0x40) { + /* + * On AST2500 and later models, MMIO is enabled by + * default. Adopt it to be compatible with ARM. + */ + resource_size_t len = pci_resource_len(pdev, 1); + + if (len < AST_IO_MM_OFFSET) + return ERR_PTR(-EIO); + if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH) + return ERR_PTR(-EIO); ast->ioregs = ast->regs + AST_IO_MM_OFFSET; - } else if (!(pci_resource_flags(pdev, 2) & IORESOURCE_IO)) { - drm_info(dev, "platform has no IO space, trying MMIO\n"); - ast->ioregs = ast->regs + AST_IO_MM_OFFSET; - } + } else if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { + /* + * Map I/O registers if we have a PCI BAR for I/O. + */ + resource_size_t len = pci_resource_len(pdev, 2); - /* "map" IO regs if the above hasn't done so already */ - if (!ast->ioregs) { + if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH) + return ERR_PTR(-EIO); ast->ioregs = pcim_iomap(pdev, 2, 0); if (!ast->ioregs) return ERR_PTR(-EIO); + } else { + /* + * Anything else is best effort. + */ + resource_size_t len = pci_resource_len(pdev, 1); + + if (len < AST_IO_MM_OFFSET) + return ERR_PTR(-EIO); + if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH) + return ERR_PTR(-EIO); + ast->ioregs = ast->regs + AST_IO_MM_OFFSET; + + drm_info(dev, "Platform has no I/O space, using MMIO\n"); } if (!ast_is_vga_enabled(dev)) { diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index 555286ecf5209..f1e1700c01ed2 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -10,6 +10,7 @@ */ #define AST_IO_MM_OFFSET (0x380) +#define AST_IO_MM_LENGTH (0xff) #define AST_IO_VGAARI_W (0x40) #define AST_IO_VGAMR_W (0x42) -- 2.42.0