ACK: [PATCH Zesty SRU] drivers/pci/hotplug: Mask PDC interrupt if required

Colin Ian King colin.king at canonical.com
Thu Apr 6 12:40:56 UTC 2017


On 06/04/17 13:31, Tim Gardner wrote:
> From: Gavin Shan <gwshan at linux.vnet.ibm.com>
> 
> BugLink: http://bugs.launchpad.net/bugs/1680328
> 
> We're supporting surprise hotplug on PCI slots behind root port
> or PCIe switch downstream ports, which don't claim the capability
> in hardware register (offset: PCIe cap + PCI_EXP_SLTCAP). PEX8718
> is one of the examples. For those PCI slots, the PDC (Presence
> Detection Change) event isn't reliable and the underly (skiboot)
> firmware has best judgement.
> 
> This masks the PDC event when skiboot requests by "ibm,slot-broken-pdc"
> property in PCI slot's device-tree node.
> 
> Reported-by: Hank Chang <hankmax0000 at gmail.com>
> Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
> Tested-by: Willie Liauw <williel at supermicro.com.tw>
> Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
> (cherry picked from commit 454593e54cac126a0f49d4b65f90a5e518c51404)
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
> ---
>  arch/powerpc/include/asm/pnv-pci.h |  2 ++
>  drivers/pci/hotplug/pnv_php.c      | 27 ++++++++++++++++++++++-----
>  2 files changed, 24 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h
> index 696438f..de96810 100644
> --- a/arch/powerpc/include/asm/pnv-pci.h
> +++ b/arch/powerpc/include/asm/pnv-pci.h
> @@ -57,6 +57,8 @@ struct pnv_php_slot {
>  	uint64_t			id;
>  	char				*name;
>  	int				slot_no;
> +	unsigned int			flags;
> +#define PNV_PHP_FLAG_BROKEN_PDC		0x1
>  	struct kref			kref;
>  #define PNV_PHP_STATE_INITIALIZED	0
>  #define PNV_PHP_STATE_REGISTERED	1
> diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
> index e96973b..335a556 100644
> --- a/drivers/pci/hotplug/pnv_php.c
> +++ b/drivers/pci/hotplug/pnv_php.c
> @@ -723,7 +723,8 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
>  	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) {
> +	} else if (!(php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) &&
> +		   (sts & PCI_EXP_SLTSTA_PDC)) {
>  		ret = pnv_pci_get_presence_state(php_slot->id, &presence);
>  		if (ret) {
>  			dev_warn(&pdev->dev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
> @@ -774,6 +775,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
>  static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
>  {
>  	struct pci_dev *pdev = php_slot->pdev;
> +	u32 broken_pdc = 0;
>  	u16 sts, ctrl;
>  	int ret;
>  
> @@ -785,9 +787,18 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
>  		return;
>  	}
>  
> +	/* Check PDC (Presence Detection Change) is broken or not */
> +	ret = of_property_read_u32(php_slot->dn, "ibm,slot-broken-pdc",
> +				   &broken_pdc);
> +	if (!ret && broken_pdc)
> +		php_slot->flags |= PNV_PHP_FLAG_BROKEN_PDC;
> +
>  	/* Clear pending interrupts */
>  	pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
> -	sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
> +	if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC)
> +		sts |= PCI_EXP_SLTSTA_DLLSC;
> +	else
> +		sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
>  	pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
>  
>  	/* Request the interrupt */
> @@ -801,9 +812,15 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
>  
>  	/* Enable the interrupts */
>  	pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl);
> -	ctrl |= (PCI_EXP_SLTCTL_HPIE |
> -		 PCI_EXP_SLTCTL_PDCE |
> -		 PCI_EXP_SLTCTL_DLLSCE);
> +	if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) {
> +		ctrl &= ~PCI_EXP_SLTCTL_PDCE;
> +		ctrl |= (PCI_EXP_SLTCTL_HPIE |
> +			 PCI_EXP_SLTCTL_DLLSCE);
> +	} else {
> +		ctrl |= (PCI_EXP_SLTCTL_HPIE |
> +			 PCI_EXP_SLTCTL_PDCE |
> +			 PCI_EXP_SLTCTL_DLLSCE);
> +	}
>  	pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl);
>  
>  	/* The interrupt is initialized successfully when @irq is valid */
> 

Clean upstream cherry pick.  Looks sane to me.

Acked-by: Colin Ian King <colin.king at canonical.com>




More information about the kernel-team mailing list