aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-02-18 19:57:44 -0500
committerDave Airlie <airlied@redhat.com>2016-02-18 19:57:44 -0500
commit08244c00859f25036417ea7b790cfa73e43443fc (patch)
tree051d7d2572f3a5569514d92407b9dd38e5c431c2
parent5443ce86fa37e7d3cc63d2067d05e3388fdeec17 (diff)
parenta6ddd2f1b99f1c00b4e00289b13c3e451c7130b0 (diff)
Merge tag 'topic/drm-misc-2016-02-18' of git://anongit.freedesktop.org/drm-intel into drm-next
Misc stuff all over: - more mode_fixup removal from Carlos, there's another final pile still left. - final bits of vgaswitcheroo from Lukas for apple gmux, we're still discussing an api cleanup patch to make it a bit more abuse-safe as a follow-up - dp aux interface for userspace for tools&tests from Rafael Antognolli - actual interface parts for dma-buf flushing for userspace mmap - few small bits all over - vgaswitcheroo support for apple gmux from Lukas Wunner - checks for ->mode_fixup in non-atomic helpers from Carlos Palminha, plus removing dummy funcs from drivers. Carlos promised to follow up with more, since there's lots more silly dummy functions around. - dma-buf patches from Tiago, except the ioctl itself (that needed a respin to address review from David Herrmann) - encoder mask for atomic from Maarten - bunch of random things all over. * tag 'topic/drm-misc-2016-02-18' of git://anongit.freedesktop.org/drm-intel: (57 commits) drm/udl: Use module_usb_driver drm: fixes crct set_mode when crtc mode_fixup is null. drm/tilcdc: removed optional dummy encoder mode_fixup function. drm/sti: removed optional dummy encoder mode_fixup function. drm/rockchip: removed optional dummy encoder mode_fixup function. drm/qxl: removed optional dummy encoder mode_fixup function. drm/mgag200: removed optional dummy encoder mode_fixup function. drm/msm/mdp: removed optional dummy encoder mode_fixup function. drm/imx: removed optional dummy encoder mode_fixup function. drm/gma500: removed optional dummy encoder mode_fixup function. drm/radeon: removed optional dummy encoder mode_fixup function. drm/cirrus: removed optional dummy encoder mode_fixup function. drm/bochs: removed optional dummy encoder mode_fixup function. drm/ast: removed optional dummy encoder mode_fixup function. drm/amdgpu: removed optional dummy encoder mode_fixup function. drm/exynos: removed optional dummy encoder mode_fixup function. drm/udl: removed optional dummy encoder mode_fixup function. drm/virtio: removed optional dummy encoder mode_fixup function. drm/fb_helper: Use add_one_connector in add_all_connectors. drm/fb_helper: Use correct allocation count for arrays. ...
-rw-r--r--Documentation/DocBook/gpu.tmpl5
-rw-r--r--Documentation/dma-buf-sharing.txt40
-rw-r--r--drivers/dma-buf/dma-buf.c58
-rw-r--r--drivers/gpu/drm/Kconfig8
-rw-r--r--drivers/gpu/drm/Makefile5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c8
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c8
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c8
-rw-r--r--drivers/gpu/drm/bridge/dw-hdmi.c8
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c9
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c57
-rw-r--r--drivers/gpu/drm/drm_crtc.c65
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c22
-rw-r--r--drivers/gpu/drm/drm_dp_aux_dev.c368
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c16
-rw-r--r--drivers/gpu/drm/drm_edid.c26
-rw-r--r--drivers/gpu/drm/drm_encoder_slave.c3
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c35
-rw-r--r--drivers/gpu/drm/drm_kms_helper_common.c60
-rw-r--r--drivers/gpu/drm/drm_modes.c3
-rw-r--r--drivers/gpu/drm/drm_prime.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c8
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c1
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c1
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c7
-rw-r--r--drivers/gpu/drm/gma500/gma_display.h3
-rw-r--r--drivers/gpu/drm/gma500/intel_gmbus.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c1
-rw-r--r--drivers/gpu/drm/i2c/ch7006_drv.c2
-rw-r--r--drivers/gpu/drm/i2c/sil164_drv.c9
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c9
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c12
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c42
-rw-r--r--drivers/gpu/drm/i915/intel_display.c5
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c18
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c8
-rw-r--r--drivers/gpu/drm/imx/dw_hdmi-imx.c8
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c8
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c8
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c8
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c8
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c8
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c8
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c8
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c9
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c8
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c21
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c11
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c9
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c11
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c8
-rw-r--r--drivers/gpu/drm/sti/sti_tvout.c10
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c9
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_tfp410.c9
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c14
-rw-r--r--drivers/gpu/drm/udl/udl_encoder.c8
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c8
-rw-r--r--drivers/gpu/vga/vga_switcheroo.c119
-rw-r--r--drivers/platform/x86/apple-gmux.c111
-rw-r--r--drivers/staging/android/ion/ion.c6
-rw-r--r--drivers/staging/android/ion/ion_test.c4
-rw-r--r--include/drm/drm_crtc.h18
-rw-r--r--include/drm/drm_dp_aux_dev.h62
-rw-r--r--include/drm/drm_fb_helper.h6
-rw-r--r--include/drm/drm_modeset_helper_vtables.h2
-rw-r--r--include/linux/apple-gmux.h50
-rw-r--r--include/linux/dma-buf.h12
-rw-r--r--include/linux/vga_switcheroo.h36
-rw-r--r--include/uapi/drm/drm.h1
-rw-r--r--include/uapi/linux/dma-buf.h40
83 files changed, 1260 insertions, 428 deletions
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
index 49c97913c5ae..fe6b36a2fd98 100644
--- a/Documentation/DocBook/gpu.tmpl
+++ b/Documentation/DocBook/gpu.tmpl
@@ -3422,6 +3422,7 @@ int num_ioctls;</synopsis>
3422 </sect1> 3422 </sect1>
3423 <sect1> 3423 <sect1>
3424 <title>Public constants</title> 3424 <title>Public constants</title>
3425!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler_flags_t
3425!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id 3426!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id
3426!Finclude/linux/vga_switcheroo.h vga_switcheroo_state 3427!Finclude/linux/vga_switcheroo.h vga_switcheroo_state
3427 </sect1> 3428 </sect1>
@@ -3450,6 +3451,10 @@ int num_ioctls;</synopsis>
3450 <title>Backlight control</title> 3451 <title>Backlight control</title>
3451!Pdrivers/platform/x86/apple-gmux.c Backlight control 3452!Pdrivers/platform/x86/apple-gmux.c Backlight control
3452 </sect2> 3453 </sect2>
3454 <sect2>
3455 <title>Public functions</title>
3456!Iinclude/linux/apple-gmux.h
3457 </sect2>
3453 </sect1> 3458 </sect1>
3454 </chapter> 3459 </chapter>
3455 3460
diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt
index 480c8de3c2c4..32ac32e773e1 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -257,17 +257,15 @@ Access to a dma_buf from the kernel context involves three steps:
257 257
258 Interface: 258 Interface:
259 int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, 259 int dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
260 size_t start, size_t len,
261 enum dma_data_direction direction) 260 enum dma_data_direction direction)
262 261
263 This allows the exporter to ensure that the memory is actually available for 262 This allows the exporter to ensure that the memory is actually available for
264 cpu access - the exporter might need to allocate or swap-in and pin the 263 cpu access - the exporter might need to allocate or swap-in and pin the
265 backing storage. The exporter also needs to ensure that cpu access is 264 backing storage. The exporter also needs to ensure that cpu access is
266 coherent for the given range and access direction. The range and access 265 coherent for the access direction. The direction can be used by the exporter
267 direction can be used by the exporter to optimize the cache flushing, i.e. 266 to optimize the cache flushing, i.e. access with a different direction (read
268 access outside of the range or with a different direction (read instead of 267 instead of write) might return stale or even bogus data (e.g. when the
269 write) might return stale or even bogus data (e.g. when the exporter needs to 268 exporter needs to copy the data to temporary storage).
270 copy the data to temporary storage).
271 269
272 This step might fail, e.g. in oom conditions. 270 This step might fail, e.g. in oom conditions.
273 271
@@ -322,14 +320,13 @@ Access to a dma_buf from the kernel context involves three steps:
322 320
3233. Finish access 3213. Finish access
324 322
325 When the importer is done accessing the range specified in begin_cpu_access, 323 When the importer is done accessing the CPU, it needs to announce this to
326 it needs to announce this to the exporter (to facilitate cache flushing and 324 the exporter (to facilitate cache flushing and unpinning of any pinned
327 unpinning of any pinned resources). The result of any dma_buf kmap calls 325 resources). The result of any dma_buf kmap calls after end_cpu_access is
328 after end_cpu_access is undefined. 326 undefined.
329 327
330 Interface: 328 Interface:
331 void dma_buf_end_cpu_access(struct dma_buf *dma_buf, 329 void dma_buf_end_cpu_access(struct dma_buf *dma_buf,
332 size_t start, size_t len,
333 enum dma_data_direction dir); 330 enum dma_data_direction dir);
334 331
335 332
@@ -353,7 +350,26 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases:
353 handles, too). So it's beneficial to support this in a similar fashion on 350 handles, too). So it's beneficial to support this in a similar fashion on
354 dma-buf to have a good transition path for existing Android userspace. 351 dma-buf to have a good transition path for existing Android userspace.
355 352
356 No special interfaces, userspace simply calls mmap on the dma-buf fd. 353 No special interfaces, userspace simply calls mmap on the dma-buf fd, making
354 sure that the cache synchronization ioctl (DMA_BUF_IOCTL_SYNC) is *always*
355 used when the access happens. This is discussed next paragraphs.
356
357 Some systems might need some sort of cache coherency management e.g. when
358 CPU and GPU domains are being accessed through dma-buf at the same time. To
359 circumvent this problem there are begin/end coherency markers, that forward
360 directly to existing dma-buf device drivers vfunc hooks. Userspace can make
361 use of those markers through the DMA_BUF_IOCTL_SYNC ioctl. The sequence
362 would be used like following:
363 - mmap dma-buf fd
364 - for each drawing/upload cycle in CPU 1. SYNC_START ioctl, 2. read/write
365 to mmap area 3. SYNC_END ioctl. This can be repeated as often as you
366 want (with the new data being consumed by the GPU or say scanout device)
367 - munmap once you don't need the buffer any more
368
369 Therefore, for correctness and optimal performance, systems with the memory
370 cache shared by the GPU and CPU i.e. the "coherent" and also the
371 "incoherent" are always required to use SYNC_START and SYNC_END before and
372 after, respectively, when accessing the mapped address.
357 373
3582. Supporting existing mmap interfaces in importers 3742. Supporting existing mmap interfaces in importers
359 375
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 155c1464948e..9810d1df0691 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -34,6 +34,8 @@
34#include <linux/poll.h> 34#include <linux/poll.h>
35#include <linux/reservation.h> 35#include <linux/reservation.h>
36 36
37#include <uapi/linux/dma-buf.h>
38
37static inline int is_dma_buf_file(struct file *); 39static inline int is_dma_buf_file(struct file *);
38 40
39struct dma_buf_list { 41struct dma_buf_list {
@@ -251,11 +253,54 @@ out:
251 return events; 253 return events;
252} 254}
253 255
256static long dma_buf_ioctl(struct file *file,
257 unsigned int cmd, unsigned long arg)
258{
259 struct dma_buf *dmabuf;
260 struct dma_buf_sync sync;
261 enum dma_data_direction direction;
262
263 dmabuf = file->private_data;
264
265 switch (cmd) {
266 case DMA_BUF_IOCTL_SYNC:
267 if (copy_from_user(&sync, (void __user *) arg, sizeof(sync)))
268 return -EFAULT;
269
270 if (sync.flags & ~DMA_BUF_SYNC_VALID_FLAGS_MASK)
271 return -EINVAL;
272
273 switch (sync.flags & DMA_BUF_SYNC_RW) {
274 case DMA_BUF_SYNC_READ:
275 direction = DMA_FROM_DEVICE;
276 break;
277 case DMA_BUF_SYNC_WRITE:
278 direction = DMA_TO_DEVICE;
279 break;
280 case DMA_BUF_SYNC_RW:
281 direction = DMA_BIDIRECTIONAL;
282 break;
283 default:
284 return -EINVAL;
285 }
286
287 if (sync.flags & DMA_BUF_SYNC_END)
288 dma_buf_end_cpu_access(dmabuf, direction);
289 else
290 dma_buf_begin_cpu_access(dmabuf, direction);
291
292 return 0;
293 default:
294 return -ENOTTY;
295 }
296}
297
254static const struct file_operations dma_buf_fops = { 298static const struct file_operations dma_buf_fops = {
255 .release = dma_buf_release, 299 .release = dma_buf_release,
256 .mmap = dma_buf_mmap_internal, 300 .mmap = dma_buf_mmap_internal,
257 .llseek = dma_buf_llseek, 301 .llseek = dma_buf_llseek,
258 .poll = dma_buf_poll, 302 .poll = dma_buf_poll,
303 .unlocked_ioctl = dma_buf_ioctl,
259}; 304};
260 305
261/* 306/*
@@ -539,13 +584,11 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment);
539 * preparations. Coherency is only guaranteed in the specified range for the 584 * preparations. Coherency is only guaranteed in the specified range for the
540 * specified access direction. 585 * specified access direction.
541 * @dmabuf: [in] buffer to prepare cpu access for. 586 * @dmabuf: [in] buffer to prepare cpu access for.
542 * @start: [in] start of range for cpu access.
543 * @len: [in] length of range for cpu access.
544 * @direction: [in] length of range for cpu access. 587 * @direction: [in] length of range for cpu access.
545 * 588 *
546 * Can return negative error values, returns 0 on success. 589 * Can return negative error values, returns 0 on success.
547 */ 590 */
548int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, 591int dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
549 enum dma_data_direction direction) 592 enum dma_data_direction direction)
550{ 593{
551 int ret = 0; 594 int ret = 0;
@@ -554,8 +597,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len,
554 return -EINVAL; 597 return -EINVAL;
555 598
556 if (dmabuf->ops->begin_cpu_access) 599 if (dmabuf->ops->begin_cpu_access)
557 ret = dmabuf->ops->begin_cpu_access(dmabuf, start, 600 ret = dmabuf->ops->begin_cpu_access(dmabuf, direction);
558 len, direction);
559 601
560 return ret; 602 return ret;
561} 603}
@@ -567,19 +609,17 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access);
567 * actions. Coherency is only guaranteed in the specified range for the 609 * actions. Coherency is only guaranteed in the specified range for the
568 * specified access direction. 610 * specified access direction.
569 * @dmabuf: [in] buffer to complete cpu access for. 611 * @dmabuf: [in] buffer to complete cpu access for.
570 * @start: [in] start of range for cpu access.
571 * @len: [in] length of range for cpu access.
572 * @direction: [in] length of range for cpu access. 612 * @direction: [in] length of range for cpu access.
573 * 613 *
574 * This call must always succeed. 614 * This call must always succeed.
575 */ 615 */
576void dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, 616void dma_buf_end_cpu_access(struct dma_buf *dmabuf,
577 enum dma_data_direction direction) 617 enum dma_data_direction direction)
578{ 618{
579 WARN_ON(!dmabuf); 619 WARN_ON(!dmabuf);
580 620
581 if (dmabuf->ops->end_cpu_access) 621 if (dmabuf->ops->end_cpu_access)
582 dmabuf->ops->end_cpu_access(dmabuf, start, len, direction); 622 dmabuf->ops->end_cpu_access(dmabuf, direction);
583} 623}
584EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); 624EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access);
585 625
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 438e92d4c389..08706f064e6e 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -25,6 +25,14 @@ config DRM_MIPI_DSI
25 bool 25 bool
26 depends on DRM 26 depends on DRM
27 27
28config DRM_DP_AUX_CHARDEV
29 bool "DRM DP AUX Interface"
30 depends on DRM
31 help
32 Choose this option to enable a /dev/drm_dp_auxN node that allows to
33 read and write values to arbitrary DPCD registers on the DP aux
34 channel.
35
28config DRM_KMS_HELPER 36config DRM_KMS_HELPER
29 tristate 37 tristate
30 depends on DRM 38 depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f80fdbaeb641..6eb94fc561dc 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -22,10 +22,13 @@ drm-$(CONFIG_OF) += drm_of.o
22drm-$(CONFIG_AGP) += drm_agpsupport.o 22drm-$(CONFIG_AGP) += drm_agpsupport.o
23 23
24drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 24drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
25 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o 25 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
26 drm_kms_helper_common.o
27
26drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 28drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
27drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 29drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
28drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o 30drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
31drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
29 32
30obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o 33obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
31 34
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index 3c895863fcf5..fa948dcbdd5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -552,13 +552,14 @@ static bool amdgpu_atpx_detect(void)
552void amdgpu_register_atpx_handler(void) 552void amdgpu_register_atpx_handler(void)
553{ 553{
554 bool r; 554 bool r;
555 enum vga_switcheroo_handler_flags_t handler_flags = 0;
555 556
556 /* detect if we have any ATPX + 2 VGA in the system */ 557 /* detect if we have any ATPX + 2 VGA in the system */
557 r = amdgpu_atpx_detect(); 558 r = amdgpu_atpx_detect();
558 if (!r) 559 if (!r)
559 return; 560 return;
560 561
561 vga_switcheroo_register_handler(&amdgpu_atpx_handler); 562 vga_switcheroo_register_handler(&amdgpu_atpx_handler, handler_flags);
562} 563}
563 564
564/** 565/**
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 093599aba64b..34830189311e 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -3624,16 +3624,8 @@ dce_v10_0_ext_dpms(struct drm_encoder *encoder, int mode)
3624 3624
3625} 3625}
3626 3626
3627static bool dce_v10_0_ext_mode_fixup(struct drm_encoder *encoder,
3628 const struct drm_display_mode *mode,
3629 struct drm_display_mode *adjusted_mode)
3630{
3631 return true;
3632}
3633
3634static const struct drm_encoder_helper_funcs dce_v10_0_ext_helper_funcs = { 3627static const struct drm_encoder_helper_funcs dce_v10_0_ext_helper_funcs = {
3635 .dpms = dce_v10_0_ext_dpms, 3628 .dpms = dce_v10_0_ext_dpms,
3636 .mode_fixup = dce_v10_0_ext_mode_fixup,
3637 .prepare = dce_v10_0_ext_prepare, 3629 .prepare = dce_v10_0_ext_prepare,
3638 .mode_set = dce_v10_0_ext_mode_set, 3630 .mode_set = dce_v10_0_ext_mode_set,
3639 .commit = dce_v10_0_ext_commit, 3631 .commit = dce_v10_0_ext_commit,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 8e67249d4367..36deea162779 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -3619,16 +3619,8 @@ dce_v11_0_ext_dpms(struct drm_encoder *encoder, int mode)
3619 3619
3620} 3620}
3621 3621
3622static bool dce_v11_0_ext_mode_fixup(struct drm_encoder *encoder,
3623 const struct drm_display_mode *mode,
3624 struct drm_display_mode *adjusted_mode)
3625{
3626 return true;
3627}
3628
3629static const struct drm_encoder_helper_funcs dce_v11_0_ext_helper_funcs = { 3622static const struct drm_encoder_helper_funcs dce_v11_0_ext_helper_funcs = {
3630 .dpms = dce_v11_0_ext_dpms, 3623 .dpms = dce_v11_0_ext_dpms,
3631 .mode_fixup = dce_v11_0_ext_mode_fixup,
3632 .prepare = dce_v11_0_ext_prepare, 3624 .prepare = dce_v11_0_ext_prepare,
3633 .mode_set = dce_v11_0_ext_mode_set, 3625 .mode_set = dce_v11_0_ext_mode_set,
3634 .commit = dce_v11_0_ext_commit, 3626 .commit = dce_v11_0_ext_commit,
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index d0e128c24813..25dd8b668ea5 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -3554,16 +3554,8 @@ dce_v8_0_ext_dpms(struct drm_encoder *encoder, int mode)
3554 3554
3555} 3555}
3556 3556
3557static bool dce_v8_0_ext_mode_fixup(struct drm_encoder *encoder,
3558 const struct drm_display_mode *mode,
3559 struct drm_display_mode *adjusted_mode)
3560{
3561 return true;
3562}
3563
3564static const struct drm_encoder_helper_funcs dce_v8_0_ext_helper_funcs = { 3557static const struct drm_encoder_helper_funcs dce_v8_0_ext_helper_funcs = {
3565 .dpms = dce_v8_0_ext_dpms, 3558 .dpms = dce_v8_0_ext_dpms,
3566 .mode_fixup = dce_v8_0_ext_mode_fixup,
3567 .prepare = dce_v8_0_ext_prepare, 3559 .prepare = dce_v8_0_ext_prepare,
3568 .mode_set = dce_v8_0_ext_mode_set, 3560 .mode_set = dce_v8_0_ext_mode_set,
3569 .commit = dce_v8_0_ext_commit, 3561 .commit = dce_v8_0_ext_commit,
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 0123458cbd83..f221e2dc1b0d 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -710,13 +710,6 @@ static void ast_encoder_dpms(struct drm_encoder *encoder, int mode)
710 710
711} 711}
712 712
713static bool ast_mode_fixup(struct drm_encoder *encoder,
714 const struct drm_display_mode *mode,
715 struct drm_display_mode *adjusted_mode)
716{
717 return true;
718}
719
720static void ast_encoder_mode_set(struct drm_encoder *encoder, 713static void ast_encoder_mode_set(struct drm_encoder *encoder,
721 struct drm_display_mode *mode, 714 struct drm_display_mode *mode,
722 struct drm_display_mode *adjusted_mode) 715 struct drm_display_mode *adjusted_mode)
@@ -736,7 +729,6 @@ static void ast_encoder_commit(struct drm_encoder *encoder)
736 729
737static const struct drm_encoder_helper_funcs ast_enc_helper_funcs = { 730static const struct drm_encoder_helper_funcs ast_enc_helper_funcs = {
738 .dpms = ast_encoder_dpms, 731 .dpms = ast_encoder_dpms,
739 .mode_fixup = ast_mode_fixup,
740 .prepare = ast_encoder_prepare, 732 .prepare = ast_encoder_prepare,
741 .commit = ast_encoder_commit, 733 .commit = ast_encoder_commit,
742 .mode_set = ast_encoder_mode_set, 734 .mode_set = ast_encoder_mode_set,
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 2849f1b95eec..317c27f2a50b 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -152,13 +152,6 @@ static void bochs_crtc_init(struct drm_device *dev)
152 drm_crtc_helper_add(crtc, &bochs_helper_funcs); 152 drm_crtc_helper_add(crtc, &bochs_helper_funcs);
153} 153}
154 154
155static bool bochs_encoder_mode_fixup(struct drm_encoder *encoder,
156 const struct drm_display_mode *mode,
157 struct drm_display_mode *adjusted_mode)
158{
159 return true;
160}
161
162static void bochs_encoder_mode_set(struct drm_encoder *encoder, 155static void bochs_encoder_mode_set(struct drm_encoder *encoder,
163 struct drm_display_mode *mode, 156 struct drm_display_mode *mode,
164 struct drm_display_mode *adjusted_mode) 157 struct drm_display_mode *adjusted_mode)
@@ -179,7 +172,6 @@ static void bochs_encoder_commit(struct drm_encoder *encoder)
179 172
180static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = { 173static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = {
181 .dpms = bochs_encoder_dpms, 174 .dpms = bochs_encoder_dpms,
182 .mode_fixup = bochs_encoder_mode_fixup,
183 .mode_set = bochs_encoder_mode_set, 175 .mode_set = bochs_encoder_mode_set,
184 .prepare = bochs_encoder_prepare, 176 .prepare = bochs_encoder_prepare,
185 .commit = bochs_encoder_commit, 177 .commit = bochs_encoder_commit,
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index b0aac4733020..9795b72472ba 100644
--- a/drivers/gpu/drm/bridge/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -1391,13 +1391,6 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
1391 mutex_unlock(&hdmi->mutex); 1391 mutex_unlock(&hdmi->mutex);
1392} 1392}
1393 1393
1394static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
1395 const struct drm_display_mode *mode,
1396 struct drm_display_mode *adjusted_mode)
1397{
1398 return true;
1399}
1400
1401static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) 1394static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
1402{ 1395{
1403 struct dw_hdmi *hdmi = bridge->driver_private; 1396 struct dw_hdmi *hdmi = bridge->driver_private;
@@ -1546,7 +1539,6 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
1546 .pre_enable = dw_hdmi_bridge_nop, 1539 .pre_enable = dw_hdmi_bridge_nop,
1547 .post_disable = dw_hdmi_bridge_nop, 1540 .post_disable = dw_hdmi_bridge_nop,
1548 .mode_set = dw_hdmi_bridge_mode_set, 1541 .mode_set = dw_hdmi_bridge_mode_set,
1549 .mode_fixup = dw_hdmi_bridge_mode_fixup,
1550}; 1542};
1551 1543
1552static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id) 1544static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 4a02854a6963..432ce9440e09 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -430,14 +430,6 @@ void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
430 *blue = cirrus_crtc->lut_b[regno]; 430 *blue = cirrus_crtc->lut_b[regno];
431} 431}
432 432
433
434static bool cirrus_encoder_mode_fixup(struct drm_encoder *encoder,
435 const struct drm_display_mode *mode,
436 struct drm_display_mode *adjusted_mode)
437{
438 return true;
439}
440
441static void cirrus_encoder_mode_set(struct drm_encoder *encoder, 433static void cirrus_encoder_mode_set(struct drm_encoder *encoder,
442 struct drm_display_mode *mode, 434 struct drm_display_mode *mode,
443 struct drm_display_mode *adjusted_mode) 435 struct drm_display_mode *adjusted_mode)
@@ -466,7 +458,6 @@ static void cirrus_encoder_destroy(struct drm_encoder *encoder)
466 458
467static const struct drm_encoder_helper_funcs cirrus_encoder_helper_funcs = { 459static const struct drm_encoder_helper_funcs cirrus_encoder_helper_funcs = {
468 .dpms = cirrus_encoder_dpms, 460 .dpms = cirrus_encoder_dpms,
469 .mode_fixup = cirrus_encoder_mode_fixup,
470 .mode_set = cirrus_encoder_mode_set, 461 .mode_set = cirrus_encoder_mode_set,
471 .prepare = cirrus_encoder_prepare, 462 .prepare = cirrus_encoder_prepare,
472 .commit = cirrus_encoder_commit, 463 .commit = cirrus_encoder_commit,
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 0ab7c24cd7d6..2b430b05f35d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -125,6 +125,47 @@ get_current_crtc_for_encoder(struct drm_device *dev,
125 return NULL; 125 return NULL;
126} 126}
127 127
128static void
129set_best_encoder(struct drm_atomic_state *state,
130 struct drm_connector_state *conn_state,
131 struct drm_encoder *encoder)
132{
133 struct drm_crtc_state *crtc_state;
134 struct drm_crtc *crtc;
135
136 if (conn_state->best_encoder) {
137 /* Unset the encoder_mask in the old crtc state. */
138 crtc = conn_state->connector->state->crtc;
139
140 /* A NULL crtc is an error here because we should have
141 * duplicated a NULL best_encoder when crtc was NULL.
142 * As an exception restoring duplicated atomic state
143 * during resume is allowed, so don't warn when
144 * best_encoder is equal to encoder we intend to set.
145 */
146 WARN_ON(!crtc && encoder != conn_state->best_encoder);
147 if (crtc) {
148 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
149
150 crtc_state->encoder_mask &=
151 ~(1 << drm_encoder_index(conn_state->best_encoder));
152 }
153 }
154
155 if (encoder) {
156 crtc = conn_state->crtc;
157 WARN_ON(!crtc);
158 if (crtc) {
159 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
160
161 crtc_state->encoder_mask |=
162 1 << drm_encoder_index(encoder);
163 }
164 }
165
166 conn_state->best_encoder = encoder;
167}
168
128static int 169static int
129steal_encoder(struct drm_atomic_state *state, 170steal_encoder(struct drm_atomic_state *state,
130 struct drm_encoder *encoder, 171 struct drm_encoder *encoder,
@@ -134,7 +175,6 @@ steal_encoder(struct drm_atomic_state *state,
134 struct drm_crtc_state *crtc_state; 175 struct drm_crtc_state *crtc_state;
135 struct drm_connector *connector; 176 struct drm_connector *connector;
136 struct drm_connector_state *connector_state; 177 struct drm_connector_state *connector_state;
137 int ret;
138 178
139 /* 179 /*
140 * We can only steal an encoder coming from a connector, which means we 180 * We can only steal an encoder coming from a connector, which means we
@@ -165,10 +205,10 @@ steal_encoder(struct drm_atomic_state *state,
165 if (IS_ERR(connector_state)) 205 if (IS_ERR(connector_state))
166 return PTR_ERR(connector_state); 206 return PTR_ERR(connector_state);
167 207
168 ret = drm_atomic_set_crtc_for_connector(connector_state, NULL); 208 if (connector_state->best_encoder != encoder)
169 if (ret) 209 continue;
170 return ret; 210
171 connector_state->best_encoder = NULL; 211 set_best_encoder(state, connector_state, NULL);
172 } 212 }
173 213
174 return 0; 214 return 0;
@@ -216,7 +256,7 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
216 connector->base.id, 256 connector->base.id,
217 connector->name); 257 connector->name);
218 258
219 connector_state->best_encoder = NULL; 259 set_best_encoder(state, connector_state, NULL);
220 260
221 return 0; 261 return 0;
222 } 262 }
@@ -245,6 +285,8 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
245 } 285 }
246 286
247 if (new_encoder == connector_state->best_encoder) { 287 if (new_encoder == connector_state->best_encoder) {
288 set_best_encoder(state, connector_state, new_encoder);
289
248 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", 290 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
249 connector->base.id, 291 connector->base.id,
250 connector->name, 292 connector->name,
@@ -279,7 +321,8 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
279 if (WARN_ON(!connector_state->crtc)) 321 if (WARN_ON(!connector_state->crtc))
280 return -EINVAL; 322 return -EINVAL;
281 323
282 connector_state->best_encoder = new_encoder; 324 set_best_encoder(state, connector_state, new_encoder);
325
283 idx = drm_crtc_index(connector_state->crtc); 326 idx = drm_crtc_index(connector_state->crtc);
284 327
285 crtc_state = state->crtc_states[idx]; 328 crtc_state = state->crtc_states[idx];
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6e6514ef9968..65258acddb90 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1161,6 +1161,29 @@ out_unlock:
1161EXPORT_SYMBOL(drm_encoder_init); 1161EXPORT_SYMBOL(drm_encoder_init);
1162 1162
1163/** 1163/**
1164 * drm_encoder_index - find the index of a registered encoder
1165 * @encoder: encoder to find index for
1166 *
1167 * Given a registered encoder, return the index of that encoder within a DRM
1168 * device's list of encoders.
1169 */
1170unsigned int drm_encoder_index(struct drm_encoder *encoder)
1171{
1172 unsigned int index = 0;
1173 struct drm_encoder *tmp;
1174
1175 drm_for_each_encoder(tmp, encoder->dev) {
1176 if (tmp == encoder)
1177 return index;
1178
1179 index++;
1180 }
1181
1182 BUG();
1183}
1184EXPORT_SYMBOL(drm_encoder_index);
1185
1186/**
1164 * drm_encoder_cleanup - cleans up an initialised encoder 1187 * drm_encoder_cleanup - cleans up an initialised encoder
1165 * @encoder: encoder to cleanup 1188 * @encoder: encoder to cleanup
1166 * 1189 *
@@ -5715,6 +5738,48 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
5715EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); 5738EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
5716 5739
5717/** 5740/**
5741 * drm_format_plane_width - width of the plane given the first plane
5742 * @width: width of the first plane
5743 * @format: pixel format
5744 * @plane: plane index
5745 *
5746 * Returns:
5747 * The width of @plane, given that the width of the first plane is @width.
5748 */
5749int drm_format_plane_width(int width, uint32_t format, int plane)
5750{
5751 if (plane >= drm_format_num_planes(format))
5752 return 0;
5753
5754 if (plane == 0)
5755 return width;
5756
5757 return width / drm_format_horz_chroma_subsampling(format);
5758}
5759EXPORT_SYMBOL(drm_format_plane_width);
5760
5761/**
5762 * drm_format_plane_height - height of the plane given the first plane
5763 * @height: height of the first plane
5764 * @format: pixel format
5765 * @plane: plane index
5766 *
5767 * Returns:
5768 * The height of @plane, given that the height of the first plane is @height.
5769 */
5770int drm_format_plane_height(int height, uint32_t format, int plane)
5771{
5772 if (plane >= drm_format_num_planes(format))
5773 return 0;
5774
5775 if (plane == 0)
5776 return height;
5777
5778 return height / drm_format_vert_chroma_subsampling(format);
5779}
5780EXPORT_SYMBOL(drm_format_plane_height);
5781
5782/**
5718 * drm_rotation_simplify() - Try to simplify the rotation 5783 * drm_rotation_simplify() - Try to simplify the rotation
5719 * @rotation: Rotation to be simplified 5784 * @rotation: Rotation to be simplified
5720 * @supported_rotations: Supported rotations 5785 * @supported_rotations: Supported rotations
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9f8b894f4480..7539eea4ccbc 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -73,9 +73,6 @@
73 * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct 73 * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
74 * &drm_connector_helper_funcs. 74 * &drm_connector_helper_funcs.
75 */ 75 */
76MODULE_AUTHOR("David Airlie, Jesse Barnes");
77MODULE_DESCRIPTION("DRM KMS helper");
78MODULE_LICENSE("GPL and additional rights");
79 76
80/** 77/**
81 * drm_helper_move_panel_connectors_to_head() - move panels to the front in the 78 * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
@@ -337,16 +334,21 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
337 } 334 }
338 335
339 encoder_funcs = encoder->helper_private; 336 encoder_funcs = encoder->helper_private;
340 if (!(ret = encoder_funcs->mode_fixup(encoder, mode, 337 if (encoder_funcs->mode_fixup) {
341 adjusted_mode))) { 338 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
342 DRM_DEBUG_KMS("Encoder fixup failed\n"); 339 adjusted_mode))) {
343 goto done; 340 DRM_DEBUG_KMS("Encoder fixup failed\n");
341 goto done;
342 }
344 } 343 }
345 } 344 }
346 345
347 if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { 346 if (crtc_funcs->mode_fixup) {
348 DRM_DEBUG_KMS("CRTC fixup failed\n"); 347 if (!(ret = crtc_funcs->mode_fixup(crtc, mode,
349 goto done; 348 adjusted_mode))) {
349 DRM_DEBUG_KMS("CRTC fixup failed\n");
350 goto done;
351 }
350 } 352 }
351 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); 353 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
352 354
diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c b/drivers/gpu/drm/drm_dp_aux_dev.c
new file mode 100644
index 000000000000..f73b38b33a8e
--- /dev/null
+++ b/drivers/gpu/drm/drm_dp_aux_dev.c
@@ -0,0 +1,368 @@
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rafael Antognolli <rafael.antognolli@intel.com>
25 *
26 */
27
28#include <linux/device.h>
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/uaccess.h>
35#include <drm/drm_dp_helper.h>
36#include <drm/drm_crtc.h>
37#include <drm/drmP.h>
38
39struct drm_dp_aux_dev {
40 unsigned index;
41 struct drm_dp_aux *aux;
42 struct device *dev;
43 struct kref refcount;
44 atomic_t usecount;
45};
46
47#define DRM_AUX_MINORS 256
48#define AUX_MAX_OFFSET (1 << 20)
49static DEFINE_IDR(aux_idr);
50static DEFINE_MUTEX(aux_idr_mutex);
51static struct class *drm_dp_aux_dev_class;
52static int drm_dev_major = -1;
53
54static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
55{
56 struct drm_dp_aux_dev *aux_dev = NULL;
57
58 mutex_lock(&aux_idr_mutex);
59 aux_dev = idr_find(&aux_idr, index);
60 if (!kref_get_unless_zero(&aux_dev->refcount))
61 aux_dev = NULL;
62 mutex_unlock(&aux_idr_mutex);
63
64 return aux_dev;
65}
66
67static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
68{
69 struct drm_dp_aux_dev *aux_dev;
70 int index;
71
72 aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL);
73 if (!aux_dev)
74 return ERR_PTR(-ENOMEM);
75 aux_dev->aux = aux;
76 atomic_set(&aux_dev->usecount, 1);
77 kref_init(&aux_dev->refcount);
78
79 mutex_lock(&aux_idr_mutex);
80 index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS,
81 GFP_KERNEL);
82 mutex_unlock(&aux_idr_mutex);
83 if (index < 0) {
84 kfree(aux_dev);
85 return ERR_PTR(index);
86 }
87 aux_dev->index = index;
88
89 return aux_dev;
90}
91
92static void release_drm_dp_aux_dev(struct kref *ref)
93{
94 struct drm_dp_aux_dev *aux_dev =
95 container_of(ref, struct drm_dp_aux_dev, refcount);
96
97 kfree(aux_dev);
98}
99
100static ssize_t name_show(struct device *dev,
101 struct device_attribute *attr, char *buf)
102{
103 ssize_t res;
104 struct drm_dp_aux_dev *aux_dev =
105 drm_dp_aux_dev_get_by_minor(MINOR(dev->devt));
106
107 if (!aux_dev)
108 return -ENODEV;
109
110 res = sprintf(buf, "%s\n", aux_dev->aux->name);
111 kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
112
113 return res;
114}
115static DEVICE_ATTR_RO(name);
116
117static struct attribute *drm_dp_aux_attrs[] = {
118 &dev_attr_name.attr,
119 NULL,
120};
121ATTRIBUTE_GROUPS(drm_dp_aux);
122
123static int auxdev_open(struct inode *inode, struct file *file)
124{
125 unsigned int minor = iminor(inode);
126 struct drm_dp_aux_dev *aux_dev;
127
128 aux_dev = drm_dp_aux_dev_get_by_minor(minor);
129 if (!aux_dev)
130 return -ENODEV;
131
132 file->private_data = aux_dev;
133 return 0;
134}
135
136static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
137{
138 return fixed_size_llseek(file, offset, whence, AUX_MAX_OFFSET);
139}
140
141static ssize_t auxdev_read(struct file *file, char __user *buf, size_t count,
142 loff_t *offset)
143{
144 size_t bytes_pending, num_bytes_processed = 0;
145 struct drm_dp_aux_dev *aux_dev = file->private_data;
146 ssize_t res = 0;
147
148 if (!atomic_inc_not_zero(&aux_dev->usecount))
149 return -ENODEV;
150
151 bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - (*offset));
152
153 if (!access_ok(VERIFY_WRITE, buf, bytes_pending)) {
154 res = -EFAULT;
155 goto out;
156 }
157
158 while (bytes_pending > 0) {
159 uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
160 ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
161
162 res = drm_dp_dpcd_read(aux_dev->aux, *offset, localbuf, todo);
163 if (res <= 0) {
164 res = num_bytes_processed ? num_bytes_processed : res;
165 goto out;
166 }
167 if (__copy_to_user(buf + num_bytes_processed, localbuf, res)) {
168 res = num_bytes_processed ?
169 num_bytes_processed : -EFAULT;
170 goto out;
171 }
172 bytes_pending -= res;
173 *offset += res;
174 num_bytes_processed += res;
175 res = num_bytes_processed;
176 }
177
178out:
179 atomic_dec(&aux_dev->usecount);
180 wake_up_atomic_t(&aux_dev->usecount);
181 return res;
182}
183
184static ssize_t auxdev_write(struct file *file, const char __user *buf,
185 size_t count, loff_t *offset)
186{
187 size_t bytes_pending, num_bytes_processed = 0;
188 struct drm_dp_aux_dev *aux_dev = file->private_data;
189 ssize_t res = 0;
190
191 if (!atomic_inc_not_zero(&aux_dev->usecount))
192 return -ENODEV;
193
194 bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - *offset);
195
196 if (!access_ok(VERIFY_READ, buf, bytes_pending)) {
197 res = -EFAULT;
198 goto out;
199 }
200
201 while (bytes_pending > 0) {
202 uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
203 ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
204
205 if (__copy_from_user(localbuf,
206 buf + num_bytes_processed, todo)) {
207 res = num_bytes_processed ?
208 num_bytes_processed : -EFAULT;
209 goto out;
210 }
211
212 res = drm_dp_dpcd_write(aux_dev->aux, *offset, localbuf, todo);
213 if (res <= 0) {
214 res = num_bytes_processed ? num_bytes_processed : res;
215 goto out;
216 }
217 bytes_pending -= res;
218 *offset += res;
219 num_bytes_processed += res;
220 res = num_bytes_processed;
221 }
222
223out:
224 atomic_dec(&aux_dev->usecount);
225 wake_up_atomic_t(&aux_dev->usecount);
226 return res;
227}
228
229static int auxdev_release(struct inode *inode, struct file *file)
230{
231 struct drm_dp_aux_dev *aux_dev = file->private_data;
232
233 kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
234 return 0;
235}
236
237static const struct file_operations auxdev_fops = {
238 .owner = THIS_MODULE,
239 .llseek = auxdev_llseek,
240 .read = auxdev_read,
241 .write = auxdev_write,
242 .open = auxdev_open,
243 .release = auxdev_release,
244};
245
246#define to_auxdev(d) container_of(d, struct drm_dp_aux_dev, aux)
247
248static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
249{
250 struct drm_dp_aux_dev *iter, *aux_dev = NULL;
251 int id;
252
253 /* don't increase kref count here because this function should only be
254 * used by drm_dp_aux_unregister_devnode. Thus, it will always have at
255 * least one reference - the one that drm_dp_aux_register_devnode
256 * created
257 */
258 mutex_lock(&aux_idr_mutex);
259 idr_for_each_entry(&aux_idr, iter, id) {
260 if (iter->aux == aux) {
261 aux_dev = iter;
262 break;
263 }
264 }
265 mutex_unlock(&aux_idr_mutex);
266 return aux_dev;
267}
268
269static int auxdev_wait_atomic_t(atomic_t *p)
270{
271 schedule();
272 return 0;
273}
274/**
275 * drm_dp_aux_unregister_devnode() - unregister a devnode for this aux channel
276 * @aux: DisplayPort AUX channel
277 *
278 * Returns 0 on success or a negative error code on failure.
279 */
280void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
281{
282 struct drm_dp_aux_dev *aux_dev;
283 unsigned int minor;
284
285 aux_dev = drm_dp_aux_dev_get_by_aux(aux);
286 if (!aux_dev) /* attach must have failed */
287 return;
288
289 mutex_lock(&aux_idr_mutex);
290 idr_remove(&aux_idr, aux_dev->index);
291 mutex_unlock(&aux_idr_mutex);
292
293 atomic_dec(&aux_dev->usecount);
294 wait_on_atomic_t(&aux_dev->usecount, auxdev_wait_atomic_t,
295 TASK_UNINTERRUPTIBLE);
296
297 minor = aux_dev->index;
298 if (aux_dev->dev)
299 device_destroy(drm_dp_aux_dev_class,
300 MKDEV(drm_dev_major, minor));
301
302 DRM_DEBUG("drm_dp_aux_dev: aux [%s] unregistering\n", aux->name);
303 kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
304}
305EXPORT_SYMBOL(drm_dp_aux_unregister_devnode);
306
307/**
308 * drm_dp_aux_register_devnode() - register a devnode for this aux channel
309 * @aux: DisplayPort AUX channel
310 *
311 * Returns 0 on success or a negative error code on failure.
312 */
313int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
314{
315 struct drm_dp_aux_dev *aux_dev;
316 int res;
317
318 aux_dev = alloc_drm_dp_aux_dev(aux);
319 if (IS_ERR(aux_dev))
320 return PTR_ERR(aux_dev);
321
322 aux_dev->dev = device_create(drm_dp_aux_dev_class, aux->dev,
323 MKDEV(drm_dev_major, aux_dev->index), NULL,
324 "drm_dp_aux%d", aux_dev->index);
325 if (IS_ERR(aux_dev->dev)) {
326 res = PTR_ERR(aux_dev->dev);
327 aux_dev->dev = NULL;
328 goto error;
329 }
330
331 DRM_DEBUG("drm_dp_aux_dev: aux [%s] registered as minor %d\n",
332 aux->name, aux_dev->index);
333 return 0;
334error:
335 drm_dp_aux_unregister_devnode(aux);
336 return res;
337}
338EXPORT_SYMBOL(drm_dp_aux_register_devnode);
339
340int drm_dp_aux_dev_init(void)
341{
342 int res;
343
344 drm_dp_aux_dev_class = class_create(THIS_MODULE, "drm_dp_aux_dev");
345 if (IS_ERR(drm_dp_aux_dev_class)) {
346 res = PTR_ERR(drm_dp_aux_dev_class);
347 goto out;
348 }
349 drm_dp_aux_dev_class->dev_groups = drm_dp_aux_groups;
350
351 res = register_chrdev(0, "aux", &auxdev_fops);
352 if (res < 0)
353 goto out;
354 drm_dev_major = res;
355
356 return 0;
357out:
358 class_destroy(drm_dp_aux_dev_class);
359 return res;
360}
361EXPORT_SYMBOL(drm_dp_aux_dev_init);
362
363void drm_dp_aux_dev_exit(void)
364{
365 unregister_chrdev(drm_dev_major, "aux");
366 class_destroy(drm_dp_aux_dev_class);
367}
368EXPORT_SYMBOL(drm_dp_aux_dev_exit);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 9535c5b60387..7d58f594cffe 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -28,6 +28,7 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <drm/drm_dp_helper.h> 30#include <drm/drm_dp_helper.h>
31#include <drm/drm_dp_aux_dev.h>
31#include <drm/drmP.h> 32#include <drm/drmP.h>
32 33
33/** 34/**
@@ -754,6 +755,8 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
754 */ 755 */
755int drm_dp_aux_register(struct drm_dp_aux *aux) 756int drm_dp_aux_register(struct drm_dp_aux *aux)
756{ 757{
758 int ret;
759
757 mutex_init(&aux->hw_mutex); 760 mutex_init(&aux->hw_mutex);
758 761
759 aux->ddc.algo = &drm_dp_i2c_algo; 762 aux->ddc.algo = &drm_dp_i2c_algo;
@@ -768,7 +771,17 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
768 strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev), 771 strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
769 sizeof(aux->ddc.name)); 772 sizeof(aux->ddc.name));
770 773
771 return i2c_add_adapter(&aux->ddc); 774 ret = drm_dp_aux_register_devnode(aux);
775 if (ret)
776 return ret;
777
778 ret = i2c_add_adapter(&aux->ddc);
779 if (ret) {
780 drm_dp_aux_unregister_devnode(aux);
781 return ret;
782 }
783
784 return 0;
772} 785}
773EXPORT_SYMBOL(drm_dp_aux_register); 786EXPORT_SYMBOL(drm_dp_aux_register);
774 787
@@ -778,6 +791,7 @@ EXPORT_SYMBOL(drm_dp_aux_register);
778 */ 791 */
779void drm_dp_aux_unregister(struct drm_dp_aux *aux) 792void drm_dp_aux_unregister(struct drm_dp_aux *aux)
780{ 793{
794 drm_dp_aux_unregister_devnode(aux);
781 i2c_del_adapter(&aux->ddc); 795 i2c_del_adapter(&aux->ddc);
782} 796}
783EXPORT_SYMBOL(drm_dp_aux_unregister); 797EXPORT_SYMBOL(drm_dp_aux_unregister);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 04cb4877fabd..fdb1eb014586 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -32,6 +32,7 @@
32#include <linux/hdmi.h> 32#include <linux/hdmi.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/vga_switcheroo.h>
35#include <drm/drmP.h> 36#include <drm/drmP.h>
36#include <drm/drm_edid.h> 37#include <drm/drm_edid.h>
37#include <drm/drm_displayid.h> 38#include <drm/drm_displayid.h>
@@ -1395,6 +1396,31 @@ struct edid *drm_get_edid(struct drm_connector *connector,
1395EXPORT_SYMBOL(drm_get_edid); 1396EXPORT_SYMBOL(drm_get_edid);
1396 1397
1397/** 1398/**
1399 * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
1400 * @connector: connector we're probing
1401 * @adapter: I2C adapter to use for DDC
1402 *
1403 * Wrapper around drm_get_edid() for laptops with dual GPUs using one set of
1404 * outputs. The wrapper adds the requisite vga_switcheroo calls to temporarily
1405 * switch DDC to the GPU which is retrieving EDID.
1406 *
1407 * Return: Pointer to valid EDID or %NULL if we couldn't find any.
1408 */
1409struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
1410 struct i2c_adapter *adapter)
1411{
1412 struct pci_dev *pdev = connector->dev->pdev;
1413 struct edid *edid;
1414
1415 vga_switcheroo_lock_ddc(pdev);
1416 edid = drm_get_edid(connector, adapter);
1417 vga_switcheroo_unlock_ddc(pdev);
1418
1419 return edid;
1420}
1421EXPORT_SYMBOL(drm_get_edid_switcheroo);
1422
1423/**
1398 * drm_edid_duplicate - duplicate an EDID and the extensions 1424 * drm_edid_duplicate - duplicate an EDID and the extensions
1399 * @edid: EDID to duplicate 1425 * @edid: EDID to duplicate
1400 * 1426 *
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c
index e8629076de32..4484785cd9ac 100644
--- a/drivers/gpu/drm/drm_encoder_slave.c
+++ b/drivers/gpu/drm/drm_encoder_slave.c
@@ -140,6 +140,9 @@ bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
140 const struct drm_display_mode *mode, 140 const struct drm_display_mode *mode,
141 struct drm_display_mode *adjusted_mode) 141 struct drm_display_mode *adjusted_mode)
142{ 142{
143 if (!get_slave_funcs(encoder)->mode_fixup)
144 return true;
145
143 return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode); 146 return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode);
144} 147}
145EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup); 148EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 76a364e62081..855108e6e1bd 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -104,21 +104,17 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
104{ 104{
105 struct drm_device *dev = fb_helper->dev; 105 struct drm_device *dev = fb_helper->dev;
106 struct drm_connector *connector; 106 struct drm_connector *connector;
107 int i; 107 int i, ret;
108 108
109 if (!drm_fbdev_emulation) 109 if (!drm_fbdev_emulation)
110 return 0; 110 return 0;
111 111
112 mutex_lock(&dev->mode_config.mutex); 112 mutex_lock(&dev->mode_config.mutex);
113 drm_for_each_connector(connector, dev) { 113 drm_for_each_connector(connector, dev) {
114 struct drm_fb_helper_connector *fb_helper_connector; 114 ret = drm_fb_helper_add_one_connector(fb_helper, connector);
115 115
116 fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); 116 if (ret)
117 if (!fb_helper_connector)
118 goto fail; 117 goto fail;
119
120 fb_helper_connector->connector = connector;
121 fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
122 } 118 }
123 mutex_unlock(&dev->mode_config.mutex); 119 mutex_unlock(&dev->mode_config.mutex);
124 return 0; 120 return 0;
@@ -130,7 +126,7 @@ fail:
130 fb_helper->connector_count = 0; 126 fb_helper->connector_count = 0;
131 mutex_unlock(&dev->mode_config.mutex); 127 mutex_unlock(&dev->mode_config.mutex);
132 128
133 return -ENOMEM; 129 return ret;
134} 130}
135EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); 131EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
136 132
@@ -1989,13 +1985,13 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
1989 width = dev->mode_config.max_width; 1985 width = dev->mode_config.max_width;
1990 height = dev->mode_config.max_height; 1986 height = dev->mode_config.max_height;
1991 1987
1992 crtcs = kcalloc(dev->mode_config.num_connector, 1988 crtcs = kcalloc(fb_helper->connector_count,
1993 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); 1989 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
1994 modes = kcalloc(dev->mode_config.num_connector, 1990 modes = kcalloc(fb_helper->connector_count,
1995 sizeof(struct drm_display_mode *), GFP_KERNEL); 1991 sizeof(struct drm_display_mode *), GFP_KERNEL);
1996 offsets = kcalloc(dev->mode_config.num_connector, 1992 offsets = kcalloc(fb_helper->connector_count,
1997 sizeof(struct drm_fb_offset), GFP_KERNEL); 1993 sizeof(struct drm_fb_offset), GFP_KERNEL);
1998 enabled = kcalloc(dev->mode_config.num_connector, 1994 enabled = kcalloc(fb_helper->connector_count,
1999 sizeof(bool), GFP_KERNEL); 1995 sizeof(bool), GFP_KERNEL);
2000 if (!crtcs || !modes || !enabled || !offsets) { 1996 if (!crtcs || !modes || !enabled || !offsets) {
2001 DRM_ERROR("Memory allocation failed\n"); 1997 DRM_ERROR("Memory allocation failed\n");
@@ -2009,9 +2005,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
2009 fb_helper->funcs->initial_config(fb_helper, crtcs, modes, 2005 fb_helper->funcs->initial_config(fb_helper, crtcs, modes,
2010 offsets, 2006 offsets,
2011 enabled, width, height))) { 2007 enabled, width, height))) {
2012 memset(modes, 0, dev->mode_config.num_connector*sizeof(modes[0])); 2008 memset(modes, 0, fb_helper->connector_count*sizeof(modes[0]));
2013 memset(crtcs, 0, dev->mode_config.num_connector*sizeof(crtcs[0])); 2009 memset(crtcs, 0, fb_helper->connector_count*sizeof(crtcs[0]));
2014 memset(offsets, 0, dev->mode_config.num_connector*sizeof(offsets[0])); 2010 memset(offsets, 0, fb_helper->connector_count*sizeof(offsets[0]));
2015 2011
2016 if (!drm_target_cloned(fb_helper, modes, offsets, 2012 if (!drm_target_cloned(fb_helper, modes, offsets,
2017 enabled, width, height) && 2013 enabled, width, height) &&
@@ -2196,9 +2192,9 @@ EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
2196 * but the module doesn't depend on any fb console symbols. At least 2192 * but the module doesn't depend on any fb console symbols. At least
2197 * attempt to load fbcon to avoid leaving the system without a usable console. 2193 * attempt to load fbcon to avoid leaving the system without a usable console.
2198 */ 2194 */
2199#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT) 2195int __init drm_fb_helper_modinit(void)
2200static int __init drm_fb_helper_modinit(void)
2201{ 2196{
2197#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
2202 const char *name = "fbcon"; 2198 const char *name = "fbcon";
2203 struct module *fbcon; 2199 struct module *fbcon;
2204 2200
@@ -2208,8 +2204,7 @@ static int __init drm_fb_helper_modinit(void)
2208 2204
2209 if (!fbcon) 2205 if (!fbcon)
2210 request_module_nowait(name); 2206 request_module_nowait(name);
2207#endif
2211 return 0; 2208 return 0;
2212} 2209}
2213 2210EXPORT_SYMBOL(drm_fb_helper_modinit);
2214module_init(drm_fb_helper_modinit);
2215#endif
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
new file mode 100644
index 000000000000..3187c4bb01cb
--- /dev/null
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -0,0 +1,60 @@
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rafael Antognolli <rafael.antognolli@intel.com>
25 *
26 */
27
28#include <drm/drmP.h>
29#include <drm/drm_fb_helper.h>
30#include <drm/drm_dp_aux_dev.h>
31
32MODULE_AUTHOR("David Airlie, Jesse Barnes");
33MODULE_DESCRIPTION("DRM KMS helper");
34MODULE_LICENSE("GPL and additional rights");
35
36static int __init drm_kms_helper_init(void)
37{
38 int ret;
39
40 /* Call init functions from specific kms helpers here */
41 ret = drm_fb_helper_modinit();
42 if (ret < 0)
43 goto out;
44
45 ret = drm_dp_aux_dev_init();
46 if (ret < 0)
47 goto out;
48
49out:
50 return ret;
51}
52
53static void __exit drm_kms_helper_exit(void)
54{
55 /* Call exit functions from specific kms helpers here */
56 drm_dp_aux_dev_exit();
57}
58
59module_init(drm_kms_helper_init);
60module_exit(drm_kms_helper_exit);
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 20775c05235a..f7448a5e95a9 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1371,8 +1371,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
1371 } 1371 }
1372done: 1372done:
1373 if (i >= 0) { 1373 if (i >= 0) {
1374 printk(KERN_WARNING 1374 pr_warn("[drm] parse error at position %i in video mode '%s'\n",
1375 "parse error at position %i in video mode '%s'\n",
1376 i, name); 1375 i, name);
1377 mode->specified = false; 1376 mode->specified = false;
1378 return false; 1377 return false;
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 27aa7183b20b..df6cdc76a16e 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -329,7 +329,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
329 * drm_gem_prime_export - helper library implementation of the export callback 329 * drm_gem_prime_export - helper library implementation of the export callback
330 * @dev: drm_device to export from 330 * @dev: drm_device to export from
331 * @obj: GEM object to export 331 * @obj: GEM object to export
332 * @flags: flags like DRM_CLOEXEC 332 * @flags: flags like DRM_CLOEXEC and DRM_RDWR
333 * 333 *
334 * This is the implementation of the gem_prime_export functions for GEM drivers 334 * This is the implementation of the gem_prime_export functions for GEM drivers
335 * using the PRIME helpers. 335 * using the PRIME helpers.
@@ -628,7 +628,6 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
628 struct drm_file *file_priv) 628 struct drm_file *file_priv)
629{ 629{
630 struct drm_prime_handle *args = data; 630 struct drm_prime_handle *args = data;
631 uint32_t flags;
632 631
633 if (!drm_core_check_feature(dev, DRIVER_PRIME)) 632 if (!drm_core_check_feature(dev, DRIVER_PRIME))
634 return -EINVAL; 633 return -EINVAL;
@@ -637,14 +636,11 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
637 return -ENOSYS; 636 return -ENOSYS;
638 637
639 /* check flags are valid */ 638 /* check flags are valid */
640 if (args->flags & ~DRM_CLOEXEC) 639 if (args->flags & ~(DRM_CLOEXEC | DRM_RDWR))
641 return -EINVAL; 640 return -EINVAL;
642 641
643 /* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */
644 flags = args->flags & DRM_CLOEXEC;
645
646 return dev->driver->prime_handle_to_fd(dev, file_priv, 642 return dev->driver->prime_handle_to_fd(dev, file_priv,
647 args->handle, flags, &args->fd); 643 args->handle, args->flags, &args->fd);
648} 644}
649 645
650int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, 646int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 673164b331c8..9fd12c621270 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1155,13 +1155,6 @@ static int exynos_dp_create_connector(struct drm_encoder *encoder)
1155 return 0; 1155 return 0;
1156} 1156}
1157 1157
1158static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
1159 const struct drm_display_mode *mode,
1160 struct drm_display_mode *adjusted_mode)
1161{
1162 return true;
1163}
1164
1165static void exynos_dp_mode_set(struct drm_encoder *encoder, 1158static void exynos_dp_mode_set(struct drm_encoder *encoder,
1166 struct drm_display_mode *mode, 1159 struct drm_display_mode *mode,
1167 struct drm_display_mode *adjusted_mode) 1160 struct drm_display_mode *adjusted_mode)
@@ -1177,7 +1170,6 @@ static void exynos_dp_disable(struct drm_encoder *encoder)
1177} 1170}
1178 1171
1179static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = { 1172static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
1180 .mode_fixup = exynos_dp_mode_fixup,
1181 .mode_set = exynos_dp_mode_set, 1173 .mode_set = exynos_dp_mode_set,
1182 .enable = exynos_dp_enable, 1174 .enable = exynos_dp_enable,
1183 .disable = exynos_dp_disable, 1175 .disable = exynos_dp_disable,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 05350ae0785b..75e570f45259 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -128,13 +128,6 @@ static int exynos_dpi_create_connector(struct drm_encoder *encoder)
128 return 0; 128 return 0;
129} 129}
130 130
131static bool exynos_dpi_mode_fixup(struct drm_encoder *encoder,
132 const struct drm_display_mode *mode,
133 struct drm_display_mode *adjusted_mode)
134{
135 return true;
136}
137
138static void exynos_dpi_mode_set(struct drm_encoder *encoder, 131static void exynos_dpi_mode_set(struct drm_encoder *encoder,
139 struct drm_display_mode *mode, 132 struct drm_display_mode *mode,
140 struct drm_display_mode *adjusted_mode) 133 struct drm_display_mode *adjusted_mode)
@@ -162,7 +155,6 @@ static void exynos_dpi_disable(struct drm_encoder *encoder)
162} 155}
163 156
164static const struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = { 157static const struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = {
165 .mode_fixup = exynos_dpi_mode_fixup,
166 .mode_set = exynos_dpi_mode_set, 158 .mode_set = exynos_dpi_mode_set,
167 .enable = exynos_dpi_enable, 159 .enable = exynos_dpi_enable,
168 .disable = exynos_dpi_disable, 160 .disable = exynos_dpi_disable,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index e977a81af2e6..736115c580fc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1597,13 +1597,6 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
1597 return 0; 1597 return 0;
1598} 1598}
1599 1599
1600static bool exynos_dsi_mode_fixup(struct drm_encoder *encoder,
1601 const struct drm_display_mode *mode,
1602 struct drm_display_mode *adjusted_mode)
1603{
1604 return true;
1605}
1606
1607static void exynos_dsi_mode_set(struct drm_encoder *encoder, 1600static void exynos_dsi_mode_set(struct drm_encoder *encoder,
1608 struct drm_display_mode *mode, 1601 struct drm_display_mode *mode,
1609 struct drm_display_mode *adjusted_mode) 1602 struct drm_display_mode *adjusted_mode)
@@ -1623,7 +1616,6 @@ static void exynos_dsi_mode_set(struct drm_encoder *encoder,
1623} 1616}
1624 1617
1625static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = { 1618static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
1626 .mode_fixup = exynos_dsi_mode_fixup,
1627 .mode_set = exynos_dsi_mode_set, 1619 .mode_set = exynos_dsi_mode_set,
1628 .enable = exynos_dsi_enable, 1620 .enable = exynos_dsi_enable,
1629 .disable = exynos_dsi_disable, 1621 .disable = exynos_dsi_disable,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 62ac4e5fa51d..65108cbd79d4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -410,13 +410,6 @@ static int vidi_create_connector(struct drm_encoder *encoder)
410 return 0; 410 return 0;
411} 411}
412 412
413static bool exynos_vidi_mode_fixup(struct drm_encoder *encoder,
414 const struct drm_display_mode *mode,
415 struct drm_display_mode *adjusted_mode)
416{
417 return true;
418}
419
420static void exynos_vidi_mode_set(struct drm_encoder *encoder, 413static void exynos_vidi_mode_set(struct drm_encoder *encoder,
421 struct drm_display_mode *mode, 414 struct drm_display_mode *mode,
422 struct drm_display_mode *adjusted_mode) 415 struct drm_display_mode *adjusted_mode)
@@ -432,7 +425,6 @@ static void exynos_vidi_disable(struct drm_encoder *encoder)
432} 425}
433 426
434static const struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs = { 427static const struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs = {
435 .mode_fixup = exynos_vidi_mode_fixup,
436 .mode_set = exynos_vidi_mode_set, 428 .mode_set = exynos_vidi_mode_set,
437 .enable = exynos_vidi_enable, 429 .enable = exynos_vidi_enable,
438 .disable = exynos_vidi_disable, 430 .disable = exynos_vidi_disable,
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index d0717a85c7ec..b837e7a92196 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -217,7 +217,6 @@ static int cdv_intel_crt_set_property(struct drm_connector *connector,
217 217
218static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = { 218static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = {
219 .dpms = cdv_intel_crt_dpms, 219 .dpms = cdv_intel_crt_dpms,
220 .mode_fixup = gma_encoder_mode_fixup,
221 .prepare = gma_encoder_prepare, 220 .prepare = gma_encoder_prepare,
222 .commit = gma_encoder_commit, 221 .commit = gma_encoder_commit,
223 .mode_set = cdv_intel_crt_mode_set, 222 .mode_set = cdv_intel_crt_mode_set,
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index ddf2d7700759..28f9d90988ff 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -255,7 +255,6 @@ static void cdv_hdmi_destroy(struct drm_connector *connector)
255 255
256static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = { 256static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = {
257 .dpms = cdv_hdmi_dpms, 257 .dpms = cdv_hdmi_dpms,
258 .mode_fixup = gma_encoder_mode_fixup,
259 .prepare = gma_encoder_prepare, 258 .prepare = gma_encoder_prepare,
260 .mode_set = cdv_hdmi_mode_set, 259 .mode_set = cdv_hdmi_mode_set,
261 .commit = gma_encoder_commit, 260 .commit = gma_encoder_commit,
diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index ff17af4cfc64..927082148d4d 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -478,13 +478,6 @@ int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
478 return 0; 478 return 0;
479} 479}
480 480
481bool gma_encoder_mode_fixup(struct drm_encoder *encoder,
482 const struct drm_display_mode *mode,
483 struct drm_display_mode *adjusted_mode)
484{
485 return true;
486}
487
488bool gma_crtc_mode_fixup(struct drm_crtc *crtc, 481bool gma_crtc_mode_fixup(struct drm_crtc *crtc,
489 const struct drm_display_mode *mode, 482 const struct drm_display_mode *mode,
490 struct drm_display_mode *adjusted_mode) 483 struct drm_display_mode *adjusted_mode)
diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h
index ed569d8a6af3..78b9f986a6e5 100644
--- a/drivers/gpu/drm/gma500/gma_display.h
+++ b/drivers/gpu/drm/gma500/gma_display.h
@@ -90,9 +90,6 @@ extern void gma_crtc_restore(struct drm_crtc *crtc);
90extern void gma_encoder_prepare(struct drm_encoder *encoder); 90extern void gma_encoder_prepare(struct drm_encoder *encoder);
91extern void gma_encoder_commit(struct drm_encoder *encoder); 91extern void gma_encoder_commit(struct drm_encoder *encoder);
92extern void gma_encoder_destroy(struct drm_encoder *encoder); 92extern void gma_encoder_destroy(struct drm_encoder *encoder);
93extern bool gma_encoder_mode_fixup(struct drm_encoder *encoder,
94 const struct drm_display_mode *mode,
95 struct drm_display_mode *adjusted_mode);
96 93
97/* Common clock related functions */ 94/* Common clock related functions */
98extern const struct gma_limit_t *gma_limit(struct drm_crtc *crtc, int refclk); 95extern const struct gma_limit_t *gma_limit(struct drm_crtc *crtc, int refclk);
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c
index 566d330aaeea..e7e22187c539 100644
--- a/drivers/gpu/drm/gma500/intel_gmbus.c
+++ b/drivers/gpu/drm/gma500/intel_gmbus.c
@@ -436,7 +436,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev)
436 return 0; 436 return 0;
437 437
438err: 438err:
439 while (--i) { 439 while (i--) {
440 struct intel_gmbus *bus = &dev_priv->gmbus[i]; 440 struct intel_gmbus *bus = &dev_priv->gmbus[i];
441 i2c_del_adapter(&bus->adapter); 441 i2c_del_adapter(&bus->adapter);
442 } 442 }
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index 2d18499d6060..8b2eb32ee988 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -601,7 +601,6 @@ static void oaktrail_hdmi_destroy(struct drm_connector *connector)
601 601
602static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = { 602static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
603 .dpms = oaktrail_hdmi_dpms, 603 .dpms = oaktrail_hdmi_dpms,
604 .mode_fixup = gma_encoder_mode_fixup,
605 .prepare = gma_encoder_prepare, 604 .prepare = gma_encoder_prepare,
606 .mode_set = oaktrail_hdmi_mode_set, 605 .mode_set = oaktrail_hdmi_mode_set,
607 .commit = gma_encoder_commit, 606 .commit = gma_encoder_commit,
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
index 90db5f4dcce5..0594c45f7164 100644
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -253,6 +253,8 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder,
253 drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); 253 drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
254 254
255 priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2); 255 priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2);
256 if (!priv->scale_property)
257 return -ENOMEM;
256 258
257 drm_object_attach_property(&connector->base, conf->tv_select_subconnector_property, 259 drm_object_attach_property(&connector->base, conf->tv_select_subconnector_property,
258 priv->select_subconnector); 260 priv->select_subconnector);
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c
index c400428f6c8c..db0b03fb0ff1 100644
--- a/drivers/gpu/drm/i2c/sil164_drv.c
+++ b/drivers/gpu/drm/i2c/sil164_drv.c
@@ -252,14 +252,6 @@ sil164_encoder_restore(struct drm_encoder *encoder)
252 priv->saved_slave_state); 252 priv->saved_slave_state);
253} 253}
254 254
255static bool
256sil164_encoder_mode_fixup(struct drm_encoder *encoder,
257 const struct drm_display_mode *mode,
258 struct drm_display_mode *adjusted_mode)
259{
260 return true;
261}
262
263static int 255static int
264sil164_encoder_mode_valid(struct drm_encoder *encoder, 256sil164_encoder_mode_valid(struct drm_encoder *encoder,
265 struct drm_display_mode *mode) 257 struct drm_display_mode *mode)
@@ -347,7 +339,6 @@ static const struct drm_encoder_slave_funcs sil164_encoder_funcs = {
347 .dpms = sil164_encoder_dpms, 339 .dpms = sil164_encoder_dpms,
348 .save = sil164_encoder_save, 340 .save = sil164_encoder_save,
349 .restore = sil164_encoder_restore, 341 .restore = sil164_encoder_restore,
350 .mode_fixup = sil164_encoder_mode_fixup,
351 .mode_valid = sil164_encoder_mode_valid, 342 .mode_valid = sil164_encoder_mode_valid,
352 .mode_set = sil164_encoder_mode_set, 343 .mode_set = sil164_encoder_mode_set,
353 .detect = sil164_encoder_detect, 344 .detect = sil164_encoder_detect,
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 34e38749a817..b61282d89aa3 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -856,14 +856,6 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
856 priv->dpms = mode; 856 priv->dpms = mode;
857} 857}
858 858
859static bool
860tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
861 const struct drm_display_mode *mode,
862 struct drm_display_mode *adjusted_mode)
863{
864 return true;
865}
866
867static int tda998x_connector_mode_valid(struct drm_connector *connector, 859static int tda998x_connector_mode_valid(struct drm_connector *connector,
868 struct drm_display_mode *mode) 860 struct drm_display_mode *mode)
869{ 861{
@@ -1343,7 +1335,6 @@ static void tda998x_encoder_commit(struct drm_encoder *encoder)
1343 1335
1344static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { 1336static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = {
1345 .dpms = tda998x_encoder_dpms, 1337 .dpms = tda998x_encoder_dpms,
1346 .mode_fixup = tda998x_encoder_mode_fixup,
1347 .prepare = tda998x_encoder_prepare, 1338 .prepare = tda998x_encoder_prepare,
1348 .commit = tda998x_encoder_commit, 1339 .commit = tda998x_encoder_commit,
1349 .mode_set = tda998x_encoder_mode_set, 1340 .mode_set = tda998x_encoder_mode_set,
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 11d8414edbbe..44912ecebc1a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -35,9 +35,12 @@
35#include "i915_trace.h" 35#include "i915_trace.h"
36#include "intel_drv.h" 36#include "intel_drv.h"
37 37
38#include <linux/apple-gmux.h>
38#include <linux/console.h> 39#include <linux/console.h>
39#include <linux/module.h> 40#include <linux/module.h>
40#include <linux/pm_runtime.h> 41#include <linux/pm_runtime.h>
42#include <linux/vgaarb.h>
43#include <linux/vga_switcheroo.h>
41#include <drm/drm_crtc_helper.h> 44#include <drm/drm_crtc_helper.h>
42 45
43static struct drm_driver driver; 46static struct drm_driver driver;
@@ -969,6 +972,15 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
969 if (PCI_FUNC(pdev->devfn)) 972 if (PCI_FUNC(pdev->devfn))
970 return -ENODEV; 973 return -ENODEV;
971 974
975 /*
976 * apple-gmux is needed on dual GPU MacBook Pro
977 * to probe the panel if we're the inactive GPU.
978 */
979 if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) &&
980 apple_gmux_present() && pdev != vga_default_device() &&
981 !vga_switcheroo_handler_flags())
982 return -EPROBE_DEFER;
983
972 return drm_get_pci_dev(pdev, ent, &driver); 984 return drm_get_pci_dev(pdev, ent, &driver);
973} 985}
974 986
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index e9c2bfd85b52..1f3eef6fb345 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -193,10 +193,26 @@ static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_n
193 193
194static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) 194static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
195{ 195{
196 return -EINVAL; 196 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
197 int ret;
198
199 if (obj->base.size < vma->vm_end - vma->vm_start)
200 return -EINVAL;
201
202 if (!obj->base.filp)
203 return -ENODEV;
204
205 ret = obj->base.filp->f_op->mmap(obj->base.filp, vma);
206 if (ret)
207 return ret;
208
209 fput(vma->vm_file);
210 vma->vm_file = get_file(obj->base.filp);
211
212 return 0;
197} 213}
198 214
199static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t length, enum dma_data_direction direction) 215static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
200{ 216{
201 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); 217 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
202 struct drm_device *dev = obj->base.dev; 218 struct drm_device *dev = obj->base.dev;
@@ -212,6 +228,27 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size
212 return ret; 228 return ret;
213} 229}
214 230
231static void i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
232{
233 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
234 struct drm_device *dev = obj->base.dev;
235 struct drm_i915_private *dev_priv = to_i915(dev);
236 bool was_interruptible;
237 int ret;
238
239 mutex_lock(&dev->struct_mutex);
240 was_interruptible = dev_priv->mm.interruptible;
241 dev_priv->mm.interruptible = false;
242
243 ret = i915_gem_object_set_to_gtt_domain(obj, false);
244
245 dev_priv->mm.interruptible = was_interruptible;
246 mutex_unlock(&dev->struct_mutex);
247
248 if (unlikely(ret))
249 DRM_ERROR("unable to flush buffer following CPU access; rendering may be corrupt\n");
250}
251
215static const struct dma_buf_ops i915_dmabuf_ops = { 252static const struct dma_buf_ops i915_dmabuf_ops = {
216 .map_dma_buf = i915_gem_map_dma_buf, 253 .map_dma_buf = i915_gem_map_dma_buf,
217 .unmap_dma_buf = i915_gem_unmap_dma_buf, 254 .unmap_dma_buf = i915_gem_unmap_dma_buf,
@@ -224,6 +261,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = {
224 .vmap = i915_gem_dmabuf_vmap, 261 .vmap = i915_gem_dmabuf_vmap,
225 .vunmap = i915_gem_dmabuf_vunmap, 262 .vunmap = i915_gem_dmabuf_vunmap,
226 .begin_cpu_access = i915_gem_begin_cpu_access, 263 .begin_cpu_access = i915_gem_begin_cpu_access,
264 .end_cpu_access = i915_gem_end_cpu_access,
227}; 265};
228 266
229struct dma_buf *i915_gem_prime_export(struct drm_device *dev, 267struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7a5ed95f2cd9..e1e7cdee3bbd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10521,7 +10521,6 @@ retry:
10521 } 10521 }
10522 10522
10523 connector_state->crtc = crtc; 10523 connector_state->crtc = crtc;
10524 connector_state->best_encoder = &intel_encoder->base;
10525 10524
10526 crtc_state = intel_atomic_get_crtc_state(state, intel_crtc); 10525 crtc_state = intel_atomic_get_crtc_state(state, intel_crtc);
10527 if (IS_ERR(crtc_state)) { 10526 if (IS_ERR(crtc_state)) {
@@ -10617,7 +10616,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
10617 if (IS_ERR(crtc_state)) 10616 if (IS_ERR(crtc_state))
10618 goto fail; 10617 goto fail;
10619 10618
10620 connector_state->best_encoder = NULL;
10621 connector_state->crtc = NULL; 10619 connector_state->crtc = NULL;
10622 10620
10623 crtc_state->base.enable = crtc_state->base.active = false; 10621 crtc_state->base.enable = crtc_state->base.active = false;
@@ -15593,6 +15591,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
15593 crtc->base.state->active = crtc->active; 15591 crtc->base.state->active = crtc->active;
15594 crtc->base.enabled = crtc->active; 15592 crtc->base.enabled = crtc->active;
15595 crtc->base.state->connector_mask = 0; 15593 crtc->base.state->connector_mask = 0;
15594 crtc->base.state->encoder_mask = 0;
15596 15595
15597 /* Because we only establish the connector -> encoder -> 15596 /* Because we only establish the connector -> encoder ->
15598 * crtc links if something is active, this means the 15597 * crtc links if something is active, this means the
@@ -15832,6 +15831,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15832 */ 15831 */
15833 encoder->base.crtc->state->connector_mask |= 15832 encoder->base.crtc->state->connector_mask |=
15834 1 << drm_connector_index(&connector->base); 15833 1 << drm_connector_index(&connector->base);
15834 encoder->base.crtc->state->encoder_mask |=
15835 1 << drm_encoder_index(&encoder->base);
15835 } 15836 }
15836 15837
15837 } else { 15838 } else {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e2bea710614f..da704c6ee5cb 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1188,7 +1188,6 @@ intel_dp_aux_fini(struct intel_dp *intel_dp)
1188static int 1188static int
1189intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) 1189intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
1190{ 1190{
1191 struct drm_device *dev = intel_dp_to_dev(intel_dp);
1192 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 1191 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
1193 enum port port = intel_dig_port->port; 1192 enum port port = intel_dig_port->port;
1194 int ret; 1193 int ret;
@@ -1199,7 +1198,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
1199 if (!intel_dp->aux.name) 1198 if (!intel_dp->aux.name)
1200 return -ENOMEM; 1199 return -ENOMEM;
1201 1200
1202 intel_dp->aux.dev = dev->dev; 1201 intel_dp->aux.dev = connector->base.kdev;
1203 intel_dp->aux.transfer = intel_dp_aux_transfer; 1202 intel_dp->aux.transfer = intel_dp_aux_transfer;
1204 1203
1205 DRM_DEBUG_KMS("registering %s bus for %s\n", 1204 DRM_DEBUG_KMS("registering %s bus for %s\n",
@@ -1214,16 +1213,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
1214 return ret; 1213 return ret;
1215 } 1214 }
1216 1215
1217 ret = sysfs_create_link(&connector->base.kdev->kobj,
1218 &intel_dp->aux.ddc.dev.kobj,
1219 intel_dp->aux.ddc.dev.kobj.name);
1220 if (ret < 0) {
1221 DRM_ERROR("sysfs_create_link() for %s failed (%d)\n",
1222 intel_dp->aux.name, ret);
1223 intel_dp_aux_fini(intel_dp);
1224 return ret;
1225 }
1226
1227 return 0; 1216 return 0;
1228} 1217}
1229 1218
@@ -1232,9 +1221,7 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
1232{ 1221{
1233 struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base); 1222 struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
1234 1223
1235 if (!intel_connector->mst_port) 1224 intel_dp_aux_fini(intel_dp);
1236 sysfs_remove_link(&intel_connector->base.kdev->kobj,
1237 intel_dp->aux.ddc.dev.kobj.name);
1238 intel_connector_unregister(intel_connector); 1225 intel_connector_unregister(intel_connector);
1239} 1226}
1240 1227
@@ -4868,7 +4855,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
4868 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); 4855 struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
4869 struct intel_dp *intel_dp = &intel_dig_port->dp; 4856 struct intel_dp *intel_dp = &intel_dig_port->dp;
4870 4857
4871 intel_dp_aux_fini(intel_dp);
4872 intel_dp_mst_encoder_cleanup(intel_dig_port); 4858 intel_dp_mst_encoder_cleanup(intel_dig_port);
4873 if (is_edp(intel_dp)) { 4859 if (is_edp(intel_dp)) {
4874 cancel_delayed_work_sync(&intel_dp->panel_vdd_work); 4860 cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 0da0240caf81..811ddf7799f0 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -31,6 +31,7 @@
31#include <linux/dmi.h> 31#include <linux/dmi.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/vga_switcheroo.h>
34#include <drm/drmP.h> 35#include <drm/drmP.h>
35#include <drm/drm_atomic_helper.h> 36#include <drm/drm_atomic_helper.h>
36#include <drm/drm_crtc.h> 37#include <drm/drm_crtc.h>
@@ -1080,7 +1081,12 @@ void intel_lvds_init(struct drm_device *dev)
1080 * preferred mode is the right one. 1081 * preferred mode is the right one.
1081 */ 1082 */
1082 mutex_lock(&dev->mode_config.mutex); 1083 mutex_lock(&dev->mode_config.mutex);
1083 edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin)); 1084 if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
1085 edid = drm_get_edid_switcheroo(connector,
1086 intel_gmbus_get_adapter(dev_priv, pin));
1087 else
1088 edid = drm_get_edid(connector,
1089 intel_gmbus_get_adapter(dev_priv, pin));
1084 if (edid) { 1090 if (edid) {
1085 if (drm_add_edid_modes(connector, edid)) { 1091 if (drm_add_edid_modes(connector, edid)) {
1086 drm_mode_connector_update_edid_property(connector, 1092 drm_mode_connector_update_edid_property(connector,
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 063825fecbe2..21d615827837 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -109,13 +109,6 @@ static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder)
109{ 109{
110} 110}
111 111
112static bool dw_hdmi_imx_encoder_mode_fixup(struct drm_encoder *encoder,
113 const struct drm_display_mode *mode,
114 struct drm_display_mode *adj_mode)
115{
116 return true;
117}
118
119static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder, 112static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder,
120 struct drm_display_mode *mode, 113 struct drm_display_mode *mode,
121 struct drm_display_mode *adj_mode) 114 struct drm_display_mode *adj_mode)
@@ -138,7 +131,6 @@ static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
138} 131}
139 132
140static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { 133static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
141 .mode_fixup = dw_hdmi_imx_encoder_mode_fixup,
142 .mode_set = dw_hdmi_imx_encoder_mode_set, 134 .mode_set = dw_hdmi_imx_encoder_mode_set,
143 .prepare = dw_hdmi_imx_encoder_prepare, 135 .prepare = dw_hdmi_imx_encoder_prepare,
144 .commit = dw_hdmi_imx_encoder_commit, 136 .commit = dw_hdmi_imx_encoder_commit,
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 22ac482231ed..024d6134b848 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -139,13 +139,6 @@ static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode)
139{ 139{
140} 140}
141 141
142static bool imx_ldb_encoder_mode_fixup(struct drm_encoder *encoder,
143 const struct drm_display_mode *mode,
144 struct drm_display_mode *adjusted_mode)
145{
146 return true;
147}
148
149static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, 142static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
150 unsigned long serial_clk, unsigned long di_clk) 143 unsigned long serial_clk, unsigned long di_clk)
151{ 144{
@@ -376,7 +369,6 @@ static const struct drm_encoder_funcs imx_ldb_encoder_funcs = {
376 369
377static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { 370static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
378 .dpms = imx_ldb_encoder_dpms, 371 .dpms = imx_ldb_encoder_dpms,
379 .mode_fixup = imx_ldb_encoder_mode_fixup,
380 .prepare = imx_ldb_encoder_prepare, 372 .prepare = imx_ldb_encoder_prepare,
381 .commit = imx_ldb_encoder_commit, 373 .commit = imx_ldb_encoder_commit,
382 .mode_set = imx_ldb_encoder_mode_set, 374 .mode_set = imx_ldb_encoder_mode_set,
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 292349f0b132..ae7a9fb3b8a2 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -286,13 +286,6 @@ static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode)
286 dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret); 286 dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret);
287} 287}
288 288
289static bool imx_tve_encoder_mode_fixup(struct drm_encoder *encoder,
290 const struct drm_display_mode *mode,
291 struct drm_display_mode *adjusted_mode)
292{
293 return true;
294}
295
296static void imx_tve_encoder_prepare(struct drm_encoder *encoder) 289static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
297{ 290{
298 struct imx_tve *tve = enc_to_tve(encoder); 291 struct imx_tve *tve = enc_to_tve(encoder);
@@ -379,7 +372,6 @@ static const struct drm_encoder_funcs imx_tve_encoder_funcs = {
379 372
380static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { 373static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = {
381 .dpms = imx_tve_encoder_dpms, 374 .dpms = imx_tve_encoder_dpms,
382 .mode_fixup = imx_tve_encoder_mode_fixup,
383 .prepare = imx_tve_encoder_prepare, 375 .prepare = imx_tve_encoder_prepare,
384 .mode_set = imx_tve_encoder_mode_set, 376 .mode_set = imx_tve_encoder_mode_set,
385 .commit = imx_tve_encoder_commit, 377 .commit = imx_tve_encoder_commit,
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 0ffef172afb4..363e2c7741e2 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -112,13 +112,6 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
112 drm_panel_enable(imxpd->panel); 112 drm_panel_enable(imxpd->panel);
113} 113}
114 114
115static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder,
116 const struct drm_display_mode *mode,
117 struct drm_display_mode *adjusted_mode)
118{
119 return true;
120}
121
122static void imx_pd_encoder_prepare(struct drm_encoder *encoder) 115static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
123{ 116{
124 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 117 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
@@ -166,7 +159,6 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = {
166 159
167static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { 160static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
168 .dpms = imx_pd_encoder_dpms, 161 .dpms = imx_pd_encoder_dpms,
169 .mode_fixup = imx_pd_encoder_mode_fixup,
170 .prepare = imx_pd_encoder_prepare, 162 .prepare = imx_pd_encoder_prepare,
171 .commit = imx_pd_encoder_commit, 163 .commit = imx_pd_encoder_commit,
172 .mode_set = imx_pd_encoder_mode_set, 164 .mode_set = imx_pd_encoder_mode_set,
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index dc13c4857e6f..af8b4c19cf15 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1479,13 +1479,6 @@ void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
1479 * These functions are analagous to those in the CRTC code, but are intended 1479 * These functions are analagous to those in the CRTC code, but are intended
1480 * to handle any encoder-specific limitations 1480 * to handle any encoder-specific limitations
1481 */ 1481 */
1482static bool mga_encoder_mode_fixup(struct drm_encoder *encoder,
1483 const struct drm_display_mode *mode,
1484 struct drm_display_mode *adjusted_mode)
1485{
1486 return true;
1487}
1488
1489static void mga_encoder_mode_set(struct drm_encoder *encoder, 1482static void mga_encoder_mode_set(struct drm_encoder *encoder,
1490 struct drm_display_mode *mode, 1483 struct drm_display_mode *mode,
1491 struct drm_display_mode *adjusted_mode) 1484 struct drm_display_mode *adjusted_mode)
@@ -1515,7 +1508,6 @@ static void mga_encoder_destroy(struct drm_encoder *encoder)
1515 1508
1516static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = { 1509static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = {
1517 .dpms = mga_encoder_dpms, 1510 .dpms = mga_encoder_dpms,
1518 .mode_fixup = mga_encoder_mode_fixup,
1519 .mode_set = mga_encoder_mode_set, 1511 .mode_set = mga_encoder_mode_set,
1520 .prepare = mga_encoder_prepare, 1512 .prepare = mga_encoder_prepare,
1521 .commit = mga_encoder_commit, 1513 .commit = mga_encoder_commit,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c
index 2f57e9453b67..106f0e772595 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dsi_encoder.c
@@ -47,13 +47,6 @@ static const struct drm_encoder_funcs mdp4_dsi_encoder_funcs = {
47 .destroy = mdp4_dsi_encoder_destroy, 47 .destroy = mdp4_dsi_encoder_destroy,
48}; 48};
49 49
50static bool mdp4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
51 const struct drm_display_mode *mode,
52 struct drm_display_mode *adjusted_mode)
53{
54 return true;
55}
56
57static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder, 50static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder,
58 struct drm_display_mode *mode, 51 struct drm_display_mode *mode,
59 struct drm_display_mode *adjusted_mode) 52 struct drm_display_mode *adjusted_mode)
@@ -163,7 +156,6 @@ static void mdp4_dsi_encoder_enable(struct drm_encoder *encoder)
163} 156}
164 157
165static const struct drm_encoder_helper_funcs mdp4_dsi_encoder_helper_funcs = { 158static const struct drm_encoder_helper_funcs mdp4_dsi_encoder_helper_funcs = {
166 .mode_fixup = mdp4_dsi_encoder_mode_fixup,
167 .mode_set = mdp4_dsi_encoder_mode_set, 159 .mode_set = mdp4_dsi_encoder_mode_set,
168 .disable = mdp4_dsi_encoder_disable, 160 .disable = mdp4_dsi_encoder_disable,
169 .enable = mdp4_dsi_encoder_enable, 161 .enable = mdp4_dsi_encoder_enable,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c
index a21df54cb50f..35ad78a1dc1c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c
@@ -94,13 +94,6 @@ static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = {
94 .destroy = mdp4_dtv_encoder_destroy, 94 .destroy = mdp4_dtv_encoder_destroy,
95}; 95};
96 96
97static bool mdp4_dtv_encoder_mode_fixup(struct drm_encoder *encoder,
98 const struct drm_display_mode *mode,
99 struct drm_display_mode *adjusted_mode)
100{
101 return true;
102}
103
104static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder, 97static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
105 struct drm_display_mode *mode, 98 struct drm_display_mode *mode,
106 struct drm_display_mode *adjusted_mode) 99 struct drm_display_mode *adjusted_mode)
@@ -234,7 +227,6 @@ static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder)
234} 227}
235 228
236static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = { 229static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = {
237 .mode_fixup = mdp4_dtv_encoder_mode_fixup,
238 .mode_set = mdp4_dtv_encoder_mode_set, 230 .mode_set = mdp4_dtv_encoder_mode_set,
239 .enable = mdp4_dtv_encoder_enable, 231 .enable = mdp4_dtv_encoder_enable,
240 .disable = mdp4_dtv_encoder_disable, 232 .disable = mdp4_dtv_encoder_disable,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c
index cd63fedb67cc..bc3d8e719c6c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c
@@ -260,13 +260,6 @@ static void setup_phy(struct drm_encoder *encoder)
260 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0); 260 mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0);
261} 261}
262 262
263static bool mdp4_lcdc_encoder_mode_fixup(struct drm_encoder *encoder,
264 const struct drm_display_mode *mode,
265 struct drm_display_mode *adjusted_mode)
266{
267 return true;
268}
269
270static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder, 263static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder,
271 struct drm_display_mode *mode, 264 struct drm_display_mode *mode,
272 struct drm_display_mode *adjusted_mode) 265 struct drm_display_mode *adjusted_mode)
@@ -430,7 +423,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
430} 423}
431 424
432static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = { 425static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = {
433 .mode_fixup = mdp4_lcdc_encoder_mode_fixup,
434 .mode_set = mdp4_lcdc_encoder_mode_set, 426 .mode_set = mdp4_lcdc_encoder_mode_set,
435 .disable = mdp4_lcdc_encoder_disable, 427 .disable = mdp4_lcdc_encoder_disable,
436 .enable = mdp4_lcdc_encoder_enable, 428 .enable = mdp4_lcdc_encoder_enable,
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
index 1aa21dba663d..69094cb28103 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
@@ -188,13 +188,6 @@ static const struct drm_encoder_funcs mdp5_cmd_encoder_funcs = {
188 .destroy = mdp5_cmd_encoder_destroy, 188 .destroy = mdp5_cmd_encoder_destroy,
189}; 189};
190 190
191static bool mdp5_cmd_encoder_mode_fixup(struct drm_encoder *encoder,
192 const struct drm_display_mode *mode,
193 struct drm_display_mode *adjusted_mode)
194{
195 return true;
196}
197
198static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, 191static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
199 struct drm_display_mode *mode, 192 struct drm_display_mode *mode,
200 struct drm_display_mode *adjusted_mode) 193 struct drm_display_mode *adjusted_mode)
@@ -256,7 +249,6 @@ static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
256} 249}
257 250
258static const struct drm_encoder_helper_funcs mdp5_cmd_encoder_helper_funcs = { 251static const struct drm_encoder_helper_funcs mdp5_cmd_encoder_helper_funcs = {
259 .mode_fixup = mdp5_cmd_encoder_mode_fixup,
260 .mode_set = mdp5_cmd_encoder_mode_set, 252 .mode_set = mdp5_cmd_encoder_mode_set,
261 .disable = mdp5_cmd_encoder_disable, 253 .disable = mdp5_cmd_encoder_disable,
262 .enable = mdp5_cmd_encoder_enable, 254 .enable = mdp5_cmd_encoder_enable,
@@ -340,4 +332,3 @@ fail:
340 332
341 return ERR_PTR(ret); 333 return ERR_PTR(ret);
342} 334}
343
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
index 0d737cad03a6..1d95f9fd9dc7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
@@ -112,13 +112,6 @@ static const struct drm_encoder_funcs mdp5_encoder_funcs = {
112 .destroy = mdp5_encoder_destroy, 112 .destroy = mdp5_encoder_destroy,
113}; 113};
114 114
115static bool mdp5_encoder_mode_fixup(struct drm_encoder *encoder,
116 const struct drm_display_mode *mode,
117 struct drm_display_mode *adjusted_mode)
118{
119 return true;
120}
121
122static void mdp5_encoder_mode_set(struct drm_encoder *encoder, 115static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
123 struct drm_display_mode *mode, 116 struct drm_display_mode *mode,
124 struct drm_display_mode *adjusted_mode) 117 struct drm_display_mode *adjusted_mode)
@@ -287,7 +280,6 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
287} 280}
288 281
289static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { 282static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
290 .mode_fixup = mdp5_encoder_mode_fixup,
291 .mode_set = mdp5_encoder_mode_set, 283 .mode_set = mdp5_encoder_mode_set,
292 .disable = mdp5_encoder_disable, 284 .disable = mdp5_encoder_disable,
293 .enable = mdp5_encoder_enable, 285 .enable = mdp5_encoder_enable,
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index d95af6eba602..d9759bf3482e 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -62,12 +62,8 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
62 struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par; 62 struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
63 struct msm_fbdev *fbdev = to_msm_fbdev(helper); 63 struct msm_fbdev *fbdev = to_msm_fbdev(helper);
64 struct drm_gem_object *drm_obj = fbdev->bo; 64 struct drm_gem_object *drm_obj = fbdev->bo;
65 struct drm_device *dev = helper->dev;
66 int ret = 0; 65 int ret = 0;
67 66
68 if (drm_device_is_unplugged(dev))
69 return -ENODEV;
70
71 ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma); 67 ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
72 if (ret) { 68 if (ret) {
73 pr_err("%s:drm_gem_mmap_obj fail\n", __func__); 69 pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index d5e6938cc6bc..cdf522770cfa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -314,7 +314,7 @@ void nouveau_register_dsm_handler(void)
314 if (!r) 314 if (!r)
315 return; 315 return;
316 316
317 vga_switcheroo_register_handler(&nouveau_dsm_handler); 317 vga_switcheroo_register_handler(&nouveau_dsm_handler, 0);
318} 318}
319 319
320/* Must be called for Optimus models before the card can be turned off */ 320/* Must be called for Optimus models before the card can be turned off */
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index fcebfae5d426..ae96ebc490fb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -27,6 +27,7 @@
27#include <acpi/button.h> 27#include <acpi/button.h>
28 28
29#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
30#include <linux/vga_switcheroo.h>
30 31
31#include <drm/drmP.h> 32#include <drm/drmP.h>
32#include <drm/drm_edid.h> 33#include <drm/drm_edid.h>
@@ -153,6 +154,17 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
153 if (ret == 0) 154 if (ret == 0)
154 break; 155 break;
155 } else 156 } else
157 if ((vga_switcheroo_handler_flags() &
158 VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
159 nv_encoder->dcb->type == DCB_OUTPUT_LVDS &&
160 nv_encoder->i2c) {
161 int ret;
162 vga_switcheroo_lock_ddc(dev->pdev);
163 ret = nvkm_probe_i2c(nv_encoder->i2c, 0x50);
164 vga_switcheroo_unlock_ddc(dev->pdev);
165 if (ret)
166 break;
167 } else
156 if (nv_encoder->i2c) { 168 if (nv_encoder->i2c) {
157 if (nvkm_probe_i2c(nv_encoder->i2c, 0x50)) 169 if (nvkm_probe_i2c(nv_encoder->i2c, 0x50))
158 break; 170 break;
@@ -265,7 +277,14 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
265 277
266 nv_encoder = nouveau_connector_ddc_detect(connector); 278 nv_encoder = nouveau_connector_ddc_detect(connector);
267 if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { 279 if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
268 nv_connector->edid = drm_get_edid(connector, i2c); 280 if ((vga_switcheroo_handler_flags() &
281 VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
282 nv_connector->type == DCB_CONNECTOR_LVDS)
283 nv_connector->edid = drm_get_edid_switcheroo(connector,
284 i2c);
285 else
286 nv_connector->edid = drm_get_edid(connector, i2c);
287
269 drm_mode_connector_update_edid_property(connector, 288 drm_mode_connector_update_edid_property(connector,
270 nv_connector->edid); 289 nv_connector->edid);
271 if (!nv_connector->edid) { 290 if (!nv_connector->edid) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 2f2f252e3fb6..bb8498c9b13e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -22,11 +22,13 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <linux/apple-gmux.h>
25#include <linux/console.h> 26#include <linux/console.h>
26#include <linux/delay.h> 27#include <linux/delay.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/pci.h> 29#include <linux/pci.h>
29#include <linux/pm_runtime.h> 30#include <linux/pm_runtime.h>
31#include <linux/vgaarb.h>
30#include <linux/vga_switcheroo.h> 32#include <linux/vga_switcheroo.h>
31 33
32#include "drmP.h" 34#include "drmP.h"
@@ -312,6 +314,15 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
312 bool boot = false; 314 bool boot = false;
313 int ret; 315 int ret;
314 316
317 /*
318 * apple-gmux is needed on dual GPU MacBook Pro
319 * to probe the panel if we're the inactive GPU.
320 */
321 if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) &&
322 apple_gmux_present() && pdev != vga_default_device() &&
323 !vga_switcheroo_handler_flags())
324 return -EPROBE_DEFER;
325
315 /* remove conflicting drivers (vesafb, efifb etc) */ 326 /* remove conflicting drivers (vesafb, efifb etc) */
316 aper = alloc_apertures(3); 327 aper = alloc_apertures(3);
317 if (!aper) 328 if (!aper)
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 27c297672076..aebae1c2dab2 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -79,7 +79,7 @@ static void omap_gem_dmabuf_release(struct dma_buf *buffer)
79 79
80 80
81static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer, 81static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer,
82 size_t start, size_t len, enum dma_data_direction dir) 82 enum dma_data_direction dir)
83{ 83{
84 struct drm_gem_object *obj = buffer->priv; 84 struct drm_gem_object *obj = buffer->priv;
85 struct page **pages; 85 struct page **pages;
@@ -94,7 +94,7 @@ static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer,
94} 94}
95 95
96static void omap_gem_dmabuf_end_cpu_access(struct dma_buf *buffer, 96static void omap_gem_dmabuf_end_cpu_access(struct dma_buf *buffer,
97 size_t start, size_t len, enum dma_data_direction dir) 97 enum dma_data_direction dir)
98{ 98{
99 struct drm_gem_object *obj = buffer->priv; 99 struct drm_gem_object *obj = buffer->priv;
100 omap_gem_put_pages(obj); 100 omap_gem_put_pages(obj);
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 86276519b2ef..43e5f503d1c5 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -734,14 +734,6 @@ static void qxl_enc_dpms(struct drm_encoder *encoder, int mode)
734 DRM_DEBUG("\n"); 734 DRM_DEBUG("\n");
735} 735}
736 736
737static bool qxl_enc_mode_fixup(struct drm_encoder *encoder,
738 const struct drm_display_mode *mode,
739 struct drm_display_mode *adjusted_mode)
740{
741 DRM_DEBUG("\n");
742 return true;
743}
744
745static void qxl_enc_prepare(struct drm_encoder *encoder) 737static void qxl_enc_prepare(struct drm_encoder *encoder)
746{ 738{
747 DRM_DEBUG("\n"); 739 DRM_DEBUG("\n");
@@ -864,7 +856,6 @@ static struct drm_encoder *qxl_best_encoder(struct drm_connector *connector)
864 856
865static const struct drm_encoder_helper_funcs qxl_enc_helper_funcs = { 857static const struct drm_encoder_helper_funcs qxl_enc_helper_funcs = {
866 .dpms = qxl_enc_dpms, 858 .dpms = qxl_enc_dpms,
867 .mode_fixup = qxl_enc_mode_fixup,
868 .prepare = qxl_enc_prepare, 859 .prepare = qxl_enc_prepare,
869 .mode_set = qxl_enc_mode_set, 860 .mode_set = qxl_enc_mode_set,
870 .commit = qxl_enc_commit, 861 .commit = qxl_enc_commit,
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 01b20e14a247..1603751b1164 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -2623,16 +2623,8 @@ radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)
2623 2623
2624} 2624}
2625 2625
2626static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder,
2627 const struct drm_display_mode *mode,
2628 struct drm_display_mode *adjusted_mode)
2629{
2630 return true;
2631}
2632
2633static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { 2626static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {
2634 .dpms = radeon_atom_ext_dpms, 2627 .dpms = radeon_atom_ext_dpms,
2635 .mode_fixup = radeon_atom_ext_mode_fixup,
2636 .prepare = radeon_atom_ext_prepare, 2628 .prepare = radeon_atom_ext_prepare,
2637 .mode_set = radeon_atom_ext_mode_set, 2629 .mode_set = radeon_atom_ext_mode_set,
2638 .commit = radeon_atom_ext_commit, 2630 .commit = radeon_atom_ext_commit,
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index c4b4f298a283..56482e35d43e 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -551,13 +551,14 @@ static bool radeon_atpx_detect(void)
551void radeon_register_atpx_handler(void) 551void radeon_register_atpx_handler(void)
552{ 552{
553 bool r; 553 bool r;
554 enum vga_switcheroo_handler_flags_t handler_flags = 0;
554 555
555 /* detect if we have any ATPX + 2 VGA in the system */ 556 /* detect if we have any ATPX + 2 VGA in the system */
556 r = radeon_atpx_detect(); 557 r = radeon_atpx_detect();
557 if (!r) 558 if (!r)
558 return; 559 return;
559 560
560 vga_switcheroo_register_handler(&radeon_atpx_handler); 561 vga_switcheroo_register_handler(&radeon_atpx_handler, handler_flags);
561} 562}
562 563
563/** 564/**
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 340f3f549f29..cfcc099c537d 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -34,6 +34,7 @@
34#include "atom.h" 34#include "atom.h"
35 35
36#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37#include <linux/vga_switcheroo.h>
37 38
38static int radeon_dp_handle_hpd(struct drm_connector *connector) 39static int radeon_dp_handle_hpd(struct drm_connector *connector)
39{ 40{
@@ -344,6 +345,11 @@ static void radeon_connector_get_edid(struct drm_connector *connector)
344 else if (radeon_connector->ddc_bus) 345 else if (radeon_connector->ddc_bus)
345 radeon_connector->edid = drm_get_edid(&radeon_connector->base, 346 radeon_connector->edid = drm_get_edid(&radeon_connector->base,
346 &radeon_connector->ddc_bus->adapter); 347 &radeon_connector->ddc_bus->adapter);
348 } else if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC &&
349 connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
350 radeon_connector->ddc_bus) {
351 radeon_connector->edid = drm_get_edid_switcheroo(&radeon_connector->base,
352 &radeon_connector->ddc_bus->adapter);
347 } else if (radeon_connector->ddc_bus) { 353 } else if (radeon_connector->ddc_bus) {
348 radeon_connector->edid = drm_get_edid(&radeon_connector->base, 354 radeon_connector->edid = drm_get_edid(&radeon_connector->base,
349 &radeon_connector->ddc_bus->adapter); 355 &radeon_connector->ddc_bus->adapter);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index e266ffc520d2..cad25557650f 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -34,9 +34,11 @@
34#include "radeon_drv.h" 34#include "radeon_drv.h"
35 35
36#include <drm/drm_pciids.h> 36#include <drm/drm_pciids.h>
37#include <linux/apple-gmux.h>
37#include <linux/console.h> 38#include <linux/console.h>
38#include <linux/module.h> 39#include <linux/module.h>
39#include <linux/pm_runtime.h> 40#include <linux/pm_runtime.h>
41#include <linux/vgaarb.h>
40#include <linux/vga_switcheroo.h> 42#include <linux/vga_switcheroo.h>
41#include <drm/drm_gem.h> 43#include <drm/drm_gem.h>
42 44
@@ -319,6 +321,15 @@ static int radeon_pci_probe(struct pci_dev *pdev,
319{ 321{
320 int ret; 322 int ret;
321 323
324 /*
325 * apple-gmux is needed on dual GPU MacBook Pro
326 * to probe the panel if we're the inactive GPU.
327 */
328 if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) &&
329 apple_gmux_present() && pdev != vga_default_device() &&
330 !vga_switcheroo_handler_flags())
331 return -EPROBE_DEFER;
332
322 /* Get rid of things like offb */ 333 /* Get rid of things like offb */
323 ret = radeon_kick_out_firmware_fb(pdev); 334 ret = radeon_kick_out_firmware_fb(pdev);
324 if (ret) 335 if (ret)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index f8f8f29fb7c3..77662068bc11 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -875,13 +875,6 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
875 clk_disable_unprepare(dsi->pclk); 875 clk_disable_unprepare(dsi->pclk);
876} 876}
877 877
878static bool dw_mipi_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
879 const struct drm_display_mode *mode,
880 struct drm_display_mode *adjusted_mode)
881{
882 return true;
883}
884
885static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder) 878static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
886{ 879{
887 struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder); 880 struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
@@ -931,7 +924,6 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
931 924
932static struct drm_encoder_helper_funcs 925static struct drm_encoder_helper_funcs
933dw_mipi_dsi_encoder_helper_funcs = { 926dw_mipi_dsi_encoder_helper_funcs = {
934 .mode_fixup = dw_mipi_dsi_encoder_mode_fixup,
935 .commit = dw_mipi_dsi_encoder_commit, 927 .commit = dw_mipi_dsi_encoder_commit,
936 .mode_set = dw_mipi_dsi_encoder_mode_set, 928 .mode_set = dw_mipi_dsi_encoder_mode_set,
937 .disable = dw_mipi_dsi_encoder_disable, 929 .disable = dw_mipi_dsi_encoder_disable,
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
index f2afcf5438b8..24a3735b88fd 100644
--- a/drivers/gpu/drm/sti/sti_tvout.c
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -440,13 +440,6 @@ static void sti_tvout_encoder_dpms(struct drm_encoder *encoder, int mode)
440{ 440{
441} 441}
442 442
443static bool sti_tvout_encoder_mode_fixup(struct drm_encoder *encoder,
444 const struct drm_display_mode *mode,
445 struct drm_display_mode *adjusted_mode)
446{
447 return true;
448}
449
450static void sti_tvout_encoder_mode_set(struct drm_encoder *encoder, 443static void sti_tvout_encoder_mode_set(struct drm_encoder *encoder,
451 struct drm_display_mode *mode, 444 struct drm_display_mode *mode,
452 struct drm_display_mode *adjusted_mode) 445 struct drm_display_mode *adjusted_mode)
@@ -486,7 +479,6 @@ static void sti_dvo_encoder_disable(struct drm_encoder *encoder)
486 479
487static const struct drm_encoder_helper_funcs sti_dvo_encoder_helper_funcs = { 480static const struct drm_encoder_helper_funcs sti_dvo_encoder_helper_funcs = {
488 .dpms = sti_tvout_encoder_dpms, 481 .dpms = sti_tvout_encoder_dpms,
489 .mode_fixup = sti_tvout_encoder_mode_fixup,
490 .mode_set = sti_tvout_encoder_mode_set, 482 .mode_set = sti_tvout_encoder_mode_set,
491 .prepare = sti_tvout_encoder_prepare, 483 .prepare = sti_tvout_encoder_prepare,
492 .commit = sti_dvo_encoder_commit, 484 .commit = sti_dvo_encoder_commit,
@@ -540,7 +532,6 @@ static void sti_hda_encoder_disable(struct drm_encoder *encoder)
540 532
541static const struct drm_encoder_helper_funcs sti_hda_encoder_helper_funcs = { 533static const struct drm_encoder_helper_funcs sti_hda_encoder_helper_funcs = {
542 .dpms = sti_tvout_encoder_dpms, 534 .dpms = sti_tvout_encoder_dpms,
543 .mode_fixup = sti_tvout_encoder_mode_fixup,
544 .mode_set = sti_tvout_encoder_mode_set, 535 .mode_set = sti_tvout_encoder_mode_set,
545 .prepare = sti_tvout_encoder_prepare, 536 .prepare = sti_tvout_encoder_prepare,
546 .commit = sti_hda_encoder_commit, 537 .commit = sti_hda_encoder_commit,
@@ -589,7 +580,6 @@ static void sti_hdmi_encoder_disable(struct drm_encoder *encoder)
589 580
590static const struct drm_encoder_helper_funcs sti_hdmi_encoder_helper_funcs = { 581static const struct drm_encoder_helper_funcs sti_hdmi_encoder_helper_funcs = {
591 .dpms = sti_tvout_encoder_dpms, 582 .dpms = sti_tvout_encoder_dpms,
592 .mode_fixup = sti_tvout_encoder_mode_fixup,
593 .mode_set = sti_tvout_encoder_mode_set, 583 .mode_set = sti_tvout_encoder_mode_set,
594 .prepare = sti_tvout_encoder_prepare, 584 .prepare = sti_tvout_encoder_prepare,
595 .commit = sti_hdmi_encoder_commit, 585 .commit = sti_hdmi_encoder_commit,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 4dda6e2f464b..8dcf02a79b23 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -70,14 +70,6 @@ static void panel_encoder_dpms(struct drm_encoder *encoder, int mode)
70 mode == DRM_MODE_DPMS_ON ? 1 : 0); 70 mode == DRM_MODE_DPMS_ON ? 1 : 0);
71} 71}
72 72
73static bool panel_encoder_mode_fixup(struct drm_encoder *encoder,
74 const struct drm_display_mode *mode,
75 struct drm_display_mode *adjusted_mode)
76{
77 /* nothing needed */
78 return true;
79}
80
81static void panel_encoder_prepare(struct drm_encoder *encoder) 73static void panel_encoder_prepare(struct drm_encoder *encoder)
82{ 74{
83 struct panel_encoder *panel_encoder = to_panel_encoder(encoder); 75 struct panel_encoder *panel_encoder = to_panel_encoder(encoder);
@@ -103,7 +95,6 @@ static const struct drm_encoder_funcs panel_encoder_funcs = {
103 95
104static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = { 96static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = {
105 .dpms = panel_encoder_dpms, 97 .dpms = panel_encoder_dpms,
106 .mode_fixup = panel_encoder_mode_fixup,
107 .prepare = panel_encoder_prepare, 98 .prepare = panel_encoder_prepare,
108 .commit = panel_encoder_commit, 99 .commit = panel_encoder_commit,
109 .mode_set = panel_encoder_mode_set, 100 .mode_set = panel_encoder_mode_set,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
index 5052a8af7ecb..1c230172b402 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
@@ -80,14 +80,6 @@ static void tfp410_encoder_dpms(struct drm_encoder *encoder, int mode)
80 tfp410_encoder->dpms = mode; 80 tfp410_encoder->dpms = mode;
81} 81}
82 82
83static bool tfp410_encoder_mode_fixup(struct drm_encoder *encoder,
84 const struct drm_display_mode *mode,
85 struct drm_display_mode *adjusted_mode)
86{
87 /* nothing needed */
88 return true;
89}
90
91static void tfp410_encoder_prepare(struct drm_encoder *encoder) 83static void tfp410_encoder_prepare(struct drm_encoder *encoder)
92{ 84{
93 tfp410_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 85 tfp410_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
@@ -112,7 +104,6 @@ static const struct drm_encoder_funcs tfp410_encoder_funcs = {
112 104
113static const struct drm_encoder_helper_funcs tfp410_encoder_helper_funcs = { 105static const struct drm_encoder_helper_funcs tfp410_encoder_helper_funcs = {
114 .dpms = tfp410_encoder_dpms, 106 .dpms = tfp410_encoder_dpms,
115 .mode_fixup = tfp410_encoder_mode_fixup,
116 .prepare = tfp410_encoder_prepare, 107 .prepare = tfp410_encoder_prepare,
117 .commit = tfp410_encoder_commit, 108 .commit = tfp410_encoder_commit,
118 .mode_set = tfp410_encoder_mode_set, 109 .mode_set = tfp410_encoder_mode_set,
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index d5728ec85254..772ec9e1f590 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -125,17 +125,5 @@ static struct usb_driver udl_driver = {
125 .disconnect = udl_usb_disconnect, 125 .disconnect = udl_usb_disconnect,
126 .id_table = id_table, 126 .id_table = id_table,
127}; 127};
128 128module_usb_driver(udl_driver);
129static int __init udl_init(void)
130{
131 return usb_register(&udl_driver);
132}
133
134static void __exit udl_exit(void)
135{
136 usb_deregister(&udl_driver);
137}
138
139module_init(udl_init);
140module_exit(udl_exit);
141MODULE_LICENSE("GPL"); 129MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/udl/udl_encoder.c b/drivers/gpu/drm/udl/udl_encoder.c
index a181a647fcf9..59a4b34e87ed 100644
--- a/drivers/gpu/drm/udl/udl_encoder.c
+++ b/drivers/gpu/drm/udl/udl_encoder.c
@@ -26,13 +26,6 @@ static void udl_encoder_disable(struct drm_encoder *encoder)
26{ 26{
27} 27}
28 28
29static bool udl_mode_fixup(struct drm_encoder *encoder,
30 const struct drm_display_mode *mode,
31 struct drm_display_mode *adjusted_mode)
32{
33 return true;
34}
35
36static void udl_encoder_prepare(struct drm_encoder *encoder) 29static void udl_encoder_prepare(struct drm_encoder *encoder)
37{ 30{
38} 31}
@@ -54,7 +47,6 @@ udl_encoder_dpms(struct drm_encoder *encoder, int mode)
54 47
55static const struct drm_encoder_helper_funcs udl_helper_funcs = { 48static const struct drm_encoder_helper_funcs udl_helper_funcs = {
56 .dpms = udl_encoder_dpms, 49 .dpms = udl_encoder_dpms,
57 .mode_fixup = udl_mode_fixup,
58 .prepare = udl_encoder_prepare, 50 .prepare = udl_encoder_prepare,
59 .mode_set = udl_encoder_mode_set, 51 .mode_set = udl_encoder_mode_set,
60 .commit = udl_encoder_commit, 52 .commit = udl_encoder_commit,
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 200419d4d43c..c427499133d6 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -409,7 +409,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
409 409
410 if (ufb->obj->base.import_attach) { 410 if (ufb->obj->base.import_attach) {
411 ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf, 411 ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf,
412 0, ufb->obj->base.size,
413 DMA_FROM_DEVICE); 412 DMA_FROM_DEVICE);
414 if (ret) 413 if (ret)
415 goto unlock; 414 goto unlock;
@@ -425,7 +424,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
425 424
426 if (ufb->obj->base.import_attach) { 425 if (ufb->obj->base.import_attach) {
427 dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf, 426 dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
428 0, ufb->obj->base.size,
429 DMA_FROM_DEVICE); 427 DMA_FROM_DEVICE);
430 } 428 }
431 429
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index a165f03eaa79..429aa311685a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -282,13 +282,6 @@ static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = {
282 .atomic_check = virtio_gpu_crtc_atomic_check, 282 .atomic_check = virtio_gpu_crtc_atomic_check,
283}; 283};
284 284
285static bool virtio_gpu_enc_mode_fixup(struct drm_encoder *encoder,
286 const struct drm_display_mode *mode,
287 struct drm_display_mode *adjusted_mode)
288{
289 return true;
290}
291
292static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, 285static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder,
293 struct drm_display_mode *mode, 286 struct drm_display_mode *mode,
294 struct drm_display_mode *adjusted_mode) 287 struct drm_display_mode *adjusted_mode)
@@ -362,7 +355,6 @@ virtio_gpu_best_encoder(struct drm_connector *connector)
362} 355}
363 356
364static const struct drm_encoder_helper_funcs virtio_gpu_enc_helper_funcs = { 357static const struct drm_encoder_helper_funcs virtio_gpu_enc_helper_funcs = {
365 .mode_fixup = virtio_gpu_enc_mode_fixup,
366 .mode_set = virtio_gpu_enc_mode_set, 358 .mode_set = virtio_gpu_enc_mode_set,
367 .enable = virtio_gpu_enc_enable, 359 .enable = virtio_gpu_enc_enable,
368 .disable = virtio_gpu_enc_disable, 360 .disable = virtio_gpu_enc_disable,
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 665ab9fd0e01..cbd7c986d926 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -74,9 +74,17 @@
74 * there can thus be up to three clients: Two vga clients (GPUs) and one audio 74 * there can thus be up to three clients: Two vga clients (GPUs) and one audio
75 * client (on the discrete GPU). The code is mostly prepared to support 75 * client (on the discrete GPU). The code is mostly prepared to support
76 * machines with more than two GPUs should they become available. 76 * machines with more than two GPUs should they become available.
77 *
77 * The GPU to which the outputs are currently switched is called the 78 * The GPU to which the outputs are currently switched is called the
78 * active client in vga_switcheroo parlance. The GPU not in use is the 79 * active client in vga_switcheroo parlance. The GPU not in use is the
79 * inactive client. 80 * inactive client. When the inactive client's DRM driver is loaded,
81 * it will be unable to probe the panel's EDID and hence depends on
82 * VBIOS to provide its display modes. If the VBIOS modes are bogus or
83 * if there is no VBIOS at all (which is common on the MacBook Pro),
84 * a client may alternatively request that the DDC lines are temporarily
85 * switched to it, provided that the handler supports this. Switching
86 * only the DDC lines and not the entire output avoids unnecessary
87 * flickering.
80 */ 88 */
81 89
82/** 90/**
@@ -126,6 +134,10 @@ static DEFINE_MUTEX(vgasr_mutex);
126 * (counting only vga clients, not audio clients) 134 * (counting only vga clients, not audio clients)
127 * @clients: list of registered clients 135 * @clients: list of registered clients
128 * @handler: registered handler 136 * @handler: registered handler
137 * @handler_flags: flags of registered handler
138 * @mux_hw_lock: protects mux state
139 * (in particular while DDC lines are temporarily switched)
140 * @old_ddc_owner: client to which DDC lines will be switched back on unlock
129 * 141 *
130 * vga_switcheroo private data. Currently only one vga_switcheroo instance 142 * vga_switcheroo private data. Currently only one vga_switcheroo instance
131 * per system is supported. 143 * per system is supported.
@@ -142,6 +154,9 @@ struct vgasr_priv {
142 struct list_head clients; 154 struct list_head clients;
143 155
144 const struct vga_switcheroo_handler *handler; 156 const struct vga_switcheroo_handler *handler;
157 enum vga_switcheroo_handler_flags_t handler_flags;
158 struct mutex mux_hw_lock;
159 int old_ddc_owner;
145}; 160};
146 161
147#define ID_BIT_AUDIO 0x100 162#define ID_BIT_AUDIO 0x100
@@ -156,6 +171,7 @@ static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
156/* only one switcheroo per system */ 171/* only one switcheroo per system */
157static struct vgasr_priv vgasr_priv = { 172static struct vgasr_priv vgasr_priv = {
158 .clients = LIST_HEAD_INIT(vgasr_priv.clients), 173 .clients = LIST_HEAD_INIT(vgasr_priv.clients),
174 .mux_hw_lock = __MUTEX_INITIALIZER(vgasr_priv.mux_hw_lock),
159}; 175};
160 176
161static bool vga_switcheroo_ready(void) 177static bool vga_switcheroo_ready(void)
@@ -190,13 +206,15 @@ static void vga_switcheroo_enable(void)
190/** 206/**
191 * vga_switcheroo_register_handler() - register handler 207 * vga_switcheroo_register_handler() - register handler
192 * @handler: handler callbacks 208 * @handler: handler callbacks
209 * @handler_flags: handler flags
193 * 210 *
194 * Register handler. Enable vga_switcheroo if two vga clients have already 211 * Register handler. Enable vga_switcheroo if two vga clients have already
195 * registered. 212 * registered.
196 * 213 *
197 * Return: 0 on success, -EINVAL if a handler was already registered. 214 * Return: 0 on success, -EINVAL if a handler was already registered.
198 */ 215 */
199int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler) 216int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
217 enum vga_switcheroo_handler_flags_t handler_flags)
200{ 218{
201 mutex_lock(&vgasr_mutex); 219 mutex_lock(&vgasr_mutex);
202 if (vgasr_priv.handler) { 220 if (vgasr_priv.handler) {
@@ -205,6 +223,7 @@ int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler
205 } 223 }
206 224
207 vgasr_priv.handler = handler; 225 vgasr_priv.handler = handler;
226 vgasr_priv.handler_flags = handler_flags;
208 if (vga_switcheroo_ready()) { 227 if (vga_switcheroo_ready()) {
209 pr_info("enabled\n"); 228 pr_info("enabled\n");
210 vga_switcheroo_enable(); 229 vga_switcheroo_enable();
@@ -222,16 +241,33 @@ EXPORT_SYMBOL(vga_switcheroo_register_handler);
222void vga_switcheroo_unregister_handler(void) 241void vga_switcheroo_unregister_handler(void)
223{ 242{
224 mutex_lock(&vgasr_mutex); 243 mutex_lock(&vgasr_mutex);
244 mutex_lock(&vgasr_priv.mux_hw_lock);
245 vgasr_priv.handler_flags = 0;
225 vgasr_priv.handler = NULL; 246 vgasr_priv.handler = NULL;
226 if (vgasr_priv.active) { 247 if (vgasr_priv.active) {
227 pr_info("disabled\n"); 248 pr_info("disabled\n");
228 vga_switcheroo_debugfs_fini(&vgasr_priv); 249 vga_switcheroo_debugfs_fini(&vgasr_priv);
229 vgasr_priv.active = false; 250 vgasr_priv.active = false;
230 } 251 }
252 mutex_unlock(&vgasr_priv.mux_hw_lock);
231 mutex_unlock(&vgasr_mutex); 253 mutex_unlock(&vgasr_mutex);
232} 254}
233EXPORT_SYMBOL(vga_switcheroo_unregister_handler); 255EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
234 256
257/**
258 * vga_switcheroo_handler_flags() - obtain handler flags
259 *
260 * Helper for clients to obtain the handler flags bitmask.
261 *
262 * Return: Handler flags. A value of 0 means that no handler is registered
263 * or that the handler has no special capabilities.
264 */
265enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void)
266{
267 return vgasr_priv.handler_flags;
268}
269EXPORT_SYMBOL(vga_switcheroo_handler_flags);
270
235static int register_client(struct pci_dev *pdev, 271static int register_client(struct pci_dev *pdev,
236 const struct vga_switcheroo_client_ops *ops, 272 const struct vga_switcheroo_client_ops *ops,
237 enum vga_switcheroo_client_id id, bool active, 273 enum vga_switcheroo_client_id id, bool active,
@@ -413,6 +449,76 @@ void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
413EXPORT_SYMBOL(vga_switcheroo_client_fb_set); 449EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
414 450
415/** 451/**
452 * vga_switcheroo_lock_ddc() - temporarily switch DDC lines to a given client
453 * @pdev: client pci device
454 *
455 * Temporarily switch DDC lines to the client identified by @pdev
456 * (but leave the outputs otherwise switched to where they are).
457 * This allows the inactive client to probe EDID. The DDC lines must
458 * afterwards be switched back by calling vga_switcheroo_unlock_ddc(),
459 * even if this function returns an error.
460 *
461 * Return: Previous DDC owner on success or a negative int on error.
462 * Specifically, %-ENODEV if no handler has registered or if the handler
463 * does not support switching the DDC lines. Also, a negative value
464 * returned by the handler is propagated back to the caller.
465 * The return value has merely an informational purpose for any caller
466 * which might be interested in it. It is acceptable to ignore the return
467 * value and simply rely on the result of the subsequent EDID probe,
468 * which will be %NULL if DDC switching failed.
469 */
470int vga_switcheroo_lock_ddc(struct pci_dev *pdev)
471{
472 enum vga_switcheroo_client_id id;
473
474 mutex_lock(&vgasr_priv.mux_hw_lock);
475 if (!vgasr_priv.handler || !vgasr_priv.handler->switch_ddc) {
476 vgasr_priv.old_ddc_owner = -ENODEV;
477 return -ENODEV;
478 }
479
480 id = vgasr_priv.handler->get_client_id(pdev);
481 vgasr_priv.old_ddc_owner = vgasr_priv.handler->switch_ddc(id);
482 return vgasr_priv.old_ddc_owner;
483}
484EXPORT_SYMBOL(vga_switcheroo_lock_ddc);
485
486/**
487 * vga_switcheroo_unlock_ddc() - switch DDC lines back to previous owner
488 * @pdev: client pci device
489 *
490 * Switch DDC lines back to the previous owner after calling
491 * vga_switcheroo_lock_ddc(). This must be called even if
492 * vga_switcheroo_lock_ddc() returned an error.
493 *
494 * Return: Previous DDC owner on success (i.e. the client identifier of @pdev)
495 * or a negative int on error.
496 * Specifically, %-ENODEV if no handler has registered or if the handler
497 * does not support switching the DDC lines. Also, a negative value
498 * returned by the handler is propagated back to the caller.
499 * Finally, invoking this function without calling vga_switcheroo_lock_ddc()
500 * first is not allowed and will result in %-EINVAL.
501 */
502int vga_switcheroo_unlock_ddc(struct pci_dev *pdev)
503{
504 enum vga_switcheroo_client_id id;
505 int ret = vgasr_priv.old_ddc_owner;
506
507 if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv.mux_hw_lock)))
508 return -EINVAL;
509
510 if (vgasr_priv.old_ddc_owner >= 0) {
511 id = vgasr_priv.handler->get_client_id(pdev);
512 if (vgasr_priv.old_ddc_owner != id)
513 ret = vgasr_priv.handler->switch_ddc(
514 vgasr_priv.old_ddc_owner);
515 }
516 mutex_unlock(&vgasr_priv.mux_hw_lock);
517 return ret;
518}
519EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
520
521/**
416 * DOC: Manual switching and manual power control 522 * DOC: Manual switching and manual power control
417 * 523 *
418 * In this mode of use, the file /sys/kernel/debug/vgaswitcheroo/switch 524 * In this mode of use, the file /sys/kernel/debug/vgaswitcheroo/switch
@@ -549,7 +655,9 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
549 console_unlock(); 655 console_unlock();
550 } 656 }
551 657
658 mutex_lock(&vgasr_priv.mux_hw_lock);
552 ret = vgasr_priv.handler->switchto(new_client->id); 659 ret = vgasr_priv.handler->switchto(new_client->id);
660 mutex_unlock(&vgasr_priv.mux_hw_lock);
553 if (ret) 661 if (ret)
554 return ret; 662 return ret;
555 663
@@ -664,7 +772,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
664 vgasr_priv.delayed_switch_active = false; 772 vgasr_priv.delayed_switch_active = false;
665 773
666 if (just_mux) { 774 if (just_mux) {
775 mutex_lock(&vgasr_priv.mux_hw_lock);
667 ret = vgasr_priv.handler->switchto(client_id); 776 ret = vgasr_priv.handler->switchto(client_id);
777 mutex_unlock(&vgasr_priv.mux_hw_lock);
668 goto out; 778 goto out;
669 } 779 }
670 780
@@ -876,8 +986,11 @@ static int vga_switcheroo_runtime_suspend(struct device *dev)
876 if (ret) 986 if (ret)
877 return ret; 987 return ret;
878 mutex_lock(&vgasr_mutex); 988 mutex_lock(&vgasr_mutex);
879 if (vgasr_priv.handler->switchto) 989 if (vgasr_priv.handler->switchto) {
990 mutex_lock(&vgasr_priv.mux_hw_lock);
880 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD); 991 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
992 mutex_unlock(&vgasr_priv.mux_hw_lock);
993 }
881 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF); 994 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
882 mutex_unlock(&vgasr_mutex); 995 mutex_unlock(&vgasr_mutex);
883 return 0; 996 return 0;
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index f236250ac106..4034d2d4c507 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -19,6 +19,7 @@
19#include <linux/acpi.h> 19#include <linux/acpi.h>
20#include <linux/pnp.h> 20#include <linux/pnp.h>
21#include <linux/apple_bl.h> 21#include <linux/apple_bl.h>
22#include <linux/apple-gmux.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/pci.h> 25#include <linux/pci.h>
@@ -57,7 +58,9 @@ struct apple_gmux_data {
57 /* switcheroo data */ 58 /* switcheroo data */
58 acpi_handle dhandle; 59 acpi_handle dhandle;
59 int gpe; 60 int gpe;
60 enum vga_switcheroo_client_id resume_client_id; 61 enum vga_switcheroo_client_id switch_state_display;
62 enum vga_switcheroo_client_id switch_state_ddc;
63 enum vga_switcheroo_client_id switch_state_external;
61 enum vga_switcheroo_state power_state; 64 enum vga_switcheroo_state power_state;
62 struct completion powerchange_done; 65 struct completion powerchange_done;
63}; 66};
@@ -368,19 +371,70 @@ static const struct backlight_ops gmux_bl_ops = {
368 * for the selected GPU. 371 * for the selected GPU.
369 */ 372 */
370 373
374static void gmux_read_switch_state(struct apple_gmux_data *gmux_data)
375{
376 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DDC) == 1)
377 gmux_data->switch_state_ddc = VGA_SWITCHEROO_IGD;
378 else
379 gmux_data->switch_state_ddc = VGA_SWITCHEROO_DIS;
380
381 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2)
382 gmux_data->switch_state_display = VGA_SWITCHEROO_IGD;
383 else
384 gmux_data->switch_state_display = VGA_SWITCHEROO_DIS;
385
386 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL) == 2)
387 gmux_data->switch_state_external = VGA_SWITCHEROO_IGD;
388 else
389 gmux_data->switch_state_external = VGA_SWITCHEROO_DIS;
390}
391
392static void gmux_write_switch_state(struct apple_gmux_data *gmux_data)
393{
394 if (gmux_data->switch_state_ddc == VGA_SWITCHEROO_IGD)
395 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 1);
396 else
397 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 2);
398
399 if (gmux_data->switch_state_display == VGA_SWITCHEROO_IGD)
400 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2);
401 else
402 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
403
404 if (gmux_data->switch_state_external == VGA_SWITCHEROO_IGD)
405 gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
406 else
407 gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
408}
409
371static int gmux_switchto(enum vga_switcheroo_client_id id) 410static int gmux_switchto(enum vga_switcheroo_client_id id)
372{ 411{
373 if (id == VGA_SWITCHEROO_IGD) { 412 apple_gmux_data->switch_state_ddc = id;
413 apple_gmux_data->switch_state_display = id;
414 apple_gmux_data->switch_state_external = id;
415
416 gmux_write_switch_state(apple_gmux_data);
417
418 return 0;
419}
420
421static int gmux_switch_ddc(enum vga_switcheroo_client_id id)
422{
423 enum vga_switcheroo_client_id old_ddc_owner =
424 apple_gmux_data->switch_state_ddc;
425
426 if (id == old_ddc_owner)
427 return id;
428
429 pr_debug("Switching DDC from %d to %d\n", old_ddc_owner, id);
430 apple_gmux_data->switch_state_ddc = id;
431
432 if (id == VGA_SWITCHEROO_IGD)
374 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); 433 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
375 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); 434 else
376 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
377 } else {
378 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); 435 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
379 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
380 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
381 }
382 436
383 return 0; 437 return old_ddc_owner;
384} 438}
385 439
386/** 440/**
@@ -440,17 +494,15 @@ static int gmux_get_client_id(struct pci_dev *pdev)
440 return VGA_SWITCHEROO_DIS; 494 return VGA_SWITCHEROO_DIS;
441} 495}
442 496
443static enum vga_switcheroo_client_id 497static const struct vga_switcheroo_handler gmux_handler_indexed = {
444gmux_active_client(struct apple_gmux_data *gmux_data) 498 .switchto = gmux_switchto,
445{ 499 .power_state = gmux_set_power_state,
446 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) 500 .get_client_id = gmux_get_client_id,
447 return VGA_SWITCHEROO_IGD; 501};
448
449 return VGA_SWITCHEROO_DIS;
450}
451 502
452static const struct vga_switcheroo_handler gmux_handler = { 503static const struct vga_switcheroo_handler gmux_handler_classic = {
453 .switchto = gmux_switchto, 504 .switchto = gmux_switchto,
505 .switch_ddc = gmux_switch_ddc,
454 .power_state = gmux_set_power_state, 506 .power_state = gmux_set_power_state,
455 .get_client_id = gmux_get_client_id, 507 .get_client_id = gmux_get_client_id,
456}; 508};
@@ -513,7 +565,6 @@ static int gmux_suspend(struct device *dev)
513 struct pnp_dev *pnp = to_pnp_dev(dev); 565 struct pnp_dev *pnp = to_pnp_dev(dev);
514 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); 566 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
515 567
516 gmux_data->resume_client_id = gmux_active_client(gmux_data);
517 gmux_disable_interrupts(gmux_data); 568 gmux_disable_interrupts(gmux_data);
518 return 0; 569 return 0;
519} 570}
@@ -524,7 +575,7 @@ static int gmux_resume(struct device *dev)
524 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); 575 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
525 576
526 gmux_enable_interrupts(gmux_data); 577 gmux_enable_interrupts(gmux_data);
527 gmux_switchto(gmux_data->resume_client_id); 578 gmux_write_switch_state(gmux_data);
528 if (gmux_data->power_state == VGA_SWITCHEROO_OFF) 579 if (gmux_data->power_state == VGA_SWITCHEROO_OFF)
529 gmux_set_discrete_state(gmux_data, gmux_data->power_state); 580 gmux_set_discrete_state(gmux_data, gmux_data->power_state);
530 return 0; 581 return 0;
@@ -704,9 +755,23 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
704 apple_gmux_data = gmux_data; 755 apple_gmux_data = gmux_data;
705 init_completion(&gmux_data->powerchange_done); 756 init_completion(&gmux_data->powerchange_done);
706 gmux_enable_interrupts(gmux_data); 757 gmux_enable_interrupts(gmux_data);
758 gmux_read_switch_state(gmux_data);
707 759
708 if (vga_switcheroo_register_handler(&gmux_handler)) { 760 /*
709 ret = -ENODEV; 761 * Retina MacBook Pros cannot switch the panel's AUX separately
762 * and need eDP pre-calibration. They are distinguishable from
763 * pre-retinas by having an "indexed" gmux.
764 *
765 * Pre-retina MacBook Pros can switch the panel's DDC separately.
766 */
767 if (gmux_data->indexed)
768 ret = vga_switcheroo_register_handler(&gmux_handler_indexed,
769 VGA_SWITCHEROO_NEEDS_EDP_CONFIG);
770 else
771 ret = vga_switcheroo_register_handler(&gmux_handler_classic,
772 VGA_SWITCHEROO_CAN_SWITCH_DDC);
773 if (ret) {
774 pr_err("Failed to register vga_switcheroo handler\n");
710 goto err_register_handler; 775 goto err_register_handler;
711 } 776 }
712 777
@@ -764,7 +829,7 @@ static void gmux_remove(struct pnp_dev *pnp)
764} 829}
765 830
766static const struct pnp_device_id gmux_device_ids[] = { 831static const struct pnp_device_id gmux_device_ids[] = {
767 {"APP000B", 0}, 832 {GMUX_ACPI_HID, 0},
768 {"", 0} 833 {"", 0}
769}; 834};
770 835
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index e237e9f3312d..0754a37c9674 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1057,8 +1057,7 @@ static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset,
1057{ 1057{
1058} 1058}
1059 1059
1060static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, 1060static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
1061 size_t len,
1062 enum dma_data_direction direction) 1061 enum dma_data_direction direction)
1063{ 1062{
1064 struct ion_buffer *buffer = dmabuf->priv; 1063 struct ion_buffer *buffer = dmabuf->priv;
@@ -1076,8 +1075,7 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start,
1076 return PTR_ERR_OR_ZERO(vaddr); 1075 return PTR_ERR_OR_ZERO(vaddr);
1077} 1076}
1078 1077
1079static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, 1078static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
1080 size_t len,
1081 enum dma_data_direction direction) 1079 enum dma_data_direction direction)
1082{ 1080{
1083 struct ion_buffer *buffer = dmabuf->priv; 1081 struct ion_buffer *buffer = dmabuf->priv;
diff --git a/drivers/staging/android/ion/ion_test.c b/drivers/staging/android/ion/ion_test.c
index b8dcf5a26cc4..da34bc12cd7c 100644
--- a/drivers/staging/android/ion/ion_test.c
+++ b/drivers/staging/android/ion/ion_test.c
@@ -109,7 +109,7 @@ static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr,
109 if (offset > dma_buf->size || size > dma_buf->size - offset) 109 if (offset > dma_buf->size || size > dma_buf->size - offset)
110 return -EINVAL; 110 return -EINVAL;
111 111
112 ret = dma_buf_begin_cpu_access(dma_buf, offset, size, dir); 112 ret = dma_buf_begin_cpu_access(dma_buf, dir);
113 if (ret) 113 if (ret)
114 return ret; 114 return ret;
115 115
@@ -139,7 +139,7 @@ static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr,
139 copy_offset = 0; 139 copy_offset = 0;
140 } 140 }
141err: 141err:
142 dma_buf_end_cpu_access(dma_buf, offset, size, dir); 142 dma_buf_end_cpu_access(dma_buf, dir);
143 return ret; 143 return ret;
144} 144}
145 145
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c65a212db77e..8c7fb3d0f9d0 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -307,6 +307,7 @@ struct drm_plane_helper_funcs;
307 * @connectors_changed: connectors to this crtc have been updated 307 * @connectors_changed: connectors to this crtc have been updated
308 * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes 308 * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
309 * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors 309 * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors
310 * @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders
310 * @last_vblank_count: for helpers and drivers to capture the vblank of the 311 * @last_vblank_count: for helpers and drivers to capture the vblank of the
311 * update to ensure framebuffer cleanup isn't done too early 312 * update to ensure framebuffer cleanup isn't done too early
312 * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings 313 * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
@@ -341,6 +342,7 @@ struct drm_crtc_state {
341 u32 plane_mask; 342 u32 plane_mask;
342 343
343 u32 connector_mask; 344 u32 connector_mask;
345 u32 encoder_mask;
344 346
345 /* last_vblank_count: for vblank waits before cleanup */ 347 /* last_vblank_count: for vblank waits before cleanup */
346 u32 last_vblank_count; 348 u32 last_vblank_count;
@@ -2153,6 +2155,17 @@ struct drm_mode_config {
2153 list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \ 2155 list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \
2154 for_each_if ((plane_mask) & (1 << drm_plane_index(plane))) 2156 for_each_if ((plane_mask) & (1 << drm_plane_index(plane)))
2155 2157
2158/**
2159 * drm_for_each_encoder_mask - iterate over encoders specified by bitmask
2160 * @encoder: the loop cursor
2161 * @dev: the DRM device
2162 * @encoder_mask: bitmask of encoder indices
2163 *
2164 * Iterate over all encoders specified by bitmask.
2165 */
2166#define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \
2167 list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \
2168 for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder)))
2156 2169
2157#define obj_to_crtc(x) container_of(x, struct drm_crtc, base) 2170#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
2158#define obj_to_connector(x) container_of(x, struct drm_connector, base) 2171#define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -2225,6 +2238,7 @@ int drm_encoder_init(struct drm_device *dev,
2225 struct drm_encoder *encoder, 2238 struct drm_encoder *encoder,
2226 const struct drm_encoder_funcs *funcs, 2239 const struct drm_encoder_funcs *funcs,
2227 int encoder_type, const char *name, ...); 2240 int encoder_type, const char *name, ...);
2241extern unsigned int drm_encoder_index(struct drm_encoder *encoder);
2228 2242
2229/** 2243/**
2230 * drm_encoder_crtc_ok - can a given crtc drive a given encoder? 2244 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
@@ -2282,6 +2296,8 @@ extern void drm_property_destroy_user_blobs(struct drm_device *dev,
2282extern bool drm_probe_ddc(struct i2c_adapter *adapter); 2296extern bool drm_probe_ddc(struct i2c_adapter *adapter);
2283extern struct edid *drm_get_edid(struct drm_connector *connector, 2297extern struct edid *drm_get_edid(struct drm_connector *connector,
2284 struct i2c_adapter *adapter); 2298 struct i2c_adapter *adapter);
2299extern struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
2300 struct i2c_adapter *adapter);
2285extern struct edid *drm_edid_duplicate(const struct edid *edid); 2301extern struct edid *drm_edid_duplicate(const struct edid *edid);
2286extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); 2302extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
2287extern void drm_mode_config_init(struct drm_device *dev); 2303extern void drm_mode_config_init(struct drm_device *dev);
@@ -2482,6 +2498,8 @@ extern int drm_format_num_planes(uint32_t format);
2482extern int drm_format_plane_cpp(uint32_t format, int plane); 2498extern int drm_format_plane_cpp(uint32_t format, int plane);
2483extern int drm_format_horz_chroma_subsampling(uint32_t format); 2499extern int drm_format_horz_chroma_subsampling(uint32_t format);
2484extern int drm_format_vert_chroma_subsampling(uint32_t format); 2500extern int drm_format_vert_chroma_subsampling(uint32_t format);
2501extern int drm_format_plane_width(int width, uint32_t format, int plane);
2502extern int drm_format_plane_height(int height, uint32_t format, int plane);
2485extern const char *drm_get_format_name(uint32_t format); 2503extern const char *drm_get_format_name(uint32_t format);
2486extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, 2504extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
2487 unsigned int supported_rotations); 2505 unsigned int supported_rotations);
diff --git a/include/drm/drm_dp_aux_dev.h b/include/drm/drm_dp_aux_dev.h
new file mode 100644
index 000000000000..1b76d990d8ab
--- /dev/null
+++ b/include/drm/drm_dp_aux_dev.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rafael Antognolli <rafael.antognolli@intel.com>
25 *
26 */
27
28#ifndef DRM_DP_AUX_DEV
29#define DRM_DP_AUX_DEV
30
31#include <drm/drm_dp_helper.h>
32
33#ifdef CONFIG_DRM_DP_AUX_CHARDEV
34
35int drm_dp_aux_dev_init(void);
36void drm_dp_aux_dev_exit(void);
37int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
38void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
39
40#else
41
42static inline int drm_dp_aux_dev_init(void)
43{
44 return 0;
45}
46
47static inline void drm_dp_aux_dev_exit(void)
48{
49}
50
51static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
52{
53 return 0;
54}
55
56static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
57{
58}
59
60#endif
61
62#endif
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index d8a40dff0d1d..062723bdcabe 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -219,6 +219,7 @@ struct drm_fb_helper {
219}; 219};
220 220
221#ifdef CONFIG_DRM_FBDEV_EMULATION 221#ifdef CONFIG_DRM_FBDEV_EMULATION
222int drm_fb_helper_modinit(void);
222void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, 223void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
223 const struct drm_fb_helper_funcs *funcs); 224 const struct drm_fb_helper_funcs *funcs);
224int drm_fb_helper_init(struct drm_device *dev, 225int drm_fb_helper_init(struct drm_device *dev,
@@ -283,6 +284,11 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
283int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, 284int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
284 struct drm_connector *connector); 285 struct drm_connector *connector);
285#else 286#else
287static inline int drm_fb_helper_modinit(void)
288{
289 return 0;
290}
291
286static inline void drm_fb_helper_prepare(struct drm_device *dev, 292static inline void drm_fb_helper_prepare(struct drm_device *dev,
287 struct drm_fb_helper *helper, 293 struct drm_fb_helper *helper,
288 const struct drm_fb_helper_funcs *funcs) 294 const struct drm_fb_helper_funcs *funcs)
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index a126a0d7aed4..b61c2d45192e 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -439,7 +439,7 @@ struct drm_encoder_helper_funcs {
439 * can be modified by this callback and does not need to match mode. 439 * can be modified by this callback and does not need to match mode.
440 * 440 *
441 * This function is used by both legacy CRTC helpers and atomic helpers. 441 * This function is used by both legacy CRTC helpers and atomic helpers.
442 * With atomic helpers it is optional. 442 * This hook is optional.
443 * 443 *
444 * NOTE: 444 * NOTE:
445 * 445 *
diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h
new file mode 100644
index 000000000000..b2d32e01dfe4
--- /dev/null
+++ b/include/linux/apple-gmux.h
@@ -0,0 +1,50 @@
1/*
2 * apple-gmux.h - microcontroller built into dual GPU MacBook Pro & Mac Pro
3 * Copyright (C) 2015 Lukas Wunner <lukas@wunner.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License (version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef LINUX_APPLE_GMUX_H
19#define LINUX_APPLE_GMUX_H
20
21#include <linux/acpi.h>
22
23#define GMUX_ACPI_HID "APP000B"
24
25#if IS_ENABLED(CONFIG_APPLE_GMUX)
26
27/**
28 * apple_gmux_present() - detect if gmux is built into the machine
29 *
30 * Drivers may use this to activate quirks specific to dual GPU MacBook Pros
31 * and Mac Pros, e.g. for deferred probing, runtime pm and backlight.
32 *
33 * Return: %true if gmux is present and the kernel was configured
34 * with CONFIG_APPLE_GMUX, %false otherwise.
35 */
36static inline bool apple_gmux_present(void)
37{
38 return acpi_dev_present(GMUX_ACPI_HID);
39}
40
41#else /* !CONFIG_APPLE_GMUX */
42
43static inline bool apple_gmux_present(void)
44{
45 return false;
46}
47
48#endif /* !CONFIG_APPLE_GMUX */
49
50#endif /* LINUX_APPLE_GMUX_H */
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index f98bd7068d55..532108ea0c1c 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -54,7 +54,7 @@ struct dma_buf_attachment;
54 * @release: release this buffer; to be called after the last dma_buf_put. 54 * @release: release this buffer; to be called after the last dma_buf_put.
55 * @begin_cpu_access: [optional] called before cpu access to invalidate cpu 55 * @begin_cpu_access: [optional] called before cpu access to invalidate cpu
56 * caches and allocate backing storage (if not yet done) 56 * caches and allocate backing storage (if not yet done)
57 * respectively pin the objet into memory. 57 * respectively pin the object into memory.
58 * @end_cpu_access: [optional] called after cpu access to flush caches. 58 * @end_cpu_access: [optional] called after cpu access to flush caches.
59 * @kmap_atomic: maps a page from the buffer into kernel address 59 * @kmap_atomic: maps a page from the buffer into kernel address
60 * space, users may not block until the subsequent unmap call. 60 * space, users may not block until the subsequent unmap call.
@@ -93,10 +93,8 @@ struct dma_buf_ops {
93 /* after final dma_buf_put() */ 93 /* after final dma_buf_put() */
94 void (*release)(struct dma_buf *); 94 void (*release)(struct dma_buf *);
95 95
96 int (*begin_cpu_access)(struct dma_buf *, size_t, size_t, 96 int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction);
97 enum dma_data_direction); 97 void (*end_cpu_access)(struct dma_buf *, enum dma_data_direction);
98 void (*end_cpu_access)(struct dma_buf *, size_t, size_t,
99 enum dma_data_direction);
100 void *(*kmap_atomic)(struct dma_buf *, unsigned long); 98 void *(*kmap_atomic)(struct dma_buf *, unsigned long);
101 void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); 99 void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *);
102 void *(*kmap)(struct dma_buf *, unsigned long); 100 void *(*kmap)(struct dma_buf *, unsigned long);
@@ -224,9 +222,9 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
224 enum dma_data_direction); 222 enum dma_data_direction);
225void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, 223void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
226 enum dma_data_direction); 224 enum dma_data_direction);
227int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, 225int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
228 enum dma_data_direction dir); 226 enum dma_data_direction dir);
229void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, 227void dma_buf_end_cpu_access(struct dma_buf *dma_buf,
230 enum dma_data_direction dir); 228 enum dma_data_direction dir);
231void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); 229void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long);
232void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); 230void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *);
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 69e1d4a1f1b3..b39a5f3153bd 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -36,6 +36,26 @@
36struct pci_dev; 36struct pci_dev;
37 37
38/** 38/**
39 * enum vga_switcheroo_handler_flags_t - handler flags bitmask
40 * @VGA_SWITCHEROO_CAN_SWITCH_DDC: whether the handler is able to switch the
41 * DDC lines separately. This signals to clients that they should call
42 * drm_get_edid_switcheroo() to probe the EDID
43 * @VGA_SWITCHEROO_NEEDS_EDP_CONFIG: whether the handler is unable to switch
44 * the AUX channel separately. This signals to clients that the active
45 * GPU needs to train the link and communicate the link parameters to the
46 * inactive GPU (mediated by vga_switcheroo). The inactive GPU may then
47 * skip the AUX handshake and set up its output with these pre-calibrated
48 * values (DisplayPort specification v1.1a, section 2.5.3.3)
49 *
50 * Handler flags bitmask. Used by handlers to declare their capabilities upon
51 * registering with vga_switcheroo.
52 */
53enum vga_switcheroo_handler_flags_t {
54 VGA_SWITCHEROO_CAN_SWITCH_DDC = (1 << 0),
55 VGA_SWITCHEROO_NEEDS_EDP_CONFIG = (1 << 1),
56};
57
58/**
39 * enum vga_switcheroo_state - client power state 59 * enum vga_switcheroo_state - client power state
40 * @VGA_SWITCHEROO_OFF: off 60 * @VGA_SWITCHEROO_OFF: off
41 * @VGA_SWITCHEROO_ON: on 61 * @VGA_SWITCHEROO_ON: on
@@ -82,6 +102,9 @@ enum vga_switcheroo_client_id {
82 * Mandatory. For muxless machines this should be a no-op. Returning 0 102 * Mandatory. For muxless machines this should be a no-op. Returning 0
83 * denotes success, anything else failure (in which case the switch is 103 * denotes success, anything else failure (in which case the switch is
84 * aborted) 104 * aborted)
105 * @switch_ddc: switch DDC lines to given client.
106 * Optional. Should return the previous DDC owner on success or a
107 * negative int on failure
85 * @power_state: cut or reinstate power of given client. 108 * @power_state: cut or reinstate power of given client.
86 * Optional. The return value is ignored 109 * Optional. The return value is ignored
87 * @get_client_id: determine if given pci device is integrated or discrete GPU. 110 * @get_client_id: determine if given pci device is integrated or discrete GPU.
@@ -93,6 +116,7 @@ enum vga_switcheroo_client_id {
93struct vga_switcheroo_handler { 116struct vga_switcheroo_handler {
94 int (*init)(void); 117 int (*init)(void);
95 int (*switchto)(enum vga_switcheroo_client_id id); 118 int (*switchto)(enum vga_switcheroo_client_id id);
119 int (*switch_ddc)(enum vga_switcheroo_client_id id);
96 int (*power_state)(enum vga_switcheroo_client_id id, 120 int (*power_state)(enum vga_switcheroo_client_id id,
97 enum vga_switcheroo_state state); 121 enum vga_switcheroo_state state);
98 enum vga_switcheroo_client_id (*get_client_id)(struct pci_dev *pdev); 122 enum vga_switcheroo_client_id (*get_client_id)(struct pci_dev *pdev);
@@ -132,8 +156,12 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
132void vga_switcheroo_client_fb_set(struct pci_dev *dev, 156void vga_switcheroo_client_fb_set(struct pci_dev *dev,
133 struct fb_info *info); 157 struct fb_info *info);
134 158
135int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler); 159int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
160 enum vga_switcheroo_handler_flags_t handler_flags);
136void vga_switcheroo_unregister_handler(void); 161void vga_switcheroo_unregister_handler(void);
162enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void);
163int vga_switcheroo_lock_ddc(struct pci_dev *pdev);
164int vga_switcheroo_unlock_ddc(struct pci_dev *pdev);
137 165
138int vga_switcheroo_process_delayed_switch(void); 166int vga_switcheroo_process_delayed_switch(void);
139 167
@@ -150,11 +178,15 @@ static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
150static inline int vga_switcheroo_register_client(struct pci_dev *dev, 178static inline int vga_switcheroo_register_client(struct pci_dev *dev,
151 const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; } 179 const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; }
152static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {} 180static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {}
153static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler) { return 0; } 181static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
182 enum vga_switcheroo_handler_flags_t handler_flags) { return 0; }
154static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, 183static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
155 const struct vga_switcheroo_client_ops *ops, 184 const struct vga_switcheroo_client_ops *ops,
156 enum vga_switcheroo_client_id id) { return 0; } 185 enum vga_switcheroo_client_id id) { return 0; }
157static inline void vga_switcheroo_unregister_handler(void) {} 186static inline void vga_switcheroo_unregister_handler(void) {}
187static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void) { return 0; }
188static inline int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { return -ENODEV; }
189static inline int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) { return -ENODEV; }
158static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } 190static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
159static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } 191static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
160 192
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index b4e92eb12044..a0ebfe7c9a28 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -669,6 +669,7 @@ struct drm_set_client_cap {
669 __u64 value; 669 __u64 value;
670}; 670};
671 671
672#define DRM_RDWR O_RDWR
672#define DRM_CLOEXEC O_CLOEXEC 673#define DRM_CLOEXEC O_CLOEXEC
673struct drm_prime_handle { 674struct drm_prime_handle {
674 __u32 handle; 675 __u32 handle;
diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h
new file mode 100644
index 000000000000..fb0dedb7c121
--- /dev/null
+++ b/include/uapi/linux/dma-buf.h
@@ -0,0 +1,40 @@
1/*
2 * Framework for buffer objects that can be shared across devices/subsystems.
3 *
4 * Copyright(C) 2015 Intel Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef _DMA_BUF_UAPI_H_
20#define _DMA_BUF_UAPI_H_
21
22#include <linux/types.h>
23
24/* begin/end dma-buf functions used for userspace mmap. */
25struct dma_buf_sync {
26 __u64 flags;
27};
28
29#define DMA_BUF_SYNC_READ (1 << 0)
30#define DMA_BUF_SYNC_WRITE (2 << 0)
31#define DMA_BUF_SYNC_RW (DMA_BUF_SYNC_READ | DMA_BUF_SYNC_WRITE)
32#define DMA_BUF_SYNC_START (0 << 2)
33#define DMA_BUF_SYNC_END (1 << 2)
34#define DMA_BUF_SYNC_VALID_FLAGS_MASK \
35 (DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END)
36
37#define DMA_BUF_BASE 'b'
38#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
39
40#endif