aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorYu Zhao <yu.zhao@intel.com>2009-06-13 03:52:15 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-16 17:30:16 -0400
commitc12ff1df5f114484e3d8abd028769a624cc3399f (patch)
tree410cb0adf85a52772d5acf6621b421c33b44820a /drivers/pci/pci.c
parentf85876ba82281f15bc4da11e41b94243a8b2b5b4 (diff)
PCI: support Secondary Bus Reset
PCI-to-PCI Bridge 1.2 specifies that the Secondary Bus Reset bit can force the assertion of RST# on the secondary interface, which can be used to reset all devices including subordinates under this bus. This can be used to reset a function if this function is the only device under this bus. Reviewed-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Yu Zhao <yu.zhao@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 2e58acc66a8c..c56a4a0355a8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2162,6 +2162,33 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
2162 return 0; 2162 return 0;
2163} 2163}
2164 2164
2165static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
2166{
2167 u16 ctrl;
2168 struct pci_dev *pdev;
2169
2170 if (dev->subordinate)
2171 return -ENOTTY;
2172
2173 list_for_each_entry(pdev, &dev->bus->devices, bus_list)
2174 if (pdev != dev)
2175 return -ENOTTY;
2176
2177 if (probe)
2178 return 0;
2179
2180 pci_read_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, &ctrl);
2181 ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
2182 pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
2183 msleep(100);
2184
2185 ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
2186 pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
2187 msleep(100);
2188
2189 return 0;
2190}
2191
2165static int pci_dev_reset(struct pci_dev *dev, int probe) 2192static int pci_dev_reset(struct pci_dev *dev, int probe)
2166{ 2193{
2167 int rc; 2194 int rc;
@@ -2183,6 +2210,10 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
2183 goto done; 2210 goto done;
2184 2211
2185 rc = pci_pm_reset(dev, probe); 2212 rc = pci_pm_reset(dev, probe);
2213 if (rc != -ENOTTY)
2214 goto done;
2215
2216 rc = pci_parent_bus_reset(dev, probe);
2186done: 2217done:
2187 if (!probe) { 2218 if (!probe) {
2188 up(&dev->dev.sem); 2219 up(&dev->dev.sem);