Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c0c8461 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Linus Torvalds
Browse files

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: default avatarGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 254f9c5c
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -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,12 +808,15 @@ 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;