Пример #1
0
static void seromap_enable(DEV_OMAP *dev, int enable)
{
	uintptr_t		*port = dev->port;

	write_omap(port[OMAP_UART_LCR], 0x80);

	if (!enable) {
		atomic_set(&dev->pwm_flag, SEROMAP_PWM_PAGED);

		// If HW flow control is ON, assert the RTS line
		if (dev->tty.c_cflag & IHFLOW)
			set_port(port[OMAP_UART_MCR], OMAP_MCR_DTR|OMAP_MCR_RTS, 0);

		while (!(read_omap(port[OMAP_UART_LSR]) & OMAP_LSR_TSRE))
			;
		nanospin_ns(1000000);			// pause for 1ms
		write_omap(port[OMAP_UART_MDR1], 0x07);
		write_omap(port[OMAP_UART_DLL], 0xFF);
		write_omap(port[OMAP_UART_DLH], 0xFF);
	}
	else {
		write_omap(port[OMAP_UART_DLL], dev->brd);
		write_omap(port[OMAP_UART_DLH], (dev->brd >> 8) & 0xff);
		write_omap(port[OMAP_UART_MDR1], 0x00);

		// If HW flow control is ON, de-assert the RTS line
		if(dev->tty.c_cflag & IHFLOW)
			set_port(port[OMAP_UART_MCR], OMAP_MCR_DTR|OMAP_MCR_RTS, OMAP_MCR_DTR|OMAP_MCR_RTS);

		// Allow data transmission to resume
		atomic_clr(&dev->pwm_flag, SEROMAP_PWM_PAGED);
	}

	write_omap(port[OMAP_UART_LCR], dev->lcr);
}
Пример #2
0
static int _aio_wakeup(struct aiocb *aiocbp) {
	struct sigevent *ev = &aiocbp->aio_sigevent;
	int flag, ret = EOK;
	
	/* let's see if there is an suspend waiting us */
	flag = atomic_set_value(&aiocbp->_aio_flag, _AIO_FLAG_DONE);
	if (flag & _AIO_FLAG_SUSPEND) {
		struct _aio_waiter *w;
		
		_mutex_lock(&_aio_cb->cb_mutex);
		if ((w = aiocbp->_aio_suspend) != NULL) {
			atomic_clr(&aiocbp->_aio_flag, _AIO_FLAG_SUSPEND);
			if ((ret = pthread_cond_signal(&w->w_cond)) != EOK) {
				aiocbp->_aio_result = (unsigned)-1;
				aiocbp->_aio_error = ret;
			}
			w->w_count--;
			aiocbp->_aio_suspend = NULL;
		}
		_mutex_unlock(&_aio_cb->cb_mutex);
		/* shall it be a wakeup even if there is an suspend ? */
		return ret;
	}
		
	switch (SIGEV_GET_TYPE(ev)) {
	  case SIGEV_SIGNAL:
	  case SIGEV_SIGNAL_CODE:
	  case SIGEV_SIGNAL_THREAD:
		ret = SignalKill_r(0, getpid(), 0, ev->sigev_signo, SI_ASYNCIO, 
						   ev->sigev_value.sival_int);
		break;
	  case SIGEV_PULSE:
		ret = MsgSendPulse_r(ev->sigev_coid, ev->sigev_priority, 
							 ev->sigev_code, ev->sigev_value.sival_int);
		break;
	  case SIGEV_THREAD:
		ret = pthread_create(NULL, ev->sigev_notify_attributes,
							 (void *)ev->sigev_notify_function, 
							 ev->sigev_value.sival_ptr);
		break;
	  case SIGEV_NONE:
		ret = EOK;
		break;
	  case SIGEV_UNBLOCK:
	  case SIGEV_INTR:
	  default:
		/* don't know how to deliever these 2 */
		ret = EOPNOTSUPP;
		break;
	}
	
	if (ret != EOK) {
		/* what if the io operation itself failed ? */
		aiocbp->_aio_result = (unsigned)-1;
		aiocbp->_aio_error = ret;
	}
	
	return ret;
}
Пример #3
0
void
omap_clock_enable(DEV_OMAP* dev, clk_enable_t clk_cfg)
{
	int enable_rc = 0;
	int functional_rc = 0;

	/* Our idle state can be changed by the ISR so we must use a spinlock */
	InterruptLock(&dev->idle_spinlock);

	/* Only enable clocks if they aren't enabled already */
	if (dev->idle == 0) {
		goto done;
	}

	if (dev->clkctrl_base) {
		/* Enable the clock */
		out32(dev->clkctrl_base, OMAP_CLKCTRL_MODMODE_ENABLE);

		/* Wait for the module mode to have been written */
		enable_rc = poll_for_condition(dev->clkctrl_base, OMAP_CLKCTRL_MODMODE_MASK, OMAP_CLKCTRL_MODMODE_ENABLE);

		/* Wait for the module idle status to report "fully functional" */
		functional_rc = poll_for_condition(dev->clkctrl_base, OMAP_CLKCTRL_IDLEST_MASK, OMAP_CLKCTRL_IDLEST_FUNCTIONAL);
        
		/* Re-configure clock if specified otherwise simply skip it */
		if (clk_cfg != clk_enable_skip) {

			/* Set the idle mode to smart idle with wake up */
			set_port(dev->port[OMAP_UART_SYSC], OMAP_UART_SYSC_IDLEMODE_MASK, clk_cfg);	
        }

		/* Enable the CTS wakeup */
		write_omap(dev->port[OMAP_UART_WER], OMAP_UART_WER_CTS_ENABLE);

		/* Indicate clocks are enabled */
		dev->idle = 0;
	}

done:
#ifdef WINBT
	/* clear CTS debounce timer and OHW_PAGED flag */
	if (dev->tty.un.s.spare_tmr > 0) {
		dev->tty.un.s.spare_tmr = 0;
		if (dev->tty.flags & OHW_PAGED)
			atomic_clr (&dev->tty.flags, OHW_PAGED);
	}
#endif
	omap_uart_ctx_restore(dev);
	InterruptUnlock(&dev->idle_spinlock);

	/* Don't slog while interrupts are disabled - otherwise slogf() will re-enable interrupts */
	if (enable_rc) {
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Failed to set module mode to 'enabled'", __FUNCTION__);
	}

	if (functional_rc) {
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Module failed to report 'fully functional'", __FUNCTION__);
	}
}
Пример #4
0
void
pthread_exit(void *value_ptr) {
	struct __cleanup_handler				*handler;
	int										loop, again;
	volatile struct _thread_local_storage	*tls = LIBC_TLS();

	// Disable pthread_cancel and set cancel type to deferred
	atomic_set(&tls->__flags, PTHREAD_CANCEL_DISABLE);
	atomic_clr(&tls->__flags, PTHREAD_CANCEL_ASYNCHRONOUS); /* make defered */

	// call the cleanup handlers
	while((handler = tls->__cleanup)) {
		tls->__cleanup = handler->__next;
		handler->__routine(handler->__save);
	}

	// Call the thread_specific_data destructor functions
	for(loop = 0, again = 1; again && loop < PTHREAD_DESTRUCTOR_ITERATIONS; loop++) {
		int										i;
		int										num;

		again = 0;
		num = min(tls->__numkeys, _key_count);
		for(i = 0; i < num; i++) {
			void									*data;
			void									(*destructor)(void *);

			if((destructor = _key_destructor[i]) && (destructor != _KEY_NONE) && (data = tls->__keydata[i])) {
				// Setting the data to NULL was the intention of the POSIX
				// committe, but did not make it into the POSIX spec. Doing
				// this still keeps our implementation POSIX complient, but
				// allow non-POSIX complient applications to be more efficient.
				tls->__keydata[i] = 0;

				destructor(data);
				again = 1;
			}
		}
	}

	// Unlock hanging file mutexes before exiting
	_Unlockfilemtx();

	// Unlock hanging system mutexes before exiting
	_Unlocksysmtx();

	(void)ThreadDestroy_r(0, -1, value_ptr);
#ifdef __GNUC__
	for( ;; ) ; /* Get gcc to shut up about a noreturn function returning */
#endif
}
Пример #5
0
static void mmc_unit_ready(SIM_HBA *hba)
{
	SIM_MMC_EXT	*ext = (SIM_MMC_EXT *)hba->ext;
	CCB_SCSIIO	*ccb = ext->nexus;

	if (ext->eflags & MMC_EFLAG_MEDIA_CHANGED) {
		mmc_sense(hba, SK_UNIT_ATN, ASC_MEDIUM_CHANGED, ASCQ_UNKNOWN_CHANGED);
		atomic_clr(&ext->eflags, MMC_EFLAG_MEDIA_CHANGED);
	} else if (ext->eflags & MMC_EFLAG_READY) {
		if (ext->detect(hba) != MMC_SUCCESS) {
			mmc_media_check(hba);
			mmc_sense(hba, SK_NOT_RDY, ASC_MEDIA_NOT_PRESENT, 0);
		} else
			ccb->cam_ch.cam_status = CAM_REQ_CMP;
	} else
		mmc_sense(hba, SK_NOT_RDY, ASC_MEDIA_NOT_PRESENT, 0);
}
Пример #6
0
void dio_clear(uint8_t mask){
	atomic_clr((unsigned*)&value, mask);
	out8(portHandle, value);
}
Пример #7
0
int
tto(TTYDEV *ttydev, int action, int arg1) {
	TTYBUF 			*bup = &ttydev->obuf;
	DEV_OMAP		*dev = (DEV_OMAP *)ttydev;
	const uintptr_t	*port = dev->port;
	unsigned char 	c;
	
#ifdef PWR_MAN

	if (dev->idle) {

		/* Check the client lists for notify conditions */
		return(tto_checkclients(&dev->tty));
	}
#endif

	switch(action) {
	case TTO_STTY:
//            if (dev->driver_pmd.cur_mode == PM_MODE_ACTIVE)
			ser_stty(dev);
		return (0);

	case TTO_CTRL:

		if(arg1 & _SERCTL_BRK_CHG)
			set_port(port[OMAP_UART_LCR], OMAP_LCR_BREAK, arg1 &_SERCTL_BRK ? OMAP_LCR_BREAK : 0);

		if(arg1 & _SERCTL_DTR_CHG)
			set_port(port[OMAP_UART_MCR], OMAP_MCR_DTR, arg1 & _SERCTL_DTR ? OMAP_MCR_DTR : 0);

		if(arg1 & _SERCTL_RTS_CHG)
		{
			if (dev->auto_rts_enable)
			{
				/* For auto-rts enable/disable RX & LS interrupts to assert/clear 
				 * input flow control (the FIFO will automatically handle the RTS line) 
				*/
				if (arg1 & _SERCTL_RTS)
					write_omap(port[OMAP_UART_IER], read_omap(port[OMAP_UART_IER] ) | OMAP_IER_RHR | OMAP_IER_LS );
				else
					write_omap(port[OMAP_UART_IER], read_omap(port[OMAP_UART_IER] ) & ~(OMAP_IER_RHR | OMAP_IER_LS ) );
			}
			else
				set_port(port[OMAP_UART_MCR], OMAP_MCR_RTS, arg1 & _SERCTL_RTS ? OMAP_MCR_RTS : 0);
		}

#ifdef WINBT
        if (arg1 & _CTL_TIMED_CHG) {

            slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Turning clocks OFF due to CTS glitch\n", __FUNCTION__);
            dev->signal_oband_notification = 0;
            omap_clock_disable(dev);
        }
#endif
		return (0);

	case TTO_LINESTATUS:
		return (((read_omap(port[OMAP_UART_MSR]) << 8) | read_omap(port[OMAP_UART_MCR])) & 0xf003);

	case TTO_DATA:
	case TTO_EVENT:
		break;

	default:
		return (0);
	}


	while (bup->cnt > 0 && (!(read_omap(port[OMAP_UART_SSR]) & OMAP_SSR_TXFULL)) )
	{
		/*
    		* If the OSW_PAGED_OVERRIDE flag is set then allow
   		* transmit of character even if output is suspended via
    		* the OSW_PAGED flag. This flag implies that the next
    		* character in the obuf is a software flow control
    		* charater (STOP/START).
    		* Note: tx_inject sets it up so that the contol
    		*       character is at the start (tail) of the buffer.
    		*
		*/
	

		if (dev->tty.flags & (OHW_PAGED | OSW_PAGED) && !(dev->tty.xflags & OSW_PAGED_OVERRIDE))
			break;

		/* Get character from obuf and do any output processing */
		dev_lock(&dev->tty);
		c = tto_getchar(&dev->tty);
		dev_unlock(&dev->tty);
	    	
		/* Print the character */
		dev->tty.un.s.tx_tmr = 3;       /* Timeout 3 */
		write_omap(port[OMAP_UART_THR], c);

		/* Clear the OSW_PAGED_OVERRIDE flag as we only want
      		* one character to be transmitted in this case.
     		*/
    		if (dev->tty.xflags & OSW_PAGED_OVERRIDE){
           		atomic_clr(&dev->tty.xflags, OSW_PAGED_OVERRIDE);
			break;
 		}	
 	}

	/* If there is still data in the obuf and we are not in a flow 
	 * controlled state then turn TX interrupts back on to notify us
	 * when the hardware is ready for more characters.
	 */
	if (bup->cnt > 0 && !(dev->tty.flags & (OHW_PAGED|OSW_PAGED)) )
	 { 
		// enable all interrupts
		set_port(dev->port[OMAP_UART_IER], OMAP_IER_THR, OMAP_IER_THR);
	 }
	 

	/* Check the client lists for notify conditions */
	return(tto_checkclients(&dev->tty));
}