Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8720d27d authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by Jesse Barnes
Browse files

PCI: pciehp: remove slot_list field



Since PCIe downstream port has only one slot at most, we don't need
'slot_list' linked list to manage multiple slots under the port.

Acked-by: default avatarAlex Chiang <achiang@hp.com>
Signed-off-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent e2d4304b
Loading
Loading
Loading
Loading
+1 −15
Original line number Diff line number Diff line
@@ -80,7 +80,6 @@ struct slot {
	struct controller *ctrl;
	struct hpc_ops *hpc_ops;
	struct hotplug_slot *hotplug_slot;
	struct list_head	slot_list;
	struct delayed_work work;	/* work for button event */
	struct mutex lock;
};
@@ -98,7 +97,7 @@ struct controller {
	int slot_num_inc;		/* 1 or -1 */
	struct pci_dev *pci_dev;
	struct pcie_device *pcie;	/* PCI Express port service */
	struct list_head slot_list;
	struct slot *slot;
	struct hpc_ops *hpc_ops;
	wait_queue_head_t queue;	/* sleep & wake process */
	u8 slot_device_offset;
@@ -181,19 +180,6 @@ static inline const char *slot_name(struct slot *slot)
	return hotplug_slot_name(slot->hotplug_slot);
}

static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
{
	struct slot *slot;

	list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
		if (slot->device == device)
			return slot;
	}

	ctrl_err(ctrl, "Slot (device=0x%02x) not found\n", device);
	return NULL;
}

