Ejemplo n.º 1
0
static void sbd_console_write(struct console *co, const char *s,
			      unsigned int count)
{
	int chip = co->index / DUART_MAX_SIDE;
	int side = co->index % DUART_MAX_SIDE;
	struct sbd_port *sport = &sbd_duarts[chip].sport[side];
	struct uart_port *uport = &sport->port;
	unsigned long flags;
	unsigned int mask;

	/* Disable transmit interrupts and enable the transmitter. */
	spin_lock_irqsave(&uport->lock, flags);
	mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),
		     mask & ~M_DUART_IMR_TX);
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN);
	spin_unlock_irqrestore(&uport->lock, flags);

	uart_console_write(&sport->port, s, count, sbd_console_putchar);

	/* Restore transmit interrupts and the transmitter enable. */
	spin_lock_irqsave(&uport->lock, flags);
	sbd_line_drain(sport);
	if (sport->tx_stopped)
		write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS);
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);
	spin_unlock_irqrestore(&uport->lock, flags);
}
Ejemplo n.º 2
0
static void sbd_start_tx(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mask;

	/* Enable tx interrupts.  */
	mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
	mask |= M_DUART_IMR_TX;
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);

	/* Go!, go!, go!...  */
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN);
	sport->tx_stopped = 0;
};
Ejemplo n.º 3
0
static int sbd_startup(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mode1;
	int ret;

	ret = request_irq(sport->port.irq, sbd_interrupt,
			  IRQF_SHARED, "sb1250-duart", sport);
	if (ret)
		return ret;

	/* Clear the receive FIFO.  */
	sbd_receive_drain(sport);

	/* Clear the interrupt registers.  */
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT);
	read_sbdshr(sport, R_DUART_INCHREG((uport->line) % 2));

	/* Set rx/tx interrupt to FIFO available.  */
	mode1 = read_sbdchn(sport, R_DUART_MODE_REG_1);
	mode1 &= ~(M_DUART_RX_IRQ_SEL_RXFULL | M_DUART_TX_IRQ_SEL_TXEMPT);
	write_sbdchn(sport, R_DUART_MODE_REG_1, mode1);

	/* Disable tx, enable rx.  */
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_EN);
	sport->tx_stopped = 1;

	/* Enable interrupts.  */
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),
		     M_DUART_IMR_IN | M_DUART_IMR_RX);

	return 0;
}
Ejemplo n.º 4
0
static irqreturn_t sbd_interrupt(int irq, void *dev_id)
{
	struct sbd_port *sport = dev_id;
	struct uart_port *uport = &sport->port;
	irqreturn_t status = IRQ_NONE;
	unsigned int intstat;
	int count;

	for (count = 16; count; count--) {
		intstat = read_sbdshr(sport,
				      R_DUART_ISRREG((uport->line) % 2));
		intstat &= read_sbdshr(sport,
				       R_DUART_IMRREG((uport->line) % 2));
		intstat &= M_DUART_ISR_ALL;
		if (!intstat)
			break;

		if (intstat & M_DUART_ISR_RX)
			sbd_receive_chars(sport);
		if (intstat & M_DUART_ISR_IN)
			sbd_status_handle(sport);
		if (intstat & M_DUART_ISR_TX)
			sbd_transmit_chars(sport);

		status = IRQ_HANDLED;
	}

	return status;
}
Ejemplo n.º 5
0
static int sbd_startup(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mode1;
	int ret;

	ret = request_irq(sport->port.irq, sbd_interrupt,
			  IRQF_SHARED, "sb1250-duart", sport);
	if (ret)
		return ret;

	
	sbd_receive_drain(sport);

	
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT);
	read_sbdshr(sport, R_DUART_INCHREG((uport->line) % 2));

	
	mode1 = read_sbdchn(sport, R_DUART_MODE_REG_1);
	mode1 &= ~(M_DUART_RX_IRQ_SEL_RXFULL | M_DUART_TX_IRQ_SEL_TXEMPT);
	write_sbdchn(sport, R_DUART_MODE_REG_1, mode1);

	
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_EN);
	sport->tx_stopped = 1;

	
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),
		     M_DUART_IMR_IN | M_DUART_IMR_RX);

	return 0;
}
Ejemplo n.º 6
0
static void sb1250_uart_probe(cfe_driver_t *drv,
			      unsigned long probe_a, unsigned long probe_b, 
			      void *probe_ptr)
{
    sb1250_uart_t *softc;
    char descr[80];

    /* 
     * probe_a is the DUART base address.
     * probe_b is the channel-number-within-duart (0 or 1)
     * probe_ptr is unused.
     */

    softc = (sb1250_uart_t *) KMALLOC(sizeof(sb1250_uart_t),0);
    if (softc) {
	softc->uart_mode_reg_1 = probe_a + R_DUART_CHANREG(probe_b,R_DUART_MODE_REG_1);
	softc->uart_mode_reg_2 = probe_a + R_DUART_CHANREG(probe_b,R_DUART_MODE_REG_2);
	softc->uart_clk_sel    = probe_a + R_DUART_CHANREG(probe_b,R_DUART_CLK_SEL);
	softc->uart_cmd        = probe_a + R_DUART_CHANREG(probe_b,R_DUART_CMD);
	softc->uart_status     = probe_a + R_DUART_CHANREG(probe_b,R_DUART_STATUS);
	softc->uart_tx_hold    = probe_a + R_DUART_CHANREG(probe_b,R_DUART_TX_HOLD);
	softc->uart_rx_hold    = probe_a + R_DUART_CHANREG(probe_b,R_DUART_RX_HOLD);	
	softc->uart_imr        = probe_a + R_DUART_IMRREG(probe_b);
	softc->uart_oprset     = probe_a + R_DUART_SET_OPR;
	xsprintf(descr,"%s at 0x%X channel %d",drv->drv_description,probe_a,probe_b);
	softc->uart_speed = CFG_SERIAL_BAUD_RATE;
	softc->uart_flowcontrol = SERIAL_FLOW_NONE;
    
	cfe_attach(drv,softc,NULL,descr);
	}

}
Ejemplo n.º 7
0
static void sbd_transmit_chars(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;
	struct circ_buf *xmit = &sport->port.state->xmit;
	unsigned int mask;
	int stop_tx;

	/* XON/XOFF chars.  */
	if (sport->port.x_char) {
		write_sbdchn(sport, R_DUART_TX_HOLD, sport->port.x_char);
		sport->port.icount.tx++;
		sport->port.x_char = 0;
		return;
	}

	/* If nothing to do or stopped or hardware stopped.  */
	stop_tx = (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port));

	/* Send char.  */
	if (!stop_tx) {
		write_sbdchn(sport, R_DUART_TX_HOLD, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		sport->port.icount.tx++;

		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
			uart_write_wakeup(&sport->port);
	}

	/* Are we are done?  */
	if (stop_tx || uart_circ_empty(xmit)) {
		/* Disable tx interrupts.  */
		mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
		mask &= ~M_DUART_IMR_TX;
		write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);
	}
}
Ejemplo n.º 8
0
static void sbd_transmit_chars(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;
	struct circ_buf *xmit = &sport->port.state->xmit;
	unsigned int mask;
	int stop_tx;

	
	if (sport->port.x_char) {
		write_sbdchn(sport, R_DUART_TX_HOLD, sport->port.x_char);
		sport->port.icount.tx++;
		sport->port.x_char = 0;
		return;
	}

	
	stop_tx = (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port));

	
	if (!stop_tx) {
		write_sbdchn(sport, R_DUART_TX_HOLD, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		sport->port.icount.tx++;

		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
			uart_write_wakeup(&sport->port);
	}

	
	if (stop_tx || uart_circ_empty(xmit)) {
		
		mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
		mask &= ~M_DUART_IMR_TX;
		write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);
	}
}
Ejemplo n.º 9
0
void bcm1250DuartDevInit
    (
    BCM1250_DUART_CHAN * pChan
    )
    {
    int oldlevel;

    pChan->intEnable		= FALSE;

    if((pChan->channel != BCM1250_DUART_CHANNEL_A ) && 
       (pChan->channel != BCM1250_DUART_CHANNEL_B))
      return;

    pChan->duartBase = (void *)PHYS_TO_K1(A_DUART);

    pChan->chanBase = pChan->duartBase + R_DUART_CHANREG(pChan->channel, 0);
    pChan->chanIMR  = (unsigned long long *)
      (pChan->duartBase + R_DUART_IMRREG(pChan->channel));
    pChan->chanISR  = (unsigned long long *)
      (pChan->duartBase + R_DUART_ISRREG(pChan->channel));

    pChan->intSource = (pChan->channel == BCM1250_DUART_CHANNEL_A) ?
      K_INT_UART_0 : K_INT_UART_1;

    /* clear delta interrupts */
    bcm1250DuartAcrSet (pChan, 0);

    /* don't relay TX clock on output in */
    bcm1250DuartTxCoutRelay (pChan, FALSE );

    /* assert RTS (request to send ) */
    bcm1250DuartRts (pChan, TRUE);

    /* init callbacks and set default options */
    bcm1250DuartInitStruct (pChan);

    oldlevel =  intLock ();

    /* Clear the interrupt mask register */
    MIPS3_SD(pChan->chanIMR, 0);

    bcm1250DuartInitChannel (pChan);

    intUnlock (oldlevel);
    }
Ejemplo n.º 10
0
static void sbd_init_port(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;

	if (sport->initialised)
		return;

	/* There is no DUART reset feature, so just set some sane defaults.  */
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_TX);
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_RX);
	write_sbdchn(sport, R_DUART_MODE_REG_1, V_DUART_BITS_PER_CHAR_8);
	write_sbdchn(sport, R_DUART_MODE_REG_2, 0);
	write_sbdchn(sport, R_DUART_FULL_CTL,
		     V_DUART_INT_TIME(0) | V_DUART_SIG_FULL(15));
	write_sbdchn(sport, R_DUART_OPCR_X, 0);
	write_sbdchn(sport, R_DUART_AUXCTL_X, 0);
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0);

	sport->initialised = 1;
}
Ejemplo n.º 11
0
static void sbd_stop_rx(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);

	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0);
};