--- /dev/null
+From 013ead48a843442e63b9426e3bd5df18ca5d054a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 1 May 2015 12:34:12 +0200
+Subject: drm/radeon: disable semaphores for UVD V1 (v2)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+
+commit 013ead48a843442e63b9426e3bd5df18ca5d054a upstream.
+
+Hardware doesn't seem to work correctly, just block userspace in this case.
+
+v2: add missing defines
+
+Bugs: https://bugs.freedesktop.org/show_bug.cgi?id=85320
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_asic.c | 2 +-
+ drivers/gpu/drm/radeon/radeon_asic.h | 4 ++++
+ drivers/gpu/drm/radeon/rv770d.h | 3 +++
+ drivers/gpu/drm/radeon/uvd_v1_0.c | 14 ++------------
+ drivers/gpu/drm/radeon/uvd_v2_2.c | 29 +++++++++++++++++++++++++++++
+ 5 files changed, 39 insertions(+), 13 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_asic.c
++++ b/drivers/gpu/drm/radeon/radeon_asic.c
+@@ -1180,7 +1180,7 @@ static struct radeon_asic rs780_asic = {
+ static struct radeon_asic_ring rv770_uvd_ring = {
+ .ib_execute = &uvd_v1_0_ib_execute,
+ .emit_fence = &uvd_v2_2_fence_emit,
+- .emit_semaphore = &uvd_v1_0_semaphore_emit,
++ .emit_semaphore = &uvd_v2_2_semaphore_emit,
+ .cs_parse = &radeon_uvd_cs_parse,
+ .ring_test = &uvd_v1_0_ring_test,
+ .ib_test = &uvd_v1_0_ib_test,
+--- a/drivers/gpu/drm/radeon/radeon_asic.h
++++ b/drivers/gpu/drm/radeon/radeon_asic.h
+@@ -919,6 +919,10 @@ void uvd_v1_0_ib_execute(struct radeon_d
+ int uvd_v2_2_resume(struct radeon_device *rdev);
+ void uvd_v2_2_fence_emit(struct radeon_device *rdev,
+ struct radeon_fence *fence);
++bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev,
++ struct radeon_ring *ring,
++ struct radeon_semaphore *semaphore,
++ bool emit_wait);
+
+ /* uvd v3.1 */
+ bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
+--- a/drivers/gpu/drm/radeon/rv770d.h
++++ b/drivers/gpu/drm/radeon/rv770d.h
+@@ -989,6 +989,9 @@
+ ((n) & 0x3FFF) << 16)
+
+ /* UVD */
++#define UVD_SEMA_ADDR_LOW 0xef00
++#define UVD_SEMA_ADDR_HIGH 0xef04
++#define UVD_SEMA_CMD 0xef08
+ #define UVD_GPCOM_VCPU_CMD 0xef0c
+ #define UVD_GPCOM_VCPU_DATA0 0xef10
+ #define UVD_GPCOM_VCPU_DATA1 0xef14
+--- a/drivers/gpu/drm/radeon/uvd_v1_0.c
++++ b/drivers/gpu/drm/radeon/uvd_v1_0.c
+@@ -466,18 +466,8 @@ bool uvd_v1_0_semaphore_emit(struct rade
+ struct radeon_semaphore *semaphore,
+ bool emit_wait)
+ {
+- uint64_t addr = semaphore->gpu_addr;
+-
+- radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
+- radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
+-
+- radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
+- radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
+-
+- radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
+- radeon_ring_write(ring, emit_wait ? 1 : 0);
+-
+- return true;
++ /* disable semaphores for UVD V1 hardware */
++ return false;
+ }
+
+ /**
+--- a/drivers/gpu/drm/radeon/uvd_v2_2.c
++++ b/drivers/gpu/drm/radeon/uvd_v2_2.c
+@@ -60,6 +60,35 @@ void uvd_v2_2_fence_emit(struct radeon_d
+ }
+
+ /**
++ * uvd_v2_2_semaphore_emit - emit semaphore command
++ *
++ * @rdev: radeon_device pointer
++ * @ring: radeon_ring pointer
++ * @semaphore: semaphore to emit commands for
++ * @emit_wait: true if we should emit a wait command
++ *
++ * Emit a semaphore command (either wait or signal) to the UVD ring.
++ */
++bool uvd_v2_2_semaphore_emit(struct radeon_device *rdev,
++ struct radeon_ring *ring,
++ struct radeon_semaphore *semaphore,
++ bool emit_wait)
++{
++ uint64_t addr = semaphore->gpu_addr;
++
++ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
++ radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
++
++ radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
++ radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
++
++ radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
++ radeon_ring_write(ring, emit_wait ? 1 : 0);
++
++ return true;
++}
++
++/**
+ * uvd_v2_2_resume - memory controller programming
+ *
+ * @rdev: radeon_device pointer
--- /dev/null
+From d73a824acc705571c0f47596326d7967fba9a1d9 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 4 May 2015 14:35:01 -0400
+Subject: drm/radeon: don't setup audio on asics that don't support it
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit d73a824acc705571c0f47596326d7967fba9a1d9 upstream.
+
+bug: https://bugzilla.kernel.org/show_bug.cgi?id=97701
+
+Reported-by: Mikael Pettersson <mikpelinux@gmail.com>
+Tested-by: Mikael Pettersson <mikpelinux@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_audio.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_audio.c
++++ b/drivers/gpu/drm/radeon/radeon_audio.c
+@@ -464,6 +464,10 @@ void radeon_audio_detect(struct drm_conn
+ return;
+
+ rdev = connector->encoder->dev->dev_private;
++
++ if (!radeon_audio_chipset_supported(rdev))
++ return;
++
+ radeon_encoder = to_radeon_encoder(connector->encoder);
+ dig = radeon_encoder->enc_priv;
+
--- /dev/null
+From db12973cd581d4e79f4aadd0960948f268d15af7 Mon Sep 17 00:00:00 2001
+From: "monk.liu" <monk.liu@amd.com>
+Date: Tue, 5 May 2015 09:24:17 +0200
+Subject: drm/radeon: fix userptr BO unpin bug v3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: "monk.liu" <monk.liu@amd.com>
+
+commit db12973cd581d4e79f4aadd0960948f268d15af7 upstream.
+
+Fixing a memory leak with userptrs.
+
+v2: clean up the loop, use an iterator instead
+v3: remove unused variable
+
+Signed-off-by: monk.liu <monk.liu@amd.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_ttm.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -591,8 +591,7 @@ static void radeon_ttm_tt_unpin_userptr(
+ {
+ struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
+ struct radeon_ttm_tt *gtt = (void *)ttm;
+- struct scatterlist *sg;
+- int i;
++ struct sg_page_iter sg_iter;
+
+ int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
+ enum dma_data_direction direction = write ?
+@@ -605,9 +604,8 @@ static void radeon_ttm_tt_unpin_userptr(
+ /* free the sg table and pages again */
+ dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+
+- for_each_sg(ttm->sg->sgl, sg, ttm->sg->nents, i) {
+- struct page *page = sg_page(sg);
+-
++ for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
++ struct page *page = sg_page_iter_page(&sg_iter);
+ if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
+ set_page_dirty(page);
+
--- /dev/null
+From a1b403da70e038ca6c6c6fe434d1d873546873a3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 7 May 2015 15:19:23 +0200
+Subject: drm/radeon: make UVD handle checking more strict
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+
+commit a1b403da70e038ca6c6c6fe434d1d873546873a3 upstream.
+
+Invalid messages can crash the hw otherwise.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_uvd.c | 72 +++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 29 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_uvd.c
++++ b/drivers/gpu/drm/radeon/radeon_uvd.c
+@@ -436,50 +436,64 @@ static int radeon_uvd_cs_msg(struct rade
+ return -EINVAL;
+ }
+
+- if (msg_type == 1) {
++ switch (msg_type) {
++ case 0:
++ /* it's a create msg, calc image size (width * height) */
++ img_size = msg[7] * msg[8];
++ radeon_bo_kunmap(bo);
++
++ /* try to alloc a new handle */
++ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
++ if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
++ DRM_ERROR("Handle 0x%x already in use!\n", handle);
++ return -EINVAL;
++ }
++
++ if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
++ p->rdev->uvd.filp[i] = p->filp;
++ p->rdev->uvd.img_size[i] = img_size;
++ return 0;
++ }
++ }
++
++ DRM_ERROR("No more free UVD handles!\n");
++ return -EINVAL;
++
++ case 1:
+ /* it's a decode msg, calc buffer sizes */
+ r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
+- /* calc image size (width * height) */
+- img_size = msg[6] * msg[7];
+ radeon_bo_kunmap(bo);
+ if (r)
+ return r;
+
+- } else if (msg_type == 2) {
++ /* validate the handle */
++ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
++ if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
++ if (p->rdev->uvd.filp[i] != p->filp) {
++ DRM_ERROR("UVD handle collision detected!\n");
++ return -EINVAL;
++ }
++ return 0;
++ }
++ }
++
++ DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
++ return -ENOENT;
++
++ case 2:
+ /* it's a destroy msg, free the handle */
+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
+ atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
+ radeon_bo_kunmap(bo);
+ return 0;
+- } else {
+- /* it's a create msg, calc image size (width * height) */
+- img_size = msg[7] * msg[8];
+- radeon_bo_kunmap(bo);
+-
+- if (msg_type != 0) {
+- DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
+- return -EINVAL;
+- }
+
+- /* it's a create msg, no special handling needed */
+- }
+-
+- /* create or decode, validate the handle */
+- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
+- if (atomic_read(&p->rdev->uvd.handles[i]) == handle)
+- return 0;
+- }
++ default:
+
+- /* handle not found try to alloc a new one */
+- for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
+- if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
+- p->rdev->uvd.filp[i] = p->filp;
+- p->rdev->uvd.img_size[i] = img_size;
+- return 0;
+- }
++ DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
++ return -EINVAL;
+ }
+
+- DRM_ERROR("No more free UVD handles!\n");
++ BUG();
+ return -EINVAL;
+ }
+
--- /dev/null
+From 29c63fe22a17c64e54016040cd882481bd45ee5a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 7 May 2015 15:19:22 +0200
+Subject: drm/radeon: make VCE handle check more strict
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+
+commit 29c63fe22a17c64e54016040cd882481bd45ee5a upstream.
+
+Invalid handles can crash the hw.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_vce.c | 65 ++++++++++++++++++++++++++----------
+ 1 file changed, 48 insertions(+), 17 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_vce.c
++++ b/drivers/gpu/drm/radeon/radeon_vce.c
+@@ -493,18 +493,27 @@ int radeon_vce_cs_reloc(struct radeon_cs
+ *
+ * @p: parser context
+ * @handle: handle to validate
++ * @allocated: allocated a new handle?
+ *
+ * Validates the handle and return the found session index or -EINVAL
+ * we we don't have another free session index.
+ */
+-int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle)
++static int radeon_vce_validate_handle(struct radeon_cs_parser *p,
++ uint32_t handle, bool *allocated)
+ {
+ unsigned i;
+
++ *allocated = false;
++
+ /* validate the handle */
+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
+- if (atomic_read(&p->rdev->vce.handles[i]) == handle)
++ if (atomic_read(&p->rdev->vce.handles[i]) == handle) {
++ if (p->rdev->vce.filp[i] != p->filp) {
++ DRM_ERROR("VCE handle collision detected!\n");
++ return -EINVAL;
++ }
+ return i;
++ }
+ }
+
+ /* handle not found try to alloc a new one */
+@@ -512,6 +521,7 @@ int radeon_vce_validate_handle(struct ra
+ if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
+ p->rdev->vce.filp[i] = p->filp;
+ p->rdev->vce.img_size[i] = 0;
++ *allocated = true;
+ return i;
+ }
+ }
+@@ -529,10 +539,10 @@ int radeon_vce_validate_handle(struct ra
+ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
+ {
+ int session_idx = -1;
+- bool destroyed = false;
++ bool destroyed = false, created = false, allocated = false;
+ uint32_t tmp, handle = 0;
+ uint32_t *size = &tmp;
+- int i, r;
++ int i, r = 0;
+
+ while (p->idx < p->chunk_ib->length_dw) {
+ uint32_t len = radeon_get_ib_value(p, p->idx);
+@@ -540,18 +550,21 @@ int radeon_vce_cs_parse(struct radeon_cs
+
+ if ((len < 8) || (len & 3)) {
+ DRM_ERROR("invalid VCE command length (%d)!\n", len);
+- return -EINVAL;
++ r = -EINVAL;
++ goto out;
+ }
+
+ if (destroyed) {
+ DRM_ERROR("No other command allowed after destroy!\n");
+- return -EINVAL;
++ r = -EINVAL;
++ goto out;
+ }
+
+ switch (cmd) {
+ case 0x00000001: // session
+ handle = radeon_get_ib_value(p, p->idx + 2);
+- session_idx = radeon_vce_validate_handle(p, handle);
++ session_idx = radeon_vce_validate_handle(p, handle,
++ &allocated);
+ if (session_idx < 0)
+ return session_idx;
+ size = &p->rdev->vce.img_size[session_idx];
+@@ -561,6 +574,13 @@ int radeon_vce_cs_parse(struct radeon_cs
+ break;
+
+ case 0x01000001: // create
++ created = true;
++ if (!allocated) {
++ DRM_ERROR("Handle already in use!\n");
++ r = -EINVAL;
++ goto out;
++ }
++
+ *size = radeon_get_ib_value(p, p->idx + 8) *
+ radeon_get_ib_value(p, p->idx + 10) *
+ 8 * 3 / 2;
+@@ -577,12 +597,12 @@ int radeon_vce_cs_parse(struct radeon_cs
+ r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9,
+ *size);
+ if (r)
+- return r;
++ goto out;
+
+ r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11,
+ *size / 3);
+ if (r)
+- return r;
++ goto out;
+ break;
+
+ case 0x02000001: // destroy
+@@ -593,7 +613,7 @@ int radeon_vce_cs_parse(struct radeon_cs
+ r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
+ *size * 2);
+ if (r)
+- return r;
++ goto out;
+ break;
+
+ case 0x05000004: // video bitstream buffer
+@@ -601,36 +621,47 @@ int radeon_vce_cs_parse(struct radeon_cs
+ r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
+ tmp);
+ if (r)
+- return r;
++ goto out;
+ break;
+
+ case 0x05000005: // feedback buffer
+ r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
+ 4096);
+ if (r)
+- return r;
++ goto out;
+ break;
+
+ default:
+ DRM_ERROR("invalid VCE command (0x%x)!\n", cmd);
+- return -EINVAL;
++ r = -EINVAL;
++ goto out;
+ }
+
+ if (session_idx == -1) {
+ DRM_ERROR("no session command at start of IB\n");
+- return -EINVAL;
++ r = -EINVAL;
++ goto out;
+ }
+
+ p->idx += len / 4;
+ }
+
+- if (destroyed) {
+- /* IB contains a destroy msg, free the handle */
++ if (allocated && !created) {
++ DRM_ERROR("New session without create command!\n");
++ r = -ENOENT;
++ }
++
++out:
++ if ((!r && destroyed) || (r && allocated)) {
++ /*
++ * IB contains a destroy msg or we have allocated an
++ * handle and got an error, anyway free the handle
++ */
+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
+ atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0);
+ }
+
+- return 0;
++ return r;
+ }
+
+ /**
--- /dev/null
+From d52cdfa4a0c6406bbfb33206341eaf1fb1555994 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 7 May 2015 15:19:24 +0200
+Subject: drm/radeon: more strictly validate the UVD codec
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+
+commit d52cdfa4a0c6406bbfb33206341eaf1fb1555994 upstream.
+
+MPEG 2/4 are only supported since UVD3.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++++++++--
+ 1 file changed, 31 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_uvd.c
++++ b/drivers/gpu/drm/radeon/radeon_uvd.c
+@@ -396,6 +396,29 @@ static int radeon_uvd_cs_msg_decode(uint
+ return 0;
+ }
+
++static int radeon_uvd_validate_codec(struct radeon_cs_parser *p,
++ unsigned stream_type)
++{
++ switch (stream_type) {
++ case 0: /* H264 */
++ case 1: /* VC1 */
++ /* always supported */
++ return 0;
++
++ case 3: /* MPEG2 */
++ case 4: /* MPEG4 */
++ /* only since UVD 3 */
++ if (p->rdev->family >= CHIP_PALM)
++ return 0;
++
++ /* fall through */
++ default:
++ DRM_ERROR("UVD codec not supported by hardware %d!\n",
++ stream_type);
++ return -EINVAL;
++ }
++}
++
+ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
+ unsigned offset, unsigned buf_sizes[])
+ {
+@@ -440,7 +463,11 @@ static int radeon_uvd_cs_msg(struct rade
+ case 0:
+ /* it's a create msg, calc image size (width * height) */
+ img_size = msg[7] * msg[8];
++
++ r = radeon_uvd_validate_codec(p, msg[4]);
+ radeon_bo_kunmap(bo);
++ if (r)
++ return r;
+
+ /* try to alloc a new handle */
+ for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
+@@ -460,8 +487,10 @@ static int radeon_uvd_cs_msg(struct rade
+ return -EINVAL;
+
+ case 1:
+- /* it's a decode msg, calc buffer sizes */
+- r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
++ /* it's a decode msg, validate codec and calc buffer sizes */
++ r = radeon_uvd_validate_codec(p, msg[4]);
++ if (!r)
++ r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
+ radeon_bo_kunmap(bo);
+ if (r)
+ return r;
--- /dev/null
+From 4e93b9a6abc0d028daf3c8a00cb77b679d8a4df4 Mon Sep 17 00:00:00 2001
+From: Chuanxiao Dong <chuanxiao.dong@intel.com>
+Date: Tue, 12 Aug 2014 12:01:30 +0800
+Subject: mmc: card: Don't access RPMB partitions for normal read/write
+
+From: Chuanxiao Dong <chuanxiao.dong@intel.com>
+
+commit 4e93b9a6abc0d028daf3c8a00cb77b679d8a4df4 upstream.
+
+During kernel boot, it will try to read some logical sectors
+of each block device node for the possible partition table.
+
+But since RPMB partition is special and can not be accessed
+by normal eMMC read / write CMDs, it will cause below error
+messages during kernel boot:
+...
+ mmc0: Got data interrupt 0x00000002 even though no data operation was in progress.
+ mmcblk0rpmb: error -110 transferring data, sector 0, nr 32, cmd response 0x900, card status 0xb00
+ mmcblk0rpmb: retrying using single block read
+ mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
+ mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
+ mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
+ mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
+ mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
+ mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
+ end_request: I/O error, dev mmcblk0rpmb, sector 0
+ Buffer I/O error on device mmcblk0rpmb, logical block 0
+ end_request: I/O error, dev mmcblk0rpmb, sector 8
+ Buffer I/O error on device mmcblk0rpmb, logical block 1
+ end_request: I/O error, dev mmcblk0rpmb, sector 16
+ Buffer I/O error on device mmcblk0rpmb, logical block 2
+ end_request: I/O error, dev mmcblk0rpmb, sector 24
+ Buffer I/O error on device mmcblk0rpmb, logical block 3
+...
+
+This patch will discard the access request in eMMC queue if
+it is RPMB partition access request. By this way, it avoids
+trigger above error messages.
+
+Fixes: 090d25fe224c ("mmc: core: Expose access to RPMB partition")
+Signed-off-by: Yunpeng Gao <yunpeng.gao@intel.com>
+Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.com>
+Tested-by: Michael Shigorin <mike@altlinux.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/card/block.c | 12 ++++++++++++
+ drivers/mmc/card/queue.c | 2 +-
+ drivers/mmc/card/queue.h | 2 ++
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -1029,6 +1029,18 @@ static inline void mmc_blk_reset_success
+ md->reset_done &= ~type;
+ }
+
++int mmc_access_rpmb(struct mmc_queue *mq)
++{
++ struct mmc_blk_data *md = mq->data;
++ /*
++ * If this is a RPMB partition access, return ture
++ */
++ if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB)
++ return true;
++
++ return false;
++}
++
+ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
+ {
+ struct mmc_blk_data *md = mq->data;
+--- a/drivers/mmc/card/queue.c
++++ b/drivers/mmc/card/queue.c
+@@ -38,7 +38,7 @@ static int mmc_prep_request(struct reque
+ return BLKPREP_KILL;
+ }
+
+- if (mq && mmc_card_removed(mq->card))
++ if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq)))
+ return BLKPREP_KILL;
+
+ req->cmd_flags |= REQ_DONTPREP;
+--- a/drivers/mmc/card/queue.h
++++ b/drivers/mmc/card/queue.h
+@@ -73,4 +73,6 @@ extern void mmc_queue_bounce_post(struct
+ extern int mmc_packed_init(struct mmc_queue *, struct mmc_card *);
+ extern void mmc_packed_clean(struct mmc_queue *);
+
++extern int mmc_access_rpmb(struct mmc_queue *);
++
+ #endif
--- /dev/null
+From 184af16b09360d6273fd6160e6ff7f8e2482ef23 Mon Sep 17 00:00:00 2001
+From: Grygorii Strashko <Grygorii.Strashko@linaro.org>
+Date: Thu, 23 Apr 2015 13:43:43 +0300
+Subject: mmc: core: add missing pm event in mmc_pm_notify to fix hib restore
+
+From: Grygorii Strashko <Grygorii.Strashko@linaro.org>
+
+commit 184af16b09360d6273fd6160e6ff7f8e2482ef23 upstream.
+
+The PM_RESTORE_PREPARE is not handled now in mmc_pm_notify(),
+as result mmc_rescan() could be scheduled and executed at
+late hibernation restore stages when MMC device is suspended
+already - which, in turn, will lead to system crash on TI dra7-evm board:
+
+WARNING: CPU: 0 PID: 3188 at drivers/bus/omap_l3_noc.c:148 l3_interrupt_handler+0x258/0x374()
+44000000.ocp:L3 Custom Error: MASTER MPU TARGET L4_PER1_P3 (Idle): Data Access in User mode during Functional access
+
+Hence, add missed PM_RESTORE_PREPARE PM event in mmc_pm_notify().
+
+Fixes: 4c2ef25fe0b8 (mmc: fix all hangs related to mmc/sd card...)
+Signed-off-by: Grygorii Strashko <Grygorii.Strashko@linaro.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -2648,6 +2648,7 @@ int mmc_pm_notify(struct notifier_block
+ switch (mode) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
++ case PM_RESTORE_PREPARE:
+ spin_lock_irqsave(&host->lock, flags);
+ host->rescan_disable = 1;
+ spin_unlock_irqrestore(&host->lock, flags);
--- /dev/null
+From bad4371d87d1d1ed1aecd9c9cc21c41ac3f289c8 Mon Sep 17 00:00:00 2001
+From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
+Date: Thu, 30 Apr 2015 02:03:51 +0900
+Subject: mmc: sh_mmcif: Fix timeout value for command request
+
+From: Takeshi Kihara <takeshi.kihara.df@renesas.com>
+
+commit bad4371d87d1d1ed1aecd9c9cc21c41ac3f289c8 upstream.
+
+f9fd54f22e ("mmc: sh_mmcif: Use msecs_to_jiffies() for host->timeout")
+changed the timeout value from 1000 jiffies to 1s. In the case where
+HZ is 1000 the values are the same. However, for smaller HZ values the
+timeout is now smaller, 1s instead of 10s in the case of HZ=100.
+
+Since the timeout occurs in spite of a normal data transfer a timeout of
+10s seems more appropriate. This restores the previous timeout in the
+case where HZ=100 and results in an increase over the previous timeout
+for larger values of HZ.
+
+Fixes: f9fd54f22e ("mmc: sh_mmcif: Use msecs_to_jiffies() for host->timeout")
+Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
+[horms: rewrote changelog to refer to HZ]
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sh_mmcif.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -1402,7 +1402,7 @@ static int sh_mmcif_probe(struct platfor
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->addr = reg;
+- host->timeout = msecs_to_jiffies(1000);
++ host->timeout = msecs_to_jiffies(10000);
+ host->ccs_enable = !pd || !pd->ccs_unsupported;
+ host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present;
+
--- /dev/null
+From c5272a28566b00cce79127ad382406e0a8650690 Mon Sep 17 00:00:00 2001
+From: Doug Anderson <dianders@chromium.org>
+Date: Fri, 1 May 2015 09:01:27 -0700
+Subject: pinctrl: Don't just pretend to protect pinctrl_maps, do it for real
+
+From: Doug Anderson <dianders@chromium.org>
+
+commit c5272a28566b00cce79127ad382406e0a8650690 upstream.
+
+Way back, when the world was a simpler place and there was no war, no
+evil, and no kernel bugs, there was just a single pinctrl lock. That
+was how the world was when (57291ce pinctrl: core device tree mapping
+table parsing support) was written. In that case, there were
+instances where the pinctrl mutex was already held when
+pinctrl_register_map() was called, hence a "locked" parameter was
+passed to the function to indicate that the mutex was already locked
+(so we shouldn't lock it again).
+
+A few years ago in (42fed7b pinctrl: move subsystem mutex to
+pinctrl_dev struct), we switched to a separate pinctrl_maps_mutex.
+...but (oops) we forgot to re-think about the whole "locked" parameter
+for pinctrl_register_map(). Basically the "locked" parameter appears
+to still refer to whether the bigger pinctrl_dev mutex is locked, but
+we're using it to skip locks of our (now separate) pinctrl_maps_mutex.
+
+That's kind of a bad thing(TM). Probably nobody noticed because most
+of the calls to pinctrl_register_map happen at boot time and we've got
+synchronous device probing. ...and even cases where we're
+asynchronous don't end up actually hitting the race too often. ...but
+after banging my head against the wall for a bug that reproduced 1 out
+of 1000 reboots and lots of looking through kgdb, I finally noticed
+this.
+
+Anyway, we can now safely remove the "locked" parameter and go back to
+a war-free, evil-free, and kernel-bug-free world.
+
+Fixes: 42fed7ba44e4 ("pinctrl: move subsystem mutex to pinctrl_dev struct")
+Signed-off-by: Doug Anderson <dianders@chromium.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/core.c | 10 ++++------
+ drivers/pinctrl/core.h | 2 +-
+ drivers/pinctrl/devicetree.c | 2 +-
+ 3 files changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/pinctrl/core.c
++++ b/drivers/pinctrl/core.c
+@@ -1110,7 +1110,7 @@ void devm_pinctrl_put(struct pinctrl *p)
+ EXPORT_SYMBOL_GPL(devm_pinctrl_put);
+
+ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
+- bool dup, bool locked)
++ bool dup)
+ {
+ int i, ret;
+ struct pinctrl_maps *maps_node;
+@@ -1178,11 +1178,9 @@ int pinctrl_register_map(struct pinctrl_
+ maps_node->maps = maps;
+ }
+
+- if (!locked)
+- mutex_lock(&pinctrl_maps_mutex);
++ mutex_lock(&pinctrl_maps_mutex);
+ list_add_tail(&maps_node->node, &pinctrl_maps);
+- if (!locked)
+- mutex_unlock(&pinctrl_maps_mutex);
++ mutex_unlock(&pinctrl_maps_mutex);
+
+ return 0;
+ }
+@@ -1197,7 +1195,7 @@ int pinctrl_register_map(struct pinctrl_
+ int pinctrl_register_mappings(struct pinctrl_map const *maps,
+ unsigned num_maps)
+ {
+- return pinctrl_register_map(maps, num_maps, true, false);
++ return pinctrl_register_map(maps, num_maps, true);
+ }
+
+ void pinctrl_unregister_map(struct pinctrl_map const *map)
+--- a/drivers/pinctrl/core.h
++++ b/drivers/pinctrl/core.h
+@@ -183,7 +183,7 @@ static inline struct pin_desc *pin_desc_
+ }
+
+ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
+- bool dup, bool locked);
++ bool dup);
+ void pinctrl_unregister_map(struct pinctrl_map const *map);
+
+ extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev);
+--- a/drivers/pinctrl/devicetree.c
++++ b/drivers/pinctrl/devicetree.c
+@@ -92,7 +92,7 @@ static int dt_remember_or_free_map(struc
+ dt_map->num_maps = num_maps;
+ list_add_tail(&dt_map->node, &p->dt_maps);
+
+- return pinctrl_register_map(map, num_maps, false, true);
++ return pinctrl_register_map(map, num_maps, false);
+ }
+
+ struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
drm-i915-dp-there-is-no-audio-on-port-a.patch
drm-amdkfd-allow-unregister-process-with-queues.patch
drm-amdkfd-initialize-sdma-vm-when-creating-sdma-queue.patch
+drm-radeon-disable-semaphores-for-uvd-v1-v2.patch
+drm-radeon-don-t-setup-audio-on-asics-that-don-t-support-it.patch
+drm-radeon-fix-userptr-bo-unpin-bug-v3.patch
+drm-radeon-make-vce-handle-check-more-strict.patch
+drm-radeon-make-uvd-handle-checking-more-strict.patch
+drm-radeon-more-strictly-validate-the-uvd-codec.patch
+pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch
+mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch
+mmc-core-add-missing-pm-event-in-mmc_pm_notify-to-fix-hib-restore.patch
+mmc-sh_mmcif-fix-timeout-value-for-command-request.patch