diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index f9e34c493cbbcb3764a7f584296ca5809cfa60a9..4299365590d89366adbb29bda7e30a4f835f8153 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -516,4 +516,7 @@ void ps3_sync_irq(int node);
 u32 ps3_get_hw_thread_id(int cpu);
 u64 ps3_get_spe_id(void *arg);
 
+/* mutex synchronizing GPU accesses and video mode changes */
+extern struct mutex ps3_gpu_mutex;
+
 #endif
diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h
index 5aa22cffdbd658d02c616ba822e3071ac642e3ac..cd24ac16660a2d595f7679694a7e800c92c2a7f3 100644
--- a/arch/powerpc/include/asm/ps3av.h
+++ b/arch/powerpc/include/asm/ps3av.h
@@ -740,8 +740,4 @@ extern int ps3av_audio_mute(int);
 extern int ps3av_audio_mute_analog(int);
 extern int ps3av_dev_open(void);
 extern int ps3av_dev_close(void);
-extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
-				    void *flip_data);
-extern void ps3av_flip_ctl(int on);
-
 #endif	/* _ASM_POWERPC_PS3AV_H_ */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 77bc330263c4e3063f6d6dd4686e9c83a532bc0d..bfc33fb2c7c42fac707577c19a59abe4931f1e3a 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -42,6 +42,10 @@
 #define DBG pr_debug
 #endif
 
+/* mutex synchronizing GPU accesses and video mode changes */
+DEFINE_MUTEX(ps3_gpu_mutex);
+EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
+
 #if !defined(CONFIG_SMP)
 static void smp_send_stop(void) {}
 #endif
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 06848b254d5752d3a5d40ad2a68b8c4bb686b01e..5324978b73fba2d8aeee419d0debd31c0428ee38 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -59,8 +59,6 @@ static struct ps3av {
 		struct ps3av_reply_hdr reply_hdr;
 		u8 raw[PS3AV_BUF_SIZE];
 	} recv_buf;
-	void (*flip_ctl)(int on, void *data);
-	void *flip_data;
 } *ps3av;
 
 /* color space */
@@ -939,24 +937,6 @@ int ps3av_audio_mute(int mute)
 
 EXPORT_SYMBOL_GPL(ps3av_audio_mute);
 
-void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
-			     void *flip_data)
-{
-	mutex_lock(&ps3av->mutex);
-	ps3av->flip_ctl = flip_ctl;
-	ps3av->flip_data = flip_data;
-	mutex_unlock(&ps3av->mutex);
-}
-EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl);
-
-void ps3av_flip_ctl(int on)
-{
-	mutex_lock(&ps3av->mutex);
-	if (ps3av->flip_ctl)
-		ps3av->flip_ctl(on, ps3av->flip_data);
-	mutex_unlock(&ps3av->mutex);
-}
-
 static int ps3av_probe(struct ps3_system_bus_device *dev)
 {
 	int res;
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index 11eb50318fec9ce093e6b9ef99e6fd858c4ead20..716596e8e5b0acdc26d92d607af85516897f932d 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -864,7 +864,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
 {
 	int res;
 
-	ps3av_flip_ctl(0);	/* flip off */
+	mutex_lock(&ps3_gpu_mutex);
 
 	/* avb packet */
 	res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb),
@@ -878,7 +878,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
 			 res);
 
       out:
-	ps3av_flip_ctl(1);	/* flip on */
+	mutex_unlock(&ps3_gpu_mutex);
 	return res;
 }
 
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 4b5d807719041e99aa7f1d70afb1b9a308c21fa6..bd3e39baf7d20fee65077f86d34cf4ef55788d2d 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -460,12 +460,16 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
 		line_length |= (u64)src_line_length << 32;
 
 	src_offset += GPU_FB_START;
+
+	mutex_lock(&ps3_gpu_mutex);
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
 					   dst_offset, GPU_IOIF + src_offset,
 					   L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
 					   (width << 16) | height,
 					   line_length);
+	mutex_unlock(&ps3_gpu_mutex);
+
 	if (status)
 		dev_err(dev,
 			"%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
@@ -784,15 +788,6 @@ static int ps3fb_wait_for_vsync(u32 crtc)
 	return 0;
 }
 
-static void ps3fb_flip_ctl(int on, void *data)
-{
-	struct ps3fb_priv *priv = data;
-	if (on)
-		atomic_dec_if_positive(&priv->ext_flip);
-	else
-		atomic_inc(&priv->ext_flip);
-}
-
 
     /*
      * ioctl
@@ -1228,7 +1223,6 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
 	}
 
 	ps3fb.task = task;
-	ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
 
 	return 0;
 
@@ -1258,10 +1252,9 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
 
 	dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
 
-	ps3fb_flip_ctl(0, &ps3fb);	/* flip off */
+	atomic_inc(&ps3fb.ext_flip);	/* flip off */
 	ps3fb.dinfo->irq.mask = 0;
 
-	ps3av_register_flip_ctl(NULL, NULL);
 	if (ps3fb.task) {
 		struct task_struct *task = ps3fb.task;
 		ps3fb.task = NULL;