Example #1
0
static int sa1100_startup(struct uart_port *port)
{
	struct sa1100_port *sport = (struct sa1100_port *)port;
	int retval;

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(sport->port.irq, sa1100_int, 0,
			     "sa11x0-uart", sport);
	if (retval)
		return retval;

	/*
	 * If there is a specific "open" function
	 * (to register control line interrupts)
	 */
	if (sa1100_open) {
		retval = sa1100_open(port);
		if (retval) {
			free_irq(sport->port.irq, sport);
			return retval;
		}
	}

	/*
	 * Finally, clear and enable interrupts
	 */
	UART_PUT_UTSR0(sport, -1);
	UART_PUT_UTCR3(sport, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);

	return 0;
}
static int sa1100_startup(struct uart_port *port)
{
	struct sa1100_port *sport = (struct sa1100_port *)port;
	int retval;

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(sport->port.irq, sa1100_int, 0,
			     "sa11x0-uart", sport);
	if (retval)
		return retval;

	/*
	 * Finally, clear and enable interrupts
	 */
	UART_PUT_UTSR0(sport, -1);
	UART_PUT_UTCR3(sport, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);

	/*
	 * Enable modem status interrupts
	 */
	spin_lock_irq(&sport->port.lock);
	sa1100_enable_ms(&sport->port);
	spin_unlock_irq(&sport->port.lock);

	return 0;
}
Example #3
0
static int sa1100_startup(struct uart_port *port, struct uart_info *info)
{
	int retval;

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(port->irq, sa1100_int, 0, "serial_sa1100", info);
	if (retval)
		return retval;

	/*
	 * If there is a specific "open" function (to register
	 * control line interrupts)
	 */
	if (sa1100_open) {
		retval = sa1100_open(port, info);
		if (retval) {
			free_irq(port->irq, info);
			return retval;
		}
	}

	/*
	 * Finally, clear and enable interrupts
	 */
	UART_PUT_UTSR0(port, -1);
	UART_PUT_UTCR3(port, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);

	return 0;
}
Example #4
0
static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
{
	struct uart_info *info = dev_id;
	struct uart_port *port = info->port;
	unsigned int status, pass_counter = 0;

	status = UART_GET_UTSR0(port);
	status &= (SM_TO_UTSR0(port->read_status_mask) | ~UTSR0_TFS);
	do {
		if (status & (UTSR0_RFS | UTSR0_RID)) {
			/* Clear the receiver idle bit, if set */
			if (status & UTSR0_RID)
				UART_PUT_UTSR0(port, UTSR0_RID);
			sa1100_rx_chars(info, regs);
		}

		/* Clear the relevent break bits */
		if (status & (UTSR0_RBB | UTSR0_REB))
			UART_PUT_UTSR0(port, status & (UTSR0_RBB | UTSR0_REB));

		if (status & UTSR0_RBB)
			port->icount.brk++;

		if (status & UTSR0_REB) {
#ifdef SUPPORT_SYSRQ
			if (port->line == sa1100_console.index &&
			    !info->sysrq) {
				info->sysrq = jiffies + HZ*5;
			}
#endif
		}
		if (status & UTSR0_TFS)
			sa1100_tx_chars(info);
		if (pass_counter++ > SA1100_ISR_PASS_LIMIT)
			break;
		status = UART_GET_UTSR0(port);
		status &= (SM_TO_UTSR0(port->read_status_mask) | ~UTSR0_TFS);
	} while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));
}
static irqreturn_t sa1100_int(int irq, void *dev_id)
{
	struct sa1100_port *sport = dev_id;
	unsigned int status, pass_counter = 0;

	spin_lock(&sport->port.lock);
	status = UART_GET_UTSR0(sport);
	status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS;
	do {
		if (status & (UTSR0_RFS | UTSR0_RID)) {
			/* Clear the receiver idle bit, if set */
			if (status & UTSR0_RID)
				UART_PUT_UTSR0(sport, UTSR0_RID);
			sa1100_rx_chars(sport);
		}

		/* Clear the relevant break bits */
		if (status & (UTSR0_RBB | UTSR0_REB))
			UART_PUT_UTSR0(sport, status & (UTSR0_RBB | UTSR0_REB));

		if (status & UTSR0_RBB)
			sport->port.icount.brk++;

		if (status & UTSR0_REB)
			uart_handle_break(&sport->port);

		if (status & UTSR0_TFS)
			sa1100_tx_chars(sport);
		if (pass_counter++ > SA1100_ISR_PASS_LIMIT)
			break;
		status = UART_GET_UTSR0(sport);
		status &= SM_TO_UTSR0(sport->port.read_status_mask) |
			  ~UTSR0_TFS;
	} while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));
	spin_unlock(&sport->port.lock);

	return IRQ_HANDLED;
}
Example #6
0
static int sa1100_startup(struct uart_port *port)
{
	struct sa1100_port *sport = (struct sa1100_port *)port;
	int retval;

	
	retval = request_irq(sport->port.irq, sa1100_int, 0,
			     "sa11x0-uart", sport);
	if (retval)
		return retval;

	
	UART_PUT_UTSR0(sport, -1);
	UART_PUT_UTCR3(sport, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);

	
	spin_lock_irq(&sport->port.lock);
	sa1100_enable_ms(&sport->port);
	spin_unlock_irq(&sport->port.lock);

	return 0;
}
static void
sa1100_set_termios(struct uart_port *port, struct ktermios *termios,
		   struct ktermios *old)
{
	struct sa1100_port *sport = (struct sa1100_port *)port;
	unsigned long flags;
	unsigned int utcr0, old_utcr3, baud, quot;
	unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;

