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 <gws...@linux.vnet.ibm.com> >---
.../... >+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