Example #1
0
static void __exit scc_enet_cleanup(void)
{
	struct rtnet_device *rtdev = rtdev_root;
	struct scc_enet_private *cep = (struct scc_enet_private *)rtdev->priv;
	volatile cpm8xx_t *cp = cpmp;
	volatile scc_enet_t *ep;

	if (rtdev) {
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);

		ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);
		m8xx_cpm_dpfree(ep->sen_genscc.scc_rbase);
		m8xx_cpm_dpfree(ep->sen_genscc.scc_tbase);

		rt_stack_disconnect(rtdev);
		rt_unregister_rtnetdev(rtdev);
		rt_rtdev_disconnect(rtdev);

		printk("%s: unloaded\n", rtdev->name);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		rtdev_root = NULL;
	}
}
Example #2
0
static int uart_close_nrt(struct rtdm_dev_context *context,rtdm_user_info_t * user_info)
{
	int err;
        MY_DEV *up=(MY_DEV *)context->device->device_data;
	
	dev_dbg(up->dev, "serial_omap_shutdown+%d\n", up->line);	
	
	up->ier = 0;
	serial_out(up, UART_IER, 0);

	//disable break condition and FIFOs
	serial_out(up,UART_LCR,serial_in(up,UART_LCR) & ~UART_LCR_SBC);
	serial_omap_clear_fifos(up);

	//read data port to reset things and then free irq
	if(serial_in(up,UART_LSR) & UART_LSR_DR)
		(void)serial_in(up,UART_RX);

	err=rtdm_irq_disable(&up->irq_handle);//enable irq
        if(err<0)
        {
                rtdm_printk("error in rtdm_irq_disable\n");
                return err;
        }
        rtdm_printk("rtdm_irq_disable\n");
	rtdm_irq_free(&up->irq_handle);	
	 free_irq(up->irq, up);		
        return 0;
}
Example #3
0
static void tulip_down (/*RTnet*/struct rtnet_device *rtdev)
{
	long ioaddr = rtdev->base_addr;
	struct tulip_private *tp = (struct tulip_private *) rtdev->priv;

	rtdm_irq_disable(&tp->irq_handle);
	rtdm_lock_get(&tp->lock); /* sync with IRQ handler on other cpu -JK- */

	/* Disable interrupts by clearing the interrupt mask. */
	outl (0x00000000, ioaddr + CSR7);

	/* Stop the Tx and Rx processes. */
	tulip_stop_rxtx(tp);

	/* prepare receive buffers */
	tulip_refill_rx(rtdev);

	/* release any unconsumed transmit buffers */
	tulip_clean_tx_ring(tp);

	/* 21040 -- Leave the card in 10baseT state. */
	if (tp->chip_id == DC21040)
		outl (0x00000004, ioaddr + CSR13);

	if (inl (ioaddr + CSR6) != 0xffffffff)
		tp->stats.rx_missed_errors += inl (ioaddr + CSR8) & 0xffff;

	rtdm_lock_put(&tp->lock);
	rtdm_irq_enable(&tp->irq_handle);

	rtdev->if_port = tp->saved_if_port;

	/* Leave the driver in snooze, not sleep, mode. */
	tulip_set_power_state (tp, 0, 1);
}
Example #4
0
void cleanup_mpu9150_irq(void)
{
	rtdm_printk("MPU9150-IRQ: Releasing IRQ resources...\n");

	if( irq_requested )
	{
		rtdm_irq_disable( &mpu9150_irq );
		rtdm_irq_free( &mpu9150_irq );
	}

	if( irq_gpio_requested )
		gpio_free( mpu9150_irq_desc.gpio_desc.gpio );

	// Close the pipe
	rt_pipe_delete( &pipe_desc );

	rtdm_printk("MPU9150-IRQ: IRQ resources released\n");
}
Example #5
0
/* Initialize the CPM Ethernet on SCC.  If EPPC-Bug loaded us, or performed
 * some other network I/O, a whole bunch of this has already been set up.
 * It is no big deal if we do it again, we just have to disable the
 * transmit and receive to make sure we don't catch the CPM with some
 * inconsistent control information.
 */
