cregit-Linux how code gets into the kernel

Release 4.8 arch/mips/mti-malta/malta-int.c

/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Carsten Langgaard, carstenl@mips.com
 * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
 * Copyright (C) 2001 Ralf Baechle
 * Copyright (C) 2013 Imagination Technologies Ltd.
 *
 * Routines for generic manipulation of the interrupts found on the MIPS
 * Malta board. The interrupt controller is located in the South Bridge
 * a PIIX4 device with two internal 82C95 interrupt controllers.
 */
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irqchip/mips-gic.h>
#include <linux/kernel_stat.h>
#include <linux/kernel.h>
#include <linux/random.h>

#include <asm/traps.h>
#include <asm/i8259.h>
#include <asm/irq_cpu.h>
#include <asm/irq_regs.h>
#include <asm/mips-cm.h>
#include <asm/mips-boards/malta.h>
#include <asm/mips-boards/maltaint.h>
#include <asm/gt64120.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/msc01_pci.h>
#include <asm/msc01_ic.h>
#include <asm/setup.h>
#include <asm/rtlx.h>


static void __iomem *_msc01_biu_base;

static DEFINE_RAW_SPINLOCK(mips_irq_lock);


static inline int mips_pcibios_iack(void) { int irq; /* * Determine highest priority pending interrupt by performing * a PCI Interrupt Acknowledge cycle. */ switch (mips_revision_sconid) { case MIPS_REVISION_SCON_SOCIT: case MIPS_REVISION_SCON_ROCIT: case MIPS_REVISION_SCON_SOCITSC: case MIPS_REVISION_SCON_SOCITSCP: MSC_READ(MSC01_PCI_IACK, irq); irq &= 0xff; break; case MIPS_REVISION_SCON_GT64120: irq = GT_READ(GT_PCI0_IACK_OFS); irq &= 0xff; break; case MIPS_REVISION_SCON_BONITO: /* The following will generate a PCI IACK cycle on the * Bonito controller. It's a little bit kludgy, but it * was the easiest way to implement it in hardware at * the given time. */ BONITO_PCIMAP_CFG = 0x20000; /* Flush Bonito register block */ (void) BONITO_PCIMAP_CFG; iob(); /* sync */ irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); iob(); /* sync */ irq &= 0xff; BONITO_PCIMAP_CFG = 0; break; default: pr_emerg("Unknown system controller.\n"); return -1; } return irq; }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton9684.96%114.29%
chris dearmanchris dearman97.96%228.57%
ralf baechleralf baechle76.19%342.86%
steven j. hillsteven j. hill10.88%114.29%
Total113100.00%7100.00%


static inline int get_int(void) { unsigned long flags; int irq; raw_spin_lock_irqsave(&mips_irq_lock, flags); irq = mips_pcibios_iack(); /* * The only way we can decide if an interrupt is spurious * is by checking the 8259 registers. This needs a spinlock * on an SMP system, so leave it up to the generic code... */ raw_spin_unlock_irqrestore(&mips_irq_lock, flags); return irq; }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle3482.93%457.14%
linus torvaldslinus torvalds614.63%228.57%
pre-gitpre-git12.44%114.29%
Total41100.00%7100.00%


