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