aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2005-07-27 10:19:44 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-08 17:57:24 -0400
commit064b53dbcc977dbf2753a67c2b8fc1c061d74f21 (patch)
tree39efa08fb7b0b7991bbfc4772f4fc3de0e8d11fa /include/linux
parent1248d636122e4ec9d7802b850904e3bb48a0da23 (diff)
[PATCH] PCI: restore BAR values after D3hot->D0 for devices that need it
Some PCI devices (e.g. 3c905B, 3c556B) lose all configuration (including BARs) when transitioning from D3hot->D0. This leaves such a device in an inaccessible state. The patch below causes the BARs to be restored when enabling such a device, so that its driver will be able to access it. The patch also adds pci_restore_bars as a new global symbol, and adds a correpsonding EXPORT_SYMBOL_GPL for that. Some firmware (e.g. Thinkpad T21) leaves devices in D3hot after a (re)boot. Most drivers call pci_enable_device very early, so devices left in D3hot that lose configuration during the D3hot->D0 transition will be inaccessible to their drivers. Drivers could be modified to account for this, but it would be difficult to know which drivers need modification. This is especially true since often many devices are covered by the same driver. It likely would be necessary to replicate code across dozens of drivers. The patch below should trigger only when transitioning from D3hot->D0 (or at boot), and only for devices that have the "no soft reset" bit cleared in the PM control register. I believe it is safe to include this patch as part of the PCI infrastructure. The cleanest implementation of pci_restore_bars was to call pci_update_resource. Unfortunately, that does not currently exist for the sparc64 architecture. The patch below includes a null implemenation of pci_update_resource for sparc64. Some have expressed interest in making general use of the the pci_restore_bars function, so that has been exported to GPL licensed modules. Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/pci_regs.h1
2 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 830c1bae56cc..8878ccff9e3c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -384,7 +384,9 @@ int pci_set_mwi(struct pci_dev *dev);
384void pci_clear_mwi(struct pci_dev *dev); 384void pci_clear_mwi(struct pci_dev *dev);
385int pci_set_dma_mask(struct pci_dev *dev, u64 mask); 385int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
386int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); 386int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
387void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
387int pci_assign_resource(struct pci_dev *dev, int i); 388int pci_assign_resource(struct pci_dev *dev, int i);
389void pci_restore_bars(struct pci_dev *dev);
388 390
389/* ROM control related routines */ 391/* ROM control related routines */
390void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size); 392void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size);
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 7dc391cad10d..e2a089b051ed 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -222,6 +222,7 @@
222#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ 222#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
223#define PCI_PM_CTRL 4 /* PM control and status register */ 223#define PCI_PM_CTRL 4 /* PM control and status register */
224#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ 224#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
225#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */
225#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ 226#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
226#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ 227#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
227#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ 228#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */