blackfin: SEC: clean up SEC interrupt initialization
Sonic Zhang [Fri, 14 Dec 2012 03:19:24 +0000 (11:19 +0800)]
Append the SEC IRQ after the IVG6, which is consistent to BF5xx SIC.
Exclude SIC irqchip fucntions from SEC code.
Call handle_fasteoi_irq in SEC error and fault handler.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>

arch/blackfin/include/mach-common/irq.h
arch/blackfin/mach-bf609/include/mach/irq.h
arch/blackfin/mach-bf609/pm.c
arch/blackfin/mach-common/ints-priority.c

index cab14e9..af9fc81 100644 (file)
@@ -40,8 +40,6 @@
 #define IRQ_HWERR              5       /* Hardware Error */
 #define IRQ_CORETMR            6       /* Core timer */
 
-#define BFIN_IRQ(x)            ((x) + 7)
-
 #define IVG7                   7
 #define IVG8                   8
 #define IVG9                   9
@@ -52,6 +50,9 @@
 #define IVG14                  14
 #define IVG15                  15
 
+#define BFIN_IRQ(x)            ((x) + IVG7)
+#define BFIN_SYSIRQ(x)         ((x) - IVG7)
+
 #define NR_IRQS                        (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #endif
index 23e74cd..fa0843d 100644 (file)
@@ -9,9 +9,6 @@
 
 #include <mach-common/irq.h>
 
-#undef BFIN_IRQ
-#define BFIN_IRQ(x) ((x) + IVG15)
-
 #define NR_PERI_INTS           (5 * 32)
 
 #define IRQ_SEC_ERR            BFIN_IRQ(0)     /* SEC Error */
index dacafc1..ad505d9 100644 (file)
@@ -174,7 +174,6 @@ void bfin_hibernate_syscontrol(void)
        bfin_write32(DPM0_RESTORE5, bfin_read32(DPM0_RESTORE5) | 4);
 }
 
-#define IRQ_SID(irq)   ((irq) - IVG15)
 asmlinkage void enter_deepsleep(void);
 
 __attribute__((l1_text))
@@ -311,7 +310,7 @@ static irqreturn_t test_isr(int irq, void *dev_id)
 {
        printk(KERN_DEBUG "gpio irq %d\n", irq);
        if (irq == 231)
-               bfin_sec_raise_irq(IRQ_SID(IRQ_SOFT1));
+               bfin_sec_raise_irq(BFIN_SYSIRQ(IRQ_SOFT1));
        return IRQ_HANDLED;
 }
 
index 902bebc..83ff311 100644 (file)
 #include <asm/dpmc.h>
 #include <asm/traps.h>
 
-#ifndef SEC_GCTL
-# define SIC_SYSIRQ(irq)       (irq - (IRQ_CORETMR + 1))
-#else
-# define SIC_SYSIRQ(irq)       ((irq) - IVG15)
-#endif
-
 /*
  * NOTES:
  * - we have separated the physical Hardware interrupt from the
@@ -141,13 +135,13 @@ static void bfin_core_unmask_irq(struct irq_data *d)
        return;
 }
 
+#ifndef SEC_GCTL
 void bfin_internal_mask_irq(unsigned int irq)
 {
        unsigned long flags = hard_local_irq_save();
-#ifndef SEC_GCTL
 #ifdef SIC_IMASK0
-       unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
-       unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
+       unsigned mask_bank = BFIN_SYSIRQ(irq) / 32;
+       unsigned mask_bit = BFIN_SYSIRQ(irq) % 32;
        bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
                        ~(1 << mask_bit));
 # if defined(CONFIG_SMP) || defined(CONFIG_ICC)
@@ -156,9 +150,8 @@ void bfin_internal_mask_irq(unsigned int irq)
 # endif
 #else
        bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
-                       ~(1 << SIC_SYSIRQ(irq)));
+                       ~(1 << BFIN_SYSIRQ(irq)));
 #endif /* end of SIC_IMASK0 */
-#endif
        hard_local_irq_restore(flags);
 }
 
