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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_8/] [apps/] [sw/] [driver/] [spartan_drv.c] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 mihad
#include <linux/module.h>
2
#include <linux/errno.h>
3
#include <linux/kernel.h>
4
#include <linux/pci.h>
5 103 mihad
#include <linux/wrapper.h>
6 21 mihad
 
7
#include <asm/uaccess.h>
8
#include <spartan_kint.h> //IOCTL definitions
9
 
10
// define vendor and device ID here - currently this definitions specify reference designs from insight electronic
11
#ifdef __SDRAM__
12
#define OC_PCI_VENDOR 0x1597
13
#define OC_PCI_DEVICE 0x0300
14
#endif
15
#ifdef __VGA__
16 85 mihad
#define OC_PCI_VENDOR 0x1895
17 21 mihad
#define OC_PCI_DEVICE 0x0001
18
#endif
19 103 mihad
#ifdef __OC_TEST__
20
#define OC_PCI_VENDOR 0x1895
21
#define OC_PCI_DEVICE 0x0001
22
#define __VGA__
23
#endif
24 21 mihad
 
25
// if someone wants specific major number assigned to spartan board - specify it here 
26
// if 0 is used, kernel assigns it automaticaly
27
#ifdef __SDRAM__
28 103 mihad
#define REQUESTED_MAJOR 0 
29 21 mihad
#endif
30
 
31
#ifdef __VGA__
32 103 mihad
#define REQUESTED_MAJOR 0
33 21 mihad
#endif
34
 
35
// if compiling module for kernel 2.4 - leave this defined
36
// for kernel 2.2 - comment this out
37
#define KERNEL_VER_24
38
 
39
#ifndef SEEK_SET
40
        #define SEEK_SET 0
41
        #define SEEK_CUR 1
42
        #define SEEK_END 2
43
#endif
44
 
45
// io.h needed just for kernel 2.2
46
#ifndef KERNEL_VER_24
47
        #include <asm/io.h>
48
#endif
49
 
50
// memory mapped or IO mapped region definitions
51
#define SPARTAN_MEM_MAPPED 0
52
#define SPARTAN_IO_MAPPED 1
53
 
54
#ifdef __VGA__
55 103 mihad
#ifdef __OC_TEST__
56
    #define VIDEO_SZ (16384)
57
#else
58
    #define VIDEO_SZ (640*480)
59 21 mihad
#endif
60 103 mihad
#endif
61 21 mihad
 
62
// structure for holding board information
63
// (6 base addresses, mapping, page etc.
64
static struct our_dev
65
{
66
        int major ;
67
        u32 bases[6] ;
68
        u8 num_of_bases ;
69
        u32 base_size[6] ;
70
        u32 offset ;
71
        u32 page_addr ;
72
        u32 base_page_offset ;
73
        int current_resource ;
74
        int base_map[6] ;
75
        u32 video_base ;
76
        u32 video_vbase ;
77
        u32 video_size ;
78
        struct pci_dev *ppci_spartan_dev ;
79
} pspartan_dev ;
80
 
81
// function prototypes
82
int spartan_open(struct inode *inode, struct file *filp);
83
 
84
int spartan_release(struct inode *inode, struct file *filp);
85
 
86
ssize_t spartan_read(struct file *filp, char *buf, size_t count, loff_t *offset ) ;
87
ssize_t spartan_write(struct file *filp, const char *buf, size_t count, loff_t *offset) ;
88
int     spartan_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg) ;
89
loff_t  spartan_seek(struct file *filp, loff_t offset, int what) ;
90
 
91
// file operations structure - different for kernels 2.2 and 2.4
92
static struct file_operations *pspartan_fops ;
93
static struct file_operations spartan_fops = {
94
        #ifdef KERNEL_VER_24
95
        NULL,
96
        #endif
97
        spartan_seek,
98
        spartan_read,
99
        spartan_write,
100
        NULL,
101
        NULL,
102
        spartan_ioctl,
103
        NULL,
104
        spartan_open,
105
        NULL,
106
        spartan_release,
107
} ;
108
 
109
int open_mem_mapped(void) ;
110
 
