ARM64: DTS: Add rk3399-firefly uart4 device, node as /dev/ttyS1
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / common_port / dwc_common_linux.c
1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/module.h>
4 #include <linux/kthread.h>
5
6 #ifdef DWC_CCLIB
7 # include "dwc_cc.h"
8 #endif
9
10 #ifdef DWC_CRYPTOLIB
11 # include "dwc_modpow.h"
12 # include "dwc_dh.h"
13 # include "dwc_crypto.h"
14 #endif
15
16 #ifdef DWC_NOTIFYLIB
17 # include "dwc_notifier.h"
18 #endif
19
20 /* OS-Level Implementations */
21
22 /* This is the Linux kernel implementation of the DWC platform library. */
23 #include <linux/moduleparam.h>
24 #include <linux/ctype.h>
25 #include <linux/crypto.h>
26 #include <linux/delay.h>
27 #include <linux/device.h>
28 #include <linux/dma-mapping.h>
29 #include <linux/cdev.h>
30 #include <linux/errno.h>
31 #include <linux/interrupt.h>
32 #include <linux/jiffies.h>
33 #include <linux/list.h>
34 #include <linux/pci.h>
35 #include <linux/random.h>
36 #include <linux/scatterlist.h>
37 #include <linux/slab.h>
38 #include <linux/stat.h>
39 #include <linux/string.h>
40 #include <linux/timer.h>
41 #include <linux/usb.h>
42
43 #include <linux/version.h>
44
45 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
46 # include <linux/usb/gadget.h>
47 #else
48 # include <linux/usb_gadget.h>
49 #endif
50
51 #include <asm/io.h>
52 #include <asm/page.h>
53 #include <asm/uaccess.h>
54 #include <asm/unaligned.h>
55
56 #include "dwc_os.h"
57 #include "dwc_list.h"
58
59 /** Prefix string for DWC_DEBUG print macros. */
60
61
62 /* MISC */
63
64 void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size)
65 {
66         return memset(dest, byte, size);
67 }
68
69 void *DWC_MEMCPY(void *dest, void const *src, uint32_t size)
70 {
71         return memcpy(dest, src, size);
72 }
73
74 void *DWC_MEMMOVE(void *dest, void *src, uint32_t size)
75 {
76         return memmove(dest, src, size);
77 }
78
79 int DWC_MEMCMP(void *m1, void *m2, uint32_t size)
80 {
81         return memcmp(m1, m2, size);
82 }
83
84 int DWC_STRNCMP(void *s1, void *s2, uint32_t size)
85 {
86         return strncmp(s1, s2, size);
87 }
88
89 int DWC_STRCMP(void *s1, void *s2)
90 {
91         return strcmp(s1, s2);
92 }
93
94 int DWC_STRLEN(char const *str)
95 {
96         return strlen(str);
97 }
98
99 char *DWC_STRCPY(char *to, char const *from)
100 {
101         return strcpy(to, from);
102 }
103
104 char *DWC_STRDUP(char const *str)
105 {
106         int len = DWC_STRLEN(str) + 1;
107         char *new = DWC_ALLOC_ATOMIC(len);
108
109         if (!new) {
110                 return NULL;
111         }
112
113         DWC_MEMCPY(new, str, len);
114         return new;
115 }
116
117 int DWC_ATOI(const char *str, int32_t *value)
118 {
119         char *end = NULL;
120
121         *value = simple_strtol(str, &end, 0);
122         if (*end == '\0') {
123                 return 0;
124         }
125
126         return -1;
127 }
128
129 int DWC_ATOUI(const char *str, uint32_t *value)
130 {
131         char *end = NULL;
132
133         *value = simple_strtoul(str, &end, 0);
134         if (*end == '\0') {
135                 return 0;
136         }
137
138         return -1;
139 }
140
141
142 #ifdef DWC_UTFLIB
143 /* From usbstring.c */
144
145 int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len)
146 {
147         int     count = 0;
148         u8      c;
149         u16     uchar;
150
151         /* this insists on correct encodings, though not minimal ones.
152          * BUT it currently rejects legit 4-byte UTF-8 code points,
153          * which need surrogate pairs.  (Unicode 3.1 can use them.)
154          */
155         while (len != 0 && (c = (u8) *s++) != 0) {
156                 if (unlikely(c & 0x80)) {
157                         /* 2-byte sequence: */
158                         /* 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx */
159                         if ((c & 0xe0) == 0xc0) {
160                                 uchar = (c & 0x1f) << 6;
161
162                                 c = (u8) *s++;
163                                 if ((c & 0xc0) != 0xc0)
164                                         goto fail;
165                                 c &= 0x3f;
166                                 uchar |= c;
167
168                         /* 3-byte sequence (most CJKV characters): */
169                         /* zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx */
170                         } else if ((c & 0xf0) == 0xe0) {
171                                 uchar = (c & 0x0f) << 12;
172
173                                 c = (u8) *s++;
174                                 if ((c & 0xc0) != 0xc0)
175                                         goto fail;
176                                 c &= 0x3f;
177                                 uchar |= c << 6;
178
179                                 c = (u8) *s++;
180                                 if ((c & 0xc0) != 0xc0)
181                                         goto fail;
182                                 c &= 0x3f;
183                                 uchar |= c;
184
185                                 /* no bogus surrogates */
186                                 if (0xd800 <= uchar && uchar <= 0xdfff)
187                                         goto fail;
188
189                         /* 4-byte sequence (surrogate pairs, currently rare): */
190                         /* 11101110wwwwzzzzyy + 110111yyyyxxxxxx */
191                         /*     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx */
192                         /* (uuuuu = wwww + 1) */
193                         /*  FIXME accept the surrogate code points (only) */
194                         } else
195                                 goto fail;
196                 } else
197                         uchar = c;
198                 put_unaligned (cpu_to_le16 (uchar), cp++);
199                 count++;
200                 len--;
201         }
202         return count;
203 fail:
204         return -1;
205 }
206 #endif  /* DWC_UTFLIB */
207
208
209 /* dwc_debug.h */
210
211 dwc_bool_t DWC_IN_IRQ(void)
212 {
213         return in_irq();
214 }
215
216 dwc_bool_t DWC_IN_BH(void)
217 {
218         return in_softirq();
219 }
220
221 void DWC_VPRINTF(char *format, va_list args)
222 {
223         vprintk(format, args);
224 }
225
226 int DWC_VSNPRINTF(char *str, int size, char *format, va_list args)
227 {
228         return vsnprintf(str, size, format, args);
229 }
230
231 void DWC_PRINTF(char *format, ...)
232 {
233         va_list args;
234
235         va_start(args, format);
236         DWC_VPRINTF(format, args);
237         va_end(args);
238 }
239
240 int DWC_SPRINTF(char *buffer, char *format, ...)
241 {
242         int retval;
243         va_list args;
244
245         va_start(args, format);
246         retval = vsprintf(buffer, format, args);
247         va_end(args);
248         return retval;
249 }
250
251 int DWC_SNPRINTF(char *buffer, int size, char *format, ...)
252 {
253         int retval;
254         va_list args;
255
256         va_start(args, format);
257         retval = vsnprintf(buffer, size, format, args);
258         va_end(args);
259         return retval;
260 }
261
262 void __DWC_WARN(char *format, ...)
263 {
264         va_list args;
265
266         va_start(args, format);
267         DWC_PRINTF(KERN_WARNING);
268         DWC_VPRINTF(format, args);
269         va_end(args);
270 }
271
272 void __DWC_ERROR(char *format, ...)
273 {
274         va_list args;
275
276         va_start(args, format);
277         DWC_PRINTF(KERN_ERR);
278         DWC_VPRINTF(format, args);
279         va_end(args);
280 }
281
282 void DWC_EXCEPTION(char *format, ...)
283 {
284         va_list args;
285
286         va_start(args, format);
287         DWC_PRINTF(KERN_ERR);
288         DWC_VPRINTF(format, args);
289         va_end(args);
290         BUG_ON(1);
291 }
292
293 #ifdef DEBUG
294 void __DWC_DEBUG(char *format, ...)
295 {
296         va_list args;
297
298         va_start(args, format);
299         DWC_PRINTF(KERN_ERR);
300         DWC_VPRINTF(format, args);
301         va_end(args);
302 }
303 #else
304 void __DWC_DEBUG(char *format, ...)
305 {
306     ;
307 }
308 #endif
309
310
311
312 /* dwc_mem.h */
313
314 #if 0
315 dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size,
316                                 uint32_t align,
317                                 uint32_t alloc)
318 {
319         struct dma_pool *pool = dma_pool_create("Pool", NULL,
320                                                 size, align, alloc);
321         return (dwc_pool_t *)pool;
322 }
323
324 void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool)
325 {
326         dma_pool_destroy((struct dma_pool *)pool);
327 }
328
329 void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
330 {
331         return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr);
332 }
333
334 void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
335 {
336         void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr);
337         memset(..);
338 }
339
340 void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr)
341 {
342         dma_pool_free(pool, vaddr, daddr);
343 }
344 #endif
345
346 void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
347 {
348 #if 1 /* def xxCOSIM  Only works for 32-bit cosim */
349         void *buf = dma_alloc_coherent((struct device *)dma_ctx, (size_t)size,
350                                        dma_addr, GFP_KERNEL);
351 #else
352         void *buf = dma_alloc_coherent(dma_ctx, (size_t)size, dma_addr, GFP_KERNEL | GFP_DMA32);
353 #endif
354         if (!buf) {
355                 return NULL;
356         }
357
358         memset(buf, 0, (size_t)size);
359         return buf;
360 }
361
362 void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
363 {
364         void *buf = dma_alloc_coherent((struct device *)dma_ctx, (size_t)size,
365                                        dma_addr, GFP_ATOMIC);
366         if (!buf) {
367                 return NULL;
368         }
369         memset(buf, 0, (size_t)size);
370         return buf;
371 }
372
373 void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
374 {
375         dma_free_coherent((struct device *)dma_ctx, size, virt_addr, dma_addr);
376 }
377
378 void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
379 {
380         return kzalloc(size, GFP_KERNEL);
381 }
382
383 void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
384 {
385         return kzalloc(size, GFP_ATOMIC);
386 }
387
388 void __DWC_FREE(void *mem_ctx, void *addr)
389 {
390         kfree(addr);
391 }
392
393
394 #ifdef DWC_CRYPTOLIB
395 /* dwc_crypto.h */
396
397 void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
398 {
399         get_random_bytes(buffer, length);
400 }
401
402 int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
403 {
404         struct crypto_blkcipher *tfm;
405         struct blkcipher_desc desc;
406         struct scatterlist sgd;
407         struct scatterlist sgs;
408
409         tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
410         if (tfm == NULL) {
411                 printk("failed to load transform for aes CBC\n");
412                 return -1;
413         }
414
415         crypto_blkcipher_setkey(tfm, key, keylen);
416         crypto_blkcipher_set_iv(tfm, iv, 16);
417
418         sg_init_one(&sgd, out, messagelen);
419         sg_init_one(&sgs, message, messagelen);
420
421         desc.tfm = tfm;
422         desc.flags = 0;
423
424         if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
425                 crypto_free_blkcipher(tfm);
426                 DWC_ERROR("AES CBC encryption failed");
427                 return -1;
428         }
429
430         crypto_free_blkcipher(tfm);
431         return 0;
432 }
433
434 int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
435 {
436         struct crypto_hash *tfm;
437         struct hash_desc desc;
438         struct scatterlist sg;
439
440         tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
441         if (IS_ERR(tfm)) {
442                 DWC_ERROR("Failed to load transform for sha256: %ld\n", PTR_ERR(tfm));
443                 return 0;
444         }
445         desc.tfm = tfm;
446         desc.flags = 0;
447
448         sg_init_one(&sg, message, len);
449         crypto_hash_digest(&desc, &sg, len, out);
450         crypto_free_hash(tfm);
451
452         return 1;
453 }
454
455 int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
456                     uint8_t *key, uint32_t keylen, uint8_t *out)
457 {
458         struct crypto_hash *tfm;
459         struct hash_desc desc;
460         struct scatterlist sg;
461
462         tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
463         if (IS_ERR(tfm)) {
464                 DWC_ERROR("Failed to load transform for hmac(sha256): %ld\n", PTR_ERR(tfm));
465                 return 0;
466         }
467         desc.tfm = tfm;
468         desc.flags = 0;
469
470         sg_init_one(&sg, message, messagelen);
471         crypto_hash_setkey(tfm, key, keylen);
472         crypto_hash_digest(&desc, &sg, messagelen, out);
473         crypto_free_hash(tfm);
474
475         return 1;
476 }
477 #endif  /* DWC_CRYPTOLIB */
478
479
480 /* Byte Ordering Conversions */
481
482 uint32_t DWC_CPU_TO_LE32(uint32_t *p)
483 {
484 #ifdef __LITTLE_ENDIAN
485         return *p;
486 #else
487         uint8_t *u_p = (uint8_t *)p;
488         uint32_t ret;
489         ret = u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24);
490
491         return ret;
492 #endif
493 }
494
495 uint32_t DWC_CPU_TO_BE32(uint32_t *p)
496 {
497 #ifdef __BIG_ENDIAN
498         return *p;
499 #else
500         uint8_t *u_p = (uint8_t *)p;
501         uint32_t ret;
502         ret = u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24);
503
504         return ret;
505 #endif
506 }
507
508 uint32_t DWC_LE32_TO_CPU(uint32_t *p)
509 {
510 #ifdef __LITTLE_ENDIAN
511         return *p;
512 #else
513         uint8_t *u_p = (uint8_t *)p;
514         uint32_t ret;
515         ret = u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24);
516
517         return ret;
518 #endif
519 }
520
521 uint32_t DWC_BE32_TO_CPU(uint32_t *p)
522 {
523 #ifdef __BIG_ENDIAN
524         return *p;
525 #else
526         uint8_t *u_p = (uint8_t *)p;
527         uint32_t ret;
528         ret = u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24);
529
530         return ret;
531 #endif
532 }
533
534 uint16_t DWC_CPU_TO_LE16(uint16_t *p)
535 {
536 #ifdef __LITTLE_ENDIAN
537         return *p;
538 #else
539         uint8_t *u_p = (uint8_t *)p;
540         uint16_t ret;
541         ret = u_p[1] | (u_p[0] << 8);
542         return ret;
543 #endif
544 }
545
546 uint16_t DWC_CPU_TO_BE16(uint16_t *p)
547 {
548 #ifdef __BIG_ENDIAN
549         return *p;
550 #else
551         uint8_t *u_p = (uint8_t *)p;
552         uint16_t ret;
553         ret = u_p[1] | (u_p[0] << 8);
554         return ret;
555 #endif
556 }
557
558 uint16_t DWC_LE16_TO_CPU(uint16_t *p)
559 {
560 #ifdef __LITTLE_ENDIAN
561         return *p;
562 #else
563         uint8_t *u_p = (uint8_t *)p;
564         uint16_t ret;
565         ret = u_p[1] | (u_p[0] << 8);
566         return ret;
567 #endif
568 }
569
570 uint16_t DWC_BE16_TO_CPU(uint16_t *p)
571 {
572 #ifdef __BIG_ENDIAN
573         return *p;
574 #else
575         uint8_t *u_p = (uint8_t *)p;
576         uint16_t ret;
577         ret = u_p[1] | (u_p[0] << 8);
578         return ret;
579 #endif
580 }
581
582
583 /* Registers */
584
585 uint32_t DWC_READ_REG32(volatile uint32_t *reg)
586 {
587         return readl_relaxed(reg);
588 }
589
590 #if 0
591 uint64_t DWC_READ_REG64(volatile uint64_t *reg)
592 {
593 }
594 #endif
595
596 void DWC_WRITE_REG32(volatile uint32_t *reg, uint32_t value)
597 {
598         writel_relaxed(value, reg);
599         dsb(sy);
600 }
601
602 #if 0
603 void DWC_WRITE_REG64(volatile uint64_t *reg, uint64_t value)
604 {
605 }
606 #endif
607
608 void DWC_MODIFY_REG32(volatile uint32_t *reg, uint32_t clear_mask, uint32_t set_mask)
609 {
610         writel_relaxed((readl_relaxed(reg) & ~clear_mask) | set_mask, reg);
611         dsb(sy);
612 }
613
614 #if 0
615 void DWC_MODIFY_REG64(volatile uint64_t *reg, uint64_t clear_mask, uint64_t set_mask)
616 {
617 }
618 #endif
619
620
621 /* Locking */
622
623 dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
624 {
625         spinlock_t *sl = (spinlock_t *)1;
626
627 #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
628         sl = DWC_ALLOC(sizeof(*sl));
629         if (!sl) {
630                 DWC_ERROR("Cannot allocate memory for spinlock\n");
631                 return NULL;
632         }
633
634         spin_lock_init(sl);
635 #endif
636         return (dwc_spinlock_t *)sl;
637 }
638
639 void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
640 {
641 #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
642         DWC_FREE(lock);
643 #endif
644 }
645
646 void DWC_SPINLOCK(dwc_spinlock_t *lock)
647 {
648 #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
649         spin_lock((spinlock_t *)lock);
650 #endif
651 }
652
653 void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
654 {
655 #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
656         spin_unlock((spinlock_t *)lock);
657 #endif
658 }
659
660 void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
661 {
662         dwc_irqflags_t f;
663
664 #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
665         spin_lock_irqsave((spinlock_t *)lock, f);
666 #else
667         local_irq_save(f);
668 #endif
669         *flags = f;
670 }
671
672 void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
673 {
674 #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
675         spin_unlock_irqrestore((spinlock_t *)lock, flags);
676 #else
677         local_irq_restore(flags);
678 #endif
679 }
680
681 dwc_mutex_t *DWC_MUTEX_ALLOC(void)
682 {
683         struct mutex *m;
684         dwc_mutex_t *mutex = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex));
685
686         if (!mutex) {
687                 DWC_ERROR("Cannot allocate memory for mutex\n");
688                 return NULL;
689         }
690
691         m = (struct mutex *)mutex;
692         mutex_init(m);
693         return mutex;
694 }
695
696 #if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
697 #else
698 void DWC_MUTEX_FREE(dwc_mutex_t *mutex)
699 {
700         mutex_destroy((struct mutex *)mutex);
701         DWC_FREE(mutex);
702 }
703 #endif
704
705 void DWC_MUTEX_LOCK(dwc_mutex_t *mutex)
706 {
707         struct mutex *m = (struct mutex *)mutex;
708         mutex_lock(m);
709 }
710
711 int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex)
712 {
713         struct mutex *m = (struct mutex *)mutex;
714         return mutex_trylock(m);
715 }
716
717 void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex)
718 {
719         struct mutex *m = (struct mutex *)mutex;
720         mutex_unlock(m);
721 }
722
723
724 /* Timing */
725
726 void DWC_UDELAY(uint32_t usecs)
727 {
728         udelay(usecs);
729 }
730
731 void DWC_MDELAY(uint32_t msecs)
732 {
733         mdelay(msecs);
734 }
735
736 void DWC_MSLEEP(uint32_t msecs)
737 {
738         msleep(msecs);
739 }
740
741 uint32_t DWC_TIME(void)
742 {
743         return jiffies_to_msecs(jiffies);
744 }
745
746
747 /* Timers */
748
749 struct dwc_timer {
750         struct timer_list *t;
751         char *name;
752         dwc_timer_callback_t cb;
753         void *data;
754         uint8_t scheduled;
755         dwc_spinlock_t *lock;
756 };
757
758 static void timer_callback(unsigned long data)
759 {
760         dwc_timer_t *timer = (dwc_timer_t *)data;
761         dwc_irqflags_t flags;
762
763         DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
764         timer->scheduled = 0;
765         DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
766         /* DWC_DEBUG("Timer %s callback", timer->name); */
767         timer->cb(timer->data);
768 }
769
770 dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data)
771 {
772         dwc_timer_t *t = DWC_ALLOC(sizeof(*t));
773
774         if (!t) {
775                 DWC_ERROR("Cannot allocate memory for timer");
776                 return NULL;
777         }
778
779         t->t = DWC_ALLOC(sizeof(*t->t));
780         if (!t->t) {
781                 DWC_ERROR("Cannot allocate memory for timer->t");
782                 goto no_timer;
783         }
784
785         t->name = DWC_STRDUP(name);
786         if (!t->name) {
787                 DWC_ERROR("Cannot allocate memory for timer->name");
788                 goto no_name;
789         }
790
791         t->lock = DWC_SPINLOCK_ALLOC();
792         if (!t->lock) {
793                 DWC_ERROR("Cannot allocate memory for lock");
794                 goto no_lock;
795         }
796
797         t->scheduled = 0;
798         t->t->expires = jiffies;
799         setup_timer(t->t, timer_callback, (unsigned long)t);
800
801         t->cb = cb;
802         t->data = data;
803
804         return t;
805
806  no_lock:
807         DWC_FREE(t->name);
808  no_name:
809         DWC_FREE(t->t);
810  no_timer:
811         DWC_FREE(t);
812         return NULL;
813 }
814
815 void DWC_TIMER_FREE(dwc_timer_t *timer)
816 {
817         dwc_irqflags_t flags;
818
819         DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
820
821         if (timer->scheduled) {
822                 del_timer(timer->t);
823                 timer->scheduled = 0;
824         }
825
826         DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
827         DWC_SPINLOCK_FREE(timer->lock);
828         DWC_FREE(timer->t);
829         DWC_FREE(timer->name);
830         DWC_FREE(timer);
831 }
832
833 void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time)
834 {
835         dwc_irqflags_t flags;
836
837         DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
838
839         if (!timer->scheduled) {
840                 timer->scheduled = 1;
841                 /* DWC_DEBUG("Scheduling timer %s to expire in +%d msec",
842                  *           timer->name, time);*/
843                 timer->t->expires = jiffies + msecs_to_jiffies(time);
844                 add_timer(timer->t);
845         } else {
846                 /* DWC_DEBUG("Modifying timer %s to expire in +%d msec",
847                  *           timer->name, time);*/
848                 mod_timer(timer->t, jiffies + msecs_to_jiffies(time));
849         }
850
851         DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
852 }
853
854 void DWC_TIMER_CANCEL(dwc_timer_t *timer)
855 {
856         del_timer(timer->t);
857 }
858
859
860 /* Wait Queues */
861
862 struct dwc_waitq {
863         wait_queue_head_t queue;
864         int abort;
865 };
866
867 dwc_waitq_t *DWC_WAITQ_ALLOC(void)
868 {
869         dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq));
870
871         if (!wq) {
872                 DWC_ERROR("Cannot allocate memory for waitqueue\n");
873                 return NULL;
874         }
875
876         init_waitqueue_head(&wq->queue);
877         wq->abort = 0;
878         return wq;
879 }
880
881 void DWC_WAITQ_FREE(dwc_waitq_t *wq)
882 {
883         DWC_FREE(wq);
884 }
885
886 int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data)
887 {
888         int result = wait_event_interruptible(wq->queue,
889                                               cond(data) || wq->abort);
890         if (result == -ERESTARTSYS) {
891                 wq->abort = 0;
892                 return -DWC_E_RESTART;
893         }
894
895         if (wq->abort == 1) {
896                 wq->abort = 0;
897                 return -DWC_E_ABORT;
898         }
899
900         wq->abort = 0;
901
902         if (result == 0) {
903                 return 0;
904         }
905
906         return -DWC_E_UNKNOWN;
907 }
908
909 int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
910                                void *data, int32_t msecs)
911 {
912         int32_t tmsecs;
913         int result = wait_event_interruptible_timeout(wq->queue,
914                                                       cond(data) || wq->abort,
915                                                       msecs_to_jiffies(msecs));
916         if (result == -ERESTARTSYS) {
917                 wq->abort = 0;
918                 return -DWC_E_RESTART;
919         }
920
921         if (wq->abort == 1) {
922                 wq->abort = 0;
923                 return -DWC_E_ABORT;
924         }
925
926         wq->abort = 0;
927
928         if (result > 0) {
929                 tmsecs = jiffies_to_msecs(result);
930                 if (!tmsecs) {
931                         return 1;
932                 }
933
934                 return tmsecs;
935         }
936
937         if (result == 0) {
938                 return -DWC_E_TIMEOUT;
939         }
940
941         return -DWC_E_UNKNOWN;
942 }
943
944 void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq)
945 {
946         wq->abort = 0;
947         wake_up_interruptible(&wq->queue);
948 }
949
950 void DWC_WAITQ_ABORT(dwc_waitq_t *wq)
951 {
952         wq->abort = 1;
953         wake_up_interruptible(&wq->queue);
954 }
955
956
957 /* Threading */
958
959 dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data)
960 {
961         struct task_struct *thread = kthread_run(func, data, name);
962
963         if (thread == ERR_PTR(-ENOMEM)) {
964                 return NULL;
965         }
966
967         return (dwc_thread_t *)thread;
968 }
969
970 int DWC_THREAD_STOP(dwc_thread_t *thread)
971 {
972         return kthread_stop((struct task_struct *)thread);
973 }
974
975 dwc_bool_t DWC_THREAD_SHOULD_STOP(void)
976 {
977         return kthread_should_stop();
978 }
979
980
981 /* tasklets
982  - run in interrupt context (cannot sleep)
983  - each tasklet runs on a single CPU
984  - different tasklets can be running simultaneously on different CPUs
985  */
986 struct dwc_tasklet {
987         struct tasklet_struct t;
988         dwc_tasklet_callback_t cb;
989         void *data;
990 };
991
992 static void tasklet_callback(unsigned long data)
993 {
994         dwc_tasklet_t *t = (dwc_tasklet_t *)data;
995         t->cb(t->data);
996 }
997
998 dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
999 {
1000         dwc_tasklet_t *t = DWC_ALLOC(sizeof(*t));
1001
1002         if (t) {
1003                 t->cb = cb;
1004                 t->data = data;
1005                 tasklet_init(&t->t, tasklet_callback, (unsigned long)t);
1006         } else {
1007                 DWC_ERROR("Cannot allocate memory for tasklet\n");
1008         }
1009
1010         return t;
1011 }
1012
1013 void DWC_TASK_FREE(dwc_tasklet_t *task)
1014 {
1015         DWC_FREE(task);
1016 }
1017
1018 void DWC_TASK_SCHEDULE(dwc_tasklet_t *task)
1019 {
1020         tasklet_schedule(&task->t);
1021 }
1022
1023
1024 /* workqueues
1025  - run in process context (can sleep)
1026  */
1027 typedef struct work_container {
1028         dwc_work_callback_t cb;
1029         void *data;
1030         dwc_workq_t *wq;
1031         char *name;
1032
1033 #ifdef DEBUG
1034         DWC_CIRCLEQ_ENTRY(work_container) entry;
1035 #endif
1036         struct delayed_work work;
1037 } work_container_t;
1038
1039 #ifdef DEBUG
1040 DWC_CIRCLEQ_HEAD(work_container_queue, work_container);
1041 #endif
1042
1043 struct dwc_workq {
1044         struct workqueue_struct *wq;
1045         dwc_spinlock_t *lock;
1046         dwc_waitq_t *waitq;
1047         int pending;
1048
1049 #ifdef DEBUG
1050         struct work_container_queue entries;
1051 #endif
1052 };
1053
1054 static void do_work(struct work_struct *work)
1055 {
1056         dwc_irqflags_t flags;
1057         struct delayed_work *dw = container_of(work, struct delayed_work, work);
1058         work_container_t *container = container_of(dw, struct work_container, work);
1059         dwc_workq_t *wq = container->wq;
1060
1061         container->cb(container->data);
1062
1063 #ifdef DEBUG
1064         DWC_CIRCLEQ_REMOVE(&wq->entries, container, entry);
1065 #endif
1066         /* DWC_DEBUG("Work done: %s, container=%p",
1067          *           container->name, container); */
1068         if (container->name) {
1069                 DWC_FREE(container->name);
1070         }
1071         DWC_FREE(container);
1072
1073         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1074         wq->pending--;
1075         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1076         DWC_WAITQ_TRIGGER(wq->waitq);
1077 }
1078
1079 static int work_done(void *data)
1080 {
1081         dwc_workq_t *workq = (dwc_workq_t *)data;
1082         return workq->pending == 0;
1083 }
1084
1085 int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout)
1086 {
1087         return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout);
1088 }
1089
1090 dwc_workq_t *DWC_WORKQ_ALLOC(char *name)
1091 {
1092         dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq));
1093
1094         if (!wq) {
1095                 return NULL;
1096         }
1097
1098         wq->wq = create_singlethread_workqueue(name);
1099         if (!wq->wq) {
1100                 goto no_wq;
1101         }
1102
1103         wq->pending = 0;
1104
1105         wq->lock = DWC_SPINLOCK_ALLOC();
1106         if (!wq->lock) {
1107                 goto no_lock;
1108         }
1109
1110         wq->waitq = DWC_WAITQ_ALLOC();
1111         if (!wq->waitq) {
1112                 goto no_waitq;
1113         }
1114
1115 #ifdef DEBUG
1116         DWC_CIRCLEQ_INIT(&wq->entries);
1117 #endif
1118         return wq;
1119
1120  no_waitq:
1121         DWC_SPINLOCK_FREE(wq->lock);
1122  no_lock:
1123         destroy_workqueue(wq->wq);
1124  no_wq:
1125         DWC_FREE(wq);
1126
1127         return NULL;
1128 }
1129
1130 void DWC_WORKQ_FREE(dwc_workq_t *wq)
1131 {
1132 #ifdef DEBUG
1133         if (wq->pending != 0) {
1134                 struct work_container *wc;
1135                 DWC_ERROR("Destroying work queue with pending work");
1136                 DWC_CIRCLEQ_FOREACH(wc, &wq->entries, entry) {
1137                         DWC_ERROR("Work %s still pending", wc->name);
1138                 }
1139         }
1140 #endif
1141         destroy_workqueue(wq->wq);
1142         DWC_SPINLOCK_FREE(wq->lock);
1143         DWC_WAITQ_FREE(wq->waitq);
1144         DWC_FREE(wq);
1145 }
1146
1147 void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data,
1148                         char *format, ...)
1149 {
1150         dwc_irqflags_t flags;
1151         work_container_t *container;
1152         static char name[128];
1153         va_list args;
1154
1155         va_start(args, format);
1156         DWC_VSNPRINTF(name, 128, format, args);
1157         va_end(args);
1158
1159         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1160         wq->pending++;
1161         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1162         DWC_WAITQ_TRIGGER(wq->waitq);
1163
1164         container = DWC_ALLOC_ATOMIC(sizeof(*container));
1165         if (!container) {
1166                 DWC_ERROR("Cannot allocate memory for container\n");
1167                 return;
1168         }
1169
1170         container->name = DWC_STRDUP(name);
1171         if (!container->name) {
1172                 DWC_ERROR("Cannot allocate memory for container->name\n");
1173                 DWC_FREE(container);
1174                 return;
1175         }
1176
1177         container->cb = cb;
1178         container->data = data;
1179         container->wq = wq;
1180         /* DWC_DEBUG("Queueing work: %s, container=%p",
1181          *           container->name, container);*/
1182         INIT_WORK(&container->work.work, do_work);
1183
1184 #ifdef DEBUG
1185         DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
1186 #endif
1187         queue_work(wq->wq, &container->work.work);
1188 }
1189
1190 void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb,
1191                                 void *data, uint32_t time, char *format, ...)
1192 {
1193         dwc_irqflags_t flags;
1194         work_container_t *container;
1195         static char name[128];
1196         va_list args;
1197
1198         va_start(args, format);
1199         DWC_VSNPRINTF(name, 128, format, args);
1200         va_end(args);
1201
1202         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1203         wq->pending++;
1204         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1205         DWC_WAITQ_TRIGGER(wq->waitq);
1206
1207         container = DWC_ALLOC_ATOMIC(sizeof(*container));
1208         if (!container) {
1209                 DWC_ERROR("Cannot allocate memory for container\n");
1210                 return;
1211         }
1212
1213         container->name = DWC_STRDUP(name);
1214         if (!container->name) {
1215                 DWC_ERROR("Cannot allocate memory for container->name\n");
1216                 DWC_FREE(container);
1217                 return;
1218         }
1219
1220         container->cb = cb;
1221         container->data = data;
1222         container->wq = wq;
1223         /* DWC_DEBUG("Queueing work: %s, container=%p",
1224          *           container->name, container);*/
1225         INIT_DELAYED_WORK(&container->work, do_work);
1226
1227 #ifdef DEBUG
1228         DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
1229 #endif
1230         queue_delayed_work(wq->wq, &container->work, msecs_to_jiffies(time));
1231 }
1232
1233 int DWC_WORKQ_PENDING(dwc_workq_t *wq)
1234 {
1235         return wq->pending;
1236 }
1237
1238
1239 #ifdef DWC_LIBMODULE
1240
1241 #ifdef DWC_CCLIB
1242 /* CC */
1243 EXPORT_SYMBOL(dwc_cc_if_alloc);
1244 EXPORT_SYMBOL(dwc_cc_if_free);
1245 EXPORT_SYMBOL(dwc_cc_clear);
1246 EXPORT_SYMBOL(dwc_cc_add);
1247 EXPORT_SYMBOL(dwc_cc_remove);
1248 EXPORT_SYMBOL(dwc_cc_change);
1249 EXPORT_SYMBOL(dwc_cc_data_for_save);
1250 EXPORT_SYMBOL(dwc_cc_restore_from_data);
1251 EXPORT_SYMBOL(dwc_cc_match_chid);
1252 EXPORT_SYMBOL(dwc_cc_match_cdid);
1253 EXPORT_SYMBOL(dwc_cc_ck);
1254 EXPORT_SYMBOL(dwc_cc_chid);
1255 EXPORT_SYMBOL(dwc_cc_cdid);
1256 EXPORT_SYMBOL(dwc_cc_name);
1257 #endif  /* DWC_CCLIB */
1258
1259 #ifdef DWC_CRYPTOLIB
1260 # ifndef CONFIG_MACH_IPMATE
1261 /* Modpow */
1262 EXPORT_SYMBOL(dwc_modpow);
1263
1264 /* DH */
1265 EXPORT_SYMBOL(dwc_dh_modpow);
1266 EXPORT_SYMBOL(dwc_dh_derive_keys);
1267 EXPORT_SYMBOL(dwc_dh_pk);
1268 # endif /* CONFIG_MACH_IPMATE */
1269
1270 /* Crypto */
1271 EXPORT_SYMBOL(dwc_wusb_aes_encrypt);
1272 EXPORT_SYMBOL(dwc_wusb_cmf);
1273 EXPORT_SYMBOL(dwc_wusb_prf);
1274 EXPORT_SYMBOL(dwc_wusb_fill_ccm_nonce);
1275 EXPORT_SYMBOL(dwc_wusb_gen_nonce);
1276 EXPORT_SYMBOL(dwc_wusb_gen_key);
1277 EXPORT_SYMBOL(dwc_wusb_gen_mic);
1278 #endif  /* DWC_CRYPTOLIB */
1279
1280 /* Notification */
1281 #ifdef DWC_NOTIFYLIB
1282 EXPORT_SYMBOL(dwc_alloc_notification_manager);
1283 EXPORT_SYMBOL(dwc_free_notification_manager);
1284 EXPORT_SYMBOL(dwc_register_notifier);
1285 EXPORT_SYMBOL(dwc_unregister_notifier);
1286 EXPORT_SYMBOL(dwc_add_observer);
1287 EXPORT_SYMBOL(dwc_remove_observer);
1288 EXPORT_SYMBOL(dwc_notify);
1289 #endif
1290
1291 /* Memory Debugging Routines */
1292 #ifdef DWC_DEBUG_MEMORY
1293 EXPORT_SYMBOL(dwc_alloc_debug);
1294 EXPORT_SYMBOL(dwc_alloc_atomic_debug);
1295 EXPORT_SYMBOL(dwc_free_debug);
1296 EXPORT_SYMBOL(dwc_dma_alloc_debug);
1297 EXPORT_SYMBOL(dwc_dma_free_debug);
1298 #endif
1299
1300 EXPORT_SYMBOL(DWC_MEMSET);
1301 EXPORT_SYMBOL(DWC_MEMCPY);
1302 EXPORT_SYMBOL(DWC_MEMMOVE);
1303 EXPORT_SYMBOL(DWC_MEMCMP);
1304 EXPORT_SYMBOL(DWC_STRNCMP);
1305 EXPORT_SYMBOL(DWC_STRCMP);
1306 EXPORT_SYMBOL(DWC_STRLEN);
1307 EXPORT_SYMBOL(DWC_STRCPY);
1308 EXPORT_SYMBOL(DWC_STRDUP);
1309 EXPORT_SYMBOL(DWC_ATOI);
1310 EXPORT_SYMBOL(DWC_ATOUI);
1311
1312 #ifdef DWC_UTFLIB
1313 EXPORT_SYMBOL(DWC_UTF8_TO_UTF16LE);
1314 #endif  /* DWC_UTFLIB */
1315
1316 EXPORT_SYMBOL(DWC_IN_IRQ);
1317 EXPORT_SYMBOL(DWC_IN_BH);
1318 EXPORT_SYMBOL(DWC_VPRINTF);
1319 EXPORT_SYMBOL(DWC_VSNPRINTF);
1320 EXPORT_SYMBOL(DWC_PRINTF);
1321 EXPORT_SYMBOL(DWC_SPRINTF);
1322 EXPORT_SYMBOL(DWC_SNPRINTF);
1323 EXPORT_SYMBOL(__DWC_WARN);
1324 EXPORT_SYMBOL(__DWC_ERROR);
1325 EXPORT_SYMBOL(DWC_EXCEPTION);
1326
1327 #ifdef DEBUG
1328 EXPORT_SYMBOL(__DWC_DEBUG);
1329 #endif
1330
1331 EXPORT_SYMBOL(__DWC_DMA_ALLOC);
1332 EXPORT_SYMBOL(__DWC_DMA_ALLOC_ATOMIC);
1333 EXPORT_SYMBOL(__DWC_DMA_FREE);
1334 EXPORT_SYMBOL(__DWC_ALLOC);
1335 EXPORT_SYMBOL(__DWC_ALLOC_ATOMIC);
1336 EXPORT_SYMBOL(__DWC_FREE);
1337
1338 #ifdef DWC_CRYPTOLIB
1339 EXPORT_SYMBOL(DWC_RANDOM_BYTES);
1340 EXPORT_SYMBOL(DWC_AES_CBC);
1341 EXPORT_SYMBOL(DWC_SHA256);
1342 EXPORT_SYMBOL(DWC_HMAC_SHA256);
1343 #endif
1344
1345 EXPORT_SYMBOL(DWC_CPU_TO_LE32);
1346 EXPORT_SYMBOL(DWC_CPU_TO_BE32);
1347 EXPORT_SYMBOL(DWC_LE32_TO_CPU);
1348 EXPORT_SYMBOL(DWC_BE32_TO_CPU);
1349 EXPORT_SYMBOL(DWC_CPU_TO_LE16);
1350 EXPORT_SYMBOL(DWC_CPU_TO_BE16);
1351 EXPORT_SYMBOL(DWC_LE16_TO_CPU);
1352 EXPORT_SYMBOL(DWC_BE16_TO_CPU);
1353 EXPORT_SYMBOL(DWC_READ_REG32);
1354 EXPORT_SYMBOL(DWC_WRITE_REG32);
1355 EXPORT_SYMBOL(DWC_MODIFY_REG32);
1356
1357 #if 0
1358 EXPORT_SYMBOL(DWC_READ_REG64);
1359 EXPORT_SYMBOL(DWC_WRITE_REG64);
1360 EXPORT_SYMBOL(DWC_MODIFY_REG64);
1361 #endif
1362
1363 EXPORT_SYMBOL(DWC_SPINLOCK_ALLOC);
1364 EXPORT_SYMBOL(DWC_SPINLOCK_FREE);
1365 EXPORT_SYMBOL(DWC_SPINLOCK);
1366 EXPORT_SYMBOL(DWC_SPINUNLOCK);
1367 EXPORT_SYMBOL(DWC_SPINLOCK_IRQSAVE);
1368 EXPORT_SYMBOL(DWC_SPINUNLOCK_IRQRESTORE);
1369 EXPORT_SYMBOL(DWC_MUTEX_ALLOC);
1370
1371 #if (!defined(DWC_LINUX) || !defined(CONFIG_DEBUG_MUTEXES))
1372 EXPORT_SYMBOL(DWC_MUTEX_FREE);
1373 #endif
1374
1375 EXPORT_SYMBOL(DWC_MUTEX_LOCK);
1376 EXPORT_SYMBOL(DWC_MUTEX_TRYLOCK);
1377 EXPORT_SYMBOL(DWC_MUTEX_UNLOCK);
1378 EXPORT_SYMBOL(DWC_UDELAY);
1379 EXPORT_SYMBOL(DWC_MDELAY);
1380 EXPORT_SYMBOL(DWC_MSLEEP);
1381 EXPORT_SYMBOL(DWC_TIME);
1382 EXPORT_SYMBOL(DWC_TIMER_ALLOC);
1383 EXPORT_SYMBOL(DWC_TIMER_FREE);
1384 EXPORT_SYMBOL(DWC_TIMER_SCHEDULE);
1385 EXPORT_SYMBOL(DWC_TIMER_CANCEL);
1386 EXPORT_SYMBOL(DWC_WAITQ_ALLOC);
1387 EXPORT_SYMBOL(DWC_WAITQ_FREE);
1388 EXPORT_SYMBOL(DWC_WAITQ_WAIT);
1389 EXPORT_SYMBOL(DWC_WAITQ_WAIT_TIMEOUT);
1390 EXPORT_SYMBOL(DWC_WAITQ_TRIGGER);
1391 EXPORT_SYMBOL(DWC_WAITQ_ABORT);
1392 EXPORT_SYMBOL(DWC_THREAD_RUN);
1393 EXPORT_SYMBOL(DWC_THREAD_STOP);
1394 EXPORT_SYMBOL(DWC_THREAD_SHOULD_STOP);
1395 EXPORT_SYMBOL(DWC_TASK_ALLOC);
1396 EXPORT_SYMBOL(DWC_TASK_FREE);
1397 EXPORT_SYMBOL(DWC_TASK_SCHEDULE);
1398 EXPORT_SYMBOL(DWC_WORKQ_WAIT_WORK_DONE);
1399 EXPORT_SYMBOL(DWC_WORKQ_ALLOC);
1400 EXPORT_SYMBOL(DWC_WORKQ_FREE);
1401 EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE);
1402 EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE_DELAYED);
1403 EXPORT_SYMBOL(DWC_WORKQ_PENDING);
1404
1405 static int dwc_common_port_init_module(void)
1406 {
1407         int result = 0;
1408
1409         printk(KERN_DEBUG "Module dwc_common_port init\n");
1410
1411 #ifdef DWC_DEBUG_MEMORY
1412         result = dwc_memory_debug_start(NULL);
1413         if (result) {
1414                 printk(KERN_ERR
1415                        "dwc_memory_debug_start() failed with error %d\n",
1416                        result);
1417                 return result;
1418         }
1419 #endif
1420
1421 #ifdef DWC_NOTIFYLIB
1422         result = dwc_alloc_notification_manager(NULL, NULL);
1423         if (result) {
1424                 printk(KERN_ERR
1425                        "dwc_alloc_notification_manager() failed with error %d\n",
1426                        result);
1427                 return result;
1428         }
1429 #endif
1430         return result;
1431 }
1432
1433 static void dwc_common_port_exit_module(void)
1434 {
1435         printk(KERN_DEBUG "Module dwc_common_port exit\n");
1436
1437 #ifdef DWC_NOTIFYLIB
1438         dwc_free_notification_manager();
1439 #endif
1440
1441 #ifdef DWC_DEBUG_MEMORY
1442         dwc_memory_debug_stop();
1443 #endif
1444 }
1445
1446 module_init(dwc_common_port_init_module);
1447 module_exit(dwc_common_port_exit_module);
1448
1449 MODULE_DESCRIPTION("DWC Common Library - Portable version");
1450 MODULE_AUTHOR("Synopsys Inc.");
1451 MODULE_LICENSE ("GPL");
1452
1453 #endif  /* DWC_LIBMODULE */