Lines Matching +full:kona +full:- +full:gpio

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Broadcom Kona GPIO Driver
5 * Author: Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>
6 * Copyright (C) 2012-2014 Broadcom Corporation
12 #include <linux/gpio/driver.h>
25 #define GPIO_BANK(gpio) ((gpio) >> 5) argument
26 #define GPIO_BIT(gpio) ((gpio) & (GPIO_PER_BANK - 1)) argument
28 /* There is a GPIO control register for each GPIO */
29 #define GPIO_CONTROL(gpio) (0x00000100 + ((gpio) << 2)) argument
31 /* The remaining registers are per GPIO bank */
74 * Used to keep track of lock/unlock operations for each GPIO in the
81 * The lock function only locks the GPIO once its unlock counter is
82 * down to 0. This is necessary because the GPIO is unlocked in two
84 * requested IRQs. Since it is possible for a GPIO to be requested
85 * as both a GPIO and an IRQ, we need to ensure that we don't lock it
101 unsigned gpio) in bcm_kona_gpio_lock_gpio() argument
104 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_lock_gpio()
105 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_lock_gpio()
106 struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; in bcm_kona_gpio_lock_gpio()
108 if (bank->gpio_unlock_count[bit] == 0) { in bcm_kona_gpio_lock_gpio()
109 dev_err(kona_gpio->gpio_chip.parent, in bcm_kona_gpio_lock_gpio()
110 "Unbalanced locks for GPIO %u\n", gpio); in bcm_kona_gpio_lock_gpio()
114 if (--bank->gpio_unlock_count[bit] == 0) { in bcm_kona_gpio_lock_gpio()
115 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_lock_gpio()
117 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); in bcm_kona_gpio_lock_gpio()
119 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); in bcm_kona_gpio_lock_gpio()
124 unsigned gpio) in bcm_kona_gpio_unlock_gpio() argument
127 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_unlock_gpio()
128 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_unlock_gpio()
129 struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; in bcm_kona_gpio_unlock_gpio()
131 if (bank->gpio_unlock_count[bit] == 0) { in bcm_kona_gpio_unlock_gpio()
132 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_unlock_gpio()
134 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); in bcm_kona_gpio_unlock_gpio()
136 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); in bcm_kona_gpio_unlock_gpio()
139 ++bank->gpio_unlock_count[bit]; in bcm_kona_gpio_unlock_gpio()
142 static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_get_dir() argument
145 void __iomem *reg_base = kona_gpio->reg_base; in bcm_kona_gpio_get_dir()
148 val = readl(reg_base + GPIO_CONTROL(gpio)) & GPIO_GPCTR0_IOTR_MASK; in bcm_kona_gpio_get_dir()
152 static int bcm_kona_gpio_set(struct gpio_chip *chip, unsigned int gpio, in bcm_kona_gpio_set() argument
157 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_set()
158 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_set()
162 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_set()
164 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_set()
167 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) in bcm_kona_gpio_set()
179 static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_get() argument
183 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_get()
184 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_get()
188 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_get()
190 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_get()
192 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) in bcm_kona_gpio_get()
197 /* read the GPIO bank status */ in bcm_kona_gpio_get()
204 static int bcm_kona_gpio_request(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_request() argument
208 bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); in bcm_kona_gpio_request()
212 static void bcm_kona_gpio_free(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_free() argument
216 bcm_kona_gpio_lock_gpio(kona_gpio, gpio); in bcm_kona_gpio_free()
219 static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_direction_input() argument
226 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_direction_input()
228 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_direction_input()
230 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_input()
233 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_input()
239 unsigned gpio, int value) in bcm_kona_gpio_direction_output() argument
243 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_direction_output()
244 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_direction_output()
248 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_direction_output()
250 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_direction_output()
252 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_output()
255 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_output()
265 static int bcm_kona_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_to_irq() argument
270 if (gpio >= kona_gpio->gpio_chip.ngpio) in bcm_kona_gpio_to_irq()
271 return -ENXIO; in bcm_kona_gpio_to_irq()
272 return irq_create_mapping(kona_gpio->irq_domain, gpio); in bcm_kona_gpio_to_irq()
275 static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, in bcm_kona_gpio_set_debounce() argument
283 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_set_debounce()
284 /* debounce must be 1-128ms (or 0) */ in bcm_kona_gpio_set_debounce()
286 dev_err(chip->parent, "Debounce value %u not in range\n", in bcm_kona_gpio_set_debounce()
288 return -EINVAL; in bcm_kona_gpio_set_debounce()
296 res = fls(debounce) - 1; in bcm_kona_gpio_set_debounce()
297 /* Check if MSB-1 is set (round up or down) */ in bcm_kona_gpio_set_debounce()
298 if (res > 0 && (debounce & BIT(res - 1))) in bcm_kona_gpio_set_debounce()
302 /* spin lock for read-modify-write of the GPIO register */ in bcm_kona_gpio_set_debounce()
303 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_set_debounce()
305 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_set_debounce()
316 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_set_debounce()
321 static int bcm_kona_gpio_set_config(struct gpio_chip *chip, unsigned gpio, in bcm_kona_gpio_set_config() argument
327 return -ENOTSUPP; in bcm_kona_gpio_set_config()
330 return bcm_kona_gpio_set_debounce(chip, gpio, debounce); in bcm_kona_gpio_set_config()
334 .label = "bcm-kona-gpio",
352 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_ack() local
353 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_ack()
354 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_ack()
358 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_ack()
360 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_irq_ack()
371 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_mask() local
372 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_mask()
373 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_mask()
377 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_mask()
379 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_irq_mask()
384 gpiochip_disable_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_mask()
391 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_unmask() local
392 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_unmask()
393 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_unmask()
397 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_unmask()
399 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_irq_unmask()
404 gpiochip_enable_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_unmask()
411 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_set_type() local
416 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_set_type()
432 /* BCM GPIO doesn't support level triggering */ in bcm_kona_gpio_irq_set_type()
434 dev_err(kona_gpio->gpio_chip.parent, in bcm_kona_gpio_irq_set_type()
435 "Invalid BCM GPIO irq type 0x%x\n", type); in bcm_kona_gpio_irq_set_type()
436 return -EINVAL; in bcm_kona_gpio_irq_set_type()
439 guard(raw_spinlock_irqsave)(&kona_gpio->lock); in bcm_kona_gpio_irq_set_type()
441 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_irq_set_type()
444 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_irq_set_type()
464 reg_base = bank->kona_gpio->reg_base; in bcm_kona_gpio_irq_handler()
465 bank_id = bank->id; in bcm_kona_gpio_irq_handler()
478 generic_handle_domain_irq(bank->kona_gpio->irq_domain, in bcm_kona_gpio_irq_handler()
489 unsigned int gpio = d->hwirq; in bcm_kona_gpio_irq_reqres() local
492 * We need to unlock the GPIO before any other operations are performed in bcm_kona_gpio_irq_reqres()
493 * on the relevant GPIO configuration registers in bcm_kona_gpio_irq_reqres()
495 bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); in bcm_kona_gpio_irq_reqres()
497 return gpiochip_reqres_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_reqres()
503 unsigned int gpio = d->hwirq; in bcm_kona_gpio_irq_relres() local
505 /* Once we no longer use it, lock the GPIO again */ in bcm_kona_gpio_irq_relres()
506 bcm_kona_gpio_lock_gpio(kona_gpio, gpio); in bcm_kona_gpio_irq_relres()
508 gpiochip_relres_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_relres()
512 .name = "bcm-kona-gpio",
523 { .compatible = "brcm,kona-gpio" },
528 * This lock class tells lockdep that GPIO irqs are in a different
539 ret = irq_set_chip_data(irq, d->host_data); in bcm_kona_gpio_irq_map()
566 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_reset()
568 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_reset()
573 /* Now re-lock the bank */ in bcm_kona_gpio_reset()
580 struct device *dev = &pdev->dev; in bcm_kona_gpio_probe()
589 return -ENOMEM; in bcm_kona_gpio_probe()
591 kona_gpio->gpio_chip = template_chip; in bcm_kona_gpio_probe()
592 chip = &kona_gpio->gpio_chip; in bcm_kona_gpio_probe()
595 dev_err(dev, "Couldn't determine # GPIO banks\n"); in bcm_kona_gpio_probe()
596 return -ENOENT; in bcm_kona_gpio_probe()
598 return dev_err_probe(dev, ret, "Couldn't determine GPIO banks\n"); in bcm_kona_gpio_probe()
600 kona_gpio->num_bank = ret; in bcm_kona_gpio_probe()
602 if (kona_gpio->num_bank > GPIO_MAX_BANK_NUM) { in bcm_kona_gpio_probe()
603 dev_err(dev, "Too many GPIO banks configured (max=%d)\n", in bcm_kona_gpio_probe()
605 return -ENXIO; in bcm_kona_gpio_probe()
607 kona_gpio->banks = devm_kcalloc(dev, in bcm_kona_gpio_probe()
608 kona_gpio->num_bank, in bcm_kona_gpio_probe()
609 sizeof(*kona_gpio->banks), in bcm_kona_gpio_probe()
611 if (!kona_gpio->banks) in bcm_kona_gpio_probe()
612 return -ENOMEM; in bcm_kona_gpio_probe()
614 chip->parent = dev; in bcm_kona_gpio_probe()
615 chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK; in bcm_kona_gpio_probe()
617 kona_gpio->irq_domain = irq_domain_create_linear(dev_fwnode(dev), in bcm_kona_gpio_probe()
618 chip->ngpio, in bcm_kona_gpio_probe()
621 if (!kona_gpio->irq_domain) { in bcm_kona_gpio_probe()
623 return -ENXIO; in bcm_kona_gpio_probe()
626 kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); in bcm_kona_gpio_probe()
627 if (IS_ERR(kona_gpio->reg_base)) { in bcm_kona_gpio_probe()
628 ret = PTR_ERR(kona_gpio->reg_base); in bcm_kona_gpio_probe()
632 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_probe()
633 bank = &kona_gpio->banks[i]; in bcm_kona_gpio_probe()
634 bank->id = i; in bcm_kona_gpio_probe()
635 bank->irq = platform_get_irq(pdev, i); in bcm_kona_gpio_probe()
636 bank->kona_gpio = kona_gpio; in bcm_kona_gpio_probe()
637 if (bank->irq < 0) { in bcm_kona_gpio_probe()
639 ret = -ENOENT; in bcm_kona_gpio_probe()
644 dev_info(&pdev->dev, "Setting up Kona GPIO\n"); in bcm_kona_gpio_probe()
650 dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret); in bcm_kona_gpio_probe()
653 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_probe()
654 bank = &kona_gpio->banks[i]; in bcm_kona_gpio_probe()
655 irq_set_chained_handler_and_data(bank->irq, in bcm_kona_gpio_probe()
660 raw_spin_lock_init(&kona_gpio->lock); in bcm_kona_gpio_probe()
665 irq_domain_remove(kona_gpio->irq_domain); in bcm_kona_gpio_probe()
672 .name = "bcm-kona-gpio",