GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / gpio / gpio-etraxfs.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/gpio/driver.h>
5 #include <linux/of_gpio.h>
6 #include <linux/io.h>
7 #include <linux/interrupt.h>
8 #include <linux/platform_device.h>
9
10 #define ETRAX_FS_rw_pa_dout     0
11 #define ETRAX_FS_r_pa_din       4
12 #define ETRAX_FS_rw_pa_oe       8
13 #define ETRAX_FS_rw_intr_cfg    12
14 #define ETRAX_FS_rw_intr_mask   16
15 #define ETRAX_FS_rw_ack_intr    20
16 #define ETRAX_FS_r_intr         24
17 #define ETRAX_FS_r_masked_intr  28
18 #define ETRAX_FS_rw_pb_dout     32
19 #define ETRAX_FS_r_pb_din       36
20 #define ETRAX_FS_rw_pb_oe       40
21 #define ETRAX_FS_rw_pc_dout     48
22 #define ETRAX_FS_r_pc_din       52
23 #define ETRAX_FS_rw_pc_oe       56
24 #define ETRAX_FS_rw_pd_dout     64
25 #define ETRAX_FS_r_pd_din       68
26 #define ETRAX_FS_rw_pd_oe       72
27 #define ETRAX_FS_rw_pe_dout     80
28 #define ETRAX_FS_r_pe_din       84
29 #define ETRAX_FS_rw_pe_oe       88
30
31 #define ARTPEC3_r_pa_din        0
32 #define ARTPEC3_rw_pa_dout      4
33 #define ARTPEC3_rw_pa_oe        8
34 #define ARTPEC3_r_pb_din        44
35 #define ARTPEC3_rw_pb_dout      48
36 #define ARTPEC3_rw_pb_oe        52
37 #define ARTPEC3_r_pc_din        88
38 #define ARTPEC3_rw_pc_dout      92
39 #define ARTPEC3_rw_pc_oe        96
40 #define ARTPEC3_r_pd_din        116
41 #define ARTPEC3_rw_intr_cfg     120
42 #define ARTPEC3_rw_intr_pins    124
43 #define ARTPEC3_rw_intr_mask    128
44 #define ARTPEC3_rw_ack_intr     132
45 #define ARTPEC3_r_masked_intr   140
46
47 #define GIO_CFG_OFF             0
48 #define GIO_CFG_HI              1
49 #define GIO_CFG_LO              2
50 #define GIO_CFG_SET             3
51 #define GIO_CFG_POSEDGE         5
52 #define GIO_CFG_NEGEDGE         6
53 #define GIO_CFG_ANYEDGE         7
54
55 struct etraxfs_gpio_info;
56
57 struct etraxfs_gpio_block {
58         raw_spinlock_t lock;
59         u32 mask;
60         u32 cfg;
61         u32 pins;
62         unsigned int group[8];
63
64         void __iomem *regs;
65         const struct etraxfs_gpio_info *info;
66 };
67
68 struct etraxfs_gpio_chip {
69         struct gpio_chip gc;
70         struct etraxfs_gpio_block *block;
71 };
72
73 struct etraxfs_gpio_port {
74         const char *label;
75         unsigned int oe;
76         unsigned int dout;
77         unsigned int din;
78         unsigned int ngpio;
79 };
80
81 struct etraxfs_gpio_info {
82         unsigned int num_ports;
83         const struct etraxfs_gpio_port *ports;
84
85         unsigned int rw_ack_intr;
86         unsigned int rw_intr_mask;
87         unsigned int rw_intr_cfg;
88         unsigned int rw_intr_pins;
89         unsigned int r_masked_intr;
90 };
91
92 static const struct etraxfs_gpio_port etraxfs_gpio_etraxfs_ports[] = {
93         {
94                 .label  = "A",
95                 .ngpio  = 8,
96                 .oe     = ETRAX_FS_rw_pa_oe,
97                 .dout   = ETRAX_FS_rw_pa_dout,
98                 .din    = ETRAX_FS_r_pa_din,
99         },
100         {
101                 .label  = "B",
102                 .ngpio  = 18,
103                 .oe     = ETRAX_FS_rw_pb_oe,
104                 .dout   = ETRAX_FS_rw_pb_dout,
105                 .din    = ETRAX_FS_r_pb_din,
106         },
107         {
108                 .label  = "C",
109                 .ngpio  = 18,
110                 .oe     = ETRAX_FS_rw_pc_oe,
111                 .dout   = ETRAX_FS_rw_pc_dout,
112                 .din    = ETRAX_FS_r_pc_din,
113         },
114         {
115                 .label  = "D",
116                 .ngpio  = 18,
117                 .oe     = ETRAX_FS_rw_pd_oe,
118                 .dout   = ETRAX_FS_rw_pd_dout,
119                 .din    = ETRAX_FS_r_pd_din,
120         },
121         {
122                 .label  = "E",
123                 .ngpio  = 18,
124                 .oe     = ETRAX_FS_rw_pe_oe,
125                 .dout   = ETRAX_FS_rw_pe_dout,
126                 .din    = ETRAX_FS_r_pe_din,
127         },
128 };
129
130 static const struct etraxfs_gpio_info etraxfs_gpio_etraxfs = {
131         .num_ports = ARRAY_SIZE(etraxfs_gpio_etraxfs_ports),
132         .ports = etraxfs_gpio_etraxfs_ports,
133         .rw_ack_intr    = ETRAX_FS_rw_ack_intr,
134         .rw_intr_mask   = ETRAX_FS_rw_intr_mask,
135         .rw_intr_cfg    = ETRAX_FS_rw_intr_cfg,
136         .r_masked_intr  = ETRAX_FS_r_masked_intr,
137 };
138
139 static const struct etraxfs_gpio_port etraxfs_gpio_artpec3_ports[] = {
140         {
141                 .label  = "A",
142                 .ngpio  = 32,
143                 .oe     = ARTPEC3_rw_pa_oe,
144                 .dout   = ARTPEC3_rw_pa_dout,
145                 .din    = ARTPEC3_r_pa_din,
146         },
147         {
148                 .label  = "B",
149                 .ngpio  = 32,
150                 .oe     = ARTPEC3_rw_pb_oe,
151                 .dout   = ARTPEC3_rw_pb_dout,
152                 .din    = ARTPEC3_r_pb_din,
153         },
154         {
155                 .label  = "C",
156                 .ngpio  = 16,
157                 .oe     = ARTPEC3_rw_pc_oe,
158                 .dout   = ARTPEC3_rw_pc_dout,
159                 .din    = ARTPEC3_r_pc_din,
160         },
161         {
162                 .label  = "D",
163                 .ngpio  = 32,
164                 .din    = ARTPEC3_r_pd_din,
165         },
166 };
167
168 static const struct etraxfs_gpio_info etraxfs_gpio_artpec3 = {
169         .num_ports = ARRAY_SIZE(etraxfs_gpio_artpec3_ports),
170         .ports = etraxfs_gpio_artpec3_ports,
171         .rw_ack_intr    = ARTPEC3_rw_ack_intr,
172         .rw_intr_mask   = ARTPEC3_rw_intr_mask,
173         .rw_intr_cfg    = ARTPEC3_rw_intr_cfg,
174         .r_masked_intr  = ARTPEC3_r_masked_intr,
175         .rw_intr_pins   = ARTPEC3_rw_intr_pins,
176 };
177
178 static unsigned int etraxfs_gpio_chip_to_port(struct gpio_chip *gc)
179 {
180         return gc->label[0] - 'A';
181 }
182
183 static int etraxfs_gpio_of_xlate(struct gpio_chip *gc,
184                                const struct of_phandle_args *gpiospec,
185                                u32 *flags)
186 {
187         /*
188          * Port numbers are A to E, and the properties are integers, so we
189          * specify them as 0xA - 0xE.
190          */
191         if (etraxfs_gpio_chip_to_port(gc) + 0xA != gpiospec->args[2])
192                 return -EINVAL;
193
194         return of_gpio_simple_xlate(gc, gpiospec, flags);
195 }
196
197 static const struct of_device_id etraxfs_gpio_of_table[] = {
198         {
199                 .compatible = "axis,etraxfs-gio",
200                 .data = &etraxfs_gpio_etraxfs,
201         },
202         {
203                 .compatible = "axis,artpec3-gio",
204                 .data = &etraxfs_gpio_artpec3,
205         },
206         {},
207 };
208
209 static unsigned int etraxfs_gpio_to_group_irq(unsigned int gpio)
210 {
211         return gpio % 8;
212 }
213
214 static unsigned int etraxfs_gpio_to_group_pin(struct etraxfs_gpio_chip *chip,
215                                               unsigned int gpio)
216 {
217         return 4 * etraxfs_gpio_chip_to_port(&chip->gc) + gpio / 8;
218 }
219
220 static void etraxfs_gpio_irq_ack(struct irq_data *d)
221 {
222         struct etraxfs_gpio_chip *chip =
223                 gpiochip_get_data(irq_data_get_irq_chip_data(d));
224         struct etraxfs_gpio_block *block = chip->block;
225         unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
226
227         writel(BIT(grpirq), block->regs + block->info->rw_ack_intr);
228 }
229
230 static void etraxfs_gpio_irq_mask(struct irq_data *d)
231 {
232         struct etraxfs_gpio_chip *chip =
233                 gpiochip_get_data(irq_data_get_irq_chip_data(d));
234         struct etraxfs_gpio_block *block = chip->block;
235         unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
236
237         raw_spin_lock(&block->lock);
238         block->mask &= ~BIT(grpirq);
239         writel(block->mask, block->regs + block->info->rw_intr_mask);
240         raw_spin_unlock(&block->lock);
241 }
242
243 static void etraxfs_gpio_irq_unmask(struct irq_data *d)
244 {
245         struct etraxfs_gpio_chip *chip =
246                 gpiochip_get_data(irq_data_get_irq_chip_data(d));
247         struct etraxfs_gpio_block *block = chip->block;
248         unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
249
250         raw_spin_lock(&block->lock);
251         block->mask |= BIT(grpirq);
252         writel(block->mask, block->regs + block->info->rw_intr_mask);
253         raw_spin_unlock(&block->lock);
254 }
255
256 static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type)
257 {
258         struct etraxfs_gpio_chip *chip =
259                 gpiochip_get_data(irq_data_get_irq_chip_data(d));
260         struct etraxfs_gpio_block *block = chip->block;
261         unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
262         u32 cfg;
263
264         switch (type) {
265         case IRQ_TYPE_EDGE_RISING:
266                 cfg = GIO_CFG_POSEDGE;
267                 break;
268         case IRQ_TYPE_EDGE_FALLING:
269                 cfg = GIO_CFG_NEGEDGE;
270                 break;
271         case IRQ_TYPE_EDGE_BOTH:
272                 cfg = GIO_CFG_ANYEDGE;
273                 break;
274         case IRQ_TYPE_LEVEL_LOW:
275                 cfg = GIO_CFG_LO;
276                 break;
277         case IRQ_TYPE_LEVEL_HIGH:
278                 cfg = GIO_CFG_HI;
279                 break;
280         default:
281                 return -EINVAL;
282         }
283
284         raw_spin_lock(&block->lock);
285         block->cfg &= ~(0x7 << (grpirq * 3));
286         block->cfg |= (cfg << (grpirq * 3));
287         writel(block->cfg, block->regs + block->info->rw_intr_cfg);
288         raw_spin_unlock(&block->lock);
289
290         return 0;
291 }
292
293 static int etraxfs_gpio_irq_request_resources(struct irq_data *d)
294 {
295         struct etraxfs_gpio_chip *chip =
296                 gpiochip_get_data(irq_data_get_irq_chip_data(d));
297         struct etraxfs_gpio_block *block = chip->block;
298         unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
299         int ret = -EBUSY;
300
301         raw_spin_lock(&block->lock);
302         if (block->group[grpirq])
303                 goto out;
304
305         ret = gpiochip_lock_as_irq(&chip->gc, d->hwirq);
306         if (ret)
307                 goto out;
308
309         block->group[grpirq] = d->irq;
310         if (block->info->rw_intr_pins) {
311                 unsigned int pin = etraxfs_gpio_to_group_pin(chip, d->hwirq);
312
313                 block->pins &= ~(0xf << (grpirq * 4));
314                 block->pins |= (pin << (grpirq * 4));
315
316                 writel(block->pins, block->regs + block->info->rw_intr_pins);
317         }
318
319 out:
320         raw_spin_unlock(&block->lock);
321         return ret;
322 }
323
324 static void etraxfs_gpio_irq_release_resources(struct irq_data *d)
325 {
326         struct etraxfs_gpio_chip *chip =
327                 gpiochip_get_data(irq_data_get_irq_chip_data(d));
328         struct etraxfs_gpio_block *block = chip->block;
329         unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
330
331         raw_spin_lock(&block->lock);
332         block->group[grpirq] = 0;
333         gpiochip_unlock_as_irq(&chip->gc, d->hwirq);
334         raw_spin_unlock(&block->lock);
335 }
336
337 static struct irq_chip etraxfs_gpio_irq_chip = {
338         .name           = "gpio-etraxfs",
339         .irq_ack        = etraxfs_gpio_irq_ack,
340         .irq_mask       = etraxfs_gpio_irq_mask,
341         .irq_unmask     = etraxfs_gpio_irq_unmask,
342         .irq_set_type   = etraxfs_gpio_irq_set_type,
343         .irq_request_resources = etraxfs_gpio_irq_request_resources,
344         .irq_release_resources = etraxfs_gpio_irq_release_resources,
345 };
346
347 static irqreturn_t etraxfs_gpio_interrupt(int irq, void *dev_id)
348 {
349         struct etraxfs_gpio_block *block = dev_id;
350         unsigned long intr = readl(block->regs + block->info->r_masked_intr);
351         int bit;
352
353         for_each_set_bit(bit, &intr, 8)
354                 generic_handle_irq(block->group[bit]);
355
356         return IRQ_RETVAL(intr & 0xff);
357 }
358
359 static int etraxfs_gpio_probe(struct platform_device *pdev)
360 {
361         struct device *dev = &pdev->dev;
362         const struct etraxfs_gpio_info *info;
363         const struct of_device_id *match;
364         struct etraxfs_gpio_block *block;
365         struct etraxfs_gpio_chip *chips;
366         struct resource *res, *irq;
367         bool allportsirq = false;
368         void __iomem *regs;
369         int ret;
370         int i;
371
372         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
373         regs = devm_ioremap_resource(dev, res);
374         if (IS_ERR(regs))
375                 return PTR_ERR(regs);
376
377         match = of_match_node(etraxfs_gpio_of_table, dev->of_node);
378         if (!match)
379                 return -EINVAL;
380
381         info = match->data;
382
383         chips = devm_kzalloc(dev, sizeof(*chips) * info->num_ports, GFP_KERNEL);
384         if (!chips)
385                 return -ENOMEM;
386
387         irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
388         if (!irq)
389                 return -EINVAL;
390
391         block = devm_kzalloc(dev, sizeof(*block), GFP_KERNEL);
392         if (!block)
393                 return -ENOMEM;
394
395         raw_spin_lock_init(&block->lock);
396
397         block->regs = regs;
398         block->info = info;
399
400         writel(0, block->regs + info->rw_intr_mask);
401         writel(0, block->regs + info->rw_intr_cfg);
402         if (info->rw_intr_pins) {
403                 allportsirq = true;
404                 writel(0, block->regs + info->rw_intr_pins);
405         }
406
407         ret = devm_request_irq(dev, irq->start, etraxfs_gpio_interrupt,
408                                IRQF_SHARED, dev_name(dev), block);
409         if (ret) {
410                 dev_err(dev, "Unable to request irq %d\n", ret);
411                 return ret;
412         }
413
414         for (i = 0; i < info->num_ports; i++) {
415                 struct etraxfs_gpio_chip *chip = &chips[i];
416                 struct gpio_chip *gc = &chip->gc;
417                 const struct etraxfs_gpio_port *port = &info->ports[i];
418                 unsigned long flags = BGPIOF_READ_OUTPUT_REG_SET;
419                 void __iomem *dat = regs + port->din;
420                 void __iomem *set = regs + port->dout;
421                 void __iomem *dirout = regs + port->oe;
422
423                 chip->block = block;
424
425                 if (dirout == set) {
426                         dirout = set = NULL;
427                         flags = BGPIOF_NO_OUTPUT;
428                 }
429
430                 ret = bgpio_init(gc, dev, 4,
431                                  dat, set, NULL, dirout, NULL,
432                                  flags);
433                 if (ret) {
434                         dev_err(dev, "Unable to init port %s\n",
435                                 port->label);
436                         continue;
437                 }
438
439                 gc->ngpio = port->ngpio;
440                 gc->label = port->label;
441
442                 gc->of_node = dev->of_node;
443                 gc->of_gpio_n_cells = 3;
444                 gc->of_xlate = etraxfs_gpio_of_xlate;
445
446                 ret = gpiochip_add_data(gc, chip);
447                 if (ret) {
448                         dev_err(dev, "Unable to register port %s\n",
449                                 gc->label);
450                         continue;
451                 }
452
453                 if (i > 0 && !allportsirq)
454                         continue;
455
456                 ret = gpiochip_irqchip_add(gc, &etraxfs_gpio_irq_chip, 0,
457                                            handle_level_irq, IRQ_TYPE_NONE);
458                 if (ret) {
459                         dev_err(dev, "Unable to add irqchip to port %s\n",
460                                 gc->label);
461                 }
462         }
463
464         return 0;
465 }
466
467 static struct platform_driver etraxfs_gpio_driver = {
468         .driver = {
469                 .name           = "etraxfs-gpio",
470                 .of_match_table = of_match_ptr(etraxfs_gpio_of_table),
471         },
472         .probe  = etraxfs_gpio_probe,
473 };
474
475 builtin_platform_driver(etraxfs_gpio_driver);