111
// seek file operation function
112
loff_t  spartan_seek(struct file *filp, loff_t offset, int origin)
113
{
114
        loff_t requested_offset ;
115
        int resource_num = pspartan_dev.current_resource ;
116
 
117
        switch (origin)
118
        {
119
                case SEEK_CUR:requested_offset = pspartan_dev.offset + offset ; break ;
120
                case SEEK_END:requested_offset = pspartan_dev.base_size[resource_num] + offset ; break ;
121
                default:requested_offset  = offset ; break ;
122
        }
123
 
124
        if ((requested_offset < 0) || (requested_offset > pspartan_dev.base_size[resource_num]))
125
                return -EFAULT ;
126
 
127
        pspartan_dev.offset = requested_offset ;
128
 
129
        return requested_offset ;
130
}
131
 
132
// ioctl for device
133
// currently just a few operations are supported here - defined in spartan_kint.h header
134
int     spartan_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg)
135
{
136
        int error = 0;
137
        int size = _IOC_SIZE(cmd) ;
138
        unsigned long base ;
139
        unsigned long base_size ;
140
        int i;
141
 
142
        if (_IOC_TYPE(cmd) != SPARTAN_IOC_NUM) return -EINVAL ;
143
        if (_IOC_NR(cmd) > SPARTAN_IOC_MAX_NUM) return -EINVAL ;
144
 
145
        // Writes through pointers not allowed - writes only through argument 
146
        if (_IOC_DIR(cmd) & _IOC_WRITE) return -EINVAL ;
147
        else if (_IOC_DIR(cmd) & _IOC_READ)
148
                error = verify_area(VERIFY_WRITE, (void *) arg, size) ;
149
 
150
        if (error)
151
                return error ;
152
 
153
        switch (cmd){
154
                case SPARTAN_IOC_CURRESGET:
155
                        // current resource - they start at 1
156
                        return (pspartan_dev.current_resource + 1) ;
157
                case SPARTAN_IOC_CURRESSET:
158
                        // check if resource is in a range of implemented resources
159
                        if (arg < 0 )
160
                                return -EINVAL ;
161
 
162
                        // unmap previous resource if it was mapped
163
                        if (pspartan_dev.current_resource >= 0)
164
                        {
165
                                iounmap((void *)pspartan_dev.page_addr) ;
166
                        }
167
 
168
                        if (arg == 0)
169
                        {
170
                                // previous resource unmaped - that's all
171
                                pspartan_dev.current_resource = -1 ;
172
                                return 0 ;
173
                        }
174
 
175
                        if (pspartan_dev.num_of_bases < arg)
176
                                return -ENODEV ;
177
 
178
                        // IO mapped not supported yet
179
                        if (pspartan_dev.base_map[arg] == SPARTAN_IO_MAPPED)
180
                        {
181
                                // set current resource to none, since it was unmapped
182
                                pspartan_dev.current_resource = -1 ;
183
                                return -ENODEV ;
184
                        }
185
                        pspartan_dev.current_resource= (int)(arg-1) ;
186
                        // remap new resource
187
                        if ( (error = open_mem_mapped()) )
188
                        {
189
                                pspartan_dev.current_resource = -1 ;
190
                                return error ;
191
                        }
192
                        return 0 ;
193
                case SPARTAN_IOC_CURBASE:
194
                        // check if any resource is currently activated
195
                        if (pspartan_dev.current_resource>=0)
196
                                base = pspartan_dev.bases[pspartan_dev.current_resource] ;
197
                        else
198
                                base = 0x00000000 ;
199
 
200
                        *(unsigned long *)arg = base ;
201
                        return 0 ;
202
                case SPARTAN_IOC_CURBASEMAP:
203
                        // check if any resource is currently activated
204
                        if (pspartan_dev.current_resource>=0)
205
                                base = pspartan_dev.page_addr ;
206
                        else
207
                                base = 0x00000000 ;
208
 
209
                        *(unsigned long *)arg = base ;
210
 
211
                        return 0 ;
212
                case SPARTAN_IOC_CURBASESIZE:
213
                        // check if any resource is currently activated
214
                        if (pspartan_dev.current_resource>=0)
215
                                base_size = pspartan_dev.base_size[pspartan_dev.current_resource] ;
216
                        else
217
                                base_size = 0x00000000 ;
218
 
219
                        *(unsigned long *)arg = base_size ;
220
                        return 0 ;
221
                case SPARTAN_IOC_NUMOFRES:
222
                        return (pspartan_dev.num_of_bases) ;
223
#ifdef __VGA__          
224
                case SPARTAN_IOC_VIDEO_BASE:
225
                        *((unsigned long *)arg) = pspartan_dev.video_base;
226
                        put_user(pspartan_dev.video_base, ((unsigned long *)arg));
227
                        return 0 ;
228
 
229
                case SPARTAN_IOC_VIDEO_VBASE:
230
                        *(unsigned long *)arg = pspartan_dev.video_vbase;
231
                        put_user(pspartan_dev.video_vbase, ((unsigned long *)arg));
232
                        return 0 ;
233
 
234
                case SPARTAN_IOC_VIDEO_SIZE:
235
                        *(unsigned long *)arg = pspartan_dev.video_size;
236
                        put_user(pspartan_dev.video_size, ((unsigned long *)arg));
237
                        return 0;
238
 
239
                case SPARTAN_IOC_SET_VIDEO_BUFF:
240
                        for(i = 0; i < VIDEO_SZ; i++) {
241
                                get_user(*((char *)(pspartan_dev.video_vbase +  i)), ((char *)(arg + i)));
242
                        }
243
 
244
                        return 0;
245 103 mihad
        case SPARTAN_IOC_GET_VIDEO_BUFF:
246
            for(i = 0; i < VIDEO_SZ; i++) {
247
                put_user(*((char *)(pspartan_dev.video_vbase +  i)), ((char *)(arg + i))) ;
248
            }
249
 
250
            return 0 ;
251 21 mihad
#endif
252
                default:
253
                        return -EINVAL ;
254
        }
255
}
256
 
