From patchwork Thu Feb 14 11:15:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 2141261 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id DAB3A3FCFC for ; Thu, 14 Feb 2013 11:16:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758435Ab3BNLQI (ORCPT ); Thu, 14 Feb 2013 06:16:08 -0500 Received: from comal.ext.ti.com ([198.47.26.152]:55938 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753087Ab3BNLQH (ORCPT ); Thu, 14 Feb 2013 06:16:07 -0500 Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id r1EBG4De023729; Thu, 14 Feb 2013 05:16:04 -0600 Received: from DLEE74.ent.ti.com (dlee74.ent.ti.com [157.170.170.8]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id r1EBG4kg029927; Thu, 14 Feb 2013 05:16:04 -0600 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Thu, 14 Feb 2013 05:16:04 -0600 Received: from localhost (h79-8.vpn.ti.com [172.24.79.8]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r1EBG3Pk000933; Thu, 14 Feb 2013 05:16:04 -0600 From: Felipe Balbi To: Linux OMAP Mailing List CC: Tony Lindgren , Linux ARM Kernel Mailing List , Felipe Balbi Subject: [RFC/NOT FOR MERGING 2/3] serial: omap: remove hwmod dependency Date: Thu, 14 Feb 2013 13:15:53 +0200 Message-ID: <1360840554-26901-2-git-send-email-balbi@ti.com> X-Mailer: git-send-email 1.8.1.rc1.5.g7e0651a In-Reply-To: <1360840554-26901-1-git-send-email-balbi@ti.com> References: <1360840554-26901-1-git-send-email-balbi@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org Currently the omap-serial driver will not work properly if booted via DT with CPUIDLE enabled because it depends on function pointers provided by hwmod to change its own SYSCONFIG register. Remove that relyance on hwmod by moving SYSCONFIG handling to driver itself. Note that this also fixes a possible corner case bug where we could be putting UART in Force Idle mode if we called omap_serial_enable_wakeup(up, false) after setting NOIDLE to the idle mode. This is because hwmod has no protection against that situation. NYET-Signed-off-by: Felipe Balbi --- drivers/tty/serial/omap-serial.c | 67 +++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 57d6b29..078beb1 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -96,6 +96,18 @@ #define OMAP_UART_TCR_TRIG 0x0F +#define OMAP_UART_SYSC 0x54 +#define OMAP_UART_AUTOIDLE (1 << 0) +#define OMAP_UART_SOFTRESET (1 << 1) +#define OMAP_UART_ENAWAKEUP (1 << 2) + +#define OMAP_UART_IDLEMODE(n) (((n) & 3) << 3) +#define OMAP_UART_FORCE_IDLE OMAP_UART_IDLEMODE(0) +#define OMAP_UART_NO_IDLE OMAP_UART_IDLEMODE(1) +#define OMAP_UART_SMART_IDLE OMAP_UART_IDLEMODE(2) +#define OMAP_UART_SMART_IDLE_WKUP OMAP_UART_IDLEMODE(3) +#define OMAP_UART_IDLEMODE_MASK OMAP_UART_SMART_IDLE_WKUP + struct uart_omap_dma { u8 uart_dma_tx; u8 uart_dma_rx; @@ -191,44 +203,39 @@ static inline void serial_omap_clear_fifos(struct uart_omap_port *up) serial_out(up, UART_FCR, 0); } -static int serial_omap_get_context_loss_count(struct uart_omap_port *up) -{ - struct omap_uart_port_info *pdata = up->dev->platform_data; - - if (!pdata || !pdata->get_context_loss_count) - return 0; - - return pdata->get_context_loss_count(up->dev); -} - static void serial_omap_set_forceidle(struct uart_omap_port *up) { - struct omap_uart_port_info *pdata = up->dev->platform_data; - - if (!pdata || !pdata->set_forceidle) - return; + u32 reg; - pdata->set_forceidle(up->dev); + reg = serial_in(up, OMAP_UART_SYSC); + reg &= ~OMAP_UART_IDLEMODE_MASK; + reg |= OMAP_UART_FORCE_IDLE; + serial_out(up, OMAP_UART_SYSC, reg); } static void serial_omap_set_noidle(struct uart_omap_port *up) { - struct omap_uart_port_info *pdata = up->dev->platform_data; + u32 reg; - if (!pdata || !pdata->set_noidle) - return; - - pdata->set_noidle(up->dev); + reg = serial_in(up, OMAP_UART_SYSC); + reg &= ~OMAP_UART_IDLEMODE_MASK; + reg |= OMAP_UART_NO_IDLE; + serial_out(up, OMAP_UART_SYSC, reg); } static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) { - struct omap_uart_port_info *pdata = up->dev->platform_data; + u32 reg; - if (!pdata || !pdata->enable_wakeup) - return; + reg = serial_in(up, OMAP_UART_SYSC); + reg &= ~OMAP_UART_IDLEMODE_MASK; + + if (enable) + reg |= OMAP_UART_SMART_IDLE_WKUP; + else + reg |= OMAP_UART_SMART_IDLE; - pdata->enable_wakeup(up->dev, enable); + serial_out(up, OMAP_UART_SYSC, reg); } /* @@ -1596,8 +1603,6 @@ static int serial_omap_runtime_suspend(struct device *dev) if (!pdata) return 0; - up->context_loss_cnt = serial_omap_get_context_loss_count(up); - if (device_may_wakeup(dev)) { if (!up->wakeups_enabled) { serial_omap_enable_wakeup(up, true); @@ -1620,15 +1625,7 @@ static int serial_omap_runtime_resume(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); - int loss_cnt = serial_omap_get_context_loss_count(up); - - if (loss_cnt < 0) { - dev_err(dev, "serial_omap_get_context_loss_count failed : %d\n", - loss_cnt); - serial_omap_restore_context(up); - } else if (up->context_loss_cnt != loss_cnt) { - serial_omap_restore_context(up); - } + serial_omap_restore_context(up); up->latency = up->calc_latency; schedule_work(&up->qos_work);