diff options
author | Tejun Heo <tj@kernel.org> | 2010-07-20 16:09:02 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-07-22 17:18:20 -0400 |
commit | 991ea75cb1df7188d209274b3d51c105b4f18ffe (patch) | |
tree | 3798ac7d956cfdbb9f77497597d3a9c24cc6e6e5 | |
parent | 9b646972467fb5fdc677f9e4251875db20bdbb64 (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.c | 29 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 3 |
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 | } |
809 | EXPORT_SYMBOL(drm_helper_resume_force_mode); | 809 | EXPORT_SYMBOL(drm_helper_resume_force_mode); |
810 | 810 | ||
811 | static struct slow_work_ops output_poll_ops; | ||
812 | |||
813 | #define DRM_OUTPUT_POLL_PERIOD (10*HZ) | 811 | #define DRM_OUTPUT_POLL_PERIOD (10*HZ) |
814 | static void output_poll_execute(struct slow_work *work) | 812 | static 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 | } |
869 | EXPORT_SYMBOL(drm_kms_helper_poll_disable); | 867 | EXPORT_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 | ||
890 | void drm_kms_helper_poll_init(struct drm_device *dev) | 888 | void 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); | |||
901 | void drm_kms_helper_poll_fini(struct drm_device *dev) | 897 | void 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 | } |
906 | EXPORT_SYMBOL(drm_kms_helper_poll_fini); | 901 | EXPORT_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 | } |
916 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); | 911 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); |
917 | |||
918 | static 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 | ||
36 | struct drm_device; | 35 | struct drm_device; |
37 | struct drm_mode_set; | 36 | struct 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; |