	/*
	 * We only support CS7 and CS8.
	 */
	while ((termios->c_cflag & CSIZE) != CS7 &&
	       (termios->c_cflag & CSIZE) != CS8) {
		termios->c_cflag &= ~CSIZE;
		termios->c_cflag |= old_csize;
		old_csize = CS8;
	}

	if ((termios->c_cflag & CSIZE) == CS8)
		utcr0 = UTCR0_DSS;
	else
		utcr0 = 0;

	if (termios->c_cflag & CSTOPB)
		utcr0 |= UTCR0_SBS;
	if (termios->c_cflag & PARENB) {
		utcr0 |= UTCR0_PE;
		if (!(termios->c_cflag & PARODD))
			utcr0 |= UTCR0_OES;
	}

	/*
	 * Ask the core to calculate the divisor for us.
	 */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
	quot = uart_get_divisor(port, baud);

	spin_lock_irqsave(&sport->port.lock, flags);

	sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
	sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
	if (termios->c_iflag & INPCK)
		sport->port.read_status_mask |=
				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (termios->c_iflag & (BRKINT | PARMRK))
		sport->port.read_status_mask |=
				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);

	/*
	 * Characters to ignore
	 */
	sport->port.ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		sport->port.ignore_status_mask |=
				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (termios->c_iflag & IGNBRK) {
		sport->port.ignore_status_mask |=
				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			sport->port.ignore_status_mask |=
				UTSR1_TO_SM(UTSR1_ROR);
	}

	del_timer_sync(&sport->timer);

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	/*
	 * disable interrupts and drain transmitter
	 */
	old_utcr3 = UART_GET_UTCR3(sport);
	UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));

	while (UART_GET_UTSR1(sport) & UTSR1_TBY)
		barrier();

	/* then, disable everything */
	UART_PUT_UTCR3(sport, 0);

	/* set the parity, stop bits and data size */
	UART_PUT_UTCR0(sport, utcr0);

	/* set the baud rate */
	quot -= 1;
	UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8));
	UART_PUT_UTCR2(sport, (quot & 0xff));

	UART_PUT_UTSR0(sport, -1);

	UART_PUT_UTCR3(sport, old_utcr3);

	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
		sa1100_enable_ms(&sport->port);

	spin_unlock_irqrestore(&sport->port.lock, flags);
}
Example #8
0
static void
sa1100_set_termios(struct uart_port *port, struct ktermios *termios,
		   struct ktermios *old)
{
	struct sa1100_port *sport = (struct sa1100_port *)port;
	unsigned long flags;
	unsigned int utcr0, old_utcr3, baud, quot;
	unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;

	
	while ((termios->c_cflag & CSIZE) != CS7 &&
	       (termios->c_cflag & CSIZE) != CS8) {
		termios->c_cflag &= ~CSIZE;
		termios->c_cflag |= old_csize;
		old_csize = CS8;
	}

	if ((termios->c_cflag & CSIZE) == CS8)
		utcr0 = UTCR0_DSS;
	else
		utcr0 = 0;

	if (termios->c_cflag & CSTOPB)
		utcr0 |= UTCR0_SBS;
	if (termios->c_cflag & PARENB) {
		utcr0 |= UTCR0_PE;
		if (!(termios->c_cflag & PARODD))
			utcr0 |= UTCR0_OES;
	}

	
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
	quot = uart_get_divisor(port, baud);

	spin_lock_irqsave(&sport->port.lock, flags);

	sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
	sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
	if (termios->c_iflag & INPCK)
		sport->port.read_status_mask |=
				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (termios->c_iflag & (BRKINT | PARMRK))
		sport->port.read_status_mask |=
				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);

	
	sport->port.ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		sport->port.ignore_status_mask |=
				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (termios->c_iflag & IGNBRK) {
		sport->port.ignore_status_mask |=
				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
		
		if (termios->c_iflag & IGNPAR)
			sport->port.ignore_status_mask |=
				UTSR1_TO_SM(UTSR1_ROR);
	}

	del_timer_sync(&sport->timer);

	
	uart_update_timeout(port, termios->c_cflag, baud);

	
	old_utcr3 = UART_GET_UTCR3(sport);
	UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));

	while (UART_GET_UTSR1(sport) & UTSR1_TBY)
		barrier();

	
	UART_PUT_UTCR3(sport, 0);

	
	UART_PUT_UTCR0(sport, utcr0);

	
	quot -= 1;
	UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8));
	UART_PUT_UTCR2(sport, (quot & 0xff));

	UART_PUT_UTSR0(sport, -1);

	UART_PUT_UTCR3(sport, old_utcr3);

	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
		sa1100_enable_ms(&sport->port);

	spin_unlock_irqrestore(&sport->port.lock, flags);
}
Example #9
0
static void sa1100_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
{
	struct sa1100_port *sport = (struct sa1100_port *)port;
	unsigned long flags;
	unsigned int utcr0, old_utcr3;

	if ((cflag & CSIZE) == CS8)
		utcr0 = UTCR0_DSS;
	else
		utcr0 = 0;

	if (cflag & CSTOPB)
		utcr0 |= UTCR0_SBS;
	if (cflag & PARENB) {
		utcr0 |= UTCR0_PE;
		if (!(cflag & PARODD))
			utcr0 |= UTCR0_OES;
	}

	spin_lock_irqsave(&sport->port.lock, flags);

	sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
	sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
	if (iflag & INPCK)
		sport->port.read_status_mask |=
				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (iflag & (BRKINT | PARMRK))
		sport->port.read_status_mask |=
				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);

	/*
	 * Characters to ignore
	 */
	sport->port.ignore_status_mask = 0;
	if (iflag & IGNPAR)
		sport->port.ignore_status_mask |=
				UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (iflag & IGNBRK) {
		sport->port.ignore_status_mask |=
				UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (iflag & IGNPAR)
			sport->port.ignore_status_mask |=
				UTSR1_TO_SM(UTSR1_ROR);
	}

	del_timer_sync(&sport->timer);

	/*
	 * disable interrupts and drain transmitter
	 */
	old_utcr3 = UART_GET_UTCR3(sport);
	UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));

	while (UART_GET_UTSR1(sport) & UTSR1_TBY)
		barrier();

	/* then, disable everything */
	UART_PUT_UTCR3(sport, 0);

	/* set the parity, stop bits and data size */
	UART_PUT_UTCR0(sport, utcr0);

	/* set the baud rate */
	quot -= 1;
	UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8));
	UART_PUT_UTCR2(sport, (quot & 0xff));

	UART_PUT_UTSR0(sport, -1);

	UART_PUT_UTCR3(sport, old_utcr3);

	if (UART_ENABLE_MS(&sport->port, cflag))
		sa1100_enable_ms(&sport->port);

	spin_unlock_irqrestore(&sport->port.lock, flags);
}
Example #10
0
static void sa1100_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
{
	unsigned long flags;
	u_int utcr0, old_utcr3;

	/* byte size and parity */
	switch (cflag & CSIZE) {
	case CS7:	utcr0 = 0;		break;
	default:	utcr0 = UTCR0_DSS;	break;
	}
	if (cflag & CSTOPB)
		utcr0 |= UTCR0_SBS;
	if (cflag & PARENB) {
		utcr0 |= UTCR0_PE;
		if (!(cflag & PARODD))
			utcr0 |= UTCR0_OES;
	}

	port->read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
	port->read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
	if (iflag & INPCK)
		port->read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (iflag & IGNPAR)
		port->ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
	if (iflag & IGNBRK) {
		port->ignore_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (iflag & IGNPAR)
			port->ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
	}

	/* first, disable interrupts and drain transmitter */
	local_irq_save(flags);
	old_utcr3 = UART_GET_UTCR3(port);
	UART_PUT_UTCR3(port, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));
	local_irq_restore(flags);
	while (UART_GET_UTSR1(port) & UTSR1_TBY);

	/* then, disable everything */
	UART_PUT_UTCR3(port, 0);

	/* set the parity, stop bits and data size */
	UART_PUT_UTCR0(port, utcr0);

	/* set the baud rate */
	quot -= 1;
	UART_PUT_UTCR1(port, ((quot & 0xf00) >> 8));
	UART_PUT_UTCR2(port, (quot & 0xff));

	UART_PUT_UTSR0(port, -1);

	UART_PUT_UTCR3(port, old_utcr3);
}