Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: sun50i-a100: Switch to device_for_each_child_node_scoped()

Switch to device_for_each_child_node_scoped() to simplify the code by
removing the need for calls to fwnode_handle_put() in the error paths.

This also prevents possible memory leaks if new error paths are added
without the required call to fwnode_handle_put().

The error handling after 'err_put_child' has been moved to the only goto
that jumps to it (second device_for_each_child_node()), and the call to
fwnode_handle_put() has been removed accordingly.

Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://lore.kernel.org/r/20240927-leds_device_for_each_child_node_scoped-v1-15-95c0614b38c8@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Javier Carrasco and committed by
Lee Jones
8cf103de e3456071

+9 -18
+9 -18
drivers/leds/leds-sun50i-a100.c
··· 392 392 struct sun50i_a100_ledc_led *led; 393 393 struct device *dev = &pdev->dev; 394 394 struct sun50i_a100_ledc *priv; 395 - struct fwnode_handle *child; 396 395 struct resource *mem; 397 396 u32 max_addr = 0; 398 397 u32 num_leds = 0; ··· 401 402 * The maximum LED address must be known in sun50i_a100_ledc_resume() before 402 403 * class device registration, so parse and validate the subnodes up front. 403 404 */ 404 - device_for_each_child_node(dev, child) { 405 + device_for_each_child_node_scoped(dev, child) { 405 406 u32 addr, color; 406 407 407 408 ret = fwnode_property_read_u32(child, "reg", &addr); 408 - if (ret || addr >= LEDC_MAX_LEDS) { 409 - fwnode_handle_put(child); 409 + if (ret || addr >= LEDC_MAX_LEDS) 410 410 return dev_err_probe(dev, -EINVAL, "'reg' must be between 0 and %d\n", 411 411 LEDC_MAX_LEDS - 1); 412 - } 413 412 414 413 ret = fwnode_property_read_u32(child, "color", &color); 415 - if (ret || color != LED_COLOR_ID_RGB) { 416 - fwnode_handle_put(child); 414 + if (ret || color != LED_COLOR_ID_RGB) 417 415 return dev_err_probe(dev, -EINVAL, "'color' must be LED_COLOR_ID_RGB\n"); 418 - } 419 416 420 417 max_addr = max(max_addr, addr); 421 418 num_leds++; ··· 497 502 return ret; 498 503 499 504 led = priv->leds; 500 - device_for_each_child_node(dev, child) { 505 + device_for_each_child_node_scoped(dev, child) { 501 506 struct led_classdev *cdev; 502 507 503 508 /* The node was already validated above. */ ··· 522 527 ret = led_classdev_multicolor_register_ext(dev, &led->mc_cdev, &init_data); 523 528 if (ret) { 524 529 dev_err_probe(dev, ret, "Failed to register multicolor LED %u", led->addr); 525 - goto err_put_child; 530 + while (led-- > priv->leds) 531 + led_classdev_multicolor_unregister(&led->mc_cdev); 532 + sun50i_a100_ledc_suspend(&pdev->dev); 533 + 534 + return ret; 526 535 } 527 536 528 537 led++; ··· 535 536 dev_info(dev, "Registered %u LEDs\n", num_leds); 536 537 537 538 return 0; 538 - 539 - err_put_child: 540 - fwnode_handle_put(child); 541 - while (led-- > priv->leds) 542 - led_classdev_multicolor_unregister(&led->mc_cdev); 543 - sun50i_a100_ledc_suspend(&pdev->dev); 544 - 545 - return ret; 546 539 } 547 540 548 541 static void sun50i_a100_ledc_remove(struct platform_device *pdev)