From patchwork Fri May 4 13:04:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bastian Krause X-Patchwork-Id: 908703 X-Patchwork-Delegate: patchwork@peda.user.lysator.liu.se 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-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40csh76byvz9s4n for ; Fri, 4 May 2018 23:05:43 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751268AbeEDNFh (ORCPT ); Fri, 4 May 2018 09:05:37 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:59077 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751196AbeEDNFg (ORCPT ); Fri, 4 May 2018 09:05:36 -0400 Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7] helo=dude.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.89) (envelope-from ) id 1fEaP0-00010G-0N; Fri, 04 May 2018 15:05:34 +0200 From: Bastian Stender To: Peter Rosin , Wolfram Sang Cc: linux-i2c@vger.kernel.org, devicetree@vger.kernel.org, Michael Lawnick , kernel@pengutronix.de, Bastian Stender Subject: [PATCH v2 3/3] i2c: mux: pca954x: add option to use as mux-locked Date: Fri, 4 May 2018 15:04:49 +0200 Message-Id: <20180504130449.13730-3-bst@pengutronix.de> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180504130449.13730-1-bst@pengutronix.de> References: <20180504130449.13730-1-bst@pengutronix.de> X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: bst@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-i2c@vger.kernel.org Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Commit 6ef91fcca8a8 ("i2c: mux: relax locking of the top i2c adapter during mux-locked muxing") introduced a new locking concept "mux-locked", so that these muxes lock only the muxes on the parent adapter instead of the whole i2c bus. In case the dt property "mux-locked" is present make use of this concept. This makes interaction between i2c devices behind the mux and devices directly on the bus possible - at least in simple cases. It might not work properly for complex i2c topologies. If the dt property is not present use the parent-locked concept as before. Signed-off-by: Bastian Stender --- Changes since implicit v1 ("i2c: mux: pca954x: use relaxed locking of the top i2c adapter during mux-locked muxing"): - fix unlocked SMBus access - make mux-locked optional via dt --- drivers/i2c/muxes/i2c-mux-pca954x.c | 32 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 09bafd3e68fa..dfa9e8d350c7 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -219,6 +219,7 @@ MODULE_DEVICE_TABLE(of, pca954x_of_match); static int pca954x_reg_write(struct i2c_adapter *adap, struct i2c_client *client, u8 val) { + struct i2c_mux_core *muxc = i2c_get_clientdata(client); int ret = -ENODEV; if (adap->algo->master_xfer) { @@ -230,16 +231,26 @@ static int pca954x_reg_write(struct i2c_adapter *adap, msg.len = 1; buf[0] = val; msg.buf = buf; - ret = __i2c_transfer(adap, &msg, 1); + + if (muxc->mux_locked) + ret = i2c_transfer(adap, &msg, 1); + else + ret = __i2c_transfer(adap, &msg, 1); if (ret >= 0 && ret != 1) ret = -EREMOTEIO; } else { union i2c_smbus_data data; - ret = adap->algo->smbus_xfer(adap, client->addr, + if (muxc->mux_locked) + ret = i2c_smbus_xfer(adap, client->addr, client->flags, I2C_SMBUS_WRITE, val, I2C_SMBUS_BYTE, &data); + else + ret = adap->algo->smbus_xfer(adap, client->addr, + client->flags, + I2C_SMBUS_WRITE, val, + I2C_SMBUS_BYTE, &data); } return ret; @@ -371,7 +382,9 @@ static int pca954x_probe(struct i2c_client *client, bool idle_disconnect_dt; struct gpio_desc *gpio; int num, force, class; + bool mux_locked; struct i2c_mux_core *muxc; + u32 mux_alloc_flags; struct pca954x *data; const struct of_device_id *match; int ret; @@ -379,9 +392,13 @@ static int pca954x_probe(struct i2c_client *client, if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) return -ENODEV; + mux_locked = of_property_read_bool(of_node, "mux-locked"); + + mux_alloc_flags = mux_locked ? I2C_MUX_LOCKED : 0; muxc = i2c_mux_alloc(adap, &client->dev, - PCA954X_MAX_NCHANS, sizeof(*data), 0, - pca954x_select_chan, pca954x_deselect_mux); + PCA954X_MAX_NCHANS, sizeof(*data), + mux_alloc_flags, pca954x_select_chan, + pca954x_deselect_mux); if (!muxc) return -ENOMEM; data = i2c_mux_priv(muxc); @@ -389,6 +406,8 @@ static int pca954x_probe(struct i2c_client *client, i2c_set_clientdata(client, muxc); data->client = client; + muxc->mux_locked = mux_locked; + /* Get the mux out of reset if a reset GPIO is specified. */ gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(gpio)) @@ -470,8 +489,9 @@ static int pca954x_probe(struct i2c_client *client, } dev_info(&client->dev, - "registered %d multiplexed busses for I2C %s %s\n", - num, data->chip->muxtype == pca954x_ismux + "registered %d multiplexed busses for %s-locked I2C %s %s\n", + num, muxc->mux_locked ? "mux" : "parent", + data->chip->muxtype == pca954x_ismux ? "mux" : "switch", client->name); return 0;