- /* set polarity
- * 1 = default/pos/rising , 0= neg/falling internal
- * 1 = neg/falling , 0= pos/rising external
- * Sense
- * 0 = default level internal
- * 0 = level, 1 = edge external
- */
-
- unsigned int sense, irq;
- int bit, word;
- unsigned long ppc_cached_sense_mask[NR_MASK_WORDS];
- unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
- ppc_cached_sense_mask[0] = 0;
- ppc_cached_sense_mask[1] = 0;
- ppc_cached_sense_mask[2] = 0;
- ppc_cached_pol_mask[0] = 0;
- ppc_cached_pol_mask[1] = 0;
- ppc_cached_pol_mask[2] = 0;
-
- for (irq = 0; irq < NR_IRQS; irq++) {
-
- bit = irq & 0x1f;
- word = irq >> 5;
-
- sense =
- (irq <
- ibm4xxPIC_NumInitSenses) ? ibm4xxPIC_InitSenses[irq] : 3;
-#ifdef PPC4xx_PIC_DEBUG
- printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word,
- bit, sense);
-#endif
- ppc_cached_sense_mask[word] |=
- (~sense & IRQ_SENSE_MASK) << (31 - bit);
- ppc_cached_pol_mask[word] |=
- ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit);
- switch (word) {
- case 0:
-#ifdef PPC4xx_PIC_DEBUG
- printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0)));
- printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0)));
-#endif
- /* polarity setting */
- mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]);
-
- /* Level setting */
- mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]);
-
- break;
- case 1:
-#ifdef PPC4xx_PIC_DEBUG
- printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1)));
- printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1)));
-#endif
- /* polarity setting */
- mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]);
-
- /* Level setting */
- mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
-
- break;
- case 2:
-#ifdef PPC4xx_PIC_DEBUG
- printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC2)));
- printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC2)));
-#endif
- /* polarity setting */
- mtdcr(DCRN_UIC_PR(UIC2), ppc_cached_pol_mask[word]);
-
- /* Level setting */
- mtdcr(DCRN_UIC_TR(UIC2), ppc_cached_sense_mask[word]);
-
- break;
+ int i;
+ unsigned char* eirqs = ppc4xx_uic_ext_irq_cfg;
+
+ for (i = 0; i < NR_UICS; ++i){
+ int base = __uic[i].base;
+
+ /* Disable everything by default */
+ ppc_cached_irq_mask[i] = 0;
+ mtdcr(DCRN_UIC_ER(base), 0);
+
+ /* We don't use critical interrupts */
+ mtdcr(DCRN_UIC_CR(base), 0);
+
+ /* Configure polarity and triggering */
+ if (ppc4xx_core_uic_cfg){
+ struct ppc4xx_uic_settings* p = ppc4xx_core_uic_cfg + i;
+ u32 mask = p->ext_irq_mask;
+ u32 pr = mfdcr(DCRN_UIC_PR(base)) & mask;
+ u32 tr = mfdcr(DCRN_UIC_TR(base)) & mask;
+
+ /* "Fixed" interrupts (on-chip devices) */
+ pr |= p->polarity & ~mask;
+ tr |= p->triggering & ~mask;
+
+ /* Merge external IRQs settings if board port
+ * provided them
+ */
+ if (eirqs && mask){
+ pr &= ~mask;
+ tr &= ~mask;
+ while (mask){
+ /* Extract current external IRQ mask */
+ u32 eirq_mask = 1 << __ilog2(mask);
+
+ if (!(*eirqs & IRQ_SENSE_LEVEL))
+ tr |= eirq_mask;
+
+ if (*eirqs & IRQ_POLARITY_POSITIVE)
+ pr |= eirq_mask;
+
+ mask &= ~eirq_mask;
+ ++eirqs;
+ }
+ }
+ mtdcr(DCRN_UIC_PR(base), pr);
+ mtdcr(DCRN_UIC_TR(base), tr);