Skip to content

Commit

Permalink
arc: Mask individual IRQ lines during core INTC init
Browse files Browse the repository at this point in the history
ARC cores on reset have all interrupt lines of built-in INTC enabled.
Which means once we globally enable interrupts (very early on boot)
faulty hardware blocks may trigger an interrupt that Linux kernel
cannot handle yet as corresponding handler is not yet installed.

In that case system falls in "interrupt storm" and basically never
does anything useful except entering and exiting generic IRQ handling
code.

One real example of that kind of problematic hardware is DW GMAC which
also has interrupts enabled on reset and if Ethernet PHY informs GMAC
about link state, GMAC immediately reports that upstream to ARC core
and here we are.

Now with that change we mask all individual IRQ lines making entire
system more fool-proof.

[This patch was motivated by Adaptrum platform support]

Signed-off-by: Alexey Brodkin <[email protected]>
Cc: Eugeniy Paltsev <[email protected]>
Tested-by: Alexandru Gagniuc <[email protected]>
Signed-off-by: Vineet Gupta <[email protected]>
  • Loading branch information
abrodkin authored and vineetgarc committed Aug 11, 2017
1 parent b5ddb6d commit a8ec3ee
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
3 changes: 3 additions & 0 deletions arch/arc/kernel/intc-arcv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ void arc_init_IRQ(void)
* Set a default priority for all available interrupts to prevent
* switching of register banks if Fast IRQ and multiple register banks
* are supported by CPU.
* Also disable all IRQ lines so faulty external hardware won't
* trigger interrupt that kernel is not ready to handle.
*/
for (i = NR_EXCEPTIONS; i < irq_bcr.irqs + NR_EXCEPTIONS; i++) {
write_aux_reg(AUX_IRQ_SELECT, i);
write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO);
write_aux_reg(AUX_IRQ_ENABLE, 0);
}

/* setup status32, don't enable intr yet as kernel doesn't want */
Expand Down
14 changes: 13 additions & 1 deletion arch/arc/kernel/intc-compact.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
void arc_init_IRQ(void)
{
int level_mask = 0;
int level_mask = 0, i;

/* Is timer high priority Interrupt (Level2 in ARCompact jargon) */
level_mask |= IS_ENABLED(CONFIG_ARC_COMPACT_IRQ_LEVELS) << TIMER0_IRQ;
Expand All @@ -40,6 +40,18 @@ void arc_init_IRQ(void)

if (level_mask)
pr_info("Level-2 interrupts bitset %x\n", level_mask);

/*
* Disable all IRQ lines so faulty external hardware won't
* trigger interrupt that kernel is not ready to handle.
*/
for (i = TIMER0_IRQ; i < NR_CPU_IRQS; i++) {
unsigned int ienb;

ienb = read_aux_reg(AUX_IENABLE);
ienb &= ~(1 << i);
write_aux_reg(AUX_IENABLE, ienb);
}
}

/*
Expand Down

0 comments on commit a8ec3ee

Please sign in to comment.