Exemplo n.º 1
0
/*
 * Main handler for inter-processor interrupts
 */
void handle_IPI(int ipinr, struct pt_regs *regs)
{
	unsigned int cpu = smp_processor_id();
	struct pt_regs *old_regs = set_irq_regs(regs);

	if ((unsigned)ipinr < NR_IPI) {
		trace_ipi_entry_rcuidle(ipi_types[ipinr]);
		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
	}

	switch (ipinr) {
	case IPI_RESCHEDULE:
		scheduler_ipi();
		break;

	case IPI_CALL_FUNC:
		irq_enter();
		generic_smp_call_function_interrupt();
		irq_exit();
		break;

	case IPI_CPU_STOP:
		irq_enter();
		ipi_cpu_stop(cpu);
		irq_exit();
		break;

#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
	case IPI_TIMER:
		irq_enter();
		tick_receive_broadcast();
		irq_exit();
		break;
#endif

#ifdef CONFIG_IRQ_WORK
	case IPI_IRQ_WORK:
		irq_enter();
		irq_work_run();
		irq_exit();
		break;
#endif

#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
	case IPI_WAKEUP:
		WARN_ONCE(!acpi_parking_protocol_valid(cpu),
			  "CPU%u: Wake-up IPI outside the ACPI parking protocol\n",
			  cpu);
		break;
#endif

	default:
		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
		break;
	}

	if ((unsigned)ipinr < NR_IPI)
		trace_ipi_exit_rcuidle(ipi_types[ipinr]);
	set_irq_regs(old_regs);
}
Exemplo n.º 2
0
/*
 * Main handler for inter-processor interrupts
 */
void handle_IPI(int ipinr, struct pt_regs *regs)
{
    unsigned int cpu = smp_processor_id();
    struct pt_regs *old_regs = set_irq_regs(regs);

    if ((unsigned)ipinr < NR_IPI) {
        trace_ipi_entry(ipi_types[ipinr]);
        __inc_irq_stat(cpu, ipi_irqs[ipinr]);
    }

    switch (ipinr) {
    case IPI_RESCHEDULE:
        scheduler_ipi();
        break;

    case IPI_CALL_FUNC:
        irq_enter();
        generic_smp_call_function_interrupt();
        irq_exit();
        break;

    case IPI_CALL_FUNC_SINGLE:
        irq_enter();
        generic_smp_call_function_single_interrupt();
        irq_exit();
        break;

    case IPI_CPU_STOP:
        irq_enter();
        ipi_cpu_stop(cpu);
        irq_exit();
        break;

#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
    case IPI_TIMER:
        irq_enter();
        tick_receive_broadcast();
        irq_exit();
        break;
#endif

#ifdef CONFIG_IRQ_WORK
    case IPI_IRQ_WORK:
        irq_enter();
        irq_work_run();
        irq_exit();
        break;
#endif

    default:
        pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
        break;
    }

    if ((unsigned)ipinr < NR_IPI)
        trace_ipi_exit(ipi_types[ipinr]);
    set_irq_regs(old_regs);
}
Exemplo n.º 3
0
/*
 * Main handler for inter-processor interrupts
 */
void handle_IPI(int ipinr, struct pt_regs *regs)
{
	unsigned int cpu = smp_processor_id();
	struct pt_regs *old_regs = set_irq_regs(regs);

	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);

	exynos_ss_irq(ipinr, handle_IPI, irqs_disabled(), ESS_FLAG_IN);

	switch (ipinr) {
	case IPI_RESCHEDULE:
		scheduler_ipi();
		break;

	case IPI_CALL_FUNC:
		irq_enter();
		generic_smp_call_function_interrupt();
		irq_exit();
		break;

	case IPI_CALL_FUNC_SINGLE:
		irq_enter();
		generic_smp_call_function_single_interrupt();
		irq_exit();
		break;

	case IPI_CPU_STOP:
		irq_enter();
		ipi_cpu_stop(cpu, regs);
		irq_exit();
		break;

#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
	case IPI_TIMER:
		irq_enter();
		tick_receive_broadcast();
		irq_exit();
		break;
#endif
	case IPI_WAKEUP:
		break;
	default:
		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
		break;
	}
	exynos_ss_irq(ipinr, handle_IPI, irqs_disabled(), ESS_FLAG_OUT);

	set_irq_regs(old_regs);
}
Exemplo n.º 4
0
/*
 * Main handler for inter-processor interrupts
 */
