int mmc_wait_command(SIM_HBA *hba) { SIM_MMC_EXT *ext; struct _pulse pulse; iov_t iov; int rcvid, intr=0, retry=0; ext = (SIM_MMC_EXT *)hba->ext; SETIOV(&iov, &pulse, sizeof(pulse)); while (1) { if ((rcvid = MsgReceivev(hba->chid, &iov, 1, NULL)) == -1) continue; intr = 0; switch (pulse.code) { case SIM_INTERRUPT: intr=ext->interrupt(hba, hba->cfg.IRQRegisters[0], ext->resp_type, ext->mmc_resp); InterruptUnmask(hba->cfg.IRQRegisters[0], hba->iid); break; case SIM_DMA_INTERRUPT: intr=ext->interrupt(hba, hba->cfg.IRQRegisters[0], ext->resp_type, ext->mmc_resp); if(hba->cfg.NumIRQs > 1) { InterruptUnmask(hba->cfg.IRQRegisters[1], ext->iid); } break; case SIM_TIMER: // Only check media if card detection interrupt is not supported if (!(ext->hccap & MMC_HCCAP_CD_INTR)) mmc_media_check(hba); if(!(ext->eflags & MMC_EFLAG_INSERTED)) return MMC_FAILURE; break; default: break; } if(intr & MMC_INTR_CARD){ mmc_media_check(hba); return MMC_FAILURE; } if((intr & MMC_INTR_COMMAND) && !(intr & MMC_INTR_ERROR)) return MMC_SUCCESS; if(retry++ >5) return MMC_FAILURE; } return MMC_FAILURE; }
int seromap_setpower(pmd_attr_t *pmd) { int ret = EOK; pm_power_mode_t mode = PM_POWER_MODE(pmd->new_mode); DEV_OMAP *dev = (DEV_OMAP *)pmd->data; uintptr_t *port = dev->port; if (pmd->cur_mode == pmd->new_mode && pmd->cur_flags == pmd->new_flags) return (EOK); InterruptMask(dev->intr, dev->iid); switch (mode) { case PM_MODE_ACTIVE: // Power UP seromap_setsleep(port, 0, 0); if (pmd->cur_mode != PM_MODE_IDLE) seromap_enable(dev, 1); break; case PM_MODE_IDLE: // Idle mode : active + enable the sleep mode if (pmd->cur_mode != PM_MODE_ACTIVE) { seromap_setsleep(port, 0, 0); // Disable sleep mode first seromap_enable(dev, 1); // Re-enable UART } seromap_setsleep(port, OMAP_IER_SLEEP, OMAP_SCR_WAKEUPEN); break; case PM_MODE_OFF: // Off if (pmd->cur_mode != PM_MODE_STANDBY) { if (pmd->cur_mode == PM_MODE_IDLE) seromap_setsleep(port, 0, 0); // Disable sleep mode first seromap_enable(dev, 0); // Disable UART } seromap_setsleep(port, OMAP_IER_SLEEP, 0); // Enable sleep mode, disable wakeup break; case PM_MODE_STANDBY: if (pmd->cur_mode != PM_MODE_OFF) { if (pmd->cur_mode == PM_MODE_IDLE) seromap_setsleep(port, 0, 0); // Disable sleep mode first seromap_enable(dev, 0); // Disable UART } seromap_setsleep(port, OMAP_IER_SLEEP, OMAP_SCR_WAKEUPEN); break; default: // Unsupported Power Mode ret = EINVAL; break; } InterruptUnmask(dev->intr, dev->iid); // Kick the driver to restart data transmission if (mode == PM_MODE_IDLE || mode == PM_MODE_ACTIVE) kick((TTYDEV *)dev); // pmd_confirm(pmd, EOK); return ret; }
//////////////////////////////////////////////////// // 功能: 延迟N个豪秒 // 输入: // 输出: // 返回: // 说明: //////////////////////////////////////////////////// static void dma_start(unsigned int channel, unsigned int srcAddr, unsigned int dstAddr, unsigned int count, unsigned char mode) { #ifdef KPRINTF_DEF kprintf("dma channle = %d\n",channel); kprintf("source = %x, destion = %x, count = %x\n",srcAddr,dstAddr,count*16); #endif OUTREG32(A_DMA_DSA(channel), srcAddr); // DMA数据地址 OUTREG32(A_DMA_DTA(channel), dstAddr); // DMA目标地址 OUTREG32(A_DMA_DTC(channel), count / 16); // 传送DMA的数据组数,当前设置1组为16个数据 SETREG32(A_DMA_DCS(channel), DCS_CTE); // 开始DMA数据传送 //判断是否允许DMA中断 if( mode ) InterruptUnmask(IRQ_DMA_0 + channel, 0); // 允许DMA结束后,自动产生中断 }
void *InterruptTask::IntThread(void *arg){ static int interruptId; struct sigevent event; int s; InterruptTask *taskInst; taskInst = (InterruptTask *)arg; event.sigev_notify = SIGEV_INTR; interruptId = InterruptAttachEvent(taskInst->mIntNum, &event, 0); while(1){ if(InterruptWait(0, NULL) == -1){ continue; } InterruptUnmask(taskInst->mIntNum, interruptId); taskInst->mRunning = 1; taskInst->IntTask(); taskInst->mRunning = 0; } }
int omap3530_wait(omap3530_spi_t *dev, int len) { struct _pulse pulse; int rx_idx = dev->sdma_rx_chid; while (1) { if (len) { uint64_t to = dev->dtime * 1000 * 50; /* 50 times for time out */ to *= len ; TimerTimeout(CLOCK_REALTIME, _NTO_TIMEOUT_RECEIVE, NULL, &to, NULL); } if (MsgReceivePulse(dev->chid, &pulse, sizeof(pulse), NULL) == -1){ fprintf(stderr, "omap3530_wait: errono %s(%d), status %x\n", strerror(errno), errno, in32(dev->vbase+ OMAP3530_MCSPI_IRQ_STATUS_OFFSET)); return -1; } switch (pulse.code) { case OMAP3530_SPI_EVENT: return 0; case OMAP3530_SDMA_EVENT: { /* Unmask the Interrupt */ InterruptUnmask(dev->irq_sdma+rx_idx, dev->iid_sdma); if ((dev->dma4->channel[rx_idx].csr & DMA4_CSR_FRAME)){ /* clear interrupt status line 0 for transmit channel */ dev->dma4->channel[rx_idx].csr |= DMA4_CSR_FRAME; return 0; }else { continue; } } } } return 0; }
static void *interrupt_thread( void *p ) { int ret; int intr; int intr_id; struct sigevent event; struct _pulse pulse; iov_t iov; int rcvid; int chid; int coid; int count; uint64_t rdata; uint16_t target; uint64_t clk; int pool_id; intr = (int)p; rdata = 0; target = 512; ret = ThreadCtl( _NTO_TCTL_IO, 0 ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to gain IO privs: %s", strerror( errno ) ); return NULL; } chid = ChannelCreate( 0 ); if( chid == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: ChannelCreate() failed: %s", strerror( errno ) ); return NULL; } coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 ); if( coid == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: ConnectAttach() failed: %s", strerror( errno ) ); return NULL; } ret = yarrow_add_source( Yarrow, &pool_id ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to get pool_id for interrupt %d thread.", intr ); return NULL; } event.sigev_notify = SIGEV_PULSE; event.sigev_coid = coid; event.sigev_code = 1; event.sigev_priority = 15; intr_id = InterruptAttachEvent( intr, &event, _NTO_INTR_FLAGS_TRK_MSK ); if( intr_id == -1 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to attach event to intr %d: %s", intr, strerror( errno ) ); return NULL; } /* This is how many interrupts we are gonna get */ if( Yarrow ) { yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); target = rdata & 0x1FF; } count = 0; SETIOV( &iov, &pulse, sizeof( pulse ) ); while( 1 ) { rcvid = MsgReceivev( chid, &iov, 1, NULL ); if( rcvid == -1 ) { if( errno == ESRCH ) return NULL; continue; } switch( pulse.code ) { case 1: InterruptUnmask( intr, intr_id ); count++; if( count >= target ) { ClockTime( CLOCK_REALTIME, NULL, &clk ); clk = clk ^ rdata; if( Yarrow ) { yarrow_input( Yarrow, (uint8_t *)&clk, sizeof( clk ), pool_id, 8 ); yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); } target = rdata & 0x1FF; count = 0; } break; default: if( rcvid ) MsgError( rcvid, ENOTSUP ); } } return NULL; }