diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index b5a542fbd8187b97006c800e902ca13921b16701..d9424bee04574f29f07238d0711447778db5471b 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -97,6 +97,8 @@ static struct {
 
 /* protects dss_data */
 static spinlock_t data_lock;
+/* lock for blocking functions */
+static DEFINE_MUTEX(apply_lock);
 
 static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
 {
@@ -639,14 +641,22 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 
 void dss_mgr_enable(struct omap_overlay_manager *mgr)
 {
+	mutex_lock(&apply_lock);
+
 	dispc_mgr_enable(mgr->id, true);
 	mgr->enabled = true;
+
+	mutex_unlock(&apply_lock);
 }
 
 void dss_mgr_disable(struct omap_overlay_manager *mgr)
 {
+	mutex_lock(&apply_lock);
+
 	dispc_mgr_enable(mgr->id, false);
 	mgr->enabled = false;
+
+	mutex_unlock(&apply_lock);
 }
 
 int dss_mgr_set_info(struct omap_overlay_manager *mgr,
@@ -669,44 +679,65 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 {
 	int r;
 
+	mutex_lock(&apply_lock);
+
 	if (dssdev->manager) {
 		DSSERR("display '%s' already has a manager '%s'\n",
 			       dssdev->name, dssdev->manager->name);
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	if ((mgr->supported_displays & dssdev->type) == 0) {
 		DSSERR("display '%s' does not support manager '%s'\n",
 			       dssdev->name, mgr->name);
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	dssdev->manager = mgr;
 	mgr->device = dssdev;
 	mgr->device_changed = true;
 
+	mutex_unlock(&apply_lock);
+
 	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
 }
 
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
 {
+	int r;
+
+	mutex_lock(&apply_lock);
+
 	if (!mgr->device) {
 		DSSERR("failed to unset display, display not set.\n");
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	/*
 	 * Don't allow currently enabled displays to have the overlay manager
 	 * pulled out from underneath them
 	 */
-	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
-		return -EINVAL;
+	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
 
 	mgr->device->manager = NULL;
 	mgr->device = NULL;
 	mgr->device_changed = true;
 
+	mutex_unlock(&apply_lock);
+
 	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
 }
 
 
@@ -729,18 +760,24 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
 int dss_ovl_set_manager(struct omap_overlay *ovl,
 		struct omap_overlay_manager *mgr)
 {
+	int r;
+
 	if (!mgr)
 		return -EINVAL;
 
+	mutex_lock(&apply_lock);
+
 	if (ovl->manager) {
 		DSSERR("overlay '%s' already has a manager '%s'\n",
 				ovl->name, ovl->manager->name);
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	if (ovl->info.enabled) {
 		DSSERR("overlay has to be disabled to change the manager\n");
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	ovl->manager = mgr;
@@ -760,25 +797,41 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
 	 * the overlay, but before moving the overlay to TV.
 	 */
 
+	mutex_unlock(&apply_lock);
+
 	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
 }
 
 int dss_ovl_unset_manager(struct omap_overlay *ovl)
 {
+	int r;
+
+	mutex_lock(&apply_lock);
+
 	if (!ovl->manager) {
 		DSSERR("failed to detach overlay: manager not set\n");
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	if (ovl->info.enabled) {
 		DSSERR("overlay has to be disabled to unset the manager\n");
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	ovl->manager = NULL;
 	list_del(&ovl->list);
 	ovl->manager_changed = true;
 
+	mutex_unlock(&apply_lock);
+
 	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
 }