[media] v4l: omap3isp: Fix OF node double put when parsing OF graph
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Thu, 29 Sep 2016 08:41:24 +0000 (05:41 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Wed, 16 Nov 2016 18:13:39 +0000 (16:13 -0200)
When parsing the graph the driver loops over all endpoints using
of_graph_get_next_endpoint(). The function handles reference counting of
the passed and returned nodes, so the returned node's reference count
must not be decreased manually in the normal path.

Move the offending of_node_put() call to the error path that requires
manual reference count handling.

Reported-by: H. Nikolaus Schaller <hns@goldelico.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/omap3isp/isp.c

index 2e1b17e..084ecf4 100644 (file)
@@ -2117,23 +2117,18 @@ static int isp_of_parse_nodes(struct device *dev,
                struct isp_async_subdev *isd;
 
                isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
-               if (!isd) {
-                       of_node_put(node);
-                       return -ENOMEM;
-               }
+               if (!isd)
+                       goto error;
 
                notifier->subdevs[notifier->num_subdevs] = &isd->asd;
 
-               if (isp_of_parse_node(dev, node, isd)) {
-                       of_node_put(node);
-                       return -EINVAL;
-               }
+               if (isp_of_parse_node(dev, node, isd))
+                       goto error;
 
                isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
-               of_node_put(node);
                if (!isd->asd.match.of.node) {
                        dev_warn(dev, "bad remote port parent\n");
-                       return -EINVAL;
+                       goto error;
                }
 
                isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
@@ -2141,6 +2136,10 @@ static int isp_of_parse_nodes(struct device *dev,
        }
 
        return notifier->num_subdevs;
+
+error:
+       of_node_put(node);
+       return -EINVAL;
 }
 
 static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,