cregit-Linux how code gets into the kernel

Release 4.11 arch/mips/pmcs-msp71xx/msp_irq_cic.c

/*
 * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
 *
 * This file define the irq handler for MSP CIC subsystem interrupts.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/irq.h>

#include <asm/mipsregs.h>

#include <msp_cic_int.h>
#include <msp_regs.h>

/*
 * External API
 */
extern void msp_per_irq_init(void);
extern void msp_per_irq_dispatch(void);


/*
 * Convenience Macro.  Should be somewhere generic.
 */

#define get_current_vpe()   \
	((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)

#ifdef CONFIG_SMP


#define LOCK_VPE(flags, mtflags) \
do {                            \
        local_irq_save(flags);  \
        mtflags = dmt();        \
} while (0)


#define UNLOCK_VPE(flags, mtflags) \
do {                            \
        emt(mtflags);           \
        local_irq_restore(flags);\
} while (0)


#define LOCK_CORE(flags, mtflags) \
do {                            \
        local_irq_save(flags);  \
        mtflags = dvpe();       \
} while (0)


#define UNLOCK_CORE(flags, mtflags)		\
do {                            \
        evpe(mtflags);          \
        local_irq_restore(flags);\
} while (0)

#else


#define LOCK_VPE(flags, mtflags)

#define UNLOCK_VPE(flags, mtflags)
#endif

/* ensure writes to cic are completed */

static inline void cic_wmb(void) { const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG; volatile u32 dummy_read; wmb(); dummy_read = __raw_readl(cic_mem); dummy_read++; }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A3291.43%150.00%
Marc St-Jean38.57%150.00%
Total35100.00%2100.00%


static void unmask_cic_irq(struct irq_data *d) { volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; int vpe; #ifdef CONFIG_SMP unsigned int mtflags; unsigned long flags; /* * Make sure we have IRQ affinity. It may have changed while * we were processing the IRQ. */ if (!cpumask_test_cpu(smp_processor_id(), irq_data_get_affinity_mask(d))) return; #endif vpe = get_current_vpe(); LOCK_VPE(flags, mtflags); cic_msk_reg[vpe] |= (1 << (d->irq - MSP_CIC_INTBASE)); UNLOCK_VPE(flags, mtflags); cic_wmb(); }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A6067.42%125.00%
Marc St-Jean1921.35%125.00%
Thomas Gleixner77.87%125.00%
Jiang Liu33.37%125.00%
Total89100.00%4100.00%


static void mask_cic_irq(struct irq_data *d) { volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; int vpe = get_current_vpe(); #ifdef CONFIG_SMP unsigned long flags, mtflags; #endif LOCK_VPE(flags, mtflags); cic_msk_reg[vpe] &= ~(1 << (d->irq - MSP_CIC_INTBASE)); UNLOCK_VPE(flags, mtflags); cic_wmb(); }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A4462.86%133.33%
Marc St-Jean2028.57%133.33%
Thomas Gleixner68.57%133.33%
Total70100.00%3100.00%


static void msp_cic_irq_ack(struct irq_data *d) { mask_cic_irq(d); /* * Only really necessary for 18, 16-14 and sometimes 3:0 * (since these can be edge sensitive) but it doesn't * hurt for the others */ *CIC_STS_REG = (1 << (d->irq - MSP_CIC_INTBASE)); }

Contributors

PersonTokensPropCommitsCommitProp
Marc St-Jean2165.62%133.33%
Thomas Gleixner721.88%133.33%
Anoop P A412.50%133.33%
Total32100.00%3100.00%

/* Note: Limiting to VSMP. */ #ifdef CONFIG_MIPS_MT_SMP
static int msp_cic_irq_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force) { int cpu; unsigned long flags; unsigned int mtflags; unsigned long imask = (1 << (d->irq - MSP_CIC_INTBASE)); volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG; /* timer balancing should be disabled in kernel code */ BUG_ON(d->irq == MSP_INT_VPE0_TIMER || d->irq == MSP_INT_VPE1_TIMER); LOCK_CORE(flags, mtflags); /* enable if any of each VPE's TCs require this IRQ */ for_each_online_cpu(cpu) { if (cpumask_test_cpu(cpu, cpumask)) cic_mask[cpu] |= imask; else cic_mask[cpu] &= ~imask; } UNLOCK_CORE(flags, mtflags); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Anoop P A10181.45%125.00%
Marc St-Jean108.06%125.00%
Thomas Gleixner75.65%125.00%
Stefan Hengelein64.84%125.00%
Total124100.00%4100.00%

#endif static struct irq_chip msp_cic_irq_controller = { .name = "MSP_CIC", .irq_mask = mask_cic_irq, .irq_mask_ack = msp_cic_irq_ack, .irq_unmask = unmask_cic_irq, .irq_ack = msp_cic_irq_ack, #ifdef CONFIG_MIPS_MT_SMP .irq_set_affinity = msp_cic_irq_set_affinity, #endif };
void __init msp_cic_irq_init(void) { int i; /* Mask/clear interrupts. */ *CIC_VPE0_MSK_REG = 0x00000000; *CIC_VPE1_MSK_REG = 0x00000000; *CIC_STS_REG = 0xFFFFFFFF; /* * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI. * These inputs map to EXT_INT_POL[6:4] inside the CIC. * They are to be active low, level sensitive. */ *CIC_EXT_CFG_REG &= 0xFFFF8F8F; /* initialize all the IRQ descriptors */ for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) { irq_set_chip_and_handler(i, &msp_cic_irq_controller, handle_level_irq); } /* Initialize the PER interrupt sub-system */ msp_per_irq_init(); }

Contributors

PersonTokensPropCommitsCommitProp
Marc St-Jean5584.62%133.33%
Anoop P A913.85%133.33%
Thomas Gleixner11.54%133.33%
Total65100.00%3100.00%

/* CIC masked by CIC vector processing before dispatch called */
void msp_cic_irq_dispatch(void) { volatile u32 *cic_msk_reg = (volatile u32 *)CIC_VPE0_MSK_REG; u32 cic_mask; u32 pending; int cic_status = *CIC_STS_REG; cic_mask = cic_msk_reg[get_current_vpe()]; pending = cic_status & cic_mask; if (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))) { do_IRQ(MSP_INT_VPE0_TIMER); } else if (pending & (1 << (MSP_INT_VPE1_TIMER - MSP_CIC_INTBASE))) { do_IRQ(MSP_INT_VPE1_TIMER); } else if (pending & (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) { msp_per_irq_dispatch(); } else if (pending) { do_IRQ(ffs(pending) + MSP_CIC_INTBASE - 1); } else{ spurious_interrupt(); } }

Contributors

PersonTokensPropCommitsCommitProp
Marc St-Jean6951.88%150.00%
Anoop P A6448.12%150.00%
Total133100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Anoop P A42760.23%111.11%
Marc St-Jean23533.15%111.11%
Thomas Gleixner334.65%222.22%
Stefan Hengelein60.85%111.11%
Jiang Liu30.42%111.11%
David Howells30.42%111.11%
Ralf Bächle20.28%222.22%
Total709100.00%9100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.