Commit 3749c51a authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Jesse Barnes

PCI: Make current and maximum bus speeds part of the PCI core

Move the max_bus_speed and cur_bus_speed into the pci_bus.  Expose the
values through the PCI slot driver instead of the hotplug slot driver.
Update all the hotplug drivers to use the pci_bus instead of their own
data structures.
Signed-off-by: default avatarMatthew Wilcox <willy@linux.intel.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 536c8cb4
...@@ -332,8 +332,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) ...@@ -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->attention_status = 0;
slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); 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->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; acpiphp_slot->slot = slot;
snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun);
......
...@@ -310,8 +310,6 @@ struct controller { ...@@ -310,8 +310,6 @@ struct controller {
u8 first_slot; u8 first_slot;
u8 add_support; u8 add_support;
u8 push_flag; u8 push_flag;
enum pci_bus_speed speed;
enum pci_bus_speed speed_capability;
u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */
u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ u8 slot_switch_type; /* 0 = no switch, 1 = switch present */
u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */
......
...@@ -583,30 +583,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -583,30 +583,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
return 0; 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 = { static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
.set_attention_status = set_attention_status, .set_attention_status = set_attention_status,
.enable_slot = process_SI, .enable_slot = process_SI,
...@@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { ...@@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_latch_status = get_latch_status, .get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_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 #define SLOT_NAME_SIZE 10
...@@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct controller *ctrl, ...@@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
struct slot *slot; struct slot *slot;
struct hotplug_slot *hotplug_slot; struct hotplug_slot *hotplug_slot;
struct hotplug_slot_info *hotplug_slot_info; struct hotplug_slot_info *hotplug_slot_info;
struct pci_bus *bus = ctrl->pci_bus;
u8 number_of_slots; u8 number_of_slots;
u8 slot_device; u8 slot_device;
u8 slot_number; u8 slot_number;
...@@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct controller *ctrl, ...@@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
if (is_slot66mhz(slot)) if (is_slot66mhz(slot))
slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; 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; slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
ctrl_slot = ctrl_slot =
...@@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u32 rc; u32 rc;
struct controller *ctrl; struct controller *ctrl;
struct pci_func *func; struct pci_func *func;
struct pci_bus *bus;
int err; int err;
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
...@@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_name(pdev), err); pci_name(pdev), err);
return err; return err;
} }
bus = pdev->subordinate;
/* Need to read VID early b/c it's used to differentiate CPQ and INTC /* Need to read VID early b/c it's used to differentiate CPQ and INTC
* discovery * discovery
...@@ -929,22 +906,22 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -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); pci_read_config_byte(pdev, 0x41, &bus_cap);
if (bus_cap & 0x80) { if (bus_cap & 0x80) {
dbg("bus max supports 133MHz PCI-X\n"); dbg("bus max supports 133MHz PCI-X\n");
ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; bus->max_bus_speed = PCI_SPEED_133MHz_PCIX;
break; break;
} }
if (bus_cap & 0x40) { if (bus_cap & 0x40) {
dbg("bus max supports 100MHz PCI-X\n"); dbg("bus max supports 100MHz PCI-X\n");
ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; bus->max_bus_speed = PCI_SPEED_100MHz_PCIX;
break; break;
} }
if (bus_cap & 20) { if (bus_cap & 20) {
dbg("bus max supports 66MHz PCI-X\n"); dbg("bus max supports 66MHz PCI-X\n");
ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; bus->max_bus_speed = PCI_SPEED_66MHz_PCIX;
break; break;
} }
if (bus_cap & 10) { if (bus_cap & 10) {
dbg("bus max supports 66MHz PCI\n"); dbg("bus max supports 66MHz PCI\n");
ctrl->speed_capability = PCI_SPEED_66MHz; bus->max_bus_speed = PCI_SPEED_66MHz;
break; break;
} }
...@@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
case PCI_SUB_HPC_ID: case PCI_SUB_HPC_ID:
/* Original 6500/7000 implementation */ /* Original 6500/7000 implementation */
ctrl->slot_switch_type = 1; ctrl->slot_switch_type = 1;
ctrl->speed_capability = PCI_SPEED_33MHz; bus->max_bus_speed = PCI_SPEED_33MHz;
ctrl->push_button = 0; ctrl->push_button = 0;
ctrl->pci_config_space = 1; ctrl->pci_config_space = 1;
ctrl->defeature_PHP = 1; ctrl->defeature_PHP = 1;
...@@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* First Pushbutton implementation */ /* First Pushbutton implementation */
ctrl->push_flag = 1; ctrl->push_flag = 1;
ctrl->slot_switch_type = 1; ctrl->slot_switch_type = 1;
ctrl->speed_capability = PCI_SPEED_33MHz; bus->max_bus_speed = PCI_SPEED_33MHz;
ctrl->push_button = 1; ctrl->push_button = 1;
ctrl->pci_config_space = 1; ctrl->pci_config_space = 1;
ctrl->defeature_PHP = 1; ctrl->defeature_PHP = 1;
...@@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
case PCI_SUB_HPC_ID_INTC: case PCI_SUB_HPC_ID_INTC:
/* Third party (6500/7000) */ /* Third party (6500/7000) */
ctrl->slot_switch_type = 1; ctrl->slot_switch_type = 1;
ctrl->speed_capability = PCI_SPEED_33MHz; bus->max_bus_speed = PCI_SPEED_33MHz;
ctrl->push_button = 0; ctrl->push_button = 0;
ctrl->pci_config_space = 1; ctrl->pci_config_space = 1;
ctrl->defeature_PHP = 1; ctrl->defeature_PHP = 1;
...@@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* First 66 Mhz implementation */ /* First 66 Mhz implementation */
ctrl->push_flag = 1; ctrl->push_flag = 1;
ctrl->slot_switch_type = 1; ctrl->slot_switch_type = 1;
ctrl->speed_capability = PCI_SPEED_66MHz; bus->max_bus_speed = PCI_SPEED_66MHz;
ctrl->push_button = 1; ctrl->push_button = 1;
ctrl->pci_config_space = 1; ctrl->pci_config_space = 1;
ctrl->defeature_PHP = 1; ctrl->defeature_PHP = 1;
...@@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* First PCI-X implementation, 100MHz */ /* First PCI-X implementation, 100MHz */
ctrl->push_flag = 1; ctrl->push_flag = 1;
ctrl->slot_switch_type = 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->push_button = 1;
ctrl->pci_config_space = 1; ctrl->pci_config_space = 1;
ctrl->defeature_PHP = 1; ctrl->defeature_PHP = 1;
...@@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
case PCI_VENDOR_ID_INTEL: case PCI_VENDOR_ID_INTEL:
/* Check for speed capability (0=33, 1=66) */ /* Check for speed capability (0=33, 1=66) */
if (subsystem_deviceid & 0x0001) if (subsystem_deviceid & 0x0001)
ctrl->speed_capability = PCI_SPEED_66MHz; bus->max_bus_speed = PCI_SPEED_66MHz;
else else
ctrl->speed_capability = PCI_SPEED_33MHz; bus->max_bus_speed = PCI_SPEED_33MHz;
/* Check for push button */ /* Check for push button */
if (subsystem_deviceid & 0x0002) if (subsystem_deviceid & 0x0002)
...@@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pdev->bus->number); pdev->bus->number);
dbg("Hotplug controller capabilities:\n"); 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 ? dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ?
"switch present" : "no switch"); "switch present" : "no switch");
dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ?
...@@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
/* Check for 66Mhz operation */ /* Check for 66Mhz operation */
ctrl->speed = get_controller_speed(ctrl); bus->cur_bus_speed = get_controller_speed(ctrl);
/******************************************************** /********************************************************
......
...@@ -1130,12 +1130,13 @@ static int is_bridge(struct pci_func * func) ...@@ -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) static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
{ {
struct slot *slot; struct slot *slot;
struct pci_bus *bus = ctrl->pci_bus;
u8 reg; u8 reg;
u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
u16 reg16; u16 reg16;
u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
if (ctrl->speed == adapter_speed) if (bus->cur_bus_speed == adapter_speed)
return 0; return 0;
/* We don't allow freq/mode changes if we find another adapter running /* 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,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 * lower speed/mode, we allow the new adapter to function at
* this rate if supported * this rate if supported
*/ */
if (ctrl->speed < adapter_speed) if (bus->cur_bus_speed < adapter_speed)
return 0; return 0;
return 1; return 1;
...@@ -1161,20 +1162,20 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ ...@@ -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 /* If the controller doesn't support freq/mode changes and the
* controller is running at a higher mode, we bail * 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; return 1;
/* But we allow the adapter to run at a lower rate if possible */ /* 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; return 0;
/* We try to set the max speed supported by both the adapter and /* We try to set the max speed supported by both the adapter and
* controller * controller
*/ */
if (ctrl->speed_capability < adapter_speed) { if (bus->max_bus_speed < adapter_speed) {
if (ctrl->speed == ctrl->speed_capability) if (bus->cur_bus_speed == bus->max_bus_speed)
return 0; return 0;
adapter_speed = ctrl->speed_capability; adapter_speed = bus->max_bus_speed;
} }
writel(0x0L, ctrl->hpc_reg + LED_CONTROL); 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,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); pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
/* Only if mode change...*/ /* Only if mode change...*/
if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) ((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))
set_SOGO(ctrl); set_SOGO(ctrl);
wait_for_ctrl_irq(ctrl); wait_for_ctrl_irq(ctrl);
...@@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ ...@@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
set_SOGO(ctrl); set_SOGO(ctrl);
wait_for_ctrl_irq(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); slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
info("Successfully changed frequency/mode for adapter in slot %d\n", 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,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) static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
{ {
struct pci_bus *bus = ctrl->pci_bus;
u8 hp_slot; u8 hp_slot;
u8 temp_byte; u8 temp_byte;
u8 adapter_speed; u8 adapter_speed;
...@@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) ...@@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
adapter_speed = get_adapter_speed(ctrl, hp_slot); 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)) if (set_controller_speed(ctrl, adapter_speed, hp_slot))
rc = WRONG_BUS_FREQUENCY; rc = WRONG_BUS_FREQUENCY;
...@@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) ...@@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
u32 temp_register = 0xFFFFFFFF; u32 temp_register = 0xFFFFFFFF;
u32 rc = 0; u32 rc = 0;
struct pci_func *new_slot = NULL; struct pci_func *new_slot = NULL;
struct pci_bus *bus = ctrl->pci_bus;
struct slot *p_slot; struct slot *p_slot;
struct resource_lists res_lists; struct resource_lists res_lists;
...@@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) ...@@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
adapter_speed = get_adapter_speed(ctrl, hp_slot); 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)) if (set_controller_speed(ctrl, adapter_speed, hp_slot))
rc = WRONG_BUS_FREQUENCY; rc = WRONG_BUS_FREQUENCY;
......
...@@ -395,89 +395,40 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -395,89 +395,40 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
return rc; 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; int rc;
struct slot *pslot;
u8 mode = 0; 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__, debug("%s - Entry slot[%p]\n", __func__, slot);
hotplug_slot, value);
ibmphp_lock_operations(); ibmphp_lock_operations();
mode = slot->supported_bus_mode;
if (hotplug_slot) { speed = slot->supported_speed;
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;
}
}
}
ibmphp_unlock_operations(); 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) switch (speed) {
{ case BUS_SPEED_33:
int rc = -ENODEV; break;
struct slot *pslot; case BUS_SPEED_66:
u8 mode = 0; if (mode == BUS_MODE_PCIX)
speed += 0x01;
debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, break;
hotplug_slot, value); case BUS_SPEED_100:
case BUS_SPEED_133:
ibmphp_lock_operations(); speed += 0x01;
break;
if (hotplug_slot) { default:
pslot = hotplug_slot->private; /* Note (will need to change): there would be soon 256, 512 also */
if (pslot) { rc = -ENODEV;
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;
}
}
}
} }
ibmphp_unlock_operations(); if (!rc)
debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); bus->max_bus_speed = speed;
debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed);
return rc; return rc;
} }
...@@ -572,6 +523,7 @@ static int __init init_ops(void) ...@@ -572,6 +523,7 @@ static int __init init_ops(void)
if (slot_cur->bus_on->current_speed == 0xFF) if (slot_cur->bus_on->current_speed == 0xFF)
if (get_cur_bus_info(&slot_cur)) if (get_cur_bus_info(&slot_cur))
return -1; return -1;
get_max_bus_speed(slot_cur);
if (slot_cur->ctrl->options == 0xFF) if (slot_cur->ctrl->options == 0xFF)
if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
...@@ -655,6 +607,7 @@ static int validate(struct slot *slot_cur, int opn) ...@@ -655,6 +607,7 @@ static int validate(struct slot *slot_cur, int opn)
int ibmphp_update_slot_info(struct slot *slot_cur) int ibmphp_update_slot_info(struct slot *slot_cur)
{ {
struct hotplug_slot_info *info; struct hotplug_slot_info *info;
struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus;
int rc; int rc;
u8 bus_speed; u8 bus_speed;
u8 mode; u8 mode;
...@@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur) ...@@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur)
bus_speed = PCI_SPEED_UNKNOWN; bus_speed = PCI_SPEED_UNKNOWN;
} }
info->cur_bus_speed = bus_speed; bus->cur_bus_speed = bus_speed;
info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
// To do: bus_names // To do: bus_names
rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
...@@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { ...@@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_latch_status = get_latch_status, .get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_present, .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_max_adapter_speed = get_max_adapter_speed,
.get_bus_name_status = get_bus_name, .get_bus_name_status = get_bus_name,
*/ */
......
...@@ -64,32 +64,6 @@ static int debug; ...@@ -64,32 +64,6 @@ static int debug;
static LIST_HEAD(pci_hotplug_slot_list); static LIST_HEAD(pci_hotplug_slot_list);
static DEFINE_MUTEX(pci_hp_mutex); 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 #ifdef CONFIG_HOTPLUG_PCI_CPCI
extern int cpci_hotplug_init(int debug); extern int cpci_hotplug_init(int debug);
extern void cpci_hotplug_exit(void); extern void cpci_hotplug_exit(void);
...@@ -118,8 +92,6 @@ GET_STATUS(power_status, u8) ...@@ -118,8 +92,6 @@ GET_STATUS(power_status, u8)
GET_STATUS(attention_status, u8) GET_STATUS(attention_status, u8)
GET_STATUS(latch_status, u8) GET_STATUS(latch_status, u8)
GET_STATUS(adapter_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) 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 = { ...@@ -263,60 +235,6 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = {
.show = presence_read_file, .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, static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf,
size_t count) size_t count)
{ {
...@@ -391,26 +309,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot) ...@@ -391,26 +309,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot)
return false; 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) static bool has_test_file(struct pci_slot *pci_slot)
{ {
struct hotplug_slot *slot = pci_slot->hotplug; struct hotplug_slot *slot = pci_slot->hotplug;
...@@ -456,20 +354,6 @@ static int fs_add_slot(struct pci_slot *slot) ...@@ -456,20 +354,6 @@ static int fs_add_slot(struct pci_slot *slot)
goto exit_adapter; 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)) { if (has_test_file(slot)) {
retval = sysfs_create_file(&slot->kobj, retval = sysfs_create_file(&slot->kobj,
&hotplug_slot_attr_test.attr); &hotplug_slot_attr_test.attr);
...@@ -480,14 +364,6 @@ static int fs_add_slot(struct pci_slot *slot) ...@@ -480,14 +364,6 @@ static int fs_add_slot(struct pci_slot *slot)
goto exit; goto exit;
exit_test: 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)) if (has_adapter_file(slot))
sysfs_remove_file(&slot->kobj, sysfs_remove_file(&slot->kobj,
&hotplug_slot_attr_presence.attr); &hotplug_slot_attr_presence.attr);
...@@ -523,14 +399,6 @@ static void fs_remove_slot(struct pci_slot *slot) ...@@ -523,14 +399,6 @@ static void fs_remove_slot(struct pci_slot *slot)
sysfs_remove_file(&slot->kobj, sysfs_remove_file(&slot->kobj,
&hotplug_slot_attr_presence.attr); &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)) if (has_test_file(slot))
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
......
...@@ -69,8 +69,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); ...@@ -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_attention_status (struct hotplug_slot *slot, u8 *value);
static int get_latch_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_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 * release_slot - free up the memory used by a slot
...@@ -113,8 +111,6 @@ static int init_slot(struct controller *ctrl) ...@@ -113,8 +111,6 @@ static int init_slot(struct controller *ctrl)
ops->disable_slot = disable_slot; ops->disable_slot = disable_slot;
ops->get_power_status = get_power_status; ops->get_power_status = get_power_status;
ops->get_adapter_status = get_adapter_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)) if (MRL_SENS(ctrl))
ops->get_latch_status = get_latch_status; ops->get_latch_status = get_latch_status;
if (ATTN_LED(ctrl)) { if (ATTN_LED(ctrl)) {
...@@ -227,27 +223,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -227,27 +223,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
return pciehp_get_adapter_status(slot, 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) static int pciehp_probe(struct pcie_device *dev)
{ {
int rc; int rc;
......
...@@ -492,6 +492,7 @@ int pciehp_power_on_slot(struct slot * slot) ...@@ -492,6 +492,7 @@ int pciehp_power_on_slot(struct slot * slot)
u16 slot_cmd; u16 slot_cmd;
u16 cmd_mask; u16 cmd_mask;
u16 slot_status; u16 slot_status;
u16 lnk_status;
int retval = 0; int retval = 0;
/* Clear sticky power-fault bit from previous power failures */ /* Clear sticky power-fault bit from previous power failures */
...@@ -523,6 +524,14 @@ int pciehp_power_on_slot(struct slot * slot) ...@@ -523,6 +524,14 @@ int pciehp_power_on_slot(struct slot * slot)
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); 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; return retval;
} }
...@@ -610,37 +619,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) ...@@ -610,37 +619,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value)
{
struct controller *ctrl = slot->ctrl;
enum pci_bus_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_SPEED_2_5GT;
break;
case 2:
lnk_speed = PCIE_SPEED_5_0GT;
break;
default:
lnk_speed = PCI_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, int pciehp_get_max_lnk_width(struct slot *slot,
enum pcie_link_width *value) enum pcie_link_width *value)
{ {
...@@ -691,38 +669,6 @@ int pciehp_get_max_lnk_width(struct slot *slot, ...@@ -691,38 +669,6 @@ int pciehp_get_max_lnk_width(struct slot *slot,
return retval; return retval;
} }
int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value)
{
struct controller *ctrl = slot->ctrl;
enum pci_bus_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_SPEED_2_5GT;
break;
case 2:
lnk_speed = PCIE_SPEED_5_0GT;
break;
default:
lnk_speed = PCI_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, int pciehp_get_cur_lnk_width(struct slot *slot,
enum pcie_link_width *value) enum pcie_link_width *value)
{ {
......
...@@ -130,10 +130,9 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -130,10 +130,9 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
return 0; 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) { switch (slot->type) {
case 1: case 1:
case 2: case 2:
...@@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe ...@@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
case 4: case 4:
case 5: case 5:
case 6: case 6:
*value = PCI_SPEED_33MHz; /* speed for case 1-6 */ speed = PCI_SPEED_33MHz; /* speed for case 1-6 */
break; break;
case 7: case 7:
case 8: case 8:
*value = PCI_SPEED_66MHz; speed = PCI_SPEED_66MHz;
break; break;
case 11: case 11:
case 14: case 14:
*value = PCI_SPEED_66MHz_PCIX; speed = PCI_SPEED_66MHz_PCIX;
break; break;
case 12: case 12:
case 15: case 15:
*value = PCI_SPEED_100MHz_PCIX; speed = PCI_SPEED_100MHz_PCIX;
break; break;
case 13: case 13:
case 16: case 16:
*value = PCI_SPEED_133MHz_PCIX; speed = PCI_SPEED_133MHz_PCIX;
break; break;
default: default:
*value = PCI_SPEED_UNKNOWN; speed = PCI_SPEED_UNKNOWN;
break; break;
} }
return 0;
return speed;
} }
static int get_children_props(struct device_node *dn, const int **drc_indexes, static int get_children_props(struct device_node *dn, const int **drc_indexes,
...@@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) ...@@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
slot->state = NOT_VALID; slot->state = NOT_VALID;
return -EINVAL; return -EINVAL;
} }
slot->bus->max_bus_speed = get_max_bus_speed(slot);
return 0; return 0;
} }
......
...@@ -333,8 +333,6 @@ struct hpc_ops { ...@@ -333,8 +333,6 @@ struct hpc_ops {
int (*set_attention_status)(struct slot *slot, u8 status); int (*set_attention_status)(struct slot *slot, u8 status);
int (*get_latch_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_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_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed);
int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode);
int (*get_prog_int)(struct slot *slot, u8 *prog_int); int (*get_prog_int)(struct slot *slot, u8 *prog_int);
......
...@@ -65,8 +65,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); ...@@ -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_attention_status (struct hotplug_slot *slot, u8 *value);
static int get_latch_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_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 = { static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
.set_attention_status = set_attention_status, .set_attention_status = set_attention_status,
...@@ -76,8 +74,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { ...@@ -76,8 +74,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_latch_status = get_latch_status, .get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_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) ...@@ -279,37 +275,6 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
return 0; 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) static int is_shpc_capable(struct pci_dev *dev)
{ {
if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device ==
......
...@@ -285,17 +285,8 @@ static int board_added(struct slot *p_slot) ...@@ -285,17 +285,8 @@ static int board_added(struct slot *p_slot)
return WRONG_BUS_FREQUENCY; return WRONG_BUS_FREQUENCY;
} }
rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp); bsp = ctrl->pci_dev->bus->cur_bus_speed;
if (rc) { msp = ctrl->pci_dev->bus->max_bus_speed;
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;
}
/* Check if there are other slots or devices on the same bus */ /* Check if there are other slots or devices on the same bus */
if (!list_empty(&ctrl->pci_dev->subordinate->devices)) if (!list_empty(&ctrl->pci_dev->subordinate->devices))
......
...@@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot) ...@@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot)
return retval; 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) static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
{ {
int retval; int retval;
...@@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) ...@@ -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); retval = shpc_write_cmd(slot, 0, cmd);
if (retval) if (retval)
ctrl_err(ctrl, "%s: Write command failed!\n", __func__); ctrl_err(ctrl, "%s: Write command failed!\n", __func__);
else
shpc_get_cur_bus_speed(ctrl);
return retval; return retval;
} }
...@@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) ...@@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
return IRQ_HANDLED; 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; 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; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
u8 pi = shpc_readb(ctrl, PROG_INTERFACE); u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1);
...@@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) ...@@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
retval = -ENODEV; retval = -ENODEV;
} }
*value = bus_speed; bus->max_bus_speed = bus_speed;
ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed);
return retval; 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 = { static struct hpc_ops shpchp_hpc_ops = {
.power_on_slot = hpc_power_on_slot, .power_on_slot = hpc_power_on_slot,
.slot_enable = hpc_slot_enable, .slot_enable = hpc_slot_enable,
...@@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = { ...@@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = {
.get_latch_status = hpc_get_latch_status, .get_latch_status = hpc_get_latch_status,
.get_adapter_status = hpc_get_adapter_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_adapter_speed = hpc_get_adapter_speed,
.get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap,
.get_prog_int = hpc_get_prog_int, .get_prog_int = hpc_get_prog_int,
...@@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) ...@@ -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); 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, * If this is the first controller to be initialized,
* initialize the shpchpd work queue * initialize the shpchpd work queue
......
...@@ -387,10 +387,37 @@ static struct pci_bus * pci_alloc_bus(void) ...@@ -387,10 +387,37 @@ static struct pci_bus * pci_alloc_bus(void)
INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->children);
INIT_LIST_HEAD(&b->devices); INIT_LIST_HEAD(&b->devices);
INIT_LIST_HEAD(&b->slots); INIT_LIST_HEAD(&b->slots);
b->max_bus_speed = PCI_SPEED_UNKNOWN;
b->cur_bus_speed = PCI_SPEED_UNKNOWN;
} }
return b; return b;
} }
static unsigned char pcie_link_speed[] = {
PCI_SPEED_UNKNOWN, /* 0 */
PCIE_SPEED_2_5GT, /* 1 */
PCIE_SPEED_5_0GT, /* 2 */
PCI_SPEED_UNKNOWN, /* 3 */
PCI_SPEED_UNKNOWN, /* 4 */
PCI_SPEED_UNKNOWN, /* 5 */
PCI_SPEED_UNKNOWN, /* 6 */
PCI_SPEED_UNKNOWN, /* 7 */
PCI_SPEED_UNKNOWN, /* 8 */
PCI_SPEED_UNKNOWN, /* 9 */
PCI_SPEED_UNKNOWN, /* A */
PCI_SPEED_UNKNOWN, /* B */
PCI_SPEED_UNKNOWN, /* C */
PCI_SPEED_UNKNOWN, /* D */
PCI_SPEED_UNKNOWN, /* E */
PCI_SPEED_UNKNOWN /* F */
};
void pcie_update_link_speed(struct pci_bus *bus, u16 linksta)
{
bus->cur_bus_speed = pcie_link_speed[linksta & 0xf];
}
EXPORT_SYMBOL_GPL(pcie_update_link_speed);
static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
struct pci_dev *bridge, int busnr) struct pci_dev *bridge, int busnr)
{ {
......
...@@ -47,6 +47,54 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) ...@@ -47,6 +47,54 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
slot->number); slot->number);
} }
/* 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 */
};
static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
{
const char *speed_string;
if (speed < ARRAY_SIZE(pci_bus_speed_strings))
speed_string = pci_bus_speed_strings[speed];
else
speed_string = "Unknown";
return sprintf(buf, "%s\n", speed_string);
}
static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)
{
return bus_speed_read(slot->bus->max_bus_speed, buf);
}
static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
{
return bus_speed_read(slot->bus->cur_bus_speed, buf);
}
static void pci_slot_release(struct kobject *kobj) static void pci_slot_release(struct kobject *kobj)
{ {
struct pci_dev *dev; struct pci_dev *dev;
...@@ -66,9 +114,15 @@ static void pci_slot_release(struct kobject *kobj) ...@@ -66,9 +114,15 @@ static void pci_slot_release(struct kobject *kobj)
static struct pci_slot_attribute pci_slot_attr_address = static struct pci_slot_attribute pci_slot_attr_address =
__ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL);
static struct pci_slot_attribute pci_slot_attr_max_speed =
__ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL);
static struct pci_slot_attribute pci_slot_attr_cur_speed =
__ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL);
static struct attribute *pci_slot_default_attrs[] = { static struct attribute *pci_slot_default_attrs[] = {
&pci_slot_attr_address.attr, &pci_slot_attr_address.attr,
&pci_slot_attr_max_speed.attr,
&pci_slot_attr_cur_speed.attr,
NULL, NULL,
}; };
......
...@@ -380,6 +380,8 @@ struct pci_bus { ...@@ -380,6 +380,8 @@ struct pci_bus {
unsigned char primary; /* number of primary bridge */ unsigned char primary; /* number of primary bridge */
unsigned char secondary; /* number of secondary bridge */ unsigned char secondary; /* number of secondary bridge */
unsigned char subordinate; /* max number of subordinate buses */ unsigned char subordinate; /* max number of subordinate buses */
unsigned char max_bus_speed; /* enum pci_bus_speed */
unsigned char cur_bus_speed; /* enum pci_bus_speed */
char name[48]; char name[48];
...@@ -610,6 +612,7 @@ struct pci_bus *pci_create_bus(struct device *parent, int bus, ...@@ -610,6 +612,7 @@ struct pci_bus *pci_create_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata); struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
int busnr); int busnr);
void pcie_update_link_speed(struct pci_bus *bus, u16 link_status);
struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
const char *name, const char *name,
struct hotplug_slot *hotplug); struct hotplug_slot *hotplug);
......
...@@ -63,12 +63,6 @@ enum pcie_link_width { ...@@ -63,12 +63,6 @@ enum pcie_link_width {
* @get_adapter_status: Called to get see if an adapter is present in the slot or not. * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
* If this field is NULL, the value passed in the struct hotplug_slot_info * If this field is NULL, the value passed in the struct hotplug_slot_info
* will be used when this value is requested by a user. * will be used when this value is requested by a user.
* @get_max_bus_speed: Called to get the max bus speed for a slot.
* If this field is NULL, the value passed in the struct hotplug_slot_info
* will be used when this value is requested by a user.
* @get_cur_bus_speed: Called to get the current bus speed for a slot.
* If this field is NULL, the value passed in the struct hotplug_slot_info
* will be used when this value is requested by a user.
* *
* The table of function pointers that is passed to the hotplug pci core by a * The table of function pointers that is passed to the hotplug pci core by a
* hotplug pci driver. These functions are called by the hotplug pci core when * hotplug pci driver. These functions are called by the hotplug pci core when
...@@ -86,17 +80,14 @@ struct hotplug_slot_ops { ...@@ -86,17 +80,14 @@ struct hotplug_slot_ops {
int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); int (*get_attention_status) (struct hotplug_slot *slot, u8 *value);
int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_latch_status) (struct hotplug_slot *slot, u8 *value);
int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value);
int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
}; };
/** /**
* struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
* @power: if power is enabled or not (1/0) * @power_status: if power is enabled or not (1/0)
* @attention_status: if the attention light is enabled or not (1/0) * @attention_status: if the attention light is enabled or not (1/0)
* @latch_status: if the latch (if any) is open or closed (1/0) * @latch_status: if the latch (if any) is open or closed (1/0)
* @adapter_present: if there is a pci board present in the slot or not (1/0) * @adapter_status: if there is a pci board present in the slot or not (1/0)
* @address: (domain << 16 | bus << 8 | dev)
* *
* Used to notify the hotplug pci core of the status of a specific slot. * Used to notify the hotplug pci core of the status of a specific slot.
*/ */
...@@ -105,8 +96,6 @@ struct hotplug_slot_info { ...@@ -105,8 +96,6 @@ struct hotplug_slot_info {
u8 attention_status; u8 attention_status;
u8 latch_status; u8 latch_status;
u8 adapter_status; u8 adapter_status;
enum pci_bus_speed max_bus_speed;
enum pci_bus_speed cur_bus_speed;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment