Skip to content

Commit bf22ff4

Browse files
JeffyCNKAGA-KOKO
authored andcommitted
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
1 parent d829b8f commit bf22ff4

File tree

1 file changed

+33
-20
lines changed

1 file changed

+33
-20
lines changed

kernel/irq/chip.c

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -314,22 +314,32 @@ void irq_shutdown(struct irq_desc *desc)
314314

315315
void irq_enable(struct irq_desc *desc)
316316
{
317-
irq_state_clr_disabled(desc);
318-
if (desc->irq_data.chip->irq_enable)
319-
desc->irq_data.chip->irq_enable(&desc->irq_data);
320-
else
321-
desc->irq_data.chip->irq_unmask(&desc->irq_data);
322-
irq_state_clr_masked(desc);
317+
if (!irqd_irq_disabled(&desc->irq_data)) {
318+
unmask_irq(desc);
319+
} else {
320+
irq_state_clr_disabled(desc);
321+
if (desc->irq_data.chip->irq_enable) {
322+
desc->irq_data.chip->irq_enable(&desc->irq_data);
323+
irq_state_clr_masked(desc);
324+
} else {
325+
unmask_irq(desc);
326+
}
327+
}
323328
}
324329

325330
static void __irq_disable(struct irq_desc *desc, bool mask)
326331
{
327-
irq_state_set_disabled(desc);
328-
if (desc->irq_data.chip->irq_disable) {
329-
desc->irq_data.chip->irq_disable(&desc->irq_data);
330-
irq_state_set_masked(desc);
331-
} else if (mask) {
332-
mask_irq(desc);
332+
if (irqd_irq_disabled(&desc->irq_data)) {
333+
if (mask)
334+
mask_irq(desc);
335+
} else {
336+
irq_state_set_disabled(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+
}
333343
}
334344
}
335345

@@ -378,18 +388,21 @@ void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
378388

379389
static inline void mask_ack_irq(struct irq_desc *desc)
380390
{
381-
if (desc->irq_data.chip->irq_mask_ack)
391+
if (desc->irq_data.chip->irq_mask_ack) {
382392
desc->irq_data.chip->irq_mask_ack(&desc->irq_data);
383-
else {
384-
desc->irq_data.chip->irq_mask(&desc->irq_data);
393+
irq_state_set_masked(desc);
394+
} else {
395+
mask_irq(desc);
385396
if (desc->irq_data.chip->irq_ack)
386397
desc->irq_data.chip->irq_ack(&desc->irq_data);
387398
}
388-
irq_state_set_masked(desc);
389399
}
390400

391401
void mask_irq(struct irq_desc *desc)
392402
{
403+
if (irqd_irq_masked(&desc->irq_data))
404+
return;
405+
393406
if (desc->irq_data.chip->irq_mask) {
394407
desc->irq_data.chip->irq_mask(&desc->irq_data);
395408
irq_state_set_masked(desc);
@@ -398,6 +411,9 @@ void mask_irq(struct irq_desc *desc)
398411

399412
void unmask_irq(struct irq_desc *desc)
400413
{
414+
if (!irqd_irq_masked(&desc->irq_data))
415+
return;
416+
401417
if (desc->irq_data.chip->irq_unmask) {
402418
desc->irq_data.chip->irq_unmask(&desc->irq_data);
403419
irq_state_clr_masked(desc);
@@ -411,10 +427,7 @@ void unmask_threaded_irq(struct irq_desc *desc)
411427
if (chip->flags & IRQCHIP_EOI_THREADED)
412428
chip->irq_eoi(&desc->irq_data);
413429

414-
if (chip->irq_unmask) {
415-
chip->irq_unmask(&desc->irq_data);
416-
irq_state_clr_masked(desc);
417-
}
430+
unmask_irq(desc);
418431
}
419432

420433
/*

0 commit comments

Comments
 (0)