Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-microblaze.git] / drivers / gpio / gpio-vr41xx.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Driver for NEC VR4100 series General-purpose I/O Unit.
4  *
5  *  Copyright (C) 2002 MontaVista Software Inc.
6  *      Author: Yoichi Yuasa <source@mvista.com>
7  *  Copyright (C) 2003-2009  Yoichi Yuasa <yuasa@linux-mips.org>
8  */
9 #include <linux/errno.h>
10 #include <linux/fs.h>
11 #include <linux/gpio/driver.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/io.h>
15 #include <linux/irq.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/spinlock.h>
20 #include <linux/types.h>
21
22 #include <asm/vr41xx/giu.h>
23 #include <asm/vr41xx/irq.h>
24 #include <asm/vr41xx/vr41xx.h>
25
26 MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>");
27 MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver");
28 MODULE_LICENSE("GPL");
29
30 #define GIUIOSELL       0x00
31 #define GIUIOSELH       0x02
32 #define GIUPIODL        0x04
33 #define GIUPIODH        0x06
34 #define GIUINTSTATL     0x08
35 #define GIUINTSTATH     0x0a
36 #define GIUINTENL       0x0c
37 #define GIUINTENH       0x0e
38 #define GIUINTTYPL      0x10
39 #define GIUINTTYPH      0x12
40 #define GIUINTALSELL    0x14
41 #define GIUINTALSELH    0x16
42 #define GIUINTHTSELL    0x18
43 #define GIUINTHTSELH    0x1a
44 #define GIUPODATL       0x1c
45 #define GIUPODATEN      0x1c
46 #define GIUPODATH       0x1e
47  #define PIOEN0         0x0100
48  #define PIOEN1         0x0200
49 #define GIUPODAT        0x1e
50 #define GIUFEDGEINHL    0x20
51 #define GIUFEDGEINHH    0x22
52 #define GIUREDGEINHL    0x24
53 #define GIUREDGEINHH    0x26
54
55 #define GIUUSEUPDN      0x1e0
56 #define GIUTERMUPDN     0x1e2
57
58 #define GPIO_HAS_PULLUPDOWN_IO          0x0001
59 #define GPIO_HAS_OUTPUT_ENABLE          0x0002
60 #define GPIO_HAS_INTERRUPT_EDGE_SELECT  0x0100
61
62 enum {
63         GPIO_INPUT,
64         GPIO_OUTPUT,
65 };
66
67 static DEFINE_SPINLOCK(giu_lock);
68 static unsigned long giu_flags;
69
70 static void __iomem *giu_base;
71 static struct gpio_chip vr41xx_gpio_chip;
72
73 #define giu_read(offset)                readw(giu_base + (offset))
74 #define giu_write(offset, value)        writew((value), giu_base + (offset))
75
76 #define GPIO_PIN_OF_IRQ(irq)    ((irq) - GIU_IRQ_BASE)
77 #define GIUINT_HIGH_OFFSET      16
78 #define GIUINT_HIGH_MAX         32
79
80 static inline u16 giu_set(u16 offset, u16 set)
81 {
82         u16 data;
83
84         data = giu_read(offset);
85         data |= set;
86         giu_write(offset, data);
87
88         return data;
89 }
90
91 static inline u16 giu_clear(u16 offset, u16 clear)
92 {
93         u16 data;
94
95         data = giu_read(offset);
96         data &= ~clear;
97         giu_write(offset, data);
98
99         return data;
100 }
101
102 static void ack_giuint_low(struct irq_data *d)
103 {
104         giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(d->irq));
105 }
106
107 static void mask_giuint_low(struct irq_data *d)
108 {
109         giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
110 }
111
112 static void mask_ack_giuint_low(struct irq_data *d)
113 {
114         unsigned int pin;
115
116         pin = GPIO_PIN_OF_IRQ(d->irq);
117         giu_clear(GIUINTENL, 1 << pin);
118         giu_write(GIUINTSTATL, 1 << pin);
119 }
120
121 static void unmask_giuint_low(struct irq_data *d)
122 {
123         giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
124 }
125
126 static unsigned int startup_giuint(struct irq_data *data)
127 {
128         int ret;
129
130         ret = gpiochip_lock_as_irq(&vr41xx_gpio_chip, irqd_to_hwirq(data));
131         if (ret) {
132                 dev_err(vr41xx_gpio_chip.parent,
133                         "unable to lock HW IRQ %lu for IRQ\n",
134                         data->hwirq);
135                 return ret;
136         }
137
138         /* Satisfy the .enable semantics by unmasking the line */
139         unmask_giuint_low(data);
140         return 0;
141 }
142
143 static void shutdown_giuint(struct irq_data *data)
144 {
145         mask_giuint_low(data);
146         gpiochip_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq);
147 }
148
149 static struct irq_chip giuint_low_irq_chip = {
150         .name           = "GIUINTL",
151         .irq_ack        = ack_giuint_low,
152         .irq_mask       = mask_giuint_low,
153         .irq_mask_ack   = mask_ack_giuint_low,
154         .irq_unmask     = unmask_giuint_low,
155         .irq_startup    = startup_giuint,
156         .irq_shutdown   = shutdown_giuint,
157 };
158
159 static void ack_giuint_high(struct irq_data *d)
160 {
161         giu_write(GIUINTSTATH,
162                   1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
163 }
164
165 static void mask_giuint_high(struct irq_data *d)
166 {
167         giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
168 }
169
170 static void mask_ack_giuint_high(struct irq_data *d)
171 {
172         unsigned int pin;
173
174         pin = GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET;
175         giu_clear(GIUINTENH, 1 << pin);
176         giu_write(GIUINTSTATH, 1 << pin);
177 }
178
179 static void unmask_giuint_high(struct irq_data *d)
180 {
181         giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
182 }
183
184 static struct irq_chip giuint_high_irq_chip = {
185         .name           = "GIUINTH",
186         .irq_ack        = ack_giuint_high,
187         .irq_mask       = mask_giuint_high,
188         .irq_mask_ack   = mask_ack_giuint_high,
189         .irq_unmask     = unmask_giuint_high,
190 };
191
192 static int giu_get_irq(unsigned int irq)
193 {
194         u16 pendl, pendh, maskl, maskh;
195         int i;
196
197         pendl = giu_read(GIUINTSTATL);
198         pendh = giu_read(GIUINTSTATH);
199         maskl = giu_read(GIUINTENL);
200         maskh = giu_read(GIUINTENH);
201
202         maskl &= pendl;
203         maskh &= pendh;
204
205         if (maskl) {
206                 for (i = 0; i < 16; i++) {
207                         if (maskl & (1 << i))
208                                 return GIU_IRQ(i);
209                 }
210         } else if (maskh) {
211                 for (i = 0; i < 16; i++) {
212                         if (maskh & (1 << i))
213                                 return GIU_IRQ(i + GIUINT_HIGH_OFFSET);
214                 }
215         }
216
217         printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
218                maskl, pendl, maskh, pendh);
219
220         atomic_inc(&irq_err_count);
221
222         return -EINVAL;
223 }
224
225 void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger,
226                             irq_signal_t signal)
227 {
228         u16 mask;
229
230         if (pin < GIUINT_HIGH_OFFSET) {
231                 mask = 1 << pin;
232                 if (trigger != IRQ_TRIGGER_LEVEL) {
233                         giu_set(GIUINTTYPL, mask);
234                         if (signal == IRQ_SIGNAL_HOLD)
235                                 giu_set(GIUINTHTSELL, mask);
236                         else
237                                 giu_clear(GIUINTHTSELL, mask);
238                         if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
239                                 switch (trigger) {
240                                 case IRQ_TRIGGER_EDGE_FALLING:
241                                         giu_set(GIUFEDGEINHL, mask);
242                                         giu_clear(GIUREDGEINHL, mask);
243                                         break;
244                                 case IRQ_TRIGGER_EDGE_RISING:
245                                         giu_clear(GIUFEDGEINHL, mask);
246                                         giu_set(GIUREDGEINHL, mask);
247                                         break;
248                                 default:
249                                         giu_set(GIUFEDGEINHL, mask);
250                                         giu_set(GIUREDGEINHL, mask);
251                                         break;
252                                 }
253                         }
254                         irq_set_chip_and_handler(GIU_IRQ(pin),
255                                                  &giuint_low_irq_chip,
256                                                  handle_edge_irq);
257                 } else {
258                         giu_clear(GIUINTTYPL, mask);
259                         giu_clear(GIUINTHTSELL, mask);
260                         irq_set_chip_and_handler(GIU_IRQ(pin),
261                                                  &giuint_low_irq_chip,
262                                                  handle_level_irq);
263                 }
264                 giu_write(GIUINTSTATL, mask);
265         } else if (pin < GIUINT_HIGH_MAX) {
266                 mask = 1 << (pin - GIUINT_HIGH_OFFSET);
267                 if (trigger != IRQ_TRIGGER_LEVEL) {
268                         giu_set(GIUINTTYPH, mask);
269                         if (signal == IRQ_SIGNAL_HOLD)
270                                 giu_set(GIUINTHTSELH, mask);
271                         else
272                                 giu_clear(GIUINTHTSELH, mask);
273                         if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
274                                 switch (trigger) {
275                                 case IRQ_TRIGGER_EDGE_FALLING:
276                                         giu_set(GIUFEDGEINHH, mask);
277                                         giu_clear(GIUREDGEINHH, mask);
278                                         break;
279                                 case IRQ_TRIGGER_EDGE_RISING:
280                                         giu_clear(GIUFEDGEINHH, mask);
281                                         giu_set(GIUREDGEINHH, mask);
282                                         break;
283                                 default:
284                                         giu_set(GIUFEDGEINHH, mask);
285                                         giu_set(GIUREDGEINHH, mask);
286                                         break;
287                                 }
288                         }
289                         irq_set_chip_and_handler(GIU_IRQ(pin),
290                                                  &giuint_high_irq_chip,
291                                                  handle_edge_irq);
292                 } else {
293                         giu_clear(GIUINTTYPH, mask);
294                         giu_clear(GIUINTHTSELH, mask);
295                         irq_set_chip_and_handler(GIU_IRQ(pin),
296                                                  &giuint_high_irq_chip,
297                                                  handle_level_irq);
298                 }
299                 giu_write(GIUINTSTATH, mask);
300         }
301 }
302 EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
303
304 void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
305 {
306         u16 mask;
307
308         if (pin < GIUINT_HIGH_OFFSET) {
309                 mask = 1 << pin;
310                 if (level == IRQ_LEVEL_HIGH)
311                         giu_set(GIUINTALSELL, mask);
312                 else
313                         giu_clear(GIUINTALSELL, mask);
314                 giu_write(GIUINTSTATL, mask);
315         } else if (pin < GIUINT_HIGH_MAX) {
316                 mask = 1 << (pin - GIUINT_HIGH_OFFSET);
317                 if (level == IRQ_LEVEL_HIGH)
318                         giu_set(GIUINTALSELH, mask);
319                 else
320                         giu_clear(GIUINTALSELH, mask);
321                 giu_write(GIUINTSTATH, mask);
322         }
323 }
324 EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
325
326 static int giu_set_direction(struct gpio_chip *chip, unsigned pin, int dir)
327 {
328         u16 offset, mask, reg;
329         unsigned long flags;
330
331         if (pin >= chip->ngpio)
332                 return -EINVAL;
333
334         if (pin < 16) {
335                 offset = GIUIOSELL;
336                 mask = 1 << pin;
337         } else if (pin < 32) {
338                 offset = GIUIOSELH;
339                 mask = 1 << (pin - 16);
340         } else {
341                 if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) {
342                         offset = GIUPODATEN;
343                         mask = 1 << (pin - 32);
344                 } else {
345                         switch (pin) {
346                         case 48:
347                                 offset = GIUPODATH;
348                                 mask = PIOEN0;
349                                 break;
350                         case 49:
351                                 offset = GIUPODATH;
352                                 mask = PIOEN1;
353                                 break;
354                         default:
355                                 return -EINVAL;
356                         }
357                 }
358         }
359
360         spin_lock_irqsave(&giu_lock, flags);
361
362         reg = giu_read(offset);
363         if (dir == GPIO_OUTPUT)
364                 reg |= mask;
365         else
366                 reg &= ~mask;
367         giu_write(offset, reg);
368
369         spin_unlock_irqrestore(&giu_lock, flags);
370
371         return 0;
372 }
373
374 static int vr41xx_gpio_get(struct gpio_chip *chip, unsigned pin)
375 {
376         u16 reg, mask;
377
378         if (pin >= chip->ngpio)
379                 return -EINVAL;
380
381         if (pin < 16) {
382                 reg = giu_read(GIUPIODL);
383                 mask = 1 << pin;
384         } else if (pin < 32) {
385                 reg = giu_read(GIUPIODH);
386                 mask = 1 << (pin - 16);
387         } else if (pin < 48) {
388                 reg = giu_read(GIUPODATL);
389                 mask = 1 << (pin - 32);
390         } else {
391                 reg = giu_read(GIUPODATH);
392                 mask = 1 << (pin - 48);
393         }
394
395         if (reg & mask)
396                 return 1;
397
398         return 0;
399 }
400
401 static void vr41xx_gpio_set(struct gpio_chip *chip, unsigned pin,
402                             int value)
403 {
404         u16 offset, mask, reg;
405         unsigned long flags;
406
407         if (pin >= chip->ngpio)
408                 return;
409
410         if (pin < 16) {
411                 offset = GIUPIODL;
412                 mask = 1 << pin;
413         } else if (pin < 32) {
414                 offset = GIUPIODH;
415                 mask = 1 << (pin - 16);
416         } else if (pin < 48) {
417                 offset = GIUPODATL;
418                 mask = 1 << (pin - 32);
419         } else {
420                 offset = GIUPODATH;
421                 mask = 1 << (pin - 48);
422         }
423
424         spin_lock_irqsave(&giu_lock, flags);
425
426         reg = giu_read(offset);
427         if (value)
428                 reg |= mask;
429         else
430                 reg &= ~mask;
431         giu_write(offset, reg);
432
433         spin_unlock_irqrestore(&giu_lock, flags);
434 }
435
436
437 static int vr41xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
438 {
439         return giu_set_direction(chip, offset, GPIO_INPUT);
440 }
441
442 static int vr41xx_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
443                                 int value)
444 {
445         vr41xx_gpio_set(chip, offset, value);
446
447         return giu_set_direction(chip, offset, GPIO_OUTPUT);
448 }
449
450 static int vr41xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
451 {
452         if (offset >= chip->ngpio)
453                 return -EINVAL;
454
455         return GIU_IRQ_BASE + offset;
456 }
457
458 static struct gpio_chip vr41xx_gpio_chip = {
459         .label                  = "vr41xx",
460         .owner                  = THIS_MODULE,
461         .direction_input        = vr41xx_gpio_direction_input,
462         .get                    = vr41xx_gpio_get,
463         .direction_output       = vr41xx_gpio_direction_output,
464         .set                    = vr41xx_gpio_set,
465         .to_irq                 = vr41xx_gpio_to_irq,
466 };
467
468 static int giu_probe(struct platform_device *pdev)
469 {
470         unsigned int trigger, i, pin;
471         struct irq_chip *chip;
472         int irq;
473
474         switch (pdev->id) {
475         case GPIO_50PINS_PULLUPDOWN:
476                 giu_flags = GPIO_HAS_PULLUPDOWN_IO;
477                 vr41xx_gpio_chip.ngpio = 50;
478                 break;
479         case GPIO_36PINS:
480                 vr41xx_gpio_chip.ngpio = 36;
481                 break;
482         case GPIO_48PINS_EDGE_SELECT:
483                 giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
484                 vr41xx_gpio_chip.ngpio = 48;
485                 break;
486         default:
487                 dev_err(&pdev->dev, "GIU: unknown ID %d\n", pdev->id);
488                 return -ENODEV;
489         }
490
491         giu_base = devm_platform_ioremap_resource(pdev, 0);
492         if (IS_ERR(giu_base))
493                 return PTR_ERR(giu_base);
494
495         vr41xx_gpio_chip.parent = &pdev->dev;
496
497         if (gpiochip_add_data(&vr41xx_gpio_chip, NULL))
498                 return -ENODEV;
499
500         giu_write(GIUINTENL, 0);
501         giu_write(GIUINTENH, 0);
502
503         trigger = giu_read(GIUINTTYPH) << 16;
504         trigger |= giu_read(GIUINTTYPL);
505         for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
506                 pin = GPIO_PIN_OF_IRQ(i);
507                 if (pin < GIUINT_HIGH_OFFSET)
508                         chip = &giuint_low_irq_chip;
509                 else
510                         chip = &giuint_high_irq_chip;
511
512                 if (trigger & (1 << pin))
513                         irq_set_chip_and_handler(i, chip, handle_edge_irq);
514                 else
515                         irq_set_chip_and_handler(i, chip, handle_level_irq);
516
517         }
518
519         irq = platform_get_irq(pdev, 0);
520         if (irq < 0 || irq >= nr_irqs)
521                 return -EBUSY;
522
523         return cascade_irq(irq, giu_get_irq);
524 }
525
526 static int giu_remove(struct platform_device *pdev)
527 {
528         if (giu_base) {
529                 giu_base = NULL;
530         }
531
532         return 0;
533 }
534
535 static struct platform_driver giu_device_driver = {
536         .probe          = giu_probe,
537         .remove         = giu_remove,
538         .driver         = {
539                 .name   = "GIU",
540         },
541 };
542
543 module_platform_driver(giu_device_driver);