@@ -176,10 +169,9 @@ void bfin_internal_unmask_irq(unsigned int irq)
 {
        unsigned long flags = hard_local_irq_save();
 
-#ifndef SEC_GCTL
 #ifdef SIC_IMASK0
-       unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
-       unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
+       unsigned mask_bank = BFIN_SYSIRQ(irq) / 32;
+       unsigned mask_bit = BFIN_SYSIRQ(irq) % 32;
 # ifdef CONFIG_SMP
        if (cpumask_test_cpu(0, affinity))
 # endif
@@ -194,17 +186,103 @@ void bfin_internal_unmask_irq(unsigned int irq)
 # endif
 #else
        bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
-                       (1 << SIC_SYSIRQ(irq)));
+                       (1 << BFIN_SYSIRQ(irq)));
+#endif
+       hard_local_irq_restore(flags);
+}
+
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq_chip(struct irq_data *d)
+{
+       bfin_internal_unmask_irq_affinity(d->irq, d->affinity);
+}
+
+static int bfin_internal_set_affinity(struct irq_data *d,
+                                     const struct cpumask *mask, bool force)
+{
+       bfin_internal_mask_irq(d->irq);
+       bfin_internal_unmask_irq_affinity(d->irq, mask);
+
+       return 0;
+}
+#else
+static void bfin_internal_unmask_irq_chip(struct irq_data *d)
+{
+       bfin_internal_unmask_irq(d->irq);
+}
 #endif
+
+#if defined(CONFIG_PM)
+int bfin_internal_set_wake(unsigned int irq, unsigned int state)
+{
+       u32 bank, bit, wakeup = 0;
+       unsigned long flags;
+       bank = BFIN_SYSIRQ(irq) / 32;
+       bit = BFIN_SYSIRQ(irq) % 32;
+
+       switch (irq) {
+#ifdef IRQ_RTC
+       case IRQ_RTC:
+       wakeup |= WAKE;
+       break;
+#endif
+#ifdef IRQ_CAN0_RX
+       case IRQ_CAN0_RX:
+       wakeup |= CANWE;
+       break;
 #endif
+#ifdef IRQ_CAN1_RX
+       case IRQ_CAN1_RX:
+       wakeup |= CANWE;
+       break;
+#endif
+#ifdef IRQ_USB_INT0
+       case IRQ_USB_INT0:
+       wakeup |= USBWE;
+       break;
+#endif
+#ifdef CONFIG_BF54x
+       case IRQ_CNT:
+       wakeup |= ROTWE;
+       break;
+#endif
+       default:
+       break;
+       }
+
+       flags = hard_local_irq_save();
+
+       if (state) {
+               bfin_sic_iwr[bank] |= (1 << bit);
+               vr_wakeup  |= wakeup;
+
+       } else {
+               bfin_sic_iwr[bank] &= ~(1 << bit);
+               vr_wakeup  &= ~wakeup;
+       }
+
        hard_local_irq_restore(flags);
+
+       return 0;
 }
 
