aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_drv.c71
-rw-r--r--drivers/gpu/drm/drm_stub.c89
-rw-r--r--drivers/gpu/drm/drm_sysfs.c8
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c38
-rw-r--r--include/drm/drmP.h2
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)
252int drm_init(struct drm_driver *driver) 252int 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
286EXPORT_SYMBOL(drm_init); 290EXPORT_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 */
295static 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
343void drm_exit(struct drm_driver *driver) 292void 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 413EXPORT_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 */
423int 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 */
450void 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}
504EXPORT_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);
42unsigned int i915_fbpercrtc = 0; 42unsigned int i915_fbpercrtc = 0;
43module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); 43module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
44 44
45static struct drm_driver driver;
46
45static struct pci_device_id pciidlist[] = { 47static 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
122static int __devinit
123i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
124{
125 return drm_get_dev(pdev, ent, &driver);
126}
127
128static void
129i915_pci_remove(struct pci_dev *pdev)
130{
131 struct drm_device *dev = pci_get_drvdata(pdev);
132
133 drm_put_dev(dev);
134}
135
136static int
137i915_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
144static int
145i915_pci_resume(struct pci_dev *pdev)
146{
147 struct drm_device *dev = pci_get_drvdata(pdev);
148
149 return i915_resume(dev);
150}
151
120static struct vm_operations_struct i915_gem_vm_ops = { 152static 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);
1265extern void drm_master_put(struct drm_master **master); 1265extern void drm_master_put(struct drm_master **master);
1266extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, 1266extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
1267 struct drm_driver *driver); 1267 struct drm_driver *driver);
1268extern int drm_put_dev(struct drm_device *dev); 1268extern void drm_put_dev(struct drm_device *dev);
1269extern int drm_put_minor(struct drm_minor **minor); 1269extern int drm_put_minor(struct drm_minor **minor);
1270extern unsigned int drm_debug; 1270extern unsigned int drm_debug;
1271 1271