Skip to content

Commit

Permalink
firmware: rp1: Linger on firmware failure
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
pelwell committed Feb 4, 2025
1 parent 0cec3cd commit bb99009
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions drivers/firmware/rp1.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ static void rp1_firmware_delete(struct kref *kref)

void rp1_firmware_put(struct rp1_firmware *fw)
{
kref_put(&fw->consumers, rp1_firmware_delete);
if (!IS_ERR_OR_NULL(fw))
kref_put(&fw->consumers, rp1_firmware_delete);
}
EXPORT_SYMBOL_GPL(rp1_firmware_put);

Expand Down Expand Up @@ -157,7 +158,7 @@ struct rp1_firmware *rp1_firmware_get(struct device_node *client)
const char *match = rp1_firmware_of_match[0].compatible;
struct platform_device *pdev;
struct device_node *fwnode;
struct rp1_firmware *fw;
struct rp1_firmware *fw = NULL;

if (!client)
return NULL;
Expand All @@ -166,17 +167,17 @@ struct rp1_firmware *rp1_firmware_get(struct device_node *client)
return NULL;
if (!of_device_is_compatible(fwnode, match)) {
of_node_put(fwnode);
return NULL;
return ERR_PTR(-ENXIO);
}

pdev = of_find_device_by_node(fwnode);
of_node_put(fwnode);

if (!pdev)
goto err_exit;
return ERR_PTR(-ENXIO);

fw = platform_get_drvdata(pdev);
if (!fw)
if (IS_ERR_OR_NULL(fw))
goto err_exit;

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

err_exit:
put_device(&pdev->dev);
return NULL;
return fw;
}
EXPORT_SYMBOL_GPL(rp1_firmware_get);

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

fw = rp1_firmware_get(client);
if (!fw)
return NULL;
if (IS_ERR_OR_NULL(fw))
return fw;

ret = devm_add_action_or_reset(dev, devm_rp1_firmware_put, fw);
if (ret)
Expand Down Expand Up @@ -270,19 +271,18 @@ static int rp1_firmware_probe(struct platform_device *pdev)
init_completion(&fw->c);
kref_init(&fw->consumers);

platform_set_drvdata(pdev, fw);

ret = rp1_firmware_message(fw, GET_FIRMWARE_VERSION,
NULL, 0, &version, sizeof(version));
if (ret == sizeof(version)) {
dev_info(dev, "RP1 Firmware version %08x%08x%08x%08x%08x\n",
version[0], version[1], version[2], version[3], version[4]);
ret = 0;
} else if (ret >= 0) {
ret = -EIO;
platform_set_drvdata(pdev, fw);
} else {
rp1_firmware_put(fw);
platform_set_drvdata(pdev, ERR_PTR(-ENOENT));
}

return ret;
return 0;
}

static void rp1_firmware_remove(struct platform_device *pdev)
Expand Down

0 comments on commit bb99009

Please sign in to comment.