diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-04-09 10:17:41 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-04-09 10:21:12 -0400 |
commit | 87d8a69709d971913e6cc7210450fcb8be963667 (patch) | |
tree | 4f8eb95c588f7df84554dcf97d67540664333a7b /drivers/pci | |
parent | 0b8973a81876d90f916507ac40d1381068dc986a (diff) | |
parent | 2eaa9cfdf33b8d7fb7aff27792192e0019ae8fc6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/pci')
58 files changed, 2779 insertions, 855 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b1ecefa2a23d..7858a117e80b 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -21,17 +21,6 @@ config PCI_MSI | |||
21 | 21 | ||
22 | If you don't know what to do here, say N. | 22 | If you don't know what to do here, say N. |
23 | 23 | ||
24 | config PCI_LEGACY | ||
25 | bool "Enable deprecated pci_find_* API" | ||
26 | depends on PCI | ||
27 | default y | ||
28 | help | ||
29 | Say Y here if you want to include support for the deprecated | ||
30 | pci_find_device() API. Most drivers have been converted over | ||
31 | to using the proper hotplug APIs, so this option serves to | ||
32 | include/exclude only a few drivers that are still using this | ||
33 | API. | ||
34 | |||
35 | config PCI_DEBUG | 24 | config PCI_DEBUG |
36 | bool "PCI Debugging" | 25 | bool "PCI Debugging" |
37 | depends on PCI && DEBUG_KERNEL | 26 | depends on PCI && DEBUG_KERNEL |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 4df48d58eaa6..0b51857fbaf7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -2,14 +2,13 @@ | |||
2 | # Makefile for the PCI bus specific drivers. | 2 | # Makefile for the PCI bus specific drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ | 5 | obj-y += access.o bus.o probe.o remove.o pci.o \ |
6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ | 6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ |
7 | irq.o | 7 | irq.o vpd.o |
8 | obj-$(CONFIG_PROC_FS) += proc.o | 8 | obj-$(CONFIG_PROC_FS) += proc.o |
9 | obj-$(CONFIG_SYSFS) += slot.o | 9 | obj-$(CONFIG_SYSFS) += slot.o |
10 | 10 | ||
11 | obj-$(CONFIG_PCI_LEGACY) += legacy.o | 11 | obj-$(CONFIG_PCI_QUIRKS) += quirks.o |
12 | CFLAGS_legacy.o += -Wno-deprecated-declarations | ||
13 | 12 | ||
14 | # Build PCI Express stuff if needed | 13 | # Build PCI Express stuff if needed |
15 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | 14 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ |
@@ -49,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o | |||
49 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | 48 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o |
50 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
51 | obj-$(CONFIG_MN10300) += setup-bus.o | 50 | obj-$(CONFIG_MN10300) += setup-bus.o |
51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | ||
52 | 52 | ||
53 | # | 53 | # |
54 | # ACPI Related PCI FW Functions | 54 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index cef28a79103f..26301cb25e7f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -17,6 +17,52 @@ | |||
17 | 17 | ||
18 | #include "pci.h" | 18 | #include "pci.h" |
19 | 19 | ||
20 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, | ||
21 | unsigned int flags) | ||
22 | { | ||
23 | struct pci_bus_resource *bus_res; | ||
24 | |||
25 | bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL); | ||
26 | if (!bus_res) { | ||
27 | dev_err(&bus->dev, "can't add %pR resource\n", res); | ||
28 | return; | ||
29 | } | ||
30 | |||
31 | bus_res->res = res; | ||
32 | bus_res->flags = flags; | ||
33 | list_add_tail(&bus_res->list, &bus->resources); | ||
34 | } | ||
35 | |||
36 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n) | ||
37 | { | ||
38 | struct pci_bus_resource *bus_res; | ||
39 | |||
40 | if (n < PCI_BRIDGE_RESOURCE_NUM) | ||
41 | return bus->resource[n]; | ||
42 | |||
43 | n -= PCI_BRIDGE_RESOURCE_NUM; | ||
44 | list_for_each_entry(bus_res, &bus->resources, list) { | ||
45 | if (n-- == 0) | ||
46 | return bus_res->res; | ||
47 | } | ||
48 | return NULL; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(pci_bus_resource_n); | ||
51 | |||
52 | void pci_bus_remove_resources(struct pci_bus *bus) | ||
53 | { | ||
54 | struct pci_bus_resource *bus_res, *tmp; | ||
55 | int i; | ||
56 | |||
57 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) | ||
58 | bus->resource[i] = 0; | ||
59 | |||
60 | list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) { | ||
61 | list_del(&bus_res->list); | ||
62 | kfree(bus_res); | ||
63 | } | ||
64 | } | ||
65 | |||
20 | /** | 66 | /** |
21 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 67 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
22 | * @bus: PCI bus | 68 | * @bus: PCI bus |
@@ -36,11 +82,14 @@ int | |||
36 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 82 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
37 | resource_size_t size, resource_size_t align, | 83 | resource_size_t size, resource_size_t align, |
38 | resource_size_t min, unsigned int type_mask, | 84 | resource_size_t min, unsigned int type_mask, |
39 | void (*alignf)(void *, struct resource *, resource_size_t, | 85 | resource_size_t (*alignf)(void *, |
40 | resource_size_t), | 86 | const struct resource *, |
87 | resource_size_t, | ||
88 | resource_size_t), | ||
41 | void *alignf_data) | 89 | void *alignf_data) |
42 | { | 90 | { |
43 | int i, ret = -ENOMEM; | 91 | int i, ret = -ENOMEM; |
92 | struct resource *r; | ||
44 | resource_size_t max = -1; | 93 | resource_size_t max = -1; |
45 | 94 | ||
46 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 95 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
@@ -49,8 +98,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
49 | if (!(res->flags & IORESOURCE_MEM_64)) | 98 | if (!(res->flags & IORESOURCE_MEM_64)) |
50 | max = PCIBIOS_MAX_MEM_32; | 99 | max = PCIBIOS_MAX_MEM_32; |
51 | 100 | ||
52 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 101 | pci_bus_for_each_resource(bus, r, i) { |
53 | struct resource *r = bus->resource[i]; | ||
54 | if (!r) | 102 | if (!r) |
55 | continue; | 103 | continue; |
56 | 104 | ||
@@ -240,9 +288,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | |||
240 | next = dev->bus_list.next; | 288 | next = dev->bus_list.next; |
241 | 289 | ||
242 | /* Run device routines with the device locked */ | 290 | /* Run device routines with the device locked */ |
243 | down(&dev->dev.sem); | 291 | device_lock(&dev->dev); |
244 | retval = cb(dev, userdata); | 292 | retval = cb(dev, userdata); |
245 | up(&dev->dev.sem); | 293 | device_unlock(&dev->dev); |
246 | if (retval) | 294 | if (retval) |
247 | break; | 295 | break; |
248 | } | 296 | } |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4dd7114964ac..efa9f2de51c1 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -332,8 +332,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | |||
332 | slot->hotplug_slot->info->attention_status = 0; | 332 | slot->hotplug_slot->info->attention_status = 0; |
333 | slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); | 333 | slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); |
334 | slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); | 334 | slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); |
335 | slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; | ||
336 | slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; | ||
337 | 335 | ||
338 | acpiphp_slot->slot = slot; | 336 | acpiphp_slot->slot = slot; |
339 | snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); | 337 | snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 8e952fdab764..b5dad9f37453 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -720,12 +720,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func) | |||
720 | -ret_val); | 720 | -ret_val); |
721 | goto acpiphp_bus_add_out; | 721 | goto acpiphp_bus_add_out; |
722 | } | 722 | } |
723 | /* | ||
724 | * try to start anyway. We could have failed to add | ||
725 | * simply because this bus had previously been added | ||
726 | * on another add. Don't bother with the return value | ||
727 | * we just keep going. | ||
728 | */ | ||
729 | ret_val = acpi_bus_start(device); | 723 | ret_val = acpi_bus_start(device); |
730 | 724 | ||
731 | acpiphp_bus_add_out: | 725 | acpiphp_bus_add_out: |
@@ -755,6 +749,24 @@ static int acpiphp_bus_trim(acpi_handle handle) | |||
755 | return retval; | 749 | return retval; |
756 | } | 750 | } |
757 | 751 | ||
752 | static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | ||
753 | { | ||
754 | struct acpiphp_func *func; | ||
755 | union acpi_object params[2]; | ||
756 | struct acpi_object_list arg_list; | ||
757 | |||
758 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
759 | arg_list.count = 2; | ||
760 | arg_list.pointer = params; | ||
761 | params[0].type = ACPI_TYPE_INTEGER; | ||
762 | params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; | ||
763 | params[1].type = ACPI_TYPE_INTEGER; | ||
764 | params[1].integer.value = 1; | ||
765 | /* _REG is optional, we don't care about if there is failure */ | ||
766 | acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); | ||
767 | } | ||
768 | } | ||
769 | |||
758 | /** | 770 | /** |
759 | * enable_device - enable, configure a slot | 771 | * enable_device - enable, configure a slot |
760 | * @slot: slot to be enabled | 772 | * @slot: slot to be enabled |
@@ -811,6 +823,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
811 | pci_bus_assign_resources(bus); | 823 | pci_bus_assign_resources(bus); |
812 | acpiphp_sanitize_bus(bus); | 824 | acpiphp_sanitize_bus(bus); |
813 | acpiphp_set_hpp_values(bus); | 825 | acpiphp_set_hpp_values(bus); |
826 | acpiphp_set_acpi_region(slot); | ||
814 | pci_enable_bridges(bus); | 827 | pci_enable_bridges(bus); |
815 | pci_bus_add_devices(bus); | 828 | pci_bus_add_devices(bus); |
816 | 829 | ||
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index 148fb463b81c..fb3f84661bdc 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
@@ -162,6 +162,7 @@ static int __init cpcihp_generic_init(void) | |||
162 | dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); | 162 | dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); |
163 | if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { | 163 | if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { |
164 | err("Invalid bridge device %s", bridge); | 164 | err("Invalid bridge device %s", bridge); |
165 | pci_dev_put(dev); | ||
165 | return -EINVAL; | 166 | return -EINVAL; |
166 | } | 167 | } |
167 | bus = dev->subordinate; | 168 | bus = dev->subordinate; |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index 9c6a9fd26812..d8ffc7366801 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -310,8 +310,6 @@ struct controller { | |||
310 | u8 first_slot; | 310 | u8 first_slot; |
311 | u8 add_support; | 311 | u8 add_support; |
312 | u8 push_flag; | 312 | u8 push_flag; |
313 | enum pci_bus_speed speed; | ||
314 | enum pci_bus_speed speed_capability; | ||
315 | u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ | 313 | u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ |
316 | u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ | 314 | u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ |
317 | u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ | 315 | u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 075b4f4b6e0d..f184d1d2ecbe 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -583,30 +583,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
583 | return 0; | 583 | return 0; |
584 | } | 584 | } |
585 | 585 | ||
586 | static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
587 | { | ||
588 | struct slot *slot = hotplug_slot->private; | ||
589 | struct controller *ctrl = slot->ctrl; | ||
590 | |||
591 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | ||
592 | |||
593 | *value = ctrl->speed_capability; | ||
594 | |||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
599 | { | ||
600 | struct slot *slot = hotplug_slot->private; | ||
601 | struct controller *ctrl = slot->ctrl; | ||
602 | |||
603 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | ||
604 | |||
605 | *value = ctrl->speed; | ||
606 | |||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { | 586 | static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { |
611 | .set_attention_status = set_attention_status, | 587 | .set_attention_status = set_attention_status, |
612 | .enable_slot = process_SI, | 588 | .enable_slot = process_SI, |
@@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { | |||
616 | .get_attention_status = get_attention_status, | 592 | .get_attention_status = get_attention_status, |
617 | .get_latch_status = get_latch_status, | 593 | .get_latch_status = get_latch_status, |
618 | .get_adapter_status = get_adapter_status, | 594 | .get_adapter_status = get_adapter_status, |
619 | .get_max_bus_speed = get_max_bus_speed, | ||
620 | .get_cur_bus_speed = get_cur_bus_speed, | ||
621 | }; | 595 | }; |
622 | 596 | ||
623 | #define SLOT_NAME_SIZE 10 | 597 | #define SLOT_NAME_SIZE 10 |
@@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct controller *ctrl, | |||
629 | struct slot *slot; | 603 | struct slot *slot; |
630 | struct hotplug_slot *hotplug_slot; | 604 | struct hotplug_slot *hotplug_slot; |
631 | struct hotplug_slot_info *hotplug_slot_info; | 605 | struct hotplug_slot_info *hotplug_slot_info; |
606 | struct pci_bus *bus = ctrl->pci_bus; | ||
632 | u8 number_of_slots; | 607 | u8 number_of_slots; |
633 | u8 slot_device; | 608 | u8 slot_device; |
634 | u8 slot_number; | 609 | u8 slot_number; |
@@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct controller *ctrl, | |||
694 | slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; | 669 | slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; |
695 | if (is_slot66mhz(slot)) | 670 | if (is_slot66mhz(slot)) |
696 | slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; | 671 | slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; |
697 | if (ctrl->speed == PCI_SPEED_66MHz) | 672 | if (bus->cur_bus_speed == PCI_SPEED_66MHz) |
698 | slot->capabilities |= PCISLOT_66_MHZ_OPERATION; | 673 | slot->capabilities |= PCISLOT_66_MHZ_OPERATION; |
699 | 674 | ||
700 | ctrl_slot = | 675 | ctrl_slot = |
@@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
844 | u32 rc; | 819 | u32 rc; |
845 | struct controller *ctrl; | 820 | struct controller *ctrl; |
846 | struct pci_func *func; | 821 | struct pci_func *func; |
822 | struct pci_bus *bus; | ||
847 | int err; | 823 | int err; |
848 | 824 | ||
849 | err = pci_enable_device(pdev); | 825 | err = pci_enable_device(pdev); |
@@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
852 | pci_name(pdev), err); | 828 | pci_name(pdev), err); |
853 | return err; | 829 | return err; |
854 | } | 830 | } |
831 | bus = pdev->subordinate; | ||
855 | 832 | ||
856 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC | 833 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC |
857 | * discovery | 834 | * discovery |
@@ -929,22 +906,22 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
929 | pci_read_config_byte(pdev, 0x41, &bus_cap); | 906 | pci_read_config_byte(pdev, 0x41, &bus_cap); |
930 | if (bus_cap & 0x80) { | 907 | if (bus_cap & 0x80) { |
931 | dbg("bus max supports 133MHz PCI-X\n"); | 908 | dbg("bus max supports 133MHz PCI-X\n"); |
932 | ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; | 909 | bus->max_bus_speed = PCI_SPEED_133MHz_PCIX; |
933 | break; | 910 | break; |
934 | } | 911 | } |
935 | if (bus_cap & 0x40) { | 912 | if (bus_cap & 0x40) { |
936 | dbg("bus max supports 100MHz PCI-X\n"); | 913 | dbg("bus max supports 100MHz PCI-X\n"); |
937 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | 914 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
938 | break; | 915 | break; |
939 | } | 916 | } |
940 | if (bus_cap & 20) { | 917 | if (bus_cap & 20) { |
941 | dbg("bus max supports 66MHz PCI-X\n"); | 918 | dbg("bus max supports 66MHz PCI-X\n"); |
942 | ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; | 919 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; |
943 | break; | 920 | break; |
944 | } | 921 | } |
945 | if (bus_cap & 10) { | 922 | if (bus_cap & 10) { |
946 | dbg("bus max supports 66MHz PCI\n"); | 923 | dbg("bus max supports 66MHz PCI\n"); |
947 | ctrl->speed_capability = PCI_SPEED_66MHz; | 924 | bus->max_bus_speed = PCI_SPEED_66MHz; |
948 | break; | 925 | break; |
949 | } | 926 | } |
950 | 927 | ||
@@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
955 | case PCI_SUB_HPC_ID: | 932 | case PCI_SUB_HPC_ID: |
956 | /* Original 6500/7000 implementation */ | 933 | /* Original 6500/7000 implementation */ |
957 | ctrl->slot_switch_type = 1; | 934 | ctrl->slot_switch_type = 1; |
958 | ctrl->speed_capability = PCI_SPEED_33MHz; | 935 | bus->max_bus_speed = PCI_SPEED_33MHz; |
959 | ctrl->push_button = 0; | 936 | ctrl->push_button = 0; |
960 | ctrl->pci_config_space = 1; | 937 | ctrl->pci_config_space = 1; |
961 | ctrl->defeature_PHP = 1; | 938 | ctrl->defeature_PHP = 1; |
@@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
966 | /* First Pushbutton implementation */ | 943 | /* First Pushbutton implementation */ |
967 | ctrl->push_flag = 1; | 944 | ctrl->push_flag = 1; |
968 | ctrl->slot_switch_type = 1; | 945 | ctrl->slot_switch_type = 1; |
969 | ctrl->speed_capability = PCI_SPEED_33MHz; | 946 | bus->max_bus_speed = PCI_SPEED_33MHz; |
970 | ctrl->push_button = 1; | 947 | ctrl->push_button = 1; |
971 | ctrl->pci_config_space = 1; | 948 | ctrl->pci_config_space = 1; |
972 | ctrl->defeature_PHP = 1; | 949 | ctrl->defeature_PHP = 1; |
@@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
976 | case PCI_SUB_HPC_ID_INTC: | 953 | case PCI_SUB_HPC_ID_INTC: |
977 | /* Third party (6500/7000) */ | 954 | /* Third party (6500/7000) */ |
978 | ctrl->slot_switch_type = 1; | 955 | ctrl->slot_switch_type = 1; |
979 | ctrl->speed_capability = PCI_SPEED_33MHz; | 956 | bus->max_bus_speed = PCI_SPEED_33MHz; |
980 | ctrl->push_button = 0; | 957 | ctrl->push_button = 0; |
981 | ctrl->pci_config_space = 1; | 958 | ctrl->pci_config_space = 1; |
982 | ctrl->defeature_PHP = 1; | 959 | ctrl->defeature_PHP = 1; |
@@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
987 | /* First 66 Mhz implementation */ | 964 | /* First 66 Mhz implementation */ |
988 | ctrl->push_flag = 1; | 965 | ctrl->push_flag = 1; |
989 | ctrl->slot_switch_type = 1; | 966 | ctrl->slot_switch_type = 1; |
990 | ctrl->speed_capability = PCI_SPEED_66MHz; | 967 | bus->max_bus_speed = PCI_SPEED_66MHz; |
991 | ctrl->push_button = 1; | 968 | ctrl->push_button = 1; |
992 | ctrl->pci_config_space = 1; | 969 | ctrl->pci_config_space = 1; |
993 | ctrl->defeature_PHP = 1; | 970 | ctrl->defeature_PHP = 1; |
@@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
998 | /* First PCI-X implementation, 100MHz */ | 975 | /* First PCI-X implementation, 100MHz */ |
999 | ctrl->push_flag = 1; | 976 | ctrl->push_flag = 1; |
1000 | ctrl->slot_switch_type = 1; | 977 | ctrl->slot_switch_type = 1; |
1001 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | 978 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
1002 | ctrl->push_button = 1; | 979 | ctrl->push_button = 1; |
1003 | ctrl->pci_config_space = 1; | 980 | ctrl->pci_config_space = 1; |
1004 | ctrl->defeature_PHP = 1; | 981 | ctrl->defeature_PHP = 1; |
@@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1015 | case PCI_VENDOR_ID_INTEL: | 992 | case PCI_VENDOR_ID_INTEL: |
1016 | /* Check for speed capability (0=33, 1=66) */ | 993 | /* Check for speed capability (0=33, 1=66) */ |
1017 | if (subsystem_deviceid & 0x0001) | 994 | if (subsystem_deviceid & 0x0001) |
1018 | ctrl->speed_capability = PCI_SPEED_66MHz; | 995 | bus->max_bus_speed = PCI_SPEED_66MHz; |
1019 | else | 996 | else |
1020 | ctrl->speed_capability = PCI_SPEED_33MHz; | 997 | bus->max_bus_speed = PCI_SPEED_33MHz; |
1021 | 998 | ||
1022 | /* Check for push button */ | 999 | /* Check for push button */ |
1023 | if (subsystem_deviceid & 0x0002) | 1000 | if (subsystem_deviceid & 0x0002) |
@@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1079 | pdev->bus->number); | 1056 | pdev->bus->number); |
1080 | 1057 | ||
1081 | dbg("Hotplug controller capabilities:\n"); | 1058 | dbg("Hotplug controller capabilities:\n"); |
1082 | dbg(" speed_capability %d\n", ctrl->speed_capability); | 1059 | dbg(" speed_capability %d\n", bus->max_bus_speed); |
1083 | dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? | 1060 | dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? |
1084 | "switch present" : "no switch"); | 1061 | "switch present" : "no switch"); |
1085 | dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? | 1062 | dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? |
@@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1142 | } | 1119 | } |
1143 | 1120 | ||
1144 | /* Check for 66Mhz operation */ | 1121 | /* Check for 66Mhz operation */ |
1145 | ctrl->speed = get_controller_speed(ctrl); | 1122 | bus->cur_bus_speed = get_controller_speed(ctrl); |
1146 | 1123 | ||
1147 | 1124 | ||
1148 | /******************************************************** | 1125 | /******************************************************** |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 0ff689afa757..e43908d9b5df 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -1130,12 +1130,13 @@ static int is_bridge(struct pci_func * func) | |||
1130 | static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) | 1130 | static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) |
1131 | { | 1131 | { |
1132 | struct slot *slot; | 1132 | struct slot *slot; |
1133 | struct pci_bus *bus = ctrl->pci_bus; | ||
1133 | u8 reg; | 1134 | u8 reg; |
1134 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); | 1135 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); |
1135 | u16 reg16; | 1136 | u16 reg16; |
1136 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); | 1137 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); |
1137 | 1138 | ||
1138 | if (ctrl->speed == adapter_speed) | 1139 | if (bus->cur_bus_speed == adapter_speed) |
1139 | return 0; | 1140 | return 0; |
1140 | 1141 | ||
1141 | /* We don't allow freq/mode changes if we find another adapter running | 1142 | /* We don't allow freq/mode changes if we find another adapter running |
@@ -1152,7 +1153,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1152 | * lower speed/mode, we allow the new adapter to function at | 1153 | * lower speed/mode, we allow the new adapter to function at |
1153 | * this rate if supported | 1154 | * this rate if supported |
1154 | */ | 1155 | */ |
1155 | if (ctrl->speed < adapter_speed) | 1156 | if (bus->cur_bus_speed < adapter_speed) |
1156 | return 0; | 1157 | return 0; |
1157 | 1158 | ||
1158 | return 1; | 1159 | return 1; |
@@ -1161,20 +1162,20 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1161 | /* If the controller doesn't support freq/mode changes and the | 1162 | /* If the controller doesn't support freq/mode changes and the |
1162 | * controller is running at a higher mode, we bail | 1163 | * controller is running at a higher mode, we bail |
1163 | */ | 1164 | */ |
1164 | if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) | 1165 | if ((bus->cur_bus_speed > adapter_speed) && (!ctrl->pcix_speed_capability)) |
1165 | return 1; | 1166 | return 1; |
1166 | 1167 | ||
1167 | /* But we allow the adapter to run at a lower rate if possible */ | 1168 | /* But we allow the adapter to run at a lower rate if possible */ |
1168 | if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) | 1169 | if ((bus->cur_bus_speed < adapter_speed) && (!ctrl->pcix_speed_capability)) |
1169 | return 0; | 1170 | return 0; |
1170 | 1171 | ||
1171 | /* We try to set the max speed supported by both the adapter and | 1172 | /* We try to set the max speed supported by both the adapter and |
1172 | * controller | 1173 | * controller |
1173 | */ | 1174 | */ |
1174 | if (ctrl->speed_capability < adapter_speed) { | 1175 | if (bus->max_bus_speed < adapter_speed) { |
1175 | if (ctrl->speed == ctrl->speed_capability) | 1176 | if (bus->cur_bus_speed == bus->max_bus_speed) |
1176 | return 0; | 1177 | return 0; |
1177 | adapter_speed = ctrl->speed_capability; | 1178 | adapter_speed = bus->max_bus_speed; |
1178 | } | 1179 | } |
1179 | 1180 | ||
1180 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); | 1181 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); |
@@ -1229,8 +1230,8 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1229 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); | 1230 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); |
1230 | 1231 | ||
1231 | /* Only if mode change...*/ | 1232 | /* Only if mode change...*/ |
1232 | if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || | 1233 | if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || |
1233 | ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) | 1234 | ((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) |
1234 | set_SOGO(ctrl); | 1235 | set_SOGO(ctrl); |
1235 | 1236 | ||
1236 | wait_for_ctrl_irq(ctrl); | 1237 | wait_for_ctrl_irq(ctrl); |
@@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1243 | set_SOGO(ctrl); | 1244 | set_SOGO(ctrl); |
1244 | wait_for_ctrl_irq(ctrl); | 1245 | wait_for_ctrl_irq(ctrl); |
1245 | 1246 | ||
1246 | ctrl->speed = adapter_speed; | 1247 | bus->cur_bus_speed = adapter_speed; |
1247 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 1248 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
1248 | 1249 | ||
1249 | info("Successfully changed frequency/mode for adapter in slot %d\n", | 1250 | info("Successfully changed frequency/mode for adapter in slot %d\n", |
@@ -1269,6 +1270,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1269 | */ | 1270 | */ |
1270 | static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | 1271 | static u32 board_replaced(struct pci_func *func, struct controller *ctrl) |
1271 | { | 1272 | { |
1273 | struct pci_bus *bus = ctrl->pci_bus; | ||
1272 | u8 hp_slot; | 1274 | u8 hp_slot; |
1273 | u8 temp_byte; | 1275 | u8 temp_byte; |
1274 | u8 adapter_speed; | 1276 | u8 adapter_speed; |
@@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1309 | wait_for_ctrl_irq (ctrl); | 1311 | wait_for_ctrl_irq (ctrl); |
1310 | 1312 | ||
1311 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1313 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1312 | if (ctrl->speed != adapter_speed) | 1314 | if (bus->cur_bus_speed != adapter_speed) |
1313 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1315 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
1314 | rc = WRONG_BUS_FREQUENCY; | 1316 | rc = WRONG_BUS_FREQUENCY; |
1315 | 1317 | ||
@@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1426 | u32 temp_register = 0xFFFFFFFF; | 1428 | u32 temp_register = 0xFFFFFFFF; |
1427 | u32 rc = 0; | 1429 | u32 rc = 0; |
1428 | struct pci_func *new_slot = NULL; | 1430 | struct pci_func *new_slot = NULL; |
1431 | struct pci_bus *bus = ctrl->pci_bus; | ||
1429 | struct slot *p_slot; | 1432 | struct slot *p_slot; |
1430 | struct resource_lists res_lists; | 1433 | struct resource_lists res_lists; |
1431 | 1434 | ||
@@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1456 | wait_for_ctrl_irq (ctrl); | 1459 | wait_for_ctrl_irq (ctrl); |
1457 | 1460 | ||
1458 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1461 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1459 | if (ctrl->speed != adapter_speed) | 1462 | if (bus->cur_bus_speed != adapter_speed) |
1460 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1463 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
1461 | rc = WRONG_BUS_FREQUENCY; | 1464 | rc = WRONG_BUS_FREQUENCY; |
1462 | 1465 | ||
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..0a894efd4b9b 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | static struct kobj_type legacy_ktype = { | 75 | static struct kobj_type legacy_ktype = { |
76 | .sysfs_ops = &(struct sysfs_ops){ | 76 | .sysfs_ops = &(const struct sysfs_ops){ |
77 | .store = legacy_store, .show = legacy_show | 77 | .store = legacy_store, .show = legacy_show |
78 | }, | 78 | }, |
79 | .release = &legacy_release, | 79 | .release = &legacy_release, |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 7485ffda950c..d934dd4fa873 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -395,89 +395,40 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) | |||
395 | return rc; | 395 | return rc; |
396 | } | 396 | } |
397 | 397 | ||
398 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 398 | static int get_max_bus_speed(struct slot *slot) |
399 | { | 399 | { |
400 | int rc = -ENODEV; | 400 | int rc; |
401 | struct slot *pslot; | ||
402 | u8 mode = 0; | 401 | u8 mode = 0; |
402 | enum pci_bus_speed speed; | ||
403 | struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; | ||
403 | 404 | ||
404 | debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, | 405 | debug("%s - Entry slot[%p]\n", __func__, slot); |
405 | hotplug_slot, value); | ||
406 | 406 | ||
407 | ibmphp_lock_operations(); | 407 | ibmphp_lock_operations(); |
408 | 408 | mode = slot->supported_bus_mode; | |
409 | if (hotplug_slot) { | 409 | speed = slot->supported_speed; |
410 | pslot = hotplug_slot->private; | ||
411 | if (pslot) { | ||
412 | rc = 0; | ||
413 | mode = pslot->supported_bus_mode; | ||
414 | *value = pslot->supported_speed; | ||
415 | switch (*value) { | ||
416 | case BUS_SPEED_33: | ||
417 | break; | ||
418 | case BUS_SPEED_66: | ||
419 | if (mode == BUS_MODE_PCIX) | ||
420 | *value += 0x01; | ||
421 | break; | ||
422 | case BUS_SPEED_100: | ||
423 | case BUS_SPEED_133: | ||
424 | *value = pslot->supported_speed + 0x01; | ||
425 | break; | ||
426 | default: | ||
427 | /* Note (will need to change): there would be soon 256, 512 also */ | ||
428 | rc = -ENODEV; | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | |||
433 | ibmphp_unlock_operations(); | 410 | ibmphp_unlock_operations(); |
434 | debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); | ||
435 | return rc; | ||
436 | } | ||
437 | 411 | ||
438 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 412 | switch (speed) { |
439 | { | 413 | case BUS_SPEED_33: |
440 | int rc = -ENODEV; | 414 | break; |
441 | struct slot *pslot; | 415 | case BUS_SPEED_66: |
442 | u8 mode = 0; | 416 | if (mode == BUS_MODE_PCIX) |
443 | 417 | speed += 0x01; | |
444 | debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, | 418 | break; |
445 | hotplug_slot, value); | 419 | case BUS_SPEED_100: |
446 | 420 | case BUS_SPEED_133: | |
447 | ibmphp_lock_operations(); | 421 | speed += 0x01; |
448 | 422 | break; | |
449 | if (hotplug_slot) { | 423 | default: |
450 | pslot = hotplug_slot->private; | 424 | /* Note (will need to change): there would be soon 256, 512 also */ |
451 | if (pslot) { | 425 | rc = -ENODEV; |
452 | rc = get_cur_bus_info(&pslot); | ||
453 | if (!rc) { | ||
454 | mode = pslot->bus_on->current_bus_mode; | ||
455 | *value = pslot->bus_on->current_speed; | ||
456 | switch (*value) { | ||
457 | case BUS_SPEED_33: | ||
458 | break; | ||
459 | case BUS_SPEED_66: | ||
460 | if (mode == BUS_MODE_PCIX) | ||
461 | *value += 0x01; | ||
462 | else if (mode == BUS_MODE_PCI) | ||
463 | ; | ||
464 | else | ||
465 | *value = PCI_SPEED_UNKNOWN; | ||
466 | break; | ||
467 | case BUS_SPEED_100: | ||
468 | case BUS_SPEED_133: | ||
469 | *value += 0x01; | ||
470 | break; | ||
471 | default: | ||
472 | /* Note of change: there would also be 256, 512 soon */ | ||
473 | rc = -ENODEV; | ||
474 | } | ||
475 | } | ||
476 | } | ||
477 | } | 426 | } |
478 | 427 | ||
479 | ibmphp_unlock_operations(); | 428 | if (!rc) |
480 | debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); | 429 | bus->max_bus_speed = speed; |
430 | |||
431 | debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed); | ||
481 | return rc; | 432 | return rc; |
482 | } | 433 | } |
483 | 434 | ||
@@ -572,6 +523,7 @@ static int __init init_ops(void) | |||
572 | if (slot_cur->bus_on->current_speed == 0xFF) | 523 | if (slot_cur->bus_on->current_speed == 0xFF) |
573 | if (get_cur_bus_info(&slot_cur)) | 524 | if (get_cur_bus_info(&slot_cur)) |
574 | return -1; | 525 | return -1; |
526 | get_max_bus_speed(slot_cur); | ||
575 | 527 | ||
576 | if (slot_cur->ctrl->options == 0xFF) | 528 | if (slot_cur->ctrl->options == 0xFF) |
577 | if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) | 529 | if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) |
@@ -655,6 +607,7 @@ static int validate(struct slot *slot_cur, int opn) | |||
655 | int ibmphp_update_slot_info(struct slot *slot_cur) | 607 | int ibmphp_update_slot_info(struct slot *slot_cur) |
656 | { | 608 | { |
657 | struct hotplug_slot_info *info; | 609 | struct hotplug_slot_info *info; |
610 | struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; | ||
658 | int rc; | 611 | int rc; |
659 | u8 bus_speed; | 612 | u8 bus_speed; |
660 | u8 mode; | 613 | u8 mode; |
@@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur) | |||
700 | bus_speed = PCI_SPEED_UNKNOWN; | 653 | bus_speed = PCI_SPEED_UNKNOWN; |
701 | } | 654 | } |
702 | 655 | ||
703 | info->cur_bus_speed = bus_speed; | 656 | bus->cur_bus_speed = bus_speed; |
704 | info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed; | ||
705 | // To do: bus_names | 657 | // To do: bus_names |
706 | 658 | ||
707 | rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); | 659 | rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); |
@@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { | |||
1326 | .get_attention_status = get_attention_status, | 1278 | .get_attention_status = get_attention_status, |
1327 | .get_latch_status = get_latch_status, | 1279 | .get_latch_status = get_latch_status, |
1328 | .get_adapter_status = get_adapter_present, | 1280 | .get_adapter_status = get_adapter_present, |
1329 | .get_max_bus_speed = get_max_bus_speed, | ||
1330 | .get_cur_bus_speed = get_cur_bus_speed, | ||
1331 | /* .get_max_adapter_speed = get_max_adapter_speed, | 1281 | /* .get_max_adapter_speed = get_max_adapter_speed, |
1332 | .get_bus_name_status = get_bus_name, | 1282 | .get_bus_name_status = get_bus_name, |
1333 | */ | 1283 | */ |
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index c1abac8ab5c3..5becbdee4027 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void) | |||
245 | 245 | ||
246 | int __init ibmphp_access_ebda (void) | 246 | int __init ibmphp_access_ebda (void) |
247 | { | 247 | { |
248 | u8 format, num_ctlrs, rio_complete, hs_complete; | 248 | u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz; |
249 | u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; | 249 | u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; |
250 | int rc = 0; | 250 | int rc = 0; |
251 | 251 | ||
@@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void) | |||
260 | iounmap (io_mem); | 260 | iounmap (io_mem); |
261 | debug ("returned ebda segment: %x\n", ebda_seg); | 261 | debug ("returned ebda segment: %x\n", ebda_seg); |
262 | 262 | ||
263 | io_mem = ioremap(ebda_seg<<4, 1024); | 263 | io_mem = ioremap(ebda_seg<<4, 1); |
264 | if (!io_mem) | ||
265 | return -ENOMEM; | ||
266 | ebda_sz = readb(io_mem); | ||
267 | iounmap(io_mem); | ||
268 | debug("ebda size: %d(KiB)\n", ebda_sz); | ||
269 | if (ebda_sz == 0) | ||
270 | return -ENOMEM; | ||
271 | |||
272 | io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024)); | ||
264 | if (!io_mem ) | 273 | if (!io_mem ) |
265 | return -ENOMEM; | 274 | return -ENOMEM; |
266 | next_offset = 0x180; | 275 | next_offset = 0x180; |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index c7084f0eca5a..1aaf3f32d3cd 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/semaphore.h> | ||
38 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
39 | #include "ibmphp.h" | 40 | #include "ibmphp.h" |
40 | 41 | ||
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index ec73294d1fa6..e2dc289f767c 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c | |||
@@ -40,7 +40,7 @@ static void update_resources (struct bus_node *bus_cur, int type, int rangeno); | |||
40 | static int once_over (void); | 40 | static int once_over (void); |
41 | static int remove_ranges (struct bus_node *, struct bus_node *); | 41 | static int remove_ranges (struct bus_node *, struct bus_node *); |
42 | static int update_bridge_ranges (struct bus_node **); | 42 | static int update_bridge_ranges (struct bus_node **); |
43 | static int add_range (int type, struct range_node *, struct bus_node *); | 43 | static int add_bus_range (int type, struct range_node *, struct bus_node *); |
44 | static void fix_resources (struct bus_node *); | 44 | static void fix_resources (struct bus_node *); |
45 | static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); | 45 | static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); |
46 | 46 | ||
@@ -133,7 +133,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node | |||
133 | newrange->rangeno = 1; | 133 | newrange->rangeno = 1; |
134 | else { | 134 | else { |
135 | /* need to insert our range */ | 135 | /* need to insert our range */ |
136 | add_range (flag, newrange, newbus); | 136 | add_bus_range (flag, newrange, newbus); |
137 | debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end); | 137 | debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end); |
138 | } | 138 | } |
139 | 139 | ||
@@ -384,7 +384,7 @@ int __init ibmphp_rsrc_init (void) | |||
384 | * Input: type of the resource, range to add, current bus | 384 | * Input: type of the resource, range to add, current bus |
385 | * Output: 0 or -1, bus and range ptrs | 385 | * Output: 0 or -1, bus and range ptrs |
386 | ********************************************************************************/ | 386 | ********************************************************************************/ |
387 | static int add_range (int type, struct range_node *range, struct bus_node *bus_cur) | 387 | static int add_bus_range (int type, struct range_node *range, struct bus_node *bus_cur) |
388 | { | 388 | { |
389 | struct range_node *range_cur = NULL; | 389 | struct range_node *range_cur = NULL; |
390 | struct range_node *range_prev; | 390 | struct range_node *range_prev; |
@@ -455,7 +455,7 @@ static int add_range (int type, struct range_node *range, struct bus_node *bus_c | |||
455 | 455 | ||
456 | /******************************************************************************* | 456 | /******************************************************************************* |
457 | * This routine goes through the list of resources of type 'type' and updates | 457 | * This routine goes through the list of resources of type 'type' and updates |
458 | * the range numbers that they correspond to. It was called from add_range fnc | 458 | * the range numbers that they correspond to. It was called from add_bus_range fnc |
459 | * | 459 | * |
460 | * Input: bus, type of the resource, the rangeno starting from which to update | 460 | * Input: bus, type of the resource, the rangeno starting from which to update |
461 | ******************************************************************************/ | 461 | ******************************************************************************/ |
@@ -1999,7 +1999,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) | |||
1999 | 1999 | ||
2000 | if (bus_sec->noIORanges > 0) { | 2000 | if (bus_sec->noIORanges > 0) { |
2001 | if (!range_exists_already (range, bus_sec, IO)) { | 2001 | if (!range_exists_already (range, bus_sec, IO)) { |
2002 | add_range (IO, range, bus_sec); | 2002 | add_bus_range (IO, range, bus_sec); |
2003 | ++bus_sec->noIORanges; | 2003 | ++bus_sec->noIORanges; |
2004 | } else { | 2004 | } else { |
2005 | kfree (range); | 2005 | kfree (range); |
@@ -2048,7 +2048,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) | |||
2048 | 2048 | ||
2049 | if (bus_sec->noMemRanges > 0) { | 2049 | if (bus_sec->noMemRanges > 0) { |
2050 | if (!range_exists_already (range, bus_sec, MEM)) { | 2050 | if (!range_exists_already (range, bus_sec, MEM)) { |
2051 | add_range (MEM, range, bus_sec); | 2051 | add_bus_range (MEM, range, bus_sec); |
2052 | ++bus_sec->noMemRanges; | 2052 | ++bus_sec->noMemRanges; |
2053 | } else { | 2053 | } else { |
2054 | kfree (range); | 2054 | kfree (range); |
@@ -2102,7 +2102,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) | |||
2102 | 2102 | ||
2103 | if (bus_sec->noPFMemRanges > 0) { | 2103 | if (bus_sec->noPFMemRanges > 0) { |
2104 | if (!range_exists_already (range, bus_sec, PFMEM)) { | 2104 | if (!range_exists_already (range, bus_sec, PFMEM)) { |
2105 | add_range (PFMEM, range, bus_sec); | 2105 | add_bus_range (PFMEM, range, bus_sec); |
2106 | ++bus_sec->noPFMemRanges; | 2106 | ++bus_sec->noPFMemRanges; |
2107 | } else { | 2107 | } else { |
2108 | kfree (range); | 2108 | kfree (range); |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 38183a534b65..728b119f71ad 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -64,32 +64,6 @@ static int debug; | |||
64 | static LIST_HEAD(pci_hotplug_slot_list); | 64 | static LIST_HEAD(pci_hotplug_slot_list); |
65 | static DEFINE_MUTEX(pci_hp_mutex); | 65 | static DEFINE_MUTEX(pci_hp_mutex); |
66 | 66 | ||
67 | /* these strings match up with the values in pci_bus_speed */ | ||
68 | static char *pci_bus_speed_strings[] = { | ||
69 | "33 MHz PCI", /* 0x00 */ | ||
70 | "66 MHz PCI", /* 0x01 */ | ||
71 | "66 MHz PCI-X", /* 0x02 */ | ||
72 | "100 MHz PCI-X", /* 0x03 */ | ||
73 | "133 MHz PCI-X", /* 0x04 */ | ||
74 | NULL, /* 0x05 */ | ||
75 | NULL, /* 0x06 */ | ||
76 | NULL, /* 0x07 */ | ||
77 | NULL, /* 0x08 */ | ||
78 | "66 MHz PCI-X 266", /* 0x09 */ | ||
79 | "100 MHz PCI-X 266", /* 0x0a */ | ||
80 | "133 MHz PCI-X 266", /* 0x0b */ | ||
81 | NULL, /* 0x0c */ | ||
82 | NULL, /* 0x0d */ | ||
83 | NULL, /* 0x0e */ | ||
84 | NULL, /* 0x0f */ | ||
85 | NULL, /* 0x10 */ | ||
86 | "66 MHz PCI-X 533", /* 0x11 */ | ||
87 | "100 MHz PCI-X 533", /* 0x12 */ | ||
88 | "133 MHz PCI-X 533", /* 0x13 */ | ||
89 | "2.5 GT/s PCIe", /* 0x14 */ | ||
90 | "5.0 GT/s PCIe", /* 0x15 */ | ||
91 | }; | ||
92 | |||
93 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | 67 | #ifdef CONFIG_HOTPLUG_PCI_CPCI |
94 | extern int cpci_hotplug_init(int debug); | 68 | extern int cpci_hotplug_init(int debug); |
95 | extern void cpci_hotplug_exit(void); | 69 | extern void cpci_hotplug_exit(void); |
@@ -118,8 +92,6 @@ GET_STATUS(power_status, u8) | |||
118 | GET_STATUS(attention_status, u8) | 92 | GET_STATUS(attention_status, u8) |
119 | GET_STATUS(latch_status, u8) | 93 | GET_STATUS(latch_status, u8) |
120 | GET_STATUS(adapter_status, u8) | 94 | GET_STATUS(adapter_status, u8) |
121 | GET_STATUS(max_bus_speed, enum pci_bus_speed) | ||
122 | GET_STATUS(cur_bus_speed, enum pci_bus_speed) | ||
123 | 95 | ||
124 | static ssize_t power_read_file(struct pci_slot *slot, char *buf) | 96 | static ssize_t power_read_file(struct pci_slot *slot, char *buf) |
125 | { | 97 | { |
@@ -263,60 +235,6 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = { | |||
263 | .show = presence_read_file, | 235 | .show = presence_read_file, |
264 | }; | 236 | }; |
265 | 237 | ||
266 | static char *unknown_speed = "Unknown bus speed"; | ||
267 | |||
268 | static ssize_t max_bus_speed_read_file(struct pci_slot *slot, char *buf) | ||
269 | { | ||
270 | char *speed_string; | ||
271 | int retval; | ||
272 | enum pci_bus_speed value; | ||
273 | |||
274 | retval = get_max_bus_speed(slot->hotplug, &value); | ||
275 | if (retval) | ||
276 | goto exit; | ||
277 | |||
278 | if (value == PCI_SPEED_UNKNOWN) | ||
279 | speed_string = unknown_speed; | ||
280 | else | ||
281 | speed_string = pci_bus_speed_strings[value]; | ||
282 | |||
283 | retval = sprintf (buf, "%s\n", speed_string); | ||
284 | |||
285 | exit: | ||
286 | return retval; | ||
287 | } | ||
288 | |||
289 | static struct pci_slot_attribute hotplug_slot_attr_max_bus_speed = { | ||
290 | .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO}, | ||
291 | .show = max_bus_speed_read_file, | ||
292 | }; | ||
293 | |||
294 | static ssize_t cur_bus_speed_read_file(struct pci_slot *slot, char *buf) | ||
295 | { | ||
296 | char *speed_string; | ||
297 | int retval; | ||
298 | enum pci_bus_speed value; | ||
299 | |||
300 | retval = get_cur_bus_speed(slot->hotplug, &value); | ||
301 | if (retval) | ||
302 | goto exit; | ||
303 | |||
304 | if (value == PCI_SPEED_UNKNOWN) | ||
305 | speed_string = unknown_speed; | ||
306 | else | ||
307 | speed_string = pci_bus_speed_strings[value]; | ||
308 | |||
309 | retval = sprintf (buf, "%s\n", speed_string); | ||
310 | |||
311 | exit: | ||
312 | return retval; | ||
313 | } | ||
314 | |||
315 | static struct pci_slot_attribute hotplug_slot_attr_cur_bus_speed = { | ||
316 | .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO}, | ||
317 | .show = cur_bus_speed_read_file, | ||
318 | }; | ||
319 | |||
320 | static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, | 238 | static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, |
321 | size_t count) | 239 | size_t count) |
322 | { | 240 | { |
@@ -391,26 +309,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot) | |||
391 | return false; | 309 | return false; |
392 | } | 310 | } |
393 | 311 | ||
394 | static bool has_max_bus_speed_file(struct pci_slot *pci_slot) | ||
395 | { | ||
396 | struct hotplug_slot *slot = pci_slot->hotplug; | ||
397 | if ((!slot) || (!slot->ops)) | ||
398 | return false; | ||
399 | if (slot->ops->get_max_bus_speed) | ||
400 | return true; | ||
401 | return false; | ||
402 | } | ||
403 | |||
404 | static bool has_cur_bus_speed_file(struct pci_slot *pci_slot) | ||
405 | { | ||
406 | struct hotplug_slot *slot = pci_slot->hotplug; | ||
407 | if ((!slot) || (!slot->ops)) | ||
408 | return false; | ||
409 | if (slot->ops->get_cur_bus_speed) | ||
410 | return true; | ||
411 | return false; | ||
412 | } | ||
413 | |||
414 | static bool has_test_file(struct pci_slot *pci_slot) | 312 | static bool has_test_file(struct pci_slot *pci_slot) |
415 | { | 313 | { |
416 | struct hotplug_slot *slot = pci_slot->hotplug; | 314 | struct hotplug_slot *slot = pci_slot->hotplug; |
@@ -456,20 +354,6 @@ static int fs_add_slot(struct pci_slot *slot) | |||
456 | goto exit_adapter; | 354 | goto exit_adapter; |
457 | } | 355 | } |
458 | 356 | ||
459 | if (has_max_bus_speed_file(slot)) { | ||
460 | retval = sysfs_create_file(&slot->kobj, | ||
461 | &hotplug_slot_attr_max_bus_speed.attr); | ||
462 | if (retval) | ||
463 | goto exit_max_speed; | ||
464 | } | ||
465 | |||
466 | if (has_cur_bus_speed_file(slot)) { | ||
467 | retval = sysfs_create_file(&slot->kobj, | ||
468 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
469 | if (retval) | ||
470 | goto exit_cur_speed; | ||
471 | } | ||
472 | |||
473 | if (has_test_file(slot)) { | 357 | if (has_test_file(slot)) { |
474 | retval = sysfs_create_file(&slot->kobj, | 358 | retval = sysfs_create_file(&slot->kobj, |
475 | &hotplug_slot_attr_test.attr); | 359 | &hotplug_slot_attr_test.attr); |
@@ -480,14 +364,6 @@ static int fs_add_slot(struct pci_slot *slot) | |||
480 | goto exit; | 364 | goto exit; |
481 | 365 | ||
482 | exit_test: | 366 | exit_test: |
483 | if (has_cur_bus_speed_file(slot)) | ||
484 | sysfs_remove_file(&slot->kobj, | ||
485 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
486 | exit_cur_speed: | ||
487 | if (has_max_bus_speed_file(slot)) | ||
488 | sysfs_remove_file(&slot->kobj, | ||
489 | &hotplug_slot_attr_max_bus_speed.attr); | ||
490 | exit_max_speed: | ||
491 | if (has_adapter_file(slot)) | 367 | if (has_adapter_file(slot)) |
492 | sysfs_remove_file(&slot->kobj, | 368 | sysfs_remove_file(&slot->kobj, |
493 | &hotplug_slot_attr_presence.attr); | 369 | &hotplug_slot_attr_presence.attr); |
@@ -523,14 +399,6 @@ static void fs_remove_slot(struct pci_slot *slot) | |||
523 | sysfs_remove_file(&slot->kobj, | 399 | sysfs_remove_file(&slot->kobj, |
524 | &hotplug_slot_attr_presence.attr); | 400 | &hotplug_slot_attr_presence.attr); |
525 | 401 | ||
526 | if (has_max_bus_speed_file(slot)) | ||
527 | sysfs_remove_file(&slot->kobj, | ||
528 | &hotplug_slot_attr_max_bus_speed.attr); | ||
529 | |||
530 | if (has_cur_bus_speed_file(slot)) | ||
531 | sysfs_remove_file(&slot->kobj, | ||
532 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
533 | |||
534 | if (has_test_file(slot)) | 402 | if (has_test_file(slot)) |
535 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); | 403 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); |
536 | 404 | ||
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 5674b2075bdc..920f820edf87 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -69,8 +69,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); | |||
69 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | 69 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); |
70 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | 70 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); |
71 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 71 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); |
72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
74 | 72 | ||
75 | /** | 73 | /** |
76 | * release_slot - free up the memory used by a slot | 74 | * release_slot - free up the memory used by a slot |
@@ -113,8 +111,6 @@ static int init_slot(struct controller *ctrl) | |||
113 | ops->disable_slot = disable_slot; | 111 | ops->disable_slot = disable_slot; |
114 | ops->get_power_status = get_power_status; | 112 | ops->get_power_status = get_power_status; |
115 | ops->get_adapter_status = get_adapter_status; | 113 | ops->get_adapter_status = get_adapter_status; |
116 | ops->get_max_bus_speed = get_max_bus_speed; | ||
117 | ops->get_cur_bus_speed = get_cur_bus_speed; | ||
118 | if (MRL_SENS(ctrl)) | 114 | if (MRL_SENS(ctrl)) |
119 | ops->get_latch_status = get_latch_status; | 115 | ops->get_latch_status = get_latch_status; |
120 | if (ATTN_LED(ctrl)) { | 116 | if (ATTN_LED(ctrl)) { |
@@ -227,27 +223,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
227 | return pciehp_get_adapter_status(slot, value); | 223 | return pciehp_get_adapter_status(slot, value); |
228 | } | 224 | } |
229 | 225 | ||
230 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | ||
231 | enum pci_bus_speed *value) | ||
232 | { | ||
233 | struct slot *slot = hotplug_slot->private; | ||
234 | |||
235 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
236 | __func__, slot_name(slot)); | ||
237 | |||
238 | return pciehp_get_max_link_speed(slot, value); | ||
239 | } | ||
240 | |||
241 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
242 | { | ||
243 | struct slot *slot = hotplug_slot->private; | ||
244 | |||
245 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
246 | __func__, slot_name(slot)); | ||
247 | |||
248 | return pciehp_get_cur_link_speed(slot, value); | ||
249 | } | ||
250 | |||
251 | static int pciehp_probe(struct pcie_device *dev) | 226 | static int pciehp_probe(struct pcie_device *dev) |
252 | { | 227 | { |
253 | int rc; | 228 | int rc; |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index d6ac1b261dd9..9a7f247e8ac1 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -341,6 +341,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
341 | p_slot->state = POWERON_STATE; | 341 | p_slot->state = POWERON_STATE; |
342 | break; | 342 | break; |
343 | default: | 343 | default: |
344 | kfree(info); | ||
344 | goto out; | 345 | goto out; |
345 | } | 346 | } |
346 | queue_work(pciehp_wq, &info->work); | 347 | queue_work(pciehp_wq, &info->work); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 10040d58c8ef..9665d6b17a2a 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -492,6 +492,7 @@ int pciehp_power_on_slot(struct slot * slot) | |||
492 | u16 slot_cmd; | 492 | u16 slot_cmd; |
493 | u16 cmd_mask; | 493 | u16 cmd_mask; |
494 | u16 slot_status; | 494 | u16 slot_status; |
495 | u16 lnk_status; | ||
495 | int retval = 0; | 496 | int retval = 0; |
496 | 497 | ||
497 | /* Clear sticky power-fault bit from previous power failures */ | 498 | /* Clear sticky power-fault bit from previous power failures */ |
@@ -523,6 +524,14 @@ int pciehp_power_on_slot(struct slot * slot) | |||
523 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 524 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
524 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 525 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
525 | 526 | ||
527 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | ||
528 | if (retval) { | ||
529 | ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", | ||
530 | __func__); | ||
531 | return retval; | ||
532 | } | ||
533 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | ||
534 | |||
526 | return retval; | 535 | return retval; |
527 | } | 536 | } |
528 | 537 | ||
@@ -610,37 +619,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
610 | return IRQ_HANDLED; | 619 | return IRQ_HANDLED; |
611 | } | 620 | } |
612 | 621 | ||
613 | int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value) | ||
614 | { | ||
615 | struct controller *ctrl = slot->ctrl; | ||
616 | enum pcie_link_speed lnk_speed; | ||
617 | u32 lnk_cap; | ||
618 | int retval = 0; | ||
619 | |||
620 | retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); | ||
621 | if (retval) { | ||
622 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); | ||
623 | return retval; | ||
624 | } | ||
625 | |||
626 | switch (lnk_cap & 0x000F) { | ||
627 | case 1: | ||
628 | lnk_speed = PCIE_2_5GB; | ||
629 | break; | ||
630 | case 2: | ||
631 | lnk_speed = PCIE_5_0GB; | ||
632 | break; | ||
633 | default: | ||
634 | lnk_speed = PCIE_LNK_SPEED_UNKNOWN; | ||
635 | break; | ||
636 | } | ||
637 | |||
638 | *value = lnk_speed; | ||
639 | ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed); | ||
640 | |||
641 | return retval; | ||
642 | } | ||
643 | |||
644 | int pciehp_get_max_lnk_width(struct slot *slot, | 622 | int pciehp_get_max_lnk_width(struct slot *slot, |
645 | enum pcie_link_width *value) | 623 | enum pcie_link_width *value) |
646 | { | 624 | { |
@@ -691,38 +669,6 @@ int pciehp_get_max_lnk_width(struct slot *slot, | |||
691 | return retval; | 669 | return retval; |
692 | } | 670 | } |
693 | 671 | ||
694 | int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value) | ||
695 | { | ||
696 | struct controller *ctrl = slot->ctrl; | ||
697 | enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; | ||
698 | int retval = 0; | ||
699 | u16 lnk_status; | ||
700 | |||
701 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | ||
702 | if (retval) { | ||
703 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", | ||
704 | __func__); | ||
705 | return retval; | ||
706 | } | ||
707 | |||
708 | switch (lnk_status & PCI_EXP_LNKSTA_CLS) { | ||
709 | case 1: | ||
710 | lnk_speed = PCIE_2_5GB; | ||
711 | break; | ||
712 | case 2: | ||
713 | lnk_speed = PCIE_5_0GB; | ||
714 | break; | ||
715 | default: | ||
716 | lnk_speed = PCIE_LNK_SPEED_UNKNOWN; | ||
717 | break; | ||
718 | } | ||
719 | |||
720 | *value = lnk_speed; | ||
721 | ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed); | ||
722 | |||
723 | return retval; | ||
724 | } | ||
725 | |||
726 | int pciehp_get_cur_lnk_width(struct slot *slot, | 672 | int pciehp_get_cur_lnk_width(struct slot *slot, |
727 | enum pcie_link_width *value) | 673 | enum pcie_link_width *value) |
728 | { | 674 | { |
@@ -886,9 +832,8 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
886 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 832 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
887 | if (!pci_resource_len(pdev, i)) | 833 | if (!pci_resource_len(pdev, i)) |
888 | continue; | 834 | continue; |
889 | ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", | 835 | ctrl_info(ctrl, " PCI resource [%d] : %pR\n", |
890 | i, (unsigned long long)pci_resource_len(pdev, i), | 836 | i, &pdev->resource[i]); |
891 | (unsigned long long)pci_resource_start(pdev, i)); | ||
892 | } | 837 | } |
893 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); | 838 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); |
894 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); | 839 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 21733108adde..0a16444c14c9 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -53,17 +53,15 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev) | |||
53 | busnr = pci_scan_bridge(parent, dev, busnr, pass); | 53 | busnr = pci_scan_bridge(parent, dev, busnr, pass); |
54 | if (!dev->subordinate) | 54 | if (!dev->subordinate) |
55 | return -1; | 55 | return -1; |
56 | pci_bus_size_bridges(dev->subordinate); | 56 | |
57 | pci_bus_assign_resources(parent); | ||
58 | pci_enable_bridges(parent); | ||
59 | pci_bus_add_devices(parent); | ||
60 | return 0; | 57 | return 0; |
61 | } | 58 | } |
62 | 59 | ||
63 | int pciehp_configure_device(struct slot *p_slot) | 60 | int pciehp_configure_device(struct slot *p_slot) |
64 | { | 61 | { |
65 | struct pci_dev *dev; | 62 | struct pci_dev *dev; |
66 | struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; | 63 | struct pci_dev *bridge = p_slot->ctrl->pcie->port; |
64 | struct pci_bus *parent = bridge->subordinate; | ||
67 | int num, fn; | 65 | int num, fn; |
68 | struct controller *ctrl = p_slot->ctrl; | 66 | struct controller *ctrl = p_slot->ctrl; |
69 | 67 | ||
@@ -96,12 +94,25 @@ int pciehp_configure_device(struct slot *p_slot) | |||
96 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { | 94 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { |
97 | pciehp_add_bridge(dev); | 95 | pciehp_add_bridge(dev); |
98 | } | 96 | } |
97 | pci_dev_put(dev); | ||
98 | } | ||
99 | |||
100 | pci_assign_unassigned_bridge_resources(bridge); | ||
101 | |||
102 | for (fn = 0; fn < 8; fn++) { | ||
103 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | ||
104 | if (!dev) | ||
105 | continue; | ||
106 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
107 | pci_dev_put(dev); | ||
108 | continue; | ||
109 | } | ||
99 | pci_configure_slot(dev); | 110 | pci_configure_slot(dev); |
100 | pci_dev_put(dev); | 111 | pci_dev_put(dev); |
101 | } | 112 | } |
102 | 113 | ||
103 | pci_bus_assign_resources(parent); | ||
104 | pci_bus_add_devices(parent); | 114 | pci_bus_add_devices(parent); |
115 | |||
105 | return 0; | 116 | return 0; |
106 | } | 117 | } |
107 | 118 | ||
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c159223389ec..dcaae725fd79 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -130,10 +130,9 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) | |||
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 133 | static enum pci_bus_speed get_max_bus_speed(struct slot *slot) |
134 | { | 134 | { |
135 | struct slot *slot = (struct slot *)hotplug_slot->private; | 135 | enum pci_bus_speed speed; |
136 | |||
137 | switch (slot->type) { | 136 | switch (slot->type) { |
138 | case 1: | 137 | case 1: |
139 | case 2: | 138 | case 2: |
@@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe | |||
141 | case 4: | 140 | case 4: |
142 | case 5: | 141 | case 5: |
143 | case 6: | 142 | case 6: |
144 | *value = PCI_SPEED_33MHz; /* speed for case 1-6 */ | 143 | speed = PCI_SPEED_33MHz; /* speed for case 1-6 */ |
145 | break; | 144 | break; |
146 | case 7: | 145 | case 7: |
147 | case 8: | 146 | case 8: |
148 | *value = PCI_SPEED_66MHz; | 147 | speed = PCI_SPEED_66MHz; |
149 | break; | 148 | break; |
150 | case 11: | 149 | case 11: |
151 | case 14: | 150 | case 14: |
152 | *value = PCI_SPEED_66MHz_PCIX; | 151 | speed = PCI_SPEED_66MHz_PCIX; |
153 | break; | 152 | break; |
154 | case 12: | 153 | case 12: |
155 | case 15: | 154 | case 15: |
156 | *value = PCI_SPEED_100MHz_PCIX; | 155 | speed = PCI_SPEED_100MHz_PCIX; |
157 | break; | 156 | break; |
158 | case 13: | 157 | case 13: |
159 | case 16: | 158 | case 16: |
160 | *value = PCI_SPEED_133MHz_PCIX; | 159 | speed = PCI_SPEED_133MHz_PCIX; |
161 | break; | 160 | break; |
162 | default: | 161 | default: |
163 | *value = PCI_SPEED_UNKNOWN; | 162 | speed = PCI_SPEED_UNKNOWN; |
164 | break; | 163 | break; |
165 | |||
166 | } | 164 | } |
167 | return 0; | 165 | |
166 | return speed; | ||
168 | } | 167 | } |
169 | 168 | ||
170 | static int get_children_props(struct device_node *dn, const int **drc_indexes, | 169 | static int get_children_props(struct device_node *dn, const int **drc_indexes, |
@@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
408 | slot->state = NOT_VALID; | 407 | slot->state = NOT_VALID; |
409 | return -EINVAL; | 408 | return -EINVAL; |
410 | } | 409 | } |
410 | |||
411 | slot->bus->max_bus_speed = get_max_bus_speed(slot); | ||
411 | return 0; | 412 | return 0; |
412 | } | 413 | } |
413 | 414 | ||
@@ -429,7 +430,6 @@ struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { | |||
429 | .get_power_status = get_power_status, | 430 | .get_power_status = get_power_status, |
430 | .get_attention_status = get_attention_status, | 431 | .get_attention_status = get_attention_status, |
431 | .get_adapter_status = get_adapter_status, | 432 | .get_adapter_status = get_adapter_status, |
432 | .get_max_bus_speed = get_max_bus_speed, | ||
433 | }; | 433 | }; |
434 | 434 | ||
435 | module_init(rpaphp_init); | 435 | module_init(rpaphp_init); |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index bd588eb8e922..d2627e1c3ac1 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -121,7 +121,7 @@ struct controller { | |||
121 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 | 121 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 |
122 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 | 122 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 |
123 | 123 | ||
124 | /* AMD PCIX bridge registers */ | 124 | /* AMD PCI-X bridge registers */ |
125 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C | 125 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C |
126 | #define PCIX_MISCII_OFFSET 0x48 | 126 | #define PCIX_MISCII_OFFSET 0x48 |
127 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 | 127 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 |
@@ -333,8 +333,6 @@ struct hpc_ops { | |||
333 | int (*set_attention_status)(struct slot *slot, u8 status); | 333 | int (*set_attention_status)(struct slot *slot, u8 status); |
334 | int (*get_latch_status)(struct slot *slot, u8 *status); | 334 | int (*get_latch_status)(struct slot *slot, u8 *status); |
335 | int (*get_adapter_status)(struct slot *slot, u8 *status); | 335 | int (*get_adapter_status)(struct slot *slot, u8 *status); |
336 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | ||
337 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | ||
338 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); | 336 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); |
339 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); | 337 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); |
340 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); | 338 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 8a520a3d0f59..a5062297f488 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -65,8 +65,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); | |||
65 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | 65 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); |
66 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | 66 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); |
67 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 67 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); |
68 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
69 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
70 | 68 | ||
71 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | 69 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { |
72 | .set_attention_status = set_attention_status, | 70 | .set_attention_status = set_attention_status, |
@@ -76,8 +74,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | |||
76 | .get_attention_status = get_attention_status, | 74 | .get_attention_status = get_attention_status, |
77 | .get_latch_status = get_latch_status, | 75 | .get_latch_status = get_latch_status, |
78 | .get_adapter_status = get_adapter_status, | 76 | .get_adapter_status = get_adapter_status, |
79 | .get_max_bus_speed = get_max_bus_speed, | ||
80 | .get_cur_bus_speed = get_cur_bus_speed, | ||
81 | }; | 77 | }; |
82 | 78 | ||
83 | /** | 79 | /** |
@@ -279,37 +275,6 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
279 | return 0; | 275 | return 0; |
280 | } | 276 | } |
281 | 277 | ||
282 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | ||
283 | enum pci_bus_speed *value) | ||
284 | { | ||
285 | struct slot *slot = get_slot(hotplug_slot); | ||
286 | int retval; | ||
287 | |||
288 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
289 | __func__, slot_name(slot)); | ||
290 | |||
291 | retval = slot->hpc_ops->get_max_bus_speed(slot, value); | ||
292 | if (retval < 0) | ||
293 | *value = PCI_SPEED_UNKNOWN; | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
299 | { | ||
300 | struct slot *slot = get_slot(hotplug_slot); | ||
301 | int retval; | ||
302 | |||
303 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
304 | __func__, slot_name(slot)); | ||
305 | |||
306 | retval = slot->hpc_ops->get_cur_bus_speed(slot, value); | ||
307 | if (retval < 0) | ||
308 | *value = PCI_SPEED_UNKNOWN; | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int is_shpc_capable(struct pci_dev *dev) | 278 | static int is_shpc_capable(struct pci_dev *dev) |
314 | { | 279 | { |
315 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == | 280 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b8ab2796e66a..3bba0c0888ff 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -285,17 +285,8 @@ static int board_added(struct slot *p_slot) | |||
285 | return WRONG_BUS_FREQUENCY; | 285 | return WRONG_BUS_FREQUENCY; |
286 | } | 286 | } |
287 | 287 | ||
288 | rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp); | 288 | bsp = ctrl->pci_dev->bus->cur_bus_speed; |
289 | if (rc) { | 289 | msp = ctrl->pci_dev->bus->max_bus_speed; |
290 | ctrl_err(ctrl, "Can't get bus operation speed\n"); | ||
291 | return WRONG_BUS_FREQUENCY; | ||
292 | } | ||
293 | |||
294 | rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp); | ||
295 | if (rc) { | ||
296 | ctrl_err(ctrl, "Can't get max bus operation speed\n"); | ||
297 | msp = bsp; | ||
298 | } | ||
299 | 290 | ||
300 | /* Check if there are other slots or devices on the same bus */ | 291 | /* Check if there are other slots or devices on the same bus */ |
301 | if (!list_empty(&ctrl->pci_dev->subordinate->devices)) | 292 | if (!list_empty(&ctrl->pci_dev->subordinate->devices)) |
@@ -462,6 +453,7 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) | |||
462 | p_slot->state = POWERON_STATE; | 453 | p_slot->state = POWERON_STATE; |
463 | break; | 454 | break; |
464 | default: | 455 | default: |
456 | kfree(info); | ||
465 | goto out; | 457 | goto out; |
466 | } | 458 | } |
467 | queue_work(shpchp_wq, &info->work); | 459 | queue_work(shpchp_wq, &info->work); |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 86dc39847769..5f5e8d2e3552 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot) | |||
660 | return retval; | 660 | return retval; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int shpc_get_cur_bus_speed(struct controller *ctrl) | ||
664 | { | ||
665 | int retval = 0; | ||
666 | struct pci_bus *bus = ctrl->pci_dev->subordinate; | ||
667 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
668 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
669 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
670 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
671 | |||
672 | if ((pi == 1) && (speed_mode > 4)) { | ||
673 | retval = -ENODEV; | ||
674 | goto out; | ||
675 | } | ||
676 | |||
677 | switch (speed_mode) { | ||
678 | case 0x0: | ||
679 | bus_speed = PCI_SPEED_33MHz; | ||
680 | break; | ||
681 | case 0x1: | ||
682 | bus_speed = PCI_SPEED_66MHz; | ||
683 | break; | ||
684 | case 0x2: | ||
685 | bus_speed = PCI_SPEED_66MHz_PCIX; | ||
686 | break; | ||
687 | case 0x3: | ||
688 | bus_speed = PCI_SPEED_100MHz_PCIX; | ||
689 | break; | ||
690 | case 0x4: | ||
691 | bus_speed = PCI_SPEED_133MHz_PCIX; | ||
692 | break; | ||
693 | case 0x5: | ||
694 | bus_speed = PCI_SPEED_66MHz_PCIX_ECC; | ||
695 | break; | ||
696 | case 0x6: | ||
697 | bus_speed = PCI_SPEED_100MHz_PCIX_ECC; | ||
698 | break; | ||
699 | case 0x7: | ||
700 | bus_speed = PCI_SPEED_133MHz_PCIX_ECC; | ||
701 | break; | ||
702 | case 0x8: | ||
703 | bus_speed = PCI_SPEED_66MHz_PCIX_266; | ||
704 | break; | ||
705 | case 0x9: | ||
706 | bus_speed = PCI_SPEED_100MHz_PCIX_266; | ||
707 | break; | ||
708 | case 0xa: | ||
709 | bus_speed = PCI_SPEED_133MHz_PCIX_266; | ||
710 | break; | ||
711 | case 0xb: | ||
712 | bus_speed = PCI_SPEED_66MHz_PCIX_533; | ||
713 | break; | ||
714 | case 0xc: | ||
715 | bus_speed = PCI_SPEED_100MHz_PCIX_533; | ||
716 | break; | ||
717 | case 0xd: | ||
718 | bus_speed = PCI_SPEED_133MHz_PCIX_533; | ||
719 | break; | ||
720 | default: | ||
721 | retval = -ENODEV; | ||
722 | break; | ||
723 | } | ||
724 | |||
725 | out: | ||
726 | bus->cur_bus_speed = bus_speed; | ||
727 | dbg("Current bus speed = %d\n", bus_speed); | ||
728 | return retval; | ||
729 | } | ||
730 | |||
731 | |||
663 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 732 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
664 | { | 733 | { |
665 | int retval; | 734 | int retval; |
@@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
720 | retval = shpc_write_cmd(slot, 0, cmd); | 789 | retval = shpc_write_cmd(slot, 0, cmd); |
721 | if (retval) | 790 | if (retval) |
722 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); | 791 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); |
792 | else | ||
793 | shpc_get_cur_bus_speed(ctrl); | ||
723 | 794 | ||
724 | return retval; | 795 | return retval; |
725 | } | 796 | } |
@@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
803 | return IRQ_HANDLED; | 874 | return IRQ_HANDLED; |
804 | } | 875 | } |
805 | 876 | ||
806 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 877 | static int shpc_get_max_bus_speed(struct controller *ctrl) |
807 | { | 878 | { |
808 | int retval = 0; | 879 | int retval = 0; |
809 | struct controller *ctrl = slot->ctrl; | 880 | struct pci_bus *bus = ctrl->pci_dev->subordinate; |
810 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 881 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
811 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | 882 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
812 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); | 883 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); |
@@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
842 | retval = -ENODEV; | 913 | retval = -ENODEV; |
843 | } | 914 | } |
844 | 915 | ||
845 | *value = bus_speed; | 916 | bus->max_bus_speed = bus_speed; |
846 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); | 917 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); |
847 | 918 | ||
848 | return retval; | 919 | return retval; |
849 | } | 920 | } |
850 | 921 | ||
851 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | ||
852 | { | ||
853 | int retval = 0; | ||
854 | struct controller *ctrl = slot->ctrl; | ||
855 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
856 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
857 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
858 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
859 | |||
860 | if ((pi == 1) && (speed_mode > 4)) { | ||
861 | *value = PCI_SPEED_UNKNOWN; | ||
862 | return -ENODEV; | ||
863 | } | ||
864 | |||
865 | switch (speed_mode) { | ||
866 | case 0x0: | ||
867 | *value = PCI_SPEED_33MHz; | ||
868 | break; | ||
869 | case 0x1: | ||
870 | *value = PCI_SPEED_66MHz; | ||
871 | break; | ||
872 | case 0x2: | ||
873 | *value = PCI_SPEED_66MHz_PCIX; | ||
874 | break; | ||
875 | case 0x3: | ||
876 | *value = PCI_SPEED_100MHz_PCIX; | ||
877 | break; | ||
878 | case 0x4: | ||
879 | *value = PCI_SPEED_133MHz_PCIX; | ||
880 | break; | ||
881 | case 0x5: | ||
882 | *value = PCI_SPEED_66MHz_PCIX_ECC; | ||
883 | break; | ||
884 | case 0x6: | ||
885 | *value = PCI_SPEED_100MHz_PCIX_ECC; | ||
886 | break; | ||
887 | case 0x7: | ||
888 | *value = PCI_SPEED_133MHz_PCIX_ECC; | ||
889 | break; | ||
890 | case 0x8: | ||
891 | *value = PCI_SPEED_66MHz_PCIX_266; | ||
892 | break; | ||
893 | case 0x9: | ||
894 | *value = PCI_SPEED_100MHz_PCIX_266; | ||
895 | break; | ||
896 | case 0xa: | ||
897 | *value = PCI_SPEED_133MHz_PCIX_266; | ||
898 | break; | ||
899 | case 0xb: | ||
900 | *value = PCI_SPEED_66MHz_PCIX_533; | ||
901 | break; | ||
902 | case 0xc: | ||
903 | *value = PCI_SPEED_100MHz_PCIX_533; | ||
904 | break; | ||
905 | case 0xd: | ||
906 | *value = PCI_SPEED_133MHz_PCIX_533; | ||
907 | break; | ||
908 | default: | ||
909 | *value = PCI_SPEED_UNKNOWN; | ||
910 | retval = -ENODEV; | ||
911 | break; | ||
912 | } | ||
913 | |||
914 | ctrl_dbg(ctrl, "Current bus speed = %d\n", bus_speed); | ||
915 | return retval; | ||
916 | } | ||
917 | |||
918 | static struct hpc_ops shpchp_hpc_ops = { | 922 | static struct hpc_ops shpchp_hpc_ops = { |
919 | .power_on_slot = hpc_power_on_slot, | 923 | .power_on_slot = hpc_power_on_slot, |
920 | .slot_enable = hpc_slot_enable, | 924 | .slot_enable = hpc_slot_enable, |
@@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
926 | .get_latch_status = hpc_get_latch_status, | 930 | .get_latch_status = hpc_get_latch_status, |
927 | .get_adapter_status = hpc_get_adapter_status, | 931 | .get_adapter_status = hpc_get_adapter_status, |
928 | 932 | ||
929 | .get_max_bus_speed = hpc_get_max_bus_speed, | ||
930 | .get_cur_bus_speed = hpc_get_cur_bus_speed, | ||
931 | .get_adapter_speed = hpc_get_adapter_speed, | 933 | .get_adapter_speed = hpc_get_adapter_speed, |
932 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, | 934 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, |
933 | .get_prog_int = hpc_get_prog_int, | 935 | .get_prog_int = hpc_get_prog_int, |
@@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1086 | } | 1088 | } |
1087 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); | 1089 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); |
1088 | 1090 | ||
1091 | shpc_get_max_bus_speed(ctrl); | ||
1092 | shpc_get_cur_bus_speed(ctrl); | ||
1093 | |||
1089 | /* | 1094 | /* |
1090 | * If this is the first controller to be initialized, | 1095 | * If this is the first controller to be initialized, |
1091 | * initialize the shpchpd work queue | 1096 | * initialize the shpchpd work queue |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 29fa9d26adae..071b7dc0094b 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -47,8 +47,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
47 | bus = pdev->subordinate; | 47 | bus = pdev->subordinate; |
48 | 48 | ||
49 | out += sprintf(buf, "Free resources: memory\n"); | 49 | out += sprintf(buf, "Free resources: memory\n"); |
50 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 50 | pci_bus_for_each_resource(bus, res, index) { |
51 | res = bus->resource[index]; | ||
52 | if (res && (res->flags & IORESOURCE_MEM) && | 51 | if (res && (res->flags & IORESOURCE_MEM) && |
53 | !(res->flags & IORESOURCE_PREFETCH)) { | 52 | !(res->flags & IORESOURCE_PREFETCH)) { |
54 | out += sprintf(out, "start = %8.8llx, " | 53 | out += sprintf(out, "start = %8.8llx, " |
@@ -58,8 +57,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
58 | } | 57 | } |
59 | } | 58 | } |
60 | out += sprintf(out, "Free resources: prefetchable memory\n"); | 59 | out += sprintf(out, "Free resources: prefetchable memory\n"); |
61 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 60 | pci_bus_for_each_resource(bus, res, index) { |
62 | res = bus->resource[index]; | ||
63 | if (res && (res->flags & IORESOURCE_MEM) && | 61 | if (res && (res->flags & IORESOURCE_MEM) && |
64 | (res->flags & IORESOURCE_PREFETCH)) { | 62 | (res->flags & IORESOURCE_PREFETCH)) { |
65 | out += sprintf(out, "start = %8.8llx, " | 63 | out += sprintf(out, "start = %8.8llx, " |
@@ -69,8 +67,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
69 | } | 67 | } |
70 | } | 68 | } |
71 | out += sprintf(out, "Free resources: IO\n"); | 69 | out += sprintf(out, "Free resources: IO\n"); |
72 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 70 | pci_bus_for_each_resource(bus, res, index) { |
73 | res = bus->resource[index]; | ||
74 | if (res && (res->flags & IORESOURCE_IO)) { | 71 | if (res && (res->flags & IORESOURCE_IO)) { |
75 | out += sprintf(out, "start = %8.8llx, " | 72 | out += sprintf(out, "start = %8.8llx, " |
76 | "length = %8.8llx\n", | 73 | "length = %8.8llx\n", |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e56f9bed6f2b..417312528ddf 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -305,7 +305,7 @@ struct device_domain_info { | |||
305 | int segment; /* PCI domain */ | 305 | int segment; /* PCI domain */ |
306 | u8 bus; /* PCI bus number */ | 306 | u8 bus; /* PCI bus number */ |
307 | u8 devfn; /* PCI devfn number */ | 307 | u8 devfn; /* PCI devfn number */ |
308 | struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ | 308 | struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */ |
309 | struct intel_iommu *iommu; /* IOMMU used by this device */ | 309 | struct intel_iommu *iommu; /* IOMMU used by this device */ |
310 | struct dmar_domain *domain; /* pointer to domain */ | 310 | struct dmar_domain *domain; /* pointer to domain */ |
311 | }; | 311 | }; |
@@ -1604,7 +1604,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, | |||
1604 | return ret; | 1604 | return ret; |
1605 | parent = parent->bus->self; | 1605 | parent = parent->bus->self; |
1606 | } | 1606 | } |
1607 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ | 1607 | if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ |
1608 | return domain_context_mapping_one(domain, | 1608 | return domain_context_mapping_one(domain, |
1609 | pci_domain_nr(tmp->subordinate), | 1609 | pci_domain_nr(tmp->subordinate), |
1610 | tmp->subordinate->number, 0, | 1610 | tmp->subordinate->number, 0, |
@@ -3325,7 +3325,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | |||
3325 | parent->devfn); | 3325 | parent->devfn); |
3326 | parent = parent->bus->self; | 3326 | parent = parent->bus->self; |
3327 | } | 3327 | } |
3328 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ | 3328 | if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ |
3329 | iommu_detach_dev(iommu, | 3329 | iommu_detach_dev(iommu, |
3330 | tmp->subordinate->number, 0); | 3330 | tmp->subordinate->number, 0); |
3331 | else /* this is a legacy PCI bridge */ | 3331 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 8b65a489581b..95b849130ad4 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -528,7 +528,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
528 | 528 | ||
529 | bridge = pci_find_upstream_pcie_bridge(dev); | 529 | bridge = pci_find_upstream_pcie_bridge(dev); |
530 | if (bridge) { | 530 | if (bridge) { |
531 | if (pci_is_pcie(bridge))/* this is a PCIE-to-PCI/PCIX bridge */ | 531 | if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */ |
532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, | 532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, |
533 | (bridge->bus->number << 8) | dev->bus->number); | 533 | (bridge->bus->number << 8) | dev->bus->number); |
534 | else /* this is a legacy PCI bridge */ | 534 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 3e0d7b5dd1b9..fb9fdf4a42bf 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c | |||
@@ -31,9 +31,9 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
31 | acpi_status status; | 31 | acpi_status status; |
32 | unsigned long long gsb; | 32 | unsigned long long gsb; |
33 | struct ioapic *ioapic; | 33 | struct ioapic *ioapic; |
34 | u64 addr; | ||
35 | int ret; | 34 | int ret; |
36 | char *type; | 35 | char *type; |
36 | struct resource *res; | ||
37 | 37 | ||
38 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | 38 | handle = DEVICE_ACPI_HANDLE(&dev->dev); |
39 | if (!handle) | 39 | if (!handle) |
@@ -69,13 +69,12 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
69 | if (pci_request_region(dev, 0, type)) | 69 | if (pci_request_region(dev, 0, type)) |
70 | goto exit_disable; | 70 | goto exit_disable; |
71 | 71 | ||
72 | addr = pci_resource_start(dev, 0); | 72 | res = &dev->resource[0]; |
73 | if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) | 73 | if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) |
74 | goto exit_release; | 74 | goto exit_release; |
75 | 75 | ||
76 | pci_set_drvdata(dev, ioapic); | 76 | pci_set_drvdata(dev, ioapic); |
77 | dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, | 77 | dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); |
78 | ioapic->gsi_base); | ||
79 | return 0; | 78 | return 0; |
80 | 79 | ||
81 | exit_release: | 80 | exit_release: |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index b2a448e19fe6..3e5ab2bf6a5c 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -706,6 +706,21 @@ irqreturn_t pci_sriov_migration(struct pci_dev *dev) | |||
706 | } | 706 | } |
707 | EXPORT_SYMBOL_GPL(pci_sriov_migration); | 707 | EXPORT_SYMBOL_GPL(pci_sriov_migration); |
708 | 708 | ||
709 | /** | ||
710 | * pci_num_vf - return number of VFs associated with a PF device_release_driver | ||
711 | * @dev: the PCI device | ||
712 | * | ||
713 | * Returns number of VFs, or 0 if SR-IOV is not enabled. | ||
714 | */ | ||
715 | int pci_num_vf(struct pci_dev *dev) | ||
716 | { | ||
717 | if (!dev || !dev->is_physfn) | ||
718 | return 0; | ||
719 | else | ||
720 | return dev->sriov->nr_virtfn; | ||
721 | } | ||
722 | EXPORT_SYMBOL_GPL(pci_num_vf); | ||
723 | |||
709 | static int ats_alloc_one(struct pci_dev *dev, int ps) | 724 | static int ats_alloc_one(struct pci_dev *dev, int ps) |
710 | { | 725 | { |
711 | int pos; | 726 | int pos; |
diff --git a/drivers/pci/legacy.c b/drivers/pci/legacy.c deleted file mode 100644 index 871f65c15936..000000000000 --- a/drivers/pci/legacy.c +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/pci.h> | ||
3 | #include <linux/module.h> | ||
4 | #include <linux/interrupt.h> | ||
5 | #include "pci.h" | ||
6 | |||
7 | /** | ||
8 | * pci_find_device - begin or continue searching for a PCI device by vendor/device id | ||
9 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | ||
10 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | ||
11 | * @from: Previous PCI device found in search, or %NULL for new search. | ||
12 | * | ||
13 | * Iterates through the list of known PCI devices. If a PCI device is found | ||
14 | * with a matching @vendor and @device, a pointer to its device structure is | ||
15 | * returned. Otherwise, %NULL is returned. | ||
16 | * A new search is initiated by passing %NULL as the @from argument. | ||
17 | * Otherwise if @from is not %NULL, searches continue from next device | ||
18 | * on the global list. | ||
19 | * | ||
20 | * NOTE: Do not use this function any more; use pci_get_device() instead, as | ||
21 | * the PCI device returned by this function can disappear at any moment in | ||
22 | * time. | ||
23 | */ | ||
24 | struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, | ||
25 | struct pci_dev *from) | ||
26 | { | ||
27 | struct pci_dev *pdev; | ||
28 | |||
29 | pci_dev_get(from); | ||
30 | pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); | ||
31 | pci_dev_put(pdev); | ||
32 | return pdev; | ||
33 | } | ||
34 | EXPORT_SYMBOL(pci_find_device); | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index cc617ddd33d0..2e7a3bf13824 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -16,8 +16,144 @@ | |||
16 | #include <acpi/acpi_bus.h> | 16 | #include <acpi/acpi_bus.h> |
17 | 17 | ||
18 | #include <linux/pci-acpi.h> | 18 | #include <linux/pci-acpi.h> |
19 | #include <linux/pm_runtime.h> | ||
19 | #include "pci.h" | 20 | #include "pci.h" |
20 | 21 | ||
22 | static DEFINE_MUTEX(pci_acpi_pm_notify_mtx); | ||
23 | |||
24 | /** | ||
25 | * pci_acpi_wake_bus - Wake-up notification handler for root buses. | ||
26 | * @handle: ACPI handle of a device the notification is for. | ||
27 | * @event: Type of the signaled event. | ||
28 | * @context: PCI root bus to wake up devices on. | ||
29 | */ | ||
30 | static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) | ||
31 | { | ||
32 | struct pci_bus *pci_bus = context; | ||
33 | |||
34 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) | ||
35 | pci_pme_wakeup_bus(pci_bus); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * pci_acpi_wake_dev - Wake-up notification handler for PCI devices. | ||
40 | * @handle: ACPI handle of a device the notification is for. | ||
41 | * @event: Type of the signaled event. | ||
42 | * @context: PCI device object to wake up. | ||
43 | */ | ||
44 | static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | ||
45 | { | ||
46 | struct pci_dev *pci_dev = context; | ||
47 | |||
48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | ||
49 | pci_check_pme_status(pci_dev); | ||
50 | pm_runtime_resume(&pci_dev->dev); | ||
51 | if (pci_dev->subordinate) | ||
52 | pci_pme_wakeup_bus(pci_dev->subordinate); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * add_pm_notifier - Register PM notifier for given ACPI device. | ||
58 | * @dev: ACPI device to add the notifier for. | ||
59 | * @context: PCI device or bus to check for PME status if an event is signaled. | ||
60 | * | ||
61 | * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of | ||
62 | * PM wake-up events. For example, wake-up events may be generated for bridges | ||
63 | * if one of the devices below the bridge is signaling PME, even if the bridge | ||
64 | * itself doesn't have a wake-up GPE associated with it. | ||
65 | */ | ||
66 | static acpi_status add_pm_notifier(struct acpi_device *dev, | ||
67 | acpi_notify_handler handler, | ||
68 | void *context) | ||
69 | { | ||
70 | acpi_status status = AE_ALREADY_EXISTS; | ||
71 | |||
72 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
73 | |||
74 | if (dev->wakeup.flags.notifier_present) | ||
75 | goto out; | ||
76 | |||
77 | status = acpi_install_notify_handler(dev->handle, | ||
78 | ACPI_SYSTEM_NOTIFY, | ||
79 | handler, context); | ||
80 | if (ACPI_FAILURE(status)) | ||
81 | goto out; | ||
82 | |||
83 | dev->wakeup.flags.notifier_present = true; | ||
84 | |||
85 | out: | ||
86 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
87 | return status; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * remove_pm_notifier - Unregister PM notifier from given ACPI device. | ||
92 | * @dev: ACPI device to remove the notifier from. | ||
93 | */ | ||
94 | static acpi_status remove_pm_notifier(struct acpi_device *dev, | ||
95 | acpi_notify_handler handler) | ||
96 | { | ||
97 | acpi_status status = AE_BAD_PARAMETER; | ||
98 | |||
99 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
100 | |||
101 | if (!dev->wakeup.flags.notifier_present) | ||
102 | goto out; | ||
103 | |||
104 | status = acpi_remove_notify_handler(dev->handle, | ||
105 | ACPI_SYSTEM_NOTIFY, | ||
106 | handler); | ||
107 | if (ACPI_FAILURE(status)) | ||
108 | goto out; | ||
109 | |||
110 | dev->wakeup.flags.notifier_present = false; | ||
111 | |||
112 | out: | ||
113 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
114 | return status; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. | ||
119 | * @dev: ACPI device to add the notifier for. | ||
120 | * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. | ||
121 | */ | ||
122 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | ||
123 | struct pci_bus *pci_bus) | ||
124 | { | ||
125 | return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier. | ||
130 | * @dev: ACPI device to remove the notifier from. | ||
131 | */ | ||
132 | acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | ||
133 | { | ||
134 | return remove_pm_notifier(dev, pci_acpi_wake_bus); | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * pci_acpi_add_pm_notifier - Register PM notifier for given PCI device. | ||
139 | * @dev: ACPI device to add the notifier for. | ||
140 | * @pci_dev: PCI device to check for the PME status if an event is signaled. | ||
141 | */ | ||
142 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | ||
143 | struct pci_dev *pci_dev) | ||
144 | { | ||
145 | return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier. | ||
150 | * @dev: ACPI device to remove the notifier from. | ||
151 | */ | ||
152 | acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | ||
153 | { | ||
154 | return remove_pm_notifier(dev, pci_acpi_wake_dev); | ||
155 | } | ||
156 | |||
21 | /* | 157 | /* |
22 | * _SxD returns the D-state with the highest power | 158 | * _SxD returns the D-state with the highest power |
23 | * (lowest D-state number) supported in the S-state "x". | 159 | * (lowest D-state number) supported in the S-state "x". |
@@ -112,11 +248,7 @@ static bool acpi_pci_can_wakeup(struct pci_dev *dev) | |||
112 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | 248 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) |
113 | { | 249 | { |
114 | while (bus->parent) { | 250 | while (bus->parent) { |
115 | struct pci_dev *bridge = bus->self; | 251 | if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable)) |
116 | int ret; | ||
117 | |||
118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); | ||
119 | if (!ret || pci_is_pcie(bridge)) | ||
120 | return; | 252 | return; |
121 | bus = bus->parent; | 253 | bus = bus->parent; |
122 | } | 254 | } |
@@ -131,9 +263,81 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
131 | if (acpi_pci_can_wakeup(dev)) | 263 | if (acpi_pci_can_wakeup(dev)) |
132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | 264 | return acpi_pm_device_sleep_wake(&dev->dev, enable); |
133 | 265 | ||
134 | if (!pci_is_pcie(dev)) | 266 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); |
135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); | 267 | return 0; |
268 | } | ||
269 | |||
270 | /** | ||
271 | * acpi_dev_run_wake - Enable/disable wake-up for given device. | ||
272 | * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||
273 | * @enable: Whether enable or disable the wake-up functionality. | ||
274 | * | ||
275 | * Find the ACPI device object corresponding to @pci_dev and try to | ||
276 | * enable/disable the GPE associated with it. | ||
277 | */ | ||
278 | static int acpi_dev_run_wake(struct device *phys_dev, bool enable) | ||
279 | { | ||
280 | struct acpi_device *dev; | ||
281 | acpi_handle handle; | ||
282 | int error = -ENODEV; | ||
283 | |||
284 | if (!device_run_wake(phys_dev)) | ||
285 | return -EINVAL; | ||
286 | |||
287 | handle = DEVICE_ACPI_HANDLE(phys_dev); | ||
288 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||
289 | dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||
290 | __func__); | ||
291 | return -ENODEV; | ||
292 | } | ||
293 | |||
294 | if (enable) { | ||
295 | if (!dev->wakeup.run_wake_count++) { | ||
296 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||
297 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
298 | dev->wakeup.gpe_number, | ||
299 | ACPI_GPE_TYPE_RUNTIME); | ||
300 | } | ||
301 | } else if (dev->wakeup.run_wake_count > 0) { | ||
302 | if (!--dev->wakeup.run_wake_count) { | ||
303 | acpi_disable_gpe(dev->wakeup.gpe_device, | ||
304 | dev->wakeup.gpe_number, | ||
305 | ACPI_GPE_TYPE_RUNTIME); | ||
306 | acpi_disable_wakeup_device_power(dev); | ||
307 | } | ||
308 | } else { | ||
309 | error = -EALREADY; | ||
310 | } | ||
311 | |||
312 | return error; | ||
313 | } | ||
314 | |||
315 | static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | ||
316 | { | ||
317 | while (bus->parent) { | ||
318 | struct pci_dev *bridge = bus->self; | ||
319 | |||
320 | if (bridge->pme_interrupt) | ||
321 | return; | ||
322 | if (!acpi_dev_run_wake(&bridge->dev, enable)) | ||
323 | return; | ||
324 | bus = bus->parent; | ||
325 | } | ||
326 | |||
327 | /* We have reached the root bus. */ | ||
328 | if (bus->bridge) | ||
329 | acpi_dev_run_wake(bus->bridge, enable); | ||
330 | } | ||
331 | |||
332 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | ||
333 | { | ||
334 | if (dev->pme_interrupt) | ||
335 | return 0; | ||
336 | |||
337 | if (!acpi_dev_run_wake(&dev->dev, enable)) | ||
338 | return 0; | ||
136 | 339 | ||
340 | acpi_pci_propagate_run_wake(dev->bus, enable); | ||
137 | return 0; | 341 | return 0; |
138 | } | 342 | } |
139 | 343 | ||
@@ -143,13 +347,14 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
143 | .choose_state = acpi_pci_choose_state, | 347 | .choose_state = acpi_pci_choose_state, |
144 | .can_wakeup = acpi_pci_can_wakeup, | 348 | .can_wakeup = acpi_pci_can_wakeup, |
145 | .sleep_wake = acpi_pci_sleep_wake, | 349 | .sleep_wake = acpi_pci_sleep_wake, |
350 | .run_wake = acpi_pci_run_wake, | ||
146 | }; | 351 | }; |
147 | 352 | ||
148 | /* ACPI bus type */ | 353 | /* ACPI bus type */ |
149 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | 354 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) |
150 | { | 355 | { |
151 | struct pci_dev * pci_dev; | 356 | struct pci_dev * pci_dev; |
152 | acpi_integer addr; | 357 | u64 addr; |
153 | 358 | ||
154 | pci_dev = to_pci_dev(dev); | 359 | pci_dev = to_pci_dev(dev); |
155 | /* Please ref to ACPI spec for the syntax of _ADR */ | 360 | /* Please ref to ACPI spec for the syntax of _ADR */ |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e5d47be3c6d7..f9a0aec3abcf 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -17,6 +17,7 @@ | |||
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 <linux/cpu.h> |
20 | #include <linux/pm_runtime.h> | ||
20 | #include "pci.h" | 21 | #include "pci.h" |
21 | 22 | ||
22 | struct pci_dynid { | 23 | struct pci_dynid { |
@@ -404,6 +405,35 @@ static void pci_device_shutdown(struct device *dev) | |||
404 | pci_msix_shutdown(pci_dev); | 405 | pci_msix_shutdown(pci_dev); |
405 | } | 406 | } |
406 | 407 | ||
408 | #ifdef CONFIG_PM_OPS | ||
409 | |||
410 | /* Auxiliary functions used for system resume and run-time resume. */ | ||
411 | |||
412 | /** | ||
413 | * pci_restore_standard_config - restore standard config registers of PCI device | ||
414 | * @pci_dev: PCI device to handle | ||
415 | */ | ||
416 | static int pci_restore_standard_config(struct pci_dev *pci_dev) | ||
417 | { | ||
418 | pci_update_current_state(pci_dev, PCI_UNKNOWN); | ||
419 | |||
420 | if (pci_dev->current_state != PCI_D0) { | ||
421 | int error = pci_set_power_state(pci_dev, PCI_D0); | ||
422 | if (error) | ||
423 | return error; | ||
424 | } | ||
425 | |||
426 | return pci_restore_state(pci_dev); | ||
427 | } | ||
428 | |||
429 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) | ||
430 | { | ||
431 | pci_restore_standard_config(pci_dev); | ||
432 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
433 | } | ||
434 | |||
435 | #endif | ||
436 | |||
407 | #ifdef CONFIG_PM_SLEEP | 437 | #ifdef CONFIG_PM_SLEEP |
408 | 438 | ||
409 | /* | 439 | /* |
@@ -520,29 +550,6 @@ static int pci_legacy_resume(struct device *dev) | |||
520 | 550 | ||
521 | /* Auxiliary functions used by the new power management framework */ | 551 | /* Auxiliary functions used by the new power management framework */ |
522 | 552 | ||
523 | /** | ||
524 | * pci_restore_standard_config - restore standard config registers of PCI device | ||
525 | * @pci_dev: PCI device to handle | ||
526 | */ | ||
527 | static int pci_restore_standard_config(struct pci_dev *pci_dev) | ||
528 | { | ||
529 | pci_update_current_state(pci_dev, PCI_UNKNOWN); | ||
530 | |||
531 | if (pci_dev->current_state != PCI_D0) { | ||
532 | int error = pci_set_power_state(pci_dev, PCI_D0); | ||
533 | if (error) | ||
534 | return error; | ||
535 | } | ||
536 | |||
537 | return pci_restore_state(pci_dev); | ||
538 | } | ||
539 | |||
540 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) | ||
541 | { | ||
542 | pci_restore_standard_config(pci_dev); | ||
543 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
544 | } | ||
545 | |||
546 | static void pci_pm_default_resume(struct pci_dev *pci_dev) | 553 | static void pci_pm_default_resume(struct pci_dev *pci_dev) |
547 | { | 554 | { |
548 | pci_fixup_device(pci_fixup_resume, pci_dev); | 555 | pci_fixup_device(pci_fixup_resume, pci_dev); |
@@ -581,6 +588,17 @@ static int pci_pm_prepare(struct device *dev) | |||
581 | struct device_driver *drv = dev->driver; | 588 | struct device_driver *drv = dev->driver; |
582 | int error = 0; | 589 | int error = 0; |
583 | 590 | ||
591 | /* | ||
592 | * PCI devices suspended at run time need to be resumed at this | ||
593 | * point, because in general it is necessary to reconfigure them for | ||
594 | * system suspend. Namely, if the device is supposed to wake up the | ||
595 | * system from the sleep state, we may need to reconfigure it for this | ||
596 | * purpose. In turn, if the device is not supposed to wake up the | ||
597 | * system from the sleep state, we'll have to prevent it from signaling | ||
598 | * wake-up. | ||
599 | */ | ||
600 | pm_runtime_resume(dev); | ||
601 | |||
584 | if (drv && drv->pm && drv->pm->prepare) | 602 | if (drv && drv->pm && drv->pm->prepare) |
585 | error = drv->pm->prepare(dev); | 603 | error = drv->pm->prepare(dev); |
586 | 604 | ||
@@ -595,6 +613,13 @@ static void pci_pm_complete(struct device *dev) | |||
595 | drv->pm->complete(dev); | 613 | drv->pm->complete(dev); |
596 | } | 614 | } |
597 | 615 | ||
616 | #else /* !CONFIG_PM_SLEEP */ | ||
617 | |||
618 | #define pci_pm_prepare NULL | ||
619 | #define pci_pm_complete NULL | ||
620 | |||
621 | #endif /* !CONFIG_PM_SLEEP */ | ||
622 | |||
598 | #ifdef CONFIG_SUSPEND | 623 | #ifdef CONFIG_SUSPEND |
599 | 624 | ||
600 | static int pci_pm_suspend(struct device *dev) | 625 | static int pci_pm_suspend(struct device *dev) |
@@ -681,7 +706,7 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
681 | struct device_driver *drv = dev->driver; | 706 | struct device_driver *drv = dev->driver; |
682 | int error = 0; | 707 | int error = 0; |
683 | 708 | ||
684 | pci_pm_default_resume_noirq(pci_dev); | 709 | pci_pm_default_resume_early(pci_dev); |
685 | 710 | ||
686 | if (pci_has_legacy_pm_support(pci_dev)) | 711 | if (pci_has_legacy_pm_support(pci_dev)) |
687 | return pci_legacy_resume_early(dev); | 712 | return pci_legacy_resume_early(dev); |
@@ -879,7 +904,7 @@ static int pci_pm_restore_noirq(struct device *dev) | |||
879 | struct device_driver *drv = dev->driver; | 904 | struct device_driver *drv = dev->driver; |
880 | int error = 0; | 905 | int error = 0; |
881 | 906 | ||
882 | pci_pm_default_resume_noirq(pci_dev); | 907 | pci_pm_default_resume_early(pci_dev); |
883 | 908 | ||
884 | if (pci_has_legacy_pm_support(pci_dev)) | 909 | if (pci_has_legacy_pm_support(pci_dev)) |
885 | return pci_legacy_resume_early(dev); | 910 | return pci_legacy_resume_early(dev); |
@@ -931,6 +956,84 @@ static int pci_pm_restore(struct device *dev) | |||
931 | 956 | ||
932 | #endif /* !CONFIG_HIBERNATION */ | 957 | #endif /* !CONFIG_HIBERNATION */ |
933 | 958 | ||
959 | #ifdef CONFIG_PM_RUNTIME | ||
960 | |||
961 | static int pci_pm_runtime_suspend(struct device *dev) | ||
962 | { | ||
963 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
964 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
965 | pci_power_t prev = pci_dev->current_state; | ||
966 | int error; | ||
967 | |||
968 | if (!pm || !pm->runtime_suspend) | ||
969 | return -ENOSYS; | ||
970 | |||
971 | error = pm->runtime_suspend(dev); | ||
972 | suspend_report_result(pm->runtime_suspend, error); | ||
973 | if (error) | ||
974 | return error; | ||
975 | |||
976 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
977 | |||
978 | if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 | ||
979 | && pci_dev->current_state != PCI_UNKNOWN) { | ||
980 | WARN_ONCE(pci_dev->current_state != prev, | ||
981 | "PCI PM: State of device not saved by %pF\n", | ||
982 | pm->runtime_suspend); | ||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | if (!pci_dev->state_saved) | ||
987 | pci_save_state(pci_dev); | ||
988 | |||
989 | pci_finish_runtime_suspend(pci_dev); | ||
990 | |||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | static int pci_pm_runtime_resume(struct device *dev) | ||
995 | { | ||
996 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
997 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
998 | |||
999 | if (!pm || !pm->runtime_resume) | ||
1000 | return -ENOSYS; | ||
1001 | |||
1002 | pci_pm_default_resume_early(pci_dev); | ||
1003 | __pci_enable_wake(pci_dev, PCI_D0, true, false); | ||
1004 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
1005 | |||
1006 | return pm->runtime_resume(dev); | ||
1007 | } | ||
1008 | |||
1009 | static int pci_pm_runtime_idle(struct device *dev) | ||
1010 | { | ||
1011 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
1012 | |||
1013 | if (!pm) | ||
1014 | return -ENOSYS; | ||
1015 | |||
1016 | if (pm->runtime_idle) { | ||
1017 | int ret = pm->runtime_idle(dev); | ||
1018 | if (ret) | ||
1019 | return ret; | ||
1020 | } | ||
1021 | |||
1022 | pm_runtime_suspend(dev); | ||
1023 | |||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1027 | #else /* !CONFIG_PM_RUNTIME */ | ||
1028 | |||
1029 | #define pci_pm_runtime_suspend NULL | ||
1030 | #define pci_pm_runtime_resume NULL | ||
1031 | #define pci_pm_runtime_idle NULL | ||
1032 | |||
1033 | #endif /* !CONFIG_PM_RUNTIME */ | ||
1034 | |||
1035 | #ifdef CONFIG_PM_OPS | ||
1036 | |||
934 | const struct dev_pm_ops pci_dev_pm_ops = { | 1037 | const struct dev_pm_ops pci_dev_pm_ops = { |
935 | .prepare = pci_pm_prepare, | 1038 | .prepare = pci_pm_prepare, |
936 | .complete = pci_pm_complete, | 1039 | .complete = pci_pm_complete, |
@@ -946,15 +1049,18 @@ const struct dev_pm_ops pci_dev_pm_ops = { | |||
946 | .thaw_noirq = pci_pm_thaw_noirq, | 1049 | .thaw_noirq = pci_pm_thaw_noirq, |
947 | .poweroff_noirq = pci_pm_poweroff_noirq, | 1050 | .poweroff_noirq = pci_pm_poweroff_noirq, |
948 | .restore_noirq = pci_pm_restore_noirq, | 1051 | .restore_noirq = pci_pm_restore_noirq, |
1052 | .runtime_suspend = pci_pm_runtime_suspend, | ||
1053 | .runtime_resume = pci_pm_runtime_resume, | ||
1054 | .runtime_idle = pci_pm_runtime_idle, | ||
949 | }; | 1055 | }; |
950 | 1056 | ||
951 | #define PCI_PM_OPS_PTR (&pci_dev_pm_ops) | 1057 | #define PCI_PM_OPS_PTR (&pci_dev_pm_ops) |
952 | 1058 | ||
953 | #else /* !CONFIG_PM_SLEEP */ | 1059 | #else /* !COMFIG_PM_OPS */ |
954 | 1060 | ||
955 | #define PCI_PM_OPS_PTR NULL | 1061 | #define PCI_PM_OPS_PTR NULL |
956 | 1062 | ||
957 | #endif /* !CONFIG_PM_SLEEP */ | 1063 | #endif /* !COMFIG_PM_OPS */ |
958 | 1064 | ||
959 | /** | 1065 | /** |
960 | * __pci_register_driver - register a new pci driver | 1066 | * __pci_register_driver - register a new pci driver |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index c5df94e86678..997668558e79 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -75,7 +75,8 @@ static ssize_t local_cpus_show(struct device *dev, | |||
75 | int len; | 75 | int len; |
76 | 76 | ||
77 | #ifdef CONFIG_NUMA | 77 | #ifdef CONFIG_NUMA |
78 | mask = cpumask_of_node(dev_to_node(dev)); | 78 | mask = (dev_to_node(dev) == -1) ? cpu_online_mask : |
79 | cpumask_of_node(dev_to_node(dev)); | ||
79 | #else | 80 | #else |
80 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 81 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
81 | #endif | 82 | #endif |
@@ -93,7 +94,8 @@ static ssize_t local_cpulist_show(struct device *dev, | |||
93 | int len; | 94 | int len; |
94 | 95 | ||
95 | #ifdef CONFIG_NUMA | 96 | #ifdef CONFIG_NUMA |
96 | mask = cpumask_of_node(dev_to_node(dev)); | 97 | mask = (dev_to_node(dev) == -1) ? cpu_online_mask : |
98 | cpumask_of_node(dev_to_node(dev)); | ||
97 | #else | 99 | #else |
98 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 100 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
99 | #endif | 101 | #endif |
@@ -640,6 +642,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
640 | if (!b->legacy_io) | 642 | if (!b->legacy_io) |
641 | goto kzalloc_err; | 643 | goto kzalloc_err; |
642 | 644 | ||
645 | sysfs_bin_attr_init(b->legacy_io); | ||
643 | b->legacy_io->attr.name = "legacy_io"; | 646 | b->legacy_io->attr.name = "legacy_io"; |
644 | b->legacy_io->size = 0xffff; | 647 | b->legacy_io->size = 0xffff; |
645 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | 648 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; |
@@ -653,6 +656,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
653 | 656 | ||
654 | /* Allocated above after the legacy_io struct */ | 657 | /* Allocated above after the legacy_io struct */ |
655 | b->legacy_mem = b->legacy_io + 1; | 658 | b->legacy_mem = b->legacy_io + 1; |
659 | sysfs_bin_attr_init(b->legacy_mem); | ||
656 | b->legacy_mem->attr.name = "legacy_mem"; | 660 | b->legacy_mem->attr.name = "legacy_mem"; |
657 | b->legacy_mem->size = 1024*1024; | 661 | b->legacy_mem->size = 1024*1024; |
658 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | 662 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; |
@@ -798,6 +802,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | |||
798 | if (res_attr) { | 802 | if (res_attr) { |
799 | char *res_attr_name = (char *)(res_attr + 1); | 803 | char *res_attr_name = (char *)(res_attr + 1); |
800 | 804 | ||
805 | sysfs_bin_attr_init(res_attr); | ||
801 | if (write_combine) { | 806 | if (write_combine) { |
802 | pdev->res_attr_wc[num] = res_attr; | 807 | pdev->res_attr_wc[num] = res_attr; |
803 | sprintf(res_attr_name, "resource%d_wc", num); | 808 | sprintf(res_attr_name, "resource%d_wc", num); |
@@ -970,6 +975,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) | |||
970 | if (!attr) | 975 | if (!attr) |
971 | return -ENOMEM; | 976 | return -ENOMEM; |
972 | 977 | ||
978 | sysfs_bin_attr_init(attr); | ||
973 | attr->size = dev->vpd->len; | 979 | attr->size = dev->vpd->len; |
974 | attr->attr.name = "vpd"; | 980 | attr->attr.name = "vpd"; |
975 | attr->attr.mode = S_IRUSR | S_IWUSR; | 981 | attr->attr.mode = S_IRUSR | S_IWUSR; |
@@ -1036,6 +1042,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
1036 | retval = -ENOMEM; | 1042 | retval = -ENOMEM; |
1037 | goto err_resource_files; | 1043 | goto err_resource_files; |
1038 | } | 1044 | } |
1045 | sysfs_bin_attr_init(attr); | ||
1039 | attr->size = rom_size; | 1046 | attr->size = rom_size; |
1040 | attr->attr.name = "rom"; | 1047 | attr->attr.name = "rom"; |
1041 | attr->attr.mode = S_IRUSR; | 1048 | attr->attr.mode = S_IRUSR; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0bc27e059019..1531f3a49879 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/pci-aspm.h> | 19 | #include <linux/pci-aspm.h> |
20 | #include <linux/pm_wakeup.h> | 20 | #include <linux/pm_wakeup.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | ||
23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/pm_runtime.h> | ||
24 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
25 | #include "pci.h" | 25 | #include "pci.h" |
26 | 26 | ||
@@ -29,7 +29,23 @@ const char *pci_power_names[] = { | |||
29 | }; | 29 | }; |
30 | EXPORT_SYMBOL_GPL(pci_power_names); | 30 | EXPORT_SYMBOL_GPL(pci_power_names); |
31 | 31 | ||
32 | unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; | 32 | int isa_dma_bridge_buggy; |
33 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
34 | |||
35 | int pci_pci_problems; | ||
36 | EXPORT_SYMBOL(pci_pci_problems); | ||
37 | |||
38 | unsigned int pci_pm_d3_delay; | ||
39 | |||
40 | static void pci_dev_d3_sleep(struct pci_dev *dev) | ||
41 | { | ||
42 | unsigned int delay = dev->d3_delay; | ||
43 | |||
44 | if (delay < pci_pm_d3_delay) | ||
45 | delay = pci_pm_d3_delay; | ||
46 | |||
47 | msleep(delay); | ||
48 | } | ||
33 | 49 | ||
34 | #ifdef CONFIG_PCI_DOMAINS | 50 | #ifdef CONFIG_PCI_DOMAINS |
35 | int pci_domains_supported = 1; | 51 | int pci_domains_supported = 1; |
@@ -287,6 +303,49 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) | |||
287 | } | 303 | } |
288 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 304 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); |
289 | 305 | ||
306 | /** | ||
307 | * pci_bus_find_ext_capability - find an extended capability | ||
308 | * @bus: the PCI bus to query | ||
309 | * @devfn: PCI device to query | ||
310 | * @cap: capability code | ||
311 | * | ||
312 | * Like pci_find_ext_capability() but works for pci devices that do not have a | ||
313 | * pci_dev structure set up yet. | ||
314 | * | ||
315 | * Returns the address of the requested capability structure within the | ||
316 | * device's PCI configuration space or 0 in case the device does not | ||
317 | * support it. | ||
318 | */ | ||
319 | int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn, | ||
320 | int cap) | ||
321 | { | ||
322 | u32 header; | ||
323 | int ttl; | ||
324 | int pos = PCI_CFG_SPACE_SIZE; | ||
325 | |||
326 | /* minimum 8 bytes per capability */ | ||
327 | ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; | ||
328 | |||
329 | if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) | ||
330 | return 0; | ||
331 | if (header == 0xffffffff || header == 0) | ||
332 | return 0; | ||
333 | |||
334 | while (ttl-- > 0) { | ||
335 | if (PCI_EXT_CAP_ID(header) == cap) | ||
336 | return pos; | ||
337 | |||
338 | pos = PCI_EXT_CAP_NEXT(header); | ||
339 | if (pos < PCI_CFG_SPACE_SIZE) | ||
340 | break; | ||
341 | |||
342 | if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
290 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | 349 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) |
291 | { | 350 | { |
292 | int rc, ttl = PCI_FIND_CAP_TTL; | 351 | int rc, ttl = PCI_FIND_CAP_TTL; |
@@ -370,10 +429,9 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
370 | { | 429 | { |
371 | const struct pci_bus *bus = dev->bus; | 430 | const struct pci_bus *bus = dev->bus; |
372 | int i; | 431 | int i; |
373 | struct resource *best = NULL; | 432 | struct resource *best = NULL, *r; |
374 | 433 | ||
375 | for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 434 | pci_bus_for_each_resource(bus, r, i) { |
376 | struct resource *r = bus->resource[i]; | ||
377 | if (!r) | 435 | if (!r) |
378 | continue; | 436 | continue; |
379 | if (res->start && !(res->start >= r->start && res->end <= r->end)) | 437 | if (res->start && !(res->start >= r->start && res->end <= r->end)) |
@@ -447,6 +505,12 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
447 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; | 505 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; |
448 | } | 506 | } |
449 | 507 | ||
508 | static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | ||
509 | { | ||
510 | return pci_platform_pm ? | ||
511 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | ||
512 | } | ||
513 | |||
450 | /** | 514 | /** |
451 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of | 515 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of |
452 | * given PCI device | 516 | * given PCI device |
@@ -522,7 +586,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
522 | /* Mandatory power management transition delays */ | 586 | /* Mandatory power management transition delays */ |
523 | /* see PCI PM 1.1 5.6.1 table 18 */ | 587 | /* see PCI PM 1.1 5.6.1 table 18 */ |
524 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) | 588 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) |
525 | msleep(pci_pm_d3_delay); | 589 | pci_dev_d3_sleep(dev); |
526 | else if (state == PCI_D2 || dev->current_state == PCI_D2) | 590 | else if (state == PCI_D2 || dev->current_state == PCI_D2) |
527 | udelay(PCI_PM_D2_DELAY); | 591 | udelay(PCI_PM_D2_DELAY); |
528 | 592 | ||
@@ -1153,11 +1217,11 @@ pci_disable_device(struct pci_dev *dev) | |||
1153 | 1217 | ||
1154 | /** | 1218 | /** |
1155 | * pcibios_set_pcie_reset_state - set reset state for device dev | 1219 | * pcibios_set_pcie_reset_state - set reset state for device dev |
1156 | * @dev: the PCI-E device reset | 1220 | * @dev: the PCIe device reset |
1157 | * @state: Reset state to enter into | 1221 | * @state: Reset state to enter into |
1158 | * | 1222 | * |
1159 | * | 1223 | * |
1160 | * Sets the PCI-E reset state for the device. This is the default | 1224 | * Sets the PCIe reset state for the device. This is the default |
1161 | * implementation. Architecture implementations can override this. | 1225 | * implementation. Architecture implementations can override this. |
1162 | */ | 1226 | */ |
1163 | int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, | 1227 | int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, |
@@ -1168,7 +1232,7 @@ int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, | |||
1168 | 1232 | ||
1169 | /** | 1233 | /** |
1170 | * pci_set_pcie_reset_state - set reset state for device dev | 1234 | * pci_set_pcie_reset_state - set reset state for device dev |
1171 | * @dev: the PCI-E device reset | 1235 | * @dev: the PCIe device reset |
1172 | * @state: Reset state to enter into | 1236 | * @state: Reset state to enter into |
1173 | * | 1237 | * |
1174 | * | 1238 | * |
@@ -1180,6 +1244,66 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) | |||
1180 | } | 1244 | } |
1181 | 1245 | ||
1182 | /** | 1246 | /** |
1247 | * pci_check_pme_status - Check if given device has generated PME. | ||
1248 | * @dev: Device to check. | ||
1249 | * | ||
1250 | * Check the PME status of the device and if set, clear it and clear PME enable | ||
1251 | * (if set). Return 'true' if PME status and PME enable were both set or | ||
1252 | * 'false' otherwise. | ||
1253 | */ | ||
1254 | bool pci_check_pme_status(struct pci_dev *dev) | ||
1255 | { | ||
1256 | int pmcsr_pos; | ||
1257 | u16 pmcsr; | ||
1258 | bool ret = false; | ||
1259 | |||
1260 | if (!dev->pm_cap) | ||
1261 | return false; | ||
1262 | |||
1263 | pmcsr_pos = dev->pm_cap + PCI_PM_CTRL; | ||
1264 | pci_read_config_word(dev, pmcsr_pos, &pmcsr); | ||
1265 | if (!(pmcsr & PCI_PM_CTRL_PME_STATUS)) | ||
1266 | return false; | ||
1267 | |||
1268 | /* Clear PME status. */ | ||
1269 | pmcsr |= PCI_PM_CTRL_PME_STATUS; | ||
1270 | if (pmcsr & PCI_PM_CTRL_PME_ENABLE) { | ||
1271 | /* Disable PME to avoid interrupt flood. */ | ||
1272 | pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; | ||
1273 | ret = true; | ||
1274 | } | ||
1275 | |||
1276 | pci_write_config_word(dev, pmcsr_pos, pmcsr); | ||
1277 | |||
1278 | return ret; | ||
1279 | } | ||
1280 | |||
1281 | /** | ||
1282 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | ||
1283 | * @dev: Device to handle. | ||
1284 | * @ign: Ignored. | ||
1285 | * | ||
1286 | * Check if @dev has generated PME and queue a resume request for it in that | ||
1287 | * case. | ||
1288 | */ | ||
1289 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | ||
1290 | { | ||
1291 | if (pci_check_pme_status(dev)) | ||
1292 | pm_request_resume(&dev->dev); | ||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | /** | ||
1297 | * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary. | ||
1298 | * @bus: Top bus of the subtree to walk. | ||
1299 | */ | ||
1300 | void pci_pme_wakeup_bus(struct pci_bus *bus) | ||
1301 | { | ||
1302 | if (bus) | ||
1303 | pci_walk_bus(bus, pci_pme_wakeup, NULL); | ||
1304 | } | ||
1305 | |||
1306 | /** | ||
1183 | * pci_pme_capable - check the capability of PCI device to generate PME# | 1307 | * pci_pme_capable - check the capability of PCI device to generate PME# |
1184 | * @dev: PCI device to handle. | 1308 | * @dev: PCI device to handle. |
1185 | * @state: PCI state from which device will issue PME#. | 1309 | * @state: PCI state from which device will issue PME#. |
@@ -1220,9 +1344,10 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1220 | } | 1344 | } |
1221 | 1345 | ||
1222 | /** | 1346 | /** |
1223 | * pci_enable_wake - enable PCI device as wakeup event source | 1347 | * __pci_enable_wake - enable PCI device as wakeup event source |
1224 | * @dev: PCI device affected | 1348 | * @dev: PCI device affected |
1225 | * @state: PCI state from which device will issue wakeup events | 1349 | * @state: PCI state from which device will issue wakeup events |
1350 | * @runtime: True if the events are to be generated at run time | ||
1226 | * @enable: True to enable event generation; false to disable | 1351 | * @enable: True to enable event generation; false to disable |
1227 | * | 1352 | * |
1228 | * This enables the device as a wakeup event source, or disables it. | 1353 | * This enables the device as a wakeup event source, or disables it. |
@@ -1238,11 +1363,12 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1238 | * Error code depending on the platform is returned if both the platform and | 1363 | * Error code depending on the platform is returned if both the platform and |
1239 | * the native mechanism fail to enable the generation of wake-up events | 1364 | * the native mechanism fail to enable the generation of wake-up events |
1240 | */ | 1365 | */ |
1241 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | 1366 | int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, |
1367 | bool runtime, bool enable) | ||
1242 | { | 1368 | { |
1243 | int ret = 0; | 1369 | int ret = 0; |
1244 | 1370 | ||
1245 | if (enable && !device_may_wakeup(&dev->dev)) | 1371 | if (enable && !runtime && !device_may_wakeup(&dev->dev)) |
1246 | return -EINVAL; | 1372 | return -EINVAL; |
1247 | 1373 | ||
1248 | /* Don't do the same thing twice in a row for one device. */ | 1374 | /* Don't do the same thing twice in a row for one device. */ |
@@ -1262,19 +1388,24 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | |||
1262 | pci_pme_active(dev, true); | 1388 | pci_pme_active(dev, true); |
1263 | else | 1389 | else |
1264 | ret = 1; | 1390 | ret = 1; |
1265 | error = platform_pci_sleep_wake(dev, true); | 1391 | error = runtime ? platform_pci_run_wake(dev, true) : |
1392 | platform_pci_sleep_wake(dev, true); | ||
1266 | if (ret) | 1393 | if (ret) |
1267 | ret = error; | 1394 | ret = error; |
1268 | if (!ret) | 1395 | if (!ret) |
1269 | dev->wakeup_prepared = true; | 1396 | dev->wakeup_prepared = true; |
1270 | } else { | 1397 | } else { |
1271 | platform_pci_sleep_wake(dev, false); | 1398 | if (runtime) |
1399 | platform_pci_run_wake(dev, false); | ||
1400 | else | ||
1401 | platform_pci_sleep_wake(dev, false); | ||
1272 | pci_pme_active(dev, false); | 1402 | pci_pme_active(dev, false); |
1273 | dev->wakeup_prepared = false; | 1403 | dev->wakeup_prepared = false; |
1274 | } | 1404 | } |
1275 | 1405 | ||
1276 | return ret; | 1406 | return ret; |
1277 | } | 1407 | } |
1408 | EXPORT_SYMBOL(__pci_enable_wake); | ||
1278 | 1409 | ||
1279 | /** | 1410 | /** |
1280 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold | 1411 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold |
@@ -1384,6 +1515,66 @@ int pci_back_from_sleep(struct pci_dev *dev) | |||
1384 | } | 1515 | } |
1385 | 1516 | ||
1386 | /** | 1517 | /** |
1518 | * pci_finish_runtime_suspend - Carry out PCI-specific part of runtime suspend. | ||
1519 | * @dev: PCI device being suspended. | ||
1520 | * | ||
1521 | * Prepare @dev to generate wake-up events at run time and put it into a low | ||
1522 | * power state. | ||
1523 | */ | ||
1524 | int pci_finish_runtime_suspend(struct pci_dev *dev) | ||
1525 | { | ||
1526 | pci_power_t target_state = pci_target_state(dev); | ||
1527 | int error; | ||
1528 | |||
1529 | if (target_state == PCI_POWER_ERROR) | ||
1530 | return -EIO; | ||
1531 | |||
1532 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); | ||
1533 | |||
1534 | error = pci_set_power_state(dev, target_state); | ||
1535 | |||
1536 | if (error) | ||
1537 | __pci_enable_wake(dev, target_state, true, false); | ||
1538 | |||
1539 | return error; | ||
1540 | } | ||
1541 | |||
1542 | /** | ||
1543 | * pci_dev_run_wake - Check if device can generate run-time wake-up events. | ||
1544 | * @dev: Device to check. | ||
1545 | * | ||
1546 | * Return true if the device itself is cabable of generating wake-up events | ||
1547 | * (through the platform or using the native PCIe PME) or if the device supports | ||
1548 | * PME and one of its upstream bridges can generate wake-up events. | ||
1549 | */ | ||
1550 | bool pci_dev_run_wake(struct pci_dev *dev) | ||
1551 | { | ||
1552 | struct pci_bus *bus = dev->bus; | ||
1553 | |||
1554 | if (device_run_wake(&dev->dev)) | ||
1555 | return true; | ||
1556 | |||
1557 | if (!dev->pme_support) | ||
1558 | return false; | ||
1559 | |||
1560 | while (bus->parent) { | ||
1561 | struct pci_dev *bridge = bus->self; | ||
1562 | |||
1563 | if (device_run_wake(&bridge->dev)) | ||
1564 | return true; | ||
1565 | |||
1566 | bus = bus->parent; | ||
1567 | } | ||
1568 | |||
1569 | /* We have reached the root bus. */ | ||
1570 | if (bus->bridge) | ||
1571 | return device_run_wake(bus->bridge); | ||
1572 | |||
1573 | return false; | ||
1574 | } | ||
1575 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | ||
1576 | |||
1577 | /** | ||
1387 | * pci_pm_init - Initialize PM functions of given PCI device | 1578 | * pci_pm_init - Initialize PM functions of given PCI device |
1388 | * @dev: PCI device to handle. | 1579 | * @dev: PCI device to handle. |
1389 | */ | 1580 | */ |
@@ -1392,7 +1583,10 @@ void pci_pm_init(struct pci_dev *dev) | |||
1392 | int pm; | 1583 | int pm; |
1393 | u16 pmc; | 1584 | u16 pmc; |
1394 | 1585 | ||
1586 | pm_runtime_forbid(&dev->dev); | ||
1587 | device_enable_async_suspend(&dev->dev); | ||
1395 | dev->wakeup_prepared = false; | 1588 | dev->wakeup_prepared = false; |
1589 | |||
1396 | dev->pm_cap = 0; | 1590 | dev->pm_cap = 0; |
1397 | 1591 | ||
1398 | /* find PCI PM capability in list */ | 1592 | /* find PCI PM capability in list */ |
@@ -1409,6 +1603,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1409 | } | 1603 | } |
1410 | 1604 | ||
1411 | dev->pm_cap = pm; | 1605 | dev->pm_cap = pm; |
1606 | dev->d3_delay = PCI_PM_D3_WAIT; | ||
1412 | 1607 | ||
1413 | dev->d1_support = false; | 1608 | dev->d1_support = false; |
1414 | dev->d2_support = false; | 1609 | dev->d2_support = false; |
@@ -2103,35 +2298,6 @@ void pci_msi_off(struct pci_dev *dev) | |||
2103 | } | 2298 | } |
2104 | } | 2299 | } |
2105 | 2300 | ||
2106 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK | ||
2107 | /* | ||
2108 | * These can be overridden by arch-specific implementations | ||
2109 | */ | ||
2110 | int | ||
2111 | pci_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
2112 | { | ||
2113 | if (!pci_dma_supported(dev, mask)) | ||
2114 | return -EIO; | ||
2115 | |||
2116 | dev->dma_mask = mask; | ||
2117 | dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask)); | ||
2118 | |||
2119 | return 0; | ||
2120 | } | ||
2121 | |||
2122 | int | ||
2123 | pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | ||
2124 | { | ||
2125 | if (!pci_dma_supported(dev, mask)) | ||
2126 | return -EIO; | ||
2127 | |||
2128 | dev->dev.coherent_dma_mask = mask; | ||
2129 | dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask)); | ||
2130 | |||
2131 | return 0; | ||
2132 | } | ||
2133 | #endif | ||
2134 | |||
2135 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE | 2301 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE |
2136 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) | 2302 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) |
2137 | { | 2303 | { |
@@ -2247,12 +2413,12 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
2247 | csr &= ~PCI_PM_CTRL_STATE_MASK; | 2413 | csr &= ~PCI_PM_CTRL_STATE_MASK; |
2248 | csr |= PCI_D3hot; | 2414 | csr |= PCI_D3hot; |
2249 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); | 2415 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); |
2250 | msleep(pci_pm_d3_delay); | 2416 | pci_dev_d3_sleep(dev); |
2251 | 2417 | ||
2252 | csr &= ~PCI_PM_CTRL_STATE_MASK; | 2418 | csr &= ~PCI_PM_CTRL_STATE_MASK; |
2253 | csr |= PCI_D0; | 2419 | csr |= PCI_D0; |
2254 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); | 2420 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); |
2255 | msleep(pci_pm_d3_delay); | 2421 | pci_dev_d3_sleep(dev); |
2256 | 2422 | ||
2257 | return 0; | 2423 | return 0; |
2258 | } | 2424 | } |
@@ -2293,9 +2459,13 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2293 | if (!probe) { | 2459 | if (!probe) { |
2294 | pci_block_user_cfg_access(dev); | 2460 | pci_block_user_cfg_access(dev); |
2295 | /* block PM suspend, driver probe, etc. */ | 2461 | /* block PM suspend, driver probe, etc. */ |
2296 | down(&dev->dev.sem); | 2462 | device_lock(&dev->dev); |
2297 | } | 2463 | } |
2298 | 2464 | ||
2465 | rc = pci_dev_specific_reset(dev, probe); | ||
2466 | if (rc != -ENOTTY) | ||
2467 | goto done; | ||
2468 | |||
2299 | rc = pcie_flr(dev, probe); | 2469 | rc = pcie_flr(dev, probe); |
2300 | if (rc != -ENOTTY) | 2470 | if (rc != -ENOTTY) |
2301 | goto done; | 2471 | goto done; |
@@ -2311,7 +2481,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2311 | rc = pci_parent_bus_reset(dev, probe); | 2481 | rc = pci_parent_bus_reset(dev, probe); |
2312 | done: | 2482 | done: |
2313 | if (!probe) { | 2483 | if (!probe) { |
2314 | up(&dev->dev.sem); | 2484 | device_unlock(&dev->dev); |
2315 | pci_unblock_user_cfg_access(dev); | 2485 | pci_unblock_user_cfg_access(dev); |
2316 | } | 2486 | } |
2317 | 2487 | ||
@@ -2406,18 +2576,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function); | |||
2406 | */ | 2576 | */ |
2407 | int pcix_get_max_mmrbc(struct pci_dev *dev) | 2577 | int pcix_get_max_mmrbc(struct pci_dev *dev) |
2408 | { | 2578 | { |
2409 | int err, cap; | 2579 | int cap; |
2410 | u32 stat; | 2580 | u32 stat; |
2411 | 2581 | ||
2412 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2582 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2413 | if (!cap) | 2583 | if (!cap) |
2414 | return -EINVAL; | 2584 | return -EINVAL; |
2415 | 2585 | ||
2416 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | 2586 | if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) |
2417 | if (err) | ||
2418 | return -EINVAL; | 2587 | return -EINVAL; |
2419 | 2588 | ||
2420 | return (stat & PCI_X_STATUS_MAX_READ) >> 12; | 2589 | return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); |
2421 | } | 2590 | } |
2422 | EXPORT_SYMBOL(pcix_get_max_mmrbc); | 2591 | EXPORT_SYMBOL(pcix_get_max_mmrbc); |
2423 | 2592 | ||
@@ -2430,18 +2599,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); | |||
2430 | */ | 2599 | */ |
2431 | int pcix_get_mmrbc(struct pci_dev *dev) | 2600 | int pcix_get_mmrbc(struct pci_dev *dev) |
2432 | { | 2601 | { |
2433 | int ret, cap; | 2602 | int cap; |
2434 | u32 cmd; | 2603 | u16 cmd; |
2435 | 2604 | ||
2436 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2605 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2437 | if (!cap) | 2606 | if (!cap) |
2438 | return -EINVAL; | 2607 | return -EINVAL; |
2439 | 2608 | ||
2440 | ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | 2609 | if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) |
2441 | if (!ret) | 2610 | return -EINVAL; |
2442 | ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); | ||
2443 | 2611 | ||
2444 | return ret; | 2612 | return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); |
2445 | } | 2613 | } |
2446 | EXPORT_SYMBOL(pcix_get_mmrbc); | 2614 | EXPORT_SYMBOL(pcix_get_mmrbc); |
2447 | 2615 | ||
@@ -2456,28 +2624,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); | |||
2456 | */ | 2624 | */ |
2457 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | 2625 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) |
2458 | { | 2626 | { |
2459 | int cap, err = -EINVAL; | 2627 | int cap; |
2460 | u32 stat, cmd, v, o; | 2628 | u32 stat, v, o; |
2629 | u16 cmd; | ||
2461 | 2630 | ||
2462 | if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) | 2631 | if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) |
2463 | goto out; | 2632 | return -EINVAL; |
2464 | 2633 | ||
2465 | v = ffs(mmrbc) - 10; | 2634 | v = ffs(mmrbc) - 10; |
2466 | 2635 | ||
2467 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2636 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2468 | if (!cap) | 2637 | if (!cap) |
2469 | goto out; | 2638 | return -EINVAL; |
2470 | 2639 | ||
2471 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | 2640 | if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) |
2472 | if (err) | 2641 | return -EINVAL; |
2473 | goto out; | ||
2474 | 2642 | ||
2475 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) | 2643 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) |
2476 | return -E2BIG; | 2644 | return -E2BIG; |
2477 | 2645 | ||
2478 | err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | 2646 | if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) |
2479 | if (err) | 2647 | return -EINVAL; |
2480 | goto out; | ||
2481 | 2648 | ||
2482 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; | 2649 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; |
2483 | if (o != v) { | 2650 | if (o != v) { |
@@ -2487,10 +2654,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | |||
2487 | 2654 | ||
2488 | cmd &= ~PCI_X_CMD_MAX_READ; | 2655 | cmd &= ~PCI_X_CMD_MAX_READ; |
2489 | cmd |= v << 2; | 2656 | cmd |= v << 2; |
2490 | err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); | 2657 | if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) |
2658 | return -EIO; | ||
2491 | } | 2659 | } |
2492 | out: | 2660 | return 0; |
2493 | return err; | ||
2494 | } | 2661 | } |
2495 | EXPORT_SYMBOL(pcix_set_mmrbc); | 2662 | EXPORT_SYMBOL(pcix_set_mmrbc); |
2496 | 2663 | ||
@@ -2600,6 +2767,23 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | |||
2600 | return 0; | 2767 | return 0; |
2601 | } | 2768 | } |
2602 | 2769 | ||
2770 | /* Some architectures require additional programming to enable VGA */ | ||
2771 | static arch_set_vga_state_t arch_set_vga_state; | ||
2772 | |||
2773 | void __init pci_register_set_vga_state(arch_set_vga_state_t func) | ||
2774 | { | ||
2775 | arch_set_vga_state = func; /* NULL disables */ | ||
2776 | } | ||
2777 | |||
2778 | static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode, | ||
2779 | unsigned int command_bits, bool change_bridge) | ||
2780 | { | ||
2781 | if (arch_set_vga_state) | ||
2782 | return arch_set_vga_state(dev, decode, command_bits, | ||
2783 | change_bridge); | ||
2784 | return 0; | ||
2785 | } | ||
2786 | |||
2603 | /** | 2787 | /** |
2604 | * pci_set_vga_state - set VGA decode state on device and parents if requested | 2788 | * pci_set_vga_state - set VGA decode state on device and parents if requested |
2605 | * @dev: the PCI device | 2789 | * @dev: the PCI device |
@@ -2613,9 +2797,15 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, | |||
2613 | struct pci_bus *bus; | 2797 | struct pci_bus *bus; |
2614 | struct pci_dev *bridge; | 2798 | struct pci_dev *bridge; |
2615 | u16 cmd; | 2799 | u16 cmd; |
2800 | int rc; | ||
2616 | 2801 | ||
2617 | WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); | 2802 | WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); |
2618 | 2803 | ||
2804 | /* ARCH specific VGA enables */ | ||
2805 | rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge); | ||
2806 | if (rc) | ||
2807 | return rc; | ||
2808 | |||
2619 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 2809 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
2620 | if (decode == true) | 2810 | if (decode == true) |
2621 | cmd |= command_bits; | 2811 | cmd |= command_bits; |
@@ -2779,6 +2969,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) | |||
2779 | return 1; | 2969 | return 1; |
2780 | } | 2970 | } |
2781 | 2971 | ||
2972 | void __weak pci_fixup_cardbus(struct pci_bus *bus) | ||
2973 | { | ||
2974 | } | ||
2975 | EXPORT_SYMBOL(pci_fixup_cardbus); | ||
2976 | |||
2782 | static int __init pci_setup(char *str) | 2977 | static int __init pci_setup(char *str) |
2783 | { | 2978 | { |
2784 | while (str) { | 2979 | while (str) { |
@@ -2840,8 +3035,6 @@ EXPORT_SYMBOL(pci_set_mwi); | |||
2840 | EXPORT_SYMBOL(pci_try_set_mwi); | 3035 | EXPORT_SYMBOL(pci_try_set_mwi); |
2841 | EXPORT_SYMBOL(pci_clear_mwi); | 3036 | EXPORT_SYMBOL(pci_clear_mwi); |
2842 | EXPORT_SYMBOL_GPL(pci_intx); | 3037 | EXPORT_SYMBOL_GPL(pci_intx); |
2843 | EXPORT_SYMBOL(pci_set_dma_mask); | ||
2844 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); | ||
2845 | EXPORT_SYMBOL(pci_assign_resource); | 3038 | EXPORT_SYMBOL(pci_assign_resource); |
2846 | EXPORT_SYMBOL(pci_find_parent_resource); | 3039 | EXPORT_SYMBOL(pci_find_parent_resource); |
2847 | EXPORT_SYMBOL(pci_select_bars); | 3040 | EXPORT_SYMBOL(pci_select_bars); |
@@ -2851,10 +3044,8 @@ EXPORT_SYMBOL(pci_save_state); | |||
2851 | EXPORT_SYMBOL(pci_restore_state); | 3044 | EXPORT_SYMBOL(pci_restore_state); |
2852 | EXPORT_SYMBOL(pci_pme_capable); | 3045 | EXPORT_SYMBOL(pci_pme_capable); |
2853 | EXPORT_SYMBOL(pci_pme_active); | 3046 | EXPORT_SYMBOL(pci_pme_active); |
2854 | EXPORT_SYMBOL(pci_enable_wake); | ||
2855 | EXPORT_SYMBOL(pci_wake_from_d3); | 3047 | EXPORT_SYMBOL(pci_wake_from_d3); |
2856 | EXPORT_SYMBOL(pci_target_state); | 3048 | EXPORT_SYMBOL(pci_target_state); |
2857 | EXPORT_SYMBOL(pci_prepare_to_sleep); | 3049 | EXPORT_SYMBOL(pci_prepare_to_sleep); |
2858 | EXPORT_SYMBOL(pci_back_from_sleep); | 3050 | EXPORT_SYMBOL(pci_back_from_sleep); |
2859 | EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); | 3051 | EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); |
2860 | |||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 33ed8e0aba1e..4eb10f48d270 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -35,6 +35,10 @@ int pci_probe_reset_function(struct pci_dev *dev); | |||
35 | * | 35 | * |
36 | * @sleep_wake: enables/disables the system wake up capability of given device | 36 | * @sleep_wake: enables/disables the system wake up capability of given device |
37 | * | 37 | * |
38 | * @run_wake: enables/disables the platform to generate run-time wake-up events | ||
39 | * for given device (the device's wake-up capability has to be | ||
40 | * enabled by @sleep_wake for this feature to work) | ||
41 | * | ||
38 | * If given platform is generally capable of power managing PCI devices, all of | 42 | * If given platform is generally capable of power managing PCI devices, all of |
39 | * these callbacks are mandatory. | 43 | * these callbacks are mandatory. |
40 | */ | 44 | */ |
@@ -44,11 +48,16 @@ struct pci_platform_pm_ops { | |||
44 | pci_power_t (*choose_state)(struct pci_dev *dev); | 48 | pci_power_t (*choose_state)(struct pci_dev *dev); |
45 | bool (*can_wakeup)(struct pci_dev *dev); | 49 | bool (*can_wakeup)(struct pci_dev *dev); |
46 | int (*sleep_wake)(struct pci_dev *dev, bool enable); | 50 | int (*sleep_wake)(struct pci_dev *dev, bool enable); |
51 | int (*run_wake)(struct pci_dev *dev, bool enable); | ||
47 | }; | 52 | }; |
48 | 53 | ||
49 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 54 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
50 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | 55 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); |
51 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 56 | extern void pci_disable_enabled_device(struct pci_dev *dev); |
57 | extern bool pci_check_pme_status(struct pci_dev *dev); | ||
58 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | ||
59 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | ||
60 | extern void pci_pme_wakeup_bus(struct pci_bus *bus); | ||
52 | extern void pci_pm_init(struct pci_dev *dev); | 61 | extern void pci_pm_init(struct pci_dev *dev); |
53 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 62 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
54 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 63 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
@@ -313,4 +322,19 @@ static inline int pci_resource_alignment(struct pci_dev *dev, | |||
313 | 322 | ||
314 | extern void pci_enable_acs(struct pci_dev *dev); | 323 | extern void pci_enable_acs(struct pci_dev *dev); |
315 | 324 | ||
325 | struct pci_dev_reset_methods { | ||
326 | u16 vendor; | ||
327 | u16 device; | ||
328 | int (*reset)(struct pci_dev *dev, int probe); | ||
329 | }; | ||
330 | |||
331 | #ifdef CONFIG_PCI_QUIRKS | ||
332 | extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); | ||
333 | #else | ||
334 | static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) | ||
335 | { | ||
336 | return -ENOTTY; | ||
337 | } | ||
338 | #endif | ||
339 | |||
316 | #endif /* DRIVERS_PCI_H */ | 340 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 5a0c6ad53f8e..b8b494b3e0d0 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -46,3 +46,7 @@ config PCIEASPM_DEBUG | |||
46 | help | 46 | help |
47 | This enables PCI Express ASPM debug support. It will add per-device | 47 | This enables PCI Express ASPM debug support. It will add per-device |
48 | interface to control ASPM. | 48 | interface to control ASPM. |
49 | |||
50 | config PCIE_PME | ||
51 | def_bool y | ||
52 | depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI | ||
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index 11f6bb1eae24..ea654545e7c4 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile | |||
@@ -11,3 +11,5 @@ obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o | |||
11 | 11 | ||
12 | # Build PCI Express AER if needed | 12 | # Build PCI Express AER if needed |
13 | obj-$(CONFIG_PCIEAER) += aer/ | 13 | obj-$(CONFIG_PCIEAER) += aer/ |
14 | |||
15 | obj-$(CONFIG_PCIE_PME) += pme/ | ||
diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug index b8c925c1f6aa..9142949734f5 100644 --- a/drivers/pci/pcie/aer/Kconfig.debug +++ b/drivers/pci/pcie/aer/Kconfig.debug | |||
@@ -3,14 +3,14 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | config PCIEAER_INJECT | 5 | config PCIEAER_INJECT |
6 | tristate "PCIE AER error injector support" | 6 | tristate "PCIe AER error injector support" |
7 | depends on PCIEAER | 7 | depends on PCIEAER |
8 | default n | 8 | default n |
9 | help | 9 | help |
10 | This enables PCI Express Root Port Advanced Error Reporting | 10 | This enables PCI Express Root Port Advanced Error Reporting |
11 | (AER) software error injector. | 11 | (AER) software error injector. |
12 | 12 | ||
13 | Debuging PCIE AER code is quite difficult because it is hard | 13 | Debugging PCIe AER code is quite difficult because it is hard |
14 | to trigger various real hardware errors. Software based | 14 | to trigger various real hardware errors. Software based |
15 | error injection can fake almost all kinds of errors with the | 15 | error injection can fake almost all kinds of errors with the |
16 | help of a user space helper tool aer-inject, which can be | 16 | help of a user space helper tool aer-inject, which can be |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 7fcd5331b14c..223052b73563 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * PCIE AER software error injection support. | 2 | * PCIe AER software error injection support. |
3 | * | 3 | * |
4 | * Debuging PCIE AER code is quite difficult because it is hard to | 4 | * Debuging PCIe AER code is quite difficult because it is hard to |
5 | * trigger various real hardware errors. Software based error | 5 | * trigger various real hardware errors. Software based error |
6 | * injection can fake almost all kinds of errors with the help of a | 6 | * injection can fake almost all kinds of errors with the help of a |
7 | * user space helper tool aer-inject, which can be gotten from: | 7 | * user space helper tool aer-inject, which can be gotten from: |
@@ -321,7 +321,7 @@ static int aer_inject(struct aer_error_inj *einj) | |||
321 | unsigned long flags; | 321 | unsigned long flags; |
322 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); | 322 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); |
323 | int pos_cap_err, rp_pos_cap_err; | 323 | int pos_cap_err, rp_pos_cap_err; |
324 | u32 sever; | 324 | u32 sever, cor_mask, uncor_mask; |
325 | int ret = 0; | 325 | int ret = 0; |
326 | 326 | ||
327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); | 327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); |
@@ -339,6 +339,9 @@ static int aer_inject(struct aer_error_inj *einj) | |||
339 | goto out_put; | 339 | goto out_put; |
340 | } | 340 | } |
341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
342 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask); | ||
343 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, | ||
344 | &uncor_mask); | ||
342 | 345 | ||
343 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 346 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
344 | if (!rp_pos_cap_err) { | 347 | if (!rp_pos_cap_err) { |
@@ -374,6 +377,21 @@ static int aer_inject(struct aer_error_inj *einj) | |||
374 | err->header_log2 = einj->header_log2; | 377 | err->header_log2 = einj->header_log2; |
375 | err->header_log3 = einj->header_log3; | 378 | err->header_log3 = einj->header_log3; |
376 | 379 | ||
380 | if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { | ||
381 | ret = -EINVAL; | ||
382 | printk(KERN_WARNING "The correctable error(s) is masked " | ||
383 | "by device\n"); | ||
384 | spin_unlock_irqrestore(&inject_lock, flags); | ||
385 | goto out_put; | ||
386 | } | ||
387 | if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { | ||
388 | ret = -EINVAL; | ||
389 | printk(KERN_WARNING "The uncorrectable error(s) is masked " | ||
390 | "by device\n"); | ||
391 | spin_unlock_irqrestore(&inject_lock, flags); | ||
392 | goto out_put; | ||
393 | } | ||
394 | |||
377 | rperr = __find_aer_error_by_dev(rpdev); | 395 | rperr = __find_aer_error_by_dev(rpdev); |
378 | if (!rperr) { | 396 | if (!rperr) { |
379 | rperr = rperr_alloc; | 397 | rperr = rperr_alloc; |
@@ -413,8 +431,14 @@ static int aer_inject(struct aer_error_inj *einj) | |||
413 | if (ret) | 431 | if (ret) |
414 | goto out_put; | 432 | goto out_put; |
415 | 433 | ||
416 | if (find_aer_device(rpdev, &edev)) | 434 | if (find_aer_device(rpdev, &edev)) { |
435 | if (!get_service_data(edev)) { | ||
436 | printk(KERN_WARNING "AER service is not initialized\n"); | ||
437 | ret = -EINVAL; | ||
438 | goto out_put; | ||
439 | } | ||
417 | aer_irq(-1, edev); | 440 | aer_irq(-1, edev); |
441 | } | ||
418 | else | 442 | else |
419 | ret = -EINVAL; | 443 | ret = -EINVAL; |
420 | out_put: | 444 | out_put: |
@@ -484,5 +508,5 @@ static void __exit aer_inject_exit(void) | |||
484 | module_init(aer_inject_init); | 508 | module_init(aer_inject_init); |
485 | module_exit(aer_inject_exit); | 509 | module_exit(aer_inject_exit); |
486 | 510 | ||
487 | MODULE_DESCRIPTION("PCIE AER software error injector"); | 511 | MODULE_DESCRIPTION("PCIe AER software error injector"); |
488 | MODULE_LICENSE("GPL"); | 512 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 97a345927b55..21f215f4daa3 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -155,7 +155,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) | |||
155 | mutex_init(&rpc->rpc_mutex); | 155 | mutex_init(&rpc->rpc_mutex); |
156 | init_waitqueue_head(&rpc->wait_release); | 156 | init_waitqueue_head(&rpc->wait_release); |
157 | 157 | ||
158 | /* Use PCIE bus function to store rpc into PCIE device */ | 158 | /* Use PCIe bus function to store rpc into PCIe device */ |
159 | set_service_data(dev, rpc); | 159 | set_service_data(dev, rpc); |
160 | 160 | ||
161 | return rpc; | 161 | return rpc; |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 8edb2f300e8f..04814087658d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * | 24 | * |
25 | * @return: Zero on success. Nonzero otherwise. | 25 | * @return: Zero on success. Nonzero otherwise. |
26 | * | 26 | * |
27 | * Invoked when PCIE bus loads AER service driver. To avoid conflict with | 27 | * Invoked when PCIe bus loads AER service driver. To avoid conflict with |
28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. | 28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. |
29 | **/ | 29 | **/ |
30 | int aer_osc_setup(struct pcie_device *pciedev) | 30 | int aer_osc_setup(struct pcie_device *pciedev) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ae672ca80333..c843a799814d 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -587,7 +587,7 @@ static void handle_error_source(struct pcie_device *aerdev, | |||
587 | * aer_enable_rootport - enable Root Port's interrupts when receiving messages | 587 | * aer_enable_rootport - enable Root Port's interrupts when receiving messages |
588 | * @rpc: pointer to a Root Port data structure | 588 | * @rpc: pointer to a Root Port data structure |
589 | * | 589 | * |
590 | * Invoked when PCIE bus loads AER service driver. | 590 | * Invoked when PCIe bus loads AER service driver. |
591 | */ | 591 | */ |
592 | void aer_enable_rootport(struct aer_rpc *rpc) | 592 | void aer_enable_rootport(struct aer_rpc *rpc) |
593 | { | 593 | { |
@@ -597,7 +597,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
597 | u32 reg32; | 597 | u32 reg32; |
598 | 598 | ||
599 | pos = pci_pcie_cap(pdev); | 599 | pos = pci_pcie_cap(pdev); |
600 | /* Clear PCIE Capability's Device Status */ | 600 | /* Clear PCIe Capability's Device Status */ |
601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); | 601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); |
602 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); | 602 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); |
603 | 603 | ||
@@ -631,7 +631,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
631 | * disable_root_aer - disable Root Port's interrupts when receiving messages | 631 | * disable_root_aer - disable Root Port's interrupts when receiving messages |
632 | * @rpc: pointer to a Root Port data structure | 632 | * @rpc: pointer to a Root Port data structure |
633 | * | 633 | * |
634 | * Invoked when PCIE bus unloads AER service driver. | 634 | * Invoked when PCIe bus unloads AER service driver. |
635 | */ | 635 | */ |
636 | static void disable_root_aer(struct aer_rpc *rpc) | 636 | static void disable_root_aer(struct aer_rpc *rpc) |
637 | { | 637 | { |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 44acde72294f..9d3e4c8d0184 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -184,7 +184,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
184 | 184 | ||
185 | if (info->status == 0) { | 185 | if (info->status == 0) { |
186 | AER_PR(info, dev, | 186 | AER_PR(info, dev, |
187 | "PCIE Bus Error: severity=%s, type=Unaccessible, " | 187 | "PCIe Bus Error: severity=%s, type=Unaccessible, " |
188 | "id=%04x(Unregistered Agent ID)\n", | 188 | "id=%04x(Unregistered Agent ID)\n", |
189 | aer_error_severity_string[info->severity], id); | 189 | aer_error_severity_string[info->severity], id); |
190 | } else { | 190 | } else { |
@@ -194,7 +194,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
194 | agent = AER_GET_AGENT(info->severity, info->status); | 194 | agent = AER_GET_AGENT(info->severity, info->status); |
195 | 195 | ||
196 | AER_PR(info, dev, | 196 | AER_PR(info, dev, |
197 | "PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n", | 197 | "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", |
198 | aer_error_severity_string[info->severity], | 198 | aer_error_severity_string[info->severity], |
199 | aer_error_layer[layer], id, aer_agent_string[agent]); | 199 | aer_error_layer[layer], id, aer_agent_string[agent]); |
200 | 200 | ||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 5a01fc7fbf05..be53d98fa384 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/pci/pcie/aspm.c | 2 | * File: drivers/pci/pcie/aspm.c |
3 | * Enabling PCIE link L0s/L1 state and Clock Power Management | 3 | * Enabling PCIe link L0s/L1 state and Clock Power Management |
4 | * | 4 | * |
5 | * Copyright (C) 2007 Intel | 5 | * Copyright (C) 2007 Intel |
6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) | 6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) |
@@ -499,7 +499,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
499 | int pos; | 499 | int pos; |
500 | u32 reg32; | 500 | u32 reg32; |
501 | /* | 501 | /* |
502 | * Some functions in a slot might not all be PCIE functions, | 502 | * Some functions in a slot might not all be PCIe functions, |
503 | * very strange. Disable ASPM for the whole slot | 503 | * very strange. Disable ASPM for the whole slot |
504 | */ | 504 | */ |
505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { | 505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { |
diff --git a/drivers/pci/pcie/pme/Makefile b/drivers/pci/pcie/pme/Makefile new file mode 100644 index 000000000000..8b9238053080 --- /dev/null +++ b/drivers/pci/pcie/pme/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for PCI-Express Root Port PME signaling driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PCIE_PME) += pmedriver.o | ||
6 | |||
7 | pmedriver-objs := pcie_pme.o | ||
8 | pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c new file mode 100644 index 000000000000..7b3cbff547ee --- /dev/null +++ b/drivers/pci/pcie/pme/pcie_pme.c | |||
@@ -0,0 +1,505 @@ | |||
1 | /* | ||
2 | * PCIe Native PME support | ||
3 | * | ||
4 | * Copyright (C) 2007 - 2009 Intel Corp | ||
5 | * Copyright (C) 2007 - 2009 Shaohua Li <shaohua.li@intel.com> | ||
6 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License V2. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/pcieport_if.h> | ||
21 | #include <linux/acpi.h> | ||
22 | #include <linux/pci-acpi.h> | ||
23 | #include <linux/pm_runtime.h> | ||
24 | |||
25 | #include "../../pci.h" | ||
26 | #include "pcie_pme.h" | ||
27 | |||
28 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | ||
29 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | ||
30 | |||
31 | /* | ||
32 | * If set, this switch will prevent the PCIe root port PME service driver from | ||
33 | * being registered. Consequently, the interrupt-based PCIe PME signaling will | ||
34 | * not be used by any PCIe root ports in that case. | ||
35 | */ | ||
36 | static bool pcie_pme_disabled; | ||
37 | |||
38 | /* | ||
39 | * The PCI Express Base Specification 2.0, Section 6.1.8, states the following: | ||
40 | * "In order to maintain compatibility with non-PCI Express-aware system | ||
41 | * software, system power management logic must be configured by firmware to use | ||
42 | * the legacy mechanism of signaling PME by default. PCI Express-aware system | ||
43 | * software must notify the firmware prior to enabling native, interrupt-based | ||
44 | * PME signaling." However, if the platform doesn't provide us with a suitable | ||
45 | * notification mechanism or the notification fails, it is not clear whether or | ||
46 | * not we are supposed to use the interrupt-based PCIe PME signaling. The | ||
47 | * switch below can be used to indicate the desired behaviour. When set, it | ||
48 | * will make the kernel use the interrupt-based PCIe PME signaling regardless of | ||
49 | * the platform notification status, although the kernel will attempt to notify | ||
50 | * the platform anyway. When unset, it will prevent the kernel from using the | ||
51 | * the interrupt-based PCIe PME signaling if the platform notification fails, | ||
52 | * which is the default. | ||
53 | */ | ||
54 | static bool pcie_pme_force_enable; | ||
55 | |||
56 | /* | ||
57 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | ||
58 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | ||
59 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based | ||
60 | * wake-up from system sleep states. | ||
61 | */ | ||
62 | bool pcie_pme_msi_disabled; | ||
63 | |||
64 | static int __init pcie_pme_setup(char *str) | ||
65 | { | ||
66 | if (!strcmp(str, "off")) | ||
67 | pcie_pme_disabled = true; | ||
68 | else if (!strcmp(str, "force")) | ||
69 | pcie_pme_force_enable = true; | ||
70 | else if (!strcmp(str, "nomsi")) | ||
71 | pcie_pme_msi_disabled = true; | ||
72 | return 1; | ||
73 | } | ||
74 | __setup("pcie_pme=", pcie_pme_setup); | ||
75 | |||
76 | /** | ||
77 | * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME. | ||
78 | * @srv: PCIe PME root port service to use for carrying out the check. | ||
79 | * | ||
80 | * Notify the platform that the native PCIe PME is going to be used and return | ||
81 | * 'true' if the control of the PCIe PME registers has been acquired from the | ||
82 | * platform. | ||
83 | */ | ||
84 | static bool pcie_pme_platform_setup(struct pcie_device *srv) | ||
85 | { | ||
86 | if (!pcie_pme_platform_notify(srv)) | ||
87 | return true; | ||
88 | return pcie_pme_force_enable; | ||
89 | } | ||
90 | |||
91 | struct pcie_pme_service_data { | ||
92 | spinlock_t lock; | ||
93 | struct pcie_device *srv; | ||
94 | struct work_struct work; | ||
95 | bool noirq; /* Don't enable the PME interrupt used by this service. */ | ||
96 | }; | ||
97 | |||
98 | /** | ||
99 | * pcie_pme_interrupt_enable - Enable/disable PCIe PME interrupt generation. | ||
100 | * @dev: PCIe root port or event collector. | ||
101 | * @enable: Enable or disable the interrupt. | ||
102 | */ | ||
103 | static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) | ||
104 | { | ||
105 | int rtctl_pos; | ||
106 | u16 rtctl; | ||
107 | |||
108 | rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL; | ||
109 | |||
110 | pci_read_config_word(dev, rtctl_pos, &rtctl); | ||
111 | if (enable) | ||
112 | rtctl |= PCI_EXP_RTCTL_PMEIE; | ||
113 | else | ||
114 | rtctl &= ~PCI_EXP_RTCTL_PMEIE; | ||
115 | pci_write_config_word(dev, rtctl_pos, rtctl); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * pcie_pme_clear_status - Clear root port PME interrupt status. | ||
120 | * @dev: PCIe root port or event collector. | ||
121 | */ | ||
122 | static void pcie_pme_clear_status(struct pci_dev *dev) | ||
123 | { | ||
124 | int rtsta_pos; | ||
125 | u32 rtsta; | ||
126 | |||
127 | rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; | ||
128 | |||
129 | pci_read_config_dword(dev, rtsta_pos, &rtsta); | ||
130 | rtsta |= PCI_EXP_RTSTA_PME; | ||
131 | pci_write_config_dword(dev, rtsta_pos, rtsta); | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. | ||
136 | * @bus: PCI bus to scan. | ||
137 | * | ||
138 | * Scan given PCI bus and all buses under it for devices asserting PME#. | ||
139 | */ | ||
140 | static bool pcie_pme_walk_bus(struct pci_bus *bus) | ||
141 | { | ||
142 | struct pci_dev *dev; | ||
143 | bool ret = false; | ||
144 | |||
145 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
146 | /* Skip PCIe devices in case we started from a root port. */ | ||
147 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { | ||
148 | pm_request_resume(&dev->dev); | ||
149 | ret = true; | ||
150 | } | ||
151 | |||
152 | if (dev->subordinate && pcie_pme_walk_bus(dev->subordinate)) | ||
153 | ret = true; | ||
154 | } | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * pcie_pme_from_pci_bridge - Check if PCIe-PCI bridge generated a PME. | ||
161 | * @bus: Secondary bus of the bridge. | ||
162 | * @devfn: Device/function number to check. | ||
163 | * | ||
164 | * PME from PCI devices under a PCIe-PCI bridge may be converted to an in-band | ||
165 | * PCIe PME message. In such that case the bridge should use the Requester ID | ||
166 | * of device/function number 0 on its secondary bus. | ||
167 | */ | ||
168 | static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn) | ||
169 | { | ||
170 | struct pci_dev *dev; | ||
171 | bool found = false; | ||
172 | |||
173 | if (devfn) | ||
174 | return false; | ||
175 | |||
176 | dev = pci_dev_get(bus->self); | ||
177 | if (!dev) | ||
178 | return false; | ||
179 | |||
180 | if (pci_is_pcie(dev) && dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { | ||
181 | down_read(&pci_bus_sem); | ||
182 | if (pcie_pme_walk_bus(bus)) | ||
183 | found = true; | ||
184 | up_read(&pci_bus_sem); | ||
185 | } | ||
186 | |||
187 | pci_dev_put(dev); | ||
188 | return found; | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * pcie_pme_handle_request - Find device that generated PME and handle it. | ||
193 | * @port: Root port or event collector that generated the PME interrupt. | ||
194 | * @req_id: PCIe Requester ID of the device that generated the PME. | ||
195 | */ | ||
196 | static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) | ||
197 | { | ||
198 | u8 busnr = req_id >> 8, devfn = req_id & 0xff; | ||
199 | struct pci_bus *bus; | ||
200 | struct pci_dev *dev; | ||
201 | bool found = false; | ||
202 | |||
203 | /* First, check if the PME is from the root port itself. */ | ||
204 | if (port->devfn == devfn && port->bus->number == busnr) { | ||
205 | if (pci_check_pme_status(port)) { | ||
206 | pm_request_resume(&port->dev); | ||
207 | found = true; | ||
208 | } else { | ||
209 | /* | ||
210 | * Apparently, the root port generated the PME on behalf | ||
211 | * of a non-PCIe device downstream. If this is done by | ||
212 | * a root port, the Requester ID field in its status | ||
213 | * register may contain either the root port's, or the | ||
214 | * source device's information (PCI Express Base | ||
215 | * Specification, Rev. 2.0, Section 6.1.9). | ||
216 | */ | ||
217 | down_read(&pci_bus_sem); | ||
218 | found = pcie_pme_walk_bus(port->subordinate); | ||
219 | up_read(&pci_bus_sem); | ||
220 | } | ||
221 | goto out; | ||
222 | } | ||
223 | |||
224 | /* Second, find the bus the source device is on. */ | ||
225 | bus = pci_find_bus(pci_domain_nr(port->bus), busnr); | ||
226 | if (!bus) | ||
227 | goto out; | ||
228 | |||
229 | /* Next, check if the PME is from a PCIe-PCI bridge. */ | ||
230 | found = pcie_pme_from_pci_bridge(bus, devfn); | ||
231 | if (found) | ||
232 | goto out; | ||
233 | |||
234 | /* Finally, try to find the PME source on the bus. */ | ||
235 | down_read(&pci_bus_sem); | ||
236 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
237 | pci_dev_get(dev); | ||
238 | if (dev->devfn == devfn) { | ||
239 | found = true; | ||
240 | break; | ||
241 | } | ||
242 | pci_dev_put(dev); | ||
243 | } | ||
244 | up_read(&pci_bus_sem); | ||
245 | |||
246 | if (found) { | ||
247 | /* The device is there, but we have to check its PME status. */ | ||
248 | found = pci_check_pme_status(dev); | ||
249 | if (found) | ||
250 | pm_request_resume(&dev->dev); | ||
251 | pci_dev_put(dev); | ||
252 | } else if (devfn) { | ||
253 | /* | ||
254 | * The device is not there, but we can still try to recover by | ||
255 | * assuming that the PME was reported by a PCIe-PCI bridge that | ||
256 | * used devfn different from zero. | ||
257 | */ | ||
258 | dev_dbg(&port->dev, "PME interrupt generated for " | ||
259 | "non-existent device %02x:%02x.%d\n", | ||
260 | busnr, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||
261 | found = pcie_pme_from_pci_bridge(bus, 0); | ||
262 | } | ||
263 | |||
264 | out: | ||
265 | if (!found) | ||
266 | dev_dbg(&port->dev, "Spurious native PME interrupt!\n"); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * pcie_pme_work_fn - Work handler for PCIe PME interrupt. | ||
271 | * @work: Work structure giving access to service data. | ||
272 | */ | ||
273 | static void pcie_pme_work_fn(struct work_struct *work) | ||
274 | { | ||
275 | struct pcie_pme_service_data *data = | ||
276 | container_of(work, struct pcie_pme_service_data, work); | ||
277 | struct pci_dev *port = data->srv->port; | ||
278 | int rtsta_pos; | ||
279 | u32 rtsta; | ||
280 | |||
281 | rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA; | ||
282 | |||
283 | spin_lock_irq(&data->lock); | ||
284 | |||
285 | for (;;) { | ||
286 | if (data->noirq) | ||
287 | break; | ||
288 | |||
289 | pci_read_config_dword(port, rtsta_pos, &rtsta); | ||
290 | if (rtsta & PCI_EXP_RTSTA_PME) { | ||
291 | /* | ||
292 | * Clear PME status of the port. If there are other | ||
293 | * pending PMEs, the status will be set again. | ||
294 | */ | ||
295 | pcie_pme_clear_status(port); | ||
296 | |||
297 | spin_unlock_irq(&data->lock); | ||
298 | pcie_pme_handle_request(port, rtsta & 0xffff); | ||
299 | spin_lock_irq(&data->lock); | ||
300 | |||
301 | continue; | ||
302 | } | ||
303 | |||
304 | /* No need to loop if there are no more PMEs pending. */ | ||
305 | if (!(rtsta & PCI_EXP_RTSTA_PENDING)) | ||
306 | break; | ||
307 | |||
308 | spin_unlock_irq(&data->lock); | ||
309 | cpu_relax(); | ||
310 | spin_lock_irq(&data->lock); | ||
311 | } | ||
312 | |||
313 | if (!data->noirq) | ||
314 | pcie_pme_interrupt_enable(port, true); | ||
315 | |||
316 | spin_unlock_irq(&data->lock); | ||
317 | } | ||
318 | |||
319 | /** | ||
320 | * pcie_pme_irq - Interrupt handler for PCIe root port PME interrupt. | ||
321 | * @irq: Interrupt vector. | ||
322 | * @context: Interrupt context pointer. | ||
323 | */ | ||
324 | static irqreturn_t pcie_pme_irq(int irq, void *context) | ||
325 | { | ||
326 | struct pci_dev *port; | ||
327 | struct pcie_pme_service_data *data; | ||
328 | int rtsta_pos; | ||
329 | u32 rtsta; | ||
330 | unsigned long flags; | ||
331 | |||
332 | port = ((struct pcie_device *)context)->port; | ||
333 | data = get_service_data((struct pcie_device *)context); | ||
334 | |||
335 | rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA; | ||
336 | |||
337 | spin_lock_irqsave(&data->lock, flags); | ||
338 | pci_read_config_dword(port, rtsta_pos, &rtsta); | ||
339 | |||
340 | if (!(rtsta & PCI_EXP_RTSTA_PME)) { | ||
341 | spin_unlock_irqrestore(&data->lock, flags); | ||
342 | return IRQ_NONE; | ||
343 | } | ||
344 | |||
345 | pcie_pme_interrupt_enable(port, false); | ||
346 | spin_unlock_irqrestore(&data->lock, flags); | ||
347 | |||
348 | /* We don't use pm_wq, because it's freezable. */ | ||
349 | schedule_work(&data->work); | ||
350 | |||
351 | return IRQ_HANDLED; | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * pcie_pme_set_native - Set the PME interrupt flag for given device. | ||
356 | * @dev: PCI device to handle. | ||
357 | * @ign: Ignored. | ||
358 | */ | ||
359 | static int pcie_pme_set_native(struct pci_dev *dev, void *ign) | ||
360 | { | ||
361 | dev_info(&dev->dev, "Signaling PME through PCIe PME interrupt\n"); | ||
362 | |||
363 | device_set_run_wake(&dev->dev, true); | ||
364 | dev->pme_interrupt = true; | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * pcie_pme_mark_devices - Set the PME interrupt flag for devices below a port. | ||
370 | * @port: PCIe root port or event collector to handle. | ||
371 | * | ||
372 | * For each device below given root port, including the port itself (or for each | ||
373 | * root complex integrated endpoint if @port is a root complex event collector) | ||
374 | * set the flag indicating that it can signal run-time wake-up events via PCIe | ||
375 | * PME interrupts. | ||
376 | */ | ||
377 | static void pcie_pme_mark_devices(struct pci_dev *port) | ||
378 | { | ||
379 | pcie_pme_set_native(port, NULL); | ||
380 | if (port->subordinate) { | ||
381 | pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL); | ||
382 | } else { | ||
383 | struct pci_bus *bus = port->bus; | ||
384 | struct pci_dev *dev; | ||
385 | |||
386 | /* Check if this is a root port event collector. */ | ||
387 | if (port->pcie_type != PCI_EXP_TYPE_RC_EC || !bus) | ||
388 | return; | ||
389 | |||
390 | down_read(&pci_bus_sem); | ||
391 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
392 | if (pci_is_pcie(dev) | ||
393 | && dev->pcie_type == PCI_EXP_TYPE_RC_END) | ||
394 | pcie_pme_set_native(dev, NULL); | ||
395 | up_read(&pci_bus_sem); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | /** | ||
400 | * pcie_pme_probe - Initialize PCIe PME service for given root port. | ||
401 | * @srv: PCIe service to initialize. | ||
402 | */ | ||
403 | static int pcie_pme_probe(struct pcie_device *srv) | ||
404 | { | ||
405 | struct pci_dev *port; | ||
406 | struct pcie_pme_service_data *data; | ||
407 | int ret; | ||
408 | |||
409 | if (!pcie_pme_platform_setup(srv)) | ||
410 | return -EACCES; | ||
411 | |||
412 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
413 | if (!data) | ||
414 | return -ENOMEM; | ||
415 | |||
416 | spin_lock_init(&data->lock); | ||
417 | INIT_WORK(&data->work, pcie_pme_work_fn); | ||
418 | data->srv = srv; | ||
419 | set_service_data(srv, data); | ||
420 | |||
421 | port = srv->port; | ||
422 | pcie_pme_interrupt_enable(port, false); | ||
423 | pcie_pme_clear_status(port); | ||
424 | |||
425 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); | ||
426 | if (ret) { | ||
427 | kfree(data); | ||
428 | } else { | ||
429 | pcie_pme_mark_devices(port); | ||
430 | pcie_pme_interrupt_enable(port, true); | ||
431 | } | ||
432 | |||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | /** | ||
437 | * pcie_pme_suspend - Suspend PCIe PME service device. | ||
438 | * @srv: PCIe service device to suspend. | ||
439 | */ | ||
440 | static int pcie_pme_suspend(struct pcie_device *srv) | ||
441 | { | ||
442 | struct pcie_pme_service_data *data = get_service_data(srv); | ||
443 | struct pci_dev *port = srv->port; | ||
444 | |||
445 | spin_lock_irq(&data->lock); | ||
446 | pcie_pme_interrupt_enable(port, false); | ||
447 | pcie_pme_clear_status(port); | ||
448 | data->noirq = true; | ||
449 | spin_unlock_irq(&data->lock); | ||
450 | |||
451 | synchronize_irq(srv->irq); | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * pcie_pme_resume - Resume PCIe PME service device. | ||
458 | * @srv - PCIe service device to resume. | ||
459 | */ | ||
460 | static int pcie_pme_resume(struct pcie_device *srv) | ||
461 | { | ||
462 | struct pcie_pme_service_data *data = get_service_data(srv); | ||
463 | struct pci_dev *port = srv->port; | ||
464 | |||
465 | spin_lock_irq(&data->lock); | ||
466 | data->noirq = false; | ||
467 | pcie_pme_clear_status(port); | ||
468 | pcie_pme_interrupt_enable(port, true); | ||
469 | spin_unlock_irq(&data->lock); | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * pcie_pme_remove - Prepare PCIe PME service device for removal. | ||
476 | * @srv - PCIe service device to resume. | ||
477 | */ | ||
478 | static void pcie_pme_remove(struct pcie_device *srv) | ||
479 | { | ||
480 | pcie_pme_suspend(srv); | ||
481 | free_irq(srv->irq, srv); | ||
482 | kfree(get_service_data(srv)); | ||
483 | } | ||
484 | |||
485 | static struct pcie_port_service_driver pcie_pme_driver = { | ||
486 | .name = "pcie_pme", | ||
487 | .port_type = PCI_EXP_TYPE_ROOT_PORT, | ||
488 | .service = PCIE_PORT_SERVICE_PME, | ||
489 | |||
490 | .probe = pcie_pme_probe, | ||
491 | .suspend = pcie_pme_suspend, | ||
492 | .resume = pcie_pme_resume, | ||
493 | .remove = pcie_pme_remove, | ||
494 | }; | ||
495 | |||
496 | /** | ||
497 | * pcie_pme_service_init - Register the PCIe PME service driver. | ||
498 | */ | ||
499 | static int __init pcie_pme_service_init(void) | ||
500 | { | ||
501 | return pcie_pme_disabled ? | ||
502 | -ENODEV : pcie_port_service_register(&pcie_pme_driver); | ||
503 | } | ||
504 | |||
505 | module_init(pcie_pme_service_init); | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme.h b/drivers/pci/pcie/pme/pcie_pme.h new file mode 100644 index 000000000000..b30d2b7c9775 --- /dev/null +++ b/drivers/pci/pcie/pme/pcie_pme.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * drivers/pci/pcie/pme/pcie_pme.h | ||
3 | * | ||
4 | * PCI Express Root Port PME signaling support | ||
5 | * | ||
6 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
7 | */ | ||
8 | |||
9 | #ifndef _PCIE_PME_H_ | ||
10 | #define _PCIE_PME_H_ | ||
11 | |||
12 | struct pcie_device; | ||
13 | |||
14 | #ifdef CONFIG_ACPI | ||
15 | extern int pcie_pme_acpi_setup(struct pcie_device *srv); | ||
16 | |||
17 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
18 | { | ||
19 | return pcie_pme_acpi_setup(srv); | ||
20 | } | ||
21 | #else /* !CONFIG_ACPI */ | ||
22 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | #endif /* !CONFIG_ACPI */ | ||
27 | |||
28 | #endif | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme_acpi.c b/drivers/pci/pcie/pme/pcie_pme_acpi.c new file mode 100644 index 000000000000..83ab2287ae3f --- /dev/null +++ b/drivers/pci/pcie/pme/pcie_pme_acpi.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * PCIe Native PME support, ACPI-related part | ||
3 | * | ||
4 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License V2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/pci-acpi.h> | ||
16 | #include <linux/pcieport_if.h> | ||
17 | |||
18 | /** | ||
19 | * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME. | ||
20 | * @srv - PCIe PME service for a root port or event collector. | ||
21 | * | ||
22 | * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid | ||
23 | * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME | ||
24 | * control to the kernel. | ||
25 | */ | ||
26 | int pcie_pme_acpi_setup(struct pcie_device *srv) | ||
27 | { | ||
28 | acpi_status status = AE_NOT_FOUND; | ||
29 | struct pci_dev *port = srv->port; | ||
30 | acpi_handle handle; | ||
31 | int error = 0; | ||
32 | |||
33 | if (acpi_pci_disabled) | ||
34 | return -ENOSYS; | ||
35 | |||
36 | dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n"); | ||
37 | |||
38 | handle = acpi_find_root_bridge_handle(port); | ||
39 | if (!handle) | ||
40 | return -EINVAL; | ||
41 | |||
42 | status = acpi_pci_osc_control_set(handle, | ||
43 | OSC_PCI_EXPRESS_PME_CONTROL | | ||
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
45 | if (ACPI_FAILURE(status)) { | ||
46 | dev_info(&port->dev, | ||
47 | "Failed to receive control of PCIe PME service: %s\n", | ||
48 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? | ||
49 | "no _OSC support" : "ACPI _OSC failed"); | ||
50 | error = -ENODEV; | ||
51 | } | ||
52 | |||
53 | return error; | ||
54 | } | ||
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index aaeb9d21cba5..813a5c3427b6 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -30,4 +30,21 @@ extern void pcie_port_device_remove(struct pci_dev *dev); | |||
30 | extern int __must_check pcie_port_bus_register(void); | 30 | extern int __must_check pcie_port_bus_register(void); |
31 | extern void pcie_port_bus_unregister(void); | 31 | extern void pcie_port_bus_unregister(void); |
32 | 32 | ||
33 | #ifdef CONFIG_PCIE_PME | ||
34 | extern bool pcie_pme_msi_disabled; | ||
35 | |||
36 | static inline void pcie_pme_disable_msi(void) | ||
37 | { | ||
38 | pcie_pme_msi_disabled = true; | ||
39 | } | ||
40 | |||
41 | static inline bool pcie_pme_no_msi(void) | ||
42 | { | ||
43 | return pcie_pme_msi_disabled; | ||
44 | } | ||
45 | #else /* !CONFIG_PCIE_PME */ | ||
46 | static inline void pcie_pme_disable_msi(void) {} | ||
47 | static inline bool pcie_pme_no_msi(void) { return false; } | ||
48 | #endif /* !CONFIG_PCIE_PME */ | ||
49 | |||
33 | #endif /* _PORTDRV_H_ */ | 50 | #endif /* _PORTDRV_H_ */ |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 413262eb95b7..e73effbe402c 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | static void release_pcie_device(struct device *dev) | 28 | static void release_pcie_device(struct device *dev) |
29 | { | 29 | { |
30 | kfree(to_pcie_device(dev)); | 30 | kfree(to_pcie_device(dev)); |
31 | } | 31 | } |
32 | 32 | ||
33 | /** | 33 | /** |
@@ -186,16 +186,24 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
186 | */ | 186 | */ |
187 | static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) | 187 | static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) |
188 | { | 188 | { |
189 | int i, irq; | 189 | int i, irq = -1; |
190 | |||
191 | /* We have to use INTx if MSI cannot be used for PCIe PME. */ | ||
192 | if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) { | ||
193 | if (dev->pin) | ||
194 | irq = dev->irq; | ||
195 | goto no_msi; | ||
196 | } | ||
190 | 197 | ||
191 | /* Try to use MSI-X if supported */ | 198 | /* Try to use MSI-X if supported */ |
192 | if (!pcie_port_enable_msix(dev, irqs, mask)) | 199 | if (!pcie_port_enable_msix(dev, irqs, mask)) |
193 | return 0; | 200 | return 0; |
201 | |||
194 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ | 202 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ |
195 | irq = -1; | ||
196 | if (!pci_enable_msi(dev) || dev->pin) | 203 | if (!pci_enable_msi(dev) || dev->pin) |
197 | irq = dev->irq; | 204 | irq = dev->irq; |
198 | 205 | ||
206 | no_msi: | ||
199 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) | 207 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) |
200 | irqs[i] = irq; | 208 | irqs[i] = irq; |
201 | irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | 209 | irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1; |
@@ -277,6 +285,7 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) | |||
277 | pci_name(pdev), | 285 | pci_name(pdev), |
278 | get_descriptor_id(pdev->pcie_type, service)); | 286 | get_descriptor_id(pdev->pcie_type, service)); |
279 | device->parent = &pdev->dev; | 287 | device->parent = &pdev->dev; |
288 | device_enable_async_suspend(device); | ||
280 | 289 | ||
281 | retval = device_register(device); | 290 | retval = device_register(device); |
282 | if (retval) | 291 | if (retval) |
@@ -346,12 +355,11 @@ static int suspend_iter(struct device *dev, void *data) | |||
346 | { | 355 | { |
347 | struct pcie_port_service_driver *service_driver; | 356 | struct pcie_port_service_driver *service_driver; |
348 | 357 | ||
349 | if ((dev->bus == &pcie_port_bus_type) && | 358 | if ((dev->bus == &pcie_port_bus_type) && dev->driver) { |
350 | (dev->driver)) { | 359 | service_driver = to_service_driver(dev->driver); |
351 | service_driver = to_service_driver(dev->driver); | 360 | if (service_driver->suspend) |
352 | if (service_driver->suspend) | 361 | service_driver->suspend(to_pcie_device(dev)); |
353 | service_driver->suspend(to_pcie_device(dev)); | 362 | } |
354 | } | ||
355 | return 0; | 363 | return 0; |
356 | } | 364 | } |
357 | 365 | ||
@@ -494,6 +502,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) | |||
494 | 502 | ||
495 | return driver_register(&new->driver); | 503 | return driver_register(&new->driver); |
496 | } | 504 | } |
505 | EXPORT_SYMBOL(pcie_port_service_register); | ||
497 | 506 | ||
498 | /** | 507 | /** |
499 | * pcie_port_service_unregister - unregister PCI Express port service driver | 508 | * pcie_port_service_unregister - unregister PCI Express port service driver |
@@ -503,6 +512,4 @@ void pcie_port_service_unregister(struct pcie_port_service_driver *drv) | |||
503 | { | 512 | { |
504 | driver_unregister(&drv->driver); | 513 | driver_unregister(&drv->driver); |
505 | } | 514 | } |
506 | |||
507 | EXPORT_SYMBOL(pcie_port_service_register); | ||
508 | EXPORT_SYMBOL(pcie_port_service_unregister); | 515 | EXPORT_SYMBOL(pcie_port_service_unregister); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index a49452e2aed9..127e8f169d9c 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 16 | #include <linux/pcieport_if.h> |
17 | #include <linux/aer.h> | 17 | #include <linux/aer.h> |
18 | #include <linux/dmi.h> | ||
18 | 19 | ||
19 | #include "portdrv.h" | 20 | #include "portdrv.h" |
20 | #include "aer/aerdrv.h" | 21 | #include "aer/aerdrv.h" |
@@ -24,7 +25,7 @@ | |||
24 | */ | 25 | */ |
25 | #define DRIVER_VERSION "v1.0" | 26 | #define DRIVER_VERSION "v1.0" |
26 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" | 27 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" |
27 | #define DRIVER_DESC "PCIE Port Bus Driver" | 28 | #define DRIVER_DESC "PCIe Port Bus Driver" |
28 | MODULE_AUTHOR(DRIVER_AUTHOR); | 29 | MODULE_AUTHOR(DRIVER_AUTHOR); |
29 | MODULE_DESCRIPTION(DRIVER_DESC); | 30 | MODULE_DESCRIPTION(DRIVER_DESC); |
30 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
@@ -63,7 +64,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
63 | * pcie_portdrv_probe - Probe PCI-Express port devices | 64 | * pcie_portdrv_probe - Probe PCI-Express port devices |
64 | * @dev: PCI-Express port device being probed | 65 | * @dev: PCI-Express port device being probed |
65 | * | 66 | * |
66 | * If detected invokes the pcie_port_device_register() method for | 67 | * If detected invokes the pcie_port_device_register() method for |
67 | * this port device. | 68 | * this port device. |
68 | * | 69 | * |
69 | */ | 70 | */ |
@@ -78,7 +79,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, | |||
78 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) | 79 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) |
79 | return -ENODEV; | 80 | return -ENODEV; |
80 | 81 | ||
81 | if (!dev->irq && dev->pin) { | 82 | if (!dev->irq && dev->pin) { |
82 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " | 83 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " |
83 | "check vendor BIOS\n", dev->vendor, dev->device); | 84 | "check vendor BIOS\n", dev->vendor, dev->device); |
84 | } | 85 | } |
@@ -91,7 +92,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, | |||
91 | return 0; | 92 | return 0; |
92 | } | 93 | } |
93 | 94 | ||
94 | static void pcie_portdrv_remove (struct pci_dev *dev) | 95 | static void pcie_portdrv_remove(struct pci_dev *dev) |
95 | { | 96 | { |
96 | pcie_port_device_remove(dev); | 97 | pcie_port_device_remove(dev); |
97 | pci_disable_device(dev); | 98 | pci_disable_device(dev); |
@@ -129,14 +130,13 @@ static int error_detected_iter(struct device *device, void *data) | |||
129 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, | 130 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, |
130 | enum pci_channel_state error) | 131 | enum pci_channel_state error) |
131 | { | 132 | { |
132 | struct aer_broadcast_data result_data = | 133 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; |
133 | {error, PCI_ERS_RESULT_CAN_RECOVER}; | 134 | int ret; |
134 | int retval; | ||
135 | 135 | ||
136 | /* can not fail */ | 136 | /* can not fail */ |
137 | retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); | 137 | ret = device_for_each_child(&dev->dev, &data, error_detected_iter); |
138 | 138 | ||
139 | return result_data.result; | 139 | return data.result; |
140 | } | 140 | } |
141 | 141 | ||
142 | static int mmio_enabled_iter(struct device *device, void *data) | 142 | static int mmio_enabled_iter(struct device *device, void *data) |
@@ -274,10 +274,36 @@ static struct pci_driver pcie_portdriver = { | |||
274 | .driver.pm = PCIE_PORTDRV_PM_OPS, | 274 | .driver.pm = PCIE_PORTDRV_PM_OPS, |
275 | }; | 275 | }; |
276 | 276 | ||
277 | static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d) | ||
278 | { | ||
279 | pr_notice("%s detected: will not use MSI for PCIe PME signaling\n", | ||
280 | d->ident); | ||
281 | pcie_pme_disable_msi(); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = { | ||
286 | /* | ||
287 | * Boxes that should not use MSI for PCIe PME signaling. | ||
288 | */ | ||
289 | { | ||
290 | .callback = dmi_pcie_pme_disable_msi, | ||
291 | .ident = "MSI Wind U-100", | ||
292 | .matches = { | ||
293 | DMI_MATCH(DMI_SYS_VENDOR, | ||
294 | "MICRO-STAR INTERNATIONAL CO., LTD"), | ||
295 | DMI_MATCH(DMI_PRODUCT_NAME, "U-100"), | ||
296 | }, | ||
297 | }, | ||
298 | {} | ||
299 | }; | ||
300 | |||
277 | static int __init pcie_portdrv_init(void) | 301 | static int __init pcie_portdrv_init(void) |
278 | { | 302 | { |
279 | int retval; | 303 | int retval; |
280 | 304 | ||
305 | dmi_check_system(pcie_portdrv_dmi_table); | ||
306 | |||
281 | retval = pcie_port_bus_register(); | 307 | retval = pcie_port_bus_register(); |
282 | if (retval) { | 308 | if (retval) { |
283 | printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); | 309 | printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); |
@@ -290,7 +316,7 @@ static int __init pcie_portdrv_init(void) | |||
290 | return retval; | 316 | return retval; |
291 | } | 317 | } |
292 | 318 | ||
293 | static void __exit pcie_portdrv_exit(void) | 319 | static void __exit pcie_portdrv_exit(void) |
294 | { | 320 | { |
295 | pci_unregister_driver(&pcie_portdriver); | 321 | pci_unregister_driver(&pcie_portdriver); |
296 | pcie_port_bus_unregister(); | 322 | pcie_port_bus_unregister(); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 98ffb2de22e9..882bd8d29fe3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -89,6 +89,7 @@ static void release_pcibus_dev(struct device *dev) | |||
89 | 89 | ||
90 | if (pci_bus->bridge) | 90 | if (pci_bus->bridge) |
91 | put_device(pci_bus->bridge); | 91 | put_device(pci_bus->bridge); |
92 | pci_bus_remove_resources(pci_bus); | ||
92 | kfree(pci_bus); | 93 | kfree(pci_bus); |
93 | } | 94 | } |
94 | 95 | ||
@@ -173,14 +174,19 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
173 | pci_read_config_dword(dev, pos, &sz); | 174 | pci_read_config_dword(dev, pos, &sz); |
174 | pci_write_config_dword(dev, pos, l); | 175 | pci_write_config_dword(dev, pos, l); |
175 | 176 | ||
177 | if (!sz) | ||
178 | goto fail; /* BAR not implemented */ | ||
179 | |||
176 | /* | 180 | /* |
177 | * All bits set in sz means the device isn't working properly. | 181 | * All bits set in sz means the device isn't working properly. |
178 | * If the BAR isn't implemented, all bits must be 0. If it's a | 182 | * If it's a memory BAR or a ROM, bit 0 must be clear; if it's |
179 | * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit | 183 | * an io BAR, bit 1 must be clear. |
180 | * 1 must be clear. | ||
181 | */ | 184 | */ |
182 | if (!sz || sz == 0xffffffff) | 185 | if (sz == 0xffffffff) { |
186 | dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n", | ||
187 | pos, sz); | ||
183 | goto fail; | 188 | goto fail; |
189 | } | ||
184 | 190 | ||
185 | /* | 191 | /* |
186 | * I don't know how l can have all bits set. Copied from old code. | 192 | * I don't know how l can have all bits set. Copied from old code. |
@@ -243,13 +249,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
243 | pos, res); | 249 | pos, res); |
244 | } | 250 | } |
245 | } else { | 251 | } else { |
246 | sz = pci_size(l, sz, mask); | 252 | u32 size = pci_size(l, sz, mask); |
247 | 253 | ||
248 | if (!sz) | 254 | if (!size) { |
255 | dev_err(&dev->dev, "reg %x: invalid size " | ||
256 | "(l %#x sz %#x mask %#x); broken device?", | ||
257 | pos, l, sz, mask); | ||
249 | goto fail; | 258 | goto fail; |
259 | } | ||
250 | 260 | ||
251 | res->start = l; | 261 | res->start = l; |
252 | res->end = l + sz; | 262 | res->end = l + size; |
253 | 263 | ||
254 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | 264 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
255 | } | 265 | } |
@@ -281,26 +291,12 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) | |||
281 | } | 291 | } |
282 | } | 292 | } |
283 | 293 | ||
284 | void __devinit pci_read_bridge_bases(struct pci_bus *child) | 294 | static void __devinit pci_read_bridge_io(struct pci_bus *child) |
285 | { | 295 | { |
286 | struct pci_dev *dev = child->self; | 296 | struct pci_dev *dev = child->self; |
287 | u8 io_base_lo, io_limit_lo; | 297 | u8 io_base_lo, io_limit_lo; |
288 | u16 mem_base_lo, mem_limit_lo; | ||
289 | unsigned long base, limit; | 298 | unsigned long base, limit; |
290 | struct resource *res; | 299 | struct resource *res; |
291 | int i; | ||
292 | |||
293 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | ||
294 | return; | ||
295 | |||
296 | dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", | ||
297 | child->secondary, child->subordinate, | ||
298 | dev->transparent ? " (subtractive decode)": ""); | ||
299 | |||
300 | if (dev->transparent) { | ||
301 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | ||
302 | child->resource[i] = child->parent->resource[i - 3]; | ||
303 | } | ||
304 | 300 | ||
305 | res = child->resource[0]; | 301 | res = child->resource[0]; |
306 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | 302 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); |
@@ -316,26 +312,50 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
316 | limit |= (io_limit_hi << 16); | 312 | limit |= (io_limit_hi << 16); |
317 | } | 313 | } |
318 | 314 | ||
319 | if (base <= limit) { | 315 | if (base && base <= limit) { |
320 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | 316 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; |
321 | if (!res->start) | 317 | if (!res->start) |
322 | res->start = base; | 318 | res->start = base; |
323 | if (!res->end) | 319 | if (!res->end) |
324 | res->end = limit + 0xfff; | 320 | res->end = limit + 0xfff; |
325 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 321 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
322 | } else { | ||
323 | dev_printk(KERN_DEBUG, &dev->dev, | ||
324 | " bridge window [io %#06lx-%#06lx] (disabled)\n", | ||
325 | base, limit); | ||
326 | } | 326 | } |
327 | } | ||
328 | |||
329 | static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | ||
330 | { | ||
331 | struct pci_dev *dev = child->self; | ||
332 | u16 mem_base_lo, mem_limit_lo; | ||
333 | unsigned long base, limit; | ||
334 | struct resource *res; | ||
327 | 335 | ||
328 | res = child->resource[1]; | 336 | res = child->resource[1]; |
329 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | 337 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); |
330 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | 338 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); |
331 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | 339 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; |
332 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | 340 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; |
333 | if (base <= limit) { | 341 | if (base && base <= limit) { |
334 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 342 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
335 | res->start = base; | 343 | res->start = base; |
336 | res->end = limit + 0xfffff; | 344 | res->end = limit + 0xfffff; |
337 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 345 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
346 | } else { | ||
347 | dev_printk(KERN_DEBUG, &dev->dev, | ||
348 | " bridge window [mem %#010lx-%#010lx] (disabled)\n", | ||
349 | base, limit + 0xfffff); | ||
338 | } | 350 | } |
351 | } | ||
352 | |||
353 | static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | ||
354 | { | ||
355 | struct pci_dev *dev = child->self; | ||
356 | u16 mem_base_lo, mem_limit_lo; | ||
357 | unsigned long base, limit; | ||
358 | struct resource *res; | ||
339 | 359 | ||
340 | res = child->resource[2]; | 360 | res = child->resource[2]; |
341 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | 361 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); |
@@ -366,7 +386,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
366 | #endif | 386 | #endif |
367 | } | 387 | } |
368 | } | 388 | } |
369 | if (base <= limit) { | 389 | if (base && base <= limit) { |
370 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | | 390 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | |
371 | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 391 | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
372 | if (res->flags & PCI_PREF_RANGE_TYPE_64) | 392 | if (res->flags & PCI_PREF_RANGE_TYPE_64) |
@@ -374,6 +394,44 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
374 | res->start = base; | 394 | res->start = base; |
375 | res->end = limit + 0xfffff; | 395 | res->end = limit + 0xfffff; |
376 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 396 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
397 | } else { | ||
398 | dev_printk(KERN_DEBUG, &dev->dev, | ||
399 | " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", | ||
400 | base, limit + 0xfffff); | ||
401 | } | ||
402 | } | ||
403 | |||
404 | void __devinit pci_read_bridge_bases(struct pci_bus *child) | ||
405 | { | ||
406 | struct pci_dev *dev = child->self; | ||
407 | struct resource *res; | ||
408 | int i; | ||
409 | |||
410 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | ||
411 | return; | ||
412 | |||
413 | dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", | ||
414 | child->secondary, child->subordinate, | ||
415 | dev->transparent ? " (subtractive decode)" : ""); | ||
416 | |||
417 | pci_bus_remove_resources(child); | ||
418 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) | ||
419 | child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i]; | ||
420 | |||
421 | pci_read_bridge_io(child); | ||
422 | pci_read_bridge_mmio(child); | ||
423 | pci_read_bridge_mmio_pref(child); | ||
424 | |||
425 | if (dev->transparent) { | ||
426 | pci_bus_for_each_resource(child->parent, res, i) { | ||
427 | if (res) { | ||
428 | pci_bus_add_resource(child, res, | ||
429 | PCI_SUBTRACTIVE_DECODE); | ||
430 | dev_printk(KERN_DEBUG, &dev->dev, | ||
431 | " bridge window %pR (subtractive decode)\n", | ||
432 | res); | ||
433 | } | ||
434 | } | ||
377 | } | 435 | } |
378 | } | 436 | } |
379 | 437 | ||
@@ -387,10 +445,147 @@ static struct pci_bus * pci_alloc_bus(void) | |||
387 | INIT_LIST_HEAD(&b->children); | 445 | INIT_LIST_HEAD(&b->children); |
388 | INIT_LIST_HEAD(&b->devices); | 446 | INIT_LIST_HEAD(&b->devices); |
389 | INIT_LIST_HEAD(&b->slots); | 447 | INIT_LIST_HEAD(&b->slots); |
448 | INIT_LIST_HEAD(&b->resources); | ||
449 | b->max_bus_speed = PCI_SPEED_UNKNOWN; | ||
450 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; | ||
390 | } | 451 | } |
391 | return b; | 452 | return b; |
392 | } | 453 | } |
393 | 454 | ||
455 | static unsigned char pcix_bus_speed[] = { | ||
456 | PCI_SPEED_UNKNOWN, /* 0 */ | ||
457 | PCI_SPEED_66MHz_PCIX, /* 1 */ | ||
458 | PCI_SPEED_100MHz_PCIX, /* 2 */ | ||
459 | PCI_SPEED_133MHz_PCIX, /* 3 */ | ||
460 | PCI_SPEED_UNKNOWN, /* 4 */ | ||
461 | PCI_SPEED_66MHz_PCIX_ECC, /* 5 */ | ||
462 | PCI_SPEED_100MHz_PCIX_ECC, /* 6 */ | ||
463 | PCI_SPEED_133MHz_PCIX_ECC, /* 7 */ | ||
464 | PCI_SPEED_UNKNOWN, /* 8 */ | ||
465 | PCI_SPEED_66MHz_PCIX_266, /* 9 */ | ||
466 | PCI_SPEED_100MHz_PCIX_266, /* A */ | ||
467 | PCI_SPEED_133MHz_PCIX_266, /* B */ | ||
468 | PCI_SPEED_UNKNOWN, /* C */ | ||
469 | PCI_SPEED_66MHz_PCIX_533, /* D */ | ||
470 | PCI_SPEED_100MHz_PCIX_533, /* E */ | ||
471 | PCI_SPEED_133MHz_PCIX_533 /* F */ | ||
472 | }; | ||
473 | |||
474 | static unsigned char pcie_link_speed[] = { | ||
475 | PCI_SPEED_UNKNOWN, /* 0 */ | ||
476 | PCIE_SPEED_2_5GT, /* 1 */ | ||
477 | PCIE_SPEED_5_0GT, /* 2 */ | ||
478 | PCIE_SPEED_8_0GT, /* 3 */ | ||
479 | PCI_SPEED_UNKNOWN, /* 4 */ | ||
480 | PCI_SPEED_UNKNOWN, /* 5 */ | ||
481 | PCI_SPEED_UNKNOWN, /* 6 */ | ||
482 | PCI_SPEED_UNKNOWN, /* 7 */ | ||
483 | PCI_SPEED_UNKNOWN, /* 8 */ | ||
484 | PCI_SPEED_UNKNOWN, /* 9 */ | ||
485 | PCI_SPEED_UNKNOWN, /* A */ | ||
486 | PCI_SPEED_UNKNOWN, /* B */ | ||
487 | PCI_SPEED_UNKNOWN, /* C */ | ||
488 | PCI_SPEED_UNKNOWN, /* D */ | ||
489 | PCI_SPEED_UNKNOWN, /* E */ | ||
490 | PCI_SPEED_UNKNOWN /* F */ | ||
491 | }; | ||
492 | |||
493 | void pcie_update_link_speed(struct pci_bus *bus, u16 linksta) | ||
494 | { | ||
495 | bus->cur_bus_speed = pcie_link_speed[linksta & 0xf]; | ||
496 | } | ||
497 | EXPORT_SYMBOL_GPL(pcie_update_link_speed); | ||
498 | |||
499 | static unsigned char agp_speeds[] = { | ||
500 | AGP_UNKNOWN, | ||
501 | AGP_1X, | ||
502 | AGP_2X, | ||
503 | AGP_4X, | ||
504 | AGP_8X | ||
505 | }; | ||
506 | |||
507 | static enum pci_bus_speed agp_speed(int agp3, int agpstat) | ||
508 | { | ||
509 | int index = 0; | ||
510 | |||
511 | if (agpstat & 4) | ||
512 | index = 3; | ||
513 | else if (agpstat & 2) | ||
514 | index = 2; | ||
515 | else if (agpstat & 1) | ||
516 | index = 1; | ||
517 | else | ||
518 | goto out; | ||
519 | |||
520 | if (agp3) { | ||
521 | index += 2; | ||
522 | if (index == 5) | ||
523 | index = 0; | ||
524 | } | ||
525 | |||
526 | out: | ||
527 | return agp_speeds[index]; | ||
528 | } | ||
529 | |||
530 | |||
531 | static void pci_set_bus_speed(struct pci_bus *bus) | ||
532 | { | ||
533 | struct pci_dev *bridge = bus->self; | ||
534 | int pos; | ||
535 | |||
536 | pos = pci_find_capability(bridge, PCI_CAP_ID_AGP); | ||
537 | if (!pos) | ||
538 | pos = pci_find_capability(bridge, PCI_CAP_ID_AGP3); | ||
539 | if (pos) { | ||
540 | u32 agpstat, agpcmd; | ||
541 | |||
542 | pci_read_config_dword(bridge, pos + PCI_AGP_STATUS, &agpstat); | ||
543 | bus->max_bus_speed = agp_speed(agpstat & 8, agpstat & 7); | ||
544 | |||
545 | pci_read_config_dword(bridge, pos + PCI_AGP_COMMAND, &agpcmd); | ||
546 | bus->cur_bus_speed = agp_speed(agpstat & 8, agpcmd & 7); | ||
547 | } | ||
548 | |||
549 | pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX); | ||
550 | if (pos) { | ||
551 | u16 status; | ||
552 | enum pci_bus_speed max; | ||
553 | pci_read_config_word(bridge, pos + 2, &status); | ||
554 | |||
555 | if (status & 0x8000) { | ||
556 | max = PCI_SPEED_133MHz_PCIX_533; | ||
557 | } else if (status & 0x4000) { | ||
558 | max = PCI_SPEED_133MHz_PCIX_266; | ||
559 | } else if (status & 0x0002) { | ||
560 | if (((status >> 12) & 0x3) == 2) { | ||
561 | max = PCI_SPEED_133MHz_PCIX_ECC; | ||
562 | } else { | ||
563 | max = PCI_SPEED_133MHz_PCIX; | ||
564 | } | ||
565 | } else { | ||
566 | max = PCI_SPEED_66MHz_PCIX; | ||
567 | } | ||
568 | |||
569 | bus->max_bus_speed = max; | ||
570 | bus->cur_bus_speed = pcix_bus_speed[(status >> 6) & 0xf]; | ||
571 | |||
572 | return; | ||
573 | } | ||
574 | |||
575 | pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); | ||
576 | if (pos) { | ||
577 | u32 linkcap; | ||
578 | u16 linksta; | ||
579 | |||
580 | pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap); | ||
581 | bus->max_bus_speed = pcie_link_speed[linkcap & 0xf]; | ||
582 | |||
583 | pci_read_config_word(bridge, pos + PCI_EXP_LNKSTA, &linksta); | ||
584 | pcie_update_link_speed(bus, linksta); | ||
585 | } | ||
586 | } | ||
587 | |||
588 | |||
394 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | 589 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, |
395 | struct pci_dev *bridge, int busnr) | 590 | struct pci_dev *bridge, int busnr) |
396 | { | 591 | { |
@@ -430,6 +625,8 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
430 | child->self = bridge; | 625 | child->self = bridge; |
431 | child->bridge = get_device(&bridge->dev); | 626 | child->bridge = get_device(&bridge->dev); |
432 | 627 | ||
628 | pci_set_bus_speed(child); | ||
629 | |||
433 | /* Set up default resource pointers and names.. */ | 630 | /* Set up default resource pointers and names.. */ |
434 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { | 631 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { |
435 | child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; | 632 | child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; |
@@ -485,16 +682,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
485 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 682 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
486 | u32 buses, i, j = 0; | 683 | u32 buses, i, j = 0; |
487 | u16 bctl; | 684 | u16 bctl; |
685 | u8 primary, secondary, subordinate; | ||
488 | int broken = 0; | 686 | int broken = 0; |
489 | 687 | ||
490 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 688 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
689 | primary = buses & 0xFF; | ||
690 | secondary = (buses >> 8) & 0xFF; | ||
691 | subordinate = (buses >> 16) & 0xFF; | ||
491 | 692 | ||
492 | dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", | 693 | dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", |
493 | buses & 0xffffff, pass); | 694 | secondary, subordinate, pass); |
494 | 695 | ||
495 | /* Check if setup is sensible at all */ | 696 | /* Check if setup is sensible at all */ |
496 | if (!pass && | 697 | if (!pass && |
497 | ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { | 698 | (primary != bus->number || secondary <= bus->number)) { |
498 | dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); | 699 | dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); |
499 | broken = 1; | 700 | broken = 1; |
500 | } | 701 | } |
@@ -505,15 +706,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
505 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, | 706 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, |
506 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); | 707 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); |
507 | 708 | ||
508 | if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { | 709 | if ((secondary || subordinate) && !pcibios_assign_all_busses() && |
509 | unsigned int cmax, busnr; | 710 | !is_cardbus && !broken) { |
711 | unsigned int cmax; | ||
510 | /* | 712 | /* |
511 | * Bus already configured by firmware, process it in the first | 713 | * Bus already configured by firmware, process it in the first |
512 | * pass and just note the configuration. | 714 | * pass and just note the configuration. |
513 | */ | 715 | */ |
514 | if (pass) | 716 | if (pass) |
515 | goto out; | 717 | goto out; |
516 | busnr = (buses >> 8) & 0xFF; | ||
517 | 718 | ||
518 | /* | 719 | /* |
519 | * If we already got to this bus through a different bridge, | 720 | * If we already got to this bus through a different bridge, |
@@ -522,13 +723,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
522 | * However, we continue to descend down the hierarchy and | 723 | * However, we continue to descend down the hierarchy and |
523 | * scan remaining child buses. | 724 | * scan remaining child buses. |
524 | */ | 725 | */ |
525 | child = pci_find_bus(pci_domain_nr(bus), busnr); | 726 | child = pci_find_bus(pci_domain_nr(bus), secondary); |
526 | if (!child) { | 727 | if (!child) { |
527 | child = pci_add_new_bus(bus, dev, busnr); | 728 | child = pci_add_new_bus(bus, dev, secondary); |
528 | if (!child) | 729 | if (!child) |
529 | goto out; | 730 | goto out; |
530 | child->primary = buses & 0xFF; | 731 | child->primary = primary; |
531 | child->subordinate = (buses >> 16) & 0xFF; | 732 | child->subordinate = subordinate; |
532 | child->bridge_ctl = bctl; | 733 | child->bridge_ctl = bctl; |
533 | } | 734 | } |
534 | 735 | ||
@@ -681,7 +882,7 @@ static void pci_read_irq(struct pci_dev *dev) | |||
681 | dev->irq = irq; | 882 | dev->irq = irq; |
682 | } | 883 | } |
683 | 884 | ||
684 | static void set_pcie_port_type(struct pci_dev *pdev) | 885 | void set_pcie_port_type(struct pci_dev *pdev) |
685 | { | 886 | { |
686 | int pos; | 887 | int pos; |
687 | u16 reg16; | 888 | u16 reg16; |
@@ -695,7 +896,7 @@ static void set_pcie_port_type(struct pci_dev *pdev) | |||
695 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | 896 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; |
696 | } | 897 | } |
697 | 898 | ||
698 | static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | 899 | void set_pcie_hotplug_bridge(struct pci_dev *pdev) |
699 | { | 900 | { |
700 | int pos; | 901 | int pos; |
701 | u16 reg16; | 902 | u16 reg16; |
@@ -1081,6 +1282,45 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
1081 | } | 1282 | } |
1082 | EXPORT_SYMBOL(pci_scan_single_device); | 1283 | EXPORT_SYMBOL(pci_scan_single_device); |
1083 | 1284 | ||
1285 | static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) | ||
1286 | { | ||
1287 | u16 cap; | ||
1288 | unsigned pos, next_fn; | ||
1289 | |||
1290 | if (!dev) | ||
1291 | return 0; | ||
1292 | |||
1293 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | ||
1294 | if (!pos) | ||
1295 | return 0; | ||
1296 | pci_read_config_word(dev, pos + 4, &cap); | ||
1297 | next_fn = cap >> 8; | ||
1298 | if (next_fn <= fn) | ||
1299 | return 0; | ||
1300 | return next_fn; | ||
1301 | } | ||
1302 | |||
1303 | static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn) | ||
1304 | { | ||
1305 | return (fn + 1) % 8; | ||
1306 | } | ||
1307 | |||
1308 | static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) | ||
1309 | { | ||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | static int only_one_child(struct pci_bus *bus) | ||
1314 | { | ||
1315 | struct pci_dev *parent = bus->self; | ||
1316 | if (!parent || !pci_is_pcie(parent)) | ||
1317 | return 0; | ||
1318 | if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | ||
1319 | parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | ||
1320 | return 1; | ||
1321 | return 0; | ||
1322 | } | ||
1323 | |||
1084 | /** | 1324 | /** |
1085 | * pci_scan_slot - scan a PCI slot on a bus for devices. | 1325 | * pci_scan_slot - scan a PCI slot on a bus for devices. |
1086 | * @bus: PCI bus to scan | 1326 | * @bus: PCI bus to scan |
@@ -1094,21 +1334,30 @@ EXPORT_SYMBOL(pci_scan_single_device); | |||
1094 | */ | 1334 | */ |
1095 | int pci_scan_slot(struct pci_bus *bus, int devfn) | 1335 | int pci_scan_slot(struct pci_bus *bus, int devfn) |
1096 | { | 1336 | { |
1097 | int fn, nr = 0; | 1337 | unsigned fn, nr = 0; |
1098 | struct pci_dev *dev; | 1338 | struct pci_dev *dev; |
1339 | unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn; | ||
1340 | |||
1341 | if (only_one_child(bus) && (devfn > 0)) | ||
1342 | return 0; /* Already scanned the entire slot */ | ||
1099 | 1343 | ||
1100 | dev = pci_scan_single_device(bus, devfn); | 1344 | dev = pci_scan_single_device(bus, devfn); |
1101 | if (dev && !dev->is_added) /* new device? */ | 1345 | if (!dev) |
1346 | return 0; | ||
1347 | if (!dev->is_added) | ||
1102 | nr++; | 1348 | nr++; |
1103 | 1349 | ||
1104 | if (dev && dev->multifunction) { | 1350 | if (pci_ari_enabled(bus)) |
1105 | for (fn = 1; fn < 8; fn++) { | 1351 | next_fn = next_ari_fn; |
1106 | dev = pci_scan_single_device(bus, devfn + fn); | 1352 | else if (dev->multifunction) |
1107 | if (dev) { | 1353 | next_fn = next_trad_fn; |
1108 | if (!dev->is_added) | 1354 | |
1109 | nr++; | 1355 | for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) { |
1110 | dev->multifunction = 1; | 1356 | dev = pci_scan_single_device(bus, devfn + fn); |
1111 | } | 1357 | if (dev) { |
1358 | if (!dev->is_added) | ||
1359 | nr++; | ||
1360 | dev->multifunction = 1; | ||
1112 | } | 1361 | } |
1113 | } | 1362 | } |
1114 | 1363 | ||
@@ -1200,6 +1449,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1200 | if (error) | 1449 | if (error) |
1201 | goto dev_reg_err; | 1450 | goto dev_reg_err; |
1202 | b->bridge = get_device(dev); | 1451 | b->bridge = get_device(dev); |
1452 | device_enable_async_suspend(b->bridge); | ||
1203 | 1453 | ||
1204 | if (!parent) | 1454 | if (!parent) |
1205 | set_dev_node(b->bridge, pcibus_to_node(b)); | 1455 | set_dev_node(b->bridge, pcibus_to_node(b)); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7cfa7c38d318..3ea0b29c0104 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -25,14 +25,9 @@ | |||
25 | #include <linux/dmi.h> | 25 | #include <linux/dmi.h> |
26 | #include <linux/pci-aspm.h> | 26 | #include <linux/pci-aspm.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | ||
28 | #include "pci.h" | 29 | #include "pci.h" |
29 | 30 | ||
30 | int isa_dma_bridge_buggy; | ||
31 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
32 | int pci_pci_problems; | ||
33 | EXPORT_SYMBOL(pci_pci_problems); | ||
34 | |||
35 | #ifdef CONFIG_PCI_QUIRKS | ||
36 | /* | 31 | /* |
37 | * This quirk function disables memory decoding and releases memory resources | 32 | * This quirk function disables memory decoding and releases memory resources |
38 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | 33 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. |
@@ -338,6 +333,23 @@ static void __devinit quirk_s3_64M(struct pci_dev *dev) | |||
338 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); | 333 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); |
339 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); | 334 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); |
340 | 335 | ||
336 | /* | ||
337 | * Some CS5536 BIOSes (for example, the Soekris NET5501 board w/ comBIOS | ||
338 | * ver. 1.33 20070103) don't set the correct ISA PCI region header info. | ||
339 | * BAR0 should be 8 bytes; instead, it may be set to something like 8k | ||
340 | * (which conflicts w/ BAR1's memory range). | ||
341 | */ | ||
342 | static void __devinit quirk_cs5536_vsa(struct pci_dev *dev) | ||
343 | { | ||
344 | if (pci_resource_len(dev, 0) != 8) { | ||
345 | struct resource *res = &dev->resource[0]; | ||
346 | res->end = res->start + 8 - 1; | ||
347 | dev_info(&dev->dev, "CS5536 ISA bridge bug detected " | ||
348 | "(incorrect header); workaround applied.\n"); | ||
349 | } | ||
350 | } | ||
351 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); | ||
352 | |||
341 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | 353 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, |
342 | unsigned size, int nr, const char *name) | 354 | unsigned size, int nr, const char *name) |
343 | { | 355 | { |
@@ -356,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
356 | bus_region.end = res->end; | 368 | bus_region.end = res->end; |
357 | pcibios_bus_to_resource(dev, res, &bus_region); | 369 | pcibios_bus_to_resource(dev, res, &bus_region); |
358 | 370 | ||
359 | pci_claim_resource(dev, nr); | 371 | if (pci_claim_resource(dev, nr) == 0) |
360 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); | 372 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", |
373 | res, name); | ||
361 | } | 374 | } |
362 | } | 375 | } |
363 | 376 | ||
@@ -1965,11 +1978,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
1965 | /* | 1978 | /* |
1966 | * Disable PCI Bus Parking and PCI Master read caching on CX700 | 1979 | * Disable PCI Bus Parking and PCI Master read caching on CX700 |
1967 | * which causes unspecified timing errors with a VT6212L on the PCI | 1980 | * which causes unspecified timing errors with a VT6212L on the PCI |
1968 | * bus leading to USB2.0 packet loss. The defaults are that these | 1981 | * bus leading to USB2.0 packet loss. |
1969 | * features are turned off but some BIOSes turn them on. | 1982 | * |
1983 | * This quirk is only enabled if a second (on the external PCI bus) | ||
1984 | * VT6212L is found -- the CX700 core itself also contains a USB | ||
1985 | * host controller with the same PCI ID as the VT6212L. | ||
1970 | */ | 1986 | */ |
1971 | 1987 | ||
1988 | /* Count VT6212L instances */ | ||
1989 | struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA, | ||
1990 | PCI_DEVICE_ID_VIA_8235_USB_2, NULL); | ||
1972 | uint8_t b; | 1991 | uint8_t b; |
1992 | |||
1993 | /* p should contain the first (internal) VT6212L -- see if we have | ||
1994 | an external one by searching again */ | ||
1995 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p); | ||
1996 | if (!p) | ||
1997 | return; | ||
1998 | pci_dev_put(p); | ||
1999 | |||
1973 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { | 2000 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { |
1974 | if (b & 0x40) { | 2001 | if (b & 0x40) { |
1975 | /* Turn off PCI Bus Parking */ | 2002 | /* Turn off PCI Bus Parking */ |
@@ -1996,7 +2023,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
1996 | } | 2023 | } |
1997 | } | 2024 | } |
1998 | } | 2025 | } |
1999 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); | 2026 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); |
2000 | 2027 | ||
2001 | /* | 2028 | /* |
2002 | * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the | 2029 | * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the |
@@ -2096,6 +2123,7 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) | |||
2096 | } | 2123 | } |
2097 | } | 2124 | } |
2098 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); | 2125 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); |
2126 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); | ||
2099 | 2127 | ||
2100 | /* Go through the list of Hypertransport capabilities and | 2128 | /* Go through the list of Hypertransport capabilities and |
2101 | * return 1 if a HT MSI capability is found and enabled */ | 2129 | * return 1 if a HT MSI capability is found and enabled */ |
@@ -2467,6 +2495,39 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4374, | |||
2467 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, | 2495 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, |
2468 | quirk_msi_intx_disable_bug); | 2496 | quirk_msi_intx_disable_bug); |
2469 | 2497 | ||
2498 | /* | ||
2499 | * MSI does not work with the AMD RS780/RS880 internal graphics and HDMI audio | ||
2500 | * devices unless the BIOS has initialized the nb_cntl.strap_msi_enable bit. | ||
2501 | */ | ||
2502 | static void __init rs780_int_gfx_disable_msi(struct pci_dev *int_gfx_bridge) | ||
2503 | { | ||
2504 | u32 nb_cntl; | ||
2505 | |||
2506 | if (!int_gfx_bridge->subordinate) | ||
2507 | return; | ||
2508 | |||
2509 | pci_bus_write_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), | ||
2510 | 0x60, 0); | ||
2511 | pci_bus_read_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), | ||
2512 | 0x64, &nb_cntl); | ||
2513 | |||
2514 | if (!(nb_cntl & BIT(10))) { | ||
2515 | dev_warn(&int_gfx_bridge->dev, | ||
2516 | FW_WARN "RS780: MSI for internal graphics disabled\n"); | ||
2517 | int_gfx_bridge->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | ||
2518 | } | ||
2519 | } | ||
2520 | |||
2521 | #define PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX 0x9602 | ||
2522 | |||
2523 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, | ||
2524 | PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, | ||
2525 | rs780_int_gfx_disable_msi); | ||
2526 | /* wrong vendor ID on M4A785TD motherboard: */ | ||
2527 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, | ||
2528 | PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, | ||
2529 | rs780_int_gfx_disable_msi); | ||
2530 | |||
2470 | #endif /* CONFIG_PCI_MSI */ | 2531 | #endif /* CONFIG_PCI_MSI */ |
2471 | 2532 | ||
2472 | #ifdef CONFIG_PCI_IOV | 2533 | #ifdef CONFIG_PCI_IOV |
@@ -2517,9 +2578,95 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); | |||
2517 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); | 2578 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); |
2518 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); | 2579 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); |
2519 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); | 2580 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); |
2581 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); | ||
2520 | 2582 | ||
2521 | #endif /* CONFIG_PCI_IOV */ | 2583 | #endif /* CONFIG_PCI_IOV */ |
2522 | 2584 | ||
2585 | /* | ||
2586 | * This is a quirk for the Ricoh MMC controller found as a part of | ||
2587 | * some mulifunction chips. | ||
2588 | |||
2589 | * This is very similiar and based on the ricoh_mmc driver written by | ||
2590 | * Philip Langdale. Thank you for these magic sequences. | ||
2591 | * | ||
2592 | * These chips implement the four main memory card controllers (SD, MMC, MS, xD) | ||
2593 | * and one or both of cardbus or firewire. | ||
2594 | * | ||
2595 | * It happens that they implement SD and MMC | ||
2596 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
2597 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
2598 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
2599 | * them. | ||
2600 | * | ||
2601 | * To get around this, we must disable the useless MMC controller. | ||
2602 | * At that point, the SDHCI controller will start seeing them | ||
2603 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
2604 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
2605 | * or the firewire controller, depending on the particular chip in question | ||
2606 | * | ||
2607 | * This has to be done early, because as soon as we disable the MMC controller | ||
2608 | * other pci functions shift up one level, e.g. function #2 becomes function | ||
2609 | * #1, and this will confuse the pci core. | ||
2610 | */ | ||
2611 | |||
2612 | #ifdef CONFIG_MMC_RICOH_MMC | ||
2613 | static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev) | ||
2614 | { | ||
2615 | /* disable via cardbus interface */ | ||
2616 | u8 write_enable; | ||
2617 | u8 write_target; | ||
2618 | u8 disable; | ||
2619 | |||
2620 | /* disable must be done via function #0 */ | ||
2621 | if (PCI_FUNC(dev->devfn)) | ||
2622 | return; | ||
2623 | |||
2624 | pci_read_config_byte(dev, 0xB7, &disable); | ||
2625 | if (disable & 0x02) | ||
2626 | return; | ||
2627 | |||
2628 | pci_read_config_byte(dev, 0x8E, &write_enable); | ||
2629 | pci_write_config_byte(dev, 0x8E, 0xAA); | ||
2630 | pci_read_config_byte(dev, 0x8D, &write_target); | ||
2631 | pci_write_config_byte(dev, 0x8D, 0xB7); | ||
2632 | pci_write_config_byte(dev, 0xB7, disable | 0x02); | ||
2633 | pci_write_config_byte(dev, 0x8E, write_enable); | ||
2634 | pci_write_config_byte(dev, 0x8D, write_target); | ||
2635 | |||
2636 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n"); | ||
2637 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2638 | } | ||
2639 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2640 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2641 | |||
2642 | static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
2643 | { | ||
2644 | /* disable via firewire interface */ | ||
2645 | u8 write_enable; | ||
2646 | u8 disable; | ||
2647 | |||
2648 | /* disable must be done via function #0 */ | ||
2649 | if (PCI_FUNC(dev->devfn)) | ||
2650 | return; | ||
2651 | |||
2652 | pci_read_config_byte(dev, 0xCB, &disable); | ||
2653 | |||
2654 | if (disable & 0x02) | ||
2655 | return; | ||
2656 | |||
2657 | pci_read_config_byte(dev, 0xCA, &write_enable); | ||
2658 | pci_write_config_byte(dev, 0xCA, 0x57); | ||
2659 | pci_write_config_byte(dev, 0xCB, disable | 0x02); | ||
2660 | pci_write_config_byte(dev, 0xCA, write_enable); | ||
2661 | |||
2662 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); | ||
2663 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2664 | } | ||
2665 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2666 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2667 | #endif /*CONFIG_MMC_RICOH_MMC*/ | ||
2668 | |||
2669 | |||
2523 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2670 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2524 | struct pci_fixup *end) | 2671 | struct pci_fixup *end) |
2525 | { | 2672 | { |
@@ -2595,6 +2742,7 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
2595 | } | 2742 | } |
2596 | pci_do_fixups(dev, start, end); | 2743 | pci_do_fixups(dev, start, end); |
2597 | } | 2744 | } |
2745 | EXPORT_SYMBOL(pci_fixup_device); | ||
2598 | 2746 | ||
2599 | static int __init pci_apply_final_quirks(void) | 2747 | static int __init pci_apply_final_quirks(void) |
2600 | { | 2748 | { |
@@ -2629,14 +2777,80 @@ static int __init pci_apply_final_quirks(void) | |||
2629 | if (!pci_cache_line_size) { | 2777 | if (!pci_cache_line_size) { |
2630 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | 2778 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", |
2631 | cls << 2, pci_dfl_cache_line_size << 2); | 2779 | cls << 2, pci_dfl_cache_line_size << 2); |
2632 | pci_cache_line_size = cls; | 2780 | pci_cache_line_size = cls ? cls : pci_dfl_cache_line_size; |
2633 | } | 2781 | } |
2634 | 2782 | ||
2635 | return 0; | 2783 | return 0; |
2636 | } | 2784 | } |
2637 | 2785 | ||
2638 | fs_initcall_sync(pci_apply_final_quirks); | 2786 | fs_initcall_sync(pci_apply_final_quirks); |
2639 | #else | 2787 | |
2640 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} | 2788 | /* |
2641 | #endif | 2789 | * Followings are device-specific reset methods which can be used to |
2642 | EXPORT_SYMBOL(pci_fixup_device); | 2790 | * reset a single function if other methods (e.g. FLR, PM D0->D3) are |
2791 | * not available. | ||
2792 | */ | ||
2793 | static int reset_intel_generic_dev(struct pci_dev *dev, int probe) | ||
2794 | { | ||
2795 | int pos; | ||
2796 | |||
2797 | /* only implement PCI_CLASS_SERIAL_USB at present */ | ||
2798 | if (dev->class == PCI_CLASS_SERIAL_USB) { | ||
2799 | pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); | ||
2800 | if (!pos) | ||
2801 | return -ENOTTY; | ||
2802 | |||
2803 | if (probe) | ||
2804 | return 0; | ||
2805 | |||
2806 | pci_write_config_byte(dev, pos + 0x4, 1); | ||
2807 | msleep(100); | ||
2808 | |||
2809 | return 0; | ||
2810 | } else { | ||
2811 | return -ENOTTY; | ||
2812 | } | ||
2813 | } | ||
2814 | |||
2815 | static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) | ||
2816 | { | ||
2817 | int pos; | ||
2818 | |||
2819 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
2820 | if (!pos) | ||
2821 | return -ENOTTY; | ||
2822 | |||
2823 | if (probe) | ||
2824 | return 0; | ||
2825 | |||
2826 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, | ||
2827 | PCI_EXP_DEVCTL_BCR_FLR); | ||
2828 | msleep(100); | ||
2829 | |||
2830 | return 0; | ||
2831 | } | ||
2832 | |||
2833 | #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed | ||
2834 | |||
2835 | static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { | ||
2836 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, | ||
2837 | reset_intel_82599_sfp_virtfn }, | ||
2838 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | ||
2839 | reset_intel_generic_dev }, | ||
2840 | { 0 } | ||
2841 | }; | ||
2842 | |||
2843 | int pci_dev_specific_reset(struct pci_dev *dev, int probe) | ||
2844 | { | ||
2845 | const struct pci_dev_reset_methods *i; | ||
2846 | |||
2847 | for (i = pci_dev_reset_methods; i->reset; i++) { | ||
2848 | if ((i->vendor == dev->vendor || | ||
2849 | i->vendor == (u16)PCI_ANY_ID) && | ||
2850 | (i->device == dev->device || | ||
2851 | i->device == (u16)PCI_ANY_ID)) | ||
2852 | return i->reset(dev, probe); | ||
2853 | } | ||
2854 | |||
2855 | return -ENOTTY; | ||
2856 | } | ||
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 6dae87143258..4a471dc4f4b9 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -15,9 +15,9 @@ | |||
15 | 15 | ||
16 | DECLARE_RWSEM(pci_bus_sem); | 16 | DECLARE_RWSEM(pci_bus_sem); |
17 | /* | 17 | /* |
18 | * find the upstream PCIE-to-PCI bridge of a PCI device | 18 | * find the upstream PCIe-to-PCI bridge of a PCI device |
19 | * if the device is PCIE, return NULL | 19 | * if the device is PCIE, return NULL |
20 | * if the device isn't connected to a PCIE bridge (that is its parent is a | 20 | * if the device isn't connected to a PCIe bridge (that is its parent is a |
21 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its | 21 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its |
22 | * parent | 22 | * parent |
23 | */ | 23 | */ |
@@ -37,7 +37,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
37 | tmp = pdev; | 37 | tmp = pdev; |
38 | continue; | 38 | continue; |
39 | } | 39 | } |
40 | /* PCI device should connect to a PCIE bridge */ | 40 | /* PCI device should connect to a PCIe bridge */ |
41 | if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { | 41 | if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { |
42 | /* Busted hardware? */ | 42 | /* Busted hardware? */ |
43 | WARN_ON_ONCE(1); | 43 | WARN_ON_ONCE(1); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index c48cd377b3f5..4fe36d2e1049 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -27,37 +27,91 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include "pci.h" | 28 | #include "pci.h" |
29 | 29 | ||
30 | static void pbus_assign_resources_sorted(const struct pci_bus *bus) | 30 | struct resource_list_x { |
31 | { | 31 | struct resource_list_x *next; |
32 | struct pci_dev *dev; | ||
33 | struct resource *res; | 32 | struct resource *res; |
34 | struct resource_list head, *list, *tmp; | 33 | struct pci_dev *dev; |
35 | int idx; | 34 | resource_size_t start; |
35 | resource_size_t end; | ||
36 | unsigned long flags; | ||
37 | }; | ||
36 | 38 | ||
37 | head.next = NULL; | 39 | static void add_to_failed_list(struct resource_list_x *head, |
38 | list_for_each_entry(dev, &bus->devices, bus_list) { | 40 | struct pci_dev *dev, struct resource *res) |
39 | u16 class = dev->class >> 8; | 41 | { |
42 | struct resource_list_x *list = head; | ||
43 | struct resource_list_x *ln = list->next; | ||
44 | struct resource_list_x *tmp; | ||
40 | 45 | ||
41 | /* Don't touch classless devices or host bridges or ioapics. */ | 46 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); |
42 | if (class == PCI_CLASS_NOT_DEFINED || | 47 | if (!tmp) { |
43 | class == PCI_CLASS_BRIDGE_HOST) | 48 | pr_warning("add_to_failed_list: kmalloc() failed!\n"); |
44 | continue; | 49 | return; |
50 | } | ||
45 | 51 | ||
46 | /* Don't touch ioapic devices already enabled by firmware */ | 52 | tmp->next = ln; |
47 | if (class == PCI_CLASS_SYSTEM_PIC) { | 53 | tmp->res = res; |
48 | u16 command; | 54 | tmp->dev = dev; |
49 | pci_read_config_word(dev, PCI_COMMAND, &command); | 55 | tmp->start = res->start; |
50 | if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | 56 | tmp->end = res->end; |
51 | continue; | 57 | tmp->flags = res->flags; |
52 | } | 58 | list->next = tmp; |
59 | } | ||
60 | |||
61 | static void free_failed_list(struct resource_list_x *head) | ||
62 | { | ||
63 | struct resource_list_x *list, *tmp; | ||
53 | 64 | ||
54 | pdev_sort_resources(dev, &head); | 65 | for (list = head->next; list;) { |
66 | tmp = list; | ||
67 | list = list->next; | ||
68 | kfree(tmp); | ||
55 | } | 69 | } |
56 | 70 | ||
57 | for (list = head.next; list;) { | 71 | head->next = NULL; |
72 | } | ||
73 | |||
74 | static void __dev_sort_resources(struct pci_dev *dev, | ||
75 | struct resource_list *head) | ||
76 | { | ||
77 | u16 class = dev->class >> 8; | ||
78 | |||
79 | /* Don't touch classless devices or host bridges or ioapics. */ | ||
80 | if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST) | ||
81 | return; | ||
82 | |||
83 | /* Don't touch ioapic devices already enabled by firmware */ | ||
84 | if (class == PCI_CLASS_SYSTEM_PIC) { | ||
85 | u16 command; | ||
86 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
87 | if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | pdev_sort_resources(dev, head); | ||
92 | } | ||
93 | |||
94 | static void __assign_resources_sorted(struct resource_list *head, | ||
95 | struct resource_list_x *fail_head) | ||
96 | { | ||
97 | struct resource *res; | ||
98 | struct resource_list *list, *tmp; | ||
99 | int idx; | ||
100 | |||
101 | for (list = head->next; list;) { | ||
58 | res = list->res; | 102 | res = list->res; |
59 | idx = res - &list->dev->resource[0]; | 103 | idx = res - &list->dev->resource[0]; |
104 | |||
60 | if (pci_assign_resource(list->dev, idx)) { | 105 | if (pci_assign_resource(list->dev, idx)) { |
106 | if (fail_head && !pci_is_root_bus(list->dev->bus)) { | ||
107 | /* | ||
108 | * if the failed res is for ROM BAR, and it will | ||
109 | * be enabled later, don't add it to the list | ||
110 | */ | ||
111 | if (!((idx == PCI_ROM_RESOURCE) && | ||
112 | (!(res->flags & IORESOURCE_ROM_ENABLE)))) | ||
113 | add_to_failed_list(fail_head, list->dev, res); | ||
114 | } | ||
61 | res->start = 0; | 115 | res->start = 0; |
62 | res->end = 0; | 116 | res->end = 0; |
63 | res->flags = 0; | 117 | res->flags = 0; |
@@ -68,6 +122,30 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus) | |||
68 | } | 122 | } |
69 | } | 123 | } |
70 | 124 | ||
125 | static void pdev_assign_resources_sorted(struct pci_dev *dev, | ||
126 | struct resource_list_x *fail_head) | ||
127 | { | ||
128 | struct resource_list head; | ||
129 | |||
130 | head.next = NULL; | ||
131 | __dev_sort_resources(dev, &head); | ||
132 | __assign_resources_sorted(&head, fail_head); | ||
133 | |||
134 | } | ||
135 | |||
136 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, | ||
137 | struct resource_list_x *fail_head) | ||
138 | { | ||
139 | struct pci_dev *dev; | ||
140 | struct resource_list head; | ||
141 | |||
142 | head.next = NULL; | ||
143 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
144 | __dev_sort_resources(dev, &head); | ||
145 | |||
146 | __assign_resources_sorted(&head, fail_head); | ||
147 | } | ||
148 | |||
71 | void pci_setup_cardbus(struct pci_bus *bus) | 149 | void pci_setup_cardbus(struct pci_bus *bus) |
72 | { | 150 | { |
73 | struct pci_dev *bridge = bus->self; | 151 | struct pci_dev *bridge = bus->self; |
@@ -134,18 +212,12 @@ EXPORT_SYMBOL(pci_setup_cardbus); | |||
134 | config space writes, so it's quite possible that an I/O window of | 212 | config space writes, so it's quite possible that an I/O window of |
135 | the bridge will have some undesirable address (e.g. 0) after the | 213 | the bridge will have some undesirable address (e.g. 0) after the |
136 | first write. Ditto 64-bit prefetchable MMIO. */ | 214 | first write. Ditto 64-bit prefetchable MMIO. */ |
137 | static void pci_setup_bridge(struct pci_bus *bus) | 215 | static void pci_setup_bridge_io(struct pci_bus *bus) |
138 | { | 216 | { |
139 | struct pci_dev *bridge = bus->self; | 217 | struct pci_dev *bridge = bus->self; |
140 | struct resource *res; | 218 | struct resource *res; |
141 | struct pci_bus_region region; | 219 | struct pci_bus_region region; |
142 | u32 l, bu, lu, io_upper16; | 220 | u32 l, io_upper16; |
143 | |||
144 | if (pci_is_enabled(bridge)) | ||
145 | return; | ||
146 | |||
147 | dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", | ||
148 | bus->secondary, bus->subordinate); | ||
149 | 221 | ||
150 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 222 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
151 | res = bus->resource[0]; | 223 | res = bus->resource[0]; |
@@ -158,8 +230,7 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
158 | /* Set up upper 16 bits of I/O base/limit. */ | 230 | /* Set up upper 16 bits of I/O base/limit. */ |
159 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); | 231 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); |
160 | dev_info(&bridge->dev, " bridge window %pR\n", res); | 232 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
161 | } | 233 | } else { |
162 | else { | ||
163 | /* Clear upper 16 bits of I/O base/limit. */ | 234 | /* Clear upper 16 bits of I/O base/limit. */ |
164 | io_upper16 = 0; | 235 | io_upper16 = 0; |
165 | l = 0x00f0; | 236 | l = 0x00f0; |
@@ -171,21 +242,35 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
171 | pci_write_config_dword(bridge, PCI_IO_BASE, l); | 242 | pci_write_config_dword(bridge, PCI_IO_BASE, l); |
172 | /* Update upper 16 bits of I/O base/limit. */ | 243 | /* Update upper 16 bits of I/O base/limit. */ |
173 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); | 244 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); |
245 | } | ||
246 | |||
247 | static void pci_setup_bridge_mmio(struct pci_bus *bus) | ||
248 | { | ||
249 | struct pci_dev *bridge = bus->self; | ||
250 | struct resource *res; | ||
251 | struct pci_bus_region region; | ||
252 | u32 l; | ||
174 | 253 | ||
175 | /* Set up the top and bottom of the PCI Memory segment | 254 | /* Set up the top and bottom of the PCI Memory segment for this bus. */ |
176 | for this bus. */ | ||
177 | res = bus->resource[1]; | 255 | res = bus->resource[1]; |
178 | pcibios_resource_to_bus(bridge, ®ion, res); | 256 | pcibios_resource_to_bus(bridge, ®ion, res); |
179 | if (res->flags & IORESOURCE_MEM) { | 257 | if (res->flags & IORESOURCE_MEM) { |
180 | l = (region.start >> 16) & 0xfff0; | 258 | l = (region.start >> 16) & 0xfff0; |
181 | l |= region.end & 0xfff00000; | 259 | l |= region.end & 0xfff00000; |
182 | dev_info(&bridge->dev, " bridge window %pR\n", res); | 260 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
183 | } | 261 | } else { |
184 | else { | ||
185 | l = 0x0000fff0; | 262 | l = 0x0000fff0; |
186 | dev_info(&bridge->dev, " bridge window [mem disabled]\n"); | 263 | dev_info(&bridge->dev, " bridge window [mem disabled]\n"); |
187 | } | 264 | } |
188 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | 265 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); |
266 | } | ||
267 | |||
268 | static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) | ||
269 | { | ||
270 | struct pci_dev *bridge = bus->self; | ||
271 | struct resource *res; | ||
272 | struct pci_bus_region region; | ||
273 | u32 l, bu, lu; | ||
189 | 274 | ||
190 | /* Clear out the upper 32 bits of PREF limit. | 275 | /* Clear out the upper 32 bits of PREF limit. |
191 | If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily | 276 | If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily |
@@ -204,8 +289,7 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
204 | lu = upper_32_bits(region.end); | 289 | lu = upper_32_bits(region.end); |
205 | } | 290 | } |
206 | dev_info(&bridge->dev, " bridge window %pR\n", res); | 291 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
207 | } | 292 | } else { |
208 | else { | ||
209 | l = 0x0000fff0; | 293 | l = 0x0000fff0; |
210 | dev_info(&bridge->dev, " bridge window [mem pref disabled]\n"); | 294 | dev_info(&bridge->dev, " bridge window [mem pref disabled]\n"); |
211 | } | 295 | } |
@@ -214,10 +298,35 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
214 | /* Set the upper 32 bits of PREF base & limit. */ | 298 | /* Set the upper 32 bits of PREF base & limit. */ |
215 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); | 299 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); |
216 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); | 300 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); |
301 | } | ||
302 | |||
303 | static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) | ||
304 | { | ||
305 | struct pci_dev *bridge = bus->self; | ||
306 | |||
307 | dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", | ||
308 | bus->secondary, bus->subordinate); | ||
309 | |||
310 | if (type & IORESOURCE_IO) | ||
311 | pci_setup_bridge_io(bus); | ||
312 | |||
313 | if (type & IORESOURCE_MEM) | ||
314 | pci_setup_bridge_mmio(bus); | ||
315 | |||
316 | if (type & IORESOURCE_PREFETCH) | ||
317 | pci_setup_bridge_mmio_pref(bus); | ||
217 | 318 | ||
218 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | 319 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); |
219 | } | 320 | } |
220 | 321 | ||
322 | static void pci_setup_bridge(struct pci_bus *bus) | ||
323 | { | ||
324 | unsigned long type = IORESOURCE_IO | IORESOURCE_MEM | | ||
325 | IORESOURCE_PREFETCH; | ||
326 | |||
327 | __pci_setup_bridge(bus, type); | ||
328 | } | ||
329 | |||
221 | /* Check whether the bridge supports optional I/O and | 330 | /* Check whether the bridge supports optional I/O and |
222 | prefetchable memory ranges. If not, the respective | 331 | prefetchable memory ranges. If not, the respective |
223 | base/limit registers must be read-only and read as 0. */ | 332 | base/limit registers must be read-only and read as 0. */ |
@@ -253,8 +362,11 @@ static void pci_bridge_check_ranges(struct pci_bus *bus) | |||
253 | } | 362 | } |
254 | if (pmem) { | 363 | if (pmem) { |
255 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; | 364 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; |
256 | if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) | 365 | if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == |
366 | PCI_PREF_RANGE_TYPE_64) { | ||
257 | b_res[2].flags |= IORESOURCE_MEM_64; | 367 | b_res[2].flags |= IORESOURCE_MEM_64; |
368 | b_res[2].flags |= PCI_PREF_RANGE_TYPE_64; | ||
369 | } | ||
258 | } | 370 | } |
259 | 371 | ||
260 | /* double check if bridge does support 64 bit pref */ | 372 | /* double check if bridge does support 64 bit pref */ |
@@ -283,8 +395,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon | |||
283 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 395 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
284 | IORESOURCE_PREFETCH; | 396 | IORESOURCE_PREFETCH; |
285 | 397 | ||
286 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 398 | pci_bus_for_each_resource(bus, r, i) { |
287 | r = bus->resource[i]; | ||
288 | if (r == &ioport_resource || r == &iomem_resource) | 399 | if (r == &ioport_resource || r == &iomem_resource) |
289 | continue; | 400 | continue; |
290 | if (r && (r->flags & type_mask) == type && !r->parent) | 401 | if (r && (r->flags & type_mask) == type && !r->parent) |
@@ -301,7 +412,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
301 | { | 412 | { |
302 | struct pci_dev *dev; | 413 | struct pci_dev *dev; |
303 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | 414 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); |
304 | unsigned long size = 0, size1 = 0; | 415 | unsigned long size = 0, size1 = 0, old_size; |
305 | 416 | ||
306 | if (!b_res) | 417 | if (!b_res) |
307 | return; | 418 | return; |
@@ -326,12 +437,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
326 | } | 437 | } |
327 | if (size < min_size) | 438 | if (size < min_size) |
328 | size = min_size; | 439 | size = min_size; |
440 | old_size = resource_size(b_res); | ||
441 | if (old_size == 1) | ||
442 | old_size = 0; | ||
329 | /* To be fixed in 2.5: we should have sort of HAVE_ISA | 443 | /* To be fixed in 2.5: we should have sort of HAVE_ISA |
330 | flag in the struct pci_bus. */ | 444 | flag in the struct pci_bus. */ |
331 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | 445 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
332 | size = (size & 0xff) + ((size & ~0xffUL) << 2); | 446 | size = (size & 0xff) + ((size & ~0xffUL) << 2); |
333 | #endif | 447 | #endif |
334 | size = ALIGN(size + size1, 4096); | 448 | size = ALIGN(size + size1, 4096); |
449 | if (size < old_size) | ||
450 | size = old_size; | ||
335 | if (!size) { | 451 | if (!size) { |
336 | if (b_res->start || b_res->end) | 452 | if (b_res->start || b_res->end) |
337 | dev_info(&bus->self->dev, "disabling bridge window " | 453 | dev_info(&bus->self->dev, "disabling bridge window " |
@@ -352,7 +468,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
352 | unsigned long type, resource_size_t min_size) | 468 | unsigned long type, resource_size_t min_size) |
353 | { | 469 | { |
354 | struct pci_dev *dev; | 470 | struct pci_dev *dev; |
355 | resource_size_t min_align, align, size; | 471 | resource_size_t min_align, align, size, old_size; |
356 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ | 472 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ |
357 | int order, max_order; | 473 | int order, max_order; |
358 | struct resource *b_res = find_free_bus_resource(bus, type); | 474 | struct resource *b_res = find_free_bus_resource(bus, type); |
@@ -402,6 +518,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
402 | } | 518 | } |
403 | if (size < min_size) | 519 | if (size < min_size) |
404 | size = min_size; | 520 | size = min_size; |
521 | old_size = resource_size(b_res); | ||
522 | if (old_size == 1) | ||
523 | old_size = 0; | ||
524 | if (size < old_size) | ||
525 | size = old_size; | ||
405 | 526 | ||
406 | align = 0; | 527 | align = 0; |
407 | min_align = 0; | 528 | min_align = 0; |
@@ -538,23 +659,25 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
538 | } | 659 | } |
539 | EXPORT_SYMBOL(pci_bus_size_bridges); | 660 | EXPORT_SYMBOL(pci_bus_size_bridges); |
540 | 661 | ||
541 | void __ref pci_bus_assign_resources(const struct pci_bus *bus) | 662 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
663 | struct resource_list_x *fail_head) | ||
542 | { | 664 | { |
543 | struct pci_bus *b; | 665 | struct pci_bus *b; |
544 | struct pci_dev *dev; | 666 | struct pci_dev *dev; |
545 | 667 | ||
546 | pbus_assign_resources_sorted(bus); | 668 | pbus_assign_resources_sorted(bus, fail_head); |
547 | 669 | ||
548 | list_for_each_entry(dev, &bus->devices, bus_list) { | 670 | list_for_each_entry(dev, &bus->devices, bus_list) { |
549 | b = dev->subordinate; | 671 | b = dev->subordinate; |
550 | if (!b) | 672 | if (!b) |
551 | continue; | 673 | continue; |
552 | 674 | ||
553 | pci_bus_assign_resources(b); | 675 | __pci_bus_assign_resources(b, fail_head); |
554 | 676 | ||
555 | switch (dev->class >> 8) { | 677 | switch (dev->class >> 8) { |
556 | case PCI_CLASS_BRIDGE_PCI: | 678 | case PCI_CLASS_BRIDGE_PCI: |
557 | pci_setup_bridge(b); | 679 | if (!pci_is_enabled(dev)) |
680 | pci_setup_bridge(b); | ||
558 | break; | 681 | break; |
559 | 682 | ||
560 | case PCI_CLASS_BRIDGE_CARDBUS: | 683 | case PCI_CLASS_BRIDGE_CARDBUS: |
@@ -568,15 +691,130 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus) | |||
568 | } | 691 | } |
569 | } | 692 | } |
570 | } | 693 | } |
694 | |||
695 | void __ref pci_bus_assign_resources(const struct pci_bus *bus) | ||
696 | { | ||
697 | __pci_bus_assign_resources(bus, NULL); | ||
698 | } | ||
571 | EXPORT_SYMBOL(pci_bus_assign_resources); | 699 | EXPORT_SYMBOL(pci_bus_assign_resources); |
572 | 700 | ||
701 | static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, | ||
702 | struct resource_list_x *fail_head) | ||
703 | { | ||
704 | struct pci_bus *b; | ||
705 | |||
706 | pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head); | ||
707 | |||
708 | b = bridge->subordinate; | ||
709 | if (!b) | ||
710 | return; | ||
711 | |||
712 | __pci_bus_assign_resources(b, fail_head); | ||
713 | |||
714 | switch (bridge->class >> 8) { | ||
715 | case PCI_CLASS_BRIDGE_PCI: | ||
716 | pci_setup_bridge(b); | ||
717 | break; | ||
718 | |||
719 | case PCI_CLASS_BRIDGE_CARDBUS: | ||
720 | pci_setup_cardbus(b); | ||
721 | break; | ||
722 | |||
723 | default: | ||
724 | dev_info(&bridge->dev, "not setting up bridge for bus " | ||
725 | "%04x:%02x\n", pci_domain_nr(b), b->number); | ||
726 | break; | ||
727 | } | ||
728 | } | ||
729 | static void pci_bridge_release_resources(struct pci_bus *bus, | ||
730 | unsigned long type) | ||
731 | { | ||
732 | int idx; | ||
733 | bool changed = false; | ||
734 | struct pci_dev *dev; | ||
735 | struct resource *r; | ||
736 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
737 | IORESOURCE_PREFETCH; | ||
738 | |||
739 | dev = bus->self; | ||
740 | for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END; | ||
741 | idx++) { | ||
742 | r = &dev->resource[idx]; | ||
743 | if ((r->flags & type_mask) != type) | ||
744 | continue; | ||
745 | if (!r->parent) | ||
746 | continue; | ||
747 | /* | ||
748 | * if there are children under that, we should release them | ||
749 | * all | ||
750 | */ | ||
751 | release_child_resources(r); | ||
752 | if (!release_resource(r)) { | ||
753 | dev_printk(KERN_DEBUG, &dev->dev, | ||
754 | "resource %d %pR released\n", idx, r); | ||
755 | /* keep the old size */ | ||
756 | r->end = resource_size(r) - 1; | ||
757 | r->start = 0; | ||
758 | r->flags = 0; | ||
759 | changed = true; | ||
760 | } | ||
761 | } | ||
762 | |||
763 | if (changed) { | ||
764 | /* avoiding touch the one without PREF */ | ||
765 | if (type & IORESOURCE_PREFETCH) | ||
766 | type = IORESOURCE_PREFETCH; | ||
767 | __pci_setup_bridge(bus, type); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | enum release_type { | ||
772 | leaf_only, | ||
773 | whole_subtree, | ||
774 | }; | ||
775 | /* | ||
776 | * try to release pci bridge resources that is from leaf bridge, | ||
777 | * so we can allocate big new one later | ||
778 | */ | ||
779 | static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus, | ||
780 | unsigned long type, | ||
781 | enum release_type rel_type) | ||
782 | { | ||
783 | struct pci_dev *dev; | ||
784 | bool is_leaf_bridge = true; | ||
785 | |||
786 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
787 | struct pci_bus *b = dev->subordinate; | ||
788 | if (!b) | ||
789 | continue; | ||
790 | |||
791 | is_leaf_bridge = false; | ||
792 | |||
793 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
794 | continue; | ||
795 | |||
796 | if (rel_type == whole_subtree) | ||
797 | pci_bus_release_bridge_resources(b, type, | ||
798 | whole_subtree); | ||
799 | } | ||
800 | |||
801 | if (pci_is_root_bus(bus)) | ||
802 | return; | ||
803 | |||
804 | if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
805 | return; | ||
806 | |||
807 | if ((rel_type == whole_subtree) || is_leaf_bridge) | ||
808 | pci_bridge_release_resources(bus, type); | ||
809 | } | ||
810 | |||
573 | static void pci_bus_dump_res(struct pci_bus *bus) | 811 | static void pci_bus_dump_res(struct pci_bus *bus) |
574 | { | 812 | { |
575 | int i; | 813 | struct resource *res; |
814 | int i; | ||
576 | 815 | ||
577 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 816 | pci_bus_for_each_resource(bus, res, i) { |
578 | struct resource *res = bus->resource[i]; | 817 | if (!res || !res->end || !res->flags) |
579 | if (!res || !res->end) | ||
580 | continue; | 818 | continue; |
581 | 819 | ||
582 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res); | 820 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res); |
@@ -600,11 +838,65 @@ static void pci_bus_dump_resources(struct pci_bus *bus) | |||
600 | } | 838 | } |
601 | } | 839 | } |
602 | 840 | ||
841 | static int __init pci_bus_get_depth(struct pci_bus *bus) | ||
842 | { | ||
843 | int depth = 0; | ||
844 | struct pci_dev *dev; | ||
845 | |||
846 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
847 | int ret; | ||
848 | struct pci_bus *b = dev->subordinate; | ||
849 | if (!b) | ||
850 | continue; | ||
851 | |||
852 | ret = pci_bus_get_depth(b); | ||
853 | if (ret + 1 > depth) | ||
854 | depth = ret + 1; | ||
855 | } | ||
856 | |||
857 | return depth; | ||
858 | } | ||
859 | static int __init pci_get_max_depth(void) | ||
860 | { | ||
861 | int depth = 0; | ||
862 | struct pci_bus *bus; | ||
863 | |||
864 | list_for_each_entry(bus, &pci_root_buses, node) { | ||
865 | int ret; | ||
866 | |||
867 | ret = pci_bus_get_depth(bus); | ||
868 | if (ret > depth) | ||
869 | depth = ret; | ||
870 | } | ||
871 | |||
872 | return depth; | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * first try will not touch pci bridge res | ||
877 | * second and later try will clear small leaf bridge res | ||
878 | * will stop till to the max deepth if can not find good one | ||
879 | */ | ||
603 | void __init | 880 | void __init |
604 | pci_assign_unassigned_resources(void) | 881 | pci_assign_unassigned_resources(void) |
605 | { | 882 | { |
606 | struct pci_bus *bus; | 883 | struct pci_bus *bus; |
884 | int tried_times = 0; | ||
885 | enum release_type rel_type = leaf_only; | ||
886 | struct resource_list_x head, *list; | ||
887 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
888 | IORESOURCE_PREFETCH; | ||
889 | unsigned long failed_type; | ||
890 | int max_depth = pci_get_max_depth(); | ||
891 | int pci_try_num; | ||
892 | |||
893 | head.next = NULL; | ||
894 | |||
895 | pci_try_num = max_depth + 1; | ||
896 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | ||
897 | max_depth, pci_try_num); | ||
607 | 898 | ||
899 | again: | ||
608 | /* Depth first, calculate sizes and alignments of all | 900 | /* Depth first, calculate sizes and alignments of all |
609 | subordinate buses. */ | 901 | subordinate buses. */ |
610 | list_for_each_entry(bus, &pci_root_buses, node) { | 902 | list_for_each_entry(bus, &pci_root_buses, node) { |
@@ -612,12 +904,130 @@ pci_assign_unassigned_resources(void) | |||
612 | } | 904 | } |
613 | /* Depth last, allocate resources and update the hardware. */ | 905 | /* Depth last, allocate resources and update the hardware. */ |
614 | list_for_each_entry(bus, &pci_root_buses, node) { | 906 | list_for_each_entry(bus, &pci_root_buses, node) { |
615 | pci_bus_assign_resources(bus); | 907 | __pci_bus_assign_resources(bus, &head); |
616 | pci_enable_bridges(bus); | ||
617 | } | 908 | } |
909 | tried_times++; | ||
910 | |||
911 | /* any device complain? */ | ||
912 | if (!head.next) | ||
913 | goto enable_and_dump; | ||
914 | failed_type = 0; | ||
915 | for (list = head.next; list;) { | ||
916 | failed_type |= list->flags; | ||
917 | list = list->next; | ||
918 | } | ||
919 | /* | ||
920 | * io port are tight, don't try extra | ||
921 | * or if reach the limit, don't want to try more | ||
922 | */ | ||
923 | failed_type &= type_mask; | ||
924 | if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { | ||
925 | free_failed_list(&head); | ||
926 | goto enable_and_dump; | ||
927 | } | ||
928 | |||
929 | printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", | ||
930 | tried_times + 1); | ||
931 | |||
932 | /* third times and later will not check if it is leaf */ | ||
933 | if ((tried_times + 1) > 2) | ||
934 | rel_type = whole_subtree; | ||
935 | |||
936 | /* | ||
937 | * Try to release leaf bridge's resources that doesn't fit resource of | ||
938 | * child device under that bridge | ||
939 | */ | ||
940 | for (list = head.next; list;) { | ||
941 | bus = list->dev->bus; | ||
942 | pci_bus_release_bridge_resources(bus, list->flags & type_mask, | ||
943 | rel_type); | ||
944 | list = list->next; | ||
945 | } | ||
946 | /* restore size and flags */ | ||
947 | for (list = head.next; list;) { | ||
948 | struct resource *res = list->res; | ||
949 | |||
950 | res->start = list->start; | ||
951 | res->end = list->end; | ||
952 | res->flags = list->flags; | ||
953 | if (list->dev->subordinate) | ||
954 | res->flags = 0; | ||
955 | |||
956 | list = list->next; | ||
957 | } | ||
958 | free_failed_list(&head); | ||
959 | |||
960 | goto again; | ||
961 | |||
962 | enable_and_dump: | ||
963 | /* Depth last, update the hardware. */ | ||
964 | list_for_each_entry(bus, &pci_root_buses, node) | ||
965 | pci_enable_bridges(bus); | ||
618 | 966 | ||
619 | /* dump the resource on buses */ | 967 | /* dump the resource on buses */ |
620 | list_for_each_entry(bus, &pci_root_buses, node) { | 968 | list_for_each_entry(bus, &pci_root_buses, node) { |
621 | pci_bus_dump_resources(bus); | 969 | pci_bus_dump_resources(bus); |
622 | } | 970 | } |
623 | } | 971 | } |
972 | |||
973 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) | ||
974 | { | ||
975 | struct pci_bus *parent = bridge->subordinate; | ||
976 | int tried_times = 0; | ||
977 | struct resource_list_x head, *list; | ||
978 | int retval; | ||
979 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
980 | IORESOURCE_PREFETCH; | ||
981 | |||
982 | head.next = NULL; | ||
983 | |||
984 | again: | ||
985 | pci_bus_size_bridges(parent); | ||
986 | __pci_bridge_assign_resources(bridge, &head); | ||
987 | retval = pci_reenable_device(bridge); | ||
988 | pci_set_master(bridge); | ||
989 | pci_enable_bridges(parent); | ||
990 | |||
991 | tried_times++; | ||
992 | |||
993 | if (!head.next) | ||
994 | return; | ||
995 | |||
996 | if (tried_times >= 2) { | ||
997 | /* still fail, don't need to try more */ | ||
998 | free_failed_list(&head); | ||
999 | return; | ||
1000 | } | ||
1001 | |||
1002 | printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", | ||
1003 | tried_times + 1); | ||
1004 | |||
1005 | /* | ||
1006 | * Try to release leaf bridge's resources that doesn't fit resource of | ||
1007 | * child device under that bridge | ||
1008 | */ | ||
1009 | for (list = head.next; list;) { | ||
1010 | struct pci_bus *bus = list->dev->bus; | ||
1011 | unsigned long flags = list->flags; | ||
1012 | |||
1013 | pci_bus_release_bridge_resources(bus, flags & type_mask, | ||
1014 | whole_subtree); | ||
1015 | list = list->next; | ||
1016 | } | ||
1017 | /* restore size and flags */ | ||
1018 | for (list = head.next; list;) { | ||
1019 | struct resource *res = list->res; | ||
1020 | |||
1021 | res->start = list->start; | ||
1022 | res->end = list->end; | ||
1023 | res->flags = list->flags; | ||
1024 | if (list->dev->subordinate) | ||
1025 | res->flags = 0; | ||
1026 | |||
1027 | list = list->next; | ||
1028 | } | ||
1029 | free_failed_list(&head); | ||
1030 | |||
1031 | goto again; | ||
1032 | } | ||
1033 | EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 7d678bb15ffb..17bed18d24ad 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
93 | int pci_claim_resource(struct pci_dev *dev, int resource) | 93 | int pci_claim_resource(struct pci_dev *dev, int resource) |
94 | { | 94 | { |
95 | struct resource *res = &dev->resource[resource]; | 95 | struct resource *res = &dev->resource[resource]; |
96 | struct resource *root; | 96 | struct resource *root, *conflict; |
97 | int err; | ||
98 | 97 | ||
99 | root = pci_find_parent_resource(dev, res); | 98 | root = pci_find_parent_resource(dev, res); |
100 | if (!root) { | 99 | if (!root) { |
@@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
103 | return -EINVAL; | 102 | return -EINVAL; |
104 | } | 103 | } |
105 | 104 | ||
106 | err = request_resource(root, res); | 105 | conflict = request_resource_conflict(root, res); |
107 | if (err) | 106 | if (conflict) { |
108 | dev_err(&dev->dev, | 107 | dev_err(&dev->dev, |
109 | "address space collision: %pR already in use\n", res); | 108 | "address space collision: %pR conflicts with %s %pR\n", |
109 | res, conflict->name, conflict); | ||
110 | return -EBUSY; | ||
111 | } | ||
110 | 112 | ||
111 | return err; | 113 | return 0; |
112 | } | 114 | } |
113 | EXPORT_SYMBOL(pci_claim_resource); | 115 | EXPORT_SYMBOL(pci_claim_resource); |
114 | 116 | ||
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 8c02b6c53bdb..f75a44d37fbe 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj, | |||
29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; | 29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; |
30 | } | 30 | } |
31 | 31 | ||
32 | static struct sysfs_ops pci_slot_sysfs_ops = { | 32 | static const struct sysfs_ops pci_slot_sysfs_ops = { |
33 | .show = pci_slot_attr_show, | 33 | .show = pci_slot_attr_show, |
34 | .store = pci_slot_attr_store, | 34 | .store = pci_slot_attr_store, |
35 | }; | 35 | }; |
@@ -47,6 +47,55 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) | |||
47 | slot->number); | 47 | slot->number); |
48 | } | 48 | } |
49 | 49 | ||
50 | /* these strings match up with the values in pci_bus_speed */ | ||
51 | static char *pci_bus_speed_strings[] = { | ||
52 | "33 MHz PCI", /* 0x00 */ | ||
53 | "66 MHz PCI", /* 0x01 */ | ||
54 | "66 MHz PCI-X", /* 0x02 */ | ||
55 | "100 MHz PCI-X", /* 0x03 */ | ||
56 | "133 MHz PCI-X", /* 0x04 */ | ||
57 | NULL, /* 0x05 */ | ||
58 | NULL, /* 0x06 */ | ||
59 | NULL, /* 0x07 */ | ||
60 | NULL, /* 0x08 */ | ||
61 | "66 MHz PCI-X 266", /* 0x09 */ | ||
62 | "100 MHz PCI-X 266", /* 0x0a */ | ||
63 | "133 MHz PCI-X 266", /* 0x0b */ | ||
64 | "Unknown AGP", /* 0x0c */ | ||
65 | "1x AGP", /* 0x0d */ | ||
66 | "2x AGP", /* 0x0e */ | ||
67 | "4x AGP", /* 0x0f */ | ||
68 | "8x AGP", /* 0x10 */ | ||
69 | "66 MHz PCI-X 533", /* 0x11 */ | ||
70 | "100 MHz PCI-X 533", /* 0x12 */ | ||
71 | "133 MHz PCI-X 533", /* 0x13 */ | ||
72 | "2.5 GT/s PCIe", /* 0x14 */ | ||
73 | "5.0 GT/s PCIe", /* 0x15 */ | ||
74 | "8.0 GT/s PCIe", /* 0x16 */ | ||
75 | }; | ||
76 | |||
77 | static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf) | ||
78 | { | ||
79 | const char *speed_string; | ||
80 | |||
81 | if (speed < ARRAY_SIZE(pci_bus_speed_strings)) | ||
82 | speed_string = pci_bus_speed_strings[speed]; | ||
83 | else | ||
84 | speed_string = "Unknown"; | ||
85 | |||
86 | return sprintf(buf, "%s\n", speed_string); | ||
87 | } | ||
88 | |||
89 | static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf) | ||
90 | { | ||
91 | return bus_speed_read(slot->bus->max_bus_speed, buf); | ||
92 | } | ||
93 | |||
94 | static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf) | ||
95 | { | ||
96 | return bus_speed_read(slot->bus->cur_bus_speed, buf); | ||
97 | } | ||
98 | |||
50 | static void pci_slot_release(struct kobject *kobj) | 99 | static void pci_slot_release(struct kobject *kobj) |
51 | { | 100 | { |
52 | struct pci_dev *dev; | 101 | struct pci_dev *dev; |
@@ -66,9 +115,15 @@ static void pci_slot_release(struct kobject *kobj) | |||
66 | 115 | ||
67 | static struct pci_slot_attribute pci_slot_attr_address = | 116 | static struct pci_slot_attribute pci_slot_attr_address = |
68 | __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); | 117 | __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); |
118 | static struct pci_slot_attribute pci_slot_attr_max_speed = | ||
119 | __ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL); | ||
120 | static struct pci_slot_attribute pci_slot_attr_cur_speed = | ||
121 | __ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL); | ||
69 | 122 | ||
70 | static struct attribute *pci_slot_default_attrs[] = { | 123 | static struct attribute *pci_slot_default_attrs[] = { |
71 | &pci_slot_attr_address.attr, | 124 | &pci_slot_attr_address.attr, |
125 | &pci_slot_attr_max_speed.attr, | ||
126 | &pci_slot_attr_cur_speed.attr, | ||
72 | NULL, | 127 | NULL, |
73 | }; | 128 | }; |
74 | 129 | ||
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c new file mode 100644 index 000000000000..a5a5ca17cfe6 --- /dev/null +++ b/drivers/pci/vpd.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * File: vpd.c | ||
3 | * Purpose: Provide PCI VPD support | ||
4 | * | ||
5 | * Copyright (C) 2010 Broadcom Corporation. | ||
6 | */ | ||
7 | |||
8 | #include <linux/pci.h> | ||
9 | |||
10 | int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt) | ||
11 | { | ||
12 | int i; | ||
13 | |||
14 | for (i = off; i < len; ) { | ||
15 | u8 val = buf[i]; | ||
16 | |||
17 | if (val & PCI_VPD_LRDT) { | ||
18 | /* Don't return success of the tag isn't complete */ | ||
19 | if (i + PCI_VPD_LRDT_TAG_SIZE > len) | ||
20 | break; | ||
21 | |||
22 | if (val == rdt) | ||
23 | return i; | ||
24 | |||
25 | i += PCI_VPD_LRDT_TAG_SIZE + | ||
26 | pci_vpd_lrdt_size(&buf[i]); | ||
27 | } else { | ||
28 | u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK; | ||
29 | |||
30 | if (tag == rdt) | ||
31 | return i; | ||
32 | |||
33 | if (tag == PCI_VPD_SRDT_END) | ||
34 | break; | ||
35 | |||
36 | i += PCI_VPD_SRDT_TAG_SIZE + | ||
37 | pci_vpd_srdt_size(&buf[i]); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | return -ENOENT; | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(pci_vpd_find_tag); | ||
44 | |||
45 | int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, | ||
46 | unsigned int len, const char *kw) | ||
47 | { | ||
48 | int i; | ||
49 | |||
50 | for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) { | ||
51 | if (buf[i + 0] == kw[0] && | ||
52 | buf[i + 1] == kw[1]) | ||
53 | return i; | ||
54 | |||
55 | i += PCI_VPD_INFO_FLD_HDR_SIZE + | ||
56 | pci_vpd_info_field_size(&buf[i]); | ||
57 | } | ||
58 | |||
59 | return -ENOENT; | ||
60 | } | ||
61 | EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword); | ||