aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrczykowski, Juergen <juergen.orczykowski@siemens.com>2007-05-08 03:37:25 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:26 -0400
commit71c6efd9930bd87249d007120425341d1293303d (patch)
tree43cdb8c00526f16ca5e2cbb99012277fbb1fe116
parent33a9f640a2511155517d316e696654b84dd48654 (diff)
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: Dave Airlie <airlied@gmail.com> Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/video/intelfb/intelfbhw.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index c1eb18bf0883..16bc8d75e36e 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo);
1428static void reset_state(struct intelfb_info *dinfo); 1428static void reset_state(struct intelfb_info *dinfo);
1429static void do_flush(struct intelfb_info *dinfo); 1429static void do_flush(struct intelfb_info *dinfo);
1430 1430
1431static u32 get_ring_space(struct intelfb_info *dinfo)
1432{
1433 u32 ring_space;
1434
1435 if (dinfo->ring_tail >= dinfo->ring_head)
1436 ring_space = dinfo->ring.size -
1437 (dinfo->ring_tail - dinfo->ring_head);
1438 else
1439 ring_space = dinfo->ring_head - dinfo->ring_tail;
1440
1441 if (ring_space > RING_MIN_FREE)
1442 ring_space -= RING_MIN_FREE;
1443 else
1444 ring_space = 0;
1445
1446 return ring_space;
1447}
1448
1431static int 1449static int
1432wait_ring(struct intelfb_info *dinfo, int n) 1450wait_ring(struct intelfb_info *dinfo, int n)
1433{ 1451{
@@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n)
1442 end = jiffies + (HZ * 3); 1460 end = jiffies + (HZ * 3);
1443 while (dinfo->ring_space < n) { 1461 while (dinfo->ring_space < n) {
1444 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1462 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1445 if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) 1463 dinfo->ring_space = get_ring_space(dinfo);
1446 dinfo->ring_space = dinfo->ring_head 1464
1447 - (dinfo->ring_tail + RING_MIN_FREE);
1448 else
1449 dinfo->ring_space = (dinfo->ring.size +
1450 dinfo->ring_head)
1451 - (dinfo->ring_tail + RING_MIN_FREE);
1452 if (dinfo->ring_head != last_head) { 1465 if (dinfo->ring_head != last_head) {
1453 end = jiffies + (HZ * 3); 1466 end = jiffies + (HZ * 3);
1454 last_head = dinfo->ring_head; 1467 last_head = dinfo->ring_head;
@@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo)
1513 1526
1514 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1527 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1515 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; 1528 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
1516 if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) 1529 dinfo->ring_space = get_ring_space(dinfo);
1517 dinfo->ring_space = dinfo->ring_head
1518 - (dinfo->ring_tail + RING_MIN_FREE);
1519 else
1520 dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
1521 - (dinfo->ring_tail + RING_MIN_FREE);
1522} 1530}
1523 1531
1524static void 1532static void