diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 27 | ||||
-rw-r--r-- | drivers/pci/hotplug/Kconfig | 5 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 9 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_core.c | 1 | ||||
-rw-r--r-- | drivers/pci/pcie/Kconfig | 5 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 69 |
6 files changed, 79 insertions, 37 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 13a633b1612e..7bf3926aecc0 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -86,10 +86,6 @@ struct mvebu_sw_pci_bridge { | |||
86 | u16 secondary_status; | 86 | u16 secondary_status; |
87 | u16 membase; | 87 | u16 membase; |
88 | u16 memlimit; | 88 | u16 memlimit; |
89 | u16 prefmembase; | ||
90 | u16 prefmemlimit; | ||
91 | u32 prefbaseupper; | ||
92 | u32 preflimitupper; | ||
93 | u16 iobaseupper; | 89 | u16 iobaseupper; |
94 | u16 iolimitupper; | 90 | u16 iolimitupper; |
95 | u8 cappointer; | 91 | u8 cappointer; |
@@ -419,15 +415,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | |||
419 | break; | 415 | break; |
420 | 416 | ||
421 | case PCI_PREF_MEMORY_BASE: | 417 | case PCI_PREF_MEMORY_BASE: |
422 | *value = (bridge->prefmemlimit << 16 | bridge->prefmembase); | 418 | *value = 0; |
423 | break; | ||
424 | |||
425 | case PCI_PREF_BASE_UPPER32: | ||
426 | *value = bridge->prefbaseupper; | ||
427 | break; | ||
428 | |||
429 | case PCI_PREF_LIMIT_UPPER32: | ||
430 | *value = bridge->preflimitupper; | ||
431 | break; | 419 | break; |
432 | 420 | ||
433 | case PCI_IO_BASE_UPPER16: | 421 | case PCI_IO_BASE_UPPER16: |
@@ -501,19 +489,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, | |||
501 | mvebu_pcie_handle_membase_change(port); | 489 | mvebu_pcie_handle_membase_change(port); |
502 | break; | 490 | break; |
503 | 491 | ||
504 | case PCI_PREF_MEMORY_BASE: | ||
505 | bridge->prefmembase = value & 0xffff; | ||
506 | bridge->prefmemlimit = value >> 16; | ||
507 | break; | ||
508 | |||
509 | case PCI_PREF_BASE_UPPER32: | ||
510 | bridge->prefbaseupper = value; | ||
511 | break; | ||
512 | |||
513 | case PCI_PREF_LIMIT_UPPER32: | ||
514 | bridge->preflimitupper = value; | ||
515 | break; | ||
516 | |||
517 | case PCI_IO_BASE_UPPER16: | 492 | case PCI_IO_BASE_UPPER16: |
518 | bridge->iobaseupper = value & 0xffff; | 493 | bridge->iobaseupper = value & 0xffff; |
519 | bridge->iolimitupper = value >> 16; | 494 | bridge->iolimitupper = value >> 16; |
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index bb7ebb22db01..d85009de713d 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -3,16 +3,13 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig HOTPLUG_PCI | 5 | menuconfig HOTPLUG_PCI |
6 | tristate "Support for PCI Hotplug" | 6 | bool "Support for PCI Hotplug" |
7 | depends on PCI && SYSFS | 7 | depends on PCI && SYSFS |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here if you have a motherboard with a PCI Hotplug controller. | 9 | Say Y here if you have a motherboard with a PCI Hotplug controller. |
10 | This allows you to add and remove PCI cards while the machine is | 10 | This allows you to add and remove PCI cards while the machine is |
11 | powered up and running. | 11 | powered up and running. |
12 | 12 | ||
13 | To compile this driver as a module, choose M here: the | ||
14 | module will be called pci_hotplug. | ||
15 | |||
16 | When in doubt, say N. | 13 | When in doubt, say N. |
17 | 14 | ||
18 | if HOTPLUG_PCI | 15 | if HOTPLUG_PCI |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index aac7a40e4a4a..0e0d0f7f63fd 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
92 | if (ret) | 92 | if (ret) |
93 | presence = 0; | 93 | presence = 0; |
94 | 94 | ||
95 | list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { | 95 | /* |
96 | * Stopping an SR-IOV PF device removes all the associated VFs, | ||
97 | * which will update the bus->devices list and confuse the | ||
98 | * iterator. Therefore, iterate in reverse so we remove the VFs | ||
99 | * first, then the PF. We do the same in pci_stop_bus_device(). | ||
100 | */ | ||
101 | list_for_each_entry_safe_reverse(dev, temp, &parent->devices, | ||
102 | bus_list) { | ||
96 | pci_dev_get(dev); | 103 | pci_dev_get(dev); |
97 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { | 104 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { |
98 | pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); | 105 | pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index b29e20b7862f..bb7af78e4eed 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -388,7 +388,6 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) | |||
388 | /* Remove the EADS bridge device itself */ | 388 | /* Remove the EADS bridge device itself */ |
389 | BUG_ON(!bus->self); | 389 | BUG_ON(!bus->self); |
390 | pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); | 390 | pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); |
391 | eeh_remove_bus_device(bus->self, true); | ||
392 | pci_stop_and_remove_bus_device(bus->self); | 391 | pci_stop_and_remove_bus_device(bus->self); |
393 | 392 | ||
394 | return 0; | 393 | return 0; |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 569f82fc9e22..3b94cfcfa03b 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -14,15 +14,12 @@ config PCIEPORTBUS | |||
14 | # Include service Kconfig here | 14 | # Include service Kconfig here |
15 | # | 15 | # |
16 | config HOTPLUG_PCI_PCIE | 16 | config HOTPLUG_PCI_PCIE |
17 | tristate "PCI Express Hotplug driver" | 17 | bool "PCI Express Hotplug driver" |
18 | depends on HOTPLUG_PCI && PCIEPORTBUS | 18 | depends on HOTPLUG_PCI && PCIEPORTBUS |
19 | help | 19 | help |
20 | Say Y here if you have a motherboard that supports PCI Express Native | 20 | Say Y here if you have a motherboard that supports PCI Express Native |
21 | Hotplug | 21 | Hotplug |
22 | 22 | ||
23 | To compile this driver as a module, choose M here: the | ||
24 | module will be called pciehp. | ||
25 | |||
26 | When in doubt, say N. | 23 | When in doubt, say N. |
27 | 24 | ||
28 | source "drivers/pci/pcie/aer/Kconfig" | 25 | source "drivers/pci/pcie/aer/Kconfig" |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d254e2379533..64a7de22d9af 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -300,6 +300,47 @@ static void assign_requested_resources_sorted(struct list_head *head, | |||
300 | } | 300 | } |
301 | } | 301 | } |
302 | 302 | ||
303 | static unsigned long pci_fail_res_type_mask(struct list_head *fail_head) | ||
304 | { | ||
305 | struct pci_dev_resource *fail_res; | ||
306 | unsigned long mask = 0; | ||
307 | |||
308 | /* check failed type */ | ||
309 | list_for_each_entry(fail_res, fail_head, list) | ||
310 | mask |= fail_res->flags; | ||
311 | |||
312 | /* | ||
313 | * one pref failed resource will set IORESOURCE_MEM, | ||
314 | * as we can allocate pref in non-pref range. | ||
315 | * Will release all assigned non-pref sibling resources | ||
316 | * according to that bit. | ||
317 | */ | ||
318 | return mask & (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH); | ||
319 | } | ||
320 | |||
321 | static bool pci_need_to_release(unsigned long mask, struct resource *res) | ||
322 | { | ||
323 | if (res->flags & IORESOURCE_IO) | ||
324 | return !!(mask & IORESOURCE_IO); | ||
325 | |||
326 | /* check pref at first */ | ||
327 | if (res->flags & IORESOURCE_PREFETCH) { | ||
328 | if (mask & IORESOURCE_PREFETCH) | ||
329 | return true; | ||
330 | /* count pref if its parent is non-pref */ | ||
331 | else if ((mask & IORESOURCE_MEM) && | ||
332 | !(res->parent->flags & IORESOURCE_PREFETCH)) | ||
333 | return true; | ||
334 | else | ||
335 | return false; | ||
336 | } | ||
337 | |||
338 | if (res->flags & IORESOURCE_MEM) | ||
339 | return !!(mask & IORESOURCE_MEM); | ||
340 | |||
341 | return false; /* should not get here */ | ||
342 | } | ||
343 | |||
303 | static void __assign_resources_sorted(struct list_head *head, | 344 | static void __assign_resources_sorted(struct list_head *head, |
304 | struct list_head *realloc_head, | 345 | struct list_head *realloc_head, |
305 | struct list_head *fail_head) | 346 | struct list_head *fail_head) |
@@ -312,11 +353,24 @@ static void __assign_resources_sorted(struct list_head *head, | |||
312 | * if could do that, could get out early. | 353 | * if could do that, could get out early. |
313 | * if could not do that, we still try to assign requested at first, | 354 | * if could not do that, we still try to assign requested at first, |
314 | * then try to reassign add_size for some resources. | 355 | * then try to reassign add_size for some resources. |
356 | * | ||
357 | * Separate three resource type checking if we need to release | ||
358 | * assigned resource after requested + add_size try. | ||
359 | * 1. if there is io port assign fail, will release assigned | ||
360 | * io port. | ||
361 | * 2. if there is pref mmio assign fail, release assigned | ||
362 | * pref mmio. | ||
363 | * if assigned pref mmio's parent is non-pref mmio and there | ||
364 | * is non-pref mmio assign fail, will release that assigned | ||
365 | * pref mmio. | ||
366 | * 3. if there is non-pref mmio assign fail or pref mmio | ||
367 | * assigned fail, will release assigned non-pref mmio. | ||
315 | */ | 368 | */ |
316 | LIST_HEAD(save_head); | 369 | LIST_HEAD(save_head); |
317 | LIST_HEAD(local_fail_head); | 370 | LIST_HEAD(local_fail_head); |
318 | struct pci_dev_resource *save_res; | 371 | struct pci_dev_resource *save_res; |
319 | struct pci_dev_resource *dev_res; | 372 | struct pci_dev_resource *dev_res, *tmp_res; |
373 | unsigned long fail_type; | ||
320 | 374 | ||
321 | /* Check if optional add_size is there */ | 375 | /* Check if optional add_size is there */ |
322 | if (!realloc_head || list_empty(realloc_head)) | 376 | if (!realloc_head || list_empty(realloc_head)) |
@@ -348,6 +402,19 @@ static void __assign_resources_sorted(struct list_head *head, | |||
348 | return; | 402 | return; |
349 | } | 403 | } |
350 | 404 | ||
405 | /* check failed type */ | ||
406 | fail_type = pci_fail_res_type_mask(&local_fail_head); | ||
407 | /* remove not need to be released assigned res from head list etc */ | ||
408 | list_for_each_entry_safe(dev_res, tmp_res, head, list) | ||
409 | if (dev_res->res->parent && | ||
410 | !pci_need_to_release(fail_type, dev_res->res)) { | ||
411 | /* remove it from realloc_head list */ | ||
412 | remove_from_list(realloc_head, dev_res->res); | ||
413 | remove_from_list(&save_head, dev_res->res); | ||
414 | list_del(&dev_res->list); | ||
415 | kfree(dev_res); | ||
416 | } | ||
417 | |||
351 | free_list(&local_fail_head); | 418 | free_list(&local_fail_head); |
352 | /* Release assigned resource */ | 419 | /* Release assigned resource */ |
353 | list_for_each_entry(dev_res, head, list) | 420 | list_for_each_entry(dev_res, head, list) |