diff options
author | Lajos Molnar <molnar@ti.com> | 2010-06-29 06:23:47 -0400 |
---|---|---|
committer | Paolo Pisati <paolo.pisati@canonical.com> | 2012-08-17 04:18:57 -0400 |
commit | e47c00628ac013f55fa36f98779c6582b0a609d2 (patch) | |
tree | 8e865a05e3403ac8d23fe7607352f389bb94cda3 | |
parent | fe0ae617ff9b61bedc4f8a88289bf5b982aba2ef (diff) |
TILER: Added key-id enforcement.
TILER block lookup is now based on key & id. However, it is still
possible to look up a block's key & id based on its system space
address.
Signed-off-by: Lajos Molnar <molnar@ti.com>
TILER: Added address space support for mmap.
Now each TILER buffer occupies a range of the correct size in
TILER's mmap memory space (offset + size).
Signed-off-by: Lajos Molnar <molnar@ti.com>
TILER: Added support for partial mmaping of TILER buffers
Added support for mmapping only a portion of a TILER buffer.
Also added helper functions that can be used by other drivers that
use TILER to mmap and ioremap portions of TILER blocks.
Signed-off-by: Lajos Molnar <molnar@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/include/mach/tiler.h | 32 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler.c | 242 |
2 files changed, 212 insertions, 62 deletions
diff --git a/arch/arm/mach-omap2/include/mach/tiler.h b/arch/arm/mach-omap2/include/mach/tiler.h index 6f0757b9b24..be29f3ce3e2 100644 --- a/arch/arm/mach-omap2/include/mach/tiler.h +++ b/arch/arm/mach-omap2/include/mach/tiler.h | |||
@@ -26,6 +26,8 @@ | |||
26 | 26 | ||
27 | #define TILER_MAX_NUM_BLOCKS 16 | 27 | #define TILER_MAX_NUM_BLOCKS 16 |
28 | 28 | ||
29 | #include <linux/mm.h> | ||
30 | |||
29 | #define TILIOC_GBLK _IOWR('z', 100, struct tiler_block_info) | 31 | #define TILIOC_GBLK _IOWR('z', 100, struct tiler_block_info) |
30 | #define TILIOC_FBLK _IOW('z', 101, struct tiler_block_info) | 32 | #define TILIOC_FBLK _IOW('z', 101, struct tiler_block_info) |
31 | #define TILIOC_GSSP _IOWR('z', 102, u32) | 33 | #define TILIOC_GSSP _IOWR('z', 102, u32) |
@@ -125,6 +127,36 @@ s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align, | |||
125 | u32 offs, u32 gid, pid_t pid); | 127 | u32 offs, u32 gid, pid_t pid); |
126 | 128 | ||
127 | /** | 129 | /** |
130 | * Mmaps a portion of a tiler block to a virtual address. Use this method in | ||
131 | * your driver's mmap function to potentially combine multiple tiler blocks as | ||
132 | * one virtual buffer. | ||
133 | * | ||
134 | * @param blk pointer to tiler block data | ||
135 | * @param offs offset from where to map (must be page aligned) | ||
136 | * @param size size of area to map (must be page aligned) | ||
137 | * @param addr virtual address | ||
138 | * | ||
139 | * @return error status | ||
140 | */ | ||
141 | s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size, | ||
142 | struct vm_area_struct *vma, u32 voffs); | ||
143 | |||
144 | /** | ||
145 | * Ioremaps a portion of a tiler block. Use this method in your driver instead | ||
146 | * of ioremap to potentially combine multiple tiler blocks as one virtual | ||
147 | * buffer. | ||
148 | * | ||
149 | * @param blk pointer to tiler block data | ||
150 | * @param offs offset from where to map (must be page aligned) | ||
151 | * @param size size of area to map (must be page aligned) | ||
152 | * @param addr virtual address | ||
153 | * | ||
154 | * @return error status | ||
155 | */ | ||
156 | s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size, u32 addr, | ||
157 | u32 mtype); | ||
158 | |||
159 | /** | ||
128 | * Maps an existing buffer to a 1D or 2D TILER area for the | 160 | * Maps an existing buffer to a 1D or 2D TILER area for the |
129 | * current process with group ID 0. | 161 | * current process with group ID 0. |
130 | * | 162 | * |
diff --git a/drivers/media/video/tiler/tiler.c b/drivers/media/video/tiler/tiler.c index 0d3aa51efa8..903df67b86f 100644 --- a/drivers/media/video/tiler/tiler.c +++ b/drivers/media/video/tiler/tiler.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/pagemap.h> /* page_cache_release() */ | 32 | #include <linux/pagemap.h> /* page_cache_release() */ |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | 34 | ||
35 | #include <asm/mach/map.h> /* for ioremap_page */ | ||
35 | #include <mach/tiler.h> | 36 | #include <mach/tiler.h> |
36 | #include <mach/dmm.h> | 37 | #include <mach/dmm.h> |
37 | #include "../dmm/tmm.h" | 38 | #include "../dmm/tmm.h" |
@@ -117,7 +118,6 @@ static s32 tiler_major; | |||
117 | static s32 tiler_minor; | 118 | static s32 tiler_minor; |
118 | static struct tiler_dev *tiler_device; | 119 | static struct tiler_dev *tiler_device; |
119 | static struct class *tilerdev_class; | 120 | static struct class *tilerdev_class; |
120 | static u32 id; | ||
121 | static struct mutex mtx; | 121 | static struct mutex mtx; |
122 | static struct tcm *tcm[TILER_FORMATS]; | 122 | static struct tcm *tcm[TILER_FORMATS]; |
123 | static struct tmm *tmm[TILER_FORMATS]; | 123 | static struct tmm *tmm[TILER_FORMATS]; |
@@ -170,7 +170,6 @@ static inline u32 tiler_size(const struct tiler_block_t *b) | |||
170 | return b->height * tiler_vstride(b); | 170 | return b->height * tiler_vstride(b); |
171 | } | 171 | } |
172 | 172 | ||
173 | |||
174 | /* get process info, and increment refs for device tracking */ | 173 | /* get process info, and increment refs for device tracking */ |
175 | static struct process_info *__get_pi(pid_t pid, bool kernel) | 174 | static struct process_info *__get_pi(pid_t pid, bool kernel) |
176 | { | 175 | { |
@@ -557,6 +556,56 @@ static inline bool _m_try_free(struct mem_info *mi) | |||
557 | return _m_chk_ref(mi); | 556 | return _m_chk_ref(mi); |
558 | } | 557 | } |
559 | 558 | ||
559 | /* check if an id is used */ | ||
560 | static bool _m_id_in_use(u32 id) | ||
561 | { | ||
562 | struct mem_info *mi; | ||
563 | list_for_each_entry(mi, &blocks, global) | ||
564 | if (mi->blk.id == id) | ||
565 | return 1; | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | /* check if an offset is used */ | ||
570 | static bool _m_offs_in_use(u32 offs, u32 length, struct process_info *pi) | ||
571 | { | ||
572 | struct __buf_info *_b; | ||
573 | list_for_each_entry(_b, &pi->bufs, by_pid) | ||
574 | if (_b->buf_info.offset < offs + length && | ||
575 | _b->buf_info.offset + _b->buf_info.length > offs) | ||
576 | return 1; | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | /* get an id */ | ||
581 | static u32 _m_get_id(void) | ||
582 | { | ||
583 | static u32 id = 0x2d7ae; | ||
584 | |||
585 | /* ensure noone is using this id */ | ||
586 | while (_m_id_in_use(id)) { | ||
587 | /* Galois LSFR: 32, 22, 2, 1 */ | ||
588 | id = (id >> 1) ^ (u32)((0 - (id & 1u)) & 0x80200003u); | ||
589 | } | ||
590 | |||
591 | return id; | ||
592 | } | ||
593 | |||
594 | /* get an offset */ | ||
595 | static u32 _m_get_offs(struct process_info *pi, u32 length) | ||
596 | { | ||
597 | static u32 offs = 0xda7a; | ||
598 | |||
599 | /* ensure no-one is using this offset */ | ||
600 | while ((offs << PAGE_SHIFT) + length < length || | ||
601 | _m_offs_in_use(offs << PAGE_SHIFT, length, pi)) { | ||
602 | /* Galois LSF: 20, 17 */ | ||
603 | offs = (offs >> 1) ^ (u32)((0 - (offs & 1u)) & 0x90000); | ||
604 | } | ||
605 | |||
606 | return offs << PAGE_SHIFT; | ||
607 | } | ||
608 | |||
560 | static s32 register_buf(struct __buf_info *_b, struct process_info *pi) | 609 | static s32 register_buf(struct __buf_info *_b, struct process_info *pi) |
561 | { | 610 | { |
562 | struct mem_info *mi = NULL; | 611 | struct mem_info *mi = NULL; |
@@ -570,11 +619,13 @@ static s32 register_buf(struct __buf_info *_b, struct process_info *pi) | |||
570 | mutex_lock(&mtx); | 619 | mutex_lock(&mtx); |
571 | 620 | ||
572 | /* find each block */ | 621 | /* find each block */ |
622 | b->length = 0; | ||
573 | list_for_each_entry(mi, &blocks, global) { | 623 | list_for_each_entry(mi, &blocks, global) { |
574 | for (i = 0; i < num; i++) { | 624 | for (i = 0; i < num; i++) { |
575 | if (!_b->mi[i] && mi->blk.phys == b->blocks[i].ssptr) { | 625 | if (!_b->mi[i] && mi->blk.id == b->blocks[i].id && |
626 | mi->blk.key == b->blocks[i].key) { | ||
576 | _b->mi[i] = mi; | 627 | _b->mi[i] = mi; |
577 | 628 | b->length += tiler_size(&mi->blk); | |
578 | /* quit if found all*/ | 629 | /* quit if found all*/ |
579 | if (!--remain) | 630 | if (!--remain) |
580 | break; | 631 | break; |
@@ -585,8 +636,7 @@ static s32 register_buf(struct __buf_info *_b, struct process_info *pi) | |||
585 | 636 | ||
586 | /* if found all, register buffer */ | 637 | /* if found all, register buffer */ |
587 | if (!remain) { | 638 | if (!remain) { |
588 | b->offset = id; | 639 | b->offset = _m_get_offs(pi, b->length); |
589 | id += 0x1000; | ||
590 | 640 | ||
591 | list_add(&_b->by_pid, &pi->bufs); | 641 | list_add(&_b->by_pid, &pi->bufs); |
592 | 642 | ||
@@ -821,42 +871,123 @@ static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height, | |||
821 | return mi; | 871 | return mi; |
822 | } | 872 | } |
823 | 873 | ||
874 | s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size, | ||
875 | struct vm_area_struct *vma, u32 voffs) | ||
876 | { | ||
877 | u32 v, p; | ||
878 | u32 len; /* area to map */ | ||
879 | |||
880 | /* don't allow mremap */ | ||
881 | vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; | ||
882 | |||
883 | /* mapping must fit into vma */ | ||
884 | if (vma->vm_start > vma->vm_start + voffs || | ||
885 | vma->vm_start + voffs > vma->vm_start + voffs + size || | ||
886 | vma->vm_start + voffs + size > vma->vm_end) | ||
887 | BUG(); | ||
888 | |||
889 | /* mapping must fit into block */ | ||
890 | if (offs > offs + size || | ||
891 | offs + size > tiler_size(blk)) | ||
892 | BUG(); | ||
893 | |||
894 | v = tiler_vstride(blk); | ||
895 | p = tiler_pstride(blk); | ||
896 | |||
897 | /* remap block portion */ | ||
898 | len = v - (offs % v); /* initial area to map */ | ||
899 | while (size) { | ||
900 | if (len > size) | ||
901 | len = size; | ||
902 | |||
903 | vma->vm_pgoff = (blk->phys + offs) >> PAGE_SHIFT; | ||
904 | if (remap_pfn_range(vma, vma->vm_start + voffs, vma->vm_pgoff, | ||
905 | len, vma->vm_page_prot)) | ||
906 | return -EAGAIN; | ||
907 | voffs += len; | ||
908 | offs += len + p - v; | ||
909 | size -= len; | ||
910 | len = v; /* subsequent area to map */ | ||
911 | } | ||
912 | return 0; | ||
913 | } | ||
914 | EXPORT_SYMBOL(tiler_mmap_blk); | ||
915 | |||
916 | s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size, | ||
917 | u32 addr, u32 mtype) | ||
918 | { | ||
919 | u32 v, p; | ||
920 | u32 len; /* area to map */ | ||
921 | const struct mem_type *type = get_mem_type(mtype); | ||
922 | |||
923 | /* mapping must fit into address space */ | ||
924 | if (addr > addr + size) | ||
925 | BUG(); | ||
926 | |||
927 | /* mapping must fit into block */ | ||
928 | if (offs > offs + size || | ||
929 | offs + size > tiler_size(blk)) | ||
930 | BUG(); | ||
931 | |||
932 | v = tiler_vstride(blk); | ||
933 | p = tiler_pstride(blk); | ||
934 | |||
935 | /* move offset and address to end */ | ||
936 | offs += blk->phys + size; | ||
937 | addr += size; | ||
938 | |||
939 | len = v - (offs % v); /* initial area to map */ | ||
940 | while (size) { | ||
941 | while (len && size) { | ||
942 | if (ioremap_page(addr - size, offs - size, type)) | ||
943 | return -EAGAIN; | ||
944 | len -= PAGE_SIZE; | ||
945 | size -= PAGE_SIZE; | ||
946 | } | ||
947 | |||
948 | offs += p - v; | ||
949 | len = v; /* subsequent area to map */ | ||
950 | } | ||
951 | return 0; | ||
952 | } | ||
953 | EXPORT_SYMBOL(tiler_ioremap_blk); | ||
954 | |||
824 | static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma) | 955 | static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma) |
825 | { | 956 | { |
826 | struct __buf_info *_b = NULL; | 957 | struct __buf_info *_b = NULL; |
827 | struct tiler_buf_info *b = NULL; | 958 | struct tiler_buf_info *b = NULL; |
828 | s32 i = 0, j = 0, k = 0, m = 0, p = 0; | 959 | u32 i, map_offs, map_size, blk_offs, blk_size, mapped_size; |
829 | struct list_head *pos = NULL; | ||
830 | struct process_info *pi = filp->private_data; | 960 | struct process_info *pi = filp->private_data; |
961 | u32 offs = vma->vm_pgoff << PAGE_SHIFT; | ||
962 | u32 size = vma->vm_end - vma->vm_start; | ||
831 | 963 | ||
832 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 964 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
833 | 965 | ||
834 | /* don't allow mremap */ | ||
835 | vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; | ||
836 | |||
837 | mutex_lock(&mtx); | 966 | mutex_lock(&mtx); |
838 | list_for_each(pos, &pi->bufs) { | 967 | list_for_each_entry(_b, &pi->bufs, by_pid) { |
839 | _b = list_entry(pos, struct __buf_info, by_pid); | 968 | if (offs >= _b->buf_info.offset && |
840 | if ((vma->vm_pgoff << PAGE_SHIFT) == _b->buf_info.offset) | 969 | offs + size <= _b->buf_info.offset + _b->buf_info.length) { |
970 | b = &_b->buf_info; | ||
841 | break; | 971 | break; |
972 | } | ||
842 | } | 973 | } |
843 | mutex_unlock(&mtx); | 974 | mutex_unlock(&mtx); |
844 | if (!_b) | 975 | if (!b) |
845 | return -ENXIO; | 976 | return -ENXIO; |
846 | 977 | ||
847 | b = &_b->buf_info; | 978 | /* mmap relevant blocks */ |
848 | 979 | blk_offs = _b->buf_info.offset; | |
849 | for (i = 0; i < b->num_blocks; i++) { | 980 | mapped_size = 0; |
850 | p = tiler_vstride(&_b->mi[i]->blk); | 981 | for (i = 0; i < b->num_blocks; i++, blk_offs += blk_size) { |
851 | for (m = j = 0; j < _b->mi[i]->blk.height; j++) { | 982 | blk_size = tiler_size(&_b->mi[i]->blk); |
852 | /* map each page of the line */ | 983 | if (offs >= blk_offs + blk_size || offs + size < blk_offs) |
853 | vma->vm_pgoff = (b->blocks[i].ssptr + m) >> PAGE_SHIFT; | 984 | continue; |
854 | if (remap_pfn_range(vma, vma->vm_start + k, | 985 | map_offs = max(offs, blk_offs) - blk_offs; |
855 | vma->vm_pgoff, p, vma->vm_page_prot)) | 986 | map_size = min(size - mapped_size, blk_size); |
856 | return -EAGAIN; | 987 | if (tiler_mmap_blk(&_b->mi[i]->blk, map_offs, map_size, vma, |
857 | k += p; | 988 | mapped_size)) |
858 | m += tiler_pstride(&_b->mi[i]->blk); | 989 | return -EAGAIN; |
859 | } | 990 | mapped_size += map_size; |
860 | } | 991 | } |
861 | return 0; | 992 | return 0; |
862 | } | 993 | } |
@@ -939,6 +1070,10 @@ static s32 map_block(enum tiler_fmt fmt, u32 width, u32 height, | |||
939 | 1070 | ||
940 | mi->blk.width = width; | 1071 | mi->blk.width = width; |
941 | mi->blk.height = height; | 1072 | mi->blk.height = height; |
1073 | mi->blk.key = key; | ||
1074 | mutex_lock(&mtx); | ||
1075 | mi->blk.id = _m_get_id(); | ||
1076 | mutex_unlock(&mtx); | ||
942 | mi->usr = usr_addr; | 1077 | mi->usr = usr_addr; |
943 | 1078 | ||
944 | /* allocate pages */ | 1079 | /* allocate pages */ |
@@ -1047,7 +1182,7 @@ s32 tiler_map(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 usr_addr) | |||
1047 | } | 1182 | } |
1048 | EXPORT_SYMBOL(tiler_map); | 1183 | EXPORT_SYMBOL(tiler_map); |
1049 | 1184 | ||
1050 | s32 free_block(u32 sys_addr, struct process_info *pi) | 1185 | s32 free_block(u32 key, u32 id, struct process_info *pi) |
1051 | { | 1186 | { |
1052 | struct gid_info *gi = NULL; | 1187 | struct gid_info *gi = NULL; |
1053 | struct area_info *ai = NULL; | 1188 | struct area_info *ai = NULL; |
@@ -1058,19 +1193,11 @@ s32 free_block(u32 sys_addr, struct process_info *pi) | |||
1058 | 1193 | ||
1059 | /* find block in process list and free it */ | 1194 | /* find block in process list and free it */ |
1060 | list_for_each_entry(gi, &pi->groups, by_pid) { | 1195 | list_for_each_entry(gi, &pi->groups, by_pid) { |
1061 | /* currently we know if block is 1D or 2D by the address */ | 1196 | { |
1062 | if (TILER_GET_ACC_MODE(sys_addr) == TILFMT_PAGE) { | ||
1063 | list_for_each_entry(mi, &gi->onedim, by_area) { | ||
1064 | if (mi->blk.phys == sys_addr) { | ||
1065 | _m_try_free(mi); | ||
1066 | res = 0; | ||
1067 | goto done; | ||
1068 | } | ||
1069 | } | ||
1070 | } else { | ||
1071 | list_for_each_entry(ai, &gi->areas, by_gid) { | 1197 | list_for_each_entry(ai, &gi->areas, by_gid) { |
1072 | list_for_each_entry(mi, &ai->blocks, by_area) { | 1198 | list_for_each_entry(mi, &ai->blocks, by_area) { |
1073 | if (mi->blk.phys == sys_addr) { | 1199 | if (mi->blk.key == key && |
1200 | mi->blk.id == id) { | ||
1074 | _m_try_free(mi); | 1201 | _m_try_free(mi); |
1075 | res = 0; | 1202 | res = 0; |
1076 | goto done; | 1203 | goto done; |
@@ -1087,7 +1214,7 @@ done: | |||
1087 | return res; | 1214 | return res; |
1088 | } | 1215 | } |
1089 | 1216 | ||
1090 | s32 free_block_global(u32 ssptr) | 1217 | static s32 free_block_global(u32 key, u32 id) |
1091 | { | 1218 | { |
1092 | struct mem_info *mi; | 1219 | struct mem_info *mi; |
1093 | s32 res = -ENOENT; | 1220 | s32 res = -ENOENT; |
@@ -1096,7 +1223,7 @@ s32 free_block_global(u32 ssptr) | |||
1096 | 1223 | ||
1097 | /* find block in global list and free it */ | 1224 | /* find block in global list and free it */ |
1098 | list_for_each_entry(mi, &blocks, global) { | 1225 | list_for_each_entry(mi, &blocks, global) { |
1099 | if (mi->blk.phys == ssptr) { | 1226 | if (mi->blk.key == key && mi->blk.id == id) { |
1100 | _m_try_free(mi); | 1227 | _m_try_free(mi); |
1101 | res = 0; | 1228 | res = 0; |
1102 | break; | 1229 | break; |
@@ -1110,23 +1237,7 @@ s32 free_block_global(u32 ssptr) | |||
1110 | 1237 | ||
1111 | s32 tiler_free(struct tiler_block_t *blk) | 1238 | s32 tiler_free(struct tiler_block_t *blk) |
1112 | { | 1239 | { |
1113 | struct mem_info *mi; | 1240 | return free_block_global(blk->key, blk->id); |
1114 | s32 res = -ENOENT; | ||
1115 | |||
1116 | mutex_lock(&mtx); | ||
1117 | |||
1118 | /* find block in global list and free it */ | ||
1119 | list_for_each_entry(mi, &blocks, global) { | ||
1120 | if (mi->blk.phys == blk->phys) { | ||
1121 | _m_try_free(mi); | ||
1122 | res = 0; | ||
1123 | break; | ||
1124 | } | ||
1125 | } | ||
1126 | mutex_unlock(&mtx); | ||
1127 | |||
1128 | /* for debugging, we can set the PAT entries to DMM_LISA_MAP__0 */ | ||
1129 | return res; | ||
1130 | } | 1241 | } |
1131 | EXPORT_SYMBOL(tiler_free); | 1242 | EXPORT_SYMBOL(tiler_free); |
1132 | 1243 | ||
@@ -1163,6 +1274,8 @@ found: | |||
1163 | blk->dim.area.height = i->blk.height; | 1274 | blk->dim.area.height = i->blk.height; |
1164 | blk->group_id = ((struct area_info *) i->parent)->gi->gid; | 1275 | blk->group_id = ((struct area_info *) i->parent)->gi->gid; |
1165 | } | 1276 | } |
1277 | blk->id = i->blk.id; | ||
1278 | blk->key = i->blk.key; | ||
1166 | blk->offs = i->blk.phys & ~PAGE_MASK; | 1279 | blk->offs = i->blk.phys & ~PAGE_MASK; |
1167 | blk->align = 0; | 1280 | blk->align = 0; |
1168 | return 0; | 1281 | return 0; |
@@ -1218,6 +1331,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, | |||
1218 | } | 1331 | } |
1219 | 1332 | ||
1220 | if (mi) { | 1333 | if (mi) { |
1334 | block_info.id = mi->blk.id; | ||
1221 | block_info.stride = tiler_vstride(&mi->blk); | 1335 | block_info.stride = tiler_vstride(&mi->blk); |
1222 | block_info.ssptr = mi->blk.phys; | 1336 | block_info.ssptr = mi->blk.phys; |
1223 | } | 1337 | } |
@@ -1232,8 +1346,8 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, | |||
1232 | return -EFAULT; | 1346 | return -EFAULT; |
1233 | 1347 | ||
1234 | /* search current process first, then all processes */ | 1348 | /* search current process first, then all processes */ |
1235 | free_block(block_info.ssptr, pi) ? | 1349 | free_block(block_info.key, block_info.id, pi) ? |
1236 | free_block_global(block_info.ssptr) : 0; | 1350 | free_block_global(block_info.key, block_info.id) : 0; |
1237 | 1351 | ||
1238 | /* free always succeeds */ | 1352 | /* free always succeeds */ |
1239 | break; | 1353 | break; |
@@ -1270,6 +1384,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, | |||
1270 | return r; | 1384 | return r; |
1271 | 1385 | ||
1272 | if (mi) { | 1386 | if (mi) { |
1387 | block_info.id = mi->blk.id; | ||
1273 | block_info.stride = tiler_vstride(&mi->blk); | 1388 | block_info.stride = tiler_vstride(&mi->blk); |
1274 | block_info.ssptr = mi->blk.phys; | 1389 | block_info.ssptr = mi->blk.phys; |
1275 | } | 1390 | } |
@@ -1390,6 +1505,10 @@ s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height, | |||
1390 | 1505 | ||
1391 | mi->blk.width = width; | 1506 | mi->blk.width = width; |
1392 | mi->blk.height = height; | 1507 | mi->blk.height = height; |
1508 | mi->blk.key = key; | ||
1509 | mutex_lock(&mtx); | ||
1510 | mi->blk.id = _m_get_id(); | ||
1511 | mutex_unlock(&mtx); | ||
1393 | 1512 | ||
1394 | /* allocate and map if mapping is supported */ | 1513 | /* allocate and map if mapping is supported */ |
1395 | if (tmm_can_map(TMM(fmt))) { | 1514 | if (tmm_can_map(TMM(fmt))) { |
@@ -1642,7 +1761,6 @@ static s32 __init tiler_init(void) | |||
1642 | INIT_LIST_HEAD(&procs); | 1761 | INIT_LIST_HEAD(&procs); |
1643 | INIT_LIST_HEAD(&orphan_areas); | 1762 | INIT_LIST_HEAD(&orphan_areas); |
1644 | INIT_LIST_HEAD(&orphan_onedim); | 1763 | INIT_LIST_HEAD(&orphan_onedim); |
1645 | id = 0xda7a000; | ||
1646 | 1764 | ||
1647 | error: | 1765 | error: |
1648 | /* TODO: error handling for device registration */ | 1766 | /* TODO: error handling for device registration */ |