/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
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; }
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; }
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; }
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; }