Commit 6069fd81 authored by Thomas Zimmermann's avatar Thomas Zimmermann Committed by Patrik Jakobsson

drm/gma500: Cleanup GTT uninit and error handling

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: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220308195222.13471-8-tzimmermann@suse.de
parent 97bd66c4
...@@ -125,23 +125,20 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r ...@@ -125,23 +125,20 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r
mutex_unlock(&pdev->gtt_mutex); 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 drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
if (dev_priv->gtt_map) { iounmap(dev_priv->vram_addr);
iounmap(dev_priv->gtt_map); iounmap(dev_priv->gtt_map);
dev_priv->gtt_map = NULL;
} pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl);
if (dev_priv->gtt_initialized) { PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
pci_write_config_word(pdev, PSB_GMCH_CTRL, (void)PSB_RVDC32(PSB_PGETBL_CTL);
dev_priv->gmch_ctrl);
PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); mutex_destroy(&dev_priv->mmap_mutex);
(void) PSB_RVDC32(PSB_PGETBL_CTL); mutex_destroy(&dev_priv->gtt_mutex);
}
if (dev_priv->vram_addr)
iounmap(dev_priv->gtt_map);
} }
/* Clear GTT. Use a scratch page to avoid accidents or scribbles. */ /* Clear GTT. Use a scratch page to avoid accidents or scribbles. */
...@@ -233,8 +230,6 @@ int psb_gtt_init(struct drm_device *dev) ...@@ -233,8 +230,6 @@ int psb_gtt_init(struct drm_device *dev)
(void) PSB_RVDC32(PSB_PGETBL_CTL); (void) PSB_RVDC32(PSB_PGETBL_CTL);
/* The root resource we allocate address space from */ /* The root resource we allocate address space from */
dev_priv->gtt_initialized = 1;
pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
/* /*
...@@ -299,14 +294,14 @@ int psb_gtt_init(struct drm_device *dev) ...@@ -299,14 +294,14 @@ int psb_gtt_init(struct drm_device *dev)
if (!dev_priv->gtt_map) { if (!dev_priv->gtt_map) {
dev_err(dev->dev, "Failure to map gtt.\n"); dev_err(dev->dev, "Failure to map gtt.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_err; goto err_gtt_disable;
} }
dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
if (!dev_priv->vram_addr) { if (!dev_priv->vram_addr) {
dev_err(dev->dev, "Failure to map stolen base.\n"); dev_err(dev->dev, "Failure to map stolen base.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_err; goto err_iounmap;
} }
psb_gtt_clear(dev_priv); psb_gtt_clear(dev_priv);
...@@ -314,8 +309,14 @@ int psb_gtt_init(struct drm_device *dev) ...@@ -314,8 +309,14 @@ int psb_gtt_init(struct drm_device *dev)
return 0; return 0;
out_err: err_iounmap:
psb_gtt_takedown(dev); 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; return ret;
} }
...@@ -340,8 +341,6 @@ static int psb_gtt_resume(struct drm_device *dev) ...@@ -340,8 +341,6 @@ static int psb_gtt_resume(struct drm_device *dev)
(void) PSB_RVDC32(PSB_PGETBL_CTL); (void) PSB_RVDC32(PSB_PGETBL_CTL);
/* The root resource we allocate address space from */ /* The root resource we allocate address space from */
dev_priv->gtt_initialized = 1;
pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
/* /*
...@@ -398,7 +397,7 @@ static int psb_gtt_resume(struct drm_device *dev) ...@@ -398,7 +397,7 @@ static int psb_gtt_resume(struct drm_device *dev)
if ((gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { if ((gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) {
dev_err(dev->dev, "GTT resume error.\n"); dev_err(dev->dev, "GTT resume error.\n");
ret = -EINVAL; ret = -EINVAL;
goto out_err; goto err_gtt_disable;
} }
pg->gtt_pages = gtt_pages; pg->gtt_pages = gtt_pages;
...@@ -410,8 +409,10 @@ static int psb_gtt_resume(struct drm_device *dev) ...@@ -410,8 +409,10 @@ static int psb_gtt_resume(struct drm_device *dev)
return 0; return 0;
out_err: err_gtt_disable:
psb_gtt_takedown(dev); 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; return ret;
} }
......
...@@ -26,7 +26,7 @@ struct psb_gtt { ...@@ -26,7 +26,7 @@ struct psb_gtt {
/* Exported functions */ /* Exported functions */
int psb_gtt_init(struct drm_device *dev); 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); extern int psb_gtt_restore(struct drm_device *dev);
int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res, int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res,
......
...@@ -192,7 +192,7 @@ static void psb_driver_unload(struct drm_device *dev) ...@@ -192,7 +192,7 @@ static void psb_driver_unload(struct drm_device *dev)
psb_mmu_driver_takedown(dev_priv->mmu); psb_mmu_driver_takedown(dev_priv->mmu);
dev_priv->mmu = NULL; dev_priv->mmu = NULL;
} }
psb_gtt_takedown(dev); psb_gtt_fini(dev);
if (dev_priv->scratch_page) { if (dev_priv->scratch_page) {
set_pages_wb(dev_priv->scratch_page, 1); set_pages_wb(dev_priv->scratch_page, 1);
__free_page(dev_priv->scratch_page); __free_page(dev_priv->scratch_page);
......
...@@ -408,7 +408,6 @@ struct drm_psb_private { ...@@ -408,7 +408,6 @@ struct drm_psb_private {
uint32_t stolen_base; uint32_t stolen_base;
u8 __iomem *vram_addr; u8 __iomem *vram_addr;
unsigned long vram_stolen_size; unsigned long vram_stolen_size;
int gtt_initialized;
u16 gmch_ctrl; /* Saved GTT setup */ u16 gmch_ctrl; /* Saved GTT setup */
u32 pge_ctl; u32 pge_ctl;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment