From patchwork Sun Mar 25 12:49:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 890630 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=bootlin.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 408HCX12MCz9rxs for ; Sun, 25 Mar 2018 23:49:12 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751997AbeCYMtJ (ORCPT ); Sun, 25 Mar 2018 08:49:09 -0400 Received: from mail.bootlin.com ([62.4.15.54]:52523 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752146AbeCYMtJ (ORCPT ); Sun, 25 Mar 2018 08:49:09 -0400 Received: by mail.bootlin.com (Postfix, from userid 110) id 16BD82084D; Sun, 25 Mar 2018 14:49:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (91-160-177-164.subs.proxad.net [91.160.177.164]) by mail.bootlin.com (Postfix) with ESMTPSA id C2A252072D; Sun, 25 Mar 2018 14:49:06 +0200 (CEST) From: Boris Brezillon To: Wolfram Sang , linux-i2c@vger.kernel.org Cc: Boris Brezillon Subject: [PATCH v4 1/3] i2c: Get rid of i2c_board_info->archdata Date: Sun, 25 Mar 2018 14:49:01 +0200 Message-Id: <20180325124903.2909-2-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180325124903.2909-1-boris.brezillon@bootlin.com> References: <20180325124903.2909-1-boris.brezillon@bootlin.com> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org The only user of i2c_board_info->archdata is the OF parsing code and it just pass a zero-initialized object which has the same effect as leaving ->archdata to NULL since the client object is allocated with kzalloc(). Get rid of this useless field. Signed-off-by: Boris Brezillon --- Changes in v4: - patch added in v4 --- drivers/i2c/i2c-core-base.c | 4 ---- drivers/i2c/i2c-core-of.c | 2 -- include/linux/i2c.h | 2 -- 3 files changed, 8 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index c8bfe008f208..0d710eae5422 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -717,10 +717,6 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->adapter = adap; client->dev.platform_data = info->platform_data; - - if (info->archdata) - client->dev.archdata = *info->archdata; - client->flags = info->flags; client->addr = info->addr; diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index c405270a98b4..15bd51eca37b 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -27,7 +27,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, { struct i2c_client *client; struct i2c_board_info info = {}; - struct dev_archdata dev_ad = {}; u32 addr; int ret; @@ -56,7 +55,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, } info.addr = addr; - info.archdata = &dev_ad; info.of_node = of_node_get(node); if (of_property_read_bool(node, "host-notify")) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 44ad14e016b5..aeb655772ef8 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -394,7 +394,6 @@ static inline bool i2c_detect_slave_mode(struct device *dev) { return false; } * @addr: stored in i2c_client.addr * @dev_name: Overrides the default - dev_name if set * @platform_data: stored in i2c_client.dev.platform_data - * @archdata: copied into i2c_client.dev.archdata * @of_node: pointer to OpenFirmware device node * @fwnode: device node supplied by the platform firmware * @properties: additional device properties for the device @@ -419,7 +418,6 @@ struct i2c_board_info { unsigned short addr; const char *dev_name; void *platform_data; - struct dev_archdata *archdata; struct device_node *of_node; struct fwnode_handle *fwnode; const struct property_entry *properties; From patchwork Sun Mar 25 12:49:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 890632 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=bootlin.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 408HCX6hWnz9s0R for ; Sun, 25 Mar 2018 23:49:12 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752629AbeCYMtK (ORCPT ); Sun, 25 Mar 2018 08:49:10 -0400 Received: from mail.bootlin.com ([62.4.15.54]:52524 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752324AbeCYMtJ (ORCPT ); Sun, 25 Mar 2018 08:49:09 -0400 Received: by mail.bootlin.com (Postfix, from userid 110) id 467BB2083D; Sun, 25 Mar 2018 14:49:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (91-160-177-164.subs.proxad.net [91.160.177.164]) by mail.bootlin.com (Postfix) with ESMTPSA id DF3D820808; Sun, 25 Mar 2018 14:49:06 +0200 (CEST) From: Boris Brezillon To: Wolfram Sang , linux-i2c@vger.kernel.org Cc: Boris Brezillon Subject: [PATCH v4 2/3] i2c: Retain info->of_node in i2c_new_device() Date: Sun, 25 Mar 2018 14:49:02 +0200 Message-Id: <20180325124903.2909-3-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180325124903.2909-1-boris.brezillon@bootlin.com> References: <20180325124903.2909-1-boris.brezillon@bootlin.com> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Currently, of_i2c_register_devices() is responsible for retaining info->of_node, but we're about to expose a function to parse I2C board info without registering the I2C device. We could possibly let this function retain ->of_node, but this approach is prone to reference leak since people will have to remember to call of_node_put() if something goes wrong between the OF node parsing and the registration step. Let's just retain the ->of_node in i2c_new_register() instead. Signed-off-by: Boris Brezillon --- Changes in v4: - patch added in v4 --- drivers/i2c/i2c-core-base.c | 6 ++++-- drivers/i2c/i2c-core-of.c | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 0d710eae5422..5227a3ceb659 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -742,7 +742,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.parent = &client->adapter->dev; client->dev.bus = &i2c_bus_type; client->dev.type = &i2c_client_type; - client->dev.of_node = info->of_node; + client->dev.of_node = of_node_get(info->of_node); client->dev.fwnode = info->fwnode; i2c_dev_set_name(adap, client, info); @@ -753,7 +753,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) dev_err(&adap->dev, "Failed to add properties to client %s: %d\n", client->name, status); - goto out_err; + goto out_err_put_of_node; } } @@ -769,6 +769,8 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) out_free_props: if (info->properties) device_remove_properties(&client->dev); +out_err_put_of_node: + of_node_put(info->of_node); out_err: dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x (%d)\n", diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 15bd51eca37b..9fb38e99a6c6 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -55,7 +55,7 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, } info.addr = addr; - info.of_node = of_node_get(node); + info.of_node = node; if (of_property_read_bool(node, "host-notify")) info.flags |= I2C_CLIENT_HOST_NOTIFY; @@ -66,7 +66,6 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, client = i2c_new_device(adap, &info); if (!client) { dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node); - of_node_put(node); return ERR_PTR(-EINVAL); } return client; From patchwork Sun Mar 25 12:49:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 890633 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=bootlin.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 408HCY5SGyz9s0v for ; Sun, 25 Mar 2018 23:49:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752324AbeCYMtL (ORCPT ); Sun, 25 Mar 2018 08:49:11 -0400 Received: from mail.bootlin.com ([62.4.15.54]:52527 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752374AbeCYMtJ (ORCPT ); Sun, 25 Mar 2018 08:49:09 -0400 Received: by mail.bootlin.com (Postfix, from userid 110) id 5AF1220808; Sun, 25 Mar 2018 14:49:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (91-160-177-164.subs.proxad.net [91.160.177.164]) by mail.bootlin.com (Postfix) with ESMTPSA id 06E3C2082C; Sun, 25 Mar 2018 14:49:07 +0200 (CEST) From: Boris Brezillon To: Wolfram Sang , linux-i2c@vger.kernel.org Cc: Boris Brezillon Subject: [PATCH v4 3/3] i2c: Export of_i2c_get_board_info() Date: Sun, 25 Mar 2018 14:49:03 +0200 Message-Id: <20180325124903.2909-4-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180325124903.2909-1-boris.brezillon@bootlin.com> References: <20180325124903.2909-1-boris.brezillon@bootlin.com> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org I3C busses have to know about all I2C devices connected on the I3C bus to properly initialize the I3C master, and I2C frames can't be sent on the bus until this initialization is done. We can't let the I2C core parse the DT and instantiate I2C devices as part of its i2c_add_adapter() procedure because, when done this way, I2C devices are directly registered to the device-model and might be attached to drivers which could in turn start sending frames on the bus, which won't work since, as said above, the bus is not yet initialized. Export of_i2c_register_device() in order to let the I3C core parse the I2C device nodes by itself and initialize the bus. Signed-off-by: Boris Brezillon --- Changes in v4: - document of_i2c_get_board_info() - rebased on i2c/for-next - moved the ->archdata assignment removal in a separate patch - moved the of_node_get/put() changes in a separate patch Changes in v3: - rebased on v4.16-rc1 Changes in v2: - fix memset() call - rebase on v4.15-rc1 --- drivers/i2c/i2c-core-of.c | 48 ++++++++++++++++++++++++++++++----------------- include/linux/i2c.h | 10 ++++++++++ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index 9fb38e99a6c6..6cb7ad608bcd 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c @@ -22,46 +22,60 @@ #include "i2c-core.h" -static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, - struct device_node *node) +int of_i2c_get_board_info(struct device *dev, struct device_node *node, + struct i2c_board_info *info) { - struct i2c_client *client; - struct i2c_board_info info = {}; u32 addr; int ret; - dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); + memset(info, 0, sizeof(*info)); - if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { - dev_err(&adap->dev, "of_i2c: modalias failure on %pOF\n", - node); - return ERR_PTR(-EINVAL); + if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { + dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); + return -EINVAL; } ret = of_property_read_u32(node, "reg", &addr); if (ret) { - dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node); - return ERR_PTR(ret); + dev_err(dev, "of_i2c: invalid reg on %pOF\n", node); + return ret; } if (addr & I2C_TEN_BIT_ADDRESS) { addr &= ~I2C_TEN_BIT_ADDRESS; - info.flags |= I2C_CLIENT_TEN; + info->flags |= I2C_CLIENT_TEN; } if (addr & I2C_OWN_SLAVE_ADDRESS) { addr &= ~I2C_OWN_SLAVE_ADDRESS; - info.flags |= I2C_CLIENT_SLAVE; + info->flags |= I2C_CLIENT_SLAVE; } - info.addr = addr; - info.of_node = node; + info->addr = addr; + info->of_node = node; if (of_property_read_bool(node, "host-notify")) - info.flags |= I2C_CLIENT_HOST_NOTIFY; + info->flags |= I2C_CLIENT_HOST_NOTIFY; if (of_get_property(node, "wakeup-source", NULL)) - info.flags |= I2C_CLIENT_WAKE; + info->flags |= I2C_CLIENT_WAKE; + + return 0; +} +EXPORT_SYMBOL_GPL(of_i2c_get_board_info); + +static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, + struct device_node *node) +{ + struct i2c_client *client; + struct i2c_board_info info; + int ret; + + dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); + + ret = of_i2c_get_board_info(&adap->dev, node, &info); + if (ret) + return ERR_PTR(ret); client = i2c_new_device(adap, &info); if (!client) { diff --git a/include/linux/i2c.h b/include/linux/i2c.h index aeb655772ef8..254cd34eeae2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -901,6 +901,9 @@ extern const struct of_device_id *i2c_of_match_device(const struct of_device_id *matches, struct i2c_client *client); +int of_i2c_get_board_info(struct device *dev, struct device_node *node, + struct i2c_board_info *info); + #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) @@ -925,6 +928,13 @@ static inline const struct of_device_id return NULL; } +static inline int of_i2c_get_board_info(struct device *dev, + struct device_node *node, + struct i2c_board_info *info) +{ + return -ENOTSUPP; +} + #endif /* CONFIG_OF */ #if IS_ENABLED(CONFIG_ACPI)