]>
Commit | Line | Data |
---|---|---|
36e3f504 SL |
1 | From fa273e562ea7c78c0575598e66eff1d68715a39c Mon Sep 17 00:00:00 2001 |
2 | From: Julia Lawall <Julia.Lawall@lip6.fr> | |
3 | Date: Sun, 13 Jan 2019 09:47:42 +0100 | |
4 | Subject: drm/imx: imx-ldb: add missing of_node_puts | |
5 | ||
6 | [ Upstream commit aa3312012f103f91f123600bbf768b11c8f431bc ] | |
7 | ||
8 | The device node iterators perform an of_node_get on each | |
9 | iteration, so a jump out of the loop requires an of_node_put. | |
10 | ||
11 | Move the initialization channel->child = child; down to just | |
12 | before the call to imx_ldb_register so that intervening failures | |
13 | don't need to clear it. Add a label at the end of the function to | |
14 | do all the of_node_puts. | |
15 | ||
16 | The semantic patch that finds part of this problem is as follows | |
17 | (http://coccinelle.lip6.fr): | |
18 | ||
19 | // <smpl> | |
20 | @@ | |
21 | expression root,e; | |
22 | local idexpression child; | |
23 | iterator name for_each_child_of_node; | |
24 | @@ | |
25 | ||
26 | for_each_child_of_node(root, child) { | |
27 | ... when != of_node_put(child) | |
28 | when != e = child | |
29 | ( | |
30 | return child; | |
31 | | | |
32 | * return ...; | |
33 | ) | |
34 | ... | |
35 | } | |
36 | // </smpl> | |
37 | ||
38 | Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> | |
39 | Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> | |
40 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
41 | --- | |
42 | drivers/gpu/drm/imx/imx-ldb.c | 25 +++++++++++++++++-------- | |
43 | 1 file changed, 17 insertions(+), 8 deletions(-) | |
44 | ||
45 | diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c | |
46 | index 3bd0f8a18e74..42daa5c9ff8e 100644 | |
47 | --- a/drivers/gpu/drm/imx/imx-ldb.c | |
48 | +++ b/drivers/gpu/drm/imx/imx-ldb.c | |
49 | @@ -651,8 +651,10 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |
50 | int bus_format; | |
51 | ||
52 | ret = of_property_read_u32(child, "reg", &i); | |
53 | - if (ret || i < 0 || i > 1) | |
54 | - return -EINVAL; | |
55 | + if (ret || i < 0 || i > 1) { | |
56 | + ret = -EINVAL; | |
57 | + goto free_child; | |
58 | + } | |
59 | ||
60 | if (!of_device_is_available(child)) | |
61 | continue; | |
62 | @@ -665,7 +667,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |
63 | channel = &imx_ldb->channel[i]; | |
64 | channel->ldb = imx_ldb; | |
65 | channel->chno = i; | |
66 | - channel->child = child; | |
67 | ||
68 | /* | |
69 | * The output port is port@4 with an external 4-port mux or | |
70 | @@ -675,13 +676,13 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |
71 | imx_ldb->lvds_mux ? 4 : 2, 0, | |
72 | &channel->panel, &channel->bridge); | |
73 | if (ret && ret != -ENODEV) | |
74 | - return ret; | |
75 | + goto free_child; | |
76 | ||
77 | /* panel ddc only if there is no bridge */ | |
78 | if (!channel->bridge) { | |
79 | ret = imx_ldb_panel_ddc(dev, channel, child); | |
80 | if (ret) | |
81 | - return ret; | |
82 | + goto free_child; | |
83 | } | |
84 | ||
85 | bus_format = of_get_bus_format(dev, child); | |
86 | @@ -697,18 +698,26 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |
87 | if (bus_format < 0) { | |
88 | dev_err(dev, "could not determine data mapping: %d\n", | |
89 | bus_format); | |
90 | - return bus_format; | |
91 | + ret = bus_format; | |
92 | + goto free_child; | |
93 | } | |
94 | channel->bus_format = bus_format; | |
95 | + channel->child = child; | |
96 | ||
97 | ret = imx_ldb_register(drm, channel); | |
98 | - if (ret) | |
99 | - return ret; | |
100 | + if (ret) { | |
101 | + channel->child = NULL; | |
102 | + goto free_child; | |
103 | + } | |
104 | } | |
105 | ||
106 | dev_set_drvdata(dev, imx_ldb); | |
107 | ||
108 | return 0; | |
109 | + | |
110 | +free_child: | |
111 | + of_node_put(child); | |
112 | + return ret; | |
113 | } | |
114 | ||
115 | static void imx_ldb_unbind(struct device *dev, struct device *master, | |
116 | -- | |
117 | 2.19.1 | |
118 |