extern unsigned long ht_eoi_space;
#endif
-#ifdef CONFIG_KGDB
-#include <asm/gdb-stub.h>
-extern void breakpoint(void);
-static int kgdb_irq;
-#ifdef CONFIG_GDB_CONSOLE
-extern void register_gdb_console(void);
-#endif
-
-/* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */
-static int kgdb_flag = 1;
-static int __init nokgdb(char *str)
-{
- kgdb_flag = 0;
- return 1;
-}
-__setup("nokgdb", nokgdb);
-
-/* Default to UART1 */
-int kgdb_port = 1;
-#ifdef CONFIG_SERIAL_SB1250_DUART
-extern char sb1250_duart_present[];
-#endif
-#endif
-
static struct irq_chip bcm1480_irq_type = {
.name = "BCM1480-IMR",
.ack = ack_bcm1480_irq,
}
}
-
-static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id)
-{
- return IRQ_NONE;
-}
-
-static struct irqaction bcm1480_dummy_action = {
- .handler = bcm1480_dummy_handler,
- .flags = 0,
- .mask = CPU_MASK_NONE,
- .name = "bcm1480-private",
- .next = NULL,
- .dev_id = 0
-};
-
-int bcm1480_steal_irq(int irq)
-{
- struct irq_desc *desc = irq_desc + irq;
- unsigned long flags;
- int retval = 0;
-
- if (irq >= BCM1480_NR_IRQS)
- return -EINVAL;
-
- spin_lock_irqsave(&desc->lock, flags);
- /* Don't allow sharing at all for these */
- if (desc->action != NULL)
- retval = -EBUSY;
- else {
- desc->action = &bcm1480_dummy_action;
- desc->depth = 0;
- }
- spin_unlock_irqrestore(&desc->lock, flags);
- return 0;
-}
-
/*
* init_IRQ is called early in the boot sequence from init/main.c. It
* is responsible for setting up the interrupt mapper and installing the
void __init arch_init_irq(void)
{
-
unsigned int i, cpu;
u64 tmp;
unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
__raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
}
- bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
-
/*
* Note that the timer interrupts are also mapped, but this is
* done in bcm1480_time_init(). Also, the profiling driver
* does its own management of IP7.
*/
-#ifdef CONFIG_KGDB
- imask |= STATUSF_IP6;
-#endif
/* Enable necessary IPs, disable the rest */
change_c0_status(ST0_IM, imask);
-
-#ifdef CONFIG_KGDB
- if (kgdb_flag) {
- kgdb_irq = K_BCM1480_INT_UART_0 + kgdb_port;
-
-#ifdef CONFIG_SERIAL_SB1250_DUART
- sb1250_duart_present[kgdb_port] = 0;
-#endif
- /* Setup uart 1 settings, mapper */
- /* QQQ FIXME */
- __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
-
- bcm1480_steal_irq(kgdb_irq);
- __raw_writeq(IMR_IP6_VAL,
- IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
- (kgdb_irq<<3));
- bcm1480_unmask_irq(0, kgdb_irq);
-
-#ifdef CONFIG_GDB_CONSOLE
- register_gdb_console();
-#endif
- printk("Waiting for GDB on UART port %d\n", kgdb_port);
- set_debug_traps();
- breakpoint();
- }
-#endif
}
-#ifdef CONFIG_KGDB
-
-#include <linux/delay.h>
-
-#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
-#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port, reg)))
+extern void bcm1480_mailbox_interrupt(void);
-static void bcm1480_kgdb_interrupt(void)
+static inline void dispatch_ip2(void)
{
+ unsigned long long mask_h, mask_l;
+ unsigned int cpu = smp_processor_id();
+ unsigned long base;
+
/*
- * Clear break-change status (allow some time for the remote
- * host to stop the break, since we would see another
- * interrupt on the end-of-break too)
+ * 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.
*/
- kstat.irqs[smp_processor_id()][kgdb_irq]++;
- mdelay(500);
- duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
- M_DUART_RX_EN | M_DUART_TX_EN);
- set_async_breakpoint(&get_irq_regs()->cp0_epc);
+ base = A_BCM1480_IMR_MAPPER(cpu);
+ 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);
+ else if (mask_l)
+ do_IRQ(63 + fls64(mask_l));
+ }
}
-#endif /* CONFIG_KGDB */
-
-extern void bcm1480_mailbox_interrupt(void);
-
asmlinkage void plat_irq_dispatch(void)
{
+ unsigned int cpu = smp_processor_id();
unsigned int pending;
#ifdef CONFIG_SIBYTE_BCM1480_PROF
else
#endif
- if (pending & CAUSEF_IP4) {
- int cpu = smp_processor_id();
- int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
- /* Reset the timer */
- __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
- do_IRQ(irq);
- }
-
+ if (pending & CAUSEF_IP4)
+ do_IRQ(K_BCM1480_INT_TIMER_0 + cpu);
#ifdef CONFIG_SMP
else if (pending & CAUSEF_IP3)
bcm1480_mailbox_interrupt();
#endif
-#ifdef CONFIG_KGDB
- else if (pending & CAUSEF_IP6)
- bcm1480_kgdb_interrupt(); /* 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);
- else
- do_IRQ(63 + fls64(mask_l));
- }
- }
+ else if (pending & CAUSEF_IP2)
+ dispatch_ip2();
}