MLK-17275-1 drm/bridge: adv7511: Add support for OF_DYNAMIC
When CONFIG_OF_DYNAMIC is used, and this driver is enabled in devicetree, but fails to probe a physical i2c client, it should disable it's remote endpoint, so that the DRM master device won't fail to bind the other available devices. Usually, the remote endpoint of this device is a DRM encoder. If a DRM encoder fails to bind, the DRM master device will also fail to bind. This is why, we should disable the encoder node dynamically in devicetree. Signed-off-by: Robert Chiras <robert.chiras@nxp.com> Reviewed-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>5.4-rM2-2.2.x-imx-squashed
parent
453cd42feb
commit
369b5f06ac
|
@ -9,7 +9,9 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <media/cec.h>
|
||||
|
@ -1109,6 +1111,11 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
|
|||
struct adv7511_link_config link_config;
|
||||
struct adv7511 *adv7511;
|
||||
struct device *dev = &i2c->dev;
|
||||
#if IS_ENABLED(CONFIG_OF_DYNAMIC)
|
||||
struct device_node *remote_node = NULL, *endpoint = NULL;
|
||||
struct of_changeset ocs;
|
||||
struct property *prop;
|
||||
#endif
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
|
@ -1249,6 +1256,44 @@ err_i2c_unregister_edid:
|
|||
i2c_unregister_device(adv7511->i2c_edid);
|
||||
uninit_regulators:
|
||||
adv7511_uninit_regulators(adv7511);
|
||||
#if IS_ENABLED(CONFIG_OF_DYNAMIC)
|
||||
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
|
||||
if (endpoint)
|
||||
remote_node = of_graph_get_remote_port_parent(endpoint);
|
||||
|
||||
if (remote_node) {
|
||||
int num_endpoints = 0;
|
||||
|
||||
/*
|
||||
* Remote node should have two endpoints (input and output: us)
|
||||
* If remote node has more than two endpoints, probably that it
|
||||
* has more outputs, so there is no need to disable it.
|
||||
*/
|
||||
endpoint = NULL;
|
||||
while ((endpoint = of_graph_get_next_endpoint(remote_node,
|
||||
endpoint)))
|
||||
num_endpoints++;
|
||||
|
||||
if (num_endpoints > 2) {
|
||||
of_node_put(remote_node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
|
||||
prop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
|
||||
prop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
|
||||
prop->length = 9;
|
||||
of_changeset_init(&ocs);
|
||||
of_changeset_update_property(&ocs, remote_node, prop);
|
||||
ret = of_changeset_apply(&ocs);
|
||||
if (!ret)
|
||||
dev_warn(dev,
|
||||
"Probe failed. Remote port '%s' disabled\n",
|
||||
remote_node->full_name);
|
||||
|
||||
of_node_put(remote_node);
|
||||
};
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue