static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vdev) { struct pci_dev *pdev = to_pci_dev(vdev->dev.parent); const char *pname = dev_name(&pdev->dev); bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; char unique[20]; DRM_INFO("pci: %s detected at %s\n", vga ? "virtio-vga" : "virtio-gpu-pci", pname); dev->pdev = pdev; if (vga) drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "virtiodrmfb"); /* * Normally the drm_dev_set_unique() call is done by core DRM. * The following comment covers, why virtio cannot rely on it. * * Unlike the other virtual GPU drivers, virtio abstracts the * underlying bus type by using struct virtio_device. * * Hence the dev_is_pci() check, used in core DRM, will fail * and the unique returned will be the virtio_device "virtio0", * while a "pci:..." one is required. * * A few other ideas were considered: * - Extend the dev_is_pci() check [in drm_set_busid] to * consider virtio. * Seems like a bigger hack than what we have already. * * - Point drm_device::dev to the parent of the virtio_device * Semantic changes: * * Using the wrong device for i2c, framebuffer_alloc and * prime import. * Visual changes: * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer, * will print the wrong information. * * We could address the latter issues, by introducing * drm_device::bus_dev, ... which would be used solely for this. * * So for the moment keep things as-is, with a bulky comment * for the next person who feels like removing this * drm_dev_set_unique() quirk. */ snprintf(unique, sizeof(unique), "pci:%s", pname); return drm_dev_set_unique(dev, unique); }
static int rcar_du_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct rcar_du_device *rcdu; struct drm_connector *connector; struct drm_device *ddev; struct resource *mem; int ret; if (np == NULL) { dev_err(&pdev->dev, "no device tree node\n"); return -ENODEV; } /* Allocate and initialize the DRM and R-Car device structures. */ rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL); if (rcdu == NULL) return -ENOMEM; init_waitqueue_head(&rcdu->commit.wait); rcdu->dev = &pdev->dev; rcdu->info = of_match_device(rcar_du_of_table, rcdu->dev)->data; ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev); if (!ddev) return -ENOMEM; drm_dev_set_unique(ddev, dev_name(&pdev->dev)); rcdu->ddev = ddev; ddev->dev_private = rcdu; platform_set_drvdata(pdev, rcdu); /* I/O resources */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(rcdu->mmio)) { ret = PTR_ERR(rcdu->mmio); goto error; } /* Initialize vertical blanking interrupts handling. Start with vblank * disabled for all CRTCs. */ ret = drm_vblank_init(ddev, (1 << rcdu->info->num_crtcs) - 1); if (ret < 0) { dev_err(&pdev->dev, "failed to initialize vblank\n"); goto error; } /* DRM/KMS objects */ ret = rcar_du_modeset_init(rcdu); if (ret < 0) { dev_err(&pdev->dev, "failed to initialize DRM/KMS (%d)\n", ret); goto error; } ddev->irq_enabled = 1; /* Register the DRM device with the core and the connectors with * sysfs. */ ret = drm_dev_register(ddev, 0); if (ret) goto error; mutex_lock(&ddev->mode_config.mutex); drm_for_each_connector(connector, ddev) { ret = drm_connector_register(connector); if (ret < 0) break; }
/** * drm_dev_init - Initialise new DRM device * @dev: DRM device * @driver: DRM driver * @parent: Parent device object * * Initialize a new DRM device. No device registration is done. * Call drm_dev_register() to advertice the device to user space and register it * with other core subsystems. This should be done last in the device * initialization sequence to make sure userspace can't access an inconsistent * state. * * The initial ref-count of the object is 1. Use drm_dev_ref() and * drm_dev_unref() to take and drop further ref-counts. * * Note that for purely virtual devices @parent can be NULL. * * Drivers that do not want to allocate their own device struct * embedding struct &drm_device can call drm_dev_alloc() instead. * * RETURNS: * 0 on success, or error code on failure. */ int drm_dev_init(struct drm_device *dev, struct drm_driver *driver, struct device *parent) { int ret; kref_init(&dev->ref); dev->dev = parent; dev->driver = driver; INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->ctxlist); INIT_LIST_HEAD(&dev->vmalist); INIT_LIST_HEAD(&dev->maplist); INIT_LIST_HEAD(&dev->vblank_event_list); spin_lock_init(&dev->buf_lock); spin_lock_init(&dev->event_lock); mutex_init(&dev->struct_mutex); mutex_init(&dev->filelist_mutex); mutex_init(&dev->ctxlist_mutex); mutex_init(&dev->master_mutex); dev->anon_inode = drm_fs_inode_new(); if (IS_ERR(dev->anon_inode)) { ret = PTR_ERR(dev->anon_inode); DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret); goto err_free; } if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL); if (ret) goto err_minors; } if (drm_core_check_feature(dev, DRIVER_RENDER)) { ret = drm_minor_alloc(dev, DRM_MINOR_RENDER); if (ret) goto err_minors; } ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY); if (ret) goto err_minors; ret = drm_ht_create(&dev->map_hash, 12); if (ret) goto err_minors; drm_legacy_ctxbitmap_init(dev); if (drm_core_check_feature(dev, DRIVER_GEM)) { ret = drm_gem_init(dev); if (ret) { DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n"); goto err_ctxbitmap; } } /* Use the parent device name as DRM device unique identifier, but fall * back to the driver name for virtual devices like vgem. */ ret = drm_dev_set_unique(dev, parent ? dev_name(parent) : driver->name); if (ret) goto err_setunique; return 0; err_setunique: if (drm_core_check_feature(dev, DRIVER_GEM)) drm_gem_destroy(dev); err_ctxbitmap: drm_legacy_ctxbitmap_cleanup(dev); drm_ht_remove(&dev->map_hash); err_minors: drm_minor_free(dev, DRM_MINOR_PRIMARY); drm_minor_free(dev, DRM_MINOR_RENDER); drm_minor_free(dev, DRM_MINOR_CONTROL); drm_fs_inode_free(dev->anon_inode); err_free: mutex_destroy(&dev->master_mutex); return ret; }