Beispiel #1
0
static int txx9_sio_kgdb_init(void)
{
	struct uart_port *port = &uart_txx9_port[kgdb_txx9_ttyS];
	unsigned int quot, sibgr;

	if (port->iotype != UPIO_MEM && port->iotype != UPIO_MEM32)
		return -1;

	/* Reset the UART. */
	sio_out(port, TXX9_SIFCR, TXX9_SIFCR_SWRST);
#ifdef CONFIG_CPU_TX49XX
	/*
	 * TX4925 BUG WORKAROUND.  Accessing SIOC register
	 * immediately after soft reset causes bus error.
	 */
	iob();
	udelay(1);
#endif
	/* Wait until reset is complete. */
	while (sio_in(port, TXX9_SIFCR) & TXX9_SIFCR_SWRST);

	/* Select the frame format and input clock. */
	sio_out(port, TXX9_SILCR,
		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
		((port->flags & UPF_MAGIC_MULTIPLIER) ?
		TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));

	/* Select the input clock prescaler that fits the baud rate. */
	quot = (port->uartclk + 8 * kgdb_txx9_baud) / (16 * kgdb_txx9_baud);
	if (quot < (256 << 1))
		sibgr = (quot >> 1) | TXX9_SIBGR_BCLK_T0;
	else if (quot < ( 256 << 3))
Beispiel #2
0
/*
 * This is the serial driver's interrupt routine.
 *
 * Arjan thinks the old way was overly complex, so it got simplified.
 * Alan disagrees, saying that need the complexity to handle the weird
 * nature of ISA shared interrupts.  (This is a special exception.)
 *
 * In order to handle ISA shared interrupts properly, we need to check
 * that all ports have been serviced, and therefore the ISA interrupt
 * line has been de-asserted.
 *
 * This means we need to loop through all ports. checking that they
 * don't have an interrupt pending.
 */
static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id)
{
	struct irq_info *i = dev_id;
	struct list_head *l, *end = NULL;
	int pass_counter = 0;

	pr_debug("m32r_sio_interrupt(%d)...\n", irq);

#ifdef CONFIG_SERIAL_M32R_PLDSIO
//	if (irq == PLD_IRQ_SIO0_SND)
//		irq = PLD_IRQ_SIO0_RCV;
#else
	if (irq == M32R_IRQ_SIO0_S)
		irq = M32R_IRQ_SIO0_R;
#endif

	spin_lock(&i->lock);

	l = i->head;
	do {
		struct uart_sio_port *up;
		unsigned int sts;

		up = list_entry(l, struct uart_sio_port, list);

		sts = sio_in(up, SIOSTS);
		if (sts & 0x5) {
			spin_lock(&up->port.lock);
			m32r_sio_handle_port(up, sts);
			spin_unlock(&up->port.lock);

			end = NULL;
		} else if (end == NULL)
			end = l;

		l = l->next;

		if (l == i->head && pass_counter++ > PASS_LIMIT) {
			if (sts & 0xe0)
				sio_error(&sts);
			break;
		}
	} while (l != end);

	spin_unlock(&i->lock);

	pr_debug("end.\n");

	return IRQ_HANDLED;
}
Beispiel #3
0
/*
 * This function is used to handle ports that do not have an interrupt.
 */
static void m32r_sio_timeout(unsigned long data)
{
	struct uart_sio_port *up = (struct uart_sio_port *)data;
	unsigned int timeout;
	unsigned int sts;

	sts = sio_in(up, SIOSTS);
	if (sts & 0x5) {
		spin_lock(&up->port.lock);
		m32r_sio_handle_port(up, sts);
		spin_unlock(&up->port.lock);
	}

	timeout = up->port.timeout;
	timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
	mod_timer(&up->timer, jiffies + timeout);
}
Beispiel #4
0
/*
 *	Wait for transmitter & holding register to empty
 */
static void wait_for_xmitr(struct uart_sio_port *up)
{
	unsigned int status, tmout = 10000;

	/* Wait up to 10ms for the character(s) to be sent. */
	do {
		status = sio_in(up, SIOSTS);

		if (--tmout == 0)
			break;
		udelay(1);
	} while ((status & UART_EMPTY) != UART_EMPTY);

	/* Wait up to 1s for flow control if necessary */
	if (up->port.flags & UPF_CONS_FLOW) {
		tmout = 1000000;
		while (--tmout)
			udelay(1);
	}
}
Beispiel #5
0
/*
 *	Print a string to the serial port trying not to disturb
 *	any possible real use of the port...
 *
 *	The console_lock must be held when we get here.
 */
static void m32r_sio_console_write(struct console *co, const char *s,
	unsigned int count)
{
	struct uart_sio_port *up = &m32r_sio_ports[co->index];
	unsigned int ier;

	/*
	 *	First save the UER then disable the interrupts
	 */
	ier = sio_in(up, SIOTRCR);
	sio_out(up, SIOTRCR, 0);

	uart_console_write(&up->port, s, count, m32r_sio_console_putchar);

	/*
	 *	Finally, wait for transmitter to become empty
	 *	and restore the IER
	 */
	wait_for_xmitr(up);
	sio_out(up, SIOTRCR, ier);
}
Beispiel #6
0
static void receive_chars(struct uart_sio_port *up, int *status)
{
	struct tty_port *port = &up->port.state->port;
	unsigned char ch;
	unsigned char flag;
	int max_count = 256;

	do {
		ch = sio_in(up, SIORXB);
		flag = TTY_NORMAL;
		up->port.icount.rx++;

		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
				       UART_LSR_FE | UART_LSR_OE))) {
			/*
			 * For statistics only
			 */
			if (*status & UART_LSR_BI) {
				*status &= ~(UART_LSR_FE | UART_LSR_PE);
				up->port.icount.brk++;
				/*
				 * We do the SysRQ and SAK checking
				 * here because otherwise the break
				 * may get masked by ignore_status_mask
				 * or read_status_mask.
				 */
				if (uart_handle_break(&up->port))
					goto ignore_char;
			} else if (*status & UART_LSR_PE)
				up->port.icount.parity++;
			else if (*status & UART_LSR_FE)
				up->port.icount.frame++;
			if (*status & UART_LSR_OE)
				up->port.icount.overrun++;

			/*
			 * Mask off conditions which should be ingored.
			 */
			*status &= up->port.read_status_mask;

			if (*status & UART_LSR_BI) {
				pr_debug("handling break....\n");
				flag = TTY_BREAK;
			} else if (*status & UART_LSR_PE)
				flag = TTY_PARITY;
			else if (*status & UART_LSR_FE)
				flag = TTY_FRAME;
		}
		if (uart_handle_sysrq_char(&up->port, ch))
			goto ignore_char;
		if ((*status & up->port.ignore_status_mask) == 0)
			tty_insert_flip_char(port, ch, flag);

		if (*status & UART_LSR_OE) {
			/*
			 * Overrun is special, since it's reported
			 * immediately, and doesn't affect the current
			 * character.
			 */
			tty_insert_flip_char(port, 0, TTY_OVERRUN);
		}
	ignore_char:
		*status = serial_in(up, UART_LSR);
	} while ((*status & UART_LSR_DR) && (max_count-- > 0));

	spin_unlock(&up->port.lock);
	tty_flip_buffer_push(port);
	spin_lock(&up->port.lock);
}
Beispiel #7
0
static inline void
sio_set(struct uart_txx9_port *up, int offset, unsigned int value)
{
	sio_out(up, offset, sio_in(up, offset) | value);
}