^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define MTK_BANK_CNT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define MTK_BANK_WIDTH 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define GPIO_BANK_STRIDE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define GPIO_REG_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define GPIO_REG_POL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define GPIO_REG_DATA 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define GPIO_REG_DSET 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define GPIO_REG_DCLR 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define GPIO_REG_REDGE 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define GPIO_REG_FEDGE 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define GPIO_REG_HLVL 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define GPIO_REG_LLVL 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define GPIO_REG_STAT 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define GPIO_REG_EDGE 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct mtk_gc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct irq_chip irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u32 rising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u32 falling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u32 hlevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u32 llevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * struct mtk - state container for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * data of the platform driver. It is 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * separate gpio-chip each one with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * own irq_chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @dev: device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @base: memory base address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @gpio_irq: irq number from the device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * @gc_map: array of the gpio chips
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct mtk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int gpio_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct mtk_gc gc_map[MTK_BANK_CNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static inline struct mtk_gc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) to_mediatek_gpio(struct gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return container_of(chip, struct mtk_gc, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mtk_gpio_w32(struct mtk_gc *rg, u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct gpio_chip *gc = &rg->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct mtk *mtk = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) offset = (rg->bank * GPIO_BANK_STRIDE) + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) gc->write_reg(mtk->base + offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static inline u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mtk_gpio_r32(struct mtk_gc *rg, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct gpio_chip *gc = &rg->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct mtk *mtk = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) offset = (rg->bank * GPIO_BANK_STRIDE) + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return gc->read_reg(mtk->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mediatek_gpio_irq_handler(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct gpio_chip *gc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct mtk_gc *rg = to_mediatek_gpio(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned long pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u32 map = irq_find_mapping(gc->irq.domain, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) generic_handle_irq(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret |= IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mediatek_gpio_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct mtk_gc *rg = to_mediatek_gpio(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int pin = d->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 rise, fall, high, low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) spin_lock_irqsave(&rg->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(pin) & rg->rising));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(pin) & rg->falling));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (BIT(pin) & rg->hlevel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (BIT(pin) & rg->llevel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spin_unlock_irqrestore(&rg->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mediatek_gpio_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct mtk_gc *rg = to_mediatek_gpio(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int pin = d->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 rise, fall, high, low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) spin_lock_irqsave(&rg->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spin_unlock_irqrestore(&rg->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct mtk_gc *rg = to_mediatek_gpio(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int pin = d->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u32 mask = BIT(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (type == IRQ_TYPE_PROBE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if ((rg->rising | rg->falling |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) rg->hlevel | rg->llevel) & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rg->rising &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) rg->falling &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rg->hlevel &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) rg->llevel &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) switch (type & IRQ_TYPE_SENSE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rg->rising |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rg->falling |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rg->rising |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rg->falling |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) rg->hlevel |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) rg->llevel |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mediatek_gpio_xlate(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) const struct of_phandle_args *spec, u32 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int gpio = spec->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct mtk_gc *rg = to_mediatek_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (rg->bank != gpio / MTK_BANK_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *flags = spec->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return gpio % MTK_BANK_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) mediatek_gpio_bank_probe(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct device_node *node, int bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct mtk *mtk = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct mtk_gc *rg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void __iomem *dat, *set, *ctrl, *diro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rg = &mtk->gc_map[bank];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) memset(rg, 0, sizeof(*rg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) spin_lock_init(&rg->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) rg->chip.of_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) rg->bank = bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dat = mtk->base + GPIO_REG_DATA + (rg->bank * GPIO_BANK_STRIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) set = mtk->base + GPIO_REG_DSET + (rg->bank * GPIO_BANK_STRIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ctrl = mtk->base + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_STRIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) diro = mtk->base + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_STRIDE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = bgpio_init(&rg->chip, dev, 4, dat, set, ctrl, diro, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) BGPIOF_NO_SET_ON_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_err(dev, "bgpio_init() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rg->chip.of_gpio_n_cells = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) rg->chip.of_xlate = mediatek_gpio_xlate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rg->chip.label = devm_kasprintf(dev, GFP_KERNEL, "%s-bank%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dev_name(dev), bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!rg->chip.label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) rg->irq_chip.name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) rg->irq_chip.parent_device = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) rg->irq_chip.irq_unmask = mediatek_gpio_irq_unmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rg->irq_chip.irq_mask = mediatek_gpio_irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rg->irq_chip.irq_mask_ack = mediatek_gpio_irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rg->irq_chip.irq_set_type = mediatek_gpio_irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (mtk->gpio_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct gpio_irq_chip *girq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Directly request the irq here instead of passing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * a flow-handler because the irq is shared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ret = devm_request_irq(dev, mtk->gpio_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) mediatek_gpio_irq_handler, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) rg->chip.label, &rg->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_err(dev, "Error requesting IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) mtk->gpio_irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) girq = &rg->chip.irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) girq->chip = &rg->irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* This will let us handle the parent IRQ in the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) girq->parent_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) girq->num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) girq->parents = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) girq->default_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) girq->handler = handle_simple_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret = devm_gpiochip_add_data(dev, &rg->chip, mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev_err(dev, "Could not register gpio %d, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) rg->chip.ngpio, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* set polarity to low for all gpios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mtk_gpio_w32(rg, GPIO_REG_POL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dev_info(dev, "registering %d gpios\n", rg->chip.ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) mediatek_gpio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct mtk *mtk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mtk->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (IS_ERR(mtk->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return PTR_ERR(mtk->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) mtk->gpio_irq = irq_of_parse_and_map(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) mtk->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) platform_set_drvdata(pdev, mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) for (i = 0; i < MTK_BANK_CNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = mediatek_gpio_bank_probe(dev, np, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static const struct of_device_id mediatek_gpio_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) { .compatible = "mediatek,mt7621-gpio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static struct platform_driver mediatek_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .probe = mediatek_gpio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .name = "mt7621_gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) .of_match_table = mediatek_gpio_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) builtin_platform_driver(mediatek_gpio_driver);