diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/probe.c | 10 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 13 |
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index f4adba2d1dd3..12625d90f8b5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -163,9 +163,16 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
163 | struct resource *res, unsigned int pos) | 163 | struct resource *res, unsigned int pos) |
164 | { | 164 | { |
165 | u32 l, sz, mask; | 165 | u32 l, sz, mask; |
166 | u16 orig_cmd; | ||
166 | 167 | ||
167 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 168 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
168 | 169 | ||
170 | if (!dev->mmio_always_on) { | ||
171 | pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); | ||
172 | pci_write_config_word(dev, PCI_COMMAND, | ||
173 | orig_cmd & ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); | ||
174 | } | ||
175 | |||
169 | res->name = pci_name(dev); | 176 | res->name = pci_name(dev); |
170 | 177 | ||
171 | pci_read_config_dword(dev, pos, &l); | 178 | pci_read_config_dword(dev, pos, &l); |
@@ -173,6 +180,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
173 | pci_read_config_dword(dev, pos, &sz); | 180 | pci_read_config_dword(dev, pos, &sz); |
174 | pci_write_config_dword(dev, pos, l); | 181 | pci_write_config_dword(dev, pos, l); |
175 | 182 | ||
183 | if (!dev->mmio_always_on) | ||
184 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); | ||
185 | |||
176 | /* | 186 | /* |
177 | * All bits set in sz means the device isn't working properly. | 187 | * All bits set in sz means the device isn't working properly. |
178 | * If the BAR isn't implemented, all bits must be 0. If it's a | 188 | * If the BAR isn't implemented, all bits must be 0. If it's a |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 3a81d9d44019..202efa6f57c4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -91,6 +91,19 @@ static void __devinit quirk_resource_alignment(struct pci_dev *dev) | |||
91 | } | 91 | } |
92 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | 92 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); |
93 | 93 | ||
94 | /* | ||
95 | * Decoding should be disabled for a PCI device during BAR sizing to avoid | ||
96 | * conflict. But doing so may cause problems on host bridge and perhaps other | ||
97 | * key system devices. For devices that need to have mmio decoding always-on, | ||
98 | * we need to set the dev->mmio_always_on bit. | ||
99 | */ | ||
100 | static void __devinit quirk_mmio_always_on(struct pci_dev *dev) | ||
101 | { | ||
102 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
103 | dev->mmio_always_on = 1; | ||
104 | } | ||
105 | DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on); | ||
106 | |||
94 | /* The Mellanox Tavor device gives false positive parity errors | 107 | /* The Mellanox Tavor device gives false positive parity errors |
95 | * Mark this device with a broken_parity_status, to allow | 108 | * Mark this device with a broken_parity_status, to allow |
96 | * PCI scanning code to "skip" this now blacklisted device. | 109 | * PCI scanning code to "skip" this now blacklisted device. |