static void crash_kexec_stop_spus(void) { struct spu *spu; int i; u64 tmp; for (i = 0; i < CRASH_NUM_SPUS; i++) { if (!crash_spu_info[i].spu) continue; spu = crash_spu_info[i].spu; crash_spu_info[i].saved_spu_runcntl_RW = in_be32(&spu->problem->spu_runcntl_RW); crash_spu_info[i].saved_spu_status_R = in_be32(&spu->problem->spu_status_R); crash_spu_info[i].saved_spu_npc_RW = in_be32(&spu->problem->spu_npc_RW); crash_spu_info[i].saved_mfc_dar = spu_mfc_dar_get(spu); crash_spu_info[i].saved_mfc_dsisr = spu_mfc_dsisr_get(spu); tmp = spu_mfc_sr1_get(spu); crash_spu_info[i].saved_mfc_sr1_RW = tmp; tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; spu_mfc_sr1_set(spu, tmp); __delay(200); } }
static irqreturn_t spu_irq_class_1(int irq, void *data, struct pt_regs *regs) { struct spu *spu; unsigned long stat, mask, dar, dsisr; spu = data; /* atomically read & clear class1 status. */ spin_lock(&spu->register_lock); mask = spu_int_mask_get(spu, 1); stat = spu_int_stat_get(spu, 1) & mask; dar = spu_mfc_dar_get(spu); dsisr = spu_mfc_dsisr_get(spu); if (stat & 2) /* mapping fault */ spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); spin_unlock(&spu->register_lock); pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, dar, dsisr); if (stat & 1) /* segment fault */ __spu_trap_data_seg(spu, dar); if (stat & 2) { /* mapping fault */ __spu_trap_data_map(spu, dar, dsisr); } if (stat & 4) /* ls compare & suspend on get */ ; if (stat & 8) /* ls compare & suspend on put */ ; return stat ? IRQ_HANDLED : IRQ_NONE; }