diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 19 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpcihp_generic.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_core.c | 57 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 27 | ||||
-rw-r--r-- | drivers/pci/hotplug/fakephp.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 106 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_ebda.c | 13 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_hpc.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_res.c | 14 | ||||
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug_core.c | 132 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 25 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 72 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 23 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_core.c | 24 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 35 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 14 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 149 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_sysfs.c | 9 |
22 files changed, 222 insertions, 508 deletions
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) slot->hotplug_slot->info->attention_status = 0; slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); - slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; - slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; acpiphp_slot->slot = slot; 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 cb2fd01eddae..b5dad9f37453 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -749,6 +749,24 @@ static int acpiphp_bus_trim(acpi_handle handle) return retval; } +static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) +{ + struct acpiphp_func *func; + union acpi_object params[2]; + struct acpi_object_list arg_list; + + list_for_each_entry(func, &slot->funcs, sibling) { + arg_list.count = 2; + arg_list.pointer = params; + params[0].type = ACPI_TYPE_INTEGER; + params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; + params[1].type = ACPI_TYPE_INTEGER; + params[1].integer.value = 1; + /* _REG is optional, we don't care about if there is failure */ + acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); + } +} + /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -805,6 +823,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); acpiphp_set_hpp_values(bus); + acpiphp_set_acpi_region(slot); pci_enable_bridges(bus); pci_bus_add_devices(bus); 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) dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { err("Invalid bridge device %s", bridge); + pci_dev_put(dev); return -EINVAL; } 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 { u8 first_slot; u8 add_support; u8 push_flag; - enum pci_bus_speed speed; - enum pci_bus_speed speed_capability; u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 075b4f4b6e0d..f184d1d2ecbe 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -583,30 +583,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - struct controller *ctrl = slot->ctrl; - - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); - - *value = ctrl->speed_capability; - - return 0; -} - -static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - struct controller *ctrl = slot->ctrl; - - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); - - *value = ctrl->speed; - - return 0; -} - static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .set_attention_status = set_attention_status, .enable_slot = process_SI, @@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, - .get_cur_bus_speed = get_cur_bus_speed, }; #define SLOT_NAME_SIZE 10 @@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct controller *ctrl, struct slot *slot; struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *hotplug_slot_info; + struct pci_bus *bus = ctrl->pci_bus; u8 number_of_slots; u8 slot_device; u8 slot_number; @@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct controller *ctrl, slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; if (is_slot66mhz(slot)) slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; - if (ctrl->speed == PCI_SPEED_66MHz) + if (bus->cur_bus_speed == PCI_SPEED_66MHz) slot->capabilities |= PCISLOT_66_MHZ_OPERATION; ctrl_slot = @@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u32 rc; struct controller *ctrl; struct pci_func *func; + struct pci_bus *bus; int err; err = pci_enable_device(pdev); @@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_name(pdev), err); return err; } + bus = pdev->subordinate; /* Need to read VID early b/c it's used to differentiate CPQ and INTC * discovery @@ -929,22 +906,22 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_read_config_byte(pdev, 0x41, &bus_cap); if (bus_cap & 0x80) { dbg("bus max supports 133MHz PCI-X\n"); - ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_133MHz_PCIX; break; } if (bus_cap & 0x40) { dbg("bus max supports 100MHz PCI-X\n"); - ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; break; } if (bus_cap & 20) { dbg("bus max supports 66MHz PCI-X\n"); - ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; break; } if (bus_cap & 10) { dbg("bus max supports 66MHz PCI\n"); - ctrl->speed_capability = PCI_SPEED_66MHz; + bus->max_bus_speed = PCI_SPEED_66MHz; break; } @@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_SUB_HPC_ID: /* Original 6500/7000 implementation */ ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; ctrl->push_button = 0; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First Pushbutton implementation */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; ctrl->push_button = 1; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_SUB_HPC_ID_INTC: /* Third party (6500/7000) */ ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; ctrl->push_button = 0; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First 66 Mhz implementation */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_66MHz; + bus->max_bus_speed = PCI_SPEED_66MHz; ctrl->push_button = 1; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First PCI-X implementation, 100MHz */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; ctrl->push_button = 1; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_VENDOR_ID_INTEL: /* Check for speed capability (0=33, 1=66) */ if (subsystem_deviceid & 0x0001) - ctrl->speed_capability = PCI_SPEED_66MHz; + bus->max_bus_speed = PCI_SPEED_66MHz; else - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; /* Check for push button */ if (subsystem_deviceid & 0x0002) @@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pdev->bus->number); dbg("Hotplug controller capabilities:\n"); - dbg(" speed_capability %d\n", ctrl->speed_capability); + dbg(" speed_capability %d\n", bus->max_bus_speed); dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? "switch present" : "no switch"); dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? @@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Check for 66Mhz operation */ - ctrl->speed = get_controller_speed(ctrl); + bus->cur_bus_speed = get_controller_speed(ctrl); /******************************************************** 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) static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) { struct slot *slot; + struct pci_bus *bus = ctrl->pci_bus; u8 reg; u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); u16 reg16; u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); - if (ctrl->speed == adapter_speed) + if (bus->cur_bus_speed == adapter_speed) return 0; /* 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_ * lower speed/mode, we allow the new adapter to function at * this rate if supported */ - if (ctrl->speed < adapter_speed) + if (bus->cur_bus_speed < adapter_speed) return 0; return 1; @@ -1161,20 +1162,20 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ /* If the controller doesn't support freq/mode changes and the * controller is running at a higher mode, we bail */ - if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) + if ((bus->cur_bus_speed > adapter_speed) && (!ctrl->pcix_speed_capability)) return 1; /* But we allow the adapter to run at a lower rate if possible */ - if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) + if ((bus->cur_bus_speed < adapter_speed) && (!ctrl->pcix_speed_capability)) return 0; /* We try to set the max speed supported by both the adapter and * controller */ - if (ctrl->speed_capability < adapter_speed) { - if (ctrl->speed == ctrl->speed_capability) + if (bus->max_bus_speed < adapter_speed) { + if (bus->cur_bus_speed == bus->max_bus_speed) return 0; - adapter_speed = ctrl->speed_capability; + adapter_speed = bus->max_bus_speed; } writel(0x0L, ctrl->hpc_reg + LED_CONTROL); @@ -1229,8 +1230,8 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ pci_write_config_byte(ctrl->pci_dev, 0x43, reg); /* Only if mode change...*/ - if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || - ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) + if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || + ((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) set_SOGO(ctrl); wait_for_ctrl_irq(ctrl); @@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ set_SOGO(ctrl); wait_for_ctrl_irq(ctrl); - ctrl->speed = adapter_speed; + bus->cur_bus_speed = adapter_speed; slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 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_ */ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) { + struct pci_bus *bus = ctrl->pci_bus; u8 hp_slot; u8 temp_byte; u8 adapter_speed; @@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) wait_for_ctrl_irq (ctrl); adapter_speed = get_adapter_speed(ctrl, hp_slot); - if (ctrl->speed != adapter_speed) + if (bus->cur_bus_speed != adapter_speed) if (set_controller_speed(ctrl, adapter_speed, hp_slot)) rc = WRONG_BUS_FREQUENCY; @@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) u32 temp_register = 0xFFFFFFFF; u32 rc = 0; struct pci_func *new_slot = NULL; + struct pci_bus *bus = ctrl->pci_bus; struct slot *p_slot; struct resource_lists res_lists; @@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) wait_for_ctrl_irq (ctrl); adapter_speed = get_adapter_speed(ctrl, hp_slot); - if (ctrl->speed != adapter_speed) + if (bus->cur_bus_speed != adapter_speed) if (set_controller_speed(ctrl, adapter_speed, hp_slot)) rc = WRONG_BUS_FREQUENCY; diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..0a894efd4b9b 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj) } static struct kobj_type legacy_ktype = { - .sysfs_ops = &(struct sysfs_ops){ + .sysfs_ops = &(const struct sysfs_ops){ .store = legacy_store, .show = legacy_show }, .release = &legacy_release, diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 7485ffda950c..d934dd4fa873 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -395,89 +395,40 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) return rc; } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) +static int get_max_bus_speed(struct slot *slot) { - int rc = -ENODEV; - struct slot *pslot; + int rc; u8 mode = 0; + enum pci_bus_speed speed; + struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; - debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, - hotplug_slot, value); + debug("%s - Entry slot[%p]\n", __func__, slot); ibmphp_lock_operations(); - - if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - rc = 0; - mode = pslot->supported_bus_mode; - *value = pslot->supported_speed; - switch (*value) { - case BUS_SPEED_33: - break; - case BUS_SPEED_66: - if (mode == BUS_MODE_PCIX) - *value += 0x01; - break; - case BUS_SPEED_100: - case BUS_SPEED_133: - *value = pslot->supported_speed + 0x01; - break; - default: - /* Note (will need to change): there would be soon 256, 512 also */ - rc = -ENODEV; - } - } - } - + mode = slot->supported_bus_mode; + speed = slot->supported_speed; ibmphp_unlock_operations(); - debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); - return rc; -} -static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - int rc = -ENODEV; - struct slot *pslot; - u8 mode = 0; - - debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, - hotplug_slot, value); - - ibmphp_lock_operations(); - - if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - rc = get_cur_bus_info(&pslot); - if (!rc) { - mode = pslot->bus_on->current_bus_mode; - *value = pslot->bus_on->current_speed; - switch (*value) { - case BUS_SPEED_33: - break; - case BUS_SPEED_66: - if (mode == BUS_MODE_PCIX) - *value += 0x01; - else if (mode == BUS_MODE_PCI) - ; - else - *value = PCI_SPEED_UNKNOWN; - break; - case BUS_SPEED_100: - case BUS_SPEED_133: - *value += 0x01; - break; - default: - /* Note of change: there would also be 256, 512 soon */ - rc = -ENODEV; - } - } - } + switch (speed) { + case BUS_SPEED_33: + break; + case BUS_SPEED_66: + if (mode == BUS_MODE_PCIX) + speed += 0x01; + break; + case BUS_SPEED_100: + case BUS_SPEED_133: + speed += 0x01; + break; + default: + /* Note (will need to change): there would be soon 256, 512 also */ + rc = -ENODEV; } - ibmphp_unlock_operations(); - debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); + if (!rc) + bus->max_bus_speed = speed; + + debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed); return rc; } @@ -572,6 +523,7 @@ static int __init init_ops(void) if (slot_cur->bus_on->current_speed == 0xFF) if (get_cur_bus_info(&slot_cur)) return -1; + get_max_bus_speed(slot_cur); if (slot_cur->ctrl->options == 0xFF) if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) @@ -655,6 +607,7 @@ static int validate(struct slot *slot_cur, int opn) int ibmphp_update_slot_info(struct slot *slot_cur) { struct hotplug_slot_info *info; + struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; int rc; u8 bus_speed; u8 mode; @@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur) bus_speed = PCI_SPEED_UNKNOWN; } - info->cur_bus_speed = bus_speed; - info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed; + bus->cur_bus_speed = bus_speed; // To do: bus_names rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); @@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_present, - .get_max_bus_speed = get_max_bus_speed, - .get_cur_bus_speed = get_cur_bus_speed, /* .get_max_adapter_speed = get_max_adapter_speed, .get_bus_name_status = get_bus_name, */ diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index c1abac8ab5c3..5becbdee4027 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void) int __init ibmphp_access_ebda (void) { - u8 format, num_ctlrs, rio_complete, hs_complete; + u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz; u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; int rc = 0; @@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void) iounmap (io_mem); debug ("returned ebda segment: %x\n", ebda_seg); - io_mem = ioremap(ebda_seg<<4, 1024); + io_mem = ioremap(ebda_seg<<4, 1); + if (!io_mem) + return -ENOMEM; + ebda_sz = readb(io_mem); + iounmap(io_mem); + debug("ebda size: %d(KiB)\n", ebda_sz); + if (ebda_sz == 0) + return -ENOMEM; + + io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024)); if (!io_mem ) return -ENOMEM; next_offset = 0x180; diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index c7084f0eca5a..1aaf3f32d3cd 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c @@ -35,6 +35,7 @@ #include <linux/init.h> #include <linux/mutex.h> #include <linux/sched.h> +#include <linux/semaphore.h> #include <linux/kthread.h> #include "ibmphp.h" 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); static int once_over (void); static int remove_ranges (struct bus_node *, struct bus_node *); static int update_bridge_ranges (struct bus_node **); -static int add_range (int type, struct range_node *, struct bus_node *); +static int add_bus_range (int type, struct range_node *, struct bus_node *); static void fix_resources (struct bus_node *); static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); @@ -133,7 +133,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node newrange->rangeno = 1; else { /* need to insert our range */ - add_range (flag, newrange, newbus); + add_bus_range (flag, newrange, newbus); debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end); } @@ -384,7 +384,7 @@ int __init ibmphp_rsrc_init (void) * Input: type of the resource, range to add, current bus * Output: 0 or -1, bus and range ptrs ********************************************************************************/ -static int add_range (int type, struct range_node *range, struct bus_node *bus_cur) +static int add_bus_range (int type, struct range_node *range, struct bus_node *bus_cur) { struct range_node *range_cur = NULL; struct range_node *range_prev; @@ -455,7 +455,7 @@ static int add_range (int type, struct range_node *range, struct bus_node *bus_c /******************************************************************************* * This routine goes through the list of resources of type 'type' and updates - * the range numbers that they correspond to. It was called from add_range fnc + * the range numbers that they correspond to. It was called from add_bus_range fnc * * Input: bus, type of the resource, the rangeno starting from which to update ******************************************************************************/ @@ -1999,7 +1999,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) if (bus_sec->noIORanges > 0) { if (!range_exists_already (range, bus_sec, IO)) { - add_range (IO, range, bus_sec); + add_bus_range (IO, range, bus_sec); ++bus_sec->noIORanges; } else { kfree (range); @@ -2048,7 +2048,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) if (bus_sec->noMemRanges > 0) { if (!range_exists_already (range, bus_sec, MEM)) { - add_range (MEM, range, bus_sec); + add_bus_range (MEM, range, bus_sec); ++bus_sec->noMemRanges; } else { kfree (range); @@ -2102,7 +2102,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) if (bus_sec->noPFMemRanges > 0) { if (!range_exists_already (range, bus_sec, PFMEM)) { - add_range (PFMEM, range, bus_sec); + add_bus_range (PFMEM, range, bus_sec); ++bus_sec->noPFMemRanges; } else { kfree (range); diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 38183a534b65..728b119f71ad 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -64,32 +64,6 @@ static int debug; static LIST_HEAD(pci_hotplug_slot_list); static DEFINE_MUTEX(pci_hp_mutex); -/* these strings match up with the values in pci_bus_speed */ -static char *pci_bus_speed_strings[] = { - "33 MHz PCI", /* 0x00 */ - "66 MHz PCI", /* 0x01 */ - "66 MHz PCI-X", /* 0x02 */ - "100 MHz PCI-X", /* 0x03 */ - "133 MHz PCI-X", /* 0x04 */ - NULL, /* 0x05 */ - NULL, /* 0x06 */ - NULL, /* 0x07 */ - NULL, /* 0x08 */ - "66 MHz PCI-X 266", /* 0x09 */ - "100 MHz PCI-X 266", /* 0x0a */ - "133 MHz PCI-X 266", /* 0x0b */ - NULL, /* 0x0c */ - NULL, /* 0x0d */ - NULL, /* 0x0e */ - NULL, /* 0x0f */ - NULL, /* 0x10 */ - "66 MHz PCI-X 533", /* 0x11 */ - "100 MHz PCI-X 533", /* 0x12 */ - "133 MHz PCI-X 533", /* 0x13 */ - "2.5 GT/s PCIe", /* 0x14 */ - "5.0 GT/s PCIe", /* 0x15 */ -}; - #ifdef CONFIG_HOTPLUG_PCI_CPCI extern int cpci_hotplug_init(int debug); extern void cpci_hotplug_exit(void); @@ -118,8 +92,6 @@ GET_STATUS(power_status, u8) GET_STATUS(attention_status, u8) GET_STATUS(latch_status, u8) GET_STATUS(adapter_status, u8) -GET_STATUS(max_bus_speed, enum pci_bus_speed) -GET_STATUS(cur_bus_speed, enum pci_bus_speed) static ssize_t power_read_file(struct pci_slot *slot, char *buf) { @@ -263,60 +235,6 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = { .show = presence_read_file, }; -static char *unknown_speed = "Unknown bus speed"; - -static ssize_t max_bus_speed_read_file(struct pci_slot *slot, char *buf) -{ - char *speed_string; - int retval; - enum pci_bus_speed value; - - retval = get_max_bus_speed(slot->hotplug, &value); - if (retval) - goto exit; - - if (value == PCI_SPEED_UNKNOWN) - speed_string = unknown_speed; - else - speed_string = pci_bus_speed_strings[value]; - - retval = sprintf (buf, "%s\n", speed_string); - -exit: - return retval; -} - -static struct pci_slot_attribute hotplug_slot_attr_max_bus_speed = { - .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO}, - .show = max_bus_speed_read_file, -}; - -static ssize_t cur_bus_speed_read_file(struct pci_slot *slot, char *buf) -{ - char *speed_string; - int retval; - enum pci_bus_speed value; - - retval = get_cur_bus_speed(slot->hotplug, &value); - if (retval) - goto exit; - - if (value == PCI_SPEED_UNKNOWN) - speed_string = unknown_speed; - else - speed_string = pci_bus_speed_strings[value]; - - retval = sprintf (buf, "%s\n", speed_string); - -exit: - return retval; -} - -static struct pci_slot_attribute hotplug_slot_attr_cur_bus_speed = { - .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO}, - .show = cur_bus_speed_read_file, -}; - static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, size_t count) { @@ -391,26 +309,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot) return false; } -static bool has_max_bus_speed_file(struct pci_slot *pci_slot) -{ - struct hotplug_slot *slot = pci_slot->hotplug; - if ((!slot) || (!slot->ops)) - return false; - if (slot->ops->get_max_bus_speed) - return true; - return false; -} - -static bool has_cur_bus_speed_file(struct pci_slot *pci_slot) -{ - struct hotplug_slot *slot = pci_slot->hotplug; - if ((!slot) || (!slot->ops)) - return false; - if (slot->ops->get_cur_bus_speed) - return true; - return false; -} - static bool has_test_file(struct pci_slot *pci_slot) { struct hotplug_slot *slot = pci_slot->hotplug; @@ -456,20 +354,6 @@ static int fs_add_slot(struct pci_slot *slot) goto exit_adapter; } - if (has_max_bus_speed_file(slot)) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); - if (retval) - goto exit_max_speed; - } - - if (has_cur_bus_speed_file(slot)) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); - if (retval) - goto exit_cur_speed; - } - if (has_test_file(slot)) { retval = sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr); @@ -480,14 +364,6 @@ static int fs_add_slot(struct pci_slot *slot) goto exit; exit_test: - if (has_cur_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); -exit_cur_speed: - if (has_max_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); -exit_max_speed: if (has_adapter_file(slot)) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); @@ -523,14 +399,6 @@ static void fs_remove_slot(struct pci_slot *slot) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); - if (has_max_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); - - if (has_cur_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); - if (has_test_file(slot)) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 5674b2075bdc..920f820edf87 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -69,8 +69,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); -static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); -static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); /** * release_slot - free up the memory used by a slot @@ -113,8 +111,6 @@ static int init_slot(struct controller *ctrl) ops->disable_slot = disable_slot; ops->get_power_status = get_power_status; ops->get_adapter_status = get_adapter_status; - ops->get_max_bus_speed = get_max_bus_speed; - ops->get_cur_bus_speed = get_cur_bus_speed; if (MRL_SENS(ctrl)) ops->get_latch_status = get_latch_status; if (ATTN_LED(ctrl)) { @@ -227,27 +223,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return pciehp_get_adapter_status(slot, value); } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, - enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - return pciehp_get_max_link_speed(slot, value); -} - -static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - return pciehp_get_cur_link_speed(slot, value); -} - static int pciehp_probe(struct pcie_device *dev) { int rc; diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index d6ac1b261dd9..9a7f247e8ac1 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -341,6 +341,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) p_slot->state = POWERON_STATE; break; default: + kfree(info); goto out; } queue_work(pciehp_wq, &info->work); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 10040d58c8ef..40b48f569b1e 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -492,6 +492,7 @@ int pciehp_power_on_slot(struct slot * slot) u16 slot_cmd; u16 cmd_mask; u16 slot_status; + u16 lnk_status; int retval = 0; /* Clear sticky power-fault bit from previous power failures */ @@ -523,6 +524,14 @@ int pciehp_power_on_slot(struct slot * slot) ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); + retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); + if (retval) { + ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", + __func__); + return retval; + } + pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); + return retval; } @@ -610,37 +619,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) return IRQ_HANDLED; } -int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value) -{ - struct controller *ctrl = slot->ctrl; - enum pcie_link_speed lnk_speed; - u32 lnk_cap; - int retval = 0; - - retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); - return retval; - } - - switch (lnk_cap & 0x000F) { - case 1: - lnk_speed = PCIE_2_5GB; - break; - case 2: - lnk_speed = PCIE_5_0GB; - break; - default: - lnk_speed = PCIE_LNK_SPEED_UNKNOWN; - break; - } - - *value = lnk_speed; - ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed); - - return retval; -} - int pciehp_get_max_lnk_width(struct slot *slot, enum pcie_link_width *value) { @@ -691,38 +669,6 @@ int pciehp_get_max_lnk_width(struct slot *slot, return retval; } -int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value) -{ - struct controller *ctrl = slot->ctrl; - enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; - int retval = 0; - u16 lnk_status; - - retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", - __func__); - return retval; - } - - switch (lnk_status & PCI_EXP_LNKSTA_CLS) { - case 1: - lnk_speed = PCIE_2_5GB; - break; - case 2: - lnk_speed = PCIE_5_0GB; - break; - default: - lnk_speed = PCIE_LNK_SPEED_UNKNOWN; - break; - } - - *value = lnk_speed; - ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed); - - return retval; -} - int pciehp_get_cur_lnk_width(struct slot *slot, enum pcie_link_width *value) { diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 21733108adde..0a16444c14c9 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -53,17 +53,15 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev) busnr = pci_scan_bridge(parent, dev, busnr, pass); if (!dev->subordinate) return -1; - pci_bus_size_bridges(dev->subordinate); - pci_bus_assign_resources(parent); - pci_enable_bridges(parent); - pci_bus_add_devices(parent); + return 0; } int pciehp_configure_device(struct slot *p_slot) { struct pci_dev *dev; - struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; + struct pci_dev *bridge = p_slot->ctrl->pcie->port; + struct pci_bus *parent = bridge->subordinate; int num, fn; struct controller *ctrl = p_slot->ctrl; @@ -96,12 +94,25 @@ int pciehp_configure_device(struct slot *p_slot) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { pciehp_add_bridge(dev); } + pci_dev_put(dev); + } + + pci_assign_unassigned_bridge_resources(bridge); + + for (fn = 0; fn < 8; fn++) { + dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); + if (!dev) + continue; + if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + pci_dev_put(dev); + continue; + } pci_configure_slot(dev); pci_dev_put(dev); } - pci_bus_assign_resources(parent); pci_bus_add_devices(parent); + return 0; } diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c159223389ec..dcaae725fd79 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -130,10 +130,9 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) return 0; } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) +static enum pci_bus_speed get_max_bus_speed(struct slot *slot) { - struct slot *slot = (struct slot *)hotplug_slot->private; - + enum pci_bus_speed speed; switch (slot->type) { case 1: case 2: @@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe case 4: case 5: case 6: - *value = PCI_SPEED_33MHz; /* speed for case 1-6 */ + speed = PCI_SPEED_33MHz; /* speed for case 1-6 */ break; case 7: case 8: - *value = PCI_SPEED_66MHz; + speed = PCI_SPEED_66MHz; break; case 11: case 14: - *value = PCI_SPEED_66MHz_PCIX; + speed = PCI_SPEED_66MHz_PCIX; break; case 12: case 15: - *value = PCI_SPEED_100MHz_PCIX; + speed = PCI_SPEED_100MHz_PCIX; break; case 13: case 16: - *value = PCI_SPEED_133MHz_PCIX; + speed = PCI_SPEED_133MHz_PCIX; break; default: - *value = PCI_SPEED_UNKNOWN; + speed = PCI_SPEED_UNKNOWN; break; - } - return 0; + + return speed; } static int get_children_props(struct device_node *dn, const int **drc_indexes, @@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) slot->state = NOT_VALID; return -EINVAL; } + + slot->bus->max_bus_speed = get_max_bus_speed(slot); return 0; } @@ -429,7 +430,6 @@ struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .get_power_status = get_power_status, .get_attention_status = get_attention_status, .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, }; module_init(rpaphp_init); diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 8e210cd76e55..d2627e1c3ac1 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -333,8 +333,6 @@ struct hpc_ops { int (*set_attention_status)(struct slot *slot, u8 status); int (*get_latch_status)(struct slot *slot, u8 *status); int (*get_adapter_status)(struct slot *slot, u8 *status); - int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); - int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); int (*get_prog_int)(struct slot *slot, u8 *prog_int); diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 8a520a3d0f59..a5062297f488 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -65,8 +65,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); -static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); -static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { .set_attention_status = set_attention_status, @@ -76,8 +74,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, - .get_cur_bus_speed = get_cur_bus_speed, }; /** @@ -279,37 +275,6 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, - enum pci_bus_speed *value) -{ - struct slot *slot = get_slot(hotplug_slot); - int retval; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - retval = slot->hpc_ops->get_max_bus_speed(slot, value); - if (retval < 0) - *value = PCI_SPEED_UNKNOWN; - - return 0; -} - -static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = get_slot(hotplug_slot); - int retval; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - retval = slot->hpc_ops->get_cur_bus_speed(slot, value); - if (retval < 0) - *value = PCI_SPEED_UNKNOWN; - - return 0; -} - static int is_shpc_capable(struct pci_dev *dev) { if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b8ab2796e66a..3bba0c0888ff 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -285,17 +285,8 @@ static int board_added(struct slot *p_slot) return WRONG_BUS_FREQUENCY; } - rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp); - if (rc) { - ctrl_err(ctrl, "Can't get bus operation speed\n"); - return WRONG_BUS_FREQUENCY; - } - - rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp); - if (rc) { - ctrl_err(ctrl, "Can't get max bus operation speed\n"); - msp = bsp; - } + bsp = ctrl->pci_dev->bus->cur_bus_speed; + msp = ctrl->pci_dev->bus->max_bus_speed; /* Check if there are other slots or devices on the same bus */ if (!list_empty(&ctrl->pci_dev->subordinate->devices)) @@ -462,6 +453,7 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) p_slot->state = POWERON_STATE; break; default: + kfree(info); goto out; } queue_work(shpchp_wq, &info->work); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 86dc39847769..5f5e8d2e3552 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot) return retval; } +static int shpc_get_cur_bus_speed(struct controller *ctrl) +{ + int retval = 0; + struct pci_bus *bus = ctrl->pci_dev->subordinate; + enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; + u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); + u8 pi = shpc_readb(ctrl, PROG_INTERFACE); + u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); + + if ((pi == 1) && (speed_mode > 4)) { + retval = -ENODEV; + goto out; + } + + switch (speed_mode) { + case 0x0: + bus_speed = PCI_SPEED_33MHz; + break; + case 0x1: + bus_speed = PCI_SPEED_66MHz; + break; + case 0x2: + bus_speed = PCI_SPEED_66MHz_PCIX; + break; + case 0x3: + bus_speed = PCI_SPEED_100MHz_PCIX; + break; + case 0x4: + bus_speed = PCI_SPEED_133MHz_PCIX; + break; + case 0x5: + bus_speed = PCI_SPEED_66MHz_PCIX_ECC; + break; + case 0x6: + bus_speed = PCI_SPEED_100MHz_PCIX_ECC; + break; + case 0x7: + bus_speed = PCI_SPEED_133MHz_PCIX_ECC; + break; + case 0x8: + bus_speed = PCI_SPEED_66MHz_PCIX_266; + break; + case 0x9: + bus_speed = PCI_SPEED_100MHz_PCIX_266; + break; + case 0xa: + bus_speed = PCI_SPEED_133MHz_PCIX_266; + break; + case 0xb: + bus_speed = PCI_SPEED_66MHz_PCIX_533; + break; + case 0xc: + bus_speed = PCI_SPEED_100MHz_PCIX_533; + break; + case 0xd: + bus_speed = PCI_SPEED_133MHz_PCIX_533; + break; + default: + retval = -ENODEV; + break; + } + + out: + bus->cur_bus_speed = bus_speed; + dbg("Current bus speed = %d\n", bus_speed); + return retval; +} + + static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) { int retval; @@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) retval = shpc_write_cmd(slot, 0, cmd); if (retval) ctrl_err(ctrl, "%s: Write command failed!\n", __func__); + else + shpc_get_cur_bus_speed(ctrl); return retval; } @@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) +static int shpc_get_max_bus_speed(struct controller *ctrl) { int retval = 0; - struct controller *ctrl = slot->ctrl; + struct pci_bus *bus = ctrl->pci_dev->subordinate; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; u8 pi = shpc_readb(ctrl, PROG_INTERFACE); u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); @@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) retval = -ENODEV; } - *value = bus_speed; + bus->max_bus_speed = bus_speed; ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); return retval; } -static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) -{ - int retval = 0; - struct controller *ctrl = slot->ctrl; - enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; - u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); - u8 pi = shpc_readb(ctrl, PROG_INTERFACE); - u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); - - if ((pi == 1) && (speed_mode > 4)) { - *value = PCI_SPEED_UNKNOWN; - return -ENODEV; - } - - switch (speed_mode) { - case 0x0: - *value = PCI_SPEED_33MHz; - break; - case 0x1: - *value = PCI_SPEED_66MHz; - break; - case 0x2: - *value = PCI_SPEED_66MHz_PCIX; - break; - case 0x3: - *value = PCI_SPEED_100MHz_PCIX; - break; - case 0x4: - *value = PCI_SPEED_133MHz_PCIX; - break; - case 0x5: - *value = PCI_SPEED_66MHz_PCIX_ECC; - break; - case 0x6: - *value = PCI_SPEED_100MHz_PCIX_ECC; - break; - case 0x7: - *value = PCI_SPEED_133MHz_PCIX_ECC; - break; - case 0x8: - *value = PCI_SPEED_66MHz_PCIX_266; - break; - case 0x9: - *value = PCI_SPEED_100MHz_PCIX_266; - break; - case 0xa: - *value = PCI_SPEED_133MHz_PCIX_266; - break; - case 0xb: - *value = PCI_SPEED_66MHz_PCIX_533; - break; - case 0xc: - *value = PCI_SPEED_100MHz_PCIX_533; - break; - case 0xd: - *value = PCI_SPEED_133MHz_PCIX_533; - break; - default: - *value = PCI_SPEED_UNKNOWN; - retval = -ENODEV; - break; - } - - ctrl_dbg(ctrl, "Current bus speed = %d\n", bus_speed); - return retval; -} - static struct hpc_ops shpchp_hpc_ops = { .power_on_slot = hpc_power_on_slot, .slot_enable = hpc_slot_enable, @@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = { .get_latch_status = hpc_get_latch_status, .get_adapter_status = hpc_get_adapter_status, - .get_max_bus_speed = hpc_get_max_bus_speed, - .get_cur_bus_speed = hpc_get_cur_bus_speed, .get_adapter_speed = hpc_get_adapter_speed, .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, .get_prog_int = hpc_get_prog_int, @@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) } ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); + shpc_get_max_bus_speed(ctrl); + shpc_get_cur_bus_speed(ctrl); + /* * If this is the first controller to be initialized, * initialize the shpchpd work queue diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 29fa9d26adae..071b7dc0094b 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -47,8 +47,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha bus = pdev->subordinate; out += sprintf(buf, "Free resources: memory\n"); - for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { - res = bus->resource[index]; + pci_bus_for_each_resource(bus, res, index) { if (res && (res->flags & IORESOURCE_MEM) && !(res->flags & IORESOURCE_PREFETCH)) { out += sprintf(out, "start = %8.8llx, " @@ -58,8 +57,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } } out += sprintf(out, "Free resources: prefetchable memory\n"); - for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { - res = bus->resource[index]; + pci_bus_for_each_resource(bus, res, index) { if (res && (res->flags & IORESOURCE_MEM) && (res->flags & IORESOURCE_PREFETCH)) { out += sprintf(out, "start = %8.8llx, " @@ -69,8 +67,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } } out += sprintf(out, "Free resources: IO\n"); - for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { - res = bus->resource[index]; + pci_bus_for_each_resource(bus, res, index) { if (res && (res->flags & IORESOURCE_IO)) { out += sprintf(out, "start = %8.8llx, " "length = %8.8llx\n", |