diff options
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 71 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 89 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 38 | ||||
-rw-r--r-- | include/drm/drmP.h | 2 |
5 files changed, 123 insertions, 85 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 6394c2b67658..1441655388ab 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -252,15 +252,19 @@ int drm_lastclose(struct drm_device * dev) | |||
252 | int drm_init(struct drm_driver *driver) | 252 | int drm_init(struct drm_driver *driver) |
253 | { | 253 | { |
254 | struct pci_dev *pdev = NULL; | 254 | struct pci_dev *pdev = NULL; |
255 | struct pci_device_id *pid; | 255 | const struct pci_device_id *pid; |
256 | int i; | 256 | int i; |
257 | 257 | ||
258 | DRM_DEBUG("\n"); | 258 | DRM_DEBUG("\n"); |
259 | 259 | ||
260 | INIT_LIST_HEAD(&driver->device_list); | 260 | INIT_LIST_HEAD(&driver->device_list); |
261 | 261 | ||
262 | if (driver->driver_features & DRIVER_MODESET) | ||
263 | return pci_register_driver(&driver->pci_driver); | ||
264 | |||
265 | /* If not using KMS, fall back to stealth mode manual scanning. */ | ||
262 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { | 266 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { |
263 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; | 267 | pid = &driver->pci_driver.id_table[i]; |
264 | 268 | ||
265 | /* Loop around setting up a DRM device for each PCI device | 269 | /* Loop around setting up a DRM device for each PCI device |
266 | * matching our ID and device class. If we had the internal | 270 | * matching our ID and device class. If we had the internal |
@@ -285,68 +289,17 @@ int drm_init(struct drm_driver *driver) | |||
285 | 289 | ||
286 | EXPORT_SYMBOL(drm_init); | 290 | EXPORT_SYMBOL(drm_init); |
287 | 291 | ||
288 | /** | ||
289 | * Called via cleanup_module() at module unload time. | ||
290 | * | ||
291 | * Cleans up all DRM device, calling drm_lastclose(). | ||
292 | * | ||
293 | * \sa drm_init | ||
294 | */ | ||
295 | static void drm_cleanup(struct drm_device * dev) | ||
296 | { | ||
297 | struct drm_map_list *r_list, *list_temp; | ||
298 | DRM_DEBUG("\n"); | ||
299 | |||
300 | if (!dev) { | ||
301 | DRM_ERROR("cleanup called no dev\n"); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | drm_vblank_cleanup(dev); | ||
306 | |||
307 | drm_lastclose(dev); | ||
308 | |||
309 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && | ||
310 | dev->agp && dev->agp->agp_mtrr >= 0) { | ||
311 | int retval; | ||
312 | retval = mtrr_del(dev->agp->agp_mtrr, | ||
313 | dev->agp->agp_info.aper_base, | ||
314 | dev->agp->agp_info.aper_size * 1024 * 1024); | ||
315 | DRM_DEBUG("mtrr_del=%d\n", retval); | ||
316 | } | ||
317 | |||
318 | if (dev->driver->unload) | ||
319 | dev->driver->unload(dev); | ||
320 | |||
321 | if (drm_core_has_AGP(dev) && dev->agp) { | ||
322 | drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); | ||
323 | dev->agp = NULL; | ||
324 | } | ||
325 | |||
326 | drm_ht_remove(&dev->map_hash); | ||
327 | drm_ctxbitmap_cleanup(dev); | ||
328 | |||
329 | list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) | ||
330 | drm_rmmap(dev, r_list->map); | ||
331 | |||
332 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
333 | drm_put_minor(&dev->control); | ||
334 | |||
335 | if (dev->driver->driver_features & DRIVER_GEM) | ||
336 | drm_gem_destroy(dev); | ||
337 | |||
338 | drm_put_minor(&dev->primary); | ||
339 | if (drm_put_dev(dev)) | ||
340 | DRM_ERROR("Cannot unload module\n"); | ||
341 | } | ||
342 | |||
343 | void drm_exit(struct drm_driver *driver) | 292 | void drm_exit(struct drm_driver *driver) |
344 | { | 293 | { |
345 | struct drm_device *dev, *tmp; | 294 | struct drm_device *dev, *tmp; |
346 | DRM_DEBUG("\n"); | 295 | DRM_DEBUG("\n"); |
347 | 296 | ||
348 | list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) | 297 | if (driver->driver_features & DRIVER_MODESET) { |
349 | drm_cleanup(dev); | 298 | pci_unregister_driver(&driver->pci_driver); |
299 | } else { | ||
300 | list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) | ||
301 | drm_put_dev(dev); | ||
302 | } | ||
350 | 303 | ||
351 | DRM_INFO("Module unloaded\n"); | 304 | DRM_INFO("Module unloaded\n"); |
352 | } | 305 | } |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 7c8b15b22bf2..f51c685011ed 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -372,6 +372,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
372 | } | 372 | } |
373 | 373 | ||
374 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 374 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
375 | pci_set_drvdata(pdev, dev); | ||
375 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | 376 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); |
376 | if (ret) | 377 | if (ret) |
377 | goto err_g2; | 378 | goto err_g2; |
@@ -409,29 +410,7 @@ err_g1: | |||
409 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); | 410 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); |
410 | return ret; | 411 | return ret; |
411 | } | 412 | } |
412 | 413 | EXPORT_SYMBOL(drm_get_dev); | |
413 | /** | ||
414 | * Put a device minor number. | ||
415 | * | ||
416 | * \param dev device data structure | ||
417 | * \return always zero | ||
418 | * | ||
419 | * Cleans up the proc resources. If it is the last minor then release the foreign | ||
420 | * "drm" data, otherwise unregisters the "drm" data, frees the dev list and | ||
421 | * unregisters the character device. | ||
422 | */ | ||
423 | int drm_put_dev(struct drm_device * dev) | ||
424 | { | ||
425 | DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name); | ||
426 | |||
427 | if (dev->devname) { | ||
428 | drm_free(dev->devname, strlen(dev->devname) + 1, | ||
429 | DRM_MEM_DRIVER); | ||
430 | dev->devname = NULL; | ||
431 | } | ||
432 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); | ||
433 | return 0; | ||
434 | } | ||
435 | 414 | ||
436 | /** | 415 | /** |
437 | * Put a secondary minor number. | 416 | * Put a secondary minor number. |
@@ -459,3 +438,67 @@ int drm_put_minor(struct drm_minor **minor_p) | |||
459 | *minor_p = NULL; | 438 | *minor_p = NULL; |
460 | return 0; | 439 | return 0; |
461 | } | 440 | } |
441 | |||
442 | /** | ||
443 | * Called via drm_exit() at module unload time or when pci device is | ||
444 | * unplugged. | ||
445 | * | ||
446 | * Cleans up all DRM device, calling drm_lastclose(). | ||
447 | * | ||
448 | * \sa drm_init | ||
449 | */ | ||
450 | void drm_put_dev(struct drm_device *dev) | ||
451 | { | ||
452 | struct drm_driver *driver = dev->driver; | ||
453 | struct drm_map_list *r_list, *list_temp; | ||
454 | |||
455 | DRM_DEBUG("\n"); | ||
456 | |||
457 | if (!dev) { | ||
458 | DRM_ERROR("cleanup called no dev\n"); | ||
459 | return; | ||
460 | } | ||
461 | |||
462 | drm_vblank_cleanup(dev); | ||
463 | |||
464 | drm_lastclose(dev); | ||
465 | |||
466 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && | ||
467 | dev->agp && dev->agp->agp_mtrr >= 0) { | ||
468 | int retval; | ||
469 | retval = mtrr_del(dev->agp->agp_mtrr, | ||
470 | dev->agp->agp_info.aper_base, | ||
471 | dev->agp->agp_info.aper_size * 1024 * 1024); | ||
472 | DRM_DEBUG("mtrr_del=%d\n", retval); | ||
473 | } | ||
474 | |||
475 | if (dev->driver->unload) | ||
476 | dev->driver->unload(dev); | ||
477 | |||
478 | if (drm_core_has_AGP(dev) && dev->agp) { | ||
479 | drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); | ||
480 | dev->agp = NULL; | ||
481 | } | ||
482 | |||
483 | drm_ht_remove(&dev->map_hash); | ||
484 | drm_ctxbitmap_cleanup(dev); | ||
485 | |||
486 | list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) | ||
487 | drm_rmmap(dev, r_list->map); | ||
488 | |||
489 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
490 | drm_put_minor(&dev->control); | ||
491 | |||
492 | if (driver->driver_features & DRIVER_GEM) | ||
493 | drm_gem_destroy(dev); | ||
494 | |||
495 | drm_put_minor(&dev->primary); | ||
496 | |||
497 | if (dev->devname) { | ||
498 | drm_free(dev->devname, strlen(dev->devname) + 1, | ||
499 | DRM_MEM_DRIVER); | ||
500 | dev->devname = NULL; | ||
501 | } | ||
502 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); | ||
503 | } | ||
504 | EXPORT_SYMBOL(drm_put_dev); | ||
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 5aa6780652aa..480546b542fe 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -35,7 +35,9 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
35 | struct drm_minor *drm_minor = to_drm_minor(dev); | 35 | struct drm_minor *drm_minor = to_drm_minor(dev); |
36 | struct drm_device *drm_dev = drm_minor->dev; | 36 | struct drm_device *drm_dev = drm_minor->dev; |
37 | 37 | ||
38 | if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend) | 38 | if (drm_minor->type == DRM_MINOR_LEGACY && |
39 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | ||
40 | drm_dev->driver->suspend) | ||
39 | return drm_dev->driver->suspend(drm_dev, state); | 41 | return drm_dev->driver->suspend(drm_dev, state); |
40 | 42 | ||
41 | return 0; | 43 | return 0; |
@@ -53,7 +55,9 @@ static int drm_sysfs_resume(struct device *dev) | |||
53 | struct drm_minor *drm_minor = to_drm_minor(dev); | 55 | struct drm_minor *drm_minor = to_drm_minor(dev); |
54 | struct drm_device *drm_dev = drm_minor->dev; | 56 | struct drm_device *drm_dev = drm_minor->dev; |
55 | 57 | ||
56 | if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume) | 58 | if (drm_minor->type == DRM_MINOR_LEGACY && |
59 | !drm_core_check_feature(drm_dev, DRIVER_MODESET) && | ||
60 | drm_dev->driver->resume) | ||
57 | return drm_dev->driver->resume(drm_dev); | 61 | return drm_dev->driver->resume(drm_dev); |
58 | 62 | ||
59 | return 0; | 63 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b293ef0bae71..d10ec9e5033c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -42,6 +42,8 @@ module_param_named(modeset, i915_modeset, int, 0400); | |||
42 | unsigned int i915_fbpercrtc = 0; | 42 | unsigned int i915_fbpercrtc = 0; |
43 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); | 43 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); |
44 | 44 | ||
45 | static struct drm_driver driver; | ||
46 | |||
45 | static struct pci_device_id pciidlist[] = { | 47 | static struct pci_device_id pciidlist[] = { |
46 | i915_PCI_IDS | 48 | i915_PCI_IDS |
47 | }; | 49 | }; |
@@ -117,6 +119,36 @@ static int i915_resume(struct drm_device *dev) | |||
117 | return ret; | 119 | return ret; |
118 | } | 120 | } |
119 | 121 | ||
122 | static int __devinit | ||
123 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
124 | { | ||
125 | return drm_get_dev(pdev, ent, &driver); | ||
126 | } | ||
127 | |||
128 | static void | ||
129 | i915_pci_remove(struct pci_dev *pdev) | ||
130 | { | ||
131 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
132 | |||
133 | drm_put_dev(dev); | ||
134 | } | ||
135 | |||
136 | static int | ||
137 | i915_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
138 | { | ||
139 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
140 | |||
141 | return i915_suspend(dev, state); | ||
142 | } | ||
143 | |||
144 | static int | ||
145 | i915_pci_resume(struct pci_dev *pdev) | ||
146 | { | ||
147 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
148 | |||
149 | return i915_resume(dev); | ||
150 | } | ||
151 | |||
120 | static struct vm_operations_struct i915_gem_vm_ops = { | 152 | static struct vm_operations_struct i915_gem_vm_ops = { |
121 | .fault = i915_gem_fault, | 153 | .fault = i915_gem_fault, |
122 | .open = drm_gem_vm_open, | 154 | .open = drm_gem_vm_open, |
@@ -172,6 +204,12 @@ static struct drm_driver driver = { | |||
172 | .pci_driver = { | 204 | .pci_driver = { |
173 | .name = DRIVER_NAME, | 205 | .name = DRIVER_NAME, |
174 | .id_table = pciidlist, | 206 | .id_table = pciidlist, |
207 | .probe = i915_pci_probe, | ||
208 | .remove = i915_pci_remove, | ||
209 | #ifdef CONFIG_PM | ||
210 | .resume = i915_pci_resume, | ||
211 | .suspend = i915_pci_suspend, | ||
212 | #endif | ||
175 | }, | 213 | }, |
176 | 214 | ||
177 | .name = DRIVER_NAME, | 215 | .name = DRIVER_NAME, |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c91fbb68b460..533d35baa085 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -1265,7 +1265,7 @@ extern struct drm_master *drm_master_get(struct drm_master *master); | |||
1265 | extern void drm_master_put(struct drm_master **master); | 1265 | extern void drm_master_put(struct drm_master **master); |
1266 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | 1266 | extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, |
1267 | struct drm_driver *driver); | 1267 | struct drm_driver *driver); |
1268 | extern int drm_put_dev(struct drm_device *dev); | 1268 | extern void drm_put_dev(struct drm_device *dev); |
1269 | extern int drm_put_minor(struct drm_minor **minor); | 1269 | extern int drm_put_minor(struct drm_minor **minor); |
1270 | extern unsigned int drm_debug; | 1270 | extern unsigned int drm_debug; |
1271 | 1271 | ||