diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-03-16 08:13:51 -0400 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-03-16 08:13:51 -0400 |
commit | 07b48c3ac539828d744f0562da1f24e8a234d06e (patch) | |
tree | bb1d32d025f97fc47f44a037951563c72eaf586d | |
parent | afab4463acc5ae7aa975a0c2400b85ff541c6a5b (diff) | |
parent | 0d639883ee26359e1bf38195df1dbca0f879e239 (diff) |
Merge branch 'drm-minor' into drm-next
Fix minor conflicts with drm-anon:
- allocation/free order
- drm_device header cleanups
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fops.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_pci.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_platform.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 348 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_usb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/bus.c | 2 | ||||
-rw-r--r-- | include/drm/drmP.h | 41 |
8 files changed, 278 insertions, 193 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 345be03c23db..ec651be2f3cb 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -344,7 +344,7 @@ long drm_ioctl(struct file *filp, | |||
344 | 344 | ||
345 | DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", | 345 | DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", |
346 | task_pid_nr(current), | 346 | task_pid_nr(current), |
347 | (long)old_encode_dev(file_priv->minor->device), | 347 | (long)old_encode_dev(file_priv->minor->kdev->devt), |
348 | file_priv->authenticated, ioctl->name); | 348 | file_priv->authenticated, ioctl->name); |
349 | 349 | ||
350 | /* Do not trust userspace, use our own definition */ | 350 | /* Do not trust userspace, use our own definition */ |
@@ -402,7 +402,7 @@ long drm_ioctl(struct file *filp, | |||
402 | if (!ioctl) | 402 | if (!ioctl) |
403 | DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n", | 403 | DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n", |
404 | task_pid_nr(current), | 404 | task_pid_nr(current), |
405 | (long)old_encode_dev(file_priv->minor->device), | 405 | (long)old_encode_dev(file_priv->minor->kdev->devt), |
406 | file_priv->authenticated, cmd, nr); | 406 | file_priv->authenticated, cmd, nr); |
407 | 407 | ||
408 | if (kdata != stack_kdata) | 408 | if (kdata != stack_kdata) |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 147a84d9da9b..9b02f126fb0d 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -39,12 +39,12 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | 41 | ||
42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ | 42 | /* from BKL pushdown */ |
43 | DEFINE_MUTEX(drm_global_mutex); | 43 | DEFINE_MUTEX(drm_global_mutex); |
44 | EXPORT_SYMBOL(drm_global_mutex); | 44 | EXPORT_SYMBOL(drm_global_mutex); |
45 | 45 | ||
46 | static int drm_open_helper(struct inode *inode, struct file *filp, | 46 | static int drm_open_helper(struct inode *inode, struct file *filp, |
47 | struct drm_device * dev); | 47 | struct drm_minor *minor); |
48 | 48 | ||
49 | static int drm_setup(struct drm_device * dev) | 49 | static int drm_setup(struct drm_device * dev) |
50 | { | 50 | { |
@@ -79,29 +79,23 @@ static int drm_setup(struct drm_device * dev) | |||
79 | */ | 79 | */ |
80 | int drm_open(struct inode *inode, struct file *filp) | 80 | int drm_open(struct inode *inode, struct file *filp) |
81 | { | 81 | { |
82 | struct drm_device *dev = NULL; | 82 | struct drm_device *dev; |
83 | int minor_id = iminor(inode); | ||
84 | struct drm_minor *minor; | 83 | struct drm_minor *minor; |
85 | int retcode = 0; | 84 | int retcode; |
86 | int need_setup = 0; | 85 | int need_setup = 0; |
87 | 86 | ||
88 | minor = idr_find(&drm_minors_idr, minor_id); | 87 | minor = drm_minor_acquire(iminor(inode)); |
89 | if (!minor) | 88 | if (IS_ERR(minor)) |
90 | return -ENODEV; | 89 | return PTR_ERR(minor); |
91 | |||
92 | if (!(dev = minor->dev)) | ||
93 | return -ENODEV; | ||
94 | |||
95 | if (drm_device_is_unplugged(dev)) | ||
96 | return -ENODEV; | ||
97 | 90 | ||
91 | dev = minor->dev; | ||
98 | if (!dev->open_count++) | 92 | if (!dev->open_count++) |
99 | need_setup = 1; | 93 | need_setup = 1; |
100 | 94 | ||
101 | /* share address_space across all char-devs of a single device */ | 95 | /* share address_space across all char-devs of a single device */ |
102 | filp->f_mapping = dev->anon_inode->i_mapping; | 96 | filp->f_mapping = dev->anon_inode->i_mapping; |
103 | 97 | ||
104 | retcode = drm_open_helper(inode, filp, dev); | 98 | retcode = drm_open_helper(inode, filp, minor); |
105 | if (retcode) | 99 | if (retcode) |
106 | goto err_undo; | 100 | goto err_undo; |
107 | if (need_setup) { | 101 | if (need_setup) { |
@@ -113,6 +107,7 @@ int drm_open(struct inode *inode, struct file *filp) | |||
113 | 107 | ||
114 | err_undo: | 108 | err_undo: |
115 | dev->open_count--; | 109 | dev->open_count--; |
110 | drm_minor_release(minor); | ||
116 | return retcode; | 111 | return retcode; |
117 | } | 112 | } |
118 | EXPORT_SYMBOL(drm_open); | 113 | EXPORT_SYMBOL(drm_open); |
@@ -128,33 +123,30 @@ EXPORT_SYMBOL(drm_open); | |||
128 | */ | 123 | */ |
129 | int drm_stub_open(struct inode *inode, struct file *filp) | 124 | int drm_stub_open(struct inode *inode, struct file *filp) |
130 | { | 125 | { |
131 | struct drm_device *dev = NULL; | 126 | struct drm_device *dev; |
132 | struct drm_minor *minor; | 127 | struct drm_minor *minor; |
133 | int minor_id = iminor(inode); | ||
134 | int err = -ENODEV; | 128 | int err = -ENODEV; |
135 | const struct file_operations *new_fops; | 129 | const struct file_operations *new_fops; |
136 | 130 | ||
137 | DRM_DEBUG("\n"); | 131 | DRM_DEBUG("\n"); |
138 | 132 | ||
139 | mutex_lock(&drm_global_mutex); | 133 | mutex_lock(&drm_global_mutex); |
140 | minor = idr_find(&drm_minors_idr, minor_id); | 134 | minor = drm_minor_acquire(iminor(inode)); |
141 | if (!minor) | 135 | if (IS_ERR(minor)) |
142 | goto out; | 136 | goto out_unlock; |
143 | |||
144 | if (!(dev = minor->dev)) | ||
145 | goto out; | ||
146 | |||
147 | if (drm_device_is_unplugged(dev)) | ||
148 | goto out; | ||
149 | 137 | ||
138 | dev = minor->dev; | ||
150 | new_fops = fops_get(dev->driver->fops); | 139 | new_fops = fops_get(dev->driver->fops); |
151 | if (!new_fops) | 140 | if (!new_fops) |
152 | goto out; | 141 | goto out_release; |
153 | 142 | ||
154 | replace_fops(filp, new_fops); | 143 | replace_fops(filp, new_fops); |
155 | if (filp->f_op->open) | 144 | if (filp->f_op->open) |
156 | err = filp->f_op->open(inode, filp); | 145 | err = filp->f_op->open(inode, filp); |
157 | out: | 146 | |
147 | out_release: | ||
148 | drm_minor_release(minor); | ||
149 | out_unlock: | ||
158 | mutex_unlock(&drm_global_mutex); | 150 | mutex_unlock(&drm_global_mutex); |
159 | return err; | 151 | return err; |
160 | } | 152 | } |
@@ -181,16 +173,16 @@ static int drm_cpu_valid(void) | |||
181 | * | 173 | * |
182 | * \param inode device inode. | 174 | * \param inode device inode. |
183 | * \param filp file pointer. | 175 | * \param filp file pointer. |
184 | * \param dev device. | 176 | * \param minor acquired minor-object. |
185 | * \return zero on success or a negative number on failure. | 177 | * \return zero on success or a negative number on failure. |
186 | * | 178 | * |
187 | * Creates and initializes a drm_file structure for the file private data in \p | 179 | * Creates and initializes a drm_file structure for the file private data in \p |
188 | * filp and add it into the double linked list in \p dev. | 180 | * filp and add it into the double linked list in \p dev. |
189 | */ | 181 | */ |
190 | static int drm_open_helper(struct inode *inode, struct file *filp, | 182 | static int drm_open_helper(struct inode *inode, struct file *filp, |
191 | struct drm_device * dev) | 183 | struct drm_minor *minor) |
192 | { | 184 | { |
193 | int minor_id = iminor(inode); | 185 | struct drm_device *dev = minor->dev; |
194 | struct drm_file *priv; | 186 | struct drm_file *priv; |
195 | int ret; | 187 | int ret; |
196 | 188 | ||
@@ -201,7 +193,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
201 | if (dev->switch_power_state != DRM_SWITCH_POWER_ON && dev->switch_power_state != DRM_SWITCH_POWER_DYNAMIC_OFF) | 193 | if (dev->switch_power_state != DRM_SWITCH_POWER_ON && dev->switch_power_state != DRM_SWITCH_POWER_DYNAMIC_OFF) |
202 | return -EINVAL; | 194 | return -EINVAL; |
203 | 195 | ||
204 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); | 196 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor->index); |
205 | 197 | ||
206 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 198 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
207 | if (!priv) | 199 | if (!priv) |
@@ -211,11 +203,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
211 | priv->filp = filp; | 203 | priv->filp = filp; |
212 | priv->uid = current_euid(); | 204 | priv->uid = current_euid(); |
213 | priv->pid = get_pid(task_pid(current)); | 205 | priv->pid = get_pid(task_pid(current)); |
214 | priv->minor = idr_find(&drm_minors_idr, minor_id); | 206 | priv->minor = minor; |
215 | if (!priv->minor) { | ||
216 | ret = -ENODEV; | ||
217 | goto out_put_pid; | ||
218 | } | ||
219 | 207 | ||
220 | /* for compatibility root is always authenticated */ | 208 | /* for compatibility root is always authenticated */ |
221 | priv->always_authenticated = capable(CAP_SYS_ADMIN); | 209 | priv->always_authenticated = capable(CAP_SYS_ADMIN); |
@@ -321,7 +309,6 @@ out_prime_destroy: | |||
321 | drm_prime_destroy_file_private(&priv->prime); | 309 | drm_prime_destroy_file_private(&priv->prime); |
322 | if (dev->driver->driver_features & DRIVER_GEM) | 310 | if (dev->driver->driver_features & DRIVER_GEM) |
323 | drm_gem_release(dev, priv); | 311 | drm_gem_release(dev, priv); |
324 | out_put_pid: | ||
325 | put_pid(priv->pid); | 312 | put_pid(priv->pid); |
326 | kfree(priv); | 313 | kfree(priv); |
327 | filp->private_data = NULL; | 314 | filp->private_data = NULL; |
@@ -442,7 +429,8 @@ int drm_lastclose(struct drm_device * dev) | |||
442 | int drm_release(struct inode *inode, struct file *filp) | 429 | int drm_release(struct inode *inode, struct file *filp) |
443 | { | 430 | { |
444 | struct drm_file *file_priv = filp->private_data; | 431 | struct drm_file *file_priv = filp->private_data; |
445 | struct drm_device *dev = file_priv->minor->dev; | 432 | struct drm_minor *minor = file_priv->minor; |
433 | struct drm_device *dev = minor->dev; | ||
446 | int retcode = 0; | 434 | int retcode = 0; |
447 | 435 | ||
448 | mutex_lock(&drm_global_mutex); | 436 | mutex_lock(&drm_global_mutex); |
@@ -458,7 +446,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
458 | 446 | ||
459 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", | 447 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", |
460 | task_pid_nr(current), | 448 | task_pid_nr(current), |
461 | (long)old_encode_dev(file_priv->minor->device), | 449 | (long)old_encode_dev(file_priv->minor->kdev->devt), |
462 | dev->open_count); | 450 | dev->open_count); |
463 | 451 | ||
464 | /* Release any auth tokens that might point to this file_priv, | 452 | /* Release any auth tokens that might point to this file_priv, |
@@ -561,6 +549,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
561 | } | 549 | } |
562 | mutex_unlock(&drm_global_mutex); | 550 | mutex_unlock(&drm_global_mutex); |
563 | 551 | ||
552 | drm_minor_release(minor); | ||
553 | |||
564 | return retcode; | 554 | return retcode; |
565 | } | 555 | } |
566 | EXPORT_SYMBOL(drm_release); | 556 | EXPORT_SYMBOL(drm_release); |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 5736aaa7e86c..9ded847b05b4 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -351,7 +351,7 @@ err_agp: | |||
351 | drm_pci_agp_destroy(dev); | 351 | drm_pci_agp_destroy(dev); |
352 | pci_disable_device(pdev); | 352 | pci_disable_device(pdev); |
353 | err_free: | 353 | err_free: |
354 | drm_dev_free(dev); | 354 | drm_dev_unref(dev); |
355 | return ret; | 355 | return ret; |
356 | } | 356 | } |
357 | EXPORT_SYMBOL(drm_get_pci_dev); | 357 | EXPORT_SYMBOL(drm_get_pci_dev); |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 21fc82006b78..319ff5385601 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
@@ -64,7 +64,7 @@ static int drm_get_platform_dev(struct platform_device *platdev, | |||
64 | return 0; | 64 | return 0; |
65 | 65 | ||
66 | err_free: | 66 | err_free: |
67 | drm_dev_free(dev); | 67 | drm_dev_unref(dev); |
68 | return ret; | 68 | return ret; |
69 | } | 69 | } |
70 | 70 | ||
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 04c25cedd4c1..dc2c6095d850 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -72,6 +72,7 @@ module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); | |||
72 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); | 72 | module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); |
73 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); | 73 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); |
74 | 74 | ||
75 | static DEFINE_SPINLOCK(drm_minor_lock); | ||
75 | struct idr drm_minors_idr; | 76 | struct idr drm_minors_idr; |
76 | 77 | ||
77 | struct class *drm_class; | 78 | struct class *drm_class; |
@@ -119,26 +120,6 @@ void drm_ut_debug_printk(unsigned int request_level, | |||
119 | } | 120 | } |
120 | EXPORT_SYMBOL(drm_ut_debug_printk); | 121 | EXPORT_SYMBOL(drm_ut_debug_printk); |
121 | 122 | ||
122 | static int drm_minor_get_id(struct drm_device *dev, int type) | ||
123 | { | ||
124 | int ret; | ||
125 | int base = 0, limit = 63; | ||
126 | |||
127 | if (type == DRM_MINOR_CONTROL) { | ||
128 | base += 64; | ||
129 | limit = base + 63; | ||
130 | } else if (type == DRM_MINOR_RENDER) { | ||
131 | base += 128; | ||
132 | limit = base + 63; | ||
133 | } | ||
134 | |||
135 | mutex_lock(&dev->struct_mutex); | ||
136 | ret = idr_alloc(&drm_minors_idr, NULL, base, limit, GFP_KERNEL); | ||
137 | mutex_unlock(&dev->struct_mutex); | ||
138 | |||
139 | return ret == -ENOSPC ? -EINVAL : ret; | ||
140 | } | ||
141 | |||
142 | struct drm_master *drm_master_create(struct drm_minor *minor) | 123 | struct drm_master *drm_master_create(struct drm_minor *minor) |
143 | { | 124 | { |
144 | struct drm_master *master; | 125 | struct drm_master *master; |
@@ -262,119 +243,183 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | |||
262 | return 0; | 243 | return 0; |
263 | } | 244 | } |
264 | 245 | ||
265 | /** | 246 | /* |
266 | * drm_get_minor - Allocate and register new DRM minor | 247 | * DRM Minors |
267 | * @dev: DRM device | 248 | * A DRM device can provide several char-dev interfaces on the DRM-Major. Each |
268 | * @minor: Pointer to where new minor is stored | 249 | * of them is represented by a drm_minor object. Depending on the capabilities |
269 | * @type: Type of minor | 250 | * of the device-driver, different interfaces are registered. |
270 | * | ||
271 | * Allocate a new minor of the given type and register it. A pointer to the new | ||
272 | * minor is returned in @minor. | ||
273 | * Caller must hold the global DRM mutex. | ||
274 | * | 251 | * |
275 | * RETURNS: | 252 | * Minors can be accessed via dev->$minor_name. This pointer is either |
276 | * 0 on success, negative error code on failure. | 253 | * NULL or a valid drm_minor pointer and stays valid as long as the device is |
254 | * valid. This means, DRM minors have the same life-time as the underlying | ||
255 | * device. However, this doesn't mean that the minor is active. Minors are | ||
256 | * registered and unregistered dynamically according to device-state. | ||
277 | */ | 257 | */ |
278 | static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, | 258 | |
279 | int type) | 259 | static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, |
260 | unsigned int type) | ||
261 | { | ||
262 | switch (type) { | ||
263 | case DRM_MINOR_LEGACY: | ||
264 | return &dev->primary; | ||
265 | case DRM_MINOR_RENDER: | ||
266 | return &dev->render; | ||
267 | case DRM_MINOR_CONTROL: | ||
268 | return &dev->control; | ||
269 | default: | ||
270 | return NULL; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static int drm_minor_alloc(struct drm_device *dev, unsigned int type) | ||
275 | { | ||
276 | struct drm_minor *minor; | ||
277 | |||
278 | minor = kzalloc(sizeof(*minor), GFP_KERNEL); | ||
279 | if (!minor) | ||
280 | return -ENOMEM; | ||
281 | |||
282 | minor->type = type; | ||
283 | minor->dev = dev; | ||
284 | INIT_LIST_HEAD(&minor->master_list); | ||
285 | |||
286 | *drm_minor_get_slot(dev, type) = minor; | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static void drm_minor_free(struct drm_device *dev, unsigned int type) | ||
291 | { | ||
292 | struct drm_minor **slot; | ||
293 | |||
294 | slot = drm_minor_get_slot(dev, type); | ||
295 | if (*slot) { | ||
296 | kfree(*slot); | ||
297 | *slot = NULL; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | static int drm_minor_register(struct drm_device *dev, unsigned int type) | ||
280 | { | 302 | { |
281 | struct drm_minor *new_minor; | 303 | struct drm_minor *new_minor; |
304 | unsigned long flags; | ||
282 | int ret; | 305 | int ret; |
283 | int minor_id; | 306 | int minor_id; |
284 | 307 | ||
285 | DRM_DEBUG("\n"); | 308 | DRM_DEBUG("\n"); |
286 | 309 | ||
287 | minor_id = drm_minor_get_id(dev, type); | 310 | new_minor = *drm_minor_get_slot(dev, type); |
311 | if (!new_minor) | ||
312 | return 0; | ||
313 | |||
314 | idr_preload(GFP_KERNEL); | ||
315 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
316 | minor_id = idr_alloc(&drm_minors_idr, | ||
317 | NULL, | ||
318 | 64 * type, | ||
319 | 64 * (type + 1), | ||
320 | GFP_NOWAIT); | ||
321 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
322 | idr_preload_end(); | ||
323 | |||
288 | if (minor_id < 0) | 324 | if (minor_id < 0) |
289 | return minor_id; | 325 | return minor_id; |
290 | 326 | ||
291 | new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); | ||
292 | if (!new_minor) { | ||
293 | ret = -ENOMEM; | ||
294 | goto err_idr; | ||
295 | } | ||
296 | |||
297 | new_minor->type = type; | ||
298 | new_minor->device = MKDEV(DRM_MAJOR, minor_id); | ||
299 | new_minor->dev = dev; | ||
300 | new_minor->index = minor_id; | 327 | new_minor->index = minor_id; |
301 | INIT_LIST_HEAD(&new_minor->master_list); | ||
302 | |||
303 | idr_replace(&drm_minors_idr, new_minor, minor_id); | ||
304 | 328 | ||
305 | #if defined(CONFIG_DEBUG_FS) | ||
306 | ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); | 329 | ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); |
307 | if (ret) { | 330 | if (ret) { |
308 | DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); | 331 | DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); |
309 | goto err_mem; | 332 | goto err_id; |
310 | } | 333 | } |
311 | #endif | ||
312 | 334 | ||
313 | ret = drm_sysfs_device_add(new_minor); | 335 | ret = drm_sysfs_device_add(new_minor); |
314 | if (ret) { | 336 | if (ret) { |
315 | printk(KERN_ERR | 337 | DRM_ERROR("DRM: Error sysfs_device_add.\n"); |
316 | "DRM: Error sysfs_device_add.\n"); | ||
317 | goto err_debugfs; | 338 | goto err_debugfs; |
318 | } | 339 | } |
319 | *minor = new_minor; | 340 | |
341 | /* replace NULL with @minor so lookups will succeed from now on */ | ||
342 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
343 | idr_replace(&drm_minors_idr, new_minor, new_minor->index); | ||
344 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
320 | 345 | ||
321 | DRM_DEBUG("new minor assigned %d\n", minor_id); | 346 | DRM_DEBUG("new minor assigned %d\n", minor_id); |
322 | return 0; | 347 | return 0; |
323 | 348 | ||
324 | |||
325 | err_debugfs: | 349 | err_debugfs: |
326 | #if defined(CONFIG_DEBUG_FS) | ||
327 | drm_debugfs_cleanup(new_minor); | 350 | drm_debugfs_cleanup(new_minor); |
328 | err_mem: | 351 | err_id: |
329 | #endif | 352 | spin_lock_irqsave(&drm_minor_lock, flags); |
330 | kfree(new_minor); | ||
331 | err_idr: | ||
332 | idr_remove(&drm_minors_idr, minor_id); | 353 | idr_remove(&drm_minors_idr, minor_id); |
333 | *minor = NULL; | 354 | spin_unlock_irqrestore(&drm_minor_lock, flags); |
355 | new_minor->index = 0; | ||
334 | return ret; | 356 | return ret; |
335 | } | 357 | } |
336 | 358 | ||
337 | /** | 359 | static void drm_minor_unregister(struct drm_device *dev, unsigned int type) |
338 | * drm_unplug_minor - Unplug DRM minor | ||
339 | * @minor: Minor to unplug | ||
340 | * | ||
341 | * Unplugs the given DRM minor but keeps the object. So after this returns, | ||
342 | * minor->dev is still valid so existing open-files can still access it to get | ||
343 | * device information from their drm_file ojects. | ||
344 | * If the minor is already unplugged or if @minor is NULL, nothing is done. | ||
345 | * The global DRM mutex must be held by the caller. | ||
346 | */ | ||
347 | static void drm_unplug_minor(struct drm_minor *minor) | ||
348 | { | 360 | { |
361 | struct drm_minor *minor; | ||
362 | unsigned long flags; | ||
363 | |||
364 | minor = *drm_minor_get_slot(dev, type); | ||
349 | if (!minor || !minor->kdev) | 365 | if (!minor || !minor->kdev) |
350 | return; | 366 | return; |
351 | 367 | ||
352 | #if defined(CONFIG_DEBUG_FS) | 368 | spin_lock_irqsave(&drm_minor_lock, flags); |
353 | drm_debugfs_cleanup(minor); | 369 | idr_remove(&drm_minors_idr, minor->index); |
354 | #endif | 370 | spin_unlock_irqrestore(&drm_minor_lock, flags); |
371 | minor->index = 0; | ||
355 | 372 | ||
373 | drm_debugfs_cleanup(minor); | ||
356 | drm_sysfs_device_remove(minor); | 374 | drm_sysfs_device_remove(minor); |
357 | idr_remove(&drm_minors_idr, minor->index); | ||
358 | } | 375 | } |
359 | 376 | ||
360 | /** | 377 | /** |
361 | * drm_put_minor - Destroy DRM minor | 378 | * drm_minor_acquire - Acquire a DRM minor |
362 | * @minor: Minor to destroy | 379 | * @minor_id: Minor ID of the DRM-minor |
380 | * | ||
381 | * Looks up the given minor-ID and returns the respective DRM-minor object. The | ||
382 | * refence-count of the underlying device is increased so you must release this | ||
383 | * object with drm_minor_release(). | ||
384 | * | ||
385 | * As long as you hold this minor, it is guaranteed that the object and the | ||
386 | * minor->dev pointer will stay valid! However, the device may get unplugged and | ||
387 | * unregistered while you hold the minor. | ||
363 | * | 388 | * |
364 | * This calls drm_unplug_minor() on the given minor and then frees it. Nothing | 389 | * Returns: |
365 | * is done if @minor is NULL. It is fine to call this on already unplugged | 390 | * Pointer to minor-object with increased device-refcount, or PTR_ERR on |
366 | * minors. | 391 | * failure. |
367 | * The global DRM mutex must be held by the caller. | ||
368 | */ | 392 | */ |
369 | static void drm_put_minor(struct drm_minor *minor) | 393 | struct drm_minor *drm_minor_acquire(unsigned int minor_id) |
370 | { | 394 | { |
371 | if (!minor) | 395 | struct drm_minor *minor; |
372 | return; | 396 | unsigned long flags; |
397 | |||
398 | spin_lock_irqsave(&drm_minor_lock, flags); | ||
399 | minor = idr_find(&drm_minors_idr, minor_id); | ||
400 | if (minor) | ||
401 | drm_dev_ref(minor->dev); | ||
402 | spin_unlock_irqrestore(&drm_minor_lock, flags); | ||
403 | |||
404 | if (!minor) { | ||
405 | return ERR_PTR(-ENODEV); | ||
406 | } else if (drm_device_is_unplugged(minor->dev)) { | ||
407 | drm_dev_unref(minor->dev); | ||
408 | return ERR_PTR(-ENODEV); | ||
409 | } | ||
373 | 410 | ||
374 | DRM_DEBUG("release secondary minor %d\n", minor->index); | 411 | return minor; |
412 | } | ||
375 | 413 | ||
376 | drm_unplug_minor(minor); | 414 | /** |
377 | kfree(minor); | 415 | * drm_minor_release - Release DRM minor |
416 | * @minor: Pointer to DRM minor object | ||
417 | * | ||
418 | * Release a minor that was previously acquired via drm_minor_acquire(). | ||
419 | */ | ||
420 | void drm_minor_release(struct drm_minor *minor) | ||
421 | { | ||
422 | drm_dev_unref(minor->dev); | ||
378 | } | 423 | } |
379 | 424 | ||
380 | /** | 425 | /** |
@@ -394,18 +439,16 @@ void drm_put_dev(struct drm_device *dev) | |||
394 | } | 439 | } |
395 | 440 | ||
396 | drm_dev_unregister(dev); | 441 | drm_dev_unregister(dev); |
397 | drm_dev_free(dev); | 442 | drm_dev_unref(dev); |
398 | } | 443 | } |
399 | EXPORT_SYMBOL(drm_put_dev); | 444 | EXPORT_SYMBOL(drm_put_dev); |
400 | 445 | ||
401 | void drm_unplug_dev(struct drm_device *dev) | 446 | void drm_unplug_dev(struct drm_device *dev) |
402 | { | 447 | { |
403 | /* for a USB device */ | 448 | /* for a USB device */ |
404 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 449 | drm_minor_unregister(dev, DRM_MINOR_LEGACY); |
405 | drm_unplug_minor(dev->control); | 450 | drm_minor_unregister(dev, DRM_MINOR_RENDER); |
406 | if (dev->render) | 451 | drm_minor_unregister(dev, DRM_MINOR_CONTROL); |
407 | drm_unplug_minor(dev->render); | ||
408 | drm_unplug_minor(dev->primary); | ||
409 | 452 | ||
410 | mutex_lock(&drm_global_mutex); | 453 | mutex_lock(&drm_global_mutex); |
411 | 454 | ||
@@ -499,6 +542,9 @@ static void drm_fs_inode_free(struct inode *inode) | |||
499 | * Call drm_dev_register() to advertice the device to user space and register it | 542 | * Call drm_dev_register() to advertice the device to user space and register it |
500 | * with other core subsystems. | 543 | * with other core subsystems. |
501 | * | 544 | * |
545 | * The initial ref-count of the object is 1. Use drm_dev_ref() and | ||
546 | * drm_dev_unref() to take and drop further ref-counts. | ||
547 | * | ||
502 | * RETURNS: | 548 | * RETURNS: |
503 | * Pointer to new DRM device, or NULL if out of memory. | 549 | * Pointer to new DRM device, or NULL if out of memory. |
504 | */ | 550 | */ |
@@ -512,6 +558,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
512 | if (!dev) | 558 | if (!dev) |
513 | return NULL; | 559 | return NULL; |
514 | 560 | ||
561 | kref_init(&dev->ref); | ||
515 | dev->dev = parent; | 562 | dev->dev = parent; |
516 | dev->driver = driver; | 563 | dev->driver = driver; |
517 | 564 | ||
@@ -533,8 +580,24 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
533 | goto err_free; | 580 | goto err_free; |
534 | } | 581 | } |
535 | 582 | ||
583 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
584 | ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL); | ||
585 | if (ret) | ||
586 | goto err_minors; | ||
587 | } | ||
588 | |||
589 | if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { | ||
590 | ret = drm_minor_alloc(dev, DRM_MINOR_RENDER); | ||
591 | if (ret) | ||
592 | goto err_minors; | ||
593 | } | ||
594 | |||
595 | ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY); | ||
596 | if (ret) | ||
597 | goto err_minors; | ||
598 | |||
536 | if (drm_ht_create(&dev->map_hash, 12)) | 599 | if (drm_ht_create(&dev->map_hash, 12)) |
537 | goto err_inode; | 600 | goto err_minors; |
538 | 601 | ||
539 | ret = drm_ctxbitmap_init(dev); | 602 | ret = drm_ctxbitmap_init(dev); |
540 | if (ret) { | 603 | if (ret) { |
@@ -556,7 +619,10 @@ err_ctxbitmap: | |||
556 | drm_ctxbitmap_cleanup(dev); | 619 | drm_ctxbitmap_cleanup(dev); |
557 | err_ht: | 620 | err_ht: |
558 | drm_ht_remove(&dev->map_hash); | 621 | drm_ht_remove(&dev->map_hash); |
559 | err_inode: | 622 | err_minors: |
623 | drm_minor_free(dev, DRM_MINOR_LEGACY); | ||
624 | drm_minor_free(dev, DRM_MINOR_RENDER); | ||
625 | drm_minor_free(dev, DRM_MINOR_CONTROL); | ||
560 | drm_fs_inode_free(dev->anon_inode); | 626 | drm_fs_inode_free(dev->anon_inode); |
561 | err_free: | 627 | err_free: |
562 | kfree(dev); | 628 | kfree(dev); |
@@ -564,21 +630,9 @@ err_free: | |||
564 | } | 630 | } |
565 | EXPORT_SYMBOL(drm_dev_alloc); | 631 | EXPORT_SYMBOL(drm_dev_alloc); |
566 | 632 | ||
567 | /** | 633 | static void drm_dev_release(struct kref *ref) |
568 | * drm_dev_free - Free DRM device | ||
569 | * @dev: DRM device to free | ||
570 | * | ||
571 | * Free a DRM device that has previously been allocated via drm_dev_alloc(). | ||
572 | * You must not use kfree() instead or you will leak memory. | ||
573 | * | ||
574 | * This must not be called once the device got registered. Use drm_put_dev() | ||
575 | * instead, which then calls drm_dev_free(). | ||
576 | */ | ||
577 | void drm_dev_free(struct drm_device *dev) | ||
578 | { | 634 | { |
579 | drm_put_minor(dev->control); | 635 | struct drm_device *dev = container_of(ref, struct drm_device, ref); |
580 | drm_put_minor(dev->render); | ||
581 | drm_put_minor(dev->primary); | ||
582 | 636 | ||
583 | if (dev->driver->driver_features & DRIVER_GEM) | 637 | if (dev->driver->driver_features & DRIVER_GEM) |
584 | drm_gem_destroy(dev); | 638 | drm_gem_destroy(dev); |
@@ -587,10 +641,46 @@ void drm_dev_free(struct drm_device *dev) | |||
587 | drm_ht_remove(&dev->map_hash); | 641 | drm_ht_remove(&dev->map_hash); |
588 | drm_fs_inode_free(dev->anon_inode); | 642 | drm_fs_inode_free(dev->anon_inode); |
589 | 643 | ||
644 | drm_minor_free(dev, DRM_MINOR_LEGACY); | ||
645 | drm_minor_free(dev, DRM_MINOR_RENDER); | ||
646 | drm_minor_free(dev, DRM_MINOR_CONTROL); | ||
647 | |||
590 | kfree(dev->devname); | 648 | kfree(dev->devname); |
591 | kfree(dev); | 649 | kfree(dev); |
592 | } | 650 | } |
593 | EXPORT_SYMBOL(drm_dev_free); | 651 | |
652 | /** | ||
653 | * drm_dev_ref - Take reference of a DRM device | ||
654 | * @dev: device to take reference of or NULL | ||
655 | * | ||
656 | * This increases the ref-count of @dev by one. You *must* already own a | ||
657 | * reference when calling this. Use drm_dev_unref() to drop this reference | ||
658 | * again. | ||
659 | * | ||
660 | * This function never fails. However, this function does not provide *any* | ||
661 | * guarantee whether the device is alive or running. It only provides a | ||
662 | * reference to the object and the memory associated with it. | ||
663 | */ | ||
664 | void drm_dev_ref(struct drm_device *dev) | ||
665 | { | ||
666 | if (dev) | ||
667 | kref_get(&dev->ref); | ||
668 | } | ||
669 | EXPORT_SYMBOL(drm_dev_ref); | ||
670 | |||
671 | /** | ||
672 | * drm_dev_unref - Drop reference of a DRM device | ||
673 | * @dev: device to drop reference of or NULL | ||
674 | * | ||
675 | * This decreases the ref-count of @dev by one. The device is destroyed if the | ||
676 | * ref-count drops to zero. | ||
677 | */ | ||
678 | void drm_dev_unref(struct drm_device *dev) | ||
679 | { | ||
680 | if (dev) | ||
681 | kref_put(&dev->ref, drm_dev_release); | ||
682 | } | ||
683 | EXPORT_SYMBOL(drm_dev_unref); | ||
594 | 684 | ||
595 | /** | 685 | /** |
596 | * drm_dev_register - Register DRM device | 686 | * drm_dev_register - Register DRM device |
@@ -611,26 +701,22 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) | |||
611 | 701 | ||
612 | mutex_lock(&drm_global_mutex); | 702 | mutex_lock(&drm_global_mutex); |
613 | 703 | ||
614 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 704 | ret = drm_minor_register(dev, DRM_MINOR_CONTROL); |
615 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | 705 | if (ret) |
616 | if (ret) | 706 | goto err_minors; |
617 | goto out_unlock; | ||
618 | } | ||
619 | 707 | ||
620 | if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { | 708 | ret = drm_minor_register(dev, DRM_MINOR_RENDER); |
621 | ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); | 709 | if (ret) |
622 | if (ret) | 710 | goto err_minors; |
623 | goto err_control_node; | ||
624 | } | ||
625 | 711 | ||
626 | ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); | 712 | ret = drm_minor_register(dev, DRM_MINOR_LEGACY); |
627 | if (ret) | 713 | if (ret) |
628 | goto err_render_node; | 714 | goto err_minors; |
629 | 715 | ||
630 | if (dev->driver->load) { | 716 | if (dev->driver->load) { |
631 | ret = dev->driver->load(dev, flags); | 717 | ret = dev->driver->load(dev, flags); |
632 | if (ret) | 718 | if (ret) |
633 | goto err_primary_node; | 719 | goto err_minors; |
634 | } | 720 | } |
635 | 721 | ||
636 | /* setup grouping for legacy outputs */ | 722 | /* setup grouping for legacy outputs */ |
@@ -647,12 +733,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) | |||
647 | err_unload: | 733 | err_unload: |
648 | if (dev->driver->unload) | 734 | if (dev->driver->unload) |
649 | dev->driver->unload(dev); | 735 | dev->driver->unload(dev); |
650 | err_primary_node: | 736 | err_minors: |
651 | drm_unplug_minor(dev->primary); | 737 | drm_minor_unregister(dev, DRM_MINOR_LEGACY); |
652 | err_render_node: | 738 | drm_minor_unregister(dev, DRM_MINOR_RENDER); |
653 | drm_unplug_minor(dev->render); | 739 | drm_minor_unregister(dev, DRM_MINOR_CONTROL); |
654 | err_control_node: | ||
655 | drm_unplug_minor(dev->control); | ||
656 | out_unlock: | 740 | out_unlock: |
657 | mutex_unlock(&drm_global_mutex); | 741 | mutex_unlock(&drm_global_mutex); |
658 | return ret; | 742 | return ret; |
@@ -665,7 +749,7 @@ EXPORT_SYMBOL(drm_dev_register); | |||
665 | * | 749 | * |
666 | * Unregister the DRM device from the system. This does the reverse of | 750 | * Unregister the DRM device from the system. This does the reverse of |
667 | * drm_dev_register() but does not deallocate the device. The caller must call | 751 | * drm_dev_register() but does not deallocate the device. The caller must call |
668 | * drm_dev_free() to free all resources. | 752 | * drm_dev_unref() to drop their final reference. |
669 | */ | 753 | */ |
670 | void drm_dev_unregister(struct drm_device *dev) | 754 | void drm_dev_unregister(struct drm_device *dev) |
671 | { | 755 | { |
@@ -684,8 +768,8 @@ void drm_dev_unregister(struct drm_device *dev) | |||
684 | list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) | 768 | list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) |
685 | drm_rmmap(dev, r_list->map); | 769 | drm_rmmap(dev, r_list->map); |
686 | 770 | ||
687 | drm_unplug_minor(dev->control); | 771 | drm_minor_unregister(dev, DRM_MINOR_LEGACY); |
688 | drm_unplug_minor(dev->render); | 772 | drm_minor_unregister(dev, DRM_MINOR_RENDER); |
689 | drm_unplug_minor(dev->primary); | 773 | drm_minor_unregister(dev, DRM_MINOR_CONTROL); |
690 | } | 774 | } |
691 | EXPORT_SYMBOL(drm_dev_unregister); | 775 | EXPORT_SYMBOL(drm_dev_unregister); |
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index 0f8cb1ae7607..c3406aad2944 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c | |||
@@ -30,7 +30,7 @@ int drm_get_usb_dev(struct usb_interface *interface, | |||
30 | return 0; | 30 | return 0; |
31 | 31 | ||
32 | err_free: | 32 | err_free: |
33 | drm_dev_free(dev); | 33 | drm_dev_unref(dev); |
34 | return ret; | 34 | return ret; |
35 | 35 | ||
36 | } | 36 | } |
diff --git a/drivers/gpu/drm/tegra/bus.c b/drivers/gpu/drm/tegra/bus.c index e38e5967d77b..71cef5c13dc8 100644 --- a/drivers/gpu/drm/tegra/bus.c +++ b/drivers/gpu/drm/tegra/bus.c | |||
@@ -63,7 +63,7 @@ int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device) | |||
63 | return 0; | 63 | return 0; |
64 | 64 | ||
65 | err_free: | 65 | err_free: |
66 | drm_dev_free(drm); | 66 | drm_dev_unref(drm); |
67 | return ret; | 67 | return ret; |
68 | } | 68 | } |
69 | 69 | ||
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3227b716ffdf..99a17c8a1293 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/current.h> | 43 | #include <asm/current.h> |
44 | #endif /* __alpha__ */ | 44 | #endif /* __alpha__ */ |
45 | #include <linux/kernel.h> | 45 | #include <linux/kernel.h> |
46 | #include <linux/kref.h> | ||
46 | #include <linux/miscdevice.h> | 47 | #include <linux/miscdevice.h> |
47 | #include <linux/fs.h> | 48 | #include <linux/fs.h> |
48 | #include <linux/init.h> | 49 | #include <linux/init.h> |
@@ -1008,10 +1009,12 @@ struct drm_driver { | |||
1008 | struct list_head legacy_dev_list; | 1009 | struct list_head legacy_dev_list; |
1009 | }; | 1010 | }; |
1010 | 1011 | ||
1011 | #define DRM_MINOR_UNASSIGNED 0 | 1012 | enum drm_minor_type { |
1012 | #define DRM_MINOR_LEGACY 1 | 1013 | DRM_MINOR_LEGACY, |
1013 | #define DRM_MINOR_CONTROL 2 | 1014 | DRM_MINOR_CONTROL, |
1014 | #define DRM_MINOR_RENDER 3 | 1015 | DRM_MINOR_RENDER, |
1016 | DRM_MINOR_CNT, | ||
1017 | }; | ||
1015 | 1018 | ||
1016 | /** | 1019 | /** |
1017 | * Info file list entry. This structure represents a debugfs or proc file to | 1020 | * Info file list entry. This structure represents a debugfs or proc file to |
@@ -1040,7 +1043,6 @@ struct drm_info_node { | |||
1040 | struct drm_minor { | 1043 | struct drm_minor { |
1041 | int index; /**< Minor device number */ | 1044 | int index; /**< Minor device number */ |
1042 | int type; /**< Control or render */ | 1045 | int type; /**< Control or render */ |
1043 | dev_t device; /**< Device number for mknod */ | ||
1044 | struct device *kdev; /**< Linux device */ | 1046 | struct device *kdev; /**< Linux device */ |
1045 | struct drm_device *dev; | 1047 | struct drm_device *dev; |
1046 | 1048 | ||
@@ -1098,6 +1100,19 @@ struct drm_device { | |||
1098 | char *devname; /**< For /proc/interrupts */ | 1100 | char *devname; /**< For /proc/interrupts */ |
1099 | int if_version; /**< Highest interface version set */ | 1101 | int if_version; /**< Highest interface version set */ |
1100 | 1102 | ||
1103 | /** \name Lifetime Management */ | ||
1104 | /*@{ */ | ||
1105 | struct kref ref; /**< Object ref-count */ | ||
1106 | struct device *dev; /**< Device structure of bus-device */ | ||
1107 | struct drm_driver *driver; /**< DRM driver managing the device */ | ||
1108 | void *dev_private; /**< DRM driver private data */ | ||
1109 | struct drm_minor *control; /**< Control node */ | ||
1110 | struct drm_minor *primary; /**< Primary node */ | ||
1111 | struct drm_minor *render; /**< Render node */ | ||
1112 | atomic_t unplugged; /**< Flag whether dev is dead */ | ||
1113 | struct inode *anon_inode; /**< inode for private address-space */ | ||
1114 | /*@} */ | ||
1115 | |||
1101 | /** \name Locks */ | 1116 | /** \name Locks */ |
1102 | /*@{ */ | 1117 | /*@{ */ |
1103 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ | 1118 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ |
@@ -1171,7 +1186,6 @@ struct drm_device { | |||
1171 | 1186 | ||
1172 | struct drm_agp_head *agp; /**< AGP data */ | 1187 | struct drm_agp_head *agp; /**< AGP data */ |
1173 | 1188 | ||
1174 | struct device *dev; /**< Device structure */ | ||
1175 | struct pci_dev *pdev; /**< PCI device structure */ | 1189 | struct pci_dev *pdev; /**< PCI device structure */ |
1176 | #ifdef __alpha__ | 1190 | #ifdef __alpha__ |
1177 | struct pci_controller *hose; | 1191 | struct pci_controller *hose; |
@@ -1182,17 +1196,11 @@ struct drm_device { | |||
1182 | 1196 | ||
1183 | struct drm_sg_mem *sg; /**< Scatter gather memory */ | 1197 | struct drm_sg_mem *sg; /**< Scatter gather memory */ |
1184 | unsigned int num_crtcs; /**< Number of CRTCs on this device */ | 1198 | unsigned int num_crtcs; /**< Number of CRTCs on this device */ |
1185 | void *dev_private; /**< device private data */ | ||
1186 | struct inode *anon_inode; | ||
1187 | struct drm_sigdata sigdata; /**< For block_all_signals */ | 1199 | struct drm_sigdata sigdata; /**< For block_all_signals */ |
1188 | sigset_t sigmask; | 1200 | sigset_t sigmask; |
1189 | 1201 | ||
1190 | struct drm_driver *driver; | ||
1191 | struct drm_local_map *agp_buffer_map; | 1202 | struct drm_local_map *agp_buffer_map; |
1192 | unsigned int agp_buffer_token; | 1203 | unsigned int agp_buffer_token; |
1193 | struct drm_minor *control; /**< Control node for card */ | ||
1194 | struct drm_minor *primary; /**< render type primary screen head */ | ||
1195 | struct drm_minor *render; /**< render node for card */ | ||
1196 | 1204 | ||
1197 | struct drm_mode_config mode_config; /**< Current mode config */ | 1205 | struct drm_mode_config mode_config; /**< Current mode config */ |
1198 | 1206 | ||
@@ -1203,8 +1211,6 @@ struct drm_device { | |||
1203 | struct drm_vma_offset_manager *vma_offset_manager; | 1211 | struct drm_vma_offset_manager *vma_offset_manager; |
1204 | /*@} */ | 1212 | /*@} */ |
1205 | int switch_power_state; | 1213 | int switch_power_state; |
1206 | |||
1207 | atomic_t unplugged; /* device has been unplugged or gone away */ | ||
1208 | }; | 1214 | }; |
1209 | 1215 | ||
1210 | #define DRM_SWITCH_POWER_ON 0 | 1216 | #define DRM_SWITCH_POWER_ON 0 |
@@ -1661,9 +1667,14 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) | |||
1661 | 1667 | ||
1662 | struct drm_device *drm_dev_alloc(struct drm_driver *driver, | 1668 | struct drm_device *drm_dev_alloc(struct drm_driver *driver, |
1663 | struct device *parent); | 1669 | struct device *parent); |
1664 | void drm_dev_free(struct drm_device *dev); | 1670 | void drm_dev_ref(struct drm_device *dev); |
1671 | void drm_dev_unref(struct drm_device *dev); | ||
1665 | int drm_dev_register(struct drm_device *dev, unsigned long flags); | 1672 | int drm_dev_register(struct drm_device *dev, unsigned long flags); |
1666 | void drm_dev_unregister(struct drm_device *dev); | 1673 | void drm_dev_unregister(struct drm_device *dev); |
1674 | |||
1675 | struct drm_minor *drm_minor_acquire(unsigned int minor_id); | ||
1676 | void drm_minor_release(struct drm_minor *minor); | ||
1677 | |||
1667 | /*@}*/ | 1678 | /*@}*/ |
1668 | 1679 | ||
1669 | /* PCI section */ | 1680 | /* PCI section */ |