diff options
author | Rob Clark <robdclark@gmail.com> | 2013-08-07 13:41:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-08-18 20:33:36 -0400 |
commit | a464d618c715b7a850f7459754d9d155f5e60538 (patch) | |
tree | 78edb8216877a677fd51c5d335394cf5fe9c41f1 /drivers/gpu/drm/tilcdc | |
parent | cabaafc78935521c5abc7ec72278dbaa5400c995 (diff) |
drm/tilcdc: use flip-work helper
Signed-off-by: Rob Clark <robdclark@gmail.com>
Tested-by: Darren Etheridge <detheridge@ti.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 6d0524095fe3..fe4726628906 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/kfifo.h> | 18 | #include "drm_flip_work.h" |
19 | 19 | ||
20 | #include "tilcdc_drv.h" | 20 | #include "tilcdc_drv.h" |
21 | #include "tilcdc_regs.h" | 21 | #include "tilcdc_regs.h" |
@@ -35,21 +35,18 @@ struct tilcdc_crtc { | |||
35 | struct drm_framebuffer *scanout[2]; | 35 | struct drm_framebuffer *scanout[2]; |
36 | 36 | ||
37 | /* for deferred fb unref's: */ | 37 | /* for deferred fb unref's: */ |
38 | DECLARE_KFIFO_PTR(unref_fifo, struct drm_framebuffer *); | 38 | struct drm_flip_work unref_work; |
39 | struct work_struct work; | ||
40 | }; | 39 | }; |
41 | #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) | 40 | #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) |
42 | 41 | ||
43 | static void unref_worker(struct work_struct *work) | 42 | static void unref_worker(struct drm_flip_work *work, void *val) |
44 | { | 43 | { |
45 | struct tilcdc_crtc *tilcdc_crtc = | 44 | struct tilcdc_crtc *tilcdc_crtc = |
46 | container_of(work, struct tilcdc_crtc, work); | 45 | container_of(work, struct tilcdc_crtc, unref_work); |
47 | struct drm_device *dev = tilcdc_crtc->base.dev; | 46 | struct drm_device *dev = tilcdc_crtc->base.dev; |
48 | struct drm_framebuffer *fb; | ||
49 | 47 | ||
50 | mutex_lock(&dev->mode_config.mutex); | 48 | mutex_lock(&dev->mode_config.mutex); |
51 | while (kfifo_get(&tilcdc_crtc->unref_fifo, &fb)) | 49 | drm_framebuffer_unreference(val); |
52 | drm_framebuffer_unreference(fb); | ||
53 | mutex_unlock(&dev->mode_config.mutex); | 50 | mutex_unlock(&dev->mode_config.mutex); |
54 | } | 51 | } |
55 | 52 | ||
@@ -68,19 +65,14 @@ static void set_scanout(struct drm_crtc *crtc, int n) | |||
68 | }; | 65 | }; |
69 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); | 66 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); |
70 | struct drm_device *dev = crtc->dev; | 67 | struct drm_device *dev = crtc->dev; |
68 | struct tilcdc_drm_private *priv = dev->dev_private; | ||
71 | 69 | ||
72 | pm_runtime_get_sync(dev->dev); | 70 | pm_runtime_get_sync(dev->dev); |
73 | tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); | 71 | tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); |
74 | tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); | 72 | tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); |
75 | if (tilcdc_crtc->scanout[n]) { | 73 | if (tilcdc_crtc->scanout[n]) { |
76 | if (kfifo_put(&tilcdc_crtc->unref_fifo, | 74 | drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->scanout[n]); |
77 | (const struct drm_framebuffer **)&tilcdc_crtc->scanout[n])) { | 75 | drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); |
78 | struct tilcdc_drm_private *priv = dev->dev_private; | ||
79 | queue_work(priv->wq, &tilcdc_crtc->work); | ||
80 | } else { | ||
81 | dev_err(dev->dev, "unref fifo full!\n"); | ||
82 | drm_framebuffer_unreference(tilcdc_crtc->scanout[n]); | ||
83 | } | ||
84 | } | 76 | } |
85 | tilcdc_crtc->scanout[n] = crtc->fb; | 77 | tilcdc_crtc->scanout[n] = crtc->fb; |
86 | drm_framebuffer_reference(tilcdc_crtc->scanout[n]); | 78 | drm_framebuffer_reference(tilcdc_crtc->scanout[n]); |
@@ -149,8 +141,8 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) | |||
149 | WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON); | 141 | WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON); |
150 | 142 | ||
151 | drm_crtc_cleanup(crtc); | 143 | drm_crtc_cleanup(crtc); |
152 | WARN_ON(!kfifo_is_empty(&tilcdc_crtc->unref_fifo)); | 144 | drm_flip_work_cleanup(&tilcdc_crtc->unref_work); |
153 | kfifo_free(&tilcdc_crtc->unref_fifo); | 145 | |
154 | kfree(tilcdc_crtc); | 146 | kfree(tilcdc_crtc); |
155 | } | 147 | } |
156 | 148 | ||
@@ -671,14 +663,13 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) | |||
671 | tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; | 663 | tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; |
672 | init_waitqueue_head(&tilcdc_crtc->frame_done_wq); | 664 | init_waitqueue_head(&tilcdc_crtc->frame_done_wq); |
673 | 665 | ||
674 | ret = kfifo_alloc(&tilcdc_crtc->unref_fifo, 16, GFP_KERNEL); | 666 | ret = drm_flip_work_init(&tilcdc_crtc->unref_work, 16, |
667 | "unref", unref_worker); | ||
675 | if (ret) { | 668 | if (ret) { |
676 | dev_err(dev->dev, "could not allocate unref FIFO\n"); | 669 | dev_err(dev->dev, "could not allocate unref FIFO\n"); |
677 | goto fail; | 670 | goto fail; |
678 | } | 671 | } |
679 | 672 | ||
680 | INIT_WORK(&tilcdc_crtc->work, unref_worker); | ||
681 | |||
682 | ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); | 673 | ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); |
683 | if (ret < 0) | 674 | if (ret < 0) |
684 | goto fail; | 675 | goto fail; |