{
        struct device_node *ep_np = NULL;
        struct of_endpoint ep;
-       bool found = false;
+       bool out_found = false;
+       bool in_found = false;
 
        for_each_endpoint_of_node(state->dev->of_node, ep_np) {
                of_graph_parse_endpoint(ep_np, &ep);
                of_node_get(ep_np);
                state->endpoints[ep.port] = ep_np;
 
-               found = true;
+               /*
+                * At least one input endpoint and one output endpoint shall
+                * be defined.
+                */
+               if (ep.port < ADV748X_PORT_TXA)
+                       in_found = true;
+               else
+                       out_found = true;
        }
 
-       return found ? 0 : -ENODEV;
+       return in_found && out_found ? 0 : -ENODEV;
 }
 
 static void adv748x_dt_cleanup(struct adv748x_state *state)
        state->i2c_clients[ADV748X_PAGE_IO] = client;
        i2c_set_clientdata(client, state);
 
+       /*
+        * We can not use container_of to get back to the state with two TXs;
+        * Initialize the TXs's fields unconditionally on the endpoint
+        * presence to access them later.
+        */
+       state->txa.state = state->txb.state = state;
+       state->txa.page = ADV748X_PAGE_TXA;
+       state->txb.page = ADV748X_PAGE_TXB;
+       state->txa.port = ADV748X_PORT_TXA;
+       state->txb.port = ADV748X_PORT_TXB;
+
        /* Discover and process ports declared by the Device tree endpoints */
        ret = adv748x_parse_dt(state);
        if (ret) {
 
 
 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
 {
-       struct device_node *ep;
        int ret;
 
-       /* We can not use container_of to get back to the state with two TXs */
-       tx->state = state;
-       tx->page = is_txa(tx) ? ADV748X_PAGE_TXA : ADV748X_PAGE_TXB;
-
-       ep = state->endpoints[is_txa(tx) ? ADV748X_PORT_TXA : ADV748X_PORT_TXB];
-       if (!ep) {
-               adv_err(state, "No endpoint found for %s\n",
-                               is_txa(tx) ? "txa" : "txb");
-               return -ENODEV;
-       }
+       if (!is_tx_enabled(tx))
+               return 0;
 
        /* Initialise the virtual channel */
        adv748x_csi2_set_virtual_channel(tx, 0);
                            is_txa(tx) ? "txa" : "txb");
 
        /* Ensure that matching is based upon the endpoint fwnodes */
-       tx->sd.fwnode = of_fwnode_handle(ep);
+       tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]);
 
        /* Register internal ops for incremental subdev registration */
        tx->sd.internal_ops = &adv748x_csi2_internal_ops;
 
 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
 {
+       if (!is_tx_enabled(tx))
+               return;
+
        v4l2_async_unregister_subdev(&tx->sd);
        media_entity_cleanup(&tx->sd.entity);
        v4l2_ctrl_handler_free(&tx->ctrl_hdl);
 
        struct adv748x_state *state;
        struct v4l2_mbus_framefmt format;
        unsigned int page;
+       unsigned int port;
 
        struct media_pad pads[ADV748X_CSI2_NR_PADS];
        struct v4l2_ctrl_handler ctrl_hdl;
 
 #define notifier_to_csi2(n) container_of(n, struct adv748x_csi2, notifier)
 #define adv748x_sd_to_csi2(sd) container_of(sd, struct adv748x_csi2, sd)
+#define is_tx_enabled(_tx) ((_tx)->state->endpoints[(_tx)->port] != NULL)
 
 enum adv748x_hdmi_pads {
        ADV748X_HDMI_SINK,