From patchwork Wed Oct 24 10:56:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shinya Kuribayashi X-Patchwork-Id: 1637531 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 25BF0DF238 for ; Wed, 24 Oct 2012 10:58:47 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TQye2-0004c5-QS; Wed, 24 Oct 2012 10:57:06 +0000 Received: from relmlor4.renesas.com ([210.160.252.174]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TQydv-0004Zo-3W for linux-arm-kernel@lists.infradead.org; Wed, 24 Oct 2012 10:57:00 +0000 Received: from relmlir4.idc.renesas.com ([10.200.68.154]) by relmlor4.idc.renesas.com ( SJSMS) with ESMTP id <0MCE0069292RPU10@relmlor4.idc.renesas.com> for linux-arm-kernel@lists.infradead.org; Wed, 24 Oct 2012 19:56:51 +0900 (JST) Received: from relmlac3.idc.renesas.com ([10.200.69.23]) by relmlir4.idc.renesas.com ( SJSMS) with ESMTP id <0MCE00B8I92RDPA0@relmlir4.idc.renesas.com> for linux-arm-kernel@lists.infradead.org; Wed, 24 Oct 2012 19:56:51 +0900 (JST) Received: by relmlac3.idc.renesas.com (Postfix, from userid 0) id 5BEF51809F; Wed, 24 Oct 2012 19:56:51 +0900 (JST) Received: from relmlac3.idc.renesas.com (localhost [127.0.0.1]) by relmlac3.idc.renesas.com (Postfix) with ESMTP id 53C0B1809C; Wed, 24 Oct 2012 19:56:51 +0900 (JST) Received: from relmlii2.idc.renesas.com [10.200.68.66] by relmlac3.idc.renesas.com with ESMTP id VAG22294; Wed, 24 Oct 2012 19:56:51 +0900 X-IronPort-AV: E=Sophos; i="4.80,639,1344178800"; d="scan'208"; a="103457022" Received: from unknown (HELO [10.161.64.55]) ([10.161.64.55]) by relmlii2.idc.renesas.com with ESMTP; Wed, 24 Oct 2012 19:56:51 +0900 Message-id: <5087C973.4010305@renesas.com> Date: Wed, 24 Oct 2012 19:56:51 +0900 From: Shinya Kuribayashi User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20121010 Thunderbird/16.0.1 MIME-version: 1.0 To: w.sang@pengutronix.de, ben-linux@fluff.org, magnus.damm@gmail.com Subject: [PATCH 1/5] i2c: i2c-sh_mobile: calculate clock parameters at driver probing time References: <5087C93F.6080601@renesas.com> In-reply-to: <5087C93F.6080601@renesas.com> X-Spam-Note: CRM114 invocation failed 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 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux-i2c@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sh@vger.kernel.org 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 Currently SCL clock parameters (ICCH/ICCL) are calculated in activate_ch(), which gets called every time sh_mobile_i2c_xfer() is processed, while each I2C bus speed is system-defined and in general those parameters do not have to be updated over I2C transactions. The only reason I could see having it transaction-time is to adjust ICCH/ICCL values according to the operating frequency of the I2C hardware block, in the face of DFS (Dynamic Frequency Scaling). However, this won't be necessary. The operating frequency of the I2C hardware block can change _even_ in the middle of I2C transactions. There is no way to prevent it from happening, and I2C hardware block can work with such dynamic frequency change, of course. Another is that ICCH/ICCL clock parameters optimized for the faster operating frequency, can also be applied to the slower operating frequency, as long as slave devices work. However, the converse is not true. It would violate SCL timing specs of the I2C standard. What we can do now is to calculate the ICCH/ICCL clock parameters according to the fastest operating clock of the I2C hardware block. And if that's the case, that calculation should be done just once at driver-module-init time. This patch moves ICCH/ICCL calculating part from activate_ch() into sh_mobile_i2c_init(), and call it from sh_mobile_i2c_probe(). Note that sh_mobile_i2c_init() just prepares clock parameters using the clock rate and platform data provided, but does _not_ make any hardware I/O accesses. We don't have to care about run-time PM maintenance here. Signed-off-by: Shinya Kuribayashi --- drivers/i2c/busses/i2c-sh_mobile.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 8110ca4..309d0d5 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -187,18 +187,15 @@ static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs, iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); } -static void activate_ch(struct sh_mobile_i2c_data *pd) +static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd) { unsigned long i2c_clk; u_int32_t num; u_int32_t denom; u_int32_t tmp; - /* Wake up device and enable clock */ - pm_runtime_get_sync(pd->dev); - clk_enable(pd->clk); - /* Get clock rate after clock is enabled */ + clk_enable(pd->clk); i2c_clk = clk_get_rate(pd->clk); /* Calculate the value for iccl. From the data sheet: @@ -239,6 +236,15 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) pd->icic &= ~ICIC_ICCHB8; } + clk_disable(pd->clk); +} + +static void activate_ch(struct sh_mobile_i2c_data *pd) +{ + /* Wake up device and enable clock */ + pm_runtime_get_sync(pd->dev); + clk_enable(pd->clk); + /* Enable channel and configure rx ack */ iic_set_clr(pd, ICCR, ICCR_ICE, 0); @@ -632,6 +638,8 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) if (size > 0x17) pd->flags |= IIC_FLAG_HAS_ICIC67; + sh_mobile_i2c_init(pd); + /* Enable Runtime PM for this device. * * Also tell the Runtime PM core to ignore children