From 1c0c8461191d6d74926397abe2aa5f7cc9fd5a67 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 2 May 2007 14:48:31 +0200 Subject: 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 Signed-off-by: Linus Torvalds --- drivers/video/ps3fb.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'drivers/video/ps3fb.c') 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 @@ #include #include #include +#include +#include #include #include @@ -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; -- cgit v1.2.3 From eca28743b74736456bd75e0dabeb7d2df09fc03e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 2 May 2007 14:48:32 +0200 Subject: ps3fb: atomic fixes ps3fb: Use atomic_dec_if_positive() instead of bogus atomic_read()/atomic_dec() combinations Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- drivers/video/ps3fb.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/video/ps3fb.c') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 815b3cc78fd3..dd6dd6e222d7 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -680,13 +680,10 @@ EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync); void ps3fb_flip_ctl(int on) { - if (on) { - if (atomic_read(&ps3fb.ext_flip) > 0) { - atomic_dec(&ps3fb.ext_flip); - } - } else { + if (on) + atomic_dec_if_positive(&ps3fb.ext_flip); + else atomic_inc(&ps3fb.ext_flip); - } } EXPORT_SYMBOL_GPL(ps3fb_flip_ctl); @@ -786,8 +783,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, case PS3FB_IOCTL_OFF: DPRINTK("PS3FB_IOCTL_OFF:\n"); - if (atomic_read(&ps3fb.ext_flip) > 0) - atomic_dec(&ps3fb.ext_flip); + atomic_dec_if_positive(&ps3fb.ext_flip); retval = 0; break; -- cgit v1.2.3 From bd685ac8e78b9bfd4a0145be22a7ff11ab11adef Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 2 May 2007 14:48:34 +0200 Subject: ps3fb: kill superfluous zero initializations ps3fb: kill superfluous zero initializations Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- drivers/video/ps3fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video/ps3fb.c') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index dd6dd6e222d7..f7f228d1c2d9 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -297,10 +297,10 @@ static const struct fb_videomode ps3fb_modedb[] = { #define VP_OFF(i) (WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP) #define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET) -static int ps3fb_mode = 0; +static int ps3fb_mode; module_param(ps3fb_mode, bool, 0); -static char *mode_option __initdata = NULL; +static char *mode_option __initdata; static int ps3fb_get_res_table(u32 xres, u32 yres) -- cgit v1.2.3 From 640729014e073e6e2de1f513b2856b81aa7d84e9 Mon Sep 17 00:00:00 2001 From: Masashi Kimoto Date: Wed, 2 May 2007 14:48:36 +0200 Subject: ps3: Make `ps3videomode -v 0 (auto mode) work again ps3: Make `ps3videomode -v 0' (auto mode) work again Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- drivers/ps3/ps3av.c | 7 +++++++ drivers/video/ps3fb.c | 5 +++++ include/asm-powerpc/ps3av.h | 1 + 3 files changed, 13 insertions(+) (limited to 'drivers/video/ps3fb.c') diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 1a56d390fcd9..5a418b1b1659 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c @@ -744,6 +744,13 @@ int ps3av_set_video_mode(u32 id, int boot) EXPORT_SYMBOL_GPL(ps3av_set_video_mode); +int ps3av_get_auto_mode(int boot) +{ + return ps3av_auto_videomode(&ps3av.av_hw_conf, boot); +} + +EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); + int ps3av_set_mode(u32 id, int boot) { int res; diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index f7f228d1c2d9..9fe64829aa81 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -732,6 +732,11 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, if (copy_from_user(&val, argp, sizeof(val))) break; + if (!(val & PS3AV_MODE_MASK)) { + u32 id = ps3av_get_auto_mode(0); + if (id > 0) + val = (val & ~PS3AV_MODE_MASK) | id; + } DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val); retval = -EINVAL; old_mode = ps3fb_mode; diff --git a/include/asm-powerpc/ps3av.h b/include/asm-powerpc/ps3av.h index 1366fc5b452d..9efc40f1c778 100644 --- a/include/asm-powerpc/ps3av.h +++ b/include/asm-powerpc/ps3av.h @@ -706,6 +706,7 @@ extern int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf, extern int ps3av_set_video_mode(u32, int); extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); +extern int ps3av_get_auto_mode(int); extern int ps3av_set_mode(u32, int); extern int ps3av_get_mode(void); extern int ps3av_get_scanmode(int); -- cgit v1.2.3 From d778c9a400e569029c8a48bc898c70780d6d2c1c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 2 May 2007 14:48:37 +0200 Subject: ps3fb: Use __func__ instead of __FUNCTION__ ps3fb: Replace GNU extension `__FUNCTION__' by C99 `__func__' Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- drivers/video/ps3fb.c | 54 ++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'drivers/video/ps3fb.c') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 9fe64829aa81..07d1979bc23e 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -47,7 +47,7 @@ #include #ifdef PS3FB_DEBUG -#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args) +#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args) #else #define DPRINTK(fmt, args...) #endif @@ -396,7 +396,7 @@ static int ps3fb_sync(u32 frame) if (frame > ps3fb.num_frames - 1) { printk(KERN_WARNING "%s: invalid frame number (%u)\n", - __FUNCTION__, frame); + __func__, frame); return -EINVAL; } offset = xres * yres * BPP * frame; @@ -409,23 +409,26 @@ static int ps3fb_sync(u32 frame) (xres << 16) | yres, xres * BPP); /* line_length */ if (status) - printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", - __FUNCTION__, status); + printk(KERN_ERR + "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", + __func__, status); #ifdef HEAD_A status = lv1_gpu_context_attribute(ps3fb.context_handle, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, offset, 0, 0); if (status) - printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n", - __FUNCTION__, status); + printk(KERN_ERR + "%s: lv1_gpu_context_attribute FLIP failed: %d\n", + __func__, status); #endif #ifdef HEAD_B status = lv1_gpu_context_attribute(ps3fb.context_handle, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, offset, 0, 0); if (status) - printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n", - __FUNCTION__, status); + printk(KERN_ERR + "%s: lv1_gpu_context_attribute FLIP failed: %d\n", + __func__, status); #endif return 0; } @@ -634,7 +637,7 @@ static int ps3fb_blank(int blank, struct fb_info *info) { int retval; - DPRINTK("%s: blank:%d\n", __FUNCTION__, blank); + DPRINTK("%s: blank:%d\n", __func__, blank); switch (blank) { case FB_BLANK_POWERDOWN: case FB_BLANK_HSYNC_SUSPEND: @@ -830,7 +833,7 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr) status = lv1_gpu_context_intr(ps3fb.context_handle, &v1); if (status) { printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n", - __FUNCTION__, status); + __func__, status); return IRQ_NONE; } @@ -889,7 +892,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev) dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000); if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) { - printk(KERN_ERR "%s: version_driver err:%x\n", __FUNCTION__, + printk(KERN_ERR "%s: version_driver err:%x\n", __func__, dinfo->version_driver); return -EINVAL; } @@ -898,7 +901,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev) error = ps3_alloc_irq(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, &ps3fb.irq_no); if (error) { - printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __FUNCTION__, + printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__, error); return error; } @@ -906,7 +909,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev) error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, "ps3fb vsync", ps3fb.dev); if (error) { - printk(KERN_ERR "%s: request_irq failed %d\n", __FUNCTION__, + printk(KERN_ERR "%s: request_irq failed %d\n", __func__, error); ps3_free_irq(ps3fb.irq_no); return error; @@ -925,7 +928,7 @@ static int ps3fb_xdr_settings(u64 xdr_lpar) xdr_lpar, ps3fb_videomemory.size, 0); if (status) { printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n", - __FUNCTION__, status); + __func__, status); return -ENXIO; } DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n", @@ -937,8 +940,9 @@ static int ps3fb_xdr_settings(u64 xdr_lpar) xdr_lpar, ps3fb_videomemory.size, GPU_IOIF, 0); if (status) { - printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", - __FUNCTION__, status); + printk(KERN_ERR + "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", + __func__, status); return -ENXIO; } return 0; @@ -985,7 +989,7 @@ static int __init ps3fb_probe(struct platform_device *dev) &ps3fb.memory_handle, &ddr_lpar); if (status) { printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n", - __FUNCTION__, status); + __func__, status); goto err; } DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar); @@ -996,14 +1000,14 @@ static int __init ps3fb_probe(struct platform_device *dev) &lpar_reports, &lpar_reports_size); if (status) { printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n", - __FUNCTION__, status); + __func__, status); goto err_gpu_memory_free; } /* vsync interrupt */ ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024); if (!ps3fb.dinfo) { - printk(KERN_ERR "%s: ioremap failed\n", __FUNCTION__); + printk(KERN_ERR "%s: ioremap failed\n", __func__); goto err_gpu_context_free; } @@ -1162,8 +1166,9 @@ int ps3fb_set_sync(void) L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); if (status) { - printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n", - __FUNCTION__, status); + printk(KERN_ERR + "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n", + __func__, status); return -1; } #endif @@ -1173,8 +1178,9 @@ int ps3fb_set_sync(void) 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); if (status) { - printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n", - __FUNCTION__, status); + printk(KERN_ERR + "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n", + __func__, status); return -1; } #endif @@ -1199,7 +1205,7 @@ static int __init ps3fb_init(void) error = ps3av_dev_open(); if (error) { - printk(KERN_ERR "%s: ps3av_dev_open failed\n", __FUNCTION__); + printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__); goto err; } -- cgit v1.2.3