diff options
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_drv.c')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.c | 103 |
1 files changed, 73 insertions, 30 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index fee8748bdca5..a89d26798967 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -62,20 +62,68 @@ static struct pci_driver qxl_pci_driver; static int qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct qxl_device *qdev; + int ret; + if (pdev->revision < 4) { DRM_ERROR("qxl too old, doesn't support client_monitors_config," " use xf86-video-qxl in user mode"); return -EINVAL; /* TODO: ENODEV ? */ } - return drm_get_pci_dev(pdev, ent, &qxl_driver); + + qdev = kzalloc(sizeof(*qdev), GFP_KERNEL); + if (!qdev) + return -ENOMEM; + + ret = drm_dev_init(&qdev->ddev, &qxl_driver, &pdev->dev); + if (ret) + goto err_free; + + ret = pci_enable_device(pdev); + if (ret) + goto err_free; + + qdev->pdev = pdev; + + pci_set_drvdata(pdev, qdev); + + + mutex_lock(&drm_global_mutex); + + ret = drm_register_minors(&qdev->ddev); + if (ret) + goto err_unlock; + + ret = qxl_driver_load(qdev, ent->driver_data); + if (ret) + goto err_unlock; + + /* setup grouping for legacy outputs */ + ret = drm_mode_group_init_legacy_group(&qdev->ddev, + &qdev->ddev.primary->mode_group); + +err_unlock: + mutex_unlock(&drm_global_mutex); + + return ret; +err_pci: + pci_disable_device(pdev); +err_free: + kfree(qdev); + return ret; } static void qxl_pci_remove(struct pci_dev *pdev) { - struct drm_device *dev = pci_get_drvdata(pdev); + struct qxl_device *qdev = pci_get_drvdata(pdev); + struct drm_device *dev = &qdev->ddev; - drm_put_dev(dev); + qxl_driver_unload(qdev); + drm_dev_unregister(dev); + + drm_dev_fini(dev); + kfree(qdev); } static const struct file_operations qxl_fops = { @@ -87,20 +135,19 @@ static const struct file_operations qxl_fops = { .mmap = qxl_mmap, }; -static int qxl_drm_freeze(struct drm_device *dev) +static int qxl_drm_freeze(struct qxl_device *qdev) { - struct pci_dev *pdev = dev->pdev; - struct qxl_device *qdev = dev->dev_private; + struct pci_dev *pdev = qdev->ddev.pdev; struct drm_crtc *crtc; - drm_kms_helper_poll_disable(dev); + drm_kms_helper_poll_disable(&qdev->ddev); console_lock(); qxl_fbdev_set_suspend(qdev, 1); console_unlock(); /* unpin the front buffers */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + list_for_each_entry(crtc, &qdev->ddev.mode_config.crtc_list, head) { struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; if (crtc->enabled) (*crtc_funcs->disable)(crtc); @@ -119,10 +166,8 @@ static int qxl_drm_freeze(struct drm_device *dev) return 0; } -static int qxl_drm_resume(struct drm_device *dev, bool thaw) +static int qxl_drm_resume(struct qxl_device *qdev, bool thaw) { - struct qxl_device *qdev = dev->dev_private; - qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; if (!thaw) { qxl_reinit_memslots(qdev); @@ -130,23 +175,23 @@ static int qxl_drm_resume(struct drm_device *dev, bool thaw) } qxl_create_monitors_object(qdev); - drm_helper_resume_force_mode(dev); + drm_helper_resume_force_mode(&qdev->ddev); console_lock(); qxl_fbdev_set_suspend(qdev, 0); console_unlock(); - drm_kms_helper_poll_enable(dev); + drm_kms_helper_poll_enable(&qdev->ddev); return 0; } static int qxl_pm_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct qxl_device *qdev = pci_get_drvdata(pdev); int error; - error = qxl_drm_freeze(drm_dev); + error = qxl_drm_freeze(qdev); if (error) return error; @@ -158,7 +203,7 @@ static int qxl_pm_suspend(struct device *dev) static int qxl_pm_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct qxl_device *qdev = pci_get_drvdata(pdev); pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); @@ -166,33 +211,32 @@ static int qxl_pm_resume(struct device *dev) return -EIO; } - return qxl_drm_resume(drm_dev, false); + return qxl_drm_resume(qdev, false); } static int qxl_pm_thaw(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct qxl_device *qdev = pci_get_drvdata(pdev); - return qxl_drm_resume(drm_dev, true); + return qxl_drm_resume(qdev, true); } static int qxl_pm_freeze(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct qxl_device *qdev = pci_get_drvdata(pdev); - return qxl_drm_freeze(drm_dev); + return qxl_drm_freeze(qdev); } static int qxl_pm_restore(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct qxl_device *qdev = drm_dev->dev_private; + struct qxl_device *qdev = pci_get_drvdata(pdev); qxl_io_reset(qdev); - return qxl_drm_resume(drm_dev, false); + return qxl_drm_resume(qdev, false); } static const struct dev_pm_ops qxl_pm_ops = { @@ -214,9 +258,6 @@ static struct pci_driver qxl_pci_driver = { static struct drm_driver qxl_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, - .dev_priv_size = 0, - .load = qxl_driver_load, - .unload = qxl_driver_unload, .dumb_create = qxl_mode_dumb_create, .dumb_map_offset = qxl_mode_dumb_mmap, @@ -230,7 +271,6 @@ static struct drm_driver qxl_driver = { .gem_close_object = qxl_gem_object_close, .fops = &qxl_fops, .ioctls = qxl_ioctls, - .irq_handler = qxl_irq_handler, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, @@ -249,12 +289,15 @@ static int __init qxl_init(void) if (qxl_modeset == 0) return -EINVAL; qxl_driver.num_ioctls = qxl_max_ioctls; - return drm_pci_init(&qxl_driver, &qxl_pci_driver); + + drm_pci_driver_init(&qxl_driver, &qxl_pci_driver); + + return pci_register_driver(&qxl_pci_driver); } static void __exit qxl_exit(void) { - drm_pci_exit(&qxl_driver, &qxl_pci_driver); + pci_unregister_driver(&qxl_pci_driver); } module_init(qxl_init); |