Re: [PATCH v7 2/3] pwm: rp1: Add RP1 PWM controller driver

From: Christophe JAILLET

Date: Thu Sep 03 2026 - 16:41:11 EST


Le 20/07/2026 à 11:44, Andrea della Porta a écrit :
From: Naushir Patuck <naush@xxxxxxxxxxxxxxx>

The Raspberry Pi RP1 southbridge features an embedded PWM
controller with 4 output channels, alongside an RPM interface
to read the fan speed on the Raspberry Pi 5.

Add the supporting driver.

Signed-off-by: Naushir Patuck <naush@xxxxxxxxxxxxxxx>
Co-developed-by: Stanimir Varbanov <svarbanov@xxxxxxx>
Signed-off-by: Stanimir Varbanov <svarbanov@xxxxxxx>
Signed-off-by: Andrea della Porta <andrea.porta@xxxxxxxx>

Hi,

...

+static int rp1_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ unsigned long clk_rate;
+ struct pwm_chip *chip;
+ void __iomem *base;
+ struct rp1_pwm *rp1;
+ int ret;
+
+ chip = devm_pwmchip_alloc(dev, RP1_PWM_NUM_PWMS, sizeof(*rp1));
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+
+ rp1 = pwmchip_get_drvdata(chip);
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ rp1->regmap = devm_regmap_init_mmio(dev, base, &rp1_pwm_regmap_config);
+ if (IS_ERR(rp1->regmap))
+ return dev_err_probe(dev, PTR_ERR(rp1->regmap), "Cannot initialize regmap\n");
+
+ rp1->clk = devm_clk_get(dev, NULL);

Could it be devm_clk_get_enabled() to simplify the error handling path as done above with other devm function?
...

+ if (IS_ERR(rp1->clk))
+ return dev_err_probe(dev, PTR_ERR(rp1->clk), "Clock not found\n");
+
+ ret = clk_prepare_enable(rp1->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable clock\n");

... this also saves these 3 lines.

+ rp1->clk_enabled = true;
+
+ ret = devm_clk_rate_exclusive_get(dev, rp1->clk);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to get exclusive rate\n");
+ goto err_disable_clk;
+ }
+
+ clk_rate = clk_get_rate(rp1->clk);
+ if (!clk_rate) {
+ ret = dev_err_probe(dev, -EINVAL, "Failed to get clock rate\n");
+ goto err_disable_clk;
+ }
+ /*
+ * To prevent u64 overflow in period calculations:
+ * mul_u64_u64_div_u64(period_ns, clk_rate, NSEC_PER_SEC)
+ * If clk_rate > 1 GHz, the result can overflow.
+ */
+ if (clk_rate > HZ_PER_GHZ) {
+ ret = dev_err_probe(dev, -EINVAL, "Clock rate > 1 GHz is not supported\n");
+ goto err_disable_clk;
+ }
+ rp1->clk_rate = clk_rate;
+
+ chip->ops = &rp1_pwm_ops;
+ chip->atomic = true;
+
+ platform_set_drvdata(pdev, chip);
+
+ ret = pwmchip_add(chip);

Could it be devm_pwmchip_add() to simplify the error handling path as done above with other devm function?

+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register PWM chip\n");
+ goto err_disable_clk;
+ }
+
+ ret = of_syscon_register_regmap(np, rp1->regmap);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register syscon\n");
+ goto err_remove_chip;
+ }
+
+ return 0;
+
+err_remove_chip:
+ pwmchip_remove(chip);
+err_disable_clk:
+ clk_disable_unprepare(rp1->clk);
+
+ return ret;
+}
...

CJ