257
// helper function for memory remaping
258
int open_mem_mapped(void)
259
{
260
        int resource_num = pspartan_dev.current_resource ;
261
        unsigned long num_of_pages = 0 ;
262
        unsigned long base = pspartan_dev.bases[resource_num] ;
263
        unsigned long size = pspartan_dev.base_size[resource_num] ;
264
 
265
        if (!(num_of_pages = (unsigned long)(size/PAGE_SIZE))) ;
266
                num_of_pages++ ;
267
 
268
        pspartan_dev.base_page_offset = base & ~PAGE_MASK ;
269
 
270
        if ((pspartan_dev.base_page_offset + size) < (num_of_pages*PAGE_SIZE))
271
                num_of_pages++ ;
272
 
273
        // remap memory mapped space
274
        pspartan_dev.page_addr = (unsigned long)ioremap(base & PAGE_MASK, num_of_pages * PAGE_SIZE) ;
275
 
276
        if (pspartan_dev.page_addr == 0x00000000)
277
                return -ENOMEM ;
278
 
279
        return 0 ;
280
}
281
 
282
// add io mapped resource handler here
283
int open_io_mapped( void )
284
{
285
        return 0 ;
286
}
287
 
288
// open file operation function
289
int spartan_open(struct inode *inode, struct file *filp)
290
{
291
        if (MOD_IN_USE)
292
                return -EBUSY ;
293
 
294
        pspartan_fops = &spartan_fops ;
295
        filp->f_op = pspartan_fops ;
296
        pspartan_dev.offset = 0 ;
297
        pspartan_dev.current_resource = -1 ;
298
        MOD_INC_USE_COUNT ;
299
        return 0 ;
300
}
301
 
302
// release - called by close on file descriptor
303
int spartan_release(struct inode *inode, struct file *filp)
304
{
305
        // unmap any remaped pages
306
        if (pspartan_dev.current_resource >= 0)
307
                iounmap((void *)pspartan_dev.page_addr) ;
308
 
309
        pspartan_dev.current_resource = -1 ;
310
 
311
        MOD_DEC_USE_COUNT ;
312
        return 0 ;
313
}
314
 
