aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-07-20 16:09:02 -0400
committerTejun Heo <tj@kernel.org>2010-07-22 17:18:20 -0400
commit991ea75cb1df7188d209274b3d51c105b4f18ffe (patch)
tree3798ac7d956cfdbb9f77497597d3a9c24cc6e6e5
parent9b646972467fb5fdc677f9e4251875db20bdbb64 (diff)
drm: use workqueue instead of slow-work
Workqueue can now handle high concurrency. Convert drm_crtc_helper to use system_nrt_wq instead of slow-work. The conversion is mostly straight forward. One difference is that drm_helper_hpd_irq_event() no longer blocks and can be called from any context. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: David Airlie <airlied@linux.ie> Cc: dri-devel@lists.freedesktop.org
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c29
-rw-r--r--include/drm/drm_crtc.h3
2 files changed, 11 insertions, 21 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9b2a54117c91..7fa33805f392 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -808,13 +808,11 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
808} 808}
809EXPORT_SYMBOL(drm_helper_resume_force_mode); 809EXPORT_SYMBOL(drm_helper_resume_force_mode);
810 810
811static struct slow_work_ops output_poll_ops;
812
813#define DRM_OUTPUT_POLL_PERIOD (10*HZ) 811#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
814static void output_poll_execute(struct slow_work *work) 812static void output_poll_execute(struct work_struct *work)
815{ 813{
816 struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work); 814 struct delayed_work *delayed_work = to_delayed_work(work);
817 struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_slow_work); 815 struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
818 struct drm_connector *connector; 816 struct drm_connector *connector;
819 enum drm_connector_status old_status, status; 817 enum drm_connector_status old_status, status;
820 bool repoll = false, changed = false; 818 bool repoll = false, changed = false;
@@ -854,7 +852,7 @@ static void output_poll_execute(struct slow_work *work)
854 } 852 }
855 853
856 if (repoll) { 854 if (repoll) {
857 ret = delayed_slow_work_enqueue(delayed_work, DRM_OUTPUT_POLL_PERIOD); 855 ret = queue_delayed_work(system_nrt_wq, delayed_work, DRM_OUTPUT_POLL_PERIOD);
858 if (ret) 856 if (ret)
859 DRM_ERROR("delayed enqueue failed %d\n", ret); 857 DRM_ERROR("delayed enqueue failed %d\n", ret);
860 } 858 }
@@ -864,7 +862,7 @@ void drm_kms_helper_poll_disable(struct drm_device *dev)
864{ 862{
865 if (!dev->mode_config.poll_enabled) 863 if (!dev->mode_config.poll_enabled)
866 return; 864 return;
867 delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); 865 cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
868} 866}
869EXPORT_SYMBOL(drm_kms_helper_poll_disable); 867EXPORT_SYMBOL(drm_kms_helper_poll_disable);
870 868
@@ -880,7 +878,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
880 } 878 }
881 879
882 if (poll) { 880 if (poll) {
883 ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD); 881 ret = queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
884 if (ret) 882 if (ret)
885 DRM_ERROR("delayed enqueue failed %d\n", ret); 883 DRM_ERROR("delayed enqueue failed %d\n", ret);
886 } 884 }
@@ -889,9 +887,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_enable);
889 887
890void drm_kms_helper_poll_init(struct drm_device *dev) 888void drm_kms_helper_poll_init(struct drm_device *dev)
891{ 889{
892 slow_work_register_user(THIS_MODULE); 890 INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
893 delayed_slow_work_init(&dev->mode_config.output_poll_slow_work,
894 &output_poll_ops);
895 dev->mode_config.poll_enabled = true; 891 dev->mode_config.poll_enabled = true;
896 892
897 drm_kms_helper_poll_enable(dev); 893 drm_kms_helper_poll_enable(dev);
@@ -901,7 +897,6 @@ EXPORT_SYMBOL(drm_kms_helper_poll_init);
901void drm_kms_helper_poll_fini(struct drm_device *dev) 897void drm_kms_helper_poll_fini(struct drm_device *dev)
902{ 898{
903 drm_kms_helper_poll_disable(dev); 899 drm_kms_helper_poll_disable(dev);
904 slow_work_unregister_user(THIS_MODULE);
905} 900}
906EXPORT_SYMBOL(drm_kms_helper_poll_fini); 901EXPORT_SYMBOL(drm_kms_helper_poll_fini);
907 902
@@ -909,12 +904,8 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
909{ 904{
910 if (!dev->mode_config.poll_enabled) 905 if (!dev->mode_config.poll_enabled)
911 return; 906 return;
912 delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); 907 /* kill timer and schedule immediate execution, this doesn't block */
913 /* schedule a slow work asap */ 908 cancel_delayed_work(&dev->mode_config.output_poll_work);
914 delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0); 909 queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
915} 910}
916EXPORT_SYMBOL(drm_helper_hpd_irq_event); 911EXPORT_SYMBOL(drm_helper_hpd_irq_event);
917
918static struct slow_work_ops output_poll_ops = {
919 .execute = output_poll_execute,
920};
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 93a1a31b9c2d..c707270bff5a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -31,7 +31,6 @@
31#include <linux/idr.h> 31#include <linux/idr.h>
32 32
33#include <linux/fb.h> 33#include <linux/fb.h>
34#include <linux/slow-work.h>
35 34
36struct drm_device; 35struct drm_device;
37struct drm_mode_set; 36struct drm_mode_set;
@@ -595,7 +594,7 @@ struct drm_mode_config {
595 594
596 /* output poll support */ 595 /* output poll support */
597 bool poll_enabled; 596 bool poll_enabled;
598 struct delayed_slow_work output_poll_slow_work; 597 struct delayed_work output_poll_work;
599 598
600 /* pointers to standard properties */ 599 /* pointers to standard properties */
601 struct list_head property_blob_list; 600 struct list_head property_blob_list;