aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-02-21 17:39:26 -0500
committerDave Airlie <airlied@redhat.com>2018-02-21 17:39:26 -0500
commitdfe8db22372873d205c78a9fd5370b1b088a2b87 (patch)
treea2d0d68121caad20e1cd01ca9707c03d92d8adb9
parentccffc9ebfa66e3f2cc5e17b2579202786050b32e (diff)
parent30a3317ddc2427d173d8bcffaa3f41a61eb66560 (diff)
Merge tag 'drm-misc-fixes-2018-02-21' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
Fixes for 4.16. I contains fixes for deadlock on runtime suspend on few drivers, a memory leak on non-blocking commits, a crash on color-eviction. The is also meson and edid fixes, plus a fix for a doc warning. * tag 'drm-misc-fixes-2018-02-21' of git://anongit.freedesktop.org/drm/drm-misc: drm/tve200: fix kernel-doc documentation comment include drm/meson: fix vsync buffer update drm: Handle unexpected holes in color-eviction drm/edid: Add 6 bpc quirk for CPT panel in Asus UX303LA drm/amdgpu: Fix deadlock on runtime suspend drm/radeon: Fix deadlock on runtime suspend drm/nouveau: Fix deadlock on runtime suspend drm: Allow determining if current task is output poll worker workqueue: Allow retrieval of current task's work struct drm/atomic: Fix memleak on ERESTARTSYS during non-blocking commits
-rw-r--r--Documentation/gpu/tve200.rst2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c58
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c15
-rw-r--r--drivers/gpu/drm/drm_edid.c3
-rw-r--r--drivers/gpu/drm/drm_mm.c21
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c20
-rw-r--r--drivers/gpu/drm/meson/meson_crtc.c6
-rw-r--r--drivers/gpu/drm/meson/meson_drv.h3
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c74
-rw-r--r--include/drm/drm_atomic.h9
-rw-r--r--include/drm/drm_crtc_helper.h1
-rw-r--r--include/linux/workqueue.h1
-rw-r--r--kernel/workqueue.c16
15 files changed, 196 insertions, 58 deletions
diff --git a/Documentation/gpu/tve200.rst b/Documentation/gpu/tve200.rst
index 69b17b324e12..152ea9398f7e 100644
--- a/Documentation/gpu/tve200.rst
+++ b/Documentation/gpu/tve200.rst
@@ -3,4 +3,4 @@
3================================== 3==================================
4 4
5.. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c 5.. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c
6 :doc: Faraday TV Encoder 200 6 :doc: Faraday TV Encoder TVE200 DRM Driver
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 8ca3783f2deb..74d2efaec52f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -736,9 +736,11 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
736 enum drm_connector_status ret = connector_status_disconnected; 736 enum drm_connector_status ret = connector_status_disconnected;
737 int r; 737 int r;
738 738
739 r = pm_runtime_get_sync(connector->dev->dev); 739 if (!drm_kms_helper_is_poll_worker()) {
740 if (r < 0) 740 r = pm_runtime_get_sync(connector->dev->dev);
741 return connector_status_disconnected; 741 if (r < 0)
742 return connector_status_disconnected;
743 }
742 744
743 if (encoder) { 745 if (encoder) {
744 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); 746 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
@@ -757,8 +759,12 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
757 /* check acpi lid status ??? */ 759 /* check acpi lid status ??? */
758 760
759 amdgpu_connector_update_scratch_regs(connector, ret); 761 amdgpu_connector_update_scratch_regs(connector, ret);
760 pm_runtime_mark_last_busy(connector->dev->dev); 762
761 pm_runtime_put_autosuspend(connector->dev->dev); 763 if (!drm_kms_helper_is_poll_worker()) {
764 pm_runtime_mark_last_busy(connector->dev->dev);
765 pm_runtime_put_autosuspend(connector->dev->dev);
766 }
767
762 return ret; 768 return ret;
763} 769}
764 770
@@ -868,9 +874,11 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
868 enum drm_connector_status ret = connector_status_disconnected; 874 enum drm_connector_status ret = connector_status_disconnected;
869 int r; 875 int r;
870 876
871 r = pm_runtime_get_sync(connector->dev->dev); 877 if (!drm_kms_helper_is_poll_worker()) {
872 if (r < 0) 878 r = pm_runtime_get_sync(connector->dev->dev);
873 return connector_status_disconnected; 879 if (r < 0)
880 return connector_status_disconnected;
881 }
874 882
875 encoder = amdgpu_connector_best_single_encoder(connector); 883 encoder = amdgpu_connector_best_single_encoder(connector);
876 if (!encoder) 884 if (!encoder)
@@ -924,8 +932,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
924 amdgpu_connector_update_scratch_regs(connector, ret); 932 amdgpu_connector_update_scratch_regs(connector, ret);
925 933
926out: 934out:
927 pm_runtime_mark_last_busy(connector->dev->dev); 935 if (!drm_kms_helper_is_poll_worker()) {
928 pm_runtime_put_autosuspend(connector->dev->dev); 936 pm_runtime_mark_last_busy(connector->dev->dev);
937 pm_runtime_put_autosuspend(connector->dev->dev);
938 }
929 939
930 return ret; 940 return ret;
931} 941}
@@ -988,9 +998,11 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
988 enum drm_connector_status ret = connector_status_disconnected; 998 enum drm_connector_status ret = connector_status_disconnected;
989 bool dret = false, broken_edid = false; 999 bool dret = false, broken_edid = false;
990 1000
991 r = pm_runtime_get_sync(connector->dev->dev); 1001 if (!drm_kms_helper_is_poll_worker()) {
992 if (r < 0) 1002 r = pm_runtime_get_sync(connector->dev->dev);
993 return connector_status_disconnected; 1003 if (r < 0)
1004 return connector_status_disconnected;
1005 }
994 1006
995 if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { 1007 if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
996 ret = connector->status; 1008 ret = connector->status;
@@ -1115,8 +1127,10 @@ out:
1115 amdgpu_connector_update_scratch_regs(connector, ret); 1127 amdgpu_connector_update_scratch_regs(connector, ret);
1116 1128
1117exit: 1129exit:
1118 pm_runtime_mark_last_busy(connector->dev->dev); 1130 if (!drm_kms_helper_is_poll_worker()) {
1119 pm_runtime_put_autosuspend(connector->dev->dev); 1131 pm_runtime_mark_last_busy(connector->dev->dev);
1132 pm_runtime_put_autosuspend(connector->dev->dev);
1133 }
1120 1134
1121 return ret; 1135 return ret;
1122} 1136}
@@ -1359,9 +1373,11 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
1359 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector); 1373 struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
1360 int r; 1374 int r;
1361 1375
1362 r = pm_runtime_get_sync(connector->dev->dev); 1376 if (!drm_kms_helper_is_poll_worker()) {
1363 if (r < 0) 1377 r = pm_runtime_get_sync(connector->dev->dev);
1364 return connector_status_disconnected; 1378 if (r < 0)
1379 return connector_status_disconnected;
1380 }
1365 1381
1366 if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { 1382 if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
1367 ret = connector->status; 1383 ret = connector->status;
@@ -1429,8 +1445,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
1429 1445
1430 amdgpu_connector_update_scratch_regs(connector, ret); 1446 amdgpu_connector_update_scratch_regs(connector, ret);
1431out: 1447out:
1432 pm_runtime_mark_last_busy(connector->dev->dev); 1448 if (!drm_kms_helper_is_poll_worker()) {
1433 pm_runtime_put_autosuspend(connector->dev->dev); 1449 pm_runtime_mark_last_busy(connector->dev->dev);
1450 pm_runtime_put_autosuspend(connector->dev->dev);
1451 }
1434 1452
1435 return ret; 1453 return ret;
1436} 1454}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ab4032167094..ae3cbfe9e01c 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1878,6 +1878,8 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
1878 new_crtc_state->event->base.completion = &commit->flip_done; 1878 new_crtc_state->event->base.completion = &commit->flip_done;
1879 new_crtc_state->event->base.completion_release = release_crtc_commit; 1879 new_crtc_state->event->base.completion_release = release_crtc_commit;
1880 drm_crtc_commit_get(commit); 1880 drm_crtc_commit_get(commit);
1881
1882 commit->abort_completion = true;
1881 } 1883 }
1882 1884
1883 for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) { 1885 for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
@@ -3421,8 +3423,21 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
3421void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) 3423void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
3422{ 3424{
3423 if (state->commit) { 3425 if (state->commit) {
3426 /*
3427 * In the event that a non-blocking commit returns
3428 * -ERESTARTSYS before the commit_tail work is queued, we will
3429 * have an extra reference to the commit object. Release it, if
3430 * the event has not been consumed by the worker.
3431 *
3432 * state->event may be freed, so we can't directly look at
3433 * state->event->base.completion.
3434 */
3435 if (state->event && state->commit->abort_completion)
3436 drm_crtc_commit_put(state->commit);
3437
3424 kfree(state->commit->event); 3438 kfree(state->commit->event);
3425 state->commit->event = NULL; 3439 state->commit->event = NULL;
3440
3426 drm_crtc_commit_put(state->commit); 3441 drm_crtc_commit_put(state->commit);
3427 } 3442 }
3428 3443
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9796c29dc004..4f751a9d71a3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -113,6 +113,9 @@ static const struct edid_quirk {
113 /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ 113 /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
114 { "AEO", 0, EDID_QUIRK_FORCE_6BPC }, 114 { "AEO", 0, EDID_QUIRK_FORCE_6BPC },
115 115
116 /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
117 { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
118
116 /* Belinea 10 15 55 */ 119 /* Belinea 10 15 55 */
117 { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 }, 120 { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
118 { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 }, 121 { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 186c4e90cc1c..89eef1bb4ddc 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -836,9 +836,24 @@ struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan)
836 if (!mm->color_adjust) 836 if (!mm->color_adjust)
837 return NULL; 837 return NULL;
838 838
839 hole = list_first_entry(&mm->hole_stack, typeof(*hole), hole_stack); 839 /*
840 hole_start = __drm_mm_hole_node_start(hole); 840 * The hole found during scanning should ideally be the first element
841 hole_end = hole_start + hole->hole_size; 841 * in the hole_stack list, but due to side-effects in the driver it
842 * may not be.
843 */
844 list_for_each_entry(hole, &mm->hole_stack, hole_stack) {
845 hole_start = __drm_mm_hole_node_start(hole);
846 hole_end = hole_start + hole->hole_size;
847
848 if (hole_start <= scan->hit_start &&
849 hole_end >= scan->hit_end)
850 break;
851 }
852
853 /* We should only be called after we found the hole previously */
854 DRM_MM_BUG_ON(&hole->hole_stack == &mm->hole_stack);
855 if (unlikely(&hole->hole_stack == &mm->hole_stack))
856 return NULL;
842 857
843 DRM_MM_BUG_ON(hole_start > scan->hit_start); 858 DRM_MM_BUG_ON(hole_start > scan->hit_start);
844 DRM_MM_BUG_ON(hole_end < scan->hit_end); 859 DRM_MM_BUG_ON(hole_end < scan->hit_end);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 555fbe54d6e2..00b8445ba819 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -654,6 +654,26 @@ out:
654} 654}
655 655
656/** 656/**
657 * drm_kms_helper_is_poll_worker - is %current task an output poll worker?
658 *
659 * Determine if %current task is an output poll worker. This can be used
660 * to select distinct code paths for output polling versus other contexts.
661 *
662 * One use case is to avoid a deadlock between the output poll worker and
663 * the autosuspend worker wherein the latter waits for polling to finish
664 * upon calling drm_kms_helper_poll_disable(), while the former waits for
665 * runtime suspend to finish upon calling pm_runtime_get_sync() in a
666 * connector ->detect hook.
667 */
668bool drm_kms_helper_is_poll_worker(void)
669{
670 struct work_struct *work = current_work();
671
672 return work && work->func == output_poll_execute;
673}
674EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
675
676/**
657 * drm_kms_helper_poll_disable - disable output polling 677 * drm_kms_helper_poll_disable - disable output polling
658 * @dev: drm_device 678 * @dev: drm_device
659 * 679 *
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index 5155f0179b61..05520202c967 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -36,6 +36,7 @@
36#include "meson_venc.h" 36#include "meson_venc.h"
37#include "meson_vpp.h" 37#include "meson_vpp.h"
38#include "meson_viu.h" 38#include "meson_viu.h"
39#include "meson_canvas.h"
39#include "meson_registers.h" 40#include "meson_registers.h"
40 41
41/* CRTC definition */ 42/* CRTC definition */
@@ -192,6 +193,11 @@ void meson_crtc_irq(struct meson_drm *priv)
192 } else 193 } else
193 meson_vpp_disable_interlace_vscaler_osd1(priv); 194 meson_vpp_disable_interlace_vscaler_osd1(priv);
194 195
196 meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
197 priv->viu.osd1_addr, priv->viu.osd1_stride,
198 priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
199 MESON_CANVAS_BLKMODE_LINEAR);
200
195 /* Enable OSD1 */ 201 /* Enable OSD1 */
196 writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND, 202 writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
197 priv->io_base + _REG(VPP_MISC)); 203 priv->io_base + _REG(VPP_MISC));
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
index 5e8b392b9d1f..8450d6ac8c9b 100644
--- a/drivers/gpu/drm/meson/meson_drv.h
+++ b/drivers/gpu/drm/meson/meson_drv.h
@@ -43,6 +43,9 @@ struct meson_drm {
43 bool osd1_commit; 43 bool osd1_commit;
44 uint32_t osd1_ctrl_stat; 44 uint32_t osd1_ctrl_stat;
45 uint32_t osd1_blk0_cfg[5]; 45 uint32_t osd1_blk0_cfg[5];
46 uint32_t osd1_addr;
47 uint32_t osd1_stride;
48 uint32_t osd1_height;
46 } viu; 49 } viu;
47 50
48 struct { 51 struct {
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index d0a6ac8390f3..27bd3503e1e4 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -164,10 +164,9 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
164 /* Update Canvas with buffer address */ 164 /* Update Canvas with buffer address */
165 gem = drm_fb_cma_get_gem_obj(fb, 0); 165 gem = drm_fb_cma_get_gem_obj(fb, 0);
166 166
167 meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1, 167 priv->viu.osd1_addr = gem->paddr;
168 gem->paddr, fb->pitches[0], 168 priv->viu.osd1_stride = fb->pitches[0];
169 fb->height, MESON_CANVAS_WRAP_NONE, 169 priv->viu.osd1_height = fb->height;
170 MESON_CANVAS_BLKMODE_LINEAR);
171 170
172 spin_unlock_irqrestore(&priv->drm->event_lock, flags); 171 spin_unlock_irqrestore(&priv->drm->event_lock, flags);
173} 172}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 69d6e61a01ec..6ed9cb053dfa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -570,9 +570,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
570 nv_connector->edid = NULL; 570 nv_connector->edid = NULL;
571 } 571 }
572 572
573 ret = pm_runtime_get_sync(connector->dev->dev); 573 /* Outputs are only polled while runtime active, so acquiring a
574 if (ret < 0 && ret != -EACCES) 574 * runtime PM ref here is unnecessary (and would deadlock upon
575 return conn_status; 575 * runtime suspend because it waits for polling to finish).
576 */
577 if (!drm_kms_helper_is_poll_worker()) {
578 ret = pm_runtime_get_sync(connector->dev->dev);
579 if (ret < 0 && ret != -EACCES)
580 return conn_status;
581 }
576 582
577 nv_encoder = nouveau_connector_ddc_detect(connector); 583 nv_encoder = nouveau_connector_ddc_detect(connector);
578 if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { 584 if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
@@ -647,8 +653,10 @@ detect_analog:
647 653
648 out: 654 out:
649 655
650 pm_runtime_mark_last_busy(connector->dev->dev); 656 if (!drm_kms_helper_is_poll_worker()) {
651 pm_runtime_put_autosuspend(connector->dev->dev); 657 pm_runtime_mark_last_busy(connector->dev->dev);
658 pm_runtime_put_autosuspend(connector->dev->dev);
659 }
652 660
653 return conn_status; 661 return conn_status;
654} 662}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 5012f5e47a1e..2e2ca3c6b47d 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -899,9 +899,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
899 enum drm_connector_status ret = connector_status_disconnected; 899 enum drm_connector_status ret = connector_status_disconnected;
900 int r; 900 int r;
901 901
902 r = pm_runtime_get_sync(connector->dev->dev); 902 if (!drm_kms_helper_is_poll_worker()) {
903 if (r < 0) 903 r = pm_runtime_get_sync(connector->dev->dev);
904 return connector_status_disconnected; 904 if (r < 0)
905 return connector_status_disconnected;
906 }
905 907
906 if (encoder) { 908 if (encoder) {
907 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 909 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -924,8 +926,12 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
924 /* check acpi lid status ??? */ 926 /* check acpi lid status ??? */
925 927
926 radeon_connector_update_scratch_regs(connector, ret); 928 radeon_connector_update_scratch_regs(connector, ret);
927 pm_runtime_mark_last_busy(connector->dev->dev); 929
928 pm_runtime_put_autosuspend(connector->dev->dev); 930 if (!drm_kms_helper_is_poll_worker()) {
931 pm_runtime_mark_last_busy(connector->dev->dev);
932 pm_runtime_put_autosuspend(connector->dev->dev);
933 }
934
929 return ret; 935 return ret;
930} 936}
931 937
@@ -1039,9 +1045,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
1039 enum drm_connector_status ret = connector_status_disconnected; 1045 enum drm_connector_status ret = connector_status_disconnected;
1040 int r; 1046 int r;
1041 1047
1042 r = pm_runtime_get_sync(connector->dev->dev); 1048 if (!drm_kms_helper_is_poll_worker()) {
1043 if (r < 0) 1049 r = pm_runtime_get_sync(connector->dev->dev);
1044 return connector_status_disconnected; 1050 if (r < 0)
1051 return connector_status_disconnected;
1052 }
1045 1053
1046 encoder = radeon_best_single_encoder(connector); 1054 encoder = radeon_best_single_encoder(connector);
1047 if (!encoder) 1055 if (!encoder)
@@ -1108,8 +1116,10 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
1108 radeon_connector_update_scratch_regs(connector, ret); 1116 radeon_connector_update_scratch_regs(connector, ret);
1109 1117
1110out: 1118out:
1111 pm_runtime_mark_last_busy(connector->dev->dev); 1119 if (!drm_kms_helper_is_poll_worker()) {
1112 pm_runtime_put_autosuspend(connector->dev->dev); 1120 pm_runtime_mark_last_busy(connector->dev->dev);
1121 pm_runtime_put_autosuspend(connector->dev->dev);
1122 }
1113 1123
1114 return ret; 1124 return ret;
1115} 1125}
@@ -1173,9 +1183,11 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
1173 if (!radeon_connector->dac_load_detect) 1183 if (!radeon_connector->dac_load_detect)
1174 return ret; 1184 return ret;
1175 1185
1176 r = pm_runtime_get_sync(connector->dev->dev); 1186 if (!drm_kms_helper_is_poll_worker()) {
1177 if (r < 0) 1187 r = pm_runtime_get_sync(connector->dev->dev);
1178 return connector_status_disconnected; 1188 if (r < 0)
1189 return connector_status_disconnected;
1190 }
1179 1191
1180 encoder = radeon_best_single_encoder(connector); 1192 encoder = radeon_best_single_encoder(connector);
1181 if (!encoder) 1193 if (!encoder)
@@ -1187,8 +1199,12 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
1187 if (ret == connector_status_connected) 1199 if (ret == connector_status_connected)
1188 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); 1200 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
1189 radeon_connector_update_scratch_regs(connector, ret); 1201 radeon_connector_update_scratch_regs(connector, ret);
1190 pm_runtime_mark_last_busy(connector->dev->dev); 1202
1191 pm_runtime_put_autosuspend(connector->dev->dev); 1203 if (!drm_kms_helper_is_poll_worker()) {
1204 pm_runtime_mark_last_busy(connector->dev->dev);
1205 pm_runtime_put_autosuspend(connector->dev->dev);
1206 }
1207
1192 return ret; 1208 return ret;
1193} 1209}
1194 1210
@@ -1251,9 +1267,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
1251 enum drm_connector_status ret = connector_status_disconnected; 1267 enum drm_connector_status ret = connector_status_disconnected;
1252 bool dret = false, broken_edid = false; 1268 bool dret = false, broken_edid = false;
1253 1269
1254 r = pm_runtime_get_sync(connector->dev->dev); 1270 if (!drm_kms_helper_is_poll_worker()) {
1255 if (r < 0) 1271 r = pm_runtime_get_sync(connector->dev->dev);
1256 return connector_status_disconnected; 1272 if (r < 0)
1273 return connector_status_disconnected;
1274 }
1257 1275
1258 if (radeon_connector->detected_hpd_without_ddc) { 1276 if (radeon_connector->detected_hpd_without_ddc) {
1259 force = true; 1277 force = true;
@@ -1436,8 +1454,10 @@ out:
1436 } 1454 }
1437 1455
1438exit: 1456exit:
1439 pm_runtime_mark_last_busy(connector->dev->dev); 1457 if (!drm_kms_helper_is_poll_worker()) {
1440 pm_runtime_put_autosuspend(connector->dev->dev); 1458 pm_runtime_mark_last_busy(connector->dev->dev);
1459 pm_runtime_put_autosuspend(connector->dev->dev);
1460 }
1441 1461
1442 return ret; 1462 return ret;
1443} 1463}
@@ -1688,9 +1708,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
1688 if (radeon_dig_connector->is_mst) 1708 if (radeon_dig_connector->is_mst)
1689 return connector_status_disconnected; 1709 return connector_status_disconnected;
1690 1710
1691 r = pm_runtime_get_sync(connector->dev->dev); 1711 if (!drm_kms_helper_is_poll_worker()) {
1692 if (r < 0) 1712 r = pm_runtime_get_sync(connector->dev->dev);
1693 return connector_status_disconnected; 1713 if (r < 0)
1714 return connector_status_disconnected;
1715 }
1694 1716
1695 if (!force && radeon_check_hpd_status_unchanged(connector)) { 1717 if (!force && radeon_check_hpd_status_unchanged(connector)) {
1696 ret = connector->status; 1718 ret = connector->status;
@@ -1777,8 +1799,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
1777 } 1799 }
1778 1800
1779out: 1801out:
1780 pm_runtime_mark_last_busy(connector->dev->dev); 1802 if (!drm_kms_helper_is_poll_worker()) {
1781 pm_runtime_put_autosuspend(connector->dev->dev); 1803 pm_runtime_mark_last_busy(connector->dev->dev);
1804 pm_runtime_put_autosuspend(connector->dev->dev);
1805 }
1782 1806
1783 return ret; 1807 return ret;
1784} 1808}
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 1c27526c499e..cf13842a6dbd 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -134,6 +134,15 @@ struct drm_crtc_commit {
134 * &drm_pending_vblank_event pointer to clean up private events. 134 * &drm_pending_vblank_event pointer to clean up private events.
135 */ 135 */
136 struct drm_pending_vblank_event *event; 136 struct drm_pending_vblank_event *event;
137
138 /**
139 * @abort_completion:
140 *
141 * A flag that's set after drm_atomic_helper_setup_commit takes a second
142 * reference for the completion of $drm_crtc_state.event. It's used by
143 * the free code to remove the second reference if commit fails.
144 */
145 bool abort_completion;
137}; 146};
138 147
139struct __drm_planes_state { 148struct __drm_planes_state {
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 76e237bd989b..6914633037a5 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -77,5 +77,6 @@ void drm_kms_helper_hotplug_event(struct drm_device *dev);
77 77
78void drm_kms_helper_poll_disable(struct drm_device *dev); 78void drm_kms_helper_poll_disable(struct drm_device *dev);
79void drm_kms_helper_poll_enable(struct drm_device *dev); 79void drm_kms_helper_poll_enable(struct drm_device *dev);
80bool drm_kms_helper_is_poll_worker(void);
80 81
81#endif 82#endif
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 4a54ef96aff5..bc0cda180c8b 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -465,6 +465,7 @@ extern bool cancel_delayed_work_sync(struct delayed_work *dwork);
465 465
466extern void workqueue_set_max_active(struct workqueue_struct *wq, 466extern void workqueue_set_max_active(struct workqueue_struct *wq,
467 int max_active); 467 int max_active);
468extern struct work_struct *current_work(void);
468extern bool current_is_workqueue_rescuer(void); 469extern bool current_is_workqueue_rescuer(void);
469extern bool workqueue_congested(int cpu, struct workqueue_struct *wq); 470extern bool workqueue_congested(int cpu, struct workqueue_struct *wq);
470extern unsigned int work_busy(struct work_struct *work); 471extern unsigned int work_busy(struct work_struct *work);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 017044c26233..bb9a519cbf50 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4180,6 +4180,22 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
4180EXPORT_SYMBOL_GPL(workqueue_set_max_active); 4180EXPORT_SYMBOL_GPL(workqueue_set_max_active);
4181 4181
4182/** 4182/**
4183 * current_work - retrieve %current task's work struct
4184 *
4185 * Determine if %current task is a workqueue worker and what it's working on.
4186 * Useful to find out the context that the %current task is running in.
4187 *
4188 * Return: work struct if %current task is a workqueue worker, %NULL otherwise.
4189 */
4190struct work_struct *current_work(void)
4191{
4192 struct worker *worker = current_wq_worker();
4193
4194 return worker ? worker->current_work : NULL;
4195}
4196EXPORT_SYMBOL(current_work);
4197
4198/**
4183 * current_is_workqueue_rescuer - is %current workqueue rescuer? 4199 * current_is_workqueue_rescuer - is %current workqueue rescuer?
4184 * 4200 *
4185 * Determine whether %current is a workqueue rescuer. Can be used from 4201 * Determine whether %current is a workqueue rescuer. Can be used from