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;
}
Example #2
0
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;
}
Example #3
0
////////////////////////////////////////////////////
// 功能: 延迟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;
		
	}

}
Example #5
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;
}
Example #6
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;
}