diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /drivers/gpu/drm/drm_fops.c | |
parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
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 c59ce4d0ef75..6b5625e66119 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. |
@@ -189,35 +243,9 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
189 | mutex_lock(&dev->master_mutex); | 243 | mutex_lock(&dev->master_mutex); |
190 | if (drm_is_primary_client(priv) && !priv->minor->master) { | 244 | if (drm_is_primary_client(priv) && !priv->minor->master) { |
191 | /* create a new master */ | 245 | /* create a new master */ |
192 | priv->minor->master = drm_master_create(priv->minor); | 246 | ret = drm_new_set_master(dev, priv); |
193 | if (!priv->minor->master) { | 247 | if (ret) |
194 | ret = -ENOMEM; | ||
195 | goto out_close; | 248 | goto out_close; |
196 | } | ||
197 | |||
198 | priv->is_master = 1; | ||
199 | /* take another reference for the copy in the local file priv */ | ||
200 | priv->master = drm_master_get(priv->minor->master); | ||
201 | priv->authenticated = 1; | ||
202 | |||
203 | if (dev->driver->master_create) { | ||
204 | ret = dev->driver->master_create(dev, priv->master); | ||
205 | if (ret) { | ||
206 | /* drop both references if this fails */ | ||
207 | drm_master_put(&priv->minor->master); | ||
208 | drm_master_put(&priv->master); | ||
209 | goto out_close; | ||
210 | } | ||
211 | } | ||
212 | if (dev->driver->master_set) { | ||
213 | ret = dev->driver->master_set(dev, priv, true); | ||
214 | if (ret) { | ||
215 | /* drop both references if this fails */ | ||
216 | drm_master_put(&priv->minor->master); | ||
217 | drm_master_put(&priv->master); | ||
218 | goto out_close; | ||
219 | } | ||
220 | } | ||
221 | } else if (drm_is_primary_client(priv)) { | 249 | } else if (drm_is_primary_client(priv)) { |
222 | /* get a reference to the master */ | 250 | /* get a reference to the master */ |
223 | priv->master = drm_master_get(priv->minor->master); | 251 | priv->master = drm_master_get(priv->minor->master); |