diff options
author | Oliver Endriss <o.endriss@gmx.de> | 2007-08-09 01:41:16 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:04:44 -0400 |
commit | 276e49a01a7e6c4a7bfb78618cf2f5befbf9f5de (patch) | |
tree | 8397db6807a2311c423957165d650ba169dff263 /drivers/media/common | |
parent | c471b331dda9fdfaf67832998d0b2c848777ab4a (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/media/common')
-rw-r--r-- | drivers/media/common/saa7146_core.c | 31 | ||||
-rw-r--r-- | drivers/media/common/saa7146_i2c.c | 21 |
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 | |||
248 | static irqreturn_t interrupt_hw(int irq, void *dev_id) | 248 | static 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 | } |