-#ifdef SEC_GCTL
+static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state)
+{
+       return bfin_internal_set_wake(d->irq, state);
+}
+#else
+inline int bfin_internal_set_wake(unsigned int irq, unsigned int state)
+{
+       return 0;
+}
+# define bfin_internal_set_wake_chip NULL
+#endif
+
+#else /* SEC_GCTL */
 static void bfin_sec_preflow_handler(struct irq_data *d)
 {
        unsigned long flags = hard_local_irq_save();
-       unsigned int sid = SIC_SYSIRQ(d->irq);
+       unsigned int sid = BFIN_SYSIRQ(d->irq);
 
        bfin_write_SEC_SCI(0, SEC_CSID, sid);
 
@@ -214,7 +292,7 @@ static void bfin_sec_preflow_handler(struct irq_data *d)
 static void bfin_sec_mask_ack_irq(struct irq_data *d)
 {
        unsigned long flags = hard_local_irq_save();
-       unsigned int sid = SIC_SYSIRQ(d->irq);
+       unsigned int sid = BFIN_SYSIRQ(d->irq);
 
        bfin_write_SEC_SCI(0, SEC_CSID, sid);
 
@@ -224,7 +302,7 @@ static void bfin_sec_mask_ack_irq(struct irq_data *d)
 static void bfin_sec_unmask_irq(struct irq_data *d)
 {
        unsigned long flags = hard_local_irq_save();
-       unsigned int sid = SIC_SYSIRQ(d->irq);
+       unsigned int sid = BFIN_SYSIRQ(d->irq);
 
        bfin_write32(SEC_END, sid);
 
@@ -269,7 +347,7 @@ static void bfin_sec_enable_sci(unsigned int sid)
        unsigned long flags = hard_local_irq_save();
        uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
 
-       if (sid == SIC_SYSIRQ(IRQ_WATCH0))
+       if (sid == BFIN_SYSIRQ(IRQ_WATCH0))
                reg_sctl |= SEC_SCTL_FAULT_EN;
        else
                reg_sctl |= SEC_SCTL_INT_EN;
@@ -292,7 +370,7 @@ static void bfin_sec_disable_sci(unsigned int sid)
 static void bfin_sec_enable(struct irq_data *d)
 {
        unsigned long flags = hard_local_irq_save();
-       unsigned int sid = SIC_SYSIRQ(d->irq);
+       unsigned int sid = BFIN_SYSIRQ(d->irq);
 
        bfin_sec_enable_sci(sid);
        bfin_sec_enable_ssi(sid);
@@ -303,7 +381,7 @@ static void bfin_sec_enable(struct irq_data *d)
 static void bfin_sec_disable(struct irq_data *d)
 {
        unsigned long flags = hard_local_irq_save();
-       unsigned int sid = SIC_SYSIRQ(d->irq);
+       unsigned int sid = BFIN_SYSIRQ(d->irq);
 
        bfin_sec_disable_sci(sid);
        bfin_sec_disable_ssi(sid);
@@ -328,9 +406,10 @@ static void bfin_sec_set_priority(unsigned int sec_int_levels, u8 *sec_int_prior
        hard_local_irq_restore(flags);
 }
 
-void bfin_sec_raise_irq(unsigned int sid)
+void bfin_sec_raise_irq(unsigned int irq)
 {
        unsigned long flags = hard_local_irq_save();
+       unsigned int sid = BFIN_SYSIRQ(irq);
 
        bfin_write32(SEC_RAISE, sid);
 
@@ -341,8 +420,13 @@ static void init_software_driven_irq(void)
 {
        bfin_sec_set_ssi_coreid(34, 0);
        bfin_sec_set_ssi_coreid(35, 1);
+
+       bfin_sec_enable_sci(35);
+       bfin_sec_enable_ssi(35);
        bfin_sec_set_ssi_coreid(36, 0);
        bfin_sec_set_ssi_coreid(37, 1);
+       bfin_sec_enable_sci(37);
+       bfin_sec_enable_ssi(37);
 }
 
 void bfin_sec_resume(void)
@@ -412,6 +496,8 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
        }
 
        raw_spin_unlock(&desc->lock);
+
+       handle_fasteoi_irq(irq, desc);
 }
 
 void handle_core_fault(unsigned int irq, struct irq_desc *desc)
@@ -431,105 +517,18 @@ void handle_core_fault(unsigned int irq, struct irq_desc *desc)
                printk(KERN_NOTICE "Kernel Stack\n");
                show_stack(current, NULL);
                print_modules();
-               panic("Kernel core hardware error");
+               panic("Core 0 hardware error");
                break;
        case IRQ_C0_NMI_L1_PARITY_ERR:
-               panic("NMI occurs unexpectedly");
+               panic("Core 0 NMI L1 parity error");
                break;
        default:
-               panic("Core 1 fault occurs unexpectedly");
+               panic("Core 1 fault %d occurs unexpectedly", irq);
        }
 
        raw_spin_unlock(&desc->lock);
 }
-#endif
-
-#ifdef CONFIG_SMP
-static void bfin_internal_unmask_irq_chip(struct irq_data *d)
-{
-       bfin_internal_unmask_irq_affinity(d->irq, d->affinity);
-}
-
-static int bfin_internal_set_affinity(struct irq_data *d,
-                                     const struct cpumask *mask, bool force)
-{
-       bfin_internal_mask_irq(d->irq);
-       bfin_internal_unmask_irq_affinity(d->irq, mask);
-
-       return 0;
-}
-#else
-static void bfin_internal_unmask_irq_chip(struct irq_data *d)
-{
-       bfin_internal_unmask_irq(d->irq);
-}
-#endif
-
-#if defined(CONFIG_PM) && !defined(SEC_GCTL)
-int bfin_internal_set_wake(unsigned int irq, unsigned int state)
-{
-       u32 bank, bit, wakeup = 0;
-       unsigned long flags;
-       bank = SIC_SYSIRQ(irq) / 32;
-       bit = SIC_SYSIRQ(irq) % 32;
-
-       switch (irq) {
-#ifdef IRQ_RTC
-       case IRQ_RTC:
-       wakeup |= WAKE;
-       break;
-#endif
-#ifdef IRQ_CAN0_RX
-       case IRQ_CAN0_RX:
-       wakeup |= CANWE;
-       break;
-#endif
-#ifdef IRQ_CAN1_RX
-       case IRQ_CAN1_RX:
-       wakeup |= CANWE;
-       break;
-#endif
-#ifdef IRQ_USB_INT0
-       case IRQ_USB_INT0:
-       wakeup |= USBWE;
-       break;
-#endif
-#ifdef CONFIG_BF54x
-       case IRQ_CNT:
-       wakeup |= ROTWE;
-       break;
-#endif
-       default:
-       break;
-       }
-
-       flags = hard_local_irq_save();
-
-       if (state) {
-               bfin_sic_iwr[bank] |= (1 << bit);
-               vr_wakeup  |= wakeup;
-
-       } else {
-               bfin_sic_iwr[bank] &= ~(1 << bit);
-               vr_wakeup  &= ~wakeup;
-       }
-
-       hard_local_irq_restore(flags);
-
-       return 0;
-}
-
-static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state)
-{
-       return bfin_internal_set_wake(d->irq, state);
-}
-#else
-inline int bfin_internal_set_wake(unsigned int irq, unsigned int state)
-{
-       return 0;
-}
-# define bfin_internal_set_wake_chip NULL
-#endif
+#endif /* SEC_GCTL */
 
 static struct irq_chip bfin_core_irqchip = {
        .name = "CORE",
@@ -537,6 +536,7 @@ static struct irq_chip bfin_core_irqchip = {
        .irq_unmask = bfin_core_unmask_irq,
 };
 
+#ifndef SEC_GCTL
 static struct irq_chip bfin_internal_irqchip = {
        .name = "INTN",
        .irq_mask = bfin_internal_mask_irq_chip,
@@ -548,8 +548,7 @@ static struct irq_chip bfin_internal_irqchip = {
 #endif
        .irq_set_wake = bfin_internal_set_wake_chip,
 };
-
-#ifdef SEC_GCTL
+#else
 static struct irq_chip bfin_sec_irqchip = {
        .name = "SEC",
        .irq_mask_ack = bfin_sec_mask_ack_irq,
@@ -1138,7 +1137,9 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
                return -EINVAL;
        }
 
+#ifndef SEC_GCTL
        bfin_internal_set_wake(pint_irq, state);
+#endif
 
        return 0;
 }
@@ -1173,7 +1174,7 @@ static int sec_suspend(void)
        u32 bank;
 
        for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++)
-               save_pint_sec_ctl[bank] = bfin_read_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0));
+               save_pint_sec_ctl[bank] = bfin_read_SEC_SCTL(bank + BFIN_SYSIRQ(IRQ_PINT0));
        return 0;
 }
 