int __init scc_enet_init(void)
{
	struct rtnet_device *rtdev = NULL;
	struct scc_enet_private *cep;
	int i, j, k;
	unsigned char	*eap, *ba;
	dma_addr_t	mem_addr;
	bd_t		*bd;
	volatile	cbd_t		*bdp;
	volatile	cpm8xx_t	*cp;
	volatile	scc_t		*sccp;
	volatile	scc_enet_t	*ep;
	volatile	immap_t		*immap;

	cp = cpmp;	/* Get pointer to Communication Processor */

	immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000);	/* and to internal registers */

	bd = (bd_t *)__res;

	/* Configure the SCC parameters (this has formerly be done 
	 * by macro definitions).
	 */
	switch (rtnet_scc) {
	case 3:
		CPM_CR_ENET = CPM_CR_CH_SCC3;
		PROFF_ENET  = PROFF_SCC3;
		SCC_ENET    = 2;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC3;
		break;
	case 2:
		CPM_CR_ENET = CPM_CR_CH_SCC2;
		PROFF_ENET  = PROFF_SCC2;
		SCC_ENET    = 1;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC2;
		break;
	case 1:
		CPM_CR_ENET = CPM_CR_CH_SCC1;
		PROFF_ENET  = PROFF_SCC1;
		SCC_ENET    = 0;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC1;
		break;
	default:
		printk(KERN_ERR "enet: SCC%d doesn't exit (check rtnet_scc)\n", rtnet_scc);
		return -1;
	}

	/* Allocate some private information and create an Ethernet device instance.
	*/
	rtdev = rtdev_root = rt_alloc_etherdev(sizeof(struct scc_enet_private));
	if (rtdev == NULL) {
		printk(KERN_ERR "enet: Could not allocate ethernet device.\n");
		return -1;
	}
	rtdev_alloc_name(rtdev, "rteth%d");
	rt_rtdev_connect(rtdev, &RTDEV_manager);
	RTNET_SET_MODULE_OWNER(rtdev);
	rtdev->vers = RTDEV_VERS_2_0;

	cep = (struct scc_enet_private *)rtdev->priv;
	rtdm_lock_init(&cep->lock);

	/* Get pointer to SCC area in parameter RAM.
	*/
	ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);

	/* And another to the SCC register area.
	*/
	sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]);
	cep->sccp = (scc_t *)sccp;		/* Keep the pointer handy */

	/* Disable receive and transmit in case EPPC-Bug started it.
	*/
	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* Cookbook style from the MPC860 manual.....
	 * Not all of this is necessary if EPPC-Bug has initialized
	 * the network.
	 * So far we are lucky, all board configurations use the same
	 * pins, or at least the same I/O Port for these functions.....
	 * It can't last though......
	 */

