aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2007-08-09 01:41:16 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:04:44 -0400
commit276e49a01a7e6c4a7bfb78618cf2f5befbf9f5de (patch)
tree8397db6807a2311c423957165d650ba169dff263 /drivers
parentc471b331dda9fdfaf67832998d0b2c848777ab4a (diff)
V4L/DVB (5987): saa7146: clean-up irq processing
Interrupt processing fixed: First handle interrupt, then acknowledge it. Otherwise the same interrupt might occur twice. Cleaned-up i2c interrupt handler and i2c error messages. Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/common/saa7146_core.c31
-rw-r--r--drivers/media/common/saa7146_i2c.c21
2 files changed, 29 insertions, 23 deletions
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 12cda9eebd12..1c962a2b44df 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -248,10 +248,11 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt
248static irqreturn_t interrupt_hw(int irq, void *dev_id) 248static irqreturn_t interrupt_hw(int irq, void *dev_id)
249{ 249{
250 struct saa7146_dev *dev = dev_id; 250 struct saa7146_dev *dev = dev_id;
251 u32 isr = 0; 251 u32 isr;
252 u32 ack_isr;
252 253
253 /* read out the interrupt status register */ 254 /* read out the interrupt status register */
254 isr = saa7146_read(dev, ISR); 255 ack_isr = isr = saa7146_read(dev, ISR);
255 256
256 /* is this our interrupt? */ 257 /* is this our interrupt? */
257 if ( 0 == isr ) { 258 if ( 0 == isr ) {
@@ -259,8 +260,6 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
259 return IRQ_NONE; 260 return IRQ_NONE;
260 } 261 }
261 262
262 saa7146_write(dev, ISR, isr);
263
264 if( 0 != (dev->ext)) { 263 if( 0 != (dev->ext)) {
265 if( 0 != (dev->ext->irq_mask & isr )) { 264 if( 0 != (dev->ext->irq_mask & isr )) {
266 if( 0 != dev->ext->irq_func ) { 265 if( 0 != dev->ext->irq_func ) {
@@ -283,21 +282,16 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
283 isr &= ~MASK_28; 282 isr &= ~MASK_28;
284 } 283 }
285 if (0 != (isr & (MASK_16|MASK_17))) { 284 if (0 != (isr & (MASK_16|MASK_17))) {
286 u32 status = saa7146_read(dev, I2C_STATUS); 285 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
287 if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) { 286 /* only wake up if we expect something */
288 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); 287 if (0 != dev->i2c_op) {
289 /* only wake up if we expect something */ 288 dev->i2c_op = 0;
290 if( 0 != dev->i2c_op ) { 289 wake_up(&dev->i2c_wq);
291 u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;
292 u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;
293 DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));
294 dev->i2c_op = 0;
295 wake_up(&dev->i2c_wq);
296 } else {
297 DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
298 }
299 } else { 290 } else {
300 DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr)); 291 u32 psr = saa7146_read(dev, PSR);
292 u32 ssr = saa7146_read(dev, SSR);
293 printk(KERN_WARNING "%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
294 dev->name, isr, psr, ssr);
301 } 295 }
302 isr &= ~(MASK_16|MASK_17); 296 isr &= ~(MASK_16|MASK_17);
303 } 297 }
@@ -306,6 +300,7 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
306 ERR(("disabling interrupt source(s)!\n")); 300 ERR(("disabling interrupt source(s)!\n"));
307 SAA7146_IER_DISABLE(dev,isr); 301 SAA7146_IER_DISABLE(dev,isr);
308 } 302 }
303 saa7146_write(dev, ISR, ack_isr);
309 return IRQ_HANDLED; 304 return IRQ_HANDLED;
310} 305}
311 306
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index f823286341eb..7e7689afae62 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -202,7 +202,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
202 /* a signal arrived */ 202 /* a signal arrived */
203 return -ERESTARTSYS; 203 return -ERESTARTSYS;
204 204
205 printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n"); 205 printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n",
206 dev->name, __FUNCTION__);
206 return -EIO; 207 return -EIO;
207 } 208 }
208 status = saa7146_read(dev, I2C_STATUS); 209 status = saa7146_read(dev, I2C_STATUS);
@@ -219,7 +220,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
219 break; 220 break;
220 } 221 }
221 if (time_after(jiffies,timeout)) { 222 if (time_after(jiffies,timeout)) {
222 printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n"); 223 printk(KERN_WARNING "%s %s: timed out waiting for MC2\n",
224 dev->name, __FUNCTION__);
223 return -EIO; 225 return -EIO;
224 } 226 }
225 } 227 }
@@ -235,7 +237,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
235 /* this is normal when probing the bus 237 /* this is normal when probing the bus
236 * (no answer from nonexisistant device...) 238 * (no answer from nonexisistant device...)
237 */ 239 */
238 DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); 240 printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n",
241 dev->name, __FUNCTION__);
239 return -EIO; 242 return -EIO;
240 } 243 }
241 if (++trial < 50 && short_delay) 244 if (++trial < 50 && short_delay)
@@ -246,8 +249,16 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
246 } 249 }
247 250
248 /* give a detailed status report */ 251 /* give a detailed status report */
249 if ( 0 != (status & SAA7146_I2C_ERR)) { 252 if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
250 253 SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
254 SAA7146_I2C_AL | SAA7146_I2C_ERR |
255 SAA7146_I2C_BUSY)) ) {
256
257 if ( 0 == (status & SAA7146_I2C_ERR) ||
258 0 == (status & SAA7146_I2C_BUSY) ) {
259 /* it may take some time until ERR goes high - ignore */
260 DEB_I2C(("unexpected i2c status %04x\n", status));
261 }
251 if( 0 != (status & SAA7146_I2C_SPERR) ) { 262 if( 0 != (status & SAA7146_I2C_SPERR) ) {
252 DEB_I2C(("error due to invalid start/stop condition.\n")); 263 DEB_I2C(("error due to invalid start/stop condition.\n"));
253 } 264 }