diff options
Diffstat (limited to 'drivers/gpio/gpio-tegra186.c')
| -rw-r--r-- | drivers/gpio/gpio-tegra186.c | 408 |
1 files changed, 285 insertions, 123 deletions
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 54d9fa7da9c1..b1498b59a921 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -1,23 +1,26 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2022 NVIDIA Corporation + * Copyright (c) 2016-2025 NVIDIA Corporation * * Author: Thierry Reding <treding@nvidia.com> * Dipen Patel <dpatel@nvidia.com> */ #include <linux/gpio/driver.h> +#include <linux/hte.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> -#include <linux/hte.h> +#include <linux/property.h> +#include <linux/seq_file.h> #include <dt-bindings/gpio/tegra186-gpio.h> #include <dt-bindings/gpio/tegra194-gpio.h> #include <dt-bindings/gpio/tegra234-gpio.h> #include <dt-bindings/gpio/tegra241-gpio.h> +#include <dt-bindings/gpio/tegra256-gpio.h> /* security registers */ #define TEGRA186_GPIO_CTL_SCR 0x0c @@ -26,6 +29,16 @@ #define TEGRA186_GPIO_INT_ROUTE_MAPPING(p, x) (0x14 + (p) * 0x20 + (x) * 4) +#define TEGRA186_GPIO_VM 0x00 +#define TEGRA186_GPIO_VM_RW_MASK 0x03 +#define TEGRA186_GPIO_SCR 0x04 +#define TEGRA186_GPIO_SCR_PIN_SIZE 0x08 +#define TEGRA186_GPIO_SCR_PORT_SIZE 0x40 +#define TEGRA186_GPIO_SCR_SEC_WEN BIT(28) +#define TEGRA186_GPIO_SCR_SEC_REN BIT(27) +#define TEGRA186_GPIO_SCR_SEC_G1W BIT(9) +#define TEGRA186_GPIO_SCR_SEC_G1R BIT(1) + /* control registers */ #define TEGRA186_GPIO_ENABLE_CONFIG 0x00 #define TEGRA186_GPIO_ENABLE_CONFIG_ENABLE BIT(0) @@ -56,6 +69,30 @@ #define TEGRA186_GPIO_INTERRUPT_STATUS(x) (0x100 + (x) * 4) +/* Tegra410 GPIOs implemented by the COMPUTE GPIO controller */ +#define TEGRA410_COMPUTE_GPIO_PORT_A 0 +#define TEGRA410_COMPUTE_GPIO_PORT_B 1 +#define TEGRA410_COMPUTE_GPIO_PORT_C 2 +#define TEGRA410_COMPUTE_GPIO_PORT_D 3 +#define TEGRA410_COMPUTE_GPIO_PORT_E 4 + +/* Tegra410 GPIOs implemented by the SYSTEM GPIO controller */ +#define TEGRA410_SYSTEM_GPIO_PORT_A 0 +#define TEGRA410_SYSTEM_GPIO_PORT_B 1 +#define TEGRA410_SYSTEM_GPIO_PORT_C 2 +#define TEGRA410_SYSTEM_GPIO_PORT_D 3 +#define TEGRA410_SYSTEM_GPIO_PORT_E 4 +#define TEGRA410_SYSTEM_GPIO_PORT_I 5 +#define TEGRA410_SYSTEM_GPIO_PORT_J 6 +#define TEGRA410_SYSTEM_GPIO_PORT_K 7 +#define TEGRA410_SYSTEM_GPIO_PORT_L 8 +#define TEGRA410_SYSTEM_GPIO_PORT_M 9 +#define TEGRA410_SYSTEM_GPIO_PORT_N 10 +#define TEGRA410_SYSTEM_GPIO_PORT_P 11 +#define TEGRA410_SYSTEM_GPIO_PORT_Q 12 +#define TEGRA410_SYSTEM_GPIO_PORT_R 13 +#define TEGRA410_SYSTEM_GPIO_PORT_V 14 + struct tegra_gpio_port { const char *name; unsigned int bank; @@ -72,6 +109,7 @@ struct tegra_gpio_soc { const struct tegra_gpio_port *ports; unsigned int num_ports; const char *name; + const char *prefix; unsigned int instance; unsigned int num_irqs_per_bank; @@ -80,6 +118,7 @@ struct tegra_gpio_soc { unsigned int num_pin_ranges; const char *pinmux; bool has_gte; + bool has_vm_support; }; struct tegra_gpio { @@ -129,6 +168,88 @@ static void __iomem *tegra186_gpio_get_base(struct tegra_gpio *gpio, return gpio->base + offset + pin * 0x20; } +static void __iomem *tegra186_gpio_get_secure_base(struct tegra_gpio *gpio, + unsigned int pin) +{ + const struct tegra_gpio_port *port; + unsigned int offset; + + port = tegra186_gpio_get_port(gpio, &pin); + if (!port) + return NULL; + + offset = port->bank * 0x1000 + port->port * TEGRA186_GPIO_SCR_PORT_SIZE; + + return gpio->secure + offset + pin * TEGRA186_GPIO_SCR_PIN_SIZE; +} + +static inline bool tegra186_gpio_is_accessible(struct tegra_gpio *gpio, unsigned int pin) +{ + void __iomem *secure; + u32 value; + + secure = tegra186_gpio_get_secure_base(gpio, pin); + + if (gpio->soc->has_vm_support) { + value = readl(secure + TEGRA186_GPIO_VM); + if ((value & TEGRA186_GPIO_VM_RW_MASK) != TEGRA186_GPIO_VM_RW_MASK) + return false; + } + + value = __raw_readl(secure + TEGRA186_GPIO_SCR); + + /* + * When SCR_SEC_[R|W]EN is unset, then we have full read/write access to all the + * registers for given GPIO pin. + * When SCR_SEC[R|W]EN is set, then there is need to further check the accompanying + * SCR_SEC_G1[R|W] bit to determine read/write access to all the registers for given + * GPIO pin. + */ + + if (((value & TEGRA186_GPIO_SCR_SEC_REN) == 0 || + ((value & TEGRA186_GPIO_SCR_SEC_REN) && (value & TEGRA186_GPIO_SCR_SEC_G1R))) && + ((value & TEGRA186_GPIO_SCR_SEC_WEN) == 0 || + ((value & TEGRA186_GPIO_SCR_SEC_WEN) && (value & TEGRA186_GPIO_SCR_SEC_G1W)))) + return true; + + return false; +} + +static int tegra186_init_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, unsigned int ngpios) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + unsigned int j; + + for (j = 0; j < ngpios; j++) { + if (!tegra186_gpio_is_accessible(gpio, j)) + clear_bit(j, valid_mask); + } + return 0; +} + +static int tegra186_gpio_set(struct gpio_chip *chip, unsigned int offset, + int level) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, offset); + if (WARN_ON(base == NULL)) + return -ENODEV; + + value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE); + if (level == 0) + value &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH; + else + value |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH; + + writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE); + + return 0; +} + static int tegra186_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { @@ -176,9 +297,12 @@ static int tegra186_gpio_direction_output(struct gpio_chip *chip, struct tegra_gpio *gpio = gpiochip_get_data(chip); void __iomem *base; u32 value; + int ret; /* configure output level first */ - chip->set(chip, offset, level); + ret = tegra186_gpio_set(chip, offset, level); + if (ret) + return ret; base = tegra186_gpio_get_base(gpio, offset); if (WARN_ON(base == NULL)) @@ -286,26 +410,6 @@ static int tegra186_gpio_get(struct gpio_chip *chip, unsigned int offset) return value & BIT(0); } -static void tegra186_gpio_set(struct gpio_chip *chip, unsigned int offset, - int level) -{ - struct tegra_gpio *gpio = gpiochip_get_data(chip); - void __iomem *base; - u32 value; - - base = tegra186_gpio_get_base(gpio, offset); - if (WARN_ON(base == NULL)) - return; - - value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE); - if (level == 0) - value &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH; - else - value |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH; - - writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE); -} - static int tegra186_gpio_set_config(struct gpio_chip *chip, unsigned int offset, unsigned long config) @@ -537,7 +641,7 @@ static void tegra186_irq_print_chip(struct irq_data *data, struct seq_file *p) { struct gpio_chip *gc = irq_data_get_irq_chip_data(data); - seq_printf(p, dev_name(gc->parent)); + seq_puts(p, dev_name(gc->parent)); } static const struct irq_chip tegra186_gpio_irq_chip = { @@ -669,13 +773,14 @@ static unsigned int tegra186_gpio_child_offset_to_irq(struct gpio_chip *chip, static const struct of_device_id tegra186_pmc_of_match[] = { { .compatible = "nvidia,tegra186-pmc" }, { .compatible = "nvidia,tegra194-pmc" }, + { .compatible = "nvidia,tegra234-pmc" }, { /* sentinel */ } }; static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) { struct device *dev = gpio->gpio.parent; - unsigned int i, j; + unsigned int i; u32 value; for (i = 0; i < gpio->soc->num_ports; i++) { @@ -697,27 +802,23 @@ static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) * On Tegra194 and later, each pin can be routed to one or more * interrupts. */ - for (j = 0; j < gpio->num_irqs_per_bank; j++) { - dev_dbg(dev, "programming default interrupt routing for port %s\n", - port->name); - - offset = TEGRA186_GPIO_INT_ROUTE_MAPPING(p, j); - - /* - * By default we only want to route GPIO pins to IRQ 0. This works - * only under the assumption that we're running as the host kernel - * and hence all GPIO pins are owned by Linux. - * - * For cases where Linux is the guest OS, the hypervisor will have - * to configure the interrupt routing and pass only the valid - * interrupts via device tree. - */ - if (j == 0) { - value = readl(base + offset); - value = BIT(port->pins) - 1; - writel(value, base + offset); - } - } + dev_dbg(dev, "programming default interrupt routing for port %s\n", + port->name); + + offset = TEGRA186_GPIO_INT_ROUTE_MAPPING(p, 0); + + /* + * By default we only want to route GPIO pins to IRQ 0. This works + * only under the assumption that we're running as the host kernel + * and hence all GPIO pins are owned by Linux. + * + * For cases where Linux is the guest OS, the hypervisor will have + * to configure the interrupt routing and pass only the valid + * interrupts via device tree. + */ + value = readl(base + offset); + value = BIT(port->pins) - 1; + writel(value, base + offset); } } } @@ -753,6 +854,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) struct gpio_irq_chip *irq; struct tegra_gpio *gpio; struct device_node *np; + struct resource *res; char **names; int err; @@ -772,19 +874,19 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->num_banks++; /* get register apertures */ - gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); - if (IS_ERR(gpio->secure)) { - gpio->secure = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(gpio->secure)) - return PTR_ERR(gpio->secure); - } - - gpio->base = devm_platform_ioremap_resource_byname(pdev, "gpio"); - if (IS_ERR(gpio->base)) { - gpio->base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(gpio->base)) - return PTR_ERR(gpio->base); - } + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "security"); + if (!res) + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + gpio->secure = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(gpio->secure)) + return PTR_ERR(gpio->secure); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio"); + if (!res) + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + gpio->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); err = platform_irq_count(pdev); if (err < 0) @@ -818,6 +920,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->gpio.set = tegra186_gpio_set; gpio->gpio.set_config = tegra186_gpio_set_config; gpio->gpio.add_pin_ranges = tegra186_gpio_add_pin_ranges; + gpio->gpio.init_valid_mask = tegra186_init_valid_mask; if (gpio->soc->has_gte) { gpio->gpio.en_hw_timestamp = tegra186_gpio_en_hw_ts; gpio->gpio.dis_hw_timestamp = tegra186_gpio_dis_hw_ts; @@ -838,8 +941,12 @@ static int tegra186_gpio_probe(struct platform_device *pdev) char *name; for (j = 0; j < port->pins; j++) { - name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, - "P%s.%02x", port->name, j); + if (gpio->soc->prefix) + name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s-P%s.%02x", + gpio->soc->prefix, port->name, j); + else + name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "P%s.%02x", + port->name, j); if (!name) return -ENOMEM; @@ -858,7 +965,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) irq = &gpio->gpio.irq; gpio_irq_chip_set_chip(irq, &tegra186_gpio_irq_chip); - irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); + irq->fwnode = dev_fwnode(&pdev->dev); irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq; irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec; irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq; @@ -896,11 +1003,15 @@ static int tegra186_gpio_probe(struct platform_device *pdev) np = of_find_matching_node(NULL, tegra186_pmc_of_match); if (np) { - irq->parent_domain = irq_find_host(np); - of_node_put(np); - - if (!irq->parent_domain) - return -EPROBE_DEFER; + if (of_device_is_available(np)) { + irq->parent_domain = irq_find_host(np); + of_node_put(np); + + if (!irq->parent_domain) + return -EPROBE_DEFER; + } else { + of_node_put(np); + } } irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio, @@ -920,14 +1031,17 @@ static int tegra186_gpio_probe(struct platform_device *pdev) return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio); } -#define TEGRA186_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA186_MAIN_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ +#define TEGRA_GPIO_PORT(_prefix, _name, _bank, _port, _pins) \ + [_prefix##_GPIO_PORT_##_name] = { \ + .name = #_name, \ + .bank = _bank, \ + .port = _port, \ + .pins = _pins, \ } +#define TEGRA186_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA186_MAIN, _name, _bank, _port, _pins) + static const struct tegra_gpio_port tegra186_main_ports[] = { TEGRA186_MAIN_GPIO_PORT( A, 2, 0, 7), TEGRA186_MAIN_GPIO_PORT( B, 3, 0, 7), @@ -960,15 +1074,11 @@ static const struct tegra_gpio_soc tegra186_main_soc = { .name = "tegra186-gpio", .instance = 0, .num_irqs_per_bank = 1, + .has_vm_support = false, }; -#define TEGRA186_AON_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA186_AON_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA186_AON_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA186_AON, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra186_aon_ports[] = { TEGRA186_AON_GPIO_PORT( S, 0, 1, 5), @@ -987,15 +1097,11 @@ static const struct tegra_gpio_soc tegra186_aon_soc = { .name = "tegra186-gpio-aon", .instance = 1, .num_irqs_per_bank = 1, + .has_vm_support = false, }; -#define TEGRA194_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA194_MAIN_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA194_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA194_MAIN, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra194_main_ports[] = { TEGRA194_MAIN_GPIO_PORT( A, 1, 2, 8), @@ -1042,15 +1148,11 @@ static const struct tegra_gpio_soc tegra194_main_soc = { .num_pin_ranges = ARRAY_SIZE(tegra194_main_pin_ranges), .pin_ranges = tegra194_main_pin_ranges, .pinmux = "nvidia,tegra194-pinmux", + .has_vm_support = true, }; -#define TEGRA194_AON_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA194_AON_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA194_AON_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA194_AON, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra194_aon_ports[] = { TEGRA194_AON_GPIO_PORT(AA, 0, 3, 8), @@ -1067,15 +1169,11 @@ static const struct tegra_gpio_soc tegra194_aon_soc = { .instance = 1, .num_irqs_per_bank = 8, .has_gte = true, + .has_vm_support = false, }; -#define TEGRA234_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA234_MAIN_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA234_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA234_MAIN, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra234_main_ports[] = { TEGRA234_MAIN_GPIO_PORT( A, 0, 0, 8), @@ -1111,15 +1209,11 @@ static const struct tegra_gpio_soc tegra234_main_soc = { .name = "tegra234-gpio", .instance = 0, .num_irqs_per_bank = 8, + .has_vm_support = true, }; -#define TEGRA234_AON_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA234_AON_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA234_AON_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA234_AON, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra234_aon_ports[] = { TEGRA234_AON_GPIO_PORT(AA, 0, 4, 8), @@ -1136,15 +1230,12 @@ static const struct tegra_gpio_soc tegra234_aon_soc = { .name = "tegra234-gpio-aon", .instance = 1, .num_irqs_per_bank = 8, + .has_gte = true, + .has_vm_support = false, }; -#define TEGRA241_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA241_MAIN_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA241_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA241_MAIN, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra241_main_ports[] = { TEGRA241_MAIN_GPIO_PORT(A, 0, 0, 8), @@ -1166,15 +1257,11 @@ static const struct tegra_gpio_soc tegra241_main_soc = { .name = "tegra241-gpio", .instance = 0, .num_irqs_per_bank = 8, + .has_vm_support = false, }; -#define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA241_AON_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } +#define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA241_AON, _name, _bank, _port, _pins) static const struct tegra_gpio_port tegra241_aon_ports[] = { TEGRA241_AON_GPIO_PORT(AA, 0, 0, 8), @@ -1187,6 +1274,76 @@ static const struct tegra_gpio_soc tegra241_aon_soc = { .name = "tegra241-gpio-aon", .instance = 1, .num_irqs_per_bank = 8, + .has_vm_support = false, +}; + +#define TEGRA256_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA256_MAIN, _name, _bank, _port, _pins) + +static const struct tegra_gpio_port tegra256_main_ports[] = { + TEGRA256_MAIN_GPIO_PORT(A, 0, 0, 8), + TEGRA256_MAIN_GPIO_PORT(B, 0, 1, 8), + TEGRA256_MAIN_GPIO_PORT(C, 0, 2, 8), + TEGRA256_MAIN_GPIO_PORT(D, 0, 3, 8), +}; + +static const struct tegra_gpio_soc tegra256_main_soc = { + .num_ports = ARRAY_SIZE(tegra256_main_ports), + .ports = tegra256_main_ports, + .name = "tegra256-gpio-main", + .instance = 1, + .num_irqs_per_bank = 8, + .has_vm_support = true, +}; + +#define TEGRA410_COMPUTE_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA410_COMPUTE, _name, _bank, _port, _pins) + +static const struct tegra_gpio_port tegra410_compute_ports[] = { + TEGRA410_COMPUTE_GPIO_PORT(A, 0, 0, 3), + TEGRA410_COMPUTE_GPIO_PORT(B, 1, 0, 8), + TEGRA410_COMPUTE_GPIO_PORT(C, 1, 1, 3), + TEGRA410_COMPUTE_GPIO_PORT(D, 2, 0, 8), + TEGRA410_COMPUTE_GPIO_PORT(E, 2, 1, 8), +}; + +static const struct tegra_gpio_soc tegra410_compute_soc = { + .num_ports = ARRAY_SIZE(tegra410_compute_ports), + .ports = tegra410_compute_ports, + .name = "tegra410-gpio-compute", + .prefix = "COMPUTE", + .num_irqs_per_bank = 8, + .instance = 0, +}; + +#define TEGRA410_SYSTEM_GPIO_PORT(_name, _bank, _port, _pins) \ + TEGRA_GPIO_PORT(TEGRA410_SYSTEM, _name, _bank, _port, _pins) + +static const struct tegra_gpio_port tegra410_system_ports[] = { + TEGRA410_SYSTEM_GPIO_PORT(A, 0, 0, 7), + TEGRA410_SYSTEM_GPIO_PORT(B, 0, 1, 8), + TEGRA410_SYSTEM_GPIO_PORT(C, 0, 2, 8), + TEGRA410_SYSTEM_GPIO_PORT(D, 0, 3, 8), + TEGRA410_SYSTEM_GPIO_PORT(E, 0, 4, 6), + TEGRA410_SYSTEM_GPIO_PORT(I, 1, 0, 8), + TEGRA410_SYSTEM_GPIO_PORT(J, 1, 1, 7), + TEGRA410_SYSTEM_GPIO_PORT(K, 1, 2, 7), + TEGRA410_SYSTEM_GPIO_PORT(L, 1, 3, 7), + TEGRA410_SYSTEM_GPIO_PORT(M, 2, 0, 7), + TEGRA410_SYSTEM_GPIO_PORT(N, 2, 1, 6), + TEGRA410_SYSTEM_GPIO_PORT(P, 2, 2, 8), + TEGRA410_SYSTEM_GPIO_PORT(Q, 2, 3, 3), + TEGRA410_SYSTEM_GPIO_PORT(R, 2, 4, 2), + TEGRA410_SYSTEM_GPIO_PORT(V, 1, 4, 2), +}; + +static const struct tegra_gpio_soc tegra410_system_soc = { + .num_ports = ARRAY_SIZE(tegra410_system_ports), + .ports = tegra410_system_ports, + .name = "tegra410-gpio-system", + .prefix = "SYSTEM", + .num_irqs_per_bank = 8, + .instance = 0, }; static const struct of_device_id tegra186_gpio_of_match[] = { @@ -1209,6 +1366,9 @@ static const struct of_device_id tegra186_gpio_of_match[] = { .compatible = "nvidia,tegra234-gpio-aon", .data = &tegra234_aon_soc }, { + .compatible = "nvidia,tegra256-gpio", + .data = &tegra256_main_soc + }, { /* sentinel */ } }; @@ -1221,6 +1381,8 @@ static const struct acpi_device_id tegra186_gpio_acpi_match[] = { { .id = "NVDA0408", .driver_data = (kernel_ulong_t)&tegra194_aon_soc }, { .id = "NVDA0508", .driver_data = (kernel_ulong_t)&tegra241_main_soc }, { .id = "NVDA0608", .driver_data = (kernel_ulong_t)&tegra241_aon_soc }, + { .id = "NVDA0708", .driver_data = (kernel_ulong_t)&tegra410_compute_soc }, + { .id = "NVDA0808", .driver_data = (kernel_ulong_t)&tegra410_system_soc }, {} }; MODULE_DEVICE_TABLE(acpi, tegra186_gpio_acpi_match); |
