summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2011-09-01 08:07:10 +0100
committerAndy Green <andy.green@linaro.org>2011-09-01 08:07:10 +0100
commit15d2a95ade13bbac1b86b4a0d0b646cae3d17141 (patch)
tree9f525b24d6d3d8718017cf5add9350eb66acbde5
parent741b68d61248d1b83cd57b27d3da50b5e57aebd2 (diff)
drm/omap: make module unloading work
Uninitialize properly to make module unloading work. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/staging/omapdrm/omap_connector.c7
-rw-r--r--drivers/staging/omapdrm/omap_drv.c16
-rw-r--r--drivers/staging/omapdrm/omap_drv.h1
-rw-r--r--drivers/staging/omapdrm/omap_fbdev.c24
4 files changed, 45 insertions, 3 deletions
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c
index f0c30213609..c1071c171bd 100644
--- a/drivers/staging/omapdrm/omap_connector.c
+++ b/drivers/staging/omapdrm/omap_connector.c
@@ -106,11 +106,16 @@ enum drm_connector_status omap_connector_detect(
static void omap_connector_destroy(struct drm_connector *connector)
{
struct omap_connector *omap_connector = to_omap_connector(connector);
+ struct omap_dss_device *dssdev = omap_connector->dssdev;
+
+ dssdev->driver->disable(dssdev);
DBG("%s", omap_connector->dssdev->name);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(omap_connector);
+
+ omap_dss_put_device(dssdev);
}
#define MAX_EDID 256
@@ -341,6 +346,8 @@ struct drm_connector * omap_connector_init(struct drm_device *dev,
DBG("%s", dssdev->name);
+ omap_dss_get_device(dssdev);
+
omap_connector = kzalloc(sizeof(struct omap_connector), GFP_KERNEL);
if (!omap_connector) {
dev_err(dev->dev, "could not allocate connector\n");
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index fc2d4e9fa92..b569ae121da 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -166,8 +166,6 @@ static int omap_modeset_init(struct drm_device *dev)
return 0;
}
- omap_dss_get_device(dssdev);
-
connector = omap_connector_init(dev,
get_connector_type(dssdev), dssdev);
@@ -354,6 +352,11 @@ static int omap_modeset_init(struct drm_device *dev)
return 0;
}
+static void omap_modeset_free(struct drm_device *dev)
+{
+ drm_mode_config_cleanup(dev);
+}
+
/*
* drm driver funcs
*/
@@ -428,8 +431,15 @@ static int dev_unload(struct drm_device *dev)
ret = plugin->unload(dev);
}
- drm_kms_helper_poll_fini(dev);
drm_vblank_cleanup(dev);
+ drm_kms_helper_poll_fini(dev);
+
+ omap_fbdev_free(dev);
+
+ omap_modeset_free(dev);
+
+ kfree(dev->dev_private);
+ dev->dev_private = NULL;
loaded = false;
diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h
index 3a64d5254ea..33125ea50c5 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -40,6 +40,7 @@ struct omap_drm_private {
};
struct drm_fb_helper * omap_fbdev_init(struct drm_device *dev);
+void omap_fbdev_free(struct drm_device *dev);
struct drm_crtc * omap_crtc_init(struct drm_device *dev,
struct omap_overlay *ovl, int id);
diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c
index 205bc32b914..627fcc4455c 100644
--- a/drivers/staging/omapdrm/omap_fbdev.c
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -277,3 +277,27 @@ fail:
}
return NULL;
}
+
+void omap_fbdev_free(struct drm_device *dev)
+{
+ struct omap_drm_private *priv = dev->dev_private;
+ struct drm_fb_helper *helper = priv->fbdev;
+ struct omap_fbdev *fbdev;
+ struct fb_info *fbi;
+
+ DBG();
+
+ fbi = helper->fbdev;
+
+ unregister_framebuffer(fbi);
+ framebuffer_release(fbi);
+
+ drm_fb_helper_fini(helper);
+
+ fbdev = to_omap_fbdev(priv->fbdev);
+
+ kfree(fbdev);
+
+ priv->fbdev = NULL;
+}
+