Replace psb_gtt_takedown() with finalizer function that is only called for unloading the driver. Use roll-back pattern for error handling in psb_gtt_init() and _resume(). Also fixes a bug where vmap_addr was never unmapped. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/gpu/drm/gma500/gtt.c | 49 ++++++++++++++++---------------- drivers/gpu/drm/gma500/gtt.h | 2 +- drivers/gpu/drm/gma500/psb_drv.c | 2 +- drivers/gpu/drm/gma500/psb_drv.h | 1 - 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 43ad3ec38c80..99c644a5c5cb 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -125,23 +125,20 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r mutex_unlock(&pdev->gtt_mutex); } -void psb_gtt_takedown(struct drm_device *dev) +void psb_gtt_fini(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct pci_dev *pdev = to_pci_dev(dev->dev); - if (dev_priv->gtt_map) { - iounmap(dev_priv->gtt_map); - dev_priv->gtt_map = NULL; - } - if (dev_priv->gtt_initialized) { - pci_write_config_word(pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl); - PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); - (void) PSB_RVDC32(PSB_PGETBL_CTL); - } - if (dev_priv->vram_addr) - iounmap(dev_priv->gtt_map); + iounmap(dev_priv->vram_addr); + iounmap(dev_priv->gtt_map); + + pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl); + PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); + (void)PSB_RVDC32(PSB_PGETBL_CTL); + + mutex_destroy(&dev_priv->mmap_mutex); + mutex_destroy(&dev_priv->gtt_mutex); } /* Clear GTT. Use a scratch page to avoid accidents or scribbles. */ @@ -233,8 +230,6 @@ int psb_gtt_init(struct drm_device *dev) (void) PSB_RVDC32(PSB_PGETBL_CTL); /* The root resource we allocate address space from */ - dev_priv->gtt_initialized = 1; - pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; /* @@ -299,14 +294,14 @@ int psb_gtt_init(struct drm_device *dev) if (!dev_priv->gtt_map) { dev_err(dev->dev, "Failure to map gtt.\n"); ret = -ENOMEM; - goto out_err; + goto err_gtt_disable; } dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); if (!dev_priv->vram_addr) { dev_err(dev->dev, "Failure to map stolen base.\n"); ret = -ENOMEM; - goto out_err; + goto err_iounmap; } psb_gtt_clear(dev_priv); @@ -314,8 +309,14 @@ int psb_gtt_init(struct drm_device *dev) return 0; -out_err: - psb_gtt_takedown(dev); +err_iounmap: + iounmap(dev_priv->gtt_map); +err_gtt_disable: + pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl); + PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); + (void)PSB_RVDC32(PSB_PGETBL_CTL); + mutex_destroy(&dev_priv->mmap_mutex); + mutex_destroy(&dev_priv->gtt_mutex); return ret; } @@ -340,8 +341,6 @@ static int psb_gtt_resume(struct drm_device *dev) (void) PSB_RVDC32(PSB_PGETBL_CTL); /* The root resource we allocate address space from */ - dev_priv->gtt_initialized = 1; - pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; /* @@ -398,7 +397,7 @@ static int psb_gtt_resume(struct drm_device *dev) if ((gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { dev_err(dev->dev, "GTT resume error.\n"); ret = -EINVAL; - goto out_err; + goto err_gtt_disable; } pg->gtt_pages = gtt_pages; @@ -410,8 +409,10 @@ static int psb_gtt_resume(struct drm_device *dev) return 0; -out_err: - psb_gtt_takedown(dev); +err_gtt_disable: + pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl); + PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); + (void)PSB_RVDC32(PSB_PGETBL_CTL); return ret; } diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h index cb270ea40794..5839d5d06adc 100644 --- a/drivers/gpu/drm/gma500/gtt.h +++ b/drivers/gpu/drm/gma500/gtt.h @@ -26,7 +26,7 @@ struct psb_gtt { /* Exported functions */ int psb_gtt_init(struct drm_device *dev); -extern void psb_gtt_takedown(struct drm_device *dev); +void psb_gtt_fini(struct drm_device *dev); extern int psb_gtt_restore(struct drm_device *dev); int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res, diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 2891a3dc8d2e..41be6e1ac7f9 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -192,7 +192,7 @@ static void psb_driver_unload(struct drm_device *dev) psb_mmu_driver_takedown(dev_priv->mmu); dev_priv->mmu = NULL; } - psb_gtt_takedown(dev); + psb_gtt_fini(dev); if (dev_priv->scratch_page) { set_pages_wb(dev_priv->scratch_page, 1); __free_page(dev_priv->scratch_page); diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 0439b10d3db5..553d03190ce1 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -408,7 +408,6 @@ struct drm_psb_private { uint32_t stolen_base; u8 __iomem *vram_addr; unsigned long vram_stolen_size; - int gtt_initialized; u16 gmch_ctrl; /* Saved GTT setup */ u32 pge_ctl; -- 2.35.1