| .. | .. |
|---|
| 9 | 9 | #include <linux/kernel.h> |
|---|
| 10 | 10 | #include <linux/module.h> |
|---|
| 11 | 11 | #include <linux/slab.h> |
|---|
| 12 | | -#include <linux/gpio.h> |
|---|
| 13 | 12 | #include <linux/irq.h> |
|---|
| 14 | 13 | #include <linux/irqdomain.h> |
|---|
| 14 | +#include <linux/gpio/driver.h> |
|---|
| 15 | 15 | #include <linux/mutex.h> |
|---|
| 16 | +#include <linux/greybus.h> |
|---|
| 16 | 17 | |
|---|
| 17 | | -#include "greybus.h" |
|---|
| 18 | 18 | #include "gbphy.h" |
|---|
| 19 | 19 | |
|---|
| 20 | 20 | struct gb_gpio_line { |
|---|
| .. | .. |
|---|
| 39 | 39 | |
|---|
| 40 | 40 | struct gpio_chip chip; |
|---|
| 41 | 41 | struct irq_chip irqc; |
|---|
| 42 | | - struct irq_chip *irqchip; |
|---|
| 43 | | - struct irq_domain *irqdomain; |
|---|
| 44 | | - unsigned int irq_base; |
|---|
| 45 | | - irq_flow_handler_t irq_handler; |
|---|
| 46 | | - unsigned int irq_default_type; |
|---|
| 47 | 42 | struct mutex irq_lock; |
|---|
| 48 | 43 | }; |
|---|
| 49 | 44 | #define gpio_chip_to_gb_gpio_controller(chip) \ |
|---|
| .. | .. |
|---|
| 74 | 69 | |
|---|
| 75 | 70 | request.which = which; |
|---|
| 76 | 71 | ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE, |
|---|
| 77 | | - &request, sizeof(request), NULL, 0); |
|---|
| 72 | + &request, sizeof(request), NULL, 0); |
|---|
| 78 | 73 | if (ret) { |
|---|
| 79 | 74 | gbphy_runtime_put_autosuspend(gbphy_dev); |
|---|
| 80 | 75 | return ret; |
|---|
| .. | .. |
|---|
| 86 | 81 | } |
|---|
| 87 | 82 | |
|---|
| 88 | 83 | static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc, |
|---|
| 89 | | - u8 which) |
|---|
| 84 | + u8 which) |
|---|
| 90 | 85 | { |
|---|
| 91 | 86 | struct gbphy_device *gbphy_dev = ggc->gbphy_dev; |
|---|
| 92 | 87 | struct device *dev = &gbphy_dev->dev; |
|---|
| .. | .. |
|---|
| 95 | 90 | |
|---|
| 96 | 91 | request.which = which; |
|---|
| 97 | 92 | ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DEACTIVATE, |
|---|
| 98 | | - &request, sizeof(request), NULL, 0); |
|---|
| 93 | + &request, sizeof(request), NULL, 0); |
|---|
| 99 | 94 | if (ret) { |
|---|
| 100 | 95 | dev_err(dev, "failed to deactivate gpio %u\n", which); |
|---|
| 101 | 96 | goto out_pm_put; |
|---|
| .. | .. |
|---|
| 108 | 103 | } |
|---|
| 109 | 104 | |
|---|
| 110 | 105 | static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc, |
|---|
| 111 | | - u8 which) |
|---|
| 106 | + u8 which) |
|---|
| 112 | 107 | { |
|---|
| 113 | 108 | struct device *dev = &ggc->gbphy_dev->dev; |
|---|
| 114 | 109 | struct gb_gpio_get_direction_request request; |
|---|
| .. | .. |
|---|
| 133 | 128 | } |
|---|
| 134 | 129 | |
|---|
| 135 | 130 | static int gb_gpio_direction_in_operation(struct gb_gpio_controller *ggc, |
|---|
| 136 | | - u8 which) |
|---|
| 131 | + u8 which) |
|---|
| 137 | 132 | { |
|---|
| 138 | 133 | struct gb_gpio_direction_in_request request; |
|---|
| 139 | 134 | int ret; |
|---|
| .. | .. |
|---|
| 147 | 142 | } |
|---|
| 148 | 143 | |
|---|
| 149 | 144 | static int gb_gpio_direction_out_operation(struct gb_gpio_controller *ggc, |
|---|
| 150 | | - u8 which, bool value_high) |
|---|
| 145 | + u8 which, bool value_high) |
|---|
| 151 | 146 | { |
|---|
| 152 | 147 | struct gb_gpio_direction_out_request request; |
|---|
| 153 | 148 | int ret; |
|---|
| .. | .. |
|---|
| 162 | 157 | } |
|---|
| 163 | 158 | |
|---|
| 164 | 159 | static int gb_gpio_get_value_operation(struct gb_gpio_controller *ggc, |
|---|
| 165 | | - u8 which) |
|---|
| 160 | + u8 which) |
|---|
| 166 | 161 | { |
|---|
| 167 | 162 | struct device *dev = &ggc->gbphy_dev->dev; |
|---|
| 168 | 163 | struct gb_gpio_get_value_request request; |
|---|
| .. | .. |
|---|
| 214 | 209 | } |
|---|
| 215 | 210 | |
|---|
| 216 | 211 | static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *ggc, |
|---|
| 217 | | - u8 which, u16 debounce_usec) |
|---|
| 212 | + u8 which, u16 debounce_usec) |
|---|
| 218 | 213 | { |
|---|
| 219 | 214 | struct gb_gpio_set_debounce_request request; |
|---|
| 220 | 215 | int ret; |
|---|
| .. | .. |
|---|
| 257 | 252 | } |
|---|
| 258 | 253 | |
|---|
| 259 | 254 | static void _gb_gpio_irq_set_type(struct gb_gpio_controller *ggc, |
|---|
| 260 | | - u8 hwirq, u8 type) |
|---|
| 255 | + u8 hwirq, u8 type) |
|---|
| 261 | 256 | { |
|---|
| 262 | 257 | struct device *dev = &ggc->gbphy_dev->dev; |
|---|
| 263 | 258 | struct gb_gpio_irq_type_request request; |
|---|
| .. | .. |
|---|
| 369 | 364 | struct gb_message *request; |
|---|
| 370 | 365 | struct gb_gpio_irq_event_request *event; |
|---|
| 371 | 366 | u8 type = op->type; |
|---|
| 372 | | - int irq; |
|---|
| 373 | | - struct irq_desc *desc; |
|---|
| 367 | + int irq, ret; |
|---|
| 374 | 368 | |
|---|
| 375 | 369 | if (type != GB_GPIO_TYPE_IRQ_EVENT) { |
|---|
| 376 | 370 | dev_err(dev, "unsupported unsolicited request: %u\n", type); |
|---|
| .. | .. |
|---|
| 391 | 385 | return -EINVAL; |
|---|
| 392 | 386 | } |
|---|
| 393 | 387 | |
|---|
| 394 | | - irq = irq_find_mapping(ggc->irqdomain, event->which); |
|---|
| 388 | + irq = irq_find_mapping(ggc->chip.irq.domain, event->which); |
|---|
| 395 | 389 | if (!irq) { |
|---|
| 396 | 390 | dev_err(dev, "failed to find IRQ\n"); |
|---|
| 397 | 391 | return -EINVAL; |
|---|
| 398 | 392 | } |
|---|
| 399 | | - desc = irq_to_desc(irq); |
|---|
| 400 | | - if (!desc) { |
|---|
| 401 | | - dev_err(dev, "failed to look up irq\n"); |
|---|
| 402 | | - return -EINVAL; |
|---|
| 403 | | - } |
|---|
| 404 | 393 | |
|---|
| 405 | 394 | local_irq_disable(); |
|---|
| 406 | | - generic_handle_irq_desc(desc); |
|---|
| 395 | + ret = generic_handle_irq(irq); |
|---|
| 407 | 396 | local_irq_enable(); |
|---|
| 408 | 397 | |
|---|
| 409 | | - return 0; |
|---|
| 398 | + if (ret) |
|---|
| 399 | + dev_err(dev, "failed to invoke irq handler\n"); |
|---|
| 400 | + |
|---|
| 401 | + return ret; |
|---|
| 410 | 402 | } |
|---|
| 411 | 403 | |
|---|
| 412 | 404 | static int gb_gpio_request(struct gpio_chip *chip, unsigned int offset) |
|---|
| .. | .. |
|---|
| 506 | 498 | return ret; |
|---|
| 507 | 499 | } |
|---|
| 508 | 500 | |
|---|
| 509 | | -/** |
|---|
| 510 | | - * gb_gpio_irq_map() - maps an IRQ into a GB gpio irqchip |
|---|
| 511 | | - * @d: the irqdomain used by this irqchip |
|---|
| 512 | | - * @irq: the global irq number used by this GB gpio irqchip irq |
|---|
| 513 | | - * @hwirq: the local IRQ/GPIO line offset on this GB gpio |
|---|
| 514 | | - * |
|---|
| 515 | | - * This function will set up the mapping for a certain IRQ line on a |
|---|
| 516 | | - * GB gpio by assigning the GB gpio as chip data, and using the irqchip |
|---|
| 517 | | - * stored inside the GB gpio. |
|---|
| 518 | | - */ |
|---|
| 519 | | -static int gb_gpio_irq_map(struct irq_domain *domain, unsigned int irq, |
|---|
| 520 | | - irq_hw_number_t hwirq) |
|---|
| 521 | | -{ |
|---|
| 522 | | - struct gpio_chip *chip = domain->host_data; |
|---|
| 523 | | - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); |
|---|
| 524 | | - |
|---|
| 525 | | - irq_set_chip_data(irq, ggc); |
|---|
| 526 | | - irq_set_chip_and_handler(irq, ggc->irqchip, ggc->irq_handler); |
|---|
| 527 | | - irq_set_noprobe(irq); |
|---|
| 528 | | - /* |
|---|
| 529 | | - * No set-up of the hardware will happen if IRQ_TYPE_NONE |
|---|
| 530 | | - * is passed as default type. |
|---|
| 531 | | - */ |
|---|
| 532 | | - if (ggc->irq_default_type != IRQ_TYPE_NONE) |
|---|
| 533 | | - irq_set_irq_type(irq, ggc->irq_default_type); |
|---|
| 534 | | - |
|---|
| 535 | | - return 0; |
|---|
| 536 | | -} |
|---|
| 537 | | - |
|---|
| 538 | | -static void gb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) |
|---|
| 539 | | -{ |
|---|
| 540 | | - irq_set_chip_and_handler(irq, NULL, NULL); |
|---|
| 541 | | - irq_set_chip_data(irq, NULL); |
|---|
| 542 | | -} |
|---|
| 543 | | - |
|---|
| 544 | | -static const struct irq_domain_ops gb_gpio_domain_ops = { |
|---|
| 545 | | - .map = gb_gpio_irq_map, |
|---|
| 546 | | - .unmap = gb_gpio_irq_unmap, |
|---|
| 547 | | -}; |
|---|
| 548 | | - |
|---|
| 549 | | -/** |
|---|
| 550 | | - * gb_gpio_irqchip_remove() - removes an irqchip added to a gb_gpio_controller |
|---|
| 551 | | - * @ggc: the gb_gpio_controller to remove the irqchip from |
|---|
| 552 | | - * |
|---|
| 553 | | - * This is called only from gb_gpio_remove() |
|---|
| 554 | | - */ |
|---|
| 555 | | -static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc) |
|---|
| 556 | | -{ |
|---|
| 557 | | - unsigned int offset; |
|---|
| 558 | | - |
|---|
| 559 | | - /* Remove all IRQ mappings and delete the domain */ |
|---|
| 560 | | - if (ggc->irqdomain) { |
|---|
| 561 | | - for (offset = 0; offset < (ggc->line_max + 1); offset++) |
|---|
| 562 | | - irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, |
|---|
| 563 | | - offset)); |
|---|
| 564 | | - irq_domain_remove(ggc->irqdomain); |
|---|
| 565 | | - } |
|---|
| 566 | | - |
|---|
| 567 | | - if (ggc->irqchip) |
|---|
| 568 | | - ggc->irqchip = NULL; |
|---|
| 569 | | -} |
|---|
| 570 | | - |
|---|
| 571 | | -/** |
|---|
| 572 | | - * gb_gpio_irqchip_add() - adds an irqchip to a gpio chip |
|---|
| 573 | | - * @chip: the gpio chip to add the irqchip to |
|---|
| 574 | | - * @irqchip: the irqchip to add to the adapter |
|---|
| 575 | | - * @first_irq: if not dynamically assigned, the base (first) IRQ to |
|---|
| 576 | | - * allocate gpio irqs from |
|---|
| 577 | | - * @handler: the irq handler to use (often a predefined irq core function) |
|---|
| 578 | | - * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE |
|---|
| 579 | | - * to have the core avoid setting up any default type in the hardware. |
|---|
| 580 | | - * |
|---|
| 581 | | - * This function closely associates a certain irqchip with a certain |
|---|
| 582 | | - * gpio chip, providing an irq domain to translate the local IRQs to |
|---|
| 583 | | - * global irqs, and making sure that the gpio chip |
|---|
| 584 | | - * is passed as chip data to all related functions. Driver callbacks |
|---|
| 585 | | - * need to use container_of() to get their local state containers back |
|---|
| 586 | | - * from the gpio chip passed as chip data. An irqdomain will be stored |
|---|
| 587 | | - * in the gpio chip that shall be used by the driver to handle IRQ number |
|---|
| 588 | | - * translation. The gpio chip will need to be initialized and registered |
|---|
| 589 | | - * before calling this function. |
|---|
| 590 | | - */ |
|---|
| 591 | | -static int gb_gpio_irqchip_add(struct gpio_chip *chip, |
|---|
| 592 | | - struct irq_chip *irqchip, |
|---|
| 593 | | - unsigned int first_irq, |
|---|
| 594 | | - irq_flow_handler_t handler, |
|---|
| 595 | | - unsigned int type) |
|---|
| 596 | | -{ |
|---|
| 597 | | - struct gb_gpio_controller *ggc; |
|---|
| 598 | | - unsigned int offset; |
|---|
| 599 | | - unsigned int irq_base; |
|---|
| 600 | | - |
|---|
| 601 | | - if (!chip || !irqchip) |
|---|
| 602 | | - return -EINVAL; |
|---|
| 603 | | - |
|---|
| 604 | | - ggc = gpio_chip_to_gb_gpio_controller(chip); |
|---|
| 605 | | - |
|---|
| 606 | | - ggc->irqchip = irqchip; |
|---|
| 607 | | - ggc->irq_handler = handler; |
|---|
| 608 | | - ggc->irq_default_type = type; |
|---|
| 609 | | - ggc->irqdomain = irq_domain_add_simple(NULL, |
|---|
| 610 | | - ggc->line_max + 1, first_irq, |
|---|
| 611 | | - &gb_gpio_domain_ops, chip); |
|---|
| 612 | | - if (!ggc->irqdomain) { |
|---|
| 613 | | - ggc->irqchip = NULL; |
|---|
| 614 | | - return -EINVAL; |
|---|
| 615 | | - } |
|---|
| 616 | | - |
|---|
| 617 | | - /* |
|---|
| 618 | | - * Prepare the mapping since the irqchip shall be orthogonal to |
|---|
| 619 | | - * any gpio calls. If the first_irq was zero, this is |
|---|
| 620 | | - * necessary to allocate descriptors for all IRQs. |
|---|
| 621 | | - */ |
|---|
| 622 | | - for (offset = 0; offset < (ggc->line_max + 1); offset++) { |
|---|
| 623 | | - irq_base = irq_create_mapping(ggc->irqdomain, offset); |
|---|
| 624 | | - if (offset == 0) |
|---|
| 625 | | - ggc->irq_base = irq_base; |
|---|
| 626 | | - } |
|---|
| 627 | | - |
|---|
| 628 | | - return 0; |
|---|
| 629 | | -} |
|---|
| 630 | | - |
|---|
| 631 | | -static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) |
|---|
| 632 | | -{ |
|---|
| 633 | | - struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip); |
|---|
| 634 | | - |
|---|
| 635 | | - return irq_find_mapping(ggc->irqdomain, offset); |
|---|
| 636 | | -} |
|---|
| 637 | | - |
|---|
| 638 | 501 | static int gb_gpio_probe(struct gbphy_device *gbphy_dev, |
|---|
| 639 | 502 | const struct gbphy_device_id *id) |
|---|
| 640 | 503 | { |
|---|
| 641 | 504 | struct gb_connection *connection; |
|---|
| 642 | 505 | struct gb_gpio_controller *ggc; |
|---|
| 643 | 506 | struct gpio_chip *gpio; |
|---|
| 507 | + struct gpio_irq_chip *girq; |
|---|
| 644 | 508 | struct irq_chip *irqc; |
|---|
| 645 | 509 | int ret; |
|---|
| 646 | 510 | |
|---|
| .. | .. |
|---|
| 648 | 512 | if (!ggc) |
|---|
| 649 | 513 | return -ENOMEM; |
|---|
| 650 | 514 | |
|---|
| 651 | | - connection = gb_connection_create(gbphy_dev->bundle, |
|---|
| 652 | | - le16_to_cpu(gbphy_dev->cport_desc->id), |
|---|
| 653 | | - gb_gpio_request_handler); |
|---|
| 515 | + connection = |
|---|
| 516 | + gb_connection_create(gbphy_dev->bundle, |
|---|
| 517 | + le16_to_cpu(gbphy_dev->cport_desc->id), |
|---|
| 518 | + gb_gpio_request_handler); |
|---|
| 654 | 519 | if (IS_ERR(connection)) { |
|---|
| 655 | 520 | ret = PTR_ERR(connection); |
|---|
| 656 | 521 | goto exit_ggc_free; |
|---|
| .. | .. |
|---|
| 693 | 558 | gpio->get = gb_gpio_get; |
|---|
| 694 | 559 | gpio->set = gb_gpio_set; |
|---|
| 695 | 560 | gpio->set_config = gb_gpio_set_config; |
|---|
| 696 | | - gpio->to_irq = gb_gpio_to_irq; |
|---|
| 697 | 561 | gpio->base = -1; /* Allocate base dynamically */ |
|---|
| 698 | 562 | gpio->ngpio = ggc->line_max + 1; |
|---|
| 699 | 563 | gpio->can_sleep = true; |
|---|
| 564 | + |
|---|
| 565 | + girq = &gpio->irq; |
|---|
| 566 | + girq->chip = irqc; |
|---|
| 567 | + /* The event comes from the outside so no parent handler */ |
|---|
| 568 | + girq->parent_handler = NULL; |
|---|
| 569 | + girq->num_parents = 0; |
|---|
| 570 | + girq->parents = NULL; |
|---|
| 571 | + girq->default_type = IRQ_TYPE_NONE; |
|---|
| 572 | + girq->handler = handle_level_irq; |
|---|
| 700 | 573 | |
|---|
| 701 | 574 | ret = gb_connection_enable(connection); |
|---|
| 702 | 575 | if (ret) |
|---|
| 703 | 576 | goto exit_line_free; |
|---|
| 704 | 577 | |
|---|
| 705 | | - ret = gb_gpio_irqchip_add(gpio, irqc, 0, |
|---|
| 706 | | - handle_level_irq, IRQ_TYPE_NONE); |
|---|
| 707 | | - if (ret) { |
|---|
| 708 | | - dev_err(&gbphy_dev->dev, "failed to add irq chip: %d\n", ret); |
|---|
| 709 | | - goto exit_line_free; |
|---|
| 710 | | - } |
|---|
| 711 | | - |
|---|
| 712 | 578 | ret = gpiochip_add(gpio); |
|---|
| 713 | 579 | if (ret) { |
|---|
| 714 | 580 | dev_err(&gbphy_dev->dev, "failed to add gpio chip: %d\n", ret); |
|---|
| 715 | | - goto exit_gpio_irqchip_remove; |
|---|
| 581 | + goto exit_line_free; |
|---|
| 716 | 582 | } |
|---|
| 717 | 583 | |
|---|
| 718 | 584 | gbphy_runtime_put_autosuspend(gbphy_dev); |
|---|
| 719 | 585 | return 0; |
|---|
| 720 | 586 | |
|---|
| 721 | | -exit_gpio_irqchip_remove: |
|---|
| 722 | | - gb_gpio_irqchip_remove(ggc); |
|---|
| 723 | 587 | exit_line_free: |
|---|
| 724 | 588 | kfree(ggc->lines); |
|---|
| 725 | 589 | exit_connection_disable: |
|---|
| .. | .. |
|---|
| 743 | 607 | |
|---|
| 744 | 608 | gb_connection_disable_rx(connection); |
|---|
| 745 | 609 | gpiochip_remove(&ggc->chip); |
|---|
| 746 | | - gb_gpio_irqchip_remove(ggc); |
|---|
| 747 | 610 | gb_connection_disable(connection); |
|---|
| 748 | 611 | gb_connection_destroy(connection); |
|---|
| 749 | 612 | kfree(ggc->lines); |
|---|