aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffy Chen <jeffy.chen@rock-chips.com>2017-06-26 07:33:34 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-06-26 09:47:00 -0400
commitbf22ff45bed664aefb5c4e43029057a199b7070c (patch)
tree2cb9598c3f09a473df3b4bfc6290e4575b4fcdab
parentd829b8fb2431595422289cfc210f0a955a8bec74 (diff)
genirq: Avoid unnecessary low level irq function calls
Check irq state in enable/disable/unmask/mask_irq to avoid unnecessary low level irq function calls. This has two advantages: - Conditionals are faster than hardware access - Solves issues with the underlying refcounting of the pinctrl infrastructure Suggested-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: tfiga@chromium.org Cc: briannorris@chromium.org Cc: dianders@chromium.org Link: http://lkml.kernel.org/r/1498476814-12563-2-git-send-email-jeffy.chen@rock-chips.com
-rw-r--r--kernel/irq/chip.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index fc89eeb8a6b4..2e30d925a40d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -314,22 +314,32 @@ void irq_shutdown(struct irq_desc *desc)
314 314
315void irq_enable(struct irq_desc *desc) 315void irq_enable(struct irq_desc *desc)
316{ 316{
317 irq_state_clr_disabled(desc); 317 if (!irqd_irq_disabled(&desc->irq_data)) {
318 if (desc->irq_data.chip->irq_enable) 318 unmask_irq(desc);
319 desc->irq_data.chip->irq_enable(&desc->irq_data); 319 } else {
320 else 320 irq_state_clr_disabled(desc);
321 desc->irq_data.chip->irq_unmask(&desc->irq_data); 321 if (desc->irq_data.chip->irq_enable) {
322 irq_state_clr_masked(desc); 322 desc->irq_data.chip->irq_enable(&desc->irq_data);
323 irq_state_clr_masked(desc);
324 } else {
325 unmask_irq(desc);
326 }
327 }
323} 328}
324 329
325static void __irq_disable(struct irq_desc *desc, bool mask) 330static void __irq_disable(struct irq_desc *desc, bool mask)
326{ 331{
327 irq_state_set_disabled(desc); 332 if (irqd_irq_disabled(&desc->irq_data)) {
328 if (desc->irq_data.chip->irq_disable) { 333 if (mask)
329 desc->irq_data.chip->irq_disable(&desc->irq_data); 334 mask_irq(desc);
330 irq_state_set_masked(desc); 335 } else {
331 } else if (mask) { 336 irq_state_set_disabled(desc);
332 mask_irq(desc); 337 if (desc->irq_data.chip->irq_disable) {
338 desc->irq_data.chip->irq_disable(&desc->irq_data);
339 irq_state_set_masked(desc);
340 } else if (mask) {
341 mask_irq(desc);
342 }
333 } 343 }
334} 344}
335 345
@@ -378,18 +388,21 @@ void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
378 388
379static inline void mask_ack_irq(struct irq_desc *desc) 389static inline void mask_ack_irq(struct irq_desc *desc)
380{ 390{
381 if (desc->irq_data.chip->irq_mask_ack) 391 if (desc->irq_data.chip->irq_mask_ack) {
382 desc->irq_data.chip->irq_mask_ack(&desc->irq_data); 392 desc->irq_data.chip->irq_mask_ack(&desc->irq_data);
383 else { 393 irq_state_set_masked(desc);
384 desc->irq_data.chip->irq_mask(&desc->irq_data); 394 } else {
395 mask_irq(desc);
385 if (desc->irq_data.chip->irq_ack) 396 if (desc->irq_data.chip->irq_ack)
386 desc->irq_data.chip->irq_ack(&desc->irq_data); 397 desc->irq_data.chip->irq_ack(&desc->irq_data);
387 } 398 }
388 irq_state_set_masked(desc);
389} 399}
390 400
391void mask_irq(struct irq_desc *desc) 401void mask_irq(struct irq_desc *desc)
392{ 402{
403 if (irqd_irq_masked(&desc->irq_data))
404 return;
405
393 if (desc->irq_data.chip->irq_mask) { 406 if (desc->irq_data.chip->irq_mask) {
394 desc->irq_data.chip->irq_mask(&desc->irq_data); 407 desc->irq_data.chip->irq_mask(&desc->irq_data);
395 irq_state_set_masked(desc); 408 irq_state_set_masked(desc);
@@ -398,6 +411,9 @@ void mask_irq(struct irq_desc *desc)
398 411
399void unmask_irq(struct irq_desc *desc) 412void unmask_irq(struct irq_desc *desc)
400{ 413{
414 if (!irqd_irq_masked(&desc->irq_data))
415 return;
416
401 if (desc->irq_data.chip->irq_unmask) { 417 if (desc->irq_data.chip->irq_unmask) {
402 desc->irq_data.chip->irq_unmask(&desc->irq_data); 418 desc->irq_data.chip->irq_unmask(&desc->irq_data);
403 irq_state_clr_masked(desc); 419 irq_state_clr_masked(desc);
@@ -411,10 +427,7 @@ void unmask_threaded_irq(struct irq_desc *desc)
411 if (chip->flags & IRQCHIP_EOI_THREADED) 427 if (chip->flags & IRQCHIP_EOI_THREADED)
412 chip->irq_eoi(&desc->irq_data); 428 chip->irq_eoi(&desc->irq_data);
413 429
414 if (chip->irq_unmask) { 430 unmask_irq(desc);
415 chip->irq_unmask(&desc->irq_data);
416 irq_state_clr_masked(desc);
417 }
418} 431}
419 432
420/* 433/*