Lines Matching +full:- +full:gpio +full:- +full:bank

1 // SPDX-License-Identifier: GPL-2.0-only
3 * arch/arm/mach-tegra/gpio.c
6 * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
17 #include <linux/gpio/driver.h>
31 #define GPIO_REG(tgi, x) (GPIO_BANK(x) * tgi->soc->bank_stride + \
45 #define GPIO_MSK_CNF(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x00)
46 #define GPIO_MSK_OE(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x10)
47 #define GPIO_MSK_OUT(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0X20)
48 #define GPIO_MSK_DBC_EN(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x30)
49 #define GPIO_MSK_INT_STA(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x40)
50 #define GPIO_MSK_INT_ENB(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x50)
51 #define GPIO_MSK_INT_LVL(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x60)
63 unsigned int bank; member
66 * IRQ-core code uses raw locking, and thus, nested locking also
105 writel_relaxed(val, tgi->regs + reg); in tegra_gpio_writel()
110 return readl_relaxed(tgi->regs + reg); in tegra_gpio_readl()
113 static unsigned int tegra_gpio_compose(unsigned int bank, unsigned int port, in tegra_gpio_compose() argument
116 return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7); in tegra_gpio_compose()
120 unsigned int gpio, u32 value) in tegra_gpio_mask_write() argument
124 val = 0x100 << GPIO_BIT(gpio); in tegra_gpio_mask_write()
126 val |= 1 << GPIO_BIT(gpio); in tegra_gpio_mask_write()
130 static void tegra_gpio_enable(struct tegra_gpio_info *tgi, unsigned int gpio) in tegra_gpio_enable() argument
132 tegra_gpio_mask_write(tgi, GPIO_MSK_CNF(tgi, gpio), gpio, 1); in tegra_gpio_enable()
135 static void tegra_gpio_disable(struct tegra_gpio_info *tgi, unsigned int gpio) in tegra_gpio_disable() argument
137 tegra_gpio_mask_write(tgi, GPIO_MSK_CNF(tgi, gpio), gpio, 0); in tegra_gpio_disable()
142 return pinctrl_gpio_request(chip->base + offset); in tegra_gpio_request()
149 pinctrl_gpio_free(chip->base + offset); in tegra_gpio_free()
166 /* If gpio is in output mode then read from the out value */ in tegra_gpio_get()
182 ret = pinctrl_gpio_direction_input(chip->base + offset); in tegra_gpio_direction_input()
184 dev_err(tgi->dev, in tegra_gpio_direction_input()
185 "Failed to set pinctrl input direction of GPIO %d: %d", in tegra_gpio_direction_input()
186 chip->base + offset, ret); in tegra_gpio_direction_input()
202 ret = pinctrl_gpio_direction_output(chip->base + offset); in tegra_gpio_direction_output()
204 dev_err(tgi->dev, in tegra_gpio_direction_output()
205 "Failed to set pinctrl output direction of GPIO %d: %d", in tegra_gpio_direction_output()
206 chip->base + offset, ret); in tegra_gpio_direction_output()
220 return -EINVAL; in tegra_gpio_get_direction()
234 struct tegra_gpio_bank *bank = &tgi->bank_info[GPIO_BANK(offset)]; in tegra_gpio_set_debounce() local
251 spin_lock_irqsave(&bank->dbc_lock[port], flags); in tegra_gpio_set_debounce()
252 if (bank->dbc_cnt[port] < debounce_ms) { in tegra_gpio_set_debounce()
254 bank->dbc_cnt[port] = debounce_ms; in tegra_gpio_set_debounce()
256 spin_unlock_irqrestore(&bank->dbc_lock[port], flags); in tegra_gpio_set_debounce()
269 return -ENOTSUPP; in tegra_gpio_set_config()
279 unsigned int gpio = d->hwirq; in tegra_gpio_irq_ack() local
281 tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio)); in tegra_gpio_irq_ack()
288 unsigned int gpio = d->hwirq; in tegra_gpio_irq_mask() local
290 tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0); in tegra_gpio_irq_mask()
291 gpiochip_disable_irq(chip, gpio); in tegra_gpio_irq_mask()
298 unsigned int gpio = d->hwirq; in tegra_gpio_irq_unmask() local
300 gpiochip_enable_irq(chip, gpio); in tegra_gpio_irq_unmask()
301 tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1); in tegra_gpio_irq_unmask()
306 unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type; in tegra_gpio_irq_set_type() local
309 struct tegra_gpio_bank *bank; in tegra_gpio_irq_set_type() local
314 bank = &tgi->bank_info[GPIO_BANK(d->hwirq)]; in tegra_gpio_irq_set_type()
338 return -EINVAL; in tegra_gpio_irq_set_type()
341 raw_spin_lock_irqsave(&bank->lvl_lock[port], flags); in tegra_gpio_irq_set_type()
343 val = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_irq_set_type()
344 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); in tegra_gpio_irq_set_type()
345 val |= lvl_type << GPIO_BIT(gpio); in tegra_gpio_irq_set_type()
346 tegra_gpio_writel(tgi, val, GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_irq_set_type()
348 raw_spin_unlock_irqrestore(&bank->lvl_lock[port], flags); in tegra_gpio_irq_set_type()
350 tegra_gpio_mask_write(tgi, GPIO_MSK_OE(tgi, gpio), gpio, 0); in tegra_gpio_irq_set_type()
351 tegra_gpio_enable(tgi, gpio); in tegra_gpio_irq_set_type()
353 ret = gpiochip_lock_as_irq(&tgi->gc, gpio); in tegra_gpio_irq_set_type()
355 dev_err(tgi->dev, in tegra_gpio_irq_set_type()
356 "unable to lock Tegra GPIO %u as IRQ\n", gpio); in tegra_gpio_irq_set_type()
357 tegra_gpio_disable(tgi, gpio); in tegra_gpio_irq_set_type()
366 if (d->parent_data) in tegra_gpio_irq_set_type()
376 unsigned int gpio = d->hwirq; in tegra_gpio_irq_shutdown() local
379 gpiochip_unlock_as_irq(&tgi->gc, gpio); in tegra_gpio_irq_shutdown()
386 struct irq_domain *domain = tgi->gc.irq.domain; in tegra_gpio_irq_handler()
388 struct tegra_gpio_bank *bank = NULL; in tegra_gpio_irq_handler() local
389 unsigned int port, pin, gpio, i; in tegra_gpio_irq_handler() local
394 for (i = 0; i < tgi->bank_count; i++) { in tegra_gpio_irq_handler()
395 if (tgi->irqs[i] == irq) { in tegra_gpio_irq_handler()
396 bank = &tgi->bank_info[i]; in tegra_gpio_irq_handler()
401 if (WARN_ON(bank == NULL)) in tegra_gpio_irq_handler()
407 gpio = tegra_gpio_compose(bank->bank, port, 0); in tegra_gpio_irq_handler()
408 sta = tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)) & in tegra_gpio_irq_handler()
409 tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_irq_handler()
410 lvl = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_irq_handler()
416 GPIO_INT_CLR(tgi, gpio)); in tegra_gpio_irq_handler()
418 /* if gpio is edge triggered, clear condition in tegra_gpio_irq_handler()
427 ret = generic_handle_domain_irq(domain, gpio + pin); in tegra_gpio_irq_handler()
428 WARN_RATELIMIT(ret, "hwirq = %d", gpio + pin); in tegra_gpio_irq_handler()
442 *parent_hwirq = chip->irq.child_offset_to_irq(chip, hwirq); in tegra_gpio_child_to_parent_hwirq()
453 struct irq_fwspec *fwspec = &gfwspec->fwspec; in tegra_gpio_populate_parent_fwspec()
455 fwspec->fwnode = chip->irq.parent_domain->fwnode; in tegra_gpio_populate_parent_fwspec()
456 fwspec->param_count = 3; in tegra_gpio_populate_parent_fwspec()
457 fwspec->param[0] = 0; in tegra_gpio_populate_parent_fwspec()
458 fwspec->param[1] = parent_hwirq; in tegra_gpio_populate_parent_fwspec()
459 fwspec->param[2] = parent_type; in tegra_gpio_populate_parent_fwspec()
470 for (b = 0; b < tgi->bank_count; b++) { in tegra_gpio_resume()
471 struct tegra_gpio_bank *bank = &tgi->bank_info[b]; in tegra_gpio_resume() local
473 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { in tegra_gpio_resume()
474 unsigned int gpio = (b << 5) | (p << 3); in tegra_gpio_resume() local
476 tegra_gpio_writel(tgi, bank->cnf[p], in tegra_gpio_resume()
477 GPIO_CNF(tgi, gpio)); in tegra_gpio_resume()
479 if (tgi->soc->debounce_supported) { in tegra_gpio_resume()
480 tegra_gpio_writel(tgi, bank->dbc_cnt[p], in tegra_gpio_resume()
481 GPIO_DBC_CNT(tgi, gpio)); in tegra_gpio_resume()
482 tegra_gpio_writel(tgi, bank->dbc_enb[p], in tegra_gpio_resume()
483 GPIO_MSK_DBC_EN(tgi, gpio)); in tegra_gpio_resume()
486 tegra_gpio_writel(tgi, bank->out[p], in tegra_gpio_resume()
487 GPIO_OUT(tgi, gpio)); in tegra_gpio_resume()
488 tegra_gpio_writel(tgi, bank->oe[p], in tegra_gpio_resume()
489 GPIO_OE(tgi, gpio)); in tegra_gpio_resume()
490 tegra_gpio_writel(tgi, bank->int_lvl[p], in tegra_gpio_resume()
491 GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_resume()
492 tegra_gpio_writel(tgi, bank->int_enb[p], in tegra_gpio_resume()
493 GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_resume()
505 for (b = 0; b < tgi->bank_count; b++) { in tegra_gpio_suspend()
506 struct tegra_gpio_bank *bank = &tgi->bank_info[b]; in tegra_gpio_suspend() local
508 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { in tegra_gpio_suspend()
509 unsigned int gpio = (b << 5) | (p << 3); in tegra_gpio_suspend() local
511 bank->cnf[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
512 GPIO_CNF(tgi, gpio)); in tegra_gpio_suspend()
513 bank->out[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
514 GPIO_OUT(tgi, gpio)); in tegra_gpio_suspend()
515 bank->oe[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
516 GPIO_OE(tgi, gpio)); in tegra_gpio_suspend()
517 if (tgi->soc->debounce_supported) { in tegra_gpio_suspend()
518 bank->dbc_enb[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
519 GPIO_MSK_DBC_EN(tgi, gpio)); in tegra_gpio_suspend()
520 bank->dbc_enb[p] = (bank->dbc_enb[p] << 8) | in tegra_gpio_suspend()
521 bank->dbc_enb[p]; in tegra_gpio_suspend()
524 bank->int_enb[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
525 GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_suspend()
526 bank->int_lvl[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
527 GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_suspend()
529 /* Enable gpio irq for wake up source */ in tegra_gpio_suspend()
530 tegra_gpio_writel(tgi, bank->wake_enb[p], in tegra_gpio_suspend()
531 GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_suspend()
542 struct tegra_gpio_bank *bank; in tegra_gpio_irq_set_wake() local
543 unsigned int gpio = d->hwirq; in tegra_gpio_irq_set_wake() local
547 bank = &tgi->bank_info[GPIO_BANK(d->hwirq)]; in tegra_gpio_irq_set_wake()
549 port = GPIO_PORT(gpio); in tegra_gpio_irq_set_wake()
550 bit = GPIO_BIT(gpio); in tegra_gpio_irq_set_wake()
553 err = irq_set_irq_wake(tgi->irqs[bank->bank], enable); in tegra_gpio_irq_set_wake()
557 if (d->parent_data) { in tegra_gpio_irq_set_wake()
560 irq_set_irq_wake(tgi->irqs[bank->bank], !enable); in tegra_gpio_irq_set_wake()
566 bank->wake_enb[port] |= mask; in tegra_gpio_irq_set_wake()
568 bank->wake_enb[port] &= ~mask; in tegra_gpio_irq_set_wake()
578 if (data->parent_data) in tegra_gpio_irq_set_affinity()
581 return -EINVAL; in tegra_gpio_irq_set_affinity()
589 tegra_gpio_enable(tgi, d->hwirq); in tegra_gpio_irq_request_resources()
591 return gpiochip_reqres_irq(chip, d->hwirq); in tegra_gpio_irq_request_resources()
599 gpiochip_relres_irq(chip, d->hwirq); in tegra_gpio_irq_release_resources()
600 tegra_gpio_enable(tgi, d->hwirq); in tegra_gpio_irq_release_resources()
607 seq_printf(s, dev_name(chip->parent)); in tegra_gpio_irq_print_chip()
647 struct tegra_gpio_info *tgi = dev_get_drvdata(s->private); in tegra_dbg_gpio_show()
650 for (i = 0; i < tgi->bank_count; i++) { in tegra_dbg_gpio_show()
652 unsigned int gpio = tegra_gpio_compose(i, j, 0); in tegra_dbg_gpio_show() local
657 tegra_gpio_readl(tgi, GPIO_CNF(tgi, gpio)), in tegra_dbg_gpio_show()
658 tegra_gpio_readl(tgi, GPIO_OE(tgi, gpio)), in tegra_dbg_gpio_show()
659 tegra_gpio_readl(tgi, GPIO_OUT(tgi, gpio)), in tegra_dbg_gpio_show()
660 tegra_gpio_readl(tgi, GPIO_IN(tgi, gpio)), in tegra_dbg_gpio_show()
661 tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)), in tegra_dbg_gpio_show()
662 tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio)), in tegra_dbg_gpio_show()
663 tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio))); in tegra_dbg_gpio_show()
671 debugfs_create_devm_seqfile(tgi->dev, "tegra_gpio", NULL, in tegra_gpio_debuginit()
688 { .compatible = "nvidia,tegra210-pmc", },
694 struct tegra_gpio_bank *bank; in tegra_gpio_probe() local
701 tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL); in tegra_gpio_probe()
703 return -ENODEV; in tegra_gpio_probe()
705 tgi->soc = of_device_get_match_data(&pdev->dev); in tegra_gpio_probe()
706 tgi->dev = &pdev->dev; in tegra_gpio_probe()
712 tgi->bank_count = ret; in tegra_gpio_probe()
714 if (!tgi->bank_count) { in tegra_gpio_probe()
715 dev_err(&pdev->dev, "Missing IRQ resource\n"); in tegra_gpio_probe()
716 return -ENODEV; in tegra_gpio_probe()
719 tgi->gc.label = "tegra-gpio"; in tegra_gpio_probe()
720 tgi->gc.request = tegra_gpio_request; in tegra_gpio_probe()
721 tgi->gc.free = tegra_gpio_free; in tegra_gpio_probe()
722 tgi->gc.direction_input = tegra_gpio_direction_input; in tegra_gpio_probe()
723 tgi->gc.get = tegra_gpio_get; in tegra_gpio_probe()
724 tgi->gc.direction_output = tegra_gpio_direction_output; in tegra_gpio_probe()
725 tgi->gc.set = tegra_gpio_set; in tegra_gpio_probe()
726 tgi->gc.get_direction = tegra_gpio_get_direction; in tegra_gpio_probe()
727 tgi->gc.base = 0; in tegra_gpio_probe()
728 tgi->gc.ngpio = tgi->bank_count * 32; in tegra_gpio_probe()
729 tgi->gc.parent = &pdev->dev; in tegra_gpio_probe()
733 if (tgi->soc->debounce_supported) in tegra_gpio_probe()
734 tgi->gc.set_config = tegra_gpio_set_config; in tegra_gpio_probe()
736 tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->bank_count, in tegra_gpio_probe()
737 sizeof(*tgi->bank_info), GFP_KERNEL); in tegra_gpio_probe()
738 if (!tgi->bank_info) in tegra_gpio_probe()
739 return -ENOMEM; in tegra_gpio_probe()
741 tgi->irqs = devm_kcalloc(&pdev->dev, tgi->bank_count, in tegra_gpio_probe()
742 sizeof(*tgi->irqs), GFP_KERNEL); in tegra_gpio_probe()
743 if (!tgi->irqs) in tegra_gpio_probe()
744 return -ENOMEM; in tegra_gpio_probe()
746 for (i = 0; i < tgi->bank_count; i++) { in tegra_gpio_probe()
751 bank = &tgi->bank_info[i]; in tegra_gpio_probe()
752 bank->bank = i; in tegra_gpio_probe()
754 tgi->irqs[i] = ret; in tegra_gpio_probe()
757 raw_spin_lock_init(&bank->lvl_lock[j]); in tegra_gpio_probe()
758 spin_lock_init(&bank->dbc_lock[j]); in tegra_gpio_probe()
762 irq = &tgi->gc.irq; in tegra_gpio_probe()
763 irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); in tegra_gpio_probe()
764 irq->child_to_parent_hwirq = tegra_gpio_child_to_parent_hwirq; in tegra_gpio_probe()
765 irq->populate_parent_alloc_arg = tegra_gpio_populate_parent_fwspec; in tegra_gpio_probe()
766 irq->handler = handle_simple_irq; in tegra_gpio_probe()
767 irq->default_type = IRQ_TYPE_NONE; in tegra_gpio_probe()
768 irq->parent_handler = tegra_gpio_irq_handler; in tegra_gpio_probe()
769 irq->parent_handler_data = tgi; in tegra_gpio_probe()
770 irq->num_parents = tgi->bank_count; in tegra_gpio_probe()
771 irq->parents = tgi->irqs; in tegra_gpio_probe()
775 irq->parent_domain = irq_find_host(np); in tegra_gpio_probe()
778 if (!irq->parent_domain) in tegra_gpio_probe()
779 return -EPROBE_DEFER; in tegra_gpio_probe()
786 tgi->regs = devm_platform_ioremap_resource(pdev, 0); in tegra_gpio_probe()
787 if (IS_ERR(tgi->regs)) in tegra_gpio_probe()
788 return PTR_ERR(tgi->regs); in tegra_gpio_probe()
790 for (i = 0; i < tgi->bank_count; i++) { in tegra_gpio_probe()
792 int gpio = tegra_gpio_compose(i, j, 0); in tegra_gpio_probe() local
794 tegra_gpio_writel(tgi, 0x00, GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_probe()
798 ret = devm_gpiochip_add_data(&pdev->dev, &tgi->gc, tgi); in tegra_gpio_probe()
824 { .compatible = "nvidia,tegra210-gpio", .data = &tegra210_gpio_config },
825 { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config },
826 { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config },
833 .name = "tegra-gpio",
841 MODULE_DESCRIPTION("NVIDIA Tegra GPIO controller driver");