summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-iop32x
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-iop32x')
-rw-r--r--arch/arm/mach-iop32x/cp6.c10
-rw-r--r--arch/arm/mach-iop32x/include/mach/entry-macro.S31
-rw-r--r--arch/arm/mach-iop32x/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-iop32x/iop3xx.h1
-rw-r--r--arch/arm/mach-iop32x/irq.c29
-rw-r--r--arch/arm/mach-iop32x/irqs.h60
6 files changed, 69 insertions, 64 deletions
diff --git a/arch/arm/mach-iop32x/cp6.c b/arch/arm/mach-iop32x/cp6.c
index ec74b07fb7e3..2882674a1c39 100644
--- a/arch/arm/mach-iop32x/cp6.c
+++ b/arch/arm/mach-iop32x/cp6.c
@@ -7,7 +7,7 @@
#include <asm/traps.h>
#include <asm/ptrace.h>
-static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+void iop_enable_cp6(void)
{
u32 temp;
@@ -16,7 +16,15 @@ static int cp6_trap(struct pt_regs *regs, unsigned int instr)
"mrc p15, 0, %0, c15, c1, 0\n\t"
"orr %0, %0, #(1 << 6)\n\t"
"mcr p15, 0, %0, c15, c1, 0\n\t"
+ "mrc p15, 0, %0, c15, c1, 0\n\t"
+ "mov %0, %0\n\t"
+ "sub pc, pc, #4 @ cp_wait\n\t"
: "=r"(temp));
+}
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+ iop_enable_cp6();
return 0;
}
diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
deleted file mode 100644
index 8e6766d4621e..000000000000
--- a/arch/arm/mach-iop32x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for IOP32x-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
- .macro get_irqnr_preamble, base, tmp
- mrc p15, 0, \tmp, c15, c1, 0
- orr \tmp, \tmp, #(1 << 6)
- mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
- mrc p15, 0, \tmp, c15, c1, 0
- mov \tmp, \tmp
- sub pc, pc, #4 @ cp_wait
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
- cmp \irqstat, #0
- clzne \irqnr, \irqstat
- rsbne \irqnr, \irqnr, #31
- .endm
-
- .macro arch_ret_to_user, tmp1, tmp2
- mrc p15, 0, \tmp1, c15, c1, 0
- ands \tmp2, \tmp1, #(1 << 6)
- bicne \tmp1, \tmp1, #(1 << 6)
- mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
- .endm
diff --git a/arch/arm/mach-iop32x/include/mach/irqs.h b/arch/arm/mach-iop32x/include/mach/irqs.h
index c4e78df428e8..e09ae5f48aec 100644
--- a/arch/arm/mach-iop32x/include/mach/irqs.h
+++ b/arch/arm/mach-iop32x/include/mach/irqs.h
@@ -9,6 +9,6 @@
#ifndef __IRQS_H
#define __IRQS_H
-#define NR_IRQS 32
+#define NR_IRQS 33
#endif
diff --git a/arch/arm/mach-iop32x/iop3xx.h b/arch/arm/mach-iop32x/iop3xx.h
index 46b4b34a4ad2..a6ec7ebadb35 100644
--- a/arch/arm/mach-iop32x/iop3xx.h
+++ b/arch/arm/mach-iop32x/iop3xx.h
@@ -225,6 +225,7 @@ extern int iop3xx_get_init_atu(void);
#include <linux/reboot.h>
void iop3xx_map_io(void);
+void iop_enable_cp6(void);
void iop_init_cp6_handler(void);
void iop_init_time(unsigned long tickrate);
void iop3xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 2d48bf1398c1..6dca7e97d81f 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -29,17 +29,26 @@ static void intstr_write(u32 val)
asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
}
+static u32 iintsrc_read(void)
+{
+ int irq;
+
+ asm volatile("mrc p6, 0, %0, c8, c0, 0" : "=r" (irq));
+
+ return irq;
+}
+
static void
iop32x_irq_mask(struct irq_data *d)
{
- iop32x_mask &= ~(1 << d->irq);
+ iop32x_mask &= ~(1 << (d->irq - 1));
intctl_write(iop32x_mask);
}
static void
iop32x_irq_unmask(struct irq_data *d)
{
- iop32x_mask |= 1 << d->irq;
+ iop32x_mask |= 1 << (d->irq - 1);
intctl_write(iop32x_mask);
}
@@ -50,11 +59,25 @@ struct irq_chip ext_chip = {
.irq_unmask = iop32x_irq_unmask,
};
+static void iop_handle_irq(struct pt_regs *regs)
+{
+ u32 mask;
+
+ iop_enable_cp6();
+
+ do {
+ mask = iintsrc_read();
+ if (mask)
+ generic_handle_irq(fls(mask));
+ } while (mask);
+}
+
void __init iop32x_init_irq(void)
{
int i;
iop_init_cp6_handler();
+ set_handle_irq(iop_handle_irq);
intctl_write(0);
intstr_write(0);
@@ -65,7 +88,7 @@ void __init iop32x_init_irq(void)
machine_is_em7210())
*IOP3XX_PCIIRSR = 0x0f;
- for (i = 0; i < NR_IRQS; i++) {
+ for (i = 1; i < NR_IRQS; i++) {
irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
}
diff --git a/arch/arm/mach-iop32x/irqs.h b/arch/arm/mach-iop32x/irqs.h
index 69858e4e905d..e1dfc8b4e7d7 100644
--- a/arch/arm/mach-iop32x/irqs.h
+++ b/arch/arm/mach-iop32x/irqs.h
@@ -7,36 +7,40 @@
#ifndef __IOP32X_IRQS_H
#define __IOP32X_IRQS_H
+/* Interrupts in Linux start at 1, hardware starts at 0 */
+
+#define IOP_IRQ(x) ((x) + 1)
+
/*
* IOP80321 chipset interrupts
*/
-#define IRQ_IOP32X_DMA0_EOT 0
-#define IRQ_IOP32X_DMA0_EOC 1
-#define IRQ_IOP32X_DMA1_EOT 2
-#define IRQ_IOP32X_DMA1_EOC 3
-#define IRQ_IOP32X_AA_EOT 6
-#define IRQ_IOP32X_AA_EOC 7
-#define IRQ_IOP32X_CORE_PMON 8
-#define IRQ_IOP32X_TIMER0 9
-#define IRQ_IOP32X_TIMER1 10
-#define IRQ_IOP32X_I2C_0 11
-#define IRQ_IOP32X_I2C_1 12
-#define IRQ_IOP32X_MESSAGING 13
-#define IRQ_IOP32X_ATU_BIST 14
-#define IRQ_IOP32X_PERFMON 15
-#define IRQ_IOP32X_CORE_PMU 16
-#define IRQ_IOP32X_BIU_ERR 17
-#define IRQ_IOP32X_ATU_ERR 18
-#define IRQ_IOP32X_MCU_ERR 19
-#define IRQ_IOP32X_DMA0_ERR 20
-#define IRQ_IOP32X_DMA1_ERR 21
-#define IRQ_IOP32X_AA_ERR 23
-#define IRQ_IOP32X_MSG_ERR 24
-#define IRQ_IOP32X_SSP 25
-#define IRQ_IOP32X_XINT0 27
-#define IRQ_IOP32X_XINT1 28
-#define IRQ_IOP32X_XINT2 29
-#define IRQ_IOP32X_XINT3 30
-#define IRQ_IOP32X_HPI 31
+#define IRQ_IOP32X_DMA0_EOT IOP_IRQ(0)
+#define IRQ_IOP32X_DMA0_EOC IOP_IRQ(1)
+#define IRQ_IOP32X_DMA1_EOT IOP_IRQ(2)
+#define IRQ_IOP32X_DMA1_EOC IOP_IRQ(3)
+#define IRQ_IOP32X_AA_EOT IOP_IRQ(6)
+#define IRQ_IOP32X_AA_EOC IOP_IRQ(7)
+#define IRQ_IOP32X_CORE_PMON IOP_IRQ(8)
+#define IRQ_IOP32X_TIMER0 IOP_IRQ(9)
+#define IRQ_IOP32X_TIMER1 IOP_IRQ(10)
+#define IRQ_IOP32X_I2C_0 IOP_IRQ(11)
+#define IRQ_IOP32X_I2C_1 IOP_IRQ(12)
+#define IRQ_IOP32X_MESSAGING IOP_IRQ(13)
+#define IRQ_IOP32X_ATU_BIST IOP_IRQ(14)
+#define IRQ_IOP32X_PERFMON IOP_IRQ(15)
+#define IRQ_IOP32X_CORE_PMU IOP_IRQ(16)
+#define IRQ_IOP32X_BIU_ERR IOP_IRQ(17)
+#define IRQ_IOP32X_ATU_ERR IOP_IRQ(18)
+#define IRQ_IOP32X_MCU_ERR IOP_IRQ(19)
+#define IRQ_IOP32X_DMA0_ERR IOP_IRQ(20)
+#define IRQ_IOP32X_DMA1_ERR IOP_IRQ(21)
+#define IRQ_IOP32X_AA_ERR IOP_IRQ(23)
+#define IRQ_IOP32X_MSG_ERR IOP_IRQ(24)
+#define IRQ_IOP32X_SSP IOP_IRQ(25)
+#define IRQ_IOP32X_XINT0 IOP_IRQ(27)
+#define IRQ_IOP32X_XINT1 IOP_IRQ(28)
+#define IRQ_IOP32X_XINT2 IOP_IRQ(29)
+#define IRQ_IOP32X_XINT3 IOP_IRQ(30)
+#define IRQ_IOP32X_HPI IOP_IRQ(31)
#endif