diff options
author | Dave Airlie <airlied@redhat.com> | 2015-12-07 20:04:26 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-12-07 20:04:26 -0500 |
commit | e876b41ab074561d65f213bf5e0fc68cf5bc7380 (patch) | |
tree | 5bcbd7e4f7b6ac2a34e61011f8eb2cde90bf8603 /drivers/gpu/drm/drm_fops.c | |
parent | 47c0fd72822159eb501411f975f5672a0bf7a7fb (diff) | |
parent | 527e9316f8ec44bd53d90fb9f611fa7ffff52bb9 (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.c | 84 |
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 | */ | ||
138 | int 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 | |||
173 | out_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); |