[PATCH 1/2] firmware: raspberrypi: Handle device registration errors

Triet Hoang triet.hoang.dev at gmail.com
Fri Sep 18 20:48:39 PDT 2026


Check the return value of platform_device_register_data() when
registering the hwmon and clock devices. Propagate registration failures
to the firmware probe instead of silently ignoring them.

Use local platform device pointers so the global pointers are only
updated after successful registration. If clock registration fails,
unregister the previously registered hwmon device before releasing the
firmware instance.

Keep the existing behavior of skipping hwmon registration when the
RPI_FIRMWARE_GET_THROTTLED request fails.

Fixes: 70eea1bbb556 ("firmware: raspberrypi: Register hwmon driver")
Fixes: 91f2cf4a6b21 ("firmware: raspberrypi: register clk device")
Signed-off-by: Triet Hoang <triet.hoang.dev at gmail.com>
---
 drivers/firmware/raspberrypi.c | 57 ++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 0aa322e9a2e7..88c3de9ce67a 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -197,22 +197,31 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
 	dev_info(fw->cl.dev, "Attached to firmware from %ptT\n", &date_and_time);
 }
 
-static void
+static int
 rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
 {
+	struct platform_device *pdev;
 	u32 packet;
-	int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
-					&packet, sizeof(packet));
+	int ret;
 
+	ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
+				    &packet, sizeof(packet));
 	if (ret)
-		return;
+		return 0;
+
+	pdev = platform_device_register_data(dev, "raspberrypi-hwmon",
+					     -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
 
-	rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon",
-						  -1, NULL, 0);
+	rpi_hwmon = pdev;
+
+	return 0;
 }
 
-static void rpi_register_clk_driver(struct device *dev)
+static int rpi_register_clk_driver(struct device *dev)
 {
+	struct platform_device *pdev;
 	struct device_node *firmware;
 
 	/*
@@ -224,11 +233,17 @@ static void rpi_register_clk_driver(struct device *dev)
 					   "raspberrypi,firmware-clocks");
 	if (firmware) {
 		of_node_put(firmware);
-		return;
+		return 0;
 	}
 
-	rpi_clk = platform_device_register_data(dev, "raspberrypi-clk",
-						-1, NULL, 0);
+	pdev = platform_device_register_data(dev, "raspberrypi-clk",
+					     -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	rpi_clk = pdev;
+
+	return 0;
 }
 
 unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id)
@@ -277,6 +292,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct rpi_firmware *fw;
+	int ret;
 
 	/*
 	 * Memory will be freed by rpi_firmware_delete() once all users have
@@ -292,7 +308,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
 
 	fw->chan = mbox_request_channel(&fw->cl, 0);
 	if (IS_ERR(fw->chan)) {
-		int ret = PTR_ERR(fw->chan);
+		ret = PTR_ERR(fw->chan);
 		kfree(fw);
 		return dev_err_probe(dev, ret, "Failed to get mbox channel\n");
 	}
@@ -303,10 +319,25 @@ static int rpi_firmware_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, fw);
 
 	rpi_firmware_print_firmware_revision(fw);
-	rpi_register_hwmon_driver(dev, fw);
-	rpi_register_clk_driver(dev);
+
+	ret = rpi_register_hwmon_driver(dev, fw);
+	if (ret)
+		goto err_put_fw;
+
+	ret = rpi_register_clk_driver(dev);
+	if (ret)
+		goto err_unregister_hwmon;
 
 	return 0;
+
+err_unregister_hwmon:
+	platform_device_unregister(rpi_hwmon);
+	rpi_hwmon = NULL;
+err_put_fw:
+	platform_set_drvdata(pdev, NULL);
+	rpi_firmware_put(fw);
+
+	return ret;
 }
 
 static void rpi_firmware_shutdown(struct platform_device *pdev)
-- 
2.53.0




More information about the linux-arm-kernel mailing list