On 6/16/19 8:22 PM, Johan Korsnes wrote: > Set/invalidate physical addresses based on the configuration of the > display present control. This is relevant not only when the display > present control is modified, but also when the Vivid instance EDID is > set/cleared. > > Signed-off-by: Johan Korsnes <johan.korsnes@xxxxxxxxx> > --- > drivers/media/platform/vivid/vivid-ctrls.c | 25 ++++++++++++++++--- > drivers/media/platform/vivid/vivid-vid-cap.c | 17 +++++++++++-- > .../media/platform/vivid/vivid-vid-common.c | 2 ++ > 3 files changed, 38 insertions(+), 6 deletions(-) > > diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c > index ae3690fd1b52..807c9e92e051 100644 > --- a/drivers/media/platform/vivid/vivid-ctrls.c > +++ b/drivers/media/platform/vivid/vivid-ctrls.c > @@ -18,6 +18,7 @@ > #include "vivid-radio-common.h" > #include "vivid-osd.h" > #include "vivid-ctrls.h" > +#include "vivid-cec.h" > > #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) > #define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0) > @@ -923,7 +924,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) > struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out); > struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; > u32 display_present = 0; > - unsigned i, j; > + unsigned i, j, bus_idx; > > switch (ctrl->id) { > case VIVID_CID_HAS_CROP_OUT: > @@ -962,15 +963,31 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) > break; > > dev->display_present[dev->output] = ctrl->val; > - > for (i = 0, j = 0; i < dev->num_outputs; i++) > if (dev->output_type[i] == HDMI) > display_present |= > dev->display_present[i] << j++; > > - __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); > __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present); > - __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); > + > + if (dev->edid_blocks) { > + __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, > + display_present); > + __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, > + display_present); > + } > + > + if (!dev->cec_tx_adap) > + break; This isn't right: cec_tx_adap is an array of cec_adapter pointers, so dev->cec_tx_adap is always non-NULL. Just drop it. > + > + bus_idx = dev->cec_output2bus_map[dev->output]; Instead you need to do: if (!dev->cec_tx_adap[bus_idx]) break; to ensure that the adapter for bus_idx is non-NULL. Regards, Hans > + if (ctrl->val && dev->edid_blocks) > + cec_s_phys_addr(dev->cec_tx_adap[bus_idx], > + dev->cec_tx_adap[bus_idx]->phys_addr, > + false); > + else > + cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]); > + > break; > } > return 0; > diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c > index ca15c13abf6c..0d1ee9a221db 100644 > --- a/drivers/media/platform/vivid/vivid-vid-cap.c > +++ b/drivers/media/platform/vivid/vivid-vid-cap.c > @@ -1750,7 +1750,8 @@ int vidioc_s_edid(struct file *file, void *_fh, > { > struct vivid_dev *dev = video_drvdata(file); > u16 phys_addr; > - unsigned int i; > + u32 display_present = 0; > + unsigned int i, j; > int ret; > > memset(edid->reserved, 0, sizeof(edid->reserved)); > @@ -1760,6 +1761,8 @@ int vidioc_s_edid(struct file *file, void *_fh, > return -EINVAL; > if (edid->blocks == 0) { > dev->edid_blocks = 0; > + v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); > + v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); > phys_addr = CEC_PHYS_ADDR_INVALID; > goto set_phys_addr; > } > @@ -1778,13 +1781,23 @@ int vidioc_s_edid(struct file *file, void *_fh, > dev->edid_blocks = edid->blocks; > memcpy(dev->edid, edid->edid, edid->blocks * 128); > > + for (i = 0, j = 0; i < dev->num_outputs; i++) > + if (dev->output_type[i] == HDMI) > + display_present |= > + dev->display_present[i] << j++; > + > + v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); > + v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); > + > set_phys_addr: > /* TODO: a proper hotplug detect cycle should be emulated here */ > cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false); > > for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) > cec_s_phys_addr(dev->cec_tx_adap[i], > - v4l2_phys_addr_for_input(phys_addr, i + 1), > + dev->display_present[i] ? > + v4l2_phys_addr_for_input(phys_addr, i + 1) : > + CEC_PHYS_ADDR_INVALID, > false); > return 0; > } > diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c > index 10a344c29a1a..1f33eb1a76b6 100644 > --- a/drivers/media/platform/vivid/vivid-vid-common.c > +++ b/drivers/media/platform/vivid/vivid-vid-common.c > @@ -887,6 +887,8 @@ int vidioc_g_edid(struct file *file, void *_fh, > return -EINVAL; > if (dev->output_type[edid->pad] != HDMI) > return -EINVAL; > + if (!dev->display_present[edid->pad]) > + return -ENODATA; > bus_idx = dev->cec_output2bus_map[edid->pad]; > adap = dev->cec_tx_adap[bus_idx]; > } >