Subject: Re: [PATCH v2 5/5] drivers/pci/hotplug: Support surprise hotplug in powernv driver

From: Gavin Shan <[email-masked]>
Date: Wed, 28 Sep 2016 14:33:40 +1000

On Mon, Sep 26, 2016 at 10:56:07PM +1000, Gavin Shan wrote:
>This supports PCI surprise hotplug. The design is highlighted as
>below:
>
>   * The PCI slot's surprise hotplug capability is exposed through
>     device node property "ibm,slot-surprise-pluggable", meaning
>     PCI surprise hotplug will be disabled if skiboot doesn't support
>     it yet.
>   * The interrupt because of presence or link state change is raised
>     on surprise hotplug event. One event is allocated and queued to
>     the PCI slot for workqueue to pick it up and process in serialized
>     fashion. The code flow for surprise hotplug is same to that for
>     managed hotplug except: the affected PEs are put into frozen state
>     to avoid unexpected EEH error reporting in surprise hot remove path.
>
>Signed-off-by: Gavin Shan <[email-masked]>
>---

.../...

>+static irqreturn_t pnv_php_interrupt(int irq, void *data)
>+{
>+	struct pnv_php_slot *php_slot = data;
>+	struct pci_dev *pchild, *pdev = php_slot->pdev;
>+	struct eeh_dev *edev;
>+	struct eeh_pe *pe;
>+	struct pnv_php_event *event;
>+	u16 sts, lsts;
>+	u8 presence;
>+	bool added;
>+	unsigned long flags;
>+	int ret;
>+
>+	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
>+	sts &= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
>+	pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
>+	if (sts & PCI_EXP_SLTSTA_DLLSC) {
>+		pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lsts);
>+		added = !!(lsts & PCI_EXP_LNKSTA_DLLLA);
>+	} else if (sts & PCI_EXP_SLTSTA_PDC) {
>+		ret = pnv_pci_get_presence_state(php_slot->id, &presence);
>+		if (!ret)
>+			return IRQ_HANDLED;
>+		added = !!(presence == OPAL_PCI_SLOT_PRESENT);
>+	} else {
>+		return IRQ_NONE;
>+	}
>+
>+	/* Freeze the removed PE to avoid unexpected error reporting */
>+	if (!added) {
>+		pchild = list_first_entry_or_null(&php_slot->bus->devices,
>+						  struct pci_dev, bus_list);
>+		edev = pchild ? pci_dev_to_eeh_dev(pchild) : NULL;
>+		pe = edev ? edev->pe : NULL;
>+		if (pe) {
>+			eeh_serialize_lock(&flags);
>+			eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
>+			eeh_serialize_unlock(flags);
>+			eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE);
>+		}
>+	}
>+

I still need export @confirm_error_lock. Otherwise, it will be failed to be
built when having CONFIG_HOTPLUG_PCI_POWERNV=m. I will respin and add one
patch for that in v3.

Thanks,
Gavin