From 01f9b946b0a6fac7e24b3fbe6d14f07d1935f6be Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 2 Apr 2007 10:44:35 -0300 Subject: pluto2: fix incorrect TSCR register setting From: Andreas Oberritter The ADEF bits in the TSCR register have different meanings in read and write mode. For this reason ADEF has to be reset on every read-modify-write operation. This patch introduces a special write function for this register, which takes care of it. Thanks to Holger Magnussen for pointing my nose at this problem. Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/pluto2/pluto2.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/dvb/pluto2/pluto2.c') diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index cb049d1a8..2fe1f0d18 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -149,6 +149,15 @@ static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits) writel(val, &pluto->io_mem[reg]); } +static void pluto_write_tscr(struct pluto *pluto, u32 val) +{ + /* set the number of packets */ + val &= ~TSCR_ADEF; + val |= TS_DMA_PACKETS / 2; + + pluto_writereg(pluto, REG_TSCR, val); +} + static void pluto_setsda(void *data, int state) { struct pluto *pluto = data; @@ -213,11 +222,11 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable) if (val & TSCR_RSTN) { val &= ~TSCR_RSTN; - pluto_writereg(pluto, REG_TSCR, val); + pluto_write_tscr(pluto, val); } if (reenable) { val |= TSCR_RSTN; - pluto_writereg(pluto, REG_TSCR, val); + pluto_write_tscr(pluto, val); } } @@ -343,7 +352,7 @@ static irqreturn_t pluto_irq(int irq, void *dev_id) } /* ACK the interrupt */ - pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK); + pluto_write_tscr(pluto, tscr | TSCR_IACK); return IRQ_HANDLED; } @@ -352,9 +361,6 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto) { u32 val = pluto_readreg(pluto, REG_TSCR); - /* set the number of packets */ - val &= ~TSCR_ADEF; - val |= TS_DMA_PACKETS / 2; /* disable AFUL and LOCK interrupts */ val |= (TSCR_MSKA | TSCR_MSKL); /* enable DMA and OVERFLOW interrupts */ @@ -362,7 +368,7 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto) /* clear pending interrupts */ val |= TSCR_IACK; - pluto_writereg(pluto, REG_TSCR, val); + pluto_write_tscr(pluto, val); } static void pluto_disable_irqs(struct pluto *pluto) @@ -374,7 +380,7 @@ static void pluto_disable_irqs(struct pluto *pluto) /* clear pending interrupts */ val |= TSCR_IACK; - pluto_writereg(pluto, REG_TSCR, val); + pluto_write_tscr(pluto, val); } static int __devinit pluto_hw_init(struct pluto *pluto) -- cgit v1.2.3 From 9262c54c1ac7fccca1b6aaa51ed2081ee2c1c0da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 1 May 2007 09:25:56 -0300 Subject: Workaround for bad hardare/firmware on some pluto2 devices From: holger@muscate-magnussen.de pluto2_driver: Workaround for pluto2 card reporting wrong number of received packets and flooding system with interrupts. This patch constitutes a workaround for a hardware/firmware problem of the pluto2-based card (e.g., Satelco EasyWatch). It can happen in rare cases that the card gets into a mode where it always reports back a number of received packets (nbpackets) which is larger than the maximum permissible number of packets (TS_DMA_PACKETS). The workaround that is already in the driver in function pluto_dma_end reports back zero received packets. In spite of the (in reality) zero received packets the card continues to generate interrupts at a very high rate, which can effectively stall the system. The patch resets the TS logic, which puts the card back into normal operations. Signed-off-by: Holger Magnussen Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/pluto2/pluto2.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'linux/drivers/media/dvb/pluto2/pluto2.c') diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index 2fe1f0d18..b104e63eb 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -293,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) * but no packets have been transfered. * [2] Sometimes (actually very often) NBPACKETS stays at zero * although one packet has been transfered. + * [3] Sometimes (actually rarely), the card gets into an erroneous + * mode where it continuously generates interrupts, claiming it + * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet + * has been transfered. Only a reset seems to solve this */ if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { unsigned int i = 0; while (pluto->dma_buf[i] == 0x47) i += 188; nbpackets = i / 188; + if (i == 0) { + pluto_reset_ts(pluto, 1); + dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n"); + } } dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); -- cgit v1.2.3