| .. | .. | 
|---|
| 69 | 69 |   | 
|---|
| 70 | 70 |  static bool suspend_device_irq(struct irq_desc *desc) | 
|---|
| 71 | 71 |  { | 
|---|
 | 72 | +	unsigned long chipflags = irq_desc_get_chip(desc)->flags;  | 
|---|
 | 73 | +	struct irq_data *irqd = &desc->irq_data;  | 
|---|
 | 74 | +  | 
|---|
| 72 | 75 |  	if (!desc->action || irq_desc_is_chained(desc) || | 
|---|
| 73 | 76 |  	    desc->no_suspend_depth) | 
|---|
| 74 | 77 |  		return false; | 
|---|
| 75 | 78 |   | 
|---|
| 76 |  | -	if (irqd_is_wakeup_set(&desc->irq_data)) {  | 
|---|
| 77 |  | -		irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);  | 
|---|
 | 79 | +	if (irqd_is_wakeup_set(irqd)) {  | 
|---|
 | 80 | +		irqd_set(irqd, IRQD_WAKEUP_ARMED);  | 
|---|
 | 81 | +  | 
|---|
 | 82 | +		if ((chipflags & IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND) &&  | 
|---|
 | 83 | +		     irqd_irq_disabled(irqd)) {  | 
|---|
 | 84 | +			/*  | 
|---|
 | 85 | +			 * Interrupt marked for wakeup is in disabled state.  | 
|---|
 | 86 | +			 * Enable interrupt here to unmask/enable in irqchip  | 
|---|
 | 87 | +			 * to be able to resume with such interrupts.  | 
|---|
 | 88 | +			 */  | 
|---|
 | 89 | +			__enable_irq(desc);  | 
|---|
 | 90 | +			irqd_set(irqd, IRQD_IRQ_ENABLED_ON_SUSPEND);  | 
|---|
 | 91 | +		}  | 
|---|
| 78 | 92 |  		/* | 
|---|
| 79 | 93 |  		 * We return true here to force the caller to issue | 
|---|
| 80 | 94 |  		 * synchronize_irq(). We need to make sure that the | 
|---|
| .. | .. | 
|---|
| 93 | 107 |  	 * chip level. The chip implementation indicates that with | 
|---|
| 94 | 108 |  	 * IRQCHIP_MASK_ON_SUSPEND. | 
|---|
| 95 | 109 |  	 */ | 
|---|
| 96 |  | -	if (irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)  | 
|---|
 | 110 | +	if (chipflags & IRQCHIP_MASK_ON_SUSPEND)  | 
|---|
| 97 | 111 |  		mask_irq(desc); | 
|---|
| 98 | 112 |  	return true; | 
|---|
| 99 | 113 |  } | 
|---|
| .. | .. | 
|---|
| 137 | 151 |   | 
|---|
| 138 | 152 |  static void resume_irq(struct irq_desc *desc) | 
|---|
| 139 | 153 |  { | 
|---|
| 140 |  | -	irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED);  | 
|---|
 | 154 | +	struct irq_data *irqd = &desc->irq_data;  | 
|---|
 | 155 | +  | 
|---|
 | 156 | +	irqd_clear(irqd, IRQD_WAKEUP_ARMED);  | 
|---|
 | 157 | +  | 
|---|
 | 158 | +	if (irqd_is_enabled_on_suspend(irqd)) {  | 
|---|
 | 159 | +		/*  | 
|---|
 | 160 | +		 * Interrupt marked for wakeup was enabled during suspend  | 
|---|
 | 161 | +		 * entry. Disable such interrupts to restore them back to  | 
|---|
 | 162 | +		 * original state.  | 
|---|
 | 163 | +		 */  | 
|---|
 | 164 | +		__disable_irq(desc);  | 
|---|
 | 165 | +		irqd_clear(irqd, IRQD_IRQ_ENABLED_ON_SUSPEND);  | 
|---|
 | 166 | +	}  | 
|---|
| 141 | 167 |   | 
|---|
| 142 | 168 |  	if (desc->istate & IRQS_SUSPENDED) | 
|---|
| 143 | 169 |  		goto resume; | 
|---|
| .. | .. | 
|---|
| 177 | 203 |  } | 
|---|
| 178 | 204 |   | 
|---|
| 179 | 205 |  /** | 
|---|
 | 206 | + * rearm_wake_irq - rearm a wakeup interrupt line after signaling wakeup  | 
|---|
 | 207 | + * @irq: Interrupt to rearm  | 
|---|
 | 208 | + */  | 
|---|
 | 209 | +void rearm_wake_irq(unsigned int irq)  | 
|---|
 | 210 | +{  | 
|---|
 | 211 | +	unsigned long flags;  | 
|---|
 | 212 | +	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);  | 
|---|
 | 213 | +  | 
|---|
 | 214 | +	if (!desc)  | 
|---|
 | 215 | +		return;  | 
|---|
 | 216 | +  | 
|---|
 | 217 | +	if (!(desc->istate & IRQS_SUSPENDED) ||  | 
|---|
 | 218 | +	    !irqd_is_wakeup_set(&desc->irq_data))  | 
|---|
 | 219 | +		goto unlock;  | 
|---|
 | 220 | +  | 
|---|
 | 221 | +	desc->istate &= ~IRQS_SUSPENDED;  | 
|---|
 | 222 | +	irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);  | 
|---|
 | 223 | +	__enable_irq(desc);  | 
|---|
 | 224 | +  | 
|---|
 | 225 | +unlock:  | 
|---|
 | 226 | +	irq_put_desc_busunlock(desc, flags);  | 
|---|
 | 227 | +}  | 
|---|
 | 228 | +  | 
|---|
 | 229 | +/**  | 
|---|
| 180 | 230 |   * irq_pm_syscore_ops - enable interrupt lines early | 
|---|
| 181 | 231 |   * | 
|---|
| 182 | 232 |   * Enable all interrupt lines with %IRQF_EARLY_RESUME set. | 
|---|