#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
	/* Configure port A pins for Txd and Rxd.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_paodr &=                ~PA_ENET_TXD;
#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
	/* Configure port B pins for Txd and Rxd.
	*/
	immap->im_cpm.cp_pbpar |=  (PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbodr &=		 ~PB_ENET_TXD;
#else
#error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
#endif

#if defined(PC_ENET_LBK)
	/* Configure port C pins to disable External Loopback
	 */
	immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdir |=  PC_ENET_LBK;
	immap->im_ioport.iop_pcso  &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
#endif	/* PC_ENET_LBK */

	/* Configure port C pins to enable CLSN and RENA.
	*/
	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);

	/* Configure port A for TCLK and RCLK.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);

	/* Configure Serial Interface clock routing.
	 * First, clear all SCC bits to zero, then set the ones we want.
	 */
	cp->cp_sicr &= ~SICR_ENET_MASK;
	cp->cp_sicr |=  SICR_ENET_CLKRT;

	/* Manual says set SDDR, but I can't find anything with that
	 * name.  I think it is a misprint, and should be SDCR.  This
	 * has already been set by the communication processor initialization.
	 */

	/* Allocate space for the buffer descriptors in the DP ram.
	 * These are relative offsets in the DP ram address space.
	 * Initialize base addresses for the buffer descriptors.
	 */
	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
	ep->sen_genscc.scc_rbase = i;
	cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
	ep->sen_genscc.scc_tbase = i;
	cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
	cep->cur_rx = cep->rx_bd_base;

	/* Issue init Rx BD command for SCC.
	 * Manual says to perform an Init Rx parameters here.  We have
	 * to perform both Rx and Tx because the SCC may have been
	 * already running.
	 * In addition, we have to do it later because we don't yet have
	 * all of the BD control/status set properly.
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);
	 */

	/* Initialize function code registers for big-endian.
	*/
	ep->sen_genscc.scc_rfcr = SCC_EB;
	ep->sen_genscc.scc_tfcr = SCC_EB;

	/* Set maximum bytes per receive buffer.
	 * This appears to be an Ethernet frame size, not the buffer
	 * fragment size.  It must be a multiple of four.
	 */
	ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;

	/* Set CRC preset and mask.
	*/
	ep->sen_cpres = 0xffffffff;
	ep->sen_cmask = 0xdebb20e3;

	ep->sen_crcec = 0;	/* CRC Error counter */
	ep->sen_alec = 0;	/* alignment error counter */
	ep->sen_disfc = 0;	/* discard frame counter */

	ep->sen_pads = 0x8888;	/* Tx short frame pad character */
	ep->sen_retlim = 15;	/* Retry limit threshold */

	ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
	ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */

	ep->sen_maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
	ep->sen_maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */

	/* Clear hash tables.
	*/
	ep->sen_gaddr1 = 0;
	ep->sen_gaddr2 = 0;
	ep->sen_gaddr3 = 0;
	ep->sen_gaddr4 = 0;
	ep->sen_iaddr1 = 0;
	ep->sen_iaddr2 = 0;
	ep->sen_iaddr3 = 0;
	ep->sen_iaddr4 = 0;

	/* Set Ethernet station address.
	 */
	eap = (unsigned char *)&(ep->sen_paddrh);
#ifdef CONFIG_FEC_ENET
	/* We need a second MAC address if FEC is used by Linux */
	for (i=5; i>=0; i--)
		*eap++ = rtdev->dev_addr[i] = (bd->bi_enetaddr[i] | 
					     (i==3 ? 0x80 : 0));
#else
	for (i=5; i>=0; i--)
		*eap++ = rtdev->dev_addr[i] = bd->bi_enetaddr[i];
#endif

	ep->sen_pper = 0;	/* 'cause the book says so */
	ep->sen_taddrl = 0;	/* temp address (LSB) */
	ep->sen_taddrm = 0;
	ep->sen_taddrh = 0;	/* temp address (MSB) */

	/* Now allocate the host memory pages and initialize the
	 * buffer descriptors.
	 */
	bdp = cep->tx_bd_base;
	for (i=0; i<TX_RING_SIZE; i++) {

		/* Initialize the BD for every fragment in the page.
		*/
		bdp->cbd_sc = 0;
		bdp->cbd_bufaddr = 0;
		bdp++;
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	bdp = cep->rx_bd_base;
	k = 0;
	for (i=0; i<CPM_ENET_RX_PAGES; i++) {

		/* Allocate a page.
		*/
		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);

		/* Initialize the BD for every fragment in the page.
		*/
		for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
			bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
			bdp->cbd_bufaddr = mem_addr;
			cep->rx_vaddr[k++] = ba;
			mem_addr += CPM_ENET_RX_FRSIZE;
			ba += CPM_ENET_RX_FRSIZE;
			bdp++;
		}
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	/* Let's re-initialize the channel now.  We have to do it later
	 * than the manual describes because we have just now finished
	 * the BD initialization.
	 */
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);

	cep->skb_cur = cep->skb_dirty = 0;

	sccp->scc_scce = 0xffff;	/* Clear any pending events */

	/* Enable interrupts for transmit error, complete frame
	 * received, and any transmit buffer we have also set the
	 * interrupt flag.
	 */
	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);

	/* Install our interrupt handler.
	*/
	rtdev->irq = CPM_IRQ_OFFSET + CPMVEC_ENET;
	rt_stack_connect(rtdev, &STACK_manager);
	if ((i = rtdm_irq_request(&cep->irq_handle, rtdev->irq,
				  scc_enet_interrupt, 0, "rt_mpc8xx_enet", rtdev))) {
		printk(KERN_ERR "Couldn't request IRQ %d\n", rtdev->irq);
		rtdev_free(rtdev);
		return i;
	}
	

	/* Set GSMR_H to enable all normal operating modes.
	 * Set GSMR_L to enable Ethernet to MC68160.
	 */
	sccp->scc_gsmrh = 0;
	sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);

	/* Set sync/delimiters.
	*/
	sccp->scc_dsr = 0xd555;

	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
	 * start frame search 22 bit times after RENA.
	 */
	sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);

	/* It is now OK to enable the Ethernet transmitter.
	 * Unfortunately, there are board implementation differences here.
	 */
