a3a0f8c8ed
Add the Cisco Powertv cable settop box to the MIPS tree. This platform is based on a MIPS 24Kc processor with various devices integrated on the same ASIC. There are multiple models of this box, with differing configuration but the same kernel runs across the product line. Signed-off-by: David VomLehn <dvomlehn@cisco.com> Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/132/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
117 lines
2.8 KiB
C
117 lines
2.8 KiB
C
/*
|
|
* Portions copyright (C) 2005-2009 Scientific Atlanta
|
|
* Portions copyright (C) 2009 Cisco Systems, Inc.
|
|
*
|
|
* Modified from arch/mips/kernel/irq-rm7000.c:
|
|
* Copyright (C) 2003 Ralf Baechle
|
|
*
|
|
* 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.
|
|
*/
|
|
#include <linux/init.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/kernel.h>
|
|
|
|
#include <asm/irq_cpu.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/system.h>
|
|
|
|
#include <asm/mach-powertv/asic_regs.h>
|
|
|
|
static inline void unmask_asic_irq(unsigned int irq)
|
|
{
|
|
unsigned long enable_bit;
|
|
|
|
enable_bit = (1 << (irq & 0x1f));
|
|
|
|
switch (irq >> 5) {
|
|
case 0:
|
|
asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
|
|
break;
|
|
case 1:
|
|
asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
|
|
break;
|
|
case 2:
|
|
asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
|
|
break;
|
|
case 3:
|
|
asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
|
|
break;
|
|
default:
|
|
BUG();
|
|
}
|
|
}
|
|
|
|
static inline void mask_asic_irq(unsigned int irq)
|
|
{
|
|
unsigned long disable_mask;
|
|
|
|
disable_mask = ~(1 << (irq & 0x1f));
|
|
|
|
switch (irq >> 5) {
|
|
case 0:
|
|
asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
|
|
break;
|
|
case 1:
|
|
asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
|
|
break;
|
|
case 2:
|
|
asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
|
|
break;
|
|
case 3:
|
|
asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
|
|
break;
|
|
default:
|
|
BUG();
|
|
}
|
|
}
|
|
|
|
static struct irq_chip asic_irq_chip = {
|
|
.name = "ASIC Level",
|
|
.ack = mask_asic_irq,
|
|
.mask = mask_asic_irq,
|
|
.mask_ack = mask_asic_irq,
|
|
.unmask = unmask_asic_irq,
|
|
.eoi = unmask_asic_irq,
|
|
};
|
|
|
|
void __init asic_irq_init(void)
|
|
{
|
|
int i;
|
|
|
|
/* set priority to 0 */
|
|
write_c0_status(read_c0_status() & ~(0x0000fc00));
|
|
|
|
asic_write(0, ien_int_0);
|
|
asic_write(0, ien_int_1);
|
|
asic_write(0, ien_int_2);
|
|
asic_write(0, ien_int_3);
|
|
|
|
asic_write(0x0fffffff, int_level_3_3);
|
|
asic_write(0xffffffff, int_level_3_2);
|
|
asic_write(0xffffffff, int_level_3_1);
|
|
asic_write(0xffffffff, int_level_3_0);
|
|
asic_write(0xffffffff, int_level_2_3);
|
|
asic_write(0xffffffff, int_level_2_2);
|
|
asic_write(0xffffffff, int_level_2_1);
|
|
asic_write(0xffffffff, int_level_2_0);
|
|
asic_write(0xffffffff, int_level_1_3);
|
|
asic_write(0xffffffff, int_level_1_2);
|
|
asic_write(0xffffffff, int_level_1_1);
|
|
asic_write(0xffffffff, int_level_1_0);
|
|
asic_write(0xffffffff, int_level_0_3);
|
|
asic_write(0xffffffff, int_level_0_2);
|
|
asic_write(0xffffffff, int_level_0_1);
|
|
asic_write(0xffffffff, int_level_0_0);
|
|
|
|
asic_write(0xf, int_int_scan);
|
|
|
|
/*
|
|
* Initialize interrupt handlers.
|
|
*/
|
|
for (i = 0; i < NR_IRQS; i++)
|
|
set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
|
|
}
|