media: i2c: max9286: [Workaround] 'device is bound'

This introduces a local workaround to support multiple MAX9286 devices
on the same I2C bus.

Not for upstream consumption due to device_is_bound being an in kernel
symbol, and requires the module to be a built-in only.

Not-signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index b73884e..2491c68 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -154,6 +154,7 @@ struct max9286_priv {
 	struct media_pad pads[MAX9286_N_PADS];
 	struct regulator *regulator;
 	struct dentry *dbgroot;
+	bool poc_enabled;
 
 	struct gpio_chip gpio;
 	u8 gpio_state;
@@ -1172,12 +1173,22 @@ static int max9286_register_gpio(struct max9286_priv *priv)
 	return ret;
 }
 
-static int max9286_init(struct device *dev)
+static const struct of_device_id max9286_dt_ids[] = {
+	{ .compatible = "maxim,max9286" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, max9286_dt_ids);
+
+static int max9286_init(struct device *dev, void *data)
 {
 	struct max9286_priv *priv;
 	struct i2c_client *client;
 	int ret;
 
+	/* Skip non-max9286 devices. */
+	if (!dev->of_node || !of_match_node(max9286_dt_ids, dev->of_node))
+		return 0;
+
 	client = to_i2c_client(dev);
 	priv = i2c_get_clientdata(client);
 
@@ -1188,6 +1199,8 @@ static int max9286_init(struct device *dev)
 		return ret;
 	}
 
+	priv->poc_enabled = true;
+
 	/*
 	 * Regulator Workaround:
 	 *
@@ -1233,10 +1246,30 @@ static int max9286_init(struct device *dev)
 	max9286_v4l2_unregister(priv);
 err_regulator:
 	regulator_disable(priv->regulator);
+	priv->poc_enabled = false;
 
 	return ret;
 }
 
+static int max9286_is_bound(struct device *dev, void *data)
+{
+	struct device *this = data;
+	int ret;
+
+	if (dev == this)
+		return 0;
+
+	/* Skip non-max9286 devices. */
+	if (!dev->of_node || !of_match_node(max9286_dt_ids, dev->of_node))
+		return 0;
+
+	ret = device_is_bound(dev);
+	if (!ret)
+		return -EPROBE_DEFER;
+
+	return 0;
+}
+
 static void max9286_cleanup_dt(struct max9286_priv *priv)
 {
 	struct max9286_source *source;
@@ -1388,16 +1421,26 @@ static int max9286_probe(struct i2c_client *client)
 		usleep_range(4000, 5000);
 
 	/*
-	 * The MAX9286 starts by default with all ports enabled, we disable all
-	 * ports early to ensure that all channels are disabled if we error out
-	 * and keep the bus consistent.
+	 * We can have multiple MAX9286 instances on the same physical I2C
+	 * bus, and I2C children behind ports of separate MAX9286 instances
+	 * having the same I2C address. As the MAX9286 starts by default with
+	 * all ports enabled, we need to disable all ports on all MAX9286
+	 * instances before proceeding to further initialize the devices and
+	 * instantiate children.
+	 *
+	 * Start by just disabling all channels on the current device. Then,
+	 * if all other MAX9286 on the parent bus have been probed, proceed
+	 * to initialize them all, including the current one.
 	 */
 	max9286_i2c_mux_close(priv);
 
 	/*
 	 * The MAX9286 initialises with auto-acknowledge enabled by default.
-	 * This can be invasive to other transactions on the same bus, so
-	 * disable it early. It will be enabled only as and when needed.
+	 * This means that if multiple MAX9286 devices are connected to an I2C
+	 * bus, another MAX9286 could ack I2C transfers meant for a device on
+	 * the other side of the GMSL links for this MAX9286 (such as a
+	 * MAX9271). To prevent that disable auto-acknowledge early on; it
+	 * will be enabled later as needed.
 	 */
 	max9286_configure_i2c(priv, false);
 
@@ -1422,10 +1465,21 @@ static int max9286_probe(struct i2c_client *client)
 	/* Add any userspace support before we return early. */
 	max9286_debugfs_init(priv);
 
-	ret = max9286_init(&client->dev);
+	ret = device_for_each_child(client->dev.parent, &client->dev,
+				    max9286_is_bound);
+	if (ret)
+		return 0;
+
+	dev_dbg(&client->dev,
+		"All max9286 probed: start initialization sequence\n");
+	ret = device_for_each_child(client->dev.parent, NULL,
+				    max9286_init);
 	if (ret < 0)
 		goto err_cleanup_dt;
 
+	/* Leave the mux channels disabled until they are selected. */
+	max9286_i2c_mux_close(priv);
+
 	return 0;
 
 err_cleanup_dt:
@@ -1448,7 +1502,8 @@ static int max9286_remove(struct i2c_client *client)
 
 	max9286_v4l2_unregister(priv);
 
-	regulator_disable(priv->regulator);
+	if (priv->poc_enabled)
+		regulator_disable(priv->regulator);
 
 	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
 
@@ -1457,12 +1512,6 @@ static int max9286_remove(struct i2c_client *client)
 	return 0;
 }
 
-static const struct of_device_id max9286_dt_ids[] = {
-	{ .compatible = "maxim,max9286" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, max9286_dt_ids);
-
 static struct i2c_driver max9286_i2c_driver = {
 	.driver	= {
 		.name		= "max9286",