Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934117AbcKILKm (ORCPT ); Wed, 9 Nov 2016 06:10:42 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:55448 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933357AbcKILKj (ORCPT ); Wed, 9 Nov 2016 06:10:39 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ralf Ramsauer , Geert Uytterhoeven , Pantelis Antoniou , Wolfram Sang Subject: [PATCH 4.8 121/138] i2c: mark device nodes only in case of successful instantiation Date: Wed, 9 Nov 2016 11:46:44 +0100 Message-Id: <20161109102850.511729854@linuxfoundation.org> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161109102844.808685475@linuxfoundation.org> References: <20161109102844.808685475@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2254 Lines: 68 4.8-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ralf Ramsauer commit 6a676fb69dcbf3310b9e462c1db66c8e7f6ead38 upstream. Instantiated I2C device nodes are marked with OF_POPULATE. This was introduced in 4f001fd30145a6. On unloading, loaded device nodes will of course be unmarked. The problem are nodes that fail during initialisation: If a node fails, it won't be unloaded and hence not be unmarked. If a I2C driver module is unloaded and reloaded, it will skip nodes that failed before. Skip device nodes that are already populated and mark them only in case of success. Fixes: 4f001fd30145a6 ("i2c: Mark instantiated device nodes with OF_POPULATE") Signed-off-by: Ralf Ramsauer Reviewed-by: Geert Uytterhoeven Acked-by: Pantelis Antoniou [wsa: use 14-digit commit sha] Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/i2c-core.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1592,6 +1592,7 @@ static struct i2c_client *of_i2c_registe static void of_i2c_register_devices(struct i2c_adapter *adap) { struct device_node *node; + struct i2c_client *client; /* Only register child devices if the adapter has a node pointer set */ if (!adap->dev.of_node) @@ -1602,7 +1603,14 @@ static void of_i2c_register_devices(stru for_each_available_child_of_node(adap->dev.of_node, node) { if (of_node_test_and_set_flag(node, OF_POPULATED)) continue; - of_i2c_register_device(adap, node); + + client = of_i2c_register_device(adap, node); + if (IS_ERR(client)) { + dev_warn(&adap->dev, + "Failed to create I2C device for %s\n", + node->full_name); + of_node_clear_flag(node, OF_POPULATED); + } } } @@ -2201,6 +2209,7 @@ static int of_i2c_notify(struct notifier if (IS_ERR(client)) { dev_err(&adap->dev, "failed to create client for '%s'\n", rd->dn->full_name); + of_node_clear_flag(rd->dn, OF_POPULATED); return notifier_from_errno(PTR_ERR(client)); } break;