static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags = 0; dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); pm_runtime_get_sync(up->dev); /* * Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); spin_lock_irqsave(&up->port.lock, flags); up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); /* * Disable break condition and FIFOs */ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); /* * Read data port to reset things, and then free the irq */ if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); free_irq(up->port.irq, up); }
static int uart_close_nrt(struct rtdm_dev_context *context,rtdm_user_info_t * user_info) { int err; MY_DEV *up=(MY_DEV *)context->device->device_data; dev_dbg(up->dev, "serial_omap_shutdown+%d\n", up->line); up->ier = 0; serial_out(up, UART_IER, 0); //disable break condition and FIFOs serial_out(up,UART_LCR,serial_in(up,UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); //read data port to reset things and then free irq if(serial_in(up,UART_LSR) & UART_LSR_DR) (void)serial_in(up,UART_RX); err=rtdm_irq_disable(&up->irq_handle);//enable irq if(err<0) { rtdm_printk("error in rtdm_irq_disable\n"); return err; } rtdm_printk("rtdm_irq_disable\n"); rtdm_irq_free(&up->irq_handle); free_irq(up->irq, up); return 0; }
static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; u8 lcr, efr; dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id); /* * Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); /* If we're using auto-rts then disable it. */ spin_lock_irqsave(&up->port.lock, flags); lcr = serial_in(up, UART_LCR); serial_out(up, UART_LCR, 0xbf); efr = serial_in(up, UART_EFR); serial_out(up, UART_LCR, lcr); if (efr & UART_EFR_RTS) { serial_omap_set_autorts(up, 0); up->restore_autorts = 1; } up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, (up->port.mctrl & ~TIOCM_RTS)); spin_unlock_irqrestore(&up->port.lock, flags); /* * Disable break condition and FIFOs */ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); /* * Read data port to reset things, and then free the irq */ if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); if (up->use_dma) { int tmp; dma_free_coherent(up->port.dev, UART_XMIT_SIZE, up->port.state->xmit.buf, up->uart_dma.tx_buf_dma_phys); up->port.state->xmit.buf = NULL; serial_omap_stop_rx(port); dma_free_coherent(up->port.dev, up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); up->uart_dma.rx_buf = NULL; tmp = serial_in(up, UART_OMAP_SYSC) & OMAP_UART_SYSC_RESET; serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ } free_irq(up->port.irq, up); }
static int serial_omap_startup(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; int retval; retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags, up->name, up); if (retval) return retval; dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); pm_runtime_get_sync(&up->pdev->dev); serial_omap_clear_fifos(up); serial_out(up, UART_MCR, UART_MCR_RTS); (void) serial_in(up, UART_LSR); if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); (void) serial_in(up, UART_IIR); (void) serial_in(up, UART_MSR); serial_out(up, UART_LCR, UART_LCR_WLEN8); spin_lock_irqsave(&up->port.lock, flags); up->port.mctrl |= TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); up->msr_saved_flags = 0; if (up->use_dma) { free_page((unsigned long)up->port.state->xmit.buf); up->port.state->xmit.buf = dma_alloc_coherent(NULL, UART_XMIT_SIZE, (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); init_timer(&(up->uart_dma.rx_timer)); up->uart_dma.rx_timer.function = serial_omap_rxdma_poll; up->uart_dma.rx_timer.data = up->port.line; up->uart_dma.rx_buf = dma_alloc_coherent(NULL, up->uart_dma.rx_buf_size, (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); } up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); pm_runtime_mark_last_busy(&up->pdev->dev); pm_runtime_put_autosuspend(&up->pdev->dev); up->port_activity = jiffies; return 0; }
static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id); /* * Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); spin_lock_irqsave(&up->port.lock, flags); up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); /* * Disable break condition and FIFOs */ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); /* * Read data port to reset things, and then free the irq */ if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); if (up->use_dma) { int tmp; dma_free_coherent(up->port.dev, UART_XMIT_SIZE, up->port.state->xmit.buf, up->uart_dma.tx_buf_dma_phys); up->port.state->xmit.buf = NULL; serial_omap_stop_rx(port); dma_free_coherent(up->port.dev, up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); up->uart_dma.rx_buf = NULL; tmp = serial_in(up, UART_OMAP_SYSC) & OMAP_UART_SYSC_RESET; serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ } free_irq(up->port.irq, up); #if defined(CONFIG_KEYBOARD_P1) if((up->port.line == 2)&&(g_keyboard)) { send_keyevent(0); } #endif /* Set this to zero, would be initialsed * to the corrcet value at set_stermios. */ up->baud_rate = 0; }
static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags; DPRINTK("serial_omap_shutdown+%d\n", up->pdev->id); /* * Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); spin_lock_irqsave(&up->port.lock, flags); if (up->port.flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ inb((up->port.iobase & 0xfe0) | 0x1f); up->port.mctrl |= TIOCM_OUT1; } else up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); /* * Disable break condition and FIFOs */ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); /* * Read data port to reset things, and then free the irq */ (void) serial_in(up, UART_RX); if (up->use_dma) { int tmp; if (up->is_buf_dma_alloced) { dma_free_coherent(up->port.dev, UART_XMIT_SIZE, up->port.info->xmit.buf, up->uart_dma.tx_buf_dma_phys); up->port.info->xmit.buf = NULL; up->is_buf_dma_alloced = 0; } /*TBD: Check if this is really needed here*/ serial_omap_stop_rx(port); dma_free_coherent(up->port.dev, up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); up->uart_dma.rx_buf = NULL; tmp = serial_in(up, UART_OMAP_SYSC) & 0x7; serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ } free_irq(up->port.irq, up); }
static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id); serial_omap_port_enable(up); /* * Disable interrupts & wakeup events from this port */ up->ier = 0; up->wer_restore = 0; serial_out(up, UART_OMAP_WER, 0); serial_out(up, UART_IER, 0); spin_lock_irqsave(&up->port.lock, flags); up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); /* * Disable break condition and FIFOs */ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); /* * Read data port to reset things, and then free the irq */ if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); if (up->use_dma) { dma_free_coherent(up->port.dev, UART_XMIT_SIZE, up->port.state->xmit.buf, up->uart_dma.tx_buf_dma_phys); up->port.state->xmit.buf = NULL; serial_omap_stop_rx(port); dma_free_coherent(up->port.dev, up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); up->uart_dma.rx_buf = NULL; } serial_omap_port_disable(up); free_irq(up->port.irq, up); }
int omap_uart_active(int num, u32 timeout) { struct uart_omap_port *up = ui[num]; struct circ_buf *xmit; unsigned int status, iir; /* Check for recent driver activity. If time delta from now * to last activty < "uart idle timeout" second keep clocks on. */ if (((jiffies - up->port_activity) < timeout)) return 1; xmit = &up->port.state->xmit; if (!(uart_circ_empty(xmit) || uart_tx_stopped(&up->port))) return 1; status = serial_in(up, UART_LSR); /* TX hardware not empty */ if (!(status & (UART_LSR_TEMT | UART_LSR_THRE))) return 1; /* The data ready in receive line, however, no interrupt * is pending. The uart controller could not recover from * this state. Clear the uart fifos to work around this bug. */ iir = serial_in(up, UART_IIR); /* Any rx activity? */ if (status & UART_LSR_DR) { if ((up->console_port) && (!(iir & UART_IIR_RLSI) && (iir & UART_IIR_NO_INT))) serial_omap_clear_fifos(up); else return 1; } /* Check if DMA channels are active */ if (up->use_dma && (up->uart_dma.rx_dma_channel != OMAP_UART_DMA_CH_FREE || up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE)) return 1; return 0; }
static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); pm_runtime_get_sync(&up->pdev->dev); up->ier = 0; serial_out(up, UART_IER, 0); spin_lock_irqsave(&up->port.lock, flags); up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); if (up->use_dma) { dma_free_coherent(up->port.dev, UART_XMIT_SIZE, up->port.state->xmit.buf, up->uart_dma.tx_buf_dma_phys); up->port.state->xmit.buf = NULL; serial_omap_stop_rx(port); dma_free_coherent(up->port.dev, up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); up->uart_dma.rx_buf = NULL; } pm_runtime_put(&up->pdev->dev); free_irq(up->port.irq, up); }
static int serial_omap_startup(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; int retval; /* * Allocate the IRQ */ retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags, up->name, up); if (retval) return retval; dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id); /* * Clear the FIFO buffers and disable them. * (they will be reenabled in set_termios()) */ serial_omap_clear_fifos(up); /* For Hardware flow control */ serial_out(up, UART_MCR, UART_MCR_RTS); /* * Clear the interrupt registers. */ (void) serial_in(up, UART_LSR); if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); (void) serial_in(up, UART_IIR); (void) serial_in(up, UART_MSR); /* * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); spin_lock_irqsave(&up->port.lock, flags); /* * Most PC uarts need OUT2 raised to enable interrupts. */ up->port.mctrl |= TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); up->msr_saved_flags = 0; if (up->use_dma) { free_page((unsigned long)up->port.state->xmit.buf); up->port.state->xmit.buf = dma_alloc_coherent(NULL, UART_XMIT_SIZE, (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); init_timer(&(up->uart_dma.rx_timer)); up->uart_dma.rx_timer.function = serial_omap_rx_timeout; up->uart_dma.rx_timer.data = up->pdev->id; /* Currently the buffer size is 4KB. Can increase it */ up->uart_dma.rx_buf = dma_alloc_coherent(NULL, up->uart_dma.rx_buf_size, (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); } /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. */ up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); /* Enable module level wake up */ serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); up->port_activity = jiffies; return 0; }
static int serial_omap_startup(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags = 0; int retval; /* * Allocate the IRQ */ retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags, up->name, up); if (retval) return retval; /* Optional wake-up IRQ */ if (up->wakeirq) { retval = dev_pm_set_dedicated_wake_irq(up->dev, up->wakeirq); if (retval) { free_irq(up->port.irq, up); return retval; } } dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); pm_runtime_get_sync(up->dev); /* * Clear the FIFO buffers and disable them. * (they will be reenabled in set_termios()) */ serial_omap_clear_fifos(up); /* * Clear the interrupt registers. */ (void) serial_in(up, UART_LSR); if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); (void) serial_in(up, UART_IIR); (void) serial_in(up, UART_MSR); /* * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); spin_lock_irqsave(&up->port.lock, flags); /* * Most PC uarts need OUT2 raised to enable interrupts. */ up->port.mctrl |= TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); up->msr_saved_flags = 0; /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. */ up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); /* Enable module level wake up */ up->wer = OMAP_UART_WER_MOD_WKUP; if (up->features & OMAP_UART_WER_HAS_TX_WAKEUP) up->wer |= OMAP_UART_TX_WAKEUP_EN; serial_out(up, UART_OMAP_WER, up->wer); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); up->port_activity = jiffies; return 0; }
static int uart_open_nrt(struct rtdm_dev_context *context,rtdm_user_info_t *user_info_t,int oflags_t) { MY_DEV *up=(MY_DEV *)context->device->device_data; // rtdm_lockctx_t context1; int retval; printk("Local struct up=%x\n",up); f_cir_buf(up); rtdm_lock_init(&up->lock); rtdm_event_init(&up->w_event_tx,0); rtdm_event_init(&up->w_event_rx,0); printk("name of irq=%s\n",up->name); retval = request_irq(up->irq, serial_omap_irq,0, up->name, up); // if (retval) // return retval; retval=rtdm_irq_request(&up->irq_handle,up->irq,rtdm_my_isr,0,up->name,up); if(retval<0) { rtdm_printk("error in requesting irq\n"); dev_err(up->dev, "failure requesting irq %i\n", up->irq); return retval; } dev_dbg(up->dev, "serial_omap_startup+%d\n", up->line); serial_omap_clear_fifos(up); serial_out(up,UART_MCR,UART_MCR_RTS); (void)serial_in(up,UART_LSR); if(serial_in(up,UART_LSR) & UART_LSR_DR) (void)serial_in(up,UART_RX); (void)serial_in(up,UART_IIR); (void)serial_in(up,UART_MSR); /* * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); printk("UART has word length of 8 bit\n"); up->msr_saved_flags=0; //enabling interrupts up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up,UART_IER,up->ier); printk("enabling RLSI and RDI interrupt\n"); //enable module level wake up serial_out(up,UART_OMAP_WER,OMAP_UART_WER_MOD_WKUP); printk("OMAP_UART_WER_MOD_WKUP\n"); // up->port_activity=jiffies; return 0; }
static int serial_omap_startup(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags; int irq_flags = 0; int retval; /* Zoom2 has GPIO_102 connected to Serial device: * Active High */ if (up->port.flags & UPF_TRIGGER_HIGH) irq_flags |= IRQF_TRIGGER_HIGH; /* * Allocate the IRQ */ retval = request_irq(up->port.irq, serial_omap_irq, irq_flags, up->name, up); if (retval) { return retval; } /* * Stop the baud clock and disable the UART. UART will be enabled * back in set_termios. This is essential for DMA mode operations. */ serial_out(up, UART_LCR, UART_LCR_DLAB); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); /* * Clear the FIFO buffers and disable them. * (they will be reenabled in set_termios()) */ serial_omap_clear_fifos(up); serial_out(up, UART_SCR, 0x00); /* For Hardware flow control */ serial_out(up, UART_MCR, 0x2); /* * Clear the interrupt registers. */ (void) serial_in(up, UART_LSR); (void) serial_in(up, UART_RX); (void) serial_in(up, UART_IIR); (void) serial_in(up, UART_MSR); /* * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); spin_lock_irqsave(&up->port.lock, flags); if (up->port.flags & UPF_FOURPORT) { if (!is_real_interrupt(up->port.irq)) up->port.mctrl |= TIOCM_OUT1; } else { /* * Most PC uarts need OUT2 raised to enable interrupts. */ if (is_real_interrupt(up->port.irq)) up->port.mctrl |= TIOCM_OUT2; } serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); up->msr_saved_flags = 0; if (up->port.flags & UPF_FOURPORT) { unsigned int icp; /* * Enable interrupts on the AST Fourport board */ icp = (up->port.iobase & 0xfe0) | 0x01f; outb_p(0x80, icp); (void) inb_p(icp); } if (up->use_dma) { if (!up->is_buf_dma_alloced) { free_page((unsigned long)up->port.info->xmit.buf); up->port.info->xmit.buf = NULL; up->port.info->xmit.buf = dma_alloc_coherent(NULL, UART_XMIT_SIZE, (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); up->is_buf_dma_alloced = 1; } init_timer(&(up->uart_dma.rx_timer)); up->uart_dma.rx_timer.function = serial_omap_rx_timeout; up->uart_dma.rx_timer.data = up->pdev->id; /* Currently the buffer size is 4KB. Can increase it later*/ up->uart_dma.rx_buf = dma_alloc_coherent(NULL, up->uart_dma.rx_buf_size, (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); serial_omap_start_rxdma(up); } else { /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. */ up->ier = UART_IER_RLSI | UART_IER_RDI; //| UART_IER_RTOIE |UART_IER_THRI; serial_out(up, UART_IER, up->ier); } return 0; }
static int serial_omap_startup(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags = 0; int retval; /* Enable the Wake-up on CTS for a UART. The UART for * which is defined in board file, would get enabled. */ omap_uart_cts_wakeup(up->pdev->id, 1); /* * Allocate the IRQ */ retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags, up->name, up); if (retval) return retval; dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id); /* * Clear the FIFO buffers and disable them. * (they will be reenabled in set_termios()) */ serial_omap_clear_fifos(up); /* For Hardware flow control */ serial_out(up, UART_MCR, UART_MCR_RTS); /* * Clear the interrupt registers. */ (void) serial_in(up, UART_LSR); if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); (void) serial_in(up, UART_IIR); /* * We _do_ need to save this value as we pass here after suspend */ up->msr_saved_flags = serial_in(up, UART_MSR); /* * Now, initialize the UART */ serial_out(up, UART_LCR, UART_LCR_WLEN8); spin_lock_irqsave(&up->port.lock, flags); /* * Most PC uarts need OUT2 raised to enable interrupts. */ up->port.mctrl |= TIOCM_OUT2; serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); if (up->use_dma) { free_page((unsigned long)up->port.state->xmit.buf); up->port.state->xmit.buf = dma_alloc_coherent(NULL, UART_XMIT_SIZE, (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); init_timer(&(up->uart_dma.rx_timer)); up->uart_dma.rx_timer.function = serial_omap_rxdma_poll; up->uart_dma.rx_timer.data = up->pdev->id; /* Currently the buffer size is 4KB. Can increase it */ up->uart_dma.rx_buf = dma_alloc_coherent(NULL, up->uart_dma.rx_buf_size, (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); } /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. */ up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); up->port_activity = jiffies; #ifdef GPS_UART_WORKAROUND if (up->pdev->id == UART1) { mutex_lock(&gps_uart_wa); gps_uart_wa_open_flag = GPS_UART_OPEN; mutex_unlock(&gps_uart_wa); } #endif return 0; }
static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned long flags; u8 lcr, efr; DPRINTK("serial_omap_shutdown+%d\n", up->pdev->id); /* * If we're using auto-rts then disable it. */ lcr = serial_in(up, UART_LCR); serial_out(up, UART_LCR, 0xbf); efr = serial_in(up, UART_EFR); serial_out(up, UART_LCR, lcr); if (efr & UART_EFR_RTS) { serial_omap_set_autorts(up, 0); up->restore_autorts = 1; } /* * Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); spin_lock_irqsave(&up->port.lock, flags); if (up->port.flags & UPF_FOURPORT) { /* reset interrupts on the AST Fourport board */ inb((up->port.iobase & 0xfe0) | 0x1f); up->port.mctrl |= TIOCM_OUT1; } else up->port.mctrl &= ~TIOCM_OUT2; serial_omap_set_mctrl(&up->port, (up->port.mctrl & ~TIOCM_RTS)); spin_unlock_irqrestore(&up->port.lock, flags); if (up->pdev->id == gps_port) { serial_out(up, UART_LCR, UART_LCR_DLAB); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); } /* * Disable break condition and FIFOs */ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); serial_omap_clear_fifos(up); /* * Read data port to reset things, and then free the irq */ if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); if (up->use_dma) { int tmp; if (up->is_buf_dma_alloced) { dma_free_coherent(up->port.dev, UART_XMIT_SIZE, up->port.state->xmit.buf, up->uart_dma.tx_buf_dma_phys); up->port.state->xmit.buf = NULL; up->is_buf_dma_alloced = 0; } /*TBD: Check if this is really needed here*/ serial_omap_stop_rx(port); dma_free_coherent(up->port.dev, up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, up->uart_dma.rx_buf_dma_phys); up->uart_dma.rx_buf = NULL; tmp = serial_in(up, UART_OMAP_SYSC) & 0x7; serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ } free_irq(up->port.irq, up); if (cancel_work_sync(&up->tty_work)) tty_flip_buffer_work(&up->tty_work); }
static int serial_omap_probe(struct platform_device *pdev) { struct plat_serialomap_port *pdata = pdev->dev.platform_data; struct uart_omap_port *up; struct resource *mem, *irq; int ret = -ENOSPC; char str[7]; if (!pdata) { dev_err(&pdev->dev, "no platform data?\n"); return -ENODEV; } if (pdata->disabled) { dev_err(&pdev->dev, "device disabled\n"); return -ENODEV; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "no irq resource?\n"); return -ENODEV; } ret = (int) request_mem_region(mem->start, (mem->end - mem->start) + 1, pdev->dev.driver->name); if (!ret) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } up = kzalloc(sizeof(*up), GFP_KERNEL); if (up == NULL) { ret = -ENOMEM; goto do_release_region; } sprintf(up->name, "OMAP UART%d", pdev->id); up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.mapbase = mem->start; up->port.irq = irq->start; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; up->port.line = pdev->id - 1; #define QUART_CLK (1843200) if (pdev->id == 4) { up->port.membase = ioremap_nocache(mem->start, 0x16 << 1); up->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ | UPF_TRIGGER_HIGH; up->port.uartclk = QUART_CLK; up->port.regshift = 1; } else { up->port.membase = (void *) OMAP2_L4_IO_ADDRESS(mem->start); up->port.flags = pdata->flags; up->port.uartclk = 48000000; up->port.regshift = 2; #ifdef CONFIG_SERIAL_OMAP3430_HW_FLOW_CONTROL up->ctsrts = pdata->ctsrts; #endif } if (pdev->id == (UART1+1)) { #ifdef CONFIG_SERIAL_OMAP_DMA_UART1 up->use_dma = 1; up->uart_dma.rx_buf_size = CONFIG_SERIAL_OMAP_UART1_RXDMA_BUFSIZE; up->uart_dma.rx_timeout = CONFIG_SERIAL_OMAP_UART1_RXDMA_TIMEOUT; #endif } else if (pdev->id == (UART2+1)) { #ifdef CONFIG_SERIAL_OMAP_DMA_UART2 up->use_dma = 1; up->uart_dma.rx_buf_size = CONFIG_SERIAL_OMAP_UART2_RXDMA_BUFSIZE; up->uart_dma.rx_timeout = CONFIG_SERIAL_OMAP_UART2_RXDMA_TIMEOUT; #endif } else if (pdev->id == (UART3+1)) { #ifdef CONFIG_SERIAL_OMAP_DMA_UART3 up->use_dma = 1; up->uart_dma.rx_buf_size = CONFIG_SERIAL_OMAP_UART3_RXDMA_BUFSIZE; up->uart_dma.rx_timeout = CONFIG_SERIAL_OMAP_UART3_RXDMA_TIMEOUT; #endif } if (up->use_dma) { spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = 0xFF; up->uart_dma.rx_dma_channel = 0xFF; } if (console_detect(str)) printk("Invalid console paramter. UART Library Init Failed!\n"); up->use_console = 0; fcr[pdev->id - 1] = 0; if (!strcmp(str, "ttyS0")) up->use_console = 1; else if (!strcmp(str, "ttyS1")) up->use_console = 1; else if (!strcmp(str, "ttyS2")) up->use_console = 1; else if (!strcmp(str, "ttyS3")) up->use_console = 1; else printk(KERN_INFO "!!!!!!!! Unable to recongnize Console UART........\n"); ui[pdev->id - 1] = up; serial_omap_add_console_port(up); serial_omap_clear_fifos(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto do_release_region; platform_set_drvdata(pdev, up); if (pdata->wake_gpio_strobe) { if (gpio_request(pdata->wake_gpio_strobe, "UART AP -> BP wakeup strobe")) { printk(KERN_ERR "Error requesting GPIO\n"); } else gpio_direction_output(pdata->wake_gpio_strobe, 0); } INIT_WORK(&up->tty_work, tty_flip_buffer_work); return 0; do_release_region: release_mem_region(mem->start, (mem->end - mem->start) + 1); return ret; }