/* 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)
 {
 
 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,
 {
        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;
 }
 
 
 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;
         * 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;
 }