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

Commit 71c6efd9 authored by Orczykowski, Juergen's avatar Orczykowski, Juergen Committed by Linus Torvalds
Browse files

intelfb: fix ring space calculation



If there is less than RING_MIN_FREE available in the ring buffer,
dinfo->ring_space is set to a big value forcing wait_ring to return.

Fix by making ring space = 0 if ring space < RING_MIN_FREE.

Signed-off-by: default avatarDave Airlie <airlied@gmail.com>
Signed-off-by: default avatarAntonino Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 33a9f640
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo);
static void reset_state(struct intelfb_info *dinfo);
static void do_flush(struct intelfb_info *dinfo);

static  u32 get_ring_space(struct intelfb_info *dinfo)
{
	u32 ring_space;

	if (dinfo->ring_tail >= dinfo->ring_head)
		ring_space = dinfo->ring.size -
			(dinfo->ring_tail - dinfo->ring_head);
	else
		ring_space = dinfo->ring_head - dinfo->ring_tail;

	if (ring_space > RING_MIN_FREE)
		ring_space -= RING_MIN_FREE;
	else
		ring_space = 0;

	return ring_space;
}

static int
wait_ring(struct intelfb_info *dinfo, int n)
{
@@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n)
	end = jiffies + (HZ * 3);
	while (dinfo->ring_space < n) {
		dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
		if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
			dinfo->ring_space = dinfo->ring_head
				- (dinfo->ring_tail + RING_MIN_FREE);
		else
			dinfo->ring_space = (dinfo->ring.size +
					     dinfo->ring_head)
				- (dinfo->ring_tail + RING_MIN_FREE);
		dinfo->ring_space = get_ring_space(dinfo);

		if (dinfo->ring_head != last_head) {
			end = jiffies + (HZ * 3);
			last_head = dinfo->ring_head;
@@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo)

	dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
	dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
	if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
		dinfo->ring_space = dinfo->ring_head
			- (dinfo->ring_tail + RING_MIN_FREE);
	else
		dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
			- (dinfo->ring_tail + RING_MIN_FREE);
	dinfo->ring_space = get_ring_space(dinfo);
}

static void