diff options
author | Kay, Allen M <allen.m.kay@intel.com> | 2012-01-26 13:25:53 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-02-14 11:45:02 -0500 |
commit | 26f41062f28de65e11d3cf353e52d0be73442be1 (patch) | |
tree | 55ff1002ff04ad6eb8efd8e60f8b60419bc16c64 /drivers/pci/pci.c | |
parent | 2debd9289997fc5d1c0043b41201a8b40d5e11d0 (diff) |
PCI: check for pci bar restore completion and retry
On some OEM systems, pci_restore_state() is called while FLR has not yet
completed. As a result, PCI BAR register restore is not successful. This fix
reads back the restored value and compares it with saved value and re-tries 10
times before giving up.
Signed-off-by: Jean Guyader <jean.guyader@eu.citrix.com>
Signed-off-by: Eric Chanudet <eric.chanudet@citrix.com>
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 053670e09e2b..9c89447e7b21 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -959,6 +959,7 @@ void pci_restore_state(struct pci_dev *dev) | |||
959 | { | 959 | { |
960 | int i; | 960 | int i; |
961 | u32 val; | 961 | u32 val; |
962 | int tries; | ||
962 | 963 | ||
963 | if (!dev->state_saved) | 964 | if (!dev->state_saved) |
964 | return; | 965 | return; |
@@ -973,12 +974,16 @@ void pci_restore_state(struct pci_dev *dev) | |||
973 | */ | 974 | */ |
974 | for (i = 15; i >= 0; i--) { | 975 | for (i = 15; i >= 0; i--) { |
975 | pci_read_config_dword(dev, i * 4, &val); | 976 | pci_read_config_dword(dev, i * 4, &val); |
976 | if (val != dev->saved_config_space[i]) { | 977 | tries = 10; |
978 | while (tries && val != dev->saved_config_space[i]) { | ||
977 | dev_dbg(&dev->dev, "restoring config " | 979 | dev_dbg(&dev->dev, "restoring config " |
978 | "space at offset %#x (was %#x, writing %#x)\n", | 980 | "space at offset %#x (was %#x, writing %#x)\n", |
979 | i, val, (int)dev->saved_config_space[i]); | 981 | i, val, (int)dev->saved_config_space[i]); |
980 | pci_write_config_dword(dev,i * 4, | 982 | pci_write_config_dword(dev,i * 4, |
981 | dev->saved_config_space[i]); | 983 | dev->saved_config_space[i]); |
984 | pci_read_config_dword(dev, i * 4, &val); | ||
985 | mdelay(10); | ||
986 | tries--; | ||
982 | } | 987 | } |
983 | } | 988 | } |
984 | pci_restore_pcix_state(dev); | 989 | pci_restore_pcix_state(dev); |