Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1c0c8461191d6d74926397abe2aa5f7cc9fd5a67
Commit:     1c0c8461191d6d74926397abe2aa5f7cc9fd5a67
Parent:     254f9c5cd2d3b41e64f59df816630f7ca5548a8a
Author:     Geert Uytterhoeven <[EMAIL PROTECTED]>
AuthorDate: Wed May 2 14:48:31 2007 +0200
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri May 4 17:59:08 2007 -0700

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 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 81e43cd..815b3cc 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,6 +32,8 @@
 #include <linux/ioctl.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 #include <linux/fb.h>
@@ -129,7 +131,6 @@ struct ps3fb_priv {
        u64 context_handle, memory_handle;
        void *xdr_ea;
        struct gpu_driver_info *dinfo;
-       struct semaphore sem;
        u32 res_index;
 
        u64 vblank_count;       /* frame count */
@@ -139,6 +140,8 @@ struct ps3fb_priv {
        atomic_t ext_flip;      /* on/off flip with vsync */
        atomic_t f_count;       /* fb_open count */
        int is_blanked;
+       int is_kicked;
+       struct task_struct *task;
 };
 static struct ps3fb_priv ps3fb;
 
@@ -805,11 +808,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int 
cmd,
 
 static int ps3fbd(void *arg)
 {
-       daemonize("ps3fbd");
-       for (;;) {
-               down(&ps3fb.sem);
-               if (atomic_read(&ps3fb.ext_flip) == 0)
+       while (!kthread_should_stop()) {
+               try_to_freeze();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (ps3fb.is_kicked) {
+                       ps3fb.is_kicked = 0;
                        ps3fb_sync(0);  /* single buffer */
+               }
+               schedule();
        }
        return 0;
 }
@@ -830,8 +836,11 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void 
*ptr)
        if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
                /* VSYNC */
                ps3fb.vblank_count = head->vblank_count;
-               if (!ps3fb.is_blanked)
-                       up(&ps3fb.sem);
+               if (ps3fb.task && !ps3fb.is_blanked &&
+                   !atomic_read(&ps3fb.ext_flip)) {
+                       ps3fb.is_kicked = 1;
+                       wake_up_process(ps3fb.task);
+               }
                wake_up_interruptible(&ps3fb.wait_vsync);
        }
 
@@ -968,6 +977,7 @@ static int __init ps3fb_probe(struct platform_device *dev)
        u64 xdr_lpar;
        int status;
        unsigned long offset;
+       struct task_struct *task;
 
        /* get gpu context handle */
        status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
@@ -1050,9 +1060,18 @@ static int __init ps3fb_probe(struct platform_device 
*dev)
               "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
               info->node, ps3fb_videomemory.size >> 10);
 
-       kernel_thread(ps3fbd, info, CLONE_KERNEL);
+       task = kthread_run(ps3fbd, info, "ps3fbd");
+       if (IS_ERR(task)) {
+               retval = PTR_ERR(task);
+               goto err_unregister_framebuffer;
+       }
+
+       ps3fb.task = task;
+
        return 0;
 
+err_unregister_framebuffer:
+       unregister_framebuffer(info);
 err_fb_dealloc:
        fb_dealloc_cmap(&info->cmap);
 err_framebuffer_release:
@@ -1083,6 +1102,11 @@ void ps3fb_cleanup(void)
 {
        int status;
 
+       if (ps3fb.task) {
+               struct task_struct *task = ps3fb.task;
+               ps3fb.task = NULL;
+               kthread_stop(task);
+       }
        if (ps3fb.irq_no) {
                free_irq(ps3fb.irq_no, ps3fb.dev);
                ps3_free_irq(ps3fb.irq_no);
@@ -1195,7 +1219,6 @@ static int __init ps3fb_init(void)
 
        atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
        atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
-       init_MUTEX(&ps3fb.sem);
        init_waitqueue_head(&ps3fb.wait_vsync);
        ps3fb.num_frames = 1;
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to