#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA))
	immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;
#else
#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
#endif

#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
	/* And while we are here, set the configuration to enable ethernet.
	*/
	*((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
	*((volatile uint *)RPX_CSR_ADDR) |=
			(BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS);
#endif

#ifdef CONFIG_BSEIP
	/* BSE uses port B and C for PHY control.
	*/
	cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);

	immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
#endif

#ifdef CONFIG_FADS
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;

	/* Enable the EEST PHY.
	*/
	*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
#endif

	rtdev->base_addr = (unsigned long)ep;

	/* The CPM Ethernet specific entries in the device structure. */
	rtdev->open = scc_enet_open;
	rtdev->hard_start_xmit = scc_enet_start_xmit;
	rtdev->stop = scc_enet_close;
	rtdev->hard_header = &rt_eth_header;
	rtdev->get_stats = scc_enet_get_stats;

	if (!rx_pool_size)
		rx_pool_size = RX_RING_SIZE * 2;
	if (rtskb_pool_init(&cep->skb_pool, rx_pool_size) < rx_pool_size) {
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		return -ENOMEM;
	}

	if ((i = rt_register_rtnetdev(rtdev))) {
		printk(KERN_ERR "Couldn't register rtdev\n");
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		return i;
	}

	/* And last, enable the transmit and receive processing.
	*/
	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	printk("%s: CPM ENET Version 0.2 on SCC%d, irq %d, addr %02x:%02x:%02x:%02x:%02x:%02x\n", 
	       rtdev->name, SCC_ENET+1, rtdev->irq,
	       rtdev->dev_addr[0], rtdev->dev_addr[1], rtdev->dev_addr[2],
	       rtdev->dev_addr[3], rtdev->dev_addr[4], rtdev->dev_addr[5]);
	
	return 0;
}
Example #6
0
static int
scc_enet_start_xmit(struct rtskb *skb, struct rtnet_device *rtdev)
{
	struct scc_enet_private *cep = (struct scc_enet_private *)rtdev->priv;
	volatile cbd_t	*bdp;
	rtdm_lockctx_t context;


	RT_DEBUG(__FUNCTION__": ...\n");

	/* Fill in a Tx ring entry */
	bdp = cep->cur_tx;

#ifndef final_version
	if (bdp->cbd_sc & BD_ENET_TX_READY) {
		/* Ooops.  All transmit buffers are full.  Bail out.
		 * This should not happen, since cep->tx_busy should be set.
		 */
		rtdm_printk("%s: tx queue full!.\n", rtdev->name);
		return 1;
	}
#endif

	/* Clear all of the status flags.
	 */
	bdp->cbd_sc &= ~BD_ENET_TX_STATS;

	/* If the frame is short, tell CPM to pad it.
	*/
	if (skb->len <= ETH_ZLEN)
		bdp->cbd_sc |= BD_ENET_TX_PAD;
	else
		bdp->cbd_sc &= ~BD_ENET_TX_PAD;

	/* Set buffer length and buffer pointer.
	*/
	bdp->cbd_datlen = skb->len;
	bdp->cbd_bufaddr = __pa(skb->data);

	/* Save skb pointer.
	*/
	cep->tx_skbuff[cep->skb_cur] = skb;

	cep->stats.tx_bytes += skb->len;
	cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
	
	/* Prevent interrupts from changing the Tx ring from underneath us. */
	// *** RTnet ***
#if 0
	rtdm_irq_disable(&cep->irq_handle);
	rtdm_lock_get(&cep->lock);
#else
	rtdm_lock_get_irqsave(&cep->lock, context);
#endif

	/* Get and patch time stamp just before the transmission */
	if (skb->xmit_stamp)
		*skb->xmit_stamp = cpu_to_be64(rtdm_clock_read() + *skb->xmit_stamp);

	/* Push the data cache so the CPM does not get stale memory
	 * data.
	 */
	flush_dcache_range((unsigned long)(skb->data),
			   (unsigned long)(skb->data + skb->len));


	/* Send it on its way.  Tell CPM its ready, interrupt when done,
	 * its the last BD of the frame, and to put the CRC on the end.
	 */
	bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
#if 0
	dev->trans_start = jiffies;
#endif

	/* If this was the last BD in the ring, start at the beginning again.
	*/
	if (bdp->cbd_sc & BD_ENET_TX_WRAP)
		bdp = cep->tx_bd_base;
	else
		bdp++;

	if (bdp->cbd_sc & BD_ENET_TX_READY) {
	        rtnetif_stop_queue(rtdev);
		cep->tx_full = 1;
	}

	cep->cur_tx = (cbd_t *)bdp;

	// *** RTnet ***
#if 0
	rtdm_lock_put(&cep->lock);
	rtdm_irq_enable(&cep->irq_handle);
#else
	rtdm_lock_put_irqrestore(&cep->lock, context);
#endif

	return 0;
}
Example #7
0
static int rtdm_my_isr(rtdm_irq_t *irq_context)
{

	MY_DEV *up=rtdm_irq_get_arg(irq_context,MY_DEV);

	up->systime1 = rtdm_clock_read();

	up->timeout = up->systime1 - up->systime;

	printk("Interrupt Latency=%dl\n",up->timeout);

	up->systime1=0;
	up->systime=0;

	unsigned int iir,lsr;
	unsigned int type;
	irqreturn_t ret=IRQ_NONE;
	int err;
	int max_count = 256;
	rtdm_lockctx_t context1;

	printk("I am in rtdm_my_isr......!!!\n");

	printk("Local struct up=%x\n",up);

        err = rtdm_irq_disable(&up->irq_handle);
        if(err<0)
             rtdm_printk("error in rtdm_irq_enable\n");
        rtdm_lock_get_irqsave(&up->lock,context1);

	do{
	iir = serial_in(up,UART_IIR);
	if(iir & UART_IIR_NO_INT)
		break;

	ret=IRQ_HANDLED;
	lsr = serial_in(up,UART_LSR);
	type = iir & 0x3e;
	
		switch(type)
		{
			case UART_IIR_THRI:
			printk("type of int:UART_IIR_THRI\n");
			transmit_chars(up,lsr);
			rtdm_event_signal(&up->w_event_tx);
			break;

			case UART_IIR_RX_TIMEOUT:
			/*FALLTHROUGH*/

			case UART_IIR_RDI:
				printk("type of int:UART_IIR_RDI\n");
				serial_omap_rdi(up,lsr);	
				 rtdm_event_signal(&up->w_event_rx);
				break;
			
			case UART_IIR_RLSI:
				printk("type of int:UART_IIR_RLSI\n");
//				serial_omap_rlsi(up,lsr);
				break;
			
			case UART_IIR_CTS_RTS_DSR:
				break;
			
			case UART_IIR_XOFF:
			/*simpleThrough*/
			default:
				break;
		}
	}while(!(iir & UART_IIR_NO_INT) && max_count--);

      	rtdm_lock_put_irqrestore(&up->lock,context1);
        err = rtdm_irq_enable(&up->irq_handle);
        if(err<0)
              rtdm_printk("error in rtdm_irq_enable\n");

	printk("rtdm_irq ended\n");
	
	 up->systime = rtdm_clock_read();
	
	return RTDM_IRQ_HANDLED;
}
Example #8
0
static void serial_omap_set_termios(MY_DEV *up, unsigned int request)
{
	int val;
	unsigned char cval = 0;
	unsigned int baud, quot;
	rtdm_lockctx_t context1;
	int err;

	printk("serial_omap_set_termios\n");
	printk("Local struct up=%x\n",up);

	printk("request=%x\n",request);
	val=request & 0x03;
	printk("val=%x",val);
	switch(val)
	{
		case CS5_1:
			printk("CS5\n");
			cval = UART_LCR_WLEN5;
			break;
		
		case CS6_1:
			printk("CS6\n");
			cval = UART_LCR_WLEN6;
			break;
		
		case CS7_1:
			printk("CS7\n");
			cval = UART_LCR_WLEN7;
			break;
		default:
		case CS8_1:
			printk("CS8\n");
			cval = UART_LCR_WLEN8;
			break;
	}
	
	if(request & 0x04)
	{	printk("set two stop bits\n");
		cval |= UART_LCR_STOP;
	}

	if(request & 0x08)
	{	printk("set even patity\n");
		cval |= UART_LCR_PARITY;
	}

	if(request & 0x10)
	{	printk("set odd parity\n");
		cval |=  UART_LCR_EPAR;
	}

	val=request & 0x60;
	val = val >> 5;

	switch(val)
	{
		case BAUD_4800:
			printk("BAUD_4800\n");
			baud = 4800;
			break;
		case BAUD_9600:
			printk("BAUD_9600\n");
			baud = 9600;
			break;
		case BAUD_115200:
			printk("BAUD_115200\n");
			baud = 115200;
		default:
			printk("default\n");
			baud = 9600;
	}
//	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13);
	quot = serial_omap_get_divisor(up, baud);//for getting dll and dlh register value
	printk("serial_omap_get_divisor=%d\n",quot);

	up->calc_latency = (USEC_PER_SEC * up->fifosize) / (baud / 8);
	up->latency = up->calc_latency;

	up->dll = quot & 0xff;
	up->dlh = quot >> 8;
	up->mdr1 = UART_OMAP_MDR1_DISABLE;

	up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO;

       err = rtdm_irq_disable(&up->irq_handle);
       if(err<0)
               rtdm_printk("error in rtdm_irq_enable\n");
       rtdm_lock_get_irqsave(&up->lock,context1);

		up->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;    

//	if (termios->c_iflag & INPCK)
//		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;	      //Frame error indicator, Parity error indicator
//
//	if (termios->c_iflag & (BRKINT | PARMRK))
//		up->port.read_status_mask |= UART_LSR_BI;		      //Break interrupt indicator


		up->ignore_status_mask = 0;
	//this should be passed from user space
//	if (termios->c_iflag & IGNBRK) 					// IGNBRK Ignore BREAK condition on input.						
//	{
		printk("Ignore Break condition on input\n");
		up->ignore_status_mask |= UART_LSR_BI;
//	}
		
		up->ier &= ~UART_IER_MSI;
		
		serial_out(up, UART_IER, up->ier);	
		printk("Enable interrupt\n");
		serial_out(up, UART_LCR, cval);	//writing the setting to Line control register 	/* reset DLAB */
		
		up->lcr = cval;			//saving the setting of line control register
		up->scr = OMAP_UART_SCR_TX_EMPTY;	
		
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);		
		serial_out(up, UART_DLL, 0);
		serial_out(up, UART_DLM, 0);
		serial_out(up, UART_LCR, 0);
