aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/ps3fb.c
diff options
context:
space:
mode:
authorGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>2007-05-02 08:48:31 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 20:59:08 -0400
commit1c0c8461191d6d74926397abe2aa5f7cc9fd5a67 (patch)
tree51d5e765aab9208b18c41467ec26e7779538a98a /drivers/video/ps3fb.c
parent254f9c5cd2d3b41e64f59df816630f7ca5548a8a (diff)
ps3fb: thread updates
ps3fb: Replace the kernel_thread and the semaphore by a proper kthread, which is simply woken up when the screen must be updated Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/ps3fb.c')
-rw-r--r--drivers/video/ps3fb.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 81e43cda7d8b..815b3cc78fd3 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,6 +32,8 @@
32#include <linux/ioctl.h> 32#include <linux/ioctl.h>
33#include <linux/notifier.h> 33#include <linux/notifier.h>
34#include <linux/reboot.h> 34#include <linux/reboot.h>
35#include <linux/kthread.h>
36#include <linux/freezer.h>
35 37
36#include <asm/uaccess.h> 38#include <asm/uaccess.h>
37#include <linux/fb.h> 39#include <linux/fb.h>
@@ -129,7 +131,6 @@ struct ps3fb_priv {
129 u64 context_handle, memory_handle; 131 u64 context_handle, memory_handle;
130 void *xdr_ea; 132 void *xdr_ea;
131 struct gpu_driver_info *dinfo; 133 struct gpu_driver_info *dinfo;
132 struct semaphore sem;
133 u32 res_index; 134 u32 res_index;
134 135
135 u64 vblank_count; /* frame count */ 136 u64 vblank_count; /* frame count */
@@ -139,6 +140,8 @@ struct ps3fb_priv {
139 atomic_t ext_flip; /* on/off flip with vsync */ 140 atomic_t ext_flip; /* on/off flip with vsync */
140 atomic_t f_count; /* fb_open count */ 141 atomic_t f_count; /* fb_open count */
141 int is_blanked; 142 int is_blanked;
143 int is_kicked;
144 struct task_struct *task;
142}; 145};
143static struct ps3fb_priv ps3fb; 146static struct ps3fb_priv ps3fb;
144 147
@@ -805,11 +808,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
805 808
806static int ps3fbd(void *arg) 809static int ps3fbd(void *arg)
807{ 810{
808 daemonize("ps3fbd"); 811 while (!kthread_should_stop()) {
809 for (;;) { 812 try_to_freeze();
810 down(&ps3fb.sem); 813 set_current_state(TASK_INTERRUPTIBLE);
811 if (atomic_read(&ps3fb.ext_flip) == 0) 814 if (ps3fb.is_kicked) {
815 ps3fb.is_kicked = 0;
812 ps3fb_sync(0); /* single buffer */ 816 ps3fb_sync(0); /* single buffer */
817 }
818 schedule();
813 } 819 }
814 return 0; 820 return 0;
815} 821}
@@ -830,8 +836,11 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
830 if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) { 836 if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
831 /* VSYNC */ 837 /* VSYNC */
832 ps3fb.vblank_count = head->vblank_count; 838 ps3fb.vblank_count = head->vblank_count;
833 if (!ps3fb.is_blanked) 839 if (ps3fb.task && !ps3fb.is_blanked &&
834 up(&ps3fb.sem); 840 !atomic_read(&ps3fb.ext_flip)) {
841 ps3fb.is_kicked = 1;
842 wake_up_process(ps3fb.task);
843 }
835 wake_up_interruptible(&ps3fb.wait_vsync); 844 wake_up_interruptible(&ps3fb.wait_vsync);
836 } 845 }
837 846
@@ -968,6 +977,7 @@ static int __init ps3fb_probe(struct platform_device *dev)
968 u64 xdr_lpar; 977 u64 xdr_lpar;
969 int status; 978 int status;
970 unsigned long offset; 979 unsigned long offset;
980 struct task_struct *task;
971 981
972 /* get gpu context handle */ 982 /* get gpu context handle */
973 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0, 983 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
@@ -1050,9 +1060,18 @@ static int __init ps3fb_probe(struct platform_device *dev)
1050 "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n", 1060 "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
1051 info->node, ps3fb_videomemory.size >> 10); 1061 info->node, ps3fb_videomemory.size >> 10);
1052 1062
1053 kernel_thread(ps3fbd, info, CLONE_KERNEL); 1063 task = kthread_run(ps3fbd, info, "ps3fbd");
1064 if (IS_ERR(task)) {
1065 retval = PTR_ERR(task);
1066 goto err_unregister_framebuffer;
1067 }
1068
1069 ps3fb.task = task;
1070
1054 return 0; 1071 return 0;
1055 1072
1073err_unregister_framebuffer:
1074 unregister_framebuffer(info);
1056err_fb_dealloc: 1075err_fb_dealloc:
1057 fb_dealloc_cmap(&info->cmap); 1076 fb_dealloc_cmap(&info->cmap);
1058err_framebuffer_release: 1077err_framebuffer_release:
@@ -1083,6 +1102,11 @@ void ps3fb_cleanup(void)
1083{ 1102{
1084 int status; 1103 int status;
1085 1104
1105 if (ps3fb.task) {
1106 struct task_struct *task = ps3fb.task;
1107 ps3fb.task = NULL;
1108 kthread_stop(task);
1109 }
1086 if (ps3fb.irq_no) { 1110 if (ps3fb.irq_no) {
1087 free_irq(ps3fb.irq_no, ps3fb.dev); 1111 free_irq(ps3fb.irq_no, ps3fb.dev);
1088 ps3_free_irq(ps3fb.irq_no); 1112 ps3_free_irq(ps3fb.irq_no);
@@ -1195,7 +1219,6 @@ static int __init ps3fb_init(void)
1195 1219
1196 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ 1220 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
1197 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1221 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1198 init_MUTEX(&ps3fb.sem);
1199 init_waitqueue_head(&ps3fb.wait_vsync); 1222 init_waitqueue_head(&ps3fb.wait_vsync);
1200 ps3fb.num_frames = 1; 1223 ps3fb.num_frames = 1;
1201 1224