OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [char/] [vr41xx_giu.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.