//***********************************************************************
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);    //config to mode B

		up->efr = serial_in(up, UART_EFR) & ~UART_EFR_ECB;//value of efr register without enhance function write enable bit
		up->efr &= ~UART_EFR_SCD;			  //remove special character detect enable
		serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); //writing to EFR register with enhance function write enable bit

//************************************************************************************

		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);   	//config to mode A

		up->mcr = serial_in(up, UART_MCR) & ~UART_MCR_TCRTLR;	//value to TCRTLR=0(No action) if 1 then we can enable TCR and TLR
		serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);    //writing value to the MCR with TCRTLR enable
	/* FIFO ENABLE, DMA MODE */

		up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK;		//enable the granularity of 1 for trigger RX level
		
//*******************************************************************
	/* Set receive FIFO threshold to 16 characters and
	 * transmit FIFO threshold to 16 spaces
	 */
		up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK;						// dont set RX_FIFO_TRIG to 60 character
		up->fcr &= ~OMAP_UART_FCR_TX_FIFO_TRIG_MASK;						//dont set TX_FIFO_TRIG to 56 character	
		up->fcr |= UART_FCR6_R_TRIGGER_16 | UART_FCR6_T_TRIGGER_24 | UART_FCR_ENABLE_FIFO;	//Rx fifo trigger at 16 character | Tx fifo trigger at 32 char | FIFO_EN		
		
		serial_out(up, UART_FCR, up->fcr);							//write to FCR
