* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/linkage.h>
#endif
#endif
-static struct hw_interrupt_type bcm1480_irq_type = {
+static struct irq_chip bcm1480_irq_type = {
.typename = "BCM1480-IMR",
.startup = startup_bcm1480_irq,
.shutdown = shutdown_bcm1480_irq,
{
int i = 0, old_cpu, cpu, int_on, k;
u64 cur_ints;
- irq_desc_t *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_desc + irq;
unsigned long flags;
unsigned int irq_dirty;
#endif
-/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
-extern void bcm1480_irq_handler(void);
-
/*****************************************************************************/
static unsigned int startup_bcm1480_irq(unsigned int irq)
irq_desc[i].action = 0;
irq_desc[i].depth = 1;
if (i < BCM1480_NR_IRQS) {
- irq_desc[i].handler = &bcm1480_irq_type;
+ irq_desc[i].chip = &bcm1480_irq_type;
bcm1480_irq_owner[i] = 0;
} else {
- irq_desc[i].handler = &no_irq_type;
+ irq_desc[i].chip = &no_irq_chip;
}
}
}
int bcm1480_steal_irq(int irq)
{
- irq_desc_t *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_desc + irq;
unsigned long flags;
int retval = 0;
#endif
/* Enable necessary IPs, disable the rest */
change_c0_status(ST0_IM, imask);
- set_except_vector(0, bcm1480_irq_handler);
#ifdef CONFIG_KGDB
if (kgdb_flag) {
}
#endif /* CONFIG_KGDB */
+
+extern void bcm1480_timer_interrupt(struct pt_regs *regs);
+extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
+extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+ unsigned int pending;
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ /* Set compare to count to silence count/compare timer interrupts */
+ write_c0_compare(read_c0_count());
+#endif
+
+ pending = read_c0_cause();
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
+ sbprof_cpu_intr(exception_epc(regs));
+ else
+#endif
+
+ if (pending & CAUSEF_IP4)
+ bcm1480_timer_interrupt(regs);
+
+#ifdef CONFIG_SMP
+ else if (pending & CAUSEF_IP3)
+ bcm1480_mailbox_interrupt(regs);
+#endif
+
+#ifdef CONFIG_KGDB
+ else if (pending & CAUSEF_IP6)
+ bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */
+#endif
+
+ else if (pending & CAUSEF_IP2) {
+ unsigned long long mask_h, mask_l;
+ unsigned long base;
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've
+ * got to check the 1480 interrupt registers to figure out what
+ * to do. Need to detect which CPU we're on, now that
+ * smp_affinity is supported.
+ */
+ base = A_BCM1480_IMR_MAPPER(smp_processor_id());
+ mask_h = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+ mask_l = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+ if (mask_h) {
+ if (mask_h ^ 1)
+ do_IRQ(fls64(mask_h) - 1, regs);
+ else
+ do_IRQ(63 + fls64(mask_l), regs);
+ }
+ }
+}