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; }
/* TODO: in future, this should happen via API in drivers/reset/ */ static int omap8250_soft_reset(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); int timeout = 100; int sysc; int syss; sysc = serial_in(up, UART_OMAP_SYSC); /* softreset the UART */ sysc |= OMAP_UART_SYSC_SOFTRESET; serial_out(up, UART_OMAP_SYSC, sysc); /* By experiments, 1us enough for reset complete on AM335x */ do { udelay(1); syss = serial_in(up, UART_OMAP_SYSS); } while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE)); if (!timeout) { dev_err(dev, "timed out waiting for reset done\n"); return -ETIMEDOUT; } 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 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; }
static int omap8250_suspend(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); serial8250_suspend_port(priv->line); pm_runtime_get_sync(dev); if (!device_may_wakeup(dev)) priv->wer = 0; serial_out(up, UART_OMAP_WER, priv->wer); pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); flush_work(&priv->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; /* 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 int omap8250_runtime_resume(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); if (omap8250_lost_context(up)) omap8250_restore_regs(up); if (up->dma && up->dma->rxchan) omap_8250_rx_dma(up); priv->latency = priv->calc_latency; schedule_work(&priv->qos_work); return 0; }
/* TODO: in future, this should happen via API in drivers/reset/ */ static int omap8250_soft_reset(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); int timeout = 100; int sysc; int syss; /* * At least on omap4, unused uarts may not idle after reset without * a basic scr dma configuration even with no dma in use. The * module clkctrl status bits will be 1 instead of 3 blocking idle * for the whole clockdomain. The softreset below will clear scr, * and we restore it on resume so this is safe to do on all SoCs * needing omap8250_soft_reset() quirk. Do it in two writes as * recommended in the comment for omap8250_update_scr(). */ serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL); sysc = serial_in(up, UART_OMAP_SYSC); /* softreset the UART */ sysc |= OMAP_UART_SYSC_SOFTRESET; serial_out(up, UART_OMAP_SYSC, sysc); /* By experiments, 1us enough for reset complete on AM335x */ do { udelay(1); syss = serial_in(up, UART_OMAP_SYSS); } while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE)); if (!timeout) { dev_err(dev, "timed out waiting for reset done\n"); return -ETIMEDOUT; } return 0; }
static int omap8250_runtime_resume(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up; int loss_cntx; /* In case runtime-pm tries this before we are setup */ if (!priv) return 0; up = serial8250_get_port(priv->line); omap8250_enable_wakeup(priv, false); loss_cntx = omap8250_lost_context(up); if (loss_cntx) omap8250_restore_regs(up); if (up->dma) omap_8250_rx_dma(up, 0); priv->latency = priv->calc_latency; schedule_work(&priv->qos_work); return 0; }