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 | 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 | |
| @@ -201,6 +201,25 @@ logical address types are already defined will return with error ``EBUSY``. · 50 unmodified lines | ||
| 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 | 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 | 223 | .. _cec-versions: |
| 205 | 224 | |
| 206 | 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 | 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 | |
| @@ -72,7 +73,10 @@ it is guaranteed that the state did change in between the two events. · 1 unmodified line | ||
| 72 | 73 | |
| 73 | 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 | 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); |
| @@ -1552,6 +1552,7 @@ int cx23885_417_register(struct cx23885_dev *dev) · 1551 unmodified lines | ||
| 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) |
| @@ -1238,6 +1238,7 @@ static int dvb_init(struct saa7134_dev *dev) · 1237 unmodified lines | ||
| 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); |
| @@ -295,6 +295,7 @@ static int empress_init(struct saa7134_dev *dev) · 294 unmodified lines | ||
| 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; |
| @@ -169,7 +169,7 @@ config VIDEO_MEDIATEK_VPU · 168 unmodified lines | ||
| 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 |
| @@ -23,7 +23,6 @@ · 22 unmodified lines | ||
| 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" |
| @@ -487,7 +487,6 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, · 486 unmodified lines | ||
| 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); |
| @@ -530,15 +529,6 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, · 36 unmodified lines | ||
| 530 | 529 | q_data->coded_width = f->fmt.pix_mp.width; |
| 531 | 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 | 532 | q_data->field = f->fmt.pix_mp.field; |
| 543 | 533 | ctx->colorspace = f->fmt.pix_mp.colorspace; |
| 544 | 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 | 869 | struct mtk_vcodec_ctx *ctx = priv; |
| 880 | 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 | 873 | struct mtk_vcodec_mem bs_buf; |
| 883 | 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 | 902 | mtk_v4l2_err("venc_if_encode failed=%d", ret); |
| 912 | 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 | 915 | ctx->state = MTK_STATE_HEADER; |
| 916 | 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 | 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,9 +1043,14 @@ static void mtk_venc_worker(struct work_struct *work) · 33 unmodified lines | ||
| 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), |
| @@ -1217,7 +1222,7 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) · 165 unmodified lines | ||
| 1217 | 1222 | 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); |
| 1218 | 1223 | v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, |
| 1219 | 1224 | V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, |
| 1220 | − 0, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN); | |
| 1225 | + 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); | |
| 1221 | 1226 | v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, |
| 1222 | 1227 | V4L2_MPEG_VIDEO_H264_LEVEL_4_2, |
| 1223 | 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 | 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 | 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--; |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 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 | |
| @@ -61,6 +61,8 @@ enum venc_h264_bs_mode { · 60 unmodified lines | ||
| 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, |
| @@ -94,13 +96,13 @@ struct venc_h264_vpu_config { · 27 unmodified lines | ||
| 94 | 96 | |
| 95 | 97 | /* |
| 96 | 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 | 101 | * @iova: IO virtual address |
| 99 | 102 | * @vpua: VPU side memory addr which is used by RC_CODE |
| 100 | 103 | * @size: buffer size (in bytes) |
| 101 | 104 | */ |
| 102 | 105 | struct venc_h264_vpu_buf { |
| 103 | − u32 align; | |
| 104 | 106 | u32 iova; |
| 105 | 107 | u32 vpua; |
| 106 | 108 | u32 size; |
| @@ -108,6 +110,8 @@ struct venc_h264_vpu_buf { · 1 unmodified line | ||
| 108 | 110 | |
| 109 | 111 | /* |
| 110 | 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 | 115 | * This structure is allocated in VPU side and shared to AP side. |
| 112 | 116 | * @config: h264 encoder configuration |
| 113 | 117 | * @work_bufs: working buffer information in VPU side |
| @@ -150,12 +154,6 @@ struct venc_h264_inst { · 36 unmodified lines | ||
| 150 | 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 | 157 | static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) |
| 160 | 158 | { |
| 161 | 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 | 212 | return 40; |
| 215 | 213 | case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: |
| 216 | 214 | return 41; |
| 215 | + case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: | |
| 216 | + return 42; | |
| 217 | 217 | default: |
| 218 | 218 | mtk_vcodec_debug(inst, "unsupported level %d", level); |
| 219 | 219 | return 31; |
| @@ -56,6 +56,8 @@ enum venc_vp8_vpu_work_buf { · 55 unmodified lines | ||
| 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, |
| @@ -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 | |
| 87 | − * @align: buffer alignment (in bytes) | |
| 88 | + * struct venc_vp8_vpu_buf - Structure for buffer information | |
| 89 | + * AP-W/R : AP is writer/reader on this item | |
| 90 | + * VPU-W/R: VPU is write/reader on this item | |
| 88 | 91 | * @iova: IO virtual address |
| 89 | 92 | * @vpua: VPU side memory addr which is used by RC_CODE |
| 90 | 93 | * @size: buffer size (in bytes) |
| 91 | 94 | */ |
| 92 | 95 | struct venc_vp8_vpu_buf { |
| 93 | − u32 align; | |
| 94 | 96 | u32 iova; |
| 95 | 97 | u32 vpua; |
| 96 | 98 | u32 size; |
| @@ -98,6 +100,8 @@ struct venc_vp8_vpu_buf { · 1 unmodified line | ||
| 98 | 100 | |
| 99 | 101 | /* |
| 100 | 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 | 105 | * This structure is allocated in VPU side and shared to AP side. |
| 102 | 106 | * @config: vp8 encoder configuration |
| 103 | 107 | * @work_bufs: working buffer information in VPU side |
| @@ -138,12 +142,6 @@ struct venc_vp8_inst { · 34 unmodified lines | ||
| 138 | 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 | 145 | static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr) |
| 148 | 146 | { |
| 149 | 147 | return readl(inst->hw_base + addr); |
| @@ -99,10 +99,16 @@ EXPORT_SYMBOL_GPL(rcar_fcp_put); · 98 unmodified lines | ||
| 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 | |
| @@ -12,6 +12,7 @@ Hopefully this will happen later in 2016. · 11 unmodified lines | ||
| 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 |
| @@ -124,10 +124,10 @@ static void cec_queue_event(struct cec_adapter *adap, · 123 unmodified lines | ||
| 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,12 +191,12 @@ static void cec_queue_msg_monitor(struct cec_adapter *adap, · 57 unmodified lines | ||
| 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,12 +207,12 @@ static void cec_queue_msg_followers(struct cec_adapter *adap, · 4 unmodified lines | ||
| 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,6 +851,9 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) · 632 unmodified lines | ||
| 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) |
| @@ -1047,11 +1050,17 @@ static int cec_config_thread_func(void *arg) · 190 unmodified lines | ||
| 1047 | 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 | 1057 | configured: |
| 1051 | 1058 | if (adap->log_addrs.log_addr_mask == 0) { |
| 1052 | 1059 | /* Fall back to unregistered */ |
| 1053 | 1060 | las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; |
| 1054 | 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 | 1065 | adap->is_configured = true; |
| 1057 | 1066 | adap->is_configuring = false; |
| @@ -1070,6 +1079,8 @@ configured: · 12 unmodified lines | ||
| 1070 | 1079 | cec_report_features(adap, i); |
| 1071 | 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 | 1084 | mutex_lock(&adap->lock); |
| 1074 | 1085 | adap->kthread_config = NULL; |
| 1075 | 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 | 1409 | u8 init_laddr = cec_msg_initiator(msg); |
| 1399 | 1410 | u8 devtype = cec_log_addr2dev(adap, dest_laddr); |
| 1400 | 1411 | int la_idx = cec_log_addr2idx(adap, dest_laddr); |
| 1401 | − bool is_directed = la_idx >= 0; | |
| 1402 | 1412 | bool from_unregistered = init_laddr == 0xf; |
| 1403 | 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 | 1570 | * Unprocessed messages are aborted if userspace isn't doing |
| 1561 | 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 | 1574 | !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) |
| 1565 | 1575 | return cec_feature_abort(adap, msg); |
| 1566 | 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 | 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,7 +435,7 @@ static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 266 unmodified lines | ||
| 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,14 +508,14 @@ static int cec_open(struct inode *inode, struct file *filp) · 66 unmodified lines | ||
| 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,9 +540,9 @@ static int cec_release(struct inode *inode, struct file *filp) · 18 unmodified lines | ||
| 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); |
| @@ -51,31 +51,29 @@ int cec_get_device(struct cec_devnode *devnode) · 50 unmodified lines | ||
| 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. */ |
| @@ -84,11 +82,10 @@ static void cec_devnode_release(struct device *cd) · 2 unmodified lines | ||
| 84 | 82 | struct cec_devnode *devnode = to_cec_devnode(cd); |
| 85 | 83 | |
| 86 | 84 | mutex_lock(&cec_devnode_lock); |
| 87 | − | |
| 88 | 85 | /* Mark device node number as free */ |
| 89 | 86 | clear_bit(devnode->minor, cec_devnode_nums); |
| 90 | − | |
| 91 | 87 | mutex_unlock(&cec_devnode_lock); |
| 88 | + | |
| 92 | 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 | 115 | /* Initialization */ |
| 119 | 116 | INIT_LIST_HEAD(&devnode->fhs); |
| 120 | − mutex_init(&devnode->fhs_lock); | |
| 117 | + mutex_init(&devnode->lock); | |
| 121 | 118 | |
| 122 | 119 | /* Part 1: Find a free minor number */ |
| 123 | 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 | 157 | cdev_del: |
| 161 | 158 | cdev_del(&devnode->cdev); |
| 162 | 159 | clr_bit: |
| 160 | + mutex_lock(&cec_devnode_lock); | |
| 163 | 161 | clear_bit(devnode->minor, cec_devnode_nums); |
| 162 | + mutex_unlock(&cec_devnode_lock); | |
| 164 | 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 | 177 | struct cec_fh *fh; |
| 179 | 178 | |
| 179 | + mutex_lock(&devnode->lock); | |
| 180 | + | |
| 180 | 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 | 184 | return; |
| 185 | + } | |
| 183 | 186 | |
| 184 | − mutex_lock(&devnode->fhs_lock); | |
| 185 | 187 | list_for_each_entry(fh, &devnode->fhs, list) |
| 186 | 188 | wake_up_interruptible(&fh->wait); |
| 187 | − mutex_unlock(&devnode->fhs_lock); | |
| 188 | 189 | |
| 189 | 190 | devnode->registered = false; |
| 190 | 191 | devnode->unregistered = true; |
| 192 | + mutex_unlock(&devnode->lock); | |
| 193 | + | |
| 191 | 194 | device_del(&devnode->dev); |
| 192 | 195 | cdev_del(&devnode->cdev); |
| 193 | 196 | put_device(&devnode->dev); |
| @@ -114,14 +114,11 @@ static void pulse8_irq_work_handler(struct work_struct *work) · 113 unmodified lines | ||
| 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, |
| @@ -170,6 +167,9 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, · 42 unmodified lines | ||
| 170 | 167 | case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: |
| 171 | 168 | schedule_work(&pulse8->work); |
| 172 | 169 | break; |
| 170 | + case MSGCODE_HIGH_ERROR: | |
| 171 | + case MSGCODE_LOW_ERROR: | |
| 172 | + case MSGCODE_RECEIVE_FAILED: | |
| 173 | 173 | case MSGCODE_TIMEOUT_ERROR: |
| 174 | 174 | break; |
| 175 | 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 | 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; |
| @@ -162,10 +162,11 @@ static inline void cec_msg_standby(struct cec_msg *msg) · 161 unmodified lines | ||
| 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 { |
| @@ -227,7 +228,7 @@ static inline void cec_set_digital_service_id(__u8 *msg, · 55 unmodified lines | ||
| 227 | 228 | if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) { |
| 228 | 229 | *msg++ = (digital->channel.channel_number_fmt << 2) | |
| 229 | 230 | (digital->channel.major >> 8); |
| 230 | − *msg++ = digital->channel.major && 0xff; | |
| 231 | + *msg++ = digital->channel.major & 0xff; | |
| 231 | 232 | *msg++ = digital->channel.minor >> 8; |
| 232 | 233 | *msg++ = digital->channel.minor & 0xff; |
| 233 | 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 | 326 | static inline void cec_msg_record_on(struct cec_msg *msg, |
| 327 | + bool reply, | |
| 326 | 328 | const struct cec_op_record_src *rec_src) |
| 327 | 329 | { |
| 328 | 330 | switch (rec_src->type) { |
| @@ -346,6 +348,7 @@ static inline void cec_msg_record_on(struct cec_msg *msg, · 17 unmodified lines | ||
| 346 | 348 | rec_src->ext_phys_addr.phys_addr); |
| 347 | 349 | break; |
| 348 | 350 | } |
| 351 | + msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; | |
| 349 | 352 | } |
| 350 | 353 | |
| 351 | 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 | 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 | 1216 | static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg) |
| 1145 | 1217 | { |
| 1146 | 1218 | msg->len = 2; |
| @@ -1277,7 +1349,7 @@ static inline void cec_msg_user_control_pressed(struct cec_msg *msg, · 130 unmodified lines | ||
| 1277 | 1349 | msg->len += 4; |
| 1278 | 1350 | msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) | |
| 1279 | 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 | 1353 | msg->msg[5] = ui_cmd->channel_identifier.minor >> 8; |
| 1282 | 1354 | msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff; |
| 1283 | 1355 | break; |
| @@ -364,7 +364,7 @@ struct cec_caps { · 363 unmodified lines | ||
| 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. |
| @@ -389,6 +389,9 @@ struct cec_log_addrs { · 18 unmodified lines | ||
| 389 | 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 | 395 | /* Events */ |
| 393 | 396 | |
| 394 | 397 | /* Event that occurs when the adapter state changes */ |
| @@ -57,8 +57,8 @@ struct cec_devnode { · 56 unmodified lines | ||
| 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; |