struct hpc_ops {
	int (*power_on_slot)(struct slot *slot);
	int (*power_off_slot)(struct slot *slot);
+11 −6
Original line number Diff line number Diff line
@@ -33,6 +33,11 @@
#define PCIEHP_DETECT_AUTO	(2)
#define PCIEHP_DETECT_DEFAULT	PCIEHP_DETECT_AUTO

struct dummy_slot {
	u32 number;
	struct list_head list;
};

static int slot_detection_mode;
static char *pciehp_detect_mode;
module_param(pciehp_detect_mode, charp, 0444);
@@ -77,7 +82,7 @@ static int __init dummy_probe(struct pcie_device *dev)
	int pos;
	u32 slot_cap;
	acpi_handle handle;
	struct slot *slot, *tmp;
	struct dummy_slot *slot, *tmp;
	struct pci_dev *pdev = dev->port;
	/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
	if (pciehp_get_hp_hw_control_from_firmware(pdev))
@@ -89,11 +94,11 @@ static int __init dummy_probe(struct pcie_device *dev)
	if (!slot)
		return -ENOMEM;
	slot->number = slot_cap >> 19;
	list_for_each_entry(tmp, &dummy_slots, slot_list) {
	list_for_each_entry(tmp, &dummy_slots, list) {
		if (tmp->number == slot->number)
			dup_slot_id++;
	}
	list_add_tail(&slot->slot_list, &dummy_slots);
	list_add_tail(&slot->list, &dummy_slots);
	handle = DEVICE_ACPI_HANDLE(&pdev->dev);
	if (!acpi_slot_detected && acpi_pci_detect_ejectable(handle))
		acpi_slot_detected = 1;
@@ -109,11 +114,11 @@ static struct pcie_port_service_driver __initdata dummy_driver = {

static int __init select_detection_mode(void)
{
	struct slot *slot, *tmp;
	struct dummy_slot *slot, *tmp;
	pcie_port_service_register(&dummy_driver);
	pcie_port_service_unregister(&dummy_driver);
	list_for_each_entry_safe(slot, tmp, &dummy_slots, slot_list) {
		list_del(&slot->slot_list);
	list_for_each_entry_safe(slot, tmp, &dummy_slots, list) {
		list_del(&slot->list);
		kfree(slot);
	}
	if (acpi_slot_detected && dup_slot_id)
+57 −63
Original line number Diff line number Diff line
@@ -99,29 +99,28 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
	kfree(hotplug_slot);
}

static int init_slots(struct controller *ctrl)
static int init_slot(struct controller *ctrl)
{
	struct slot *slot;
	struct hotplug_slot *hotplug_slot;
	struct hotplug_slot_info *info;
	struct slot *slot = ctrl->slot;
	struct hotplug_slot *hotplug = NULL;
	struct hotplug_slot_info *info = NULL;
	char name[SLOT_NAME_SIZE];
	int retval = -ENOMEM;

	list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
		hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
		if (!hotplug_slot)
			goto error;
	hotplug = kzalloc(sizeof(*hotplug), GFP_KERNEL);
	if (!hotplug)
		goto out;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
			goto error_hpslot;
		goto out;

	/* register this slot with the hotplug pci core */
		hotplug_slot->info = info;
		hotplug_slot->private = slot;
		hotplug_slot->release = &release_slot;
		hotplug_slot->ops = &pciehp_hotplug_slot_ops;
		slot->hotplug_slot = hotplug_slot;
	hotplug->info = info;
	hotplug->private = slot;
	hotplug->release = &release_slot;
	hotplug->ops = &pciehp_hotplug_slot_ops;
	slot->hotplug_slot = hotplug;
	snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);

	ctrl_dbg(ctrl, "Registering domain:bus:dev=%04x:%02x:%02x "
@@ -129,35 +128,30 @@ static int init_slots(struct controller *ctrl)
		 pci_domain_nr(ctrl->pci_dev->subordinate),
		 slot->bus, slot->device, slot->hp_slot, slot->number,
		 ctrl->slot_device_offset);
		retval = pci_hp_register(hotplug_slot,
	retval = pci_hp_register(hotplug,
				 ctrl->pci_dev->subordinate,
				 slot->device,
				 name);
	if (retval) {
			ctrl_err(ctrl, "pci_hp_register failed with error %d\n",
				 retval);
			goto error_info;
		}
		get_power_status(hotplug_slot, &info->power_status);
		get_attention_status(hotplug_slot, &info->attention_status);
		get_latch_status(hotplug_slot, &info->latch_status);
		get_adapter_status(hotplug_slot, &info->adapter_status);
		ctrl_err(ctrl,
			 "pci_hp_register failed with error %d\n", retval);
		goto out;
	}

	return 0;
error_info:
	get_power_status(hotplug, &info->power_status);
	get_attention_status(hotplug, &info->attention_status);
	get_latch_status(hotplug, &info->latch_status);
	get_adapter_status(hotplug, &info->adapter_status);
out:
	if (retval) {
		kfree(info);
error_hpslot:
	kfree(hotplug_slot);
error:
		kfree(hotplug);
	}
	return retval;
}

static void cleanup_slots(struct controller *ctrl)
static void cleanup_slot(struct controller *ctrl)
{
	struct slot *slot;
	list_for_each_entry(slot, &ctrl->slot_list, slot_list)
		pci_hp_deregister(slot->hotplug_slot);
	pci_hp_deregister(ctrl->slot->hotplug_slot);
}

/*
@@ -295,7 +289,7 @@ static int pciehp_probe(struct pcie_device *dev)
{
	int rc;
	struct controller *ctrl;
	struct slot *t_slot;
	struct slot *slot;
	u8 value;
	struct pci_dev *pdev = dev->port;

@@ -314,7 +308,7 @@ static int pciehp_probe(struct pcie_device *dev)
	set_service_data(dev, ctrl);

	/* Setup the slot information structures */
	rc = init_slots(ctrl);
	rc = init_slot(ctrl);
	if (rc) {
		if (rc == -EBUSY)
			ctrl_warn(ctrl, "Slot already registered by another "
@@ -332,15 +326,15 @@ static int pciehp_probe(struct pcie_device *dev)
	}

	/* Check if slot is occupied */
	t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
	t_slot->hpc_ops->get_adapter_status(t_slot, &value);
	slot = ctrl->slot;
	slot->hpc_ops->get_adapter_status(slot, &value);
	if (value) {
		if (pciehp_force)
			pciehp_enable_slot(t_slot);
			pciehp_enable_slot(slot);
	} else {
		/* Power off slot if not occupied */
		if (POWER_CTRL(ctrl)) {
			rc = t_slot->hpc_ops->power_off_slot(t_slot);
			rc = slot->hpc_ops->power_off_slot(slot);
			if (rc)
				goto err_out_free_ctrl_slot;
		}
@@ -349,7 +343,7 @@ static int pciehp_probe(struct pcie_device *dev)
	return 0;

err_out_free_ctrl_slot:
	cleanup_slots(ctrl);
	cleanup_slot(ctrl);
err_out_release_ctlr:
	ctrl->hpc_ops->release_ctlr(ctrl);
err_out_none:
@@ -360,7 +354,7 @@ static void pciehp_remove (struct pcie_device *dev)
{
	struct controller *ctrl = get_service_data(dev);

	cleanup_slots(ctrl);
	cleanup_slot(ctrl);
	ctrl->hpc_ops->release_ctlr(ctrl);
}

@@ -376,20 +370,20 @@ static int pciehp_resume (struct pcie_device *dev)
	dev_info(&dev->device, "%s ENTRY\n", __func__);
	if (pciehp_force) {
		struct controller *ctrl = get_service_data(dev);
		struct slot *t_slot;
		struct slot *slot;
		u8 status;

		/* reinitialize the chipset's event detection logic */
		pcie_enable_notification(ctrl);

		t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
		slot = ctrl->slot;

		/* Check if slot is occupied */
		t_slot->hpc_ops->get_adapter_status(t_slot, &status);
		slot->hpc_ops->get_adapter_status(slot, &status);
		if (status)
			pciehp_enable_slot(t_slot);
			pciehp_enable_slot(slot);
		else
			pciehp_disable_slot(t_slot);
			pciehp_disable_slot(slot);
	}
	return 0;
}
+7 −13
Original line number Diff line number Diff line
@@ -614,8 +614,8 @@ static int hpc_power_off_slot(struct slot * slot)
static irqreturn_t pcie_isr(int irq, void *dev_id)
{
	struct controller *ctrl = (struct controller *)dev_id;
	struct slot *slot = ctrl->slot;
	u16 detected, intr_loc;
	struct slot *p_slot;

	/*
	 * In order to guarantee that all interrupt events are
@@ -656,24 +656,22 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
	if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
		return IRQ_HANDLED;

	p_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);

	/* Check MRL Sensor Changed */
	if (intr_loc & PCI_EXP_SLTSTA_MRLSC)
		pciehp_handle_switch_change(p_slot);
		pciehp_handle_switch_change(slot);

	/* Check Attention Button Pressed */
	if (intr_loc & PCI_EXP_SLTSTA_ABP)
		pciehp_handle_attention_button(p_slot);
		pciehp_handle_attention_button(slot);

	/* Check Presence Detect Changed */
	if (intr_loc & PCI_EXP_SLTSTA_PDC)
		pciehp_handle_presence_change(p_slot);
		pciehp_handle_presence_change(slot);

	/* Check Power Fault Detected */
	if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
		ctrl->power_fault_detected = 1;
		pciehp_handle_power_fault(p_slot);
		pciehp_handle_power_fault(slot);
	}
	return IRQ_HANDLED;
}
@@ -938,15 +936,13 @@ static int pcie_init_slot(struct controller *ctrl)
	slot->number = ctrl->first_slot;
	mutex_init(&slot->lock);
	INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
	list_add(&slot->slot_list, &ctrl->slot_list);
	ctrl->slot = slot;
	return 0;
}

static void pcie_cleanup_slot(struct controller *ctrl)
{
	struct slot *slot;
	slot = list_first_entry(&ctrl->slot_list, struct slot, slot_list);
	list_del(&slot->slot_list);
	struct slot *slot = ctrl->slot;
	cancel_delayed_work(&slot->work);
	flush_scheduled_work();
	flush_workqueue(pciehp_wq);
@@ -1014,8 +1010,6 @@ struct controller *pcie_init(struct pcie_device *dev)
		dev_err(&dev->device, "%s: Out of memory\n", __func__);
		goto abort;
	}
	INIT_LIST_HEAD(&ctrl->slot_list);

	ctrl->pcie = dev;
	ctrl->pci_dev = pdev;
	ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);