Commit 276e49a01a7e6c4a7bfb78618cf2f5befbf9f5de
Committed by
Mauro Carvalho Chehab
1 parent
c471b331dd
Exists in
master
and in
7 other branches
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>
Showing 2 changed files with 29 additions and 23 deletions Side-by-side Diff
drivers/media/common/saa7146_core.c
... | ... | @@ -248,10 +248,11 @@ |
248 | 248 | static irqreturn_t interrupt_hw(int irq, void *dev_id) |
249 | 249 | { |
250 | 250 | struct saa7146_dev *dev = dev_id; |
251 | - u32 isr = 0; | |
251 | + u32 isr; | |
252 | + u32 ack_isr; | |
252 | 253 | |
253 | 254 | /* read out the interrupt status register */ |
254 | - isr = saa7146_read(dev, ISR); | |
255 | + ack_isr = isr = saa7146_read(dev, ISR); | |
255 | 256 | |
256 | 257 | /* is this our interrupt? */ |
257 | 258 | if ( 0 == isr ) { |
... | ... | @@ -259,8 +260,6 @@ |
259 | 260 | return IRQ_NONE; |
260 | 261 | } |
261 | 262 | |
262 | - saa7146_write(dev, ISR, isr); | |
263 | - | |
264 | 263 | if( 0 != (dev->ext)) { |
265 | 264 | if( 0 != (dev->ext->irq_mask & isr )) { |
266 | 265 | if( 0 != dev->ext->irq_func ) { |
267 | 266 | |
... | ... | @@ -283,21 +282,16 @@ |
283 | 282 | isr &= ~MASK_28; |
284 | 283 | } |
285 | 284 | if (0 != (isr & (MASK_16|MASK_17))) { |
286 | - u32 status = saa7146_read(dev, I2C_STATUS); | |
287 | - if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) { | |
288 | - SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); | |
289 | - /* only wake up if we expect something */ | |
290 | - if( 0 != dev->i2c_op ) { | |
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 | - } | |
285 | + SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); | |
286 | + /* only wake up if we expect something */ | |
287 | + if (0 != dev->i2c_op) { | |
288 | + dev->i2c_op = 0; | |
289 | + wake_up(&dev->i2c_wq); | |
299 | 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 | 296 | isr &= ~(MASK_16|MASK_17); |
303 | 297 | } |
... | ... | @@ -306,6 +300,7 @@ |
306 | 300 | ERR(("disabling interrupt source(s)!\n")); |
307 | 301 | SAA7146_IER_DISABLE(dev,isr); |
308 | 302 | } |
303 | + saa7146_write(dev, ISR, ack_isr); | |
309 | 304 | return IRQ_HANDLED; |
310 | 305 | } |
311 | 306 |
drivers/media/common/saa7146_i2c.c
... | ... | @@ -202,7 +202,8 @@ |
202 | 202 | /* a signal arrived */ |
203 | 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 | 207 | return -EIO; |
207 | 208 | } |
208 | 209 | status = saa7146_read(dev, I2C_STATUS); |
... | ... | @@ -219,7 +220,8 @@ |
219 | 220 | break; |
220 | 221 | } |
221 | 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 | 225 | return -EIO; |
224 | 226 | } |
225 | 227 | } |
... | ... | @@ -235,7 +237,8 @@ |
235 | 237 | /* this is normal when probing the bus |
236 | 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 | 242 | return -EIO; |
240 | 243 | } |
241 | 244 | if (++trial < 50 && short_delay) |
242 | 245 | |
... | ... | @@ -246,8 +249,16 @@ |
246 | 249 | } |
247 | 250 | |
248 | 251 | /* give a detailed status report */ |
249 | - if ( 0 != (status & SAA7146_I2C_ERR)) { | |
252 | + if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR | | |
253 | + SAA7146_I2C_DTERR | SAA7146_I2C_DRERR | | |
254 | + SAA7146_I2C_AL | SAA7146_I2C_ERR | | |
255 | + SAA7146_I2C_BUSY)) ) { | |
250 | 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 | 262 | if( 0 != (status & SAA7146_I2C_SPERR) ) { |
252 | 263 | DEB_I2C(("error due to invalid start/stop condition.\n")); |
253 | 264 | } |