| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for ISSI IS31FL32xx family of I2C LED controllers |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2015 Allworx Corp. |
|---|
| 5 | | - * |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 6 | * |
|---|
| 11 | 7 | * Datasheets: |
|---|
| 12 | 8 | * http://www.issi.com/US/product-analog-fxled-driver.shtml |
|---|
| .. | .. |
|---|
| 48 | 44 | const struct is31fl32xx_chipdef *cdef; |
|---|
| 49 | 45 | struct i2c_client *client; |
|---|
| 50 | 46 | unsigned int num_leds; |
|---|
| 51 | | - struct is31fl32xx_led_data leds[0]; |
|---|
| 47 | + struct is31fl32xx_led_data leds[]; |
|---|
| 52 | 48 | }; |
|---|
| 53 | 49 | |
|---|
| 54 | 50 | /** |
|---|
| .. | .. |
|---|
| 328 | 324 | return 0; |
|---|
| 329 | 325 | } |
|---|
| 330 | 326 | |
|---|
| 331 | | -static inline size_t sizeof_is31fl32xx_priv(int num_leds) |
|---|
| 332 | | -{ |
|---|
| 333 | | - return sizeof(struct is31fl32xx_priv) + |
|---|
| 334 | | - (sizeof(struct is31fl32xx_led_data) * num_leds); |
|---|
| 335 | | -} |
|---|
| 336 | | - |
|---|
| 337 | 327 | static int is31fl32xx_parse_child_dt(const struct device *dev, |
|---|
| 338 | 328 | const struct device_node *child, |
|---|
| 339 | 329 | struct is31fl32xx_led_data *led_data) |
|---|
| .. | .. |
|---|
| 341 | 331 | struct led_classdev *cdev = &led_data->cdev; |
|---|
| 342 | 332 | int ret = 0; |
|---|
| 343 | 333 | u32 reg; |
|---|
| 344 | | - |
|---|
| 345 | | - if (of_property_read_string(child, "label", &cdev->name)) |
|---|
| 346 | | - cdev->name = child->name; |
|---|
| 347 | 334 | |
|---|
| 348 | 335 | ret = of_property_read_u32(child, "reg", ®); |
|---|
| 349 | 336 | if (ret || reg < 1 || reg > led_data->priv->cdef->channels) { |
|---|
| .. | .. |
|---|
| 353 | 340 | return -EINVAL; |
|---|
| 354 | 341 | } |
|---|
| 355 | 342 | led_data->channel = reg; |
|---|
| 356 | | - |
|---|
| 357 | | - of_property_read_string(child, "linux,default-trigger", |
|---|
| 358 | | - &cdev->default_trigger); |
|---|
| 359 | 343 | |
|---|
| 360 | 344 | cdev->brightness_set_blocking = is31fl32xx_brightness_set; |
|---|
| 361 | 345 | |
|---|
| .. | .. |
|---|
| 382 | 366 | struct device_node *child; |
|---|
| 383 | 367 | int ret = 0; |
|---|
| 384 | 368 | |
|---|
| 385 | | - for_each_child_of_node(dev->of_node, child) { |
|---|
| 369 | + for_each_available_child_of_node(dev_of_node(dev), child) { |
|---|
| 370 | + struct led_init_data init_data = {}; |
|---|
| 386 | 371 | struct is31fl32xx_led_data *led_data = |
|---|
| 387 | 372 | &priv->leds[priv->num_leds]; |
|---|
| 388 | 373 | const struct is31fl32xx_led_data *other_led_data; |
|---|
| .. | .. |
|---|
| 398 | 383 | led_data->channel); |
|---|
| 399 | 384 | if (other_led_data) { |
|---|
| 400 | 385 | dev_err(dev, |
|---|
| 401 | | - "%s and %s both attempting to use channel %d\n", |
|---|
| 402 | | - led_data->cdev.name, |
|---|
| 403 | | - other_led_data->cdev.name, |
|---|
| 404 | | - led_data->channel); |
|---|
| 386 | + "Node %pOF 'reg' conflicts with another LED\n", |
|---|
| 387 | + child); |
|---|
| 388 | + ret = -EINVAL; |
|---|
| 405 | 389 | goto err; |
|---|
| 406 | 390 | } |
|---|
| 407 | 391 | |
|---|
| 408 | | - ret = devm_led_classdev_register(dev, &led_data->cdev); |
|---|
| 392 | + init_data.fwnode = of_fwnode_handle(child); |
|---|
| 393 | + |
|---|
| 394 | + ret = devm_led_classdev_register_ext(dev, &led_data->cdev, |
|---|
| 395 | + &init_data); |
|---|
| 409 | 396 | if (ret) { |
|---|
| 410 | | - dev_err(dev, "failed to register PWM led for %s: %d\n", |
|---|
| 411 | | - led_data->cdev.name, ret); |
|---|
| 397 | + dev_err(dev, "Failed to register LED for %pOF: %d\n", |
|---|
| 398 | + child, ret); |
|---|
| 412 | 399 | goto err; |
|---|
| 413 | 400 | } |
|---|
| 414 | 401 | |
|---|
| .. | .. |
|---|
| 438 | 425 | const struct i2c_device_id *id) |
|---|
| 439 | 426 | { |
|---|
| 440 | 427 | const struct is31fl32xx_chipdef *cdef; |
|---|
| 441 | | - const struct of_device_id *of_dev_id; |
|---|
| 442 | 428 | struct device *dev = &client->dev; |
|---|
| 443 | 429 | struct is31fl32xx_priv *priv; |
|---|
| 444 | 430 | int count; |
|---|
| 445 | 431 | int ret = 0; |
|---|
| 446 | 432 | |
|---|
| 447 | | - of_dev_id = of_match_device(of_is31fl32xx_match, dev); |
|---|
| 448 | | - if (!of_dev_id) |
|---|
| 449 | | - return -EINVAL; |
|---|
| 433 | + cdef = device_get_match_data(dev); |
|---|
| 450 | 434 | |
|---|
| 451 | | - cdef = of_dev_id->data; |
|---|
| 452 | | - |
|---|
| 453 | | - count = of_get_child_count(dev->of_node); |
|---|
| 435 | + count = of_get_available_child_count(dev_of_node(dev)); |
|---|
| 454 | 436 | if (!count) |
|---|
| 455 | 437 | return -EINVAL; |
|---|
| 456 | 438 | |
|---|
| 457 | | - priv = devm_kzalloc(dev, sizeof_is31fl32xx_priv(count), |
|---|
| 439 | + priv = devm_kzalloc(dev, struct_size(priv, leds, count), |
|---|
| 458 | 440 | GFP_KERNEL); |
|---|
| 459 | 441 | if (!priv) |
|---|
| 460 | 442 | return -ENOMEM; |
|---|