Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19-rc2 675 lines 18 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright 2012-2019 Red Hat 4 * 5 * This file is subject to the terms and conditions of the GNU General 6 * Public License version 2. See the file COPYING in the main 7 * directory of this archive for more details. 8 * 9 * Authors: Matthew Garrett 10 * Dave Airlie 11 * Gerd Hoffmann 12 * 13 * Portions of this code derived from cirrusfb.c: 14 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets 15 * 16 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> 17 */ 18 19#include <linux/aperture.h> 20#include <linux/iosys-map.h> 21#include <linux/module.h> 22#include <linux/pci.h> 23 24#include <video/cirrus.h> 25#include <video/vga.h> 26 27#include <drm/clients/drm_client_setup.h> 28#include <drm/drm_atomic.h> 29#include <drm/drm_atomic_helper.h> 30#include <drm/drm_atomic_state_helper.h> 31#include <drm/drm_connector.h> 32#include <drm/drm_damage_helper.h> 33#include <drm/drm_drv.h> 34#include <drm/drm_edid.h> 35#include <drm/drm_fbdev_shmem.h> 36#include <drm/drm_file.h> 37#include <drm/drm_format_helper.h> 38#include <drm/drm_fourcc.h> 39#include <drm/drm_framebuffer.h> 40#include <drm/drm_gem_atomic_helper.h> 41#include <drm/drm_gem_framebuffer_helper.h> 42#include <drm/drm_gem_shmem_helper.h> 43#include <drm/drm_ioctl.h> 44#include <drm/drm_managed.h> 45#include <drm/drm_modeset_helper_vtables.h> 46#include <drm/drm_module.h> 47#include <drm/drm_print.h> 48#include <drm/drm_probe_helper.h> 49#include <drm/drm_vblank.h> 50#include <drm/drm_vblank_helper.h> 51 52#define DRIVER_NAME "cirrus-qemu" 53#define DRIVER_DESC "qemu cirrus vga" 54#define DRIVER_MAJOR 2 55#define DRIVER_MINOR 0 56 57#define CIRRUS_MAX_PITCH (0x1FF << 3) /* (4096 - 1) & ~111b bytes */ 58#define CIRRUS_VRAM_SIZE (4 * 1024 * 1024) /* 4 MB */ 59 60struct cirrus_device { 61 struct drm_device dev; 62 63 /* modesetting pipeline */ 64 struct drm_plane primary_plane; 65 struct drm_crtc crtc; 66 struct drm_encoder encoder; 67 struct drm_connector connector; 68 69 /* HW resources */ 70 void __iomem *vram; 71 void __iomem *mmio; 72}; 73 74#define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev) 75 76/* ------------------------------------------------------------------ */ 77/* 78 * The meat of this driver. The core passes us a mode and we have to program 79 * it. The modesetting here is the bare minimum required to satisfy the qemu 80 * emulation of this hardware, and running this against a real device is 81 * likely to result in an inadequately programmed mode. We've already had 82 * the opportunity to modify the mode, so whatever we receive here should 83 * be something that can be correctly programmed and displayed 84 */ 85 86#define SEQ_INDEX 4 87#define SEQ_DATA 5 88 89static u8 rreg_seq(struct cirrus_device *cirrus, u8 reg) 90{ 91 iowrite8(reg, cirrus->mmio + SEQ_INDEX); 92 return ioread8(cirrus->mmio + SEQ_DATA); 93} 94 95static void wreg_seq(struct cirrus_device *cirrus, u8 reg, u8 val) 96{ 97 iowrite8(reg, cirrus->mmio + SEQ_INDEX); 98 iowrite8(val, cirrus->mmio + SEQ_DATA); 99} 100 101#define CRT_INDEX 0x14 102#define CRT_DATA 0x15 103 104static u8 rreg_crt(struct cirrus_device *cirrus, u8 reg) 105{ 106 iowrite8(reg, cirrus->mmio + CRT_INDEX); 107 return ioread8(cirrus->mmio + CRT_DATA); 108} 109 110static void wreg_crt(struct cirrus_device *cirrus, u8 reg, u8 val) 111{ 112 iowrite8(reg, cirrus->mmio + CRT_INDEX); 113 iowrite8(val, cirrus->mmio + CRT_DATA); 114} 115 116#define GFX_INDEX 0xe 117#define GFX_DATA 0xf 118 119static void wreg_gfx(struct cirrus_device *cirrus, u8 reg, u8 val) 120{ 121 iowrite8(reg, cirrus->mmio + GFX_INDEX); 122 iowrite8(val, cirrus->mmio + GFX_DATA); 123} 124 125#define VGA_DAC_MASK 0x06 126 127static void wreg_hdr(struct cirrus_device *cirrus, u8 val) 128{ 129 ioread8(cirrus->mmio + VGA_DAC_MASK); 130 ioread8(cirrus->mmio + VGA_DAC_MASK); 131 ioread8(cirrus->mmio + VGA_DAC_MASK); 132 ioread8(cirrus->mmio + VGA_DAC_MASK); 133 iowrite8(val, cirrus->mmio + VGA_DAC_MASK); 134} 135 136static void cirrus_set_start_address(struct cirrus_device *cirrus, u32 offset) 137{ 138 u32 addr; 139 u8 tmp; 140 141 addr = offset >> 2; 142 wreg_crt(cirrus, 0x0c, (u8)((addr >> 8) & 0xff)); 143 wreg_crt(cirrus, 0x0d, (u8)(addr & 0xff)); 144 145 tmp = rreg_crt(cirrus, 0x1b); 146 tmp &= 0xf2; 147 tmp |= (addr >> 16) & 0x01; 148 tmp |= (addr >> 15) & 0x0c; 149 wreg_crt(cirrus, 0x1b, tmp); 150 151 tmp = rreg_crt(cirrus, 0x1d); 152 tmp &= 0x7f; 153 tmp |= (addr >> 12) & 0x80; 154 wreg_crt(cirrus, 0x1d, tmp); 155} 156 157static void cirrus_mode_set(struct cirrus_device *cirrus, 158 struct drm_display_mode *mode) 159{ 160 int hsyncstart, hsyncend, htotal, hdispend; 161 int vtotal, vdispend; 162 int tmp; 163 164 htotal = mode->htotal / 8; 165 hsyncend = mode->hsync_end / 8; 166 hsyncstart = mode->hsync_start / 8; 167 hdispend = mode->hdisplay / 8; 168 169 vtotal = mode->vtotal; 170 vdispend = mode->vdisplay; 171 172 vdispend -= 1; 173 vtotal -= 2; 174 175 htotal -= 5; 176 hdispend -= 1; 177 hsyncstart += 1; 178 hsyncend += 1; 179 180 wreg_crt(cirrus, VGA_CRTC_V_SYNC_END, 0x20); 181 wreg_crt(cirrus, VGA_CRTC_H_TOTAL, htotal); 182 wreg_crt(cirrus, VGA_CRTC_H_DISP, hdispend); 183 wreg_crt(cirrus, VGA_CRTC_H_SYNC_START, hsyncstart); 184 wreg_crt(cirrus, VGA_CRTC_H_SYNC_END, hsyncend); 185 wreg_crt(cirrus, VGA_CRTC_V_TOTAL, vtotal & 0xff); 186 wreg_crt(cirrus, VGA_CRTC_V_DISP_END, vdispend & 0xff); 187 188 tmp = 0x40; 189 if ((vdispend + 1) & 512) 190 tmp |= 0x20; 191 wreg_crt(cirrus, VGA_CRTC_MAX_SCAN, tmp); 192 193 /* 194 * Overflow bits for values that don't fit in the standard registers 195 */ 196 tmp = 0x10; 197 if (vtotal & 0x100) 198 tmp |= 0x01; 199 if (vdispend & 0x100) 200 tmp |= 0x02; 201 if ((vdispend + 1) & 0x100) 202 tmp |= 0x08; 203 if (vtotal & 0x200) 204 tmp |= 0x20; 205 if (vdispend & 0x200) 206 tmp |= 0x40; 207 wreg_crt(cirrus, VGA_CRTC_OVERFLOW, tmp); 208 209 tmp = 0; 210 211 /* More overflow bits */ 212 213 if ((htotal + 5) & 0x40) 214 tmp |= 0x10; 215 if ((htotal + 5) & 0x80) 216 tmp |= 0x20; 217 if (vtotal & 0x100) 218 tmp |= 0x40; 219 if (vtotal & 0x200) 220 tmp |= 0x80; 221 222 wreg_crt(cirrus, CL_CRT1A, tmp); 223 224 /* Disable Hercules/CGA compatibility */ 225 wreg_crt(cirrus, VGA_CRTC_MODE, 0x03); 226} 227 228static void cirrus_format_set(struct cirrus_device *cirrus, 229 const struct drm_format_info *format) 230{ 231 u8 sr07, hdr; 232 233 sr07 = rreg_seq(cirrus, 0x07); 234 sr07 &= 0xe0; 235 236 switch (format->format) { 237 case DRM_FORMAT_C8: 238 sr07 |= 0x11; 239 hdr = 0x00; 240 break; 241 case DRM_FORMAT_RGB565: 242 sr07 |= 0x17; 243 hdr = 0xc1; 244 break; 245 case DRM_FORMAT_RGB888: 246 sr07 |= 0x15; 247 hdr = 0xc5; 248 break; 249 case DRM_FORMAT_XRGB8888: 250 sr07 |= 0x19; 251 hdr = 0xc5; 252 break; 253 default: 254 return; 255 } 256 257 wreg_seq(cirrus, 0x7, sr07); 258 259 /* Enable high-colour modes */ 260 wreg_gfx(cirrus, VGA_GFX_MODE, 0x40); 261 262 /* And set graphics mode */ 263 wreg_gfx(cirrus, VGA_GFX_MISC, 0x01); 264 265 wreg_hdr(cirrus, hdr); 266} 267 268static void cirrus_pitch_set(struct cirrus_device *cirrus, unsigned int pitch) 269{ 270 u8 cr13, cr1b; 271 272 /* Program the pitch */ 273 cr13 = pitch / 8; 274 wreg_crt(cirrus, VGA_CRTC_OFFSET, cr13); 275 276 /* Enable extended blanking and pitch bits, and enable full memory */ 277 cr1b = 0x22; 278 cr1b |= (pitch >> 7) & 0x10; 279 wreg_crt(cirrus, 0x1b, cr1b); 280 281 cirrus_set_start_address(cirrus, 0); 282} 283 284/* ------------------------------------------------------------------ */ 285/* cirrus display pipe */ 286 287static const uint32_t cirrus_primary_plane_formats[] = { 288 DRM_FORMAT_RGB565, 289 DRM_FORMAT_RGB888, 290 DRM_FORMAT_XRGB8888, 291}; 292 293static const uint64_t cirrus_primary_plane_format_modifiers[] = { 294 DRM_FORMAT_MOD_LINEAR, 295 DRM_FORMAT_MOD_INVALID 296}; 297 298static int cirrus_primary_plane_helper_atomic_check(struct drm_plane *plane, 299 struct drm_atomic_state *state) 300{ 301 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); 302 struct drm_framebuffer *fb = new_plane_state->fb; 303 struct drm_crtc *new_crtc = new_plane_state->crtc; 304 struct drm_crtc_state *new_crtc_state = NULL; 305 int ret; 306 307 if (new_crtc) 308 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); 309 310 ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state, 311 DRM_PLANE_NO_SCALING, 312 DRM_PLANE_NO_SCALING, 313 false, false); 314 if (ret) 315 return ret; 316 else if (!new_plane_state->visible) 317 return 0; 318 319 /* validate size constraints */ 320 if (fb->pitches[0] > CIRRUS_MAX_PITCH) 321 return -EINVAL; 322 else if (fb->pitches[0] > CIRRUS_VRAM_SIZE / fb->height) 323 return -EINVAL; 324 325 return 0; 326} 327 328static void cirrus_primary_plane_helper_atomic_update(struct drm_plane *plane, 329 struct drm_atomic_state *state) 330{ 331 struct cirrus_device *cirrus = to_cirrus(plane->dev); 332 struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); 333 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); 334 struct drm_framebuffer *fb = plane_state->fb; 335 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); 336 struct drm_framebuffer *old_fb = old_plane_state->fb; 337 struct iosys_map vaddr = IOSYS_MAP_INIT_VADDR_IOMEM(cirrus->vram); 338 struct drm_atomic_helper_damage_iter iter; 339 struct drm_rect damage; 340 int idx; 341 342 if (!fb) 343 return; 344 345 if (!drm_dev_enter(&cirrus->dev, &idx)) 346 return; 347 348 if (!old_fb || old_fb->format != fb->format) 349 cirrus_format_set(cirrus, fb->format); 350 if (!old_fb || old_fb->pitches[0] != fb->pitches[0]) 351 cirrus_pitch_set(cirrus, fb->pitches[0]); 352 353 drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); 354 drm_atomic_for_each_plane_damage(&iter, &damage) { 355 unsigned int offset = drm_fb_clip_offset(fb->pitches[0], fb->format, &damage); 356 struct iosys_map dst = IOSYS_MAP_INIT_OFFSET(&vaddr, offset); 357 358 drm_fb_memcpy(&dst, fb->pitches, shadow_plane_state->data, fb, &damage); 359 } 360 361 drm_dev_exit(idx); 362} 363 364static const struct drm_plane_helper_funcs cirrus_primary_plane_helper_funcs = { 365 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, 366 .atomic_check = cirrus_primary_plane_helper_atomic_check, 367 .atomic_update = cirrus_primary_plane_helper_atomic_update, 368}; 369 370static const struct drm_plane_funcs cirrus_primary_plane_funcs = { 371 .update_plane = drm_atomic_helper_update_plane, 372 .disable_plane = drm_atomic_helper_disable_plane, 373 .destroy = drm_plane_cleanup, 374 DRM_GEM_SHADOW_PLANE_FUNCS, 375}; 376 377static int cirrus_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) 378{ 379 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 380 int ret; 381 382 if (!crtc_state->enable) 383 return 0; 384 385 ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state); 386 if (ret) 387 return ret; 388 389 return 0; 390} 391 392static void cirrus_crtc_helper_atomic_enable(struct drm_crtc *crtc, 393 struct drm_atomic_state *state) 394{ 395 struct cirrus_device *cirrus = to_cirrus(crtc->dev); 396 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 397 int idx; 398 399 if (!drm_dev_enter(&cirrus->dev, &idx)) 400 return; 401 402 cirrus_mode_set(cirrus, &crtc_state->mode); 403 404#ifdef CONFIG_HAS_IOPORT 405 /* Unblank (needed on S3 resume, vgabios doesn't do it then) */ 406 outb(VGA_AR_ENABLE_DISPLAY, VGA_ATT_W); 407#endif 408 409 drm_dev_exit(idx); 410 411 drm_crtc_vblank_on(crtc); 412} 413 414static const struct drm_crtc_helper_funcs cirrus_crtc_helper_funcs = { 415 .atomic_check = cirrus_crtc_helper_atomic_check, 416 .atomic_flush = drm_crtc_vblank_atomic_flush, 417 .atomic_enable = cirrus_crtc_helper_atomic_enable, 418 .atomic_disable = drm_crtc_vblank_atomic_disable, 419}; 420 421static const struct drm_crtc_funcs cirrus_crtc_funcs = { 422 .reset = drm_atomic_helper_crtc_reset, 423 .destroy = drm_crtc_cleanup, 424 .set_config = drm_atomic_helper_set_config, 425 .page_flip = drm_atomic_helper_page_flip, 426 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 427 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 428 DRM_CRTC_VBLANK_TIMER_FUNCS, 429}; 430 431static const struct drm_encoder_funcs cirrus_encoder_funcs = { 432 .destroy = drm_encoder_cleanup, 433}; 434 435static int cirrus_connector_helper_get_modes(struct drm_connector *connector) 436{ 437 int count; 438 439 count = drm_add_modes_noedid(connector, 440 connector->dev->mode_config.max_width, 441 connector->dev->mode_config.max_height); 442 drm_set_preferred_mode(connector, 1024, 768); 443 return count; 444} 445 446static const struct drm_connector_helper_funcs cirrus_connector_helper_funcs = { 447 .get_modes = cirrus_connector_helper_get_modes, 448}; 449 450static const struct drm_connector_funcs cirrus_connector_funcs = { 451 .fill_modes = drm_helper_probe_single_connector_modes, 452 .destroy = drm_connector_cleanup, 453 .reset = drm_atomic_helper_connector_reset, 454 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 455 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 456}; 457 458static int cirrus_pipe_init(struct cirrus_device *cirrus) 459{ 460 struct drm_device *dev = &cirrus->dev; 461 struct drm_plane *primary_plane; 462 struct drm_crtc *crtc; 463 struct drm_encoder *encoder; 464 struct drm_connector *connector; 465 int ret; 466 467 primary_plane = &cirrus->primary_plane; 468 ret = drm_universal_plane_init(dev, primary_plane, 0, 469 &cirrus_primary_plane_funcs, 470 cirrus_primary_plane_formats, 471 ARRAY_SIZE(cirrus_primary_plane_formats), 472 cirrus_primary_plane_format_modifiers, 473 DRM_PLANE_TYPE_PRIMARY, NULL); 474 if (ret) 475 return ret; 476 drm_plane_helper_add(primary_plane, &cirrus_primary_plane_helper_funcs); 477 drm_plane_enable_fb_damage_clips(primary_plane); 478 479 crtc = &cirrus->crtc; 480 ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, 481 &cirrus_crtc_funcs, NULL); 482 if (ret) 483 return ret; 484 drm_crtc_helper_add(crtc, &cirrus_crtc_helper_funcs); 485 486 encoder = &cirrus->encoder; 487 ret = drm_encoder_init(dev, encoder, &cirrus_encoder_funcs, 488 DRM_MODE_ENCODER_VIRTUAL, NULL); 489 if (ret) 490 return ret; 491 encoder->possible_crtcs = drm_crtc_mask(crtc); 492 493 connector = &cirrus->connector; 494 ret = drm_connector_init(dev, connector, &cirrus_connector_funcs, 495 DRM_MODE_CONNECTOR_VIRTUAL); 496 if (ret) 497 return ret; 498 drm_connector_helper_add(connector, &cirrus_connector_helper_funcs); 499 500 ret = drm_connector_attach_encoder(connector, encoder); 501 if (ret) 502 return ret; 503 504 ret = drm_vblank_init(dev, 1); 505 if (ret) 506 return ret; 507 508 return 0; 509} 510 511/* ------------------------------------------------------------------ */ 512/* cirrus framebuffers & mode config */ 513 514static enum drm_mode_status cirrus_mode_config_mode_valid(struct drm_device *dev, 515 const struct drm_display_mode *mode) 516{ 517 const struct drm_format_info *format = drm_format_info(DRM_FORMAT_XRGB8888); 518 u64 pitch; 519 520 if (drm_WARN_ON_ONCE(dev, !format)) 521 return MODE_ERROR; /* driver bug */ 522 523 pitch = drm_format_info_min_pitch(format, 0, mode->hdisplay); 524 if (!pitch) 525 return MODE_BAD_WIDTH; 526 if (pitch > CIRRUS_MAX_PITCH) 527 return MODE_BAD_WIDTH; /* maximum programmable pitch */ 528 if (pitch > CIRRUS_VRAM_SIZE / mode->vdisplay) 529 return MODE_MEM; 530 531 return MODE_OK; 532} 533 534static const struct drm_mode_config_funcs cirrus_mode_config_funcs = { 535 .fb_create = drm_gem_fb_create_with_dirty, 536 .mode_valid = cirrus_mode_config_mode_valid, 537 .atomic_check = drm_atomic_helper_check, 538 .atomic_commit = drm_atomic_helper_commit, 539}; 540 541static int cirrus_mode_config_init(struct cirrus_device *cirrus) 542{ 543 struct drm_device *dev = &cirrus->dev; 544 int ret; 545 546 ret = drmm_mode_config_init(dev); 547 if (ret) 548 return ret; 549 550 dev->mode_config.min_width = 0; 551 dev->mode_config.min_height = 0; 552 dev->mode_config.max_width = CIRRUS_MAX_PITCH / 2; 553 dev->mode_config.max_height = 1024; 554 dev->mode_config.preferred_depth = 16; 555 dev->mode_config.prefer_shadow = 0; 556 dev->mode_config.funcs = &cirrus_mode_config_funcs; 557 558 return 0; 559} 560 561/* ------------------------------------------------------------------ */ 562 563DEFINE_DRM_GEM_FOPS(cirrus_fops); 564 565static const struct drm_driver cirrus_driver = { 566 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 567 568 .name = DRIVER_NAME, 569 .desc = DRIVER_DESC, 570 .major = DRIVER_MAJOR, 571 .minor = DRIVER_MINOR, 572 573 .fops = &cirrus_fops, 574 DRM_GEM_SHMEM_DRIVER_OPS, 575 DRM_FBDEV_SHMEM_DRIVER_OPS, 576}; 577 578static int cirrus_pci_probe(struct pci_dev *pdev, 579 const struct pci_device_id *ent) 580{ 581 struct drm_device *dev; 582 struct cirrus_device *cirrus; 583 int ret; 584 585 ret = aperture_remove_conflicting_pci_devices(pdev, cirrus_driver.name); 586 if (ret) 587 return ret; 588 589 ret = pcim_enable_device(pdev); 590 if (ret) 591 return ret; 592 593 ret = pcim_request_all_regions(pdev, DRIVER_NAME); 594 if (ret) 595 return ret; 596 597 ret = -ENOMEM; 598 cirrus = devm_drm_dev_alloc(&pdev->dev, &cirrus_driver, 599 struct cirrus_device, dev); 600 if (IS_ERR(cirrus)) 601 return PTR_ERR(cirrus); 602 603 dev = &cirrus->dev; 604 605 cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), 606 pci_resource_len(pdev, 0)); 607 if (cirrus->vram == NULL) 608 return -ENOMEM; 609 610 cirrus->mmio = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 1), 611 pci_resource_len(pdev, 1)); 612 if (cirrus->mmio == NULL) 613 return -ENOMEM; 614 615 ret = cirrus_mode_config_init(cirrus); 616 if (ret) 617 return ret; 618 619 ret = cirrus_pipe_init(cirrus); 620 if (ret < 0) 621 return ret; 622 623 drm_mode_config_reset(dev); 624 625 pci_set_drvdata(pdev, dev); 626 ret = drm_dev_register(dev, 0); 627 if (ret) 628 return ret; 629 630 drm_client_setup(dev, NULL); 631 return 0; 632} 633 634static void cirrus_pci_remove(struct pci_dev *pdev) 635{ 636 struct drm_device *dev = pci_get_drvdata(pdev); 637 638 drm_dev_unplug(dev); 639 drm_atomic_helper_shutdown(dev); 640} 641 642static void cirrus_pci_shutdown(struct pci_dev *pdev) 643{ 644 drm_atomic_helper_shutdown(pci_get_drvdata(pdev)); 645} 646 647static const struct pci_device_id pciidlist[] = { 648 { 649 .vendor = PCI_VENDOR_ID_CIRRUS, 650 .device = PCI_DEVICE_ID_CIRRUS_5446, 651 /* only bind to the cirrus chip in qemu */ 652 .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET, 653 .subdevice = PCI_SUBDEVICE_ID_QEMU, 654 }, { 655 .vendor = PCI_VENDOR_ID_CIRRUS, 656 .device = PCI_DEVICE_ID_CIRRUS_5446, 657 .subvendor = PCI_VENDOR_ID_XEN, 658 .subdevice = 0x0001, 659 }, 660 { /* end if list */ } 661}; 662 663static struct pci_driver cirrus_pci_driver = { 664 .name = DRIVER_NAME, 665 .id_table = pciidlist, 666 .probe = cirrus_pci_probe, 667 .remove = cirrus_pci_remove, 668 .shutdown = cirrus_pci_shutdown, 669}; 670 671drm_module_pci_driver(cirrus_pci_driver) 672 673MODULE_DEVICE_TABLE(pci, pciidlist); 674MODULE_DESCRIPTION("Cirrus driver for QEMU emulated device"); 675MODULE_LICENSE("GPL");