int ykbec_suspend() { struct ykbec_softc *sc = ykbec_sc; int ctrl; /* * Set up wakeup sources: currently only the internal keyboard. */ loongson_set_isa_imr(1 << 1); /* USB */ DPRINTF(("USB\n")); ykbec_write(sc, REG_USB0, USB_FLAG_OFF); ykbec_write(sc, REG_USB1, USB_FLAG_OFF); ykbec_write(sc, REG_USB2, USB_FLAG_OFF); /* EC */ DPRINTF(("REG_PMUCFG\n")); ctrl = PMUCFG_SCI_WAKEUP | PMUCFG_WDT_WAKEUP | PMUCFG_GPWU_WAKEUP | PMUCFG_LPC_WAKEUP | PMUCFG_STOP_MODE | PMUCFG_RESET_8051; ykbec_write(sc, REG_PMUCFG, ctrl); /* FAN */ DPRINTF(("FAN\n")); ykbec_write(sc, REG_FAN_CONTROL, REG_FAN_OFF); /* CPU */ DPRINTF(("CPU\n")); ykbec_chip_config = REGVAL(LOONGSON_CHIP_CONFIG0); enableintr(); REGVAL(LOONGSON_CHIP_CONFIG0) = ykbec_chip_config & ~0x7; (void)REGVAL(LOONGSON_CHIP_CONFIG0); /* * When a resume interrupt fires, we will enter the interrupt * dispatcher, which will do nothing because we are at splhigh, * and execution flow will return here and continue. */ (void)disableintr(); return 0; }
/* * Process legacy interrupts. * * XXX On 2F, ISA interrupts only occur on LOONGSON_INTR_INT0, but since * XXX the other LOONGSON_INTR_INT# are unmaskable, bad things will happen * XXX if they ever are triggered... */ uint32_t lemote_isa_intr(uint32_t hwpend, struct trap_frame *frame) { uint64_t imr, isr, mask; int bit; struct intrhand *ih; int rc; isr = lemote_get_isa_isr(); imr = lemote_get_isa_imr(); isr &= imr; isr &= ~(1 << 2); /* cascade */ #ifdef DEBUG printf("isa interrupt: imr %04x isr %04x\n", imr, isr); #endif if (isr == 0) return 0; /* not for us */ /* * Mask all pending interrupts. */ loongson_set_isa_imr(imr & ~isr); /* * If interrupts are spl-masked, mask them and wait for splx() * to reenable them when necessary. */ if ((mask = isr & (BONITO_ISA_MASK(bonito_imask[frame->ipl]))) != 0) { isr &= ~mask; imr &= ~mask; } /* * Now process allowed interrupts. */ if (isr != 0) { int lvl, bitno, ret; uint64_t tmpisr; /* Service higher level interrupts first */ bit = BONITO_NISA - 1; for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) { tmpisr = isr & BONITO_ISA_MASK(bonito_imask[lvl] ^ bonito_imask[lvl - 1]); if (tmpisr == 0) continue; for (bitno = bit, mask = 1UL << bitno; mask != 0; bitno--, mask >>= 1) { if ((tmpisr & mask) == 0) continue; rc = 0; for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)]; ih != NULL; ih = ih->ih_next) { splraise(ih->ih_level); ret = (*ih->ih_fun)(ih->ih_arg); if (ret) { rc = 1; ih->ih_count.ec_count++; } __asm__ (".set noreorder\n"); curcpu()->ci_ipl = frame->ipl; __asm__ ("sync\n\t.set reorder\n"); if (ret == 1) break; } if (rc == 0) printf("spurious isa interrupt %d\n", bitno); loongson_isa_specific_eoi(bitno); if ((isr ^= mask) == 0) goto done; if ((tmpisr ^= mask) == 0) break; } } done: /* * Reenable interrupts which have been serviced. */ loongson_set_isa_imr(imr); }