Skip to content

Commit 178d22f

Browse files
committed
firmware: rp1: Linger on firmware failure
To avoid pointless retries, let the probe function succeed if the firmware interface is configured correctly but the firmware is incompatible. The value of the private drvdata field holds the outcome. Link: #6642 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
1 parent de6f468 commit 178d22f

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

drivers/firmware/rp1.c

+14-14
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ static void rp1_firmware_delete(struct kref *kref)
114114

115115
void rp1_firmware_put(struct rp1_firmware *fw)
116116
{
117-
kref_put(&fw->consumers, rp1_firmware_delete);
117+
if (!IS_ERR_OR_NULL(fw))
118+
kref_put(&fw->consumers, rp1_firmware_delete);
118119
}
119120
EXPORT_SYMBOL_GPL(rp1_firmware_put);
120121

@@ -157,7 +158,7 @@ struct rp1_firmware *rp1_firmware_get(struct device_node *client)
157158
const char *match = rp1_firmware_of_match[0].compatible;
158159
struct platform_device *pdev;
159160
struct device_node *fwnode;
160-
struct rp1_firmware *fw;
161+
struct rp1_firmware *fw = NULL;
161162

162163
if (!client)
163164
return NULL;
@@ -166,17 +167,17 @@ struct rp1_firmware *rp1_firmware_get(struct device_node *client)
166167
return NULL;
167168
if (!of_device_is_compatible(fwnode, match)) {
168169
of_node_put(fwnode);
169-
return NULL;
170+
return ERR_PTR(-ENXIO);
170171
}
171172

172173
pdev = of_find_device_by_node(fwnode);
173174
of_node_put(fwnode);
174175

175176
if (!pdev)
176-
goto err_exit;
177+
return ERR_PTR(-ENXIO);
177178

178179
fw = platform_get_drvdata(pdev);
179-
if (!fw)
180+
if (IS_ERR_OR_NULL(fw))
180181
goto err_exit;
181182

182183
if (!kref_get_unless_zero(&fw->consumers))
@@ -188,7 +189,7 @@ struct rp1_firmware *rp1_firmware_get(struct device_node *client)
188189

189190
err_exit:
190191
put_device(&pdev->dev);
191-
return NULL;
192+
return fw;
192193
}
193194
EXPORT_SYMBOL_GPL(rp1_firmware_get);
194195

@@ -204,8 +205,8 @@ struct rp1_firmware *devm_rp1_firmware_get(struct device *dev, struct device_nod
204205
int ret;
205206

206207
fw = rp1_firmware_get(client);
207-
if (!fw)
208-
return NULL;
208+
if (IS_ERR_OR_NULL(fw))
209+
return fw;
209210

210211
ret = devm_add_action_or_reset(dev, devm_rp1_firmware_put, fw);
211212
if (ret)
@@ -270,19 +271,18 @@ static int rp1_firmware_probe(struct platform_device *pdev)
270271
init_completion(&fw->c);
271272
kref_init(&fw->consumers);
272273

273-
platform_set_drvdata(pdev, fw);
274-
275274
ret = rp1_firmware_message(fw, GET_FIRMWARE_VERSION,
276275
NULL, 0, &version, sizeof(version));
277276
if (ret == sizeof(version)) {
278277
dev_info(dev, "RP1 Firmware version %08x%08x%08x%08x%08x\n",
279278
version[0], version[1], version[2], version[3], version[4]);
280-
ret = 0;
281-
} else if (ret >= 0) {
282-
ret = -EIO;
279+
platform_set_drvdata(pdev, fw);
280+
} else {
281+
rp1_firmware_put(fw);
282+
platform_set_drvdata(pdev, ERR_PTR(-ENOENT));
283283
}
284284

285-
return ret;
285+
return 0;
286286
}
287287

288288
static void rp1_firmware_remove(struct platform_device *pdev)

0 commit comments

Comments
 (0)