aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fops.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-12-07 20:04:26 -0500
committerDave Airlie <airlied@redhat.com>2015-12-07 20:04:26 -0500
commite876b41ab074561d65f213bf5e0fc68cf5bc7380 (patch)
tree5bcbd7e4f7b6ac2a34e61011f8eb2cde90bf8603 /drivers/gpu/drm/drm_fops.c
parent47c0fd72822159eb501411f975f5672a0bf7a7fb (diff)
parent527e9316f8ec44bd53d90fb9f611fa7ffff52bb9 (diff)
Back merge tag 'v4.4-rc4' into drm-next
We've picked up a few conflicts and it would be nice to resolve them before we move onwards.
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r--drivers/gpu/drm/drm_fops.c84
1 files changed, 56 insertions, 28 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 81df9ae95e2e..1ea8790e5090 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -126,6 +126,60 @@ static int drm_cpu_valid(void)
126} 126}
127 127
128/** 128/**
129 * drm_new_set_master - Allocate a new master object and become master for the
130 * associated master realm.
131 *
132 * @dev: The associated device.
133 * @fpriv: File private identifying the client.
134 *
135 * This function must be called with dev::struct_mutex held.
136 * Returns negative error code on failure. Zero on success.
137 */
138int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
139{
140 struct drm_master *old_master;
141 int ret;
142
143 lockdep_assert_held_once(&dev->master_mutex);
144
145 /* create a new master */
146 fpriv->minor->master = drm_master_create(fpriv->minor);
147 if (!fpriv->minor->master)
148 return -ENOMEM;
149
150 /* take another reference for the copy in the local file priv */
151 old_master = fpriv->master;
152 fpriv->master = drm_master_get(fpriv->minor->master);
153
154 if (dev->driver->master_create) {
155 ret = dev->driver->master_create(dev, fpriv->master);
156 if (ret)
157 goto out_err;
158 }
159 if (dev->driver->master_set) {
160 ret = dev->driver->master_set(dev, fpriv, true);
161 if (ret)
162 goto out_err;
163 }
164
165 fpriv->is_master = 1;
166 fpriv->allowed_master = 1;
167 fpriv->authenticated = 1;
168 if (old_master)
169 drm_master_put(&old_master);
170
171 return 0;
172
173out_err:
174 /* drop both references and restore old master on failure */
175 drm_master_put(&fpriv->minor->master);
176 drm_master_put(&fpriv->master);
177 fpriv->master = old_master;
178
179 return ret;
180}
181
182/**
129 * Called whenever a process opens /dev/drm. 183 * Called whenever a process opens /dev/drm.
130 * 184 *
131 * \param filp file pointer. 185 * \param filp file pointer.
@@ -191,35 +245,9 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
191 mutex_lock(&dev->master_mutex); 245 mutex_lock(&dev->master_mutex);
192 if (drm_is_primary_client(priv) && !priv->minor->master) { 246 if (drm_is_primary_client(priv) && !priv->minor->master) {
193 /* create a new master */ 247 /* create a new master */
194 priv->minor->master = drm_master_create(priv->minor); 248 ret = drm_new_set_master(dev, priv);
195 if (!priv->minor->master) { 249 if (ret)
196 ret = -ENOMEM;
197 goto out_close; 250 goto out_close;
198 }
199
200 priv->is_master = 1;
201 /* take another reference for the copy in the local file priv */
202 priv->master = drm_master_get(priv->minor->master);
203 priv->authenticated = 1;
204
205 if (dev->driver->master_create) {
206 ret = dev->driver->master_create(dev, priv->master);
207 if (ret) {
208 /* drop both references if this fails */
209 drm_master_put(&priv->minor->master);
210 drm_master_put(&priv->master);
211 goto out_close;
212 }
213 }
214 if (dev->driver->master_set) {
215 ret = dev->driver->master_set(dev, priv, true);
216 if (ret) {
217 /* drop both references if this fails */
218 drm_master_put(&priv->minor->master);
219 drm_master_put(&priv->master);
220 goto out_close;
221 }
222 }
223 } else if (drm_is_primary_client(priv)) { 251 } else if (drm_is_primary_client(priv)) {
224 /* get a reference to the master */ 252 /* get a reference to the master */
225 priv->master = drm_master_get(priv->minor->master); 253 priv->master = drm_master_get(priv->minor->master);