-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch adds the support for IRQ handling. Signed-off-by: Ley Foon Tan <lftan@altera.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
- Loading branch information
Ley Foon Tan
committed
Dec 8, 2014
1 parent
c983e92
commit f27ffc7
Showing
3 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (C) 2013 Altera Corporation | ||
* Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
#ifndef _ASM_NIOS2_IRQ_H | ||
#define _ASM_NIOS2_IRQ_H | ||
|
||
#define NIOS2_CPU_NR_IRQS 32 | ||
|
||
#include <asm-generic/irq.h> | ||
#include <linux/irqdomain.h> | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
#ifndef _ASM_IRQFLAGS_H | ||
#define _ASM_IRQFLAGS_H | ||
|
||
#include <asm/registers.h> | ||
|
||
static inline unsigned long arch_local_save_flags(void) | ||
{ | ||
return RDCTL(CTL_STATUS); | ||
} | ||
|
||
/* | ||
* This will restore ALL status register flags, not only the interrupt | ||
* mask flag. | ||
*/ | ||
static inline void arch_local_irq_restore(unsigned long flags) | ||
{ | ||
WRCTL(CTL_STATUS, flags); | ||
} | ||
|
||
static inline void arch_local_irq_disable(void) | ||
{ | ||
unsigned long flags; | ||
|
||
flags = arch_local_save_flags(); | ||
arch_local_irq_restore(flags & ~STATUS_PIE); | ||
} | ||
|
||
static inline void arch_local_irq_enable(void) | ||
{ | ||
unsigned long flags; | ||
|
||
flags = arch_local_save_flags(); | ||
arch_local_irq_restore(flags | STATUS_PIE); | ||
} | ||
|
||
static inline int arch_irqs_disabled_flags(unsigned long flags) | ||
{ | ||
return (flags & STATUS_PIE) == 0; | ||
} | ||
|
||
static inline int arch_irqs_disabled(void) | ||
{ | ||
return arch_irqs_disabled_flags(arch_local_save_flags()); | ||
} | ||
|
||
static inline unsigned long arch_local_irq_save(void) | ||
{ | ||
unsigned long flags; | ||
|
||
flags = arch_local_save_flags(); | ||
arch_local_irq_restore(flags & ~STATUS_PIE); | ||
return flags; | ||
} | ||
|
||
#endif /* _ASM_IRQFLAGS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright (C) 2013 Altera Corporation | ||
* Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> | ||
* Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw> | ||
* | ||
* based on irq.c from m68k which is: | ||
* | ||
* Copyright (C) 2007 Greg Ungerer <gerg@snapgear.com> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
#include <linux/init.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/of.h> | ||
|
||
static u32 ienable; | ||
|
||
asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) | ||
{ | ||
struct pt_regs *oldregs = set_irq_regs(regs); | ||
int irq; | ||
|
||
irq_enter(); | ||
irq = irq_find_mapping(NULL, hwirq); | ||
generic_handle_irq(irq); | ||
irq_exit(); | ||
|
||
set_irq_regs(oldregs); | ||
} | ||
|
||
static void chip_unmask(struct irq_data *d) | ||
{ | ||
ienable |= (1 << d->hwirq); | ||
WRCTL(CTL_IENABLE, ienable); | ||
} | ||
|
||
static void chip_mask(struct irq_data *d) | ||
{ | ||
ienable &= ~(1 << d->hwirq); | ||
WRCTL(CTL_IENABLE, ienable); | ||
} | ||
|
||
static struct irq_chip m_irq_chip = { | ||
.name = "NIOS2-INTC", | ||
.irq_unmask = chip_unmask, | ||
.irq_mask = chip_mask, | ||
}; | ||
|
||
static int irq_map(struct irq_domain *h, unsigned int virq, | ||
irq_hw_number_t hw_irq_num) | ||
{ | ||
irq_set_chip_and_handler(virq, &m_irq_chip, handle_level_irq); | ||
|
||
return 0; | ||
} | ||
|
||
static struct irq_domain_ops irq_ops = { | ||
.map = irq_map, | ||
.xlate = irq_domain_xlate_onecell, | ||
}; | ||
|
||
void __init init_IRQ(void) | ||
{ | ||
struct irq_domain *domain; | ||
struct device_node *node; | ||
|
||
node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.0"); | ||
if (!node) | ||
node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.1"); | ||
|
||
BUG_ON(!node); | ||
|
||
domain = irq_domain_add_linear(node, NIOS2_CPU_NR_IRQS, &irq_ops, NULL); | ||
BUG_ON(!domain); | ||
|
||
irq_set_default_host(domain); | ||
of_node_put(node); | ||
/* Load the initial ienable value */ | ||
ienable = RDCTL(CTL_IENABLE); | ||
} |