diff options
author | Andy Walls <awalls@radix.net> | 2008-10-31 19:49:12 -0400 |
---|---|---|
committer | Andy Walls <awalls@radix.net> | 2008-10-31 19:49:12 -0400 |
commit | e983ee4b8803e5659b8f3e418169e5d8c019d230 (patch) | |
tree | 00c267682d0e50ddde92c72261a96b907535bef5 /linux/drivers/media/video/cx18/cx18-io.c | |
parent | 3abc5a28999dce72afa17a7a057122a088affef7 (diff) | |
download | mediapointer-dvb-s2-e983ee4b8803e5659b8f3e418169e5d8c019d230.tar.gz mediapointer-dvb-s2-e983ee4b8803e5659b8f3e418169e5d8c019d230.tar.bz2 |
cx18: Fix write retries for registers that always change - part 2.
From: Andy Walls <awalls@radix.net>
cx18: Fix write retries for registers that always change - part 2.
Some registers, especially interrupt related ones, will never read
back the value just written. Modified interrupt register readback
checks to make sure the intended effect was achieved.
Priority: high
Signed-off-by: Andy Walls <awalls@radix.net>
Diffstat (limited to 'linux/drivers/media/video/cx18/cx18-io.c')
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-io.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-io.c b/linux/drivers/media/video/cx18/cx18-io.c index 31be5e868..220fae8d4 100644 --- a/linux/drivers/media/video/cx18/cx18-io.c +++ b/linux/drivers/media/video/cx18/cx18-io.c @@ -88,6 +88,19 @@ void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) cx18_log_write_retries(cx, i, addr); } +void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, + u32 eval, u32 mask) +{ + int i; + eval &= mask; + for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { + cx18_writel_noretry(cx, val, addr); + if (eval == (cx18_readl_noretry(cx, addr) & mask)) + break; + } + cx18_log_write_retries(cx, i, addr); +} + void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) { int i; @@ -218,7 +231,7 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) { u32 r; - cx18_write_reg_noretry(cx, val, SW1_INT_STATUS); + cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val); r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); } @@ -233,7 +246,7 @@ void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) { u32 r; - cx18_write_reg_noretry(cx, val, SW2_INT_STATUS); + cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val); r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); } |