aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2007-10-30 23:39:48 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-11-04 18:41:23 -0500
commit26ac14e24f3c84ed7a619639c2027f03b52bd64b (patch)
treedf6539dae9ace10b8391c22a52b5d8a5a8faa566 /drivers/media/common
parentcb20630cefb382a360fcc9ea054e597596153f42 (diff)
V4L/DVB (6495): saa7146: saa7146_wait_for_debi_done fixes
Two fixes for the 'saa7146_wait_for_debi_done' code: (a) Timeout did not work when the routine was called with interrupts disabled. (b) Reduce PCI I/O load caused by saa7146_wait_for_debi_done. Seems to be very important on fast machines! Based on code posted by Hartmut Birr @vdr-portal. Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/saa7146_core.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index cb034ead95ab..7d04a6fd1acb 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -59,43 +59,89 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
59} 59}
60 60
61/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */ 61/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
62int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop) 62static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
63 unsigned long us1, unsigned long us2)
63{ 64{
64 unsigned long start; 65 unsigned long timeout;
65 int err; 66 int err;
66 67
67 /* wait for registers to be programmed */ 68 /* wait for registers to be programmed */
68 start = jiffies; 69 timeout = jiffies + usecs_to_jiffies(us1);
69 while (1) { 70 while (1) {
70 err = time_after(jiffies, start + HZ/20); 71 err = time_after(jiffies, timeout);
71 if (saa7146_read(dev, MC2) & 2) 72 if (saa7146_read(dev, MC2) & 2)
72 break; 73 break;
73 if (err) { 74 if (err) {
74 DEB_S(("timed out while waiting for registers getting programmed\n")); 75 printk(KERN_ERR "%s: %s timed out while waiting for "
76 "registers getting programmed\n",
77 dev->name, __FUNCTION__);
75 return -ETIMEDOUT; 78 return -ETIMEDOUT;
76 } 79 }
77 if (nobusyloop) 80 msleep(1);
78 msleep(1);
79 } 81 }
80 82
81 /* wait for transfer to complete */ 83 /* wait for transfer to complete */
82 start = jiffies; 84 timeout = jiffies + usecs_to_jiffies(us2);
83 while (1) { 85 while (1) {
84 err = time_after(jiffies, start + HZ/4); 86 err = time_after(jiffies, timeout);
85 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) 87 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
86 break; 88 break;
87 saa7146_read(dev, MC2); 89 saa7146_read(dev, MC2);
88 if (err) { 90 if (err) {
89 DEB_S(("timed out while waiting for transfer completion\n")); 91 DEB_S(("%s: %s timed out while waiting for transfer "
92 "completion\n", dev->name, __FUNCTION__));
90 return -ETIMEDOUT; 93 return -ETIMEDOUT;
91 } 94 }
92 if (nobusyloop) 95 msleep(1);
93 msleep(1);
94 } 96 }
95 97
96 return 0; 98 return 0;
97} 99}
98 100
101static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
102 unsigned long us1, unsigned long us2)
103{
104 unsigned long loops;
105
106 /* wait for registers to be programmed */
107 loops = us1;
108 while (1) {
109 if (saa7146_read(dev, MC2) & 2)
110 break;
111 if (!loops--) {
112 printk(KERN_ERR "%s: %s timed out while waiting for "
113 "registers getting programmed\n",
114 dev->name, __FUNCTION__);
115 return -ETIMEDOUT;
116 }
117 udelay(1);
118 }
119
120 /* wait for transfer to complete */
121 loops = us2 / 5;
122 while (1) {
123 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
124 break;
125 saa7146_read(dev, MC2);
126 if (!loops--) {
127 DEB_S(("%s: %s timed out while waiting for transfer "
128 "completion\n", dev->name, __FUNCTION__));
129 return -ETIMEDOUT;
130 }
131 udelay(5);
132 }
133
134 return 0;
135}
136
137int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
138{
139 if (nobusyloop)
140 return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
141 else
142 return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
143}
144
99/**************************************************************************** 145/****************************************************************************
100 * general helper functions 146 * general helper functions
101 ****************************************************************************/ 147 ****************************************************************************/