Received: by 2002:ac0:a874:0:0:0:0:0 with SMTP id c49csp397405ima; Fri, 15 Mar 2019 05:25:35 -0700 (PDT) X-Google-Smtp-Source: APXvYqxLB8eXlTfzguUSLou3N7l7nWpI5m8BsAzTHhkI/ENVX4HoQ3ke2GSGJmoPiDQ3eW4UJAfx X-Received: by 2002:a17:902:28a7:: with SMTP id f36mr3965106plb.169.1552652735806; Fri, 15 Mar 2019 05:25:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552652735; cv=none; d=google.com; s=arc-20160816; b=dTwKB0fkJcsP+DEA3q4dQRfx4UNd7rJQfOMuAezyYyTlZZQ4wshYZCXiCzqALW1o7A EZvbyv7aMRyuH+hfsFjILQwg5/VlQhJee+2hnJXcp+lHEFGymm6vHV0tFKYKtEJwV7/B ySR20sYOfVHPxiTrPNt84B9PbfORjL3rZvbMSsq3KscI3UiHDlE/Ww0pIMoc5v9k3l+u cI3DQwqkLjWYUMIuFpUCBPaAnkyy6VDF8d43u06xrJo5N0KFSihhlNWcMIv9P8sl6a3u rp2p4yluO0T3RPOTGfCl9BYbyBCEou6ybCHXk1mx+32pSH+N0wYi2Y0fEhVB3DRuhKu2 pSSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:organisation:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=q/jkztv1+4kN/OfXbSbJcCZ9e3Zo5gD4khnEsOmQxeg=; b=v9KuEQa13mluQVwH1yhLJj5oEKaMUpcBkRAj7MLRoEq+Qq5AX4BwHj0tL3UoMdpK7+ dm+rwekBIQd1V7+Iw7U4yJOwmMbqHT4PbpdU85VHY7uxE90a/hxobQG2QSWXT130zmuo TK1gLnAh3yzQl16VVmLC8NSkjYdDeDp8KRqA2xNKd96cIh1l7NuzJp0gzdCywPc3jcEe BCm48qaMbGF1lxg3zdRQYj6F6uhxE1DrlLg50u14MdHmPZYowVu63YLshnuATEtrRrGx Tfv02bHLPyoyIKPZP4hNzu0oCjqYeMX/ZjEqfzLPJhXe2UYnajwSmWzrQ/D3YwNb9aBM jaKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@verge.net.au header.s=mail header.b=axLkF47r; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 70si1794107ple.294.2019.03.15.05.25.20; Fri, 15 Mar 2019 05:25:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@verge.net.au header.s=mail header.b=axLkF47r; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728947AbfCOMX0 (ORCPT + 99 others); Fri, 15 Mar 2019 08:23:26 -0400 Received: from kirsty.vergenet.net ([202.4.237.240]:35960 "EHLO kirsty.vergenet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726996AbfCOMX0 (ORCPT ); Fri, 15 Mar 2019 08:23:26 -0400 Received: from reginn.horms.nl (watermunt.horms.nl [80.127.179.77]) by kirsty.vergenet.net (Postfix) with ESMTPA id 9DE8F25B76D; Fri, 15 Mar 2019 23:23:22 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=verge.net.au; s=mail; t=1552652602; bh=0gua/VrmG9wPPjt3WJ2QMSRoRzTyJbDgOfBBIa6Dhe0=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=axLkF47rfC7j9q3K1GzHMClcbTR20FaEWnI77RghrrSXhIVpak4Amy8KuSB5qO8hZ 4bwMT/rOyIQ+i5iUQ4+EEGFLov27PnBYrrroKp2XoJt8YG8ZsrblsTYO2N1kwvwg3z wAZx4LgStU3JGa7aNhqJKO3EQKHmlIgdH6LGUe3Y= Received: by reginn.horms.nl (Postfix, from userid 7100) id 114E79403F2; Fri, 15 Mar 2019 13:23:21 +0100 (CET) Date: Fri, 15 Mar 2019 13:23:21 +0100 From: Simon Horman To: Wolfram Sang Cc: linux-i2c@vger.kernel.org, Tero Kristo , Phil Reid , Tony Lindgren , Keerthy , linux-kernel@vger.kernel.org, Russell King , linux-renesas-soc@vger.kernel.org, linux-omap@vger.kernel.org, linux-tegra@vger.kernel.org, Stefan Lengfeld , Andy Shevchenko , Peter Rosin , linux-arm-kernel@lists.infradead.org Subject: Re: [RFC PATCH v2 3/7] i2c: core: introduce callbacks for atomic transfers Message-ID: <20190315122320.34yibpfhv2b6ptwl@verge.net.au> References: <20190302134735.4393-1-wsa+renesas@sang-engineering.com> <20190302134735.4393-4-wsa+renesas@sang-engineering.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190302134735.4393-4-wsa+renesas@sang-engineering.com> Organisation: Horms Solutions BV User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Mar 02, 2019 at 02:47:31PM +0100, Wolfram Sang wrote: > 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 > --- > 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 004f8a3b6365..2127dd08ff01 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 ((in_atomic() || irqs_disabled()) && 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..e01a548fc559 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 (in_atomic() || irqs_disabled()) { > + 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 6e98aa811980..01a6cb9b53aa 100644 > --- a/drivers/i2c/i2c-core.h > +++ b/drivers/i2c/i2c-core.h > @@ -33,10 +33,13 @@ static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) > { > int ret = 0; > > - if (in_atomic() || irqs_disabled()) > + if (in_atomic() || irqs_disabled()) { > + WARN(!adap->algo->master_xfer_atomic && !adap->algo->smbus_xfer_atomic, > + "No atomic I2C transfer handler for '%s'\n", dev_name(&adap->dev)); Is WARN_ONCE more appropriate here? > 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..3cd921dd39e3 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} field should indicate the I think "field" should be "fields" in the new text. > + * 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); > -- > 2.11.0 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel >