From patchwork Wed May 13 13:03:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander A Sverdlin X-Patchwork-Id: 471870 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 57468140662 for ; Wed, 13 May 2015 23:03:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934203AbbEMNDh (ORCPT ); Wed, 13 May 2015 09:03:37 -0400 Received: from demumfd001.nsn-inter.net ([93.183.12.32]:39902 "EHLO demumfd001.nsn-inter.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933410AbbEMNDg (ORCPT ); Wed, 13 May 2015 09:03:36 -0400 Received: from demuprx017.emea.nsn-intra.net ([10.150.129.56]) by demumfd001.nsn-inter.net (8.15.1/8.15.1) with ESMTPS id t4DD3TXe025869 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 13 May 2015 13:03:30 GMT Received: from [10.151.15.185] ([10.151.15.185]) by demuprx017.emea.nsn-intra.net (8.12.11.20060308/8.12.11) with ESMTP id t4DD3SQT003195; Wed, 13 May 2015 15:03:28 +0200 Message-ID: <55534BA0.3000506@nokia.com> Date: Wed, 13 May 2015 15:03:28 +0200 From: Alexander Sverdlin User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: linux-i2c@vger.kernel.org, Wolfram Sang , Kevin Hilman , Sekhar Nori , Grygorii Strashko , Santosh Shilimkar , "Vishwanathrao Badarkhe, Manish" , Murali Karicheri CC: Lawnick Michael 61283229 , Mike Looijmans , Mastalski Bartosz Subject: [PATCH v2] i2c: davinci: Refactor i2c_davinci_wait_bus_not_busy() X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: clean X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate-size: 2485 X-purgate-ID: 151667::1431522210-00004750-BDF179C1/0/0 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org There are several problems in the function: - "to_cnt" variable does nothing - schedule_timeout() call without setting current state does nothing - "allow_sleep" parameter is not really used Refactor the function so that it really tries to wait. In case of timeout try to recover the bus. Signed-off-by: Alexander Sverdlin Reviewed-by: Grygorii Strashko --- Changes in v2: - rebased on 110bc76729d4 of Linus's tree; drivers/i2c/busses/i2c-davinci.c | 42 +++++++++++++++++-------------------- 1 files changed, 19 insertions(+), 23 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index df96ab6..03afdee 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -350,29 +350,25 @@ static struct i2c_bus_recovery_info davinci_i2c_scl_recovery_info = { /* * Waiting for bus not busy */ -static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, - char allow_sleep) +static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev) { - unsigned long timeout; - static u16 to_cnt; - - timeout = jiffies + dev->adapter.timeout; - while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) - & DAVINCI_I2C_STR_BB) { - if (to_cnt <= DAVINCI_I2C_MAX_TRIES) { - if (time_after(jiffies, timeout)) { - dev_warn(dev->dev, - "timeout waiting for bus ready\n"); - to_cnt++; - return -ETIMEDOUT; - } else { - to_cnt = 0; - i2c_recover_bus(&dev->adapter); - } - } - if (allow_sleep) - schedule_timeout(1); - } + unsigned long timeout = jiffies + dev->adapter.timeout; + + do { + if (!(davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB)) + return 0; + schedule_timeout_uninterruptible(1); + } while (time_before_eq(jiffies, timeout)); + + dev_warn(dev->dev, "timeout waiting for bus ready\n"); + i2c_recover_bus(dev); + + /* + * if bus is still "busy" here, it's most probably a HW problem like + * short-circuit + */ + if (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) + return -EIO; return 0; } @@ -508,7 +504,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); - ret = i2c_davinci_wait_bus_not_busy(dev, 1); + ret = i2c_davinci_wait_bus_not_busy(dev); if (ret < 0) { dev_warn(dev->dev, "timeout waiting for bus ready\n"); return ret;