From patchwork Wed Apr 3 12:40:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075916 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5Ll4S7Yz9sSt for ; Wed, 3 Apr 2019 23:42:07 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726424AbfDCMkg (ORCPT ); Wed, 3 Apr 2019 08:40:36 -0400 Received: from sauhun.de ([88.99.104.3]:48284 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726206AbfDCMkg (ORCPT ); Wed, 3 Apr 2019 08:40:36 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id F11803E604C; Wed, 3 Apr 2019 14:40:34 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 01/12] i2c: remove use of in_atomic() Date: Wed, 3 Apr 2019 14:40:08 +0200 Message-Id: <20190403124019.8947-2-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Commit cea443a81c9c ("i2c: Support i2c_transfer in atomic contexts") added in_atomic() to the I2C core. However, the use of in_atomic() outside of core kernel code is discouraged and was already[1] when this code was added in early 2008. The above commit was a preparation for commit b7a3670131c7 ("i2c-pxa: Add polling transfer"). Its commit message says explicitly it was added "for cases where I2C transactions have to occur at times interrup[t]s are disabled". So, the intention was 'disabled interrupts'. This matches the use cases for atomic I2C transfers I have seen so far: very late communication (mostly to a PMIC) to powerdown or reboot the system. For those cases, interrupts are disabled then. It doesn't seem that in_atomic() adds value. After a discussion with Peter Zijlstra[2], we came up with a better set of conditionals to match the use case. The I2C core will soon gain an extra callback into bus drivers especially for atomic transfers to make them more generic. The code deciding which transfer to use (atomic/non-atomic) should mimic the behaviour which locking to use (trylock/lock). This is why we add a helper for it. [1] https://lwn.net/Articles/274695/ [2] http://patchwork.ozlabs.org/patch/1067437/ Signed-off-by: Wolfram Sang Tested-by: Stefan Lengfeld --- drivers/i2c/i2c-core-base.c | 2 +- drivers/i2c/i2c-core.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 38af18645133..f8502064cd6b 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1946,7 +1946,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) * one (discarding status on the second message) or errno * (discarding status on the first one). */ - if (in_atomic() || irqs_disabled()) { + if (i2c_in_atomic_xfer_mode()) { ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT); if (!ret) /* I2C activity is ongoing. */ diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h index 37576f50fe20..9d8526415b26 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h @@ -29,6 +29,16 @@ extern int __i2c_first_dynamic_bus_num; int i2c_check_7bit_addr_validity_strict(unsigned short addr); +/* + * We only allow atomic transfers for very late communication, e.g. to send + * the powerdown command to a PMIC. Atomic transfers are a corner case and not + * for generic use! + */ +static inline bool i2c_in_atomic_xfer_mode(void) +{ + return system_state > SYSTEM_RUNNING && irqs_disabled(); +} + #ifdef CONFIG_ACPI const struct acpi_device_id * i2c_acpi_match_device(const struct acpi_device_id *matches, From patchwork Wed Apr 3 12:40:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075913 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5Ld6T55z9sSs for ; Wed, 3 Apr 2019 23:42:01 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726602AbfDCMlx (ORCPT ); Wed, 3 Apr 2019 08:41:53 -0400 Received: from sauhun.de ([88.99.104.3]:48300 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726155AbfDCMkh (ORCPT ); Wed, 3 Apr 2019 08:40:37 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 870A23E4246; Wed, 3 Apr 2019 14:40:35 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 02/12] i2c: core: use I2C locking behaviour also for SMBUS Date: Wed, 3 Apr 2019 14:40:09 +0200 Message-Id: <20190403124019.8947-3-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org If I2C transfers are executed in atomic contexts, trylock is used instead of lock. This behaviour was missing for SMBUS, although a lot of transfers are of SMBUS type, either emulated or direct. So, factor out the locking routine into a helper and use it for I2C and SMBUS. Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 11 +++-------- drivers/i2c/i2c-core-smbus.c | 7 ++++++- drivers/i2c/i2c-core.h | 12 ++++++++++++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index f8502064cd6b..ad14f38a67e4 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1946,14 +1946,9 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) * one (discarding status on the second message) or errno * (discarding status on the first one). */ - if (i2c_in_atomic_xfer_mode()) { - ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT); - if (!ret) - /* I2C activity is ongoing. */ - return -EAGAIN; - } else { - i2c_lock_bus(adap, I2C_LOCK_SEGMENT); - } + ret = __i2c_lock_bus_helper(adap); + if (ret) + return ret; ret = __i2c_transfer(adap, msgs, num); i2c_unlock_bus(adap, I2C_LOCK_SEGMENT); diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 132119112596..357e083e8f45 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -20,6 +20,8 @@ #include #include +#include "i2c-core.h" + #define CREATE_TRACE_POINTS #include @@ -530,7 +532,10 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, { s32 res; - i2c_lock_bus(adapter, I2C_LOCK_SEGMENT); + res = __i2c_lock_bus_helper(adapter); + if (res) + return res; + res = __i2c_smbus_xfer(adapter, addr, flags, read_write, command, protocol, data); i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT); diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h index 9d8526415b26..deea47c576e5 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h @@ -39,6 +39,18 @@ static inline bool i2c_in_atomic_xfer_mode(void) return system_state > SYSTEM_RUNNING && irqs_disabled(); } +static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) +{ + int ret = 0; + + if (i2c_in_atomic_xfer_mode()) + ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT) ? 0 : -EAGAIN; + else + i2c_lock_bus(adap, I2C_LOCK_SEGMENT); + + return ret; +} + #ifdef CONFIG_ACPI const struct acpi_device_id * i2c_acpi_match_device(const struct acpi_device_id *matches, From patchwork Wed Apr 3 12:40:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075906 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5LG6Hfkz9sSd for ; Wed, 3 Apr 2019 23:41:42 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727403AbfDCMld (ORCPT ); Wed, 3 Apr 2019 08:41:33 -0400 Received: from sauhun.de ([88.99.104.3]:48322 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726245AbfDCMki (ORCPT ); Wed, 3 Apr 2019 08:40:38 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 1A1293E43CA; Wed, 3 Apr 2019 14:40:36 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 03/12] i2c: core: introduce callbacks for atomic transfers Date: Wed, 3 Apr 2019 14:40:10 +0200 Message-Id: <20190403124019.8947-4-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org We had the request to access devices very late when interrupts are not available anymore multiple times now. Mostly to prepare shutdown or reboot. Allow adapters to specify a specific callback for this case. Note that we fall back to the generic {master|smbus}_xfer callback if this new atomic one is not present. This is intentional to preserve the previous behaviour and avoid regressions. Because there are drivers not using interrupts or because it might have worked "accidently" before. Signed-off-by: Wolfram Sang Tested-by: Stefan Lengfeld --- drivers/i2c/i2c-core-base.c | 6 +++++- drivers/i2c/i2c-core-smbus.c | 18 ++++++++++++++---- drivers/i2c/i2c-core.h | 7 +++++-- include/linux/i2c.h | 15 ++++++++++++--- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index ad14f38a67e4..4e6300dc2c4e 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1890,7 +1890,11 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) /* Retry automatically on arbitration loss */ orig_jiffies = jiffies; for (ret = 0, try = 0; try <= adap->retries; try++) { - ret = adap->algo->master_xfer(adap, msgs, num); + if (i2c_in_atomic_xfer_mode() && adap->algo->master_xfer_atomic) + ret = adap->algo->master_xfer_atomic(adap, msgs, num); + else + ret = adap->algo->master_xfer(adap, msgs, num); + if (ret != -EAGAIN) break; if (time_after(jiffies, orig_jiffies + adap->timeout)) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 357e083e8f45..fdb0fb9fb9aa 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -548,6 +548,9 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char read_write, u8 command, int protocol, union i2c_smbus_data *data) { + int (*xfer_func)(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data); unsigned long orig_jiffies; int try; s32 res; @@ -562,13 +565,20 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; - if (adapter->algo->smbus_xfer) { + xfer_func = adapter->algo->smbus_xfer; + if (i2c_in_atomic_xfer_mode()) { + if (adapter->algo->smbus_xfer_atomic) + xfer_func = adapter->algo->smbus_xfer_atomic; + else if (adapter->algo->master_xfer_atomic) + xfer_func = NULL; /* fallback to I2C emulation */ + } + + if (xfer_func) { /* Retry automatically on arbitration loss */ orig_jiffies = jiffies; for (res = 0, try = 0; try <= adapter->retries; try++) { - res = adapter->algo->smbus_xfer(adapter, addr, flags, - read_write, command, - protocol, data); + res = xfer_func(adapter, addr, flags, read_write, + command, protocol, data); if (res != -EAGAIN) break; if (time_after(jiffies, diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h index deea47c576e5..f9d0c417b5a5 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h @@ -43,10 +43,13 @@ static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) { int ret = 0; - if (i2c_in_atomic_xfer_mode()) + if (i2c_in_atomic_xfer_mode()) { + WARN(!adap->algo->master_xfer_atomic && !adap->algo->smbus_xfer_atomic, + "No atomic I2C transfer handler for '%s'\n", dev_name(&adap->dev)); ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT) ? 0 : -EAGAIN; - else + } else { i2c_lock_bus(adap, I2C_LOCK_SEGMENT); + } return ret; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 758a6db864c9..03755d4c9229 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -499,9 +499,13 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info, * @master_xfer: Issue a set of i2c transactions to the given I2C adapter * defined by the msgs array, with num messages available to transfer via * the adapter specified by adap. + * @master_xfer_atomic: same as @master_xfer. Yet, only using atomic context + * so e.g. PMICs can be accessed very late before shutdown. Optional. * @smbus_xfer: Issue smbus transactions to the given I2C adapter. If this * is not present, then the bus layer will try and convert the SMBus calls * into I2C transfers instead. + * @smbus_xfer_atomic: same as @smbus_xfer. Yet, only using atomic context + * so e.g. PMICs can be accessed very late before shutdown. Optional. * @functionality: Return the flags that this algorithm/adapter pair supports * from the I2C_FUNC_* flags. * @reg_slave: Register given client to I2C slave mode of this adapter @@ -512,9 +516,9 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info, * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 * to name two of the most common. * - * The return codes from the @master_xfer field should indicate the type of - * error code that occurred during the transfer, as documented in the kernel - * Documentation file Documentation/i2c/fault-codes. + * The return codes from the @master_xfer{_atomic} fields should indicate the + * type of error code that occurred during the transfer, as documented in the + * Kernel Documentation file Documentation/i2c/fault-codes. */ struct i2c_algorithm { /* @@ -528,9 +532,14 @@ struct i2c_algorithm { */ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); + int (*master_xfer_atomic)(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num); int (*smbus_xfer)(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data); + int (*smbus_xfer_atomic)(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data); /* To determine what the adapter supports */ u32 (*functionality)(struct i2c_adapter *adap); From patchwork Wed Apr 3 12:40:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075908 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5LJ2wcXz9sSt for ; Wed, 3 Apr 2019 23:41:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727352AbfDCMld (ORCPT ); Wed, 3 Apr 2019 08:41:33 -0400 Received: from sauhun.de ([88.99.104.3]:48338 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726206AbfDCMki (ORCPT ); Wed, 3 Apr 2019 08:40:38 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id A70173E43CB; Wed, 3 Apr 2019 14:40:36 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 04/12] i2c: mux: populate the new *_atomic callbacks Date: Wed, 3 Apr 2019 14:40:11 +0200 Message-Id: <20190403124019.8947-5-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org If the parent adapter has atomic_xfer callbacks, populate them for the mux adapter as well. We can use the same translation function as for the non-atomic xfer callback. Signed-off-by: Wolfram Sang Reviewed-by: Peter Rosin --- drivers/i2c/i2c-mux.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index f330690b4125..603252fa1284 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -310,12 +310,18 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, else priv->algo.master_xfer = __i2c_mux_master_xfer; } + if (parent->algo->master_xfer_atomic) + priv->algo.master_xfer_atomic = priv->algo.master_xfer; + if (parent->algo->smbus_xfer) { if (muxc->mux_locked) priv->algo.smbus_xfer = i2c_mux_smbus_xfer; else priv->algo.smbus_xfer = __i2c_mux_smbus_xfer; } + if (parent->algo->smbus_xfer_atomic) + priv->algo.smbus_xfer_atomic = priv->algo.smbus_xfer; + priv->algo.functionality = i2c_mux_functionality; /* Now fill out new adapter structure */ From patchwork Wed Apr 3 12:40:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075887 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5K45lsDz9sST for ; Wed, 3 Apr 2019 23:40:40 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726671AbfDCMkk (ORCPT ); Wed, 3 Apr 2019 08:40:40 -0400 Received: from sauhun.de ([88.99.104.3]:48350 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726606AbfDCMkj (ORCPT ); Wed, 3 Apr 2019 08:40:39 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 385293E43CC; Wed, 3 Apr 2019 14:40:37 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 05/12] i2c: demux: handle the new atomic callbacks Date: Wed, 3 Apr 2019 14:40:12 +0200 Message-Id: <20190403124019.8947-6-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org If the parent has an atomic callback, we need to translate it the same way as the non-atomic callback. Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-demux-pinctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c index 035032e20327..d50454c565ee 100644 --- a/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -99,6 +99,8 @@ static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 ne /* Now fill out current adapter structure. cur_chan must be up to date */ priv->algo.master_xfer = i2c_demux_master_xfer; + if (adap->algo->master_xfer_atomic) + priv->algo.master_xfer_atomic = i2c_demux_master_xfer; priv->algo.functionality = i2c_demux_functionality; snprintf(priv->cur_adap.name, sizeof(priv->cur_adap.name), From patchwork Wed Apr 3 12:40:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075902 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5Kx2g6Kz9sSd for ; Wed, 3 Apr 2019 23:41:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727153AbfDCMlZ (ORCPT ); Wed, 3 Apr 2019 08:41:25 -0400 Received: from sauhun.de ([88.99.104.3]:48360 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726624AbfDCMkk (ORCPT ); Wed, 3 Apr 2019 08:40:40 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id C022E3E43CD; Wed, 3 Apr 2019 14:40:37 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang , Tero Kristo , Keerthy , Simon Horman Subject: [PATCH 06/12] i2c: omap: Add the master_xfer_irqless hook Date: Wed, 3 Apr 2019 14:40:13 +0200 Message-Id: <20190403124019.8947-7-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Add the master_xfer_irqless hook to enable i2c transactions in irq disabled contexts like the poweroff case. Signed-off-by: Tero Kristo Signed-off-by: Keerthy [wsa: simplified code a little: 'timeout = !ret'] Reviewed-by: Simon Horman Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 76 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index cd9c65f3d404..faa0394048a0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -269,6 +269,8 @@ static const u8 reg_map_ip_v2[] = { [OMAP_I2C_IP_V2_IRQENABLE_CLR] = 0x30, }; +static int omap_i2c_xfer_data(struct omap_i2c_dev *omap); + static inline void omap_i2c_write_reg(struct omap_i2c_dev *omap, int reg, u16 val) { @@ -648,15 +650,28 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *omap, u8 size, bool is_rx) (1000 * omap->speed / 8); } +static void omap_i2c_wait(struct omap_i2c_dev *omap) +{ + u16 stat; + u16 mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); + int count = 0; + + do { + stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); + count++; + } while (!(stat & mask) && count < 5); +} + /* * Low level master read/write transaction. */ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, - struct i2c_msg *msg, int stop) + struct i2c_msg *msg, int stop, bool polling) { struct omap_i2c_dev *omap = i2c_get_adapdata(adap); unsigned long timeout; u16 w; + int ret; dev_dbg(omap->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", msg->addr, msg->len, msg->flags, stop); @@ -680,7 +695,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; omap_i2c_write_reg(omap, OMAP_I2C_BUF_REG, w); - reinit_completion(&omap->cmd_complete); + if (!polling) + reinit_completion(&omap->cmd_complete); omap->cmd_err = 0; w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; @@ -732,8 +748,18 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, * REVISIT: We should abort the transfer on signals, but the bus goes * into arbitration and we're currently unable to recover from it. */ - timeout = wait_for_completion_timeout(&omap->cmd_complete, - OMAP_I2C_TIMEOUT); + if (!polling) { + timeout = wait_for_completion_timeout(&omap->cmd_complete, + OMAP_I2C_TIMEOUT); + } else { + do { + omap_i2c_wait(omap); + ret = omap_i2c_xfer_data(omap); + } while (ret == -EAGAIN); + + timeout = !ret; + } + if (timeout == 0) { dev_err(omap->dev, "controller timed out\n"); omap_i2c_reset(omap); @@ -772,7 +798,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, * to do the work during IRQ processing. */ static int -omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +omap_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg msgs[], int num, + bool polling) { struct omap_i2c_dev *omap = i2c_get_adapdata(adap); int i; @@ -794,7 +821,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap->set_mpu_wkup_lat(omap->dev, omap->latency); for (i = 0; i < num; i++) { - r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); + r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)), + polling); if (r != 0) break; } @@ -813,6 +841,18 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) return r; } +static int +omap_i2c_xfer_irq(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ + return omap_i2c_xfer_common(adap, msgs, num, false); +} + +static int +omap_i2c_xfer_polling(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ + return omap_i2c_xfer_common(adap, msgs, num, true); +} + static u32 omap_i2c_func(struct i2c_adapter *adap) { @@ -1035,10 +1075,8 @@ omap_i2c_isr(int irq, void *dev_id) return ret; } -static irqreturn_t -omap_i2c_isr_thread(int this_irq, void *dev_id) +static int omap_i2c_xfer_data(struct omap_i2c_dev *omap) { - struct omap_i2c_dev *omap = dev_id; u16 bits; u16 stat; int err = 0, count = 0; @@ -1056,7 +1094,8 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) if (!stat) { /* my work here is done */ - goto out; + err = -EAGAIN; + break; } dev_dbg(omap->dev, "IRQ (ISR = 0x%04x)\n", stat); @@ -1165,14 +1204,25 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) } } while (stat); - omap_i2c_complete_cmd(omap, err); + return err; +} + +static irqreturn_t +omap_i2c_isr_thread(int this_irq, void *dev_id) +{ + int ret; + struct omap_i2c_dev *omap = dev_id; + + ret = omap_i2c_xfer_data(omap); + if (ret != -EAGAIN) + omap_i2c_complete_cmd(omap, ret); -out: return IRQ_HANDLED; } static const struct i2c_algorithm omap_i2c_algo = { - .master_xfer = omap_i2c_xfer, + .master_xfer = omap_i2c_xfer_irq, + .master_xfer_atomic = omap_i2c_xfer_polling, .functionality = omap_i2c_func, }; From patchwork Wed Apr 3 12:40:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075901 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5Kw51yTz9sSQ for ; Wed, 3 Apr 2019 23:41:24 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726974AbfDCMlN (ORCPT ); Wed, 3 Apr 2019 08:41:13 -0400 Received: from sauhun.de ([88.99.104.3]:48380 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726637AbfDCMkl (ORCPT ); Wed, 3 Apr 2019 08:40:41 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 50BB23E43CE; Wed, 3 Apr 2019 14:40:38 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang , Timo Alho , Thierry Reding , Simon Horman Subject: [PATCH 07/12] i2c: tegra-bpmp: convert to use new atomic callbacks Date: Wed, 3 Apr 2019 14:40:14 +0200 Message-Id: <20190403124019.8947-8-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org The driver did handle this internally, convert it to use the new callbacks. Reviewed-by: Timo Alho Acked-by: Thierry Reding Reviewed-by: Simon Horman Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra-bpmp.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra-bpmp.c b/drivers/i2c/busses/i2c-tegra-bpmp.c index f6cd35d0a2ac..9bb085793a0c 100644 --- a/drivers/i2c/busses/i2c-tegra-bpmp.c +++ b/drivers/i2c/busses/i2c-tegra-bpmp.c @@ -207,7 +207,8 @@ static int tegra_bpmp_i2c_msg_len_check(struct i2c_msg *msgs, unsigned int num) static int tegra_bpmp_i2c_msg_xfer(struct tegra_bpmp_i2c *i2c, struct mrq_i2c_request *request, - struct mrq_i2c_response *response) + struct mrq_i2c_response *response, + bool atomic) { struct tegra_bpmp_message msg; int err; @@ -222,7 +223,7 @@ static int tegra_bpmp_i2c_msg_xfer(struct tegra_bpmp_i2c *i2c, msg.rx.data = response; msg.rx.size = sizeof(*response); - if (irqs_disabled()) + if (atomic) err = tegra_bpmp_transfer_atomic(i2c->bpmp, &msg); else err = tegra_bpmp_transfer(i2c->bpmp, &msg); @@ -230,8 +231,9 @@ static int tegra_bpmp_i2c_msg_xfer(struct tegra_bpmp_i2c *i2c, return err; } -static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, int num) +static int tegra_bpmp_i2c_xfer_common(struct i2c_adapter *adapter, + struct i2c_msg *msgs, int num, + bool atomic) { struct tegra_bpmp_i2c *i2c = i2c_get_adapdata(adapter); struct mrq_i2c_response response; @@ -253,7 +255,7 @@ static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter, return err; } - err = tegra_bpmp_i2c_msg_xfer(i2c, &request, &response); + err = tegra_bpmp_i2c_msg_xfer(i2c, &request, &response, atomic); if (err < 0) { dev_err(i2c->dev, "failed to transfer message: %d\n", err); return err; @@ -268,6 +270,18 @@ static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter, return num; } +static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter, + struct i2c_msg *msgs, int num) +{ + return tegra_bpmp_i2c_xfer_common(adapter, msgs, num, false); +} + +static int tegra_bpmp_i2c_xfer_atomic(struct i2c_adapter *adapter, + struct i2c_msg *msgs, int num) +{ + return tegra_bpmp_i2c_xfer_common(adapter, msgs, num, true); +} + static u32 tegra_bpmp_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | @@ -276,6 +290,7 @@ static u32 tegra_bpmp_i2c_func(struct i2c_adapter *adapter) static const struct i2c_algorithm tegra_bpmp_i2c_algo = { .master_xfer = tegra_bpmp_i2c_xfer, + .master_xfer_atomic = tegra_bpmp_i2c_xfer_atomic, .functionality = tegra_bpmp_i2c_func, }; From patchwork Wed Apr 3 12:40:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075900 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5Kw0GyMz9sSd for ; Wed, 3 Apr 2019 23:41:24 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726997AbfDCMlN (ORCPT ); Wed, 3 Apr 2019 08:41:13 -0400 Received: from sauhun.de ([88.99.104.3]:48388 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726654AbfDCMkl (ORCPT ); Wed, 3 Apr 2019 08:40:41 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id D6AAD3E43CF; Wed, 3 Apr 2019 14:40:38 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang , Andrew Lunn Subject: [PATCH 08/12] i2c: ocores: refactor setup for polling Date: Wed, 3 Apr 2019 14:40:15 +0200 Message-Id: <20190403124019.8947-9-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org By properly setting up the algorithm at probe time, we can skip the check at every transfer. This allows us to get rid of the flags completely. Signed-off-by: Wolfram Sang Cc: Andrew Lunn Acked-by: Peter Korsgaard Reviewed-by: Andrew Lunn --- drivers/i2c/busses/i2c-ocores.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 4e1a077fb688..1b99f467aae0 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -26,8 +26,6 @@ #include #include -#define OCORES_FLAG_POLL BIT(0) - /* * 'process_lock' exists because ocores_process() and ocores_process_timeout() * can't run in parallel. @@ -37,7 +35,6 @@ struct ocores_i2c { int iobase; u32 reg_shift; u32 reg_io_width; - unsigned long flags; wait_queue_head_t wait; struct i2c_adapter adap; struct i2c_msg *msg; @@ -403,11 +400,7 @@ static int ocores_xfer_polling(struct i2c_adapter *adap, static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { - struct ocores_i2c *i2c = i2c_get_adapdata(adap); - - if (i2c->flags & OCORES_FLAG_POLL) - return ocores_xfer_polling(adap, msgs, num); - return ocores_xfer_core(i2c, msgs, num, false); + return ocores_xfer_core(i2c_get_adapdata(adap), msgs, num, false); } static int ocores_init(struct device *dev, struct ocores_i2c *i2c) @@ -447,7 +440,7 @@ static u32 ocores_func(struct i2c_adapter *adap) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } -static const struct i2c_algorithm ocores_algorithm = { +static struct i2c_algorithm ocores_algorithm = { .master_xfer = ocores_xfer, .functionality = ocores_func, }; @@ -673,13 +666,13 @@ static int ocores_i2c_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq == -ENXIO) { - i2c->flags |= OCORES_FLAG_POLL; + ocores_algorithm.master_xfer = ocores_xfer_polling; } else { if (irq < 0) return irq; } - if (!(i2c->flags & OCORES_FLAG_POLL)) { + if (ocores_algorithm.master_xfer != ocores_xfer_polling) { ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0, pdev->name, i2c); if (ret) { From patchwork Wed Apr 3 12:40:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075892 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5KZ023Pz9sSm for ; Wed, 3 Apr 2019 23:41:05 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726738AbfDCMkm (ORCPT ); Wed, 3 Apr 2019 08:40:42 -0400 Received: from sauhun.de ([88.99.104.3]:48400 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726682AbfDCMkl (ORCPT ); Wed, 3 Apr 2019 08:40:41 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 69DCE3E43D0; Wed, 3 Apr 2019 14:40:39 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang , Andrew Lunn Subject: [PATCH 09/12] i2c: ocores: enable atomic xfers Date: Wed, 3 Apr 2019 14:40:16 +0200 Message-Id: <20190403124019.8947-10-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org The driver already has the routine in place, tie it to the new callback. Signed-off-by: Wolfram Sang Cc: Andrew Lunn Reviewed-by: Andrew Lunn --- drivers/i2c/busses/i2c-ocores.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 1b99f467aae0..c3dabee0aa35 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -442,6 +442,7 @@ static u32 ocores_func(struct i2c_adapter *adap) static struct i2c_algorithm ocores_algorithm = { .master_xfer = ocores_xfer, + .master_xfer_atomic = ocores_xfer_polling, .functionality = ocores_func, }; From patchwork Wed Apr 3 12:40:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075888 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5K82dNHz9sSJ for ; Wed, 3 Apr 2019 23:40:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726770AbfDCMkn (ORCPT ); Wed, 3 Apr 2019 08:40:43 -0400 Received: from sauhun.de ([88.99.104.3]:48350 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726690AbfDCMkl (ORCPT ); Wed, 3 Apr 2019 08:40:41 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id EE0B03E43D2; Wed, 3 Apr 2019 14:40:39 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 10/12] i2c: stu300: use xfer_atomic callback to bail out early Date: Wed, 3 Apr 2019 14:40:17 +0200 Message-Id: <20190403124019.8947-11-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Use the new callback to reject atomic transfers. Signed-off-by: Wolfram Sang Reviewed-by: Linus Walleij --- drivers/i2c/busses/i2c-stu300.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 5503fa171df0..743c161b22c5 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -328,12 +328,6 @@ static int stu300_start_and_await_event(struct stu300_dev *dev, { int ret; - if (unlikely(irqs_disabled())) { - /* TODO: implement polling for this case if need be. */ - WARN(1, "irqs are disabled, cannot poll for event\n"); - return -EIO; - } - /* Lock command issue, fill in an event we wait for */ spin_lock_irq(&dev->cmd_issue_lock); init_completion(&dev->cmd_complete); @@ -380,13 +374,6 @@ static int stu300_await_event(struct stu300_dev *dev, { int ret; - if (unlikely(irqs_disabled())) { - /* TODO: implement polling for this case if need be. */ - dev_err(&dev->pdev->dev, "irqs are disabled on this " - "system!\n"); - return -EIO; - } - /* Is it already here? */ spin_lock_irq(&dev->cmd_issue_lock); dev->cmd_err = STU300_ERROR_NONE; @@ -846,6 +833,13 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, return num; } +static int stu300_xfer_todo(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + /* TODO: implement polling for this case if need be. */ + WARN(1, "%s: atomic transfers not implemented\n", dev_name(&adap->dev)); + return -EOPNOTSUPP; +} + static u32 stu300_func(struct i2c_adapter *adap) { /* This is the simplest thing you can think of... */ @@ -853,8 +847,9 @@ static u32 stu300_func(struct i2c_adapter *adap) } static const struct i2c_algorithm stu300_algo = { - .master_xfer = stu300_xfer, - .functionality = stu300_func, + .master_xfer = stu300_xfer, + .master_xfer_atomic = stu300_xfer_todo, + .functionality = stu300_func, }; static const struct i2c_adapter_quirks stu300_quirks = { From patchwork Wed Apr 3 12:40:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075897 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5Kk2bBNz9sSX for ; Wed, 3 Apr 2019 23:41:14 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726724AbfDCMlG (ORCPT ); Wed, 3 Apr 2019 08:41:06 -0400 Received: from sauhun.de ([88.99.104.3]:48410 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726723AbfDCMkm (ORCPT ); Wed, 3 Apr 2019 08:40:42 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 81A513E43D1; Wed, 3 Apr 2019 14:40:40 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 11/12] i2c: algo: bit: add flag to whitelist atomic transfers Date: Wed, 3 Apr 2019 14:40:18 +0200 Message-Id: <20190403124019.8947-12-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Use the new xfer_atomic callback to check a newly introduced flag to whitelist atomic transfers. This will report configurations which worked accidently. Signed-off-by: Wolfram Sang --- drivers/i2c/algos/i2c-algo-bit.c | 22 ++++++++++++++++++++-- include/linux/i2c-algo-bit.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 5e5990a83da5..913db013fe90 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -603,6 +603,23 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, return ret; } +/* + * We print a warning when we are not flagged to support atomic transfers but + * will try anyhow. That's what the I2C core would do as well. Sadly, we can't + * modify the algorithm struct at probe time because this struct is exported + * 'const'. + */ +static int bit_xfer_atomic(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], + int num) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + if (!adap->can_do_atomic) + dev_warn(&i2c_adap->dev, "not flagged for atomic transfers\n"); + + return bit_xfer(i2c_adap, msgs, num); +} + static u32 bit_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | @@ -615,8 +632,9 @@ static u32 bit_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ const struct i2c_algorithm i2c_bit_algo = { - .master_xfer = bit_xfer, - .functionality = bit_func, + .master_xfer = bit_xfer, + .master_xfer_atomic = bit_xfer_atomic, + .functionality = bit_func, }; EXPORT_SYMBOL(i2c_bit_algo); diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h index 69045df78e2d..7fd5575a368f 100644 --- a/include/linux/i2c-algo-bit.h +++ b/include/linux/i2c-algo-bit.h @@ -33,6 +33,7 @@ struct i2c_algo_bit_data { minimum 5 us for standard-mode I2C and SMBus, maximum 50 us for SMBus */ int timeout; /* in jiffies */ + bool can_do_atomic; /* callbacks don't sleep, we can be atomic */ }; int i2c_bit_add_bus(struct i2c_adapter *); From patchwork Wed Apr 3 12:40:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1075890 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44Z5KX5zqnz9sSb for ; Wed, 3 Apr 2019 23:41:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726527AbfDCMk6 (ORCPT ); Wed, 3 Apr 2019 08:40:58 -0400 Received: from sauhun.de ([88.99.104.3]:48360 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726724AbfDCMkm (ORCPT ); Wed, 3 Apr 2019 08:40:42 -0400 Received: from localhost (p54B3311F.dip0.t-ipconnect.de [84.179.49.31]) by pokefinder.org (Postfix) with ESMTPSA id 17FCD3E43D3; Wed, 3 Apr 2019 14:40:41 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Rosin , Stefan Lengfeld , linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Linus Walleij , Andy Shevchenko , Wolfram Sang Subject: [PATCH 12/12] i2c: gpio: flag atomic capability if possible Date: Wed, 3 Apr 2019 14:40:19 +0200 Message-Id: <20190403124019.8947-13-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> References: <20190403124019.8947-1-wsa+renesas@sang-engineering.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org If switching GPIOs does not sleep, then we can support atomic transfers. Signed-off-by: Wolfram Sang Reviewed-by: Linus Walleij --- drivers/i2c/busses/i2c-gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index bba5c4627de3..9684a0ac2a6d 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -413,6 +413,8 @@ static int i2c_gpio_probe(struct platform_device *pdev) if (gpiod_cansleep(priv->sda) || gpiod_cansleep(priv->scl)) dev_warn(dev, "Slow GPIO pins might wreak havoc into I2C/SMBus bus timing"); + else + bit_data->can_do_atomic = true; bit_data->setsda = i2c_gpio_setsda_val; bit_data->setscl = i2c_gpio_setscl_val;