diff options
author | Andy Walls <awalls@radix.net> | 2008-09-28 21:46:02 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 09:37:14 -0200 |
commit | d267d85101c509020a12686b96cbd179deaf4ecd (patch) | |
tree | 1a016966d11efb400ca310cd5726478053cd00a0 /drivers/media/video/cx18/cx18-av-firmware.c | |
parent | 7f9876785276ac7f8606f8bf53a3dae4c10b8adb (diff) | |
download | lwn-d267d85101c509020a12686b96cbd179deaf4ecd.tar.gz lwn-d267d85101c509020a12686b96cbd179deaf4ecd.zip |
V4L/DVB (9110): cx18: Add default behavior of checking and retrying PCI MMIO accesses
cx18: Add default behavior of checking and retrying PCI MMIO accesses.
The concept of checking and retrying PCI MMIO accesses for better reliability
in older motherboards was suggested by Steve Toth <stoth@linuxtv.org>. This
change implements MMIO retries and the retry_mmio module parameter that is
enabled by default. Limited experiments have shown this is more reliable than
the mmio_ndelay parameter. mmio_ndelay has insignificant effect with retries
enabled.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-av-firmware.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-av-firmware.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index 0488b6297704..522a035b2e8f 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c @@ -50,7 +50,7 @@ int cx18_av_loadfw(struct cx18 *cx) cx18_av_write4(cx, 0x8100, 0x00010000); /* Put the 8051 in reset and enable firmware upload */ - cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000); + cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000); ptr = fw->data; size = fw->size; @@ -59,22 +59,28 @@ int cx18_av_loadfw(struct cx18 *cx) u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); u32 value = 0; int retries2; + int unrec_err = 0; - for (retries2 = 0; retries2 < 5; retries2++) { - cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); + for (retries2 = 0; retries2 < CX18_MAX_MMIO_RETRIES; + retries2++) { + cx18_av_write4_noretry(cx, CXADEC_DL_CTL, + dl_control); udelay(10); - value = cx18_av_read4(cx, CXADEC_DL_CTL); + value = cx18_av_read4_noretry(cx, + CXADEC_DL_CTL); if (value == dl_control) break; /* Check if we can correct the byte by changing the address. We can only write the lower address byte of the address. */ if ((value & 0x3F00) != (dl_control & 0x3F00)) { - retries2 = 5; + unrec_err = 1; break; } } - if (retries2 >= 5) + cx18_log_write_retries(cx, retries2, + cx->reg_mem + 0xc40000 + CXADEC_DL_CTL); + if (unrec_err || retries2 >= CX18_MAX_MMIO_RETRIES) break; } if (i == size) |