aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorShmulik Ravid <shmulikr@broadcom.com>2009-12-03 15:27:51 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-12-04 18:49:44 -0500
commit04b55c4732780381410e52db0e9bfb7661f2b4b3 (patch)
tree6c8a96438f40aa60038a9bd422c38833bdc7aa7a /drivers/pci/pci.c
parentbb965401fd2afa26629b244e7bb2e48a117dc238 (diff)
PCI: read-modify-write the pcie device control register when initiating pcie flr
The pcie_flr routine writes the device control register with the FLR bit set clearing all other fields for the FLR duration. Among other fields, the Max_Payload_Size is also cleared which can cause errors if there are transactions lurking in the HW pipeline. The patch replaces the blank write with read-modify-write of the control register keeping the other fields intact. Signed-off-by: Shmulik Ravid <shmulikr@broadcom.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index be91a09c74a5..6af212c509c5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2140,7 +2140,7 @@ static int pcie_flr(struct pci_dev *dev, int probe)
2140 int i; 2140 int i;
2141 int pos; 2141 int pos;
2142 u32 cap; 2142 u32 cap;
2143 u16 status; 2143 u16 status, control;
2144 2144
2145 pos = pci_pcie_cap(dev); 2145 pos = pci_pcie_cap(dev);
2146 if (!pos) 2146 if (!pos)
@@ -2167,8 +2167,10 @@ static int pcie_flr(struct pci_dev *dev, int probe)
2167 "proceeding with reset anyway\n"); 2167 "proceeding with reset anyway\n");
2168 2168
2169clear: 2169clear:
2170 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, 2170 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control);
2171 PCI_EXP_DEVCTL_BCR_FLR); 2171 control |= PCI_EXP_DEVCTL_BCR_FLR;
2172 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control);
2173
2172 msleep(100); 2174 msleep(100);
2173 2175
2174 return 0; 2176 return 0;