315
// memory mapped resource read function
316
ssize_t spartan_read(struct file *filp, char *buf, size_t count, loff_t *offset_out )
317
{
318
 
319
        unsigned long current_address = pspartan_dev.page_addr + pspartan_dev.base_page_offset + pspartan_dev.offset ;
320
        unsigned long actual_count ;
321
        unsigned long offset = pspartan_dev.offset ;
322
        int resource_num = pspartan_dev.current_resource ;
323
        int i;
324 103 mihad
        unsigned int value;
325
        unsigned int *kern_buf ;
326
        unsigned int *kern_buf_tmp ;
327 21 mihad
 
328
        unsigned long size   = pspartan_dev.base_size[resource_num] ;
329
        int result ;
330
 
331
        if (pspartan_dev.current_resource < 0)
332
                return -ENODEV ;
333
 
334
        if (offset == size)
335
                return 0 ;
336
 
337
        if ( (offset + count) > size )
338
                actual_count = size - offset ;
339
        else
340
                actual_count = count ;
341
 
342
        // verify range if it is OK to copy from
343
        if ((result = verify_area(VERIFY_WRITE, buf, actual_count)))
344
                return result ;
345
 
346 103 mihad
    kern_buf = kmalloc(actual_count, GFP_KERNEL | GFP_DMA) ;
347
    kern_buf_tmp = kern_buf ;
348
    if (kern_buf <= 0)
349
        return 0 ;
350
 
351
    memcpy_fromio(kern_buf, current_address, actual_count) ;
352 21 mihad
        i = actual_count/4;
353
        while(i--) {
354
 
355 103 mihad
//              value = readl(current_address); 
356
        value = *(kern_buf) ;
357
                put_user(value, ((unsigned int *)buf));
358 21 mihad
                buf += 4;
359 103 mihad
        ++kern_buf ;
360
//              current_address += 4;
361 21 mihad
        }
362
 
363 103 mihad
    kfree(kern_buf_tmp);
364 21 mihad
        pspartan_dev.offset = pspartan_dev.offset + actual_count ;
365
 
366
        *(offset_out) = pspartan_dev.offset ;
367
 
368
        return actual_count ;
369
 }
370
 
371
// memory mapped resource write function
372
ssize_t spartan_write(struct file *filp, const char *buf, size_t count, loff_t *offset_out)
373
{
374
        unsigned long current_address = pspartan_dev.page_addr + pspartan_dev.base_page_offset + pspartan_dev.offset ;
375
        unsigned long actual_count ;
376
        unsigned long offset = pspartan_dev.offset ;
377
        int resource_num = pspartan_dev.current_resource ;
378
        int i;
379
        int value;
380
        unsigned long size   = pspartan_dev.base_size[resource_num] ;
381
        int result ;
382 103 mihad
    int *kern_buf ;
383
    int *kern_buf_tmp ;
384 21 mihad
 
385
        if (pspartan_dev.current_resource < 0)
386
                return -ENODEV ;
387
 
388
        if (offset == size)
389
                return 0 ;
390
 
391
        if ( (offset + count) > size )
392
                actual_count = size - offset ;
393
        else
394
                actual_count = count ;
395
 
396
        // verify range if it is OK to copy from
397
        if ((result = verify_area(VERIFY_READ, buf, actual_count)))
398
                return result ;
399
 
400 103 mihad
    kern_buf = kmalloc(actual_count, GFP_KERNEL | GFP_DMA) ;
401
    kern_buf_tmp = kern_buf ;
402
    if (kern_buf <= 0)
403
        return 0 ;
404
 
405 21 mihad
        i = actual_count/4;
406
        while(i--) {
407
                get_user(value, ((int *)buf));
408 103 mihad
                //writel(value, current_address);
409
        *kern_buf = value ;
410 21 mihad
                buf += 4;
411 103 mihad
                //current_address += 4;
412
        ++kern_buf ;
413 21 mihad
        }
414 103 mihad
 
415
    memcpy_toio(current_address, kern_buf_tmp, actual_count) ;
416
    kfree(kern_buf_tmp) ;
417
 
418 21 mihad
        pspartan_dev.offset = pspartan_dev.offset + actual_count ;
419
 
420
        *(offset_out) = pspartan_dev.offset ;
421
 
422
        return actual_count ;
423
}
424
 
