1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Faraday Technolog FTGPIO010 gpiochip and interrupt routines 4 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> 5 * 6 * Based on arch/arm/mach-gemini/gpio.c: 7 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 8 * 9 * Based on plat-mxc/gpio.c: 10 * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> 11 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 12 */ 13 #include <linux/gpio/driver.h> 14 #include <linux/io.h> 15 #include <linux/interrupt.h> 16 #include <linux/platform_device.h> 17 #include <linux/bitops.h> 18 19 /* GPIO registers definition */ 20 #define GPIO_DATA_OUT 0x00 21 #define GPIO_DATA_IN 0x04 22 #define GPIO_DIR 0x08 23 #define GPIO_BYPASS_IN 0x0C 24 #define GPIO_DATA_SET 0x10 25 #define GPIO_DATA_CLR 0x14 26 #define GPIO_PULL_EN 0x18 27 #define GPIO_PULL_TYPE 0x1C 28 #define GPIO_INT_EN 0x20 29 #define GPIO_INT_STAT_RAW 0x24 30 #define GPIO_INT_STAT_MASKED 0x28 31 #define GPIO_INT_MASK 0x2C 32 #define GPIO_INT_CLR 0x30 33 #define GPIO_INT_TYPE 0x34 34 #define GPIO_INT_BOTH_EDGE 0x38 35 #define GPIO_INT_LEVEL 0x3C 36 #define GPIO_DEBOUNCE_EN 0x40 37 #define GPIO_DEBOUNCE_PRESCALE 0x44 38 39 /** 40 * struct ftgpio_gpio - Gemini GPIO state container 41 * @dev: containing device for this instance 42 * @gc: gpiochip for this instance 43 */ 44 struct ftgpio_gpio { 45 struct device *dev; 46 struct gpio_chip gc; 47 void __iomem *base; 48 }; 49 50 static void ftgpio_gpio_ack_irq(struct irq_data *d) 51 { 52 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 53 struct ftgpio_gpio *g = gpiochip_get_data(gc); 54 55 writel(BIT(irqd_to_hwirq(d)), g->base + GPIO_INT_CLR); 56 } 57 58 static void ftgpio_gpio_mask_irq(struct irq_data *d) 59 { 60 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 61 struct ftgpio_gpio *g = gpiochip_get_data(gc); 62 u32 val; 63 64 val = readl(g->base + GPIO_INT_EN); 65 val &= ~BIT(irqd_to_hwirq(d)); 66 writel(val, g->base + GPIO_INT_EN); 67 } 68 69 static void ftgpio_gpio_unmask_irq(struct irq_data *d) 70 { 71 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 72 struct ftgpio_gpio *g = gpiochip_get_data(gc); 73 u32 val; 74 75 val = readl(g->base + GPIO_INT_EN); 76 val |= BIT(irqd_to_hwirq(d)); 77 writel(val, g->base + GPIO_INT_EN); 78 } 79 80 static int ftgpio_gpio_set_irq_type(struct irq_data *d, unsigned int type) 81 { 82 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 83 struct ftgpio_gpio *g = gpiochip_get_data(gc); 84 u32 mask = BIT(irqd_to_hwirq(d)); 85 u32 reg_both, reg_level, reg_type; 86 87 reg_type = readl(g->base + GPIO_INT_TYPE); 88 reg_level = readl(g->base + GPIO_INT_LEVEL); 89 reg_both = readl(g->base + GPIO_INT_BOTH_EDGE); 90 91 switch (type) { 92 case IRQ_TYPE_EDGE_BOTH: 93 irq_set_handler_locked(d, handle_edge_irq); 94 reg_type &= ~mask; 95 reg_both |= mask; 96 break; 97 case IRQ_TYPE_EDGE_RISING: 98 irq_set_handler_locked(d, handle_edge_irq); 99 reg_type &= ~mask; 100 reg_both &= ~mask; 101 reg_level &= ~mask; 102 break; 103 case IRQ_TYPE_EDGE_FALLING: 104 irq_set_handler_locked(d, handle_edge_irq); 105 reg_type &= ~mask; 106 reg_both &= ~mask; 107 reg_level |= mask; 108 break; 109 case IRQ_TYPE_LEVEL_HIGH: 110 irq_set_handler_locked(d, handle_level_irq); 111 reg_type |= mask; 112 reg_level &= ~mask; 113 break; 114 case IRQ_TYPE_LEVEL_LOW: 115 irq_set_handler_locked(d, handle_level_irq); 116 reg_type |= mask; 117 reg_level |= mask; 118 break; 119 default: 120 irq_set_handler_locked(d, handle_bad_irq); 121 return -EINVAL; 122 } 123 124 writel(reg_type, g->base + GPIO_INT_TYPE); 125 writel(reg_level, g->base + GPIO_INT_LEVEL); 126 writel(reg_both, g->base + GPIO_INT_BOTH_EDGE); 127 128 ftgpio_gpio_ack_irq(d); 129 130 return 0; 131 } 132 133 static struct irq_chip ftgpio_gpio_irqchip = { 134 .name = "FTGPIO010", 135 .irq_ack = ftgpio_gpio_ack_irq, 136 .irq_mask = ftgpio_gpio_mask_irq, 137 .irq_unmask = ftgpio_gpio_unmask_irq, 138 .irq_set_type = ftgpio_gpio_set_irq_type, 139 }; 140 141 static void ftgpio_gpio_irq_handler(struct irq_desc *desc) 142 { 143 struct gpio_chip *gc = irq_desc_get_handler_data(desc); 144 struct ftgpio_gpio *g = gpiochip_get_data(gc); 145 struct irq_chip *irqchip = irq_desc_get_chip(desc); 146 int offset; 147 unsigned long stat; 148 149 chained_irq_enter(irqchip, desc); 150 151 stat = readl(g->base + GPIO_INT_STAT_RAW); 152 if (stat) 153 for_each_set_bit(offset, &stat, gc->ngpio) 154 generic_handle_irq(irq_find_mapping(gc->irq.domain, 155 offset)); 156 157 chained_irq_exit(irqchip, desc); 158 } 159 160 static int ftgpio_gpio_probe(struct platform_device *pdev) 161 { 162 struct device *dev = &pdev->dev; 163 struct resource *res; 164 struct ftgpio_gpio *g; 165 int irq; 166 int ret; 167 168 g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); 169 if (!g) 170 return -ENOMEM; 171 172 g->dev = dev; 173 174 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 175 g->base = devm_ioremap_resource(dev, res); 176 if (IS_ERR(g->base)) 177 return PTR_ERR(g->base); 178 179 irq = platform_get_irq(pdev, 0); 180 if (irq <= 0) 181 return irq ? irq : -EINVAL; 182 183 ret = bgpio_init(&g->gc, dev, 4, 184 g->base + GPIO_DATA_IN, 185 g->base + GPIO_DATA_SET, 186 g->base + GPIO_DATA_CLR, 187 g->base + GPIO_DIR, 188 NULL, 189 0); 190 if (ret) { 191 dev_err(dev, "unable to init generic GPIO\n"); 192 return ret; 193 } 194 g->gc.label = "FTGPIO010"; 195 g->gc.base = -1; 196 g->gc.parent = dev; 197 g->gc.owner = THIS_MODULE; 198 /* ngpio is set by bgpio_init() */ 199 200 ret = devm_gpiochip_add_data(dev, &g->gc, g); 201 if (ret) 202 return ret; 203 204 /* Disable, unmask and clear all interrupts */ 205 writel(0x0, g->base + GPIO_INT_EN); 206 writel(0x0, g->base + GPIO_INT_MASK); 207 writel(~0x0, g->base + GPIO_INT_CLR); 208 209 ret = gpiochip_irqchip_add(&g->gc, &ftgpio_gpio_irqchip, 210 0, handle_bad_irq, 211 IRQ_TYPE_NONE); 212 if (ret) { 213 dev_info(dev, "could not add irqchip\n"); 214 return ret; 215 } 216 gpiochip_set_chained_irqchip(&g->gc, &ftgpio_gpio_irqchip, 217 irq, ftgpio_gpio_irq_handler); 218 219 dev_info(dev, "FTGPIO010 @%p registered\n", g->base); 220 221 return 0; 222 } 223 224 static const struct of_device_id ftgpio_gpio_of_match[] = { 225 { 226 .compatible = "cortina,gemini-gpio", 227 }, 228 { 229 .compatible = "moxa,moxart-gpio", 230 }, 231 { 232 .compatible = "faraday,ftgpio010", 233 }, 234 {}, 235 }; 236 237 static struct platform_driver ftgpio_gpio_driver = { 238 .driver = { 239 .name = "ftgpio010-gpio", 240 .of_match_table = of_match_ptr(ftgpio_gpio_of_match), 241 }, 242 .probe = ftgpio_gpio_probe, 243 }; 244 builtin_platform_driver(ftgpio_gpio_driver); 245