aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-04-25 06:24:16 -0400
committerIngo Molnar <mingo@kernel.org>2012-04-25 06:24:16 -0400
commitcd32b1616bc79b2f2ce1b1c6164beecfecc2259c (patch)
tree2e91c49b5c2bd927b9b74b7414dbb6839af601e1 /drivers/pci/pci.c
parent89b8835ec865dddd6673a8dd7003581bf2377176 (diff)
parenta720b2dd2470a52345df11dca8d6c1466599f812 (diff)
Merge tag 'l3-fix-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp into x86/urgent
A small L3 cache index disable fix from Srivatsa Bhat which unifies the way the code checks for already disabled indices. ( Pulling it into v3.4 despite the v3.5 tag - the fix is small and we better keep the same code across kernel versions for such user facing interfaces. ) Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 815674415267..d20f1334792b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -967,16 +967,47 @@ pci_save_state(struct pci_dev *dev)
967 return 0; 967 return 0;
968} 968}
969 969
970static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
971 u32 saved_val, int retry)
972{
973 u32 val;
974
975 pci_read_config_dword(pdev, offset, &val);
976 if (val == saved_val)
977 return;
978
979 for (;;) {
980 dev_dbg(&pdev->dev, "restoring config space at offset "
981 "%#x (was %#x, writing %#x)\n", offset, val, saved_val);
982 pci_write_config_dword(pdev, offset, saved_val);
983 if (retry-- <= 0)
984 return;
985
986 pci_read_config_dword(pdev, offset, &val);
987 if (val == saved_val)
988 return;
989
990 mdelay(1);
991 }
992}
993
994static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,
995 int retry)
996{
997 int index;
998
999 for (index = end; index >= start; index--)
1000 pci_restore_config_dword(pdev, 4 * index,
1001 pdev->saved_config_space[index],
1002 retry);
1003}
1004
970/** 1005/**
971 * pci_restore_state - Restore the saved state of a PCI device 1006 * pci_restore_state - Restore the saved state of a PCI device
972 * @dev: - PCI device that we're dealing with 1007 * @dev: - PCI device that we're dealing with
973 */ 1008 */
974void pci_restore_state(struct pci_dev *dev) 1009void pci_restore_state(struct pci_dev *dev)
975{ 1010{
976 int i;
977 u32 val;
978 int tries;
979
980 if (!dev->state_saved) 1011 if (!dev->state_saved)
981 return; 1012 return;
982 1013
@@ -984,24 +1015,14 @@ void pci_restore_state(struct pci_dev *dev)
984 pci_restore_pcie_state(dev); 1015 pci_restore_pcie_state(dev);
985 pci_restore_ats_state(dev); 1016 pci_restore_ats_state(dev);
986 1017
1018 pci_restore_config_space(dev, 10, 15, 0);
987 /* 1019 /*
988 * The Base Address register should be programmed before the command 1020 * The Base Address register should be programmed before the command
989 * register(s) 1021 * register(s)
990 */ 1022 */
991 for (i = 15; i >= 0; i--) { 1023 pci_restore_config_space(dev, 4, 9, 10);
992 pci_read_config_dword(dev, i * 4, &val); 1024 pci_restore_config_space(dev, 0, 3, 0);
993 tries = 10; 1025
994 while (tries && val != dev->saved_config_space[i]) {
995 dev_dbg(&dev->dev, "restoring config "
996 "space at offset %#x (was %#x, writing %#x)\n",
997 i, val, (int)dev->saved_config_space[i]);
998 pci_write_config_dword(dev,i * 4,
999 dev->saved_config_space[i]);
1000 pci_read_config_dword(dev, i * 4, &val);
1001 mdelay(10);
1002 tries--;
1003 }
1004 }
1005 pci_restore_pcix_state(dev); 1026 pci_restore_pcix_state(dev);
1006 pci_restore_msi_state(dev); 1027 pci_restore_msi_state(dev);
1007 pci_restore_iov_state(dev); 1028 pci_restore_iov_state(dev);