From patchwork Wed Jan 16 06:49:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barry Song X-Patchwork-Id: 1986751 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id BD809DF2A2 for ; Wed, 16 Jan 2013 06:53:58 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TvMpt-0005Uy-B1; Wed, 16 Jan 2013 06:50:57 +0000 Received: from cluster-g.mailcontrol.com ([208.87.233.190]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TvMpp-0005U8-Jr for linux-arm-kernel@lists.infradead.org; Wed, 16 Jan 2013 06:50:54 +0000 Received: from SHAASIEXC02.ASIA.ROOT.PRI ([210.13.83.101]) by rly21g.srv.mailcontrol.com (MailControl) with ESMTP id r0G6oZ1n024908 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=FAIL); Wed, 16 Jan 2013 06:50:44 GMT Received: from localhost.localdomain (10.125.36.195) by asimail.csr.com (10.125.12.88) with Microsoft SMTP Server (TLS) id 14.1.355.2; Wed, 16 Jan 2013 14:50:35 +0800 From: Barry Song To: , Subject: [PATCH v2] serial: sirf: only use lookup table to set baudrate when ioclk=150MHz Date: Wed, 16 Jan 2013 14:49:27 +0800 Message-ID: <1358318967-25958-1-git-send-email-Barry.Song@csr.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 X-Originating-IP: [10.125.36.195] X-Scanned-By: MailControl 11783.69 (www.mailcontrol.com) on 10.71.0.131 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130116_015053_846810_F7EF5B1B X-CRM114-Status: GOOD ( 16.23 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [208.87.233.190 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: workgroup.linux@csr.com, Russell King , linux-serial@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Barry Song X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Barry Song The fast lookup table to set baudrate is only right when ioclk is 150MHz. for most platforms, ioclk is 150MHz, but some boards might set ioclk to other frequency. so re-calc the clk_div_reg when ioclk is not 150MHz. this patch also gets clk in probe and puts it in remove. Signed-off-by: Barry Song Cc: Russell King --- -v2: 1. Get the clock at probe or port initialization time. Save that pointer according to Russell King's feedback; 2. rebase to tty/tty-next as this one has been applied: serial: sirf: add support for new SiRFmarco SMP SoC http://git.kernel.org/?p=linux/kernel/git/gregkh/tty.git;h=5425e0 drivers/tty/serial/sirfsoc_uart.c | 28 +++++++++++++++++++++------- drivers/tty/serial/sirfsoc_uart.h | 1 + 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 8f3d6c0..6bbfe99 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -357,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, struct ktermios *old) { struct sirfsoc_uart_port *sirfport = to_sirfport(port); - unsigned long ioclk_rate; unsigned long config_reg = 0; unsigned long baud_rate; unsigned long setted_baud; @@ -369,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, int threshold_div; int temp; - ioclk_rate = 150000000; switch (termios->c_cflag & CSIZE) { default: case CS8: @@ -425,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, sirfsoc_uart_disable_ms(port); } - /* common rate: fast calculation */ - for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) - if (baud_rate == baudrate_to_regv[ic].baud_rate) - clk_div_reg = baudrate_to_regv[ic].reg_val; + if (port->uartclk == 150000000) { + /* common rate: fast calculation */ + for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) + if (baud_rate == baudrate_to_regv[ic].baud_rate) + clk_div_reg = baudrate_to_regv[ic].reg_val; + } + setted_baud = baud_rate; /* arbitary rate setting */ if (unlikely(clk_div_reg == 0)) - clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, + clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk, &setted_baud); wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); @@ -691,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev) goto err; } + sirfport->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(sirfport->clk)) { + ret = PTR_ERR(sirfport->clk); + goto clk_err; + } + clk_prepare_enable(sirfport->clk); + port->uartclk = clk_get_rate(sirfport->clk); + port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); @@ -704,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev) return 0; port_err: + clk_disable_unprepare(sirfport->clk); + clk_put(sirfport->clk); +clk_err: platform_set_drvdata(pdev, NULL); if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); @@ -718,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); + clk_disable_unprepare(sirfport->clk); + clk_put(sirfport->clk); uart_remove_one_port(&sirfsoc_uart_drv, port); return 0; } diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6431640..85328ba 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h @@ -163,6 +163,7 @@ struct sirfsoc_uart_port { struct uart_port port; struct pinctrl *p; + struct clk *clk; }; /* Hardware Flow Control */