Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f001fd3 authored by Pantelis Antoniou's avatar Pantelis Antoniou Committed by Wolfram Sang
Browse files

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: default avatarPantelis Antoniou <pantelis.antoniou@konsulko.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent eb8173e3
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -1012,6 +1012,8 @@ EXPORT_SYMBOL_GPL(i2c_new_device);
 */
void i2c_unregister_device(struct i2c_client *client)
{
	if (client->dev.of_node)
		of_node_clear_flag(client->dev.of_node, OF_POPULATED);
	device_unregister(&client->dev);
}
EXPORT_SYMBOL_GPL(i2c_unregister_device);
@@ -1320,9 +1322,12 @@ static void of_i2c_register_devices(struct i2c_adapter *adap)

	dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");

	for_each_available_child_of_node(adap->dev.of_node, node)
	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);
	}
}

static 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,
		if (adap == NULL)
			return NOTIFY_OK;	/* not for us */

		if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) {
			put_device(&adap->dev);
			return NOTIFY_OK;
		}

		client = of_i2c_register_device(adap, rd->dn);
		put_device(&adap->dev);

@@ -1863,6 +1873,10 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
		}
		break;
	case OF_RECONFIG_CHANGE_REMOVE:
		/* already depopulated? */
		if (!of_node_check_flag(rd->dn, OF_POPULATED))
			return NOTIFY_OK;

		/* find our device by node */
		client = of_find_i2c_device_by_node(rd->dn);
		if (client == NULL)