From 5ad1b2705f4accf5b890c85b53d633b274e67a23 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Jan 2025 16:40:25 +0000 Subject: [PATCH 1/2] misc: rp1-pio: Handle probe errors Ensure that rp1_pio_open fails if the device failed to probe. Link: https://github.com/raspberrypi/linux/issues/6593 Signed-off-by: Phil Elwell --- drivers/misc/rp1-pio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/misc/rp1-pio.c b/drivers/misc/rp1-pio.c index c0576432281d26..dbf69279e313d9 100644 --- a/drivers/misc/rp1-pio.c +++ b/drivers/misc/rp1-pio.c @@ -1014,6 +1014,9 @@ struct rp1_pio_client *rp1_pio_open(void) { struct rp1_pio_client *client; + if (!g_pio) + return ERR_PTR(-ENOENT); + client = kzalloc(sizeof(*client), GFP_KERNEL); if (!client) return ERR_PTR(-ENOMEM); @@ -1265,9 +1268,8 @@ static int rp1_pio_probe(struct platform_device *pdev) return dev_err_probe(dev, pdev->id, "alias is missing\n"); fw = devm_rp1_firmware_get(dev, dev->of_node); - if (IS_ERR(fw)) - return PTR_ERR(fw); - + if (IS_ERR_OR_NULL(fw)) + return dev_err_probe(dev, -ENOENT, "failed to contact RP1 firmware\n"); ret = rp1_firmware_get_feature(fw, FOURCC_PIO, &op_base, &op_count); if (ret < 0) return ret; From 13aa05a9e7ec6ec8b80376ee73022c6c357f0b1d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Jan 2025 16:33:37 +0000 Subject: [PATCH 2/2] firmware: rp1: Simplify rp1_firmware_get Simplify the implementation of rp1_firmware_get, requiring its clients to have a valid 'firmware' property. Also make it return NULL on error. Link: https://github.com/raspberrypi/linux/issues/6593 Signed-off-by: Phil Elwell --- drivers/firmware/rp1.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/firmware/rp1.c b/drivers/firmware/rp1.c index 2f646ad6f8f56e..0b0760ca777641 100644 --- a/drivers/firmware/rp1.c +++ b/drivers/firmware/rp1.c @@ -159,42 +159,36 @@ struct rp1_firmware *rp1_firmware_get(struct device_node *client) struct device_node *fwnode; struct rp1_firmware *fw; - if (client) { - fwnode = of_parse_phandle(client, "firmware", 0); - if (!fwnode) - fwnode = of_get_parent(client); - if (fwnode && !of_device_is_compatible(fwnode, match)) { - of_node_put(fwnode); - fwnode = NULL; - } - } - + if (!client) + return NULL; + fwnode = of_parse_phandle(client, "firmware", 0); if (!fwnode) - fwnode = of_find_matching_node(NULL, rp1_firmware_of_match); - - if (!fwnode) - return ERR_PTR(-ENOENT); + return NULL; + if (!of_device_is_compatible(fwnode, match)) { + of_node_put(fwnode); + return NULL; + } pdev = of_find_device_by_node(fwnode); of_node_put(fwnode); if (!pdev) - return ERR_PTR(-EPROBE_DEFER); + goto err_exit; fw = platform_get_drvdata(pdev); if (!fw) - goto err_defer; + goto err_exit; if (!kref_get_unless_zero(&fw->consumers)) - goto err_defer; + goto err_exit; put_device(&pdev->dev); return fw; -err_defer: +err_exit: put_device(&pdev->dev); - return ERR_PTR(-EPROBE_DEFER); + return NULL; } EXPORT_SYMBOL_GPL(rp1_firmware_get); @@ -210,8 +204,8 @@ struct rp1_firmware *devm_rp1_firmware_get(struct device *dev, struct device_nod int ret; fw = rp1_firmware_get(client); - if (IS_ERR(fw)) - return fw; + if (!fw) + return NULL; ret = devm_add_action_or_reset(dev, devm_rp1_firmware_put, fw); if (ret)