Exemplo n.º 1
0
Arquivo: irq.c Projeto: 08opt/linux
static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
{
	set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
	irq_enable_hazard();
	bcm63xx_external_irq_unmask(d);
	return 0;
}
Exemplo n.º 2
0
static void brcmstb_send_ipi_single(int cpu, unsigned int action)
{
    //unsigned int bit = (action == SMP_RESCHEDULE_YOURSELF) ? 0 : 1;
    unsigned int bit = cpu;
    write_c0_brcm_action(0x3000 | (bit << 8) | (cpu << 9));
    irq_enable_hazard();
}
Exemplo n.º 3
0
static void brcmstb_ack_ipi(unsigned int irq)
{
    //unsigned int bit = (irq == BRCM_IRQ_IPI0) ? 0 : 1;
    unsigned int bit = smp_processor_id();
    write_c0_brcm_action(0x2000 | (bit << 8) | (smp_processor_id() << 9));
    irq_enable_hazard();
}
Exemplo n.º 4
0
static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
{
	set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
	irq_enable_hazard();
	bcm63xx_external_irq_unmask(irq);
	return 0;
}
Exemplo n.º 5
0
static void brcmstb_ack_ipi(unsigned int action)
{
    unsigned long flags;
    spin_lock_irqsave(&ipi_lock, flags);
    clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
    irq_enable_hazard();
    spin_unlock_irqrestore(&ipi_lock, flags);
}
Exemplo n.º 6
0
static void brcmstb_send_ipi_single(int cpu, unsigned int action)
{
    unsigned long flags;
    spin_lock_irqsave(&ipi_lock, flags);
    set_c0_cause(smp_processor_id() ? C_SW0 : C_SW1);
    irq_enable_hazard();
    spin_unlock_irqrestore(&ipi_lock, flags);
}
Exemplo n.º 7
0
static inline void unmask_mips_mt_irq(unsigned int irq)
{
	unsigned int vpflags = dvpe();
	int cpu_irq = 0;

	if ((irq == SI_SWINT1_INT1) || (irq == SI_SWINT_INT1))  
		cpu_irq = 1;

	set_c0_status(0x100 << cpu_irq);
	irq_enable_hazard();
	evpe(vpflags);
}
Exemplo n.º 8
0
/* Early setup - runs on TP1 after cache probe */
static void brcmstb_init_secondary(void)
{
#if defined(CONFIG_BMIPS4380)
	unsigned long cbr = BMIPS_GET_CBR();
	unsigned long old_vec = DEV_RD(cbr + BMIPS_RELO_VECTOR_CONTROL_1);

	/* make sure the NMI vector is in kseg0 now that we've booted */
	DEV_WR_RB(cbr + BMIPS_RELO_VECTOR_CONTROL_1, old_vec & ~0x20000000);
#elif defined(CONFIG_BMIPS5000)
	write_c0_brcm_bootvec(read_c0_brcm_bootvec() & ~0x20000000);
#endif
	brcmstb_ack_ipi(0);

	write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
	/* hw irq lines 3+4 (gfap) goes to tp0 (secondary thread) */
	set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5 | ST0_IE);
	irq_enable_hazard();
}
Exemplo n.º 9
0
Arquivo: irq.c Projeto: 168519/linux
static inline void unmask_loongson_irq(struct irq_data *d)
{
	/* Workaround: UART IRQ may deliver to any core */
	if (d->irq == LOONGSON_UART_IRQ) {
		int cpu = smp_processor_id();
		int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
		int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
		u64 intenset_addr = smp_group[node_id] |
			(u64)(&LOONGSON_INT_ROUTER_INTENSET);
		u64 introuter_lpc_addr = smp_group[node_id] |
			(u64)(&LOONGSON_INT_ROUTER_LPC);

		*(volatile u32 *)intenset_addr = 1 << 10;
		*(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id);
	}

	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
	irq_enable_hazard();
}
Exemplo n.º 10
0
/*
 * Interrupt handler may be called before rtlx_init has otherwise had
 * a chance to run.
 */
