1/* 2 * Copyright (C) 2014-2015 Broadcom Corporation 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation version 2. 7 * 8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 * kind, whether express or implied; without even the implied warranty 10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * This file contains the Broadcom Cygnus GPIO driver that supports 3 14 * GPIO controllers on Cygnus including the ASIU GPIO controller, the 15 * chipCommonG GPIO controller, and the always-on GPIO controller. Basic 16 * PINCONF such as bias pull up/down, and drive strength are also supported 17 * in this driver. 18 * 19 * Pins from the ASIU GPIO can be individually muxed to GPIO function, 20 * through the interaction with the Cygnus IOMUX controller 21 */ 22 23#include <linux/kernel.h> 24#include <linux/slab.h> 25#include <linux/interrupt.h> 26#include <linux/io.h> 27#include <linux/gpio.h> 28#include <linux/ioport.h> 29#include <linux/of_device.h> 30#include <linux/of_irq.h> 31#include <linux/pinctrl/pinctrl.h> 32#include <linux/pinctrl/pinconf.h> 33#include <linux/pinctrl/pinconf-generic.h> 34 35#include "../pinctrl-utils.h" 36 37#define CYGNUS_GPIO_DATA_IN_OFFSET 0x00 38#define CYGNUS_GPIO_DATA_OUT_OFFSET 0x04 39#define CYGNUS_GPIO_OUT_EN_OFFSET 0x08 40#define CYGNUS_GPIO_INT_TYPE_OFFSET 0x0c 41#define CYGNUS_GPIO_INT_DE_OFFSET 0x10 42#define CYGNUS_GPIO_INT_EDGE_OFFSET 0x14 43#define CYGNUS_GPIO_INT_MSK_OFFSET 0x18 44#define CYGNUS_GPIO_INT_STAT_OFFSET 0x1c 45#define CYGNUS_GPIO_INT_MSTAT_OFFSET 0x20 46#define CYGNUS_GPIO_INT_CLR_OFFSET 0x24 47#define CYGNUS_GPIO_PAD_RES_OFFSET 0x34 48#define CYGNUS_GPIO_RES_EN_OFFSET 0x38 49 50/* drive strength control for ASIU GPIO */ 51#define CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58 52 53/* drive strength control for CCM/CRMU (AON) GPIO */ 54#define CYGNUS_GPIO_DRV0_CTRL_OFFSET 0x00 55 56#define GPIO_BANK_SIZE 0x200 57#define NGPIOS_PER_BANK 32 58#define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK) 59 60#define CYGNUS_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg)) 61#define CYGNUS_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK) 62 63#define GPIO_DRV_STRENGTH_BIT_SHIFT 20 64#define GPIO_DRV_STRENGTH_BITS 3 65#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1) 66 67/* 68 * Cygnus GPIO core 69 * 70 * @dev: pointer to device 71 * @base: I/O register base for Cygnus GPIO controller 72 * @io_ctrl: I/O register base for certain type of Cygnus GPIO controller that 73 * has the PINCONF support implemented outside of the GPIO block 74 * @lock: lock to protect access to I/O registers 75 * @gc: GPIO chip 76 * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs 77 * @pinmux_is_supported: flag to indicate this GPIO controller contains pins 78 * that can be individually muxed to GPIO 79 * @pctl: pointer to pinctrl_dev 80 * @pctldesc: pinctrl descriptor 81 */ 82struct cygnus_gpio { 83 struct device *dev; 84 85 void __iomem *base; 86 void __iomem *io_ctrl; 87 88 spinlock_t lock; 89 90 struct gpio_chip gc; 91 unsigned num_banks; 92 93 bool pinmux_is_supported; 94 95 struct pinctrl_dev *pctl; 96 struct pinctrl_desc pctldesc; 97}; 98 99static inline struct cygnus_gpio *to_cygnus_gpio(struct gpio_chip *gc) 100{ 101 return container_of(gc, struct cygnus_gpio, gc); 102} 103 104/* 105 * Mapping from PINCONF pins to GPIO pins is 1-to-1 106 */ 107static inline unsigned cygnus_pin_to_gpio(unsigned pin) 108{ 109 return pin; 110} 111 112/** 113 * cygnus_set_bit - set or clear one bit (corresponding to the GPIO pin) in a 114 * Cygnus GPIO register 115 * 116 * @cygnus_gpio: Cygnus GPIO device 117 * @reg: register offset 118 * @gpio: GPIO pin 119 * @set: set or clear 120 */ 121static inline void cygnus_set_bit(struct cygnus_gpio *chip, unsigned int reg, 122 unsigned gpio, bool set) 123{ 124 unsigned int offset = CYGNUS_GPIO_REG(gpio, reg); 125 unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); 126 u32 val; 127 128 val = readl(chip->base + offset); 129 if (set) 130 val |= BIT(shift); 131 else 132 val &= ~BIT(shift); 133 writel(val, chip->base + offset); 134} 135 136static inline bool cygnus_get_bit(struct cygnus_gpio *chip, unsigned int reg, 137 unsigned gpio) 138{ 139 unsigned int offset = CYGNUS_GPIO_REG(gpio, reg); 140 unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); 141 142 return !!(readl(chip->base + offset) & BIT(shift)); 143} 144 145static void cygnus_gpio_irq_handler(struct irq_desc *desc) 146{ 147 struct gpio_chip *gc = irq_desc_get_handler_data(desc); 148 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 149 struct irq_chip *irq_chip = irq_desc_get_chip(desc); 150 int i, bit; 151 152 chained_irq_enter(irq_chip, desc); 153 154 /* go through the entire GPIO banks and handle all interrupts */ 155 for (i = 0; i < chip->num_banks; i++) { 156 unsigned long val = readl(chip->base + (i * GPIO_BANK_SIZE) + 157 CYGNUS_GPIO_INT_MSTAT_OFFSET); 158 159 for_each_set_bit(bit, &val, NGPIOS_PER_BANK) { 160 unsigned pin = NGPIOS_PER_BANK * i + bit; 161 int child_irq = irq_find_mapping(gc->irqdomain, pin); 162 163 /* 164 * Clear the interrupt before invoking the 165 * handler, so we do not leave any window 166 */ 167 writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) + 168 CYGNUS_GPIO_INT_CLR_OFFSET); 169 170 generic_handle_irq(child_irq); 171 } 172 } 173 174 chained_irq_exit(irq_chip, desc); 175} 176 177 178static void cygnus_gpio_irq_ack(struct irq_data *d) 179{ 180 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 181 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 182 unsigned gpio = d->hwirq; 183 unsigned int offset = CYGNUS_GPIO_REG(gpio, 184 CYGNUS_GPIO_INT_CLR_OFFSET); 185 unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); 186 u32 val = BIT(shift); 187 188 writel(val, chip->base + offset); 189} 190 191/** 192 * cygnus_gpio_irq_set_mask - mask/unmask a GPIO interrupt 193 * 194 * @d: IRQ chip data 195 * @unmask: mask/unmask GPIO interrupt 196 */ 197static void cygnus_gpio_irq_set_mask(struct irq_data *d, bool unmask) 198{ 199 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 200 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 201 unsigned gpio = d->hwirq; 202 203 cygnus_set_bit(chip, CYGNUS_GPIO_INT_MSK_OFFSET, gpio, unmask); 204} 205 206static void cygnus_gpio_irq_mask(struct irq_data *d) 207{ 208 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 209 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 210 unsigned long flags; 211 212 spin_lock_irqsave(&chip->lock, flags); 213 cygnus_gpio_irq_set_mask(d, false); 214 spin_unlock_irqrestore(&chip->lock, flags); 215} 216 217static void cygnus_gpio_irq_unmask(struct irq_data *d) 218{ 219 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 220 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 221 unsigned long flags; 222 223 spin_lock_irqsave(&chip->lock, flags); 224 cygnus_gpio_irq_set_mask(d, true); 225 spin_unlock_irqrestore(&chip->lock, flags); 226} 227 228static int cygnus_gpio_irq_set_type(struct irq_data *d, unsigned int type) 229{ 230 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 231 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 232 unsigned gpio = d->hwirq; 233 bool level_triggered = false; 234 bool dual_edge = false; 235 bool rising_or_high = false; 236 unsigned long flags; 237 238 switch (type & IRQ_TYPE_SENSE_MASK) { 239 case IRQ_TYPE_EDGE_RISING: 240 rising_or_high = true; 241 break; 242 243 case IRQ_TYPE_EDGE_FALLING: 244 break; 245 246 case IRQ_TYPE_EDGE_BOTH: 247 dual_edge = true; 248 break; 249 250 case IRQ_TYPE_LEVEL_HIGH: 251 level_triggered = true; 252 rising_or_high = true; 253 break; 254 255 case IRQ_TYPE_LEVEL_LOW: 256 level_triggered = true; 257 break; 258 259 default: 260 dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n", 261 type); 262 return -EINVAL; 263 } 264 265 spin_lock_irqsave(&chip->lock, flags); 266 cygnus_set_bit(chip, CYGNUS_GPIO_INT_TYPE_OFFSET, gpio, 267 level_triggered); 268 cygnus_set_bit(chip, CYGNUS_GPIO_INT_DE_OFFSET, gpio, dual_edge); 269 cygnus_set_bit(chip, CYGNUS_GPIO_INT_EDGE_OFFSET, gpio, 270 rising_or_high); 271 spin_unlock_irqrestore(&chip->lock, flags); 272 273 dev_dbg(chip->dev, 274 "gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n", 275 gpio, level_triggered, dual_edge, rising_or_high); 276 277 return 0; 278} 279 280static struct irq_chip cygnus_gpio_irq_chip = { 281 .name = "bcm-cygnus-gpio", 282 .irq_ack = cygnus_gpio_irq_ack, 283 .irq_mask = cygnus_gpio_irq_mask, 284 .irq_unmask = cygnus_gpio_irq_unmask, 285 .irq_set_type = cygnus_gpio_irq_set_type, 286}; 287 288/* 289 * Request the Cygnus IOMUX pinmux controller to mux individual pins to GPIO 290 */ 291static int cygnus_gpio_request(struct gpio_chip *gc, unsigned offset) 292{ 293 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 294 unsigned gpio = gc->base + offset; 295 296 /* not all Cygnus GPIO pins can be muxed individually */ 297 if (!chip->pinmux_is_supported) 298 return 0; 299 300 return pinctrl_request_gpio(gpio); 301} 302 303static void cygnus_gpio_free(struct gpio_chip *gc, unsigned offset) 304{ 305 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 306 unsigned gpio = gc->base + offset; 307 308 if (!chip->pinmux_is_supported) 309 return; 310 311 pinctrl_free_gpio(gpio); 312} 313 314static int cygnus_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) 315{ 316 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 317 unsigned long flags; 318 319 spin_lock_irqsave(&chip->lock, flags); 320 cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, false); 321 spin_unlock_irqrestore(&chip->lock, flags); 322 323 dev_dbg(chip->dev, "gpio:%u set input\n", gpio); 324 325 return 0; 326} 327 328static int cygnus_gpio_direction_output(struct gpio_chip *gc, unsigned gpio, 329 int val) 330{ 331 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 332 unsigned long flags; 333 334 spin_lock_irqsave(&chip->lock, flags); 335 cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, true); 336 cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val)); 337 spin_unlock_irqrestore(&chip->lock, flags); 338 339 dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val); 340 341 return 0; 342} 343 344static void cygnus_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) 345{ 346 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 347 unsigned long flags; 348 349 spin_lock_irqsave(&chip->lock, flags); 350 cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val)); 351 spin_unlock_irqrestore(&chip->lock, flags); 352 353 dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val); 354} 355 356static int cygnus_gpio_get(struct gpio_chip *gc, unsigned gpio) 357{ 358 struct cygnus_gpio *chip = to_cygnus_gpio(gc); 359 unsigned int offset = CYGNUS_GPIO_REG(gpio, 360 CYGNUS_GPIO_DATA_IN_OFFSET); 361 unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); 362 363 return !!(readl(chip->base + offset) & BIT(shift)); 364} 365 366static int cygnus_get_groups_count(struct pinctrl_dev *pctldev) 367{ 368 return 1; 369} 370 371/* 372 * Only one group: "gpio_grp", since this local pinctrl device only performs 373 * GPIO specific PINCONF configurations 374 */ 375static const char *cygnus_get_group_name(struct pinctrl_dev *pctldev, 376 unsigned selector) 377{ 378 return "gpio_grp"; 379} 380 381static const struct pinctrl_ops cygnus_pctrl_ops = { 382 .get_groups_count = cygnus_get_groups_count, 383 .get_group_name = cygnus_get_group_name, 384 .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 385 .dt_free_map = pinctrl_utils_dt_free_map, 386}; 387 388static int cygnus_gpio_set_pull(struct cygnus_gpio *chip, unsigned gpio, 389 bool disable, bool pull_up) 390{ 391 unsigned long flags; 392 393 spin_lock_irqsave(&chip->lock, flags); 394 395 if (disable) { 396 cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, false); 397 } else { 398 cygnus_set_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio, 399 pull_up); 400 cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, true); 401 } 402 403 spin_unlock_irqrestore(&chip->lock, flags); 404 405 dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up); 406 407 return 0; 408} 409 410static void cygnus_gpio_get_pull(struct cygnus_gpio *chip, unsigned gpio, 411 bool *disable, bool *pull_up) 412{ 413 unsigned long flags; 414 415 spin_lock_irqsave(&chip->lock, flags); 416 *disable = !cygnus_get_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio); 417 *pull_up = cygnus_get_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio); 418 spin_unlock_irqrestore(&chip->lock, flags); 419} 420 421static int cygnus_gpio_set_strength(struct cygnus_gpio *chip, unsigned gpio, 422 unsigned strength) 423{ 424 void __iomem *base; 425 unsigned int i, offset, shift; 426 u32 val; 427 unsigned long flags; 428 429 /* make sure drive strength is supported */ 430 if (strength < 2 || strength > 16 || (strength % 2)) 431 return -ENOTSUPP; 432 433 if (chip->io_ctrl) { 434 base = chip->io_ctrl; 435 offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET; 436 } else { 437 base = chip->base; 438 offset = CYGNUS_GPIO_REG(gpio, 439 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET); 440 } 441 442 shift = CYGNUS_GPIO_SHIFT(gpio); 443 444 dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio, 445 strength); 446 447 spin_lock_irqsave(&chip->lock, flags); 448 strength = (strength / 2) - 1; 449 for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) { 450 val = readl(base + offset); 451 val &= ~BIT(shift); 452 val |= ((strength >> i) & 0x1) << shift; 453 writel(val, base + offset); 454 offset += 4; 455 } 456 spin_unlock_irqrestore(&chip->lock, flags); 457 458 return 0; 459} 460 461static int cygnus_gpio_get_strength(struct cygnus_gpio *chip, unsigned gpio, 462 u16 *strength) 463{ 464 void __iomem *base; 465 unsigned int i, offset, shift; 466 u32 val; 467 unsigned long flags; 468 469 if (chip->io_ctrl) { 470 base = chip->io_ctrl; 471 offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET; 472 } else { 473 base = chip->base; 474 offset = CYGNUS_GPIO_REG(gpio, 475 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET); 476 } 477 478 shift = CYGNUS_GPIO_SHIFT(gpio); 479 480 spin_lock_irqsave(&chip->lock, flags); 481 *strength = 0; 482 for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) { 483 val = readl(base + offset) & BIT(shift); 484 val >>= shift; 485 *strength += (val << i); 486 offset += 4; 487 } 488 489 /* convert to mA */ 490 *strength = (*strength + 1) * 2; 491 spin_unlock_irqrestore(&chip->lock, flags); 492 493 return 0; 494} 495 496static int cygnus_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, 497 unsigned long *config) 498{ 499 struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev); 500 enum pin_config_param param = pinconf_to_config_param(*config); 501 unsigned gpio = cygnus_pin_to_gpio(pin); 502 u16 arg; 503 bool disable, pull_up; 504 int ret; 505 506 switch (param) { 507 case PIN_CONFIG_BIAS_DISABLE: 508 cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up); 509 if (disable) 510 return 0; 511 else 512 return -EINVAL; 513 514 case PIN_CONFIG_BIAS_PULL_UP: 515 cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up); 516 if (!disable && pull_up) 517 return 0; 518 else 519 return -EINVAL; 520 521 case PIN_CONFIG_BIAS_PULL_DOWN: 522 cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up); 523 if (!disable && !pull_up) 524 return 0; 525 else 526 return -EINVAL; 527 528 case PIN_CONFIG_DRIVE_STRENGTH: 529 ret = cygnus_gpio_get_strength(chip, gpio, &arg); 530 if (ret) 531 return ret; 532 else 533 *config = pinconf_to_config_packed(param, arg); 534 535 return 0; 536 537 default: 538 return -ENOTSUPP; 539 } 540 541 return -ENOTSUPP; 542} 543 544static int cygnus_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, 545 unsigned long *configs, unsigned num_configs) 546{ 547 struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev); 548 enum pin_config_param param; 549 u16 arg; 550 unsigned i, gpio = cygnus_pin_to_gpio(pin); 551 int ret = -ENOTSUPP; 552 553 for (i = 0; i < num_configs; i++) { 554 param = pinconf_to_config_param(configs[i]); 555 arg = pinconf_to_config_argument(configs[i]); 556 557 switch (param) { 558 case PIN_CONFIG_BIAS_DISABLE: 559 ret = cygnus_gpio_set_pull(chip, gpio, true, false); 560 if (ret < 0) 561 goto out; 562 break; 563 564 case PIN_CONFIG_BIAS_PULL_UP: 565 ret = cygnus_gpio_set_pull(chip, gpio, false, true); 566 if (ret < 0) 567 goto out; 568 break; 569 570 case PIN_CONFIG_BIAS_PULL_DOWN: 571 ret = cygnus_gpio_set_pull(chip, gpio, false, false); 572 if (ret < 0) 573 goto out; 574 break; 575 576 case PIN_CONFIG_DRIVE_STRENGTH: 577 ret = cygnus_gpio_set_strength(chip, gpio, arg); 578 if (ret < 0) 579 goto out; 580 break; 581 582 default: 583 dev_err(chip->dev, "invalid configuration\n"); 584 return -ENOTSUPP; 585 } 586 } /* for each config */ 587 588out: 589 return ret; 590} 591 592static const struct pinconf_ops cygnus_pconf_ops = { 593 .is_generic = true, 594 .pin_config_get = cygnus_pin_config_get, 595 .pin_config_set = cygnus_pin_config_set, 596}; 597 598/* 599 * Cygnus GPIO controller supports some PINCONF related configurations such as 600 * pull up, pull down, and drive strength, when the pin is configured to GPIO 601 * 602 * Here a local pinctrl device is created with simple 1-to-1 pin mapping to the 603 * local GPIO pins 604 */ 605static int cygnus_gpio_register_pinconf(struct cygnus_gpio *chip) 606{ 607 struct pinctrl_desc *pctldesc = &chip->pctldesc; 608 struct pinctrl_pin_desc *pins; 609 struct gpio_chip *gc = &chip->gc; 610 int i; 611 612 pins = devm_kcalloc(chip->dev, gc->ngpio, sizeof(*pins), GFP_KERNEL); 613 if (!pins) 614 return -ENOMEM; 615 616 for (i = 0; i < gc->ngpio; i++) { 617 pins[i].number = i; 618 pins[i].name = devm_kasprintf(chip->dev, GFP_KERNEL, 619 "gpio-%d", i); 620 if (!pins[i].name) 621 return -ENOMEM; 622 } 623 624 pctldesc->name = dev_name(chip->dev); 625 pctldesc->pctlops = &cygnus_pctrl_ops; 626 pctldesc->pins = pins; 627 pctldesc->npins = gc->ngpio; 628 pctldesc->confops = &cygnus_pconf_ops; 629 630 chip->pctl = pinctrl_register(pctldesc, chip->dev, chip); 631 if (IS_ERR(chip->pctl)) { 632 dev_err(chip->dev, "unable to register pinctrl device\n"); 633 return PTR_ERR(chip->pctl); 634 } 635 636 return 0; 637} 638 639static void cygnus_gpio_unregister_pinconf(struct cygnus_gpio *chip) 640{ 641 if (chip->pctl) 642 pinctrl_unregister(chip->pctl); 643} 644 645struct cygnus_gpio_data { 646 unsigned num_gpios; 647}; 648 649static const struct cygnus_gpio_data cygnus_cmm_gpio_data = { 650 .num_gpios = 24, 651}; 652 653static const struct cygnus_gpio_data cygnus_asiu_gpio_data = { 654 .num_gpios = 146, 655}; 656 657static const struct cygnus_gpio_data cygnus_crmu_gpio_data = { 658 .num_gpios = 6, 659}; 660 661static const struct of_device_id cygnus_gpio_of_match[] = { 662 { 663 .compatible = "brcm,cygnus-ccm-gpio", 664 .data = &cygnus_cmm_gpio_data, 665 }, 666 { 667 .compatible = "brcm,cygnus-asiu-gpio", 668 .data = &cygnus_asiu_gpio_data, 669 }, 670 { 671 .compatible = "brcm,cygnus-crmu-gpio", 672 .data = &cygnus_crmu_gpio_data, 673 } 674}; 675 676static int cygnus_gpio_probe(struct platform_device *pdev) 677{ 678 struct device *dev = &pdev->dev; 679 struct resource *res; 680 struct cygnus_gpio *chip; 681 struct gpio_chip *gc; 682 u32 ngpios; 683 int irq, ret; 684 const struct of_device_id *match; 685 const struct cygnus_gpio_data *gpio_data; 686 687 match = of_match_device(cygnus_gpio_of_match, dev); 688 if (!match) 689 return -ENODEV; 690 gpio_data = match->data; 691 ngpios = gpio_data->num_gpios; 692 693 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 694 if (!chip) 695 return -ENOMEM; 696 697 chip->dev = dev; 698 platform_set_drvdata(pdev, chip); 699 700 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 701 chip->base = devm_ioremap_resource(dev, res); 702 if (IS_ERR(chip->base)) { 703 dev_err(dev, "unable to map I/O memory\n"); 704 return PTR_ERR(chip->base); 705 } 706 707 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 708 if (res) { 709 chip->io_ctrl = devm_ioremap_resource(dev, res); 710 if (IS_ERR(chip->io_ctrl)) { 711 dev_err(dev, "unable to map I/O memory\n"); 712 return PTR_ERR(chip->io_ctrl); 713 } 714 } 715 716 spin_lock_init(&chip->lock); 717 718 gc = &chip->gc; 719 gc->base = -1; 720 gc->ngpio = ngpios; 721 chip->num_banks = (ngpios + NGPIOS_PER_BANK - 1) / NGPIOS_PER_BANK; 722 gc->label = dev_name(dev); 723 gc->dev = dev; 724 gc->of_node = dev->of_node; 725 gc->request = cygnus_gpio_request; 726 gc->free = cygnus_gpio_free; 727 gc->direction_input = cygnus_gpio_direction_input; 728 gc->direction_output = cygnus_gpio_direction_output; 729 gc->set = cygnus_gpio_set; 730 gc->get = cygnus_gpio_get; 731 732 chip->pinmux_is_supported = of_property_read_bool(dev->of_node, 733 "gpio-ranges"); 734 735 ret = gpiochip_add(gc); 736 if (ret < 0) { 737 dev_err(dev, "unable to add GPIO chip\n"); 738 return ret; 739 } 740 741 ret = cygnus_gpio_register_pinconf(chip); 742 if (ret) { 743 dev_err(dev, "unable to register pinconf\n"); 744 goto err_rm_gpiochip; 745 } 746 747 /* optional GPIO interrupt support */ 748 irq = platform_get_irq(pdev, 0); 749 if (irq) { 750 ret = gpiochip_irqchip_add(gc, &cygnus_gpio_irq_chip, 0, 751 handle_simple_irq, IRQ_TYPE_NONE); 752 if (ret) { 753 dev_err(dev, "no GPIO irqchip\n"); 754 goto err_unregister_pinconf; 755 } 756 757 gpiochip_set_chained_irqchip(gc, &cygnus_gpio_irq_chip, irq, 758 cygnus_gpio_irq_handler); 759 } 760 761 return 0; 762 763err_unregister_pinconf: 764 cygnus_gpio_unregister_pinconf(chip); 765 766err_rm_gpiochip: 767 gpiochip_remove(gc); 768 769 return ret; 770} 771 772static struct platform_driver cygnus_gpio_driver = { 773 .driver = { 774 .name = "cygnus-gpio", 775 .of_match_table = cygnus_gpio_of_match, 776 }, 777 .probe = cygnus_gpio_probe, 778}; 779 780static int __init cygnus_gpio_init(void) 781{ 782 return platform_driver_probe(&cygnus_gpio_driver, cygnus_gpio_probe); 783} 784arch_initcall_sync(cygnus_gpio_init); 785