Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: tangier: Introduce Intel Tangier GPIO driver

Intel Elkhart Lake and Merrifield platforms have same GPIO IP.
Intel Tangier implements the common GPIO functionalities for both
Elkhart Lake and Merrifield platforms.

Signed-off-by: Pandith N <pandith.n@intel.com>
Co-developed-by: Raag Jadav <raag.jadav@intel.com>
Signed-off-by: Raag Jadav <raag.jadav@intel.com>
Co-developed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

authored by

Pandith N and committed by
Andy Shevchenko
d2c19e89 380c7ba3

+653
+1
MAINTAINERS
··· 10287 10287 F: drivers/gpio/gpio-pch.c 10288 10288 F: drivers/gpio/gpio-sch.c 10289 10289 F: drivers/gpio/gpio-sodaville.c 10290 + F: drivers/gpio/gpio-tangier.c 10290 10291 10291 10292 INTEL GVT-g DRIVERS (Intel GPU Virtualization) 10292 10293 M: Zhenyu Wang <zhenyuw@linux.intel.com>
+8
drivers/gpio/Kconfig
··· 619 619 help 620 620 Say yes here to support GPIO functionality though SYSCON driver. 621 621 622 + config GPIO_TANGIER 623 + tristate 624 + select GPIOLIB_IRQCHIP 625 + help 626 + GPIO support for Intel Tangier and compatible platforms. 627 + 628 + If built as a module its name will be gpio-tangier. 629 + 622 630 config GPIO_TB10X 623 631 bool 624 632 select GPIO_GENERIC
+1
drivers/gpio/Makefile
··· 145 145 obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o 146 146 obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o 147 147 obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o 148 + obj-$(CONFIG_GPIO_TANGIER) += gpio-tangier.o 148 149 obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o 149 150 obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o 150 151 obj-$(CONFIG_GPIO_TEGRA186) += gpio-tegra186.o
+536
drivers/gpio/gpio-tangier.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Intel Tangier GPIO driver 4 + * 5 + * Copyright (c) 2016, 2021, 2023 Intel Corporation. 6 + * 7 + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 + * Pandith N <pandith.n@intel.com> 9 + * Raag Jadav <raag.jadav@intel.com> 10 + */ 11 + 12 + #include <linux/bitops.h> 13 + #include <linux/device.h> 14 + #include <linux/errno.h> 15 + #include <linux/export.h> 16 + #include <linux/interrupt.h> 17 + #include <linux/io.h> 18 + #include <linux/irq.h> 19 + #include <linux/module.h> 20 + #include <linux/pinctrl/pinconf-generic.h> 21 + #include <linux/spinlock.h> 22 + #include <linux/string_helpers.h> 23 + #include <linux/types.h> 24 + 25 + #include <linux/gpio/driver.h> 26 + 27 + #include "gpio-tangier.h" 28 + 29 + #define GCCR 0x000 /* Controller configuration */ 30 + #define GPLR 0x004 /* Pin level r/o */ 31 + #define GPDR 0x01c /* Pin direction */ 32 + #define GPSR 0x034 /* Pin set w/o */ 33 + #define GPCR 0x04c /* Pin clear w/o */ 34 + #define GRER 0x064 /* Rising edge detect */ 35 + #define GFER 0x07c /* Falling edge detect */ 36 + #define GFBR 0x094 /* Glitch filter bypass */ 37 + #define GIMR 0x0ac /* Interrupt mask */ 38 + #define GISR 0x0c4 /* Interrupt source */ 39 + #define GITR 0x300 /* Input type */ 40 + #define GLPR 0x318 /* Level input polarity */ 41 + 42 + /** 43 + * struct tng_gpio_context - Context to be saved during suspend-resume 44 + * @level: Pin level 45 + * @gpdr: Pin direction 46 + * @grer: Rising edge detect enable 47 + * @gfer: Falling edge detect enable 48 + * @gimr: Interrupt mask 49 + * @gwmr: Wake mask 50 + */ 51 + struct tng_gpio_context { 52 + u32 level; 53 + u32 gpdr; 54 + u32 grer; 55 + u32 gfer; 56 + u32 gimr; 57 + u32 gwmr; 58 + }; 59 + 60 + static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned int offset, 61 + unsigned int reg) 62 + { 63 + struct tng_gpio *priv = gpiochip_get_data(chip); 64 + u8 reg_offset = offset / 32; 65 + 66 + return priv->reg_base + reg + reg_offset * 4; 67 + } 68 + 69 + static void __iomem *gpio_reg_and_bit(struct gpio_chip *chip, unsigned int offset, 70 + unsigned int reg, u8 *bit) 71 + { 72 + struct tng_gpio *priv = gpiochip_get_data(chip); 73 + u8 reg_offset = offset / 32; 74 + u8 shift = offset % 32; 75 + 76 + *bit = shift; 77 + return priv->reg_base + reg + reg_offset * 4; 78 + } 79 + 80 + static int tng_gpio_get(struct gpio_chip *chip, unsigned int offset) 81 + { 82 + void __iomem *gplr; 83 + u8 shift; 84 + 85 + gplr = gpio_reg_and_bit(chip, offset, GPLR, &shift); 86 + 87 + return !!(readl(gplr) & BIT(shift)); 88 + } 89 + 90 + static void tng_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 91 + { 92 + struct tng_gpio *priv = gpiochip_get_data(chip); 93 + unsigned long flags; 94 + void __iomem *reg; 95 + u8 shift; 96 + 97 + reg = gpio_reg_and_bit(chip, offset, value ? GPSR : GPCR, &shift); 98 + 99 + raw_spin_lock_irqsave(&priv->lock, flags); 100 + 101 + writel(BIT(shift), reg); 102 + 103 + raw_spin_unlock_irqrestore(&priv->lock, flags); 104 + } 105 + 106 + static int tng_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 107 + { 108 + struct tng_gpio *priv = gpiochip_get_data(chip); 109 + unsigned long flags; 110 + void __iomem *gpdr; 111 + u32 value; 112 + u8 shift; 113 + 114 + gpdr = gpio_reg_and_bit(chip, offset, GPDR, &shift); 115 + 116 + raw_spin_lock_irqsave(&priv->lock, flags); 117 + 118 + value = readl(gpdr); 119 + value &= ~BIT(shift); 120 + writel(value, gpdr); 121 + 122 + raw_spin_unlock_irqrestore(&priv->lock, flags); 123 + 124 + return 0; 125 + } 126 + 127 + static int tng_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, 128 + int value) 129 + { 130 + struct tng_gpio *priv = gpiochip_get_data(chip); 131 + unsigned long flags; 132 + void __iomem *gpdr; 133 + u8 shift; 134 + 135 + gpdr = gpio_reg_and_bit(chip, offset, GPDR, &shift); 136 + tng_gpio_set(chip, offset, value); 137 + 138 + raw_spin_lock_irqsave(&priv->lock, flags); 139 + 140 + value = readl(gpdr); 141 + value |= BIT(shift); 142 + writel(value, gpdr); 143 + 144 + raw_spin_unlock_irqrestore(&priv->lock, flags); 145 + 146 + return 0; 147 + } 148 + 149 + static int tng_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 150 + { 151 + void __iomem *gpdr; 152 + u8 shift; 153 + 154 + gpdr = gpio_reg_and_bit(chip, offset, GPDR, &shift); 155 + 156 + if (readl(gpdr) & BIT(shift)) 157 + return GPIO_LINE_DIRECTION_OUT; 158 + 159 + return GPIO_LINE_DIRECTION_IN; 160 + } 161 + 162 + static int tng_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset, 163 + unsigned int debounce) 164 + { 165 + struct tng_gpio *priv = gpiochip_get_data(chip); 166 + unsigned long flags; 167 + void __iomem *gfbr; 168 + u32 value; 169 + u8 shift; 170 + 171 + gfbr = gpio_reg_and_bit(chip, offset, GFBR, &shift); 172 + 173 + raw_spin_lock_irqsave(&priv->lock, flags); 174 + 175 + value = readl(gfbr); 176 + if (debounce) 177 + value &= ~BIT(shift); 178 + else 179 + value |= BIT(shift); 180 + writel(value, gfbr); 181 + 182 + raw_spin_unlock_irqrestore(&priv->lock, flags); 183 + 184 + return 0; 185 + } 186 + 187 + static int tng_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 188 + unsigned long config) 189 + { 190 + u32 debounce; 191 + 192 + switch (pinconf_to_config_param(config)) { 193 + case PIN_CONFIG_BIAS_DISABLE: 194 + case PIN_CONFIG_BIAS_PULL_UP: 195 + case PIN_CONFIG_BIAS_PULL_DOWN: 196 + return gpiochip_generic_config(chip, offset, config); 197 + case PIN_CONFIG_INPUT_DEBOUNCE: 198 + debounce = pinconf_to_config_argument(config); 199 + return tng_gpio_set_debounce(chip, offset, debounce); 200 + default: 201 + return -ENOTSUPP; 202 + } 203 + } 204 + 205 + static void tng_irq_ack(struct irq_data *d) 206 + { 207 + struct tng_gpio *priv = irq_data_get_irq_chip_data(d); 208 + irq_hw_number_t gpio = irqd_to_hwirq(d); 209 + unsigned long flags; 210 + void __iomem *gisr; 211 + u8 shift; 212 + 213 + gisr = gpio_reg_and_bit(&priv->chip, gpio, GISR, &shift); 214 + 215 + raw_spin_lock_irqsave(&priv->lock, flags); 216 + writel(BIT(shift), gisr); 217 + raw_spin_unlock_irqrestore(&priv->lock, flags); 218 + } 219 + 220 + static void tng_irq_unmask_mask(struct tng_gpio *priv, u32 gpio, bool unmask) 221 + { 222 + unsigned long flags; 223 + void __iomem *gimr; 224 + u32 value; 225 + u8 shift; 226 + 227 + gimr = gpio_reg_and_bit(&priv->chip, gpio, GIMR, &shift); 228 + 229 + raw_spin_lock_irqsave(&priv->lock, flags); 230 + 231 + value = readl(gimr); 232 + if (unmask) 233 + value |= BIT(shift); 234 + else 235 + value &= ~BIT(shift); 236 + writel(value, gimr); 237 + 238 + raw_spin_unlock_irqrestore(&priv->lock, flags); 239 + } 240 + 241 + static void tng_irq_mask(struct irq_data *d) 242 + { 243 + struct tng_gpio *priv = irq_data_get_irq_chip_data(d); 244 + irq_hw_number_t gpio = irqd_to_hwirq(d); 245 + 246 + tng_irq_unmask_mask(priv, gpio, false); 247 + gpiochip_disable_irq(&priv->chip, gpio); 248 + } 249 + 250 + static void tng_irq_unmask(struct irq_data *d) 251 + { 252 + struct tng_gpio *priv = irq_data_get_irq_chip_data(d); 253 + irq_hw_number_t gpio = irqd_to_hwirq(d); 254 + 255 + gpiochip_enable_irq(&priv->chip, gpio); 256 + tng_irq_unmask_mask(priv, gpio, true); 257 + } 258 + 259 + static int tng_irq_set_type(struct irq_data *d, unsigned int type) 260 + { 261 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 262 + struct tng_gpio *priv = gpiochip_get_data(gc); 263 + irq_hw_number_t gpio = irqd_to_hwirq(d); 264 + void __iomem *grer = gpio_reg(&priv->chip, gpio, GRER); 265 + void __iomem *gfer = gpio_reg(&priv->chip, gpio, GFER); 266 + void __iomem *gitr = gpio_reg(&priv->chip, gpio, GITR); 267 + void __iomem *glpr = gpio_reg(&priv->chip, gpio, GLPR); 268 + u8 shift = gpio % 32; 269 + unsigned long flags; 270 + u32 value; 271 + 272 + raw_spin_lock_irqsave(&priv->lock, flags); 273 + 274 + value = readl(grer); 275 + if (type & IRQ_TYPE_EDGE_RISING) 276 + value |= BIT(shift); 277 + else 278 + value &= ~BIT(shift); 279 + writel(value, grer); 280 + 281 + value = readl(gfer); 282 + if (type & IRQ_TYPE_EDGE_FALLING) 283 + value |= BIT(shift); 284 + else 285 + value &= ~BIT(shift); 286 + writel(value, gfer); 287 + 288 + /* 289 + * To prevent glitches from triggering an unintended level interrupt, 290 + * configure GLPR register first and then configure GITR. 291 + */ 292 + value = readl(glpr); 293 + if (type & IRQ_TYPE_LEVEL_LOW) 294 + value |= BIT(shift); 295 + else 296 + value &= ~BIT(shift); 297 + writel(value, glpr); 298 + 299 + if (type & IRQ_TYPE_LEVEL_MASK) { 300 + value = readl(gitr); 301 + value |= BIT(shift); 302 + writel(value, gitr); 303 + 304 + irq_set_handler_locked(d, handle_level_irq); 305 + } else if (type & IRQ_TYPE_EDGE_BOTH) { 306 + value = readl(gitr); 307 + value &= ~BIT(shift); 308 + writel(value, gitr); 309 + 310 + irq_set_handler_locked(d, handle_edge_irq); 311 + } 312 + 313 + raw_spin_unlock_irqrestore(&priv->lock, flags); 314 + 315 + return 0; 316 + } 317 + 318 + static int tng_irq_set_wake(struct irq_data *d, unsigned int on) 319 + { 320 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 321 + struct tng_gpio *priv = gpiochip_get_data(gc); 322 + irq_hw_number_t gpio = irqd_to_hwirq(d); 323 + void __iomem *gwmr = gpio_reg(&priv->chip, gpio, priv->wake_regs.gwmr); 324 + void __iomem *gwsr = gpio_reg(&priv->chip, gpio, priv->wake_regs.gwsr); 325 + u8 shift = gpio % 32; 326 + unsigned long flags; 327 + u32 value; 328 + 329 + raw_spin_lock_irqsave(&priv->lock, flags); 330 + 331 + /* Clear the existing wake status */ 332 + writel(BIT(shift), gwsr); 333 + 334 + value = readl(gwmr); 335 + if (on) 336 + value |= BIT(shift); 337 + else 338 + value &= ~BIT(shift); 339 + writel(value, gwmr); 340 + 341 + raw_spin_unlock_irqrestore(&priv->lock, flags); 342 + 343 + dev_dbg(priv->dev, "%s wake for gpio %lu\n", str_enable_disable(on), gpio); 344 + return 0; 345 + } 346 + 347 + static const struct irq_chip tng_irqchip = { 348 + .name = "gpio-tangier", 349 + .irq_ack = tng_irq_ack, 350 + .irq_mask = tng_irq_mask, 351 + .irq_unmask = tng_irq_unmask, 352 + .irq_set_type = tng_irq_set_type, 353 + .irq_set_wake = tng_irq_set_wake, 354 + .flags = IRQCHIP_IMMUTABLE, 355 + GPIOCHIP_IRQ_RESOURCE_HELPERS, 356 + }; 357 + 358 + static void tng_irq_handler(struct irq_desc *desc) 359 + { 360 + struct gpio_chip *gc = irq_desc_get_handler_data(desc); 361 + struct tng_gpio *priv = gpiochip_get_data(gc); 362 + struct irq_chip *irqchip = irq_desc_get_chip(desc); 363 + unsigned long base, gpio; 364 + 365 + chained_irq_enter(irqchip, desc); 366 + 367 + /* Check GPIO controller to check which pin triggered the interrupt */ 368 + for (base = 0; base < priv->chip.ngpio; base += 32) { 369 + void __iomem *gisr = gpio_reg(&priv->chip, base, GISR); 370 + void __iomem *gimr = gpio_reg(&priv->chip, base, GIMR); 371 + unsigned long pending, enabled; 372 + 373 + pending = readl(gisr); 374 + enabled = readl(gimr); 375 + 376 + /* Only interrupts that are enabled */ 377 + pending &= enabled; 378 + 379 + for_each_set_bit(gpio, &pending, 32) 380 + generic_handle_domain_irq(gc->irq.domain, base + gpio); 381 + } 382 + 383 + chained_irq_exit(irqchip, desc); 384 + } 385 + 386 + static int tng_irq_init_hw(struct gpio_chip *chip) 387 + { 388 + struct tng_gpio *priv = gpiochip_get_data(chip); 389 + void __iomem *reg; 390 + unsigned int base; 391 + 392 + for (base = 0; base < priv->chip.ngpio; base += 32) { 393 + /* Clear the rising-edge detect register */ 394 + reg = gpio_reg(&priv->chip, base, GRER); 395 + writel(0, reg); 396 + 397 + /* Clear the falling-edge detect register */ 398 + reg = gpio_reg(&priv->chip, base, GFER); 399 + writel(0, reg); 400 + } 401 + 402 + return 0; 403 + } 404 + 405 + static int tng_gpio_add_pin_ranges(struct gpio_chip *chip) 406 + { 407 + struct tng_gpio *priv = gpiochip_get_data(chip); 408 + const struct tng_gpio_pinrange *range; 409 + unsigned int i; 410 + int ret; 411 + 412 + for (i = 0; i < priv->pin_info.nranges; i++) { 413 + range = &priv->pin_info.pin_ranges[i]; 414 + ret = gpiochip_add_pin_range(&priv->chip, 415 + priv->pin_info.name, 416 + range->gpio_base, 417 + range->pin_base, 418 + range->npins); 419 + if (ret) { 420 + dev_err(priv->dev, "failed to add GPIO pin range\n"); 421 + return ret; 422 + } 423 + } 424 + 425 + return 0; 426 + } 427 + 428 + int devm_tng_gpio_probe(struct device *dev, struct tng_gpio *gpio) 429 + { 430 + const struct tng_gpio_info *info = &gpio->info; 431 + struct gpio_irq_chip *girq; 432 + int ret; 433 + 434 + gpio->ctx = devm_kcalloc(dev, DIV_ROUND_UP(info->ngpio, 32), sizeof(*gpio->ctx), GFP_KERNEL); 435 + if (!gpio->ctx) 436 + return -ENOMEM; 437 + 438 + gpio->chip.label = dev_name(dev); 439 + gpio->chip.parent = dev; 440 + gpio->chip.request = gpiochip_generic_request; 441 + gpio->chip.free = gpiochip_generic_free; 442 + gpio->chip.direction_input = tng_gpio_direction_input; 443 + gpio->chip.direction_output = tng_gpio_direction_output; 444 + gpio->chip.get = tng_gpio_get; 445 + gpio->chip.set = tng_gpio_set; 446 + gpio->chip.get_direction = tng_gpio_get_direction; 447 + gpio->chip.set_config = tng_gpio_set_config; 448 + gpio->chip.base = info->base; 449 + gpio->chip.ngpio = info->ngpio; 450 + gpio->chip.can_sleep = false; 451 + gpio->chip.add_pin_ranges = tng_gpio_add_pin_ranges; 452 + 453 + raw_spin_lock_init(&gpio->lock); 454 + 455 + girq = &gpio->chip.irq; 456 + gpio_irq_chip_set_chip(girq, &tng_irqchip); 457 + girq->init_hw = tng_irq_init_hw; 458 + girq->parent_handler = tng_irq_handler; 459 + girq->num_parents = 1; 460 + girq->parents = devm_kcalloc(dev, girq->num_parents, 461 + sizeof(*girq->parents), GFP_KERNEL); 462 + if (!girq->parents) 463 + return -ENOMEM; 464 + 465 + girq->parents[0] = gpio->irq; 466 + girq->first = info->first; 467 + girq->default_type = IRQ_TYPE_NONE; 468 + girq->handler = handle_bad_irq; 469 + 470 + ret = devm_gpiochip_add_data(dev, &gpio->chip, gpio); 471 + if (ret) 472 + return dev_err_probe(dev, ret, "gpiochip_add error\n"); 473 + 474 + return 0; 475 + } 476 + EXPORT_SYMBOL_NS_GPL(devm_tng_gpio_probe, GPIO_TANGIER); 477 + 478 + int tng_gpio_suspend(struct device *dev) 479 + { 480 + struct tng_gpio *priv = dev_get_drvdata(dev); 481 + struct tng_gpio_context *ctx = priv->ctx; 482 + unsigned long flags; 483 + unsigned int base; 484 + 485 + raw_spin_lock_irqsave(&priv->lock, flags); 486 + 487 + for (base = 0; base < priv->chip.ngpio; base += 32, ctx++) { 488 + /* GPLR is RO, values read will be restored using GPSR */ 489 + ctx->level = readl(gpio_reg(&priv->chip, base, GPLR)); 490 + 491 + ctx->gpdr = readl(gpio_reg(&priv->chip, base, GPDR)); 492 + ctx->grer = readl(gpio_reg(&priv->chip, base, GRER)); 493 + ctx->gfer = readl(gpio_reg(&priv->chip, base, GFER)); 494 + ctx->gimr = readl(gpio_reg(&priv->chip, base, GIMR)); 495 + 496 + ctx->gwmr = readl(gpio_reg(&priv->chip, base, priv->wake_regs.gwmr)); 497 + } 498 + 499 + raw_spin_unlock_irqrestore(&priv->lock, flags); 500 + 501 + return 0; 502 + } 503 + EXPORT_SYMBOL_NS_GPL(tng_gpio_suspend, GPIO_TANGIER); 504 + 505 + int tng_gpio_resume(struct device *dev) 506 + { 507 + struct tng_gpio *priv = dev_get_drvdata(dev); 508 + struct tng_gpio_context *ctx = priv->ctx; 509 + unsigned long flags; 510 + unsigned int base; 511 + 512 + raw_spin_lock_irqsave(&priv->lock, flags); 513 + 514 + for (base = 0; base < priv->chip.ngpio; base += 32, ctx++) { 515 + /* GPLR is RO, values read will be restored using GPSR */ 516 + writel(ctx->level, gpio_reg(&priv->chip, base, GPSR)); 517 + 518 + writel(ctx->gpdr, gpio_reg(&priv->chip, base, GPDR)); 519 + writel(ctx->grer, gpio_reg(&priv->chip, base, GRER)); 520 + writel(ctx->gfer, gpio_reg(&priv->chip, base, GFER)); 521 + writel(ctx->gimr, gpio_reg(&priv->chip, base, GIMR)); 522 + 523 + writel(ctx->gwmr, gpio_reg(&priv->chip, base, priv->wake_regs.gwmr)); 524 + } 525 + 526 + raw_spin_unlock_irqrestore(&priv->lock, flags); 527 + 528 + return 0; 529 + } 530 + EXPORT_SYMBOL_NS_GPL(tng_gpio_resume, GPIO_TANGIER); 531 + 532 + MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); 533 + MODULE_AUTHOR("Pandith N <pandith.n@intel.com>"); 534 + MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>"); 535 + MODULE_DESCRIPTION("Intel Tangier GPIO driver"); 536 + MODULE_LICENSE("GPL");
+107
drivers/gpio/gpio-tangier.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Intel Tangier GPIO functions 4 + * 5 + * Copyright (c) 2016, 2021, 2023 Intel Corporation. 6 + * 7 + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 + * Pandith N <pandith.n@intel.com> 9 + * Raag Jadav <raag.jadav@intel.com> 10 + */ 11 + 12 + #ifndef _GPIO_TANGIER_H_ 13 + #define _GPIO_TANGIER_H_ 14 + 15 + #include <linux/gpio/driver.h> 16 + #include <linux/spinlock_types.h> 17 + #include <linux/types.h> 18 + 19 + struct device; 20 + 21 + struct tng_gpio_context; 22 + 23 + /** 24 + * struct tng_wake_regs - Platform specific wake registers 25 + * @gwmr: Wake mask 26 + * @gwsr: Wake source 27 + * @gsir: Secure input 28 + */ 29 + struct tng_wake_regs { 30 + u32 gwmr; 31 + u32 gwsr; 32 + u32 gsir; 33 + }; 34 + 35 + /** 36 + * struct tng_gpio_pinrange - Map pin numbers to gpio numbers 37 + * @gpio_base: Starting GPIO number of this range 38 + * @pin_base: Starting pin number of this range 39 + * @npins: Number of pins in this range 40 + */ 41 + struct tng_gpio_pinrange { 42 + unsigned int gpio_base; 43 + unsigned int pin_base; 44 + unsigned int npins; 45 + }; 46 + 47 + #define GPIO_PINRANGE(gstart, gend, pstart) \ 48 + (struct tng_gpio_pinrange) { \ 49 + .gpio_base = (gstart), \ 50 + .pin_base = (pstart), \ 51 + .npins = (gend) - (gstart) + 1, \ 52 + } 53 + 54 + /** 55 + * struct tng_gpio_pin_info - Platform specific pinout information 56 + * @pin_ranges: Pin to GPIO mapping 57 + * @nranges: Number of pin ranges 58 + * @name: Respective pinctrl device name 59 + */ 60 + struct tng_gpio_pin_info { 61 + const struct tng_gpio_pinrange *pin_ranges; 62 + unsigned int nranges; 63 + const char *name; 64 + }; 65 + 66 + /** 67 + * struct tng_gpio_info - Platform specific GPIO and IRQ information 68 + * @base: GPIO base to start numbering with 69 + * @ngpio: Amount of GPIOs supported by the controller 70 + * @first: First IRQ to start numbering with 71 + */ 72 + struct tng_gpio_info { 73 + int base; 74 + u16 ngpio; 75 + unsigned int first; 76 + }; 77 + 78 + /** 79 + * struct tng_gpio - Platform specific private data 80 + * @chip: Instance of the struct gpio_chip 81 + * @reg_base: Base address of MMIO registers 82 + * @irq: Interrupt for the GPIO device 83 + * @lock: Synchronization lock to prevent I/O race conditions 84 + * @dev: The GPIO device 85 + * @ctx: Context to be saved during suspend-resume 86 + * @wake_regs: Platform specific wake registers 87 + * @pin_info: Platform specific pinout information 88 + * @info: Platform specific GPIO and IRQ information 89 + */ 90 + struct tng_gpio { 91 + struct gpio_chip chip; 92 + void __iomem *reg_base; 93 + int irq; 94 + raw_spinlock_t lock; 95 + struct device *dev; 96 + struct tng_gpio_context *ctx; 97 + struct tng_wake_regs wake_regs; 98 + struct tng_gpio_pin_info pin_info; 99 + struct tng_gpio_info info; 100 + }; 101 + 102 + int devm_tng_gpio_probe(struct device *dev, struct tng_gpio *gpio); 103 + 104 + int tng_gpio_suspend(struct device *dev); 105 + int tng_gpio_resume(struct device *dev); 106 + 107 + #endif /* _GPIO_TANGIER_H_ */