static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
{
	unsigned int vpeflags;
	unsigned long flags;
	int i;

	local_irq_save(flags);
	vpeflags = dvpe();
	set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
	irq_enable_hazard();
	evpe(vpeflags);
	local_irq_restore(flags);

	for (i = 0; i < RTLX_CHANNELS; i++) {
		wake_up(&channel_wqs[i].lx_queue);
		wake_up(&channel_wqs[i].rt_queue);
	}

	return IRQ_HANDLED;
}
Exemplo n.º 11
0
/* Interrupt handler may be called before rtlx_init has otherwise had
   a chance to run.
*/
static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
{
    int i;
    unsigned int flags, vpeflags;

    /* Ought not to be strictly necessary for SMTC builds */
    local_irq_save(flags);
    vpeflags = dvpe();
    set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
    irq_enable_hazard();
    evpe(vpeflags);
    local_irq_restore(flags);

    for (i = 0; i < RTLX_CHANNELS; i++) {
        wake_up(&channel_wqs[i].lx_queue);
        wake_up(&channel_wqs[i].rt_queue);
    }

    return IRQ_HANDLED;
}
Exemplo n.º 12
0
/*
 * Route interrupts to ISR(s).
 *
 * This function is entered with the IE disabled. It can be
 * re-entered as soon as the IE is re-enabled in function
 * handle_IRQ_envet().
 */
