Re: [PATCH] drm/bridge: megachips: Fix a null pointer dereference bug

2022-08-03 Thread Ian Ray
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()

2022-11-23 Thread Ian Ray
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

2022-12-20 Thread Ian Ray
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

2023-06-14 Thread Ian Ray
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()

2023-09-05 Thread Ian Ray
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()

2023-09-08 Thread Ian Ray
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()

2023-09-21 Thread Ian Ray
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

2023-09-21 Thread Ian Ray
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

2023-09-21 Thread Ian Ray
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()

2023-09-21 Thread Ian Ray
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