diff options
author | Michal Marek <mmarek@suse.cz> | 2011-03-09 10:15:44 -0500 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2011-03-09 10:15:44 -0500 |
commit | 2d8ad8719591fa803b0d589ed057fa46f49b7155 (patch) | |
tree | 4ae051577dad1161c91dafbf4207bb10a9dc91bb /drivers/pci/hotplug | |
parent | 9b4ce7bce5f30712fd926ab4599a803314a07719 (diff) | |
parent | c56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (diff) |
Merge commit 'v2.6.38-rc1' into kbuild/packaging
Diffstat (limited to 'drivers/pci/hotplug')
32 files changed, 337 insertions, 641 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 3c76fc67cf0e..3bc72d18b121 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/pci_hotplug.h> | 32 | #include <linux/pci_hotplug.h> |
33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
34 | #include <linux/pci-acpi.h> | 34 | #include <linux/pci-acpi.h> |
35 | #include <linux/slab.h> | ||
35 | 36 | ||
36 | #define MY_NAME "acpi_pcihp" | 37 | #define MY_NAME "acpi_pcihp" |
37 | 38 | ||
@@ -337,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
337 | acpi_handle chandle, handle; | 338 | acpi_handle chandle, handle; |
338 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; | 339 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; |
339 | 340 | ||
340 | flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | 341 | flags &= OSC_SHPC_NATIVE_HP_CONTROL; |
341 | OSC_SHPC_NATIVE_HP_CONTROL | | ||
342 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
343 | if (!flags) { | 342 | if (!flags) { |
344 | err("Invalid flags %u specified!\n", flags); | 343 | err("Invalid flags %u specified!\n", flags); |
345 | return -EINVAL; | 344 | return -EINVAL; |
@@ -359,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
359 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); | 358 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); |
360 | dbg("Trying to get hotplug control for %s\n", | 359 | dbg("Trying to get hotplug control for %s\n", |
361 | (char *)string.pointer); | 360 | (char *)string.pointer); |
362 | status = acpi_pci_osc_control_set(handle, flags); | 361 | status = acpi_pci_osc_control_set(handle, &flags, flags); |
363 | if (ACPI_SUCCESS(status)) | 362 | if (ACPI_SUCCESS(status)) |
364 | goto got_one; | 363 | goto got_one; |
365 | if (status == AE_SUPPORT) | 364 | if (status == AE_SUPPORT) |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index bab52047baa8..7722108e78df 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -36,7 +36,6 @@ | |||
36 | #define _ACPIPHP_H | 36 | #define _ACPIPHP_H |
37 | 37 | ||
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/kobject.h> | ||
40 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
41 | #include <linux/pci_hotplug.h> | 40 | #include <linux/pci_hotplug.h> |
42 | 41 | ||
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..cb23aa2ebf96 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/pci_hotplug.h> | 47 | #include <linux/pci_hotplug.h> |
48 | #include <linux/pci-acpi.h> | 48 | #include <linux/pci-acpi.h> |
49 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
50 | #include <linux/slab.h> | ||
50 | 51 | ||
51 | #include "../pci.h" | 52 | #include "../pci.h" |
52 | #include "acpiphp.h" | 53 | #include "acpiphp.h" |
@@ -720,12 +721,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func) | |||
720 | -ret_val); | 721 | -ret_val); |
721 | goto acpiphp_bus_add_out; | 722 | goto acpiphp_bus_add_out; |
722 | } | 723 | } |
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); | 724 | ret_val = acpi_bus_start(device); |
730 | 725 | ||
731 | acpiphp_bus_add_out: | 726 | acpiphp_bus_add_out: |
@@ -755,6 +750,24 @@ static int acpiphp_bus_trim(acpi_handle handle) | |||
755 | return retval; | 750 | return retval; |
756 | } | 751 | } |
757 | 752 | ||
753 | static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | ||
754 | { | ||
755 | struct acpiphp_func *func; | ||
756 | union acpi_object params[2]; | ||
757 | struct acpi_object_list arg_list; | ||
758 | |||
759 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
760 | arg_list.count = 2; | ||
761 | arg_list.pointer = params; | ||
762 | params[0].type = ACPI_TYPE_INTEGER; | ||
763 | params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; | ||
764 | params[1].type = ACPI_TYPE_INTEGER; | ||
765 | params[1].integer.value = 1; | ||
766 | /* _REG is optional, we don't care about if there is failure */ | ||
767 | acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); | ||
768 | } | ||
769 | } | ||
770 | |||
758 | /** | 771 | /** |
759 | * enable_device - enable, configure a slot | 772 | * enable_device - enable, configure a slot |
760 | * @slot: slot to be enabled | 773 | * @slot: slot to be enabled |
@@ -811,6 +824,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
811 | pci_bus_assign_resources(bus); | 824 | pci_bus_assign_resources(bus); |
812 | acpiphp_sanitize_bus(bus); | 825 | acpiphp_sanitize_bus(bus); |
813 | acpiphp_set_hpp_values(bus); | 826 | acpiphp_set_hpp_values(bus); |
827 | acpiphp_set_acpi_region(slot); | ||
814 | pci_enable_bridges(bus); | 828 | pci_enable_bridges(bus); |
815 | pci_bus_add_devices(bus); | 829 | pci_bus_add_devices(bus); |
816 | 830 | ||
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index aa5df485f8cf..e525263210ee 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
31 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
@@ -107,7 +108,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status); | |||
107 | static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status); | 108 | static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status); |
108 | static void ibm_handle_events(acpi_handle handle, u32 event, void *context); | 109 | static void ibm_handle_events(acpi_handle handle, u32 event, void *context); |
109 | static int ibm_get_table_from_acpi(char **bufp); | 110 | static int ibm_get_table_from_acpi(char **bufp); |
110 | static ssize_t ibm_read_apci_table(struct kobject *kobj, | 111 | static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, |
111 | struct bin_attribute *bin_attr, | 112 | struct bin_attribute *bin_attr, |
112 | char *buffer, loff_t pos, size_t size); | 113 | char *buffer, loff_t pos, size_t size); |
113 | static acpi_status __init ibm_find_acpi_device(acpi_handle handle, | 114 | static acpi_status __init ibm_find_acpi_device(acpi_handle handle, |
@@ -350,6 +351,7 @@ read_table_done: | |||
350 | 351 | ||
351 | /** | 352 | /** |
352 | * ibm_read_apci_table - callback for the sysfs apci_table file | 353 | * ibm_read_apci_table - callback for the sysfs apci_table file |
354 | * @filp: the open sysfs file | ||
353 | * @kobj: the kobject this binary attribute is a part of | 355 | * @kobj: the kobject this binary attribute is a part of |
354 | * @bin_attr: struct bin_attribute for this file | 356 | * @bin_attr: struct bin_attribute for this file |
355 | * @buffer: the kernel space buffer to fill | 357 | * @buffer: the kernel space buffer to fill |
@@ -363,7 +365,7 @@ read_table_done: | |||
363 | * things get really tricky here... | 365 | * things get really tricky here... |
364 | * our solution is to only allow reading the table in all at once. | 366 | * our solution is to only allow reading the table in all at once. |
365 | */ | 367 | */ |
366 | static ssize_t ibm_read_apci_table(struct kobject *kobj, | 368 | static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, |
367 | struct bin_attribute *bin_attr, | 369 | struct bin_attribute *bin_attr, |
368 | char *buffer, loff_t pos, size_t size) | 370 | char *buffer, loff_t pos, size_t size) |
369 | { | 371 | { |
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..4952c3b9379d 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); |
@@ -853,6 +829,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
853 | return err; | 829 | return err; |
854 | } | 830 | } |
855 | 831 | ||
832 | bus = pdev->subordinate; | ||
833 | if (!bus) { | ||
834 | dev_notice(&pdev->dev, "the device is not a bridge, " | ||
835 | "skipping\n"); | ||
836 | rc = -ENODEV; | ||
837 | goto err_disable_device; | ||
838 | } | ||
839 | |||
856 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC | 840 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC |
857 | * discovery | 841 | * discovery |
858 | */ | 842 | */ |
@@ -871,7 +855,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
871 | goto err_disable_device; | 855 | goto err_disable_device; |
872 | } | 856 | } |
873 | 857 | ||
874 | /* Check for the proper subsytem ID's | 858 | /* Check for the proper subsystem ID's |
875 | * Intel uses a different SSID programming model than Compaq. | 859 | * Intel uses a different SSID programming model than Compaq. |
876 | * For Intel, each SSID bit identifies a PHP capability. | 860 | * For Intel, each SSID bit identifies a PHP capability. |
877 | * Also Intel HPC's may have RID=0. | 861 | * Also Intel HPC's may have RID=0. |
@@ -929,22 +913,22 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
929 | pci_read_config_byte(pdev, 0x41, &bus_cap); | 913 | pci_read_config_byte(pdev, 0x41, &bus_cap); |
930 | if (bus_cap & 0x80) { | 914 | if (bus_cap & 0x80) { |
931 | dbg("bus max supports 133MHz PCI-X\n"); | 915 | dbg("bus max supports 133MHz PCI-X\n"); |
932 | ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; | 916 | bus->max_bus_speed = PCI_SPEED_133MHz_PCIX; |
933 | break; | 917 | break; |
934 | } | 918 | } |
935 | if (bus_cap & 0x40) { | 919 | if (bus_cap & 0x40) { |
936 | dbg("bus max supports 100MHz PCI-X\n"); | 920 | dbg("bus max supports 100MHz PCI-X\n"); |
937 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | 921 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
938 | break; | 922 | break; |
939 | } | 923 | } |
940 | if (bus_cap & 20) { | 924 | if (bus_cap & 20) { |
941 | dbg("bus max supports 66MHz PCI-X\n"); | 925 | dbg("bus max supports 66MHz PCI-X\n"); |
942 | ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; | 926 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; |
943 | break; | 927 | break; |
944 | } | 928 | } |
945 | if (bus_cap & 10) { | 929 | if (bus_cap & 10) { |
946 | dbg("bus max supports 66MHz PCI\n"); | 930 | dbg("bus max supports 66MHz PCI\n"); |
947 | ctrl->speed_capability = PCI_SPEED_66MHz; | 931 | bus->max_bus_speed = PCI_SPEED_66MHz; |
948 | break; | 932 | break; |
949 | } | 933 | } |
950 | 934 | ||
@@ -955,7 +939,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
955 | case PCI_SUB_HPC_ID: | 939 | case PCI_SUB_HPC_ID: |
956 | /* Original 6500/7000 implementation */ | 940 | /* Original 6500/7000 implementation */ |
957 | ctrl->slot_switch_type = 1; | 941 | ctrl->slot_switch_type = 1; |
958 | ctrl->speed_capability = PCI_SPEED_33MHz; | 942 | bus->max_bus_speed = PCI_SPEED_33MHz; |
959 | ctrl->push_button = 0; | 943 | ctrl->push_button = 0; |
960 | ctrl->pci_config_space = 1; | 944 | ctrl->pci_config_space = 1; |
961 | ctrl->defeature_PHP = 1; | 945 | ctrl->defeature_PHP = 1; |
@@ -966,7 +950,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
966 | /* First Pushbutton implementation */ | 950 | /* First Pushbutton implementation */ |
967 | ctrl->push_flag = 1; | 951 | ctrl->push_flag = 1; |
968 | ctrl->slot_switch_type = 1; | 952 | ctrl->slot_switch_type = 1; |
969 | ctrl->speed_capability = PCI_SPEED_33MHz; | 953 | bus->max_bus_speed = PCI_SPEED_33MHz; |
970 | ctrl->push_button = 1; | 954 | ctrl->push_button = 1; |
971 | ctrl->pci_config_space = 1; | 955 | ctrl->pci_config_space = 1; |
972 | ctrl->defeature_PHP = 1; | 956 | ctrl->defeature_PHP = 1; |
@@ -976,7 +960,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
976 | case PCI_SUB_HPC_ID_INTC: | 960 | case PCI_SUB_HPC_ID_INTC: |
977 | /* Third party (6500/7000) */ | 961 | /* Third party (6500/7000) */ |
978 | ctrl->slot_switch_type = 1; | 962 | ctrl->slot_switch_type = 1; |
979 | ctrl->speed_capability = PCI_SPEED_33MHz; | 963 | bus->max_bus_speed = PCI_SPEED_33MHz; |
980 | ctrl->push_button = 0; | 964 | ctrl->push_button = 0; |
981 | ctrl->pci_config_space = 1; | 965 | ctrl->pci_config_space = 1; |
982 | ctrl->defeature_PHP = 1; | 966 | ctrl->defeature_PHP = 1; |
@@ -987,7 +971,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
987 | /* First 66 Mhz implementation */ | 971 | /* First 66 Mhz implementation */ |
988 | ctrl->push_flag = 1; | 972 | ctrl->push_flag = 1; |
989 | ctrl->slot_switch_type = 1; | 973 | ctrl->slot_switch_type = 1; |
990 | ctrl->speed_capability = PCI_SPEED_66MHz; | 974 | bus->max_bus_speed = PCI_SPEED_66MHz; |
991 | ctrl->push_button = 1; | 975 | ctrl->push_button = 1; |
992 | ctrl->pci_config_space = 1; | 976 | ctrl->pci_config_space = 1; |
993 | ctrl->defeature_PHP = 1; | 977 | ctrl->defeature_PHP = 1; |
@@ -998,7 +982,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
998 | /* First PCI-X implementation, 100MHz */ | 982 | /* First PCI-X implementation, 100MHz */ |
999 | ctrl->push_flag = 1; | 983 | ctrl->push_flag = 1; |
1000 | ctrl->slot_switch_type = 1; | 984 | ctrl->slot_switch_type = 1; |
1001 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | 985 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
1002 | ctrl->push_button = 1; | 986 | ctrl->push_button = 1; |
1003 | ctrl->pci_config_space = 1; | 987 | ctrl->pci_config_space = 1; |
1004 | ctrl->defeature_PHP = 1; | 988 | ctrl->defeature_PHP = 1; |
@@ -1015,9 +999,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1015 | case PCI_VENDOR_ID_INTEL: | 999 | case PCI_VENDOR_ID_INTEL: |
1016 | /* Check for speed capability (0=33, 1=66) */ | 1000 | /* Check for speed capability (0=33, 1=66) */ |
1017 | if (subsystem_deviceid & 0x0001) | 1001 | if (subsystem_deviceid & 0x0001) |
1018 | ctrl->speed_capability = PCI_SPEED_66MHz; | 1002 | bus->max_bus_speed = PCI_SPEED_66MHz; |
1019 | else | 1003 | else |
1020 | ctrl->speed_capability = PCI_SPEED_33MHz; | 1004 | bus->max_bus_speed = PCI_SPEED_33MHz; |
1021 | 1005 | ||
1022 | /* Check for push button */ | 1006 | /* Check for push button */ |
1023 | if (subsystem_deviceid & 0x0002) | 1007 | if (subsystem_deviceid & 0x0002) |
@@ -1079,7 +1063,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1079 | pdev->bus->number); | 1063 | pdev->bus->number); |
1080 | 1064 | ||
1081 | dbg("Hotplug controller capabilities:\n"); | 1065 | dbg("Hotplug controller capabilities:\n"); |
1082 | dbg(" speed_capability %d\n", ctrl->speed_capability); | 1066 | dbg(" speed_capability %d\n", bus->max_bus_speed); |
1083 | dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? | 1067 | dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? |
1084 | "switch present" : "no switch"); | 1068 | "switch present" : "no switch"); |
1085 | dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? | 1069 | dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? |
@@ -1098,13 +1082,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1098 | 1082 | ||
1099 | /* make our own copy of the pci bus structure, | 1083 | /* make our own copy of the pci bus structure, |
1100 | * as we like tweaking it a lot */ | 1084 | * as we like tweaking it a lot */ |
1101 | ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); | 1085 | ctrl->pci_bus = kmemdup(pdev->bus, sizeof(*ctrl->pci_bus), GFP_KERNEL); |
1102 | if (!ctrl->pci_bus) { | 1086 | if (!ctrl->pci_bus) { |
1103 | err("out of memory\n"); | 1087 | err("out of memory\n"); |
1104 | rc = -ENOMEM; | 1088 | rc = -ENOMEM; |
1105 | goto err_free_ctrl; | 1089 | goto err_free_ctrl; |
1106 | } | 1090 | } |
1107 | memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus)); | ||
1108 | 1091 | ||
1109 | ctrl->bus = pdev->bus->number; | 1092 | ctrl->bus = pdev->bus->number; |
1110 | ctrl->rev = pdev->revision; | 1093 | ctrl->rev = pdev->revision; |
@@ -1142,7 +1125,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1142 | } | 1125 | } |
1143 | 1126 | ||
1144 | /* Check for 66Mhz operation */ | 1127 | /* Check for 66Mhz operation */ |
1145 | ctrl->speed = get_controller_speed(ctrl); | 1128 | bus->cur_bus_speed = get_controller_speed(ctrl); |
1146 | 1129 | ||
1147 | 1130 | ||
1148 | /******************************************************** | 1131 | /******************************************************** |
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/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index e6089bdb6e5b..4cb30447a486 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -28,15 +28,17 @@ | |||
28 | 28 | ||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | ||
31 | #include <linux/types.h> | 32 | #include <linux/types.h> |
32 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
33 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include <linux/pci_hotplug.h> | 36 | #include <linux/pci_hotplug.h> |
36 | #include <linux/smp_lock.h> | 37 | #include <linux/mutex.h> |
37 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
38 | #include "cpqphp.h" | 39 | #include "cpqphp.h" |
39 | 40 | ||
41 | static DEFINE_MUTEX(cpqphp_mutex); | ||
40 | static int show_ctrl (struct controller *ctrl, char *buf) | 42 | static int show_ctrl (struct controller *ctrl, char *buf) |
41 | { | 43 | { |
42 | char *out = buf; | 44 | char *out = buf; |
@@ -146,7 +148,7 @@ static int open(struct inode *inode, struct file *file) | |||
146 | struct ctrl_dbg *dbg; | 148 | struct ctrl_dbg *dbg; |
147 | int retval = -ENOMEM; | 149 | int retval = -ENOMEM; |
148 | 150 | ||
149 | lock_kernel(); | 151 | mutex_lock(&cpqphp_mutex); |
150 | dbg = kmalloc(sizeof(*dbg), GFP_KERNEL); | 152 | dbg = kmalloc(sizeof(*dbg), GFP_KERNEL); |
151 | if (!dbg) | 153 | if (!dbg) |
152 | goto exit; | 154 | goto exit; |
@@ -159,7 +161,7 @@ static int open(struct inode *inode, struct file *file) | |||
159 | file->private_data = dbg; | 161 | file->private_data = dbg; |
160 | retval = 0; | 162 | retval = 0; |
161 | exit: | 163 | exit: |
162 | unlock_kernel(); | 164 | mutex_unlock(&cpqphp_mutex); |
163 | return retval; | 165 | return retval; |
164 | } | 166 | } |
165 | 167 | ||
@@ -168,7 +170,7 @@ static loff_t lseek(struct file *file, loff_t off, int whence) | |||
168 | struct ctrl_dbg *dbg; | 170 | struct ctrl_dbg *dbg; |
169 | loff_t new = -1; | 171 | loff_t new = -1; |
170 | 172 | ||
171 | lock_kernel(); | 173 | mutex_lock(&cpqphp_mutex); |
172 | dbg = file->private_data; | 174 | dbg = file->private_data; |
173 | 175 | ||
174 | switch (whence) { | 176 | switch (whence) { |
@@ -180,10 +182,10 @@ static loff_t lseek(struct file *file, loff_t off, int whence) | |||
180 | break; | 182 | break; |
181 | } | 183 | } |
182 | if (new < 0 || new > dbg->size) { | 184 | if (new < 0 || new > dbg->size) { |
183 | unlock_kernel(); | 185 | mutex_unlock(&cpqphp_mutex); |
184 | return -EINVAL; | 186 | return -EINVAL; |
185 | } | 187 | } |
186 | unlock_kernel(); | 188 | mutex_unlock(&cpqphp_mutex); |
187 | return (file->f_pos = new); | 189 | return (file->f_pos = new); |
188 | } | 190 | } |
189 | 191 | ||
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..17d10e2e8fb6 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/slab.h> | ||
22 | #include "../pci.h" | 23 | #include "../pci.h" |
23 | 24 | ||
24 | struct legacy_slot { | 25 | struct legacy_slot { |
@@ -73,7 +74,7 @@ static void legacy_release(struct kobject *kobj) | |||
73 | } | 74 | } |
74 | 75 | ||
75 | static struct kobj_type legacy_ktype = { | 76 | static struct kobj_type legacy_ktype = { |
76 | .sysfs_ops = &(struct sysfs_ops){ | 77 | .sysfs_ops = &(const struct sysfs_ops){ |
77 | .store = legacy_store, .show = legacy_show | 78 | .store = legacy_store, .show = legacy_show |
78 | }, | 79 | }, |
79 | .release = &legacy_release, | 80 | .release = &legacy_release, |
@@ -134,7 +135,7 @@ static int __init init_legacy(void) | |||
134 | struct pci_dev *pdev = NULL; | 135 | struct pci_dev *pdev = NULL; |
135 | 136 | ||
136 | /* Add existing devices */ | 137 | /* Add existing devices */ |
137 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) | 138 | for_each_pci_dev(pdev) |
138 | legacy_add_slot(pdev); | 139 | legacy_add_slot(pdev); |
139 | 140 | ||
140 | /* Be alerted of any new ones */ | 141 | /* Be alerted of any new ones */ |
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..2850e64dedae 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,13 +260,28 @@ 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; |
267 | 276 | ||
268 | for (;;) { | 277 | for (;;) { |
269 | offset = next_offset; | 278 | offset = next_offset; |
279 | |||
280 | /* Make sure what we read is still in the mapped section */ | ||
281 | if (WARN(offset > (ebda_sz * 1024 - 4), | ||
282 | "ibmphp_ebda: next read is beyond ebda_sz\n")) | ||
283 | break; | ||
284 | |||
270 | next_offset = readw (io_mem + offset); /* offset of next blk */ | 285 | next_offset = readw (io_mem + offset); /* offset of next blk */ |
271 | 286 | ||
272 | offset += 2; | 287 | offset += 2; |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index c7084f0eca5a..f59ed30512b5 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 | ||
@@ -132,8 +133,8 @@ void __init ibmphp_hpc_initvars (void) | |||
132 | debug ("%s - Entry\n", __func__); | 133 | debug ("%s - Entry\n", __func__); |
133 | 134 | ||
134 | mutex_init(&sem_hpcaccess); | 135 | mutex_init(&sem_hpcaccess); |
135 | init_MUTEX (&semOperations); | 136 | sema_init(&semOperations, 1); |
136 | init_MUTEX_LOCKED (&sem_exit); | 137 | sema_init(&sem_exit, 0); |
137 | to_debug = 0; | 138 | to_debug = 0; |
138 | 139 | ||
139 | debug ("%s - Exit\n", __func__); | 140 | debug ("%s - Exit\n", __func__); |
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..6d2eea93298f 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/kobject.h> | 33 | #include <linux/kobject.h> |
34 | #include <linux/sysfs.h> | 34 | #include <linux/sysfs.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/slab.h> | ||
37 | #include <linux/init.h> | 36 | #include <linux/init.h> |
38 | #include <linux/mount.h> | 37 | #include <linux/mount.h> |
39 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
@@ -64,32 +63,6 @@ static int debug; | |||
64 | static LIST_HEAD(pci_hotplug_slot_list); | 63 | static LIST_HEAD(pci_hotplug_slot_list); |
65 | static DEFINE_MUTEX(pci_hp_mutex); | 64 | static DEFINE_MUTEX(pci_hp_mutex); |
66 | 65 | ||
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 | 66 | #ifdef CONFIG_HOTPLUG_PCI_CPCI |
94 | extern int cpci_hotplug_init(int debug); | 67 | extern int cpci_hotplug_init(int debug); |
95 | extern void cpci_hotplug_exit(void); | 68 | extern void cpci_hotplug_exit(void); |
@@ -118,8 +91,6 @@ GET_STATUS(power_status, u8) | |||
118 | GET_STATUS(attention_status, u8) | 91 | GET_STATUS(attention_status, u8) |
119 | GET_STATUS(latch_status, u8) | 92 | GET_STATUS(latch_status, u8) |
120 | GET_STATUS(adapter_status, u8) | 93 | 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 | 94 | ||
124 | static ssize_t power_read_file(struct pci_slot *slot, char *buf) | 95 | static ssize_t power_read_file(struct pci_slot *slot, char *buf) |
125 | { | 96 | { |
@@ -263,60 +234,6 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = { | |||
263 | .show = presence_read_file, | 234 | .show = presence_read_file, |
264 | }; | 235 | }; |
265 | 236 | ||
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, | 237 | static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, |
321 | size_t count) | 238 | size_t count) |
322 | { | 239 | { |
@@ -391,26 +308,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot) | |||
391 | return false; | 308 | return false; |
392 | } | 309 | } |
393 | 310 | ||
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) | 311 | static bool has_test_file(struct pci_slot *pci_slot) |
415 | { | 312 | { |
416 | struct hotplug_slot *slot = pci_slot->hotplug; | 313 | struct hotplug_slot *slot = pci_slot->hotplug; |
@@ -456,20 +353,6 @@ static int fs_add_slot(struct pci_slot *slot) | |||
456 | goto exit_adapter; | 353 | goto exit_adapter; |
457 | } | 354 | } |
458 | 355 | ||
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)) { | 356 | if (has_test_file(slot)) { |
474 | retval = sysfs_create_file(&slot->kobj, | 357 | retval = sysfs_create_file(&slot->kobj, |
475 | &hotplug_slot_attr_test.attr); | 358 | &hotplug_slot_attr_test.attr); |
@@ -480,14 +363,6 @@ static int fs_add_slot(struct pci_slot *slot) | |||
480 | goto exit; | 363 | goto exit; |
481 | 364 | ||
482 | exit_test: | 365 | 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)) | 366 | if (has_adapter_file(slot)) |
492 | sysfs_remove_file(&slot->kobj, | 367 | sysfs_remove_file(&slot->kobj, |
493 | &hotplug_slot_attr_presence.attr); | 368 | &hotplug_slot_attr_presence.attr); |
@@ -523,14 +398,6 @@ static void fs_remove_slot(struct pci_slot *slot) | |||
523 | sysfs_remove_file(&slot->kobj, | 398 | sysfs_remove_file(&slot->kobj, |
524 | &hotplug_slot_attr_presence.attr); | 399 | &hotplug_slot_attr_presence.attr); |
525 | 400 | ||
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)) | 401 | if (has_test_file(slot)) |
535 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); | 402 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); |
536 | 403 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 4ed76b47b6dc..838f571027b7 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/sched.h> /* signal_pending() */ | 36 | #include <linux/sched.h> /* signal_pending() */ |
37 | #include <linux/pcieport_if.h> | 37 | #include <linux/pcieport_if.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/workqueue.h> | ||
39 | 40 | ||
40 | #define MY_NAME "pciehp" | 41 | #define MY_NAME "pciehp" |
41 | 42 | ||
@@ -44,6 +45,7 @@ extern int pciehp_poll_time; | |||
44 | extern int pciehp_debug; | 45 | extern int pciehp_debug; |
45 | extern int pciehp_force; | 46 | extern int pciehp_force; |
46 | extern struct workqueue_struct *pciehp_wq; | 47 | extern struct workqueue_struct *pciehp_wq; |
48 | extern struct workqueue_struct *pciehp_ordered_wq; | ||
47 | 49 | ||
48 | #define dbg(format, arg...) \ | 50 | #define dbg(format, arg...) \ |
49 | do { \ | 51 | do { \ |
@@ -176,19 +178,11 @@ static inline void pciehp_firmware_init(void) | |||
176 | { | 178 | { |
177 | pciehp_acpi_slot_detection_init(); | 179 | pciehp_acpi_slot_detection_init(); |
178 | } | 180 | } |
179 | |||
180 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) | ||
181 | { | ||
182 | int retval; | ||
183 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | ||
184 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
185 | retval = acpi_get_hp_hw_control_from_firmware(dev, flags); | ||
186 | if (retval) | ||
187 | return retval; | ||
188 | return pciehp_acpi_slot_detection_check(dev); | ||
189 | } | ||
190 | #else | 181 | #else |
191 | #define pciehp_firmware_init() do {} while (0) | 182 | #define pciehp_firmware_init() do {} while (0) |
192 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 | 183 | static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev) |
184 | { | ||
185 | return 0; | ||
186 | } | ||
193 | #endif /* CONFIG_ACPI */ | 187 | #endif /* CONFIG_ACPI */ |
194 | #endif /* _PCIEHP_H */ | 188 | #endif /* _PCIEHP_H */ |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index b09b083011d6..5f7226223a62 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/acpi.h> | 26 | #include <linux/acpi.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/pci_hotplug.h> | 28 | #include <linux/pci_hotplug.h> |
29 | #include <linux/slab.h> | ||
29 | #include "pciehp.h" | 30 | #include "pciehp.h" |
30 | 31 | ||
31 | #define PCIEHP_DETECT_PCIE (0) | 32 | #define PCIEHP_DETECT_PCIE (0) |
@@ -84,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
84 | acpi_handle handle; | 85 | acpi_handle handle; |
85 | struct dummy_slot *slot, *tmp; | 86 | struct dummy_slot *slot, *tmp; |
86 | struct pci_dev *pdev = dev->port; | 87 | struct pci_dev *pdev = dev->port; |
87 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 88 | |
88 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | ||
89 | return -ENODEV; | ||
90 | pos = pci_pcie_cap(pdev); | 89 | pos = pci_pcie_cap(pdev); |
91 | if (!pos) | 90 | if (!pos) |
92 | return -ENODEV; | 91 | return -ENODEV; |
@@ -116,7 +115,8 @@ static struct pcie_port_service_driver __initdata dummy_driver = { | |||
116 | static int __init select_detection_mode(void) | 115 | static int __init select_detection_mode(void) |
117 | { | 116 | { |
118 | struct dummy_slot *slot, *tmp; | 117 | struct dummy_slot *slot, *tmp; |
119 | pcie_port_service_register(&dummy_driver); | 118 | if (pcie_port_service_register(&dummy_driver)) |
119 | return PCIEHP_DETECT_ACPI; | ||
120 | pcie_port_service_unregister(&dummy_driver); | 120 | pcie_port_service_unregister(&dummy_driver); |
121 | list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { | 121 | list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { |
122 | list_del(&slot->list); | 122 | list_del(&slot->list); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 5674b2075bdc..7ac8358df8fd 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/types.h> | 34 | #include <linux/types.h> |
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include "pciehp.h" | 36 | #include "pciehp.h" |
@@ -42,6 +43,7 @@ int pciehp_poll_mode; | |||
42 | int pciehp_poll_time; | 43 | int pciehp_poll_time; |
43 | int pciehp_force; | 44 | int pciehp_force; |
44 | struct workqueue_struct *pciehp_wq; | 45 | struct workqueue_struct *pciehp_wq; |
46 | struct workqueue_struct *pciehp_ordered_wq; | ||
45 | 47 | ||
46 | #define DRIVER_VERSION "0.4" | 48 | #define DRIVER_VERSION "0.4" |
47 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" | 49 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" |
@@ -58,7 +60,7 @@ module_param(pciehp_force, bool, 0644); | |||
58 | MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); | 60 | MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); |
59 | MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); | 61 | MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); |
60 | MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); | 62 | MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); |
61 | MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); | 63 | MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing"); |
62 | 64 | ||
63 | #define PCIE_MODULE_NAME "pciehp" | 65 | #define PCIE_MODULE_NAME "pciehp" |
64 | 66 | ||
@@ -69,8 +71,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); | |||
69 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | 71 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); |
70 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | 72 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); |
71 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 73 | 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 | 74 | ||
75 | /** | 75 | /** |
76 | * release_slot - free up the memory used by a slot | 76 | * release_slot - free up the memory used by a slot |
@@ -113,8 +113,6 @@ static int init_slot(struct controller *ctrl) | |||
113 | ops->disable_slot = disable_slot; | 113 | ops->disable_slot = disable_slot; |
114 | ops->get_power_status = get_power_status; | 114 | ops->get_power_status = get_power_status; |
115 | ops->get_adapter_status = get_adapter_status; | 115 | 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)) | 116 | if (MRL_SENS(ctrl)) |
119 | ops->get_latch_status = get_latch_status; | 117 | ops->get_latch_status = get_latch_status; |
120 | if (ATTN_LED(ctrl)) { | 118 | if (ATTN_LED(ctrl)) { |
@@ -227,27 +225,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
227 | return pciehp_get_adapter_status(slot, value); | 225 | return pciehp_get_adapter_status(slot, value); |
228 | } | 226 | } |
229 | 227 | ||
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) | 228 | static int pciehp_probe(struct pcie_device *dev) |
252 | { | 229 | { |
253 | int rc; | 230 | int rc; |
@@ -259,7 +236,7 @@ static int pciehp_probe(struct pcie_device *dev) | |||
259 | dev_info(&dev->device, | 236 | dev_info(&dev->device, |
260 | "Bypassing BIOS check for pciehp use on %s\n", | 237 | "Bypassing BIOS check for pciehp use on %s\n", |
261 | pci_name(dev->port)); | 238 | pci_name(dev->port)); |
262 | else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) | 239 | else if (pciehp_acpi_slot_detection_check(dev->port)) |
263 | goto err_out_none; | 240 | goto err_out_none; |
264 | 241 | ||
265 | ctrl = pcie_init(dev); | 242 | ctrl = pcie_init(dev); |
@@ -364,18 +341,33 @@ static int __init pcied_init(void) | |||
364 | { | 341 | { |
365 | int retval = 0; | 342 | int retval = 0; |
366 | 343 | ||
344 | pciehp_wq = alloc_workqueue("pciehp", 0, 0); | ||
345 | if (!pciehp_wq) | ||
346 | return -ENOMEM; | ||
347 | |||
348 | pciehp_ordered_wq = alloc_ordered_workqueue("pciehp_ordered", 0); | ||
349 | if (!pciehp_ordered_wq) { | ||
350 | destroy_workqueue(pciehp_wq); | ||
351 | return -ENOMEM; | ||
352 | } | ||
353 | |||
367 | pciehp_firmware_init(); | 354 | pciehp_firmware_init(); |
368 | retval = pcie_port_service_register(&hpdriver_portdrv); | 355 | retval = pcie_port_service_register(&hpdriver_portdrv); |
369 | dbg("pcie_port_service_register = %d\n", retval); | 356 | dbg("pcie_port_service_register = %d\n", retval); |
370 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 357 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
371 | if (retval) | 358 | if (retval) { |
359 | destroy_workqueue(pciehp_ordered_wq); | ||
360 | destroy_workqueue(pciehp_wq); | ||
372 | dbg("Failure to register service\n"); | 361 | dbg("Failure to register service\n"); |
362 | } | ||
373 | return retval; | 363 | return retval; |
374 | } | 364 | } |
375 | 365 | ||
376 | static void __exit pcied_cleanup(void) | 366 | static void __exit pcied_cleanup(void) |
377 | { | 367 | { |
378 | dbg("unload_pciehpd()\n"); | 368 | dbg("unload_pciehpd()\n"); |
369 | destroy_workqueue(pciehp_ordered_wq); | ||
370 | destroy_workqueue(pciehp_wq); | ||
379 | pcie_port_service_unregister(&hpdriver_portdrv); | 371 | pcie_port_service_unregister(&hpdriver_portdrv); |
380 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); | 372 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); |
381 | } | 373 | } |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index d6ac1b261dd9..085dbb5fc168 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | #include <linux/workqueue.h> | ||
35 | #include "../pci.h" | 35 | #include "../pci.h" |
36 | #include "pciehp.h" | 36 | #include "pciehp.h" |
37 | 37 | ||
@@ -49,7 +49,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
49 | info->p_slot = p_slot; | 49 | info->p_slot = p_slot; |
50 | INIT_WORK(&info->work, interrupt_event_handler); | 50 | INIT_WORK(&info->work, interrupt_event_handler); |
51 | 51 | ||
52 | schedule_work(&info->work); | 52 | queue_work(pciehp_wq, &info->work); |
53 | 53 | ||
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
@@ -341,9 +341,10 @@ 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_ordered_wq, &info->work); |
347 | out: | 348 | out: |
348 | mutex_unlock(&p_slot->lock); | 349 | mutex_unlock(&p_slot->lock); |
349 | } | 350 | } |
@@ -376,7 +377,7 @@ static void handle_button_press_event(struct slot *p_slot) | |||
376 | if (ATTN_LED(ctrl)) | 377 | if (ATTN_LED(ctrl)) |
377 | pciehp_set_attention_status(p_slot, 0); | 378 | pciehp_set_attention_status(p_slot, 0); |
378 | 379 | ||
379 | schedule_delayed_work(&p_slot->work, 5*HZ); | 380 | queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ); |
380 | break; | 381 | break; |
381 | case BLINKINGOFF_STATE: | 382 | case BLINKINGOFF_STATE: |
382 | case BLINKINGON_STATE: | 383 | case BLINKINGON_STATE: |
@@ -438,7 +439,7 @@ static void handle_surprise_event(struct slot *p_slot) | |||
438 | else | 439 | else |
439 | p_slot->state = POWERON_STATE; | 440 | p_slot->state = POWERON_STATE; |
440 | 441 | ||
441 | queue_work(pciehp_wq, &info->work); | 442 | queue_work(pciehp_ordered_wq, &info->work); |
442 | } | 443 | } |
443 | 444 | ||
444 | static void interrupt_event_handler(struct work_struct *work) | 445 | static void interrupt_event_handler(struct work_struct *work) |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 10040d58c8ef..50a23da5d24d 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -36,12 +36,11 @@ | |||
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/time.h> | 38 | #include <linux/time.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | #include "../pci.h" | 41 | #include "../pci.h" |
41 | #include "pciehp.h" | 42 | #include "pciehp.h" |
42 | 43 | ||
43 | static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); | ||
44 | |||
45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | 44 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) |
46 | { | 45 | { |
47 | struct pci_dev *dev = ctrl->pcie->port; | 46 | struct pci_dev *dev = ctrl->pcie->port; |
@@ -492,6 +491,7 @@ int pciehp_power_on_slot(struct slot * slot) | |||
492 | u16 slot_cmd; | 491 | u16 slot_cmd; |
493 | u16 cmd_mask; | 492 | u16 cmd_mask; |
494 | u16 slot_status; | 493 | u16 slot_status; |
494 | u16 lnk_status; | ||
495 | int retval = 0; | 495 | int retval = 0; |
496 | 496 | ||
497 | /* Clear sticky power-fault bit from previous power failures */ | 497 | /* Clear sticky power-fault bit from previous power failures */ |
@@ -523,6 +523,14 @@ int pciehp_power_on_slot(struct slot * slot) | |||
523 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 523 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
524 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 524 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
525 | 525 | ||
526 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | ||
527 | if (retval) { | ||
528 | ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", | ||
529 | __func__); | ||
530 | return retval; | ||
531 | } | ||
532 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | ||
533 | |||
526 | return retval; | 534 | return retval; |
527 | } | 535 | } |
528 | 536 | ||
@@ -610,37 +618,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
610 | return IRQ_HANDLED; | 618 | return IRQ_HANDLED; |
611 | } | 619 | } |
612 | 620 | ||
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, | 621 | int pciehp_get_max_lnk_width(struct slot *slot, |
645 | enum pcie_link_width *value) | 622 | enum pcie_link_width *value) |
646 | { | 623 | { |
@@ -691,38 +668,6 @@ int pciehp_get_max_lnk_width(struct slot *slot, | |||
691 | return retval; | 668 | return retval; |
692 | } | 669 | } |
693 | 670 | ||
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, | 671 | int pciehp_get_cur_lnk_width(struct slot *slot, |
727 | enum pcie_link_width *value) | 672 | enum pcie_link_width *value) |
728 | { | 673 | { |
@@ -858,8 +803,8 @@ static void pcie_cleanup_slot(struct controller *ctrl) | |||
858 | { | 803 | { |
859 | struct slot *slot = ctrl->slot; | 804 | struct slot *slot = ctrl->slot; |
860 | cancel_delayed_work(&slot->work); | 805 | cancel_delayed_work(&slot->work); |
861 | flush_scheduled_work(); | ||
862 | flush_workqueue(pciehp_wq); | 806 | flush_workqueue(pciehp_wq); |
807 | flush_workqueue(pciehp_ordered_wq); | ||
863 | kfree(slot); | 808 | kfree(slot); |
864 | } | 809 | } |
865 | 810 | ||
@@ -886,9 +831,8 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
886 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 831 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
887 | if (!pci_resource_len(pdev, i)) | 832 | if (!pci_resource_len(pdev, i)) |
888 | continue; | 833 | continue; |
889 | ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", | 834 | ctrl_info(ctrl, " PCI resource [%d] : %pR\n", |
890 | i, (unsigned long long)pci_resource_len(pdev, i), | 835 | i, &pdev->resource[i]); |
891 | (unsigned long long)pci_resource_start(pdev, i)); | ||
892 | } | 836 | } |
893 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); | 837 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); |
894 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); | 838 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); |
@@ -966,16 +910,6 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
966 | /* Disable sotfware notification */ | 910 | /* Disable sotfware notification */ |
967 | pcie_disable_notification(ctrl); | 911 | pcie_disable_notification(ctrl); |
968 | 912 | ||
969 | /* | ||
970 | * If this is the first controller to be initialized, | ||
971 | * initialize the pciehp work queue | ||
972 | */ | ||
973 | if (atomic_add_return(1, &pciehp_num_controllers) == 1) { | ||
974 | pciehp_wq = create_singlethread_workqueue("pciehpd"); | ||
975 | if (!pciehp_wq) | ||
976 | goto abort_ctrl; | ||
977 | } | ||
978 | |||
979 | ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", | 913 | ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", |
980 | pdev->vendor, pdev->device, pdev->subsystem_vendor, | 914 | pdev->vendor, pdev->device, pdev->subsystem_vendor, |
981 | pdev->subsystem_device); | 915 | pdev->subsystem_device); |
@@ -995,11 +929,5 @@ void pciehp_release_ctrl(struct controller *ctrl) | |||
995 | { | 929 | { |
996 | pcie_shutdown_notification(ctrl); | 930 | pcie_shutdown_notification(ctrl); |
997 | pcie_cleanup_slot(ctrl); | 931 | pcie_cleanup_slot(ctrl); |
998 | /* | ||
999 | * If this is the last controller to be released, destroy the | ||
1000 | * pciehp work queue | ||
1001 | */ | ||
1002 | if (atomic_dec_and_test(&pciehp_num_controllers)) | ||
1003 | destroy_workqueue(pciehp_wq); | ||
1004 | kfree(ctrl); | 932 | kfree(ctrl); |
1005 | } | 933 | } |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 21733108adde..a4031dfe938e 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 | ||
@@ -86,22 +84,29 @@ int pciehp_configure_device(struct slot *p_slot) | |||
86 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | 84 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); |
87 | if (!dev) | 85 | if (!dev) |
88 | continue; | 86 | continue; |
89 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
90 | ctrl_err(ctrl, "Cannot hot-add display device %s\n", | ||
91 | pci_name(dev)); | ||
92 | pci_dev_put(dev); | ||
93 | continue; | ||
94 | } | ||
95 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 87 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
96 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { | 88 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { |
97 | pciehp_add_bridge(dev); | 89 | pciehp_add_bridge(dev); |
98 | } | 90 | } |
91 | pci_dev_put(dev); | ||
92 | } | ||
93 | |||
94 | pci_assign_unassigned_bridge_resources(bridge); | ||
95 | |||
96 | for (fn = 0; fn < 8; fn++) { | ||
97 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | ||
98 | if (!dev) | ||
99 | continue; | ||
100 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
101 | pci_dev_put(dev); | ||
102 | continue; | ||
103 | } | ||
99 | pci_configure_slot(dev); | 104 | pci_configure_slot(dev); |
100 | pci_dev_put(dev); | 105 | pci_dev_put(dev); |
101 | } | 106 | } |
102 | 107 | ||
103 | pci_bus_assign_resources(parent); | ||
104 | pci_bus_add_devices(parent); | 108 | pci_bus_add_devices(parent); |
109 | |||
105 | return 0; | 110 | return 0; |
106 | } | 111 | } |
107 | 112 | ||
@@ -122,15 +127,9 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
122 | presence = 0; | 127 | presence = 0; |
123 | 128 | ||
124 | for (j = 0; j < 8; j++) { | 129 | for (j = 0; j < 8; j++) { |
125 | struct pci_dev* temp = pci_get_slot(parent, PCI_DEVFN(0, j)); | 130 | struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j)); |
126 | if (!temp) | 131 | if (!temp) |
127 | continue; | 132 | continue; |
128 | if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
129 | ctrl_err(ctrl, "Cannot remove display device %s\n", | ||
130 | pci_name(temp)); | ||
131 | pci_dev_put(temp); | ||
132 | continue; | ||
133 | } | ||
134 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { | 133 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { |
135 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | 134 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); |
136 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 135 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
@@ -138,7 +137,8 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
138 | "Cannot remove display device %s\n", | 137 | "Cannot remove display device %s\n", |
139 | pci_name(temp)); | 138 | pci_name(temp)); |
140 | pci_dev_put(temp); | 139 | pci_dev_put(temp); |
141 | continue; | 140 | rc = -EINVAL; |
141 | break; | ||
142 | } | 142 | } |
143 | } | 143 | } |
144 | pci_remove_bus_device(temp); | 144 | pci_remove_bus_device(temp); |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 4e3e0382c16e..083034710fa6 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
23 | #include <linux/vmalloc.h> | ||
23 | 24 | ||
24 | #include <asm/pci-bridge.h> | 25 | #include <asm/pci-bridge.h> |
25 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
@@ -430,6 +431,8 @@ int dlpar_remove_slot(char *drc_name) | |||
430 | rc = dlpar_remove_pci_slot(drc_name, dn); | 431 | rc = dlpar_remove_pci_slot(drc_name, dn); |
431 | break; | 432 | break; |
432 | } | 433 | } |
434 | vm_unmap_aliases(); | ||
435 | |||
433 | printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); | 436 | printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); |
434 | exit: | 437 | exit: |
435 | mutex_unlock(&rpadlpar_mutex); | 438 | mutex_unlock(&rpadlpar_mutex); |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c159223389ec..ef7411c660b9 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci_hotplug.h> | 29 | #include <linux/pci_hotplug.h> |
30 | #include <linux/slab.h> | ||
31 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/vmalloc.h> | ||
33 | #include <asm/eeh.h> /* for eeh_add_device() */ | 33 | #include <asm/eeh.h> /* for eeh_add_device() */ |
34 | #include <asm/rtas.h> /* rtas_call */ | 34 | #include <asm/rtas.h> /* rtas_call */ |
35 | #include <asm/pci-bridge.h> /* for pci_controller */ | 35 | #include <asm/pci-bridge.h> /* for pci_controller */ |
@@ -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 | ||
@@ -418,6 +419,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
418 | return -EINVAL; | 419 | return -EINVAL; |
419 | 420 | ||
420 | pcibios_remove_pci_devices(slot->bus); | 421 | pcibios_remove_pci_devices(slot->bus); |
422 | vm_unmap_aliases(); | ||
423 | |||
421 | slot->state = NOT_CONFIGURED; | 424 | slot->state = NOT_CONFIGURED; |
422 | return 0; | 425 | return 0; |
423 | } | 426 | } |
@@ -429,7 +432,6 @@ struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { | |||
429 | .get_power_status = get_power_status, | 432 | .get_power_status = get_power_status, |
430 | .get_attention_status = get_attention_status, | 433 | .get_attention_status = get_attention_status, |
431 | .get_adapter_status = get_adapter_status, | 434 | .get_adapter_status = get_adapter_status, |
432 | .get_max_bus_speed = get_max_bus_speed, | ||
433 | }; | 435 | }; |
434 | 436 | ||
435 | module_init(rpaphp_init); | 437 | module_init(rpaphp_init); |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 2ea9cf1a8d02..b283bbea6d24 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
@@ -24,7 +24,6 @@ | |||
24 | */ | 24 | */ |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/kobject.h> | ||
28 | #include <linux/sysfs.h> | 27 | #include <linux/sysfs.h> |
29 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
30 | #include <linux/string.h> | 29 | #include <linux/string.h> |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 8aebe1e9d3d6..72d507b6a2aa 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/pci_hotplug.h> | 16 | #include <linux/pci_hotplug.h> |
17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
20 | 21 | ||
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 8e210cd76e55..e0c90e643b5f 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/sched.h> /* signal_pending(), struct timer_list */ | 36 | #include <linux/sched.h> /* signal_pending(), struct timer_list */ |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/workqueue.h> | ||
38 | 39 | ||
39 | #if !defined(MODULE) | 40 | #if !defined(MODULE) |
40 | #define MY_NAME "shpchp" | 41 | #define MY_NAME "shpchp" |
@@ -46,6 +47,7 @@ extern int shpchp_poll_mode; | |||
46 | extern int shpchp_poll_time; | 47 | extern int shpchp_poll_time; |
47 | extern int shpchp_debug; | 48 | extern int shpchp_debug; |
48 | extern struct workqueue_struct *shpchp_wq; | 49 | extern struct workqueue_struct *shpchp_wq; |
50 | extern struct workqueue_struct *shpchp_ordered_wq; | ||
49 | 51 | ||
50 | #define dbg(format, arg...) \ | 52 | #define dbg(format, arg...) \ |
51 | do { \ | 53 | do { \ |
@@ -333,8 +335,6 @@ struct hpc_ops { | |||
333 | int (*set_attention_status)(struct slot *slot, u8 status); | 335 | int (*set_attention_status)(struct slot *slot, u8 status); |
334 | int (*get_latch_status)(struct slot *slot, u8 *status); | 336 | int (*get_latch_status)(struct slot *slot, u8 *status); |
335 | int (*get_adapter_status)(struct slot *slot, u8 *status); | 337 | 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); | 338 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); |
339 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); | 339 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); |
340 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); | 340 | 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..aca972bbfb4c 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -31,8 +31,8 @@ | |||
31 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/slab.h> | ||
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include <linux/workqueue.h> | ||
36 | #include "shpchp.h" | 36 | #include "shpchp.h" |
37 | 37 | ||
38 | /* Global variables */ | 38 | /* Global variables */ |
@@ -40,6 +40,7 @@ int shpchp_debug; | |||
40 | int shpchp_poll_mode; | 40 | int shpchp_poll_mode; |
41 | int shpchp_poll_time; | 41 | int shpchp_poll_time; |
42 | struct workqueue_struct *shpchp_wq; | 42 | struct workqueue_struct *shpchp_wq; |
43 | struct workqueue_struct *shpchp_ordered_wq; | ||
43 | 44 | ||
44 | #define DRIVER_VERSION "0.4" | 45 | #define DRIVER_VERSION "0.4" |
45 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" | 46 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" |
@@ -65,8 +66,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); | |||
65 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | 66 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); |
66 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | 67 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); |
67 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 68 | 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 | 69 | ||
71 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | 70 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { |
72 | .set_attention_status = set_attention_status, | 71 | .set_attention_status = set_attention_status, |
@@ -76,8 +75,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | |||
76 | .get_attention_status = get_attention_status, | 75 | .get_attention_status = get_attention_status, |
77 | .get_latch_status = get_latch_status, | 76 | .get_latch_status = get_latch_status, |
78 | .get_adapter_status = get_adapter_status, | 77 | .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 | }; | 78 | }; |
82 | 79 | ||
83 | /** | 80 | /** |
@@ -177,8 +174,8 @@ void cleanup_slots(struct controller *ctrl) | |||
177 | slot = list_entry(tmp, struct slot, slot_list); | 174 | slot = list_entry(tmp, struct slot, slot_list); |
178 | list_del(&slot->slot_list); | 175 | list_del(&slot->slot_list); |
179 | cancel_delayed_work(&slot->work); | 176 | cancel_delayed_work(&slot->work); |
180 | flush_scheduled_work(); | ||
181 | flush_workqueue(shpchp_wq); | 177 | flush_workqueue(shpchp_wq); |
178 | flush_workqueue(shpchp_ordered_wq); | ||
182 | pci_hp_deregister(slot->hotplug_slot); | 179 | pci_hp_deregister(slot->hotplug_slot); |
183 | } | 180 | } |
184 | } | 181 | } |
@@ -279,37 +276,6 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
279 | return 0; | 276 | return 0; |
280 | } | 277 | } |
281 | 278 | ||
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) | 279 | static int is_shpc_capable(struct pci_dev *dev) |
314 | { | 280 | { |
315 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == | 281 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == |
@@ -394,9 +360,23 @@ static int __init shpcd_init(void) | |||
394 | { | 360 | { |
395 | int retval = 0; | 361 | int retval = 0; |
396 | 362 | ||
363 | shpchp_wq = alloc_ordered_workqueue("shpchp", 0); | ||
364 | if (!shpchp_wq) | ||
365 | return -ENOMEM; | ||
366 | |||
367 | shpchp_ordered_wq = alloc_ordered_workqueue("shpchp_ordered", 0); | ||
368 | if (!shpchp_ordered_wq) { | ||
369 | destroy_workqueue(shpchp_wq); | ||
370 | return -ENOMEM; | ||
371 | } | ||
372 | |||
397 | retval = pci_register_driver(&shpc_driver); | 373 | retval = pci_register_driver(&shpc_driver); |
398 | dbg("%s: pci_register_driver = %d\n", __func__, retval); | 374 | dbg("%s: pci_register_driver = %d\n", __func__, retval); |
399 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 375 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
376 | if (retval) { | ||
377 | destroy_workqueue(shpchp_ordered_wq); | ||
378 | destroy_workqueue(shpchp_wq); | ||
379 | } | ||
400 | return retval; | 380 | return retval; |
401 | } | 381 | } |
402 | 382 | ||
@@ -404,6 +384,8 @@ static void __exit shpcd_cleanup(void) | |||
404 | { | 384 | { |
405 | dbg("unload_shpchpd()\n"); | 385 | dbg("unload_shpchpd()\n"); |
406 | pci_unregister_driver(&shpc_driver); | 386 | pci_unregister_driver(&shpc_driver); |
387 | destroy_workqueue(shpchp_ordered_wq); | ||
388 | destroy_workqueue(shpchp_wq); | ||
407 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); | 389 | info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); |
408 | } | 390 | } |
409 | 391 | ||
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b8ab2796e66a..b00b09bdd38a 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | #include <linux/workqueue.h> | ||
35 | #include "../pci.h" | 35 | #include "../pci.h" |
36 | #include "shpchp.h" | 36 | #include "shpchp.h" |
37 | 37 | ||
@@ -51,7 +51,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
51 | info->p_slot = p_slot; | 51 | info->p_slot = p_slot; |
52 | INIT_WORK(&info->work, interrupt_event_handler); | 52 | INIT_WORK(&info->work, interrupt_event_handler); |
53 | 53 | ||
54 | schedule_work(&info->work); | 54 | queue_work(shpchp_wq, &info->work); |
55 | 55 | ||
56 | return 0; | 56 | return 0; |
57 | } | 57 | } |
@@ -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,9 +453,10 @@ 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_ordered_wq, &info->work); |
468 | out: | 460 | out: |
469 | mutex_unlock(&p_slot->lock); | 461 | mutex_unlock(&p_slot->lock); |
470 | } | 462 | } |
@@ -512,7 +504,7 @@ static void handle_button_press_event(struct slot *p_slot) | |||
512 | p_slot->hpc_ops->green_led_blink(p_slot); | 504 | p_slot->hpc_ops->green_led_blink(p_slot); |
513 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 505 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
514 | 506 | ||
515 | schedule_delayed_work(&p_slot->work, 5*HZ); | 507 | queue_delayed_work(shpchp_wq, &p_slot->work, 5*HZ); |
516 | break; | 508 | break; |
517 | case BLINKINGOFF_STATE: | 509 | case BLINKINGOFF_STATE: |
518 | case BLINKINGON_STATE: | 510 | case BLINKINGON_STATE: |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 86dc39847769..36547f0ce305 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -113,7 +113,7 @@ | |||
113 | #define CON_PFAULT_INTR_MASK (1 << 28) | 113 | #define CON_PFAULT_INTR_MASK (1 << 28) |
114 | #define MRL_CHANGE_SERR_MASK (1 << 29) | 114 | #define MRL_CHANGE_SERR_MASK (1 << 29) |
115 | #define CON_PFAULT_SERR_MASK (1 << 30) | 115 | #define CON_PFAULT_SERR_MASK (1 << 30) |
116 | #define SLOT_REG_RSVDZ_MASK (1 << 15) | (7 << 21) | 116 | #define SLOT_REG_RSVDZ_MASK ((1 << 15) | (7 << 21)) |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * SHPC Command Code definitnions | 119 | * SHPC Command Code definitnions |
@@ -179,8 +179,6 @@ | |||
179 | #define SLOT_EVENT_LATCH 0x2 | 179 | #define SLOT_EVENT_LATCH 0x2 |
180 | #define SLOT_SERR_INT_MASK 0x3 | 180 | #define SLOT_SERR_INT_MASK 0x3 |
181 | 181 | ||
182 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); | ||
183 | |||
184 | static irqreturn_t shpc_isr(int irq, void *dev_id); | 182 | static irqreturn_t shpc_isr(int irq, void *dev_id); |
185 | static void start_int_poll_timer(struct controller *ctrl, int sec); | 183 | static void start_int_poll_timer(struct controller *ctrl, int sec); |
186 | static int hpc_check_cmd_status(struct controller *ctrl); | 184 | static int hpc_check_cmd_status(struct controller *ctrl); |
@@ -614,13 +612,6 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
614 | 612 | ||
615 | iounmap(ctrl->creg); | 613 | iounmap(ctrl->creg); |
616 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | 614 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); |
617 | |||
618 | /* | ||
619 | * If this is the last controller to be released, destroy the | ||
620 | * shpchpd work queue | ||
621 | */ | ||
622 | if (atomic_dec_and_test(&shpchp_num_controllers)) | ||
623 | destroy_workqueue(shpchp_wq); | ||
624 | } | 615 | } |
625 | 616 | ||
626 | static int hpc_power_on_slot(struct slot * slot) | 617 | static int hpc_power_on_slot(struct slot * slot) |
@@ -660,6 +651,75 @@ static int hpc_slot_disable(struct slot * slot) | |||
660 | return retval; | 651 | return retval; |
661 | } | 652 | } |
662 | 653 | ||
654 | static int shpc_get_cur_bus_speed(struct controller *ctrl) | ||
655 | { | ||
656 | int retval = 0; | ||
657 | struct pci_bus *bus = ctrl->pci_dev->subordinate; | ||
658 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
659 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
660 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
661 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
662 | |||
663 | if ((pi == 1) && (speed_mode > 4)) { | ||
664 | retval = -ENODEV; | ||
665 | goto out; | ||
666 | } | ||
667 | |||
668 | switch (speed_mode) { | ||
669 | case 0x0: | ||
670 | bus_speed = PCI_SPEED_33MHz; | ||
671 | break; | ||
672 | case 0x1: | ||
673 | bus_speed = PCI_SPEED_66MHz; | ||
674 | break; | ||
675 | case 0x2: | ||
676 | bus_speed = PCI_SPEED_66MHz_PCIX; | ||
677 | break; | ||
678 | case 0x3: | ||
679 | bus_speed = PCI_SPEED_100MHz_PCIX; | ||
680 | break; | ||
681 | case 0x4: | ||
682 | bus_speed = PCI_SPEED_133MHz_PCIX; | ||
683 | break; | ||
684 | case 0x5: | ||
685 | bus_speed = PCI_SPEED_66MHz_PCIX_ECC; | ||
686 | break; | ||
687 | case 0x6: | ||
688 | bus_speed = PCI_SPEED_100MHz_PCIX_ECC; | ||
689 | break; | ||
690 | case 0x7: | ||
691 | bus_speed = PCI_SPEED_133MHz_PCIX_ECC; | ||
692 | break; | ||
693 | case 0x8: | ||
694 | bus_speed = PCI_SPEED_66MHz_PCIX_266; | ||
695 | break; | ||
696 | case 0x9: | ||
697 | bus_speed = PCI_SPEED_100MHz_PCIX_266; | ||
698 | break; | ||
699 | case 0xa: | ||
700 | bus_speed = PCI_SPEED_133MHz_PCIX_266; | ||
701 | break; | ||
702 | case 0xb: | ||
703 | bus_speed = PCI_SPEED_66MHz_PCIX_533; | ||
704 | break; | ||
705 | case 0xc: | ||
706 | bus_speed = PCI_SPEED_100MHz_PCIX_533; | ||
707 | break; | ||
708 | case 0xd: | ||
709 | bus_speed = PCI_SPEED_133MHz_PCIX_533; | ||
710 | break; | ||
711 | default: | ||
712 | retval = -ENODEV; | ||
713 | break; | ||
714 | } | ||
715 | |||
716 | out: | ||
717 | bus->cur_bus_speed = bus_speed; | ||
718 | dbg("Current bus speed = %d\n", bus_speed); | ||
719 | return retval; | ||
720 | } | ||
721 | |||
722 | |||
663 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 723 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
664 | { | 724 | { |
665 | int retval; | 725 | int retval; |
@@ -720,6 +780,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
720 | retval = shpc_write_cmd(slot, 0, cmd); | 780 | retval = shpc_write_cmd(slot, 0, cmd); |
721 | if (retval) | 781 | if (retval) |
722 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); | 782 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); |
783 | else | ||
784 | shpc_get_cur_bus_speed(ctrl); | ||
723 | 785 | ||
724 | return retval; | 786 | return retval; |
725 | } | 787 | } |
@@ -803,10 +865,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
803 | return IRQ_HANDLED; | 865 | return IRQ_HANDLED; |
804 | } | 866 | } |
805 | 867 | ||
806 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 868 | static int shpc_get_max_bus_speed(struct controller *ctrl) |
807 | { | 869 | { |
808 | int retval = 0; | 870 | int retval = 0; |
809 | struct controller *ctrl = slot->ctrl; | 871 | struct pci_bus *bus = ctrl->pci_dev->subordinate; |
810 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 872 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
811 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | 873 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
812 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); | 874 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); |
@@ -842,79 +904,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
842 | retval = -ENODEV; | 904 | retval = -ENODEV; |
843 | } | 905 | } |
844 | 906 | ||
845 | *value = bus_speed; | 907 | bus->max_bus_speed = bus_speed; |
846 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); | 908 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); |
847 | 909 | ||
848 | return retval; | 910 | return retval; |
849 | } | 911 | } |
850 | 912 | ||
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 = { | 913 | static struct hpc_ops shpchp_hpc_ops = { |
919 | .power_on_slot = hpc_power_on_slot, | 914 | .power_on_slot = hpc_power_on_slot, |
920 | .slot_enable = hpc_slot_enable, | 915 | .slot_enable = hpc_slot_enable, |
@@ -926,8 +921,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
926 | .get_latch_status = hpc_get_latch_status, | 921 | .get_latch_status = hpc_get_latch_status, |
927 | .get_adapter_status = hpc_get_adapter_status, | 922 | .get_adapter_status = hpc_get_adapter_status, |
928 | 923 | ||
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, | 924 | .get_adapter_speed = hpc_get_adapter_speed, |
932 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, | 925 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, |
933 | .get_prog_int = hpc_get_prog_int, | 926 | .get_prog_int = hpc_get_prog_int, |
@@ -1075,9 +1068,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1075 | 1068 | ||
1076 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, | 1069 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, |
1077 | MY_NAME, (void *)ctrl); | 1070 | MY_NAME, (void *)ctrl); |
1078 | ctrl_dbg(ctrl, "request_irq %d for hpc%d (returns %d)\n", | 1071 | ctrl_dbg(ctrl, "request_irq %d (returns %d)\n", |
1079 | ctrl->pci_dev->irq, | 1072 | ctrl->pci_dev->irq, rc); |
1080 | atomic_read(&shpchp_num_controllers), rc); | ||
1081 | if (rc) { | 1073 | if (rc) { |
1082 | ctrl_err(ctrl, "Can't get irq %d for the hotplug " | 1074 | ctrl_err(ctrl, "Can't get irq %d for the hotplug " |
1083 | "controller\n", ctrl->pci_dev->irq); | 1075 | "controller\n", ctrl->pci_dev->irq); |
@@ -1086,17 +1078,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1086 | } | 1078 | } |
1087 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); | 1079 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); |
1088 | 1080 | ||
1089 | /* | 1081 | shpc_get_max_bus_speed(ctrl); |
1090 | * If this is the first controller to be initialized, | 1082 | shpc_get_cur_bus_speed(ctrl); |
1091 | * initialize the shpchpd work queue | ||
1092 | */ | ||
1093 | if (atomic_add_return(1, &shpchp_num_controllers) == 1) { | ||
1094 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | ||
1095 | if (!shpchp_wq) { | ||
1096 | rc = -ENOMEM; | ||
1097 | goto abort_iounmap; | ||
1098 | } | ||
1099 | } | ||
1100 | 1083 | ||
1101 | /* | 1084 | /* |
1102 | * Unmask all event interrupts of all slots | 1085 | * Unmask all event interrupts of all slots |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 8c3d3219f227..a2ccfcd3c298 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
@@ -60,12 +60,6 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
60 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); | 60 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); |
61 | if (!dev) | 61 | if (!dev) |
62 | continue; | 62 | continue; |
63 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
64 | ctrl_err(ctrl, "Cannot hot-add display device %s\n", | ||
65 | pci_name(dev)); | ||
66 | pci_dev_put(dev); | ||
67 | continue; | ||
68 | } | ||
69 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 63 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
70 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { | 64 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { |
71 | /* Find an unused bus number for the new bridge */ | 65 | /* Find an unused bus number for the new bridge */ |
@@ -114,17 +108,11 @@ int shpchp_unconfigure_device(struct slot *p_slot) | |||
114 | ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", | 108 | ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", |
115 | __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); | 109 | __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); |
116 | 110 | ||
117 | for (j=0; j<8 ; j++) { | 111 | for (j = 0; j < 8 ; j++) { |
118 | struct pci_dev* temp = pci_get_slot(parent, | 112 | struct pci_dev *temp = pci_get_slot(parent, |
119 | (p_slot->device << 3) | j); | 113 | (p_slot->device << 3) | j); |
120 | if (!temp) | 114 | if (!temp) |
121 | continue; | 115 | continue; |
122 | if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
123 | ctrl_err(ctrl, "Cannot remove display device %s\n", | ||
124 | pci_name(temp)); | ||
125 | pci_dev_put(temp); | ||
126 | continue; | ||
127 | } | ||
128 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 116 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
129 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | 117 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); |
130 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 118 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
@@ -132,7 +120,8 @@ int shpchp_unconfigure_device(struct slot *p_slot) | |||
132 | "Cannot remove display device %s\n", | 120 | "Cannot remove display device %s\n", |
133 | pci_name(temp)); | 121 | pci_name(temp)); |
134 | pci_dev_put(temp); | 122 | pci_dev_put(temp); |
135 | continue; | 123 | rc = -EINVAL; |
124 | break; | ||
136 | } | 125 | } |
137 | } | 126 | } |
138 | pci_remove_bus_device(temp); | 127 | pci_remove_bus_device(temp); |
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", |