Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'media/v4.8-7' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

- several fixes for new drivers added for Kernel 4.8 addition (cec
core, pulse8 cec driver and Mediatek vcodec)

- a regression fix for cx23885 and saa7134 drivers

- an important fix for rcar-fcp, making rcar_fcp_enable() return 0 on
success

* tag 'media/v4.8-7' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (25 commits)
[media] cx23885/saa7134: assign q->dev to the PCI device
[media] rcar-fcp: Make sure rcar_fcp_enable() returns 0 on success
[media] cec: fix ioctl return code when not registered
[media] cec: don't Feature Abort broadcast msgs when unregistered
[media] vcodec:mediatek: Refine VP8 encoder driver
[media] vcodec:mediatek: Refine H264 encoder driver
[media] vcodec:mediatek: change H264 profile default to profile high
[media] vcodec:mediatek: Add timestamp and timecode copy for V4L2 Encoder
[media] vcodec:mediatek: Fix visible_height larger than coded_height issue in s_fmt_out
[media] vcodec:mediatek: Fix fops_vcodec_release flow for V4L2 Encoder
[media] vcodec:mediatek:code refine for v4l2 Encoder driver
[media] cec-funcs.h: add missing vendor-specific messages
[media] cec-edid: check for IEEE identifier
[media] pulse8-cec: fix error handling
[media] pulse8-cec: set correct Signal Free Time
[media] mtk-vcodec: add HAS_DMA dependency
[media] cec: ignore messages when log_addr_mask == 0
[media] cec: add item to TODO
[media] cec: set unclaimed addresses to CEC_LOG_ADDR_INVALID
[media] cec: add CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK flag
...

