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

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
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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);
+0 −2
Original line number Diff line number Diff line
@@ -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 */
+17 −40
Original line number Diff line number Diff line
@@ -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);


	/********************************************************
+15 −12
Original line number Diff line number Diff line
@@ -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;

+28 −78
Original line number Diff line number Diff line
@@ -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();
	mode = slot->supported_bus_mode;
	speed = slot->supported_speed; 
	ibmphp_unlock_operations();

	if (hotplug_slot) {
		pslot = hotplug_slot->private;
		if (pslot) {
			rc = 0;
			mode = pslot->supported_bus_mode;
			*value = pslot->supported_speed; 
			switch (*value) {
	switch (speed) {
	case BUS_SPEED_33:
		break;
	case BUS_SPEED_66:
		if (mode == BUS_MODE_PCIX) 
					*value += 0x01;
			speed += 0x01;
		break;
	case BUS_SPEED_100:
	case BUS_SPEED_133:
				*value = pslot->supported_speed + 0x01;
		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);
	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;
				}
			}
		}
	}
	if (!rc)
		bus->max_bus_speed = speed;

	ibmphp_unlock_operations();
	debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
	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,
*/
Loading