Merge git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial
[linux-2.6] / drivers / char / vr41xx_giu.c
1 /*
2  *  Driver for NEC VR4100 series General-purpose I/O Unit.
3  *
4  *  Copyright (C) 2002 MontaVista Software Inc.
5  *      Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6  *  Copyright (C) 2003-2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 #include <linux/platform_device.h>
23 #include <linux/errno.h>
24 #include <linux/fs.h>
25 #include <linux/init.h>
26 #include <linux/irq.h>
27 #include <linux/interrupt.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/spinlock.h>
31 #include <linux/types.h>
32
33 #include <asm/cpu.h>
34 #include <asm/io.h>
35 #include <asm/vr41xx/giu.h>
36 #include <asm/vr41xx/irq.h>
37 #include <asm/vr41xx/vr41xx.h>
38
39 MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
40 MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver");
41 MODULE_LICENSE("GPL");
42
43 static int major;       /* default is dynamic major device number */
44 module_param(major, int, 0);
45 MODULE_PARM_DESC(major, "Major device number");
46
47 #define GIU_TYPE1_START         0x0b000100UL
48 #define GIU_TYPE1_SIZE          0x20UL
49
50 #define GIU_TYPE2_START         0x0f000140UL
51 #define GIU_TYPE2_SIZE          0x20UL
52
53 #define GIU_TYPE3_START         0x0f000140UL
54 #define GIU_TYPE3_SIZE          0x28UL
55
56 #define GIU_PULLUPDOWN_START    0x0b0002e0UL
57 #define GIU_PULLUPDOWN_SIZE     0x04UL
58
59 #define GIUIOSELL       0x00
60 #define GIUIOSELH       0x02
61 #define GIUPIODL        0x04
62 #define GIUPIODH        0x06
63 #define GIUINTSTATL     0x08
64 #define GIUINTSTATH     0x0a
65 #define GIUINTENL       0x0c
66 #define GIUINTENH       0x0e
67 #define GIUINTTYPL      0x10
68 #define GIUINTTYPH      0x12
69 #define GIUINTALSELL    0x14
70 #define GIUINTALSELH    0x16
71 #define GIUINTHTSELL    0x18
72 #define GIUINTHTSELH    0x1a
73 #define GIUPODATL       0x1c
74 #define GIUPODATEN      0x1c
75 #define GIUPODATH       0x1e
76  #define PIOEN0         0x0100
77  #define PIOEN1         0x0200
78 #define GIUPODAT        0x1e
79 #define GIUFEDGEINHL    0x20
80 #define GIUFEDGEINHH    0x22
81 #define GIUREDGEINHL    0x24
82 #define GIUREDGEINHH    0x26
83
84 #define GIUUSEUPDN      0x1e0
85 #define GIUTERMUPDN     0x1e2
86
87 #define GPIO_HAS_PULLUPDOWN_IO          0x0001
88 #define GPIO_HAS_OUTPUT_ENABLE          0x0002
89 #define GPIO_HAS_INTERRUPT_EDGE_SELECT  0x0100
90
91 static spinlock_t giu_lock;
92 static struct resource *giu_resource1;
93 static struct resource *giu_resource2;
94 static unsigned long giu_flags;
95 static unsigned int giu_nr_pins;
96
97 static void __iomem *giu_base;
98
99 #define giu_read(offset)                readw(giu_base + (offset))
100 #define giu_write(offset, value)        writew((value), giu_base + (offset))
101
102 #define GPIO_PIN_OF_IRQ(irq)    ((irq) - GIU_IRQ_BASE)
103 #define GIUINT_HIGH_OFFSET      16
104 #define GIUINT_HIGH_MAX         32
105
106 static inline uint16_t giu_set(uint16_t offset, uint16_t set)
107 {
108         uint16_t data;
109
110         data = giu_read(offset);
111         data |= set;
112         giu_write(offset, data);
113
114         return data;
115 }
116
117 static inline uint16_t giu_clear(uint16_t offset, uint16_t clear)
118 {
119         uint16_t data;
120
121         data = giu_read(offset);
122         data &= ~clear;
123         giu_write(offset, data);
124
125         return data;
126 }
127
128 static void ack_giuint_low(unsigned int irq)
129 {
130         giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
131 }
132
133 static void mask_giuint_low(unsigned int irq)
134 {
135         giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
136 }
137
138 static void mask_ack_giuint_low(unsigned int irq)
139 {
140         unsigned int pin;
141
142         pin = GPIO_PIN_OF_IRQ(irq);
143         giu_clear(GIUINTENL, 1 << pin);
144         giu_write(GIUINTSTATL, 1 << pin);
145 }
146
147 static void unmask_giuint_low(unsigned int irq)
148 {
149         giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
150 }
151
152 static struct irq_chip giuint_low_irq_chip = {
153         .name           = "GIUINTL",
154         .ack            = ack_giuint_low,
155         .mask           = mask_giuint_low,
156         .mask_ack       = mask_ack_giuint_low,
157         .unmask         = unmask_giuint_low,
158 };
159
160 static void ack_giuint_high(unsigned int irq)
161 {
162         giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
163 }
164
165 static void mask_giuint_high(unsigned int irq)
166 {
167         giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
168 }
169
170 static void mask_ack_giuint_high(unsigned int irq)
171 {
172         unsigned int pin;
173
174         pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
175         giu_clear(GIUINTENH, 1 << pin);
176         giu_write(GIUINTSTATH, 1 << pin);
177 }
178
179 static void unmask_giuint_high(unsigned int irq)
180 {
181         giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
182 }
183
184 static struct irq_chip giuint_high_irq_chip = {
185         .name           = "GIUINTH",
186         .ack            = ack_giuint_high,
187         .mask           = mask_giuint_high,
188         .mask_ack       = mask_ack_giuint_high,
189         .unmask         = unmask_giuint_high,
190 };
191
192 static int giu_get_irq(unsigned int irq)
193 {
194         uint16_t 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, irq_signal_t signal)
226 {
227         uint16_t mask;
228
229         if (pin < GIUINT_HIGH_OFFSET) {
230                 mask = 1 << pin;
231                 if (trigger != IRQ_TRIGGER_LEVEL) {
232                         giu_set(GIUINTTYPL, mask);
233                         if (signal == IRQ_SIGNAL_HOLD)
234                                 giu_set(GIUINTHTSELL, mask);
235                         else
236                                 giu_clear(GIUINTHTSELL, mask);
237                         if (current_cpu_data.cputype == CPU_VR4133) {
238                                 switch (trigger) {
239                                 case IRQ_TRIGGER_EDGE_FALLING:
240                                         giu_set(GIUFEDGEINHL, mask);
241                                         giu_clear(GIUREDGEINHL, mask);
242                                         break;
243                                 case IRQ_TRIGGER_EDGE_RISING:
244                                         giu_clear(GIUFEDGEINHL, mask);
245                                         giu_set(GIUREDGEINHL, mask);
246                                         break;
247                                 default:
248                                         giu_set(GIUFEDGEINHL, mask);
249                                         giu_set(GIUREDGEINHL, mask);
250                                         break;
251                                 }
252                         }
253                         set_irq_chip_and_handler(GIU_IRQ(pin),
254                                                  &giuint_low_irq_chip,
255                                                  handle_edge_irq);
256                 } else {
257                         giu_clear(GIUINTTYPL, mask);
258                         giu_clear(GIUINTHTSELL, mask);
259                         set_irq_chip_and_handler(GIU_IRQ(pin),
260                                                  &giuint_low_irq_chip,
261                                                  handle_level_irq);
262                 }
263                 giu_write(GIUINTSTATL, mask);
264         } else if (pin < GIUINT_HIGH_MAX) {
265                 mask = 1 << (pin - GIUINT_HIGH_OFFSET);
266                 if (trigger != IRQ_TRIGGER_LEVEL) {
267                         giu_set(GIUINTTYPH, mask);
268                         if (signal == IRQ_SIGNAL_HOLD)
269                                 giu_set(GIUINTHTSELH, mask);
270                         else
271                                 giu_clear(GIUINTHTSELH, mask);
272                         if (current_cpu_data.cputype == CPU_VR4133) {
273                                 switch (trigger) {
274                                 case IRQ_TRIGGER_EDGE_FALLING:
275                                         giu_set(GIUFEDGEINHH, mask);
276                                         giu_clear(GIUREDGEINHH, mask);
277                                         break;
278                                 case IRQ_TRIGGER_EDGE_RISING:
279                                         giu_clear(GIUFEDGEINHH, mask);
280                                         giu_set(GIUREDGEINHH, mask);
281                                         break;
282                                 default:
283                                         giu_set(GIUFEDGEINHH, mask);
284                                         giu_set(GIUREDGEINHH, mask);
285                                         break;
286                                 }
287                         }
288                         set_irq_chip_and_handler(GIU_IRQ(pin),
289                                                  &giuint_high_irq_chip,
290                                                  handle_edge_irq);
291                 } else {
292                         giu_clear(GIUINTTYPH, mask);
293                         giu_clear(GIUINTHTSELH, mask);
294                         set_irq_chip_and_handler(GIU_IRQ(pin),
295                                                  &giuint_high_irq_chip,
296                                                  handle_level_irq);
297                 }
298                 giu_write(GIUINTSTATH, mask);
299         }
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         uint16_t 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
325 EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
326
327 gpio_data_t vr41xx_gpio_get_pin(unsigned int pin)
328 {
329         uint16_t reg, mask;
330
331         if (pin >= giu_nr_pins)
332                 return GPIO_DATA_INVAL;
333
334         if (pin < 16) {
335                 reg = giu_read(GIUPIODL);
336                 mask = (uint16_t)1 << pin;
337         } else if (pin < 32) {
338                 reg = giu_read(GIUPIODH);
339                 mask = (uint16_t)1 << (pin - 16);
340         } else if (pin < 48) {
341                 reg = giu_read(GIUPODATL);
342                 mask = (uint16_t)1 << (pin - 32);
343         } else {
344                 reg = giu_read(GIUPODATH);
345                 mask = (uint16_t)1 << (pin - 48);
346         }
347
348         if (reg & mask)
349                 return GPIO_DATA_HIGH;
350
351         return GPIO_DATA_LOW;
352 }
353
354 EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin);
355
356 int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data)
357 {
358         uint16_t offset, mask, reg;
359         unsigned long flags;
360
361         if (pin >= giu_nr_pins)
362                 return -EINVAL;
363
364         if (pin < 16) {
365                 offset = GIUPIODL;
366                 mask = (uint16_t)1 << pin;
367         } else if (pin < 32) {
368                 offset = GIUPIODH;
369                 mask = (uint16_t)1 << (pin - 16);
370         } else if (pin < 48) {
371                 offset = GIUPODATL;
372                 mask = (uint16_t)1 << (pin - 32);
373         } else {
374                 offset = GIUPODATH;
375                 mask = (uint16_t)1 << (pin - 48);
376         }
377
378         spin_lock_irqsave(&giu_lock, flags);
379
380         reg = giu_read(offset);
381         if (data == GPIO_DATA_HIGH)
382                 reg |= mask;
383         else
384                 reg &= ~mask;
385         giu_write(offset, reg);
386
387         spin_unlock_irqrestore(&giu_lock, flags);
388
389         return 0;
390 }
391
392 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin);
393
394 int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir)
395 {
396         uint16_t offset, mask, reg;
397         unsigned long flags;
398
399         if (pin >= giu_nr_pins)
400                 return -EINVAL;
401
402         if (pin < 16) {
403                 offset = GIUIOSELL;
404                 mask = (uint16_t)1 << pin;
405         } else if (pin < 32) {
406                 offset = GIUIOSELH;
407                 mask = (uint16_t)1 << (pin - 16);
408         } else {
409                 if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) {
410                         offset = GIUPODATEN;
411                         mask = (uint16_t)1 << (pin - 32);
412                 } else {
413                         switch (pin) {
414                         case 48:
415                                 offset = GIUPODATH;
416                                 mask = PIOEN0;
417                                 break;
418                         case 49:
419                                 offset = GIUPODATH;
420                                 mask = PIOEN1;
421                                 break;
422                         default:
423                                 return -EINVAL;
424                         }
425                 }
426         }
427
428         spin_lock_irqsave(&giu_lock, flags);
429
430         reg = giu_read(offset);
431         if (dir == GPIO_OUTPUT)
432                 reg |= mask;
433         else
434                 reg &= ~mask;
435         giu_write(offset, reg);
436
437         spin_unlock_irqrestore(&giu_lock, flags);
438
439         return 0;
440 }
441
442 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction);
443
444 int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
445 {
446         uint16_t reg, mask;
447         unsigned long flags;
448
449         if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO)
450                 return -EPERM;
451
452         if (pin >= 15)
453                 return -EINVAL;
454
455         mask = (uint16_t)1 << pin;
456
457         spin_lock_irqsave(&giu_lock, flags);
458
459         if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) {
460                 reg = giu_read(GIUTERMUPDN);
461                 if (pull == GPIO_PULL_UP)
462                         reg |= mask;
463                 else
464                         reg &= ~mask;
465                 giu_write(GIUTERMUPDN, reg);
466
467                 reg = giu_read(GIUUSEUPDN);
468                 reg |= mask;
469                 giu_write(GIUUSEUPDN, reg);
470         } else {
471                 reg = giu_read(GIUUSEUPDN);
472                 reg &= ~mask;
473                 giu_write(GIUUSEUPDN, reg);
474         }
475
476         spin_unlock_irqrestore(&giu_lock, flags);
477
478         return 0;
479 }
480
481 EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown);
482
483 static ssize_t gpio_read(struct file *file, char __user *buf, size_t len,
484                          loff_t *ppos)
485 {
486         unsigned int pin;
487         char value = '0';
488
489         pin = iminor(file->f_path.dentry->d_inode);
490         if (pin >= giu_nr_pins)
491                 return -EBADF;
492
493         if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH)
494                 value = '1';
495
496         if (len <= 0)
497                 return -EFAULT;
498
499         if (put_user(value, buf))
500                 return -EFAULT;
501
502         return 1;
503 }
504
505 static ssize_t gpio_write(struct file *file, const char __user *data,
506                           size_t len, loff_t *ppos)
507 {
508         unsigned int pin;
509         size_t i;
510         char c;
511         int retval = 0;
512
513         pin = iminor(file->f_path.dentry->d_inode);
514         if (pin >= giu_nr_pins)
515                 return -EBADF;
516
517         for (i = 0; i < len; i++) {
518                 if (get_user(c, data + i))
519                         return -EFAULT;
520
521                 switch (c) {
522                 case '0':
523                         retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW);
524                         break;
525                 case '1':
526                         retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH);
527                         break;
528                 case 'D':
529                         printk(KERN_INFO "GPIO%d: pull down\n", pin);
530                         retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN);
531                         break;
532                 case 'd':
533                         printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin);
534                         retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE);
535                         break;
536                 case 'I':
537                         printk(KERN_INFO "GPIO%d: input\n", pin);
538                         retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT);
539                         break;
540                 case 'O':
541                         printk(KERN_INFO "GPIO%d: output\n", pin);
542                         retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT);
543                         break;
544                 case 'o':
545                         printk(KERN_INFO "GPIO%d: output disable\n", pin);
546                         retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE);
547                         break;
548                 case 'P':
549                         printk(KERN_INFO "GPIO%d: pull up\n", pin);
550                         retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP);
551                         break;
552                 case 'p':
553                         printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin);
554                         retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE);
555                         break;
556                 default:
557                         break;
558                 }
559
560                 if (retval < 0)
561                         break;
562         }
563
564         return i;
565 }
566
567 static int gpio_open(struct inode *inode, struct file *file)
568 {
569         unsigned int pin;
570
571         pin = iminor(inode);
572         if (pin >= giu_nr_pins)
573                 return -EBADF;
574
575         return nonseekable_open(inode, file);
576 }
577
578 static int gpio_release(struct inode *inode, struct file *file)
579 {
580         unsigned int pin;
581
582         pin = iminor(inode);
583         if (pin >= giu_nr_pins)
584                 return -EBADF;
585
586         return 0;
587 }
588
589 static const struct file_operations gpio_fops = {
590         .owner          = THIS_MODULE,
591         .read           = gpio_read,
592         .write          = gpio_write,
593         .open           = gpio_open,
594         .release        = gpio_release,
595 };
596
597 static int __devinit giu_probe(struct platform_device *dev)
598 {
599         unsigned long start, size, flags = 0;
600         unsigned int nr_pins = 0, trigger, i, pin;
601         struct resource *res1, *res2 = NULL;
602         void *base;
603         struct irq_chip *chip;
604         int retval;
605
606         switch (current_cpu_data.cputype) {
607         case CPU_VR4111:
608         case CPU_VR4121:
609                 start = GIU_TYPE1_START;
610                 size = GIU_TYPE1_SIZE;
611                 flags = GPIO_HAS_PULLUPDOWN_IO;
612                 nr_pins = 50;
613                 break;
614         case CPU_VR4122:
615         case CPU_VR4131:
616                 start = GIU_TYPE2_START;
617                 size = GIU_TYPE2_SIZE;
618                 nr_pins = 36;
619                 break;
620         case CPU_VR4133:
621                 start = GIU_TYPE3_START;
622                 size = GIU_TYPE3_SIZE;
623                 flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
624                 nr_pins = 48;
625                 break;
626         default:
627                 return -ENODEV;
628         }
629
630         res1 = request_mem_region(start, size, "GIU");
631         if (res1 == NULL)
632                 return -EBUSY;
633
634         base = ioremap(start, size);
635         if (base == NULL) {
636                 release_resource(res1);
637                 return -ENOMEM;
638         }
639
640         if (flags & GPIO_HAS_PULLUPDOWN_IO) {
641                 res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU");
642                 if (res2 == NULL) {
643                         iounmap(base);
644                         release_resource(res1);
645                         return -EBUSY;
646                 }
647         }
648
649         retval = register_chrdev(major, "GIU", &gpio_fops);
650         if (retval < 0) {
651                 iounmap(base);
652                 release_resource(res1);
653                 release_resource(res2);
654                 return retval;
655         }
656
657         if (major == 0) {
658                 major = retval;
659                 printk(KERN_INFO "GIU: major number %d\n", major);
660         }
661
662         spin_lock_init(&giu_lock);
663         giu_base = base;
664         giu_resource1 = res1;
665         giu_resource2 = res2;
666         giu_flags = flags;
667         giu_nr_pins = nr_pins;
668
669         giu_write(GIUINTENL, 0);
670         giu_write(GIUINTENH, 0);
671
672         trigger = giu_read(GIUINTTYPH) << 16;
673         trigger |= giu_read(GIUINTTYPL);
674         for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
675                 pin = GPIO_PIN_OF_IRQ(i);
676                 if (pin < GIUINT_HIGH_OFFSET)
677                         chip = &giuint_low_irq_chip;
678                 else
679                         chip = &giuint_high_irq_chip;
680
681                 if (trigger & (1 << pin))
682                         set_irq_chip_and_handler(i, chip, handle_edge_irq);
683                 else
684                         set_irq_chip_and_handler(i, chip, handle_level_irq);
685
686         }
687
688         return cascade_irq(GIUINT_IRQ, giu_get_irq);
689 }
690
691 static int __devexit giu_remove(struct platform_device *dev)
692 {
693         iounmap(giu_base);
694
695         release_resource(giu_resource1);
696         if (giu_flags & GPIO_HAS_PULLUPDOWN_IO)
697                 release_resource(giu_resource2);
698
699         return 0;
700 }
701
702 static struct platform_device *giu_platform_device;
703
704 static struct platform_driver giu_device_driver = {
705         .probe          = giu_probe,
706         .remove         = __devexit_p(giu_remove),
707         .driver         = {
708                 .name   = "GIU",
709                 .owner  = THIS_MODULE,
710         },
711 };
712
713 static int __init vr41xx_giu_init(void)
714 {
715         int retval;
716
717         giu_platform_device = platform_device_alloc("GIU", -1);
718         if (!giu_platform_device)
719                 return -ENOMEM;
720
721         retval = platform_device_add(giu_platform_device);
722         if (retval < 0) {
723                 platform_device_put(giu_platform_device);
724                 return retval;
725         }
726
727         retval = platform_driver_register(&giu_device_driver);
728         if (retval < 0)
729                 platform_device_unregister(giu_platform_device);
730
731         return retval;
732 }
733
734 static void __exit vr41xx_giu_exit(void)
735 {
736         platform_driver_unregister(&giu_device_driver);
737
738         platform_device_unregister(giu_platform_device);
739 }
740
741 module_init(vr41xx_giu_init);
742 module_exit(vr41xx_giu_exit);