| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2010 LaCie |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Simon Guinot <sguinot@lacie.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 21 | 8 | */ |
|---|
| 22 | 9 | |
|---|
| 23 | 10 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 25 | 12 | #include <linux/slab.h> |
|---|
| 26 | 13 | #include <linux/spinlock.h> |
|---|
| 27 | 14 | #include <linux/platform_device.h> |
|---|
| 28 | | -#include <linux/gpio.h> |
|---|
| 29 | | -#include <linux/of_gpio.h> |
|---|
| 15 | +#include <linux/gpio/consumer.h> |
|---|
| 30 | 16 | #include <linux/leds.h> |
|---|
| 31 | | -#include <linux/platform_data/leds-kirkwood-netxbig.h> |
|---|
| 17 | +#include <linux/of.h> |
|---|
| 18 | +#include <linux/of_platform.h> |
|---|
| 19 | + |
|---|
| 20 | +struct netxbig_gpio_ext { |
|---|
| 21 | + struct gpio_desc **addr; |
|---|
| 22 | + int num_addr; |
|---|
| 23 | + struct gpio_desc **data; |
|---|
| 24 | + int num_data; |
|---|
| 25 | + struct gpio_desc *enable; |
|---|
| 26 | +}; |
|---|
| 27 | + |
|---|
| 28 | +enum netxbig_led_mode { |
|---|
| 29 | + NETXBIG_LED_OFF, |
|---|
| 30 | + NETXBIG_LED_ON, |
|---|
| 31 | + NETXBIG_LED_SATA, |
|---|
| 32 | + NETXBIG_LED_TIMER1, |
|---|
| 33 | + NETXBIG_LED_TIMER2, |
|---|
| 34 | + NETXBIG_LED_MODE_NUM, |
|---|
| 35 | +}; |
|---|
| 36 | + |
|---|
| 37 | +#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM |
|---|
| 38 | + |
|---|
| 39 | +struct netxbig_led_timer { |
|---|
| 40 | + unsigned long delay_on; |
|---|
| 41 | + unsigned long delay_off; |
|---|
| 42 | + enum netxbig_led_mode mode; |
|---|
| 43 | +}; |
|---|
| 44 | + |
|---|
| 45 | +struct netxbig_led { |
|---|
| 46 | + const char *name; |
|---|
| 47 | + const char *default_trigger; |
|---|
| 48 | + int mode_addr; |
|---|
| 49 | + int *mode_val; |
|---|
| 50 | + int bright_addr; |
|---|
| 51 | + int bright_max; |
|---|
| 52 | +}; |
|---|
| 53 | + |
|---|
| 54 | +struct netxbig_led_platform_data { |
|---|
| 55 | + struct netxbig_gpio_ext *gpio_ext; |
|---|
| 56 | + struct netxbig_led_timer *timer; |
|---|
| 57 | + int num_timer; |
|---|
| 58 | + struct netxbig_led *leds; |
|---|
| 59 | + int num_leds; |
|---|
| 60 | +}; |
|---|
| 32 | 61 | |
|---|
| 33 | 62 | /* |
|---|
| 34 | 63 | * GPIO extension bus. |
|---|
| .. | .. |
|---|
| 41 | 70 | int pin; |
|---|
| 42 | 71 | |
|---|
| 43 | 72 | for (pin = 0; pin < gpio_ext->num_addr; pin++) |
|---|
| 44 | | - gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1); |
|---|
| 73 | + gpiod_set_value(gpio_ext->addr[pin], (addr >> pin) & 1); |
|---|
| 45 | 74 | } |
|---|
| 46 | 75 | |
|---|
| 47 | 76 | static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data) |
|---|
| .. | .. |
|---|
| 49 | 78 | int pin; |
|---|
| 50 | 79 | |
|---|
| 51 | 80 | for (pin = 0; pin < gpio_ext->num_data; pin++) |
|---|
| 52 | | - gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1); |
|---|
| 81 | + gpiod_set_value(gpio_ext->data[pin], (data >> pin) & 1); |
|---|
| 53 | 82 | } |
|---|
| 54 | 83 | |
|---|
| 55 | 84 | static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext) |
|---|
| 56 | 85 | { |
|---|
| 57 | 86 | /* Enable select is done on the raising edge. */ |
|---|
| 58 | | - gpio_set_value(gpio_ext->enable, 0); |
|---|
| 59 | | - gpio_set_value(gpio_ext->enable, 1); |
|---|
| 87 | + gpiod_set_value(gpio_ext->enable, 0); |
|---|
| 88 | + gpiod_set_value(gpio_ext->enable, 1); |
|---|
| 60 | 89 | } |
|---|
| 61 | 90 | |
|---|
| 62 | 91 | static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext, |
|---|
| .. | .. |
|---|
| 69 | 98 | gpio_ext_set_data(gpio_ext, value); |
|---|
| 70 | 99 | gpio_ext_enable_select(gpio_ext); |
|---|
| 71 | 100 | spin_unlock_irqrestore(&gpio_ext_lock, flags); |
|---|
| 72 | | -} |
|---|
| 73 | | - |
|---|
| 74 | | -static int gpio_ext_init(struct platform_device *pdev, |
|---|
| 75 | | - struct netxbig_gpio_ext *gpio_ext) |
|---|
| 76 | | -{ |
|---|
| 77 | | - int err; |
|---|
| 78 | | - int i; |
|---|
| 79 | | - |
|---|
| 80 | | - if (unlikely(!gpio_ext)) |
|---|
| 81 | | - return -EINVAL; |
|---|
| 82 | | - |
|---|
| 83 | | - /* Configure address GPIOs. */ |
|---|
| 84 | | - for (i = 0; i < gpio_ext->num_addr; i++) { |
|---|
| 85 | | - err = devm_gpio_request_one(&pdev->dev, gpio_ext->addr[i], |
|---|
| 86 | | - GPIOF_OUT_INIT_LOW, |
|---|
| 87 | | - "GPIO extension addr"); |
|---|
| 88 | | - if (err) |
|---|
| 89 | | - return err; |
|---|
| 90 | | - } |
|---|
| 91 | | - /* Configure data GPIOs. */ |
|---|
| 92 | | - for (i = 0; i < gpio_ext->num_data; i++) { |
|---|
| 93 | | - err = devm_gpio_request_one(&pdev->dev, gpio_ext->data[i], |
|---|
| 94 | | - GPIOF_OUT_INIT_LOW, |
|---|
| 95 | | - "GPIO extension data"); |
|---|
| 96 | | - if (err) |
|---|
| 97 | | - return err; |
|---|
| 98 | | - } |
|---|
| 99 | | - /* Configure "enable select" GPIO. */ |
|---|
| 100 | | - err = devm_gpio_request_one(&pdev->dev, gpio_ext->enable, |
|---|
| 101 | | - GPIOF_OUT_INIT_LOW, |
|---|
| 102 | | - "GPIO extension enable"); |
|---|
| 103 | | - if (err) |
|---|
| 104 | | - return err; |
|---|
| 105 | | - |
|---|
| 106 | | - return 0; |
|---|
| 107 | 101 | } |
|---|
| 108 | 102 | |
|---|
| 109 | 103 | /* |
|---|
| .. | .. |
|---|
| 319 | 313 | return devm_led_classdev_register(&pdev->dev, &led_dat->cdev); |
|---|
| 320 | 314 | } |
|---|
| 321 | 315 | |
|---|
| 322 | | -#ifdef CONFIG_OF_GPIO |
|---|
| 323 | | -static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np, |
|---|
| 324 | | - struct netxbig_gpio_ext *gpio_ext) |
|---|
| 316 | +/** |
|---|
| 317 | + * netxbig_gpio_ext_remove() - Clean up GPIO extension data |
|---|
| 318 | + * @data: managed resource data to clean up |
|---|
| 319 | + * |
|---|
| 320 | + * Since we pick GPIO descriptors from another device than the device our |
|---|
| 321 | + * driver is probing to, we need to register a specific callback to free |
|---|
| 322 | + * these up using managed resources. |
|---|
| 323 | + */ |
|---|
| 324 | +static void netxbig_gpio_ext_remove(void *data) |
|---|
| 325 | 325 | { |
|---|
| 326 | | - int *addr, *data; |
|---|
| 326 | + struct netxbig_gpio_ext *gpio_ext = data; |
|---|
| 327 | + int i; |
|---|
| 328 | + |
|---|
| 329 | + for (i = 0; i < gpio_ext->num_addr; i++) |
|---|
| 330 | + gpiod_put(gpio_ext->addr[i]); |
|---|
| 331 | + for (i = 0; i < gpio_ext->num_data; i++) |
|---|
| 332 | + gpiod_put(gpio_ext->data[i]); |
|---|
| 333 | + gpiod_put(gpio_ext->enable); |
|---|
| 334 | +} |
|---|
| 335 | + |
|---|
| 336 | +/** |
|---|
| 337 | + * netxbig_gpio_ext_get() - Obtain GPIO extension device data |
|---|
| 338 | + * @dev: main LED device |
|---|
| 339 | + * @gpio_ext_dev: the GPIO extension device |
|---|
| 340 | + * @gpio_ext: the data structure holding the GPIO extension data |
|---|
| 341 | + * |
|---|
| 342 | + * This function walks the subdevice that only contain GPIO line |
|---|
| 343 | + * handles in the device tree and obtains the GPIO descriptors from that |
|---|
| 344 | + * device. |
|---|
| 345 | + */ |
|---|
| 346 | +static int netxbig_gpio_ext_get(struct device *dev, |
|---|
| 347 | + struct device *gpio_ext_dev, |
|---|
| 348 | + struct netxbig_gpio_ext *gpio_ext) |
|---|
| 349 | +{ |
|---|
| 350 | + struct gpio_desc **addr, **data; |
|---|
| 327 | 351 | int num_addr, num_data; |
|---|
| 352 | + struct gpio_desc *gpiod; |
|---|
| 328 | 353 | int ret; |
|---|
| 329 | 354 | int i; |
|---|
| 330 | 355 | |
|---|
| 331 | | - ret = of_gpio_named_count(np, "addr-gpios"); |
|---|
| 356 | + ret = gpiod_count(gpio_ext_dev, "addr"); |
|---|
| 332 | 357 | if (ret < 0) { |
|---|
| 333 | 358 | dev_err(dev, |
|---|
| 334 | 359 | "Failed to count GPIOs in DT property addr-gpios\n"); |
|---|
| .. | .. |
|---|
| 339 | 364 | if (!addr) |
|---|
| 340 | 365 | return -ENOMEM; |
|---|
| 341 | 366 | |
|---|
| 367 | + /* |
|---|
| 368 | + * We cannot use devm_ managed resources with these GPIO descriptors |
|---|
| 369 | + * since they are associated with the "GPIO extension device" which |
|---|
| 370 | + * does not probe any driver. The device tree parser will however |
|---|
| 371 | + * populate a platform device for it so we can anyway obtain the |
|---|
| 372 | + * GPIO descriptors from the device. |
|---|
| 373 | + */ |
|---|
| 342 | 374 | for (i = 0; i < num_addr; i++) { |
|---|
| 343 | | - ret = of_get_named_gpio(np, "addr-gpios", i); |
|---|
| 344 | | - if (ret < 0) |
|---|
| 345 | | - return ret; |
|---|
| 346 | | - addr[i] = ret; |
|---|
| 375 | + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, |
|---|
| 376 | + GPIOD_OUT_LOW); |
|---|
| 377 | + if (IS_ERR(gpiod)) |
|---|
| 378 | + return PTR_ERR(gpiod); |
|---|
| 379 | + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); |
|---|
| 380 | + addr[i] = gpiod; |
|---|
| 347 | 381 | } |
|---|
| 348 | 382 | gpio_ext->addr = addr; |
|---|
| 349 | 383 | gpio_ext->num_addr = num_addr; |
|---|
| 350 | 384 | |
|---|
| 351 | | - ret = of_gpio_named_count(np, "data-gpios"); |
|---|
| 385 | + ret = gpiod_count(gpio_ext_dev, "data"); |
|---|
| 352 | 386 | if (ret < 0) { |
|---|
| 353 | 387 | dev_err(dev, |
|---|
| 354 | 388 | "Failed to count GPIOs in DT property data-gpios\n"); |
|---|
| .. | .. |
|---|
| 360 | 394 | return -ENOMEM; |
|---|
| 361 | 395 | |
|---|
| 362 | 396 | for (i = 0; i < num_data; i++) { |
|---|
| 363 | | - ret = of_get_named_gpio(np, "data-gpios", i); |
|---|
| 364 | | - if (ret < 0) |
|---|
| 365 | | - return ret; |
|---|
| 366 | | - data[i] = ret; |
|---|
| 397 | + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, |
|---|
| 398 | + GPIOD_OUT_LOW); |
|---|
| 399 | + if (IS_ERR(gpiod)) |
|---|
| 400 | + return PTR_ERR(gpiod); |
|---|
| 401 | + gpiod_set_consumer_name(gpiod, "GPIO extension data"); |
|---|
| 402 | + data[i] = gpiod; |
|---|
| 367 | 403 | } |
|---|
| 368 | 404 | gpio_ext->data = data; |
|---|
| 369 | 405 | gpio_ext->num_data = num_data; |
|---|
| 370 | 406 | |
|---|
| 371 | | - ret = of_get_named_gpio(np, "enable-gpio", 0); |
|---|
| 372 | | - if (ret < 0) { |
|---|
| 407 | + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); |
|---|
| 408 | + if (IS_ERR(gpiod)) { |
|---|
| 373 | 409 | dev_err(dev, |
|---|
| 374 | 410 | "Failed to get GPIO from DT property enable-gpio\n"); |
|---|
| 375 | | - return ret; |
|---|
| 411 | + return PTR_ERR(gpiod); |
|---|
| 376 | 412 | } |
|---|
| 377 | | - gpio_ext->enable = ret; |
|---|
| 413 | + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); |
|---|
| 414 | + gpio_ext->enable = gpiod; |
|---|
| 378 | 415 | |
|---|
| 379 | | - return 0; |
|---|
| 416 | + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); |
|---|
| 380 | 417 | } |
|---|
| 381 | 418 | |
|---|
| 382 | 419 | static int netxbig_leds_get_of_pdata(struct device *dev, |
|---|
| 383 | 420 | struct netxbig_led_platform_data *pdata) |
|---|
| 384 | 421 | { |
|---|
| 385 | | - struct device_node *np = dev->of_node; |
|---|
| 422 | + struct device_node *np = dev_of_node(dev); |
|---|
| 386 | 423 | struct device_node *gpio_ext_np; |
|---|
| 424 | + struct platform_device *gpio_ext_pdev; |
|---|
| 425 | + struct device *gpio_ext_dev; |
|---|
| 387 | 426 | struct device_node *child; |
|---|
| 388 | 427 | struct netxbig_gpio_ext *gpio_ext; |
|---|
| 389 | 428 | struct netxbig_led_timer *timers; |
|---|
| .. | .. |
|---|
| 399 | 438 | dev_err(dev, "Failed to get DT handle gpio-ext\n"); |
|---|
| 400 | 439 | return -EINVAL; |
|---|
| 401 | 440 | } |
|---|
| 441 | + gpio_ext_pdev = of_find_device_by_node(gpio_ext_np); |
|---|
| 442 | + if (!gpio_ext_pdev) { |
|---|
| 443 | + dev_err(dev, "Failed to find platform device for gpio-ext\n"); |
|---|
| 444 | + return -ENODEV; |
|---|
| 445 | + } |
|---|
| 446 | + gpio_ext_dev = &gpio_ext_pdev->dev; |
|---|
| 402 | 447 | |
|---|
| 403 | 448 | gpio_ext = devm_kzalloc(dev, sizeof(*gpio_ext), GFP_KERNEL); |
|---|
| 404 | | - if (!gpio_ext) |
|---|
| 405 | | - return -ENOMEM; |
|---|
| 406 | | - ret = gpio_ext_get_of_pdata(dev, gpio_ext_np, gpio_ext); |
|---|
| 407 | | - if (ret) |
|---|
| 408 | | - return ret; |
|---|
| 449 | + if (!gpio_ext) { |
|---|
| 450 | + of_node_put(gpio_ext_np); |
|---|
| 451 | + ret = -ENOMEM; |
|---|
| 452 | + goto put_device; |
|---|
| 453 | + } |
|---|
| 454 | + ret = netxbig_gpio_ext_get(dev, gpio_ext_dev, gpio_ext); |
|---|
| 409 | 455 | of_node_put(gpio_ext_np); |
|---|
| 456 | + if (ret) |
|---|
| 457 | + goto put_device; |
|---|
| 410 | 458 | pdata->gpio_ext = gpio_ext; |
|---|
| 411 | 459 | |
|---|
| 412 | 460 | /* Timers (optional) */ |
|---|
| 413 | 461 | ret = of_property_count_u32_elems(np, "timers"); |
|---|
| 414 | 462 | if (ret > 0) { |
|---|
| 415 | | - if (ret % 3) |
|---|
| 416 | | - return -EINVAL; |
|---|
| 463 | + if (ret % 3) { |
|---|
| 464 | + ret = -EINVAL; |
|---|
| 465 | + goto put_device; |
|---|
| 466 | + } |
|---|
| 467 | + |
|---|
| 417 | 468 | num_timers = ret / 3; |
|---|
| 418 | 469 | timers = devm_kcalloc(dev, num_timers, sizeof(*timers), |
|---|
| 419 | 470 | GFP_KERNEL); |
|---|
| 420 | | - if (!timers) |
|---|
| 421 | | - return -ENOMEM; |
|---|
| 471 | + if (!timers) { |
|---|
| 472 | + ret = -ENOMEM; |
|---|
| 473 | + goto put_device; |
|---|
| 474 | + } |
|---|
| 422 | 475 | for (i = 0; i < num_timers; i++) { |
|---|
| 423 | 476 | u32 tmp; |
|---|
| 424 | 477 | |
|---|
| 425 | 478 | of_property_read_u32_index(np, "timers", 3 * i, |
|---|
| 426 | 479 | &timers[i].mode); |
|---|
| 427 | | - if (timers[i].mode >= NETXBIG_LED_MODE_NUM) |
|---|
| 428 | | - return -EINVAL; |
|---|
| 480 | + if (timers[i].mode >= NETXBIG_LED_MODE_NUM) { |
|---|
| 481 | + ret = -EINVAL; |
|---|
| 482 | + goto put_device; |
|---|
| 483 | + } |
|---|
| 429 | 484 | of_property_read_u32_index(np, "timers", |
|---|
| 430 | 485 | 3 * i + 1, &tmp); |
|---|
| 431 | 486 | timers[i].delay_on = tmp; |
|---|
| .. | .. |
|---|
| 438 | 493 | } |
|---|
| 439 | 494 | |
|---|
| 440 | 495 | /* LEDs */ |
|---|
| 441 | | - num_leds = of_get_child_count(np); |
|---|
| 496 | + num_leds = of_get_available_child_count(np); |
|---|
| 442 | 497 | if (!num_leds) { |
|---|
| 443 | 498 | dev_err(dev, "No LED subnodes found in DT\n"); |
|---|
| 444 | | - return -ENODEV; |
|---|
| 499 | + ret = -ENODEV; |
|---|
| 500 | + goto put_device; |
|---|
| 445 | 501 | } |
|---|
| 446 | 502 | |
|---|
| 447 | 503 | leds = devm_kcalloc(dev, num_leds, sizeof(*leds), GFP_KERNEL); |
|---|
| 448 | | - if (!leds) |
|---|
| 449 | | - return -ENOMEM; |
|---|
| 504 | + if (!leds) { |
|---|
| 505 | + ret = -ENOMEM; |
|---|
| 506 | + goto put_device; |
|---|
| 507 | + } |
|---|
| 450 | 508 | |
|---|
| 451 | 509 | led = leds; |
|---|
| 452 | | - for_each_child_of_node(np, child) { |
|---|
| 510 | + for_each_available_child_of_node(np, child) { |
|---|
| 453 | 511 | const char *string; |
|---|
| 454 | 512 | int *mode_val; |
|---|
| 455 | 513 | int num_modes; |
|---|
| .. | .. |
|---|
| 527 | 585 | |
|---|
| 528 | 586 | err_node_put: |
|---|
| 529 | 587 | of_node_put(child); |
|---|
| 588 | +put_device: |
|---|
| 589 | + put_device(gpio_ext_dev); |
|---|
| 530 | 590 | return ret; |
|---|
| 531 | 591 | } |
|---|
| 532 | 592 | |
|---|
| .. | .. |
|---|
| 535 | 595 | {}, |
|---|
| 536 | 596 | }; |
|---|
| 537 | 597 | MODULE_DEVICE_TABLE(of, of_netxbig_leds_match); |
|---|
| 538 | | -#else |
|---|
| 539 | | -static inline int |
|---|
| 540 | | -netxbig_leds_get_of_pdata(struct device *dev, |
|---|
| 541 | | - struct netxbig_led_platform_data *pdata) |
|---|
| 542 | | -{ |
|---|
| 543 | | - return -ENODEV; |
|---|
| 544 | | -} |
|---|
| 545 | | -#endif /* CONFIG_OF_GPIO */ |
|---|
| 546 | 598 | |
|---|
| 547 | 599 | static int netxbig_led_probe(struct platform_device *pdev) |
|---|
| 548 | 600 | { |
|---|
| 549 | | - struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev); |
|---|
| 601 | + struct netxbig_led_platform_data *pdata; |
|---|
| 550 | 602 | struct netxbig_led_data *leds_data; |
|---|
| 551 | 603 | int i; |
|---|
| 552 | 604 | int ret; |
|---|
| 553 | 605 | |
|---|
| 554 | | - if (!pdata) { |
|---|
| 555 | | - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
|---|
| 556 | | - if (!pdata) |
|---|
| 557 | | - return -ENOMEM; |
|---|
| 558 | | - ret = netxbig_leds_get_of_pdata(&pdev->dev, pdata); |
|---|
| 559 | | - if (ret) |
|---|
| 560 | | - return ret; |
|---|
| 561 | | - } |
|---|
| 606 | + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
|---|
| 607 | + if (!pdata) |
|---|
| 608 | + return -ENOMEM; |
|---|
| 609 | + ret = netxbig_leds_get_of_pdata(&pdev->dev, pdata); |
|---|
| 610 | + if (ret) |
|---|
| 611 | + return ret; |
|---|
| 562 | 612 | |
|---|
| 563 | 613 | leds_data = devm_kcalloc(&pdev->dev, |
|---|
| 564 | 614 | pdata->num_leds, sizeof(*leds_data), |
|---|
| 565 | 615 | GFP_KERNEL); |
|---|
| 566 | 616 | if (!leds_data) |
|---|
| 567 | 617 | return -ENOMEM; |
|---|
| 568 | | - |
|---|
| 569 | | - ret = gpio_ext_init(pdev, pdata->gpio_ext); |
|---|
| 570 | | - if (ret < 0) |
|---|
| 571 | | - return ret; |
|---|
| 572 | 618 | |
|---|
| 573 | 619 | for (i = 0; i < pdata->num_leds; i++) { |
|---|
| 574 | 620 | ret = create_netxbig_led(pdev, pdata, |
|---|
| .. | .. |
|---|
| 584 | 630 | .probe = netxbig_led_probe, |
|---|
| 585 | 631 | .driver = { |
|---|
| 586 | 632 | .name = "leds-netxbig", |
|---|
| 587 | | - .of_match_table = of_match_ptr(of_netxbig_leds_match), |
|---|
| 633 | + .of_match_table = of_netxbig_leds_match, |
|---|
| 588 | 634 | }, |
|---|
| 589 | 635 | }; |
|---|
| 590 | 636 | |
|---|