aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
authorPantelis Antoniou <pantelis.antoniou@konsulko.com>2015-01-24 02:16:29 -0500
committerWolfram Sang <wsa@the-dreams.de>2015-07-09 16:25:54 -0400
commit4f001fd30145a6a8f72f9544c982cfd3dcb7c6df (patch)
tree5d21ee5c7ded9bc74c2f1448bd045f71c53d312f /drivers/i2c/i2c-core.c
parenteb8173e3d7b94664ecd3acf34942c9c9d6f6cb73 (diff)
i2c: Mark instantiated device nodes with OF_POPULATE
Mark (and unmark) device nodes with the POPULATE flag as appropriate. This is required to avoid multi probing when using I2C and device overlays containing a mux. This patch is also more careful with the release of the adapter device which caused a deadlock with muxes, and does not break the build on !OF since the node flag accessors are not defined then. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 069a41f116dd..e6d4935161e4 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1012,6 +1012,8 @@ EXPORT_SYMBOL_GPL(i2c_new_device);
1012 */ 1012 */
1013void i2c_unregister_device(struct i2c_client *client) 1013void i2c_unregister_device(struct i2c_client *client)
1014{ 1014{
1015 if (client->dev.of_node)
1016 of_node_clear_flag(client->dev.of_node, OF_POPULATED);
1015 device_unregister(&client->dev); 1017 device_unregister(&client->dev);
1016} 1018}
1017EXPORT_SYMBOL_GPL(i2c_unregister_device); 1019EXPORT_SYMBOL_GPL(i2c_unregister_device);
@@ -1320,8 +1322,11 @@ static void of_i2c_register_devices(struct i2c_adapter *adap)
1320 1322
1321 dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); 1323 dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
1322 1324
1323 for_each_available_child_of_node(adap->dev.of_node, node) 1325 for_each_available_child_of_node(adap->dev.of_node, node) {
1326 if (of_node_test_and_set_flag(node, OF_POPULATED))
1327 continue;
1324 of_i2c_register_device(adap, node); 1328 of_i2c_register_device(adap, node);
1329 }
1325} 1330}
1326 1331
1327static int of_dev_node_match(struct device *dev, void *data) 1332static int of_dev_node_match(struct device *dev, void *data)
@@ -1853,6 +1858,11 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
1853 if (adap == NULL) 1858 if (adap == NULL)
1854 return NOTIFY_OK; /* not for us */ 1859 return NOTIFY_OK; /* not for us */
1855 1860
1861 if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) {
1862 put_device(&adap->dev);
1863 return NOTIFY_OK;
1864 }
1865
1856 client = of_i2c_register_device(adap, rd->dn); 1866 client = of_i2c_register_device(adap, rd->dn);
1857 put_device(&adap->dev); 1867 put_device(&adap->dev);
1858 1868
@@ -1863,6 +1873,10 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
1863 } 1873 }
1864 break; 1874 break;
1865 case OF_RECONFIG_CHANGE_REMOVE: 1875 case OF_RECONFIG_CHANGE_REMOVE:
1876 /* already depopulated? */
1877 if (!of_node_check_flag(rd->dn, OF_POPULATED))
1878 return NOTIFY_OK;
1879
1866 /* find our device by node */ 1880 /* find our device by node */
1867 client = of_find_i2c_device_by_node(rd->dn); 1881 client = of_find_i2c_device_by_node(rd->dn);
1868 if (client == NULL) 1882 if (client == NULL)