Ejemplo n.º 1
0
/* Use IRQ_SUPPLE_0 to request reschedule.
 * When returning from interrupt to user space,
 * there is chance to reschedule */
static irqreturn_t ipi_handler_int0(int irq, void *dev_instance)
{
	unsigned int cpu = smp_processor_id();

	platform_clear_ipi(cpu, IRQ_SUPPLE_0);
	return IRQ_HANDLED;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}