void BCMFASTPATH
plat_irq_dispatch(struct pt_regs *regs)
{
	u32 pending, ipvec;
	uint32 flags = 0;
	int irq;

	/* Disable MIPS IRQs with pending interrupts */
	pending = read_c0_cause() & CAUSEF_IP;
	pending &= read_c0_status();
	clear_c0_status(pending);
	irq_disable_hazard();

	/* Handle MIPS timer interrupt. Re-enable MIPS IRQ7
	 * immediately after servicing the interrupt so that
	 * we can take this kind of interrupt again later
	 * while servicing other interrupts.
	 */
	if (pending & CAUSEF_IP7) {
		do_IRQ(7);
		pending &= ~CAUSEF_IP7;
		set_c0_status(STATUSF_IP7);
		irq_enable_hazard();
	}

	/* Build bitvec for pending interrupts. Start with
	 * MIPS IRQ2 and add linux IRQs to higher bits to
	 * make the interrupt processing uniform.
	 */
	ipvec = pending >> CAUSEB_IP2;
	if (pending & CAUSEF_IP2) {
		if (ccsbr)
			flags = R_REG(NULL, &ccsbr->sbflagst);

		/* Read intstatus */
		if (mips_corereg)
			flags = R_REG(NULL, &((mips74kregs_t *)mips_corereg)->intstatus);

		flags &= shints;
		ipvec |= flags << SBMIPS_VIRTIRQ_BASE;
	}

#ifdef CONFIG_HND_BMIPS3300_PROF
	/* Handle MIPS core interrupt. Re-enable the MIPS IRQ that
	 * MIPS core is assigned to immediately after servicing the
	 * interrupt so that we can take this kind of interrupt again
	 * later while servicing other interrupts.
	 *
	 * mipsirq < 0 indicates MIPS core IRQ # is unknown.
	 */
	if (mipsirq >= 0 && (ipvec & (1 << mipsirq))) {
		/* MIPS core raised the interrupt on the shared MIPS IRQ2.
		 * Make sure MIPS core is the only interrupt source before
		 * re-enabling the IRQ.
		 */
		if (mipsirq >= SBMIPS_VIRTIRQ_BASE) {
			if (flags == (1 << (mipsirq-SBMIPS_VIRTIRQ_BASE))) {
				irq = mipsirq + 2;
				do_IRQ(irq);
				ipvec &= ~(1 << mipsirq);
				pending &= ~CAUSEF_IP2;
				set_c0_status(STATUSF_IP2);
				irq_enable_hazard();
			}
		}
		/* MIPS core raised the interrupt on a dedicated MIPS IRQ.
		 * Re-enable the IRQ immediately.
		 */
		else {
			irq = mipsirq + 2;
			do_IRQ(irq);
			ipvec &= ~(1 << mipsirq);
			pending &= ~CR_IP(irq);
			set_c0_status(SR_IM(irq));
			irq_enable_hazard();
		}
	}
#endif	/* CONFIG_HND_BMIPS3300_PROF */

        /* Shared interrupt bits are shifted to respective bit positions in
	 * ipvec above. IP2 (bit 0) is of no significance, hence shifting the
	 * bit map by 1 to the right.
	 */
	ipvec >>= 1;

	/* Handle all other interrupts. Re-enable disabled MIPS IRQs
	 * after processing all pending interrupts.
	 */
	for (irq = 3; ipvec != 0; irq++) {
		if (ipvec & 1)
			do_IRQ(irq);
		ipvec >>= 1;
	}
	set_c0_status(pending);
	irq_enable_hazard();

#if 0
	/* Process any pending softirqs (tasklets, softirqs ...) */
	local_irq_save(flags);
	if (local_softirq_pending() && !in_interrupt())
		__do_softirq();
	local_irq_restore(flags);
#endif
}
Exemplo n.º 13
0
irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
{
#ifdef CONFIG_SMP
	int cpu = smp_processor_id();

	/*
	 * CPU 0 handles the global timer interrupt job
	 * resets count/compare registers to trigger next timer int.
	 */
#ifndef CONFIG_MIPS_MT_SMTC
	if (cpu == 0) {
		timer_interrupt(irq, dev_id);
	} else {
		/* Everyone else needs to reset the timer int here as
		   ll_local_timer_interrupt doesn't */
		/*
		 * FIXME: need to cope with counter underflow.
		 * More support needs to be added to kernel/time for
		 * counter/timer interrupts on multiple CPU's
		 */
		write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
	}
#else /* SMTC */
	/*
	 *  In SMTC system, one Count/Compare set exists per VPE.
	 *  Which TC within a VPE gets the interrupt is essentially
	 *  random - we only know that it shouldn't be one with
	 *  IXMT set. Whichever TC gets the interrupt needs to
	 *  send special interprocessor interrupts to the other
	 *  TCs to make sure that they schedule, etc.
	 *
	 *  That code is specific to the SMTC kernel, not to
	 *  the simulation platform, so it's invoked from
	 *  the general MIPS timer_interrupt routine.
	 *
	 * We have a problem in that the interrupt vector code
	 * had to turn off the timer IM bit to avoid redundant
	 * entries, but we may never get to mips_cpu_irq_end
	 * to turn it back on again if the scheduler gets
	 * involved.  So we clear the pending timer here,
	 * and re-enable the mask...
	 */

	int vpflags = dvpe();
	write_c0_compare (read_c0_count() - 1);
	clear_c0_cause(0x100 << cp0_compare_irq);
	set_c0_status(0x100 << cp0_compare_irq);
	irq_enable_hazard();
	evpe(vpflags);

	if (cpu_data[cpu].vpe_id == 0)
		timer_interrupt(irq, dev_id);
	else
		write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
	smtc_timer_broadcast(cpu_data[cpu].vpe_id);

#endif /* CONFIG_MIPS_MT_SMTC */

	/*
	 * every CPU should do profiling and process accounting
	 */
	local_timer_interrupt (irq, dev_id);

	return IRQ_HANDLED;
#else
	return timer_interrupt (irq, dev_id);
#endif
}
Exemplo n.º 14
0
static void brcmstb_send_ipi_single(int cpu, unsigned int action)
{
	unsigned int bit = cpu;
	write_c0_brcm_action(0x3000 | (bit << 8) | (cpu << 9));
	irq_enable_hazard();
}
Exemplo n.º 15
0
static inline void unmask_mips_irq(unsigned int irq)
{
	set_c0_status(0x100 << (irq - mips_cpu_irq_base));
	irq_enable_hazard();
}
Exemplo n.º 16
0
static void brcmstb_ack_ipi(unsigned int irq)
{
	unsigned int bit = smp_processor_id();
	write_c0_brcm_action(0x2000 | (bit << 8) | (smp_processor_id() << 9));
	irq_enable_hazard();
}
Exemplo n.º 17
0
static inline void unmask_mips_irq(struct irq_data *d)
{
	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
	irq_enable_hazard();
}
Exemplo n.º 18
0
static inline void unmask_mips_irq(unsigned int irq)
{
	set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE));
	irq_enable_hazard();
}
Exemplo n.º 19
0
/* Control functions for MIPS IRQ0 to IRQ7 */
static INLINE void
enable_brcm_irq(unsigned int irq)
{
	set_c0_status(SR_IM(irq));
	irq_enable_hazard();
}