• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/errno.h>
23 #include <linux/fs.h>
24 #include <linux/init.h>
25 #include <linux/interrupt.h>
26 #include <linux/irq.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/platform_device.h>
30 #include <linux/smp_lock.h>
31 #include <linux/spinlock.h>
32 #include <linux/types.h>
33 
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 GIUIOSELL	0x00
48 #define GIUIOSELH	0x02
49 #define GIUPIODL	0x04
50 #define GIUPIODH	0x06
51 #define GIUINTSTATL	0x08
52 #define GIUINTSTATH	0x0a
53 #define GIUINTENL	0x0c
54 #define GIUINTENH	0x0e
55 #define GIUINTTYPL	0x10
56 #define GIUINTTYPH	0x12
57 #define GIUINTALSELL	0x14
58 #define GIUINTALSELH	0x16
59 #define GIUINTHTSELL	0x18
60 #define GIUINTHTSELH	0x1a
61 #define GIUPODATL	0x1c
62 #define GIUPODATEN	0x1c
63 #define GIUPODATH	0x1e
64  #define PIOEN0		0x0100
65  #define PIOEN1		0x0200
66 #define GIUPODAT	0x1e
67 #define GIUFEDGEINHL	0x20
68 #define GIUFEDGEINHH	0x22
69 #define GIUREDGEINHL	0x24
70 #define GIUREDGEINHH	0x26
71 
72 #define GIUUSEUPDN	0x1e0
73 #define GIUTERMUPDN	0x1e2
74 
75 #define GPIO_HAS_PULLUPDOWN_IO		0x0001
76 #define GPIO_HAS_OUTPUT_ENABLE		0x0002
77 #define GPIO_HAS_INTERRUPT_EDGE_SELECT	0x0100
78 
79 static spinlock_t giu_lock;
80 static unsigned long giu_flags;
81 static unsigned int giu_nr_pins;
82 
83 static void __iomem *giu_base;
84 
85 #define giu_read(offset)		readw(giu_base + (offset))
86 #define giu_write(offset, value)	writew((value), giu_base + (offset))
87 
88 #define GPIO_PIN_OF_IRQ(irq)	((irq) - GIU_IRQ_BASE)
89 #define GIUINT_HIGH_OFFSET	16
90 #define GIUINT_HIGH_MAX		32
91 
giu_set(uint16_t offset,uint16_t set)92 static inline uint16_t giu_set(uint16_t offset, uint16_t set)
93 {
94 	uint16_t data;
95 
96 	data = giu_read(offset);
97 	data |= set;
98 	giu_write(offset, data);
99 
100 	return data;
101 }
102 
giu_clear(uint16_t offset,uint16_t clear)103 static inline uint16_t giu_clear(uint16_t offset, uint16_t clear)
104 {
105 	uint16_t data;
106 
107 	data = giu_read(offset);
108 	data &= ~clear;
109 	giu_write(offset, data);
110 
111 	return data;
112 }
113 
ack_giuint_low(unsigned int irq)114 static void ack_giuint_low(unsigned int irq)
115 {
116 	giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq));
117 }
118 
mask_giuint_low(unsigned int irq)119 static void mask_giuint_low(unsigned int irq)
120 {
121 	giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
122 }
123 
mask_ack_giuint_low(unsigned int irq)124 static void mask_ack_giuint_low(unsigned int irq)
125 {
126 	unsigned int pin;
127 
128 	pin = GPIO_PIN_OF_IRQ(irq);
129 	giu_clear(GIUINTENL, 1 << pin);
130 	giu_write(GIUINTSTATL, 1 << pin);
131 }
132 
unmask_giuint_low(unsigned int irq)133 static void unmask_giuint_low(unsigned int irq)
134 {
135 	giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
136 }
137 
138 static struct irq_chip giuint_low_irq_chip = {
139 	.name		= "GIUINTL",
140 	.ack		= ack_giuint_low,
141 	.mask		= mask_giuint_low,
142 	.mask_ack	= mask_ack_giuint_low,
143 	.unmask		= unmask_giuint_low,
144 };
145 
ack_giuint_high(unsigned int irq)146 static void ack_giuint_high(unsigned int irq)
147 {
148 	giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
149 }
150 
mask_giuint_high(unsigned int irq)151 static void mask_giuint_high(unsigned int irq)
152 {
153 	giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
154 }
155 
mask_ack_giuint_high(unsigned int irq)156 static void mask_ack_giuint_high(unsigned int irq)
157 {
158 	unsigned int pin;
159 
160 	pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
161 	giu_clear(GIUINTENH, 1 << pin);
162 	giu_write(GIUINTSTATH, 1 << pin);
163 }
164 
unmask_giuint_high(unsigned int irq)165 static void unmask_giuint_high(unsigned int irq)
166 {
167 	giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
168 }
169 
170 static struct irq_chip giuint_high_irq_chip = {
171 	.name		= "GIUINTH",
172 	.ack		= ack_giuint_high,
173 	.mask		= mask_giuint_high,
174 	.mask_ack	= mask_ack_giuint_high,
175 	.unmask		= unmask_giuint_high,
176 };
177 
giu_get_irq(unsigned int irq)178 static int giu_get_irq(unsigned int irq)
179 {
180 	uint16_t pendl, pendh, maskl, maskh;
181 	int i;
182 
183 	pendl = giu_read(GIUINTSTATL);
184 	pendh = giu_read(GIUINTSTATH);
185 	maskl = giu_read(GIUINTENL);
186 	maskh = giu_read(GIUINTENH);
187 
188 	maskl &= pendl;
189 	maskh &= pendh;
190 
191 	if (maskl) {
192 		for (i = 0; i < 16; i++) {
193 			if (maskl & (1 << i))
194 				return GIU_IRQ(i);
195 		}
196 	} else if (maskh) {
197 		for (i = 0; i < 16; i++) {
198 			if (maskh & (1 << i))
199 				return GIU_IRQ(i + GIUINT_HIGH_OFFSET);
200 		}
201 	}
202 
203 	printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
204 	       maskl, pendl, maskh, pendh);
205 
206 	atomic_inc(&irq_err_count);
207 
208 	return -EINVAL;
209 }
210 
vr41xx_set_irq_trigger(unsigned int pin,irq_trigger_t trigger,irq_signal_t signal)211 void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal)
212 {
213 	uint16_t mask;
214 
215 	if (pin < GIUINT_HIGH_OFFSET) {
216 		mask = 1 << pin;
217 		if (trigger != IRQ_TRIGGER_LEVEL) {
218         		giu_set(GIUINTTYPL, mask);
219 			if (signal == IRQ_SIGNAL_HOLD)
220 				giu_set(GIUINTHTSELL, mask);
221 			else
222 				giu_clear(GIUINTHTSELL, mask);
223 			if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
224 				switch (trigger) {
225 				case IRQ_TRIGGER_EDGE_FALLING:
226 					giu_set(GIUFEDGEINHL, mask);
227 					giu_clear(GIUREDGEINHL, mask);
228 					break;
229 				case IRQ_TRIGGER_EDGE_RISING:
230 					giu_clear(GIUFEDGEINHL, mask);
231 					giu_set(GIUREDGEINHL, mask);
232 					break;
233 				default:
234 					giu_set(GIUFEDGEINHL, mask);
235 					giu_set(GIUREDGEINHL, mask);
236 					break;
237 				}
238 			}
239 			set_irq_chip_and_handler(GIU_IRQ(pin),
240 			                         &giuint_low_irq_chip,
241 			                         handle_edge_irq);
242 		} else {
243 			giu_clear(GIUINTTYPL, mask);
244 			giu_clear(GIUINTHTSELL, mask);
245 			set_irq_chip_and_handler(GIU_IRQ(pin),
246 			                         &giuint_low_irq_chip,
247 			                         handle_level_irq);
248 		}
249 		giu_write(GIUINTSTATL, mask);
250 	} else if (pin < GIUINT_HIGH_MAX) {
251 		mask = 1 << (pin - GIUINT_HIGH_OFFSET);
252 		if (trigger != IRQ_TRIGGER_LEVEL) {
253 			giu_set(GIUINTTYPH, mask);
254 			if (signal == IRQ_SIGNAL_HOLD)
255 				giu_set(GIUINTHTSELH, mask);
256 			else
257 				giu_clear(GIUINTHTSELH, mask);
258 			if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
259 				switch (trigger) {
260 				case IRQ_TRIGGER_EDGE_FALLING:
261 					giu_set(GIUFEDGEINHH, mask);
262 					giu_clear(GIUREDGEINHH, mask);
263 					break;
264 				case IRQ_TRIGGER_EDGE_RISING:
265 					giu_clear(GIUFEDGEINHH, mask);
266 					giu_set(GIUREDGEINHH, mask);
267 					break;
268 				default:
269 					giu_set(GIUFEDGEINHH, mask);
270 					giu_set(GIUREDGEINHH, mask);
271 					break;
272 				}
273 			}
274 			set_irq_chip_and_handler(GIU_IRQ(pin),
275 			                         &giuint_high_irq_chip,
276 			                         handle_edge_irq);
277 		} else {
278 			giu_clear(GIUINTTYPH, mask);
279 			giu_clear(GIUINTHTSELH, mask);
280 			set_irq_chip_and_handler(GIU_IRQ(pin),
281 			                         &giuint_high_irq_chip,
282 			                         handle_level_irq);
283 		}
284 		giu_write(GIUINTSTATH, mask);
285 	}
286 }
287 EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
288 
vr41xx_set_irq_level(unsigned int pin,irq_level_t level)289 void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
290 {
291 	uint16_t mask;
292 
293 	if (pin < GIUINT_HIGH_OFFSET) {
294 		mask = 1 << pin;
295 		if (level == IRQ_LEVEL_HIGH)
296 			giu_set(GIUINTALSELL, mask);
297 		else
298 			giu_clear(GIUINTALSELL, mask);
299 		giu_write(GIUINTSTATL, mask);
300 	} else if (pin < GIUINT_HIGH_MAX) {
301 		mask = 1 << (pin - GIUINT_HIGH_OFFSET);
302 		if (level == IRQ_LEVEL_HIGH)
303 			giu_set(GIUINTALSELH, mask);
304 		else
305 			giu_clear(GIUINTALSELH, mask);
306 		giu_write(GIUINTSTATH, mask);
307 	}
308 }
309 EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
310 
vr41xx_gpio_get_pin(unsigned int pin)311 gpio_data_t vr41xx_gpio_get_pin(unsigned int pin)
312 {
313 	uint16_t reg, mask;
314 
315 	if (pin >= giu_nr_pins)
316 		return GPIO_DATA_INVAL;
317 
318 	if (pin < 16) {
319 		reg = giu_read(GIUPIODL);
320 		mask = (uint16_t)1 << pin;
321 	} else if (pin < 32) {
322 		reg = giu_read(GIUPIODH);
323 		mask = (uint16_t)1 << (pin - 16);
324 	} else if (pin < 48) {
325 		reg = giu_read(GIUPODATL);
326 		mask = (uint16_t)1 << (pin - 32);
327 	} else {
328 		reg = giu_read(GIUPODATH);
329 		mask = (uint16_t)1 << (pin - 48);
330 	}
331 
332 	if (reg & mask)
333 		return GPIO_DATA_HIGH;
334 
335 	return GPIO_DATA_LOW;
336 }
337 EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin);
338 
vr41xx_gpio_set_pin(unsigned int pin,gpio_data_t data)339 int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data)
340 {
341 	uint16_t offset, mask, reg;
342 	unsigned long flags;
343 
344 	if (pin >= giu_nr_pins)
345 		return -EINVAL;
346 
347 	if (pin < 16) {
348 		offset = GIUPIODL;
349 		mask = (uint16_t)1 << pin;
350 	} else if (pin < 32) {
351 		offset = GIUPIODH;
352 		mask = (uint16_t)1 << (pin - 16);
353 	} else if (pin < 48) {
354 		offset = GIUPODATL;
355 		mask = (uint16_t)1 << (pin - 32);
356 	} else {
357 		offset = GIUPODATH;
358 		mask = (uint16_t)1 << (pin - 48);
359 	}
360 
361 	spin_lock_irqsave(&giu_lock, flags);
362 
363 	reg = giu_read(offset);
364 	if (data == GPIO_DATA_HIGH)
365 		reg |= mask;
366 	else
367 		reg &= ~mask;
368 	giu_write(offset, reg);
369 
370 	spin_unlock_irqrestore(&giu_lock, flags);
371 
372 	return 0;
373 }
374 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin);
375 
vr41xx_gpio_set_direction(unsigned int pin,gpio_direction_t dir)376 int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir)
377 {
378 	uint16_t offset, mask, reg;
379 	unsigned long flags;
380 
381 	if (pin >= giu_nr_pins)
382 		return -EINVAL;
383 
384 	if (pin < 16) {
385 		offset = GIUIOSELL;
386 		mask = (uint16_t)1 << pin;
387 	} else if (pin < 32) {
388 		offset = GIUIOSELH;
389 		mask = (uint16_t)1 << (pin - 16);
390 	} else {
391 		if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) {
392 			offset = GIUPODATEN;
393 			mask = (uint16_t)1 << (pin - 32);
394 		} else {
395 			switch (pin) {
396 			case 48:
397 				offset = GIUPODATH;
398 				mask = PIOEN0;
399 				break;
400 			case 49:
401 				offset = GIUPODATH;
402 				mask = PIOEN1;
403 				break;
404 			default:
405 				return -EINVAL;
406 			}
407 		}
408 	}
409 
410 	spin_lock_irqsave(&giu_lock, flags);
411 
412 	reg = giu_read(offset);
413 	if (dir == GPIO_OUTPUT)
414 		reg |= mask;
415 	else
416 		reg &= ~mask;
417 	giu_write(offset, reg);
418 
419 	spin_unlock_irqrestore(&giu_lock, flags);
420 
421 	return 0;
422 }
423 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction);
424 
vr41xx_gpio_pullupdown(unsigned int pin,gpio_pull_t pull)425 int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
426 {
427 	uint16_t reg, mask;
428 	unsigned long flags;
429 
430 	if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO)
431 		return -EPERM;
432 
433 	if (pin >= 15)
434 		return -EINVAL;
435 
436 	mask = (uint16_t)1 << pin;
437 
438 	spin_lock_irqsave(&giu_lock, flags);
439 
440 	if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) {
441 		reg = giu_read(GIUTERMUPDN);
442 		if (pull == GPIO_PULL_UP)
443 			reg |= mask;
444 		else
445 			reg &= ~mask;
446 		giu_write(GIUTERMUPDN, reg);
447 
448 		reg = giu_read(GIUUSEUPDN);
449 		reg |= mask;
450 		giu_write(GIUUSEUPDN, reg);
451 	} else {
452 		reg = giu_read(GIUUSEUPDN);
453 		reg &= ~mask;
454 		giu_write(GIUUSEUPDN, reg);
455 	}
456 
457 	spin_unlock_irqrestore(&giu_lock, flags);
458 
459 	return 0;
460 }
461 EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown);
462 
gpio_read(struct file * file,char __user * buf,size_t len,loff_t * ppos)463 static ssize_t gpio_read(struct file *file, char __user *buf, size_t len,
464                          loff_t *ppos)
465 {
466 	unsigned int pin;
467 	char value = '0';
468 
469 	pin = iminor(file->f_path.dentry->d_inode);
470 	if (pin >= giu_nr_pins)
471 		return -EBADF;
472 
473 	if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH)
474 		value = '1';
475 
476 	if (len <= 0)
477 		return -EFAULT;
478 
479 	if (put_user(value, buf))
480 		return -EFAULT;
481 
482 	return 1;
483 }
484 
gpio_write(struct file * file,const char __user * data,size_t len,loff_t * ppos)485 static ssize_t gpio_write(struct file *file, const char __user *data,
486                           size_t len, loff_t *ppos)
487 {
488 	unsigned int pin;
489 	size_t i;
490 	char c;
491 	int retval = 0;
492 
493 	pin = iminor(file->f_path.dentry->d_inode);
494 	if (pin >= giu_nr_pins)
495 		return -EBADF;
496 
497 	for (i = 0; i < len; i++) {
498 		if (get_user(c, data + i))
499 			return -EFAULT;
500 
501 		switch (c) {
502 		case '0':
503 			retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW);
504 			break;
505 		case '1':
506 			retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH);
507 			break;
508 		case 'D':
509 			printk(KERN_INFO "GPIO%d: pull down\n", pin);
510 			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN);
511 			break;
512 		case 'd':
513 			printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin);
514 			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE);
515 			break;
516 		case 'I':
517 			printk(KERN_INFO "GPIO%d: input\n", pin);
518 			retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT);
519 			break;
520 		case 'O':
521 			printk(KERN_INFO "GPIO%d: output\n", pin);
522 			retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT);
523 			break;
524 		case 'o':
525 			printk(KERN_INFO "GPIO%d: output disable\n", pin);
526 			retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE);
527 			break;
528 		case 'P':
529 			printk(KERN_INFO "GPIO%d: pull up\n", pin);
530 			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP);
531 			break;
532 		case 'p':
533 			printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin);
534 			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE);
535 			break;
536 		default:
537 			break;
538 		}
539 
540 		if (retval < 0)
541 			break;
542 	}
543 
544 	return i;
545 }
546 
gpio_open(struct inode * inode,struct file * file)547 static int gpio_open(struct inode *inode, struct file *file)
548 {
549 	unsigned int pin;
550 
551 	cycle_kernel_lock();
552 	pin = iminor(inode);
553 	if (pin >= giu_nr_pins)
554 		return -EBADF;
555 
556 	return nonseekable_open(inode, file);
557 }
558 
gpio_release(struct inode * inode,struct file * file)559 static int gpio_release(struct inode *inode, struct file *file)
560 {
561 	unsigned int pin;
562 
563 	pin = iminor(inode);
564 	if (pin >= giu_nr_pins)
565 		return -EBADF;
566 
567 	return 0;
568 }
569 
570 static const struct file_operations gpio_fops = {
571 	.owner		= THIS_MODULE,
572 	.read		= gpio_read,
573 	.write		= gpio_write,
574 	.open		= gpio_open,
575 	.release	= gpio_release,
576 };
577 
giu_probe(struct platform_device * dev)578 static int __devinit giu_probe(struct platform_device *dev)
579 {
580 	struct resource *res;
581 	unsigned int trigger, i, pin;
582 	struct irq_chip *chip;
583 	int irq, retval;
584 
585 	switch (dev->id) {
586 	case GPIO_50PINS_PULLUPDOWN:
587 		giu_flags = GPIO_HAS_PULLUPDOWN_IO;
588 		giu_nr_pins = 50;
589 		break;
590 	case GPIO_36PINS:
591 		giu_nr_pins = 36;
592 		break;
593 	case GPIO_48PINS_EDGE_SELECT:
594 		giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
595 		giu_nr_pins = 48;
596 		break;
597 	default:
598 		printk(KERN_ERR "GIU: unknown ID %d\n", dev->id);
599 		return -ENODEV;
600 	}
601 
602 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
603 	if (!res)
604 		return -EBUSY;
605 
606 	giu_base = ioremap(res->start, res->end - res->start + 1);
607 	if (!giu_base)
608 		return -ENOMEM;
609 
610 	retval = register_chrdev(major, "GIU", &gpio_fops);
611 	if (retval < 0) {
612 		iounmap(giu_base);
613 		giu_base = NULL;
614 		return retval;
615 	}
616 
617 	if (major == 0) {
618 		major = retval;
619 		printk(KERN_INFO "GIU: major number %d\n", major);
620 	}
621 
622 	spin_lock_init(&giu_lock);
623 
624 	giu_write(GIUINTENL, 0);
625 	giu_write(GIUINTENH, 0);
626 
627 	trigger = giu_read(GIUINTTYPH) << 16;
628 	trigger |= giu_read(GIUINTTYPL);
629 	for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
630 		pin = GPIO_PIN_OF_IRQ(i);
631 		if (pin < GIUINT_HIGH_OFFSET)
632 			chip = &giuint_low_irq_chip;
633 		else
634 			chip = &giuint_high_irq_chip;
635 
636 		if (trigger & (1 << pin))
637 			set_irq_chip_and_handler(i, chip, handle_edge_irq);
638 		else
639 			set_irq_chip_and_handler(i, chip, handle_level_irq);
640 
641 	}
642 
643 	irq = platform_get_irq(dev, 0);
644 	if (irq < 0 || irq >= nr_irqs)
645 		return -EBUSY;
646 
647 	return cascade_irq(irq, giu_get_irq);
648 }
649 
giu_remove(struct platform_device * dev)650 static int __devexit giu_remove(struct platform_device *dev)
651 {
652 	if (giu_base) {
653 		iounmap(giu_base);
654 		giu_base = NULL;
655 	}
656 
657 	return 0;
658 }
659 
660 static struct platform_driver giu_device_driver = {
661 	.probe		= giu_probe,
662 	.remove		= __devexit_p(giu_remove),
663 	.driver		= {
664 		.name	= "GIU",
665 		.owner	= THIS_MODULE,
666 	},
667 };
668 
vr41xx_giu_init(void)669 static int __init vr41xx_giu_init(void)
670 {
671 	return platform_driver_register(&giu_device_driver);
672 }
673 
vr41xx_giu_exit(void)674 static void __exit vr41xx_giu_exit(void)
675 {
676 	platform_driver_unregister(&giu_device_driver);
677 }
678 
679 module_init(vr41xx_giu_init);
680 module_exit(vr41xx_giu_exit);
681