forked from Minki/linux
drm fixes for 5.3-rc6
rcar-du: - LVDS dual-link mode fix mediatek: - of node refcount fix - prime buffer import fix - dma max seg fix komeda: - output polling fix - abfc format fix - memory-region DT fix amdgpu: - bpc display fix - ioctl memory leak fix - gfxoff fix - smu warnings fix i915: - HDMI mode readout fix -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJdX0hyAAoJEAx081l5xIa+1VQP/A6ItEQ3tC2fsf7ukB2w6HvS lHDP9WMgujR/8q/Q3IguXUiuCba+WsftE1ebv6G8HrcVrFe97roB2mX2g9XBYcPU oDW7jK8tbOQZ6J+aEQw5IPC4Ko4zOFtf47rUJMd2ceVuqHSf677Y8ZGUy2TSPlmn uDcwEgvZxGA6/uZwxQBpbiiWHX3l3UPVaRNhmv3K8mOtN95qHp6mhsKinnmwqMWj 9tnVTwM+kA5+n0DAYJfmAaQz7j0znfqNQra8mpGjLeLiHMNJiQ3LMdT9DqwvjFoj QqIlu/pZWlEsn2QBsxXWflZT02UGgutTgs5D5VeoCmVe9LM+b/XLZQeWwaCNZJmp XQiHXlm4nhtCxOYbvqGYQrXP6ffSK+aNwKix9DELF4oRl7ZmQ/C6sfrBS2Xdy5rX PJB1FVU16Y58/kRbkTdkaW3nz/vh5CMF5BactIYrfkQHx2x+F79QvCyRYZZlJ4S5 gZNJmhFeU/AcAHSf30NNDTjvIg3fzKZh935s+kP/9JItUBHNt+lL4KJivPZopVVL 1Ow5+QMnOWfjaSftMQ26FX2/3YAwY/bDmlzos6cluGycd7K2c/oHl8OdC3QLkUr/ w8J+vOyRZNkeGOCbODrKqmVJhlQ5BbXFiNUcMAzrzaL0OczJ1CRTIyMtZoZkK4zi wa8Cv/IebpT4Rrsjpvqi =eo32 -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2019-08-23' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "Live from the laundromat after my washing machine broke down, we have the 5.3-rc6 fixes. Changelog is in the tag below, but nothing too noteworthy in here: rcar-du: - LVDS dual-link mode fix mediatek: - of node refcount fix - prime buffer import fix - dma max seg fix komeda: - output polling fix - abfc format fix - memory-region DT fix amdgpu: - bpc display fix - ioctl memory leak fix - gfxoff fix - smu warnings fix i915: - HDMI mode readout fix" * tag 'drm-fixes-2019-08-23' of git://anongit.freedesktop.org/drm/drm: drm/amdgpu/powerplay: silence a warning in smu_v11_0_setup_pptable drm/amd/display: Calculate bpc based on max_requested_bpc drm/amdgpu: prevent memory leaks in AMDGPU_CS ioctl drm/amd/amdgpu: disable MMHUB PG for navi10 drm/amd/powerplay: remove duplicate macro smu_get_uclk_dpm_states in amdgpu_smu.h drm/amd/powerplay: fix variable type errors in smu_v11_0_setup_pptable drm/amdgpu/gfx9: update pg_flags after determining if gfx off is possible drm/i915: Fix HW readout for crtc_clock in HDMI mode drm/mediatek: mtk_drm_drv.c: Add of_node_put() before goto drm: rcar_lvds: Fix dual link mode operations drm/mediatek: set DMA max segment size drm/mediatek: use correct device to import PRIME buffers drm/omap: ensure we have a valid dma_mask drm/komeda: Add support for 'memory-region' DT node property drm/komeda: Adds internal bpp computing for arm afbc only format YU08 YU10 drm/komeda: Initialize and enable output polling on Komeda
This commit is contained in:
commit
1374a22e06
@ -1143,6 +1143,9 @@ static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
|
||||
num_deps = chunk->length_dw * 4 /
|
||||
sizeof(struct drm_amdgpu_cs_chunk_sem);
|
||||
|
||||
if (p->post_deps)
|
||||
return -EINVAL;
|
||||
|
||||
p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
|
||||
GFP_KERNEL);
|
||||
p->num_post_deps = 0;
|
||||
@ -1166,8 +1169,7 @@ static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
|
||||
|
||||
|
||||
static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p,
|
||||
struct amdgpu_cs_chunk
|
||||
*chunk)
|
||||
struct amdgpu_cs_chunk *chunk)
|
||||
{
|
||||
struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
|
||||
unsigned num_deps;
|
||||
@ -1177,6 +1179,9 @@ static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p
|
||||
num_deps = chunk->length_dw * 4 /
|
||||
sizeof(struct drm_amdgpu_cs_chunk_syncobj);
|
||||
|
||||
if (p->post_deps)
|
||||
return -EINVAL;
|
||||
|
||||
p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
|
||||
GFP_KERNEL);
|
||||
p->num_post_deps = 0;
|
||||
|
@ -604,6 +604,10 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
|
||||
(adev->gfx.rlc_feature_version < 1) ||
|
||||
!adev->gfx.rlc.is_rlc_v2_1)
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -552,7 +552,6 @@ static int nv_common_early_init(void *handle)
|
||||
AMD_CG_SUPPORT_BIF_LS;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_MMHUB |
|
||||
AMD_PG_SUPPORT_ATHUB;
|
||||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
break;
|
||||
|
@ -992,11 +992,6 @@ static int soc15_common_early_init(void *handle)
|
||||
|
||||
adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN;
|
||||
}
|
||||
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
|
@ -3131,13 +3131,25 @@ static enum dc_color_depth
|
||||
convert_color_depth_from_display_info(const struct drm_connector *connector,
|
||||
const struct drm_connector_state *state)
|
||||
{
|
||||
uint32_t bpc = connector->display_info.bpc;
|
||||
uint8_t bpc = (uint8_t)connector->display_info.bpc;
|
||||
|
||||
/* Assume 8 bpc by default if no bpc is specified. */
|
||||
bpc = bpc ? bpc : 8;
|
||||
|
||||
if (!state)
|
||||
state = connector->state;
|
||||
|
||||
if (state) {
|
||||
bpc = state->max_bpc;
|
||||
/*
|
||||
* Cap display bpc based on the user requested value.
|
||||
*
|
||||
* The value for state->max_bpc may not correctly updated
|
||||
* depending on when the connector gets added to the state
|
||||
* or if this was called outside of atomic check, so it
|
||||
* can't be used directly.
|
||||
*/
|
||||
bpc = min(bpc, state->max_requested_bpc);
|
||||
|
||||
/* Round down to the nearest even number. */
|
||||
bpc = bpc - (bpc & 1);
|
||||
}
|
||||
|
@ -907,8 +907,6 @@ struct smu_funcs
|
||||
((smu)->funcs->register_irq_handler ? (smu)->funcs->register_irq_handler(smu) : 0)
|
||||
#define smu_set_azalia_d3_pme(smu) \
|
||||
((smu)->funcs->set_azalia_d3_pme ? (smu)->funcs->set_azalia_d3_pme((smu)) : 0)
|
||||
#define smu_get_uclk_dpm_states(smu, clocks_in_khz, num_states) \
|
||||
((smu)->ppt_funcs->get_uclk_dpm_states ? (smu)->ppt_funcs->get_uclk_dpm_states((smu), (clocks_in_khz), (num_states)) : 0)
|
||||
#define smu_get_max_sustainable_clocks_by_dc(smu, max_clocks) \
|
||||
((smu)->funcs->get_max_sustainable_clocks_by_dc ? (smu)->funcs->get_max_sustainable_clocks_by_dc((smu), (max_clocks)) : 0)
|
||||
#define smu_get_uclk_dpm_states(smu, clocks_in_khz, num_states) \
|
||||
|
@ -326,7 +326,8 @@ static int smu_v11_0_setup_pptable(struct smu_context *smu)
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
const struct smc_firmware_header_v1_0 *hdr;
|
||||
int ret, index;
|
||||
uint32_t size;
|
||||
uint32_t size = 0;
|
||||
uint16_t atom_table_size;
|
||||
uint8_t frev, crev;
|
||||
void *table;
|
||||
uint16_t version_major, version_minor;
|
||||
@ -354,10 +355,11 @@ static int smu_v11_0_setup_pptable(struct smu_context *smu)
|
||||
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||
powerplayinfo);
|
||||
|
||||
ret = smu_get_atom_data_table(smu, index, (uint16_t *)&size, &frev, &crev,
|
||||
ret = smu_get_atom_data_table(smu, index, &atom_table_size, &frev, &crev,
|
||||
(uint8_t **)&table);
|
||||
if (ret)
|
||||
return ret;
|
||||
size = atom_table_size;
|
||||
}
|
||||
|
||||
if (!smu->smu_table.power_play_table)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@ -143,6 +144,12 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev)
|
||||
return mdev->irq;
|
||||
}
|
||||
|
||||
/* Get the optional framebuffer memory resource */
|
||||
ret = of_reserved_mem_device_init(dev);
|
||||
if (ret && ret != -ENODEV)
|
||||
return ret;
|
||||
ret = 0;
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
if (of_node_cmp(child->name, "pipeline") == 0) {
|
||||
ret = komeda_parse_pipe_dt(mdev, child);
|
||||
@ -289,6 +296,8 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
|
||||
|
||||
mdev->n_pipelines = 0;
|
||||
|
||||
of_reserved_mem_device_release(dev);
|
||||
|
||||
if (funcs && funcs->cleanup)
|
||||
funcs->cleanup(mdev);
|
||||
|
||||
|
@ -35,6 +35,25 @@ komeda_get_format_caps(struct komeda_format_caps_table *table,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 komeda_get_afbc_format_bpp(const struct drm_format_info *info, u64 modifier)
|
||||
{
|
||||
u32 bpp;
|
||||
|
||||
switch (info->format) {
|
||||
case DRM_FORMAT_YUV420_8BIT:
|
||||
bpp = 12;
|
||||
break;
|
||||
case DRM_FORMAT_YUV420_10BIT:
|
||||
bpp = 15;
|
||||
break;
|
||||
default:
|
||||
bpp = info->cpp[0] * 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return bpp;
|
||||
}
|
||||
|
||||
/* Two assumptions
|
||||
* 1. RGB always has YTR
|
||||
* 2. Tiled RGB always has SC
|
||||
|
@ -97,6 +97,9 @@ const struct komeda_format_caps *
|
||||
komeda_get_format_caps(struct komeda_format_caps_table *table,
|
||||
u32 fourcc, u64 modifier);
|
||||
|
||||
u32 komeda_get_afbc_format_bpp(const struct drm_format_info *info,
|
||||
u64 modifier);
|
||||
|
||||
u32 *komeda_get_layer_fourcc_list(struct komeda_format_caps_table *table,
|
||||
u32 layer_type, u32 *n_fmts);
|
||||
|
||||
|
@ -43,7 +43,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct drm_file *file,
|
||||
struct drm_framebuffer *fb = &kfb->base;
|
||||
const struct drm_format_info *info = fb->format;
|
||||
struct drm_gem_object *obj;
|
||||
u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks;
|
||||
u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
|
||||
u64 min_size;
|
||||
|
||||
obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
|
||||
@ -88,8 +88,9 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct drm_file *file,
|
||||
kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE,
|
||||
alignment_header);
|
||||
|
||||
bpp = komeda_get_afbc_format_bpp(info, fb->modifier);
|
||||
kfb->afbc_size = kfb->offset_payload + n_blocks *
|
||||
ALIGN(info->cpp[0] * AFBC_SUPERBLK_PIXELS,
|
||||
ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 8,
|
||||
AFBC_SUPERBLK_ALIGNMENT);
|
||||
min_size = kfb->afbc_size + fb->offsets[0];
|
||||
if (min_size > obj->size) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_irq.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "komeda_dev.h"
|
||||
#include "komeda_framebuffer.h"
|
||||
@ -315,6 +316,8 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
|
||||
|
||||
drm->irq_enabled = true;
|
||||
|
||||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
err = drm_dev_register(drm, 0);
|
||||
if (err)
|
||||
goto cleanup_mode_config;
|
||||
@ -322,6 +325,7 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
|
||||
return kms;
|
||||
|
||||
cleanup_mode_config:
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
drm->irq_enabled = false;
|
||||
drm_mode_config_cleanup(drm);
|
||||
komeda_kms_cleanup_private_objs(kms);
|
||||
@ -338,6 +342,7 @@ void komeda_kms_detach(struct komeda_kms_dev *kms)
|
||||
drm->irq_enabled = false;
|
||||
mdev->funcs->disable_irq(mdev);
|
||||
drm_dev_unregister(drm);
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
component_unbind_all(mdev->dev, drm);
|
||||
komeda_kms_cleanup_private_objs(kms);
|
||||
drm_mode_config_cleanup(drm);
|
||||
|
@ -1465,8 +1465,8 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
|
||||
else if (intel_crtc_has_dp_encoder(pipe_config))
|
||||
dotclock = intel_dotclock_calculate(pipe_config->port_clock,
|
||||
&pipe_config->dp_m_n);
|
||||
else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
|
||||
dotclock = pipe_config->port_clock * 2 / 3;
|
||||
else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp > 24)
|
||||
dotclock = pipe_config->port_clock * 24 / pipe_config->pipe_bpp;
|
||||
else
|
||||
dotclock = pipe_config->port_clock;
|
||||
|
||||
|
@ -829,7 +829,7 @@ struct intel_crtc_state {
|
||||
|
||||
/*
|
||||
* Frequence the dpll for the port should run at. Differs from the
|
||||
* adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
|
||||
* adjusted dotclock e.g. for DP or 10/12bpc hdmi mode. This is also
|
||||
* already multiplied by pixel_multiplier.
|
||||
*/
|
||||
int port_clock;
|
||||
|
@ -213,6 +213,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
||||
struct mtk_drm_private *private = drm->dev_private;
|
||||
struct platform_device *pdev;
|
||||
struct device_node *np;
|
||||
struct device *dma_dev;
|
||||
int ret;
|
||||
|
||||
if (!iommu_present(&platform_bus_type))
|
||||
@ -275,7 +276,29 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
||||
goto err_component_unbind;
|
||||
}
|
||||
|
||||
private->dma_dev = &pdev->dev;
|
||||
dma_dev = &pdev->dev;
|
||||
private->dma_dev = dma_dev;
|
||||
|
||||
/*
|
||||
* Configure the DMA segment size to make sure we get contiguous IOVA
|
||||
* when importing PRIME buffers.
|
||||
*/
|
||||
if (!dma_dev->dma_parms) {
|
||||
private->dma_parms_allocated = true;
|
||||
dma_dev->dma_parms =
|
||||
devm_kzalloc(drm->dev, sizeof(*dma_dev->dma_parms),
|
||||
GFP_KERNEL);
|
||||
}
|
||||
if (!dma_dev->dma_parms) {
|
||||
ret = -ENOMEM;
|
||||
goto err_component_unbind;
|
||||
}
|
||||
|
||||
ret = dma_set_max_seg_size(dma_dev, (unsigned int)DMA_BIT_MASK(32));
|
||||
if (ret) {
|
||||
dev_err(dma_dev, "Failed to set DMA segment size\n");
|
||||
goto err_unset_dma_parms;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't use the drm_irq_install() helpers provided by the DRM
|
||||
@ -285,13 +308,16 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
||||
drm->irq_enabled = true;
|
||||
ret = drm_vblank_init(drm, MAX_CRTC);
|
||||
if (ret < 0)
|
||||
goto err_component_unbind;
|
||||
goto err_unset_dma_parms;
|
||||
|
||||
drm_kms_helper_poll_init(drm);
|
||||
drm_mode_config_reset(drm);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unset_dma_parms:
|
||||
if (private->dma_parms_allocated)
|
||||
dma_dev->dma_parms = NULL;
|
||||
err_component_unbind:
|
||||
component_unbind_all(drm->dev, drm);
|
||||
err_config_cleanup:
|
||||
@ -302,9 +328,14 @@ err_config_cleanup:
|
||||
|
||||
static void mtk_drm_kms_deinit(struct drm_device *drm)
|
||||
{
|
||||
struct mtk_drm_private *private = drm->dev_private;
|
||||
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
|
||||
if (private->dma_parms_allocated)
|
||||
private->dma_dev->dma_parms = NULL;
|
||||
|
||||
component_unbind_all(drm->dev, drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
}
|
||||
@ -320,6 +351,18 @@ static const struct file_operations mtk_drm_fops = {
|
||||
.compat_ioctl = drm_compat_ioctl,
|
||||
};
|
||||
|
||||
/*
|
||||
* We need to override this because the device used to import the memory is
|
||||
* not dev->dev, as drm_gem_prime_import() expects.
|
||||
*/
|
||||
struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev,
|
||||
struct dma_buf *dma_buf)
|
||||
{
|
||||
struct mtk_drm_private *private = dev->dev_private;
|
||||
|
||||
return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev);
|
||||
}
|
||||
|
||||
static struct drm_driver mtk_drm_driver = {
|
||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
|
||||
DRIVER_ATOMIC,
|
||||
@ -331,7 +374,7 @@ static struct drm_driver mtk_drm_driver = {
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_prime_export = drm_gem_prime_export,
|
||||
.gem_prime_import = drm_gem_prime_import,
|
||||
.gem_prime_import = mtk_drm_gem_prime_import,
|
||||
.gem_prime_get_sg_table = mtk_gem_prime_get_sg_table,
|
||||
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
|
||||
.gem_prime_mmap = mtk_drm_gem_mmap_buf,
|
||||
@ -524,12 +567,15 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
||||
comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
|
||||
if (!comp) {
|
||||
ret = -ENOMEM;
|
||||
of_node_put(node);
|
||||
goto err_node;
|
||||
}
|
||||
|
||||
ret = mtk_ddp_comp_init(dev, node, comp, comp_id, NULL);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
of_node_put(node);
|
||||
goto err_node;
|
||||
}
|
||||
|
||||
private->ddp_comp[comp_id] = comp;
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ struct mtk_drm_private {
|
||||
} commit;
|
||||
|
||||
struct drm_atomic_state *suspend_state;
|
||||
|
||||
bool dma_parms_allocated;
|
||||
};
|
||||
|
||||
extern struct platform_driver mtk_ddp_driver;
|
||||
|
@ -669,7 +669,7 @@ static int pdev_probe(struct platform_device *pdev)
|
||||
if (omapdss_is_initialized() == false)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
|
||||
ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to set the DMA mask\n");
|
||||
return ret;
|
||||
|
@ -673,10 +673,8 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
|
||||
|
||||
/* Locate the companion LVDS encoder for dual-link operation, if any. */
|
||||
companion = of_parse_phandle(dev->of_node, "renesas,companion", 0);
|
||||
if (!companion) {
|
||||
dev_err(dev, "Companion LVDS encoder not found\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
if (!companion)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Sanity check: the companion encoder must have the same compatible
|
||||
|
Loading…
Reference in New Issue
Block a user