diff options
author | Andy Walls <awalls@radix.net> | 2008-09-28 20:46:02 -0400 |
---|---|---|
committer | Andy Walls <awalls@radix.net> | 2008-09-28 20:46:02 -0400 |
commit | ac5d49924a0ab6a492457817a7a08d952961ab67 (patch) | |
tree | cbb2d4779304eb8fd23de78809779bdafb0ebb56 /linux/drivers/media/video/cx18/cx18-av-firmware.c | |
parent | c20af2106a755d11b45e19ade56a98fa8bf6ca29 (diff) | |
download | mediapointer-dvb-s2-ac5d49924a0ab6a492457817a7a08d952961ab67.tar.gz mediapointer-dvb-s2-ac5d49924a0ab6a492457817a7a08d952961ab67.tar.bz2 |
cx18: Add default behavior of checking and retrying PCI MMIO accesses
From: Andy Walls <awalls@radix.net>
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.
Priority: high
Signed-off-by: Andy Walls <awalls@radix.net>
Diffstat (limited to 'linux/drivers/media/video/cx18/cx18-av-firmware.c')
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-av-firmware.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-av-firmware.c b/linux/drivers/media/video/cx18/cx18-av-firmware.c index 0488b6297..522a035b2 100644 --- a/linux/drivers/media/video/cx18/cx18-av-firmware.c +++ b/linux/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) |