aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
committerMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
commit2d8ad8719591fa803b0d589ed057fa46f49b7155 (patch)
tree4ae051577dad1161c91dafbf4207bb10a9dc91bb /drivers/pci/hotplug
parent9b4ce7bce5f30712fd926ab4599a803314a07719 (diff)
parentc56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (diff)
Merge commit 'v2.6.38-rc1' into kbuild/packaging
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c7
-rw-r--r--drivers/pci/hotplug/acpiphp.h1
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c26
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c6
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c1
-rw-r--r--drivers/pci/hotplug/cpqphp.h2
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c69
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c27
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c14
-rw-r--r--drivers/pci/hotplug/fakephp.c5
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c106
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c19
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c5
-rw-r--r--drivers/pci/hotplug/ibmphp_res.c14
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c133
-rw-r--r--drivers/pci/hotplug/pciehp.h18
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c8
-rw-r--r--drivers/pci/hotplug/pciehp_core.c48
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c11
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c98
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c40
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c3
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c28
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c1
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c1
-rw-r--r--drivers/pci/hotplug/shpchp.h4
-rw-r--r--drivers/pci/hotplug/shpchp_core.c56
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c22
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c175
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c19
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c9
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
731acpiphp_bus_add_out: 726acpiphp_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
753static 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);
107static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status); 108static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status);
108static void ibm_handle_events(acpi_handle handle, u32 event, void *context); 109static void ibm_handle_events(acpi_handle handle, u32 event, void *context);
109static int ibm_get_table_from_acpi(char **bufp); 110static int ibm_get_table_from_acpi(char **bufp);
110static ssize_t ibm_read_apci_table(struct kobject *kobj, 111static 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);
113static acpi_status __init ibm_find_acpi_device(acpi_handle handle, 114static 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 */
366static ssize_t ibm_read_apci_table(struct kobject *kobj, 368static 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
586static 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
598static 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
610static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { 586static 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)
1130static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) 1130static 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 */
1270static u32 board_replaced(struct pci_func *func, struct controller *ctrl) 1271static 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
41static DEFINE_MUTEX(cpqphp_mutex);
40static int show_ctrl (struct controller *ctrl, char *buf) 42static 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;
161exit: 163exit:
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
24struct legacy_slot { 25struct legacy_slot {
@@ -73,7 +74,7 @@ static void legacy_release(struct kobject *kobj)
73} 74}
74 75
75static struct kobj_type legacy_ktype = { 76static 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
398static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 398static 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
438static 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)
655int ibmphp_update_slot_info(struct slot *slot_cur) 607int 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
246int __init ibmphp_access_ebda (void) 246int __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);
40static int once_over (void); 40static int once_over (void);
41static int remove_ranges (struct bus_node *, struct bus_node *); 41static int remove_ranges (struct bus_node *, struct bus_node *);
42static int update_bridge_ranges (struct bus_node **); 42static int update_bridge_ranges (struct bus_node **);
43static int add_range (int type, struct range_node *, struct bus_node *); 43static int add_bus_range (int type, struct range_node *, struct bus_node *);
44static void fix_resources (struct bus_node *); 44static void fix_resources (struct bus_node *);
45static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); 45static 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 ********************************************************************************/
387static int add_range (int type, struct range_node *range, struct bus_node *bus_cur) 387static 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;
64static LIST_HEAD(pci_hotplug_slot_list); 63static LIST_HEAD(pci_hotplug_slot_list);
65static DEFINE_MUTEX(pci_hp_mutex); 64static DEFINE_MUTEX(pci_hp_mutex);
66 65
67/* these strings match up with the values in pci_bus_speed */
68static 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
94extern int cpci_hotplug_init(int debug); 67extern int cpci_hotplug_init(int debug);
95extern void cpci_hotplug_exit(void); 68extern void cpci_hotplug_exit(void);
@@ -118,8 +91,6 @@ GET_STATUS(power_status, u8)
118GET_STATUS(attention_status, u8) 91GET_STATUS(attention_status, u8)
119GET_STATUS(latch_status, u8) 92GET_STATUS(latch_status, u8)
120GET_STATUS(adapter_status, u8) 93GET_STATUS(adapter_status, u8)
121GET_STATUS(max_bus_speed, enum pci_bus_speed)
122GET_STATUS(cur_bus_speed, enum pci_bus_speed)
123 94
124static ssize_t power_read_file(struct pci_slot *slot, char *buf) 95static 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
266static char *unknown_speed = "Unknown bus speed";
267
268static 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
285exit:
286 return retval;
287}
288
289static 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
294static 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
311exit:
312 return retval;
313}
314
315static 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
320static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, 237static 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
394static 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
404static 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
414static bool has_test_file(struct pci_slot *pci_slot) 311static 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
482exit_test: 365exit_test:
483 if (has_cur_bus_speed_file(slot))
484 sysfs_remove_file(&slot->kobj,
485 &hotplug_slot_attr_cur_bus_speed.attr);
486exit_cur_speed:
487 if (has_max_bus_speed_file(slot))
488 sysfs_remove_file(&slot->kobj,
489 &hotplug_slot_attr_max_bus_speed.attr);
490exit_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;
44extern int pciehp_debug; 45extern int pciehp_debug;
45extern int pciehp_force; 46extern int pciehp_force;
46extern struct workqueue_struct *pciehp_wq; 47extern struct workqueue_struct *pciehp_wq;
48extern struct workqueue_struct *pciehp_ordered_wq;
47 49
48#define dbg(format, arg...) \ 50#define dbg(format, arg...) \
49do { \ 51do { \
@@ -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
180static 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 183static 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 = {
116static int __init select_detection_mode(void) 115static 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;
42int pciehp_poll_time; 43int pciehp_poll_time;
43int pciehp_force; 44int pciehp_force;
44struct workqueue_struct *pciehp_wq; 45struct workqueue_struct *pciehp_wq;
46struct 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);
58MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 60MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
59MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 61MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
60MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 62MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
61MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); 63MODULE_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);
69static int get_attention_status (struct hotplug_slot *slot, u8 *value); 71static int get_attention_status (struct hotplug_slot *slot, u8 *value);
70static int get_latch_status (struct hotplug_slot *slot, u8 *value); 72static int get_latch_status (struct hotplug_slot *slot, u8 *value);
71static int get_adapter_status (struct hotplug_slot *slot, u8 *value); 73static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
72static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
73static 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
230static 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
241static 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
251static int pciehp_probe(struct pcie_device *dev) 228static 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
376static void __exit pcied_cleanup(void) 366static 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
444static void interrupt_event_handler(struct work_struct *work) 445static 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
43static atomic_t pciehp_num_controllers = ATOMIC_INIT(0);
44
45static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) 44static 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
613int 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
644int pciehp_get_max_lnk_width(struct slot *slot, 621int 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
694int 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
726int pciehp_get_cur_lnk_width(struct slot *slot, 671int 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
63int pciehp_configure_device(struct slot *p_slot) 60int 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);
434exit: 437exit:
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
133static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 133static 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
170static int get_children_props(struct device_node *dn, const int **drc_indexes, 169static 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
435module_init(rpaphp_init); 437module_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;
46extern int shpchp_poll_time; 47extern int shpchp_poll_time;
47extern int shpchp_debug; 48extern int shpchp_debug;
48extern struct workqueue_struct *shpchp_wq; 49extern struct workqueue_struct *shpchp_wq;
50extern struct workqueue_struct *shpchp_ordered_wq;
49 51
50#define dbg(format, arg...) \ 52#define dbg(format, arg...) \
51do { \ 53do { \
@@ -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;
40int shpchp_poll_mode; 40int shpchp_poll_mode;
41int shpchp_poll_time; 41int shpchp_poll_time;
42struct workqueue_struct *shpchp_wq; 42struct workqueue_struct *shpchp_wq;
43struct 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);
65static int get_attention_status (struct hotplug_slot *slot, u8 *value); 66static int get_attention_status (struct hotplug_slot *slot, u8 *value);
66static int get_latch_status (struct hotplug_slot *slot, u8 *value); 67static int get_latch_status (struct hotplug_slot *slot, u8 *value);
67static int get_adapter_status (struct hotplug_slot *slot, u8 *value); 68static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
68static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
69static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
70 69
71static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { 70static 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
282static 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
298static 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
313static int is_shpc_capable(struct pci_dev *dev) 279static 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
182static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
183
184static irqreturn_t shpc_isr(int irq, void *dev_id); 182static irqreturn_t shpc_isr(int irq, void *dev_id);
185static void start_int_poll_timer(struct controller *ctrl, int sec); 183static void start_int_poll_timer(struct controller *ctrl, int sec);
186static int hpc_check_cmd_status(struct controller *ctrl); 184static 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
626static int hpc_power_on_slot(struct slot * slot) 617static 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
654static 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
663static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) 723static 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
806static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) 868static 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
851static 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
918static struct hpc_ops shpchp_hpc_ops = { 913static 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",