@@ -1187,7 +1188,7 @@ static void sec_resume(void)
        bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN);
 
        for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++)
-               bfin_write_SEC_SCTL(bank + SIC_SYSIRQ(IRQ_PINT0), save_pint_sec_ctl[bank]);
+               bfin_write_SEC_SCTL(bank + BFIN_SYSIRQ(IRQ_PINT0), save_pint_sec_ctl[bank]);
 }
 
 static struct syscore_ops sec_pm_syscore_ops = {
@@ -1538,33 +1539,26 @@ int __init init_arch_irq(void)
 
        for (irq = 0; irq <= SYS_IRQS; irq++) {
                if (irq <= IRQ_CORETMR) {
-                       irq_set_chip(irq, &bfin_core_irqchip);
-#ifdef CONFIG_TICKSOURCE_CORETMR
+                       irq_set_chip_and_handler(irq, &bfin_core_irqchip,
+                               handle_simple_irq);
+#if defined(CONFIG_TICKSOURCE_CORETMR) && defined(CONFIG_SMP)
                        if (irq == IRQ_CORETMR)
-# ifdef CONFIG_SMP
                                irq_set_handler(irq, handle_percpu_irq);
-# else
-                               irq_set_handler(irq, handle_simple_irq);
-# endif
 #endif
-               } else if (irq < BFIN_IRQ(0)) {
-                       irq_set_chip_and_handler(irq, &bfin_internal_irqchip,
-                                       handle_simple_irq);
-               } 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);
                } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) {
-                       irq_set_chip(irq, &bfin_sec_irqchip);
-                       irq_set_handler(irq, handle_percpu_irq);
-               } else {
                        irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
-                                       handle_fasteoi_irq);
+                               handle_percpu_irq);
+               } else {
+                       irq_set_chip(irq, &bfin_sec_irqchip);
+                       if (irq == IRQ_SEC_ERR)
+                               irq_set_handler(irq, handle_sec_fault);
+                       else if (irq >= IRQ_C0_DBL_FAULT && irq < CORE_IRQS)
+                               irq_set_handler(irq, handle_core_fault);
+                       else
+                               irq_set_handler(irq, handle_fasteoi_irq);
                        __irq_set_preflow_handler(irq, bfin_sec_preflow_handler);
                }
        }
@@ -1593,8 +1587,8 @@ int __init init_arch_irq(void)
 
 
        bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN);
-       bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0));
-       bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0));
+       bfin_sec_enable_sci(BFIN_SYSIRQ(IRQ_WATCH0));
+       bfin_sec_enable_ssi(BFIN_SYSIRQ(IRQ_WATCH0));
        bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
        udelay(100);
        bfin_write_SEC_GCTL(SEC_GCTL_EN);