//********************************************************************
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);			//config to mode B
							
		serial_out(up, UART_OMAP_SCR, up->scr);				//writing to SCR(supplementary control register)
//*******************************************************************							
	/* Reset UART_MCR_TCRTLR: this must be done with the EFR_ECB bit set */
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);			//config mode A
		serial_out(up, UART_MCR, up->mcr);				//writing to MCR without TCRTLR
//*******************************************************************
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);			//config mode B
		serial_out(up, UART_EFR, up->efr);				//writing to EFR register without special character detect enable
//*******************************************************************
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);			//config mode A
							
	/* Protocol, Baud Rate, and Interrupt Settings */
							
		if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)			//
			serial_omap_mdr1_errataset(up, up->mdr1);
		else
			serial_out(up, UART_OMAP_MDR1, up->mdr1);
//********************************************************************
		
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);			//config mode B
		serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);		//writing to EFR register with special character
		
		serial_out(up, UART_LCR, 0);					//writing line control register
		serial_out(up, UART_IER, 0);					//writing to IER
//********************************************************************
		
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);			
		
		serial_out(up, UART_DLL, up->dll);	/* LS of divisor */
		serial_out(up, UART_DLM, up->dlh);	/* MS of divisor */
		
		serial_out(up, UART_LCR, 0);
		serial_out(up, UART_IER, up->ier);
