• Home
  • Raw
  • Download

Lines Matching +full:port +full:- +full:base

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016-2017 NVIDIA Corporation
15 #include <dt-bindings/gpio/tegra186-gpio.h>
16 #include <dt-bindings/gpio/tegra194-gpio.h>
57 unsigned int port; member
86 void __iomem *base; member
94 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_get_port()
95 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_get_port() local
97 if (*pin >= start && *pin < start + port->pins) { in tegra186_gpio_get_port()
98 *pin -= start; in tegra186_gpio_get_port()
99 return port; in tegra186_gpio_get_port()
102 start += port->pins; in tegra186_gpio_get_port()
111 const struct tegra_gpio_port *port; in tegra186_gpio_get_base() local
114 port = tegra186_gpio_get_port(gpio, &pin); in tegra186_gpio_get_base()
115 if (!port) in tegra186_gpio_get_base()
118 offset = port->bank * 0x1000 + port->port * 0x200; in tegra186_gpio_get_base()
120 return gpio->base + offset + pin * 0x20; in tegra186_gpio_get_base()
127 void __iomem *base; in tegra186_gpio_get_direction() local
130 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_get_direction()
131 if (WARN_ON(base == NULL)) in tegra186_gpio_get_direction()
132 return -ENODEV; in tegra186_gpio_get_direction()
134 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_get_direction()
145 void __iomem *base; in tegra186_gpio_direction_input() local
148 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_direction_input()
149 if (WARN_ON(base == NULL)) in tegra186_gpio_direction_input()
150 return -ENODEV; in tegra186_gpio_direction_input()
152 value = readl(base + TEGRA186_GPIO_OUTPUT_CONTROL); in tegra186_gpio_direction_input()
154 writel(value, base + TEGRA186_GPIO_OUTPUT_CONTROL); in tegra186_gpio_direction_input()
156 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_direction_input()
159 writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_direction_input()
168 void __iomem *base; in tegra186_gpio_direction_output() local
172 chip->set(chip, offset, level); in tegra186_gpio_direction_output()
174 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_direction_output()
175 if (WARN_ON(base == NULL)) in tegra186_gpio_direction_output()
176 return -EINVAL; in tegra186_gpio_direction_output()
179 value = readl(base + TEGRA186_GPIO_OUTPUT_CONTROL); in tegra186_gpio_direction_output()
181 writel(value, base + TEGRA186_GPIO_OUTPUT_CONTROL); in tegra186_gpio_direction_output()
183 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_direction_output()
186 writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_direction_output()
194 void __iomem *base; in tegra186_gpio_get() local
197 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_get()
198 if (WARN_ON(base == NULL)) in tegra186_gpio_get()
199 return -ENODEV; in tegra186_gpio_get()
201 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_get()
203 value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE); in tegra186_gpio_get()
205 value = readl(base + TEGRA186_GPIO_INPUT); in tegra186_gpio_get()
214 void __iomem *base; in tegra186_gpio_set() local
217 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_set()
218 if (WARN_ON(base == NULL)) in tegra186_gpio_set()
221 value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE); in tegra186_gpio_set()
227 writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE); in tegra186_gpio_set()
236 void __iomem *base; in tegra186_gpio_set_config() local
238 base = tegra186_gpio_get_base(gpio, offset); in tegra186_gpio_set_config()
239 if (base == NULL) in tegra186_gpio_set_config()
240 return -ENXIO; in tegra186_gpio_set_config()
243 return -ENOTSUPP; in tegra186_gpio_set_config()
252 return -EINVAL; in tegra186_gpio_set_config()
257 writel(value, base + TEGRA186_GPIO_DEBOUNCE_CONTROL); in tegra186_gpio_set_config()
259 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_set_config()
261 writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_gpio_set_config()
274 if (!gpio->soc->pinmux || gpio->soc->num_pin_ranges == 0) in tegra186_gpio_add_pin_ranges()
277 np = of_find_compatible_node(NULL, NULL, gpio->soc->pinmux); in tegra186_gpio_add_pin_ranges()
279 return -ENODEV; in tegra186_gpio_add_pin_ranges()
284 return -EPROBE_DEFER; in tegra186_gpio_add_pin_ranges()
286 for (i = 0; i < gpio->soc->num_pin_ranges; i++) { in tegra186_gpio_add_pin_ranges()
287 unsigned int pin = gpio->soc->pin_ranges[i].offset, port; in tegra186_gpio_add_pin_ranges() local
288 const char *group = gpio->soc->pin_ranges[i].group; in tegra186_gpio_add_pin_ranges()
290 port = pin / 8; in tegra186_gpio_add_pin_ranges()
293 if (port >= gpio->soc->num_ports) { in tegra186_gpio_add_pin_ranges()
294 dev_warn(chip->parent, "invalid port %u for %s\n", in tegra186_gpio_add_pin_ranges()
295 port, group); in tegra186_gpio_add_pin_ranges()
299 for (j = 0; j < port; j++) in tegra186_gpio_add_pin_ranges()
300 pin += gpio->soc->ports[j].pins; in tegra186_gpio_add_pin_ranges()
315 unsigned int port, pin, i, offset = 0; in tegra186_gpio_of_xlate() local
317 if (WARN_ON(chip->of_gpio_n_cells < 2)) in tegra186_gpio_of_xlate()
318 return -EINVAL; in tegra186_gpio_of_xlate()
320 if (WARN_ON(spec->args_count < chip->of_gpio_n_cells)) in tegra186_gpio_of_xlate()
321 return -EINVAL; in tegra186_gpio_of_xlate()
323 port = spec->args[0] / 8; in tegra186_gpio_of_xlate()
324 pin = spec->args[0] % 8; in tegra186_gpio_of_xlate()
326 if (port >= gpio->soc->num_ports) { in tegra186_gpio_of_xlate()
327 dev_err(chip->parent, "invalid port number: %u\n", port); in tegra186_gpio_of_xlate()
328 return -EINVAL; in tegra186_gpio_of_xlate()
331 for (i = 0; i < port; i++) in tegra186_gpio_of_xlate()
332 offset += gpio->soc->ports[i].pins; in tegra186_gpio_of_xlate()
335 *flags = spec->args[1]; in tegra186_gpio_of_xlate()
346 void __iomem *base; in tegra186_irq_ack() local
348 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_ack()
349 if (WARN_ON(base == NULL)) in tegra186_irq_ack()
352 writel(1, base + TEGRA186_GPIO_INTERRUPT_CLEAR); in tegra186_irq_ack()
359 void __iomem *base; in tegra186_irq_mask() local
362 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_mask()
363 if (WARN_ON(base == NULL)) in tegra186_irq_mask()
366 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_irq_mask()
368 writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_irq_mask()
375 void __iomem *base; in tegra186_irq_unmask() local
378 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_unmask()
379 if (WARN_ON(base == NULL)) in tegra186_irq_unmask()
382 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_irq_unmask()
384 writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_irq_unmask()
391 void __iomem *base; in tegra186_irq_set_type() local
394 base = tegra186_gpio_get_base(gpio, data->hwirq); in tegra186_irq_set_type()
395 if (WARN_ON(base == NULL)) in tegra186_irq_set_type()
396 return -ENODEV; in tegra186_irq_set_type()
398 value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_irq_set_type()
429 return -EINVAL; in tegra186_irq_set_type()
432 writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); in tegra186_irq_set_type()
439 if (data->parent_data) in tegra186_irq_set_type()
447 if (data->parent_data) in tegra186_irq_set_wake()
456 struct irq_domain *domain = gpio->gpio.irq.domain; in tegra186_gpio_irq()
463 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_irq()
464 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_irq() local
467 void __iomem *base; in tegra186_gpio_irq() local
469 base = gpio->base + port->bank * 0x1000 + port->port * 0x200; in tegra186_gpio_irq()
472 if (parent != gpio->irq[port->bank]) in tegra186_gpio_irq()
475 value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1)); in tegra186_gpio_irq()
477 for_each_set_bit(pin, &value, port->pins) { in tegra186_gpio_irq()
486 offset += port->pins; in tegra186_gpio_irq()
497 struct tegra_gpio *gpio = gpiochip_get_data(domain->host_data); in tegra186_gpio_irq_domain_translate()
498 unsigned int port, pin, i, offset = 0; in tegra186_gpio_irq_domain_translate() local
500 if (WARN_ON(gpio->gpio.of_gpio_n_cells < 2)) in tegra186_gpio_irq_domain_translate()
501 return -EINVAL; in tegra186_gpio_irq_domain_translate()
503 if (WARN_ON(fwspec->param_count < gpio->gpio.of_gpio_n_cells)) in tegra186_gpio_irq_domain_translate()
504 return -EINVAL; in tegra186_gpio_irq_domain_translate()
506 port = fwspec->param[0] / 8; in tegra186_gpio_irq_domain_translate()
507 pin = fwspec->param[0] % 8; in tegra186_gpio_irq_domain_translate()
509 if (port >= gpio->soc->num_ports) in tegra186_gpio_irq_domain_translate()
510 return -EINVAL; in tegra186_gpio_irq_domain_translate()
512 for (i = 0; i < port; i++) in tegra186_gpio_irq_domain_translate()
513 offset += gpio->soc->ports[i].pins; in tegra186_gpio_irq_domain_translate()
515 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in tegra186_gpio_irq_domain_translate()
532 fwspec->fwnode = chip->irq.parent_domain->fwnode; in tegra186_gpio_populate_parent_fwspec()
533 fwspec->param_count = 3; in tegra186_gpio_populate_parent_fwspec()
534 fwspec->param[0] = gpio->soc->instance; in tegra186_gpio_populate_parent_fwspec()
535 fwspec->param[1] = parent_hwirq; in tegra186_gpio_populate_parent_fwspec()
536 fwspec->param[2] = parent_type; in tegra186_gpio_populate_parent_fwspec()
547 *parent_hwirq = chip->irq.child_offset_to_irq(chip, hwirq); in tegra186_gpio_child_to_parent_hwirq()
559 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_child_offset_to_irq()
560 if (offset < gpio->soc->ports[i].pins) in tegra186_gpio_child_offset_to_irq()
563 offset -= gpio->soc->ports[i].pins; in tegra186_gpio_child_offset_to_irq()
570 { .compatible = "nvidia,tegra186-pmc" },
571 { .compatible = "nvidia,tegra194-pmc" },
580 for (i = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_init_route_mapping()
581 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_init_route_mapping() local
582 unsigned int offset, p = port->port; in tegra186_gpio_init_route_mapping()
583 void __iomem *base; in tegra186_gpio_init_route_mapping() local
585 base = gpio->secure + port->bank * 0x1000 + 0x800; in tegra186_gpio_init_route_mapping()
587 value = readl(base + TEGRA186_GPIO_CTL_SCR); in tegra186_gpio_init_route_mapping()
598 value = readl(base + offset); in tegra186_gpio_init_route_mapping()
599 value = BIT(port->pins) - 1; in tegra186_gpio_init_route_mapping()
600 writel(value, base + offset); in tegra186_gpio_init_route_mapping()
615 gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); in tegra186_gpio_probe()
617 return -ENOMEM; in tegra186_gpio_probe()
619 gpio->soc = of_device_get_match_data(&pdev->dev); in tegra186_gpio_probe()
621 gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); in tegra186_gpio_probe()
622 if (IS_ERR(gpio->secure)) in tegra186_gpio_probe()
623 return PTR_ERR(gpio->secure); in tegra186_gpio_probe()
625 gpio->base = devm_platform_ioremap_resource_byname(pdev, "gpio"); in tegra186_gpio_probe()
626 if (IS_ERR(gpio->base)) in tegra186_gpio_probe()
627 return PTR_ERR(gpio->base); in tegra186_gpio_probe()
633 gpio->num_irq = err; in tegra186_gpio_probe()
635 gpio->irq = devm_kcalloc(&pdev->dev, gpio->num_irq, sizeof(*gpio->irq), in tegra186_gpio_probe()
637 if (!gpio->irq) in tegra186_gpio_probe()
638 return -ENOMEM; in tegra186_gpio_probe()
640 for (i = 0; i < gpio->num_irq; i++) { in tegra186_gpio_probe()
645 gpio->irq[i] = err; in tegra186_gpio_probe()
648 gpio->gpio.label = gpio->soc->name; in tegra186_gpio_probe()
649 gpio->gpio.parent = &pdev->dev; in tegra186_gpio_probe()
651 gpio->gpio.request = gpiochip_generic_request; in tegra186_gpio_probe()
652 gpio->gpio.free = gpiochip_generic_free; in tegra186_gpio_probe()
653 gpio->gpio.get_direction = tegra186_gpio_get_direction; in tegra186_gpio_probe()
654 gpio->gpio.direction_input = tegra186_gpio_direction_input; in tegra186_gpio_probe()
655 gpio->gpio.direction_output = tegra186_gpio_direction_output; in tegra186_gpio_probe()
656 gpio->gpio.get = tegra186_gpio_get, in tegra186_gpio_probe()
657 gpio->gpio.set = tegra186_gpio_set; in tegra186_gpio_probe()
658 gpio->gpio.set_config = tegra186_gpio_set_config; in tegra186_gpio_probe()
659 gpio->gpio.add_pin_ranges = tegra186_gpio_add_pin_ranges; in tegra186_gpio_probe()
661 gpio->gpio.base = -1; in tegra186_gpio_probe()
663 for (i = 0; i < gpio->soc->num_ports; i++) in tegra186_gpio_probe()
664 gpio->gpio.ngpio += gpio->soc->ports[i].pins; in tegra186_gpio_probe()
666 names = devm_kcalloc(gpio->gpio.parent, gpio->gpio.ngpio, in tegra186_gpio_probe()
669 return -ENOMEM; in tegra186_gpio_probe()
671 for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_probe()
672 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_probe() local
675 for (j = 0; j < port->pins; j++) { in tegra186_gpio_probe()
676 name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, in tegra186_gpio_probe()
677 "P%s.%02x", port->name, j); in tegra186_gpio_probe()
679 return -ENOMEM; in tegra186_gpio_probe()
684 offset += port->pins; in tegra186_gpio_probe()
687 gpio->gpio.names = (const char * const *)names; in tegra186_gpio_probe()
689 gpio->gpio.of_node = pdev->dev.of_node; in tegra186_gpio_probe()
690 gpio->gpio.of_gpio_n_cells = 2; in tegra186_gpio_probe()
691 gpio->gpio.of_xlate = tegra186_gpio_of_xlate; in tegra186_gpio_probe()
693 gpio->intc.name = pdev->dev.of_node->name; in tegra186_gpio_probe()
694 gpio->intc.irq_ack = tegra186_irq_ack; in tegra186_gpio_probe()
695 gpio->intc.irq_mask = tegra186_irq_mask; in tegra186_gpio_probe()
696 gpio->intc.irq_unmask = tegra186_irq_unmask; in tegra186_gpio_probe()
697 gpio->intc.irq_set_type = tegra186_irq_set_type; in tegra186_gpio_probe()
698 gpio->intc.irq_set_wake = tegra186_irq_set_wake; in tegra186_gpio_probe()
700 irq = &gpio->gpio.irq; in tegra186_gpio_probe()
701 irq->chip = &gpio->intc; in tegra186_gpio_probe()
702 irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); in tegra186_gpio_probe()
703 irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq; in tegra186_gpio_probe()
704 irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec; in tegra186_gpio_probe()
705 irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq; in tegra186_gpio_probe()
706 irq->child_irq_domain_ops.translate = tegra186_gpio_irq_domain_translate; in tegra186_gpio_probe()
707 irq->handler = handle_simple_irq; in tegra186_gpio_probe()
708 irq->default_type = IRQ_TYPE_NONE; in tegra186_gpio_probe()
709 irq->parent_handler = tegra186_gpio_irq; in tegra186_gpio_probe()
710 irq->parent_handler_data = gpio; in tegra186_gpio_probe()
711 irq->num_parents = gpio->num_irq; in tegra186_gpio_probe()
712 irq->parents = gpio->irq; in tegra186_gpio_probe()
716 irq->parent_domain = irq_find_host(np); in tegra186_gpio_probe()
719 if (!irq->parent_domain) in tegra186_gpio_probe()
720 return -EPROBE_DEFER; in tegra186_gpio_probe()
725 irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio, in tegra186_gpio_probe()
726 sizeof(*irq->map), GFP_KERNEL); in tegra186_gpio_probe()
727 if (!irq->map) in tegra186_gpio_probe()
728 return -ENOMEM; in tegra186_gpio_probe()
730 for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { in tegra186_gpio_probe()
731 const struct tegra_gpio_port *port = &gpio->soc->ports[i]; in tegra186_gpio_probe() local
733 for (j = 0; j < port->pins; j++) in tegra186_gpio_probe()
734 irq->map[offset + j] = irq->parents[port->bank]; in tegra186_gpio_probe()
736 offset += port->pins; in tegra186_gpio_probe()
741 err = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio); in tegra186_gpio_probe()
757 .port = _port, \
790 .name = "tegra186-gpio",
798 .port = _port, \
816 .name = "tegra186-gpio-aon",
824 .port = _port, \
867 .name = "tegra194-gpio",
871 .pinmux = "nvidia,tegra194-pinmux",
878 .port = _port, \
893 .name = "tegra194-gpio-aon",
899 .compatible = "nvidia,tegra186-gpio",
902 .compatible = "nvidia,tegra186-gpio-aon",
905 .compatible = "nvidia,tegra194-gpio",
908 .compatible = "nvidia,tegra194-gpio-aon",
918 .name = "tegra186-gpio",