]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/blackfin/mach-common/ints-priority.c
Merge branch 'for-3.6' of git://gitorious.org/linux-pwm/linux-pwm
[karo-tx-linux.git] / arch / blackfin / mach-common / ints-priority.c
index a7e97a3607da414f6d4d959a3207f39d73e88987..7ca09ec2ca539cf01ec9e3f81240b5fa9c0c94b8 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/gpio.h>
 #include <asm/irq_handler.h>
 #include <asm/dpmc.h>
+#include <asm/traps.h>
 
 #ifndef SEC_GCTL
 # define SIC_SYSIRQ(irq)       (irq - (IRQ_CORETMR + 1))
@@ -310,7 +311,24 @@ static void bfin_sec_disable(struct irq_data *d)
        hard_local_irq_restore(flags);
 }
 
-static void bfin_sec_raise_irq(unsigned int sid)
+static void bfin_sec_set_priority(unsigned int sec_int_levels, u8 *sec_int_priority)
+{
+       unsigned long flags = hard_local_irq_save();
+       uint32_t reg_sctl;
+       int i;
+
+       bfin_write_SEC_SCI(0, SEC_CPLVL, sec_int_levels);
+
+       for (i = 0; i < SYS_IRQS - BFIN_IRQ(0); i++) {
+               reg_sctl = bfin_read_SEC_SCTL(i) & ~SEC_SCTL_PRIO;
+               reg_sctl |= sec_int_priority[i] << SEC_SCTL_PRIO_OFFSET;
+               bfin_write_SEC_SCTL(i, reg_sctl);
+       }
+
+       hard_local_irq_restore(flags);
+}
+
+void bfin_sec_raise_irq(unsigned int sid)
 {
        unsigned long flags = hard_local_irq_save();
 
@@ -396,6 +414,34 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
        raw_spin_unlock(&desc->lock);
 }
 
+void handle_core_fault(unsigned int irq, struct irq_desc *desc)
+{
+       struct pt_regs *fp = get_irq_regs();
+
+       raw_spin_lock(&desc->lock);
+
+       switch (irq) {
+       case IRQ_C0_DBL_FAULT:
+               double_fault_c(fp);
+               break;
+       case IRQ_C0_HW_ERR:
+               dump_bfin_process(fp);
+               dump_bfin_mem(fp);
+               show_regs(fp);
+               printk(KERN_NOTICE "Kernel Stack\n");
+               show_stack(current, NULL);
+               print_modules();
+               panic("Kernel core hardware error");
+               break;
+       case IRQ_C0_NMI_L1_PARITY_ERR:
+               panic("NMI occurs unexpectedly");
+               break;
+       default:
+               panic("Core 1 fault occurs unexpectedly");
+       }
+
+       raw_spin_unlock(&desc->lock);
+}
 #endif
 
 #ifdef CONFIG_SMP
@@ -1505,9 +1551,12 @@ int __init init_arch_irq(void)
                } else if (irq < BFIN_IRQ(0)) {
                        irq_set_chip_and_handler(irq, &bfin_internal_irqchip,
                                        handle_simple_irq);
-               } else if (irq < CORE_IRQS && irq != IRQ_CGU_EVT) {
+               } else if (irq == IRQ_SEC_ERR) {
                        irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
                                        handle_sec_fault);
+               } else if (irq < CORE_IRQS && irq >= IRQ_C0_DBL_FAULT) {
+                       irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
+                                       handle_core_fault);
                } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) {
                        irq_set_chip(irq, &bfin_sec_irqchip);
                        irq_set_chained_handler(irq, bfin_demux_gpio_irq);
@@ -1534,6 +1583,10 @@ int __init init_arch_irq(void)
 
        printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
 
+       bfin_sec_set_priority(CONFIG_SEC_IRQ_PRIORITY_LEVELS, sec_int_priority);
+
+       bfin_sec_set_priority(CONFIG_SEC_IRQ_PRIORITY_LEVELS, sec_int_priority);
+
        /* Enable interrupts IVG7-15 */
        bfin_irq_flags |= IMASK_IVG15 |
            IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |