diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-04-23 05:52:17 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-07-03 06:32:37 -0400 |
commit | c334940ea26cb58f5514dcbb225a3f397b2684ad (patch) | |
tree | ef00fb1054c92630e1f50ec5f0af46d7d9ade671 /drivers/base | |
parent | 4c834452aad01531db949414f94f817a86348d59 (diff) |
component: fix missed cleanup in case of devres failure
In try_to_bring_up_master(), we tear down the master's component list
for each error case, except for devres group failure. Fix this
oversight by making the code less prone to such mistakes.
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/component.c | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index c4778995cd72..d0ebd4431736 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c | |||
@@ -113,44 +113,44 @@ static void master_remove_components(struct master *master) | |||
113 | static int try_to_bring_up_master(struct master *master, | 113 | static int try_to_bring_up_master(struct master *master, |
114 | struct component *component) | 114 | struct component *component) |
115 | { | 115 | { |
116 | int ret = 0; | 116 | int ret; |
117 | 117 | ||
118 | if (!master->bound) { | 118 | if (master->bound) |
119 | /* | 119 | return 0; |
120 | * Search the list of components, looking for components that | ||
121 | * belong to this master, and attach them to the master. | ||
122 | */ | ||
123 | if (master->ops->add_components(master->dev, master)) { | ||
124 | /* Failed to find all components */ | ||
125 | master_remove_components(master); | ||
126 | ret = 0; | ||
127 | goto out; | ||
128 | } | ||
129 | 120 | ||
130 | if (component && component->master != master) { | 121 | /* |
131 | master_remove_components(master); | 122 | * Search the list of components, looking for components that |
132 | ret = 0; | 123 | * belong to this master, and attach them to the master. |
133 | goto out; | 124 | */ |
134 | } | 125 | if (master->ops->add_components(master->dev, master)) { |
126 | /* Failed to find all components */ | ||
127 | ret = 0; | ||
128 | goto out; | ||
129 | } | ||
135 | 130 | ||
136 | if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) { | 131 | if (component && component->master != master) { |
137 | ret = -ENOMEM; | 132 | ret = 0; |
138 | goto out; | 133 | goto out; |
139 | } | 134 | } |
140 | 135 | ||
141 | /* Found all components */ | 136 | if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) { |
142 | ret = master->ops->bind(master->dev); | 137 | ret = -ENOMEM; |
143 | if (ret < 0) { | 138 | goto out; |
144 | devres_release_group(master->dev, NULL); | 139 | } |
145 | dev_info(master->dev, "master bind failed: %d\n", ret); | ||
146 | master_remove_components(master); | ||
147 | goto out; | ||
148 | } | ||
149 | 140 | ||
150 | master->bound = true; | 141 | /* Found all components */ |
151 | ret = 1; | 142 | ret = master->ops->bind(master->dev); |
143 | if (ret < 0) { | ||
144 | devres_release_group(master->dev, NULL); | ||
145 | dev_info(master->dev, "master bind failed: %d\n", ret); | ||
146 | goto out; | ||
152 | } | 147 | } |
148 | |||
149 | master->bound = true; | ||
150 | return 1; | ||
151 | |||
153 | out: | 152 | out: |
153 | master_remove_components(master); | ||
154 | 154 | ||
155 | return ret; | 155 | return ret; |
156 | } | 156 | } |