425
// initialization function - different for 2.2 and 2.4 kernel because of different pci_dev structure
426
int init_module(void)
427
{
428
        int result ;
429
        u32 base_address ;
430
        unsigned long size ;
431
        unsigned short num_of_bases ;
432
        u16 wvalue ;
433
        struct pci_dev *ppci_spartan_dev = NULL ;
434
        struct resource spartan_resource ;
435
        struct page *page;
436
        int sz ;
437
 
438
        if(!pci_present())
439
        {
440
                printk("<1> Kernel reports no PCI bus support!\n " );
441
                return -ENODEV;
442
        }
443
 
444
        if((ppci_spartan_dev = pci_find_device(OC_PCI_VENDOR, OC_PCI_DEVICE, ppci_spartan_dev))==NULL )
445
        {
446
                printk("<1> Device not found!\n " );
447
                return -ENODEV ;
448
        }
449
 
450
        pspartan_dev.ppci_spartan_dev = ppci_spartan_dev ;
451
 
452
#ifdef KERNEL_VER_24
453
        //printk("<1> Board found at address 0x%08X\n", ppci_spartan_dev->resource[0].start) ;
454
        // copy implemented base addresses to private structure
455
 
456
        spartan_resource = ppci_spartan_dev->resource[0] ;
457
        base_address     =  spartan_resource.start ;
458
        printk("<1> First base address register found at %08X \n ", base_address );
459
        num_of_bases = 0 ;
460
        while ((base_address != 0x00000000) && (num_of_bases < 6))
461
        {
462
                pspartan_dev.bases[num_of_bases] = spartan_resource.start ;
463
                pspartan_dev.base_size[num_of_bases] = spartan_resource.end - spartan_resource.start + 1 ;
464
                // check if resource is IO mapped
465
                if (spartan_resource.flags & IORESOURCE_IO)
466
                        pspartan_dev.base_map[num_of_bases] = SPARTAN_IO_MAPPED ;
467
                else
468
                        pspartan_dev.base_map[num_of_bases] = SPARTAN_MEM_MAPPED ;
469
 
470
                num_of_bases++ ;
471
                spartan_resource = ppci_spartan_dev->resource[num_of_bases] ;
472
                base_address = spartan_resource.start ;
473
        }
474
 
475
        result = pci_read_config_word(ppci_spartan_dev, PCI_COMMAND, &wvalue) ;
476
        if (result <  0)
477
        {
478
                printk("<1> Read from command register failed! \n " );
479
                return result ;
480
        }
481
 
482
        result = pci_write_config_word(ppci_spartan_dev, PCI_COMMAND, wvalue | PCI_COMMAND_MEMORY | PCI_COMMAND_IO) ;
483
 
484
        if (result <  0)
485
        {
486
                printk("<1>Write to command register failed! \n " );
487
                return result ;
488
        }
489
 
490
#else
491
 
492
        printk("<1> Board found at address 0x%08X\n", ppci_spartan_dev->base_address[0]);
493
 
494
        // now go through base addresses of development board 
495
        // and see what size they are - first disable devices response
496
        result = pci_read_config_word(ppci_spartan_dev, PCI_COMMAND, &wvalue) ;
497
        if (result <  0)
498
        {
499
                printk("<1> Read from command register failed! \n " );
500
                return result ;
501
        }
502
 
503
        // write masked config value back to command register to 
504
        // disable devices response! mask value
505
        result = pci_write_config_word(ppci_spartan_dev, PCI_COMMAND, wvalue & ~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY) ;
506
 
507
        if (result <  0)
508
        {
509
                printk("<1>Write to command register failed! \n " );
510
                return result ;
511
        }
512
 
513
        // write to base address registers and read back until all 0s are read
514
        base_address = ppci_spartan_dev->base_address[0] ;
515
        num_of_bases = 0 ;
516
        while ((base_address != 0x00000000) && (num_of_bases < 6))
517
        {
518
                // copy non-zero base address to private structure
519
                pspartan_dev.bases[num_of_bases] = ppci_spartan_dev->base_address[num_of_bases] ;
520
 
521
                // write to current register
522
                result = pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0 + (num_of_bases * 4), 0xFFFFFFFF) ;
523
 
524
                if (result <  0)
525
                {
526
                        printk("<1>Write to BAR%d failed! \n ", num_of_bases);
527
                        return result ;
528
                }
529
 
530
                result = pci_read_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0 + (num_of_bases * 4), &base_address) ;
531
                if (result <  0)
532
                {
533
                        printk("<1>Read from BAR%d failed! \n ", num_of_bases);
534
                        return result ;
535
                }
536
 
537
                // calculate size of this base address register's range