static void malta_hw0_irqdispatch(void) { int irq; irq = get_int(); if (irq < 0) { /* interrupt has already been cleared */ return; } do_IRQ(MALTA_INT_BASE + irq); #ifdef CONFIG_MIPS_VPE_APSP_API_MT if (aprp_hook) aprp_hook(); #endif }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle2657.78%550.00%
deng-cheng zhudeng-cheng zhu1226.67%220.00%
pre-gitpre-git48.89%110.00%
linus torvaldslinus torvalds24.44%110.00%
dmitri vorobievdmitri vorobiev12.22%110.00%
Total45100.00%10100.00%


static irqreturn_t i8259_handler(int irq, void *dev_id) { malta_hw0_irqdispatch(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
andrew brestickerandrew bresticker1157.89%133.33%
ralf baechleralf baechle736.84%133.33%
jeffrey deansjeffrey deans15.26%133.33%
Total19100.00%3100.00%


static void corehi_irqdispatch(void) { unsigned int intedge, intsteer, pcicmd, pcibadaddr; unsigned int pcimstat, intisr, inten, intpol; unsigned int intrcause, datalo, datahi; struct pt_regs *regs = get_irq_regs(); pr_emerg("CoreHI interrupt, shouldn't happen, we die here!\n"); pr_emerg("epc : %08lx\nStatus: %08lx\n" "Cause : %08lx\nbadVaddr : %08lx\n", regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); /* Read all the registers and then print them as there is a problem with interspersed printk's upsetting the Bonito controller. Do it for the others too. */ switch (mips_revision_sconid) { case MIPS_REVISION_SCON_SOCIT: case MIPS_REVISION_SCON_ROCIT: case MIPS_REVISION_SCON_SOCITSC: case MIPS_REVISION_SCON_SOCITSCP: ll_msc_irq(); break; case MIPS_REVISION_SCON_GT64120: intrcause = GT_READ(GT_INTRCAUSE_OFS); datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); pr_emerg("GT_INTRCAUSE = %08x\n", intrcause); pr_emerg("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); break; case MIPS_REVISION_SCON_BONITO: pcibadaddr = BONITO_PCIBADADDR; pcimstat = BONITO_PCIMSTAT; intisr = BONITO_INTISR; inten = BONITO_INTEN; intpol = BONITO_INTPOL; intedge = BONITO_INTEDGE; intsteer = BONITO_INTSTEER; pcicmd = BONITO_PCICMD; pr_emerg("BONITO_INTISR = %08x\n", intisr); pr_emerg("BONITO_INTEN = %08x\n", inten); pr_emerg("BONITO_INTPOL = %08x\n", intpol); pr_emerg("BONITO_INTEDGE = %08x\n", intedge); pr_emerg("BONITO_INTSTEER = %08x\n", intsteer); pr_emerg("BONITO_PCICMD = %08x\n", pcicmd); pr_emerg("BONITO_PCIBADADDR = %08x\n", pcibadaddr); pr_emerg("BONITO_PCIMSTAT = %08x\n", pcimstat); break; } die("CoreHi interrupt", regs); }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle20487.18%763.64%
steven j. hillsteven j. hill125.13%19.09%
andrew mortonandrew morton104.27%19.09%
chris dearmanchris dearman72.99%19.09%
dmitri vorobievdmitri vorobiev10.43%19.09%
Total234100.00%11100.00%


static irqreturn_t corehi_handler(int irq, void *dev_id) { corehi_irqdispatch(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
andrew brestickerandrew bresticker19100.00%1100.00%
Total19100.00%1100.00%

#ifdef CONFIG_MIPS_MT_SMP #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ #define C_RESCHED C_SW0 #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ #define C_CALL C_SW1 static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
static void ipi_resched_dispatch(void) { do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle15100.00%1100.00%
Total15100.00%1100.00%


static void ipi_call_dispatch(void) { do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle15100.00%1100.00%
Total15100.00%1100.00%


static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) { #ifdef CONFIG_MIPS_VPE_APSP_API_CMP if (aprp_hook) aprp_hook(); #endif scheduler_ipi(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle1651.61%125.00%
deng-cheng zhudeng-cheng zhu1238.71%250.00%
peter zijlstrapeter zijlstra39.68%125.00%
Total31100.00%4100.00%


static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) { generic_smp_call_function_interrupt(); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle1894.74%150.00%
alex smithalex smith15.26%150.00%
Total19100.00%2100.00%

static struct irqaction irq_resched = { .handler = ipi_resched_interrupt, .flags = IRQF_PERCPU, .name = "IPI_resched" }; static struct irqaction irq_call = { .handler = ipi_call_interrupt, .flags = IRQF_PERCPU, .name = "IPI_call" }; #endif /* CONFIG_MIPS_MT_SMP */ static struct irqaction i8259irq = { .handler = i8259_handler, .name = "XT-PIC cascade", .flags = IRQF_NO_THREAD, }; static struct irqaction corehi_irqaction = { .handler = corehi_handler, .name = "CoreHi", .flags = IRQF_NO_THREAD, }; static msc_irqmap_t msc_irqmap[] __initdata = { {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, }; static int msc_nr_irqs __initdata = ARRAY_SIZE(msc_irqmap); static msc_irqmap_t msc_eicirqmap[] __initdata = { {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} }; static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap);
void __init arch_init_ipiirq(int irq, struct irqaction *action) { setup_irq(irq, action); irq_set_handler(irq, handle_percpu_irq); }

Contributors

PersonTokensPropCommitsCommitProp
andrew brestickerandrew bresticker2589.29%125.00%
ralf baechleralf baechle27.14%250.00%
chris dearmanchris dearman13.57%125.00%
Total28100.00%4100.00%


void __init arch_init_irq(void) { int corehi_irq, i8259_irq; init_i8259_irqs(); if (!cpu_has_veic) mips_cpu_irq_init(); if (mips_cm_present()) { write_gcr_gic_base(GIC_BASE_ADDR | CM_GCR_GIC_BASE_GICEN_MSK); gic_present = 1; } else { if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); gic_present = (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) & MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; } } if (gic_present) pr_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 (gic_present) { int i; gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC, MIPS_GIC_IRQ_BASE); if (!mips_cm_present()) { /* Enable the GIC */ i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS); __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF), _msc01_biu_base + MSC01_SC_CFG_OFS); pr_debug("GIC Enabled\n"); } i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } else { #if defined(CONFIG_MIPS_MT_SMP) /* set up ipi interrupts */ if (cpu_has_veic) { set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); cpu_ipi_resched_irq = MSC01E_INT_SW0; cpu_ipi_call_irq = MSC01E_INT_SW1; } else { cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; } arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); #endif if (cpu_has_veic) { set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A; corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI; } else { i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A; corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } } setup_irq(i8259_irq, &i8259irq); setup_irq(corehi_irq, &corehi_irqaction); }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle20456.20%116.67%
andrew brestickerandrew bresticker13436.91%233.33%
chris dearmanchris dearman102.75%116.67%
jaidev patwardhanjaidev patwardhan82.20%116.67%
paul burtonpaul burton71.93%116.67%
Total363100.00%6100.00%


void malta_be_init(void) { /* Could change CM error mask register. */ }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle787.50%150.00%
steven j. hillsteven j. hill112.50%150.00%
Total8100.00%2100.00%


int malta_be_handler(struct pt_regs *regs, int is_fixup) { /* This duplicates the handling in do_be which seems wrong */ int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; mips_cm_error_report(); return retval; }

Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle2689.66%125.00%
paul burtonpaul burton13.45%125.00%
markos chandrasmarkos chandras13.45%125.00%
kevin d. kissellkevin d. kissell13.45%125.00%
Total29100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
ralf baechleralf baechle83663.77%1433.33%
andrew brestickerandrew bresticker19815.10%37.14%
andrew mortonandrew morton1118.47%12.38%
pre-gitpre-git292.21%12.38%
deng-cheng zhudeng-cheng zhu272.06%24.76%
chris dearmanchris dearman272.06%37.14%
steven j. hillsteven j. hill191.45%12.38%
wu zhangjinwu zhangjin120.92%12.38%
paul burtonpaul burton110.84%12.38%
dmitri vorobievdmitri vorobiev90.69%49.52%
linus torvaldslinus torvalds90.69%24.76%
jaidev patwardhanjaidev patwardhan80.61%12.38%
ahmed s. darwishahmed s. darwish50.38%12.38%
peter zijlstrapeter zijlstra30.23%12.38%
raghu gandhamraghu gandham20.15%12.38%
alex smithalex smith10.08%12.38%
jeffrey deansjeffrey deans10.08%12.38%
markos chandrasmarkos chandras10.08%12.38%
david howellsdavid howells10.08%12.38%
kevin d. kissellkevin d. kissell10.08%12.38%
Total1311100.00%42100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.