+214 -80
+20 -1
Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst
··· 144 144 145 145 - ``flags`` 146 146 147 - - Flags. No flags are defined yet, so set this to 0. 147 + - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. 148 148 149 149 - .. row 7 150 150 ··· 200 200 this field to all 0, or fill it in according to the CEC 2.0 guidelines to 201 201 give the CEC framework more information about the device type, even 202 202 though the framework won't use it directly in the CEC message. 203 + 204 + .. _cec-log-addrs-flags: 205 + 206 + .. flat-table:: Flags for struct cec_log_addrs 207 + :header-rows: 0 208 + :stub-columns: 0 209 + :widths: 3 1 4 210 + 211 + 212 + - .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: 213 + 214 + - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` 215 + 216 + - 1 217 + 218 + - By default if no logical address of the requested type can be claimed, then 219 + it will go back to the unconfigured state. If this flag is set, then it will 220 + fallback to the Unregistered logical address. Note that if the Unregistered 221 + logical address was explicitly requested, then this flag has no effect. 203 222 204 223 .. _cec-versions: 205 224
+6 -2
Documentation/media/uapi/cec/cec-ioc-dqevent.rst
··· 64 64 65 65 - ``phys_addr`` 66 66 67 - - The current physical address. 67 + - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no 68 + valid physical address is set. 68 69 69 70 - .. row 2 70 71 ··· 73 72 74 73 - ``log_addr_mask`` 75 74 76 - - The current set of claimed logical addresses. 75 + - The current set of claimed logical addresses. This is 0 if no logical 76 + addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. 77 + If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device 78 + has the unregistered logical address. In that case all other bits are 0. 77 79 78 80 79 81
+4 -1
drivers/media/cec-edid.c
··· 70 70 u8 tag = edid[i] >> 5; 71 71 u8 len = edid[i] & 0x1f; 72 72 73 - if (tag == 3 && len >= 5 && i + len <= end) 73 + if (tag == 3 && len >= 5 && i + len <= end && 74 + edid[i + 1] == 0x03 && 75 + edid[i + 2] == 0x0c && 76 + edid[i + 3] == 0x00) 74 77 return i + 4; 75 78 i += len + 1; 76 79 } while (i < end);
+1
drivers/media/pci/cx23885/cx23885-417.c
··· 1552 1552 q->mem_ops = &vb2_dma_sg_memops; 1553 1553 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1554 1554 q->lock = &dev->lock; 1555 + q->dev = &dev->pci->dev; 1555 1556 1556 1557 err = vb2_queue_init(q); 1557 1558 if (err < 0)
+1
drivers/media/pci/saa7134/saa7134-dvb.c
··· 1238 1238 q->buf_struct_size = sizeof(struct saa7134_buf); 1239 1239 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1240 1240 q->lock = &dev->lock; 1241 + q->dev = &dev->pci->dev; 1241 1242 ret = vb2_queue_init(q); 1242 1243 if (ret) { 1243 1244 vb2_dvb_dealloc_frontends(&dev->frontends);
+1
drivers/media/pci/saa7134/saa7134-empress.c
··· 295 295 q->buf_struct_size = sizeof(struct saa7134_buf); 296 296 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 297 297 q->lock = &dev->lock; 298 + q->dev = &dev->pci->dev; 298 299 err = vb2_queue_init(q); 299 300 if (err) 300 301 return err;
+1 -1
drivers/media/platform/Kconfig
··· 169 169 config VIDEO_MEDIATEK_VCODEC 170 170 tristate "Mediatek Video Codec driver" 171 171 depends on MTK_IOMMU || COMPILE_TEST 172 - depends on VIDEO_DEV && VIDEO_V4L2 172 + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA 173 173 depends on ARCH_MEDIATEK || COMPILE_TEST 174 174 select VIDEOBUF2_DMA_CONTIG 175 175 select V4L2_MEM2MEM_DEV
-1
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
··· 23 23 #include <media/v4l2-ioctl.h> 24 24 #include <media/videobuf2-core.h> 25 25 26 - #include "mtk_vcodec_util.h" 27 26 28 27 #define MTK_VCODEC_DRV_NAME "mtk_vcodec_drv" 29 28 #define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc"
+26 -16
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
··· 487 487 struct mtk_q_data *q_data; 488 488 int ret, i; 489 489 struct mtk_video_fmt *fmt; 490 - unsigned int pitch_w_div16; 491 490 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; 492 491 493 492 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); ··· 528 529 529 530 q_data->coded_width = f->fmt.pix_mp.width; 530 531 q_data->coded_height = f->fmt.pix_mp.height; 531 - 532 - pitch_w_div16 = DIV_ROUND_UP(q_data->visible_width, 16); 533 - if (pitch_w_div16 % 8 != 0) { 534 - /* Adjust returned width/height, so application could correctly 535 - * allocate hw required memory 536 - */ 537 - q_data->visible_height += 32; 538 - vidioc_try_fmt(f, q_data->fmt); 539 - } 540 532 541 533 q_data->field = f->fmt.pix_mp.field; 542 534 ctx->colorspace = f->fmt.pix_mp.colorspace; ··· 868 878 { 869 879 struct mtk_vcodec_ctx *ctx = priv; 870 880 int ret; 871 - struct vb2_buffer *dst_buf; 881 + struct vb2_buffer *src_buf, *dst_buf; 882 + struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; 872 883 struct mtk_vcodec_mem bs_buf; 873 884 struct venc_done_result enc_result; 874 885 ··· 901 910 VB2_BUF_STATE_ERROR); 902 911 mtk_v4l2_err("venc_if_encode failed=%d", ret); 903 912 return -EINVAL; 913 + } 914 + src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 915 + if (src_buf) { 916 + src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); 917 + dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); 918 + dst_buf->timestamp = src_buf->timestamp; 919 + dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; 920 + } else { 921 + mtk_v4l2_err("No timestamp for the header buffer."); 904 922 } 905 923 906 924 ctx->state = MTK_STATE_HEADER; ··· 1003 1003 struct mtk_vcodec_mem bs_buf; 1004 1004 struct venc_done_result enc_result; 1005 1005 int ret, i; 1006 - struct vb2_v4l2_buffer *vb2_v4l2; 1006 + struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; 1007 1007 1008 1008 /* check dst_buf, dst_buf may be removed in device_run 1009 1009 * to stored encdoe header so we need check dst_buf and ··· 1043 1043 ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, 1044 1044 &frm_buf, &bs_buf, &enc_result); 1045 1045 1046 - vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); 1046 + src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); 1047 + dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); 1048 + 1049 + dst_buf->timestamp = src_buf->timestamp; 1050 + dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; 1051 + 1047 1052 if (enc_result.is_key_frm) 1048 - vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; 1053 + dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; 1049 1054 1050 1055 if (ret) { 1051 1056 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), ··· 1222 1217 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); 1223 1218 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, 1224 1219 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1225 - 0, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN); 1220 + 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); 1226 1221 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, 1227 1222 V4L2_MPEG_VIDEO_H264_LEVEL_4_2, 1228 1223 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); ··· 1293 1288 1294 1289 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx) 1295 1290 { 1296 - venc_if_deinit(ctx); 1291 + int ret = venc_if_deinit(ctx); 1292 + 1293 + if (ret) 1294 + mtk_v4l2_err("venc_if_deinit failed=%d", ret); 1295 + 1296 + ctx->state = MTK_STATE_FREE; 1297 1297 }
+5 -1
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
··· 218 218 mtk_v4l2_debug(1, "[%d] encoder", ctx->id); 219 219 mutex_lock(&dev->dev_mutex); 220 220 221 + /* 222 + * Call v4l2_m2m_ctx_release to make sure the worker thread is not 223 + * running after venc_if_deinit. 224 + */ 225 + v4l2_m2m_ctx_release(ctx->m2m_ctx); 221 226 mtk_vcodec_enc_release(ctx); 222 227 v4l2_fh_del(&ctx->fh); 223 228 v4l2_fh_exit(&ctx->fh); 224 229 v4l2_ctrl_handler_free(&ctx->ctrl_hdl); 225 - v4l2_m2m_ctx_release(ctx->m2m_ctx); 226 230 227 231 list_del_init(&ctx->list); 228 232 dev->num_instances--;
-1
drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
··· 16 16 #define _MTK_VCODEC_INTR_H_ 17 17 18 18 #define MTK_INST_IRQ_RECEIVED 0x1 19 - #define MTK_INST_WORK_THREAD_ABORT_DONE 0x2 20 19 21 20 struct mtk_vcodec_ctx; 22 21
+8 -8
drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
··· 61 61 62 62 /* 63 63 * struct venc_h264_vpu_config - Structure for h264 encoder configuration 64 + * AP-W/R : AP is writer/reader on this item 65 + * VPU-W/R: VPU is write/reader on this item 64 66 * @input_fourcc: input fourcc 65 67 * @bitrate: target bitrate (in bps) 66 68 * @pic_w: picture width. Picture size is visible stream resolution, in pixels, ··· 96 94 97 95 /* 98 96 * struct venc_h264_vpu_buf - Structure for buffer information 99 - * @align: buffer alignment (in bytes) 97 + * AP-W/R : AP is writer/reader on this item 98 + * VPU-W/R: VPU is write/reader on this item 100 99 * @iova: IO virtual address 101 100 * @vpua: VPU side memory addr which is used by RC_CODE 102 101 * @size: buffer size (in bytes) 103 102 */ 104 103 struct venc_h264_vpu_buf { 105 - u32 align; 106 104 u32 iova; 107 105 u32 vpua; 108 106 u32 size; ··· 110 108 111 109 /* 112 110 * struct venc_h264_vsi - Structure for VPU driver control and info share 111 + * AP-W/R : AP is writer/reader on this item 112 + * VPU-W/R: VPU is write/reader on this item 113 113 * This structure is allocated in VPU side and shared to AP side. 114 114 * @config: h264 encoder configuration 115 115 * @work_bufs: working buffer information in VPU side ··· 153 149 struct venc_h264_vsi *vsi; 154 150 struct mtk_vcodec_ctx *ctx; 155 151 }; 156 - 157 - static inline void h264_write_reg(struct venc_h264_inst *inst, u32 addr, 158 - u32 val) 159 - { 160 - writel(val, inst->hw_base + addr); 161 - } 162 152 163 153 static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) 164 154 { ··· 212 214 return 40; 213 215 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 214 216 return 41; 217 + case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 218 + return 42; 215 219 default: 216 220 mtk_vcodec_debug(inst, "unsupported level %d", level); 217 221 return 31;
+7 -9
drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
··· 56 56 57 57 /* 58 58 * struct venc_vp8_vpu_config - Structure for vp8 encoder configuration 59 + * AP-W/R : AP is writer/reader on this item 60 + * VPU-W/R: VPU is write/reader on this item 59 61 * @input_fourcc: input fourcc 60 62 * @bitrate: target bitrate (in bps) 61 63 * @pic_w: picture width. Picture size is visible stream resolution, in pixels, ··· 85 83 }; 86 84 87 85 /* 88 - * struct venc_vp8_vpu_buf -Structure for buffer information 89 - * @align: buffer alignment (in bytes) 86 + * struct venc_vp8_vpu_buf - Structure for buffer information 87 + * AP-W/R : AP is writer/reader on this item 88 + * VPU-W/R: VPU is write/reader on this item 90 89 * @iova: IO virtual address 91 90 * @vpua: VPU side memory addr which is used by RC_CODE 92 91 * @size: buffer size (in bytes) 93 92 */ 94 93 struct venc_vp8_vpu_buf { 95 - u32 align; 96 94 u32 iova; 97 95 u32 vpua; 98 96 u32 size; ··· 100 98 101 99 /* 102 100 * struct venc_vp8_vsi - Structure for VPU driver control and info share 101 + * AP-W/R : AP is writer/reader on this item 102 + * VPU-W/R: VPU is write/reader on this item 103 103 * This structure is allocated in VPU side and shared to AP side. 104 104 * @config: vp8 encoder configuration 105 105 * @work_bufs: working buffer information in VPU side ··· 141 137 struct venc_vp8_vsi *vsi; 142 138 struct mtk_vcodec_ctx *ctx; 143 139 }; 144 - 145 - static inline void vp8_enc_write_reg(struct venc_vp8_inst *inst, u32 addr, 146 - u32 val) 147 - { 148 - writel(val, inst->hw_base + addr); 149 - } 150 140 151 141 static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr) 152 142 {
+7 -1
drivers/media/platform/rcar-fcp.c
··· 99 99 */ 100 100 int rcar_fcp_enable(struct rcar_fcp_device *fcp) 101 101 { 102 + int error; 103 + 102 104 if (!fcp) 103 105 return 0; 104 106 105 - return pm_runtime_get_sync(fcp->dev); 107 + error = pm_runtime_get_sync(fcp->dev); 108 + if (error < 0) 109 + return error; 110 + 111 + return 0; 106 112 } 107 113 EXPORT_SYMBOL_GPL(rcar_fcp_enable); 108 114
+1
drivers/staging/media/cec/TODO
··· 12 12 13 13 Other TODOs: 14 14 15 + - There are two possible replies to CEC_MSG_INITIATE_ARC. How to handle that? 15 16 - Add a flag to inhibit passing CEC RC messages to the rc subsystem. 16 17 Applications should be able to choose this when calling S_LOG_ADDRS. 17 18 - If the reply field of cec_msg is set then when the reply arrives it
+18 -8
drivers/staging/media/cec/cec-adap.c
··· 124 124 u64 ts = ktime_get_ns(); 125 125 struct cec_fh *fh; 126 126 127 - mutex_lock(&adap->devnode.fhs_lock); 127 + mutex_lock(&adap->devnode.lock); 128 128 list_for_each_entry(fh, &adap->devnode.fhs, list) 129 129 cec_queue_event_fh(fh, ev, ts); 130 - mutex_unlock(&adap->devnode.fhs_lock); 130 + mutex_unlock(&adap->devnode.lock); 131 131 } 132 132 133 133 /* ··· 191 191 u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : 192 192 CEC_MODE_MONITOR_ALL; 193 193 194 - mutex_lock(&adap->devnode.fhs_lock); 194 + mutex_lock(&adap->devnode.lock); 195 195 list_for_each_entry(fh, &adap->devnode.fhs, list) { 196 196 if (fh->mode_follower >= monitor_mode) 197 197 cec_queue_msg_fh(fh, msg); 198 198 } 199 - mutex_unlock(&adap->devnode.fhs_lock); 199 + mutex_unlock(&adap->devnode.lock); 200 200 } 201 201 202 202 /* ··· 207 207 { 208 208 struct cec_fh *fh; 209 209 210 - mutex_lock(&adap->devnode.fhs_lock); 210 + mutex_lock(&adap->devnode.lock); 211 211 list_for_each_entry(fh, &adap->devnode.fhs, list) { 212 212 if (fh->mode_follower == CEC_MODE_FOLLOWER) 213 213 cec_queue_msg_fh(fh, msg); 214 214 } 215 - mutex_unlock(&adap->devnode.fhs_lock); 215 + mutex_unlock(&adap->devnode.lock); 216 216 } 217 217 218 218 /* Notify userspace of an adapter state change. */ ··· 851 851 if (!valid_la || msg->len <= 1) 852 852 return; 853 853 854 + if (adap->log_addrs.log_addr_mask == 0) 855 + return; 856 + 854 857 /* 855 858 * Process the message on the protocol level. If is_reply is true, 856 859 * then cec_receive_notify() won't pass on the reply to the listener(s) ··· 1050 1047 dprintk(1, "could not claim LA %d\n", i); 1051 1048 } 1052 1049 1050 + if (adap->log_addrs.log_addr_mask == 0 && 1051 + !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK)) 1052 + goto unconfigure; 1053 + 1053 1054 configured: 1054 1055 if (adap->log_addrs.log_addr_mask == 0) { 1055 1056 /* Fall back to unregistered */ 1056 1057 las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; 1057 1058 las->log_addr_mask = 1 << las->log_addr[0]; 1059 + for (i = 1; i < las->num_log_addrs; i++) 1060 + las->log_addr[i] = CEC_LOG_ADDR_INVALID; 1058 1061 } 1059 1062 adap->is_configured = true; 1060 1063 adap->is_configuring = false; ··· 1079 1070 cec_report_features(adap, i); 1080 1071 cec_report_phys_addr(adap, i); 1081 1072 } 1073 + for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) 1074 + las->log_addr[i] = CEC_LOG_ADDR_INVALID; 1082 1075 mutex_lock(&adap->lock); 1083 1076 adap->kthread_config = NULL; 1084 1077 mutex_unlock(&adap->lock); ··· 1409 1398 u8 init_laddr = cec_msg_initiator(msg); 1410 1399 u8 devtype = cec_log_addr2dev(adap, dest_laddr); 1411 1400 int la_idx = cec_log_addr2idx(adap, dest_laddr); 1412 - bool is_directed = la_idx >= 0; 1413 1401 bool from_unregistered = init_laddr == 0xf; 1414 1402 struct cec_msg tx_cec_msg = { }; 1415 1403 ··· 1570 1560 * Unprocessed messages are aborted if userspace isn't doing 1571 1561 * any processing either. 1572 1562 */ 1573 - if (is_directed && !is_reply && !adap->follower_cnt && 1563 + if (!is_broadcast && !is_reply && !adap->follower_cnt && 1574 1564 !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) 1575 1565 return cec_feature_abort(adap, msg); 1576 1566 break;
+6 -6
drivers/staging/media/cec/cec-api.c
··· 162 162 return -ENOTTY; 163 163 if (copy_from_user(&log_addrs, parg, sizeof(log_addrs))) 164 164 return -EFAULT; 165 - log_addrs.flags = 0; 165 + log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK; 166 166 mutex_lock(&adap->lock); 167 167 if (!adap->is_configuring && 168 168 (!log_addrs.num_log_addrs || !adap->is_configured) && ··· 435 435 void __user *parg = (void __user *)arg; 436 436 437 437 if (!devnode->registered) 438 - return -EIO; 438 + return -ENODEV; 439 439 440 440 switch (cmd) { 441 441 case CEC_ADAP_G_CAPS: ··· 508 508 509 509 filp->private_data = fh; 510 510 511 - mutex_lock(&devnode->fhs_lock); 511 + mutex_lock(&devnode->lock); 512 512 /* Queue up initial state events */ 513 513 ev_state.state_change.phys_addr = adap->phys_addr; 514 514 ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; 515 515 cec_queue_event_fh(fh, &ev_state, 0); 516 516 517 517 list_add(&fh->list, &devnode->fhs); 518 - mutex_unlock(&devnode->fhs_lock); 518 + mutex_unlock(&devnode->lock); 519 519 520 520 return 0; 521 521 } ··· 540 540 cec_monitor_all_cnt_dec(adap); 541 541 mutex_unlock(&adap->lock); 542 542 543 - mutex_lock(&devnode->fhs_lock); 543 + mutex_lock(&devnode->lock); 544 544 list_del(&fh->list); 545 - mutex_unlock(&devnode->fhs_lock); 545 + mutex_unlock(&devnode->lock); 546 546 547 547 /* Unhook pending transmits from this filehandle. */ 548 548 mutex_lock(&adap->lock);
+17 -14
drivers/staging/media/cec/cec-core.c
··· 51 51 { 52 52 /* 53 53 * Check if the cec device is available. This needs to be done with 54 - * the cec_devnode_lock held to prevent an open/unregister race: 54 + * the devnode->lock held to prevent an open/unregister race: 55 55 * without the lock, the device could be unregistered and freed between 56 56 * the devnode->registered check and get_device() calls, leading to 57 57 * a crash. 58 58 */ 59 - mutex_lock(&cec_devnode_lock); 59 + mutex_lock(&devnode->lock); 60 60 /* 61 61 * return ENXIO if the cec device has been removed 62 62 * already or if it is not registered anymore. 63 63 */ 64 64 if (!devnode->registered) { 65 - mutex_unlock(&cec_devnode_lock); 65 + mutex_unlock(&devnode->lock); 66 66 return -ENXIO; 67 67 } 68 68 /* and increase the device refcount */ 69 69 get_device(&devnode->dev); 70 - mutex_unlock(&cec_devnode_lock); 70 + mutex_unlock(&devnode->lock); 71 71 return 0; 72 72 } 73 73 74 74 void cec_put_device(struct cec_devnode *devnode) 75 75 { 76 - mutex_lock(&cec_devnode_lock); 77 76 put_device(&devnode->dev); 78 - mutex_unlock(&cec_devnode_lock); 79 77 } 80 78 81 79 /* Called when the last user of the cec device exits. */ ··· 82 84 struct cec_devnode *devnode = to_cec_devnode(cd); 83 85 84 86 mutex_lock(&cec_devnode_lock); 85 - 86 87 /* Mark device node number as free */ 87 88 clear_bit(devnode->minor, cec_devnode_nums); 88 - 89 89 mutex_unlock(&cec_devnode_lock); 90 + 90 91 cec_delete_adapter(to_cec_adapter(devnode)); 91 92 } 92 93 ··· 114 117 115 118 /* Initialization */ 116 119 INIT_LIST_HEAD(&devnode->fhs); 117 - mutex_init(&devnode->fhs_lock); 120 + mutex_init(&devnode->lock); 118 121 119 122 /* Part 1: Find a free minor number */ 120 123 mutex_lock(&cec_devnode_lock); ··· 157 160 cdev_del: 158 161 cdev_del(&devnode->cdev); 159 162 clr_bit: 163 + mutex_lock(&cec_devnode_lock); 160 164 clear_bit(devnode->minor, cec_devnode_nums); 165 + mutex_unlock(&cec_devnode_lock); 161 166 return ret; 162 167 } 163 168 ··· 176 177 { 177 178 struct cec_fh *fh; 178 179 179 - /* Check if devnode was never registered or already unregistered */ 180 - if (!devnode->registered || devnode->unregistered) 181 - return; 180 + mutex_lock(&devnode->lock); 182 181 183 - mutex_lock(&devnode->fhs_lock); 182 + /* Check if devnode was never registered or already unregistered */ 183 + if (!devnode->registered || devnode->unregistered) { 184 + mutex_unlock(&devnode->lock); 185 + return; 186 + } 187 + 184 188 list_for_each_entry(fh, &devnode->fhs, list) 185 189 wake_up_interruptible(&fh->wait); 186 - mutex_unlock(&devnode->fhs_lock); 187 190 188 191 devnode->registered = false; 189 192 devnode->unregistered = true; 193 + mutex_unlock(&devnode->lock); 194 + 190 195 device_del(&devnode->dev); 191 196 cdev_del(&devnode->cdev); 192 197 put_device(&devnode->dev);
+5 -5
drivers/staging/media/pulse8-cec/pulse8-cec.c
··· 114 114 cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK, 115 115 0, 0, 0, 0); 116 116 break; 117 - case MSGCODE_TRANSMIT_FAILED_LINE: 118 - cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ARB_LOST, 119 - 1, 0, 0, 0); 120 - break; 121 117 case MSGCODE_TRANSMIT_FAILED_ACK: 122 118 cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK, 123 119 0, 1, 0, 0); 124 120 break; 121 + case MSGCODE_TRANSMIT_FAILED_LINE: 125 122 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: 126 123 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: 127 124 cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR, ··· 167 170 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: 168 171 schedule_work(&pulse8->work); 169 172 break; 173 + case MSGCODE_HIGH_ERROR: 174 + case MSGCODE_LOW_ERROR: 175 + case MSGCODE_RECEIVE_FAILED: 170 176 case MSGCODE_TIMEOUT_ERROR: 171 177 break; 172 178 case MSGCODE_COMMAND_ACCEPTED: ··· 388 388 int err; 389 389 390 390 cmd[0] = MSGCODE_TRANSMIT_IDLETIME; 391 - cmd[1] = 3; 391 + cmd[1] = signal_free_time; 392 392 err = pulse8_send_and_wait(pulse8, cmd, 2, 393 393 MSGCODE_COMMAND_ACCEPTED, 1); 394 394 cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
+75 -3
include/linux/cec-funcs.h
··· 162 162 163 163 164 164 /* One Touch Record Feature */ 165 - static inline void cec_msg_record_off(struct cec_msg *msg) 165 + static inline void cec_msg_record_off(struct cec_msg *msg, bool reply) 166 166 { 167 167 msg->len = 2; 168 168 msg->msg[1] = CEC_MSG_RECORD_OFF; 169 + msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; 169 170 } 170 171 171 172 struct cec_op_arib_data { ··· 228 227 if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { 229 228 *msg++ = (digital->channel.channel_number_fmt << 2) | 230 229 (digital->channel.major >> 8); 231 - *msg++ = digital->channel.major && 0xff; 230 + *msg++ = digital->channel.major & 0xff; 232 231 *msg++ = digital->channel.minor >> 8; 233 232 *msg++ = digital->channel.minor & 0xff; 234 233 *msg++ = 0; ··· 324 323 } 325 324 326 325 static inline void cec_msg_record_on(struct cec_msg *msg, 326 + bool reply, 327 327 const struct cec_op_record_src *rec_src) 328 328 { 329 329 switch (rec_src->type) { ··· 348 346 rec_src->ext_phys_addr.phys_addr); 349 347 break; 350 348 } 349 + msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; 351 350 } 352 351 353 352 static inline void cec_ops_record_on(const struct cec_msg *msg, ··· 1144 1141 msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0; 1145 1142 } 1146 1143 1144 + static inline void cec_msg_vendor_command(struct cec_msg *msg, 1145 + __u8 size, const __u8 *vendor_cmd) 1146 + { 1147 + if (size > 14) 1148 + size = 14; 1149 + msg->len = 2 + size; 1150 + msg->msg[1] = CEC_MSG_VENDOR_COMMAND; 1151 + memcpy(msg->msg + 2, vendor_cmd, size); 1152 + } 1153 + 1154 + static inline void cec_ops_vendor_command(const struct cec_msg *msg, 1155 + __u8 *size, 1156 + const __u8 **vendor_cmd) 1157 + { 1158 + *size = msg->len - 2; 1159 + 1160 + if (*size > 14) 1161 + *size = 14; 1162 + *vendor_cmd = msg->msg + 2; 1163 + } 1164 + 1165 + static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg, 1166 + __u32 vendor_id, __u8 size, 1167 + const __u8 *vendor_cmd) 1168 + { 1169 + if (size > 11) 1170 + size = 11; 1171 + msg->len = 5 + size; 1172 + msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID; 1173 + msg->msg[2] = vendor_id >> 16; 1174 + msg->msg[3] = (vendor_id >> 8) & 0xff; 1175 + msg->msg[4] = vendor_id & 0xff; 1176 + memcpy(msg->msg + 5, vendor_cmd, size); 1177 + } 1178 + 1179 + static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg, 1180 + __u32 *vendor_id, __u8 *size, 1181 + const __u8 **vendor_cmd) 1182 + { 1183 + *size = msg->len - 5; 1184 + 1185 + if (*size > 11) 1186 + *size = 11; 1187 + *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4]; 1188 + *vendor_cmd = msg->msg + 5; 1189 + } 1190 + 1191 + static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg, 1192 + __u8 size, 1193 + const __u8 *rc_code) 1194 + { 1195 + if (size > 14) 1196 + size = 14; 1197 + msg->len = 2 + size; 1198 + msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN; 1199 + memcpy(msg->msg + 2, rc_code, size); 1200 + } 1201 + 1202 + static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg, 1203 + __u8 *size, 1204 + const __u8 **rc_code) 1205 + { 1206 + *size = msg->len - 2; 1207 + 1208 + if (*size > 14) 1209 + *size = 14; 1210 + *rc_code = msg->msg + 2; 1211 + } 1212 + 1147 1213 static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) 1148 1214 { 1149 1215 msg->len = 2; ··· 1349 1277 msg->len += 4; 1350 1278 msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | 1351 1279 (ui_cmd->channel_identifier.major >> 8); 1352 - msg->msg[4] = ui_cmd->channel_identifier.major && 0xff; 1280 + msg->msg[4] = ui_cmd->channel_identifier.major & 0xff; 1353 1281 msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; 1354 1282 msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; 1355 1283 break;
+4 -1
include/linux/cec.h
··· 364 364 * @num_log_addrs: how many logical addresses should be claimed. Set by the 365 365 * caller. 366 366 * @vendor_id: the vendor ID of the device. Set by the caller. 367 - * @flags: set to 0. 367 + * @flags: flags. 368 368 * @osd_name: the OSD name of the device. Set by the caller. 369 369 * @primary_device_type: the primary device type for each logical address. 370 370 * Set by the caller. ··· 388 388 __u8 all_device_types[CEC_MAX_LOG_ADDRS]; 389 389 __u8 features[CEC_MAX_LOG_ADDRS][12]; 390 390 }; 391 + 392 + /* Allow a fallback to unregistered */ 393 + #define CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK (1 << 0) 391 394 392 395 /* Events */ 393 396
+1 -1
include/media/cec.h
··· 57 57 int minor; 58 58 bool registered; 59 59 bool unregistered; 60 - struct mutex fhs_lock; 61 60 struct list_head fhs; 61 + struct mutex lock; 62 62 }; 63 63 64 64 struct cec_adapter;