예제 #1
0
void ack_brcm_irq(unsigned int irq)
{
    unsigned long flags;

    spin_lock_irqsave(&brcm_irqlock, flags);
    __disable_ack_brcm_irq(irq);

#if defined(CONFIG_SMP)
    if (irq == INTERRUPT_ID_SOFTWARE_0) {
        int this_cpu = smp_processor_id();
        int other_cpu = !this_cpu;
        per_cpu(ipi_pending, this_cpu) = 0;
        clear_c0_cause(1<<CAUSEB_IP0);
        if (per_cpu(ipi_pending, other_cpu)) {
            set_c0_cause(1<<CAUSEB_IP0);
        }
    }
#else
    if (irq == INTERRUPT_ID_SOFTWARE_0) {
        clear_c0_cause(1<<CAUSEB_IP0);
    }
#endif

    if (irq == INTERRUPT_ID_SOFTWARE_1) {
        clear_c0_cause(1<<CAUSEB_IP1);
    }

    spin_unlock_irqrestore(&brcm_irqlock, flags);
}
예제 #2
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);
}
예제 #3
0
파일: setup.c 프로젝트: 1314cc/linux
static void bcm63xx_fixup_cpu1(void)
{
	/*
	 * The bootloader has set up the CPU1 reset vector at
	 * 0xa000_0200.
	 * This conflicts with the special interrupt vector (IV).
	 * The bootloader has also set up CPU1 to respond to the wrong
	 * IPI interrupt.
	 * Here we will start up CPU1 in the background and ask it to
	 * reconfigure itself then go back to sleep.
	 */
	memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
	__sync();
	set_c0_cause(C_SW0);
	cpumask_set_cpu(1, &bmips_booted_mask);
}
예제 #4
0
파일: prom.c 프로젝트: 168519/linux
void __init prom_init(void)
{
	u32 reg, mask;

	bcm63xx_cpu_init();

	/* stop any running watchdog */
	bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
	bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);

	/* disable all hardware blocks clock for now */
	if (BCMCPU_IS_3368())
		mask = CKCTL_3368_ALL_SAFE_EN;
	else if (BCMCPU_IS_6328())
		mask = CKCTL_6328_ALL_SAFE_EN;
	else if (BCMCPU_IS_6338())
		mask = CKCTL_6338_ALL_SAFE_EN;
	else if (BCMCPU_IS_6345())
		mask = CKCTL_6345_ALL_SAFE_EN;
	else if (BCMCPU_IS_6348())
		mask = CKCTL_6348_ALL_SAFE_EN;
	else if (BCMCPU_IS_6358())
		mask = CKCTL_6358_ALL_SAFE_EN;
	else if (BCMCPU_IS_6362())
		mask = CKCTL_6362_ALL_SAFE_EN;
	else if (BCMCPU_IS_6368())
		mask = CKCTL_6368_ALL_SAFE_EN;
	else
		mask = 0;

	reg = bcm_perf_readl(PERF_CKCTL_REG);
	reg &= ~mask;
	bcm_perf_writel(reg, PERF_CKCTL_REG);

	/* register gpiochip */
	bcm63xx_gpio_init();

	/* do low level board init */
	board_prom_init();

	/* set up SMP */
	if (!register_bmips_smp_ops()) {
		/*
		 * BCM6328 might not have its second CPU enabled, while BCM3368
		 * and BCM6358 need special handling for their shared TLB, so
		 * disable SMP for now.
		 */
		if (BCMCPU_IS_6328()) {
			reg = bcm_readl(BCM_6328_OTP_BASE +
					OTP_USER_BITS_6328_REG(3));

			if (reg & OTP_6328_REG3_TP1_DISABLED)
				bmips_smp_enabled = 0;
		} else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
			bmips_smp_enabled = 0;
		}

		if (!bmips_smp_enabled)
			return;

		/*
		 * The bootloader has set up the CPU1 reset vector at
		 * 0xa000_0200.
		 * This conflicts with the special interrupt vector (IV).
		 * The bootloader has also set up CPU1 to respond to the wrong
		 * IPI interrupt.
		 * Here we will start up CPU1 in the background and ask it to
		 * reconfigure itself then go back to sleep.
		 */
		memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
		__sync();
		set_c0_cause(C_SW0);
		cpumask_set_cpu(1, &bmips_booted_mask);

		/*
		 * FIXME: we really should have some sort of hazard barrier here
		 */
	}
}