linux/drivers/gpu/drm/gud/gud_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright 2020 Noralf Trønnes
   4 */
   5
   6#include <linux/dma-buf.h>
   7#include <linux/dma-mapping.h>
   8#include <linux/lz4.h>
   9#include <linux/module.h>
  10#include <linux/platform_device.h>
  11#include <linux/string_helpers.h>
  12#include <linux/usb.h>
  13#include <linux/vmalloc.h>
  14#include <linux/workqueue.h>
  15
  16#include <drm/drm_atomic_helper.h>
  17#include <drm/drm_damage_helper.h>
  18#include <drm/drm_debugfs.h>
  19#include <drm/drm_drv.h>
  20#include <drm/drm_fb_helper.h>
  21#include <drm/drm_fourcc.h>
  22#include <drm/drm_gem_atomic_helper.h>
  23#include <drm/drm_gem_framebuffer_helper.h>
  24#include <drm/drm_gem_shmem_helper.h>
  25#include <drm/drm_managed.h>
  26#include <drm/drm_print.h>
  27#include <drm/drm_probe_helper.h>
  28#include <drm/drm_simple_kms_helper.h>
  29#include <drm/gud.h>
  30
  31#include "gud_internal.h"
  32
  33/* Only used internally */
  34static const struct drm_format_info gud_drm_format_r1 = {
  35        .format = GUD_DRM_FORMAT_R1,
  36        .num_planes = 1,
  37        .char_per_block = { 1, 0, 0 },
  38        .block_w = { 8, 0, 0 },
  39        .block_h = { 1, 0, 0 },
  40        .hsub = 1,
  41        .vsub = 1,
  42};
  43
  44static const struct drm_format_info gud_drm_format_xrgb1111 = {
  45        .format = GUD_DRM_FORMAT_XRGB1111,
  46        .num_planes = 1,
  47        .char_per_block = { 1, 0, 0 },
  48        .block_w = { 2, 0, 0 },
  49        .block_h = { 1, 0, 0 },
  50        .hsub = 1,
  51        .vsub = 1,
  52};
  53
  54static int gud_usb_control_msg(struct usb_interface *intf, bool in,
  55                               u8 request, u16 value, void *buf, size_t len)
  56{
  57        u8 requesttype = USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
  58        u8 ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
  59        struct usb_device *usb = interface_to_usbdev(intf);
  60        unsigned int pipe;
  61
  62        if (len && !buf)
  63                return -EINVAL;
  64
  65        if (in) {
  66                pipe = usb_rcvctrlpipe(usb, 0);
  67                requesttype |= USB_DIR_IN;
  68        } else {
  69                pipe = usb_sndctrlpipe(usb, 0);
  70                requesttype |= USB_DIR_OUT;
  71        }
  72
  73        return usb_control_msg(usb, pipe, request, requesttype, value,
  74                               ifnum, buf, len, USB_CTRL_GET_TIMEOUT);
  75}
  76
  77static int gud_get_display_descriptor(struct usb_interface *intf,
  78                                      struct gud_display_descriptor_req *desc)
  79{
  80        void *buf;
  81        int ret;
  82
  83        buf = kmalloc(sizeof(*desc), GFP_KERNEL);
  84        if (!buf)
  85                return -ENOMEM;
  86
  87        ret = gud_usb_control_msg(intf, true, GUD_REQ_GET_DESCRIPTOR, 0, buf, sizeof(*desc));
  88        memcpy(desc, buf, sizeof(*desc));
  89        kfree(buf);
  90        if (ret < 0)
  91                return ret;
  92        if (ret != sizeof(*desc))
  93                return -EIO;
  94
  95        if (desc->magic != le32_to_cpu(GUD_DISPLAY_MAGIC))
  96                return -ENODATA;
  97
  98        DRM_DEV_DEBUG_DRIVER(&intf->dev,
  99                             "version=%u flags=0x%x compression=0x%x max_buffer_size=%u\n",
 100                             desc->version, le32_to_cpu(desc->flags), desc->compression,
 101                             le32_to_cpu(desc->max_buffer_size));
 102
 103        if (!desc->version || !desc->max_width || !desc->max_height ||
 104            le32_to_cpu(desc->min_width) > le32_to_cpu(desc->max_width) ||
 105            le32_to_cpu(desc->min_height) > le32_to_cpu(desc->max_height))
 106                return -EINVAL;
 107
 108        return 0;
 109}
 110
 111static int gud_status_to_errno(u8 status)
 112{
 113        switch (status) {
 114        case GUD_STATUS_OK:
 115                return 0;
 116        case GUD_STATUS_BUSY:
 117                return -EBUSY;
 118        case GUD_STATUS_REQUEST_NOT_SUPPORTED:
 119                return -EOPNOTSUPP;
 120        case GUD_STATUS_PROTOCOL_ERROR:
 121                return -EPROTO;
 122        case GUD_STATUS_INVALID_PARAMETER:
 123                return -EINVAL;
 124        case GUD_STATUS_ERROR:
 125                return -EREMOTEIO;
 126        default:
 127                return -EREMOTEIO;
 128        }
 129}
 130
 131static int gud_usb_get_status(struct usb_interface *intf)
 132{
 133        int ret, status = -EIO;
 134        u8 *buf;
 135
 136        buf = kmalloc(sizeof(*buf), GFP_KERNEL);
 137        if (!buf)
 138                return -ENOMEM;
 139
 140        ret = gud_usb_control_msg(intf, true, GUD_REQ_GET_STATUS, 0, buf, sizeof(*buf));
 141        if (ret == sizeof(*buf))
 142                status = gud_status_to_errno(*buf);
 143        kfree(buf);
 144
 145        if (ret < 0)
 146                return ret;
 147
 148        return status;
 149}
 150
 151static int gud_usb_transfer(struct gud_device *gdrm, bool in, u8 request, u16 index,
 152                            void *buf, size_t len)
 153{
 154        struct usb_interface *intf = to_usb_interface(gdrm->drm.dev);
 155        int idx, ret;
 156
 157        drm_dbg(&gdrm->drm, "%s: request=0x%x index=%u len=%zu\n",
 158                in ? "get" : "set", request, index, len);
 159
 160        if (!drm_dev_enter(&gdrm->drm, &idx))
 161                return -ENODEV;
 162
 163        mutex_lock(&gdrm->ctrl_lock);
 164
 165        ret = gud_usb_control_msg(intf, in, request, index, buf, len);
 166        if (ret == -EPIPE || ((gdrm->flags & GUD_DISPLAY_FLAG_STATUS_ON_SET) && !in && ret >= 0)) {
 167                int status;
 168
 169                status = gud_usb_get_status(intf);
 170                if (status < 0) {
 171                        ret = status;
 172                } else if (ret < 0) {
 173                        dev_err_once(gdrm->drm.dev,
 174                                     "Unexpected status OK for failed transfer\n");
 175                        ret = -EPIPE;
 176                }
 177        }
 178
 179        if (ret < 0) {
 180                drm_dbg(&gdrm->drm, "ret=%d\n", ret);
 181                gdrm->stats_num_errors++;
 182        }
 183
 184        mutex_unlock(&gdrm->ctrl_lock);
 185        drm_dev_exit(idx);
 186
 187        return ret;
 188}
 189
 190/*
 191 * @buf cannot be allocated on the stack.
 192 * Returns number of bytes received or negative error code on failure.
 193 */
 194int gud_usb_get(struct gud_device *gdrm, u8 request, u16 index, void *buf, size_t max_len)
 195{
 196        return gud_usb_transfer(gdrm, true, request, index, buf, max_len);
 197}
 198
 199/*
 200 * @buf can be allocated on the stack or NULL.
 201 * Returns zero on success or negative error code on failure.
 202 */
 203int gud_usb_set(struct gud_device *gdrm, u8 request, u16 index, void *buf, size_t len)
 204{
 205        void *trbuf = NULL;
 206        int ret;
 207
 208        if (buf && len) {
 209                trbuf = kmemdup(buf, len, GFP_KERNEL);
 210                if (!trbuf)
 211                        return -ENOMEM;
 212        }
 213
 214        ret = gud_usb_transfer(gdrm, false, request, index, trbuf, len);
 215        kfree(trbuf);
 216        if (ret < 0)
 217                return ret;
 218
 219        return ret != len ? -EIO : 0;
 220}
 221
 222/*
 223 * @val can be allocated on the stack.
 224 * Returns zero on success or negative error code on failure.
 225 */
 226int gud_usb_get_u8(struct gud_device *gdrm, u8 request, u16 index, u8 *val)
 227{
 228        u8 *buf;
 229        int ret;
 230
 231        buf = kmalloc(sizeof(*val), GFP_KERNEL);
 232        if (!buf)
 233                return -ENOMEM;
 234
 235        ret = gud_usb_get(gdrm, request, index, buf, sizeof(*val));
 236        *val = *buf;
 237        kfree(buf);
 238        if (ret < 0)
 239                return ret;
 240
 241        return ret != sizeof(*val) ? -EIO : 0;
 242}
 243
 244/* Returns zero on success or negative error code on failure. */
 245int gud_usb_set_u8(struct gud_device *gdrm, u8 request, u8 val)
 246{
 247        return gud_usb_set(gdrm, request, 0, &val, sizeof(val));
 248}
 249
 250static int gud_get_properties(struct gud_device *gdrm)
 251{
 252        struct gud_property_req *properties;
 253        unsigned int i, num_properties;
 254        int ret;
 255
 256        properties = kcalloc(GUD_PROPERTIES_MAX_NUM, sizeof(*properties), GFP_KERNEL);
 257        if (!properties)
 258                return -ENOMEM;
 259
 260        ret = gud_usb_get(gdrm, GUD_REQ_GET_PROPERTIES, 0,
 261                          properties, GUD_PROPERTIES_MAX_NUM * sizeof(*properties));
 262        if (ret <= 0)
 263                goto out;
 264        if (ret % sizeof(*properties)) {
 265                ret = -EIO;
 266                goto out;
 267        }
 268
 269        num_properties = ret / sizeof(*properties);
 270        ret = 0;
 271
 272        gdrm->properties = drmm_kcalloc(&gdrm->drm, num_properties, sizeof(*gdrm->properties),
 273                                        GFP_KERNEL);
 274        if (!gdrm->properties) {
 275                ret = -ENOMEM;
 276                goto out;
 277        }
 278
 279        for (i = 0; i < num_properties; i++) {
 280                u16 prop = le16_to_cpu(properties[i].prop);
 281                u64 val = le64_to_cpu(properties[i].val);
 282
 283                switch (prop) {
 284                case GUD_PROPERTY_ROTATION:
 285                        /*
 286                         * DRM UAPI matches the protocol so use the value directly,
 287                         * but mask out any additions on future devices.
 288                         */
 289                        val &= GUD_ROTATION_MASK;
 290                        ret = drm_plane_create_rotation_property(&gdrm->pipe.plane,
 291                                                                 DRM_MODE_ROTATE_0, val);
 292                        break;
 293                default:
 294                        /* New ones might show up in future devices, skip those we don't know. */
 295                        drm_dbg(&gdrm->drm, "Ignoring unknown property: %u\n", prop);
 296                        continue;
 297                }
 298
 299                if (ret)
 300                        goto out;
 301
 302                gdrm->properties[gdrm->num_properties++] = prop;
 303        }
 304out:
 305        kfree(properties);
 306
 307        return ret;
 308}
 309
 310/*
 311 * FIXME: Dma-buf sharing requires DMA support by the importing device.
 312 *        This function is a workaround to make USB devices work as well.
 313 *        See todo.rst for how to fix the issue in the dma-buf framework.
 314 */
 315static struct drm_gem_object *gud_gem_prime_import(struct drm_device *drm, struct dma_buf *dma_buf)
 316{
 317        struct gud_device *gdrm = to_gud_device(drm);
 318
 319        if (!gdrm->dmadev)
 320                return ERR_PTR(-ENODEV);
 321
 322        return drm_gem_prime_import_dev(drm, dma_buf, gdrm->dmadev);
 323}
 324
 325static int gud_stats_debugfs(struct seq_file *m, void *data)
 326{
 327        struct drm_info_node *node = m->private;
 328        struct gud_device *gdrm = to_gud_device(node->minor->dev);
 329        char buf[10];
 330
 331        string_get_size(gdrm->bulk_len, 1, STRING_UNITS_2, buf, sizeof(buf));
 332        seq_printf(m, "Max buffer size: %s\n", buf);
 333        seq_printf(m, "Number of errors:  %u\n", gdrm->stats_num_errors);
 334
 335        seq_puts(m, "Compression:      ");
 336        if (gdrm->compression & GUD_COMPRESSION_LZ4)
 337                seq_puts(m, " lz4");
 338        if (!gdrm->compression)
 339                seq_puts(m, " none");
 340        seq_puts(m, "\n");
 341
 342        if (gdrm->compression) {
 343                u64 remainder;
 344                u64 ratio = div64_u64_rem(gdrm->stats_length, gdrm->stats_actual_length,
 345                                          &remainder);
 346                u64 ratio_frac = div64_u64(remainder * 10, gdrm->stats_actual_length);
 347
 348                seq_printf(m, "Compression ratio: %llu.%llu\n", ratio, ratio_frac);
 349        }
 350
 351        return 0;
 352}
 353
 354static const struct drm_info_list gud_debugfs_list[] = {
 355        { "stats", gud_stats_debugfs, 0, NULL },
 356};
 357
 358static void gud_debugfs_init(struct drm_minor *minor)
 359{
 360        drm_debugfs_create_files(gud_debugfs_list, ARRAY_SIZE(gud_debugfs_list),
 361                                 minor->debugfs_root, minor);
 362}
 363
 364static const struct drm_simple_display_pipe_funcs gud_pipe_funcs = {
 365        .check      = gud_pipe_check,
 366        .update     = gud_pipe_update,
 367};
 368
 369static const struct drm_mode_config_funcs gud_mode_config_funcs = {
 370        .fb_create = drm_gem_fb_create_with_dirty,
 371        .atomic_check = drm_atomic_helper_check,
 372        .atomic_commit = drm_atomic_helper_commit,
 373};
 374
 375static const u64 gud_pipe_modifiers[] = {
 376        DRM_FORMAT_MOD_LINEAR,
 377        DRM_FORMAT_MOD_INVALID
 378};
 379
 380DEFINE_DRM_GEM_FOPS(gud_fops);
 381
 382static const struct drm_driver gud_drm_driver = {
 383        .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 384        .fops                   = &gud_fops,
 385        DRM_GEM_SHMEM_DRIVER_OPS,
 386        .gem_prime_import       = gud_gem_prime_import,
 387        .debugfs_init           = gud_debugfs_init,
 388
 389        .name                   = "gud",
 390        .desc                   = "Generic USB Display",
 391        .date                   = "20200422",
 392        .major                  = 1,
 393        .minor                  = 0,
 394};
 395
 396static int gud_alloc_bulk_buffer(struct gud_device *gdrm)
 397{
 398        unsigned int i, num_pages;
 399        struct page **pages;
 400        void *ptr;
 401        int ret;
 402
 403        gdrm->bulk_buf = vmalloc_32(gdrm->bulk_len);
 404        if (!gdrm->bulk_buf)
 405                return -ENOMEM;
 406
 407        num_pages = DIV_ROUND_UP(gdrm->bulk_len, PAGE_SIZE);
 408        pages = kmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL);
 409        if (!pages)
 410                return -ENOMEM;
 411
 412        for (i = 0, ptr = gdrm->bulk_buf; i < num_pages; i++, ptr += PAGE_SIZE)
 413                pages[i] = vmalloc_to_page(ptr);
 414
 415        ret = sg_alloc_table_from_pages(&gdrm->bulk_sgt, pages, num_pages,
 416                                        0, gdrm->bulk_len, GFP_KERNEL);
 417        kfree(pages);
 418
 419        return ret;
 420}
 421
 422static void gud_free_buffers_and_mutex(void *data)
 423{
 424        struct gud_device *gdrm = data;
 425
 426        vfree(gdrm->compress_buf);
 427        gdrm->compress_buf = NULL;
 428        sg_free_table(&gdrm->bulk_sgt);
 429        vfree(gdrm->bulk_buf);
 430        gdrm->bulk_buf = NULL;
 431        mutex_destroy(&gdrm->ctrl_lock);
 432}
 433
 434static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id)
 435{
 436        const struct drm_format_info *xrgb8888_emulation_format = NULL;
 437        bool rgb565_supported = false, xrgb8888_supported = false;
 438        unsigned int num_formats_dev, num_formats = 0;
 439        struct usb_endpoint_descriptor *bulk_out;
 440        struct gud_display_descriptor_req desc;
 441        struct device *dev = &intf->dev;
 442        size_t max_buffer_size = 0;
 443        struct gud_device *gdrm;
 444        struct drm_device *drm;
 445        u8 *formats_dev;
 446        u32 *formats;
 447        int ret, i;
 448
 449        ret = usb_find_bulk_out_endpoint(intf->cur_altsetting, &bulk_out);
 450        if (ret)
 451                return ret;
 452
 453        ret = gud_get_display_descriptor(intf, &desc);
 454        if (ret) {
 455                DRM_DEV_DEBUG_DRIVER(dev, "Not a display interface: ret=%d\n", ret);
 456                return -ENODEV;
 457        }
 458
 459        if (desc.version > 1) {
 460                dev_err(dev, "Protocol version %u is not supported\n", desc.version);
 461                return -ENODEV;
 462        }
 463
 464        gdrm = devm_drm_dev_alloc(dev, &gud_drm_driver, struct gud_device, drm);
 465        if (IS_ERR(gdrm))
 466                return PTR_ERR(gdrm);
 467
 468        drm = &gdrm->drm;
 469        drm->mode_config.funcs = &gud_mode_config_funcs;
 470        ret = drmm_mode_config_init(drm);
 471        if (ret)
 472                return ret;
 473
 474        gdrm->flags = le32_to_cpu(desc.flags);
 475        gdrm->compression = desc.compression & GUD_COMPRESSION_LZ4;
 476
 477        if (gdrm->flags & GUD_DISPLAY_FLAG_FULL_UPDATE && gdrm->compression)
 478                return -EINVAL;
 479
 480        mutex_init(&gdrm->ctrl_lock);
 481        mutex_init(&gdrm->damage_lock);
 482        INIT_WORK(&gdrm->work, gud_flush_work);
 483        gud_clear_damage(gdrm);
 484
 485        ret = devm_add_action(dev, gud_free_buffers_and_mutex, gdrm);
 486        if (ret)
 487                return ret;
 488
 489        drm->mode_config.min_width = le32_to_cpu(desc.min_width);
 490        drm->mode_config.max_width = le32_to_cpu(desc.max_width);
 491        drm->mode_config.min_height = le32_to_cpu(desc.min_height);
 492        drm->mode_config.max_height = le32_to_cpu(desc.max_height);
 493
 494        formats_dev = devm_kmalloc(dev, GUD_FORMATS_MAX_NUM, GFP_KERNEL);
 495        /* Add room for emulated XRGB8888 */
 496        formats = devm_kmalloc_array(dev, GUD_FORMATS_MAX_NUM + 1, sizeof(*formats), GFP_KERNEL);
 497        if (!formats_dev || !formats)
 498                return -ENOMEM;
 499
 500        ret = gud_usb_get(gdrm, GUD_REQ_GET_FORMATS, 0, formats_dev, GUD_FORMATS_MAX_NUM);
 501        if (ret < 0)
 502                return ret;
 503
 504        num_formats_dev = ret;
 505        for (i = 0; i < num_formats_dev; i++) {
 506                const struct drm_format_info *info;
 507                size_t fmt_buf_size;
 508                u32 format;
 509
 510                format = gud_to_fourcc(formats_dev[i]);
 511                if (!format) {
 512                        drm_dbg(drm, "Unsupported format: 0x%02x\n", formats_dev[i]);
 513                        continue;
 514                }
 515
 516                if (format == GUD_DRM_FORMAT_R1)
 517                        info = &gud_drm_format_r1;
 518                else if (format == GUD_DRM_FORMAT_XRGB1111)
 519                        info = &gud_drm_format_xrgb1111;
 520                else
 521                        info = drm_format_info(format);
 522
 523                switch (format) {
 524                case GUD_DRM_FORMAT_R1:
 525                        fallthrough;
 526                case GUD_DRM_FORMAT_XRGB1111:
 527                        if (!xrgb8888_emulation_format)
 528                                xrgb8888_emulation_format = info;
 529                        break;
 530                case DRM_FORMAT_RGB565:
 531                        rgb565_supported = true;
 532                        if (!xrgb8888_emulation_format)
 533                                xrgb8888_emulation_format = info;
 534                        break;
 535                case DRM_FORMAT_XRGB8888:
 536                        xrgb8888_supported = true;
 537                        break;
 538                }
 539
 540                fmt_buf_size = drm_format_info_min_pitch(info, 0, drm->mode_config.max_width) *
 541                               drm->mode_config.max_height;
 542                max_buffer_size = max(max_buffer_size, fmt_buf_size);
 543
 544                if (format == GUD_DRM_FORMAT_R1 || format == GUD_DRM_FORMAT_XRGB1111)
 545                        continue; /* Internal not for userspace */
 546
 547                formats[num_formats++] = format;
 548        }
 549
 550        if (!num_formats && !xrgb8888_emulation_format) {
 551                dev_err(dev, "No supported pixel formats found\n");
 552                return -EINVAL;
 553        }
 554
 555        /* Prefer speed over color depth */
 556        if (rgb565_supported)
 557                drm->mode_config.preferred_depth = 16;
 558
 559        if (!xrgb8888_supported && xrgb8888_emulation_format) {
 560                gdrm->xrgb8888_emulation_format = xrgb8888_emulation_format;
 561                formats[num_formats++] = DRM_FORMAT_XRGB8888;
 562        }
 563
 564        if (desc.max_buffer_size)
 565                max_buffer_size = le32_to_cpu(desc.max_buffer_size);
 566        /* Prevent a misbehaving device from allocating loads of RAM. 4096x4096@XRGB8888 = 64 MB */
 567        if (max_buffer_size > SZ_64M)
 568                max_buffer_size = SZ_64M;
 569
 570        gdrm->bulk_pipe = usb_sndbulkpipe(interface_to_usbdev(intf), usb_endpoint_num(bulk_out));
 571        gdrm->bulk_len = max_buffer_size;
 572
 573        ret = gud_alloc_bulk_buffer(gdrm);
 574        if (ret)
 575                return ret;
 576
 577        if (gdrm->compression & GUD_COMPRESSION_LZ4) {
 578                gdrm->lz4_comp_mem = devm_kmalloc(dev, LZ4_MEM_COMPRESS, GFP_KERNEL);
 579                if (!gdrm->lz4_comp_mem)
 580                        return -ENOMEM;
 581
 582                gdrm->compress_buf = vmalloc(gdrm->bulk_len);
 583                if (!gdrm->compress_buf)
 584                        return -ENOMEM;
 585        }
 586
 587        ret = drm_simple_display_pipe_init(drm, &gdrm->pipe, &gud_pipe_funcs,
 588                                           formats, num_formats,
 589                                           gud_pipe_modifiers, NULL);
 590        if (ret)
 591                return ret;
 592
 593        devm_kfree(dev, formats);
 594        devm_kfree(dev, formats_dev);
 595
 596        ret = gud_get_properties(gdrm);
 597        if (ret) {
 598                dev_err(dev, "Failed to get properties (error=%d)\n", ret);
 599                return ret;
 600        }
 601
 602        drm_plane_enable_fb_damage_clips(&gdrm->pipe.plane);
 603
 604        ret = gud_get_connectors(gdrm);
 605        if (ret) {
 606                dev_err(dev, "Failed to get connectors (error=%d)\n", ret);
 607                return ret;
 608        }
 609
 610        drm_mode_config_reset(drm);
 611
 612        usb_set_intfdata(intf, gdrm);
 613
 614        gdrm->dmadev = usb_intf_get_dma_device(intf);
 615        if (!gdrm->dmadev)
 616                dev_warn(dev, "buffer sharing not supported");
 617
 618        ret = drm_dev_register(drm, 0);
 619        if (ret) {
 620                put_device(gdrm->dmadev);
 621                return ret;
 622        }
 623
 624        drm_kms_helper_poll_init(drm);
 625
 626        drm_fbdev_generic_setup(drm, 0);
 627
 628        return 0;
 629}
 630
 631static void gud_disconnect(struct usb_interface *interface)
 632{
 633        struct gud_device *gdrm = usb_get_intfdata(interface);
 634        struct drm_device *drm = &gdrm->drm;
 635
 636        drm_dbg(drm, "%s:\n", __func__);
 637
 638        drm_kms_helper_poll_fini(drm);
 639        drm_dev_unplug(drm);
 640        drm_atomic_helper_shutdown(drm);
 641        put_device(gdrm->dmadev);
 642        gdrm->dmadev = NULL;
 643}
 644
 645static int gud_suspend(struct usb_interface *intf, pm_message_t message)
 646{
 647        struct gud_device *gdrm = usb_get_intfdata(intf);
 648
 649        return drm_mode_config_helper_suspend(&gdrm->drm);
 650}
 651
 652static int gud_resume(struct usb_interface *intf)
 653{
 654        struct gud_device *gdrm = usb_get_intfdata(intf);
 655
 656        drm_mode_config_helper_resume(&gdrm->drm);
 657
 658        return 0;
 659}
 660
 661static const struct usb_device_id gud_id_table[] = {
 662        { USB_DEVICE_INTERFACE_CLASS(0x1d50, 0x614d, USB_CLASS_VENDOR_SPEC) },
 663        { USB_DEVICE_INTERFACE_CLASS(0x16d0, 0x10a9, USB_CLASS_VENDOR_SPEC) },
 664        { }
 665};
 666
 667MODULE_DEVICE_TABLE(usb, gud_id_table);
 668
 669static struct usb_driver gud_usb_driver = {
 670        .name           = "gud",
 671        .probe          = gud_probe,
 672        .disconnect     = gud_disconnect,
 673        .id_table       = gud_id_table,
 674        .suspend        = gud_suspend,
 675        .resume         = gud_resume,
 676        .reset_resume   = gud_resume,
 677};
 678
 679module_usb_driver(gud_usb_driver);
 680
 681MODULE_AUTHOR("Noralf Trønnes");
 682MODULE_LICENSE("Dual MIT/GPL");
 683