//********************************************************************
		
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
		
		serial_out(up, UART_EFR, up->efr);
		serial_out(up, UART_LCR, cval);
		
		if (baud > 230400 && baud != 3000000)
		{	printk("baud > 230400\n");
			up->mdr1 = UART_OMAP_MDR1_13X_MODE;
		}
		else
		{	printk("baud < 230400\n");
			up->mdr1 = UART_OMAP_MDR1_16X_MODE;
		}
		if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)	
		{	printk("up->errata condition true\n");
			serial_omap_mdr1_errataset(up, up->mdr1);
		}
		else
		{	printk("up->errata condition false\n");
			serial_out(up, UART_OMAP_MDR1, up->mdr1);
		}
//***********************************************************************

	/* Configure flow control */
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);

	/* XON1/XOFF1 accessible mode B, TCRTLR=0, ECB=0 */

//	serial_out(up, UART_XON1, termios->c_cc[VSTART]);
//	serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]);

	/* Enable access to TCR/TLR */
		serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
		serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);

		serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);//TCR trasmission control register value 0xFF 

	//no hardware control 
		up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS);

	
		serial_out(up, UART_MCR, up->mcr);			//write to MCR 
		printk("write to UART_MCR\n");
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);		//write to LCR for switching to config mode B
		printk("Switch to config mode B\n");
		serial_out(up, UART_EFR, up->efr);			//write to EFR
		printk("write to EFR register\n");
		serial_out(up, UART_LCR, up->lcr);			//write to LCR
		printk("write to LCR\n");
	
      	rtdm_lock_put_irqrestore(&up->lock,context1);
        	err = rtdm_irq_enable(&up->irq_handle);
         if(err<0)
              	rtdm_printk("error in rtdm_irq_enable\n");

	printk("serial_omap_set_termios end\n");	 
}