Re: [PATCH] drm/bridge: megachips: Fix a null pointer dereference bug
On Tue, Jul 19, 2022 at 09:38:16AM +0100, Martyn Welch wrote: > On Sat, 2022-07-16 at 16:13 +0800, Zheyu Ma wrote: > > When removing the module we will get the following warning: > > > > [ 31.911505] i2c-core: driver [stdp2690-ge-b850v3-fw] unregistered > > [ 31.912484] general protection fault, probably for non-canonical > > address 0xdc01: [#1] PREEMPT SMP KASAN PTI > > [ 31.913338] KASAN: null-ptr-deref in range [0x0008- > > 0x000f] > > [ 31.915280] RIP: 0010:drm_bridge_remove+0x97/0x130 > > [ 31.921825] Call Trace: > > [ 31.922533] stdp4028_ge_b850v3_fw_remove+0x34/0x60 > > [megachips_stdp_ge_b850v3_fw] > > [ 31.923139] i2c_device_remove+0x181/0x1f0 > > > > The two bridges (stdp2690, stdp4028) do not probe at the same time, > > so > > the driver does not call ge_b850v3_resgiter() when probing, causing > > the > > driver to try to remove the object that has not been initialized. > > > > Fix this by checking whether both the bridges are probed. > > > > Signed-off-by: Zheyu Ma > > Good catch! > > Acked-by: Martyn Welch Tested-by: Ian Ray > > Would be worth adding: > > Fixes: 11632d4aa2b3 ("drm/bridge: megachips: Ensure both bridges are > probed before registration") > > > --- > > drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > index cce98bf2a4e7..c68a4cdf4625 100644 > > --- a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > +++ b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > @@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void) > > * This check is to avoid both the drivers > > * removing the bridge in their remove() function > > */ > > - if (!ge_b850v3_lvds_ptr) > > + if (!ge_b850v3_lvds_ptr || > > + !ge_b850v3_lvds_ptr->stdp2690_i2c || > > + !ge_b850v3_lvds_ptr->stdp4028_i2c) > > goto out; > > > > drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge); >
Re: [PATCH v2] drm/bridge: megachips: Fix error handling in i2c_register_driver()
On Tue, Nov 08, 2022 at 09:12:26AM +, Yuan Can wrote: > > A problem about insmod megachips-stdp-ge-b850v3-fw.ko failed is > triggered with the following log given: > > [ 4497.981497] Error: Driver 'stdp4028-ge-b850v3-fw' is already registered, > aborting... > insmod: ERROR: could not insert module megachips-stdp-ge-b850v3-fw.ko: > Device or resource busy > > The reason is that stdp_ge_b850v3_init() returns i2c_add_driver() > directly without checking its return value, if i2c_add_driver() failed, > it returns without calling i2c_del_driver() on the previous i2c driver, > resulting the megachips-stdp-ge-b850v3-fw can never be installed > later. > A simple call graph is shown as below: > > stdp_ge_b850v3_init() >i2c_add_driver(&stdp4028_ge_b850v3_fw_driver) >i2c_add_driver(&stdp2690_ge_b850v3_fw_driver) > i2c_register_driver() >driver_register() > bus_add_driver() >priv = kzalloc(...) # OOM happened ># return without delete stdp4028_ge_b850v3_fw_driver > > Fix by calling i2c_del_driver() on stdp4028_ge_b850v3_fw_driver when > i2c_add_driver() returns error. > Thank you! > Fixes: fcfa0ddc18ed ("drm/bridge: Drivers for megachips-stdpxxxx-ge-b850v3-fw > (LVDS-DP++)") > Signed-off-by: Yuan Can > Reviewed-by: Andrzej Hajda Tested-by: Ian Ray > --- > Changes in v2: > - Add Andrzej's Reviewed-by > - Change to the new error return style suggested by Andrzej > > drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > index 97359f807bfc..cbfa05a6767b 100644 > --- a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > +++ b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > @@ -440,7 +440,11 @@ static int __init stdp_ge_b850v3_init(void) > if (ret) > return ret; > > - return i2c_add_driver(&stdp2690_ge_b850v3_fw_driver); > + ret = i2c_add_driver(&stdp2690_ge_b850v3_fw_driver); > + if (ret) > + i2c_del_driver(&stdp4028_ge_b850v3_fw_driver); > + > + return ret; > } > module_init(stdp_ge_b850v3_init); > > -- > 2.17.1 >
Re: EXT: Re: [PATCH] drm/imx: ipuv3-plane: Fix overlay plane width
On Tue, Nov 08, 2022 at 03:49:55PM +0100, Sebastian Reichel wrote: > Hi, > > On Tue, Nov 08, 2022 at 03:14:20PM +0100, Philipp Zabel wrote: > > ipu_src_rect_width() was introduced to support odd screen resolutions > > such as 1366x768 by internally rounding up primary plane width to a > > multiple of 8 and compensating with reduced horizontal blanking. > > This also caused overlay plane width to be rounded up, which was not > > intended. Fix overlay plane width by limiting the rounding up to the > > primary plane. > > > > drm_rect_width(&new_state->src) >> 16 is the same value as > > drm_rect_width(dst) because there is no plane scaling support. > > > > Fixes: 94dfec48fca7 ("drm/imx: Add 8 pixel alignment fix") > > Signed-off-by: Philipp Zabel Sorry for the delay in testing, and thank you for the patch! Tested-by: Ian Ray > > --- > > Looks sensible, but I no longer have access to the affected > hardware. Maybe Ian or Kitty (both added to Cc) can give it > a test on arch/arm/boot/dts/imx6dl-b155v2.dts > > -- Sebastian > > > drivers/gpu/drm/imx/ipuv3-plane.c | 14 -- > > 1 file changed, 8 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c > > b/drivers/gpu/drm/imx/ipuv3-plane.c > > index dba4f7d81d69..80142d9a4a55 100644 > > --- a/drivers/gpu/drm/imx/ipuv3-plane.c > > +++ b/drivers/gpu/drm/imx/ipuv3-plane.c > > @@ -614,6 +614,11 @@ static void ipu_plane_atomic_update(struct drm_plane > > *plane, > > break; > > } > > > > + if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_BG) > > + width = ipu_src_rect_width(new_state); > > + else > > + width = drm_rect_width(&new_state->src) >> 16; > > + > > eba = drm_plane_state_to_eba(new_state, 0); > > > > /* > > @@ -622,8 +627,7 @@ static void ipu_plane_atomic_update(struct drm_plane > > *plane, > > */ > > if (ipu_state->use_pre) { > > axi_id = ipu_chan_assign_axi_id(ipu_plane->dma); > > - ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, > > - ipu_src_rect_width(new_state), > > + ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, width, > > drm_rect_height(&new_state->src) >> > > 16, > > fb->pitches[0], fb->format->format, > > fb->modifier, &eba); > > @@ -678,9 +682,8 @@ static void ipu_plane_atomic_update(struct drm_plane > > *plane, > > break; > > } > > > > - ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), > > 8)); > > + ipu_dmfc_config_wait4eot(ipu_plane->dmfc, width); > > > > - width = ipu_src_rect_width(new_state); > > height = drm_rect_height(&new_state->src) >> 16; > > info = drm_format_info(fb->format->format); > > ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0], > > @@ -744,8 +747,7 @@ static void ipu_plane_atomic_update(struct drm_plane > > *plane, > > ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16); > > > > ipu_cpmem_zero(ipu_plane->alpha_ch); > > - ipu_cpmem_set_resolution(ipu_plane->alpha_ch, > > -ipu_src_rect_width(new_state), > > + ipu_cpmem_set_resolution(ipu_plane->alpha_ch, width, > > drm_rect_height(&new_state->src) >> > > 16); > > ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8); > > ipu_cpmem_set_high_priority(ipu_plane->alpha_ch); > > > > base-commit: 9abf2313adc1ca1b6180c508c25f22f9395cc780 > > -- > > 2.30.2 > >
Re: [PATCH 1/1] drm/imx/ipuv-v3: Fix front porch adjustment upon hactive aligning
On Wed, May 03, 2023 at 01:14:56PM +0200, Alexander Stein wrote: > When hactive is not aligned to 8 pixels, it is aligned accordingly and > hfront porch needs to be reduced the same amount. Unfortunately the front > porch is set to the difference rather than reducing it. There are some > Samsung TVs which can't cope with a front porch of instead of 70. > > Fixes: 94dfec48fca7 ("drm/imx: Add 8 pixel alignment fix") > Signed-off-by: Alexander Stein Tested on the same 1366x768 display hardware that required the original fix in commit 94dfec48fca7. Tested-by: Ian Ray > --- > AFAICS ipu_di_adjust_videomode() checks that front porch is big enough to > reduce the alignment difference. > > drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c > b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c > index 1d306f7be9fd..341e9125bf2c 100644 > --- a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c > +++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c > @@ -311,7 +311,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) > sig_cfg.mode.hactive, new_hactive); > > dev_info(ipu_crtc->dev, "hfront_porch: %u\n", > sig_cfg.mode.hfront_porch); > - sig_cfg.mode.hfront_porch = new_hactive - > sig_cfg.mode.hactive; > + sig_cfg.mode.hfront_porch -= new_hactive - > sig_cfg.mode.hactive; > dev_info(ipu_crtc->dev, "hfront_porch: %u\n", > sig_cfg.mode.hfront_porch); > sig_cfg.mode.hactive = new_hactive; > } > -- > 2.34.1 >
Re: EXT: Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
On Mon, Sep 04, 2023 at 01:04:40PM +0300, Jani Nikula wrote: > > On Sat, 02 Sep 2023, Peter Senna Tschudin wrote: > > Good morning Jani, > > > > It has been a long time since I wrote the driver, and many many years > > since I sent my last kernel patch, so my memory does not serve me very > > well, but I will try to shed some light. > > > > On Fri, Sep 1, 2023 at 12:24 PM Jani Nikula wrote: > >> > >> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge: > >> Drivers for megachips-stdp-ge-b850v3-fw (LVDS-DP++)"). I tried to > >> look up the discussion, but didn't find anyone questioning the EDID > >> reading part. > >> > >> Why does it not use drm_get_edid() or drm_do_get_edid()? > >> > >> I don't know where client->addr comes from, so I guess it could be > >> different from DDC_ADDR, rendering drm_get_edid() unusable. > >> > >> There's also the comment: > >> > >> /* Yes, read the entire buffer, and do not skip the first > >> * EDID_LENGTH bytes. > >> */ > >> > >> But again, there's not a word on *why*. > > > > The video pipeline has two hardware bridges between the LVDS from the > > SoC and DP+ output. For reasons, we would get hot plug events from one > > of these bridges, and EDID from the other. If I am not mistaken, I > > documented this strangeness in the DTS readme file. > > > > Did this shed any light on the *why* or did I tell you something you > > already knew? > > I guess that answers the question why it's necessary to specify the ddc > to use, but not why drm_do_get_edid() could not be used. Is it really > necessary to read the EDID in one go? Moi Jani, Sorry for slow reply -- I will look into this during this week. I would hope and expect that we could use common APIs. > > BR, > Jani. > > -- > Jani Nikula, Intel Open Source Graphics Center >
Re: EXT: Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
On Fri, Sep 01, 2023 at 05:52:02PM +0300, Jani Nikula wrote: > > On Fri, 01 Sep 2023, Jani Nikula wrote: > > The driver was originally added in commit fcfa0ddc18ed ("drm/bridge: > > Drivers for megachips-stdp-ge-b850v3-fw (LVDS-DP++)"). I tried to > > look up the discussion, but didn't find anyone questioning the EDID > > reading part. > > > > Why does it not use drm_get_edid() or drm_do_get_edid()? > > > > I don't know where client->addr comes from, so I guess it could be > > different from DDC_ADDR, rendering drm_get_edid() unusable. > > > > There's also the comment: > > > > /* Yes, read the entire buffer, and do not skip the first > > * EDID_LENGTH bytes. > > */ > > > > But again, there's not a word on *why*. > > > > Maybe we could just use drm_do_get_edid()? I'd like drivers to migrate > > away from their own EDID parsing and validity checks, including stop > > using drm_edid_block_valid(). (And long term switch to drm_edid_read(), > > struct drm_edid, and friends, but this is the first step.) > > > > Cc: Andrzej Hajda > > Cc: Ian Ray > > Cc: Jernej Skrabec > > Cc: Jonas Karlman > > Cc: Laurent Pinchart > > Cc: Martin Donnelly > > Cc: Martyn Welch > > Cc: Neil Armstrong > > Cc: Peter Senna Tschudin > > Cc: Robert Foss > > Cc: Yuan Can > > Cc: Zheyu Ma > > Signed-off-by: Jani Nikula > > > > --- > > > > I haven't even tried to compile this, and I have no way to test > > this. Apologies for the long Cc list; I'm hoping someone could explain > > the existing code, and perhaps give this approach a spin. > > --- > > .../bridge/megachips-stdp-ge-b850v3-fw.c | 57 +++ > > 1 file changed, 9 insertions(+), 48 deletions(-) > > > > diff --git a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > index 460db3c8a08c..0d9eacf3d9b7 100644 > > --- a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > +++ b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c > > @@ -65,12 +65,11 @@ struct ge_b850v3_lvds { > > > > static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr; > > > > -static u8 *stdp2690_get_edid(struct i2c_client *client) > > +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, > > size_t len) > > { > > + struct i2c_client *client = context; > > struct i2c_adapter *adapter = client->adapter; > > - unsigned char start = 0x00; > > - unsigned int total_size; > > - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL); > > + unsigned char start = block * EDID_LENGTH; > > > > struct i2c_msg msgs[] = { > > { > > @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client) > > }, { > > .addr = client->addr, > > .flags = I2C_M_RD, > > - .len= EDID_LENGTH, > > - .buf= block, > > + .len= len, > > + .buf= buf, > > } > > }; > > > > - if (!block) > > - return NULL; > > + if (i2c_transfer(adapter, msgs, 2) != 2) > > + return -1; > > > > - if (i2c_transfer(adapter, msgs, 2) != 2) { > > - DRM_ERROR("Unable to read EDID.\n"); > > - goto err; > > - } > > - > > - if (!drm_edid_block_valid(block, 0, false, NULL)) { > > - DRM_ERROR("Invalid EDID data\n"); > > - goto err; > > - } > > - > > - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH; > > - if (total_size > EDID_LENGTH) { > > - kfree(block); > > - block = kmalloc(total_size, GFP_KERNEL); > > - if (!block) > > - return NULL; > > - > > - /* Yes, read the entire buffer, and do not skip the first > > -* EDID_LENGTH bytes. > > -*/ > > - start = 0x00; > > - msgs[1].len = total_size; > > - msgs[1].buf = block; > > - > > - if (i2c_transfer(adapter, msgs, 2) != 2) { > > - DRM_ERROR("Unable to read EDID extension blocks.\n"); > > - goto err; > > - } > > - if (!drm_edid_block_valid(block, 1, false, NULL)) { &
[PATCH 1/2] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
Migrate away from custom EDID parsing and validity checks. Signed-off-by: Jani Nikula Signed-off-by: Ian Ray --- .../drm/bridge/megachips-stdp-ge-b850v3-fw.c | 57 -- 1 file changed, 9 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c index 460db3c..e93083b 100644 --- a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c @@ -65,12 +65,11 @@ struct ge_b850v3_lvds { static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr; -static u8 *stdp2690_get_edid(struct i2c_client *client) +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len) { + struct i2c_client *client = context; struct i2c_adapter *adapter = client->adapter; - unsigned char start = 0x00; - unsigned int total_size; - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL); + unsigned char start = block * EDID_LENGTH; struct i2c_msg msgs[] = { { @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client) }, { .addr = client->addr, .flags = I2C_M_RD, - .len= EDID_LENGTH, - .buf= block, + .len= len, + .buf= buf, } }; - if (!block) - return NULL; + if (i2c_transfer(adapter, msgs, 2) != 2) + return -1; - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID.\n"); - goto err; - } - - if (!drm_edid_block_valid(block, 0, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH; - if (total_size > EDID_LENGTH) { - kfree(block); - block = kmalloc(total_size, GFP_KERNEL); - if (!block) - return NULL; - - /* Yes, read the entire buffer, and do not skip the first -* EDID_LENGTH bytes. -*/ - start = 0x00; - msgs[1].len = total_size; - msgs[1].buf = block; - - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID extension blocks.\n"); - goto err; - } - if (!drm_edid_block_valid(block, 1, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - } - - return block; - -err: - kfree(block); - return NULL; + return 0; } static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, client = ge_b850v3_lvds_ptr->stdp2690_i2c; - return (struct edid *)stdp2690_get_edid(client); + return drm_do_get_edid(connector, stdp2690_read_block, client); } static int ge_b850v3_lvds_get_modes(struct drm_connector *connector) -- 2.10.1
[PATCH 2/2] MAINTAINERS: Update entry for megachips-stdpxxxx-ge-b850v3-fw
Replace Martin, who has left GE. Signed-off-by: Ian Ray --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index bf0f54c..31bb835 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13524,7 +13524,7 @@ F: drivers/usb/mtu3/ MEGACHIPS STDP-GE-B850V3-FW LVDS/DP++ BRIDGES M: Peter Senna Tschudin -M: Martin Donnelly +M: Ian Ray M: Martyn Welch S: Maintained F: Documentation/devicetree/bindings/display/bridge/megachips-stdp-ge-b850v3-fw.txt -- 2.10.1
[PATCH v3 2/2] MAINTAINERS: Update entry for megachips-stdpxxxx-ge-b850v3-fw
Replace Martin, who has left GE. Signed-off-by: Ian Ray --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index bf0f54c..31bb835 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13524,7 +13524,7 @@ F: drivers/usb/mtu3/ MEGACHIPS STDP-GE-B850V3-FW LVDS/DP++ BRIDGES M: Peter Senna Tschudin -M: Martin Donnelly +M: Ian Ray M: Martyn Welch S: Maintained F: Documentation/devicetree/bindings/display/bridge/megachips-stdp-ge-b850v3-fw.txt -- 2.10.1
[PATCH v3 1/2] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
Migrate away from custom EDID parsing and validity checks. Note: This is a follow-up to the original RFC by Jani [1]. The first submission in this series should have been marked v2. [1] https://patchwork.freedesktop.org/patch/msgid/20230901102400.552254-1-jani.nik...@intel.com Co-developed-by: Jani Nikula Signed-off-by: Jani Nikula Signed-off-by: Ian Ray --- .../drm/bridge/megachips-stdp-ge-b850v3-fw.c | 57 -- 1 file changed, 9 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c index 460db3c..e93083b 100644 --- a/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c @@ -65,12 +65,11 @@ struct ge_b850v3_lvds { static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr; -static u8 *stdp2690_get_edid(struct i2c_client *client) +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len) { + struct i2c_client *client = context; struct i2c_adapter *adapter = client->adapter; - unsigned char start = 0x00; - unsigned int total_size; - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL); + unsigned char start = block * EDID_LENGTH; struct i2c_msg msgs[] = { { @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client) }, { .addr = client->addr, .flags = I2C_M_RD, - .len= EDID_LENGTH, - .buf= block, + .len= len, + .buf= buf, } }; - if (!block) - return NULL; + if (i2c_transfer(adapter, msgs, 2) != 2) + return -1; - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID.\n"); - goto err; - } - - if (!drm_edid_block_valid(block, 0, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH; - if (total_size > EDID_LENGTH) { - kfree(block); - block = kmalloc(total_size, GFP_KERNEL); - if (!block) - return NULL; - - /* Yes, read the entire buffer, and do not skip the first -* EDID_LENGTH bytes. -*/ - start = 0x00; - msgs[1].len = total_size; - msgs[1].buf = block; - - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID extension blocks.\n"); - goto err; - } - if (!drm_edid_block_valid(block, 1, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - } - - return block; - -err: - kfree(block); - return NULL; + return 0; } static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, client = ge_b850v3_lvds_ptr->stdp2690_i2c; - return (struct edid *)stdp2690_get_edid(client); + return drm_do_get_edid(connector, stdp2690_read_block, client); } static int ge_b850v3_lvds_get_modes(struct drm_connector *connector) -- 2.10.1