657 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Broadcom Kona GPIO Driver4 *5 * Author: Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>6 * Copyright (C) 2012-2014 Broadcom Corporation7 */8 9#include <linux/bitops.h>10#include <linux/err.h>11#include <linux/gpio/driver.h>12#include <linux/init.h>13#include <linux/io.h>14#include <linux/irqdomain.h>15#include <linux/irqchip/chained_irq.h>16#include <linux/mod_devicetable.h>17#include <linux/platform_device.h>18#include <linux/property.h>19 20#define BCM_GPIO_PASSWD 0x00a5a50121#define GPIO_PER_BANK 3222#define GPIO_MAX_BANK_NUM 823 24#define GPIO_BANK(gpio) ((gpio) >> 5)25#define GPIO_BIT(gpio) ((gpio) & (GPIO_PER_BANK - 1))26 27/* There is a GPIO control register for each GPIO */28#define GPIO_CONTROL(gpio) (0x00000100 + ((gpio) << 2))29 30/* The remaining registers are per GPIO bank */31#define GPIO_OUT_STATUS(bank) (0x00000000 + ((bank) << 2))32#define GPIO_IN_STATUS(bank) (0x00000020 + ((bank) << 2))33#define GPIO_OUT_SET(bank) (0x00000040 + ((bank) << 2))34#define GPIO_OUT_CLEAR(bank) (0x00000060 + ((bank) << 2))35#define GPIO_INT_STATUS(bank) (0x00000080 + ((bank) << 2))36#define GPIO_INT_MASK(bank) (0x000000a0 + ((bank) << 2))37#define GPIO_INT_MSKCLR(bank) (0x000000c0 + ((bank) << 2))38#define GPIO_PWD_STATUS(bank) (0x00000500 + ((bank) << 2))39 40#define GPIO_GPPWR_OFFSET 0x0000052041 42#define GPIO_GPCTR0_DBR_SHIFT 543#define GPIO_GPCTR0_DBR_MASK 0x000001e044 45#define GPIO_GPCTR0_ITR_SHIFT 346#define GPIO_GPCTR0_ITR_MASK 0x0000001847#define GPIO_GPCTR0_ITR_CMD_RISING_EDGE 0x0000000148#define GPIO_GPCTR0_ITR_CMD_FALLING_EDGE 0x0000000249#define GPIO_GPCTR0_ITR_CMD_BOTH_EDGE 0x0000000350 51#define GPIO_GPCTR0_IOTR_MASK 0x0000000152#define GPIO_GPCTR0_IOTR_CMD_0UTPUT 0x0000000053#define GPIO_GPCTR0_IOTR_CMD_INPUT 0x0000000154 55#define GPIO_GPCTR0_DB_ENABLE_MASK 0x0000010056 57#define LOCK_CODE 0xffffffff58#define UNLOCK_CODE 0x0000000059 60struct bcm_kona_gpio {61 void __iomem *reg_base;62 int num_bank;63 raw_spinlock_t lock;64 struct gpio_chip gpio_chip;65 struct irq_domain *irq_domain;66 struct bcm_kona_gpio_bank *banks;67};68 69struct bcm_kona_gpio_bank {70 int id;71 int irq;72 /* Used in the interrupt handler */73 struct bcm_kona_gpio *kona_gpio;74};75 76static inline void bcm_kona_gpio_write_lock_regs(void __iomem *reg_base,77 int bank_id, u32 lockcode)78{79 writel(BCM_GPIO_PASSWD, reg_base + GPIO_GPPWR_OFFSET);80 writel(lockcode, reg_base + GPIO_PWD_STATUS(bank_id));81}82 83static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio,84 unsigned gpio)85{86 u32 val;87 unsigned long flags;88 int bank_id = GPIO_BANK(gpio);89 90 raw_spin_lock_irqsave(&kona_gpio->lock, flags);91 92 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));93 val |= BIT(gpio);94 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);95 96 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);97}98 99static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,100 unsigned gpio)101{102 u32 val;103 unsigned long flags;104 int bank_id = GPIO_BANK(gpio);105 106 raw_spin_lock_irqsave(&kona_gpio->lock, flags);107 108 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));109 val &= ~BIT(gpio);110 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);111 112 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);113}114 115static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio)116{117 struct bcm_kona_gpio *kona_gpio = gpiochip_get_data(chip);118 void __iomem *reg_base = kona_gpio->reg_base;119 u32 val;120 121 val = readl(reg_base + GPIO_CONTROL(gpio)) & GPIO_GPCTR0_IOTR_MASK;122 return val ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;123}124 125static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)126{127 struct bcm_kona_gpio *kona_gpio;128 void __iomem *reg_base;129 int bank_id = GPIO_BANK(gpio);130 int bit = GPIO_BIT(gpio);131 u32 val, reg_offset;132 unsigned long flags;133 134 kona_gpio = gpiochip_get_data(chip);135 reg_base = kona_gpio->reg_base;136 raw_spin_lock_irqsave(&kona_gpio->lock, flags);137 138 /* this function only applies to output pin */139 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN)140 goto out;141 142 reg_offset = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);143 144 val = readl(reg_base + reg_offset);145 val |= BIT(bit);146 writel(val, reg_base + reg_offset);147 148out:149 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);150}151 152static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)153{154 struct bcm_kona_gpio *kona_gpio;155 void __iomem *reg_base;156 int bank_id = GPIO_BANK(gpio);157 int bit = GPIO_BIT(gpio);158 u32 val, reg_offset;159 unsigned long flags;160 161 kona_gpio = gpiochip_get_data(chip);162 reg_base = kona_gpio->reg_base;163 raw_spin_lock_irqsave(&kona_gpio->lock, flags);164 165 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN)166 reg_offset = GPIO_IN_STATUS(bank_id);167 else168 reg_offset = GPIO_OUT_STATUS(bank_id);169 170 /* read the GPIO bank status */171 val = readl(reg_base + reg_offset);172 173 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);174 175 /* return the specified bit status */176 return !!(val & BIT(bit));177}178 179static int bcm_kona_gpio_request(struct gpio_chip *chip, unsigned gpio)180{181 struct bcm_kona_gpio *kona_gpio = gpiochip_get_data(chip);182 183 bcm_kona_gpio_unlock_gpio(kona_gpio, gpio);184 return 0;185}186 187static void bcm_kona_gpio_free(struct gpio_chip *chip, unsigned gpio)188{189 struct bcm_kona_gpio *kona_gpio = gpiochip_get_data(chip);190 191 bcm_kona_gpio_lock_gpio(kona_gpio, gpio);192}193 194static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)195{196 struct bcm_kona_gpio *kona_gpio;197 void __iomem *reg_base;198 u32 val;199 unsigned long flags;200 201 kona_gpio = gpiochip_get_data(chip);202 reg_base = kona_gpio->reg_base;203 raw_spin_lock_irqsave(&kona_gpio->lock, flags);204 205 val = readl(reg_base + GPIO_CONTROL(gpio));206 val &= ~GPIO_GPCTR0_IOTR_MASK;207 val |= GPIO_GPCTR0_IOTR_CMD_INPUT;208 writel(val, reg_base + GPIO_CONTROL(gpio));209 210 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);211 212 return 0;213}214 215static int bcm_kona_gpio_direction_output(struct gpio_chip *chip,216 unsigned gpio, int value)217{218 struct bcm_kona_gpio *kona_gpio;219 void __iomem *reg_base;220 int bank_id = GPIO_BANK(gpio);221 int bit = GPIO_BIT(gpio);222 u32 val, reg_offset;223 unsigned long flags;224 225 kona_gpio = gpiochip_get_data(chip);226 reg_base = kona_gpio->reg_base;227 raw_spin_lock_irqsave(&kona_gpio->lock, flags);228 229 val = readl(reg_base + GPIO_CONTROL(gpio));230 val &= ~GPIO_GPCTR0_IOTR_MASK;231 val |= GPIO_GPCTR0_IOTR_CMD_0UTPUT;232 writel(val, reg_base + GPIO_CONTROL(gpio));233 reg_offset = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);234 235 val = readl(reg_base + reg_offset);236 val |= BIT(bit);237 writel(val, reg_base + reg_offset);238 239 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);240 241 return 0;242}243 244static int bcm_kona_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)245{246 struct bcm_kona_gpio *kona_gpio;247 248 kona_gpio = gpiochip_get_data(chip);249 if (gpio >= kona_gpio->gpio_chip.ngpio)250 return -ENXIO;251 return irq_create_mapping(kona_gpio->irq_domain, gpio);252}253 254static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio,255 unsigned debounce)256{257 struct bcm_kona_gpio *kona_gpio;258 void __iomem *reg_base;259 u32 val, res;260 unsigned long flags;261 262 kona_gpio = gpiochip_get_data(chip);263 reg_base = kona_gpio->reg_base;264 /* debounce must be 1-128ms (or 0) */265 if ((debounce > 0 && debounce < 1000) || debounce > 128000) {266 dev_err(chip->parent, "Debounce value %u not in range\n",267 debounce);268 return -EINVAL;269 }270 271 /* calculate debounce bit value */272 if (debounce != 0) {273 /* Convert to ms */274 debounce /= 1000;275 /* find the MSB */276 res = fls(debounce) - 1;277 /* Check if MSB-1 is set (round up or down) */278 if (res > 0 && (debounce & BIT(res - 1)))279 res++;280 }281 282 /* spin lock for read-modify-write of the GPIO register */283 raw_spin_lock_irqsave(&kona_gpio->lock, flags);284 285 val = readl(reg_base + GPIO_CONTROL(gpio));286 val &= ~GPIO_GPCTR0_DBR_MASK;287 288 if (debounce == 0) {289 /* disable debounce */290 val &= ~GPIO_GPCTR0_DB_ENABLE_MASK;291 } else {292 val |= GPIO_GPCTR0_DB_ENABLE_MASK |293 (res << GPIO_GPCTR0_DBR_SHIFT);294 }295 296 writel(val, reg_base + GPIO_CONTROL(gpio));297 298 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);299 300 return 0;301}302 303static int bcm_kona_gpio_set_config(struct gpio_chip *chip, unsigned gpio,304 unsigned long config)305{306 u32 debounce;307 308 if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)309 return -ENOTSUPP;310 311 debounce = pinconf_to_config_argument(config);312 return bcm_kona_gpio_set_debounce(chip, gpio, debounce);313}314 315static const struct gpio_chip template_chip = {316 .label = "bcm-kona-gpio",317 .owner = THIS_MODULE,318 .request = bcm_kona_gpio_request,319 .free = bcm_kona_gpio_free,320 .get_direction = bcm_kona_gpio_get_dir,321 .direction_input = bcm_kona_gpio_direction_input,322 .get = bcm_kona_gpio_get,323 .direction_output = bcm_kona_gpio_direction_output,324 .set = bcm_kona_gpio_set,325 .set_config = bcm_kona_gpio_set_config,326 .to_irq = bcm_kona_gpio_to_irq,327 .base = 0,328};329 330static void bcm_kona_gpio_irq_ack(struct irq_data *d)331{332 struct bcm_kona_gpio *kona_gpio;333 void __iomem *reg_base;334 unsigned gpio = d->hwirq;335 int bank_id = GPIO_BANK(gpio);336 int bit = GPIO_BIT(gpio);337 u32 val;338 unsigned long flags;339 340 kona_gpio = irq_data_get_irq_chip_data(d);341 reg_base = kona_gpio->reg_base;342 raw_spin_lock_irqsave(&kona_gpio->lock, flags);343 344 val = readl(reg_base + GPIO_INT_STATUS(bank_id));345 val |= BIT(bit);346 writel(val, reg_base + GPIO_INT_STATUS(bank_id));347 348 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);349}350 351static void bcm_kona_gpio_irq_mask(struct irq_data *d)352{353 struct bcm_kona_gpio *kona_gpio;354 void __iomem *reg_base;355 unsigned gpio = d->hwirq;356 int bank_id = GPIO_BANK(gpio);357 int bit = GPIO_BIT(gpio);358 u32 val;359 unsigned long flags;360 361 kona_gpio = irq_data_get_irq_chip_data(d);362 reg_base = kona_gpio->reg_base;363 raw_spin_lock_irqsave(&kona_gpio->lock, flags);364 365 val = readl(reg_base + GPIO_INT_MASK(bank_id));366 val |= BIT(bit);367 writel(val, reg_base + GPIO_INT_MASK(bank_id));368 gpiochip_disable_irq(&kona_gpio->gpio_chip, gpio);369 370 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);371}372 373static void bcm_kona_gpio_irq_unmask(struct irq_data *d)374{375 struct bcm_kona_gpio *kona_gpio;376 void __iomem *reg_base;377 unsigned gpio = d->hwirq;378 int bank_id = GPIO_BANK(gpio);379 int bit = GPIO_BIT(gpio);380 u32 val;381 unsigned long flags;382 383 kona_gpio = irq_data_get_irq_chip_data(d);384 reg_base = kona_gpio->reg_base;385 raw_spin_lock_irqsave(&kona_gpio->lock, flags);386 387 val = readl(reg_base + GPIO_INT_MSKCLR(bank_id));388 val |= BIT(bit);389 writel(val, reg_base + GPIO_INT_MSKCLR(bank_id));390 gpiochip_enable_irq(&kona_gpio->gpio_chip, gpio);391 392 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);393}394 395static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type)396{397 struct bcm_kona_gpio *kona_gpio;398 void __iomem *reg_base;399 unsigned gpio = d->hwirq;400 u32 lvl_type;401 u32 val;402 unsigned long flags;403 404 kona_gpio = irq_data_get_irq_chip_data(d);405 reg_base = kona_gpio->reg_base;406 switch (type & IRQ_TYPE_SENSE_MASK) {407 case IRQ_TYPE_EDGE_RISING:408 lvl_type = GPIO_GPCTR0_ITR_CMD_RISING_EDGE;409 break;410 411 case IRQ_TYPE_EDGE_FALLING:412 lvl_type = GPIO_GPCTR0_ITR_CMD_FALLING_EDGE;413 break;414 415 case IRQ_TYPE_EDGE_BOTH:416 lvl_type = GPIO_GPCTR0_ITR_CMD_BOTH_EDGE;417 break;418 419 case IRQ_TYPE_LEVEL_HIGH:420 case IRQ_TYPE_LEVEL_LOW:421 /* BCM GPIO doesn't support level triggering */422 default:423 dev_err(kona_gpio->gpio_chip.parent,424 "Invalid BCM GPIO irq type 0x%x\n", type);425 return -EINVAL;426 }427 428 raw_spin_lock_irqsave(&kona_gpio->lock, flags);429 430 val = readl(reg_base + GPIO_CONTROL(gpio));431 val &= ~GPIO_GPCTR0_ITR_MASK;432 val |= lvl_type << GPIO_GPCTR0_ITR_SHIFT;433 writel(val, reg_base + GPIO_CONTROL(gpio));434 435 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);436 437 return 0;438}439 440static void bcm_kona_gpio_irq_handler(struct irq_desc *desc)441{442 void __iomem *reg_base;443 int bit, bank_id;444 unsigned long sta;445 struct bcm_kona_gpio_bank *bank = irq_desc_get_handler_data(desc);446 struct irq_chip *chip = irq_desc_get_chip(desc);447 448 chained_irq_enter(chip, desc);449 450 /*451 * For bank interrupts, we can't use chip_data to store the kona_gpio452 * pointer, since GIC needs it for its own purposes. Therefore, we get453 * our pointer from the bank structure.454 */455 reg_base = bank->kona_gpio->reg_base;456 bank_id = bank->id;457 458 while ((sta = readl(reg_base + GPIO_INT_STATUS(bank_id)) &459 (~(readl(reg_base + GPIO_INT_MASK(bank_id)))))) {460 for_each_set_bit(bit, &sta, 32) {461 int hwirq = GPIO_PER_BANK * bank_id + bit;462 /*463 * Clear interrupt before handler is called so we don't464 * miss any interrupt occurred during executing them.465 */466 writel(readl(reg_base + GPIO_INT_STATUS(bank_id)) |467 BIT(bit), reg_base + GPIO_INT_STATUS(bank_id));468 /* Invoke interrupt handler */469 generic_handle_domain_irq(bank->kona_gpio->irq_domain,470 hwirq);471 }472 }473 474 chained_irq_exit(chip, desc);475}476 477static int bcm_kona_gpio_irq_reqres(struct irq_data *d)478{479 struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);480 481 return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq);482}483 484static void bcm_kona_gpio_irq_relres(struct irq_data *d)485{486 struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);487 488 gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq);489}490 491static struct irq_chip bcm_gpio_irq_chip = {492 .name = "bcm-kona-gpio",493 .irq_ack = bcm_kona_gpio_irq_ack,494 .irq_mask = bcm_kona_gpio_irq_mask,495 .irq_unmask = bcm_kona_gpio_irq_unmask,496 .irq_set_type = bcm_kona_gpio_irq_set_type,497 .irq_request_resources = bcm_kona_gpio_irq_reqres,498 .irq_release_resources = bcm_kona_gpio_irq_relres,499};500 501static struct of_device_id const bcm_kona_gpio_of_match[] = {502 { .compatible = "brcm,kona-gpio" },503 {}504};505 506/*507 * This lock class tells lockdep that GPIO irqs are in a different508 * category than their parents, so it won't report false recursion.509 */510static struct lock_class_key gpio_lock_class;511static struct lock_class_key gpio_request_class;512 513static int bcm_kona_gpio_irq_map(struct irq_domain *d, unsigned int irq,514 irq_hw_number_t hwirq)515{516 int ret;517 518 ret = irq_set_chip_data(irq, d->host_data);519 if (ret < 0)520 return ret;521 irq_set_lockdep_class(irq, &gpio_lock_class, &gpio_request_class);522 irq_set_chip_and_handler(irq, &bcm_gpio_irq_chip, handle_simple_irq);523 irq_set_noprobe(irq);524 525 return 0;526}527 528static void bcm_kona_gpio_irq_unmap(struct irq_domain *d, unsigned int irq)529{530 irq_set_chip_and_handler(irq, NULL, NULL);531 irq_set_chip_data(irq, NULL);532}533 534static const struct irq_domain_ops bcm_kona_irq_ops = {535 .map = bcm_kona_gpio_irq_map,536 .unmap = bcm_kona_gpio_irq_unmap,537 .xlate = irq_domain_xlate_twocell,538};539 540static void bcm_kona_gpio_reset(struct bcm_kona_gpio *kona_gpio)541{542 void __iomem *reg_base;543 int i;544 545 reg_base = kona_gpio->reg_base;546 /* disable interrupts and clear status */547 for (i = 0; i < kona_gpio->num_bank; i++) {548 /* Unlock the entire bank first */549 bcm_kona_gpio_write_lock_regs(reg_base, i, UNLOCK_CODE);550 writel(0xffffffff, reg_base + GPIO_INT_MASK(i));551 writel(0xffffffff, reg_base + GPIO_INT_STATUS(i));552 /* Now re-lock the bank */553 bcm_kona_gpio_write_lock_regs(reg_base, i, LOCK_CODE);554 }555}556 557static int bcm_kona_gpio_probe(struct platform_device *pdev)558{559 struct device *dev = &pdev->dev;560 struct bcm_kona_gpio_bank *bank;561 struct bcm_kona_gpio *kona_gpio;562 struct gpio_chip *chip;563 int ret;564 int i;565 566 kona_gpio = devm_kzalloc(dev, sizeof(*kona_gpio), GFP_KERNEL);567 if (!kona_gpio)568 return -ENOMEM;569 570 kona_gpio->gpio_chip = template_chip;571 chip = &kona_gpio->gpio_chip;572 ret = platform_irq_count(pdev);573 if (!ret) {574 dev_err(dev, "Couldn't determine # GPIO banks\n");575 return -ENOENT;576 } else if (ret < 0) {577 return dev_err_probe(dev, ret, "Couldn't determine GPIO banks\n");578 }579 kona_gpio->num_bank = ret;580 581 if (kona_gpio->num_bank > GPIO_MAX_BANK_NUM) {582 dev_err(dev, "Too many GPIO banks configured (max=%d)\n",583 GPIO_MAX_BANK_NUM);584 return -ENXIO;585 }586 kona_gpio->banks = devm_kcalloc(dev,587 kona_gpio->num_bank,588 sizeof(*kona_gpio->banks),589 GFP_KERNEL);590 if (!kona_gpio->banks)591 return -ENOMEM;592 593 chip->parent = dev;594 chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK;595 596 kona_gpio->irq_domain = irq_domain_create_linear(dev_fwnode(dev),597 chip->ngpio,598 &bcm_kona_irq_ops,599 kona_gpio);600 if (!kona_gpio->irq_domain) {601 dev_err(dev, "Couldn't allocate IRQ domain\n");602 return -ENXIO;603 }604 605 kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0);606 if (IS_ERR(kona_gpio->reg_base)) {607 ret = PTR_ERR(kona_gpio->reg_base);608 goto err_irq_domain;609 }610 611 for (i = 0; i < kona_gpio->num_bank; i++) {612 bank = &kona_gpio->banks[i];613 bank->id = i;614 bank->irq = platform_get_irq(pdev, i);615 bank->kona_gpio = kona_gpio;616 if (bank->irq < 0) {617 dev_err(dev, "Couldn't get IRQ for bank %d", i);618 ret = -ENOENT;619 goto err_irq_domain;620 }621 }622 623 dev_info(&pdev->dev, "Setting up Kona GPIO\n");624 625 bcm_kona_gpio_reset(kona_gpio);626 627 ret = devm_gpiochip_add_data(dev, chip, kona_gpio);628 if (ret < 0) {629 dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret);630 goto err_irq_domain;631 }632 for (i = 0; i < kona_gpio->num_bank; i++) {633 bank = &kona_gpio->banks[i];634 irq_set_chained_handler_and_data(bank->irq,635 bcm_kona_gpio_irq_handler,636 bank);637 }638 639 raw_spin_lock_init(&kona_gpio->lock);640 641 return 0;642 643err_irq_domain:644 irq_domain_remove(kona_gpio->irq_domain);645 646 return ret;647}648 649static struct platform_driver bcm_kona_gpio_driver = {650 .driver = {651 .name = "bcm-kona-gpio",652 .of_match_table = bcm_kona_gpio_of_match,653 },654 .probe = bcm_kona_gpio_probe,655};656builtin_platform_driver(bcm_kona_gpio_driver);657