ASoC: Fix Blackfin I2S _pointer() implementation return in bounds values
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / gma500 / psb_ttm_fence_user.c
blob36f974fc607db1c972e4f5de6953007803fec4f7
1 /**************************************************************************
3 * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
4 * All Rights Reserved.
5 * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
6 * All Rights Reserved.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 **************************************************************************/
23 * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
26 #include <drm/drmP.h>
27 #include "psb_ttm_fence_user.h"
28 #include "ttm/ttm_object.h"
29 #include "psb_ttm_fence_driver.h"
30 #include "psb_ttm_userobj_api.h"
32 /**
33 * struct ttm_fence_user_object
35 * @base: The base object used for user-space visibility and refcounting.
37 * @fence: The fence object itself.
41 struct ttm_fence_user_object {
42 struct ttm_base_object base;
43 struct ttm_fence_object fence;
46 static struct ttm_fence_user_object *ttm_fence_user_object_lookup(
47 struct ttm_object_file *tfile,
48 uint32_t handle)
50 struct ttm_base_object *base;
52 base = ttm_base_object_lookup(tfile, handle);
53 if (unlikely(base == NULL)) {
54 printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
55 (unsigned long)handle);
56 return NULL;
59 if (unlikely(base->object_type != ttm_fence_type)) {
60 ttm_base_object_unref(&base);
61 printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
62 (unsigned long)handle);
63 return NULL;
66 return container_of(base, struct ttm_fence_user_object, base);
70 * The fence object destructor.
73 static void ttm_fence_user_destroy(struct ttm_fence_object *fence)
75 struct ttm_fence_user_object *ufence =
76 container_of(fence, struct ttm_fence_user_object, fence);
78 ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence));
79 kfree(ufence);
83 * The base object destructor. We basically unly unreference the
84 * attached fence object.
87 static void ttm_fence_user_release(struct ttm_base_object **p_base)
89 struct ttm_fence_user_object *ufence;
90 struct ttm_base_object *base = *p_base;
91 struct ttm_fence_object *fence;
93 *p_base = NULL;
95 if (unlikely(base == NULL))
96 return;
98 ufence = container_of(base, struct ttm_fence_user_object, base);
99 fence = &ufence->fence;
100 ttm_fence_object_unref(&fence);
104 ttm_fence_user_create(struct ttm_fence_device *fdev,
105 struct ttm_object_file *tfile,
106 uint32_t fence_class,
107 uint32_t fence_types,
108 uint32_t create_flags,
109 struct ttm_fence_object **fence,
110 uint32_t *user_handle)
112 int ret;
113 struct ttm_fence_object *tmp;
114 struct ttm_fence_user_object *ufence;
116 ret = ttm_mem_global_alloc(fdev->mem_glob,
117 sizeof(*ufence),
118 false,
119 false);
120 if (unlikely(ret != 0))
121 return -ENOMEM;
123 ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
124 if (unlikely(ufence == NULL)) {
125 ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
126 return -ENOMEM;
129 ret = ttm_fence_object_init(fdev,
130 fence_class,
131 fence_types, create_flags,
132 &ttm_fence_user_destroy, &ufence->fence);
134 if (unlikely(ret != 0))
135 goto out_err0;
138 * One fence ref is held by the fence ptr we return.
139 * The other one by the base object. Need to up the
140 * fence refcount before we publish this object to
141 * user-space.
144 tmp = ttm_fence_object_ref(&ufence->fence);
145 ret = ttm_base_object_init(tfile, &ufence->base,
146 false, ttm_fence_type,
147 &ttm_fence_user_release, NULL);
149 if (unlikely(ret != 0))
150 goto out_err1;
152 *fence = &ufence->fence;
153 *user_handle = ufence->base.hash.key;
155 return 0;
156 out_err1:
157 ttm_fence_object_unref(&tmp);
158 tmp = &ufence->fence;
159 ttm_fence_object_unref(&tmp);
160 return ret;
161 out_err0:
162 ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
163 kfree(ufence);
164 return ret;
167 int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data)
169 int ret;
170 union ttm_fence_signaled_arg *arg = data;
171 struct ttm_fence_object *fence;
172 struct ttm_fence_info info;
173 struct ttm_fence_user_object *ufence;
174 struct ttm_base_object *base;
175 ret = 0;
177 ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
178 if (unlikely(ufence == NULL))
179 return -EINVAL;
181 fence = &ufence->fence;
183 if (arg->req.flush) {
184 ret = ttm_fence_object_flush(fence, arg->req.fence_type);
185 if (unlikely(ret != 0))
186 goto out;
189 info = ttm_fence_get_info(fence);
190 arg->rep.signaled_types = info.signaled_types;
191 arg->rep.fence_error = info.error;
193 out:
194 base = &ufence->base;
195 ttm_base_object_unref(&base);
196 return ret;
199 int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data)
201 int ret;
202 union ttm_fence_finish_arg *arg = data;
203 struct ttm_fence_user_object *ufence;
204 struct ttm_base_object *base;
205 struct ttm_fence_object *fence;
206 ret = 0;
208 ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
209 if (unlikely(ufence == NULL))
210 return -EINVAL;
212 fence = &ufence->fence;
214 ret = ttm_fence_object_wait(fence,
215 arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY,
216 true, arg->req.fence_type);
217 if (likely(ret == 0)) {
218 struct ttm_fence_info info = ttm_fence_get_info(fence);
220 arg->rep.signaled_types = info.signaled_types;
221 arg->rep.fence_error = info.error;
224 base = &ufence->base;
225 ttm_base_object_unref(&base);
227 return ret;
230 int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data)
232 struct ttm_fence_unref_arg *arg = data;
233 int ret = 0;
235 ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type);
236 return ret;