diff options
Diffstat (limited to 'arch/powerpc/sysdev/xive/common.c')
| -rw-r--r-- | arch/powerpc/sysdev/xive/common.c | 15 | 
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index f5fadbd2533a..9651ca061828 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -972,12 +972,21 @@ static int xive_get_irqchip_state(struct irq_data *data,  				  enum irqchip_irq_state which, bool *state)  {  	struct xive_irq_data *xd = irq_data_get_irq_handler_data(data); +	u8 pq;  	switch (which) {  	case IRQCHIP_STATE_ACTIVE: -		*state = !xd->stale_p && -			 (xd->saved_p || -			  !!(xive_esb_read(xd, XIVE_ESB_GET) & XIVE_ESB_VAL_P)); +		pq = xive_esb_read(xd, XIVE_ESB_GET); + +		/* +		 * The esb value being all 1's means we couldn't get +		 * the PQ state of the interrupt through mmio. It may +		 * happen, for example when querying a PHB interrupt +		 * while the PHB is in an error state. We consider the +		 * interrupt to be inactive in that case. +		 */ +		*state = (pq != XIVE_ESB_INVALID) && !xd->stale_p && +			(xd->saved_p || !!(pq & XIVE_ESB_VAL_P));  		return 0;  	default:  		return -EINVAL;  | 

