diff --git a/drivers/firmware/rp1.c b/drivers/firmware/rp1.c index 0b0760ca777641..5e99fc280121c5 100644 --- a/drivers/firmware/rp1.c +++ b/drivers/firmware/rp1.c @@ -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(fw)) + kref_put(&fw->consumers, rp1_firmware_delete); } EXPORT_SYMBOL_GPL(rp1_firmware_put); @@ -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; @@ -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)) @@ -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); @@ -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) @@ -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 { + kfree(fw); + platform_set_drvdata(pdev, ERR_PTR(-ENOENT)); } - return ret; + return 0; } static int rp1_firmware_remove(struct platform_device *pdev)