int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) { struct uart_state *state = drv->state + uport->line; struct tty_port *port = &state->port; struct device *tty_dev; struct uart_match match = {uport, drv}; mutex_lock(&port->mutex); tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (device_may_wakeup(tty_dev)) { if (!enable_irq_wake(uport->irq)) uport->irq_wake = 1; put_device(tty_dev); mutex_unlock(&port->mutex); return 0; } if (console_suspend_enabled || !uart_console(uport)) uport->suspended = 1; if (port->flags & ASYNC_INITIALIZED) { const struct uart_ops *ops = uport->ops; int tries; if (console_suspend_enabled || !uart_console(uport)) { set_bit(ASYNCB_SUSPENDED, &port->flags); clear_bit(ASYNCB_INITIALIZED, &port->flags); spin_lock_irq(&uport->lock); ops->stop_tx(uport); ops->set_mctrl(uport, 0); ops->stop_rx(uport); spin_unlock_irq(&uport->lock); } for (tries = 3; !ops->tx_empty(uport) && tries; tries--) msleep(10); if (!tries) printk(KERN_ERR "%s%s%s%d: Unable to drain " "transmitter\n", uport->dev ? dev_name(uport->dev) : "", uport->dev ? ": " : "", drv->dev_name, drv->tty_driver->name_base + uport->line); if (console_suspend_enabled || !uart_console(uport)) ops->shutdown(uport); } if (console_suspend_enabled && uart_console(uport)) console_stop(uport->cons); if (console_suspend_enabled || !uart_console(uport)) uart_change_pm(state, 3); mutex_unlock(&port->mutex); return 0; }
static int serial_omap_runtime_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); if (!up) return -EINVAL; /* * When using 'no_console_suspend', the console UART must not be * suspended. Since driver suspend is managed by runtime suspend, * preventing runtime suspend (by returning error) will keep device * active during suspend. */ if (up->is_suspending && !console_suspend_enabled && uart_console(&up->port)) return -EBUSY; up->context_loss_cnt = serial_omap_get_context_loss_count(up); serial_omap_enable_wakeup(up, true); up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; schedule_work(&up->qos_work); return 0; }
static int omap8250_runtime_suspend(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up; up = serial8250_get_port(priv->line); /* * When using 'no_console_suspend', the console UART must not be * suspended. Since driver suspend is managed by runtime suspend, * preventing runtime suspend (by returning error) will keep device * active during suspend. */ if (priv->is_suspending && !console_suspend_enabled) { if (uart_console(&up->port)) return -EBUSY; } omap8250_enable_wakeup(priv, true); if (up->dma) omap_8250_rx_dma(up, UART_IIR_RX_TIMEOUT); priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; schedule_work(&priv->qos_work); return 0; }
static void of_serial_suspend_8250(struct of_serial_info *info) { struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; serial8250_suspend_port(info->line); if (info->clk && (!uart_console(port) || console_suspend_enabled)) clk_disable_unprepare(info->clk); }
static void uart_close(struct tty_struct *tty, struct file *filp) { struct uart_state *state = tty->driver_data; struct tty_port *port; struct uart_port *uport; unsigned long flags; if (!state) return; uport = state->uart_port; port = &state->port; pr_debug("uart_close(%d) called\n", uport->line); if (tty_port_close_start(port, tty, filp) == 0) return; if (port->flags & ASYNC_INITIALIZED) { unsigned long flags; spin_lock_irqsave(&uport->lock, flags); uport->ops->stop_rx(uport); spin_unlock_irqrestore(&uport->lock, flags); uart_wait_until_sent(tty, uport->timeout); } mutex_lock(&port->mutex); uart_shutdown(tty, state); uart_flush_buffer(tty); tty_ldisc_flush(tty); tty_port_tty_set(port, NULL); spin_lock_irqsave(&port->lock, flags); tty->closing = 0; if (port->blocked_open) { spin_unlock_irqrestore(&port->lock, flags); if (port->close_delay) msleep_interruptible( jiffies_to_msecs(port->close_delay)); spin_lock_irqsave(&port->lock, flags); } else if (!uart_console(uport)) { spin_unlock_irqrestore(&port->lock, flags); uart_change_pm(state, 3); spin_lock_irqsave(&port->lock, flags); } clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); clear_bit(ASYNCB_CLOSING, &port->flags); spin_unlock_irqrestore(&port->lock, flags); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->close_wait); mutex_unlock(&port->mutex); }
static int of_serial_resume(struct device *dev) { struct of_serial_info *info = dev_get_drvdata(dev); struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; if (info->clk && (!uart_console(port) || console_suspend_enabled)) clk_prepare_enable(info->clk); serial8250_resume_port(info->line); return 0; }
int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) { struct uart_state *state; struct tty_port *port; int ret = 0; struct device *tty_dev; BUG_ON(in_interrupt()); if (uport->line >= drv->nr) return -EINVAL; state = drv->state + uport->line; port = &state->port; mutex_lock(&port_mutex); mutex_lock(&port->mutex); if (state->uart_port) { ret = -EINVAL; goto out; } state->uart_port = uport; state->pm_state = -1; uport->cons = drv->cons; uport->state = state; if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) { spin_lock_init(&uport->lock); lockdep_set_class(&uport->lock, &port_lock_key); } uart_configure_port(drv, state, uport); tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); if (likely(!IS_ERR(tty_dev))) { device_set_wakeup_capable(tty_dev, 1); } else { printk(KERN_ERR "Cannot register tty device on line %d\n", uport->line); } uport->flags &= ~UPF_DEAD; out: mutex_unlock(&port->mutex); mutex_unlock(&port_mutex); return ret; }
static void mpc52xx_uart_shutdown(struct uart_port *port) { struct mpc52xx_psc __iomem *psc = PSC(port); /* Shut down the port. Leave TX active if on a console port */ out_8(&psc->command,MPC52xx_PSC_RST_RX); if (!uart_console(port)) out_8(&psc->command,MPC52xx_PSC_RST_TX); port->read_status_mask = 0; out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); /* Release interrupt */ free_irq(port->irq, port); }
static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, int init_hw) { struct uart_port *uport = state->uart_port; struct tty_port *port = &state->port; unsigned long page; int retval = 0; if (uport->type == PORT_UNKNOWN) return 1; if (!state->xmit.buf) { page = get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; state->xmit.buf = (unsigned char *) page; uart_circ_clear(&state->xmit); } retval = uport->ops->startup(uport); if (retval == 0) { if (uart_console(uport) && uport->cons->cflag) { tty->termios->c_cflag = uport->cons->cflag; uport->cons->cflag = 0; } uart_change_speed(tty, state, NULL); if (init_hw) { if (tty->termios->c_cflag & CBAUD) uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); } if (port->flags & ASYNC_CTS_FLOW) { spin_lock_irq(&uport->lock); if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) tty->hw_stopped = 1; spin_unlock_irq(&uport->lock); } } if (retval && capable(CAP_SYS_ADMIN)) return 1; return retval; }
static int mtk8250_startup(struct uart_port *port) { #ifdef CONFIG_SERIAL_8250_DMA struct uart_8250_port *up = up_to_u8250p(port); struct mtk8250_data *data = port->private_data; /* disable DMA for console */ if (uart_console(port)) up->dma = NULL; if (up->dma) { data->rx_status = DMA_RX_START; uart_circ_clear(&port->state->xmit); } #endif memset(&port->icount, 0, sizeof(port->icount)); return serial8250_do_startup(port); }
static int omap8250_runtime_suspend(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up; /* In case runtime-pm tries this before we are setup */ if (!priv) return 0; up = serial8250_get_port(priv->line); /* * When using 'no_console_suspend', the console UART must not be * suspended. Since driver suspend is managed by runtime suspend, * preventing runtime suspend (by returning error) will keep device * active during suspend. */ if (priv->is_suspending && !console_suspend_enabled) { if (uart_console(&up->port)) return -EBUSY; } if (priv->habit & UART_ERRATA_CLOCK_DISABLE) { int ret; ret = omap8250_soft_reset(dev); if (ret) return ret; /* Restore to UART mode after reset (for wakeup) */ omap8250_update_mdr1(up, priv); /* Restore wakeup enable register */ serial_out(up, UART_OMAP_WER, priv->wer); } if (up->dma && up->dma->rxchan) omap_8250_rx_dma_flush(up); priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; schedule_work(&priv->qos_work); return 0; }
static void uart_configure_port(struct uart_driver *drv, struct uart_state *state, struct uart_port *port) { unsigned int flags; if (!port->iobase && !port->mapbase && !port->membase) return; flags = 0; if (port->flags & UPF_AUTO_IRQ) flags |= UART_CONFIG_IRQ; if (port->flags & UPF_BOOT_AUTOCONF) { if (!(port->flags & UPF_FIXED_TYPE)) { port->type = PORT_UNKNOWN; flags |= UART_CONFIG_TYPE; } port->ops->config_port(port, flags); } if (port->type != PORT_UNKNOWN) { unsigned long flags; uart_report_port(drv, port); uart_change_pm(state, 0); spin_lock_irqsave(&port->lock, flags); port->ops->set_mctrl(port, port->mctrl & TIOCM_DTR); spin_unlock_irqrestore(&port->lock, flags); if (port->cons && !(port->cons->flags & CON_ENABLED)) register_console(port->cons); if (!uart_console(port)) uart_change_pm(state, 3); } }
static void mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_8250_port *up = up_to_u8250p(port); unsigned long flags; unsigned int baud, quot; #ifdef CONFIG_SERIAL_8250_DMA if (up->dma) { if (uart_console(port)) { devm_kfree(up->port.dev, up->dma); up->dma = NULL; } else { mtk8250_dma_enable(up); } } #endif serial8250_do_set_termios(port, termios, old); /* * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS) * * We need to recalcualte the quot register, as the claculation depends * on the vaule in the highspeed register. * * Some baudrates are not supported by the chip, so we use the next * lower rate supported and update termios c_flag. * * If highspeed register is set to 3, we need to specify sample count * and sample point to increase accuracy. If not, we reset the * registers to their default values. */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / UART_DIV_MAX, port->uartclk); if (baud <= 115200) { serial_port_out(port, UART_MTK_HIGHS, 0x0); quot = uart_get_divisor(port, baud); } else if (baud <= 576000) { serial_port_out(port, UART_MTK_HIGHS, 0x2); /* Set to next lower baudrate supported */ if ((baud == 500000) || (baud == 576000)) baud = 460800; quot = DIV_ROUND_UP(port->uartclk, 4 * baud); } else { serial_port_out(port, UART_MTK_HIGHS, 0x3); quot = DIV_ROUND_UP(port->uartclk, 256 * baud); } /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ spin_lock_irqsave(&port->lock, flags); /* set DLAB we have cval saved in up->lcr from the call to the core */ serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); serial_dl_write(up, quot); /* reset DLAB */ serial_port_out(port, UART_LCR, up->lcr); if (baud > 460800) { unsigned int tmp; tmp = DIV_ROUND_CLOSEST(port->uartclk, quot * baud); serial_port_out(port, UART_MTK_SAMPLE_COUNT, tmp - 1); serial_port_out(port, UART_MTK_SAMPLE_POINT, (tmp - 2) >> 1); } else {
int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) { struct uart_state *state = drv->state + uport->line; struct tty_port *port = &state->port; struct device *tty_dev; struct uart_match match = {uport, drv}; struct ktermios termios; mutex_lock(&port->mutex); tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (!uport->suspended && device_may_wakeup(tty_dev)) { if (uport->irq_wake) { disable_irq_wake(uport->irq); uport->irq_wake = 0; } put_device(tty_dev); mutex_unlock(&port->mutex); return 0; } put_device(tty_dev); uport->suspended = 0; if (uart_console(uport)) { memset(&termios, 0, sizeof(struct ktermios)); termios.c_cflag = uport->cons->cflag; if (port->tty && port->tty->termios && termios.c_cflag == 0) termios = *(port->tty->termios); if (console_suspend_enabled) uart_change_pm(state, 0); uport->ops->set_termios(uport, &termios, NULL); if (console_suspend_enabled) console_start(uport->cons); } if (port->flags & ASYNC_SUSPENDED) { const struct uart_ops *ops = uport->ops; int ret; uart_change_pm(state, 0); spin_lock_irq(&uport->lock); ops->set_mctrl(uport, 0); spin_unlock_irq(&uport->lock); if (console_suspend_enabled || !uart_console(uport)) { struct tty_struct *tty = port->tty; ret = ops->startup(uport); if (ret == 0) { if (tty) uart_change_speed(tty, state, NULL); spin_lock_irq(&uport->lock); ops->set_mctrl(uport, uport->mctrl); ops->start_tx(uport); spin_unlock_irq(&uport->lock); set_bit(ASYNCB_INITIALIZED, &port->flags); } else { uart_shutdown(tty, state); } } clear_bit(ASYNCB_SUSPENDED, &port->flags); } mutex_unlock(&port->mutex); return 0; }
static int omap_8250_startup(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = port->private_data; int ret; if (priv->wakeirq) { ret = dev_pm_set_dedicated_wake_irq(port->dev, priv->wakeirq); if (ret) return ret; } pm_runtime_get_sync(port->dev); up->mcr = 0; serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); serial_out(up, UART_LCR, UART_LCR_WLEN8); up->lsr_saved_flags = 0; up->msr_saved_flags = 0; /* Disable DMA for console UART */ if (uart_console(port)) up->dma = NULL; if (up->dma) { ret = serial8250_request_dma(up); if (ret) { dev_warn_ratelimited(port->dev, "failed to request DMA\n"); up->dma = NULL; } } ret = request_irq(port->irq, omap8250_irq, IRQF_SHARED, dev_name(port->dev), port); if (ret < 0) goto err; up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); #ifdef CONFIG_PM up->capabilities |= UART_CAP_RPM; #endif /* Enable module level wake up */ priv->wer = OMAP_UART_WER_MOD_WKUP; if (priv->habit & OMAP_UART_WER_HAS_TX_WAKEUP) priv->wer |= OMAP_UART_TX_WAKEUP_EN; serial_out(up, UART_OMAP_WER, priv->wer); if (up->dma) up->dma->rx_dma(up); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); return 0; err: pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); dev_pm_clear_wake_irq(port->dev); return ret; }