10fdee37bSJoseph Chen /*
20fdee37bSJoseph Chen * (C) Copyright 2020 Rockchip Electronics Co., Ltd
30fdee37bSJoseph Chen *
40fdee37bSJoseph Chen * SPDX-License-Identifier: GPL-2.0+
50fdee37bSJoseph Chen */
60fdee37bSJoseph Chen
70fdee37bSJoseph Chen #include <dm.h>
80fdee37bSJoseph Chen #include <malloc.h>
90fdee37bSJoseph Chen #include "irq-internal.h"
100fdee37bSJoseph Chen
110fdee37bSJoseph Chen typedef enum GPIOIntType {
120fdee37bSJoseph Chen GPIOLevelLow = 0,
130fdee37bSJoseph Chen GPIOLevelHigh,
140fdee37bSJoseph Chen GPIOEdgelFalling,
150fdee37bSJoseph Chen GPIOEdgelRising
160fdee37bSJoseph Chen } eGPIOIntType_t;
170fdee37bSJoseph Chen
180fdee37bSJoseph Chen typedef enum eGPIOPinLevel {
190fdee37bSJoseph Chen GPIO_LOW = 0,
200fdee37bSJoseph Chen GPIO_HIGH
210fdee37bSJoseph Chen } eGPIOPinLevel_t;
220fdee37bSJoseph Chen
230fdee37bSJoseph Chen typedef enum eGPIOPinDirection {
240fdee37bSJoseph Chen GPIO_IN = 0,
250fdee37bSJoseph Chen GPIO_OUT
260fdee37bSJoseph Chen } eGPIOPinDirection_t;
270fdee37bSJoseph Chen
280fdee37bSJoseph Chen #define GPIO_SWPORT_DR 0x00
290fdee37bSJoseph Chen #define GPIO_SWPORT_DDR 0x08
300fdee37bSJoseph Chen #define GPIO_INTEN 0x10
310fdee37bSJoseph Chen #define GPIO_INTEN_L 0x10
320fdee37bSJoseph Chen #define GPIO_INTEN_H 0x14
330fdee37bSJoseph Chen #define GPIO_INTMASK 0x18
340fdee37bSJoseph Chen #define GPIO_INTTYPE_LEVEL 0x20
350fdee37bSJoseph Chen #define GPIO_INTTYPE_LEVEL_L 0x20
360fdee37bSJoseph Chen #define GPIO_INTTYPE_LEVEL_H 0x24
370fdee37bSJoseph Chen #define GPIO_INT_POLARITY 0x28
380fdee37bSJoseph Chen #define GPIO_DEBOUNCE 0x38
390fdee37bSJoseph Chen #define GPIO_INT_STATUS 0x50
400fdee37bSJoseph Chen #define GPIO_INT_RAWSTATUS 0x58
410fdee37bSJoseph Chen #define GPIO_PORTS_EOI 0x60
420fdee37bSJoseph Chen #define GPIO_EXT_PORT 0x70
430fdee37bSJoseph Chen
440fdee37bSJoseph Chen #define WMSK_SETBIT(n) (n << 16 | n)
450fdee37bSJoseph Chen #define WMSK_CLRBIT(n) (n << 16)
460fdee37bSJoseph Chen #define REG_PLUS4(off, n) (off + (n >= BIT(16) ? 4 : 0))
470fdee37bSJoseph Chen #define BIT_SUB16(n) (n >= BIT(16) ? (n >> 16) : n)
480fdee37bSJoseph Chen
offset_to_bit(unsigned offset)490fdee37bSJoseph Chen static inline unsigned offset_to_bit(unsigned offset)
500fdee37bSJoseph Chen {
510fdee37bSJoseph Chen return (1 << offset);
520fdee37bSJoseph Chen }
530fdee37bSJoseph Chen
gpio_bit_op(void __iomem * regbase,unsigned int offset,u32 bit,unsigned char flag)540fdee37bSJoseph Chen static void gpio_bit_op(void __iomem *regbase, unsigned int offset,
550fdee37bSJoseph Chen u32 bit, unsigned char flag)
560fdee37bSJoseph Chen {
570fdee37bSJoseph Chen u32 val;
580fdee37bSJoseph Chen
590fdee37bSJoseph Chen offset = REG_PLUS4(offset, bit);
600fdee37bSJoseph Chen bit = BIT_SUB16(bit);
610fdee37bSJoseph Chen
620fdee37bSJoseph Chen val = flag ? WMSK_SETBIT(bit) : WMSK_CLRBIT(bit);
630fdee37bSJoseph Chen writel(val, regbase + offset);
640fdee37bSJoseph Chen }
650fdee37bSJoseph Chen
gpio_bit_rd(void __iomem * regbase,unsigned int offset,u32 bit)660fdee37bSJoseph Chen static int gpio_bit_rd(void __iomem *regbase, unsigned int offset, u32 bit)
670fdee37bSJoseph Chen {
680fdee37bSJoseph Chen offset = REG_PLUS4(offset, bit);
690fdee37bSJoseph Chen bit = BIT_SUB16(bit);
700fdee37bSJoseph Chen
710fdee37bSJoseph Chen return readl(regbase + offset) & bit ? 1 : 0;
720fdee37bSJoseph Chen }
730fdee37bSJoseph Chen
gpio_irq_unmask(void __iomem * regbase,unsigned int bit)740fdee37bSJoseph Chen static void gpio_irq_unmask(void __iomem *regbase, unsigned int bit)
750fdee37bSJoseph Chen {
760fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INTEN, bit, 1);
770fdee37bSJoseph Chen }
780fdee37bSJoseph Chen
gpio_irq_mask(void __iomem * regbase,unsigned int bit)790fdee37bSJoseph Chen static void gpio_irq_mask(void __iomem *regbase, unsigned int bit)
800fdee37bSJoseph Chen {
810fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INTEN, bit, 0);
820fdee37bSJoseph Chen }
830fdee37bSJoseph Chen
gpio_irq_ack(void __iomem * regbase,unsigned int bit)840fdee37bSJoseph Chen static void gpio_irq_ack(void __iomem *regbase, unsigned int bit)
850fdee37bSJoseph Chen {
860fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_PORTS_EOI, bit, 1);
870fdee37bSJoseph Chen }
880fdee37bSJoseph Chen
generic_gpio_handle_irq(int irq,void * data __always_unused)890fdee37bSJoseph Chen static void generic_gpio_handle_irq(int irq, void *data __always_unused)
900fdee37bSJoseph Chen {
910fdee37bSJoseph Chen struct gpio_bank *bank = gpio_id_to_bank(irq - IRQ_GPIO0);
920fdee37bSJoseph Chen unsigned gpio_irq, pin, h_pin, unmasked = 0;
930fdee37bSJoseph Chen u32 isr, ilr_l, ilr_h;
940fdee37bSJoseph Chen
950fdee37bSJoseph Chen isr = readl(bank->regbase + GPIO_INT_STATUS);
960fdee37bSJoseph Chen ilr_l = readl(bank->regbase + GPIO_INTTYPE_LEVEL_L);
970fdee37bSJoseph Chen ilr_h = readl(bank->regbase + GPIO_INTTYPE_LEVEL_H);
980fdee37bSJoseph Chen gpio_irq = bank->irq_base;
990fdee37bSJoseph Chen
1000fdee37bSJoseph Chen while (isr) {
1010fdee37bSJoseph Chen pin = fls(isr) - 1;
1020fdee37bSJoseph Chen
1030fdee37bSJoseph Chen /* first mask and ack irq */
1040fdee37bSJoseph Chen gpio_irq_mask(bank->regbase, offset_to_bit(pin));
1050fdee37bSJoseph Chen gpio_irq_ack(bank->regbase, offset_to_bit(pin));
1060fdee37bSJoseph Chen
1070fdee37bSJoseph Chen /*
1080fdee37bSJoseph Chen * If gpio is edge triggered, clear condition before executing
1090fdee37bSJoseph Chen * the handler, so that we don't miss next edges trigger.
1100fdee37bSJoseph Chen */
1110fdee37bSJoseph Chen if (pin < 16) {
1120fdee37bSJoseph Chen if (ilr_l & (1 << pin)) {
1130fdee37bSJoseph Chen unmasked = 1;
1140fdee37bSJoseph Chen gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
1150fdee37bSJoseph Chen }
1160fdee37bSJoseph Chen } else {
1170fdee37bSJoseph Chen h_pin = pin - 16;
1180fdee37bSJoseph Chen if (ilr_h & (1 << h_pin)) {
1190fdee37bSJoseph Chen unmasked = 1;
120*976ec9ccSJoseph Chen gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
1210fdee37bSJoseph Chen }
1220fdee37bSJoseph Chen }
1230fdee37bSJoseph Chen __generic_gpio_handle_irq(gpio_irq + pin);
1240fdee37bSJoseph Chen
1250fdee37bSJoseph Chen isr &= ~(1 << pin);
1260fdee37bSJoseph Chen
1270fdee37bSJoseph Chen if (!unmasked)
1280fdee37bSJoseph Chen gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
1290fdee37bSJoseph Chen }
1300fdee37bSJoseph Chen }
1310fdee37bSJoseph Chen
gpio_set_intr_type(void __iomem * regbase,unsigned int bit,eGPIOIntType_t type)1320fdee37bSJoseph Chen static void gpio_set_intr_type(void __iomem *regbase,
1330fdee37bSJoseph Chen unsigned int bit,
1340fdee37bSJoseph Chen eGPIOIntType_t type)
1350fdee37bSJoseph Chen {
1360fdee37bSJoseph Chen switch (type) {
1370fdee37bSJoseph Chen case GPIOLevelLow:
1380fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
1390fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
1400fdee37bSJoseph Chen break;
1410fdee37bSJoseph Chen case GPIOLevelHigh:
1420fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
1430fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
1440fdee37bSJoseph Chen break;
1450fdee37bSJoseph Chen case GPIOEdgelFalling:
1460fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
1470fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
1480fdee37bSJoseph Chen break;
1490fdee37bSJoseph Chen case GPIOEdgelRising:
1500fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
1510fdee37bSJoseph Chen gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
1520fdee37bSJoseph Chen break;
1530fdee37bSJoseph Chen }
1540fdee37bSJoseph Chen }
1550fdee37bSJoseph Chen
gpio_get_intr_type(void __iomem * regbase,unsigned int bit)1560fdee37bSJoseph Chen static int gpio_get_intr_type(void __iomem *regbase,
1570fdee37bSJoseph Chen unsigned int bit)
1580fdee37bSJoseph Chen {
1590fdee37bSJoseph Chen u32 polarity, level, magic = 0;
1600fdee37bSJoseph Chen int type;
1610fdee37bSJoseph Chen
1620fdee37bSJoseph Chen polarity = gpio_bit_rd(regbase, GPIO_INT_POLARITY, bit);
1630fdee37bSJoseph Chen level = gpio_bit_rd(regbase, GPIO_INTTYPE_LEVEL, bit);
1640fdee37bSJoseph Chen magic = (polarity << 1) | (level << 0);
1650fdee37bSJoseph Chen
1660fdee37bSJoseph Chen switch (magic) {
1670fdee37bSJoseph Chen case 0x00:
1680fdee37bSJoseph Chen type = GPIOLevelLow;
1690fdee37bSJoseph Chen break;
1700fdee37bSJoseph Chen case 0x02:
1710fdee37bSJoseph Chen type = GPIOLevelHigh;
1720fdee37bSJoseph Chen break;
1730fdee37bSJoseph Chen case 0x01:
1740fdee37bSJoseph Chen type = GPIOEdgelFalling;
1750fdee37bSJoseph Chen break;
1760fdee37bSJoseph Chen case 0x03:
1770fdee37bSJoseph Chen type = GPIOEdgelRising;
1780fdee37bSJoseph Chen break;
1790fdee37bSJoseph Chen default:
1800fdee37bSJoseph Chen type = -EINVAL;
1810fdee37bSJoseph Chen }
1820fdee37bSJoseph Chen
1830fdee37bSJoseph Chen return type;
1840fdee37bSJoseph Chen }
1850fdee37bSJoseph Chen
gpio_irq_set_type(int gpio_irq,unsigned int type)1860fdee37bSJoseph Chen static int gpio_irq_set_type(int gpio_irq, unsigned int type)
1870fdee37bSJoseph Chen {
1880fdee37bSJoseph Chen int gpio = irq_to_gpio(gpio_irq);
1890fdee37bSJoseph Chen struct gpio_bank *bank = gpio_to_bank(gpio);
1900fdee37bSJoseph Chen eGPIOIntType_t int_type = 0;
1910fdee37bSJoseph Chen
1920fdee37bSJoseph Chen if (!bank)
1930fdee37bSJoseph Chen return -EINVAL;
1940fdee37bSJoseph Chen
1950fdee37bSJoseph Chen gpio &= GPIO_PIN_MASK;
1960fdee37bSJoseph Chen if (gpio >= bank->ngpio)
1970fdee37bSJoseph Chen return -EINVAL;
1980fdee37bSJoseph Chen
1990fdee37bSJoseph Chen switch (type) {
2000fdee37bSJoseph Chen case IRQ_TYPE_EDGE_RISING:
2010fdee37bSJoseph Chen int_type = GPIOEdgelRising;
2020fdee37bSJoseph Chen break;
2030fdee37bSJoseph Chen case IRQ_TYPE_EDGE_FALLING:
2040fdee37bSJoseph Chen int_type = GPIOEdgelFalling;
2050fdee37bSJoseph Chen break;
2060fdee37bSJoseph Chen case IRQ_TYPE_LEVEL_HIGH:
2070fdee37bSJoseph Chen int_type = GPIOLevelHigh;
2080fdee37bSJoseph Chen break;
2090fdee37bSJoseph Chen case IRQ_TYPE_LEVEL_LOW:
2100fdee37bSJoseph Chen int_type = GPIOLevelLow;
2110fdee37bSJoseph Chen break;
2120fdee37bSJoseph Chen default:
2130fdee37bSJoseph Chen return -EINVAL;
2140fdee37bSJoseph Chen }
2150fdee37bSJoseph Chen
2160fdee37bSJoseph Chen /* Before set interrupt type, gpio must set input */
2170fdee37bSJoseph Chen gpio_bit_op(bank->regbase, GPIO_SWPORT_DDR,
2180fdee37bSJoseph Chen offset_to_bit(gpio), GPIO_IN);
2190fdee37bSJoseph Chen gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
2200fdee37bSJoseph Chen
2210fdee37bSJoseph Chen return 0;
2220fdee37bSJoseph Chen }
2230fdee37bSJoseph Chen
gpio_irq_revert_type(int gpio_irq)2240fdee37bSJoseph Chen static int gpio_irq_revert_type(int gpio_irq)
2250fdee37bSJoseph Chen {
2260fdee37bSJoseph Chen int gpio = irq_to_gpio(gpio_irq);
2270fdee37bSJoseph Chen struct gpio_bank *bank = gpio_to_bank(gpio);
2280fdee37bSJoseph Chen eGPIOIntType_t int_type = 0;
2290fdee37bSJoseph Chen int type;
2300fdee37bSJoseph Chen
2310fdee37bSJoseph Chen if (!bank)
2320fdee37bSJoseph Chen return -EINVAL;
2330fdee37bSJoseph Chen
2340fdee37bSJoseph Chen gpio &= GPIO_PIN_MASK;
2350fdee37bSJoseph Chen if (gpio >= bank->ngpio)
2360fdee37bSJoseph Chen return -EINVAL;
2370fdee37bSJoseph Chen
2380fdee37bSJoseph Chen type = gpio_get_intr_type(bank->regbase, offset_to_bit(gpio));
2390fdee37bSJoseph Chen switch (type) {
2400fdee37bSJoseph Chen case GPIOEdgelFalling:
2410fdee37bSJoseph Chen int_type = GPIOEdgelRising;
2420fdee37bSJoseph Chen break;
2430fdee37bSJoseph Chen case GPIOEdgelRising:
2440fdee37bSJoseph Chen int_type = GPIOEdgelFalling;
2450fdee37bSJoseph Chen break;
2460fdee37bSJoseph Chen case GPIOLevelHigh:
2470fdee37bSJoseph Chen int_type = GPIOLevelLow;
2480fdee37bSJoseph Chen break;
2490fdee37bSJoseph Chen case GPIOLevelLow:
2500fdee37bSJoseph Chen int_type = GPIOLevelHigh;
2510fdee37bSJoseph Chen break;
2520fdee37bSJoseph Chen default:
2530fdee37bSJoseph Chen return -EINVAL;
2540fdee37bSJoseph Chen }
2550fdee37bSJoseph Chen
2560fdee37bSJoseph Chen gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
2570fdee37bSJoseph Chen
2580fdee37bSJoseph Chen return 0;
2590fdee37bSJoseph Chen }
2600fdee37bSJoseph Chen
gpio_irq_get_gpio_level(int gpio_irq)2610fdee37bSJoseph Chen static int gpio_irq_get_gpio_level(int gpio_irq)
2620fdee37bSJoseph Chen {
2630fdee37bSJoseph Chen int gpio = irq_to_gpio(gpio_irq);
2640fdee37bSJoseph Chen struct gpio_bank *bank = gpio_to_bank(gpio);
2650fdee37bSJoseph Chen
2660fdee37bSJoseph Chen if (!bank)
2670fdee37bSJoseph Chen return -EINVAL;
2680fdee37bSJoseph Chen
2690fdee37bSJoseph Chen gpio &= GPIO_PIN_MASK;
2700fdee37bSJoseph Chen if (gpio >= bank->ngpio)
2710fdee37bSJoseph Chen return -EINVAL;
2720fdee37bSJoseph Chen
273af1f96e9SJoseph Chen /* NOTE: GPIO_EXT_PORT doesn't have _H/_L registers */
274af1f96e9SJoseph Chen return readl(bank->regbase + GPIO_EXT_PORT) & offset_to_bit(gpio) ? 1 : 0;
2750fdee37bSJoseph Chen }
2760fdee37bSJoseph Chen
gpio_irq_enable(int gpio_irq)2770fdee37bSJoseph Chen static int gpio_irq_enable(int gpio_irq)
2780fdee37bSJoseph Chen {
2790fdee37bSJoseph Chen int gpio = irq_to_gpio(gpio_irq);
2800fdee37bSJoseph Chen struct gpio_bank *bank = gpio_to_bank(gpio);
2810fdee37bSJoseph Chen
2820fdee37bSJoseph Chen if (!bank)
2830fdee37bSJoseph Chen return -EINVAL;
2840fdee37bSJoseph Chen
2850fdee37bSJoseph Chen gpio &= GPIO_PIN_MASK;
2860fdee37bSJoseph Chen if (gpio >= bank->ngpio)
2870fdee37bSJoseph Chen return -EINVAL;
2880fdee37bSJoseph Chen
2890fdee37bSJoseph Chen gpio_irq_unmask(bank->regbase, offset_to_bit(gpio));
2900fdee37bSJoseph Chen
2910fdee37bSJoseph Chen if (bank->use_count == 0)
2920fdee37bSJoseph Chen irq_handler_enable(IRQ_GPIO0 + bank->id);
2930fdee37bSJoseph Chen bank->use_count++;
2940fdee37bSJoseph Chen
2950fdee37bSJoseph Chen return 0;
2960fdee37bSJoseph Chen }
2970fdee37bSJoseph Chen
gpio_irq_disable(int irq)2980fdee37bSJoseph Chen static int gpio_irq_disable(int irq)
2990fdee37bSJoseph Chen {
3000fdee37bSJoseph Chen int gpio = irq_to_gpio(irq);
3010fdee37bSJoseph Chen struct gpio_bank *bank = gpio_to_bank(gpio);
3020fdee37bSJoseph Chen
3030fdee37bSJoseph Chen if (!bank)
3040fdee37bSJoseph Chen return -EINVAL;
3050fdee37bSJoseph Chen
3060fdee37bSJoseph Chen if (bank->use_count <= 0)
3070fdee37bSJoseph Chen return 0;
3080fdee37bSJoseph Chen
3090fdee37bSJoseph Chen gpio &= GPIO_PIN_MASK;
3100fdee37bSJoseph Chen if (gpio >= bank->ngpio)
3110fdee37bSJoseph Chen return -EINVAL;
3120fdee37bSJoseph Chen
3130fdee37bSJoseph Chen gpio_irq_mask(bank->regbase, offset_to_bit(gpio));
3140fdee37bSJoseph Chen
3150fdee37bSJoseph Chen if (bank->use_count == 1)
3160fdee37bSJoseph Chen irq_handler_disable(IRQ_GPIO0 + bank->id);
3170fdee37bSJoseph Chen bank->use_count--;
3180fdee37bSJoseph Chen
3190fdee37bSJoseph Chen return 0;
3200fdee37bSJoseph Chen }
3210fdee37bSJoseph Chen
gpio_irq_init(void)3220fdee37bSJoseph Chen static int gpio_irq_init(void)
3230fdee37bSJoseph Chen {
3240fdee37bSJoseph Chen struct gpio_bank *bank = NULL;
3250fdee37bSJoseph Chen int i = 0;
3260fdee37bSJoseph Chen
3270fdee37bSJoseph Chen for (i = 0; i < GPIO_BANK_NUM; i++) {
3280fdee37bSJoseph Chen struct udevice *dev;
3290fdee37bSJoseph Chen
3300fdee37bSJoseph Chen dev = malloc(sizeof(*dev));
3310fdee37bSJoseph Chen if (!dev)
3320fdee37bSJoseph Chen return -ENOMEM;
3330fdee37bSJoseph Chen
3340fdee37bSJoseph Chen bank = gpio_id_to_bank(i);
3350fdee37bSJoseph Chen if (bank) {
3360fdee37bSJoseph Chen dev->name = bank->name;
3370fdee37bSJoseph Chen
3380fdee37bSJoseph Chen /* disable gpio pin interrupt */
3390fdee37bSJoseph Chen writel(0xffff0000, bank->regbase + GPIO_INTEN_L);
3400fdee37bSJoseph Chen writel(0xffff0000, bank->regbase + GPIO_INTEN_H);
3410fdee37bSJoseph Chen
3420fdee37bSJoseph Chen /* register gpio group irq handler */
3430fdee37bSJoseph Chen irq_install_handler(IRQ_GPIO0 + bank->id,
3440fdee37bSJoseph Chen (interrupt_handler_t *)generic_gpio_handle_irq, dev);
3450fdee37bSJoseph Chen
3460fdee37bSJoseph Chen /* default disable all gpio group interrupt */
3470fdee37bSJoseph Chen irq_handler_disable(IRQ_GPIO0 + bank->id);
3480fdee37bSJoseph Chen }
3490fdee37bSJoseph Chen }
3500fdee37bSJoseph Chen
3510fdee37bSJoseph Chen return 0;
3520fdee37bSJoseph Chen }
3530fdee37bSJoseph Chen
3540fdee37bSJoseph Chen static struct irq_chip gpio_irq_chip = {
3550fdee37bSJoseph Chen .name = "gpio-irq-chip",
3560fdee37bSJoseph Chen .irq_init = gpio_irq_init,
3570fdee37bSJoseph Chen .irq_enable = gpio_irq_enable,
3580fdee37bSJoseph Chen .irq_disable = gpio_irq_disable,
3590fdee37bSJoseph Chen .irq_set_type = gpio_irq_set_type,
3600fdee37bSJoseph Chen .irq_revert_type = gpio_irq_revert_type,
3610fdee37bSJoseph Chen .irq_get_gpio_level = gpio_irq_get_gpio_level,
3620fdee37bSJoseph Chen };
3630fdee37bSJoseph Chen
arch_gpio_get_irqchip(void)3640fdee37bSJoseph Chen struct irq_chip *arch_gpio_get_irqchip(void)
3650fdee37bSJoseph Chen {
3660fdee37bSJoseph Chen return &gpio_irq_chip;
3670fdee37bSJoseph Chen }
3680fdee37bSJoseph Chen
369