/* * GCMP needs to be detected before any SMP initialisation */ int __init gcmp_probe(unsigned long addr, unsigned long size) { if ((mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) && (mips_revision_sconid != MIPS_REVISION_SCON_GT64120)) { gcmp_present = 0; pr_debug("GCMP NOT present\n"); return gcmp_present; } if (gcmp_present >= 0) return gcmp_present; _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; if (gcmp_present) pr_debug("GCMP present\n"); return gcmp_present; }
void __init arch_init_irq(void) { init_i8259_irqs(); if (!cpu_has_veic) mips_cpu_irq_init(); if (gcmp_present) { GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; } else { if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; } }
/* Return the number of IOCU's present */ int __init gcmp_niocu(void) { return gcmp_present ? (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF : 0; }
void __init arch_init_irq(void) { int gic_present, gcmp_present; init_i8259_irqs(); if (!cpu_has_veic) mips_cpu_irq_init(); gcmp_present = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); if (gcmp_present) { GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; } else { _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; } if (gic_present) printk(KERN_DEBUG "GIC present\n"); switch (mips_revision_sconid) { case MIPS_REVISION_SCON_SOCIT: case MIPS_REVISION_SCON_ROCIT: if (cpu_has_veic) init_msc_irqs(MIPS_MSC01_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); else init_msc_irqs(MIPS_MSC01_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); break; case MIPS_REVISION_SCON_SOCITSC: case MIPS_REVISION_SCON_SOCITSCP: if (cpu_has_veic) init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); else init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); } if (cpu_has_veic) { set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); } else if (cpu_has_vint) { set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); #ifdef CONFIG_MIPS_MT_SMTC setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq, (0x100 << MIPSCPU_INT_I8259A)); setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); /* * Temporary hack to ensure that the subsidiary device * interrupts coing in via the i8259A, but associated * with low IRQ numbers, will restore the Status.IM * value associated with the i8259A. */ { int i; for (i = 0; i < 16; i++) irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A); } #else /* Not SMTC */ setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); #endif /* CONFIG_MIPS_MT_SMTC */ } else { setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); } #if defined(CONFIG_MIPS_MT_SMP) if (gic_present) { /* FIXME */ int i; struct { unsigned int resched; unsigned int call; } ipiirq[] = { { .resched = GIC_IPI_EXT_INTR_RESCHED_VPE0, .call = GIC_IPI_EXT_INTR_CALLFNC_VPE0}, { .resched = GIC_IPI_EXT_INTR_RESCHED_VPE1, .call = GIC_IPI_EXT_INTR_CALLFNC_VPE1 }, { .resched = GIC_IPI_EXT_INTR_RESCHED_VPE2,
void __init arch_init_irq(void) { #if (defined (CONFIG_IRQ_GIC) && defined(CONFIG_MIPS_MT_SMP)) || !defined (CONFIG_IRQ_GIC) int i; #endif /* * Mask out all interrupt by writing "1" to all bit position in * the interrupt reset reg. */ #if 0 int mips_cp0_cause, mips_cp0_status; mips_cp0_cause = read_32bit_cp0_register(CP0_CAUSE); mips_cp0_status = read_32bit_cp0_register(CP0_STATUS); printk("cause = %x, status = %x\n", mips_cp0_cause, mips_cp0_status); mips_cp0_status= mips_cp0_status& ~(CAUSEF_IP0|CAUSEF_IP1|CAUSEF_IP2|CAUSEF_IP3|CAUSEF_IP4|CAUSEF_IP5|CAUSEF_IP6|CAUSEF_IP7); write_32bit_cp0_register(CP0_STATUS, mips_cp0_status); #endif mips_cpu_irq_init(); #if defined (CONFIG_IRQ_GIC) if (gcmp_present) { GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; } if (gic_present) { #if defined(CONFIG_MIPS_MT_SMP) gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; gic_resched_int_base = gic_call_int_base - NR_CPUS; fill_ipi_map(); #endif gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); #if defined(CONFIG_MIPS_MT_SMP) set_c0_status(STATUSF_IP7 | STATUSF_IP6 | STATUSF_IP5 | STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2); /* set up ipi interrupts */ for (i = 0; i < NR_CPUS; i++) { arch_init_ipiirq(MIPS_GIC_IRQ_BASE + GIC_RESCHED_INT(i), &irq_resched); arch_init_ipiirq(MIPS_GIC_IRQ_BASE + GIC_CALL_INT(i), &irq_call); } #else set_c0_status(STATUSF_IP7 | STATUSF_IP6 | STATUSF_IP5 | STATUSF_IP2); #endif } irq_set_handler(SURFBOARDINT_PCIE0, handle_level_irq); irq_set_handler(SURFBOARDINT_PCIE1, handle_level_irq); irq_set_handler(SURFBOARDINT_PCIE2, handle_level_irq); irq_set_handler(SURFBOARDINT_FE, handle_level_irq); irq_set_handler(SURFBOARDINT_USB, handle_level_irq); irq_set_handler(SURFBOARDINT_SYSCTL, handle_level_irq); irq_set_handler(SURFBOARDINT_DRAMC, handle_level_irq); irq_set_handler(SURFBOARDINT_PCM, handle_level_irq); irq_set_handler(SURFBOARDINT_HSGDMA, handle_level_irq); irq_set_handler(SURFBOARDINT_GPIO, handle_level_irq); irq_set_handler(SURFBOARDINT_DMA, handle_level_irq); irq_set_handler(SURFBOARDINT_NAND, handle_level_irq); irq_set_handler(SURFBOARDINT_I2S, handle_level_irq); irq_set_handler(SURFBOARDINT_SPI, handle_level_irq); irq_set_handler(SURFBOARDINT_SPDIF, handle_level_irq); irq_set_handler(SURFBOARDINT_CRYPTO, handle_level_irq); irq_set_handler(SURFBOARDINT_SDXC, handle_level_irq); irq_set_handler(SURFBOARDINT_PCTRL, handle_level_irq); irq_set_handler(SURFBOARDINT_ESW, handle_level_irq); irq_set_handler(SURFBOARDINT_UART_LITE1, handle_level_irq); irq_set_handler(SURFBOARDINT_UART_LITE2, handle_level_irq); irq_set_handler(SURFBOARDINT_UART_LITE3, handle_level_irq); irq_set_handler(SURFBOARDINT_NAND_ECC, handle_level_irq); irq_set_handler(SURFBOARDINT_I2C, handle_level_irq); irq_set_handler(SURFBOARDINT_WDG, handle_level_irq); irq_set_handler(SURFBOARDINT_TIMER0, handle_level_irq); irq_set_handler(SURFBOARDINT_TIMER1, handle_level_irq); #else for (i = 0; i <= SURFBOARDINT_END; i++) { irq_set_chip_and_handler(i, &surfboard_irq_type, handle_level_irq); } /* Enable global interrupt bit */ *(volatile u32 *)(RALINK_INTENA) = M_SURFBOARD_GLOBAL_INT; /* hua: 7621 uses GIC -> SURFBOARDINT_PCTRL, which is done by code above */ cp0_perfcount_irq = SURFBOARDINT_PC; set_c0_status(ST0_IM); #endif // CONFIG_IRQ_GIC // #ifdef CONFIG_RALINK_GPIO ralink_gpio_init_irq(); #endif #ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); } #endif }
static int __init of_gic_init(struct device_node *node, struct device_node *parent) { struct irq_domain *domain; struct resource gcmp = { 0 }, gic = { 0 }; unsigned int gic_rev; int i; if (of_address_to_resource(node, 0, &gic)) panic("Failed to get gic memory range"); if (request_mem_region(gic.start, resource_size(&gic), gic.name) < 0) panic("Failed to request gic memory"); if (of_address_to_resource(node, 2, &gcmp)) panic("Failed to get gic memory range"); if (request_mem_region(gcmp.start, resource_size(&gcmp), gcmp.name) < 0) panic("Failed to request gcmp memory"); _gcmp_base = (unsigned long) ioremap_nocache(gcmp.start, resource_size(&gcmp)); if (!_gcmp_base) panic("Failed to remap gcmp memory\n"); if ((GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) != gcmp.start) panic("Failed to find gcmp core\n"); /* tell the gcmp where to find the gic */ GCMPGCB(GICBA) = gic.start | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; if (cpu_has_vint) { set_vi_handler(2, gic_irqdispatch); set_vi_handler(3, gic_irqdispatch); set_vi_handler(4, gic_irqdispatch); set_vi_handler(7, vi_timer_irqdispatch); } gic_fill_map(); gic_init(gic.start, resource_size(&gic), gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); GICREAD(GIC_REG(SHARED, GIC_SH_REVISIONID), gic_rev); pr_info("gic: revision %d.%d\n", (gic_rev >> 8) & 0xff, gic_rev & 0xff); domain = irq_domain_add_legacy(node, GIC_NUM_INTRS, MIPS_GIC_IRQ_BASE, 0, &irq_domain_ops, NULL); if (!domain) panic("Failed to add irqdomain"); #if defined(CONFIG_MIPS_MT_SMP) for (i = 0; i < nr_cpu_ids; i++) { setup_irq(MIPS_GIC_IRQ_BASE + GIC_RESCHED_INT(i), &irq_resched); setup_irq(MIPS_GIC_IRQ_BASE + GIC_CALL_INT(i), &irq_call); } #endif change_c0_status(ST0_IM, STATUSF_IP7 | STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2); return 0; }