| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * device driver for Conexant 2388x based TV cards |
|---|
| .. | .. |
|---|
| 9 | 10 | * - Multituner support |
|---|
| 10 | 11 | * - video_ioctl2 conversion |
|---|
| 11 | 12 | * - PAL/M fixes |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 14 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 15 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 16 | | - * (at your option) any later version. |
|---|
| 17 | | - * |
|---|
| 18 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 19 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 20 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 21 | | - * GNU General Public License for more details. |
|---|
| 22 | 13 | */ |
|---|
| 23 | 14 | |
|---|
| 24 | 15 | #include "cx88.h" |
|---|
| .. | .. |
|---|
| 42 | 33 | |
|---|
| 43 | 34 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); |
|---|
| 44 | 35 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
|---|
| 45 | | -MODULE_LICENSE("GPL"); |
|---|
| 36 | +MODULE_LICENSE("GPL v2"); |
|---|
| 46 | 37 | MODULE_VERSION(CX88_VERSION); |
|---|
| 47 | 38 | |
|---|
| 48 | 39 | /* ------------------------------------------------------------------ */ |
|---|
| .. | .. |
|---|
| 78 | 69 | |
|---|
| 79 | 70 | static const struct cx8800_fmt formats[] = { |
|---|
| 80 | 71 | { |
|---|
| 81 | | - .name = "8 bpp, gray", |
|---|
| 82 | 72 | .fourcc = V4L2_PIX_FMT_GREY, |
|---|
| 83 | 73 | .cxformat = ColorFormatY8, |
|---|
| 84 | 74 | .depth = 8, |
|---|
| 85 | 75 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 86 | 76 | }, { |
|---|
| 87 | | - .name = "15 bpp RGB, le", |
|---|
| 88 | 77 | .fourcc = V4L2_PIX_FMT_RGB555, |
|---|
| 89 | 78 | .cxformat = ColorFormatRGB15, |
|---|
| 90 | 79 | .depth = 16, |
|---|
| 91 | 80 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 92 | 81 | }, { |
|---|
| 93 | | - .name = "15 bpp RGB, be", |
|---|
| 94 | 82 | .fourcc = V4L2_PIX_FMT_RGB555X, |
|---|
| 95 | 83 | .cxformat = ColorFormatRGB15 | ColorFormatBSWAP, |
|---|
| 96 | 84 | .depth = 16, |
|---|
| 97 | 85 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 98 | 86 | }, { |
|---|
| 99 | | - .name = "16 bpp RGB, le", |
|---|
| 100 | 87 | .fourcc = V4L2_PIX_FMT_RGB565, |
|---|
| 101 | 88 | .cxformat = ColorFormatRGB16, |
|---|
| 102 | 89 | .depth = 16, |
|---|
| 103 | 90 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 104 | 91 | }, { |
|---|
| 105 | | - .name = "16 bpp RGB, be", |
|---|
| 106 | 92 | .fourcc = V4L2_PIX_FMT_RGB565X, |
|---|
| 107 | 93 | .cxformat = ColorFormatRGB16 | ColorFormatBSWAP, |
|---|
| 108 | 94 | .depth = 16, |
|---|
| 109 | 95 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 110 | 96 | }, { |
|---|
| 111 | | - .name = "24 bpp RGB, le", |
|---|
| 112 | 97 | .fourcc = V4L2_PIX_FMT_BGR24, |
|---|
| 113 | 98 | .cxformat = ColorFormatRGB24, |
|---|
| 114 | 99 | .depth = 24, |
|---|
| 115 | 100 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 116 | 101 | }, { |
|---|
| 117 | | - .name = "32 bpp RGB, le", |
|---|
| 118 | 102 | .fourcc = V4L2_PIX_FMT_BGR32, |
|---|
| 119 | 103 | .cxformat = ColorFormatRGB32, |
|---|
| 120 | 104 | .depth = 32, |
|---|
| 121 | 105 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 122 | 106 | }, { |
|---|
| 123 | | - .name = "32 bpp RGB, be", |
|---|
| 124 | 107 | .fourcc = V4L2_PIX_FMT_RGB32, |
|---|
| 125 | 108 | .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | |
|---|
| 126 | 109 | ColorFormatWSWAP, |
|---|
| 127 | 110 | .depth = 32, |
|---|
| 128 | 111 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 129 | 112 | }, { |
|---|
| 130 | | - .name = "4:2:2, packed, YUYV", |
|---|
| 131 | 113 | .fourcc = V4L2_PIX_FMT_YUYV, |
|---|
| 132 | 114 | .cxformat = ColorFormatYUY2, |
|---|
| 133 | 115 | .depth = 16, |
|---|
| 134 | 116 | .flags = FORMAT_FLAGS_PACKED, |
|---|
| 135 | 117 | }, { |
|---|
| 136 | | - .name = "4:2:2, packed, UYVY", |
|---|
| 137 | 118 | .fourcc = V4L2_PIX_FMT_UYVY, |
|---|
| 138 | 119 | .cxformat = ColorFormatYUY2 | ColorFormatBSWAP, |
|---|
| 139 | 120 | .depth = 16, |
|---|
| .. | .. |
|---|
| 404 | 385 | return 0; |
|---|
| 405 | 386 | } |
|---|
| 406 | 387 | |
|---|
| 407 | | -#ifdef CONFIG_PM |
|---|
| 408 | | -static int stop_video_dma(struct cx8800_dev *dev) |
|---|
| 388 | +static int __maybe_unused stop_video_dma(struct cx8800_dev *dev) |
|---|
| 409 | 389 | { |
|---|
| 410 | 390 | struct cx88_core *core = dev->core; |
|---|
| 411 | 391 | |
|---|
| .. | .. |
|---|
| 421 | 401 | return 0; |
|---|
| 422 | 402 | } |
|---|
| 423 | 403 | |
|---|
| 424 | | -static int restart_video_queue(struct cx8800_dev *dev, |
|---|
| 425 | | - struct cx88_dmaqueue *q) |
|---|
| 404 | +static int __maybe_unused restart_video_queue(struct cx8800_dev *dev, |
|---|
| 405 | + struct cx88_dmaqueue *q) |
|---|
| 426 | 406 | { |
|---|
| 427 | 407 | struct cx88_buffer *buf; |
|---|
| 428 | 408 | |
|---|
| .. | .. |
|---|
| 434 | 414 | } |
|---|
| 435 | 415 | return 0; |
|---|
| 436 | 416 | } |
|---|
| 437 | | -#endif |
|---|
| 438 | 417 | |
|---|
| 439 | 418 | /* ------------------------------------------------------------------ */ |
|---|
| 440 | 419 | |
|---|
| .. | .. |
|---|
| 452 | 431 | |
|---|
| 453 | 432 | static int buffer_prepare(struct vb2_buffer *vb) |
|---|
| 454 | 433 | { |
|---|
| 434 | + int ret; |
|---|
| 455 | 435 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
|---|
| 456 | 436 | struct cx8800_dev *dev = vb->vb2_queue->drv_priv; |
|---|
| 457 | 437 | struct cx88_core *core = dev->core; |
|---|
| .. | .. |
|---|
| 466 | 446 | |
|---|
| 467 | 447 | switch (core->field) { |
|---|
| 468 | 448 | case V4L2_FIELD_TOP: |
|---|
| 469 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 470 | | - sgt->sgl, 0, UNSET, |
|---|
| 471 | | - buf->bpl, 0, core->height); |
|---|
| 449 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 450 | + sgt->sgl, 0, UNSET, |
|---|
| 451 | + buf->bpl, 0, core->height); |
|---|
| 472 | 452 | break; |
|---|
| 473 | 453 | case V4L2_FIELD_BOTTOM: |
|---|
| 474 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 475 | | - sgt->sgl, UNSET, 0, |
|---|
| 476 | | - buf->bpl, 0, core->height); |
|---|
| 454 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 455 | + sgt->sgl, UNSET, 0, |
|---|
| 456 | + buf->bpl, 0, core->height); |
|---|
| 477 | 457 | break; |
|---|
| 478 | 458 | case V4L2_FIELD_SEQ_TB: |
|---|
| 479 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 480 | | - sgt->sgl, |
|---|
| 481 | | - 0, buf->bpl * (core->height >> 1), |
|---|
| 482 | | - buf->bpl, 0, |
|---|
| 483 | | - core->height >> 1); |
|---|
| 459 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 460 | + sgt->sgl, |
|---|
| 461 | + 0, buf->bpl * (core->height >> 1), |
|---|
| 462 | + buf->bpl, 0, |
|---|
| 463 | + core->height >> 1); |
|---|
| 484 | 464 | break; |
|---|
| 485 | 465 | case V4L2_FIELD_SEQ_BT: |
|---|
| 486 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 487 | | - sgt->sgl, |
|---|
| 488 | | - buf->bpl * (core->height >> 1), 0, |
|---|
| 489 | | - buf->bpl, 0, |
|---|
| 490 | | - core->height >> 1); |
|---|
| 466 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 467 | + sgt->sgl, |
|---|
| 468 | + buf->bpl * (core->height >> 1), 0, |
|---|
| 469 | + buf->bpl, 0, |
|---|
| 470 | + core->height >> 1); |
|---|
| 491 | 471 | break; |
|---|
| 492 | 472 | case V4L2_FIELD_INTERLACED: |
|---|
| 493 | 473 | default: |
|---|
| 494 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 495 | | - sgt->sgl, 0, buf->bpl, |
|---|
| 496 | | - buf->bpl, buf->bpl, |
|---|
| 497 | | - core->height >> 1); |
|---|
| 474 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
|---|
| 475 | + sgt->sgl, 0, buf->bpl, |
|---|
| 476 | + buf->bpl, buf->bpl, |
|---|
| 477 | + core->height >> 1); |
|---|
| 498 | 478 | break; |
|---|
| 499 | 479 | } |
|---|
| 500 | 480 | dprintk(2, |
|---|
| 501 | | - "[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", |
|---|
| 502 | | - buf, buf->vb.vb2_buf.index, |
|---|
| 503 | | - core->width, core->height, dev->fmt->depth, dev->fmt->name, |
|---|
| 481 | + "[%p/%d] %s - %dx%d %dbpp 0x%08x - dma=0x%08lx\n", |
|---|
| 482 | + buf, buf->vb.vb2_buf.index, __func__, |
|---|
| 483 | + core->width, core->height, dev->fmt->depth, dev->fmt->fourcc, |
|---|
| 504 | 484 | (unsigned long)buf->risc.dma); |
|---|
| 505 | | - return 0; |
|---|
| 485 | + return ret; |
|---|
| 506 | 486 | } |
|---|
| 507 | 487 | |
|---|
| 508 | 488 | static void buffer_finish(struct vb2_buffer *vb) |
|---|
| .. | .. |
|---|
| 809 | 789 | int cx88_querycap(struct file *file, struct cx88_core *core, |
|---|
| 810 | 790 | struct v4l2_capability *cap) |
|---|
| 811 | 791 | { |
|---|
| 812 | | - struct video_device *vdev = video_devdata(file); |
|---|
| 813 | | - |
|---|
| 814 | | - strlcpy(cap->card, core->board.name, sizeof(cap->card)); |
|---|
| 815 | | - cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; |
|---|
| 792 | + strscpy(cap->card, core->board.name, sizeof(cap->card)); |
|---|
| 793 | + cap->capabilities = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
|---|
| 794 | + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | |
|---|
| 795 | + V4L2_CAP_DEVICE_CAPS; |
|---|
| 816 | 796 | if (core->board.tuner_type != UNSET) |
|---|
| 817 | | - cap->device_caps |= V4L2_CAP_TUNER; |
|---|
| 818 | | - switch (vdev->vfl_type) { |
|---|
| 819 | | - case VFL_TYPE_RADIO: |
|---|
| 820 | | - cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; |
|---|
| 821 | | - break; |
|---|
| 822 | | - case VFL_TYPE_GRABBER: |
|---|
| 823 | | - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; |
|---|
| 824 | | - break; |
|---|
| 825 | | - case VFL_TYPE_VBI: |
|---|
| 826 | | - cap->device_caps |= V4L2_CAP_VBI_CAPTURE; |
|---|
| 827 | | - break; |
|---|
| 828 | | - default: |
|---|
| 829 | | - return -EINVAL; |
|---|
| 830 | | - } |
|---|
| 831 | | - cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE | |
|---|
| 832 | | - V4L2_CAP_VBI_CAPTURE | V4L2_CAP_DEVICE_CAPS; |
|---|
| 797 | + cap->capabilities |= V4L2_CAP_TUNER; |
|---|
| 833 | 798 | if (core->board.radio.type == CX88_RADIO) |
|---|
| 834 | 799 | cap->capabilities |= V4L2_CAP_RADIO; |
|---|
| 835 | 800 | return 0; |
|---|
| .. | .. |
|---|
| 842 | 807 | struct cx8800_dev *dev = video_drvdata(file); |
|---|
| 843 | 808 | struct cx88_core *core = dev->core; |
|---|
| 844 | 809 | |
|---|
| 845 | | - strcpy(cap->driver, "cx8800"); |
|---|
| 810 | + strscpy(cap->driver, "cx8800", sizeof(cap->driver)); |
|---|
| 846 | 811 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); |
|---|
| 847 | 812 | return cx88_querycap(file, core, cap); |
|---|
| 848 | 813 | } |
|---|
| .. | .. |
|---|
| 853 | 818 | if (unlikely(f->index >= ARRAY_SIZE(formats))) |
|---|
| 854 | 819 | return -EINVAL; |
|---|
| 855 | 820 | |
|---|
| 856 | | - strlcpy(f->description, formats[f->index].name, sizeof(f->description)); |
|---|
| 857 | 821 | f->pixelformat = formats[f->index].fourcc; |
|---|
| 858 | 822 | |
|---|
| 859 | 823 | return 0; |
|---|
| .. | .. |
|---|
| 897 | 861 | if (!INPUT(n).type) |
|---|
| 898 | 862 | return -EINVAL; |
|---|
| 899 | 863 | i->type = V4L2_INPUT_TYPE_CAMERA; |
|---|
| 900 | | - strcpy(i->name, iname[INPUT(n).type]); |
|---|
| 864 | + strscpy(i->name, iname[INPUT(n).type], sizeof(i->name)); |
|---|
| 901 | 865 | if ((INPUT(n).type == CX88_VMUX_TELEVISION) || |
|---|
| 902 | 866 | (INPUT(n).type == CX88_VMUX_CABLE)) |
|---|
| 903 | 867 | i->type = V4L2_INPUT_TYPE_TUNER; |
|---|
| .. | .. |
|---|
| 952 | 916 | if (t->index != 0) |
|---|
| 953 | 917 | return -EINVAL; |
|---|
| 954 | 918 | |
|---|
| 955 | | - strcpy(t->name, "Television"); |
|---|
| 919 | + strscpy(t->name, "Television", sizeof(t->name)); |
|---|
| 956 | 920 | t->capability = V4L2_TUNER_CAP_NORM; |
|---|
| 957 | 921 | t->rangehigh = 0xffffffffUL; |
|---|
| 958 | 922 | call_all(core, tuner, g_tuner, t); |
|---|
| .. | .. |
|---|
| 1065 | 1029 | if (unlikely(t->index > 0)) |
|---|
| 1066 | 1030 | return -EINVAL; |
|---|
| 1067 | 1031 | |
|---|
| 1068 | | - strcpy(t->name, "Radio"); |
|---|
| 1032 | + strscpy(t->name, "Radio", sizeof(t->name)); |
|---|
| 1069 | 1033 | |
|---|
| 1070 | 1034 | call_all(core, tuner, g_tuner, t); |
|---|
| 1071 | 1035 | return 0; |
|---|
| .. | .. |
|---|
| 1378 | 1342 | if (vc->id == V4L2_CID_CHROMA_AGC) |
|---|
| 1379 | 1343 | core->chroma_agc = vc; |
|---|
| 1380 | 1344 | } |
|---|
| 1381 | | - v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL); |
|---|
| 1345 | + v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL, false); |
|---|
| 1382 | 1346 | |
|---|
| 1383 | 1347 | /* load and configure helper modules */ |
|---|
| 1384 | 1348 | |
|---|
| .. | .. |
|---|
| 1420 | 1384 | }; |
|---|
| 1421 | 1385 | |
|---|
| 1422 | 1386 | request_module("rtc-isl1208"); |
|---|
| 1423 | | - core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info); |
|---|
| 1387 | + core->i2c_rtc = i2c_new_client_device(&core->i2c_adap, &rtc_info); |
|---|
| 1424 | 1388 | } |
|---|
| 1425 | | - /* fall-through */ |
|---|
| 1389 | + fallthrough; |
|---|
| 1426 | 1390 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
|---|
| 1427 | 1391 | request_module("ir-kbd-i2c"); |
|---|
| 1428 | 1392 | } |
|---|
| .. | .. |
|---|
| 1482 | 1446 | video_set_drvdata(&dev->video_dev, dev); |
|---|
| 1483 | 1447 | dev->video_dev.ctrl_handler = &core->video_hdl; |
|---|
| 1484 | 1448 | dev->video_dev.queue = &dev->vb2_vidq; |
|---|
| 1485 | | - err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, |
|---|
| 1449 | + dev->video_dev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
|---|
| 1450 | + V4L2_CAP_VIDEO_CAPTURE; |
|---|
| 1451 | + if (core->board.tuner_type != UNSET) |
|---|
| 1452 | + dev->video_dev.device_caps |= V4L2_CAP_TUNER; |
|---|
| 1453 | + err = video_register_device(&dev->video_dev, VFL_TYPE_VIDEO, |
|---|
| 1486 | 1454 | video_nr[core->nr]); |
|---|
| 1487 | 1455 | if (err < 0) { |
|---|
| 1488 | 1456 | pr_err("can't register video device\n"); |
|---|
| .. | .. |
|---|
| 1495 | 1463 | &cx8800_vbi_template, "vbi"); |
|---|
| 1496 | 1464 | video_set_drvdata(&dev->vbi_dev, dev); |
|---|
| 1497 | 1465 | dev->vbi_dev.queue = &dev->vb2_vbiq; |
|---|
| 1466 | + dev->vbi_dev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
|---|
| 1467 | + V4L2_CAP_VBI_CAPTURE; |
|---|
| 1468 | + if (core->board.tuner_type != UNSET) |
|---|
| 1469 | + dev->vbi_dev.device_caps |= V4L2_CAP_TUNER; |
|---|
| 1498 | 1470 | err = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, |
|---|
| 1499 | 1471 | vbi_nr[core->nr]); |
|---|
| 1500 | 1472 | if (err < 0) { |
|---|
| .. | .. |
|---|
| 1509 | 1481 | &cx8800_radio_template, "radio"); |
|---|
| 1510 | 1482 | video_set_drvdata(&dev->radio_dev, dev); |
|---|
| 1511 | 1483 | dev->radio_dev.ctrl_handler = &core->audio_hdl; |
|---|
| 1484 | + dev->radio_dev.device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; |
|---|
| 1512 | 1485 | err = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, |
|---|
| 1513 | 1486 | radio_nr[core->nr]); |
|---|
| 1514 | 1487 | if (err < 0) { |
|---|
| .. | .. |
|---|
| 1577 | 1550 | kfree(dev); |
|---|
| 1578 | 1551 | } |
|---|
| 1579 | 1552 | |
|---|
| 1580 | | -#ifdef CONFIG_PM |
|---|
| 1581 | | -static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) |
|---|
| 1553 | +static int __maybe_unused cx8800_suspend(struct device *dev_d) |
|---|
| 1582 | 1554 | { |
|---|
| 1583 | | - struct cx8800_dev *dev = pci_get_drvdata(pci_dev); |
|---|
| 1555 | + struct cx8800_dev *dev = dev_get_drvdata(dev_d); |
|---|
| 1584 | 1556 | struct cx88_core *core = dev->core; |
|---|
| 1585 | 1557 | unsigned long flags; |
|---|
| 1586 | 1558 | |
|---|
| .. | .. |
|---|
| 1601 | 1573 | /* FIXME -- shutdown device */ |
|---|
| 1602 | 1574 | cx88_shutdown(core); |
|---|
| 1603 | 1575 | |
|---|
| 1604 | | - pci_save_state(pci_dev); |
|---|
| 1605 | | - if (pci_set_power_state(pci_dev, |
|---|
| 1606 | | - pci_choose_state(pci_dev, state)) != 0) { |
|---|
| 1607 | | - pci_disable_device(pci_dev); |
|---|
| 1608 | | - dev->state.disabled = 1; |
|---|
| 1609 | | - } |
|---|
| 1576 | + dev->state.disabled = 1; |
|---|
| 1610 | 1577 | return 0; |
|---|
| 1611 | 1578 | } |
|---|
| 1612 | 1579 | |
|---|
| 1613 | | -static int cx8800_resume(struct pci_dev *pci_dev) |
|---|
| 1580 | +static int __maybe_unused cx8800_resume(struct device *dev_d) |
|---|
| 1614 | 1581 | { |
|---|
| 1615 | | - struct cx8800_dev *dev = pci_get_drvdata(pci_dev); |
|---|
| 1582 | + struct cx8800_dev *dev = dev_get_drvdata(dev_d); |
|---|
| 1616 | 1583 | struct cx88_core *core = dev->core; |
|---|
| 1617 | 1584 | unsigned long flags; |
|---|
| 1618 | | - int err; |
|---|
| 1619 | 1585 | |
|---|
| 1620 | | - if (dev->state.disabled) { |
|---|
| 1621 | | - err = pci_enable_device(pci_dev); |
|---|
| 1622 | | - if (err) { |
|---|
| 1623 | | - pr_err("can't enable device\n"); |
|---|
| 1624 | | - return err; |
|---|
| 1625 | | - } |
|---|
| 1626 | | - |
|---|
| 1627 | | - dev->state.disabled = 0; |
|---|
| 1628 | | - } |
|---|
| 1629 | | - err = pci_set_power_state(pci_dev, PCI_D0); |
|---|
| 1630 | | - if (err) { |
|---|
| 1631 | | - pr_err("can't set power state\n"); |
|---|
| 1632 | | - pci_disable_device(pci_dev); |
|---|
| 1633 | | - dev->state.disabled = 1; |
|---|
| 1634 | | - |
|---|
| 1635 | | - return err; |
|---|
| 1636 | | - } |
|---|
| 1637 | | - pci_restore_state(pci_dev); |
|---|
| 1586 | + dev->state.disabled = 0; |
|---|
| 1638 | 1587 | |
|---|
| 1639 | 1588 | /* FIXME: re-initialize hardware */ |
|---|
| 1640 | 1589 | cx88_reset(core); |
|---|
| .. | .. |
|---|
| 1657 | 1606 | |
|---|
| 1658 | 1607 | return 0; |
|---|
| 1659 | 1608 | } |
|---|
| 1660 | | -#endif |
|---|
| 1661 | 1609 | |
|---|
| 1662 | 1610 | /* ----------------------------------------------------------- */ |
|---|
| 1663 | 1611 | |
|---|
| .. | .. |
|---|
| 1673 | 1621 | }; |
|---|
| 1674 | 1622 | MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl); |
|---|
| 1675 | 1623 | |
|---|
| 1624 | +static SIMPLE_DEV_PM_OPS(cx8800_pm_ops, cx8800_suspend, cx8800_resume); |
|---|
| 1625 | + |
|---|
| 1676 | 1626 | static struct pci_driver cx8800_pci_driver = { |
|---|
| 1677 | | - .name = "cx8800", |
|---|
| 1678 | | - .id_table = cx8800_pci_tbl, |
|---|
| 1679 | | - .probe = cx8800_initdev, |
|---|
| 1680 | | - .remove = cx8800_finidev, |
|---|
| 1681 | | -#ifdef CONFIG_PM |
|---|
| 1682 | | - .suspend = cx8800_suspend, |
|---|
| 1683 | | - .resume = cx8800_resume, |
|---|
| 1684 | | -#endif |
|---|
| 1627 | + .name = "cx8800", |
|---|
| 1628 | + .id_table = cx8800_pci_tbl, |
|---|
| 1629 | + .probe = cx8800_initdev, |
|---|
| 1630 | + .remove = cx8800_finidev, |
|---|
| 1631 | + .driver.pm = &cx8800_pm_ops, |
|---|
| 1685 | 1632 | }; |
|---|
| 1686 | 1633 | |
|---|
| 1687 | 1634 | module_pci_driver(cx8800_pci_driver); |
|---|