diff options
author | Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> | 2007-05-02 08:48:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-04 20:59:08 -0400 |
commit | 1c0c8461191d6d74926397abe2aa5f7cc9fd5a67 (patch) | |
tree | 51d5e765aab9208b18c41467ec26e7779538a98a /drivers/video/ps3fb.c | |
parent | 254f9c5cd2d3b41e64f59df816630f7ca5548a8a (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.c | 41 |
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 | }; |
143 | static struct ps3fb_priv ps3fb; | 146 | static struct ps3fb_priv ps3fb; |
144 | 147 | ||
@@ -805,11 +808,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
805 | 808 | ||
806 | static int ps3fbd(void *arg) | 809 | static 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 | ||
1073 | err_unregister_framebuffer: | ||
1074 | unregister_framebuffer(info); | ||
1056 | err_fb_dealloc: | 1075 | err_fb_dealloc: |
1057 | fb_dealloc_cmap(&info->cmap); | 1076 | fb_dealloc_cmap(&info->cmap); |
1058 | err_framebuffer_release: | 1077 | err_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 | ||