| .. | .. | 
|---|
| 29 | 29 |   * IRQTF_WARNED    - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed | 
|---|
| 30 | 30 |   * IRQTF_AFFINITY  - irq thread is requested to adjust affinity | 
|---|
| 31 | 31 |   * IRQTF_FORCED_THREAD  - irq action is force threaded | 
|---|
 | 32 | + * IRQTF_READY     - signals that irq thread is ready  | 
|---|
| 32 | 33 |   */ | 
|---|
| 33 | 34 |  enum { | 
|---|
| 34 | 35 |  	IRQTF_RUNTHREAD, | 
|---|
| 35 | 36 |  	IRQTF_WARNED, | 
|---|
| 36 | 37 |  	IRQTF_AFFINITY, | 
|---|
| 37 | 38 |  	IRQTF_FORCED_THREAD, | 
|---|
 | 39 | +	IRQTF_READY,  | 
|---|
| 38 | 40 |  }; | 
|---|
| 39 | 41 |   | 
|---|
| 40 | 42 |  /* | 
|---|
| .. | .. | 
|---|
| 49 | 51 |   * IRQS_WAITING			- irq is waiting | 
|---|
| 50 | 52 |   * IRQS_PENDING			- irq is pending and replayed later | 
|---|
| 51 | 53 |   * IRQS_SUSPENDED		- irq is suspended | 
|---|
 | 54 | + * IRQS_NMI			- irq line is used to deliver NMIs  | 
|---|
| 52 | 55 |   */ | 
|---|
| 53 | 56 |  enum { | 
|---|
| 54 | 57 |  	IRQS_AUTODETECT		= 0x00000001, | 
|---|
| .. | .. | 
|---|
| 60 | 63 |  	IRQS_PENDING		= 0x00000200, | 
|---|
| 61 | 64 |  	IRQS_SUSPENDED		= 0x00000800, | 
|---|
| 62 | 65 |  	IRQS_TIMINGS		= 0x00001000, | 
|---|
 | 66 | +	IRQS_NMI		= 0x00002000,  | 
|---|
| 63 | 67 |  }; | 
|---|
| 64 | 68 |   | 
|---|
| 65 | 69 |  #include "debug.h" | 
|---|
| .. | .. | 
|---|
| 106 | 110 |  irqreturn_t handle_irq_event(struct irq_desc *desc); | 
|---|
| 107 | 111 |   | 
|---|
| 108 | 112 |  /* Resending of interrupts :*/ | 
|---|
| 109 |  | -void check_irq_resend(struct irq_desc *desc);  | 
|---|
 | 113 | +int check_irq_resend(struct irq_desc *desc, bool inject);  | 
|---|
| 110 | 114 |  bool irq_wait_for_poll(struct irq_desc *desc); | 
|---|
| 111 | 115 |  void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action); | 
|---|
| 112 | 116 |   | 
|---|
| .. | .. | 
|---|
| 355 | 359 |  	return value & U16_MAX; | 
|---|
| 356 | 360 |  } | 
|---|
| 357 | 361 |   | 
|---|
 | 362 | +static __always_inline void irq_timings_push(u64 ts, int irq)  | 
|---|
 | 363 | +{  | 
|---|
 | 364 | +	struct irq_timings *timings = this_cpu_ptr(&irq_timings);  | 
|---|
 | 365 | +  | 
|---|
 | 366 | +	timings->values[timings->count & IRQ_TIMINGS_MASK] =  | 
|---|
 | 367 | +		irq_timing_encode(ts, irq);  | 
|---|
 | 368 | +  | 
|---|
 | 369 | +	timings->count++;  | 
|---|
 | 370 | +}  | 
|---|
 | 371 | +  | 
|---|
| 358 | 372 |  /* | 
|---|
| 359 | 373 |   * The function record_irq_time is only called in one place in the | 
|---|
| 360 | 374 |   * interrupts handler. We want this function always inline so the code | 
|---|
| .. | .. | 
|---|
| 368 | 382 |  	if (!static_branch_likely(&irq_timing_enabled)) | 
|---|
| 369 | 383 |  		return; | 
|---|
| 370 | 384 |   | 
|---|
| 371 |  | -	if (desc->istate & IRQS_TIMINGS) {  | 
|---|
| 372 |  | -		struct irq_timings *timings = this_cpu_ptr(&irq_timings);  | 
|---|
| 373 |  | -  | 
|---|
| 374 |  | -		timings->values[timings->count & IRQ_TIMINGS_MASK] =  | 
|---|
| 375 |  | -			irq_timing_encode(local_clock(),  | 
|---|
| 376 |  | -					  irq_desc_get_irq(desc));  | 
|---|
| 377 |  | -  | 
|---|
| 378 |  | -		timings->count++;  | 
|---|
| 379 |  | -	}  | 
|---|
 | 385 | +	if (desc->istate & IRQS_TIMINGS)  | 
|---|
 | 386 | +		irq_timings_push(local_clock(), irq_desc_get_irq(desc));  | 
|---|
| 380 | 387 |  } | 
|---|
| 381 | 388 |  #else | 
|---|
| 382 | 389 |  static inline void irq_remove_timings(struct irq_desc *desc) {} | 
|---|
| .. | .. | 
|---|
| 420 | 427 |  { | 
|---|
| 421 | 428 |  	return desc->pending_mask; | 
|---|
| 422 | 429 |  } | 
|---|
 | 430 | +static inline bool handle_enforce_irqctx(struct irq_data *data)  | 
|---|
 | 431 | +{  | 
|---|
 | 432 | +	return irqd_is_handle_enforce_irqctx(data);  | 
|---|
 | 433 | +}  | 
|---|
| 423 | 434 |  bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear); | 
|---|
| 424 | 435 |  #else /* CONFIG_GENERIC_PENDING_IRQ */ | 
|---|
| 425 | 436 |  static inline bool irq_can_move_pcntxt(struct irq_data *data) | 
|---|
| .. | .. | 
|---|
| 446 | 457 |  { | 
|---|
| 447 | 458 |  	return false; | 
|---|
| 448 | 459 |  } | 
|---|
 | 460 | +static inline bool handle_enforce_irqctx(struct irq_data *data)  | 
|---|
 | 461 | +{  | 
|---|
 | 462 | +	return false;  | 
|---|
 | 463 | +}  | 
|---|
| 449 | 464 |  #endif /* !CONFIG_GENERIC_PENDING_IRQ */ | 
|---|
| 450 | 465 |   | 
|---|
| 451 | 466 |  #if !defined(CONFIG_IRQ_DOMAIN) || !defined(CONFIG_IRQ_DOMAIN_HIERARCHY) | 
|---|
| .. | .. | 
|---|
| 460 | 475 |  } | 
|---|
| 461 | 476 |  #endif | 
|---|
| 462 | 477 |   | 
|---|
 | 478 | +static inline struct irq_data *irqd_get_parent_data(struct irq_data *irqd)  | 
|---|
 | 479 | +{  | 
|---|
 | 480 | +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY  | 
|---|
 | 481 | +	return irqd->parent_data;  | 
|---|
 | 482 | +#else  | 
|---|
 | 483 | +	return NULL;  | 
|---|
 | 484 | +#endif  | 
|---|
 | 485 | +}  | 
|---|
 | 486 | +  | 
|---|
| 463 | 487 |  #ifdef CONFIG_GENERIC_IRQ_DEBUGFS | 
|---|
| 464 | 488 |  #include <linux/debugfs.h> | 
|---|
| 465 | 489 |   | 
|---|