diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/bus.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 11 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 70 | ||||
-rw-r--r-- | drivers/pci/msi.c | 10 | ||||
-rw-r--r-- | drivers/pci/pci.c | 13 |
5 files changed, 80 insertions, 26 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 00660cc502c5..38901665c770 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -162,8 +162,6 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | |||
162 | 162 | ||
163 | avail = *r; | 163 | avail = *r; |
164 | pci_clip_resource_to_region(bus, &avail, region); | 164 | pci_clip_resource_to_region(bus, &avail, region); |
165 | if (!resource_size(&avail)) | ||
166 | continue; | ||
167 | 165 | ||
168 | /* | 166 | /* |
169 | * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to | 167 | * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 13478ecd4113..0e79665afd44 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -60,14 +60,6 @@ | |||
60 | #define PCIE_DEBUG_CTRL 0x1a60 | 60 | #define PCIE_DEBUG_CTRL 0x1a60 |
61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) | 61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) |
62 | 62 | ||
63 | /* | ||
64 | * This product ID is registered by Marvell, and used when the Marvell | ||
65 | * SoC is not the root complex, but an endpoint on the PCIe bus. It is | ||
66 | * therefore safe to re-use this PCI ID for our emulated PCI-to-PCI | ||
67 | * bridge. | ||
68 | */ | ||
69 | #define MARVELL_EMULATED_PCI_PCI_BRIDGE_ID 0x7846 | ||
70 | |||
71 | /* PCI configuration space of a PCI-to-PCI bridge */ | 63 | /* PCI configuration space of a PCI-to-PCI bridge */ |
72 | struct mvebu_sw_pci_bridge { | 64 | struct mvebu_sw_pci_bridge { |
73 | u16 vendor; | 65 | u16 vendor; |
@@ -388,7 +380,8 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) | |||
388 | 380 | ||
389 | bridge->class = PCI_CLASS_BRIDGE_PCI; | 381 | bridge->class = PCI_CLASS_BRIDGE_PCI; |
390 | bridge->vendor = PCI_VENDOR_ID_MARVELL; | 382 | bridge->vendor = PCI_VENDOR_ID_MARVELL; |
391 | bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID; | 383 | bridge->device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; |
384 | bridge->revision = mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; | ||
392 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; | 385 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; |
393 | bridge->cache_line_size = 0x10; | 386 | bridge->cache_line_size = 0x10; |
394 | 387 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cd929aed3613..7c7a388c85ab 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -210,10 +210,29 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static void dock_event(acpi_handle handle, u32 type, void *data) | ||
214 | { | ||
215 | struct acpiphp_context *context; | ||
216 | |||
217 | mutex_lock(&acpiphp_context_lock); | ||
218 | context = acpiphp_get_context(handle); | ||
219 | if (!context || WARN_ON(context->handle != handle) | ||
220 | || context->func.parent->is_going_away) { | ||
221 | mutex_unlock(&acpiphp_context_lock); | ||
222 | return; | ||
223 | } | ||
224 | get_bridge(context->func.parent); | ||
225 | acpiphp_put_context(context); | ||
226 | mutex_unlock(&acpiphp_context_lock); | ||
227 | |||
228 | hotplug_event(handle, type, data); | ||
229 | |||
230 | put_bridge(context->func.parent); | ||
231 | } | ||
213 | 232 | ||
214 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 233 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
215 | .fixup = post_dock_fixups, | 234 | .fixup = post_dock_fixups, |
216 | .handler = hotplug_event, | 235 | .handler = dock_event, |
217 | }; | 236 | }; |
218 | 237 | ||
219 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | 238 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ |
@@ -441,7 +460,9 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
441 | list_del(&bridge->list); | 460 | list_del(&bridge->list); |
442 | mutex_unlock(&bridge_mutex); | 461 | mutex_unlock(&bridge_mutex); |
443 | 462 | ||
463 | mutex_lock(&acpiphp_context_lock); | ||
444 | bridge->is_going_away = true; | 464 | bridge->is_going_away = true; |
465 | mutex_unlock(&acpiphp_context_lock); | ||
445 | } | 466 | } |
446 | 467 | ||
447 | /** | 468 | /** |
@@ -709,6 +730,17 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
709 | return (unsigned int)sta; | 730 | return (unsigned int)sta; |
710 | } | 731 | } |
711 | 732 | ||
733 | static inline bool device_status_valid(unsigned int sta) | ||
734 | { | ||
735 | /* | ||
736 | * ACPI spec says that _STA may return bit 0 clear with bit 3 set | ||
737 | * if the device is valid but does not require a device driver to be | ||
738 | * loaded (Section 6.3.7 of ACPI 5.0A). | ||
739 | */ | ||
740 | unsigned int mask = ACPI_STA_DEVICE_ENABLED | ACPI_STA_DEVICE_FUNCTIONING; | ||
741 | return (sta & mask) == mask; | ||
742 | } | ||
743 | |||
712 | /** | 744 | /** |
713 | * trim_stale_devices - remove PCI devices that are not responding. | 745 | * trim_stale_devices - remove PCI devices that are not responding. |
714 | * @dev: PCI device to start walking the hierarchy from. | 746 | * @dev: PCI device to start walking the hierarchy from. |
@@ -724,7 +756,7 @@ static void trim_stale_devices(struct pci_dev *dev) | |||
724 | unsigned long long sta; | 756 | unsigned long long sta; |
725 | 757 | ||
726 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 758 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
727 | alive = (ACPI_SUCCESS(status) && sta == ACPI_STA_ALL) | 759 | alive = (ACPI_SUCCESS(status) && device_status_valid(sta)) |
728 | || acpiphp_no_hotplug(handle); | 760 | || acpiphp_no_hotplug(handle); |
729 | } | 761 | } |
730 | if (!alive) { | 762 | if (!alive) { |
@@ -742,7 +774,7 @@ static void trim_stale_devices(struct pci_dev *dev) | |||
742 | 774 | ||
743 | /* The device is a bridge. so check the bus below it. */ | 775 | /* The device is a bridge. so check the bus below it. */ |
744 | pm_runtime_get_sync(&dev->dev); | 776 | pm_runtime_get_sync(&dev->dev); |
745 | list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) | 777 | list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) |
746 | trim_stale_devices(child); | 778 | trim_stale_devices(child); |
747 | 779 | ||
748 | pm_runtime_put(&dev->dev); | 780 | pm_runtime_put(&dev->dev); |
@@ -771,10 +803,10 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
771 | mutex_lock(&slot->crit_sect); | 803 | mutex_lock(&slot->crit_sect); |
772 | if (slot_no_hotplug(slot)) { | 804 | if (slot_no_hotplug(slot)) { |
773 | ; /* do nothing */ | 805 | ; /* do nothing */ |
774 | } else if (get_slot_status(slot) == ACPI_STA_ALL) { | 806 | } else if (device_status_valid(get_slot_status(slot))) { |
775 | /* remove stale devices if any */ | 807 | /* remove stale devices if any */ |
776 | list_for_each_entry_safe(dev, tmp, &bus->devices, | 808 | list_for_each_entry_safe_reverse(dev, tmp, |
777 | bus_list) | 809 | &bus->devices, bus_list) |
778 | if (PCI_SLOT(dev->devfn) == slot->device) | 810 | if (PCI_SLOT(dev->devfn) == slot->device) |
779 | trim_stale_devices(dev); | 811 | trim_stale_devices(dev); |
780 | 812 | ||
@@ -805,7 +837,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
805 | int i; | 837 | int i; |
806 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 838 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
807 | 839 | ||
808 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 840 | list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { |
809 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | 841 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { |
810 | struct resource *res = &dev->resource[i]; | 842 | struct resource *res = &dev->resource[i]; |
811 | if ((res->flags & type_mask) && !res->start && | 843 | if ((res->flags & type_mask) && !res->start && |
@@ -829,7 +861,11 @@ void acpiphp_check_host_bridge(acpi_handle handle) | |||
829 | 861 | ||
830 | bridge = acpiphp_handle_to_bridge(handle); | 862 | bridge = acpiphp_handle_to_bridge(handle); |
831 | if (bridge) { | 863 | if (bridge) { |
864 | pci_lock_rescan_remove(); | ||
865 | |||
832 | acpiphp_check_bridge(bridge); | 866 | acpiphp_check_bridge(bridge); |
867 | |||
868 | pci_unlock_rescan_remove(); | ||
833 | put_bridge(bridge); | 869 | put_bridge(bridge); |
834 | } | 870 | } |
835 | } | 871 | } |
@@ -852,6 +888,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
852 | 888 | ||
853 | mutex_unlock(&acpiphp_context_lock); | 889 | mutex_unlock(&acpiphp_context_lock); |
854 | 890 | ||
891 | pci_lock_rescan_remove(); | ||
855 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 892 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
856 | 893 | ||
857 | switch (type) { | 894 | switch (type) { |
@@ -905,6 +942,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
905 | break; | 942 | break; |
906 | } | 943 | } |
907 | 944 | ||
945 | pci_unlock_rescan_remove(); | ||
908 | if (bridge) | 946 | if (bridge) |
909 | put_bridge(bridge); | 947 | put_bridge(bridge); |
910 | } | 948 | } |
@@ -915,11 +953,9 @@ static void hotplug_event_work(void *data, u32 type) | |||
915 | acpi_handle handle = context->handle; | 953 | acpi_handle handle = context->handle; |
916 | 954 | ||
917 | acpi_scan_lock_acquire(); | 955 | acpi_scan_lock_acquire(); |
918 | pci_lock_rescan_remove(); | ||
919 | 956 | ||
920 | hotplug_event(handle, type, context); | 957 | hotplug_event(handle, type, context); |
921 | 958 | ||
922 | pci_unlock_rescan_remove(); | ||
923 | acpi_scan_lock_release(); | 959 | acpi_scan_lock_release(); |
924 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); | 960 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); |
925 | put_bridge(context->func.parent); | 961 | put_bridge(context->func.parent); |
@@ -937,6 +973,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
937 | { | 973 | { |
938 | struct acpiphp_context *context; | 974 | struct acpiphp_context *context; |
939 | u32 ost_code = ACPI_OST_SC_SUCCESS; | 975 | u32 ost_code = ACPI_OST_SC_SUCCESS; |
976 | acpi_status status; | ||
940 | 977 | ||
941 | switch (type) { | 978 | switch (type) { |
942 | case ACPI_NOTIFY_BUS_CHECK: | 979 | case ACPI_NOTIFY_BUS_CHECK: |
@@ -972,13 +1009,20 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
972 | 1009 | ||
973 | mutex_lock(&acpiphp_context_lock); | 1010 | mutex_lock(&acpiphp_context_lock); |
974 | context = acpiphp_get_context(handle); | 1011 | context = acpiphp_get_context(handle); |
975 | if (context && !WARN_ON(context->handle != handle)) { | 1012 | if (!context || WARN_ON(context->handle != handle) |
976 | get_bridge(context->func.parent); | 1013 | || context->func.parent->is_going_away) |
977 | acpiphp_put_context(context); | 1014 | goto err_out; |
978 | acpi_hotplug_execute(hotplug_event_work, context, type); | 1015 | |
1016 | get_bridge(context->func.parent); | ||
1017 | acpiphp_put_context(context); | ||
1018 | status = acpi_hotplug_execute(hotplug_event_work, context, type); | ||
1019 | if (ACPI_SUCCESS(status)) { | ||
979 | mutex_unlock(&acpiphp_context_lock); | 1020 | mutex_unlock(&acpiphp_context_lock); |
980 | return; | 1021 | return; |
981 | } | 1022 | } |
1023 | put_bridge(context->func.parent); | ||
1024 | |||
1025 | err_out: | ||
982 | mutex_unlock(&acpiphp_context_lock); | 1026 | mutex_unlock(&acpiphp_context_lock); |
983 | ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 1027 | ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
984 | 1028 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a0fec6ce571..955ab7990c5b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -545,9 +545,15 @@ static int populate_msi_sysfs(struct pci_dev *pdev) | |||
545 | return -ENOMEM; | 545 | return -ENOMEM; |
546 | list_for_each_entry(entry, &pdev->msi_list, list) { | 546 | list_for_each_entry(entry, &pdev->msi_list, list) { |
547 | char *name = kmalloc(20, GFP_KERNEL); | 547 | char *name = kmalloc(20, GFP_KERNEL); |
548 | if (!name) | ||
549 | goto error_attrs; | ||
550 | |||
548 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); | 551 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); |
549 | if (!msi_dev_attr) | 552 | if (!msi_dev_attr) { |
553 | kfree(name); | ||
550 | goto error_attrs; | 554 | goto error_attrs; |
555 | } | ||
556 | |||
551 | sprintf(name, "%d", entry->irq); | 557 | sprintf(name, "%d", entry->irq); |
552 | sysfs_attr_init(&msi_dev_attr->attr); | 558 | sysfs_attr_init(&msi_dev_attr->attr); |
553 | msi_dev_attr->attr.name = name; | 559 | msi_dev_attr->attr.name = name; |
@@ -589,6 +595,7 @@ error_attrs: | |||
589 | ++count; | 595 | ++count; |
590 | msi_attr = msi_attrs[count]; | 596 | msi_attr = msi_attrs[count]; |
591 | } | 597 | } |
598 | kfree(msi_attrs); | ||
592 | return ret; | 599 | return ret; |
593 | } | 600 | } |
594 | 601 | ||
@@ -959,7 +966,6 @@ EXPORT_SYMBOL(pci_disable_msi); | |||
959 | /** | 966 | /** |
960 | * pci_msix_vec_count - return the number of device's MSI-X table entries | 967 | * pci_msix_vec_count - return the number of device's MSI-X table entries |
961 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 968 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
962 | |||
963 | * This function returns the number of device's MSI-X table entries and | 969 | * This function returns the number of device's MSI-X table entries and |
964 | * therefore the number of MSI-X vectors device is capable of sending. | 970 | * therefore the number of MSI-X vectors device is capable of sending. |
965 | * It returns a negative errno if the device is not capable of sending MSI-X | 971 | * It returns a negative errno if the device is not capable of sending MSI-X |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1febe90831b4..fdbc294821e6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1181,6 +1181,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); | |||
1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
1182 | { | 1182 | { |
1183 | int err; | 1183 | int err; |
1184 | u16 cmd; | ||
1185 | u8 pin; | ||
1184 | 1186 | ||
1185 | err = pci_set_power_state(dev, PCI_D0); | 1187 | err = pci_set_power_state(dev, PCI_D0); |
1186 | if (err < 0 && err != -EIO) | 1188 | if (err < 0 && err != -EIO) |
@@ -1190,6 +1192,17 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) | |||
1190 | return err; | 1192 | return err; |
1191 | pci_fixup_device(pci_fixup_enable, dev); | 1193 | pci_fixup_device(pci_fixup_enable, dev); |
1192 | 1194 | ||
1195 | if (dev->msi_enabled || dev->msix_enabled) | ||
1196 | return 0; | ||
1197 | |||
1198 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | ||
1199 | if (pin) { | ||
1200 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
1201 | if (cmd & PCI_COMMAND_INTX_DISABLE) | ||
1202 | pci_write_config_word(dev, PCI_COMMAND, | ||
1203 | cmd & ~PCI_COMMAND_INTX_DISABLE); | ||
1204 | } | ||
1205 | |||
1193 | return 0; | 1206 | return 0; |
1194 | } | 1207 | } |
1195 | 1208 | ||