diff options
author | Julia Lawall <Julia.Lawall@lip6.fr> | 2019-01-13 03:47:42 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2019-01-17 08:59:02 -0500 |
commit | aa3312012f103f91f123600bbf768b11c8f431bc (patch) | |
tree | 660389a2bafad85d57b557e1ce3c60779875483e /drivers/gpu/drm/imx/imx-ldb.c | |
parent | 2c0408dd0d8906b26fe8023889af7adf5e68b2c2 (diff) |
drm/imx: imx-ldb: add missing of_node_puts
The device node iterators perform an of_node_get on each
iteration, so a jump out of the loop requires an of_node_put.
Move the initialization channel->child = child; down to just
before the call to imx_ldb_register so that intervening failures
don't need to clear it. Add a label at the end of the function to
do all the of_node_puts.
The semantic patch that finds part of this problem is as follows
(http://coccinelle.lip6.fr):
// <smpl>
@@
expression root,e;
local idexpression child;
iterator name for_each_child_of_node;
@@
for_each_child_of_node(root, child) {
... when != of_node_put(child)
when != e = child
(
return child;
|
* return ...;
)
...
}
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/imx-ldb.c')
-rw-r--r-- | drivers/gpu/drm/imx/imx-ldb.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 2c5bbe317353..e31e263cf86b 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
@@ -643,8 +643,10 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
643 | int bus_format; | 643 | int bus_format; |
644 | 644 | ||
645 | ret = of_property_read_u32(child, "reg", &i); | 645 | ret = of_property_read_u32(child, "reg", &i); |
646 | if (ret || i < 0 || i > 1) | 646 | if (ret || i < 0 || i > 1) { |
647 | return -EINVAL; | 647 | ret = -EINVAL; |
648 | goto free_child; | ||
649 | } | ||
648 | 650 | ||
649 | if (!of_device_is_available(child)) | 651 | if (!of_device_is_available(child)) |
650 | continue; | 652 | continue; |
@@ -657,7 +659,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
657 | channel = &imx_ldb->channel[i]; | 659 | channel = &imx_ldb->channel[i]; |
658 | channel->ldb = imx_ldb; | 660 | channel->ldb = imx_ldb; |
659 | channel->chno = i; | 661 | channel->chno = i; |
660 | channel->child = child; | ||
661 | 662 | ||
662 | /* | 663 | /* |
663 | * The output port is port@4 with an external 4-port mux or | 664 | * The output port is port@4 with an external 4-port mux or |
@@ -667,13 +668,13 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
667 | imx_ldb->lvds_mux ? 4 : 2, 0, | 668 | imx_ldb->lvds_mux ? 4 : 2, 0, |
668 | &channel->panel, &channel->bridge); | 669 | &channel->panel, &channel->bridge); |
669 | if (ret && ret != -ENODEV) | 670 | if (ret && ret != -ENODEV) |
670 | return ret; | 671 | goto free_child; |
671 | 672 | ||
672 | /* panel ddc only if there is no bridge */ | 673 | /* panel ddc only if there is no bridge */ |
673 | if (!channel->bridge) { | 674 | if (!channel->bridge) { |
674 | ret = imx_ldb_panel_ddc(dev, channel, child); | 675 | ret = imx_ldb_panel_ddc(dev, channel, child); |
675 | if (ret) | 676 | if (ret) |
676 | return ret; | 677 | goto free_child; |
677 | } | 678 | } |
678 | 679 | ||
679 | bus_format = of_get_bus_format(dev, child); | 680 | bus_format = of_get_bus_format(dev, child); |
@@ -689,18 +690,26 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
689 | if (bus_format < 0) { | 690 | if (bus_format < 0) { |
690 | dev_err(dev, "could not determine data mapping: %d\n", | 691 | dev_err(dev, "could not determine data mapping: %d\n", |
691 | bus_format); | 692 | bus_format); |
692 | return bus_format; | 693 | ret = bus_format; |
694 | goto free_child; | ||
693 | } | 695 | } |
694 | channel->bus_format = bus_format; | 696 | channel->bus_format = bus_format; |
697 | channel->child = child; | ||
695 | 698 | ||
696 | ret = imx_ldb_register(drm, channel); | 699 | ret = imx_ldb_register(drm, channel); |
697 | if (ret) | 700 | if (ret) { |
698 | return ret; | 701 | channel->child = NULL; |
702 | goto free_child; | ||
703 | } | ||
699 | } | 704 | } |
700 | 705 | ||
701 | dev_set_drvdata(dev, imx_ldb); | 706 | dev_set_drvdata(dev, imx_ldb); |
702 | 707 | ||
703 | return 0; | 708 | return 0; |
709 | |||
710 | free_child: | ||
711 | of_node_put(child); | ||
712 | return ret; | ||
704 | } | 713 | } |
705 | 714 | ||
706 | static void imx_ldb_unbind(struct device *dev, struct device *master, | 715 | static void imx_ldb_unbind(struct device *dev, struct device *master, |