1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Timberdale FPGA GPIO driver
4 * Author: Mocean Laboratories
5 * Copyright (c) 2009 Intel Corporation
6 */
7
8 /* Supports:
9 * Timberdale FPGA GPIO
10 */
11
12 #include <linux/init.h>
13 #include <linux/gpio/driver.h>
14 #include <linux/platform_device.h>
15 #include <linux/irq.h>
16 #include <linux/io.h>
17 #include <linux/interrupt.h>
18 #include <linux/slab.h>
19
20 #define DRIVER_NAME "timb-gpio"
21
22 #define TGPIOVAL 0x00
23 #define TGPIODIR 0x04
24 #define TGPIO_IER 0x08
25 #define TGPIO_ISR 0x0c
26 #define TGPIO_IPR 0x10
27 #define TGPIO_ICR 0x14
28 #define TGPIO_FLR 0x18
29 #define TGPIO_LVR 0x1c
30 #define TGPIO_VER 0x20
31 #define TGPIO_BFLR 0x24
32
33 struct timbgpio {
34 void __iomem *membase;
35 spinlock_t lock; /* mutual exclusion */
36 struct gpio_chip gpio;
37 int irq_base;
38 unsigned long last_ier;
39 };
40
timbgpio_update_bit(struct gpio_chip * gpio,unsigned index,unsigned offset,bool enabled)41 static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
42 unsigned offset, bool enabled)
43 {
44 struct timbgpio *tgpio = gpiochip_get_data(gpio);
45 unsigned long flags;
46 u32 reg;
47
48 spin_lock_irqsave(&tgpio->lock, flags);
49 reg = ioread32(tgpio->membase + offset);
50
51 if (enabled)
52 reg |= (1 << index);
53 else
54 reg &= ~(1 << index);
55
56 iowrite32(reg, tgpio->membase + offset);
57 spin_unlock_irqrestore(&tgpio->lock, flags);
58
59 return 0;
60 }
61
timbgpio_gpio_direction_input(struct gpio_chip * gpio,unsigned nr)62 static int timbgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
63 {
64 return timbgpio_update_bit(gpio, nr, TGPIODIR, true);
65 }
66
timbgpio_gpio_get(struct gpio_chip * gpio,unsigned nr)67 static int timbgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
68 {
69 struct timbgpio *tgpio = gpiochip_get_data(gpio);
70 u32 value;
71
72 value = ioread32(tgpio->membase + TGPIOVAL);
73 return (value & (1 << nr)) ? 1 : 0;
74 }
75
timbgpio_gpio_direction_output(struct gpio_chip * gpio,unsigned nr,int val)76 static int timbgpio_gpio_direction_output(struct gpio_chip *gpio,
77 unsigned nr, int val)
78 {
79 return timbgpio_update_bit(gpio, nr, TGPIODIR, false);
80 }
81
timbgpio_gpio_set(struct gpio_chip * gpio,unsigned int nr,int val)82 static int timbgpio_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val)
83 {
84 return timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0);
85 }
86
timbgpio_to_irq(struct gpio_chip * gpio,unsigned offset)87 static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset)
88 {
89 struct timbgpio *tgpio = gpiochip_get_data(gpio);
90
91 if (tgpio->irq_base <= 0)
92 return -EINVAL;
93
94 return tgpio->irq_base + offset;
95 }
96
97 /*
98 * GPIO IRQ
99 */
timbgpio_irq_disable(struct irq_data * d)100 static void timbgpio_irq_disable(struct irq_data *d)
101 {
102 struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
103 int offset = d->irq - tgpio->irq_base;
104 irq_hw_number_t hwirq = irqd_to_hwirq(d);
105 unsigned long flags;
106
107 spin_lock_irqsave(&tgpio->lock, flags);
108 tgpio->last_ier &= ~(1UL << offset);
109 iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
110 spin_unlock_irqrestore(&tgpio->lock, flags);
111
112 gpiochip_disable_irq(&tgpio->gpio, hwirq);
113 }
114
timbgpio_irq_enable(struct irq_data * d)115 static void timbgpio_irq_enable(struct irq_data *d)
116 {
117 struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
118 int offset = d->irq - tgpio->irq_base;
119 irq_hw_number_t hwirq = irqd_to_hwirq(d);
120 unsigned long flags;
121
122 gpiochip_enable_irq(&tgpio->gpio, hwirq);
123
124 spin_lock_irqsave(&tgpio->lock, flags);
125 tgpio->last_ier |= 1UL << offset;
126 iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
127 spin_unlock_irqrestore(&tgpio->lock, flags);
128 }
129
timbgpio_irq_type(struct irq_data * d,unsigned trigger)130 static int timbgpio_irq_type(struct irq_data *d, unsigned trigger)
131 {
132 struct timbgpio *tgpio = irq_data_get_irq_chip_data(d);
133 int offset = d->irq - tgpio->irq_base;
134 unsigned long flags;
135 u32 lvr, flr, bflr = 0;
136 u32 ver;
137 int ret = 0;
138
139 if (offset < 0 || offset >= tgpio->gpio.ngpio)
140 return -EINVAL;
141
142 ver = ioread32(tgpio->membase + TGPIO_VER);
143
144 spin_lock_irqsave(&tgpio->lock, flags);
145
146 lvr = ioread32(tgpio->membase + TGPIO_LVR);
147 flr = ioread32(tgpio->membase + TGPIO_FLR);
148 if (ver > 2)
149 bflr = ioread32(tgpio->membase + TGPIO_BFLR);
150
151 if (trigger & IRQ_TYPE_LEVEL_MASK) {
152 bflr &= ~(1 << offset);
153 flr &= ~(1 << offset);
154 if (trigger & IRQ_TYPE_LEVEL_HIGH)
155 lvr |= 1 << offset;
156 else
157 lvr &= ~(1 << offset);
158 }
159
160 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
161 if (ver < 3) {
162 ret = -EINVAL;
163 goto out;
164 } else {
165 flr |= 1 << offset;
166 bflr |= 1 << offset;
167 }
168 } else {
169 bflr &= ~(1 << offset);
170 flr |= 1 << offset;
171 if (trigger & IRQ_TYPE_EDGE_FALLING)
172 lvr &= ~(1 << offset);
173 else
174 lvr |= 1 << offset;
175 }
176
177 iowrite32(lvr, tgpio->membase + TGPIO_LVR);
178 iowrite32(flr, tgpio->membase + TGPIO_FLR);
179 if (ver > 2)
180 iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
181
182 iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
183
184 out:
185 spin_unlock_irqrestore(&tgpio->lock, flags);
186 return ret;
187 }
188
timbgpio_irq(struct irq_desc * desc)189 static void timbgpio_irq(struct irq_desc *desc)
190 {
191 struct timbgpio *tgpio = irq_desc_get_handler_data(desc);
192 struct irq_data *data = irq_desc_get_irq_data(desc);
193 unsigned long ipr;
194 int offset;
195
196 data->chip->irq_ack(data);
197 ipr = ioread32(tgpio->membase + TGPIO_IPR);
198 iowrite32(ipr, tgpio->membase + TGPIO_ICR);
199
200 /*
201 * Some versions of the hardware trash the IER register if more than
202 * one interrupt is received simultaneously.
203 */
204 iowrite32(0, tgpio->membase + TGPIO_IER);
205
206 for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio)
207 generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
208
209 iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER);
210 }
211
212 static const struct irq_chip timbgpio_irqchip = {
213 .name = "GPIO",
214 .irq_enable = timbgpio_irq_enable,
215 .irq_disable = timbgpio_irq_disable,
216 .irq_set_type = timbgpio_irq_type,
217 .flags = IRQCHIP_IMMUTABLE,
218 GPIOCHIP_IRQ_RESOURCE_HELPERS,
219 };
220
timbgpio_probe(struct platform_device * pdev)221 static int timbgpio_probe(struct platform_device *pdev)
222 {
223 int err, i;
224 struct device *dev = &pdev->dev;
225 struct gpio_chip *gc;
226 struct timbgpio *tgpio;
227 int irq = platform_get_irq(pdev, 0);
228
229 tgpio = devm_kzalloc(dev, sizeof(*tgpio), GFP_KERNEL);
230 if (!tgpio)
231 return -ENOMEM;
232
233 gc = &tgpio->gpio;
234
235 err = device_property_read_u32(dev, "irq-base", &tgpio->irq_base);
236 if (err)
237 return err;
238
239 err = device_property_read_u32(dev, "gpio-base", &gc->base);
240 if (err)
241 return err;
242
243 spin_lock_init(&tgpio->lock);
244
245 tgpio->membase = devm_platform_ioremap_resource(pdev, 0);
246 if (IS_ERR(tgpio->membase))
247 return PTR_ERR(tgpio->membase);
248
249 gc->label = dev_name(&pdev->dev);
250 gc->owner = THIS_MODULE;
251 gc->parent = &pdev->dev;
252 gc->direction_input = timbgpio_gpio_direction_input;
253 gc->get = timbgpio_gpio_get;
254 gc->direction_output = timbgpio_gpio_direction_output;
255 gc->set = timbgpio_gpio_set;
256 gc->to_irq = (irq >= 0 && tgpio->irq_base > 0) ? timbgpio_to_irq : NULL;
257 gc->dbg_show = NULL;
258 gc->can_sleep = false;
259
260 err = devm_gpiochip_add_data(&pdev->dev, gc, tgpio);
261 if (err)
262 return err;
263
264 if (gc->ngpio > 32)
265 return dev_err_probe(dev, -EINVAL, "Invalid number of pins\n");
266
267 /* make sure to disable interrupts */
268 iowrite32(0x0, tgpio->membase + TGPIO_IER);
269
270 if (irq < 0 || tgpio->irq_base <= 0)
271 return 0;
272
273 for (i = 0; i < gc->ngpio; i++) {
274 irq_set_chip_and_handler(tgpio->irq_base + i,
275 &timbgpio_irqchip, handle_simple_irq);
276 irq_set_chip_data(tgpio->irq_base + i, tgpio);
277 irq_clear_status_flags(tgpio->irq_base + i, IRQ_NOREQUEST | IRQ_NOPROBE);
278 }
279
280 irq_set_chained_handler_and_data(irq, timbgpio_irq, tgpio);
281
282 return 0;
283 }
284
285 static struct platform_driver timbgpio_platform_driver = {
286 .driver = {
287 .name = DRIVER_NAME,
288 .suppress_bind_attrs = true,
289 },
290 .probe = timbgpio_probe,
291 };
292
293 /*--------------------------------------------------------------------------*/
294
295 builtin_platform_driver(timbgpio_platform_driver);
296