aboutsummaryrefslogtreecommitdiff
path: root/arch/cris/arch-v32/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32/kernel/irq.c')
-rw-r--r--arch/cris/arch-v32/kernel/irq.c129
1 files changed, 53 insertions, 76 deletions
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index 173c141ac9b..25437ae2812 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -97,7 +97,11 @@ extern void breakh_BUG(void);
/*
* Build the IRQ handler stubs using macros from irq.h.
*/
+#ifdef CONFIG_CRIS_MACH_ARTPEC3
+BUILD_TIMER_IRQ(0x31, 0)
+#else
BUILD_IRQ(0x31)
+#endif
BUILD_IRQ(0x32)
BUILD_IRQ(0x33)
BUILD_IRQ(0x34)
@@ -123,7 +127,11 @@ BUILD_IRQ(0x47)
BUILD_IRQ(0x48)
BUILD_IRQ(0x49)
BUILD_IRQ(0x4a)
+#ifdef CONFIG_ETRAXFS
+BUILD_TIMER_IRQ(0x4b, 0)
+#else
BUILD_IRQ(0x4b)
+#endif
BUILD_IRQ(0x4c)
BUILD_IRQ(0x4d)
BUILD_IRQ(0x4e)
@@ -199,25 +207,20 @@ block_irq(int irq, int cpu)
unsigned long flags;
spin_lock_irqsave(&irq_lock, flags);
- if (irq - FIRST_IRQ < 32)
+ /* Remember, 1 let thru, 0 block. */
+ if (irq - FIRST_IRQ < 32) {
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
rw_mask, 0);
- else
- intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
- rw_mask, 1);
-
- /* Remember; 1 let thru, 0 block. */
- if (irq - FIRST_IRQ < 32)
intr_mask &= ~(1 << (irq - FIRST_IRQ));
- else
- intr_mask &= ~(1 << (irq - FIRST_IRQ - 32));
-
- if (irq - FIRST_IRQ < 32)
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
0, intr_mask);
- else
+ } else {
+ intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
+ rw_mask, 1);
+ intr_mask &= ~(1 << (irq - FIRST_IRQ - 32));
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
1, intr_mask);
+ }
spin_unlock_irqrestore(&irq_lock, flags);
}
@@ -228,26 +231,20 @@ unblock_irq(int irq, int cpu)
unsigned long flags;
spin_lock_irqsave(&irq_lock, flags);
- if (irq - FIRST_IRQ < 32)
+ /* Remember, 1 let thru, 0 block. */
+ if (irq - FIRST_IRQ < 32) {
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
rw_mask, 0);
- else
- intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
- rw_mask, 1);
-
- /* Remember; 1 let thru, 0 block. */
- if (irq - FIRST_IRQ < 32)
intr_mask |= (1 << (irq - FIRST_IRQ));
- else
- intr_mask |= (1 << (irq - FIRST_IRQ - 32));
-
- if (irq - FIRST_IRQ < 32)
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
0, intr_mask);
- else
+ } else {
+ intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
+ rw_mask, 1);
+ intr_mask |= (1 << (irq - FIRST_IRQ - 32));
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
1, intr_mask);
-
+ }
spin_unlock_irqrestore(&irq_lock, flags);
}
@@ -269,19 +266,18 @@ static int irq_cpu(int irq)
/* Let the interrupt stay if possible */
- if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask))
+ if (cpumask_test_cpu(cpu, &irq_allocations[irq - FIRST_IRQ].mask))
goto out;
/* IRQ must be moved to another CPU. */
- cpu = first_cpu(irq_allocations[irq - FIRST_IRQ].mask);
+ cpu = cpumask_first(&irq_allocations[irq - FIRST_IRQ].mask);
irq_allocations[irq - FIRST_IRQ].cpu = cpu;
out:
spin_unlock_irqrestore(&irq_lock, flags);
return cpu;
}
-void
-mask_irq(int irq)
+void crisv32_mask_irq(int irq)
{
int cpu;
@@ -289,59 +285,39 @@ mask_irq(int irq)
block_irq(irq, cpu);
}
-void
-unmask_irq(int irq)
+void crisv32_unmask_irq(int irq)
{
unblock_irq(irq, irq_cpu(irq));
}
-static unsigned int startup_crisv32_irq(unsigned int irq)
+static void enable_crisv32_irq(struct irq_data *data)
{
- unmask_irq(irq);
- return 0;
+ crisv32_unmask_irq(data->irq);
}
-static void shutdown_crisv32_irq(unsigned int irq)
+static void disable_crisv32_irq(struct irq_data *data)
{
- mask_irq(irq);
+ crisv32_mask_irq(data->irq);
}
-static void enable_crisv32_irq(unsigned int irq)
-{
- unmask_irq(irq);
-}
-
-static void disable_crisv32_irq(unsigned int irq)
-{
- mask_irq(irq);
-}
-
-static void ack_crisv32_irq(unsigned int irq)
-{
-}
-
-static void end_crisv32_irq(unsigned int irq)
-{
-}
-
-void set_affinity_crisv32_irq(unsigned int irq, cpumask_t dest)
+static int set_affinity_crisv32_irq(struct irq_data *data,
+ const struct cpumask *dest, bool force)
{
unsigned long flags;
+
spin_lock_irqsave(&irq_lock, flags);
- irq_allocations[irq - FIRST_IRQ].mask = dest;
+ irq_allocations[data->irq - FIRST_IRQ].mask = *dest;
spin_unlock_irqrestore(&irq_lock, flags);
+ return 0;
}
-static struct hw_interrupt_type crisv32_irq_type = {
- .typename = "CRISv32",
- .startup = startup_crisv32_irq,
- .shutdown = shutdown_crisv32_irq,
- .enable = enable_crisv32_irq,
- .disable = disable_crisv32_irq,
- .ack = ack_crisv32_irq,
- .end = end_crisv32_irq,
- .set_affinity = set_affinity_crisv32_irq
+static struct irq_chip crisv32_irq_type = {
+ .name = "CRISv32",
+ .irq_shutdown = disable_crisv32_irq,
+ .irq_enable = enable_crisv32_irq,
+ .irq_disable = disable_crisv32_irq,
+ .irq_set_affinity = set_affinity_crisv32_irq,
};
void
@@ -355,11 +331,11 @@ extern void do_IRQ(int irq, struct pt_regs * regs);
void
crisv32_do_IRQ(int irq, int block, struct pt_regs* regs)
{
- /* Interrupts that may not be moved to another CPU and
- * are IRQF_DISABLED may skip blocking. This is currently
- * only valid for the timer IRQ and the IPI and is used
- * for the timer interrupt to avoid watchdog starvation.
- */
+ /* Interrupts that may not be moved to another CPU may
+ * skip blocking. This is currently only valid for the
+ * timer IRQ and the IPI and is used for the timer
+ * interrupt to avoid watchdog starvation.
+ */
if (!block) {
do_IRQ(irq, regs);
return;
@@ -398,7 +374,7 @@ crisv32_do_multiple(struct pt_regs* regs)
irq_enter();
for (i = 0; i < NBR_REGS; i++) {
- /* Get which IRQs that happend. */
+ /* Get which IRQs that happened. */
masked[i] = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
r_masked_vect, i);
@@ -428,8 +404,8 @@ crisv32_do_multiple(struct pt_regs* regs)
masked[i] &= ~TIMER_MASK;
do_IRQ(TIMER0_INTR_VECT, regs);
}
- }
#endif
+ }
#ifdef IGNORE_MASK
/* Remove IRQs that can't be handled as multiple. */
@@ -475,15 +451,16 @@ init_IRQ(void)
/* Point all IRQ's to bad handlers. */
for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
- irq_desc[j].chip = &crisv32_irq_type;
+ irq_set_chip_and_handler(j, &crisv32_irq_type,
+ handle_simple_irq);
set_exception_vector(i, interrupt[j]);
}
- /* Mark Timer and IPI IRQs as CPU local */
+ /* Mark Timer and IPI IRQs as CPU local */
irq_allocations[TIMER0_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
- irq_desc[TIMER0_INTR_VECT].status |= IRQ_PER_CPU;
+ irq_set_status_flags(TIMER0_INTR_VECT, IRQ_PER_CPU);
irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
- irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU;
+ irq_set_status_flags(IPI_INTR_VECT, IRQ_PER_CPU);
set_exception_vector(0x00, nmi_interrupt);
set_exception_vector(0x30, multiple_interrupt);