Esempio n. 1
0
static void nb85e_uart_tty_enable_tx_interrupts (void *driver_data)
{
	struct nb85e_uart_tty_port *port = driver_data;
	nb85e_intc_disable_irq (IRQ_INTST (port->chan));
	nb85e_uart_tty_tx (port);
	nb85e_intc_enable_irq (IRQ_INTST (port->chan));
}
Esempio n. 2
0
static void nb85e_uart_tty_shutdown_port (void *driver_data)
{
	struct nb85e_uart_tty_port *port = driver_data;

	port->gs.flags &= ~ GS_ACTIVE;

	/* Disable port interrupts.  */
	free_irq (IRQ_INTST (port->chan), port);
	free_irq (IRQ_INTSR (port->chan), port);

	/* Turn off xmit/recv enable bits.  */
	NB85E_UART_ASIM (port->chan) &= ~(NB85E_UART_ASIM_TXE | NB85E_UART_ASIM_RXE);
	/* Then reset the channel.  */
	NB85E_UART_ASIM (port->chan) = 0;
}
Esempio n. 3
0
void __init mach_sched_init (struct irqaction *timer_action)
{
	/* Select timer interrupt instead of external pin.  */
	TEG_ISS |= 0x1;
	/* Start hardware timer.  */
	v850e_timer_d_configure (0, HZ);
	/* Install timer interrupt handler.  */
	setup_irq (IRQ_INTCMD(0), timer_action);
}

static struct v850e_intc_irq_init irq_inits[] = {
	{ "IRQ", 0,		NUM_CPU_IRQS,	1, 7 },
	{ "CMD", IRQ_INTCMD(0),	IRQ_INTCMD_NUM,	1, 5 },
	{ "SER", IRQ_INTSER(0),	IRQ_INTSER_NUM,	1, 3 },
	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM,	1, 4 },
	{ "ST",	 IRQ_INTST(0),	IRQ_INTST_NUM,	1, 5 },
	{ 0 }
};
#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)

static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];

/* Initialize MA chip interrupts.  */
void __init teg_init_irqs (void)
{
	v850e_intc_init_irq_types (irq_inits, hw_itypes);
}

/* Called before configuring an on-chip UART.  */
void teg_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
{
Esempio n. 4
0
int nb85e_uart_tty_open (struct tty_struct *tty, struct file *filp)
{
	int err;
	struct nb85e_uart_tty_port *port;
	unsigned chan = MINOR (tty->device) - NB85E_UART_MINOR_BASE;

	if (chan >= NB85E_UART_NUM_CHANNELS)
		return -ENODEV;

	port = &nb85e_uart_tty_ports[chan];

	tty->driver_data = port;
	port->gs.tty = tty;
	port->gs.count++;

	port->tqueue.routine = gs_do_softint;
	port->tqueue.data = &port->gs;

	/*
	 * Start up serial port
	 */
	err = gs_init_port (&port->gs);
	if (err)
		goto failed_1;

	port->gs.flags |= GS_ACTIVE;

	if (port->gs.count == 1) {
		MOD_INC_USE_COUNT;

		/* Alloc RX irq.  */
		err = request_irq (IRQ_INTSR (chan), nb85e_uart_tty_rx_irq,
				   SA_INTERRUPT, "nb85e_uart", port);
		if (err)
			goto failed_2;

		/* Alloc TX irq.  */
		err = request_irq (IRQ_INTST (chan), nb85e_uart_tty_tx_irq,
				   SA_INTERRUPT, "nb85e_uart", port);
		if (err) {
			free_irq (IRQ_INTSR (chan), port);
			goto failed_2;
		}
	}

	err = gs_block_til_ready (port, filp);
	if (err)
		goto failed_3;

	*tty->termios = port->gs.normal_termios;

	nb85e_uart_tty_enable_rx_interrupts (port);

	port->gs.session = current->session;
	port->gs.pgrp = current->pgrp;

	return 0;

failed_3:
	free_irq (IRQ_INTST (chan), port);
	free_irq (IRQ_INTSR (chan), port);
failed_2:
	MOD_DEC_USE_COUNT;
failed_1:
	port->gs.count--;

	return err;
}
Esempio n. 5
0
static void nb85e_uart_cons_write (struct console *co,
				   const char *s, unsigned count)
{
	if (count > 0) {
		unsigned chan = co->index;
		unsigned irq = IRQ_INTST (chan);
		int irq_was_enabled, irq_was_pending, flags;

		/* We don't want to get `transmission completed' (INTST)
		   interrupts, since we're busy-waiting, so we disable
		   them while sending (we don't disable interrupts
		   entirely because sending over a serial line is really
		   slow).  We save the status of INTST and restore it
		   when we're done so that using printk doesn't
		   interfere with normal serial transmission (other than
		   interleaving the output, of course!).  This should
		   work correctly even if this function is interrupted
		   and the interrupt printks something.  */

		/* Disable interrupts while fiddling with INTST.  */
		save_flags_cli (flags);
		/* Get current INTST status.  */
		irq_was_enabled = nb85e_intc_irq_enabled (irq);
		irq_was_pending = nb85e_intc_irq_pending (irq);
		/* Disable INTST if necessary.  */
		if (irq_was_enabled)
			nb85e_intc_disable_irq (irq);
		/* Turn interrupts back on.  */
		restore_flags (flags);

		/* Send characters.  */
		while (count > 0) {
			int ch = *s++;

			if (ch == '\n') {
				/* We don't have the benefit of a tty
				   driver, so translate NL into CR LF.  */
				nb85e_uart_wait_for_xmit_ok (chan);
				nb85e_uart_putc (chan, '\r');
			}

			nb85e_uart_wait_for_xmit_ok (chan);
			nb85e_uart_putc (chan, ch);

			count--;
		}

		/* Restore saved INTST status.  */
		if (irq_was_enabled) {
			/* Wait for the last character we sent to be
			   completely transmitted (as we'll get an INTST
			   interrupt at that point).  */
			nb85e_uart_wait_for_xmit_done (chan);
			/* Clear pending interrupts received due
			   to our transmission, unless there was already
			   one pending, in which case we want the
			   handler to be called.  */
			if (! irq_was_pending)
				nb85e_intc_clear_pending_irq (irq);
			/* ... and then turn back on handling.  */
			nb85e_intc_enable_irq (irq);
		}
	}
}