void handle_IPI(int ipinr, struct pt_regs *regs)
{
	unsigned int cpu = smp_processor_id();
	struct pt_regs *old_regs = set_irq_regs(regs);

	if ((unsigned)ipinr < NR_IPI) {
		trace_ipi_entry(ipi_types[ipinr]);
		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
	}

	switch (ipinr) {
	case IPI_RESCHEDULE:
		scheduler_ipi();
		break;

	case IPI_CALL_FUNC:
		irq_enter();
        mt_trace_ISR_start(ipinr);
		generic_smp_call_function_interrupt();
        mt_trace_ISR_end(ipinr);
		irq_exit();
		break;

	case IPI_CALL_FUNC_SINGLE:
		irq_enter();
        mt_trace_ISR_start(ipinr);
		generic_smp_call_function_single_interrupt();
        mt_trace_ISR_end(ipinr);
		irq_exit();
		break;

	case IPI_CPU_STOP:
		irq_enter();
        mt_trace_ISR_start(ipinr);
		ipi_cpu_stop(cpu);
        mt_trace_ISR_end(ipinr);
		irq_exit();
		break;

	default:
		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
		break;
	}

	if ((unsigned)ipinr < NR_IPI)
		trace_ipi_exit(ipi_types[ipinr]);
	set_irq_regs(old_regs);
}
Exemplo n.º 5
0
static irqreturn_t ipi_handler(int irq, void *dev_instance)
{
	struct ipi_message *msg;
	struct ipi_message_queue *msg_queue;
	unsigned int cpu = smp_processor_id();

	platform_clear_ipi(cpu);

	msg_queue = &__get_cpu_var(ipi_msg_queue);
	msg_queue->count++;

	spin_lock(&msg_queue->lock);
	while (!list_empty(&msg_queue->head)) {
		msg = list_entry(msg_queue->head.next, typeof(*msg), list);
		list_del(&msg->list);
		switch (msg->type) {
		case BFIN_IPI_RESCHEDULE:
			/* That's the easiest one; leave it to
			 * return_from_int. */
			kfree(msg);
			break;
		case BFIN_IPI_CALL_FUNC:
			spin_unlock(&msg_queue->lock);
			ipi_call_function(cpu, msg);
			spin_lock(&msg_queue->lock);
			break;
		case BFIN_IPI_CPU_STOP:
			spin_unlock(&msg_queue->lock);
			ipi_cpu_stop(cpu);
			spin_lock(&msg_queue->lock);
			kfree(msg);
			break;
		default:
			printk(KERN_CRIT "CPU%u: Unknown IPI message \
			0x%lx\n", cpu, msg->type);
			kfree(msg);
			break;
		}
	}
	spin_unlock(&msg_queue->lock);
	return IRQ_HANDLED;
}
Exemplo n.º 6
0
static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
{
	struct ipi_data *bfin_ipi_data;
	unsigned int cpu = smp_processor_id();
	unsigned long pending;
	unsigned long msg;

	platform_clear_ipi(cpu, IRQ_SUPPLE_1);

	bfin_ipi_data = &__get_cpu_var(bfin_ipi);
	smp_mb();
	while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
		msg = 0;
		do {
			msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1);
			switch (msg) {
			case BFIN_IPI_TIMER:
				ipi_timer();
				break;
			case BFIN_IPI_RESCHEDULE:
				scheduler_ipi();
				break;
			case BFIN_IPI_CALL_FUNC:
				generic_smp_call_function_interrupt();
				break;

			case BFIN_IPI_CALL_FUNC_SINGLE:
				generic_smp_call_function_single_interrupt();
				break;

			case BFIN_IPI_CPU_STOP:
				ipi_cpu_stop(cpu);
				break;
			}
		} while (msg < BITS_PER_LONG);

		smp_mb();
	}
	return IRQ_HANDLED;
}
Exemplo n.º 7
0
static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
{
	struct ipi_message *msg;
	struct ipi_message_queue *msg_queue;
	unsigned int cpu = smp_processor_id();
	unsigned long flags;

	platform_clear_ipi(cpu, IRQ_SUPPLE_1);

	msg_queue = &__get_cpu_var(ipi_msg_queue);

	spin_lock_irqsave(&msg_queue->lock, flags);

	while (msg_queue->count) {
		msg = &msg_queue->ipi_message[msg_queue->head];
		switch (msg->type) {
		case BFIN_IPI_CALL_FUNC:
			spin_unlock_irqrestore(&msg_queue->lock, flags);
			ipi_call_function(cpu, msg);
			spin_lock_irqsave(&msg_queue->lock, flags);
			break;
		case BFIN_IPI_CPU_STOP:
			spin_unlock_irqrestore(&msg_queue->lock, flags);
			ipi_cpu_stop(cpu);
			spin_lock_irqsave(&msg_queue->lock, flags);
			break;
		default:
			printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n",
			       cpu, msg->type);
			break;
		}
		msg_queue->head++;
		msg_queue->head %= BFIN_IPI_MSGQ_LEN;
		msg_queue->count--;
	}
	spin_unlock_irqrestore(&msg_queue->lock, flags);
	return IRQ_HANDLED;
}
Exemplo n.º 8
0
static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
{
	struct ipi_data *bfin_ipi_data;
	unsigned int cpu = smp_processor_id();
	unsigned long pending;
	unsigned long msg;

	platform_clear_ipi(cpu, IRQ_SUPPLE_1);

	smp_rmb();
	bfin_ipi_data = this_cpu_ptr(&bfin_ipi);
	while ((pending = atomic_xchg(&bfin_ipi_data->bits, 0)) != 0) {
		msg = 0;
		do {
			msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1);
			switch (msg) {
			case BFIN_IPI_TIMER:
				ipi_timer();
				break;
			case BFIN_IPI_RESCHEDULE:
				scheduler_ipi();
				break;
			case BFIN_IPI_CALL_FUNC:
				generic_smp_call_function_interrupt();
				break;
			case BFIN_IPI_CPU_STOP:
				ipi_cpu_stop(cpu);
				break;
			default:
				goto out;
			}
			atomic_dec(&bfin_ipi_data->count);
		} while (msg < BITS_PER_LONG);

	}
out:
	return IRQ_HANDLED;
}