diff options
| -rw-r--r-- | drivers/gpio/gpiolib.c | 98 |
1 files changed, 67 insertions, 31 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5ca7c9aa4fab..b747c76fd2b1 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -68,6 +68,7 @@ LIST_HEAD(gpio_devices); | |||
| 68 | static void gpiochip_free_hogs(struct gpio_chip *chip); | 68 | static void gpiochip_free_hogs(struct gpio_chip *chip); |
| 69 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); | 69 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); |
| 70 | 70 | ||
| 71 | static bool gpiolib_initialized; | ||
| 71 | 72 | ||
| 72 | static inline void desc_set_label(struct gpio_desc *d, const char *label) | 73 | static inline void desc_set_label(struct gpio_desc *d, const char *label) |
| 73 | { | 74 | { |
| @@ -445,6 +446,58 @@ static void gpiodevice_release(struct device *dev) | |||
| 445 | kfree(gdev); | 446 | kfree(gdev); |
| 446 | } | 447 | } |
| 447 | 448 | ||
| 449 | static int gpiochip_setup_dev(struct gpio_device *gdev) | ||
| 450 | { | ||
| 451 | int status; | ||
| 452 | |||
| 453 | cdev_init(&gdev->chrdev, &gpio_fileops); | ||
| 454 | gdev->chrdev.owner = THIS_MODULE; | ||
| 455 | gdev->chrdev.kobj.parent = &gdev->dev.kobj; | ||
| 456 | gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id); | ||
| 457 | status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1); | ||
| 458 | if (status < 0) | ||
| 459 | chip_warn(gdev->chip, "failed to add char device %d:%d\n", | ||
| 460 | MAJOR(gpio_devt), gdev->id); | ||
| 461 | else | ||
| 462 | chip_dbg(gdev->chip, "added GPIO chardev (%d:%d)\n", | ||
| 463 | MAJOR(gpio_devt), gdev->id); | ||
| 464 | status = device_add(&gdev->dev); | ||
| 465 | if (status) | ||
| 466 | goto err_remove_chardev; | ||
| 467 | |||
| 468 | status = gpiochip_sysfs_register(gdev); | ||
| 469 | if (status) | ||
| 470 | goto err_remove_device; | ||
| 471 | |||
| 472 | /* From this point, the .release() function cleans up gpio_device */ | ||
| 473 | gdev->dev.release = gpiodevice_release; | ||
| 474 | get_device(&gdev->dev); | ||
| 475 | pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n", | ||
| 476 | __func__, gdev->base, gdev->base + gdev->ngpio - 1, | ||
| 477 | dev_name(&gdev->dev), gdev->chip->label ? : "generic"); | ||
| 478 | |||
| 479 | return 0; | ||
| 480 | |||
| 481 | err_remove_device: | ||
| 482 | device_del(&gdev->dev); | ||
| 483 | err_remove_chardev: | ||
| 484 | cdev_del(&gdev->chrdev); | ||
| 485 | return status; | ||
| 486 | } | ||
| 487 | |||
| 488 | static void gpiochip_setup_devs(void) | ||
| 489 | { | ||
| 490 | struct gpio_device *gdev; | ||
| 491 | int err; | ||
| 492 | |||
| 493 | list_for_each_entry(gdev, &gpio_devices, list) { | ||
| 494 | err = gpiochip_setup_dev(gdev); | ||
| 495 | if (err) | ||
| 496 | pr_err("%s: Failed to initialize gpio device (%d)\n", | ||
| 497 | dev_name(&gdev->dev), err); | ||
| 498 | } | ||
| 499 | } | ||
| 500 | |||
| 448 | /** | 501 | /** |
| 449 | * gpiochip_add_data() - register a gpio_chip | 502 | * gpiochip_add_data() - register a gpio_chip |
| 450 | * @chip: the chip to register, with chip->base initialized | 503 | * @chip: the chip to register, with chip->base initialized |
| @@ -459,6 +512,9 @@ static void gpiodevice_release(struct device *dev) | |||
| 459 | * the gpio framework's arch_initcall(). Otherwise sysfs initialization | 512 | * the gpio framework's arch_initcall(). Otherwise sysfs initialization |
| 460 | * for GPIOs will fail rudely. | 513 | * for GPIOs will fail rudely. |
| 461 | * | 514 | * |
| 515 | * gpiochip_add_data() must only be called after gpiolib initialization, | ||
| 516 | * ie after core_initcall(). | ||
| 517 | * | ||
| 462 | * If chip->base is negative, this requests dynamic assignment of | 518 | * If chip->base is negative, this requests dynamic assignment of |
| 463 | * a range of valid GPIOs. | 519 | * a range of valid GPIOs. |
| 464 | */ | 520 | */ |
| @@ -515,7 +571,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) | |||
| 515 | if (chip->ngpio == 0) { | 571 | if (chip->ngpio == 0) { |
| 516 | chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); | 572 | chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); |
| 517 | status = -EINVAL; | 573 | status = -EINVAL; |
| 518 | goto err_free_gdev; | 574 | goto err_free_descs; |
| 519 | } | 575 | } |
| 520 | 576 | ||
| 521 | if (chip->label) | 577 | if (chip->label) |
| @@ -597,39 +653,16 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) | |||
| 597 | * we get a device node entry in sysfs under | 653 | * we get a device node entry in sysfs under |
| 598 | * /sys/bus/gpio/devices/gpiochipN/dev that can be used for | 654 | * /sys/bus/gpio/devices/gpiochipN/dev that can be used for |
| 599 | * coldplug of device nodes and other udev business. | 655 | * coldplug of device nodes and other udev business. |
| 656 | * We can do this only if gpiolib has been initialized. | ||
| 657 | * Otherwise, defer until later. | ||
| 600 | */ | 658 | */ |
| 601 | cdev_init(&gdev->chrdev, &gpio_fileops); | 659 | if (gpiolib_initialized) { |
| 602 | gdev->chrdev.owner = THIS_MODULE; | 660 | status = gpiochip_setup_dev(gdev); |
| 603 | gdev->chrdev.kobj.parent = &gdev->dev.kobj; | 661 | if (status) |
| 604 | gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id); | 662 | goto err_remove_chip; |
| 605 | status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1); | 663 | } |
| 606 | if (status < 0) | ||
| 607 | chip_warn(chip, "failed to add char device %d:%d\n", | ||
| 608 | MAJOR(gpio_devt), gdev->id); | ||
| 609 | else | ||
| 610 | chip_dbg(chip, "added GPIO chardev (%d:%d)\n", | ||
| 611 | MAJOR(gpio_devt), gdev->id); | ||
| 612 | status = device_add(&gdev->dev); | ||
| 613 | if (status) | ||
| 614 | goto err_remove_chardev; | ||
| 615 | |||
| 616 | status = gpiochip_sysfs_register(gdev); | ||
| 617 | if (status) | ||
| 618 | goto err_remove_device; | ||
| 619 | |||
| 620 | /* From this point, the .release() function cleans up gpio_device */ | ||
| 621 | gdev->dev.release = gpiodevice_release; | ||
| 622 | get_device(&gdev->dev); | ||
| 623 | pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n", | ||
| 624 | __func__, gdev->base, gdev->base + gdev->ngpio - 1, | ||
| 625 | dev_name(&gdev->dev), chip->label ? : "generic"); | ||
| 626 | |||
| 627 | return 0; | 664 | return 0; |
| 628 | 665 | ||
| 629 | err_remove_device: | ||
| 630 | device_del(&gdev->dev); | ||
| 631 | err_remove_chardev: | ||
| 632 | cdev_del(&gdev->chrdev); | ||
| 633 | err_remove_chip: | 666 | err_remove_chip: |
| 634 | acpi_gpiochip_remove(chip); | 667 | acpi_gpiochip_remove(chip); |
| 635 | gpiochip_free_hogs(chip); | 668 | gpiochip_free_hogs(chip); |
| @@ -2842,6 +2875,9 @@ static int __init gpiolib_dev_init(void) | |||
| 2842 | if (ret < 0) { | 2875 | if (ret < 0) { |
| 2843 | pr_err("gpiolib: failed to allocate char dev region\n"); | 2876 | pr_err("gpiolib: failed to allocate char dev region\n"); |
| 2844 | bus_unregister(&gpio_bus_type); | 2877 | bus_unregister(&gpio_bus_type); |
| 2878 | } else { | ||
| 2879 | gpiolib_initialized = true; | ||
| 2880 | gpiochip_setup_devs(); | ||
| 2845 | } | 2881 | } |
| 2846 | return ret; | 2882 | return ret; |
| 2847 | } | 2883 | } |
