rtc: tps80031: register as mfd sub device
[linux-2.6.git] / arch / arm / mach-tegra / iovmm.c
1 /*
2  * arch/arm/mach-tegra/iovmm.c
3  *
4  * Tegra I/O VM manager
5  *
6  * Copyright (c) 2010-2012, NVIDIA Corporation.
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, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/proc_fs.h>
26 #include <linux/sched.h>
27 #include <linux/string.h>
28 #include <linux/slab.h>
29 #include <linux/syscore_ops.h>
30
31 #include <mach/iovmm.h>
32
33 /*
34  * after the best-fit block is located, the remaining pages not needed
35  * for the allocation will be split into a new free block if the
36  * number of remaining pages is >= MIN_SPLIT_PAGE.
37  */
38 #define MIN_SPLIT_PAGE          4
39 #define MIN_SPLIT_BYTES(_d)     (MIN_SPLIT_PAGE << (_d)->dev->pgsize_bits)
40 #define NO_SPLIT(m)             ((m) < MIN_SPLIT_BYTES(domain))
41 #define DO_SPLIT(m)             ((m) >= MIN_SPLIT_BYTES(domain))
42
43 #define iovmm_start(_b)         ((_b)->vm_area.iovm_start)
44 #define iovmm_length(_b)        ((_b)->vm_area.iovm_length)
45 #define iovmm_end(_b)           (iovmm_start(_b) + iovmm_length(_b))
46
47 /* flags for the block */
48 #define BK_FREE         0 /* indicates free mappings */
49 #define BK_MAP_DIRTY    1 /* used by demand-loaded mappings */
50
51 /* flags for the client */
52 #define CL_LOCKED       0
53
54 /* flags for the domain */
55 #define DM_MAP_DIRTY    0
56
57 struct tegra_iovmm_block {
58         struct tegra_iovmm_area vm_area;
59         tegra_iovmm_addr_t      start;
60         size_t                  length;
61         atomic_t                ref;
62         unsigned long           flags;
63         unsigned long           poison;
64         struct rb_node          free_node;
65         struct rb_node          all_node;
66 };
67
68 struct iovmm_share_group {
69         const char                      *name;
70         struct tegra_iovmm_domain       *domain;
71         struct list_head                client_list;
72         struct list_head                group_list;
73         spinlock_t                      lock; /* for client_list */
74 };
75
76 static LIST_HEAD(iovmm_devices);
77 static LIST_HEAD(iovmm_groups);
78 static DEFINE_MUTEX(iovmm_group_list_lock);
79 static struct kmem_cache *iovmm_cache;
80
81 #define SIMALIGN(b, a)  (((b)->start % (a)) ? ((a) - ((b)->start % (a))) : 0)
82
83 size_t tegra_iovmm_get_max_free(struct tegra_iovmm_client *client)
84 {
85         struct rb_node *n;
86         struct tegra_iovmm_block *b;
87         struct tegra_iovmm_domain *domain = client->domain;
88         tegra_iovmm_addr_t max_free = 0;
89
90         spin_lock(&domain->block_lock);
91         n = rb_first(&domain->all_blocks);
92         while (n) {
93                 b = rb_entry(n, struct tegra_iovmm_block, all_node);
94                 n = rb_next(n);
95                 if (test_bit(BK_FREE, &b->flags)) {
96                         max_free = max_t(tegra_iovmm_addr_t,
97                                 max_free, iovmm_length(b));
98                 }
99         }
100         spin_unlock(&domain->block_lock);
101         return max_free;
102 }
103
104
105 static void tegra_iovmm_block_stats(struct tegra_iovmm_domain *domain,
106         unsigned int *num_blocks, unsigned int *num_free,
107         tegra_iovmm_addr_t *total, size_t *total_free, size_t *max_free)
108 {
109         struct rb_node *n;
110         struct tegra_iovmm_block *b;
111
112         *num_blocks = 0;
113         *num_free = 0;
114         *total = 0;
115         *total_free = 0;
116         *max_free = 0;
117
118         spin_lock(&domain->block_lock);
119         n = rb_first(&domain->all_blocks);
120         while (n) {
121                 b = rb_entry(n, struct tegra_iovmm_block, all_node);
122                 n = rb_next(n);
123                 (*num_blocks)++;
124                 *total += b->length;
125                 if (test_bit(BK_FREE, &b->flags)) {
126                         (*num_free)++;
127                         *total_free += b->length;
128                         *max_free = max_t(size_t, *max_free, b->length);
129                 }
130         }
131         spin_unlock(&domain->block_lock);
132 }
133
134 static int tegra_iovmm_read_proc(char *page, char **start, off_t off,
135         int count, int *eof, void *data)
136 {
137         struct iovmm_share_group *grp;
138         size_t max_free, total_free, total;
139         unsigned int num, num_free;
140
141         int len = 0;
142
143         mutex_lock(&iovmm_group_list_lock);
144         len += snprintf(page + len, count - len, "\ngroups\n");
145         if (list_empty(&iovmm_groups))
146                 len += snprintf(page + len, count - len, "\t<empty>\n");
147         else {
148                 list_for_each_entry(grp, &iovmm_groups, group_list) {
149                         len += snprintf(page + len, count - len,
150                                 "\t%s (device: %s)\n",
151                                 grp->name ? grp->name : "<unnamed>",
152                                 grp->domain->dev->name);
153                         tegra_iovmm_block_stats(grp->domain, &num,
154                                 &num_free, &total, &total_free, &max_free);
155                         total >>= 10;
156                         total_free >>= 10;
157                         max_free >>= 10;
158                         len += snprintf(page + len, count - len,
159                                 "\t\tsize: %uKiB free: %uKiB "
160                                 "largest: %uKiB (%u free / %u total blocks)\n",
161                                 total, total_free, max_free, num_free, num);
162                 }
163         }
164         mutex_unlock(&iovmm_group_list_lock);
165
166         *eof = 1;
167         return len;
168 }
169
170 static void iovmm_block_put(struct tegra_iovmm_block *b)
171 {
172         BUG_ON(b->poison);
173         BUG_ON(atomic_read(&b->ref) == 0);
174         if (!atomic_dec_return(&b->ref)) {
175                 b->poison = 0xa5a5a5a5;
176                 kmem_cache_free(iovmm_cache, b);
177         }
178 }
179
180 static void iovmm_free_block(struct tegra_iovmm_domain *domain,
181         struct tegra_iovmm_block *block)
182 {
183         struct tegra_iovmm_block *pred = NULL; /* address-order predecessor */
184         struct tegra_iovmm_block *succ = NULL; /* address-order successor */
185         struct rb_node **p;
186         struct rb_node *parent = NULL, *temp;
187         int pred_free = 0, succ_free = 0;
188
189         iovmm_block_put(block);
190
191         spin_lock(&domain->block_lock);
192         temp = rb_prev(&block->all_node);
193         if (temp)
194                 pred = rb_entry(temp, struct tegra_iovmm_block, all_node);
195         temp = rb_next(&block->all_node);
196         if (temp)
197                 succ = rb_entry(temp, struct tegra_iovmm_block, all_node);
198
199         if (pred)
200                 pred_free = test_bit(BK_FREE, &pred->flags);
201         if (succ)
202                 succ_free = test_bit(BK_FREE, &succ->flags);
203
204         if (pred_free && succ_free) {
205                 pred->length += block->length;
206                 pred->length += succ->length;
207                 rb_erase(&block->all_node, &domain->all_blocks);
208                 rb_erase(&succ->all_node, &domain->all_blocks);
209                 rb_erase(&succ->free_node, &domain->free_blocks);
210                 rb_erase(&pred->free_node, &domain->free_blocks);
211                 iovmm_block_put(block);
212                 iovmm_block_put(succ);
213                 block = pred;
214         } else if (pred_free) {
215                 pred->length += block->length;
216                 rb_erase(&block->all_node, &domain->all_blocks);
217                 rb_erase(&pred->free_node, &domain->free_blocks);
218                 iovmm_block_put(block);
219                 block = pred;
220         } else if (succ_free) {
221                 block->length += succ->length;
222                 rb_erase(&succ->all_node, &domain->all_blocks);
223                 rb_erase(&succ->free_node, &domain->free_blocks);
224                 iovmm_block_put(succ);
225         }
226
227         p = &domain->free_blocks.rb_node;
228         while (*p) {
229                 struct tegra_iovmm_block *b;
230                 parent = *p;
231                 b = rb_entry(parent, struct tegra_iovmm_block, free_node);
232                 if (block->length >= b->length)
233                         p = &parent->rb_right;
234                 else
235                         p = &parent->rb_left;
236         }
237         rb_link_node(&block->free_node, parent, p);
238         rb_insert_color(&block->free_node, &domain->free_blocks);
239         set_bit(BK_FREE, &block->flags);
240         spin_unlock(&domain->block_lock);
241 }
242
243 /*
244  * if the best-fit block is larger than the requested size, a remainder
245  * block will be created and inserted into the free list in its place.
246  * since all free blocks are stored in two trees the new block needs to be
247  * linked into both.
248  */
249 static struct tegra_iovmm_block *iovmm_split_free_block(
250         struct tegra_iovmm_domain *domain,
251         struct tegra_iovmm_block *block, unsigned long size)
252 {
253         struct rb_node **p;
254         struct rb_node *parent = NULL;
255         struct tegra_iovmm_block *rem;
256         struct tegra_iovmm_block *b;
257
258         rem = kmem_cache_zalloc(iovmm_cache, GFP_KERNEL);
259         if (!rem)
260                 return NULL;
261
262         spin_lock(&domain->block_lock);
263         p = &domain->free_blocks.rb_node;
264
265         rem->start  = block->start + size;
266         rem->length = block->length - size;
267         atomic_set(&rem->ref, 1);
268         block->length = size;
269
270         while (*p) {
271                 parent = *p;
272                 b = rb_entry(parent, struct tegra_iovmm_block, free_node);
273                 if (rem->length >= b->length)
274                         p = &parent->rb_right;
275                 else
276                         p = &parent->rb_left;
277         }
278         set_bit(BK_FREE, &rem->flags);
279         rb_link_node(&rem->free_node, parent, p);
280         rb_insert_color(&rem->free_node, &domain->free_blocks);
281
282         p = &domain->all_blocks.rb_node;
283         parent = NULL;
284         while (*p) {
285                 parent = *p;
286                 b = rb_entry(parent, struct tegra_iovmm_block, all_node);
287                 if (rem->start >= b->start)
288                         p = &parent->rb_right;
289                 else
290                         p = &parent->rb_left;
291         }
292         rb_link_node(&rem->all_node, parent, p);
293         rb_insert_color(&rem->all_node, &domain->all_blocks);
294
295         return rem;
296 }
297
298 static int iovmm_block_splitting;
299 static struct tegra_iovmm_block *iovmm_alloc_block(
300         struct tegra_iovmm_domain *domain, size_t size, size_t align)
301 {
302         struct rb_node *n;
303         struct tegra_iovmm_block *b, *best;
304         size_t simalign;
305         unsigned long page_size = 1 << domain->dev->pgsize_bits;
306
307         BUG_ON(!size);
308
309         size = round_up(size, page_size);
310         align = round_up(align, page_size);
311         for (;;) {
312                 spin_lock(&domain->block_lock);
313                 if (!iovmm_block_splitting)
314                         break;
315                 spin_unlock(&domain->block_lock);
316                 schedule();
317         }
318         n = domain->free_blocks.rb_node;
319         best = NULL;
320         while (n) {
321                 tegra_iovmm_addr_t aligned_start, block_ceil;
322
323                 b = rb_entry(n, struct tegra_iovmm_block, free_node);
324                 simalign = SIMALIGN(b, align);
325                 aligned_start = b->start + simalign;
326                 block_ceil = b->start + b->length;
327
328                 if (block_ceil >= aligned_start + size) {
329                         /* Block has enough size */
330                         best = b;
331                         if (NO_SPLIT(simalign) &&
332                                 NO_SPLIT(block_ceil - (aligned_start + size)))
333                                 break;
334                         n = n->rb_left;
335                 } else {
336                         n = n->rb_right;
337                 }
338         }
339         if (!best) {
340                 spin_unlock(&domain->block_lock);
341                 return NULL;
342         }
343
344         simalign = SIMALIGN(best, align);
345         if (DO_SPLIT(simalign)) {
346                 iovmm_block_splitting = 1;
347                 spin_unlock(&domain->block_lock);
348
349                 /* Split off misalignment */
350                 b = best;
351                 best = iovmm_split_free_block(domain, b, simalign);
352                 if (best)
353                         simalign = 0;
354                 else
355                         best = b;
356         }
357
358         /* Unfree designed block */
359         rb_erase(&best->free_node, &domain->free_blocks);
360         clear_bit(BK_FREE, &best->flags);
361         atomic_inc(&best->ref);
362
363         iovmm_start(best) = best->start + simalign;
364         iovmm_length(best) = size;
365
366         if (DO_SPLIT((best->start + best->length) - iovmm_end(best))) {
367                 iovmm_block_splitting = 1;
368                 spin_unlock(&domain->block_lock);
369
370                 /* Split off excess */
371                 (void)iovmm_split_free_block(domain, best, size + simalign);
372         }
373
374         iovmm_block_splitting = 0;
375         spin_unlock(&domain->block_lock);
376
377         return best;
378 }
379
380 static struct tegra_iovmm_block *iovmm_allocate_vm(
381         struct tegra_iovmm_domain *domain, size_t size,
382         size_t align, unsigned long iovm_start)
383 {
384         struct rb_node *n;
385         struct tegra_iovmm_block *b, *best;
386         unsigned long page_size = 1 << domain->dev->pgsize_bits;
387
388         BUG_ON(iovm_start % align);
389         BUG_ON(!size);
390
391         size = round_up(size, page_size);
392         for (;;) {
393                 spin_lock(&domain->block_lock);
394                 if (!iovmm_block_splitting)
395                         break;
396                 spin_unlock(&domain->block_lock);
397                 schedule();
398         }
399
400         n = rb_first(&domain->free_blocks);
401         best = NULL;
402         while (n) {
403                 b = rb_entry(n, struct tegra_iovmm_block, free_node);
404                 if ((b->start <= iovm_start) &&
405                      (b->start + b->length) >= (iovm_start + size)) {
406                         best = b;
407                         break;
408                 }
409                 n = rb_next(n);
410         }
411
412         if (!best)
413                 goto fail;
414
415         /* split the mem before iovm_start. */
416         if (DO_SPLIT(iovm_start - best->start)) {
417                 iovmm_block_splitting = 1;
418                 spin_unlock(&domain->block_lock);
419                 best = iovmm_split_free_block(domain, best,
420                         (iovm_start - best->start));
421         }
422         if (!best)
423                 goto fail;
424
425         /* remove the desired block from free list. */
426         rb_erase(&best->free_node, &domain->free_blocks);
427         clear_bit(BK_FREE, &best->flags);
428         atomic_inc(&best->ref);
429
430         iovmm_start(best) = iovm_start;
431         iovmm_length(best) = size;
432
433         BUG_ON(best->start > iovmm_start(best));
434         BUG_ON((best->start + best->length) < iovmm_end(best));
435         /* split the mem after iovm_start+size. */
436         if (DO_SPLIT(best->start + best->length - iovmm_end(best))) {
437                 iovmm_block_splitting = 1;
438                 spin_unlock(&domain->block_lock);
439                 (void)iovmm_split_free_block(domain, best,
440                         (iovmm_start(best) - best->start + size));
441         }
442 fail:
443         iovmm_block_splitting = 0;
444         spin_unlock(&domain->block_lock);
445         return best;
446 }
447
448 int tegra_iovmm_domain_init(struct tegra_iovmm_domain *domain,
449         struct tegra_iovmm_device *dev, tegra_iovmm_addr_t start,
450         tegra_iovmm_addr_t end)
451 {
452         struct tegra_iovmm_block *b;
453         unsigned long page_size = 1 << dev->pgsize_bits;
454
455         b = kmem_cache_zalloc(iovmm_cache, GFP_KERNEL);
456         if (!b)
457                 return -ENOMEM;
458
459         domain->dev = dev;
460
461         atomic_set(&domain->clients, 0);
462         atomic_set(&domain->locks, 0);
463         atomic_set(&b->ref, 1);
464         spin_lock_init(&domain->block_lock);
465         init_rwsem(&domain->map_lock);
466         init_waitqueue_head(&domain->delay_lock);
467
468         b->start  = round_up(start, page_size);
469         b->length = round_down(end, page_size) - b->start;
470
471         set_bit(BK_FREE, &b->flags);
472         rb_link_node(&b->free_node, NULL, &domain->free_blocks.rb_node);
473         rb_insert_color(&b->free_node, &domain->free_blocks);
474         rb_link_node(&b->all_node, NULL, &domain->all_blocks.rb_node);
475         rb_insert_color(&b->all_node, &domain->all_blocks);
476
477         return 0;
478 }
479
480 /*
481  * If iovm_start != 0, tries to allocate specified iova block if it is
482  * free. if it is not free, it fails.
483  */
484 struct tegra_iovmm_area *tegra_iovmm_create_vm(
485         struct tegra_iovmm_client *client, struct tegra_iovmm_area_ops *ops,
486         size_t size, size_t align, pgprot_t pgprot, unsigned long iovm_start)
487 {
488         struct tegra_iovmm_block *b;
489         struct tegra_iovmm_domain *domain;
490
491         if (!client)
492                 return NULL;
493
494         domain = client->domain;
495
496         if (iovm_start)
497                 b = iovmm_allocate_vm(domain, size, align, iovm_start);
498         else
499                 b = iovmm_alloc_block(domain, size, align);
500         if (!b)
501                 return NULL;
502
503         b->vm_area.domain = domain;
504         b->vm_area.pgprot = pgprot;
505         b->vm_area.ops = ops;
506
507         down_read(&b->vm_area.domain->map_lock);
508         if (ops && !test_bit(CL_LOCKED, &client->flags)) {
509                 set_bit(BK_MAP_DIRTY, &b->flags);
510                 set_bit(DM_MAP_DIRTY, &client->domain->flags);
511         } else if (ops) {
512                 if (domain->dev->ops->map(domain, &b->vm_area))
513                         pr_err("%s failed to map locked domain\n", __func__);
514         }
515         up_read(&b->vm_area.domain->map_lock);
516
517         return &b->vm_area;
518 }
519
520 void tegra_iovmm_vm_insert_pfn(struct tegra_iovmm_area *vm,
521         tegra_iovmm_addr_t vaddr, unsigned long pfn)
522 {
523         struct tegra_iovmm_domain *domain = vm->domain;
524
525         BUG_ON(vaddr & ((1 << domain->dev->pgsize_bits) - 1));
526         BUG_ON(vaddr >= vm->iovm_start + vm->iovm_length);
527         BUG_ON(vaddr < vm->iovm_start);
528         BUG_ON(vm->ops);
529
530         domain->dev->ops->map_pfn(domain, vm, vaddr, pfn);
531 }
532
533 void tegra_iovmm_zap_vm(struct tegra_iovmm_area *vm)
534 {
535         struct tegra_iovmm_block *b;
536         struct tegra_iovmm_domain *domain;
537
538         b = container_of(vm, struct tegra_iovmm_block, vm_area);
539         domain = vm->domain;
540         /*
541          * if the vm area mapping was deferred, don't unmap it since
542          * the memory for the page tables it uses may not be allocated
543          */
544         down_read(&domain->map_lock);
545         if (!test_and_clear_bit(BK_MAP_DIRTY, &b->flags))
546                 domain->dev->ops->unmap(domain, vm, false);
547         up_read(&domain->map_lock);
548 }
549
550 void tegra_iovmm_unzap_vm(struct tegra_iovmm_area *vm)
551 {
552         struct tegra_iovmm_block *b;
553         struct tegra_iovmm_domain *domain;
554
555         b = container_of(vm, struct tegra_iovmm_block, vm_area);
556         domain = vm->domain;
557         if (!vm->ops)
558                 return;
559
560         down_read(&domain->map_lock);
561         if (vm->ops) {
562                 if (atomic_read(&domain->locks))
563                         domain->dev->ops->map(domain, vm);
564                 else {
565                         set_bit(BK_MAP_DIRTY, &b->flags);
566                         set_bit(DM_MAP_DIRTY, &domain->flags);
567                 }
568         }
569         up_read(&domain->map_lock);
570 }
571
572 void tegra_iovmm_free_vm(struct tegra_iovmm_area *vm)
573 {
574         struct tegra_iovmm_block *b;
575         struct tegra_iovmm_domain *domain;
576
577         if (!vm)
578                 return;
579
580         b = container_of(vm, struct tegra_iovmm_block, vm_area);
581         domain = vm->domain;
582         down_read(&domain->map_lock);
583         if (!test_and_clear_bit(BK_MAP_DIRTY, &b->flags))
584                 domain->dev->ops->unmap(domain, vm, true);
585         iovmm_free_block(domain, b);
586         up_read(&domain->map_lock);
587 }
588
589 struct tegra_iovmm_area *tegra_iovmm_area_get(struct tegra_iovmm_area *vm)
590 {
591         struct tegra_iovmm_block *b;
592
593         BUG_ON(!vm);
594         b = container_of(vm, struct tegra_iovmm_block, vm_area);
595
596         atomic_inc(&b->ref);
597         return &b->vm_area;
598 }
599
600 void tegra_iovmm_area_put(struct tegra_iovmm_area *vm)
601 {
602         struct tegra_iovmm_block *b;
603         BUG_ON(!vm);
604         b = container_of(vm, struct tegra_iovmm_block, vm_area);
605         iovmm_block_put(b);
606 }
607
608 struct tegra_iovmm_area *tegra_iovmm_find_area_get(
609         struct tegra_iovmm_client *client, tegra_iovmm_addr_t addr)
610 {
611         struct rb_node *n;
612         struct tegra_iovmm_block *b = NULL;
613
614         if (!client)
615                 return NULL;
616
617         spin_lock(&client->domain->block_lock);
618         n = client->domain->all_blocks.rb_node;
619
620         while (n) {
621                 b = rb_entry(n, struct tegra_iovmm_block, all_node);
622                 if (iovmm_start(b) <= addr && addr <= iovmm_end(b)) {
623                         if (test_bit(BK_FREE, &b->flags))
624                                 b = NULL;
625                         break;
626                 }
627                 if (addr > iovmm_start(b))
628                         n = n->rb_right;
629                 else
630                         n = n->rb_left;
631                 b = NULL;
632         }
633         if (b)
634                 atomic_inc(&b->ref);
635         spin_unlock(&client->domain->block_lock);
636         if (!b)
637                 return NULL;
638         return &b->vm_area;
639 }
640
641 static int _iovmm_client_lock(struct tegra_iovmm_client *client)
642 {
643         struct tegra_iovmm_device *dev;
644         struct tegra_iovmm_domain *domain;
645         int v;
646
647         if (unlikely(!client))
648                 return -ENODEV;
649
650         if (unlikely(test_bit(CL_LOCKED, &client->flags))) {
651                 pr_err("attempting to relock client %s\n", client->name);
652                 return 0;
653         }
654
655         domain = client->domain;
656         dev = domain->dev;
657         down_write(&domain->map_lock);
658         v = atomic_inc_return(&domain->locks);
659         /*
660          * if the device doesn't export the lock_domain function, the
661          * device must guarantee that any valid domain will be locked.
662          */
663         if (v == 1 && dev->ops->lock_domain) {
664                 if (dev->ops->lock_domain(domain, client)) {
665                         atomic_dec(&domain->locks);
666                         up_write(&domain->map_lock);
667                         return -EAGAIN;
668                 }
669         }
670         if (test_and_clear_bit(DM_MAP_DIRTY, &domain->flags)) {
671                 struct rb_node *n;
672                 struct tegra_iovmm_block *b;
673
674                 spin_lock(&domain->block_lock);
675                 n = rb_first(&domain->all_blocks);
676                 while (n) {
677                         b = rb_entry(n, struct tegra_iovmm_block, all_node);
678                         n = rb_next(n);
679                         if (test_bit(BK_FREE, &b->flags))
680                                 continue;
681
682                         if (test_and_clear_bit(BK_MAP_DIRTY, &b->flags)) {
683                                 if (!b->vm_area.ops) {
684                                         pr_err("%s: "
685                                                "vm_area ops must exist for lazy maps\n",
686                                                __func__);
687                                         continue;
688                                 }
689                                 dev->ops->map(domain, &b->vm_area);
690                         }
691                 }
692         }
693         set_bit(CL_LOCKED, &client->flags);
694         up_write(&domain->map_lock);
695         return 0;
696 }
697
698 int tegra_iovmm_client_trylock(struct tegra_iovmm_client *client)
699 {
700         return _iovmm_client_lock(client);
701 }
702
703 int tegra_iovmm_client_lock(struct tegra_iovmm_client *client)
704 {
705         int ret;
706
707         if (!client)
708                 return -ENODEV;
709
710         ret = wait_event_interruptible(client->domain->delay_lock,
711                 _iovmm_client_lock(client) != -EAGAIN);
712
713         if (ret == -ERESTARTSYS)
714                 return -EINTR;
715
716         return ret;
717 }
718
719 void tegra_iovmm_client_unlock(struct tegra_iovmm_client *client)
720 {
721         struct tegra_iovmm_device *dev;
722         struct tegra_iovmm_domain *domain;
723         int do_wake = 0;
724
725         if (!client)
726                 return;
727
728         if (!test_and_clear_bit(CL_LOCKED, &client->flags)) {
729                 pr_err("unlocking unlocked client %s\n", client->name);
730                 return;
731         }
732
733         domain = client->domain;
734         dev = domain->dev;
735         down_write(&domain->map_lock);
736         if (!atomic_dec_return(&domain->locks)) {
737                 if (dev->ops->unlock_domain)
738                         dev->ops->unlock_domain(domain, client);
739                 do_wake = 1;
740         }
741         up_write(&domain->map_lock);
742         if (do_wake)
743                 wake_up(&domain->delay_lock);
744 }
745
746 size_t tegra_iovmm_get_vm_size(struct tegra_iovmm_client *client)
747 {
748         struct tegra_iovmm_domain *domain;
749         struct rb_node *n;
750         struct tegra_iovmm_block *b;
751         size_t size = 0;
752
753         if (!client)
754                 return 0;
755
756         domain = client->domain;
757
758         spin_lock(&domain->block_lock);
759         n = rb_first(&domain->all_blocks);
760         while (n) {
761                 b = rb_entry(n, struct tegra_iovmm_block, all_node);
762                 n = rb_next(n);
763                 size += b->length;
764         }
765         spin_unlock(&domain->block_lock);
766
767         return size;
768 }
769
770 void tegra_iovmm_free_client(struct tegra_iovmm_client *client)
771 {
772         struct tegra_iovmm_device *dev;
773         struct tegra_iovmm_domain *domain;
774
775         if (!client)
776                 return;
777
778         BUG_ON(!client->domain || !client->domain->dev);
779
780         domain = client->domain;
781         dev = domain->dev;
782
783         if (test_and_clear_bit(CL_LOCKED, &client->flags)) {
784                 pr_err("freeing locked client %s\n", client->name);
785                 if (!atomic_dec_return(&domain->locks)) {
786                         down_write(&domain->map_lock);
787                         if (dev->ops->unlock_domain)
788                                 dev->ops->unlock_domain(domain, client);
789                         up_write(&domain->map_lock);
790                         wake_up(&domain->delay_lock);
791                 }
792         }
793         mutex_lock(&iovmm_group_list_lock);
794         if (!atomic_dec_return(&domain->clients))
795                 if (dev->ops->free_domain)
796                         dev->ops->free_domain(domain, client);
797         list_del(&client->list);
798         if (list_empty(&client->group->client_list)) {
799                 list_del(&client->group->group_list);
800                 kfree(client->group->name);
801                 kfree(client->group);
802         }
803         kfree(client->name);
804         kfree(client);
805         mutex_unlock(&iovmm_group_list_lock);
806 }
807
808 struct tegra_iovmm_client *__tegra_iovmm_alloc_client(const char *name,
809         const char *share_group, struct miscdevice *misc_dev)
810 {
811         struct tegra_iovmm_client *c = kzalloc(sizeof(*c), GFP_KERNEL);
812         struct iovmm_share_group *grp = NULL;
813         struct tegra_iovmm_device *dev;
814
815         if (!c)
816                 return NULL;
817         c->name = kstrdup(name, GFP_KERNEL);
818         if (!c->name)
819                 goto fail;
820         c->misc_dev = misc_dev;
821
822         mutex_lock(&iovmm_group_list_lock);
823         if (share_group) {
824                 list_for_each_entry(grp, &iovmm_groups, group_list) {
825                         if (grp->name && !strcmp(grp->name, share_group))
826                                 break;
827                 }
828         }
829         if (!grp || strcmp(grp->name, share_group)) {
830                 grp = kzalloc(sizeof(*grp), GFP_KERNEL);
831                 if (!grp)
832                         goto fail_lock;
833                 grp->name =
834                         share_group ? kstrdup(share_group, GFP_KERNEL) : NULL;
835                 if (share_group && !grp->name) {
836                         kfree(grp);
837                         goto fail_lock;
838                 }
839                 list_for_each_entry(dev, &iovmm_devices, list) {
840                         grp->domain = dev->ops->alloc_domain(dev, c);
841                         if (grp->domain)
842                                 break;
843                 }
844                 if (!grp->domain) {
845                         pr_err("%s: alloc_domain failed for %s\n",
846                                 __func__, c->name);
847                         dump_stack();
848                         kfree(grp->name);
849                         kfree(grp);
850                         grp = NULL;
851                         goto fail_lock;
852                 }
853                 spin_lock_init(&grp->lock);
854                 INIT_LIST_HEAD(&grp->client_list);
855                 list_add_tail(&grp->group_list, &iovmm_groups);
856         }
857
858         atomic_inc(&grp->domain->clients);
859         c->group = grp;
860         c->domain = grp->domain;
861         spin_lock(&grp->lock);
862         list_add_tail(&c->list, &grp->client_list);
863         spin_unlock(&grp->lock);
864         mutex_unlock(&iovmm_group_list_lock);
865         return c;
866
867 fail_lock:
868         mutex_unlock(&iovmm_group_list_lock);
869 fail:
870         if (c)
871                 kfree(c->name);
872         kfree(c);
873         return NULL;
874 }
875
876 int tegra_iovmm_register(struct tegra_iovmm_device *dev)
877 {
878         BUG_ON(!dev);
879         mutex_lock(&iovmm_group_list_lock);
880         if (list_empty(&iovmm_devices)) {
881                 iovmm_cache = KMEM_CACHE(tegra_iovmm_block, 0);
882                 if (!iovmm_cache) {
883                         pr_err("%s: failed to make kmem cache\n", __func__);
884                         mutex_unlock(&iovmm_group_list_lock);
885                         return -ENOMEM;
886                 }
887                 create_proc_read_entry("iovmminfo", S_IRUGO, NULL,
888                         tegra_iovmm_read_proc, NULL);
889         }
890         list_add_tail(&dev->list, &iovmm_devices);
891         mutex_unlock(&iovmm_group_list_lock);
892         pr_info("%s: added %s\n", __func__, dev->name);
893         return 0;
894 }
895
896 int tegra_iovmm_unregister(struct tegra_iovmm_device *dev)
897 {
898         mutex_lock(&iovmm_group_list_lock);
899         list_del(&dev->list);
900         mutex_unlock(&iovmm_group_list_lock);
901         return 0;
902 }
903
904 static int tegra_iovmm_suspend(void)
905 {
906         int rc = 0;
907         struct tegra_iovmm_device *dev;
908
909         list_for_each_entry(dev, &iovmm_devices, list) {
910                 if (!dev->ops->suspend)
911                         continue;
912
913                 rc = dev->ops->suspend(dev);
914                 if (rc) {
915                         pr_err("%s: %s suspend returned %d\n",
916                                __func__, dev->name, rc);
917                         return rc;
918                 }
919         }
920         return 0;
921 }
922
923 static void tegra_iovmm_resume(void)
924 {
925         struct tegra_iovmm_device *dev;
926
927         list_for_each_entry(dev, &iovmm_devices, list) {
928                 if (dev->ops->resume)
929                         dev->ops->resume(dev);
930         }
931 }
932
933 static struct syscore_ops tegra_iovmm_syscore_ops = {
934         .suspend = tegra_iovmm_suspend,
935         .resume = tegra_iovmm_resume,
936 };
937
938 static __init int tegra_iovmm_syscore_init(void)
939 {
940         register_syscore_ops(&tegra_iovmm_syscore_ops);
941         return 0;
942 }
943 subsys_initcall(tegra_iovmm_syscore_init);