diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 18:41:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 18:41:01 -0500 |
commit | b424e8d3b438e841cd1700f6433a100a5d611e4a (patch) | |
tree | 545638d0b925de4c7f740286760767cca86cb91e /drivers | |
parent | 7c7758f99d39d529a64d4f60d22129bbf2f16d74 (diff) | |
parent | f6dc1e5e3d4b523e1616b43beddb04e4fb1d376a (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (98 commits)
PCI PM: Put PM callbacks in the order of execution
PCI PM: Run default PM callbacks for all devices using new framework
PCI PM: Register power state of devices during initialization
PCI PM: Call pci_fixup_device from legacy routines
PCI PM: Rearrange code in pci-driver.c
PCI PM: Avoid touching devices behind bridges in unknown state
PCI PM: Move pci_has_legacy_pm_support
PCI PM: Power-manage devices without drivers during suspend-resume
PCI PM: Add suspend counterpart of pci_reenable_device
PCI PM: Fix poweroff and restore callbacks
PCI: Use msleep instead of cpu_relax during ASPM link retraining
PCI: PCIe portdrv: Add kerneldoc comments to remining core funtions
PCI: PCIe portdrv: Rearrange code so that related things are together
PCI: PCIe portdrv: Fix suspend and resume of PCI Express port services
PCI: PCIe portdrv: Add kerneldoc comments to some core functions
x86/PCI: Do not use interrupt links for devices using MSI-X
net: sfc: Use pci_clear_master() to disable bus mastering
PCI: Add pci_clear_master() as opposite of pci_set_master()
PCI hotplug: remove redundant test in cpq hotplug
PCI: pciehp: cleanup register and field definitions
...
Diffstat (limited to 'drivers')
41 files changed, 1867 insertions, 1088 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 642554b1b60c..5b38a026d122 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/pm.h> | 32 | #include <linux/pm.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci-acpi.h> | ||
34 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
35 | #include <acpi/acpi_bus.h> | 36 | #include <acpi/acpi_bus.h> |
36 | #include <acpi/acpi_drivers.h> | 37 | #include <acpi/acpi_drivers.h> |
@@ -193,6 +194,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
193 | unsigned long long value = 0; | 194 | unsigned long long value = 0; |
194 | acpi_handle handle = NULL; | 195 | acpi_handle handle = NULL; |
195 | struct acpi_device *child; | 196 | struct acpi_device *child; |
197 | u32 flags, base_flags; | ||
196 | 198 | ||
197 | 199 | ||
198 | if (!device) | 200 | if (!device) |
@@ -210,6 +212,13 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
210 | 212 | ||
211 | device->ops.bind = acpi_pci_bind; | 213 | device->ops.bind = acpi_pci_bind; |
212 | 214 | ||
215 | /* | ||
216 | * All supported architectures that use ACPI have support for | ||
217 | * PCI domains, so we indicate this in _OSC support capabilities. | ||
218 | */ | ||
219 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | ||
220 | pci_acpi_osc_support(device->handle, flags); | ||
221 | |||
213 | /* | 222 | /* |
214 | * Segment | 223 | * Segment |
215 | * ------- | 224 | * ------- |
@@ -335,6 +344,17 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
335 | list_for_each_entry(child, &device->children, node) | 344 | list_for_each_entry(child, &device->children, node) |
336 | acpi_pci_bridge_scan(child); | 345 | acpi_pci_bridge_scan(child); |
337 | 346 | ||
347 | /* Indicate support for various _OSC capabilities. */ | ||
348 | if (pci_ext_cfg_avail(root->bus->self)) | ||
349 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | ||
350 | if (pcie_aspm_enabled()) | ||
351 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | | ||
352 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | ||
353 | if (pci_msi_enabled()) | ||
354 | flags |= OSC_MSI_SUPPORT; | ||
355 | if (flags != base_flags) | ||
356 | pci_acpi_osc_support(device->handle, flags); | ||
357 | |||
338 | end: | 358 | end: |
339 | if (result) { | 359 | if (result) { |
340 | if (!list_empty(&root->node)) | 360 | if (!list_empty(&root->node)) |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index d4639facd1bd..91817d0afcaf 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -4807,7 +4807,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
4807 | } | 4807 | } |
4808 | } | 4808 | } |
4809 | 4809 | ||
4810 | err = pci_request_selected_regions(pdev, | 4810 | err = pci_request_selected_regions_exclusive(pdev, |
4811 | pci_select_bars(pdev, IORESOURCE_MEM), | 4811 | pci_select_bars(pdev, IORESOURCE_MEM), |
4812 | e1000e_driver_name); | 4812 | e1000e_driver_name); |
4813 | if (err) | 4813 | if (err) |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 6884dc8c1f82..5b9f2d9cc4ed 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -1403,9 +1403,9 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) | |||
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | /* Disable both devices */ | 1405 | /* Disable both devices */ |
1406 | pci_disable_device(efx->pci_dev); | 1406 | pci_clear_master(efx->pci_dev); |
1407 | if (FALCON_IS_DUAL_FUNC(efx)) | 1407 | if (FALCON_IS_DUAL_FUNC(efx)) |
1408 | pci_disable_device(nic_data->pci_dev2); | 1408 | pci_clear_master(nic_data->pci_dev2); |
1409 | falcon_disable_interrupts(efx); | 1409 | falcon_disable_interrupts(efx); |
1410 | 1410 | ||
1411 | if (++n_int_errors < FALCON_MAX_INT_ERRORS) { | 1411 | if (++n_int_errors < FALCON_MAX_INT_ERRORS) { |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 3bc54b30c3a1..77cc8bfef8c9 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -547,7 +547,7 @@ dino_card_fixup(struct pci_dev *dev) | |||
547 | ** The additional "-1" adjusts for skewing the IRQ<->slot. | 547 | ** The additional "-1" adjusts for skewing the IRQ<->slot. |
548 | */ | 548 | */ |
549 | dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); | 549 | dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); |
550 | dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ; | 550 | dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; |
551 | 551 | ||
552 | /* Shouldn't really need to do this but it's in case someone tries | 552 | /* Shouldn't really need to do this but it's in case someone tries |
553 | ** to bypass PCI services and look at the card themselves. | 553 | ** to bypass PCI services and look at the card themselves. |
@@ -672,7 +672,7 @@ dino_fixup_bus(struct pci_bus *bus) | |||
672 | 672 | ||
673 | dino_cfg_read(dev->bus, dev->devfn, | 673 | dino_cfg_read(dev->bus, dev->devfn, |
674 | PCI_INTERRUPT_PIN, 1, &irq_pin); | 674 | PCI_INTERRUPT_PIN, 1, &irq_pin); |
675 | irq_pin = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ; | 675 | irq_pin = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; |
676 | printk(KERN_WARNING "Device %s has undefined IRQ, " | 676 | printk(KERN_WARNING "Device %s has undefined IRQ, " |
677 | "setting to %d\n", pci_name(dev), irq_pin); | 677 | "setting to %d\n", pci_name(dev), irq_pin); |
678 | dino_cfg_write(dev->bus, dev->devfn, | 678 | dino_cfg_write(dev->bus, dev->devfn, |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 9dedbbd218c3..0797659ee016 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -519,8 +519,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev) | |||
519 | ** | 519 | ** |
520 | ** Advantage is it's really easy to implement. | 520 | ** Advantage is it's really easy to implement. |
521 | */ | 521 | */ |
522 | intr_pin = ((intr_pin-1)+PCI_SLOT(pcidev->devfn)) % 4; | 522 | intr_pin = pci_swizzle_interrupt_pin(pcidev, intr_pin); |
523 | intr_pin++; /* convert back to INTA-D (1-4) */ | ||
524 | #endif /* PCI_BRIDGE_FUNCS */ | 523 | #endif /* PCI_BRIDGE_FUNCS */ |
525 | 524 | ||
526 | /* | 525 | /* |
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index e1ca42591ac4..2a4501dd2515 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -42,6 +42,15 @@ config PCI_DEBUG | |||
42 | 42 | ||
43 | When in doubt, say N. | 43 | When in doubt, say N. |
44 | 44 | ||
45 | config PCI_STUB | ||
46 | tristate "PCI Stub driver" | ||
47 | depends on PCI | ||
48 | help | ||
49 | Say Y or M here if you want be able to reserve a PCI device | ||
50 | when it is going to be assigned to a guest operating system. | ||
51 | |||
52 | When in doubt, say N. | ||
53 | |||
45 | config HT_IRQ | 54 | config HT_IRQ |
46 | bool "Interrupts on hypertransport devices" | 55 | bool "Interrupts on hypertransport devices" |
47 | default y | 56 | default y |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index af3bfe22847b..3d07ce24f6a8 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -53,6 +53,8 @@ obj-$(CONFIG_HOTPLUG) += setup-bus.o | |||
53 | 53 | ||
54 | obj-$(CONFIG_PCI_SYSCALL) += syscall.o | 54 | obj-$(CONFIG_PCI_SYSCALL) += syscall.o |
55 | 55 | ||
56 | obj-$(CONFIG_PCI_STUB) += pci-stub.o | ||
57 | |||
56 | ifeq ($(CONFIG_PCI_DEBUG),y) | 58 | ifeq ($(CONFIG_PCI_DEBUG),y) |
57 | EXTRA_CFLAGS += -DDEBUG | 59 | EXTRA_CFLAGS += -DDEBUG |
58 | endif | 60 | endif |
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 39bb96b413ef..381444794778 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -66,6 +66,39 @@ EXPORT_SYMBOL(pci_bus_write_config_byte); | |||
66 | EXPORT_SYMBOL(pci_bus_write_config_word); | 66 | EXPORT_SYMBOL(pci_bus_write_config_word); |
67 | EXPORT_SYMBOL(pci_bus_write_config_dword); | 67 | EXPORT_SYMBOL(pci_bus_write_config_dword); |
68 | 68 | ||
69 | |||
70 | /** | ||
71 | * pci_read_vpd - Read one entry from Vital Product Data | ||
72 | * @dev: pci device struct | ||
73 | * @pos: offset in vpd space | ||
74 | * @count: number of bytes to read | ||
75 | * @buf: pointer to where to store result | ||
76 | * | ||
77 | */ | ||
78 | ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf) | ||
79 | { | ||
80 | if (!dev->vpd || !dev->vpd->ops) | ||
81 | return -ENODEV; | ||
82 | return dev->vpd->ops->read(dev, pos, count, buf); | ||
83 | } | ||
84 | EXPORT_SYMBOL(pci_read_vpd); | ||
85 | |||
86 | /** | ||
87 | * pci_write_vpd - Write entry to Vital Product Data | ||
88 | * @dev: pci device struct | ||
89 | * @pos: offset in vpd space | ||
90 | * @count: number of bytes to read | ||
91 | * @val: value to write | ||
92 | * | ||
93 | */ | ||
94 | ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf) | ||
95 | { | ||
96 | if (!dev->vpd || !dev->vpd->ops) | ||
97 | return -ENODEV; | ||
98 | return dev->vpd->ops->write(dev, pos, count, buf); | ||
99 | } | ||
100 | EXPORT_SYMBOL(pci_write_vpd); | ||
101 | |||
69 | /* | 102 | /* |
70 | * The following routines are to prevent the user from accessing PCI config | 103 | * The following routines are to prevent the user from accessing PCI config |
71 | * space when it's unsafe to do so. Some devices require this during BIST and | 104 | * space when it's unsafe to do so. Some devices require this during BIST and |
@@ -133,125 +166,145 @@ PCI_USER_WRITE_CONFIG(dword, u32) | |||
133 | 166 | ||
134 | struct pci_vpd_pci22 { | 167 | struct pci_vpd_pci22 { |
135 | struct pci_vpd base; | 168 | struct pci_vpd base; |
136 | spinlock_t lock; /* controls access to hardware and the flags */ | 169 | struct mutex lock; |
137 | u8 cap; | 170 | u16 flag; |
138 | bool busy; | 171 | bool busy; |
139 | bool flag; /* value of F bit to wait for */ | 172 | u8 cap; |
140 | }; | 173 | }; |
141 | 174 | ||
142 | /* Wait for last operation to complete */ | 175 | /* |
176 | * Wait for last operation to complete. | ||
177 | * This code has to spin since there is no other notification from the PCI | ||
178 | * hardware. Since the VPD is often implemented by serial attachment to an | ||
179 | * EEPROM, it may take many milliseconds to complete. | ||
180 | */ | ||
143 | static int pci_vpd_pci22_wait(struct pci_dev *dev) | 181 | static int pci_vpd_pci22_wait(struct pci_dev *dev) |
144 | { | 182 | { |
145 | struct pci_vpd_pci22 *vpd = | 183 | struct pci_vpd_pci22 *vpd = |
146 | container_of(dev->vpd, struct pci_vpd_pci22, base); | 184 | container_of(dev->vpd, struct pci_vpd_pci22, base); |
147 | u16 flag, status; | 185 | unsigned long timeout = jiffies + HZ/20 + 2; |
148 | int wait; | 186 | u16 status; |
149 | int ret; | 187 | int ret; |
150 | 188 | ||
151 | if (!vpd->busy) | 189 | if (!vpd->busy) |
152 | return 0; | 190 | return 0; |
153 | 191 | ||
154 | flag = vpd->flag ? PCI_VPD_ADDR_F : 0; | ||
155 | wait = vpd->flag ? 10 : 1000; /* read: 100 us; write: 10 ms */ | ||
156 | for (;;) { | 192 | for (;;) { |
157 | ret = pci_user_read_config_word(dev, | 193 | ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, |
158 | vpd->cap + PCI_VPD_ADDR, | ||
159 | &status); | 194 | &status); |
160 | if (ret < 0) | 195 | if (ret) |
161 | return ret; | 196 | return ret; |
162 | if ((status & PCI_VPD_ADDR_F) == flag) { | 197 | |
198 | if ((status & PCI_VPD_ADDR_F) == vpd->flag) { | ||
163 | vpd->busy = false; | 199 | vpd->busy = false; |
164 | return 0; | 200 | return 0; |
165 | } | 201 | } |
166 | if (wait-- == 0) | 202 | |
203 | if (time_after(jiffies, timeout)) | ||
167 | return -ETIMEDOUT; | 204 | return -ETIMEDOUT; |
168 | udelay(10); | 205 | if (fatal_signal_pending(current)) |
206 | return -EINTR; | ||
207 | if (!cond_resched()) | ||
208 | udelay(10); | ||
169 | } | 209 | } |
170 | } | 210 | } |
171 | 211 | ||
172 | static int pci_vpd_pci22_read(struct pci_dev *dev, int pos, int size, | 212 | static ssize_t pci_vpd_pci22_read(struct pci_dev *dev, loff_t pos, size_t count, |
173 | char *buf) | 213 | void *arg) |
174 | { | 214 | { |
175 | struct pci_vpd_pci22 *vpd = | 215 | struct pci_vpd_pci22 *vpd = |
176 | container_of(dev->vpd, struct pci_vpd_pci22, base); | 216 | container_of(dev->vpd, struct pci_vpd_pci22, base); |
177 | u32 val; | ||
178 | int ret; | 217 | int ret; |
179 | int begin, end, i; | 218 | loff_t end = pos + count; |
219 | u8 *buf = arg; | ||
180 | 220 | ||
181 | if (pos < 0 || pos > vpd->base.len || size > vpd->base.len - pos) | 221 | if (pos < 0 || pos > vpd->base.len || end > vpd->base.len) |
182 | return -EINVAL; | 222 | return -EINVAL; |
183 | if (size == 0) | ||
184 | return 0; | ||
185 | 223 | ||
186 | spin_lock_irq(&vpd->lock); | 224 | if (mutex_lock_killable(&vpd->lock)) |
187 | ret = pci_vpd_pci22_wait(dev); | 225 | return -EINTR; |
188 | if (ret < 0) | 226 | |
189 | goto out; | ||
190 | ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, | ||
191 | pos & ~3); | ||
192 | if (ret < 0) | ||
193 | goto out; | ||
194 | vpd->busy = true; | ||
195 | vpd->flag = 1; | ||
196 | ret = pci_vpd_pci22_wait(dev); | 227 | ret = pci_vpd_pci22_wait(dev); |
197 | if (ret < 0) | 228 | if (ret < 0) |
198 | goto out; | 229 | goto out; |
199 | ret = pci_user_read_config_dword(dev, vpd->cap + PCI_VPD_DATA, | 230 | |
200 | &val); | 231 | while (pos < end) { |
201 | out: | 232 | u32 val; |
202 | spin_unlock_irq(&vpd->lock); | 233 | unsigned int i, skip; |
203 | if (ret < 0) | 234 | |
204 | return ret; | 235 | ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, |
205 | 236 | pos & ~3); | |
206 | /* Convert to bytes */ | 237 | if (ret < 0) |
207 | begin = pos & 3; | 238 | break; |
208 | end = min(4, begin + size); | 239 | vpd->busy = true; |
209 | for (i = 0; i < end; ++i) { | 240 | vpd->flag = PCI_VPD_ADDR_F; |
210 | if (i >= begin) | 241 | ret = pci_vpd_pci22_wait(dev); |
211 | *buf++ = val; | 242 | if (ret < 0) |
212 | val >>= 8; | 243 | break; |
244 | |||
245 | ret = pci_user_read_config_dword(dev, vpd->cap + PCI_VPD_DATA, &val); | ||
246 | if (ret < 0) | ||
247 | break; | ||
248 | |||
249 | skip = pos & 3; | ||
250 | for (i = 0; i < sizeof(u32); i++) { | ||
251 | if (i >= skip) { | ||
252 | *buf++ = val; | ||
253 | if (++pos == end) | ||
254 | break; | ||
255 | } | ||
256 | val >>= 8; | ||
257 | } | ||
213 | } | 258 | } |
214 | return end - begin; | 259 | out: |
260 | mutex_unlock(&vpd->lock); | ||
261 | return ret ? ret : count; | ||
215 | } | 262 | } |
216 | 263 | ||
217 | static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size, | 264 | static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count, |
218 | const char *buf) | 265 | const void *arg) |
219 | { | 266 | { |
220 | struct pci_vpd_pci22 *vpd = | 267 | struct pci_vpd_pci22 *vpd = |
221 | container_of(dev->vpd, struct pci_vpd_pci22, base); | 268 | container_of(dev->vpd, struct pci_vpd_pci22, base); |
222 | u32 val; | 269 | const u8 *buf = arg; |
223 | int ret; | 270 | loff_t end = pos + count; |
271 | int ret = 0; | ||
224 | 272 | ||
225 | if (pos < 0 || pos > vpd->base.len || pos & 3 || | 273 | if (pos < 0 || (pos & 3) || (count & 3) || end > vpd->base.len) |
226 | size > vpd->base.len - pos || size < 4) | ||
227 | return -EINVAL; | 274 | return -EINVAL; |
228 | 275 | ||
229 | val = (u8) *buf++; | 276 | if (mutex_lock_killable(&vpd->lock)) |
230 | val |= ((u8) *buf++) << 8; | 277 | return -EINTR; |
231 | val |= ((u8) *buf++) << 16; | ||
232 | val |= ((u32)(u8) *buf++) << 24; | ||
233 | 278 | ||
234 | spin_lock_irq(&vpd->lock); | ||
235 | ret = pci_vpd_pci22_wait(dev); | 279 | ret = pci_vpd_pci22_wait(dev); |
236 | if (ret < 0) | 280 | if (ret < 0) |
237 | goto out; | 281 | goto out; |
238 | ret = pci_user_write_config_dword(dev, vpd->cap + PCI_VPD_DATA, | ||
239 | val); | ||
240 | if (ret < 0) | ||
241 | goto out; | ||
242 | ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, | ||
243 | pos | PCI_VPD_ADDR_F); | ||
244 | if (ret < 0) | ||
245 | goto out; | ||
246 | vpd->busy = true; | ||
247 | vpd->flag = 0; | ||
248 | ret = pci_vpd_pci22_wait(dev); | ||
249 | out: | ||
250 | spin_unlock_irq(&vpd->lock); | ||
251 | if (ret < 0) | ||
252 | return ret; | ||
253 | 282 | ||
254 | return 4; | 283 | while (pos < end) { |
284 | u32 val; | ||
285 | |||
286 | val = *buf++; | ||
287 | val |= *buf++ << 8; | ||
288 | val |= *buf++ << 16; | ||
289 | val |= *buf++ << 24; | ||
290 | |||
291 | ret = pci_user_write_config_dword(dev, vpd->cap + PCI_VPD_DATA, val); | ||
292 | if (ret < 0) | ||
293 | break; | ||
294 | ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, | ||
295 | pos | PCI_VPD_ADDR_F); | ||
296 | if (ret < 0) | ||
297 | break; | ||
298 | |||
299 | vpd->busy = true; | ||
300 | vpd->flag = 0; | ||
301 | ret = pci_vpd_pci22_wait(dev); | ||
302 | |||
303 | pos += sizeof(u32); | ||
304 | } | ||
305 | out: | ||
306 | mutex_unlock(&vpd->lock); | ||
307 | return ret ? ret : count; | ||
255 | } | 308 | } |
256 | 309 | ||
257 | static void pci_vpd_pci22_release(struct pci_dev *dev) | 310 | static void pci_vpd_pci22_release(struct pci_dev *dev) |
@@ -259,7 +312,7 @@ static void pci_vpd_pci22_release(struct pci_dev *dev) | |||
259 | kfree(container_of(dev->vpd, struct pci_vpd_pci22, base)); | 312 | kfree(container_of(dev->vpd, struct pci_vpd_pci22, base)); |
260 | } | 313 | } |
261 | 314 | ||
262 | static struct pci_vpd_ops pci_vpd_pci22_ops = { | 315 | static const struct pci_vpd_ops pci_vpd_pci22_ops = { |
263 | .read = pci_vpd_pci22_read, | 316 | .read = pci_vpd_pci22_read, |
264 | .write = pci_vpd_pci22_write, | 317 | .write = pci_vpd_pci22_write, |
265 | .release = pci_vpd_pci22_release, | 318 | .release = pci_vpd_pci22_release, |
@@ -279,7 +332,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev) | |||
279 | 332 | ||
280 | vpd->base.len = PCI_VPD_PCI22_SIZE; | 333 | vpd->base.len = PCI_VPD_PCI22_SIZE; |
281 | vpd->base.ops = &pci_vpd_pci22_ops; | 334 | vpd->base.ops = &pci_vpd_pci22_ops; |
282 | spin_lock_init(&vpd->lock); | 335 | mutex_init(&vpd->lock); |
283 | vpd->cap = cap; | 336 | vpd->cap = cap; |
284 | vpd->busy = false; | 337 | vpd->busy = false; |
285 | dev->vpd = &vpd->base; | 338 | dev->vpd = &vpd->base; |
@@ -287,6 +340,29 @@ int pci_vpd_pci22_init(struct pci_dev *dev) | |||
287 | } | 340 | } |
288 | 341 | ||
289 | /** | 342 | /** |
343 | * pci_vpd_truncate - Set available Vital Product Data size | ||
344 | * @dev: pci device struct | ||
345 | * @size: available memory in bytes | ||
346 | * | ||
347 | * Adjust size of available VPD area. | ||
348 | */ | ||
349 | int pci_vpd_truncate(struct pci_dev *dev, size_t size) | ||
350 | { | ||
351 | if (!dev->vpd) | ||
352 | return -EINVAL; | ||
353 | |||
354 | /* limited by the access method */ | ||
355 | if (size > dev->vpd->len) | ||
356 | return -EINVAL; | ||
357 | |||
358 | dev->vpd->len = size; | ||
359 | dev->vpd->attr->size = size; | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | EXPORT_SYMBOL(pci_vpd_truncate); | ||
364 | |||
365 | /** | ||
290 | * pci_block_user_cfg_access - Block userspace PCI config reads/writes | 366 | * pci_block_user_cfg_access - Block userspace PCI config reads/writes |
291 | * @dev: pci device struct | 367 | * @dev: pci device struct |
292 | * | 368 | * |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 999cc4088b59..52b54f053be0 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -71,7 +71,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
71 | } | 71 | } |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * add a single device | 74 | * pci_bus_add_device - add a single device |
75 | * @dev: device to add | 75 | * @dev: device to add |
76 | * | 76 | * |
77 | * This adds a single pci device to the global | 77 | * This adds a single pci device to the global |
@@ -91,6 +91,37 @@ int pci_bus_add_device(struct pci_dev *dev) | |||
91 | } | 91 | } |
92 | 92 | ||
93 | /** | 93 | /** |
94 | * pci_bus_add_child - add a child bus | ||
95 | * @bus: bus to add | ||
96 | * | ||
97 | * This adds sysfs entries for a single bus | ||
98 | */ | ||
99 | int pci_bus_add_child(struct pci_bus *bus) | ||
100 | { | ||
101 | int retval; | ||
102 | |||
103 | if (bus->bridge) | ||
104 | bus->dev.parent = bus->bridge; | ||
105 | |||
106 | retval = device_register(&bus->dev); | ||
107 | if (retval) | ||
108 | return retval; | ||
109 | |||
110 | bus->is_added = 1; | ||
111 | |||
112 | retval = device_create_file(&bus->dev, &dev_attr_cpuaffinity); | ||
113 | if (retval) | ||
114 | return retval; | ||
115 | |||
116 | retval = device_create_file(&bus->dev, &dev_attr_cpulistaffinity); | ||
117 | |||
118 | /* Create legacy_io and legacy_mem files for this bus */ | ||
119 | pci_create_legacy_files(bus); | ||
120 | |||
121 | return retval; | ||
122 | } | ||
123 | |||
124 | /** | ||
94 | * pci_bus_add_devices - insert newly discovered PCI devices | 125 | * pci_bus_add_devices - insert newly discovered PCI devices |
95 | * @bus: bus to check for new devices | 126 | * @bus: bus to check for new devices |
96 | * | 127 | * |
@@ -105,7 +136,7 @@ int pci_bus_add_device(struct pci_dev *dev) | |||
105 | void pci_bus_add_devices(struct pci_bus *bus) | 136 | void pci_bus_add_devices(struct pci_bus *bus) |
106 | { | 137 | { |
107 | struct pci_dev *dev; | 138 | struct pci_dev *dev; |
108 | struct pci_bus *child_bus; | 139 | struct pci_bus *child; |
109 | int retval; | 140 | int retval; |
110 | 141 | ||
111 | list_for_each_entry(dev, &bus->devices, bus_list) { | 142 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -120,45 +151,29 @@ void pci_bus_add_devices(struct pci_bus *bus) | |||
120 | list_for_each_entry(dev, &bus->devices, bus_list) { | 151 | list_for_each_entry(dev, &bus->devices, bus_list) { |
121 | BUG_ON(!dev->is_added); | 152 | BUG_ON(!dev->is_added); |
122 | 153 | ||
154 | child = dev->subordinate; | ||
123 | /* | 155 | /* |
124 | * If there is an unattached subordinate bus, attach | 156 | * If there is an unattached subordinate bus, attach |
125 | * it and then scan for unattached PCI devices. | 157 | * it and then scan for unattached PCI devices. |
126 | */ | 158 | */ |
127 | if (dev->subordinate) { | 159 | if (!child) |
128 | if (list_empty(&dev->subordinate->node)) { | 160 | continue; |
129 | down_write(&pci_bus_sem); | 161 | if (list_empty(&child->node)) { |
130 | list_add_tail(&dev->subordinate->node, | 162 | down_write(&pci_bus_sem); |
131 | &dev->bus->children); | 163 | list_add_tail(&child->node, &dev->bus->children); |
132 | up_write(&pci_bus_sem); | 164 | up_write(&pci_bus_sem); |
133 | } | ||
134 | pci_bus_add_devices(dev->subordinate); | ||
135 | |||
136 | /* register the bus with sysfs as the parent is now | ||
137 | * properly registered. */ | ||
138 | child_bus = dev->subordinate; | ||
139 | if (child_bus->is_added) | ||
140 | continue; | ||
141 | child_bus->dev.parent = child_bus->bridge; | ||
142 | retval = device_register(&child_bus->dev); | ||
143 | if (retval) | ||
144 | dev_err(&dev->dev, "Error registering pci_bus," | ||
145 | " continuing...\n"); | ||
146 | else { | ||
147 | child_bus->is_added = 1; | ||
148 | retval = device_create_file(&child_bus->dev, | ||
149 | &dev_attr_cpuaffinity); | ||
150 | } | ||
151 | if (retval) | ||
152 | dev_err(&dev->dev, "Error creating cpuaffinity" | ||
153 | " file, continuing...\n"); | ||
154 | |||
155 | retval = device_create_file(&child_bus->dev, | ||
156 | &dev_attr_cpulistaffinity); | ||
157 | if (retval) | ||
158 | dev_err(&dev->dev, | ||
159 | "Error creating cpulistaffinity" | ||
160 | " file, continuing...\n"); | ||
161 | } | 165 | } |
166 | pci_bus_add_devices(child); | ||
167 | |||
168 | /* | ||
169 | * register the bus with sysfs as the parent is now | ||
170 | * properly registered. | ||
171 | */ | ||
172 | if (child->is_added) | ||
173 | continue; | ||
174 | retval = pci_bus_add_child(child); | ||
175 | if (retval) | ||
176 | dev_err(&dev->dev, "Error adding bus, continuing\n"); | ||
162 | } | 177 | } |
163 | } | 178 | } |
164 | 179 | ||
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 9bdbe1a6688f..e31fb91652ce 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -55,6 +55,9 @@ pciehp-objs := pciehp_core.o \ | |||
55 | pciehp_ctrl.o \ | 55 | pciehp_ctrl.o \ |
56 | pciehp_pci.o \ | 56 | pciehp_pci.o \ |
57 | pciehp_hpc.o | 57 | pciehp_hpc.o |
58 | ifdef CONFIG_ACPI | ||
59 | pciehp-objs += pciehp_acpi.o | ||
60 | endif | ||
58 | 61 | ||
59 | shpchp-objs := shpchp_core.o \ | 62 | shpchp-objs := shpchp_core.o \ |
60 | shpchp_ctrl.o \ | 63 | shpchp_ctrl.o \ |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index e17ef54f0efc..c62ab8d240aa 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -501,5 +501,74 @@ int acpi_root_bridge(acpi_handle handle) | |||
501 | } | 501 | } |
502 | EXPORT_SYMBOL_GPL(acpi_root_bridge); | 502 | EXPORT_SYMBOL_GPL(acpi_root_bridge); |
503 | 503 | ||
504 | |||
505 | static int is_ejectable(acpi_handle handle) | ||
506 | { | ||
507 | acpi_status status; | ||
508 | acpi_handle tmp; | ||
509 | unsigned long long removable; | ||
510 | status = acpi_get_handle(handle, "_ADR", &tmp); | ||
511 | if (ACPI_FAILURE(status)) | ||
512 | return 0; | ||
513 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
514 | if (ACPI_SUCCESS(status)) | ||
515 | return 1; | ||
516 | status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable); | ||
517 | if (ACPI_SUCCESS(status) && removable) | ||
518 | return 1; | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | /** | ||
523 | * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot | ||
524 | * @pbus: the PCI bus of the PCI slot corresponding to 'handle' | ||
525 | * @handle: ACPI handle to check | ||
526 | * | ||
527 | * Return 1 if handle is ejectable PCI slot, 0 otherwise. | ||
528 | */ | ||
529 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle) | ||
530 | { | ||
531 | acpi_handle bridge_handle, parent_handle; | ||
532 | |||
533 | if (!(bridge_handle = acpi_pci_get_bridge_handle(pbus))) | ||
534 | return 0; | ||
535 | if ((ACPI_FAILURE(acpi_get_parent(handle, &parent_handle)))) | ||
536 | return 0; | ||
537 | if (bridge_handle != parent_handle) | ||
538 | return 0; | ||
539 | return is_ejectable(handle); | ||
540 | } | ||
541 | EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable); | ||
542 | |||
543 | static acpi_status | ||
544 | check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
545 | { | ||
546 | int *found = (int *)context; | ||
547 | if (is_ejectable(handle)) { | ||
548 | *found = 1; | ||
549 | return AE_CTRL_TERMINATE; | ||
550 | } | ||
551 | return AE_OK; | ||
552 | } | ||
553 | |||
554 | /** | ||
555 | * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots | ||
556 | * @pbus - PCI bus to scan | ||
557 | * | ||
558 | * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise. | ||
559 | */ | ||
560 | int acpi_pci_detect_ejectable(struct pci_bus *pbus) | ||
561 | { | ||
562 | acpi_handle handle; | ||
563 | int found = 0; | ||
564 | |||
565 | if (!(handle = acpi_pci_get_bridge_handle(pbus))) | ||
566 | return 0; | ||
567 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
568 | check_hotplug, (void *)&found, NULL); | ||
569 | return found; | ||
570 | } | ||
571 | EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable); | ||
572 | |||
504 | module_param(debug_acpi, bool, 0644); | 573 | module_param(debug_acpi, bool, 0644); |
505 | MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not"); | 574 | MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not"); |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 9bcb6cbd5aa9..4fc168b70095 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -44,7 +44,7 @@ | |||
44 | do { \ | 44 | do { \ |
45 | if (acpiphp_debug) \ | 45 | if (acpiphp_debug) \ |
46 | printk(KERN_DEBUG "%s: " format, \ | 46 | printk(KERN_DEBUG "%s: " format, \ |
47 | MY_NAME , ## arg); \ | 47 | MY_NAME , ## arg); \ |
48 | } while (0) | 48 | } while (0) |
49 | #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | 49 | #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) |
50 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | 50 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 3affc6472e65..f09b1010d477 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/pci_hotplug.h> | 48 | #include <linux/pci_hotplug.h> |
49 | #include <linux/pci-acpi.h> | ||
49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
50 | 51 | ||
51 | #include "../pci.h" | 52 | #include "../pci.h" |
@@ -62,61 +63,6 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus); | |||
62 | static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); | 63 | static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); |
63 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | 64 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); |
64 | 65 | ||
65 | |||
66 | /* | ||
67 | * initialization & terminatation routines | ||
68 | */ | ||
69 | |||
70 | /** | ||
71 | * is_ejectable - determine if a slot is ejectable | ||
72 | * @handle: handle to acpi namespace | ||
73 | * | ||
74 | * Ejectable slot should satisfy at least these conditions: | ||
75 | * | ||
76 | * 1. has _ADR method | ||
77 | * 2. has _EJ0 method | ||
78 | * | ||
79 | * optionally | ||
80 | * | ||
81 | * 1. has _STA method | ||
82 | * 2. has _PS0 method | ||
83 | * 3. has _PS3 method | ||
84 | * 4. .. | ||
85 | */ | ||
86 | static int is_ejectable(acpi_handle handle) | ||
87 | { | ||
88 | acpi_status status; | ||
89 | acpi_handle tmp; | ||
90 | |||
91 | status = acpi_get_handle(handle, "_ADR", &tmp); | ||
92 | if (ACPI_FAILURE(status)) { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
97 | if (ACPI_FAILURE(status)) { | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | |||
105 | /* callback routine to check for the existence of ejectable slots */ | ||
106 | static acpi_status | ||
107 | is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
108 | { | ||
109 | int *count = (int *)context; | ||
110 | |||
111 | if (is_ejectable(handle)) { | ||
112 | (*count)++; | ||
113 | /* only one ejectable slot is enough */ | ||
114 | return AE_CTRL_TERMINATE; | ||
115 | } else { | ||
116 | return AE_OK; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /* callback routine to check for the existence of a pci dock device */ | 66 | /* callback routine to check for the existence of a pci dock device */ |
121 | static acpi_status | 67 | static acpi_status |
122 | is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | 68 | is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) |
@@ -131,9 +77,6 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
131 | } | 77 | } |
132 | } | 78 | } |
133 | 79 | ||
134 | |||
135 | |||
136 | |||
137 | /* | 80 | /* |
138 | * the _DCK method can do funny things... and sometimes not | 81 | * the _DCK method can do funny things... and sometimes not |
139 | * hah-hah funny. | 82 | * hah-hah funny. |
@@ -160,9 +103,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | |||
160 | 103 | ||
161 | if (((buses >> 8) & 0xff) != bus->secondary) { | 104 | if (((buses >> 8) & 0xff) != bus->secondary) { |
162 | buses = (buses & 0xff000000) | 105 | buses = (buses & 0xff000000) |
163 | | ((unsigned int)(bus->primary) << 0) | 106 | | ((unsigned int)(bus->primary) << 0) |
164 | | ((unsigned int)(bus->secondary) << 8) | 107 | | ((unsigned int)(bus->secondary) << 8) |
165 | | ((unsigned int)(bus->subordinate) << 16); | 108 | | ((unsigned int)(bus->subordinate) << 16); |
166 | pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); | 109 | pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); |
167 | } | 110 | } |
168 | return NOTIFY_OK; | 111 | return NOTIFY_OK; |
@@ -184,17 +127,12 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
184 | acpi_status status = AE_OK; | 127 | acpi_status status = AE_OK; |
185 | unsigned long long adr, sun; | 128 | unsigned long long adr, sun; |
186 | int device, function, retval; | 129 | int device, function, retval; |
130 | struct pci_bus *pbus = bridge->pci_bus; | ||
187 | 131 | ||
188 | status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); | 132 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) |
189 | |||
190 | if (ACPI_FAILURE(status)) | ||
191 | return AE_OK; | ||
192 | |||
193 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
194 | |||
195 | if (ACPI_FAILURE(status) && !(is_dock_device(handle))) | ||
196 | return AE_OK; | 133 | return AE_OK; |
197 | 134 | ||
135 | acpi_evaluate_integer(handle, "_ADR", NULL, &adr); | ||
198 | device = (adr >> 16) & 0xffff; | 136 | device = (adr >> 16) & 0xffff; |
199 | function = adr & 0xffff; | 137 | function = adr & 0xffff; |
200 | 138 | ||
@@ -205,7 +143,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
205 | INIT_LIST_HEAD(&newfunc->sibling); | 143 | INIT_LIST_HEAD(&newfunc->sibling); |
206 | newfunc->handle = handle; | 144 | newfunc->handle = handle; |
207 | newfunc->function = function; | 145 | newfunc->function = function; |
208 | if (ACPI_SUCCESS(status)) | 146 | |
147 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) | ||
209 | newfunc->flags = FUNC_HAS_EJ0; | 148 | newfunc->flags = FUNC_HAS_EJ0; |
210 | 149 | ||
211 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp))) | 150 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp))) |
@@ -256,8 +195,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
256 | bridge->nr_slots++; | 195 | bridge->nr_slots++; |
257 | 196 | ||
258 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", | 197 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", |
259 | slot->sun, pci_domain_nr(bridge->pci_bus), | 198 | slot->sun, pci_domain_nr(pbus), pbus->number, device); |
260 | bridge->pci_bus->number, slot->device); | ||
261 | retval = acpiphp_register_hotplug_slot(slot); | 199 | retval = acpiphp_register_hotplug_slot(slot); |
262 | if (retval) { | 200 | if (retval) { |
263 | if (retval == -EBUSY) | 201 | if (retval == -EBUSY) |
@@ -274,8 +212,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
274 | list_add_tail(&newfunc->sibling, &slot->funcs); | 212 | list_add_tail(&newfunc->sibling, &slot->funcs); |
275 | 213 | ||
276 | /* associate corresponding pci_dev */ | 214 | /* associate corresponding pci_dev */ |
277 | newfunc->pci_dev = pci_get_slot(bridge->pci_bus, | 215 | newfunc->pci_dev = pci_get_slot(pbus, PCI_DEVFN(device, function)); |
278 | PCI_DEVFN(device, function)); | ||
279 | if (newfunc->pci_dev) { | 216 | if (newfunc->pci_dev) { |
280 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 217 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
281 | } | 218 | } |
@@ -324,27 +261,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
324 | 261 | ||
325 | 262 | ||
326 | /* see if it's worth looking at this bridge */ | 263 | /* see if it's worth looking at this bridge */ |
327 | static int detect_ejectable_slots(acpi_handle *bridge_handle) | 264 | static int detect_ejectable_slots(struct pci_bus *pbus) |
328 | { | 265 | { |
329 | acpi_status status; | 266 | int found = acpi_pci_detect_ejectable(pbus); |
330 | int count; | 267 | if (!found) { |
331 | 268 | acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus); | |
332 | count = 0; | 269 | acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1, |
333 | 270 | is_pci_dock_device, (void *)&found, NULL); | |
334 | /* only check slots defined directly below bridge object */ | 271 | } |
335 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1, | 272 | return found; |
336 | is_ejectable_slot, (void *)&count, NULL); | ||
337 | |||
338 | /* | ||
339 | * we also need to add this bridge if there is a dock bridge or | ||
340 | * other pci device on a dock station (removable) | ||
341 | */ | ||
342 | if (!count) | ||
343 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, | ||
344 | (u32)1, is_pci_dock_device, (void *)&count, | ||
345 | NULL); | ||
346 | |||
347 | return count; | ||
348 | } | 273 | } |
349 | 274 | ||
350 | 275 | ||
@@ -554,7 +479,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
554 | goto out; | 479 | goto out; |
555 | 480 | ||
556 | /* check if this bridge has ejectable slots */ | 481 | /* check if this bridge has ejectable slots */ |
557 | if ((detect_ejectable_slots(handle) > 0)) { | 482 | if ((detect_ejectable_slots(dev->subordinate) > 0)) { |
558 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); | 483 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); |
559 | add_p2p_bridge(handle, dev); | 484 | add_p2p_bridge(handle, dev); |
560 | } | 485 | } |
@@ -615,7 +540,7 @@ static int add_bridge(acpi_handle handle) | |||
615 | } | 540 | } |
616 | 541 | ||
617 | /* check if this bridge has ejectable slots */ | 542 | /* check if this bridge has ejectable slots */ |
618 | if (detect_ejectable_slots(handle) > 0) { | 543 | if (detect_ejectable_slots(pci_bus) > 0) { |
619 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); | 544 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); |
620 | add_host_bridge(handle, pci_bus); | 545 | add_host_bridge(handle, pci_bus); |
621 | } | 546 | } |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 881fdd2b7313..5befa7e379b7 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -271,7 +271,7 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) | |||
271 | dbg("%s: generationg bus event\n", __func__); | 271 | dbg("%s: generationg bus event\n", __func__); |
272 | acpi_bus_generate_proc_event(note->device, note->event, detail); | 272 | acpi_bus_generate_proc_event(note->device, note->event, detail); |
273 | acpi_bus_generate_netlink_event(note->device->pnp.device_class, | 273 | acpi_bus_generate_netlink_event(note->device->pnp.device_class, |
274 | note->device->dev.bus_id, | 274 | dev_name(¬e->device->dev), |
275 | note->event, detail); | 275 | note->event, detail); |
276 | } else | 276 | } else |
277 | note->event = event; | 277 | note->event = event; |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index a60a25290995..cc227a8c4b11 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -1954,7 +1954,7 @@ void cpqhp_pushbutton_thread(unsigned long slot) | |||
1954 | return ; | 1954 | return ; |
1955 | } | 1955 | } |
1956 | 1956 | ||
1957 | if (func != NULL && ctrl != NULL) { | 1957 | if (ctrl != NULL) { |
1958 | if (cpqhp_process_SI(ctrl, func) != 0) { | 1958 | if (cpqhp_process_SI(ctrl, func) != 0) { |
1959 | amber_LED_on(ctrl, hp_slot); | 1959 | amber_LED_on(ctrl, hp_slot); |
1960 | green_LED_off(ctrl, hp_slot); | 1960 | green_LED_off(ctrl, hp_slot); |
@@ -2604,7 +2604,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2604 | for (cloop = 0; cloop < 4; cloop++) { | 2604 | for (cloop = 0; cloop < 4; cloop++) { |
2605 | if (irqs.valid_INT & (0x01 << cloop)) { | 2605 | if (irqs.valid_INT & (0x01 << cloop)) { |
2606 | rc = cpqhp_set_irq(func->bus, func->device, | 2606 | rc = cpqhp_set_irq(func->bus, func->device, |
2607 | 0x0A + cloop, irqs.interrupt[cloop]); | 2607 | cloop + 1, irqs.interrupt[cloop]); |
2608 | if (rc) | 2608 | if (rc) |
2609 | goto free_and_out; | 2609 | goto free_and_out; |
2610 | } | 2610 | } |
@@ -2945,7 +2945,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2945 | } | 2945 | } |
2946 | 2946 | ||
2947 | if (!behind_bridge) { | 2947 | if (!behind_bridge) { |
2948 | rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ); | 2948 | rc = cpqhp_set_irq(func->bus, func->device, temp_byte, IRQ); |
2949 | if (rc) | 2949 | if (rc) |
2950 | return 1; | 2950 | return 1; |
2951 | } else { | 2951 | } else { |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index df146be9d2e9..6c0ed0fcb8ee 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -171,7 +171,7 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) | |||
171 | fakebus->number = bus_num; | 171 | fakebus->number = bus_num; |
172 | dbg("%s: dev %d, bus %d, pin %d, num %d\n", | 172 | dbg("%s: dev %d, bus %d, pin %d, num %d\n", |
173 | __func__, dev_num, bus_num, int_pin, irq_num); | 173 | __func__, dev_num, bus_num, int_pin, irq_num); |
174 | rc = pcibios_set_irq_routing(fakedev, int_pin - 0x0a, irq_num); | 174 | rc = pcibios_set_irq_routing(fakedev, int_pin - 1, irq_num); |
175 | kfree(fakedev); | 175 | kfree(fakedev); |
176 | kfree(fakebus); | 176 | kfree(fakebus); |
177 | dbg("%s: rc %d\n", __func__, rc); | 177 | dbg("%s: rc %d\n", __func__, rc); |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 3a2637a00934..b0e7de9e536d 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -324,6 +324,7 @@ static int disable_slot(struct hotplug_slot *slot) | |||
324 | 324 | ||
325 | if (test_and_set_bit(0, &dslot->removed)) { | 325 | if (test_and_set_bit(0, &dslot->removed)) { |
326 | dbg("Slot already scheduled for removal\n"); | 326 | dbg("Slot already scheduled for removal\n"); |
327 | pci_dev_put(dev); | ||
327 | return -ENODEV; | 328 | return -ENODEV; |
328 | } | 329 | } |
329 | 330 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index b2801a7ee37f..27fd18f019f8 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -220,11 +220,23 @@ struct hpc_ops { | |||
220 | #include <acpi/actypes.h> | 220 | #include <acpi/actypes.h> |
221 | #include <linux/pci-acpi.h> | 221 | #include <linux/pci-acpi.h> |
222 | 222 | ||
223 | extern void __init pciehp_acpi_slot_detection_init(void); | ||
224 | extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); | ||
225 | |||
226 | static inline void pciehp_firmware_init(void) | ||
227 | { | ||
228 | pciehp_acpi_slot_detection_init(); | ||
229 | } | ||
230 | |||
223 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) | 231 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) |
224 | { | 232 | { |
233 | int retval; | ||
225 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | 234 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | |
226 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | 235 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); |
227 | return acpi_get_hp_hw_control_from_firmware(dev, flags); | 236 | retval = acpi_get_hp_hw_control_from_firmware(dev, flags); |
237 | if (retval) | ||
238 | return retval; | ||
239 | return pciehp_acpi_slot_detection_check(dev); | ||
228 | } | 240 | } |
229 | 241 | ||
230 | static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, | 242 | static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, |
@@ -235,6 +247,7 @@ static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, | |||
235 | return 0; | 247 | return 0; |
236 | } | 248 | } |
237 | #else | 249 | #else |
250 | #define pciehp_firmware_init() do {} while (0) | ||
238 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 | 251 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 |
239 | #define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) | 252 | #define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) |
240 | #endif /* CONFIG_ACPI */ | 253 | #endif /* CONFIG_ACPI */ |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c new file mode 100644 index 000000000000..438d795f9fe3 --- /dev/null +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * ACPI related functions for PCI Express Hot Plug driver. | ||
3 | * | ||
4 | * Copyright (C) 2008 Kenji Kaneshige | ||
5 | * Copyright (C) 2008 Fujitsu Limited. | ||
6 | * | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
17 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
18 | * details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/acpi.h> | ||
27 | #include <linux/pci.h> | ||
28 | #include <linux/pci_hotplug.h> | ||
29 | #include "pciehp.h" | ||
30 | |||
31 | #define PCIEHP_DETECT_PCIE (0) | ||
32 | #define PCIEHP_DETECT_ACPI (1) | ||
33 | #define PCIEHP_DETECT_AUTO (2) | ||
34 | #define PCIEHP_DETECT_DEFAULT PCIEHP_DETECT_AUTO | ||
35 | |||
36 | static int slot_detection_mode; | ||
37 | static char *pciehp_detect_mode; | ||
38 | module_param(pciehp_detect_mode, charp, 0444); | ||
39 | MODULE_PARM_DESC(pciehp_detect_mode, | ||
40 | "Slot detection mode: pcie, acpi, auto\n" | ||
41 | " pcie - Use PCIe based slot detection\n" | ||
42 | " acpi - Use ACPI for slot detection\n" | ||
43 | " auto(default) - Auto select mode. Use acpi option if duplicate\n" | ||
44 | " slot ids are found. Otherwise, use pcie option\n"); | ||
45 | |||
46 | int pciehp_acpi_slot_detection_check(struct pci_dev *dev) | ||
47 | { | ||
48 | if (slot_detection_mode != PCIEHP_DETECT_ACPI) | ||
49 | return 0; | ||
50 | if (acpi_pci_detect_ejectable(dev->subordinate)) | ||
51 | return 0; | ||
52 | return -ENODEV; | ||
53 | } | ||
54 | |||
55 | static int __init parse_detect_mode(void) | ||
56 | { | ||
57 | if (!pciehp_detect_mode) | ||
58 | return PCIEHP_DETECT_DEFAULT; | ||
59 | if (!strcmp(pciehp_detect_mode, "pcie")) | ||
60 | return PCIEHP_DETECT_PCIE; | ||
61 | if (!strcmp(pciehp_detect_mode, "acpi")) | ||
62 | return PCIEHP_DETECT_ACPI; | ||
63 | if (!strcmp(pciehp_detect_mode, "auto")) | ||
64 | return PCIEHP_DETECT_AUTO; | ||
65 | warn("bad specifier '%s' for pciehp_detect_mode. Use default\n", | ||
66 | pciehp_detect_mode); | ||
67 | return PCIEHP_DETECT_DEFAULT; | ||
68 | } | ||
69 | |||
70 | static struct pcie_port_service_id __initdata port_pci_ids[] = { | ||
71 | { | ||
72 | .vendor = PCI_ANY_ID, | ||
73 | .device = PCI_ANY_ID, | ||
74 | .port_type = PCIE_ANY_PORT, | ||
75 | .service_type = PCIE_PORT_SERVICE_HP, | ||
76 | .driver_data = 0, | ||
77 | }, { /* end: all zeroes */ } | ||
78 | }; | ||
79 | |||
80 | static int __initdata dup_slot_id; | ||
81 | static int __initdata acpi_slot_detected; | ||
82 | static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots); | ||
83 | |||
84 | /* Dummy driver for dumplicate name detection */ | ||
85 | static int __init dummy_probe(struct pcie_device *dev, | ||
86 | const struct pcie_port_service_id *id) | ||
87 | { | ||
88 | int pos; | ||
89 | u32 slot_cap; | ||
90 | struct slot *slot, *tmp; | ||
91 | struct pci_dev *pdev = dev->port; | ||
92 | struct pci_bus *pbus = pdev->subordinate; | ||
93 | if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL))) | ||
94 | return -ENOMEM; | ||
95 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | ||
96 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | ||
97 | return -ENODEV; | ||
98 | if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP))) | ||
99 | return -ENODEV; | ||
100 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); | ||
101 | slot->number = slot_cap >> 19; | ||
102 | list_for_each_entry(tmp, &dummy_slots, slot_list) { | ||
103 | if (tmp->number == slot->number) | ||
104 | dup_slot_id++; | ||
105 | } | ||
106 | list_add_tail(&slot->slot_list, &dummy_slots); | ||
107 | if (!acpi_slot_detected && acpi_pci_detect_ejectable(pbus)) | ||
108 | acpi_slot_detected = 1; | ||
109 | return -ENODEV; /* dummy driver always returns error */ | ||
110 | } | ||
111 | |||
112 | static struct pcie_port_service_driver __initdata dummy_driver = { | ||
113 | .name = "pciehp_dummy", | ||
114 | .id_table = port_pci_ids, | ||
115 | .probe = dummy_probe, | ||
116 | }; | ||
117 | |||
118 | static int __init select_detection_mode(void) | ||
119 | { | ||
120 | struct slot *slot, *tmp; | ||
121 | pcie_port_service_register(&dummy_driver); | ||
122 | pcie_port_service_unregister(&dummy_driver); | ||
123 | list_for_each_entry_safe(slot, tmp, &dummy_slots, slot_list) { | ||
124 | list_del(&slot->slot_list); | ||
125 | kfree(slot); | ||
126 | } | ||
127 | if (acpi_slot_detected && dup_slot_id) | ||
128 | return PCIEHP_DETECT_ACPI; | ||
129 | return PCIEHP_DETECT_PCIE; | ||
130 | } | ||
131 | |||
132 | void __init pciehp_acpi_slot_detection_init(void) | ||
133 | { | ||
134 | slot_detection_mode = parse_detect_mode(); | ||
135 | if (slot_detection_mode != PCIEHP_DETECT_AUTO) | ||
136 | goto out; | ||
137 | slot_detection_mode = select_detection_mode(); | ||
138 | out: | ||
139 | if (slot_detection_mode == PCIEHP_DETECT_ACPI) | ||
140 | info("Using ACPI for slot detection.\n"); | ||
141 | } | ||
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 39cf248d24e3..5482d4ed8256 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -522,6 +522,7 @@ static int __init pcied_init(void) | |||
522 | { | 522 | { |
523 | int retval = 0; | 523 | int retval = 0; |
524 | 524 | ||
525 | pciehp_firmware_init(); | ||
525 | retval = pcie_port_service_register(&hpdriver_portdrv); | 526 | retval = pcie_port_service_register(&hpdriver_portdrv); |
526 | dbg("pcie_port_service_register = %d\n", retval); | 527 | dbg("pcie_port_service_register = %d\n", retval); |
527 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 528 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index fead63c6b49e..ff4034502d24 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -178,15 +178,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
178 | "Issue of Slot Power Off command failed\n"); | 178 | "Issue of Slot Power Off command failed\n"); |
179 | return; | 179 | return; |
180 | } | 180 | } |
181 | /* | ||
182 | * After turning power off, we must wait for at least 1 second | ||
183 | * before taking any action that relies on power having been | ||
184 | * removed from the slot/adapter. | ||
185 | */ | ||
186 | msleep(1000); | ||
181 | } | 187 | } |
182 | 188 | ||
183 | /* | ||
184 | * After turning power off, we must wait for at least 1 second | ||
185 | * before taking any action that relies on power having been | ||
186 | * removed from the slot/adapter. | ||
187 | */ | ||
188 | msleep(1000); | ||
189 | |||
190 | if (PWR_LED(ctrl)) | 189 | if (PWR_LED(ctrl)) |
191 | pslot->hpc_ops->green_led_off(pslot); | 190 | pslot->hpc_ops->green_led_off(pslot); |
192 | 191 | ||
@@ -286,15 +285,14 @@ static int remove_board(struct slot *p_slot) | |||
286 | "Issue of Slot Disable command failed\n"); | 285 | "Issue of Slot Disable command failed\n"); |
287 | return retval; | 286 | return retval; |
288 | } | 287 | } |
288 | /* | ||
289 | * After turning power off, we must wait for at least 1 second | ||
290 | * before taking any action that relies on power having been | ||
291 | * removed from the slot/adapter. | ||
292 | */ | ||
293 | msleep(1000); | ||
289 | } | 294 | } |
290 | 295 | ||
291 | /* | ||
292 | * After turning power off, we must wait for at least 1 second | ||
293 | * before taking any action that relies on power having been | ||
294 | * removed from the slot/adapter. | ||
295 | */ | ||
296 | msleep(1000); | ||
297 | |||
298 | if (PWR_LED(ctrl)) | 296 | if (PWR_LED(ctrl)) |
299 | /* turn off Green LED */ | 297 | /* turn off Green LED */ |
300 | p_slot->hpc_ops->green_led_off(p_slot); | 298 | p_slot->hpc_ops->green_led_off(p_slot); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index b643ca13e4f1..71a8012886b0 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -42,42 +42,6 @@ | |||
42 | 42 | ||
43 | static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); | 43 | static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); |
44 | 44 | ||
45 | struct ctrl_reg { | ||
46 | u8 cap_id; | ||
47 | u8 nxt_ptr; | ||
48 | u16 cap_reg; | ||
49 | u32 dev_cap; | ||
50 | u16 dev_ctrl; | ||
51 | u16 dev_status; | ||
52 | u32 lnk_cap; | ||
53 | u16 lnk_ctrl; | ||
54 | u16 lnk_status; | ||
55 | u32 slot_cap; | ||
56 | u16 slot_ctrl; | ||
57 | u16 slot_status; | ||
58 | u16 root_ctrl; | ||
59 | u16 rsvp; | ||
60 | u32 root_status; | ||
61 | } __attribute__ ((packed)); | ||
62 | |||
63 | /* offsets to the controller registers based on the above structure layout */ | ||
64 | enum ctrl_offsets { | ||
65 | PCIECAPID = offsetof(struct ctrl_reg, cap_id), | ||
66 | NXTCAPPTR = offsetof(struct ctrl_reg, nxt_ptr), | ||
67 | CAPREG = offsetof(struct ctrl_reg, cap_reg), | ||
68 | DEVCAP = offsetof(struct ctrl_reg, dev_cap), | ||
69 | DEVCTRL = offsetof(struct ctrl_reg, dev_ctrl), | ||
70 | DEVSTATUS = offsetof(struct ctrl_reg, dev_status), | ||
71 | LNKCAP = offsetof(struct ctrl_reg, lnk_cap), | ||
72 | LNKCTRL = offsetof(struct ctrl_reg, lnk_ctrl), | ||
73 | LNKSTATUS = offsetof(struct ctrl_reg, lnk_status), | ||
74 | SLOTCAP = offsetof(struct ctrl_reg, slot_cap), | ||
75 | SLOTCTRL = offsetof(struct ctrl_reg, slot_ctrl), | ||
76 | SLOTSTATUS = offsetof(struct ctrl_reg, slot_status), | ||
77 | ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl), | ||
78 | ROOTSTATUS = offsetof(struct ctrl_reg, root_status), | ||
79 | }; | ||
80 | |||
81 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | 45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) |
82 | { | 46 | { |
83 | struct pci_dev *dev = ctrl->pci_dev; | 47 | struct pci_dev *dev = ctrl->pci_dev; |
@@ -102,95 +66,9 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) | |||
102 | return pci_write_config_dword(dev, ctrl->cap_base + reg, value); | 66 | return pci_write_config_dword(dev, ctrl->cap_base + reg, value); |
103 | } | 67 | } |
104 | 68 | ||
105 | /* Field definitions in PCI Express Capabilities Register */ | ||
106 | #define CAP_VER 0x000F | ||
107 | #define DEV_PORT_TYPE 0x00F0 | ||
108 | #define SLOT_IMPL 0x0100 | ||
109 | #define MSG_NUM 0x3E00 | ||
110 | |||
111 | /* Device or Port Type */ | ||
112 | #define NAT_ENDPT 0x00 | ||
113 | #define LEG_ENDPT 0x01 | ||
114 | #define ROOT_PORT 0x04 | ||
115 | #define UP_STREAM 0x05 | ||
116 | #define DN_STREAM 0x06 | ||
117 | #define PCIE_PCI_BRDG 0x07 | ||
118 | #define PCI_PCIE_BRDG 0x10 | ||
119 | |||
120 | /* Field definitions in Device Capabilities Register */ | ||
121 | #define DATTN_BUTTN_PRSN 0x1000 | ||
122 | #define DATTN_LED_PRSN 0x2000 | ||
123 | #define DPWR_LED_PRSN 0x4000 | ||
124 | |||
125 | /* Field definitions in Link Capabilities Register */ | ||
126 | #define MAX_LNK_SPEED 0x000F | ||
127 | #define MAX_LNK_WIDTH 0x03F0 | ||
128 | #define LINK_ACTIVE_REPORTING 0x00100000 | ||
129 | |||
130 | /* Link Width Encoding */ | ||
131 | #define LNK_X1 0x01 | ||
132 | #define LNK_X2 0x02 | ||
133 | #define LNK_X4 0x04 | ||
134 | #define LNK_X8 0x08 | ||
135 | #define LNK_X12 0x0C | ||
136 | #define LNK_X16 0x10 | ||
137 | #define LNK_X32 0x20 | ||
138 | |||
139 | /*Field definitions of Link Status Register */ | ||
140 | #define LNK_SPEED 0x000F | ||
141 | #define NEG_LINK_WD 0x03F0 | ||
142 | #define LNK_TRN_ERR 0x0400 | ||
143 | #define LNK_TRN 0x0800 | ||
144 | #define SLOT_CLK_CONF 0x1000 | ||
145 | #define LINK_ACTIVE 0x2000 | ||
146 | |||
147 | /* Field definitions in Slot Capabilities Register */ | ||
148 | #define ATTN_BUTTN_PRSN 0x00000001 | ||
149 | #define PWR_CTRL_PRSN 0x00000002 | ||
150 | #define MRL_SENS_PRSN 0x00000004 | ||
151 | #define ATTN_LED_PRSN 0x00000008 | ||
152 | #define PWR_LED_PRSN 0x00000010 | ||
153 | #define HP_SUPR_RM_SUP 0x00000020 | ||
154 | #define HP_CAP 0x00000040 | ||
155 | #define SLOT_PWR_VALUE 0x000003F8 | ||
156 | #define SLOT_PWR_LIMIT 0x00000C00 | ||
157 | #define PSN 0xFFF80000 /* PSN: Physical Slot Number */ | ||
158 | |||
159 | /* Field definitions in Slot Control Register */ | ||
160 | #define ATTN_BUTTN_ENABLE 0x0001 | ||
161 | #define PWR_FAULT_DETECT_ENABLE 0x0002 | ||
162 | #define MRL_DETECT_ENABLE 0x0004 | ||
163 | #define PRSN_DETECT_ENABLE 0x0008 | ||
164 | #define CMD_CMPL_INTR_ENABLE 0x0010 | ||
165 | #define HP_INTR_ENABLE 0x0020 | ||
166 | #define ATTN_LED_CTRL 0x00C0 | ||
167 | #define PWR_LED_CTRL 0x0300 | ||
168 | #define PWR_CTRL 0x0400 | ||
169 | #define EMI_CTRL 0x0800 | ||
170 | |||
171 | /* Attention indicator and Power indicator states */ | ||
172 | #define LED_ON 0x01 | ||
173 | #define LED_BLINK 0x10 | ||
174 | #define LED_OFF 0x11 | ||
175 | |||
176 | /* Power Control Command */ | 69 | /* Power Control Command */ |
177 | #define POWER_ON 0 | 70 | #define POWER_ON 0 |
178 | #define POWER_OFF 0x0400 | 71 | #define POWER_OFF PCI_EXP_SLTCTL_PCC |
179 | |||
180 | /* EMI Status defines */ | ||
181 | #define EMI_DISENGAGED 0 | ||
182 | #define EMI_ENGAGED 1 | ||
183 | |||
184 | /* Field definitions in Slot Status Register */ | ||
185 | #define ATTN_BUTTN_PRESSED 0x0001 | ||
186 | #define PWR_FAULT_DETECTED 0x0002 | ||
187 | #define MRL_SENS_CHANGED 0x0004 | ||
188 | #define PRSN_DETECT_CHANGED 0x0008 | ||
189 | #define CMD_COMPLETED 0x0010 | ||
190 | #define MRL_STATE 0x0020 | ||
191 | #define PRSN_STATE 0x0040 | ||
192 | #define EMI_STATE 0x0080 | ||
193 | #define EMI_STATUS_BIT 7 | ||
194 | 72 | ||
195 | static irqreturn_t pcie_isr(int irq, void *dev_id); | 73 | static irqreturn_t pcie_isr(int irq, void *dev_id); |
196 | static void start_int_poll_timer(struct controller *ctrl, int sec); | 74 | static void start_int_poll_timer(struct controller *ctrl, int sec); |
@@ -253,22 +131,20 @@ static inline void pciehp_free_irq(struct controller *ctrl) | |||
253 | static int pcie_poll_cmd(struct controller *ctrl) | 131 | static int pcie_poll_cmd(struct controller *ctrl) |
254 | { | 132 | { |
255 | u16 slot_status; | 133 | u16 slot_status; |
256 | int timeout = 1000; | 134 | int err, timeout = 1000; |
257 | 135 | ||
258 | if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) { | 136 | err = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
259 | if (slot_status & CMD_COMPLETED) { | 137 | if (!err && (slot_status & PCI_EXP_SLTSTA_CC)) { |
260 | pciehp_writew(ctrl, SLOTSTATUS, CMD_COMPLETED); | 138 | pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_CC); |
261 | return 1; | 139 | return 1; |
262 | } | ||
263 | } | 140 | } |
264 | while (timeout > 0) { | 141 | while (timeout > 0) { |
265 | msleep(10); | 142 | msleep(10); |
266 | timeout -= 10; | 143 | timeout -= 10; |
267 | if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) { | 144 | err = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
268 | if (slot_status & CMD_COMPLETED) { | 145 | if (!err && (slot_status & PCI_EXP_SLTSTA_CC)) { |
269 | pciehp_writew(ctrl, SLOTSTATUS, CMD_COMPLETED); | 146 | pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_CC); |
270 | return 1; | 147 | return 1; |
271 | } | ||
272 | } | 148 | } |
273 | } | 149 | } |
274 | return 0; /* timeout */ | 150 | return 0; /* timeout */ |
@@ -302,14 +178,14 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
302 | 178 | ||
303 | mutex_lock(&ctrl->ctrl_lock); | 179 | mutex_lock(&ctrl->ctrl_lock); |
304 | 180 | ||
305 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 181 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
306 | if (retval) { | 182 | if (retval) { |
307 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", | 183 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
308 | __func__); | 184 | __func__); |
309 | goto out; | 185 | goto out; |
310 | } | 186 | } |
311 | 187 | ||
312 | if (slot_status & CMD_COMPLETED) { | 188 | if (slot_status & PCI_EXP_SLTSTA_CC) { |
313 | if (!ctrl->no_cmd_complete) { | 189 | if (!ctrl->no_cmd_complete) { |
314 | /* | 190 | /* |
315 | * After 1 sec and CMD_COMPLETED still not set, just | 191 | * After 1 sec and CMD_COMPLETED still not set, just |
@@ -332,7 +208,7 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
332 | } | 208 | } |
333 | } | 209 | } |
334 | 210 | ||
335 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 211 | retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); |
336 | if (retval) { | 212 | if (retval) { |
337 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); | 213 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
338 | goto out; | 214 | goto out; |
@@ -342,7 +218,7 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
342 | slot_ctrl |= (cmd & mask); | 218 | slot_ctrl |= (cmd & mask); |
343 | ctrl->cmd_busy = 1; | 219 | ctrl->cmd_busy = 1; |
344 | smp_mb(); | 220 | smp_mb(); |
345 | retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl); | 221 | retval = pciehp_writew(ctrl, PCI_EXP_SLTCTL, slot_ctrl); |
346 | if (retval) | 222 | if (retval) |
347 | ctrl_err(ctrl, "Cannot write to SLOTCTRL register\n"); | 223 | ctrl_err(ctrl, "Cannot write to SLOTCTRL register\n"); |
348 | 224 | ||
@@ -356,8 +232,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
356 | * completed interrupt is not enabled, we need to poll | 232 | * completed interrupt is not enabled, we need to poll |
357 | * command completed event. | 233 | * command completed event. |
358 | */ | 234 | */ |
359 | if (!(slot_ctrl & HP_INTR_ENABLE) || | 235 | if (!(slot_ctrl & PCI_EXP_SLTCTL_HPIE) || |
360 | !(slot_ctrl & CMD_CMPL_INTR_ENABLE)) | 236 | !(slot_ctrl & PCI_EXP_SLTCTL_CCIE)) |
361 | poll = 1; | 237 | poll = 1; |
362 | pcie_wait_cmd(ctrl, poll); | 238 | pcie_wait_cmd(ctrl, poll); |
363 | } | 239 | } |
@@ -370,9 +246,9 @@ static inline int check_link_active(struct controller *ctrl) | |||
370 | { | 246 | { |
371 | u16 link_status; | 247 | u16 link_status; |
372 | 248 | ||
373 | if (pciehp_readw(ctrl, LNKSTATUS, &link_status)) | 249 | if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &link_status)) |
374 | return 0; | 250 | return 0; |
375 | return !!(link_status & LINK_ACTIVE); | 251 | return !!(link_status & PCI_EXP_LNKSTA_DLLLA); |
376 | } | 252 | } |
377 | 253 | ||
378 | static void pcie_wait_link_active(struct controller *ctrl) | 254 | static void pcie_wait_link_active(struct controller *ctrl) |
@@ -412,15 +288,15 @@ static int hpc_check_lnk_status(struct controller *ctrl) | |||
412 | } else | 288 | } else |
413 | msleep(1000); | 289 | msleep(1000); |
414 | 290 | ||
415 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); | 291 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
416 | if (retval) { | 292 | if (retval) { |
417 | ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); | 293 | ctrl_err(ctrl, "Cannot read LNKSTATUS register\n"); |
418 | return retval; | 294 | return retval; |
419 | } | 295 | } |
420 | 296 | ||
421 | ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); | 297 | ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); |
422 | if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || | 298 | if ((lnk_status & PCI_EXP_LNKSTA_LT) || |
423 | !(lnk_status & NEG_LINK_WD)) { | 299 | !(lnk_status & PCI_EXP_LNKSTA_NLW)) { |
424 | ctrl_err(ctrl, "Link Training Error occurs \n"); | 300 | ctrl_err(ctrl, "Link Training Error occurs \n"); |
425 | retval = -1; | 301 | retval = -1; |
426 | return retval; | 302 | return retval; |
@@ -436,16 +312,16 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
436 | u8 atten_led_state; | 312 | u8 atten_led_state; |
437 | int retval = 0; | 313 | int retval = 0; |
438 | 314 | ||
439 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 315 | retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); |
440 | if (retval) { | 316 | if (retval) { |
441 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); | 317 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
442 | return retval; | 318 | return retval; |
443 | } | 319 | } |
444 | 320 | ||
445 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", | 321 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", |
446 | __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | 322 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); |
447 | 323 | ||
448 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; | 324 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; |
449 | 325 | ||
450 | switch (atten_led_state) { | 326 | switch (atten_led_state) { |
451 | case 0: | 327 | case 0: |
@@ -475,15 +351,15 @@ static int hpc_get_power_status(struct slot *slot, u8 *status) | |||
475 | u8 pwr_state; | 351 | u8 pwr_state; |
476 | int retval = 0; | 352 | int retval = 0; |
477 | 353 | ||
478 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 354 | retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); |
479 | if (retval) { | 355 | if (retval) { |
480 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); | 356 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
481 | return retval; | 357 | return retval; |
482 | } | 358 | } |
483 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", | 359 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", |
484 | __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | 360 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); |
485 | 361 | ||
486 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; | 362 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; |
487 | 363 | ||
488 | switch (pwr_state) { | 364 | switch (pwr_state) { |
489 | case 0: | 365 | case 0: |
@@ -504,17 +380,15 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
504 | { | 380 | { |
505 | struct controller *ctrl = slot->ctrl; | 381 | struct controller *ctrl = slot->ctrl; |
506 | u16 slot_status; | 382 | u16 slot_status; |
507 | int retval = 0; | 383 | int retval; |
508 | 384 | ||
509 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 385 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
510 | if (retval) { | 386 | if (retval) { |
511 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", | 387 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
512 | __func__); | 388 | __func__); |
513 | return retval; | 389 | return retval; |
514 | } | 390 | } |
515 | 391 | *status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS); | |
516 | *status = (((slot_status & MRL_STATE) >> 5) == 0) ? 0 : 1; | ||
517 | |||
518 | return 0; | 392 | return 0; |
519 | } | 393 | } |
520 | 394 | ||
@@ -522,18 +396,15 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
522 | { | 396 | { |
523 | struct controller *ctrl = slot->ctrl; | 397 | struct controller *ctrl = slot->ctrl; |
524 | u16 slot_status; | 398 | u16 slot_status; |
525 | u8 card_state; | 399 | int retval; |
526 | int retval = 0; | ||
527 | 400 | ||
528 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 401 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
529 | if (retval) { | 402 | if (retval) { |
530 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", | 403 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
531 | __func__); | 404 | __func__); |
532 | return retval; | 405 | return retval; |
533 | } | 406 | } |
534 | card_state = (u8)((slot_status & PRSN_STATE) >> 6); | 407 | *status = !!(slot_status & PCI_EXP_SLTSTA_PDS); |
535 | *status = (card_state == 1) ? 1 : 0; | ||
536 | |||
537 | return 0; | 408 | return 0; |
538 | } | 409 | } |
539 | 410 | ||
@@ -541,32 +412,28 @@ static int hpc_query_power_fault(struct slot *slot) | |||
541 | { | 412 | { |
542 | struct controller *ctrl = slot->ctrl; | 413 | struct controller *ctrl = slot->ctrl; |
543 | u16 slot_status; | 414 | u16 slot_status; |
544 | u8 pwr_fault; | 415 | int retval; |
545 | int retval = 0; | ||
546 | 416 | ||
547 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 417 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
548 | if (retval) { | 418 | if (retval) { |
549 | ctrl_err(ctrl, "Cannot check for power fault\n"); | 419 | ctrl_err(ctrl, "Cannot check for power fault\n"); |
550 | return retval; | 420 | return retval; |
551 | } | 421 | } |
552 | pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); | 422 | return !!(slot_status & PCI_EXP_SLTSTA_PFD); |
553 | |||
554 | return pwr_fault; | ||
555 | } | 423 | } |
556 | 424 | ||
557 | static int hpc_get_emi_status(struct slot *slot, u8 *status) | 425 | static int hpc_get_emi_status(struct slot *slot, u8 *status) |
558 | { | 426 | { |
559 | struct controller *ctrl = slot->ctrl; | 427 | struct controller *ctrl = slot->ctrl; |
560 | u16 slot_status; | 428 | u16 slot_status; |
561 | int retval = 0; | 429 | int retval; |
562 | 430 | ||
563 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 431 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
564 | if (retval) { | 432 | if (retval) { |
565 | ctrl_err(ctrl, "Cannot check EMI status\n"); | 433 | ctrl_err(ctrl, "Cannot check EMI status\n"); |
566 | return retval; | 434 | return retval; |
567 | } | 435 | } |
568 | *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; | 436 | *status = !!(slot_status & PCI_EXP_SLTSTA_EIS); |
569 | |||
570 | return retval; | 437 | return retval; |
571 | } | 438 | } |
572 | 439 | ||
@@ -576,8 +443,8 @@ static int hpc_toggle_emi(struct slot *slot) | |||
576 | u16 cmd_mask; | 443 | u16 cmd_mask; |
577 | int rc; | 444 | int rc; |
578 | 445 | ||
579 | slot_cmd = EMI_CTRL; | 446 | slot_cmd = PCI_EXP_SLTCTL_EIC; |
580 | cmd_mask = EMI_CTRL; | 447 | cmd_mask = PCI_EXP_SLTCTL_EIC; |
581 | rc = pcie_write_cmd(slot->ctrl, slot_cmd, cmd_mask); | 448 | rc = pcie_write_cmd(slot->ctrl, slot_cmd, cmd_mask); |
582 | slot->last_emi_toggle = get_seconds(); | 449 | slot->last_emi_toggle = get_seconds(); |
583 | 450 | ||
@@ -591,7 +458,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
591 | u16 cmd_mask; | 458 | u16 cmd_mask; |
592 | int rc; | 459 | int rc; |
593 | 460 | ||
594 | cmd_mask = ATTN_LED_CTRL; | 461 | cmd_mask = PCI_EXP_SLTCTL_AIC; |
595 | switch (value) { | 462 | switch (value) { |
596 | case 0 : /* turn off */ | 463 | case 0 : /* turn off */ |
597 | slot_cmd = 0x00C0; | 464 | slot_cmd = 0x00C0; |
@@ -607,7 +474,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
607 | } | 474 | } |
608 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 475 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
609 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 476 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
610 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 477 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); |
611 | 478 | ||
612 | return rc; | 479 | return rc; |
613 | } | 480 | } |
@@ -619,10 +486,10 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
619 | u16 cmd_mask; | 486 | u16 cmd_mask; |
620 | 487 | ||
621 | slot_cmd = 0x0100; | 488 | slot_cmd = 0x0100; |
622 | cmd_mask = PWR_LED_CTRL; | 489 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
623 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 490 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
624 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 491 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
625 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 492 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); |
626 | } | 493 | } |
627 | 494 | ||
628 | static void hpc_set_green_led_off(struct slot *slot) | 495 | static void hpc_set_green_led_off(struct slot *slot) |
@@ -632,10 +499,10 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
632 | u16 cmd_mask; | 499 | u16 cmd_mask; |
633 | 500 | ||
634 | slot_cmd = 0x0300; | 501 | slot_cmd = 0x0300; |
635 | cmd_mask = PWR_LED_CTRL; | 502 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
636 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 503 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
637 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 504 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
638 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 505 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); |
639 | } | 506 | } |
640 | 507 | ||
641 | static void hpc_set_green_led_blink(struct slot *slot) | 508 | static void hpc_set_green_led_blink(struct slot *slot) |
@@ -645,10 +512,10 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
645 | u16 cmd_mask; | 512 | u16 cmd_mask; |
646 | 513 | ||
647 | slot_cmd = 0x0200; | 514 | slot_cmd = 0x0200; |
648 | cmd_mask = PWR_LED_CTRL; | 515 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
649 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 516 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
650 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 517 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
651 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 518 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); |
652 | } | 519 | } |
653 | 520 | ||
654 | static int hpc_power_on_slot(struct slot * slot) | 521 | static int hpc_power_on_slot(struct slot * slot) |
@@ -662,15 +529,15 @@ static int hpc_power_on_slot(struct slot * slot) | |||
662 | ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot); | 529 | ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot); |
663 | 530 | ||
664 | /* Clear sticky power-fault bit from previous power failures */ | 531 | /* Clear sticky power-fault bit from previous power failures */ |
665 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 532 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); |
666 | if (retval) { | 533 | if (retval) { |
667 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", | 534 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
668 | __func__); | 535 | __func__); |
669 | return retval; | 536 | return retval; |
670 | } | 537 | } |
671 | slot_status &= PWR_FAULT_DETECTED; | 538 | slot_status &= PCI_EXP_SLTSTA_PFD; |
672 | if (slot_status) { | 539 | if (slot_status) { |
673 | retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); | 540 | retval = pciehp_writew(ctrl, PCI_EXP_SLTSTA, slot_status); |
674 | if (retval) { | 541 | if (retval) { |
675 | ctrl_err(ctrl, | 542 | ctrl_err(ctrl, |
676 | "%s: Cannot write to SLOTSTATUS register\n", | 543 | "%s: Cannot write to SLOTSTATUS register\n", |
@@ -680,13 +547,13 @@ static int hpc_power_on_slot(struct slot * slot) | |||
680 | } | 547 | } |
681 | 548 | ||
682 | slot_cmd = POWER_ON; | 549 | slot_cmd = POWER_ON; |
683 | cmd_mask = PWR_CTRL; | 550 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
684 | /* Enable detection that we turned off at slot power-off time */ | 551 | /* Enable detection that we turned off at slot power-off time */ |
685 | if (!pciehp_poll_mode) { | 552 | if (!pciehp_poll_mode) { |
686 | slot_cmd |= (PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE | | 553 | slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | |
687 | PRSN_DETECT_ENABLE); | 554 | PCI_EXP_SLTCTL_PDCE); |
688 | cmd_mask |= (PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE | | 555 | cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | |
689 | PRSN_DETECT_ENABLE); | 556 | PCI_EXP_SLTCTL_PDCE); |
690 | } | 557 | } |
691 | 558 | ||
692 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 559 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
@@ -696,7 +563,7 @@ static int hpc_power_on_slot(struct slot * slot) | |||
696 | return -1; | 563 | return -1; |
697 | } | 564 | } |
698 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 565 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
699 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 566 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); |
700 | 567 | ||
701 | return retval; | 568 | return retval; |
702 | } | 569 | } |
@@ -753,7 +620,7 @@ static int hpc_power_off_slot(struct slot * slot) | |||
753 | changed = pcie_mask_bad_dllp(ctrl); | 620 | changed = pcie_mask_bad_dllp(ctrl); |
754 | 621 | ||
755 | slot_cmd = POWER_OFF; | 622 | slot_cmd = POWER_OFF; |
756 | cmd_mask = PWR_CTRL; | 623 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
757 | /* | 624 | /* |
758 | * If we get MRL or presence detect interrupts now, the isr | 625 | * If we get MRL or presence detect interrupts now, the isr |
759 | * will notice the sticky power-fault bit too and issue power | 626 | * will notice the sticky power-fault bit too and issue power |
@@ -762,10 +629,10 @@ static int hpc_power_off_slot(struct slot * slot) | |||
762 | * till the slot is powered on again. | 629 | * till the slot is powered on again. |
763 | */ | 630 | */ |
764 | if (!pciehp_poll_mode) { | 631 | if (!pciehp_poll_mode) { |
765 | slot_cmd &= ~(PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE | | 632 | slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | |
766 | PRSN_DETECT_ENABLE); | 633 | PCI_EXP_SLTCTL_PDCE); |
767 | cmd_mask |= (PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE | | 634 | cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | |
768 | PRSN_DETECT_ENABLE); | 635 | PCI_EXP_SLTCTL_PDCE); |
769 | } | 636 | } |
770 | 637 | ||
771 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 638 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
@@ -775,7 +642,7 @@ static int hpc_power_off_slot(struct slot * slot) | |||
775 | goto out; | 642 | goto out; |
776 | } | 643 | } |
777 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 644 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
778 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 645 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); |
779 | out: | 646 | out: |
780 | if (changed) | 647 | if (changed) |
781 | pcie_unmask_bad_dllp(ctrl); | 648 | pcie_unmask_bad_dllp(ctrl); |
@@ -796,19 +663,19 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
796 | */ | 663 | */ |
797 | intr_loc = 0; | 664 | intr_loc = 0; |
798 | do { | 665 | do { |
799 | if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) { | 666 | if (pciehp_readw(ctrl, PCI_EXP_SLTSTA, &detected)) { |
800 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n", | 667 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n", |
801 | __func__); | 668 | __func__); |
802 | return IRQ_NONE; | 669 | return IRQ_NONE; |
803 | } | 670 | } |
804 | 671 | ||
805 | detected &= (ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | | 672 | detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | |
806 | MRL_SENS_CHANGED | PRSN_DETECT_CHANGED | | 673 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | |
807 | CMD_COMPLETED); | 674 | PCI_EXP_SLTSTA_CC); |
808 | intr_loc |= detected; | 675 | intr_loc |= detected; |
809 | if (!intr_loc) | 676 | if (!intr_loc) |
810 | return IRQ_NONE; | 677 | return IRQ_NONE; |
811 | if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) { | 678 | if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) { |
812 | ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", | 679 | ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", |
813 | __func__); | 680 | __func__); |
814 | return IRQ_NONE; | 681 | return IRQ_NONE; |
@@ -818,31 +685,31 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
818 | ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc); | 685 | ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc); |
819 | 686 | ||
820 | /* Check Command Complete Interrupt Pending */ | 687 | /* Check Command Complete Interrupt Pending */ |
821 | if (intr_loc & CMD_COMPLETED) { | 688 | if (intr_loc & PCI_EXP_SLTSTA_CC) { |
822 | ctrl->cmd_busy = 0; | 689 | ctrl->cmd_busy = 0; |
823 | smp_mb(); | 690 | smp_mb(); |
824 | wake_up(&ctrl->queue); | 691 | wake_up(&ctrl->queue); |
825 | } | 692 | } |
826 | 693 | ||
827 | if (!(intr_loc & ~CMD_COMPLETED)) | 694 | if (!(intr_loc & ~PCI_EXP_SLTSTA_CC)) |
828 | return IRQ_HANDLED; | 695 | return IRQ_HANDLED; |
829 | 696 | ||
830 | p_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | 697 | p_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
831 | 698 | ||
832 | /* Check MRL Sensor Changed */ | 699 | /* Check MRL Sensor Changed */ |
833 | if (intr_loc & MRL_SENS_CHANGED) | 700 | if (intr_loc & PCI_EXP_SLTSTA_MRLSC) |
834 | pciehp_handle_switch_change(p_slot); | 701 | pciehp_handle_switch_change(p_slot); |
835 | 702 | ||
836 | /* Check Attention Button Pressed */ | 703 | /* Check Attention Button Pressed */ |
837 | if (intr_loc & ATTN_BUTTN_PRESSED) | 704 | if (intr_loc & PCI_EXP_SLTSTA_ABP) |
838 | pciehp_handle_attention_button(p_slot); | 705 | pciehp_handle_attention_button(p_slot); |
839 | 706 | ||
840 | /* Check Presence Detect Changed */ | 707 | /* Check Presence Detect Changed */ |
841 | if (intr_loc & PRSN_DETECT_CHANGED) | 708 | if (intr_loc & PCI_EXP_SLTSTA_PDC) |
842 | pciehp_handle_presence_change(p_slot); | 709 | pciehp_handle_presence_change(p_slot); |
843 | 710 | ||
844 | /* Check Power Fault Detected */ | 711 | /* Check Power Fault Detected */ |
845 | if (intr_loc & PWR_FAULT_DETECTED) | 712 | if (intr_loc & PCI_EXP_SLTSTA_PFD) |
846 | pciehp_handle_power_fault(p_slot); | 713 | pciehp_handle_power_fault(p_slot); |
847 | 714 | ||
848 | return IRQ_HANDLED; | 715 | return IRQ_HANDLED; |
@@ -855,7 +722,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value) | |||
855 | u32 lnk_cap; | 722 | u32 lnk_cap; |
856 | int retval = 0; | 723 | int retval = 0; |
857 | 724 | ||
858 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); | 725 | retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); |
859 | if (retval) { | 726 | if (retval) { |
860 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); | 727 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); |
861 | return retval; | 728 | return retval; |
@@ -884,13 +751,13 @@ static int hpc_get_max_lnk_width(struct slot *slot, | |||
884 | u32 lnk_cap; | 751 | u32 lnk_cap; |
885 | int retval = 0; | 752 | int retval = 0; |
886 | 753 | ||
887 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); | 754 | retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); |
888 | if (retval) { | 755 | if (retval) { |
889 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); | 756 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); |
890 | return retval; | 757 | return retval; |
891 | } | 758 | } |
892 | 759 | ||
893 | switch ((lnk_cap & 0x03F0) >> 4){ | 760 | switch ((lnk_cap & PCI_EXP_LNKSTA_NLW) >> 4){ |
894 | case 0: | 761 | case 0: |
895 | lnk_wdth = PCIE_LNK_WIDTH_RESRV; | 762 | lnk_wdth = PCIE_LNK_WIDTH_RESRV; |
896 | break; | 763 | break; |
@@ -933,14 +800,14 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value) | |||
933 | int retval = 0; | 800 | int retval = 0; |
934 | u16 lnk_status; | 801 | u16 lnk_status; |
935 | 802 | ||
936 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); | 803 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
937 | if (retval) { | 804 | if (retval) { |
938 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", | 805 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", |
939 | __func__); | 806 | __func__); |
940 | return retval; | 807 | return retval; |
941 | } | 808 | } |
942 | 809 | ||
943 | switch (lnk_status & 0x0F) { | 810 | switch (lnk_status & PCI_EXP_LNKSTA_CLS) { |
944 | case 1: | 811 | case 1: |
945 | lnk_speed = PCIE_2PT5GB; | 812 | lnk_speed = PCIE_2PT5GB; |
946 | break; | 813 | break; |
@@ -963,14 +830,14 @@ static int hpc_get_cur_lnk_width(struct slot *slot, | |||
963 | int retval = 0; | 830 | int retval = 0; |
964 | u16 lnk_status; | 831 | u16 lnk_status; |
965 | 832 | ||
966 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); | 833 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
967 | if (retval) { | 834 | if (retval) { |
968 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", | 835 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", |
969 | __func__); | 836 | __func__); |
970 | return retval; | 837 | return retval; |
971 | } | 838 | } |
972 | 839 | ||
973 | switch ((lnk_status & 0x03F0) >> 4){ | 840 | switch ((lnk_status & PCI_EXP_LNKSTA_NLW) >> 4){ |
974 | case 0: | 841 | case 0: |
975 | lnk_wdth = PCIE_LNK_WIDTH_RESRV; | 842 | lnk_wdth = PCIE_LNK_WIDTH_RESRV; |
976 | break; | 843 | break; |
@@ -1036,18 +903,19 @@ int pcie_enable_notification(struct controller *ctrl) | |||
1036 | { | 903 | { |
1037 | u16 cmd, mask; | 904 | u16 cmd, mask; |
1038 | 905 | ||
1039 | cmd = PRSN_DETECT_ENABLE; | 906 | cmd = PCI_EXP_SLTCTL_PDCE; |
1040 | if (ATTN_BUTTN(ctrl)) | 907 | if (ATTN_BUTTN(ctrl)) |
1041 | cmd |= ATTN_BUTTN_ENABLE; | 908 | cmd |= PCI_EXP_SLTCTL_ABPE; |
1042 | if (POWER_CTRL(ctrl)) | 909 | if (POWER_CTRL(ctrl)) |
1043 | cmd |= PWR_FAULT_DETECT_ENABLE; | 910 | cmd |= PCI_EXP_SLTCTL_PFDE; |
1044 | if (MRL_SENS(ctrl)) | 911 | if (MRL_SENS(ctrl)) |
1045 | cmd |= MRL_DETECT_ENABLE; | 912 | cmd |= PCI_EXP_SLTCTL_MRLSCE; |
1046 | if (!pciehp_poll_mode) | 913 | if (!pciehp_poll_mode) |
1047 | cmd |= HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; | 914 | cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE; |
1048 | 915 | ||
1049 | mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE | | 916 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
1050 | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; | 917 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
918 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | ||
1051 | 919 | ||
1052 | if (pcie_write_cmd(ctrl, cmd, mask)) { | 920 | if (pcie_write_cmd(ctrl, cmd, mask)) { |
1053 | ctrl_err(ctrl, "Cannot enable software notification\n"); | 921 | ctrl_err(ctrl, "Cannot enable software notification\n"); |
@@ -1059,8 +927,9 @@ int pcie_enable_notification(struct controller *ctrl) | |||
1059 | static void pcie_disable_notification(struct controller *ctrl) | 927 | static void pcie_disable_notification(struct controller *ctrl) |
1060 | { | 928 | { |
1061 | u16 mask; | 929 | u16 mask; |
1062 | mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE | | 930 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
1063 | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; | 931 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
932 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | ||
1064 | if (pcie_write_cmd(ctrl, 0, mask)) | 933 | if (pcie_write_cmd(ctrl, 0, mask)) |
1065 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
1066 | } | 935 | } |
@@ -1157,9 +1026,9 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
1157 | EMI(ctrl) ? "yes" : "no"); | 1026 | EMI(ctrl) ? "yes" : "no"); |
1158 | ctrl_info(ctrl, " Command Completed : %3s\n", | 1027 | ctrl_info(ctrl, " Command Completed : %3s\n", |
1159 | NO_CMD_CMPL(ctrl) ? "no" : "yes"); | 1028 | NO_CMD_CMPL(ctrl) ? "no" : "yes"); |
1160 | pciehp_readw(ctrl, SLOTSTATUS, ®16); | 1029 | pciehp_readw(ctrl, PCI_EXP_SLTSTA, ®16); |
1161 | ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16); | 1030 | ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16); |
1162 | pciehp_readw(ctrl, SLOTCTRL, ®16); | 1031 | pciehp_readw(ctrl, PCI_EXP_SLTCTL, ®16); |
1163 | ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16); | 1032 | ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16); |
1164 | } | 1033 | } |
1165 | 1034 | ||
@@ -1183,7 +1052,7 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
1183 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); | 1052 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); |
1184 | goto abort_ctrl; | 1053 | goto abort_ctrl; |
1185 | } | 1054 | } |
1186 | if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) { | 1055 | if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { |
1187 | ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); | 1056 | ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); |
1188 | goto abort_ctrl; | 1057 | goto abort_ctrl; |
1189 | } | 1058 | } |
@@ -1208,17 +1077,17 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
1208 | ctrl->no_cmd_complete = 1; | 1077 | ctrl->no_cmd_complete = 1; |
1209 | 1078 | ||
1210 | /* Check if Data Link Layer Link Active Reporting is implemented */ | 1079 | /* Check if Data Link Layer Link Active Reporting is implemented */ |
1211 | if (pciehp_readl(ctrl, LNKCAP, &link_cap)) { | 1080 | if (pciehp_readl(ctrl, PCI_EXP_LNKCAP, &link_cap)) { |
1212 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); | 1081 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); |
1213 | goto abort_ctrl; | 1082 | goto abort_ctrl; |
1214 | } | 1083 | } |
1215 | if (link_cap & LINK_ACTIVE_REPORTING) { | 1084 | if (link_cap & PCI_EXP_LNKCAP_DLLLARC) { |
1216 | ctrl_dbg(ctrl, "Link Active Reporting supported\n"); | 1085 | ctrl_dbg(ctrl, "Link Active Reporting supported\n"); |
1217 | ctrl->link_active_reporting = 1; | 1086 | ctrl->link_active_reporting = 1; |
1218 | } | 1087 | } |
1219 | 1088 | ||
1220 | /* Clear all remaining event bits in Slot Status register */ | 1089 | /* Clear all remaining event bits in Slot Status register */ |
1221 | if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f)) | 1090 | if (pciehp_writew(ctrl, PCI_EXP_SLTSTA, 0x1f)) |
1222 | goto abort_ctrl; | 1091 | goto abort_ctrl; |
1223 | 1092 | ||
1224 | /* Disable sotfware notification */ | 1093 | /* Disable sotfware notification */ |
diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c index 6441dfa969a3..de01174aff06 100644 --- a/drivers/pci/irq.c +++ b/drivers/pci/irq.c | |||
@@ -15,7 +15,7 @@ static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason) | |||
15 | 15 | ||
16 | dev_printk(KERN_ERR, &pdev->dev, | 16 | dev_printk(KERN_ERR, &pdev->dev, |
17 | "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n", | 17 | "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n", |
18 | parent->dev.bus_id, parent->vendor, parent->device); | 18 | dev_name(&parent->dev), parent->vendor, parent->device); |
19 | dev_printk(KERN_ERR, &pdev->dev, "%s\n", reason); | 19 | dev_printk(KERN_ERR, &pdev->dev, "%s\n", reason); |
20 | dev_printk(KERN_ERR, &pdev->dev, "Please report to linux-kernel@vger.kernel.org\n"); | 20 | dev_printk(KERN_ERR, &pdev->dev, "Please report to linux-kernel@vger.kernel.org\n"); |
21 | WARN_ON(1); | 21 | WARN_ON(1); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 11a51f8ed3b3..b4a90badd0a6 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -776,28 +776,19 @@ void pci_no_msi(void) | |||
776 | pci_msi_enable = 0; | 776 | pci_msi_enable = 0; |
777 | } | 777 | } |
778 | 778 | ||
779 | void pci_msi_init_pci_dev(struct pci_dev *dev) | 779 | /** |
780 | { | 780 | * pci_msi_enabled - is MSI enabled? |
781 | INIT_LIST_HEAD(&dev->msi_list); | 781 | * |
782 | } | 782 | * Returns true if MSI has not been disabled by the command-line option |
783 | 783 | * pci=nomsi. | |
784 | #ifdef CONFIG_ACPI | 784 | **/ |
785 | #include <linux/acpi.h> | 785 | int pci_msi_enabled(void) |
786 | #include <linux/pci-acpi.h> | ||
787 | static void __devinit msi_acpi_init(void) | ||
788 | { | 786 | { |
789 | if (acpi_pci_disabled) | 787 | return pci_msi_enable; |
790 | return; | ||
791 | pci_osc_support_set(OSC_MSI_SUPPORT); | ||
792 | pcie_osc_support_set(OSC_MSI_SUPPORT); | ||
793 | } | 788 | } |
794 | #else | 789 | EXPORT_SYMBOL(pci_msi_enabled); |
795 | static inline void msi_acpi_init(void) { } | ||
796 | #endif /* CONFIG_ACPI */ | ||
797 | 790 | ||
798 | void __devinit msi_init(void) | 791 | void pci_msi_init_pci_dev(struct pci_dev *dev) |
799 | { | 792 | { |
800 | if (!pci_msi_enable) | 793 | INIT_LIST_HEAD(&dev->msi_list); |
801 | return; | ||
802 | msi_acpi_init(); | ||
803 | } | 794 | } |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ae5ec76dca77..3582512e7226 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -24,13 +24,14 @@ struct acpi_osc_data { | |||
24 | acpi_handle handle; | 24 | acpi_handle handle; |
25 | u32 support_set; | 25 | u32 support_set; |
26 | u32 control_set; | 26 | u32 control_set; |
27 | u32 control_query; | ||
28 | int is_queried; | ||
27 | struct list_head sibiling; | 29 | struct list_head sibiling; |
28 | }; | 30 | }; |
29 | static LIST_HEAD(acpi_osc_data_list); | 31 | static LIST_HEAD(acpi_osc_data_list); |
30 | 32 | ||
31 | struct acpi_osc_args { | 33 | struct acpi_osc_args { |
32 | u32 capbuf[3]; | 34 | u32 capbuf[3]; |
33 | u32 ctrl_result; | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | static DEFINE_MUTEX(pci_acpi_lock); | 37 | static DEFINE_MUTEX(pci_acpi_lock); |
@@ -56,7 +57,7 @@ static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, | |||
56 | 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; | 57 | 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; |
57 | 58 | ||
58 | static acpi_status acpi_run_osc(acpi_handle handle, | 59 | static acpi_status acpi_run_osc(acpi_handle handle, |
59 | struct acpi_osc_args *osc_args) | 60 | struct acpi_osc_args *osc_args, u32 *retval) |
60 | { | 61 | { |
61 | acpi_status status; | 62 | acpi_status status; |
62 | struct acpi_object_list input; | 63 | struct acpi_object_list input; |
@@ -112,8 +113,7 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
112 | goto out_kfree; | 113 | goto out_kfree; |
113 | } | 114 | } |
114 | out_success: | 115 | out_success: |
115 | osc_args->ctrl_result = | 116 | *retval = *((u32 *)(out_obj->buffer.pointer + 8)); |
116 | *((u32 *)(out_obj->buffer.pointer + 8)); | ||
117 | status = AE_OK; | 117 | status = AE_OK; |
118 | 118 | ||
119 | out_kfree: | 119 | out_kfree: |
@@ -121,11 +121,10 @@ out_kfree: | |||
121 | return status; | 121 | return status; |
122 | } | 122 | } |
123 | 123 | ||
124 | static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data, | 124 | static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data) |
125 | u32 *result) | ||
126 | { | 125 | { |
127 | acpi_status status; | 126 | acpi_status status; |
128 | u32 support_set; | 127 | u32 support_set, result; |
129 | struct acpi_osc_args osc_args; | 128 | struct acpi_osc_args osc_args; |
130 | 129 | ||
131 | /* do _OSC query for all possible controls */ | 130 | /* do _OSC query for all possible controls */ |
@@ -134,56 +133,45 @@ static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data, | |||
134 | osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set; | 133 | osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set; |
135 | osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; | 134 | osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; |
136 | 135 | ||
137 | status = acpi_run_osc(osc_data->handle, &osc_args); | 136 | status = acpi_run_osc(osc_data->handle, &osc_args, &result); |
138 | if (ACPI_SUCCESS(status)) { | 137 | if (ACPI_SUCCESS(status)) { |
139 | osc_data->support_set = support_set; | 138 | osc_data->support_set = support_set; |
140 | *result = osc_args.ctrl_result; | 139 | osc_data->control_query = result; |
140 | osc_data->is_queried = 1; | ||
141 | } | 141 | } |
142 | 142 | ||
143 | return status; | 143 | return status; |
144 | } | 144 | } |
145 | 145 | ||
146 | static acpi_status acpi_query_osc(acpi_handle handle, | 146 | /* |
147 | u32 level, void *context, void **retval) | 147 | * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature |
148 | * @flags: Bitmask of flags to support | ||
149 | * | ||
150 | * See the ACPI spec for the definition of the flags | ||
151 | */ | ||
152 | int pci_acpi_osc_support(acpi_handle handle, u32 flags) | ||
148 | { | 153 | { |
149 | acpi_status status; | 154 | acpi_status status; |
150 | struct acpi_osc_data *osc_data; | ||
151 | u32 flags = (unsigned long)context, dummy; | ||
152 | acpi_handle tmp; | 155 | acpi_handle tmp; |
156 | struct acpi_osc_data *osc_data; | ||
157 | int rc = 0; | ||
153 | 158 | ||
154 | status = acpi_get_handle(handle, "_OSC", &tmp); | 159 | status = acpi_get_handle(handle, "_OSC", &tmp); |
155 | if (ACPI_FAILURE(status)) | 160 | if (ACPI_FAILURE(status)) |
156 | return AE_OK; | 161 | return -ENOTTY; |
157 | 162 | ||
158 | mutex_lock(&pci_acpi_lock); | 163 | mutex_lock(&pci_acpi_lock); |
159 | osc_data = acpi_get_osc_data(handle); | 164 | osc_data = acpi_get_osc_data(handle); |
160 | if (!osc_data) { | 165 | if (!osc_data) { |
161 | printk(KERN_ERR "acpi osc data array is full\n"); | 166 | printk(KERN_ERR "acpi osc data array is full\n"); |
167 | rc = -ENOMEM; | ||
162 | goto out; | 168 | goto out; |
163 | } | 169 | } |
164 | 170 | ||
165 | __acpi_query_osc(flags, osc_data, &dummy); | 171 | __acpi_query_osc(flags, osc_data); |
166 | out: | 172 | out: |
167 | mutex_unlock(&pci_acpi_lock); | 173 | mutex_unlock(&pci_acpi_lock); |
168 | return AE_OK; | 174 | return rc; |
169 | } | ||
170 | |||
171 | /** | ||
172 | * __pci_osc_support_set - register OS support to Firmware | ||
173 | * @flags: OS support bits | ||
174 | * @hid: hardware ID | ||
175 | * | ||
176 | * Update OS support fields and doing a _OSC Query to obtain an update | ||
177 | * from Firmware on supported control bits. | ||
178 | **/ | ||
179 | acpi_status __pci_osc_support_set(u32 flags, const char *hid) | ||
180 | { | ||
181 | if (!(flags & OSC_SUPPORT_MASKS)) | ||
182 | return AE_TYPE; | ||
183 | |||
184 | acpi_get_devices(hid, acpi_query_osc, | ||
185 | (void *)(unsigned long)flags, NULL); | ||
186 | return AE_OK; | ||
187 | } | 175 | } |
188 | 176 | ||
189 | /** | 177 | /** |
@@ -196,7 +184,7 @@ acpi_status __pci_osc_support_set(u32 flags, const char *hid) | |||
196 | acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) | 184 | acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) |
197 | { | 185 | { |
198 | acpi_status status; | 186 | acpi_status status; |
199 | u32 ctrlset, control_set, result; | 187 | u32 control_req, control_set, result; |
200 | acpi_handle tmp; | 188 | acpi_handle tmp; |
201 | struct acpi_osc_data *osc_data; | 189 | struct acpi_osc_data *osc_data; |
202 | struct acpi_osc_args osc_args; | 190 | struct acpi_osc_args osc_args; |
@@ -213,28 +201,34 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) | |||
213 | goto out; | 201 | goto out; |
214 | } | 202 | } |
215 | 203 | ||
216 | ctrlset = (flags & OSC_CONTROL_MASKS); | 204 | control_req = (flags & OSC_CONTROL_MASKS); |
217 | if (!ctrlset) { | 205 | if (!control_req) { |
218 | status = AE_TYPE; | 206 | status = AE_TYPE; |
219 | goto out; | 207 | goto out; |
220 | } | 208 | } |
221 | 209 | ||
222 | status = __acpi_query_osc(osc_data->support_set, osc_data, &result); | 210 | /* No need to evaluate _OSC if the control was already granted. */ |
223 | if (ACPI_FAILURE(status)) | 211 | if ((osc_data->control_set & control_req) == control_req) |
224 | goto out; | 212 | goto out; |
225 | 213 | ||
226 | if ((result & ctrlset) != ctrlset) { | 214 | if (!osc_data->is_queried) { |
215 | status = __acpi_query_osc(osc_data->support_set, osc_data); | ||
216 | if (ACPI_FAILURE(status)) | ||
217 | goto out; | ||
218 | } | ||
219 | |||
220 | if ((osc_data->control_query & control_req) != control_req) { | ||
227 | status = AE_SUPPORT; | 221 | status = AE_SUPPORT; |
228 | goto out; | 222 | goto out; |
229 | } | 223 | } |
230 | 224 | ||
231 | control_set = osc_data->control_set | ctrlset; | 225 | control_set = osc_data->control_set | control_req; |
232 | osc_args.capbuf[OSC_QUERY_TYPE] = 0; | 226 | osc_args.capbuf[OSC_QUERY_TYPE] = 0; |
233 | osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set; | 227 | osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set; |
234 | osc_args.capbuf[OSC_CONTROL_TYPE] = control_set; | 228 | osc_args.capbuf[OSC_CONTROL_TYPE] = control_set; |
235 | status = acpi_run_osc(handle, &osc_args); | 229 | status = acpi_run_osc(handle, &osc_args, &result); |
236 | if (ACPI_SUCCESS(status)) | 230 | if (ACPI_SUCCESS(status)) |
237 | osc_data->control_set = control_set; | 231 | osc_data->control_set = result; |
238 | out: | 232 | out: |
239 | mutex_unlock(&pci_acpi_lock); | 233 | mutex_unlock(&pci_acpi_lock); |
240 | return status; | 234 | return status; |
@@ -375,7 +369,7 @@ static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) | |||
375 | * The string should be the same as root bridge's name | 369 | * The string should be the same as root bridge's name |
376 | * Please look at 'pci_scan_bus_parented' | 370 | * Please look at 'pci_scan_bus_parented' |
377 | */ | 371 | */ |
378 | num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus); | 372 | num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus); |
379 | if (num != 2) | 373 | if (num != 2) |
380 | return -ENODEV; | 374 | return -ENODEV; |
381 | *handle = acpi_get_pci_rootbridge_handle(seg, bus); | 375 | *handle = acpi_get_pci_rootbridge_handle(seg, bus); |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 99d867bcf22a..c697f2680856 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/cpu.h> | ||
19 | #include "pci.h" | 20 | #include "pci.h" |
20 | 21 | ||
21 | /* | 22 | /* |
@@ -48,7 +49,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) | |||
48 | subdevice=PCI_ANY_ID, class=0, class_mask=0; | 49 | subdevice=PCI_ANY_ID, class=0, class_mask=0; |
49 | unsigned long driver_data=0; | 50 | unsigned long driver_data=0; |
50 | int fields=0; | 51 | int fields=0; |
51 | int retval; | 52 | int retval=0; |
52 | 53 | ||
53 | fields = sscanf(buf, "%x %x %x %x %x %x %lx", | 54 | fields = sscanf(buf, "%x %x %x %x %x %x %lx", |
54 | &vendor, &device, &subvendor, &subdevice, | 55 | &vendor, &device, &subvendor, &subdevice, |
@@ -58,16 +59,18 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) | |||
58 | 59 | ||
59 | /* Only accept driver_data values that match an existing id_table | 60 | /* Only accept driver_data values that match an existing id_table |
60 | entry */ | 61 | entry */ |
61 | retval = -EINVAL; | 62 | if (ids) { |
62 | while (ids->vendor || ids->subvendor || ids->class_mask) { | 63 | retval = -EINVAL; |
63 | if (driver_data == ids->driver_data) { | 64 | while (ids->vendor || ids->subvendor || ids->class_mask) { |
64 | retval = 0; | 65 | if (driver_data == ids->driver_data) { |
65 | break; | 66 | retval = 0; |
67 | break; | ||
68 | } | ||
69 | ids++; | ||
66 | } | 70 | } |
67 | ids++; | 71 | if (retval) /* No match */ |
72 | return retval; | ||
68 | } | 73 | } |
69 | if (retval) /* No match */ | ||
70 | return retval; | ||
71 | 74 | ||
72 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | 75 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); |
73 | if (!dynid) | 76 | if (!dynid) |
@@ -183,32 +186,43 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv, | |||
183 | return pci_match_id(drv->id_table, dev); | 186 | return pci_match_id(drv->id_table, dev); |
184 | } | 187 | } |
185 | 188 | ||
189 | struct drv_dev_and_id { | ||
190 | struct pci_driver *drv; | ||
191 | struct pci_dev *dev; | ||
192 | const struct pci_device_id *id; | ||
193 | }; | ||
194 | |||
195 | static long local_pci_probe(void *_ddi) | ||
196 | { | ||
197 | struct drv_dev_and_id *ddi = _ddi; | ||
198 | |||
199 | return ddi->drv->probe(ddi->dev, ddi->id); | ||
200 | } | ||
201 | |||
186 | static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | 202 | static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, |
187 | const struct pci_device_id *id) | 203 | const struct pci_device_id *id) |
188 | { | 204 | { |
189 | int error; | 205 | int error, node; |
190 | #ifdef CONFIG_NUMA | 206 | struct drv_dev_and_id ddi = { drv, dev, id }; |
191 | /* Execute driver initialization on node where the | ||
192 | device's bus is attached to. This way the driver likely | ||
193 | allocates its local memory on the right node without | ||
194 | any need to change it. */ | ||
195 | struct mempolicy *oldpol; | ||
196 | cpumask_t oldmask = current->cpus_allowed; | ||
197 | int node = dev_to_node(&dev->dev); | ||
198 | 207 | ||
208 | /* Execute driver initialization on node where the device's | ||
209 | bus is attached to. This way the driver likely allocates | ||
210 | its local memory on the right node without any need to | ||
211 | change it. */ | ||
212 | node = dev_to_node(&dev->dev); | ||
199 | if (node >= 0) { | 213 | if (node >= 0) { |
214 | int cpu; | ||
200 | node_to_cpumask_ptr(nodecpumask, node); | 215 | node_to_cpumask_ptr(nodecpumask, node); |
201 | set_cpus_allowed_ptr(current, nodecpumask); | 216 | |
202 | } | 217 | get_online_cpus(); |
203 | /* And set default memory allocation policy */ | 218 | cpu = cpumask_any_and(nodecpumask, cpu_online_mask); |
204 | oldpol = current->mempolicy; | 219 | if (cpu < nr_cpu_ids) |
205 | current->mempolicy = NULL; /* fall back to system default policy */ | 220 | error = work_on_cpu(cpu, local_pci_probe, &ddi); |
206 | #endif | 221 | else |
207 | error = drv->probe(dev, id); | 222 | error = local_pci_probe(&ddi); |
208 | #ifdef CONFIG_NUMA | 223 | put_online_cpus(); |
209 | set_cpus_allowed_ptr(current, &oldmask); | 224 | } else |
210 | current->mempolicy = oldpol; | 225 | error = local_pci_probe(&ddi); |
211 | #endif | ||
212 | return error; | 226 | return error; |
213 | } | 227 | } |
214 | 228 | ||
@@ -300,21 +314,12 @@ static void pci_device_shutdown(struct device *dev) | |||
300 | 314 | ||
301 | #ifdef CONFIG_PM_SLEEP | 315 | #ifdef CONFIG_PM_SLEEP |
302 | 316 | ||
303 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) | ||
304 | { | ||
305 | struct pci_driver *drv = pci_dev->driver; | ||
306 | |||
307 | return drv && (drv->suspend || drv->suspend_late || drv->resume | ||
308 | || drv->resume_early); | ||
309 | } | ||
310 | |||
311 | /* | 317 | /* |
312 | * Default "suspend" method for devices that have no driver provided suspend, | 318 | * Default "suspend" method for devices that have no driver provided suspend, |
313 | * or not even a driver at all. | 319 | * or not even a driver at all (second part). |
314 | */ | 320 | */ |
315 | static void pci_default_pm_suspend(struct pci_dev *pci_dev) | 321 | static void pci_pm_set_unknown_state(struct pci_dev *pci_dev) |
316 | { | 322 | { |
317 | pci_save_state(pci_dev); | ||
318 | /* | 323 | /* |
319 | * mark its power state as "unknown", since we don't know if | 324 | * mark its power state as "unknown", since we don't know if |
320 | * e.g. the BIOS will change its device state when we suspend. | 325 | * e.g. the BIOS will change its device state when we suspend. |
@@ -325,19 +330,9 @@ static void pci_default_pm_suspend(struct pci_dev *pci_dev) | |||
325 | 330 | ||
326 | /* | 331 | /* |
327 | * Default "resume" method for devices that have no driver provided resume, | 332 | * Default "resume" method for devices that have no driver provided resume, |
328 | * or not even a driver at all (first part). | ||
329 | */ | ||
330 | static void pci_default_pm_resume_early(struct pci_dev *pci_dev) | ||
331 | { | ||
332 | /* restore the PCI config space */ | ||
333 | pci_restore_state(pci_dev); | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | * Default "resume" method for devices that have no driver provided resume, | ||
338 | * or not even a driver at all (second part). | 333 | * or not even a driver at all (second part). |
339 | */ | 334 | */ |
340 | static int pci_default_pm_resume_late(struct pci_dev *pci_dev) | 335 | static int pci_pm_reenable_device(struct pci_dev *pci_dev) |
341 | { | 336 | { |
342 | int retval; | 337 | int retval; |
343 | 338 | ||
@@ -363,8 +358,16 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) | |||
363 | i = drv->suspend(pci_dev, state); | 358 | i = drv->suspend(pci_dev, state); |
364 | suspend_report_result(drv->suspend, i); | 359 | suspend_report_result(drv->suspend, i); |
365 | } else { | 360 | } else { |
366 | pci_default_pm_suspend(pci_dev); | 361 | pci_save_state(pci_dev); |
362 | /* | ||
363 | * This is for compatibility with existing code with legacy PM | ||
364 | * support. | ||
365 | */ | ||
366 | pci_pm_set_unknown_state(pci_dev); | ||
367 | } | 367 | } |
368 | |||
369 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
370 | |||
368 | return i; | 371 | return i; |
369 | } | 372 | } |
370 | 373 | ||
@@ -381,32 +384,130 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) | |||
381 | return i; | 384 | return i; |
382 | } | 385 | } |
383 | 386 | ||
387 | static int pci_legacy_resume_early(struct device *dev) | ||
388 | { | ||
389 | int error = 0; | ||
390 | struct pci_dev * pci_dev = to_pci_dev(dev); | ||
391 | struct pci_driver * drv = pci_dev->driver; | ||
392 | |||
393 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
394 | |||
395 | if (drv && drv->resume_early) | ||
396 | error = drv->resume_early(pci_dev); | ||
397 | return error; | ||
398 | } | ||
399 | |||
384 | static int pci_legacy_resume(struct device *dev) | 400 | static int pci_legacy_resume(struct device *dev) |
385 | { | 401 | { |
386 | int error; | 402 | int error; |
387 | struct pci_dev * pci_dev = to_pci_dev(dev); | 403 | struct pci_dev * pci_dev = to_pci_dev(dev); |
388 | struct pci_driver * drv = pci_dev->driver; | 404 | struct pci_driver * drv = pci_dev->driver; |
389 | 405 | ||
406 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
407 | |||
390 | if (drv && drv->resume) { | 408 | if (drv && drv->resume) { |
391 | error = drv->resume(pci_dev); | 409 | error = drv->resume(pci_dev); |
392 | } else { | 410 | } else { |
393 | pci_default_pm_resume_early(pci_dev); | 411 | /* restore the PCI config space */ |
394 | error = pci_default_pm_resume_late(pci_dev); | 412 | pci_restore_state(pci_dev); |
413 | error = pci_pm_reenable_device(pci_dev); | ||
395 | } | 414 | } |
396 | return error; | 415 | return error; |
397 | } | 416 | } |
398 | 417 | ||
399 | static int pci_legacy_resume_early(struct device *dev) | 418 | /* Auxiliary functions used by the new power management framework */ |
419 | |||
420 | static int pci_restore_standard_config(struct pci_dev *pci_dev) | ||
400 | { | 421 | { |
422 | struct pci_dev *parent = pci_dev->bus->self; | ||
401 | int error = 0; | 423 | int error = 0; |
402 | struct pci_dev * pci_dev = to_pci_dev(dev); | ||
403 | struct pci_driver * drv = pci_dev->driver; | ||
404 | 424 | ||
405 | if (drv && drv->resume_early) | 425 | /* Check if the device's bus is operational */ |
406 | error = drv->resume_early(pci_dev); | 426 | if (!parent || parent->current_state == PCI_D0) { |
427 | pci_restore_state(pci_dev); | ||
428 | pci_update_current_state(pci_dev, PCI_D0); | ||
429 | } else { | ||
430 | dev_warn(&pci_dev->dev, "unable to restore config, " | ||
431 | "bridge %s in low power state D%d\n", pci_name(parent), | ||
432 | parent->current_state); | ||
433 | pci_dev->current_state = PCI_UNKNOWN; | ||
434 | error = -EAGAIN; | ||
435 | } | ||
436 | |||
407 | return error; | 437 | return error; |
408 | } | 438 | } |
409 | 439 | ||
440 | static bool pci_is_bridge(struct pci_dev *pci_dev) | ||
441 | { | ||
442 | return !!(pci_dev->subordinate); | ||
443 | } | ||
444 | |||
445 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) | ||
446 | { | ||
447 | if (pci_restore_standard_config(pci_dev)) | ||
448 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
449 | } | ||
450 | |||
451 | static int pci_pm_default_resume(struct pci_dev *pci_dev) | ||
452 | { | ||
453 | /* | ||
454 | * pci_restore_standard_config() should have been called once already, | ||
455 | * but it would have failed if the device's parent bridge had not been | ||
456 | * in power state D0 at that time. Check it and try again if necessary. | ||
457 | */ | ||
458 | if (pci_dev->current_state == PCI_UNKNOWN) { | ||
459 | int error = pci_restore_standard_config(pci_dev); | ||
460 | if (error) | ||
461 | return error; | ||
462 | } | ||
463 | |||
464 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
465 | |||
466 | if (!pci_is_bridge(pci_dev)) | ||
467 | pci_enable_wake(pci_dev, PCI_D0, false); | ||
468 | |||
469 | return pci_pm_reenable_device(pci_dev); | ||
470 | } | ||
471 | |||
472 | static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) | ||
473 | { | ||
474 | /* If device is enabled at this point, disable it */ | ||
475 | pci_disable_enabled_device(pci_dev); | ||
476 | /* | ||
477 | * Save state with interrupts enabled, because in principle the bus the | ||
478 | * device is on may be put into a low power state after this code runs. | ||
479 | */ | ||
480 | pci_save_state(pci_dev); | ||
481 | } | ||
482 | |||
483 | static void pci_pm_default_suspend(struct pci_dev *pci_dev) | ||
484 | { | ||
485 | pci_pm_default_suspend_generic(pci_dev); | ||
486 | |||
487 | if (!pci_is_bridge(pci_dev)) | ||
488 | pci_prepare_to_sleep(pci_dev); | ||
489 | |||
490 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
491 | } | ||
492 | |||
493 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) | ||
494 | { | ||
495 | struct pci_driver *drv = pci_dev->driver; | ||
496 | bool ret = drv && (drv->suspend || drv->suspend_late || drv->resume | ||
497 | || drv->resume_early); | ||
498 | |||
499 | /* | ||
500 | * Legacy PM support is used by default, so warn if the new framework is | ||
501 | * supported as well. Drivers are supposed to support either the | ||
502 | * former, or the latter, but not both at the same time. | ||
503 | */ | ||
504 | WARN_ON(ret && drv->driver.pm); | ||
505 | |||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | /* New power management framework */ | ||
510 | |||
410 | static int pci_pm_prepare(struct device *dev) | 511 | static int pci_pm_prepare(struct device *dev) |
411 | { | 512 | { |
412 | struct device_driver *drv = dev->driver; | 513 | struct device_driver *drv = dev->driver; |
@@ -434,15 +535,16 @@ static int pci_pm_suspend(struct device *dev) | |||
434 | struct device_driver *drv = dev->driver; | 535 | struct device_driver *drv = dev->driver; |
435 | int error = 0; | 536 | int error = 0; |
436 | 537 | ||
437 | if (drv && drv->pm) { | 538 | if (pci_has_legacy_pm_support(pci_dev)) |
438 | if (drv->pm->suspend) { | 539 | return pci_legacy_suspend(dev, PMSG_SUSPEND); |
439 | error = drv->pm->suspend(dev); | 540 | |
440 | suspend_report_result(drv->pm->suspend, error); | 541 | if (drv && drv->pm && drv->pm->suspend) { |
441 | } | 542 | error = drv->pm->suspend(dev); |
442 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 543 | suspend_report_result(drv->pm->suspend, error); |
443 | error = pci_legacy_suspend(dev, PMSG_SUSPEND); | ||
444 | } | 544 | } |
445 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 545 | |
546 | if (!error) | ||
547 | pci_pm_default_suspend(pci_dev); | ||
446 | 548 | ||
447 | return error; | 549 | return error; |
448 | } | 550 | } |
@@ -453,56 +555,50 @@ static int pci_pm_suspend_noirq(struct device *dev) | |||
453 | struct device_driver *drv = dev->driver; | 555 | struct device_driver *drv = dev->driver; |
454 | int error = 0; | 556 | int error = 0; |
455 | 557 | ||
456 | if (drv && drv->pm) { | 558 | if (pci_has_legacy_pm_support(pci_dev)) |
457 | if (drv->pm->suspend_noirq) { | 559 | return pci_legacy_suspend_late(dev, PMSG_SUSPEND); |
458 | error = drv->pm->suspend_noirq(dev); | 560 | |
459 | suspend_report_result(drv->pm->suspend_noirq, error); | 561 | if (drv && drv->pm && drv->pm->suspend_noirq) { |
460 | } | 562 | error = drv->pm->suspend_noirq(dev); |
461 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 563 | suspend_report_result(drv->pm->suspend_noirq, error); |
462 | error = pci_legacy_suspend_late(dev, PMSG_SUSPEND); | ||
463 | } else { | ||
464 | pci_default_pm_suspend(pci_dev); | ||
465 | } | 564 | } |
466 | 565 | ||
566 | if (!error) | ||
567 | pci_pm_set_unknown_state(pci_dev); | ||
568 | |||
467 | return error; | 569 | return error; |
468 | } | 570 | } |
469 | 571 | ||
470 | static int pci_pm_resume(struct device *dev) | 572 | static int pci_pm_resume_noirq(struct device *dev) |
471 | { | 573 | { |
472 | struct pci_dev *pci_dev = to_pci_dev(dev); | 574 | struct pci_dev *pci_dev = to_pci_dev(dev); |
473 | struct device_driver *drv = dev->driver; | 575 | struct device_driver *drv = dev->driver; |
474 | int error = 0; | 576 | int error = 0; |
475 | 577 | ||
476 | pci_fixup_device(pci_fixup_resume, pci_dev); | 578 | if (pci_has_legacy_pm_support(pci_dev)) |
579 | return pci_legacy_resume_early(dev); | ||
477 | 580 | ||
478 | if (drv && drv->pm) { | 581 | pci_pm_default_resume_noirq(pci_dev); |
479 | if (drv->pm->resume) | 582 | |
480 | error = drv->pm->resume(dev); | 583 | if (drv && drv->pm && drv->pm->resume_noirq) |
481 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 584 | error = drv->pm->resume_noirq(dev); |
482 | error = pci_legacy_resume(dev); | ||
483 | } else { | ||
484 | error = pci_default_pm_resume_late(pci_dev); | ||
485 | } | ||
486 | 585 | ||
487 | return error; | 586 | return error; |
488 | } | 587 | } |
489 | 588 | ||
490 | static int pci_pm_resume_noirq(struct device *dev) | 589 | static int pci_pm_resume(struct device *dev) |
491 | { | 590 | { |
492 | struct pci_dev *pci_dev = to_pci_dev(dev); | 591 | struct pci_dev *pci_dev = to_pci_dev(dev); |
493 | struct device_driver *drv = dev->driver; | 592 | struct device_driver *drv = dev->driver; |
494 | int error = 0; | 593 | int error = 0; |
495 | 594 | ||
496 | pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev)); | 595 | if (pci_has_legacy_pm_support(pci_dev)) |
596 | return pci_legacy_resume(dev); | ||
497 | 597 | ||
498 | if (drv && drv->pm) { | 598 | error = pci_pm_default_resume(pci_dev); |
499 | if (drv->pm->resume_noirq) | 599 | |
500 | error = drv->pm->resume_noirq(dev); | 600 | if (!error && drv && drv->pm && drv->pm->resume) |
501 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 601 | error = drv->pm->resume(dev); |
502 | error = pci_legacy_resume_early(dev); | ||
503 | } else { | ||
504 | pci_default_pm_resume_early(pci_dev); | ||
505 | } | ||
506 | 602 | ||
507 | return error; | 603 | return error; |
508 | } | 604 | } |
@@ -524,16 +620,17 @@ static int pci_pm_freeze(struct device *dev) | |||
524 | struct device_driver *drv = dev->driver; | 620 | struct device_driver *drv = dev->driver; |
525 | int error = 0; | 621 | int error = 0; |
526 | 622 | ||
527 | if (drv && drv->pm) { | 623 | if (pci_has_legacy_pm_support(pci_dev)) |
528 | if (drv->pm->freeze) { | 624 | return pci_legacy_suspend(dev, PMSG_FREEZE); |
529 | error = drv->pm->freeze(dev); | 625 | |
530 | suspend_report_result(drv->pm->freeze, error); | 626 | if (drv && drv->pm && drv->pm->freeze) { |
531 | } | 627 | error = drv->pm->freeze(dev); |
532 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 628 | suspend_report_result(drv->pm->freeze, error); |
533 | error = pci_legacy_suspend(dev, PMSG_FREEZE); | ||
534 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
535 | } | 629 | } |
536 | 630 | ||
631 | if (!error) | ||
632 | pci_pm_default_suspend_generic(pci_dev); | ||
633 | |||
537 | return error; | 634 | return error; |
538 | } | 635 | } |
539 | 636 | ||
@@ -543,50 +640,50 @@ static int pci_pm_freeze_noirq(struct device *dev) | |||
543 | struct device_driver *drv = dev->driver; | 640 | struct device_driver *drv = dev->driver; |
544 | int error = 0; | 641 | int error = 0; |
545 | 642 | ||
546 | if (drv && drv->pm) { | 643 | if (pci_has_legacy_pm_support(pci_dev)) |
547 | if (drv->pm->freeze_noirq) { | 644 | return pci_legacy_suspend_late(dev, PMSG_FREEZE); |
548 | error = drv->pm->freeze_noirq(dev); | 645 | |
549 | suspend_report_result(drv->pm->freeze_noirq, error); | 646 | if (drv && drv->pm && drv->pm->freeze_noirq) { |
550 | } | 647 | error = drv->pm->freeze_noirq(dev); |
551 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 648 | suspend_report_result(drv->pm->freeze_noirq, error); |
552 | error = pci_legacy_suspend_late(dev, PMSG_FREEZE); | ||
553 | } else { | ||
554 | pci_default_pm_suspend(pci_dev); | ||
555 | } | 649 | } |
556 | 650 | ||
651 | if (!error) | ||
652 | pci_pm_set_unknown_state(pci_dev); | ||
653 | |||
557 | return error; | 654 | return error; |
558 | } | 655 | } |
559 | 656 | ||
560 | static int pci_pm_thaw(struct device *dev) | 657 | static int pci_pm_thaw_noirq(struct device *dev) |
561 | { | 658 | { |
562 | struct pci_dev *pci_dev = to_pci_dev(dev); | 659 | struct pci_dev *pci_dev = to_pci_dev(dev); |
563 | struct device_driver *drv = dev->driver; | 660 | struct device_driver *drv = dev->driver; |
564 | int error = 0; | 661 | int error = 0; |
565 | 662 | ||
566 | if (drv && drv->pm) { | 663 | if (pci_has_legacy_pm_support(pci_dev)) |
567 | if (drv->pm->thaw) | 664 | return pci_legacy_resume_early(dev); |
568 | error = drv->pm->thaw(dev); | 665 | |
569 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 666 | pci_update_current_state(pci_dev, PCI_D0); |
570 | pci_fixup_device(pci_fixup_resume, pci_dev); | 667 | |
571 | error = pci_legacy_resume(dev); | 668 | if (drv && drv->pm && drv->pm->thaw_noirq) |
572 | } | 669 | error = drv->pm->thaw_noirq(dev); |
573 | 670 | ||
574 | return error; | 671 | return error; |
575 | } | 672 | } |
576 | 673 | ||
577 | static int pci_pm_thaw_noirq(struct device *dev) | 674 | static int pci_pm_thaw(struct device *dev) |
578 | { | 675 | { |
579 | struct pci_dev *pci_dev = to_pci_dev(dev); | 676 | struct pci_dev *pci_dev = to_pci_dev(dev); |
580 | struct device_driver *drv = dev->driver; | 677 | struct device_driver *drv = dev->driver; |
581 | int error = 0; | 678 | int error = 0; |
582 | 679 | ||
583 | if (drv && drv->pm) { | 680 | if (pci_has_legacy_pm_support(pci_dev)) |
584 | if (drv->pm->thaw_noirq) | 681 | return pci_legacy_resume(dev); |
585 | error = drv->pm->thaw_noirq(dev); | 682 | |
586 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 683 | pci_pm_reenable_device(pci_dev); |
587 | pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev)); | 684 | |
588 | error = pci_legacy_resume_early(dev); | 685 | if (drv && drv->pm && drv->pm->thaw) |
589 | } | 686 | error = drv->pm->thaw(dev); |
590 | 687 | ||
591 | return error; | 688 | return error; |
592 | } | 689 | } |
@@ -597,17 +694,17 @@ static int pci_pm_poweroff(struct device *dev) | |||
597 | struct device_driver *drv = dev->driver; | 694 | struct device_driver *drv = dev->driver; |
598 | int error = 0; | 695 | int error = 0; |
599 | 696 | ||
600 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 697 | if (pci_has_legacy_pm_support(pci_dev)) |
698 | return pci_legacy_suspend(dev, PMSG_HIBERNATE); | ||
601 | 699 | ||
602 | if (drv && drv->pm) { | 700 | if (drv && drv->pm && drv->pm->poweroff) { |
603 | if (drv->pm->poweroff) { | 701 | error = drv->pm->poweroff(dev); |
604 | error = drv->pm->poweroff(dev); | 702 | suspend_report_result(drv->pm->poweroff, error); |
605 | suspend_report_result(drv->pm->poweroff, error); | ||
606 | } | ||
607 | } else if (pci_has_legacy_pm_support(pci_dev)) { | ||
608 | error = pci_legacy_suspend(dev, PMSG_HIBERNATE); | ||
609 | } | 703 | } |
610 | 704 | ||
705 | if (!error) | ||
706 | pci_pm_default_suspend(pci_dev); | ||
707 | |||
611 | return error; | 708 | return error; |
612 | } | 709 | } |
613 | 710 | ||
@@ -616,54 +713,47 @@ static int pci_pm_poweroff_noirq(struct device *dev) | |||
616 | struct device_driver *drv = dev->driver; | 713 | struct device_driver *drv = dev->driver; |
617 | int error = 0; | 714 | int error = 0; |
618 | 715 | ||
619 | if (drv && drv->pm) { | 716 | if (pci_has_legacy_pm_support(to_pci_dev(dev))) |
620 | if (drv->pm->poweroff_noirq) { | 717 | return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); |
621 | error = drv->pm->poweroff_noirq(dev); | 718 | |
622 | suspend_report_result(drv->pm->poweroff_noirq, error); | 719 | if (drv && drv->pm && drv->pm->poweroff_noirq) { |
623 | } | 720 | error = drv->pm->poweroff_noirq(dev); |
624 | } else if (pci_has_legacy_pm_support(to_pci_dev(dev))) { | 721 | suspend_report_result(drv->pm->poweroff_noirq, error); |
625 | error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE); | ||
626 | } | 722 | } |
627 | 723 | ||
628 | return error; | 724 | return error; |
629 | } | 725 | } |
630 | 726 | ||
631 | static int pci_pm_restore(struct device *dev) | 727 | static int pci_pm_restore_noirq(struct device *dev) |
632 | { | 728 | { |
633 | struct pci_dev *pci_dev = to_pci_dev(dev); | 729 | struct pci_dev *pci_dev = to_pci_dev(dev); |
634 | struct device_driver *drv = dev->driver; | 730 | struct device_driver *drv = dev->driver; |
635 | int error = 0; | 731 | int error = 0; |
636 | 732 | ||
637 | if (drv && drv->pm) { | 733 | if (pci_has_legacy_pm_support(pci_dev)) |
638 | if (drv->pm->restore) | 734 | return pci_legacy_resume_early(dev); |
639 | error = drv->pm->restore(dev); | 735 | |
640 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 736 | pci_pm_default_resume_noirq(pci_dev); |
641 | error = pci_legacy_resume(dev); | 737 | |
642 | } else { | 738 | if (drv && drv->pm && drv->pm->restore_noirq) |
643 | error = pci_default_pm_resume_late(pci_dev); | 739 | error = drv->pm->restore_noirq(dev); |
644 | } | ||
645 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
646 | 740 | ||
647 | return error; | 741 | return error; |
648 | } | 742 | } |
649 | 743 | ||
650 | static int pci_pm_restore_noirq(struct device *dev) | 744 | static int pci_pm_restore(struct device *dev) |
651 | { | 745 | { |
652 | struct pci_dev *pci_dev = to_pci_dev(dev); | 746 | struct pci_dev *pci_dev = to_pci_dev(dev); |
653 | struct device_driver *drv = dev->driver; | 747 | struct device_driver *drv = dev->driver; |
654 | int error = 0; | 748 | int error = 0; |
655 | 749 | ||
656 | pci_fixup_device(pci_fixup_resume, pci_dev); | 750 | if (pci_has_legacy_pm_support(pci_dev)) |
751 | return pci_legacy_resume(dev); | ||
657 | 752 | ||
658 | if (drv && drv->pm) { | 753 | error = pci_pm_default_resume(pci_dev); |
659 | if (drv->pm->restore_noirq) | 754 | |
660 | error = drv->pm->restore_noirq(dev); | 755 | if (!error && drv && drv->pm && drv->pm->restore) |
661 | } else if (pci_has_legacy_pm_support(pci_dev)) { | 756 | error = drv->pm->restore(dev); |
662 | error = pci_legacy_resume_early(dev); | ||
663 | } else { | ||
664 | pci_default_pm_resume_early(pci_dev); | ||
665 | } | ||
666 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
667 | 757 | ||
668 | return error; | 758 | return error; |
669 | } | 759 | } |
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c new file mode 100644 index 000000000000..74fbec0bf6cb --- /dev/null +++ b/drivers/pci/pci-stub.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /* pci-stub - simple stub driver to reserve a pci device | ||
2 | * | ||
3 | * Copyright (C) 2008 Red Hat, Inc. | ||
4 | * Author: | ||
5 | * Chris Wright | ||
6 | * | ||
7 | * This work is licensed under the terms of the GNU GPL, version 2. | ||
8 | * | ||
9 | * Usage is simple, allocate a new id to the stub driver and bind the | ||
10 | * device to it. For example: | ||
11 | * | ||
12 | * # echo "8086 10f5" > /sys/bus/pci/drivers/pci-stub/new_id | ||
13 | * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind | ||
14 | * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/pci-stub/bind | ||
15 | * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver | ||
16 | * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/pci-stub | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/pci.h> | ||
21 | |||
22 | static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static struct pci_driver stub_driver = { | ||
28 | .name = "pci-stub", | ||
29 | .id_table = NULL, /* only dynamic id's */ | ||
30 | .probe = pci_stub_probe, | ||
31 | }; | ||
32 | |||
33 | static int __init pci_stub_init(void) | ||
34 | { | ||
35 | return pci_register_driver(&stub_driver); | ||
36 | } | ||
37 | |||
38 | static void __exit pci_stub_exit(void) | ||
39 | { | ||
40 | pci_unregister_driver(&stub_driver); | ||
41 | } | ||
42 | |||
43 | module_init(pci_stub_init); | ||
44 | module_exit(pci_stub_exit); | ||
45 | |||
46 | MODULE_LICENSE("GPL"); | ||
47 | MODULE_AUTHOR("Chris Wright <chrisw@sous-sol.org>"); | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index c88485860a0a..c23619fb6c4b 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -58,13 +58,14 @@ static ssize_t broken_parity_status_store(struct device *dev, | |||
58 | const char *buf, size_t count) | 58 | const char *buf, size_t count) |
59 | { | 59 | { |
60 | struct pci_dev *pdev = to_pci_dev(dev); | 60 | struct pci_dev *pdev = to_pci_dev(dev); |
61 | ssize_t consumed = -EINVAL; | 61 | unsigned long val; |
62 | 62 | ||
63 | if ((count > 0) && (*buf == '0' || *buf == '1')) { | 63 | if (strict_strtoul(buf, 0, &val) < 0) |
64 | pdev->broken_parity_status = *buf == '1' ? 1 : 0; | 64 | return -EINVAL; |
65 | consumed = count; | 65 | |
66 | } | 66 | pdev->broken_parity_status = !!val; |
67 | return consumed; | 67 | |
68 | return count; | ||
68 | } | 69 | } |
69 | 70 | ||
70 | static ssize_t local_cpus_show(struct device *dev, | 71 | static ssize_t local_cpus_show(struct device *dev, |
@@ -101,11 +102,13 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) | |||
101 | struct pci_dev * pci_dev = to_pci_dev(dev); | 102 | struct pci_dev * pci_dev = to_pci_dev(dev); |
102 | char * str = buf; | 103 | char * str = buf; |
103 | int i; | 104 | int i; |
104 | int max = 7; | 105 | int max; |
105 | resource_size_t start, end; | 106 | resource_size_t start, end; |
106 | 107 | ||
107 | if (pci_dev->subordinate) | 108 | if (pci_dev->subordinate) |
108 | max = DEVICE_COUNT_RESOURCE; | 109 | max = DEVICE_COUNT_RESOURCE; |
110 | else | ||
111 | max = PCI_BRIDGE_RESOURCES; | ||
109 | 112 | ||
110 | for (i = 0; i < max; i++) { | 113 | for (i = 0; i < max; i++) { |
111 | struct resource *res = &pci_dev->resource[i]; | 114 | struct resource *res = &pci_dev->resource[i]; |
@@ -133,19 +136,23 @@ static ssize_t is_enabled_store(struct device *dev, | |||
133 | struct device_attribute *attr, const char *buf, | 136 | struct device_attribute *attr, const char *buf, |
134 | size_t count) | 137 | size_t count) |
135 | { | 138 | { |
136 | ssize_t result = -EINVAL; | ||
137 | struct pci_dev *pdev = to_pci_dev(dev); | 139 | struct pci_dev *pdev = to_pci_dev(dev); |
140 | unsigned long val; | ||
141 | ssize_t result = strict_strtoul(buf, 0, &val); | ||
142 | |||
143 | if (result < 0) | ||
144 | return result; | ||
138 | 145 | ||
139 | /* this can crash the machine when done on the "wrong" device */ | 146 | /* this can crash the machine when done on the "wrong" device */ |
140 | if (!capable(CAP_SYS_ADMIN)) | 147 | if (!capable(CAP_SYS_ADMIN)) |
141 | return count; | 148 | return -EPERM; |
142 | 149 | ||
143 | if (*buf == '0') { | 150 | if (!val) { |
144 | if (atomic_read(&pdev->enable_cnt) != 0) | 151 | if (atomic_read(&pdev->enable_cnt) != 0) |
145 | pci_disable_device(pdev); | 152 | pci_disable_device(pdev); |
146 | else | 153 | else |
147 | result = -EIO; | 154 | result = -EIO; |
148 | } else if (*buf == '1') | 155 | } else |
149 | result = pci_enable_device(pdev); | 156 | result = pci_enable_device(pdev); |
150 | 157 | ||
151 | return result < 0 ? result : count; | 158 | return result < 0 ? result : count; |
@@ -185,25 +192,28 @@ msi_bus_store(struct device *dev, struct device_attribute *attr, | |||
185 | const char *buf, size_t count) | 192 | const char *buf, size_t count) |
186 | { | 193 | { |
187 | struct pci_dev *pdev = to_pci_dev(dev); | 194 | struct pci_dev *pdev = to_pci_dev(dev); |
195 | unsigned long val; | ||
196 | |||
197 | if (strict_strtoul(buf, 0, &val) < 0) | ||
198 | return -EINVAL; | ||
188 | 199 | ||
189 | /* bad things may happen if the no_msi flag is changed | 200 | /* bad things may happen if the no_msi flag is changed |
190 | * while some drivers are loaded */ | 201 | * while some drivers are loaded */ |
191 | if (!capable(CAP_SYS_ADMIN)) | 202 | if (!capable(CAP_SYS_ADMIN)) |
192 | return count; | 203 | return -EPERM; |
193 | 204 | ||
205 | /* Maybe pci devices without subordinate busses shouldn't even have this | ||
206 | * attribute in the first place? */ | ||
194 | if (!pdev->subordinate) | 207 | if (!pdev->subordinate) |
195 | return count; | 208 | return count; |
196 | 209 | ||
197 | if (*buf == '0') { | 210 | /* Is the flag going to change, or keep the value it already had? */ |
198 | pdev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | 211 | if (!(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) ^ |
199 | dev_warn(&pdev->dev, "forced subordinate bus to not support MSI," | 212 | !!val) { |
200 | " bad things could happen.\n"); | 213 | pdev->subordinate->bus_flags ^= PCI_BUS_FLAGS_NO_MSI; |
201 | } | ||
202 | 214 | ||
203 | if (*buf == '1') { | 215 | dev_warn(&pdev->dev, "forced subordinate bus to%s support MSI," |
204 | pdev->subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI; | 216 | " bad things could happen\n", val ? "" : " not"); |
205 | dev_warn(&pdev->dev, "forced subordinate bus to support MSI," | ||
206 | " bad things could happen.\n"); | ||
207 | } | 217 | } |
208 | 218 | ||
209 | return count; | 219 | return count; |
@@ -361,55 +371,33 @@ pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
361 | } | 371 | } |
362 | 372 | ||
363 | static ssize_t | 373 | static ssize_t |
364 | pci_read_vpd(struct kobject *kobj, struct bin_attribute *bin_attr, | 374 | read_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, |
365 | char *buf, loff_t off, size_t count) | 375 | char *buf, loff_t off, size_t count) |
366 | { | 376 | { |
367 | struct pci_dev *dev = | 377 | struct pci_dev *dev = |
368 | to_pci_dev(container_of(kobj, struct device, kobj)); | 378 | to_pci_dev(container_of(kobj, struct device, kobj)); |
369 | int end; | ||
370 | int ret; | ||
371 | 379 | ||
372 | if (off > bin_attr->size) | 380 | if (off > bin_attr->size) |
373 | count = 0; | 381 | count = 0; |
374 | else if (count > bin_attr->size - off) | 382 | else if (count > bin_attr->size - off) |
375 | count = bin_attr->size - off; | 383 | count = bin_attr->size - off; |
376 | end = off + count; | ||
377 | |||
378 | while (off < end) { | ||
379 | ret = dev->vpd->ops->read(dev, off, end - off, buf); | ||
380 | if (ret < 0) | ||
381 | return ret; | ||
382 | buf += ret; | ||
383 | off += ret; | ||
384 | } | ||
385 | 384 | ||
386 | return count; | 385 | return pci_read_vpd(dev, off, count, buf); |
387 | } | 386 | } |
388 | 387 | ||
389 | static ssize_t | 388 | static ssize_t |
390 | pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr, | 389 | write_vpd_attr(struct kobject *kobj, struct bin_attribute *bin_attr, |
391 | char *buf, loff_t off, size_t count) | 390 | char *buf, loff_t off, size_t count) |
392 | { | 391 | { |
393 | struct pci_dev *dev = | 392 | struct pci_dev *dev = |
394 | to_pci_dev(container_of(kobj, struct device, kobj)); | 393 | to_pci_dev(container_of(kobj, struct device, kobj)); |
395 | int end; | ||
396 | int ret; | ||
397 | 394 | ||
398 | if (off > bin_attr->size) | 395 | if (off > bin_attr->size) |
399 | count = 0; | 396 | count = 0; |
400 | else if (count > bin_attr->size - off) | 397 | else if (count > bin_attr->size - off) |
401 | count = bin_attr->size - off; | 398 | count = bin_attr->size - off; |
402 | end = off + count; | ||
403 | |||
404 | while (off < end) { | ||
405 | ret = dev->vpd->ops->write(dev, off, end - off, buf); | ||
406 | if (ret < 0) | ||
407 | return ret; | ||
408 | buf += ret; | ||
409 | off += ret; | ||
410 | } | ||
411 | 399 | ||
412 | return count; | 400 | return pci_write_vpd(dev, off, count, buf); |
413 | } | 401 | } |
414 | 402 | ||
415 | #ifdef HAVE_PCI_LEGACY | 403 | #ifdef HAVE_PCI_LEGACY |
@@ -569,7 +557,7 @@ void pci_remove_legacy_files(struct pci_bus *b) | |||
569 | 557 | ||
570 | #ifdef HAVE_PCI_MMAP | 558 | #ifdef HAVE_PCI_MMAP |
571 | 559 | ||
572 | static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) | 560 | int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) |
573 | { | 561 | { |
574 | unsigned long nr, start, size; | 562 | unsigned long nr, start, size; |
575 | 563 | ||
@@ -620,6 +608,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
620 | vma->vm_pgoff += start >> PAGE_SHIFT; | 608 | vma->vm_pgoff += start >> PAGE_SHIFT; |
621 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; | 609 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; |
622 | 610 | ||
611 | if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(start)) | ||
612 | return -EINVAL; | ||
613 | |||
623 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); | 614 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); |
624 | } | 615 | } |
625 | 616 | ||
@@ -832,8 +823,8 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) | |||
832 | attr->size = dev->vpd->len; | 823 | attr->size = dev->vpd->len; |
833 | attr->attr.name = "vpd"; | 824 | attr->attr.name = "vpd"; |
834 | attr->attr.mode = S_IRUSR | S_IWUSR; | 825 | attr->attr.mode = S_IRUSR | S_IWUSR; |
835 | attr->read = pci_read_vpd; | 826 | attr->read = read_vpd_attr; |
836 | attr->write = pci_write_vpd; | 827 | attr->write = write_vpd_attr; |
837 | retval = sysfs_create_bin_file(&dev->dev.kobj, attr); | 828 | retval = sysfs_create_bin_file(&dev->dev.kobj, attr); |
838 | if (retval) { | 829 | if (retval) { |
839 | kfree(dev->vpd->attr); | 830 | kfree(dev->vpd->attr); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 061d1ee0046a..c12f6c790698 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -56,6 +56,22 @@ unsigned char pci_bus_max_busnr(struct pci_bus* bus) | |||
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(pci_bus_max_busnr); | 57 | EXPORT_SYMBOL_GPL(pci_bus_max_busnr); |
58 | 58 | ||
59 | #ifdef CONFIG_HAS_IOMEM | ||
60 | void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) | ||
61 | { | ||
62 | /* | ||
63 | * Make sure the BAR is actually a memory resource, not an IO resource | ||
64 | */ | ||
65 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { | ||
66 | WARN_ON(1); | ||
67 | return NULL; | ||
68 | } | ||
69 | return ioremap_nocache(pci_resource_start(pdev, bar), | ||
70 | pci_resource_len(pdev, bar)); | ||
71 | } | ||
72 | EXPORT_SYMBOL_GPL(pci_ioremap_bar); | ||
73 | #endif | ||
74 | |||
59 | #if 0 | 75 | #if 0 |
60 | /** | 76 | /** |
61 | * pci_max_busnr - returns maximum PCI bus number | 77 | * pci_max_busnr - returns maximum PCI bus number |
@@ -360,25 +376,10 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
360 | static void | 376 | static void |
361 | pci_restore_bars(struct pci_dev *dev) | 377 | pci_restore_bars(struct pci_dev *dev) |
362 | { | 378 | { |
363 | int i, numres; | 379 | int i; |
364 | |||
365 | switch (dev->hdr_type) { | ||
366 | case PCI_HEADER_TYPE_NORMAL: | ||
367 | numres = 6; | ||
368 | break; | ||
369 | case PCI_HEADER_TYPE_BRIDGE: | ||
370 | numres = 2; | ||
371 | break; | ||
372 | case PCI_HEADER_TYPE_CARDBUS: | ||
373 | numres = 1; | ||
374 | break; | ||
375 | default: | ||
376 | /* Should never get here, but just in case... */ | ||
377 | return; | ||
378 | } | ||
379 | 380 | ||
380 | for (i = 0; i < numres; i ++) | 381 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) |
381 | pci_update_resource(dev, &dev->resource[i], i); | 382 | pci_update_resource(dev, i); |
382 | } | 383 | } |
383 | 384 | ||
384 | static struct pci_platform_pm_ops *pci_platform_pm; | 385 | static struct pci_platform_pm_ops *pci_platform_pm; |
@@ -524,14 +525,17 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
524 | * pci_update_current_state - Read PCI power state of given device from its | 525 | * pci_update_current_state - Read PCI power state of given device from its |
525 | * PCI PM registers and cache it | 526 | * PCI PM registers and cache it |
526 | * @dev: PCI device to handle. | 527 | * @dev: PCI device to handle. |
528 | * @state: State to cache in case the device doesn't have the PM capability | ||
527 | */ | 529 | */ |
528 | static void pci_update_current_state(struct pci_dev *dev) | 530 | void pci_update_current_state(struct pci_dev *dev, pci_power_t state) |
529 | { | 531 | { |
530 | if (dev->pm_cap) { | 532 | if (dev->pm_cap) { |
531 | u16 pmcsr; | 533 | u16 pmcsr; |
532 | 534 | ||
533 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | 535 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); |
534 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); | 536 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); |
537 | } else { | ||
538 | dev->current_state = state; | ||
535 | } | 539 | } |
536 | } | 540 | } |
537 | 541 | ||
@@ -574,7 +578,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
574 | */ | 578 | */ |
575 | int ret = platform_pci_set_power_state(dev, PCI_D0); | 579 | int ret = platform_pci_set_power_state(dev, PCI_D0); |
576 | if (!ret) | 580 | if (!ret) |
577 | pci_update_current_state(dev); | 581 | pci_update_current_state(dev, PCI_D0); |
578 | } | 582 | } |
579 | /* This device is quirked not to be put into D3, so | 583 | /* This device is quirked not to be put into D3, so |
580 | don't put it in D3 */ | 584 | don't put it in D3 */ |
@@ -587,7 +591,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
587 | /* Allow the platform to finalize the transition */ | 591 | /* Allow the platform to finalize the transition */ |
588 | int ret = platform_pci_set_power_state(dev, state); | 592 | int ret = platform_pci_set_power_state(dev, state); |
589 | if (!ret) { | 593 | if (!ret) { |
590 | pci_update_current_state(dev); | 594 | pci_update_current_state(dev, state); |
591 | error = 0; | 595 | error = 0; |
592 | } | 596 | } |
593 | } | 597 | } |
@@ -640,19 +644,14 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
640 | int pos, i = 0; | 644 | int pos, i = 0; |
641 | struct pci_cap_saved_state *save_state; | 645 | struct pci_cap_saved_state *save_state; |
642 | u16 *cap; | 646 | u16 *cap; |
643 | int found = 0; | ||
644 | 647 | ||
645 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 648 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); |
646 | if (pos <= 0) | 649 | if (pos <= 0) |
647 | return 0; | 650 | return 0; |
648 | 651 | ||
649 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 652 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
650 | if (!save_state) | ||
651 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); | ||
652 | else | ||
653 | found = 1; | ||
654 | if (!save_state) { | 653 | if (!save_state) { |
655 | dev_err(&dev->dev, "out of memory in pci_save_pcie_state\n"); | 654 | dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__); |
656 | return -ENOMEM; | 655 | return -ENOMEM; |
657 | } | 656 | } |
658 | cap = (u16 *)&save_state->data[0]; | 657 | cap = (u16 *)&save_state->data[0]; |
@@ -661,9 +660,7 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
661 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); | 660 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); |
662 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); | 661 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); |
663 | pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); | 662 | pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); |
664 | save_state->cap_nr = PCI_CAP_ID_EXP; | 663 | |
665 | if (!found) | ||
666 | pci_add_saved_cap(dev, save_state); | ||
667 | return 0; | 664 | return 0; |
668 | } | 665 | } |
669 | 666 | ||
@@ -688,30 +685,21 @@ static void pci_restore_pcie_state(struct pci_dev *dev) | |||
688 | 685 | ||
689 | static int pci_save_pcix_state(struct pci_dev *dev) | 686 | static int pci_save_pcix_state(struct pci_dev *dev) |
690 | { | 687 | { |
691 | int pos, i = 0; | 688 | int pos; |
692 | struct pci_cap_saved_state *save_state; | 689 | struct pci_cap_saved_state *save_state; |
693 | u16 *cap; | ||
694 | int found = 0; | ||
695 | 690 | ||
696 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 691 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
697 | if (pos <= 0) | 692 | if (pos <= 0) |
698 | return 0; | 693 | return 0; |
699 | 694 | ||
700 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); | 695 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); |
701 | if (!save_state) | ||
702 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); | ||
703 | else | ||
704 | found = 1; | ||
705 | if (!save_state) { | 696 | if (!save_state) { |
706 | dev_err(&dev->dev, "out of memory in pci_save_pcie_state\n"); | 697 | dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__); |
707 | return -ENOMEM; | 698 | return -ENOMEM; |
708 | } | 699 | } |
709 | cap = (u16 *)&save_state->data[0]; | ||
710 | 700 | ||
711 | pci_read_config_word(dev, pos + PCI_X_CMD, &cap[i++]); | 701 | pci_read_config_word(dev, pos + PCI_X_CMD, (u16 *)save_state->data); |
712 | save_state->cap_nr = PCI_CAP_ID_PCIX; | 702 | |
713 | if (!found) | ||
714 | pci_add_saved_cap(dev, save_state); | ||
715 | return 0; | 703 | return 0; |
716 | } | 704 | } |
717 | 705 | ||
@@ -982,6 +970,32 @@ void pcim_pin_device(struct pci_dev *pdev) | |||
982 | */ | 970 | */ |
983 | void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {} | 971 | void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {} |
984 | 972 | ||
973 | static void do_pci_disable_device(struct pci_dev *dev) | ||
974 | { | ||
975 | u16 pci_command; | ||
976 | |||
977 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); | ||
978 | if (pci_command & PCI_COMMAND_MASTER) { | ||
979 | pci_command &= ~PCI_COMMAND_MASTER; | ||
980 | pci_write_config_word(dev, PCI_COMMAND, pci_command); | ||
981 | } | ||
982 | |||
983 | pcibios_disable_device(dev); | ||
984 | } | ||
985 | |||
986 | /** | ||
987 | * pci_disable_enabled_device - Disable device without updating enable_cnt | ||
988 | * @dev: PCI device to disable | ||
989 | * | ||
990 | * NOTE: This function is a backend of PCI power management routines and is | ||
991 | * not supposed to be called drivers. | ||
992 | */ | ||
993 | void pci_disable_enabled_device(struct pci_dev *dev) | ||
994 | { | ||
995 | if (atomic_read(&dev->enable_cnt)) | ||
996 | do_pci_disable_device(dev); | ||
997 | } | ||
998 | |||
985 | /** | 999 | /** |
986 | * pci_disable_device - Disable PCI device after use | 1000 | * pci_disable_device - Disable PCI device after use |
987 | * @dev: PCI device to be disabled | 1001 | * @dev: PCI device to be disabled |
@@ -996,7 +1010,6 @@ void | |||
996 | pci_disable_device(struct pci_dev *dev) | 1010 | pci_disable_device(struct pci_dev *dev) |
997 | { | 1011 | { |
998 | struct pci_devres *dr; | 1012 | struct pci_devres *dr; |
999 | u16 pci_command; | ||
1000 | 1013 | ||
1001 | dr = find_pci_dr(dev); | 1014 | dr = find_pci_dr(dev); |
1002 | if (dr) | 1015 | if (dr) |
@@ -1005,14 +1018,9 @@ pci_disable_device(struct pci_dev *dev) | |||
1005 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) | 1018 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) |
1006 | return; | 1019 | return; |
1007 | 1020 | ||
1008 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); | 1021 | do_pci_disable_device(dev); |
1009 | if (pci_command & PCI_COMMAND_MASTER) { | ||
1010 | pci_command &= ~PCI_COMMAND_MASTER; | ||
1011 | pci_write_config_word(dev, PCI_COMMAND, pci_command); | ||
1012 | } | ||
1013 | dev->is_busmaster = 0; | ||
1014 | 1022 | ||
1015 | pcibios_disable_device(dev); | 1023 | dev->is_busmaster = 0; |
1016 | } | 1024 | } |
1017 | 1025 | ||
1018 | /** | 1026 | /** |
@@ -1107,7 +1115,7 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) | |||
1107 | int error = 0; | 1115 | int error = 0; |
1108 | bool pme_done = false; | 1116 | bool pme_done = false; |
1109 | 1117 | ||
1110 | if (!device_may_wakeup(&dev->dev)) | 1118 | if (enable && !device_may_wakeup(&dev->dev)) |
1111 | return -EINVAL; | 1119 | return -EINVAL; |
1112 | 1120 | ||
1113 | /* | 1121 | /* |
@@ -1252,14 +1260,15 @@ void pci_pm_init(struct pci_dev *dev) | |||
1252 | /* find PCI PM capability in list */ | 1260 | /* find PCI PM capability in list */ |
1253 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 1261 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
1254 | if (!pm) | 1262 | if (!pm) |
1255 | return; | 1263 | goto Exit; |
1264 | |||
1256 | /* Check device's ability to generate PME# */ | 1265 | /* Check device's ability to generate PME# */ |
1257 | pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); | 1266 | pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); |
1258 | 1267 | ||
1259 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { | 1268 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { |
1260 | dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", | 1269 | dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", |
1261 | pmc & PCI_PM_CAP_VER_MASK); | 1270 | pmc & PCI_PM_CAP_VER_MASK); |
1262 | return; | 1271 | goto Exit; |
1263 | } | 1272 | } |
1264 | 1273 | ||
1265 | dev->pm_cap = pm; | 1274 | dev->pm_cap = pm; |
@@ -1298,6 +1307,74 @@ void pci_pm_init(struct pci_dev *dev) | |||
1298 | } else { | 1307 | } else { |
1299 | dev->pme_support = 0; | 1308 | dev->pme_support = 0; |
1300 | } | 1309 | } |
1310 | |||
1311 | Exit: | ||
1312 | pci_update_current_state(dev, PCI_D0); | ||
1313 | } | ||
1314 | |||
1315 | /** | ||
1316 | * platform_pci_wakeup_init - init platform wakeup if present | ||
1317 | * @dev: PCI device | ||
1318 | * | ||
1319 | * Some devices don't have PCI PM caps but can still generate wakeup | ||
1320 | * events through platform methods (like ACPI events). If @dev supports | ||
1321 | * platform wakeup events, set the device flag to indicate as much. This | ||
1322 | * may be redundant if the device also supports PCI PM caps, but double | ||
1323 | * initialization should be safe in that case. | ||
1324 | */ | ||
1325 | void platform_pci_wakeup_init(struct pci_dev *dev) | ||
1326 | { | ||
1327 | if (!platform_pci_can_wakeup(dev)) | ||
1328 | return; | ||
1329 | |||
1330 | device_set_wakeup_capable(&dev->dev, true); | ||
1331 | device_set_wakeup_enable(&dev->dev, false); | ||
1332 | platform_pci_sleep_wake(dev, false); | ||
1333 | } | ||
1334 | |||
1335 | /** | ||
1336 | * pci_add_save_buffer - allocate buffer for saving given capability registers | ||
1337 | * @dev: the PCI device | ||
1338 | * @cap: the capability to allocate the buffer for | ||
1339 | * @size: requested size of the buffer | ||
1340 | */ | ||
1341 | static int pci_add_cap_save_buffer( | ||
1342 | struct pci_dev *dev, char cap, unsigned int size) | ||
1343 | { | ||
1344 | int pos; | ||
1345 | struct pci_cap_saved_state *save_state; | ||
1346 | |||
1347 | pos = pci_find_capability(dev, cap); | ||
1348 | if (pos <= 0) | ||
1349 | return 0; | ||
1350 | |||
1351 | save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL); | ||
1352 | if (!save_state) | ||
1353 | return -ENOMEM; | ||
1354 | |||
1355 | save_state->cap_nr = cap; | ||
1356 | pci_add_saved_cap(dev, save_state); | ||
1357 | |||
1358 | return 0; | ||
1359 | } | ||
1360 | |||
1361 | /** | ||
1362 | * pci_allocate_cap_save_buffers - allocate buffers for saving capabilities | ||
1363 | * @dev: the PCI device | ||
1364 | */ | ||
1365 | void pci_allocate_cap_save_buffers(struct pci_dev *dev) | ||
1366 | { | ||
1367 | int error; | ||
1368 | |||
1369 | error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, 4 * sizeof(u16)); | ||
1370 | if (error) | ||
1371 | dev_err(&dev->dev, | ||
1372 | "unable to preallocate PCI Express save buffer\n"); | ||
1373 | |||
1374 | error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_PCIX, sizeof(u16)); | ||
1375 | if (error) | ||
1376 | dev_err(&dev->dev, | ||
1377 | "unable to preallocate PCI-X save buffer\n"); | ||
1301 | } | 1378 | } |
1302 | 1379 | ||
1303 | /** | 1380 | /** |
@@ -1337,6 +1414,20 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1337 | bridge->ari_enabled = 1; | 1414 | bridge->ari_enabled = 1; |
1338 | } | 1415 | } |
1339 | 1416 | ||
1417 | /** | ||
1418 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge | ||
1419 | * @dev: the PCI device | ||
1420 | * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD) | ||
1421 | * | ||
1422 | * Perform INTx swizzling for a device behind one level of bridge. This is | ||
1423 | * required by section 9.1 of the PCI-to-PCI bridge specification for devices | ||
1424 | * behind bridges on add-in cards. | ||
1425 | */ | ||
1426 | u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin) | ||
1427 | { | ||
1428 | return (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1; | ||
1429 | } | ||
1430 | |||
1340 | int | 1431 | int |
1341 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) | 1432 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) |
1342 | { | 1433 | { |
@@ -1345,9 +1436,9 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) | |||
1345 | pin = dev->pin; | 1436 | pin = dev->pin; |
1346 | if (!pin) | 1437 | if (!pin) |
1347 | return -1; | 1438 | return -1; |
1348 | pin--; | 1439 | |
1349 | while (dev->bus->self) { | 1440 | while (dev->bus->self) { |
1350 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1441 | pin = pci_swizzle_interrupt_pin(dev, pin); |
1351 | dev = dev->bus->self; | 1442 | dev = dev->bus->self; |
1352 | } | 1443 | } |
1353 | *bridge = dev; | 1444 | *bridge = dev; |
@@ -1355,6 +1446,26 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) | |||
1355 | } | 1446 | } |
1356 | 1447 | ||
1357 | /** | 1448 | /** |
1449 | * pci_common_swizzle - swizzle INTx all the way to root bridge | ||
1450 | * @dev: the PCI device | ||
1451 | * @pinp: pointer to the INTx pin value (1=INTA, 2=INTB, 3=INTD, 4=INTD) | ||
1452 | * | ||
1453 | * Perform INTx swizzling for a device. This traverses through all PCI-to-PCI | ||
1454 | * bridges all the way up to a PCI root bus. | ||
1455 | */ | ||
1456 | u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp) | ||
1457 | { | ||
1458 | u8 pin = *pinp; | ||
1459 | |||
1460 | while (dev->bus->self) { | ||
1461 | pin = pci_swizzle_interrupt_pin(dev, pin); | ||
1462 | dev = dev->bus->self; | ||
1463 | } | ||
1464 | *pinp = pin; | ||
1465 | return PCI_SLOT(dev->devfn); | ||
1466 | } | ||
1467 | |||
1468 | /** | ||
1358 | * pci_release_region - Release a PCI bar | 1469 | * pci_release_region - Release a PCI bar |
1359 | * @pdev: PCI device whose resources were previously reserved by pci_request_region | 1470 | * @pdev: PCI device whose resources were previously reserved by pci_request_region |
1360 | * @bar: BAR to release | 1471 | * @bar: BAR to release |
@@ -1395,7 +1506,8 @@ void pci_release_region(struct pci_dev *pdev, int bar) | |||
1395 | * Returns 0 on success, or %EBUSY on error. A warning | 1506 | * Returns 0 on success, or %EBUSY on error. A warning |
1396 | * message is also printed on failure. | 1507 | * message is also printed on failure. |
1397 | */ | 1508 | */ |
1398 | int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | 1509 | static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, |
1510 | int exclusive) | ||
1399 | { | 1511 | { |
1400 | struct pci_devres *dr; | 1512 | struct pci_devres *dr; |
1401 | 1513 | ||
@@ -1408,8 +1520,9 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | |||
1408 | goto err_out; | 1520 | goto err_out; |
1409 | } | 1521 | } |
1410 | else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { | 1522 | else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { |
1411 | if (!request_mem_region(pci_resource_start(pdev, bar), | 1523 | if (!__request_mem_region(pci_resource_start(pdev, bar), |
1412 | pci_resource_len(pdev, bar), res_name)) | 1524 | pci_resource_len(pdev, bar), res_name, |
1525 | exclusive)) | ||
1413 | goto err_out; | 1526 | goto err_out; |
1414 | } | 1527 | } |
1415 | 1528 | ||
@@ -1428,6 +1541,47 @@ err_out: | |||
1428 | } | 1541 | } |
1429 | 1542 | ||
1430 | /** | 1543 | /** |
1544 | * pci_request_region - Reserved PCI I/O and memory resource | ||
1545 | * @pdev: PCI device whose resources are to be reserved | ||
1546 | * @bar: BAR to be reserved | ||
1547 | * @res_name: Name to be associated with resource. | ||
1548 | * | ||
1549 | * Mark the PCI region associated with PCI device @pdev BR @bar as | ||
1550 | * being reserved by owner @res_name. Do not access any | ||
1551 | * address inside the PCI regions unless this call returns | ||
1552 | * successfully. | ||
1553 | * | ||
1554 | * Returns 0 on success, or %EBUSY on error. A warning | ||
1555 | * message is also printed on failure. | ||
1556 | */ | ||
1557 | int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | ||
1558 | { | ||
1559 | return __pci_request_region(pdev, bar, res_name, 0); | ||
1560 | } | ||
1561 | |||
1562 | /** | ||
1563 | * pci_request_region_exclusive - Reserved PCI I/O and memory resource | ||
1564 | * @pdev: PCI device whose resources are to be reserved | ||
1565 | * @bar: BAR to be reserved | ||
1566 | * @res_name: Name to be associated with resource. | ||
1567 | * | ||
1568 | * Mark the PCI region associated with PCI device @pdev BR @bar as | ||
1569 | * being reserved by owner @res_name. Do not access any | ||
1570 | * address inside the PCI regions unless this call returns | ||
1571 | * successfully. | ||
1572 | * | ||
1573 | * Returns 0 on success, or %EBUSY on error. A warning | ||
1574 | * message is also printed on failure. | ||
1575 | * | ||
1576 | * The key difference that _exclusive makes it that userspace is | ||
1577 | * explicitly not allowed to map the resource via /dev/mem or | ||
1578 | * sysfs. | ||
1579 | */ | ||
1580 | int pci_request_region_exclusive(struct pci_dev *pdev, int bar, const char *res_name) | ||
1581 | { | ||
1582 | return __pci_request_region(pdev, bar, res_name, IORESOURCE_EXCLUSIVE); | ||
1583 | } | ||
1584 | /** | ||
1431 | * pci_release_selected_regions - Release selected PCI I/O and memory resources | 1585 | * pci_release_selected_regions - Release selected PCI I/O and memory resources |
1432 | * @pdev: PCI device whose resources were previously reserved | 1586 | * @pdev: PCI device whose resources were previously reserved |
1433 | * @bars: Bitmask of BARs to be released | 1587 | * @bars: Bitmask of BARs to be released |
@@ -1444,20 +1598,14 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) | |||
1444 | pci_release_region(pdev, i); | 1598 | pci_release_region(pdev, i); |
1445 | } | 1599 | } |
1446 | 1600 | ||
1447 | /** | 1601 | int __pci_request_selected_regions(struct pci_dev *pdev, int bars, |
1448 | * pci_request_selected_regions - Reserve selected PCI I/O and memory resources | 1602 | const char *res_name, int excl) |
1449 | * @pdev: PCI device whose resources are to be reserved | ||
1450 | * @bars: Bitmask of BARs to be requested | ||
1451 | * @res_name: Name to be associated with resource | ||
1452 | */ | ||
1453 | int pci_request_selected_regions(struct pci_dev *pdev, int bars, | ||
1454 | const char *res_name) | ||
1455 | { | 1603 | { |
1456 | int i; | 1604 | int i; |
1457 | 1605 | ||
1458 | for (i = 0; i < 6; i++) | 1606 | for (i = 0; i < 6; i++) |
1459 | if (bars & (1 << i)) | 1607 | if (bars & (1 << i)) |
1460 | if(pci_request_region(pdev, i, res_name)) | 1608 | if (__pci_request_region(pdev, i, res_name, excl)) |
1461 | goto err_out; | 1609 | goto err_out; |
1462 | return 0; | 1610 | return 0; |
1463 | 1611 | ||
@@ -1469,6 +1617,26 @@ err_out: | |||
1469 | return -EBUSY; | 1617 | return -EBUSY; |
1470 | } | 1618 | } |
1471 | 1619 | ||
1620 | |||
1621 | /** | ||
1622 | * pci_request_selected_regions - Reserve selected PCI I/O and memory resources | ||
1623 | * @pdev: PCI device whose resources are to be reserved | ||
1624 | * @bars: Bitmask of BARs to be requested | ||
1625 | * @res_name: Name to be associated with resource | ||
1626 | */ | ||
1627 | int pci_request_selected_regions(struct pci_dev *pdev, int bars, | ||
1628 | const char *res_name) | ||
1629 | { | ||
1630 | return __pci_request_selected_regions(pdev, bars, res_name, 0); | ||
1631 | } | ||
1632 | |||
1633 | int pci_request_selected_regions_exclusive(struct pci_dev *pdev, | ||
1634 | int bars, const char *res_name) | ||
1635 | { | ||
1636 | return __pci_request_selected_regions(pdev, bars, res_name, | ||
1637 | IORESOURCE_EXCLUSIVE); | ||
1638 | } | ||
1639 | |||
1472 | /** | 1640 | /** |
1473 | * pci_release_regions - Release reserved PCI I/O and memory resources | 1641 | * pci_release_regions - Release reserved PCI I/O and memory resources |
1474 | * @pdev: PCI device whose resources were previously reserved by pci_request_regions | 1642 | * @pdev: PCI device whose resources were previously reserved by pci_request_regions |
@@ -1502,27 +1670,66 @@ int pci_request_regions(struct pci_dev *pdev, const char *res_name) | |||
1502 | } | 1670 | } |
1503 | 1671 | ||
1504 | /** | 1672 | /** |
1673 | * pci_request_regions_exclusive - Reserved PCI I/O and memory resources | ||
1674 | * @pdev: PCI device whose resources are to be reserved | ||
1675 | * @res_name: Name to be associated with resource. | ||
1676 | * | ||
1677 | * Mark all PCI regions associated with PCI device @pdev as | ||
1678 | * being reserved by owner @res_name. Do not access any | ||
1679 | * address inside the PCI regions unless this call returns | ||
1680 | * successfully. | ||
1681 | * | ||
1682 | * pci_request_regions_exclusive() will mark the region so that | ||
1683 | * /dev/mem and the sysfs MMIO access will not be allowed. | ||
1684 | * | ||
1685 | * Returns 0 on success, or %EBUSY on error. A warning | ||
1686 | * message is also printed on failure. | ||
1687 | */ | ||
1688 | int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | ||
1689 | { | ||
1690 | return pci_request_selected_regions_exclusive(pdev, | ||
1691 | ((1 << 6) - 1), res_name); | ||
1692 | } | ||
1693 | |||
1694 | static void __pci_set_master(struct pci_dev *dev, bool enable) | ||
1695 | { | ||
1696 | u16 old_cmd, cmd; | ||
1697 | |||
1698 | pci_read_config_word(dev, PCI_COMMAND, &old_cmd); | ||
1699 | if (enable) | ||
1700 | cmd = old_cmd | PCI_COMMAND_MASTER; | ||
1701 | else | ||
1702 | cmd = old_cmd & ~PCI_COMMAND_MASTER; | ||
1703 | if (cmd != old_cmd) { | ||
1704 | dev_dbg(&dev->dev, "%s bus mastering\n", | ||
1705 | enable ? "enabling" : "disabling"); | ||
1706 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
1707 | } | ||
1708 | dev->is_busmaster = enable; | ||
1709 | } | ||
1710 | |||
1711 | /** | ||
1505 | * pci_set_master - enables bus-mastering for device dev | 1712 | * pci_set_master - enables bus-mastering for device dev |
1506 | * @dev: the PCI device to enable | 1713 | * @dev: the PCI device to enable |
1507 | * | 1714 | * |
1508 | * Enables bus-mastering on the device and calls pcibios_set_master() | 1715 | * Enables bus-mastering on the device and calls pcibios_set_master() |
1509 | * to do the needed arch specific settings. | 1716 | * to do the needed arch specific settings. |
1510 | */ | 1717 | */ |
1511 | void | 1718 | void pci_set_master(struct pci_dev *dev) |
1512 | pci_set_master(struct pci_dev *dev) | ||
1513 | { | 1719 | { |
1514 | u16 cmd; | 1720 | __pci_set_master(dev, true); |
1515 | |||
1516 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
1517 | if (! (cmd & PCI_COMMAND_MASTER)) { | ||
1518 | dev_dbg(&dev->dev, "enabling bus mastering\n"); | ||
1519 | cmd |= PCI_COMMAND_MASTER; | ||
1520 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
1521 | } | ||
1522 | dev->is_busmaster = 1; | ||
1523 | pcibios_set_master(dev); | 1721 | pcibios_set_master(dev); |
1524 | } | 1722 | } |
1525 | 1723 | ||
1724 | /** | ||
1725 | * pci_clear_master - disables bus-mastering for device dev | ||
1726 | * @dev: the PCI device to disable | ||
1727 | */ | ||
1728 | void pci_clear_master(struct pci_dev *dev) | ||
1729 | { | ||
1730 | __pci_set_master(dev, false); | ||
1731 | } | ||
1732 | |||
1526 | #ifdef PCI_DISABLE_MWI | 1733 | #ifdef PCI_DISABLE_MWI |
1527 | int pci_set_mwi(struct pci_dev *dev) | 1734 | int pci_set_mwi(struct pci_dev *dev) |
1528 | { | 1735 | { |
@@ -1751,24 +1958,7 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask) | |||
1751 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); | 1958 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); |
1752 | #endif | 1959 | #endif |
1753 | 1960 | ||
1754 | /** | 1961 | static int __pcie_flr(struct pci_dev *dev, int probe) |
1755 | * pci_execute_reset_function() - Reset a PCI device function | ||
1756 | * @dev: Device function to reset | ||
1757 | * | ||
1758 | * Some devices allow an individual function to be reset without affecting | ||
1759 | * other functions in the same device. The PCI device must be responsive | ||
1760 | * to PCI config space in order to use this function. | ||
1761 | * | ||
1762 | * The device function is presumed to be unused when this function is called. | ||
1763 | * Resetting the device will make the contents of PCI configuration space | ||
1764 | * random, so any caller of this must be prepared to reinitialise the | ||
1765 | * device including MSI, bus mastering, BARs, decoding IO and memory spaces, | ||
1766 | * etc. | ||
1767 | * | ||
1768 | * Returns 0 if the device function was successfully reset or -ENOTTY if the | ||
1769 | * device doesn't support resetting a single function. | ||
1770 | */ | ||
1771 | int pci_execute_reset_function(struct pci_dev *dev) | ||
1772 | { | 1962 | { |
1773 | u16 status; | 1963 | u16 status; |
1774 | u32 cap; | 1964 | u32 cap; |
@@ -1780,6 +1970,9 @@ int pci_execute_reset_function(struct pci_dev *dev) | |||
1780 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | 1970 | if (!(cap & PCI_EXP_DEVCAP_FLR)) |
1781 | return -ENOTTY; | 1971 | return -ENOTTY; |
1782 | 1972 | ||
1973 | if (probe) | ||
1974 | return 0; | ||
1975 | |||
1783 | pci_block_user_cfg_access(dev); | 1976 | pci_block_user_cfg_access(dev); |
1784 | 1977 | ||
1785 | /* Wait for Transaction Pending bit clean */ | 1978 | /* Wait for Transaction Pending bit clean */ |
@@ -1802,6 +1995,80 @@ int pci_execute_reset_function(struct pci_dev *dev) | |||
1802 | pci_unblock_user_cfg_access(dev); | 1995 | pci_unblock_user_cfg_access(dev); |
1803 | return 0; | 1996 | return 0; |
1804 | } | 1997 | } |
1998 | |||
1999 | static int __pci_af_flr(struct pci_dev *dev, int probe) | ||
2000 | { | ||
2001 | int cappos = pci_find_capability(dev, PCI_CAP_ID_AF); | ||
2002 | u8 status; | ||
2003 | u8 cap; | ||
2004 | |||
2005 | if (!cappos) | ||
2006 | return -ENOTTY; | ||
2007 | pci_read_config_byte(dev, cappos + PCI_AF_CAP, &cap); | ||
2008 | if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR)) | ||
2009 | return -ENOTTY; | ||
2010 | |||
2011 | if (probe) | ||
2012 | return 0; | ||
2013 | |||
2014 | pci_block_user_cfg_access(dev); | ||
2015 | |||
2016 | /* Wait for Transaction Pending bit clean */ | ||
2017 | msleep(100); | ||
2018 | pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); | ||
2019 | if (status & PCI_AF_STATUS_TP) { | ||
2020 | dev_info(&dev->dev, "Busy after 100ms while trying to" | ||
2021 | " reset; sleeping for 1 second\n"); | ||
2022 | ssleep(1); | ||
2023 | pci_read_config_byte(dev, | ||
2024 | cappos + PCI_AF_STATUS, &status); | ||
2025 | if (status & PCI_AF_STATUS_TP) | ||
2026 | dev_info(&dev->dev, "Still busy after 1s; " | ||
2027 | "proceeding with reset anyway\n"); | ||
2028 | } | ||
2029 | pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); | ||
2030 | mdelay(100); | ||
2031 | |||
2032 | pci_unblock_user_cfg_access(dev); | ||
2033 | return 0; | ||
2034 | } | ||
2035 | |||
2036 | static int __pci_reset_function(struct pci_dev *pdev, int probe) | ||
2037 | { | ||
2038 | int res; | ||
2039 | |||
2040 | res = __pcie_flr(pdev, probe); | ||
2041 | if (res != -ENOTTY) | ||
2042 | return res; | ||
2043 | |||
2044 | res = __pci_af_flr(pdev, probe); | ||
2045 | if (res != -ENOTTY) | ||
2046 | return res; | ||
2047 | |||
2048 | return res; | ||
2049 | } | ||
2050 | |||
2051 | /** | ||
2052 | * pci_execute_reset_function() - Reset a PCI device function | ||
2053 | * @dev: Device function to reset | ||
2054 | * | ||
2055 | * Some devices allow an individual function to be reset without affecting | ||
2056 | * other functions in the same device. The PCI device must be responsive | ||
2057 | * to PCI config space in order to use this function. | ||
2058 | * | ||
2059 | * The device function is presumed to be unused when this function is called. | ||
2060 | * Resetting the device will make the contents of PCI configuration space | ||
2061 | * random, so any caller of this must be prepared to reinitialise the | ||
2062 | * device including MSI, bus mastering, BARs, decoding IO and memory spaces, | ||
2063 | * etc. | ||
2064 | * | ||
2065 | * Returns 0 if the device function was successfully reset or -ENOTTY if the | ||
2066 | * device doesn't support resetting a single function. | ||
2067 | */ | ||
2068 | int pci_execute_reset_function(struct pci_dev *dev) | ||
2069 | { | ||
2070 | return __pci_reset_function(dev, 0); | ||
2071 | } | ||
1805 | EXPORT_SYMBOL_GPL(pci_execute_reset_function); | 2072 | EXPORT_SYMBOL_GPL(pci_execute_reset_function); |
1806 | 2073 | ||
1807 | /** | 2074 | /** |
@@ -1822,15 +2089,10 @@ EXPORT_SYMBOL_GPL(pci_execute_reset_function); | |||
1822 | */ | 2089 | */ |
1823 | int pci_reset_function(struct pci_dev *dev) | 2090 | int pci_reset_function(struct pci_dev *dev) |
1824 | { | 2091 | { |
1825 | u32 cap; | 2092 | int r = __pci_reset_function(dev, 1); |
1826 | int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1827 | int r; | ||
1828 | 2093 | ||
1829 | if (!exppos) | 2094 | if (r < 0) |
1830 | return -ENOTTY; | 2095 | return r; |
1831 | pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap); | ||
1832 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | ||
1833 | return -ENOTTY; | ||
1834 | 2096 | ||
1835 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) | 2097 | if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0) |
1836 | disable_irq(dev->irq); | 2098 | disable_irq(dev->irq); |
@@ -2022,6 +2284,28 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags) | |||
2022 | return bars; | 2284 | return bars; |
2023 | } | 2285 | } |
2024 | 2286 | ||
2287 | /** | ||
2288 | * pci_resource_bar - get position of the BAR associated with a resource | ||
2289 | * @dev: the PCI device | ||
2290 | * @resno: the resource number | ||
2291 | * @type: the BAR type to be filled in | ||
2292 | * | ||
2293 | * Returns BAR position in config space, or 0 if the BAR is invalid. | ||
2294 | */ | ||
2295 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | ||
2296 | { | ||
2297 | if (resno < PCI_ROM_RESOURCE) { | ||
2298 | *type = pci_bar_unknown; | ||
2299 | return PCI_BASE_ADDRESS_0 + 4 * resno; | ||
2300 | } else if (resno == PCI_ROM_RESOURCE) { | ||
2301 | *type = pci_bar_mem32; | ||
2302 | return dev->rom_base_reg; | ||
2303 | } | ||
2304 | |||
2305 | dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); | ||
2306 | return 0; | ||
2307 | } | ||
2308 | |||
2025 | static void __devinit pci_no_domains(void) | 2309 | static void __devinit pci_no_domains(void) |
2026 | { | 2310 | { |
2027 | #ifdef CONFIG_PCI_DOMAINS | 2311 | #ifdef CONFIG_PCI_DOMAINS |
@@ -2029,6 +2313,19 @@ static void __devinit pci_no_domains(void) | |||
2029 | #endif | 2313 | #endif |
2030 | } | 2314 | } |
2031 | 2315 | ||
2316 | /** | ||
2317 | * pci_ext_cfg_enabled - can we access extended PCI config space? | ||
2318 | * @dev: The PCI device of the root bridge. | ||
2319 | * | ||
2320 | * Returns 1 if we can access PCI extended config space (offsets | ||
2321 | * greater than 0xff). This is the default implementation. Architecture | ||
2322 | * implementations can override this. | ||
2323 | */ | ||
2324 | int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) | ||
2325 | { | ||
2326 | return 1; | ||
2327 | } | ||
2328 | |||
2032 | static int __devinit pci_init(void) | 2329 | static int __devinit pci_init(void) |
2033 | { | 2330 | { |
2034 | struct pci_dev *dev = NULL; | 2331 | struct pci_dev *dev = NULL; |
@@ -2037,8 +2334,6 @@ static int __devinit pci_init(void) | |||
2037 | pci_fixup_device(pci_fixup_final, dev); | 2334 | pci_fixup_device(pci_fixup_final, dev); |
2038 | } | 2335 | } |
2039 | 2336 | ||
2040 | msi_init(); | ||
2041 | |||
2042 | return 0; | 2337 | return 0; |
2043 | } | 2338 | } |
2044 | 2339 | ||
@@ -2083,11 +2378,15 @@ EXPORT_SYMBOL(pci_find_capability); | |||
2083 | EXPORT_SYMBOL(pci_bus_find_capability); | 2378 | EXPORT_SYMBOL(pci_bus_find_capability); |
2084 | EXPORT_SYMBOL(pci_release_regions); | 2379 | EXPORT_SYMBOL(pci_release_regions); |
2085 | EXPORT_SYMBOL(pci_request_regions); | 2380 | EXPORT_SYMBOL(pci_request_regions); |
2381 | EXPORT_SYMBOL(pci_request_regions_exclusive); | ||
2086 | EXPORT_SYMBOL(pci_release_region); | 2382 | EXPORT_SYMBOL(pci_release_region); |
2087 | EXPORT_SYMBOL(pci_request_region); | 2383 | EXPORT_SYMBOL(pci_request_region); |
2384 | EXPORT_SYMBOL(pci_request_region_exclusive); | ||
2088 | EXPORT_SYMBOL(pci_release_selected_regions); | 2385 | EXPORT_SYMBOL(pci_release_selected_regions); |
2089 | EXPORT_SYMBOL(pci_request_selected_regions); | 2386 | EXPORT_SYMBOL(pci_request_selected_regions); |
2387 | EXPORT_SYMBOL(pci_request_selected_regions_exclusive); | ||
2090 | EXPORT_SYMBOL(pci_set_master); | 2388 | EXPORT_SYMBOL(pci_set_master); |
2389 | EXPORT_SYMBOL(pci_clear_master); | ||
2091 | EXPORT_SYMBOL(pci_set_mwi); | 2390 | EXPORT_SYMBOL(pci_set_mwi); |
2092 | EXPORT_SYMBOL(pci_try_set_mwi); | 2391 | EXPORT_SYMBOL(pci_try_set_mwi); |
2093 | EXPORT_SYMBOL(pci_clear_mwi); | 2392 | EXPORT_SYMBOL(pci_clear_mwi); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9de87e9f98f5..1351bb4addde 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -10,6 +10,10 @@ extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); | |||
10 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 10 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
11 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 11 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
12 | extern void pci_cleanup_rom(struct pci_dev *dev); | 12 | extern void pci_cleanup_rom(struct pci_dev *dev); |
13 | #ifdef HAVE_PCI_MMAP | ||
14 | extern int pci_mmap_fits(struct pci_dev *pdev, int resno, | ||
15 | struct vm_area_struct *vma); | ||
16 | #endif | ||
13 | 17 | ||
14 | /** | 18 | /** |
15 | * Firmware PM callbacks | 19 | * Firmware PM callbacks |
@@ -40,7 +44,11 @@ struct pci_platform_pm_ops { | |||
40 | }; | 44 | }; |
41 | 45 | ||
42 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 46 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
47 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | ||
48 | extern void pci_disable_enabled_device(struct pci_dev *dev); | ||
43 | extern void pci_pm_init(struct pci_dev *dev); | 49 | extern void pci_pm_init(struct pci_dev *dev); |
50 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | ||
51 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | ||
44 | 52 | ||
45 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); | 53 | extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); |
46 | extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); | 54 | extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); |
@@ -50,14 +58,14 @@ extern int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); | |||
50 | extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); | 58 | extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); |
51 | 59 | ||
52 | struct pci_vpd_ops { | 60 | struct pci_vpd_ops { |
53 | int (*read)(struct pci_dev *dev, int pos, int size, char *buf); | 61 | ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); |
54 | int (*write)(struct pci_dev *dev, int pos, int size, const char *buf); | 62 | ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); |
55 | void (*release)(struct pci_dev *dev); | 63 | void (*release)(struct pci_dev *dev); |
56 | }; | 64 | }; |
57 | 65 | ||
58 | struct pci_vpd { | 66 | struct pci_vpd { |
59 | unsigned int len; | 67 | unsigned int len; |
60 | struct pci_vpd_ops *ops; | 68 | const struct pci_vpd_ops *ops; |
61 | struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ | 69 | struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ |
62 | }; | 70 | }; |
63 | 71 | ||
@@ -98,11 +106,9 @@ extern unsigned int pci_pm_d3_delay; | |||
98 | #ifdef CONFIG_PCI_MSI | 106 | #ifdef CONFIG_PCI_MSI |
99 | void pci_no_msi(void); | 107 | void pci_no_msi(void); |
100 | extern void pci_msi_init_pci_dev(struct pci_dev *dev); | 108 | extern void pci_msi_init_pci_dev(struct pci_dev *dev); |
101 | extern void __devinit msi_init(void); | ||
102 | #else | 109 | #else |
103 | static inline void pci_no_msi(void) { } | 110 | static inline void pci_no_msi(void) { } |
104 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 111 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
105 | static inline void msi_init(void) { } | ||
106 | #endif | 112 | #endif |
107 | 113 | ||
108 | #ifdef CONFIG_PCIEAER | 114 | #ifdef CONFIG_PCIEAER |
@@ -159,16 +165,28 @@ struct pci_slot_attribute { | |||
159 | }; | 165 | }; |
160 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) | 166 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) |
161 | 167 | ||
168 | enum pci_bar_type { | ||
169 | pci_bar_unknown, /* Standard PCI BAR probe */ | ||
170 | pci_bar_io, /* An io port BAR */ | ||
171 | pci_bar_mem32, /* A 32-bit memory BAR */ | ||
172 | pci_bar_mem64, /* A 64-bit memory BAR */ | ||
173 | }; | ||
174 | |||
175 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | ||
176 | struct resource *res, unsigned int reg); | ||
177 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | ||
178 | enum pci_bar_type *type); | ||
179 | extern int pci_bus_add_child(struct pci_bus *bus); | ||
162 | extern void pci_enable_ari(struct pci_dev *dev); | 180 | extern void pci_enable_ari(struct pci_dev *dev); |
163 | /** | 181 | /** |
164 | * pci_ari_enabled - query ARI forwarding status | 182 | * pci_ari_enabled - query ARI forwarding status |
165 | * @dev: the PCI device | 183 | * @bus: the PCI bus |
166 | * | 184 | * |
167 | * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; | 185 | * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; |
168 | */ | 186 | */ |
169 | static inline int pci_ari_enabled(struct pci_dev *dev) | 187 | static inline int pci_ari_enabled(struct pci_bus *bus) |
170 | { | 188 | { |
171 | return dev->ari_enabled; | 189 | return bus->self && bus->self->ari_enabled; |
172 | } | 190 | } |
173 | 191 | ||
174 | #endif /* DRIVERS_PCI_H */ | 192 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 6dd7b13e9808..ebce26c37049 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -38,7 +38,6 @@ int aer_osc_setup(struct pcie_device *pciedev) | |||
38 | 38 | ||
39 | handle = acpi_find_root_bridge_handle(pdev); | 39 | handle = acpi_find_root_bridge_handle(pdev); |
40 | if (handle) { | 40 | if (handle) { |
41 | pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); | ||
42 | status = pci_osc_control_set(handle, | 41 | status = pci_osc_control_set(handle, |
43 | OSC_PCI_EXPRESS_AER_CONTROL | | 42 | OSC_PCI_EXPRESS_AER_CONTROL | |
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | 43 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 3933d4f30e8c..0fc29ae80df8 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -233,7 +233,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
233 | 233 | ||
234 | if (info->flags & AER_TLP_HEADER_VALID_FLAG) { | 234 | if (info->flags & AER_TLP_HEADER_VALID_FLAG) { |
235 | unsigned char *tlp = (unsigned char *) &info->tlp; | 235 | unsigned char *tlp = (unsigned char *) &info->tlp; |
236 | printk("%sTLB Header:\n", loglevel); | 236 | printk("%sTLP Header:\n", loglevel); |
237 | printk("%s%02x%02x%02x%02x %02x%02x%02x%02x" | 237 | printk("%s%02x%02x%02x%02x %02x%02x%02x%02x" |
238 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", | 238 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", |
239 | loglevel, | 239 | loglevel, |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 9aad608bcf3f..586b6f75910d 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
20 | #include <linux/delay.h> | ||
20 | #include <linux/pci-aspm.h> | 21 | #include <linux/pci-aspm.h> |
21 | #include "../pci.h" | 22 | #include "../pci.h" |
22 | 23 | ||
@@ -33,6 +34,11 @@ struct endpoint_state { | |||
33 | struct pcie_link_state { | 34 | struct pcie_link_state { |
34 | struct list_head sibiling; | 35 | struct list_head sibiling; |
35 | struct pci_dev *pdev; | 36 | struct pci_dev *pdev; |
37 | bool downstream_has_switch; | ||
38 | |||
39 | struct pcie_link_state *parent; | ||
40 | struct list_head children; | ||
41 | struct list_head link; | ||
36 | 42 | ||
37 | /* ASPM state */ | 43 | /* ASPM state */ |
38 | unsigned int support_state; | 44 | unsigned int support_state; |
@@ -70,6 +76,8 @@ static const char *policy_str[] = { | |||
70 | [POLICY_POWERSAVE] = "powersave" | 76 | [POLICY_POWERSAVE] = "powersave" |
71 | }; | 77 | }; |
72 | 78 | ||
79 | #define LINK_RETRAIN_TIMEOUT HZ | ||
80 | |||
73 | static int policy_to_aspm_state(struct pci_dev *pdev) | 81 | static int policy_to_aspm_state(struct pci_dev *pdev) |
74 | { | 82 | { |
75 | struct pcie_link_state *link_state = pdev->link_state; | 83 | struct pcie_link_state *link_state = pdev->link_state; |
@@ -125,7 +133,7 @@ static void pcie_set_clock_pm(struct pci_dev *pdev, int enable) | |||
125 | link_state->clk_pm_enabled = !!enable; | 133 | link_state->clk_pm_enabled = !!enable; |
126 | } | 134 | } |
127 | 135 | ||
128 | static void pcie_check_clock_pm(struct pci_dev *pdev) | 136 | static void pcie_check_clock_pm(struct pci_dev *pdev, int blacklist) |
129 | { | 137 | { |
130 | int pos; | 138 | int pos; |
131 | u32 reg32; | 139 | u32 reg32; |
@@ -149,10 +157,26 @@ static void pcie_check_clock_pm(struct pci_dev *pdev) | |||
149 | if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) | 157 | if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) |
150 | enabled = 0; | 158 | enabled = 0; |
151 | } | 159 | } |
152 | link_state->clk_pm_capable = capable; | ||
153 | link_state->clk_pm_enabled = enabled; | 160 | link_state->clk_pm_enabled = enabled; |
154 | link_state->bios_clk_state = enabled; | 161 | link_state->bios_clk_state = enabled; |
155 | pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); | 162 | if (!blacklist) { |
163 | link_state->clk_pm_capable = capable; | ||
164 | pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); | ||
165 | } else { | ||
166 | link_state->clk_pm_capable = 0; | ||
167 | pcie_set_clock_pm(pdev, 0); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev) | ||
172 | { | ||
173 | struct pci_dev *child_dev; | ||
174 | |||
175 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
176 | if (child_dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) | ||
177 | return true; | ||
178 | } | ||
179 | return false; | ||
156 | } | 180 | } |
157 | 181 | ||
158 | /* | 182 | /* |
@@ -217,16 +241,18 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev) | |||
217 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); | 241 | pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); |
218 | 242 | ||
219 | /* Wait for link training end */ | 243 | /* Wait for link training end */ |
220 | /* break out after waiting for 1 second */ | 244 | /* break out after waiting for timeout */ |
221 | start_jiffies = jiffies; | 245 | start_jiffies = jiffies; |
222 | while ((jiffies - start_jiffies) < HZ) { | 246 | for (;;) { |
223 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); | 247 | pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, ®16); |
224 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | 248 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) |
225 | break; | 249 | break; |
226 | cpu_relax(); | 250 | if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) |
251 | break; | ||
252 | msleep(1); | ||
227 | } | 253 | } |
228 | /* training failed -> recover */ | 254 | /* training failed -> recover */ |
229 | if ((jiffies - start_jiffies) >= HZ) { | 255 | if (reg16 & PCI_EXP_LNKSTA_LT) { |
230 | dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure" | 256 | dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure" |
231 | " common clock\n"); | 257 | " common clock\n"); |
232 | i = 0; | 258 | i = 0; |
@@ -419,9 +445,9 @@ static unsigned int pcie_aspm_check_state(struct pci_dev *pdev, | |||
419 | { | 445 | { |
420 | struct pci_dev *child_dev; | 446 | struct pci_dev *child_dev; |
421 | 447 | ||
422 | /* If no child, disable the link */ | 448 | /* If no child, ignore the link */ |
423 | if (list_empty(&pdev->subordinate->devices)) | 449 | if (list_empty(&pdev->subordinate->devices)) |
424 | return 0; | 450 | return state; |
425 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | 451 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { |
426 | if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { | 452 | if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { |
427 | /* | 453 | /* |
@@ -462,6 +488,9 @@ static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state) | |||
462 | int valid = 1; | 488 | int valid = 1; |
463 | struct pcie_link_state *link_state = pdev->link_state; | 489 | struct pcie_link_state *link_state = pdev->link_state; |
464 | 490 | ||
491 | /* If no child, disable the link */ | ||
492 | if (list_empty(&pdev->subordinate->devices)) | ||
493 | state = 0; | ||
465 | /* | 494 | /* |
466 | * if the downstream component has pci bridge function, don't do ASPM | 495 | * if the downstream component has pci bridge function, don't do ASPM |
467 | * now | 496 | * now |
@@ -493,20 +522,52 @@ static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state) | |||
493 | link_state->enabled_state = state; | 522 | link_state->enabled_state = state; |
494 | } | 523 | } |
495 | 524 | ||
525 | static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link) | ||
526 | { | ||
527 | struct pcie_link_state *root_port_link = link; | ||
528 | while (root_port_link->parent) | ||
529 | root_port_link = root_port_link->parent; | ||
530 | return root_port_link; | ||
531 | } | ||
532 | |||
533 | /* check the whole hierarchy, and configure each link in the hierarchy */ | ||
496 | static void __pcie_aspm_configure_link_state(struct pci_dev *pdev, | 534 | static void __pcie_aspm_configure_link_state(struct pci_dev *pdev, |
497 | unsigned int state) | 535 | unsigned int state) |
498 | { | 536 | { |
499 | struct pcie_link_state *link_state = pdev->link_state; | 537 | struct pcie_link_state *link_state = pdev->link_state; |
538 | struct pcie_link_state *root_port_link = get_root_port_link(link_state); | ||
539 | struct pcie_link_state *leaf; | ||
500 | 540 | ||
501 | if (link_state->support_state == 0) | ||
502 | return; | ||
503 | state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; | 541 | state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; |
504 | 542 | ||
505 | /* state 0 means disabling aspm */ | 543 | /* check all links who have specific root port link */ |
506 | state = pcie_aspm_check_state(pdev, state); | 544 | list_for_each_entry(leaf, &link_list, sibiling) { |
545 | if (!list_empty(&leaf->children) || | ||
546 | get_root_port_link(leaf) != root_port_link) | ||
547 | continue; | ||
548 | state = pcie_aspm_check_state(leaf->pdev, state); | ||
549 | } | ||
550 | /* check root port link too in case it hasn't children */ | ||
551 | state = pcie_aspm_check_state(root_port_link->pdev, state); | ||
552 | |||
507 | if (link_state->enabled_state == state) | 553 | if (link_state->enabled_state == state) |
508 | return; | 554 | return; |
509 | __pcie_aspm_config_link(pdev, state); | 555 | |
556 | /* | ||
557 | * we must change the hierarchy. See comments in | ||
558 | * __pcie_aspm_config_link for the order | ||
559 | **/ | ||
560 | if (state & PCIE_LINK_STATE_L1) { | ||
561 | list_for_each_entry(leaf, &link_list, sibiling) { | ||
562 | if (get_root_port_link(leaf) == root_port_link) | ||
563 | __pcie_aspm_config_link(leaf->pdev, state); | ||
564 | } | ||
565 | } else { | ||
566 | list_for_each_entry_reverse(leaf, &link_list, sibiling) { | ||
567 | if (get_root_port_link(leaf) == root_port_link) | ||
568 | __pcie_aspm_config_link(leaf->pdev, state); | ||
569 | } | ||
570 | } | ||
510 | } | 571 | } |
511 | 572 | ||
512 | /* | 573 | /* |
@@ -570,6 +631,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
570 | unsigned int state; | 631 | unsigned int state; |
571 | struct pcie_link_state *link_state; | 632 | struct pcie_link_state *link_state; |
572 | int error = 0; | 633 | int error = 0; |
634 | int blacklist; | ||
573 | 635 | ||
574 | if (aspm_disabled || !pdev->is_pcie || pdev->link_state) | 636 | if (aspm_disabled || !pdev->is_pcie || pdev->link_state) |
575 | return; | 637 | return; |
@@ -580,29 +642,58 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
580 | if (list_empty(&pdev->subordinate->devices)) | 642 | if (list_empty(&pdev->subordinate->devices)) |
581 | goto out; | 643 | goto out; |
582 | 644 | ||
583 | if (pcie_aspm_sanity_check(pdev)) | 645 | blacklist = !!pcie_aspm_sanity_check(pdev); |
584 | goto out; | ||
585 | 646 | ||
586 | mutex_lock(&aspm_lock); | 647 | mutex_lock(&aspm_lock); |
587 | 648 | ||
588 | link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); | 649 | link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); |
589 | if (!link_state) | 650 | if (!link_state) |
590 | goto unlock_out; | 651 | goto unlock_out; |
591 | pdev->link_state = link_state; | ||
592 | 652 | ||
593 | pcie_aspm_configure_common_clock(pdev); | 653 | link_state->downstream_has_switch = pcie_aspm_downstream_has_switch(pdev); |
654 | INIT_LIST_HEAD(&link_state->children); | ||
655 | INIT_LIST_HEAD(&link_state->link); | ||
656 | if (pdev->bus->self) {/* this is a switch */ | ||
657 | struct pcie_link_state *parent_link_state; | ||
594 | 658 | ||
595 | pcie_aspm_cap_init(pdev); | 659 | parent_link_state = pdev->bus->parent->self->link_state; |
660 | if (!parent_link_state) { | ||
661 | kfree(link_state); | ||
662 | goto unlock_out; | ||
663 | } | ||
664 | list_add(&link_state->link, &parent_link_state->children); | ||
665 | link_state->parent = parent_link_state; | ||
666 | } | ||
596 | 667 | ||
597 | /* config link state to avoid BIOS error */ | 668 | pdev->link_state = link_state; |
598 | state = pcie_aspm_check_state(pdev, policy_to_aspm_state(pdev)); | ||
599 | __pcie_aspm_config_link(pdev, state); | ||
600 | 669 | ||
601 | pcie_check_clock_pm(pdev); | 670 | if (!blacklist) { |
671 | pcie_aspm_configure_common_clock(pdev); | ||
672 | pcie_aspm_cap_init(pdev); | ||
673 | } else { | ||
674 | link_state->enabled_state = PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; | ||
675 | link_state->bios_aspm_state = 0; | ||
676 | /* Set support state to 0, so we will disable ASPM later */ | ||
677 | link_state->support_state = 0; | ||
678 | } | ||
602 | 679 | ||
603 | link_state->pdev = pdev; | 680 | link_state->pdev = pdev; |
604 | list_add(&link_state->sibiling, &link_list); | 681 | list_add(&link_state->sibiling, &link_list); |
605 | 682 | ||
683 | if (link_state->downstream_has_switch) { | ||
684 | /* | ||
685 | * If link has switch, delay the link config. The leaf link | ||
686 | * initialization will config the whole hierarchy. but we must | ||
687 | * make sure BIOS doesn't set unsupported link state | ||
688 | **/ | ||
689 | state = pcie_aspm_check_state(pdev, link_state->bios_aspm_state); | ||
690 | __pcie_aspm_config_link(pdev, state); | ||
691 | } else | ||
692 | __pcie_aspm_configure_link_state(pdev, | ||
693 | policy_to_aspm_state(pdev)); | ||
694 | |||
695 | pcie_check_clock_pm(pdev, blacklist); | ||
696 | |||
606 | unlock_out: | 697 | unlock_out: |
607 | if (error) | 698 | if (error) |
608 | free_link_state(pdev); | 699 | free_link_state(pdev); |
@@ -635,6 +726,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
635 | /* All functions are removed, so just disable ASPM for the link */ | 726 | /* All functions are removed, so just disable ASPM for the link */ |
636 | __pcie_aspm_config_one_dev(parent, 0); | 727 | __pcie_aspm_config_one_dev(parent, 0); |
637 | list_del(&link_state->sibiling); | 728 | list_del(&link_state->sibiling); |
729 | list_del(&link_state->link); | ||
638 | /* Clock PM is for endpoint device */ | 730 | /* Clock PM is for endpoint device */ |
639 | 731 | ||
640 | free_link_state(parent); | 732 | free_link_state(parent); |
@@ -857,24 +949,15 @@ void pcie_no_aspm(void) | |||
857 | aspm_disabled = 1; | 949 | aspm_disabled = 1; |
858 | } | 950 | } |
859 | 951 | ||
860 | #ifdef CONFIG_ACPI | 952 | /** |
861 | #include <acpi/acpi_bus.h> | 953 | * pcie_aspm_enabled - is PCIe ASPM enabled? |
862 | #include <linux/pci-acpi.h> | 954 | * |
863 | static void pcie_aspm_platform_init(void) | 955 | * Returns true if ASPM has not been disabled by the command-line option |
864 | { | 956 | * pcie_aspm=off. |
865 | pcie_osc_support_set(OSC_ACTIVE_STATE_PWR_SUPPORT| | 957 | **/ |
866 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT); | 958 | int pcie_aspm_enabled(void) |
867 | } | ||
868 | #else | ||
869 | static inline void pcie_aspm_platform_init(void) { } | ||
870 | #endif | ||
871 | |||
872 | static int __init pcie_aspm_init(void) | ||
873 | { | 959 | { |
874 | if (aspm_disabled) | 960 | return !aspm_disabled; |
875 | return 0; | ||
876 | pcie_aspm_platform_init(); | ||
877 | return 0; | ||
878 | } | 961 | } |
962 | EXPORT_SYMBOL(pcie_aspm_enabled); | ||
879 | 963 | ||
880 | fs_initcall(pcie_aspm_init); | ||
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c index 359fe5568df1..eec89b767f9f 100644 --- a/drivers/pci/pcie/portdrv_bus.c +++ b/drivers/pci/pcie/portdrv_bus.c | |||
@@ -16,14 +16,10 @@ | |||
16 | #include "portdrv.h" | 16 | #include "portdrv.h" |
17 | 17 | ||
18 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv); | 18 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv); |
19 | static int pcie_port_bus_suspend(struct device *dev, pm_message_t state); | ||
20 | static int pcie_port_bus_resume(struct device *dev); | ||
21 | 19 | ||
22 | struct bus_type pcie_port_bus_type = { | 20 | struct bus_type pcie_port_bus_type = { |
23 | .name = "pci_express", | 21 | .name = "pci_express", |
24 | .match = pcie_port_bus_match, | 22 | .match = pcie_port_bus_match, |
25 | .suspend = pcie_port_bus_suspend, | ||
26 | .resume = pcie_port_bus_resume, | ||
27 | }; | 23 | }; |
28 | EXPORT_SYMBOL_GPL(pcie_port_bus_type); | 24 | EXPORT_SYMBOL_GPL(pcie_port_bus_type); |
29 | 25 | ||
@@ -49,32 +45,12 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | |||
49 | return 1; | 45 | return 1; |
50 | } | 46 | } |
51 | 47 | ||
52 | static int pcie_port_bus_suspend(struct device *dev, pm_message_t state) | 48 | int pcie_port_bus_register(void) |
53 | { | 49 | { |
54 | struct pcie_device *pciedev; | 50 | return bus_register(&pcie_port_bus_type); |
55 | struct pcie_port_service_driver *driver; | ||
56 | |||
57 | if (!dev || !dev->driver) | ||
58 | return 0; | ||
59 | |||
60 | pciedev = to_pcie_device(dev); | ||
61 | driver = to_service_driver(dev->driver); | ||
62 | if (driver && driver->suspend) | ||
63 | driver->suspend(pciedev, state); | ||
64 | return 0; | ||
65 | } | 51 | } |
66 | 52 | ||
67 | static int pcie_port_bus_resume(struct device *dev) | 53 | void pcie_port_bus_unregister(void) |
68 | { | 54 | { |
69 | struct pcie_device *pciedev; | 55 | bus_unregister(&pcie_port_bus_type); |
70 | struct pcie_port_service_driver *driver; | ||
71 | |||
72 | if (!dev || !dev->driver) | ||
73 | return 0; | ||
74 | |||
75 | pciedev = to_pcie_device(dev); | ||
76 | driver = to_service_driver(dev->driver); | ||
77 | if (driver && driver->resume) | ||
78 | driver->resume(pciedev); | ||
79 | return 0; | ||
80 | } | 56 | } |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 2e091e014829..8b3f8c18032f 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -19,91 +19,15 @@ | |||
19 | 19 | ||
20 | extern int pcie_mch_quirk; /* MSI-quirk Indicator */ | 20 | extern int pcie_mch_quirk; /* MSI-quirk Indicator */ |
21 | 21 | ||
22 | static int pcie_port_probe_service(struct device *dev) | 22 | /** |
23 | { | 23 | * release_pcie_device - free PCI Express port service device structure |
24 | struct pcie_device *pciedev; | 24 | * @dev: Port service device to release |
25 | struct pcie_port_service_driver *driver; | 25 | * |
26 | int status; | 26 | * Invoked automatically when device is being removed in response to |
27 | 27 | * device_unregister(dev). Release all resources being claimed. | |
28 | if (!dev || !dev->driver) | ||
29 | return -ENODEV; | ||
30 | |||
31 | driver = to_service_driver(dev->driver); | ||
32 | if (!driver || !driver->probe) | ||
33 | return -ENODEV; | ||
34 | |||
35 | pciedev = to_pcie_device(dev); | ||
36 | status = driver->probe(pciedev, driver->id_table); | ||
37 | if (!status) { | ||
38 | dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", | ||
39 | driver->name); | ||
40 | get_device(dev); | ||
41 | } | ||
42 | return status; | ||
43 | } | ||
44 | |||
45 | static int pcie_port_remove_service(struct device *dev) | ||
46 | { | ||
47 | struct pcie_device *pciedev; | ||
48 | struct pcie_port_service_driver *driver; | ||
49 | |||
50 | if (!dev || !dev->driver) | ||
51 | return 0; | ||
52 | |||
53 | pciedev = to_pcie_device(dev); | ||
54 | driver = to_service_driver(dev->driver); | ||
55 | if (driver && driver->remove) { | ||
56 | dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n", | ||
57 | driver->name); | ||
58 | driver->remove(pciedev); | ||
59 | put_device(dev); | ||
60 | } | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void pcie_port_shutdown_service(struct device *dev) {} | ||
65 | |||
66 | static int pcie_port_suspend_service(struct device *dev, pm_message_t state) | ||
67 | { | ||
68 | struct pcie_device *pciedev; | ||
69 | struct pcie_port_service_driver *driver; | ||
70 | |||
71 | if (!dev || !dev->driver) | ||
72 | return 0; | ||
73 | |||
74 | pciedev = to_pcie_device(dev); | ||
75 | driver = to_service_driver(dev->driver); | ||
76 | if (driver && driver->suspend) | ||
77 | driver->suspend(pciedev, state); | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int pcie_port_resume_service(struct device *dev) | ||
82 | { | ||
83 | struct pcie_device *pciedev; | ||
84 | struct pcie_port_service_driver *driver; | ||
85 | |||
86 | if (!dev || !dev->driver) | ||
87 | return 0; | ||
88 | |||
89 | pciedev = to_pcie_device(dev); | ||
90 | driver = to_service_driver(dev->driver); | ||
91 | |||
92 | if (driver && driver->resume) | ||
93 | driver->resume(pciedev); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * release_pcie_device | ||
99 | * | ||
100 | * Being invoked automatically when device is being removed | ||
101 | * in response to device_unregister(dev) call. | ||
102 | * Release all resources being claimed. | ||
103 | */ | 28 | */ |
104 | static void release_pcie_device(struct device *dev) | 29 | static void release_pcie_device(struct device *dev) |
105 | { | 30 | { |
106 | dev_printk(KERN_DEBUG, dev, "free port service\n"); | ||
107 | kfree(to_pcie_device(dev)); | 31 | kfree(to_pcie_device(dev)); |
108 | } | 32 | } |
109 | 33 | ||
@@ -128,7 +52,16 @@ static int is_msi_quirked(struct pci_dev *dev) | |||
128 | } | 52 | } |
129 | return quirk; | 53 | return quirk; |
130 | } | 54 | } |
131 | 55 | ||
56 | /** | ||
57 | * assign_interrupt_mode - choose interrupt mode for PCI Express port services | ||
58 | * (INTx, MSI-X, MSI) and set up vectors | ||
59 | * @dev: PCI Express port to handle | ||
60 | * @vectors: Array of interrupt vectors to populate | ||
61 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() | ||
62 | * | ||
63 | * Return value: Interrupt mode associated with the port | ||
64 | */ | ||
132 | static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | 65 | static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) |
133 | { | 66 | { |
134 | int i, pos, nvec, status = -EINVAL; | 67 | int i, pos, nvec, status = -EINVAL; |
@@ -150,7 +83,6 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | |||
150 | if (pos) { | 83 | if (pos) { |
151 | struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = | 84 | struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = |
152 | {{0, 0}, {0, 1}, {0, 2}, {0, 3}}; | 85 | {{0, 0}, {0, 1}, {0, 2}, {0, 3}}; |
153 | dev_info(&dev->dev, "found MSI-X capability\n"); | ||
154 | status = pci_enable_msix(dev, msix_entries, nvec); | 86 | status = pci_enable_msix(dev, msix_entries, nvec); |
155 | if (!status) { | 87 | if (!status) { |
156 | int j = 0; | 88 | int j = 0; |
@@ -165,7 +97,6 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | |||
165 | if (status) { | 97 | if (status) { |
166 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 98 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
167 | if (pos) { | 99 | if (pos) { |
168 | dev_info(&dev->dev, "found MSI capability\n"); | ||
169 | status = pci_enable_msi(dev); | 100 | status = pci_enable_msi(dev); |
170 | if (!status) { | 101 | if (!status) { |
171 | interrupt_mode = PCIE_PORT_MSI_MODE; | 102 | interrupt_mode = PCIE_PORT_MSI_MODE; |
@@ -177,6 +108,16 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | |||
177 | return interrupt_mode; | 108 | return interrupt_mode; |
178 | } | 109 | } |
179 | 110 | ||
111 | /** | ||
112 | * get_port_device_capability - discover capabilities of a PCI Express port | ||
113 | * @dev: PCI Express port to examine | ||
114 | * | ||
115 | * The capabilities are read from the port's PCI Express configuration registers | ||
116 | * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and | ||
117 | * 7.9 - 7.11. | ||
118 | * | ||
119 | * Return value: Bitmask of discovered port capabilities | ||
120 | */ | ||
180 | static int get_port_device_capability(struct pci_dev *dev) | 121 | static int get_port_device_capability(struct pci_dev *dev) |
181 | { | 122 | { |
182 | int services = 0, pos; | 123 | int services = 0, pos; |
@@ -204,6 +145,15 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
204 | return services; | 145 | return services; |
205 | } | 146 | } |
206 | 147 | ||
148 | /** | ||
149 | * pcie_device_init - initialize PCI Express port service device | ||
150 | * @dev: Port service device to initialize | ||
151 | * @parent: PCI Express port to associate the service device with | ||
152 | * @port_type: Type of the port | ||
153 | * @service_type: Type of service to associate with the service device | ||
154 | * @irq: Interrupt vector to associate with the service device | ||
155 | * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI) | ||
156 | */ | ||
207 | static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, | 157 | static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, |
208 | int port_type, int service_type, int irq, int irq_mode) | 158 | int port_type, int service_type, int irq, int irq_mode) |
209 | { | 159 | { |
@@ -224,11 +174,19 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, | |||
224 | device->driver = NULL; | 174 | device->driver = NULL; |
225 | device->driver_data = NULL; | 175 | device->driver_data = NULL; |
226 | device->release = release_pcie_device; /* callback to free pcie dev */ | 176 | device->release = release_pcie_device; /* callback to free pcie dev */ |
227 | snprintf(device->bus_id, sizeof(device->bus_id), "%s:pcie%02x", | 177 | dev_set_name(device, "%s:pcie%02x", |
228 | pci_name(parent), get_descriptor_id(port_type, service_type)); | 178 | pci_name(parent), get_descriptor_id(port_type, service_type)); |
229 | device->parent = &parent->dev; | 179 | device->parent = &parent->dev; |
230 | } | 180 | } |
231 | 181 | ||
182 | /** | ||
183 | * alloc_pcie_device - allocate PCI Express port service device structure | ||
184 | * @parent: PCI Express port to associate the service device with | ||
185 | * @port_type: Type of the port | ||
186 | * @service_type: Type of service to associate with the service device | ||
187 | * @irq: Interrupt vector to associate with the service device | ||
188 | * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI) | ||
189 | */ | ||
232 | static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, | 190 | static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, |
233 | int port_type, int service_type, int irq, int irq_mode) | 191 | int port_type, int service_type, int irq, int irq_mode) |
234 | { | 192 | { |
@@ -239,10 +197,13 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, | |||
239 | return NULL; | 197 | return NULL; |
240 | 198 | ||
241 | pcie_device_init(parent, device, port_type, service_type, irq,irq_mode); | 199 | pcie_device_init(parent, device, port_type, service_type, irq,irq_mode); |
242 | dev_printk(KERN_DEBUG, &device->device, "allocate port service\n"); | ||
243 | return device; | 200 | return device; |
244 | } | 201 | } |
245 | 202 | ||
203 | /** | ||
204 | * pcie_port_device_probe - check if device is a PCI Express port | ||
205 | * @dev: Device to check | ||
206 | */ | ||
246 | int pcie_port_device_probe(struct pci_dev *dev) | 207 | int pcie_port_device_probe(struct pci_dev *dev) |
247 | { | 208 | { |
248 | int pos, type; | 209 | int pos, type; |
@@ -260,6 +221,13 @@ int pcie_port_device_probe(struct pci_dev *dev) | |||
260 | return -ENODEV; | 221 | return -ENODEV; |
261 | } | 222 | } |
262 | 223 | ||
224 | /** | ||
225 | * pcie_port_device_register - register PCI Express port | ||
226 | * @dev: PCI Express port to register | ||
227 | * | ||
228 | * Allocate the port extension structure and register services associated with | ||
229 | * the port. | ||
230 | */ | ||
263 | int pcie_port_device_register(struct pci_dev *dev) | 231 | int pcie_port_device_register(struct pci_dev *dev) |
264 | { | 232 | { |
265 | struct pcie_port_device_ext *p_ext; | 233 | struct pcie_port_device_ext *p_ext; |
@@ -323,6 +291,11 @@ static int suspend_iter(struct device *dev, void *data) | |||
323 | return 0; | 291 | return 0; |
324 | } | 292 | } |
325 | 293 | ||
294 | /** | ||
295 | * pcie_port_device_suspend - suspend port services associated with a PCIe port | ||
296 | * @dev: PCI Express port to handle | ||
297 | * @state: Representation of system power management transition in progress | ||
298 | */ | ||
326 | int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) | 299 | int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) |
327 | { | 300 | { |
328 | return device_for_each_child(&dev->dev, &state, suspend_iter); | 301 | return device_for_each_child(&dev->dev, &state, suspend_iter); |
@@ -341,6 +314,10 @@ static int resume_iter(struct device *dev, void *data) | |||
341 | return 0; | 314 | return 0; |
342 | } | 315 | } |
343 | 316 | ||
317 | /** | ||
318 | * pcie_port_device_suspend - resume port services associated with a PCIe port | ||
319 | * @dev: PCI Express port to handle | ||
320 | */ | ||
344 | int pcie_port_device_resume(struct pci_dev *dev) | 321 | int pcie_port_device_resume(struct pci_dev *dev) |
345 | { | 322 | { |
346 | return device_for_each_child(&dev->dev, NULL, resume_iter); | 323 | return device_for_each_child(&dev->dev, NULL, resume_iter); |
@@ -363,6 +340,13 @@ static int remove_iter(struct device *dev, void *data) | |||
363 | return 0; | 340 | return 0; |
364 | } | 341 | } |
365 | 342 | ||
343 | /** | ||
344 | * pcie_port_device_remove - unregister PCI Express port service devices | ||
345 | * @dev: PCI Express port the service devices to unregister are associated with | ||
346 | * | ||
347 | * Remove PCI Express port service devices associated with given port and | ||
348 | * disable MSI-X or MSI for the port. | ||
349 | */ | ||
366 | void pcie_port_device_remove(struct pci_dev *dev) | 350 | void pcie_port_device_remove(struct pci_dev *dev) |
367 | { | 351 | { |
368 | struct device *device; | 352 | struct device *device; |
@@ -386,16 +370,80 @@ void pcie_port_device_remove(struct pci_dev *dev) | |||
386 | pci_disable_msi(dev); | 370 | pci_disable_msi(dev); |
387 | } | 371 | } |
388 | 372 | ||
389 | int pcie_port_bus_register(void) | 373 | /** |
374 | * pcie_port_probe_service - probe driver for given PCI Express port service | ||
375 | * @dev: PCI Express port service device to probe against | ||
376 | * | ||
377 | * If PCI Express port service driver is registered with | ||
378 | * pcie_port_service_register(), this function will be called by the driver core | ||
379 | * whenever match is found between the driver and a port service device. | ||
380 | */ | ||
381 | static int pcie_port_probe_service(struct device *dev) | ||
390 | { | 382 | { |
391 | return bus_register(&pcie_port_bus_type); | 383 | struct pcie_device *pciedev; |
384 | struct pcie_port_service_driver *driver; | ||
385 | int status; | ||
386 | |||
387 | if (!dev || !dev->driver) | ||
388 | return -ENODEV; | ||
389 | |||
390 | driver = to_service_driver(dev->driver); | ||
391 | if (!driver || !driver->probe) | ||
392 | return -ENODEV; | ||
393 | |||
394 | pciedev = to_pcie_device(dev); | ||
395 | status = driver->probe(pciedev, driver->id_table); | ||
396 | if (!status) { | ||
397 | dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", | ||
398 | driver->name); | ||
399 | get_device(dev); | ||
400 | } | ||
401 | return status; | ||
392 | } | 402 | } |
393 | 403 | ||
394 | void pcie_port_bus_unregister(void) | 404 | /** |
405 | * pcie_port_remove_service - detach driver from given PCI Express port service | ||
406 | * @dev: PCI Express port service device to handle | ||
407 | * | ||
408 | * If PCI Express port service driver is registered with | ||
409 | * pcie_port_service_register(), this function will be called by the driver core | ||
410 | * when device_unregister() is called for the port service device associated | ||
411 | * with the driver. | ||
412 | */ | ||
413 | static int pcie_port_remove_service(struct device *dev) | ||
395 | { | 414 | { |
396 | bus_unregister(&pcie_port_bus_type); | 415 | struct pcie_device *pciedev; |
416 | struct pcie_port_service_driver *driver; | ||
417 | |||
418 | if (!dev || !dev->driver) | ||
419 | return 0; | ||
420 | |||
421 | pciedev = to_pcie_device(dev); | ||
422 | driver = to_service_driver(dev->driver); | ||
423 | if (driver && driver->remove) { | ||
424 | dev_printk(KERN_DEBUG, dev, "unloading service driver %s\n", | ||
425 | driver->name); | ||
426 | driver->remove(pciedev); | ||
427 | put_device(dev); | ||
428 | } | ||
429 | return 0; | ||
397 | } | 430 | } |
398 | 431 | ||
432 | /** | ||
433 | * pcie_port_shutdown_service - shut down given PCI Express port service | ||
434 | * @dev: PCI Express port service device to handle | ||
435 | * | ||
436 | * If PCI Express port service driver is registered with | ||
437 | * pcie_port_service_register(), this function will be called by the driver core | ||
438 | * when device_shutdown() is called for the port service device associated | ||
439 | * with the driver. | ||
440 | */ | ||
441 | static void pcie_port_shutdown_service(struct device *dev) {} | ||
442 | |||
443 | /** | ||
444 | * pcie_port_service_register - register PCI Express port service driver | ||
445 | * @new: PCI Express port service driver to register | ||
446 | */ | ||
399 | int pcie_port_service_register(struct pcie_port_service_driver *new) | 447 | int pcie_port_service_register(struct pcie_port_service_driver *new) |
400 | { | 448 | { |
401 | new->driver.name = (char *)new->name; | 449 | new->driver.name = (char *)new->name; |
@@ -403,15 +451,17 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) | |||
403 | new->driver.probe = pcie_port_probe_service; | 451 | new->driver.probe = pcie_port_probe_service; |
404 | new->driver.remove = pcie_port_remove_service; | 452 | new->driver.remove = pcie_port_remove_service; |
405 | new->driver.shutdown = pcie_port_shutdown_service; | 453 | new->driver.shutdown = pcie_port_shutdown_service; |
406 | new->driver.suspend = pcie_port_suspend_service; | ||
407 | new->driver.resume = pcie_port_resume_service; | ||
408 | 454 | ||
409 | return driver_register(&new->driver); | 455 | return driver_register(&new->driver); |
410 | } | 456 | } |
411 | 457 | ||
412 | void pcie_port_service_unregister(struct pcie_port_service_driver *new) | 458 | /** |
459 | * pcie_port_service_unregister - unregister PCI Express port service driver | ||
460 | * @drv: PCI Express port service driver to unregister | ||
461 | */ | ||
462 | void pcie_port_service_unregister(struct pcie_port_service_driver *drv) | ||
413 | { | 463 | { |
414 | driver_unregister(&new->driver); | 464 | driver_unregister(&drv->driver); |
415 | } | 465 | } |
416 | 466 | ||
417 | EXPORT_SYMBOL(pcie_port_service_register); | 467 | EXPORT_SYMBOL(pcie_port_service_register); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 584422da8d8b..99a914a027f8 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -41,7 +41,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
41 | { | 41 | { |
42 | int retval; | 42 | int retval; |
43 | 43 | ||
44 | pci_restore_state(dev); | ||
45 | retval = pci_enable_device(dev); | 44 | retval = pci_enable_device(dev); |
46 | if (retval) | 45 | if (retval) |
47 | return retval; | 46 | return retval; |
@@ -52,11 +51,18 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
52 | #ifdef CONFIG_PM | 51 | #ifdef CONFIG_PM |
53 | static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) | 52 | static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) |
54 | { | 53 | { |
55 | int ret = pcie_port_device_suspend(dev, state); | 54 | return pcie_port_device_suspend(dev, state); |
56 | 55 | ||
57 | if (!ret) | 56 | } |
58 | ret = pcie_portdrv_save_config(dev); | 57 | |
59 | return ret; | 58 | static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) |
59 | { | ||
60 | return pci_save_state(dev); | ||
61 | } | ||
62 | |||
63 | static int pcie_portdrv_resume_early(struct pci_dev *dev) | ||
64 | { | ||
65 | return pci_restore_state(dev); | ||
60 | } | 66 | } |
61 | 67 | ||
62 | static int pcie_portdrv_resume(struct pci_dev *dev) | 68 | static int pcie_portdrv_resume(struct pci_dev *dev) |
@@ -66,6 +72,8 @@ static int pcie_portdrv_resume(struct pci_dev *dev) | |||
66 | } | 72 | } |
67 | #else | 73 | #else |
68 | #define pcie_portdrv_suspend NULL | 74 | #define pcie_portdrv_suspend NULL |
75 | #define pcie_portdrv_suspend_late NULL | ||
76 | #define pcie_portdrv_resume_early NULL | ||
69 | #define pcie_portdrv_resume NULL | 77 | #define pcie_portdrv_resume NULL |
70 | #endif | 78 | #endif |
71 | 79 | ||
@@ -221,6 +229,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | |||
221 | 229 | ||
222 | /* If fatal, restore cfg space for possible link reset at upstream */ | 230 | /* If fatal, restore cfg space for possible link reset at upstream */ |
223 | if (dev->error_state == pci_channel_io_frozen) { | 231 | if (dev->error_state == pci_channel_io_frozen) { |
232 | pci_restore_state(dev); | ||
224 | pcie_portdrv_restore_config(dev); | 233 | pcie_portdrv_restore_config(dev); |
225 | pci_enable_pcie_error_reporting(dev); | 234 | pci_enable_pcie_error_reporting(dev); |
226 | } | 235 | } |
@@ -283,6 +292,8 @@ static struct pci_driver pcie_portdriver = { | |||
283 | .remove = pcie_portdrv_remove, | 292 | .remove = pcie_portdrv_remove, |
284 | 293 | ||
285 | .suspend = pcie_portdrv_suspend, | 294 | .suspend = pcie_portdrv_suspend, |
295 | .suspend_late = pcie_portdrv_suspend_late, | ||
296 | .resume_early = pcie_portdrv_resume_early, | ||
286 | .resume = pcie_portdrv_resume, | 297 | .resume = pcie_portdrv_resume, |
287 | 298 | ||
288 | .err_handler = &pcie_portdrv_err_handler, | 299 | .err_handler = &pcie_portdrv_err_handler, |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5b3f5937ecf5..303644614eea 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -135,13 +135,6 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask) | |||
135 | return size; | 135 | return size; |
136 | } | 136 | } |
137 | 137 | ||
138 | enum pci_bar_type { | ||
139 | pci_bar_unknown, /* Standard PCI BAR probe */ | ||
140 | pci_bar_io, /* An io port BAR */ | ||
141 | pci_bar_mem32, /* A 32-bit memory BAR */ | ||
142 | pci_bar_mem64, /* A 64-bit memory BAR */ | ||
143 | }; | ||
144 | |||
145 | static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) | 138 | static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) |
146 | { | 139 | { |
147 | if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { | 140 | if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { |
@@ -156,11 +149,16 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) | |||
156 | return pci_bar_mem32; | 149 | return pci_bar_mem32; |
157 | } | 150 | } |
158 | 151 | ||
159 | /* | 152 | /** |
160 | * If the type is not unknown, we assume that the lowest bit is 'enable'. | 153 | * pci_read_base - read a PCI BAR |
161 | * Returns 1 if the BAR was 64-bit and 0 if it was 32-bit. | 154 | * @dev: the PCI device |
155 | * @type: type of the BAR | ||
156 | * @res: resource buffer to be filled in | ||
157 | * @pos: BAR position in the config space | ||
158 | * | ||
159 | * Returns 1 if the BAR is 64-bit, or 0 if 32-bit. | ||
162 | */ | 160 | */ |
163 | static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 161 | int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
164 | struct resource *res, unsigned int pos) | 162 | struct resource *res, unsigned int pos) |
165 | { | 163 | { |
166 | u32 l, sz, mask; | 164 | u32 l, sz, mask; |
@@ -400,19 +398,17 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
400 | if (!child) | 398 | if (!child) |
401 | return NULL; | 399 | return NULL; |
402 | 400 | ||
403 | child->self = bridge; | ||
404 | child->parent = parent; | 401 | child->parent = parent; |
405 | child->ops = parent->ops; | 402 | child->ops = parent->ops; |
406 | child->sysdata = parent->sysdata; | 403 | child->sysdata = parent->sysdata; |
407 | child->bus_flags = parent->bus_flags; | 404 | child->bus_flags = parent->bus_flags; |
408 | child->bridge = get_device(&bridge->dev); | ||
409 | 405 | ||
410 | /* initialize some portions of the bus device, but don't register it | 406 | /* initialize some portions of the bus device, but don't register it |
411 | * now as the parent is not properly set up yet. This device will get | 407 | * now as the parent is not properly set up yet. This device will get |
412 | * registered later in pci_bus_add_devices() | 408 | * registered later in pci_bus_add_devices() |
413 | */ | 409 | */ |
414 | child->dev.class = &pcibus_class; | 410 | child->dev.class = &pcibus_class; |
415 | sprintf(child->dev.bus_id, "%04x:%02x", pci_domain_nr(child), busnr); | 411 | dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); |
416 | 412 | ||
417 | /* | 413 | /* |
418 | * Set up the primary, secondary and subordinate | 414 | * Set up the primary, secondary and subordinate |
@@ -422,8 +418,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
422 | child->primary = parent->secondary; | 418 | child->primary = parent->secondary; |
423 | child->subordinate = 0xff; | 419 | child->subordinate = 0xff; |
424 | 420 | ||
421 | if (!bridge) | ||
422 | return child; | ||
423 | |||
424 | child->self = bridge; | ||
425 | child->bridge = get_device(&bridge->dev); | ||
426 | |||
425 | /* Set up default resource pointers and names.. */ | 427 | /* Set up default resource pointers and names.. */ |
426 | for (i = 0; i < 4; i++) { | 428 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { |
427 | child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; | 429 | child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; |
428 | child->resource[i]->name = child->name; | 430 | child->resource[i]->name = child->name; |
429 | } | 431 | } |
@@ -958,8 +960,12 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
958 | /* MSI/MSI-X list */ | 960 | /* MSI/MSI-X list */ |
959 | pci_msi_init_pci_dev(dev); | 961 | pci_msi_init_pci_dev(dev); |
960 | 962 | ||
963 | /* Buffers for saving PCIe and PCI-X capabilities */ | ||
964 | pci_allocate_cap_save_buffers(dev); | ||
965 | |||
961 | /* Power Management */ | 966 | /* Power Management */ |
962 | pci_pm_init(dev); | 967 | pci_pm_init(dev); |
968 | platform_pci_wakeup_init(dev); | ||
963 | 969 | ||
964 | /* Vital Product Data */ | 970 | /* Vital Product Data */ |
965 | pci_vpd_pci22_init(dev); | 971 | pci_vpd_pci22_init(dev); |
@@ -1130,7 +1136,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1130 | memset(dev, 0, sizeof(*dev)); | 1136 | memset(dev, 0, sizeof(*dev)); |
1131 | dev->parent = parent; | 1137 | dev->parent = parent; |
1132 | dev->release = pci_release_bus_bridge_dev; | 1138 | dev->release = pci_release_bus_bridge_dev; |
1133 | sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus); | 1139 | dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
1134 | error = device_register(dev); | 1140 | error = device_register(dev); |
1135 | if (error) | 1141 | if (error) |
1136 | goto dev_reg_err; | 1142 | goto dev_reg_err; |
@@ -1141,7 +1147,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1141 | 1147 | ||
1142 | b->dev.class = &pcibus_class; | 1148 | b->dev.class = &pcibus_class; |
1143 | b->dev.parent = b->bridge; | 1149 | b->dev.parent = b->bridge; |
1144 | sprintf(b->dev.bus_id, "%04x:%02x", pci_domain_nr(b), bus); | 1150 | dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus); |
1145 | error = device_register(&b->dev); | 1151 | error = device_register(&b->dev); |
1146 | if (error) | 1152 | if (error) |
1147 | goto class_dev_reg_err; | 1153 | goto class_dev_reg_err; |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index e1098c302c45..593bb844b8db 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -252,11 +252,20 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
252 | const struct proc_dir_entry *dp = PDE(inode); | 252 | const struct proc_dir_entry *dp = PDE(inode); |
253 | struct pci_dev *dev = dp->data; | 253 | struct pci_dev *dev = dp->data; |
254 | struct pci_filp_private *fpriv = file->private_data; | 254 | struct pci_filp_private *fpriv = file->private_data; |
255 | int ret; | 255 | int i, ret; |
256 | 256 | ||
257 | if (!capable(CAP_SYS_RAWIO)) | 257 | if (!capable(CAP_SYS_RAWIO)) |
258 | return -EPERM; | 258 | return -EPERM; |
259 | 259 | ||
260 | /* Make sure the caller is mapping a real resource for this device */ | ||
261 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { | ||
262 | if (pci_mmap_fits(dev, i, vma)) | ||
263 | break; | ||
264 | } | ||
265 | |||
266 | if (i >= PCI_ROM_RESOURCE) | ||
267 | return -ENODEV; | ||
268 | |||
260 | ret = pci_mmap_page_range(dev, vma, | 269 | ret = pci_mmap_page_range(dev, vma, |
261 | fpriv->mmap_state, | 270 | fpriv->mmap_state, |
262 | fpriv->write_combine); | 271 | fpriv->write_combine); |
@@ -352,15 +361,16 @@ static int show_device(struct seq_file *m, void *v) | |||
352 | dev->vendor, | 361 | dev->vendor, |
353 | dev->device, | 362 | dev->device, |
354 | dev->irq); | 363 | dev->irq); |
355 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ | 364 | |
356 | for (i=0; i<7; i++) { | 365 | /* only print standard and ROM resources to preserve compatibility */ |
366 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
357 | resource_size_t start, end; | 367 | resource_size_t start, end; |
358 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | 368 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); |
359 | seq_printf(m, "\t%16llx", | 369 | seq_printf(m, "\t%16llx", |
360 | (unsigned long long)(start | | 370 | (unsigned long long)(start | |
361 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); | 371 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); |
362 | } | 372 | } |
363 | for (i=0; i<7; i++) { | 373 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { |
364 | resource_size_t start, end; | 374 | resource_size_t start, end; |
365 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | 375 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); |
366 | seq_printf(m, "\t%16llx", | 376 | seq_printf(m, "\t%16llx", |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ce0985615133..baad093aafe3 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -56,7 +56,7 @@ static void quirk_passive_release(struct pci_dev *dev) | |||
56 | while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { | 56 | while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { |
57 | pci_read_config_byte(d, 0x82, &dlc); | 57 | pci_read_config_byte(d, 0x82, &dlc); |
58 | if (!(dlc & 1<<1)) { | 58 | if (!(dlc & 1<<1)) { |
59 | dev_err(&d->dev, "PIIX3: Enabling Passive Release\n"); | 59 | dev_info(&d->dev, "PIIX3: Enabling Passive Release\n"); |
60 | dlc |= 1<<1; | 60 | dlc |= 1<<1; |
61 | pci_write_config_byte(d, 0x82, dlc); | 61 | pci_write_config_byte(d, 0x82, dlc); |
62 | } | 62 | } |
@@ -449,7 +449,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, | |||
449 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi); | 449 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi); |
450 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi); | 450 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quirk_ich4_lpc_acpi); |
451 | 451 | ||
452 | static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | 452 | static void __devinit ich6_lpc_acpi_gpio(struct pci_dev *dev) |
453 | { | 453 | { |
454 | u32 region; | 454 | u32 region; |
455 | 455 | ||
@@ -459,20 +459,95 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | |||
459 | pci_read_config_dword(dev, 0x48, ®ion); | 459 | pci_read_config_dword(dev, 0x48, ®ion); |
460 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); | 460 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); |
461 | } | 461 | } |
462 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi); | 462 | |
463 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi); | 463 | static void __devinit ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) |
464 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi); | 464 | { |
465 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi); | 465 | u32 val; |
466 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi); | 466 | u32 size, base; |
467 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi); | 467 | |
468 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi); | 468 | pci_read_config_dword(dev, reg, &val); |
469 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi); | 469 | |
470 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich6_lpc_acpi); | 470 | /* Enabled? */ |
471 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich6_lpc_acpi); | 471 | if (!(val & 1)) |
472 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich6_lpc_acpi); | 472 | return; |
473 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich6_lpc_acpi); | 473 | base = val & 0xfffc; |
474 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich6_lpc_acpi); | 474 | if (dynsize) { |
475 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich6_lpc_acpi); | 475 | /* |
476 | * This is not correct. It is 16, 32 or 64 bytes depending on | ||
477 | * register D31:F0:ADh bits 5:4. | ||
478 | * | ||
479 | * But this gets us at least _part_ of it. | ||
480 | */ | ||
481 | size = 16; | ||
482 | } else { | ||
483 | size = 128; | ||
484 | } | ||
485 | base &= ~(size-1); | ||
486 | |||
487 | /* Just print it out for now. We should reserve it after more debugging */ | ||
488 | dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base+size-1); | ||
489 | } | ||
490 | |||
491 | static void __devinit quirk_ich6_lpc(struct pci_dev *dev) | ||
492 | { | ||
493 | /* Shared ACPI/GPIO decode with all ICH6+ */ | ||
494 | ich6_lpc_acpi_gpio(dev); | ||
495 | |||
496 | /* ICH6-specific generic IO decode */ | ||
497 | ich6_lpc_generic_decode(dev, 0x84, "LPC Generic IO decode 1", 0); | ||
498 | ich6_lpc_generic_decode(dev, 0x88, "LPC Generic IO decode 2", 1); | ||
499 | } | ||
500 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc); | ||
501 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc); | ||
502 | |||
503 | static void __devinit ich7_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name) | ||
504 | { | ||
505 | u32 val; | ||
506 | u32 mask, base; | ||
507 | |||
508 | pci_read_config_dword(dev, reg, &val); | ||
509 | |||
510 | /* Enabled? */ | ||
511 | if (!(val & 1)) | ||
512 | return; | ||
513 | |||
514 | /* | ||
515 | * IO base in bits 15:2, mask in bits 23:18, both | ||
516 | * are dword-based | ||
517 | */ | ||
518 | base = val & 0xfffc; | ||
519 | mask = (val >> 16) & 0xfc; | ||
520 | mask |= 3; | ||
521 | |||
522 | /* Just print it out for now. We should reserve it after more debugging */ | ||
523 | dev_info(&dev->dev, "%s PIO at %04x (mask %04x)\n", name, base, mask); | ||
524 | } | ||
525 | |||
526 | /* ICH7-10 has the same common LPC generic IO decode registers */ | ||
527 | static void __devinit quirk_ich7_lpc(struct pci_dev *dev) | ||
528 | { | ||
529 | /* We share the common ACPI/DPIO decode with ICH6 */ | ||
530 | ich6_lpc_acpi_gpio(dev); | ||
531 | |||
532 | /* And have 4 ICH7+ generic decodes */ | ||
533 | ich7_lpc_generic_decode(dev, 0x84, "ICH7 LPC Generic IO decode 1"); | ||
534 | ich7_lpc_generic_decode(dev, 0x88, "ICH7 LPC Generic IO decode 2"); | ||
535 | ich7_lpc_generic_decode(dev, 0x8c, "ICH7 LPC Generic IO decode 3"); | ||
536 | ich7_lpc_generic_decode(dev, 0x90, "ICH7 LPC Generic IO decode 4"); | ||
537 | } | ||
538 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich7_lpc); | ||
539 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich7_lpc); | ||
540 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich7_lpc); | ||
541 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich7_lpc); | ||
542 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich7_lpc); | ||
543 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich7_lpc); | ||
544 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich7_lpc); | ||
545 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich7_lpc); | ||
546 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich7_lpc); | ||
547 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich7_lpc); | ||
548 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich7_lpc); | ||
549 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich7_lpc); | ||
550 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, quirk_ich7_lpc); | ||
476 | 551 | ||
477 | /* | 552 | /* |
478 | * VIA ACPI: One IO region pointed to by longword at | 553 | * VIA ACPI: One IO region pointed to by longword at |
@@ -2074,11 +2149,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, | |||
2074 | 2149 | ||
2075 | #endif /* CONFIG_PCI_MSI */ | 2150 | #endif /* CONFIG_PCI_MSI */ |
2076 | 2151 | ||
2077 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) | 2152 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2153 | struct pci_fixup *end) | ||
2078 | { | 2154 | { |
2079 | while (f < end) { | 2155 | while (f < end) { |
2080 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && | 2156 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && |
2081 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { | 2157 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { |
2082 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); | 2158 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); |
2083 | f->hook(dev); | 2159 | f->hook(dev); |
2084 | } | 2160 | } |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ea979f2bc6db..704608945780 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -536,9 +536,8 @@ static void pci_bus_dump_res(struct pci_bus *bus) | |||
536 | if (!res) | 536 | if (!res) |
537 | continue; | 537 | continue; |
538 | 538 | ||
539 | printk(KERN_INFO "bus: %02x index %x %s: %pR\n", | 539 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, |
540 | bus->number, i, | 540 | (res->flags & IORESOURCE_IO) ? "io: " : "mem:", res); |
541 | (res->flags & IORESOURCE_IO) ? "io port" : "mmio", res); | ||
542 | } | 541 | } |
543 | } | 542 | } |
544 | 543 | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 2dbd96cce2d8..32e8d88a4619 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -26,11 +26,13 @@ | |||
26 | #include "pci.h" | 26 | #include "pci.h" |
27 | 27 | ||
28 | 28 | ||
29 | void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | 29 | void pci_update_resource(struct pci_dev *dev, int resno) |
30 | { | 30 | { |
31 | struct pci_bus_region region; | 31 | struct pci_bus_region region; |
32 | u32 new, check, mask; | 32 | u32 new, check, mask; |
33 | int reg; | 33 | int reg; |
34 | enum pci_bar_type type; | ||
35 | struct resource *res = dev->resource + resno; | ||
34 | 36 | ||
35 | /* | 37 | /* |
36 | * Ignore resources for unimplemented BARs and unused resource slots | 38 | * Ignore resources for unimplemented BARs and unused resource slots |
@@ -61,17 +63,13 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
61 | else | 63 | else |
62 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; | 64 | mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; |
63 | 65 | ||
64 | if (resno < 6) { | 66 | reg = pci_resource_bar(dev, resno, &type); |
65 | reg = PCI_BASE_ADDRESS_0 + 4 * resno; | 67 | if (!reg) |
66 | } else if (resno == PCI_ROM_RESOURCE) { | 68 | return; |
69 | if (type != pci_bar_unknown) { | ||
67 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) | 70 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) |
68 | return; | 71 | return; |
69 | new |= PCI_ROM_ADDRESS_ENABLE; | 72 | new |= PCI_ROM_ADDRESS_ENABLE; |
70 | reg = dev->rom_base_reg; | ||
71 | } else { | ||
72 | /* Hmm, non-standard resource. */ | ||
73 | |||
74 | return; /* kill uninitialised var warning */ | ||
75 | } | 73 | } |
76 | 74 | ||
77 | pci_write_config_dword(dev, reg, new); | 75 | pci_write_config_dword(dev, reg, new); |
@@ -134,7 +132,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
134 | 132 | ||
135 | align = resource_alignment(res); | 133 | align = resource_alignment(res); |
136 | if (!align) { | 134 | if (!align) { |
137 | dev_err(&dev->dev, "BAR %d: can't allocate resource (bogus " | 135 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " |
138 | "alignment) %pR flags %#lx\n", | 136 | "alignment) %pR flags %#lx\n", |
139 | resno, res, res->flags); | 137 | resno, res, res->flags); |
140 | return -EINVAL; | 138 | return -EINVAL; |
@@ -157,12 +155,12 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
157 | } | 155 | } |
158 | 156 | ||
159 | if (ret) { | 157 | if (ret) { |
160 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | 158 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", |
161 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | 159 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); |
162 | } else { | 160 | } else { |
163 | res->flags &= ~IORESOURCE_STARTALIGN; | 161 | res->flags &= ~IORESOURCE_STARTALIGN; |
164 | if (resno < PCI_BRIDGE_RESOURCES) | 162 | if (resno < PCI_BRIDGE_RESOURCES) |
165 | pci_update_resource(dev, res, resno); | 163 | pci_update_resource(dev, resno); |
166 | } | 164 | } |
167 | 165 | ||
168 | return ret; | 166 | return ret; |
@@ -197,7 +195,7 @@ int pci_assign_resource_fixed(struct pci_dev *dev, int resno) | |||
197 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | 195 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", |
198 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | 196 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); |
199 | } else if (resno < PCI_BRIDGE_RESOURCES) { | 197 | } else if (resno < PCI_BRIDGE_RESOURCES) { |
200 | pci_update_resource(dev, res, resno); | 198 | pci_update_resource(dev, resno); |
201 | } | 199 | } |
202 | 200 | ||
203 | return ret; | 201 | return ret; |