538
                size = 0xFFFFFFFF - base_address ;
539
 
540
                // store size in structure
541
                pspartan_dev.base_size[num_of_bases] = size + 1;
542
 
543
                // set base address back to original value
544
                base_address = pspartan_dev.bases[num_of_bases] ;
545
 
546
                // now write original base address back to this register
547
                result = pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0 + (num_of_bases * 4), base_address) ;
548
 
549
                if (result <  0)
550
                {
551
                        printk("<1>Write to BAR%d failed! \n ", num_of_bases);
552
                        return result ;
553
                }
554
                num_of_bases++ ;
555
                // read new base address
556
                base_address = ppci_spartan_dev->base_address[num_of_bases] ;
557
 
558
        }
559
        // write original value back to command register!
560
        result = pci_write_config_word(ppci_spartan_dev, PCI_COMMAND, wvalue) ;
561
 
562
        if (result <  0)
563
        {
564
                printk("<1>Write to command register failed! \n " );
565
                return result ;
566
        }
567
#endif
568
        if (num_of_bases < 1)
569
                printk("<1>No implemented base address registers found! \n ") ;
570
 
571
        pspartan_dev.current_resource = - 1 ;
572
 
573
        // store number of bases in structure
574
        pspartan_dev.num_of_bases = num_of_bases ;
575
 
576
        // display information about all base addresses found in this procedure
577
        for (num_of_bases = 0; num_of_bases < pspartan_dev.num_of_bases; num_of_bases++)
578
        {
579
                printk("<1>BAR%d range from %08X to %08X \n ", num_of_bases, pspartan_dev.bases[num_of_bases], pspartan_dev.bases[num_of_bases] + pspartan_dev.base_size[num_of_bases]);
580
        }
581
#ifdef __VGA__
582
        for (sz = 0, size = PAGE_SIZE; size < VIDEO_SZ; sz++, size <<= 1);
583
        pspartan_dev.video_vbase = __get_free_pages(GFP_KERNEL, sz);
584
 
585
        if (pspartan_dev.video_vbase == 0) {
586
                printk(KERN_ERR "spartan: abort, cannot allocate video memory\n");
587
                return -EIO;
588
        }
589
 
590
        pspartan_dev.video_size = PAGE_SIZE * (1 << sz);
591
        pspartan_dev.video_base = virt_to_bus(pspartan_dev.video_vbase);
592
 
593
        for (page = virt_to_page(pspartan_dev.video_vbase); page <= virt_to_page(pspartan_dev.video_vbase + pspartan_dev.video_size - 1); page++)
594
                mem_map_reserve(page);
595
 
596
        printk(KERN_INFO "spartan: framebuffer at 0x%lx (phy 0x%lx), mapped to 0x%p, size %dk\n",
597
               pspartan_dev.video_base, virt_to_phys(pspartan_dev.video_vbase), pspartan_dev.video_vbase, pspartan_dev.video_size/1024);
598
#endif
599
 
600
        result = register_chrdev(REQUESTED_MAJOR, "spartan", &spartan_fops) ;
601
        if (result < 0)
602
        {
603
                printk(KERN_WARNING "spartan: can't get major number %d\n",REQUESTED_MAJOR) ;
604
                return result ;
605
        }
606
 
607
        printk("<1> Major number for spartan is %d \n", result );
608
        pspartan_dev.major = result ;
609
 
610
        return 0 ;
611
}
612
 
613
// celanup - unregister device
614
void cleanup_module(void)
615
{
616
        int result ;
617
        int size, sz;
618
 
619
#ifdef __VGA__
620
        for (sz = 0, size = PAGE_SIZE; size < VIDEO_SZ; sz++, size <<= 1);
621
        free_pages(pspartan_dev.video_vbase, sz);
622
#endif
623
        result = unregister_chrdev(pspartan_dev.major, "spartan") ;
624
        if (result < 0)
625
        {
626
                printk("<1> spartan device with major number %d unregistration failed \n", pspartan_dev.major);
627
                return ;
628
        }
629
        else
630
        {
631
                printk("<1> spartan device with major number %d unregistered succesfully \n", pspartan_dev.major);
632
                return ;
633
        }
634
}
635 103 mihad
 
636
MODULE_LICENSE("GPL") ;

powered by: WebSVN 2.1.0

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