From patchwork Mon Aug 13 21:16:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Lengfeld X-Patchwork-Id: 10564817 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5476C1515 for ; Mon, 13 Aug 2018 21:16:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 46D58286FD for ; Mon, 13 Aug 2018 21:16:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3B2FE28E29; Mon, 13 Aug 2018 21:16:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D0AD528B68 for ; Mon, 13 Aug 2018 21:16:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729947AbeHNAAW (ORCPT ); Mon, 13 Aug 2018 20:00:22 -0400 Received: from stcim.de ([78.46.90.227]:34456 "EHLO stcim.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730027AbeHNAAT (ORCPT ); Mon, 13 Aug 2018 20:00:19 -0400 Received: from xdsl-87-78-37-34.netcologne.de ([87.78.37.34] helo=localhost.localdomain) by stcim with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1fpKCF-0008Ap-Nn; Mon, 13 Aug 2018 23:16:15 +0200 From: Stefan Lengfeld To: linux-i2c@vger.kernel.org Cc: wsa@the-dreams.de, preid@electromag.com.au, j-keerthy@ti.com, tony@atomide.com, nsekhar@ti.com, vigneshr@ti.com, linux-omap@vger.kernel.org Subject: [RFC PATCH 1/4] i2c: allow drivers to announce that they are IRQ safe Date: Mon, 13 Aug 2018 23:16:11 +0200 Message-Id: <20180813211614.16440-2-contact@stefanchrist.eu> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180813211614.16440-1-contact@stefanchrist.eu> References: <5bb4b898-acc3-7c73-2285-cf84a88961e6@ti.com> <20180813211614.16440-1-contact@stefanchrist.eu> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Like the PM subsystem routine pm_runtime_irq_safe() and flag 'irq_safe' add a similar function i2c_adapter_irq_safe() to the I2C core. A driver should be able to announce whether his transfer implementations are safe to be called in IRQ disabled or atomic contexts, also called polling mode or sleep free operation. Making I2C transfers in atomic context is sometimes needed, e.g. for reboot handlers. Every driver should be able to declare explicitly whether IRQ disabled operation is supported or not. When you try make a I2C transfer in atomic contexts, it's already hard enough to ensure that every code path through the kernel is sleep-free. So give the curious developer a strong hint whether a driver supports atomic operation or not. Fail early instead of hoping that the LOCKDEP framework noticed the programming error. TODOs: - checkpatch complains hat in_atomic() should not be used in driver code Signed-off-by: Stefan Lengfeld Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 8 ++++++++ include/linux/i2c.h | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 15c95aaa484c..d4a76c8cd777 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1858,6 +1858,14 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (adap->quirks && i2c_check_for_quirks(adap, msgs, num)) return -EOPNOTSUPP; + if (in_atomic() || irqs_disabled()) { + if (!adap->irq_safe) { + dev_err(&adap->dev, + "IRQ disabled transfers not supported by the driver\n"); + return -EOPNOTSUPP; + } + } + /* * i2c_trace_msg_key gets enabled when tracepoint i2c_transfer gets * enabled. This is an efficient way of keeping the for-loop from diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 254cd34eeae2..f2d31ba09afe 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -664,6 +664,13 @@ struct i2c_adapter { const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data; + /* + * implementations in i2c_algorithm like 'master_xfer' are safe to be + * use in IRQ disabled contexts. A driver should set the flag with + * i2c_adapter_irq_safe() in it's probe function. + */ + bool irq_safe; + /* data fields that are valid for all devices */ const struct i2c_lock_operations *lock_ops; struct rt_mutex bus_lock; @@ -710,6 +717,15 @@ i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter) return NULL; } +/** + * i2c_adapter_irq_safe - driver is safe to be used in IRQ disabled context + * @adapter: Target I2C bus segment + */ +static inline void i2c_adapter_irq_safe(struct i2c_adapter *adapter) +{ + adapter->irq_safe = true; +} + int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *)); /* Adapter locking functions, exported for shared pin cases */