/* * 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; }
/* * 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; }