Ejemplo n.º 1
0
/*
 * Perform initialization and enable port for reception
 */
static int atmel_startup(struct uart_port *port)
{
	struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
	int retval;

	/*
	 * Ensure that no interrupts are enabled otherwise when
	 * request_irq() is called we could get stuck trying to
	 * handle an unexpected interrupt
	 */
	UART_PUT_IDR(port, -1);

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, "atmel_serial", port);
	if (retval) {
		printk("atmel_serial: atmel_startup - Can't get irq\n");
		return retval;
	}

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

	/*
	 * Finally, enable the serial port
	 */
	UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
	UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN);		/* enable xmit & rcvr */

	UART_PUT_IER(port, ATMEL_US_RXRDY);		/* enable receive only */

	return 0;
}
Ejemplo n.º 2
0
/*
 * Perform initialization and enable port for reception
 */
static int atmel_startup(struct uart_port *port)
{
	struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
	int retval;

	/*
	 * Ensure that no interrupts are enabled otherwise when
	 * request_irq() is called we could get stuck trying to
	 * handle an unexpected interrupt
	 */
	UART_PUT_IDR(port, -1);

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, "atmel_serial", port);
	if (retval) {
		printk("atmel_serial: atmel_startup - Can't get irq\n");
		return retval;
	}

	/*
	 * Initialize DMA (if necessary)
	 */
	if (atmel_port->use_dma_rx) {
		int i;
		u32 pdc_buffer_size;
#ifdef INFRAD_NO_PDC_SUPPORT
		struct tty_struct *tty = port->info->tty;
		printk ("petworm: serial open index is %d.\n", tty->index);
		if (tty->index == 2)
		{
			printk ("petworm: DMA buffer is 16.\n");
			pdc_buffer_size = 16;
		}
		else
			pdc_buffer_size = PDC_BUFFER_SIZE;
#else
		pdc_buffer_size = PDC_BUFFER_SIZE;
#endif
		for (i = 0; i < 2; i++) {
			struct atmel_dma_buffer *pdc = &atmel_port->pdc_rx[i];

			pdc->buf = kmalloc(pdc_buffer_size, GFP_KERNEL);
			if (pdc->buf == NULL) {
				if (i != 0) {
					dma_unmap_single(port->dev, atmel_port->pdc_rx[0].dma_addr, pdc_buffer_size, DMA_FROM_DEVICE);
					kfree(atmel_port->pdc_rx[0].buf);
				}
				free_irq(port->irq, port);
				return -ENOMEM;
			}
			pdc->dma_addr = dma_map_single(port->dev, pdc->buf, pdc_buffer_size, DMA_FROM_DEVICE);
			pdc->dma_size = pdc_buffer_size;
			pdc->ofs = 0;
		}

		atmel_port->pdc_rx_idx = 0;

		UART_PUT_RPR(port, atmel_port->pdc_rx[0].dma_addr);
		UART_PUT_RCR(port, pdc_buffer_size);

		UART_PUT_RNPR(port, atmel_port->pdc_rx[1].dma_addr);
		UART_PUT_RNCR(port, pdc_buffer_size);
	}
	if (atmel_port->use_dma_tx) {
		struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
		struct circ_buf *xmit = &port->info->xmit;

		pdc->buf = xmit->buf;
		pdc->dma_addr = dma_map_single(port->dev, pdc->buf, SERIAL_XMIT_SIZE, DMA_TO_DEVICE);
		pdc->dma_size = SERIAL_XMIT_SIZE;
		pdc->ofs = 0;
	}

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

	/*
	 * Finally, enable the serial port
	 */
	UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
	UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN);		/* enable xmit & rcvr */

	if (atmel_port->use_dma_rx) {
		UART_PUT_RTOR(port, PDC_RX_TIMEOUT);		/* set UART timeout */
		UART_PUT_CR(port, ATMEL_US_STTTO);

		UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
		UART_PUT_PTCR(port, ATMEL_PDC_RXTEN);		/* enable PDC controller */
	}
	else
		UART_PUT_IER(port, ATMEL_US_RXRDY);		/* enable receive only */

	return 0;
}