Re: [PATCH] fbdev: defio: fix the pagelist corruption

2022-03-26 Thread Paul Menzel

Dear Chuansheng,


Am 17.03.22 um 06:46 schrieb Chuansheng Liu:

Easily hit the below list corruption:
==
list_add corruption. prev->next should be next (c0ceb090), but
was ec604507edc8. (prev=ec604507edc8).
WARNING: CPU: 65 PID: 3959 at lib/list_debug.c:26
__list_add_valid+0x53/0x80
CPU: 65 PID: 3959 Comm: fbdev Tainted: G U
RIP: 0010:__list_add_valid+0x53/0x80
Call Trace:
  
  fb_deferred_io_mkwrite+0xea/0x150
  do_page_mkwrite+0x57/0xc0
  do_wp_page+0x278/0x2f0
  __handle_mm_fault+0xdc2/0x1590
  handle_mm_fault+0xdd/0x2c0
  do_user_addr_fault+0x1d3/0x650
  exc_page_fault+0x77/0x180
  ? asm_exc_page_fault+0x8/0x30
  asm_exc_page_fault+0x1e/0x30
RIP: 0033:0x7fd98fc8fad1
==

Figure out the race happens when one process is adding &page->lru into
the pagelist tail in fb_deferred_io_mkwrite(), another process is
re-initializing the same &page->lru in fb_deferred_io_fault(), which is
not protected by the lock.

This fix is to init all the page lists one time during initialization,
it not only fixes the list corruption, but also avoids INIT_LIST_HEAD()
redundantly.

Fixes: 105a940416fc ("fbdev/defio: Early-out if page is already
enlisted")
Cc: Thomas Zimmermann 
Signed-off-by: Chuansheng Liu 
---
  drivers/video/fbdev/core/fb_defio.c | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fb_defio.c 
b/drivers/video/fbdev/core/fb_defio.c
index 98b0f23bf5e2..eafb66ca4f28 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -59,7 +59,6 @@ static vm_fault_t fb_deferred_io_fault(struct vm_fault *vmf)
printk(KERN_ERR "no mapping available\n");
  
  	BUG_ON(!page->mapping);

-   INIT_LIST_HEAD(&page->lru);
page->index = vmf->pgoff;
  
  	vmf->page = page;

@@ -220,6 +219,8 @@ static void fb_deferred_io_work(struct work_struct *work)
  void fb_deferred_io_init(struct fb_info *info)
  {
struct fb_deferred_io *fbdefio = info->fbdefio;
+   struct page *page;
+   int i;
  
  	BUG_ON(!fbdefio);

mutex_init(&fbdefio->lock);
@@ -227,6 +228,12 @@ void fb_deferred_io_init(struct fb_info *info)
INIT_LIST_HEAD(&fbdefio->pagelist);
if (fbdefio->delay == 0) /* set a default of 1 s */
fbdefio->delay = HZ;
+
+   /* initialize all the page lists one time */
+   for (i = 0; i < info->fix.smem_len; i += PAGE_SIZE) {
+   page = fb_deferred_io_page(info, i);
+   INIT_LIST_HEAD(&page->lru);
+   }
  }
  EXPORT_SYMBOL_GPL(fb_deferred_io_init);
  
Applying your patch on top of current Linus’ master branch, tty0 is 
unusable and looks frozen. Sometimes network card still works, sometimes 
not.


$ git log --oneline -nodecorate -2
1b351a77ed33 (HEAD -> linus) fbdev: defio: fix the pagelist corruption
52d543b5497c (origin/master, origin/HEAD) Merge tag 
'for-linus-5.17-1' of https://github.com/cminyard/linux-ipmi


```
[5.256996] raw:    

[5.269582] page dumped because: VM_BUG_ON_PAGE(compound && 
compound_order(page) != order)

[5.279507] [ cut here ]
[5.286406] kernel BUG at mm/page_alloc.c:1326!
[5.291814] invalid opcode:  [#1] PREEMPT SMP
[5.296350] CPU: 0 PID: 167 Comm: systemd-udevd Not tainted 
5.17.0-10753-g1b351a77ed33 #300
[5.304670] Hardware name: ASUS F2A85-M_PRO/F2A85-M_PRO, BIOS 
4.16-337-gb87986e67b 03/25/2022

[5.313163] RIP: 0010:free_pcp_prepare+0x295/0x400
[5.317930] Code: 00 01 00 75 0b 48 8b 45 08 45 31 ff a8 01 74 4b 48 
8b 45 00 a9 00 00 01 00 75 22 48 c7 c6 68 30 11 96 48 89 ef e8 cb 29 fd 
ff <0f> 0b 48 89 ef 41 83 c6 01 e8 bd f5 ff ff e9 2e fe ff ff 0f 1f 44

[5.336650] RSP: 0018:a6634062f9c0 EFLAGS: 00010246
[5.341849] RAX: 004e RBX: e4be8000 RCX: 

[5.348957] RDX:  RSI: 96136a37 RDI: 

[5.356063] RBP: e4be840c R08:  R09: 
dfff
[5.363170] R10: a6634062f7f0 R11: 9652c4a8 R12: 

[5.370277] R13: 0009 R14: 91fd02ebc640 R15: 
e4be840c
[5.377384] FS:  () GS:91fd7b40(0063) 
knlGS:f7eea800

[5.385443] CS:  0010 DS: 002b ES: 002b CR0: 80050033
[5.391164] CR2: f6f0e840 CR3: 000106b6 CR4: 
000406f0

[5.398272] Call Trace:
[5.400697]  
[5.402778]  free_unref_page+0x1b/0xf0
[5.406505]  __vunmap+0x216/0x2c0
[5.409798]  drm_fbdev_cleanup+0x5f/0xb0
[5.413698]  drm_fbdev_fb_destroy+0x15/0x30
[5.417857]  unregister_framebuffer+0x2c/0x40
[5.422191]  drm_client_dev_unregister+0x69/0xe0
[5.422962] usb usb4: New USB device found, idVendor=1d6b, 
idProduct=0003, bcdDevice= 5.17

[5.426784]  drm_dev_unregister+0x2e/0x80
[5.439005]  drm_dev_unplug+0x21/0x40
[5.442645

Re: [PATCH v11 5/7] dt-bindings: display: Add Loongson display controller

2022-03-26 Thread Sui Jingfeng



On 2022/3/24 21:26, Rob Herring wrote:

On Thu, Mar 24, 2022 at 09:48:19AM +0800, Sui Jingfeng wrote:

On 2022/3/23 21:03, Rob Herring wrote:

On Wed, Mar 23, 2022 at 11:38:55AM +0800, Sui Jingfeng wrote:

On 2022/3/23 04:55, Rob Herring wrote:

On Tue, Mar 22, 2022 at 10:33:45AM +0800, Sui Jingfeng wrote:

On 2022/3/22 07:20, Rob Herring wrote:

On Tue, Mar 22, 2022 at 12:29:14AM +0800, Sui Jingfeng wrote:

From: suijingfeng 


Needs a commit message.


Signed-off-by: suijingfeng 
Signed-off-by: Sui Jingfeng <15330273...@189.cn>

Same person? Don't need both emails.

Yes,  suijingf...@loongson.cn is my company's email. But it can not be used
to send patches to dri-devel,

when send patches with this email, the patch will not be shown on patch
works.

Emails  are either blocked or got  rejected  by loongson's mail server.  It
can only receive emails

from you and other people, but not dri-devel. so have to use my personal
email(15330273...@189.cn) to send patches.


---
 .../loongson/loongson,display-controller.yaml | 230 ++
 1 file changed, 230 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/loongson/loongson,display-controller.yaml

diff --git 
a/Documentation/devicetree/bindings/display/loongson/loongson,display-controller.yaml
 
b/Documentation/devicetree/bindings/display/loongson/loongson,display-controller.yaml
new file mode 100644
index ..7be63346289e
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/display/loongson/loongson,display-controller.yaml
@@ -0,0 +1,230 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/display/loongson/loongson,display-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson LS7A1000/LS2K1000/LS2K0500 Display Controller Device Tree 
Bindings
+
+maintainers:
+  - Sui Jingfeng 
+
+description: |+
+
+  Loongson display controllers are simple which require scanout buffers
+  to be physically contiguous. LS2K1000/LS2K0500 is a SOC, only system
+  memory is available. LS7A1000/LS7A2000 is bridge chip which is equipped
+  with a dedicated video RAM which is 64MB or more, precise size can be
+  read from the PCI BAR 2 of the GPU device(0x0014:0x7A15) in the bridge
+  chip.
+
+  LSDC has two display pipes, each way has a DVO interface which provide
+  RGB888 signals, vertical & horizontal synchronisations, data enable and
+  the pixel clock. LSDC has two CRTC, each CRTC is able to scanout from
+  1920x1080 resolution at 60Hz. Each CRTC has two FB address registers.
+
+  For LS7A1000, there are 4 dedicated GPIOs whose control register is
+  located at the DC register space. They are used to emulate two way i2c,
+  One for DVO0, another for DVO1.
+
+  LS2K1000 and LS2K0500 SoC grab i2c adapter from other module, either
+  general purpose GPIO emulated i2c or hardware i2c in the SoC.
+
+  LSDC's display pipeline have several components as below description,
+
+  The display controller in LS7A1000:
+ ___ _
+|---|   | |
+|  CRTC0 --> | DVO0 > Encoder0 ---> Connector0 ---> | Monitor |
+|  _   _ ---|^ ^|_|
+| | | | |---|| |
+| |_| |_|| i2c0 <+-+
+|---|
+|   DC IN LS7A1000  |
+|  _   _ ---|
+| | | | || i2c1 <+-+
+| |_| |_|---|| | _
+|---|| || |
+|  CRTC1 --> | DVO1 > Encoder1 ---> Connector1 ---> |  Panel  |
+|---|   |_|
+|___|
+
+  Simple usage of LS7A1000 with LS3A4000 CPU:
+
++--++---+
+| DDR4 ||  +---+|
++--+|  | PCIe Root complex |   LS7A1000 |
+   || MC0   |  +--++-+++|
+  +--+  HT 3.0  | || || |
+  | LS3A4000 |<>| +---++---+  +--++--++-+   +--+
+  |   CPU|<>| | GC1000 |  | LSDC |<-->| DDR3 MC |<->| VRAM |
+  +--+  | ++  +-+--+-++-+   +--+
+   || MC1   +---|--|+
++--+|  |
+| DDR4 |  +---+   DVO0  |  |  DVO1   +--+
++--+   VGA <--|ADV7125|<+  +>|TFP410|--> DVI/HDMI
+  +---+  +--+
+
+  The display controller in LS2K1000/LS2K0500:
+ ___ _
+|---|   | |
+|  CRTC0 -->

[ PATCH ] Documentation: fixed doc-build warnings

2022-03-26 Thread kushagra765
>From 9a9918b051d5709b5e14ca8afa29f3ef644b8688 Mon Sep 17 00:00:00 2001
From: Kushagra Verma 
Date: Sat, 26 Mar 2022 16:43:15 +0530
Subject: [PATCH] Documentation: fixed doc-build warnings

   This patch fixes the following (and 2 other) doc-build warnings:
  1. ./include/linux/dcache.h:308: warning: expecting prototype for dget, 
dget_dlock(). Prototype was for dget_dlock() instead

  2. ./include/linux/fscache.h:268: warning: Excess function parameter 
'object' description in 'fscache_use_cookie'

  3 ./include/linux/fscache.h:285: warning: Excess function parameter 
'object' description in 'fscache_unuse_cookie'

  4. ./drivers/gpu/drm/drm_format_helper.c:640: warning: Excess function 
parameter 'src' description in 'drm_fb_xrgb_to_mono_reversed'

Signed-off-by: Kushagra Verma 
---
 drivers/gpu/drm/drm_format_helper.c | 1 -
 drivers/usb/dwc3/core.c | 1 -
 drivers/usb/dwc3/gadget.c   | 3 +--
 include/linux/dcache.h  | 2 +-
 include/linux/fscache.h | 2 --
 5 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index bc0f49773868..d753b34950c9 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -624,7 +624,6 @@ static void drm_fb_gray8_to_mono_reversed_line(u8 *dst, 
const u8 *src, unsigned
  * drm_fb_xrgb_to_mono_reversed - Convert XRGB to reversed monochrome
  * @dst: reversed monochrome destination buffer
  * @dst_pitch: Number of bytes between two consecutive scanlines within dst
- * @src: XRGB source buffer
  * @fb: DRM framebuffer
  * @clip: Clip rectangle area to copy
  *
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f4c09951b517..63e2ccbb7c33 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -343,7 +343,6 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
  * from the default, this will set clock period in DWC3_GUCTL
  * register.
  * @dwc: Pointer to our controller context structure
- * @ref_clk_per: reference clock period in ns
  */
 static void dwc3_ref_clk_period(struct dwc3 *dwc)
 {
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index a0c883f19a41..ee98004434df 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -660,7 +660,6 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, 
bool force,
 /**
  * dwc3_gadget_calc_tx_fifo_size - calculates the txfifo size value
  * @dwc: pointer to the DWC3 context
- * @nfifos: number of fifos to calculate for
  *
  * Calculates the size value based on the equation below:
  *
@@ -693,7 +692,7 @@ static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, 
int mult)
 }
 
 /**
- * dwc3_gadget_clear_tx_fifo_size - Clears txfifo allocation
+ * dwc3_gadget_clear_tx_fifos - Clears txfifo allocation
  * @dwc: pointer to the DWC3 context
  *
  * Iterates through all the endpoint registers and clears the previous txfifo
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index f5bba51480b2..fa35ac489a42 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -297,7 +297,7 @@ extern char *dentry_path(const struct dentry *, char *, 
int);
 /* Allocation counts.. */
 
 /**
- * dget, dget_dlock -  get a reference to a dentry
+ * dget_dlock - get a reference to a dentry
  * @dentry: dentry to get a reference to
  *
  * Given a dentry or %NULL pointer increment the reference count
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index d44ff747a657..9e29494241ea 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -256,7 +256,6 @@ struct fscache_cookie *fscache_acquire_cookie(struct 
fscache_volume *volume,
 
 /**
  * fscache_use_cookie - Request usage of cookie attached to an object
- * @object: Object description
  * @will_modify: If cache is expected to be modified locally
  *
  * Request usage of the cookie attached to an object.  The caller should tell
@@ -272,7 +271,6 @@ static inline void fscache_use_cookie(struct fscache_cookie 
*cookie,
 
 /**
  * fscache_unuse_cookie - Cease usage of cookie attached to an object
- * @object: Object description
  * @aux_data: Updated auxiliary data (or NULL)
  * @object_size: Revised size of the object (or NULL)
  *
-- 
2.25.1




[ PATCH ] Documentation: fixed some doc-build warnings

2022-03-26 Thread kushagra765



Re: [PATCH] drm/bridge: anx7625: add missing destroy_workqueue() in anx7625_i2c_probe()

2022-03-26 Thread Hsin-Yi Wang
On Sat, Mar 26, 2022 at 3:24 PM Yang Yingliang  wrote:
>
> Add the missing destroy_workqueue() before return from
> anx7625_i2c_probe() in the error handling case.
>
> Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux 
> channel")
> Signed-off-by: Yang Yingliang 
> ---
Reviewed-by: Hsin-Yi Wang 

>  drivers/gpu/drm/bridge/analogix/anx7625.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
> b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 31ecf5626f1d..1895e3448c02 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -2654,7 +2654,7 @@ static int anx7625_i2c_probe(struct i2c_client *client,
> if (ret) {
> if (ret != -EPROBE_DEFER)
> DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
> -   return ret;
> +   goto free_wq;
> }
>
> if (anx7625_register_i2c_dummy_clients(platform, client) != 0) {
> @@ -2669,7 +2669,7 @@ static int anx7625_i2c_probe(struct i2c_client *client,
> pm_suspend_ignore_children(dev, true);
> ret = devm_add_action_or_reset(dev, anx7625_runtime_disable, dev);
> if (ret)
> -   return ret;
> +   goto free_wq;
>
> if (!platform->pdata.low_power_mode) {
> anx7625_disable_pd_protocol(platform);
> --
> 2.25.1
>


[PATCH 0/2] remove DC_FP_* wrappers in dml files

2022-03-26 Thread Melissa Wen
>From FPU documentation, developers must not use DC_FP_START/END in dml
files, but invoke it when calling FPU-associated functions (isolated in
dml folder). Therefore, the first patch renames dcn10_validate_bandwidth
in dml/calcs to dcn_ for generalization, declares dcn10_validate_bandwidth
in dcn10 - that calls dcn_validate_bandwidth and wraps with DC_FP_*
accordingly. The second patch removes invocations of DC_FP_* from dml
files and properly wraps FPU functions in dc code outside dml folder.

Melissa Wen (2):
  drm/amd/display: detach fpu operations from dcn10_validate_bandwidth
in calcs
  drm/amd/display: remove DC_FP_* wrapper from dml folder

 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 10 --
 .../drm/amd/display/dc/dcn10/dcn10_resource.c | 16 
 .../drm/amd/display/dc/dml/calcs/dcn_calcs.c  | 19 +--
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c  |  2 --
 .../gpu/drm/amd/display/dc/inc/dcn_calcs.h|  2 +-
 5 files changed, 26 insertions(+), 23 deletions(-)

-- 
2.35.1



[PATCH 1/2] drm/amd/display: detach fpu operations from dcn10_validate_bandwidth in calcs

2022-03-26 Thread Melissa Wen
dcn10_validate_bandwidth is only used on dcn10 files, but is declared in
dcn_calcs files. Rename dcn10_* to dcn_* in calcs, remove DC_FP_* wrapper
inside DML folder and create an specific dcn10_validate_bandwidth in
dcn10_resources that calls dcn_validate_bandwidth and properly wraps that
FPU function with DC_FP_* macro.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c  | 14 ++
 .../gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c   |  5 +
 drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h |  2 +-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 4048908dd265..1587a060b55a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1141,6 +1141,20 @@ static void dcn10_destroy_resource_pool(struct 
resource_pool **pool)
*pool = NULL;
 }
 
+static bool dcn10_validate_bandwidth(
+   struct dc *dc,
+   struct dc_state *context,
+   bool fast_validate)
+{
+   bool voltage_supported;
+
+   DC_FP_START();
+   voltage_supported = dcn_validate_bandwidth(dc, context, fast_validate);
+   DC_FP_END();
+
+   return voltage_supported;
+}
+
 static enum dc_status dcn10_validate_plane(const struct dc_plane_state 
*plane_state, struct dc_caps *caps)
 {
if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c 
b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
index e447c74be713..c25023f7d604 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
@@ -764,7 +764,7 @@ static unsigned int 
get_highest_allowed_voltage_level(uint32_t chip_family,
return 4;
 }
 
-bool dcn10_validate_bandwidth(
+bool dcn_validate_bandwidth(
struct dc *dc,
struct dc_state *context,
bool fast_validate)
@@ -790,7 +790,6 @@ bool dcn10_validate_bandwidth(
dcn_bw_sync_calcs_and_dml(dc);
 
memset(v, 0, sizeof(*v));
-   DC_FP_START();
 
v->sr_exit_time = dc->dcn_soc->sr_exit_time;
v->sr_enter_plus_exit_time = dc->dcn_soc->sr_enter_plus_exit_time;
@@ -1323,8 +1322,6 @@ bool dcn10_validate_bandwidth(
bw_limit = dc->dcn_soc->percent_disp_bw_limit * 
v->fabric_and_dram_bandwidth_vmax0p9;
bw_limit_pass = (v->total_data_read_bandwidth / 1000.0) < bw_limit;
 
-   DC_FP_END();
-
PERFORMANCE_TRACE_END();
BW_VAL_TRACE_FINISH();
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h 
b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
index 337c0161e72d..806f3041db14 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h
@@ -619,7 +619,7 @@ struct dcn_ip_params {
 };
 extern const struct dcn_ip_params dcn10_ip_defaults;
 
-bool dcn10_validate_bandwidth(
+bool dcn_validate_bandwidth(
struct dc *dc,
struct dc_state *context,
bool fast_validate);
-- 
2.35.1



[PATCH 2/2] drm/amd/display: remove DC_FP_* wrapper from dml folder

2022-03-26 Thread Melissa Wen
FPU documentation states that developers must not use DC_FP_START/END
inside dml files, but use this macro to wrap calls to FPU functions in
dc folder (outside dml folder). Therefore, this patch removes DC_FP_*
wrappers from dml folder and wraps calls for these FPU operations
outside dml, as required.

Signed-off-by: Melissa Wen 
---
 .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c  | 10 --
 .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c  |  2 ++
 .../gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c   | 14 --
 .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c   |  2 --
 4 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index c3e141c19a77..6b4d9917933b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -2979,8 +2979,11 @@ void dcn10_prepare_bandwidth(
true);
dcn10_stereo_hw_frame_pack_wa(dc, context);
 
-   if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
+   if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
+   DC_FP_START();
dcn_bw_notify_pplib_of_wm_ranges(dc);
+   DC_FP_END();
+   }
 
if (dc->debug.sanity_checks)
hws->funcs.verify_allow_pstate_change_high(dc);
@@ -3013,8 +3016,11 @@ void dcn10_optimize_bandwidth(
 
dcn10_stereo_hw_frame_pack_wa(dc, context);
 
-   if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
+   if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
+   DC_FP_START();
dcn_bw_notify_pplib_of_wm_ranges(dc);
+   DC_FP_END();
+   }
 
if (dc->debug.sanity_checks)
hws->funcs.verify_allow_pstate_change_high(dc);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 1587a060b55a..bca049b2f867 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1506,6 +1506,7 @@ static bool dcn10_resource_construct(
&& pool->base.pp_smu->rv_funcs.set_pme_wa_enable != 
NULL)
dc->debug.az_endpoint_mute_only = false;
 
+   DC_FP_START();
if (!dc->debug.disable_pplib_clock_request)
dcn_bw_update_from_pplib(dc);
dcn_bw_sync_calcs_and_dml(dc);
@@ -1513,6 +1514,7 @@ static bool dcn10_resource_construct(
dc->res_pool = &pool->base;
dcn_bw_notify_pplib_of_wm_ranges(dc);
}
+   DC_FP_END();
 
{
struct irq_service_init_data init_data;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c 
b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
index c25023f7d604..db3b16b77034 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
@@ -639,7 +639,6 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
 {
bool updated = false;
 
-   DC_FP_START();
if ((int)(dc->dcn_soc->sr_exit_time * 1000) != dc->debug.sr_exit_time_ns
&& dc->debug.sr_exit_time_ns) {
updated = true;
@@ -675,7 +674,6 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
dc->dcn_soc->dram_clock_change_latency =
dc->debug.dram_clock_change_latency_ns / 1000.0;
}
-   DC_FP_END();
 
return updated;
 }
@@ -1492,8 +1490,6 @@ void dcn_bw_update_from_pplib(struct dc *dc)
res = dm_pp_get_clock_levels_by_type_with_voltage(
ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks);
 
-   DC_FP_START();
-
if (res)
res = verify_clock_values(&fclks);
 
@@ -1523,13 +1519,9 @@ void dcn_bw_update_from_pplib(struct dc *dc)
} else
BREAK_TO_DEBUGGER();
 
-   DC_FP_END();
-
res = dm_pp_get_clock_levels_by_type_with_voltage(
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks);
 
-   DC_FP_START();
-
if (res)
res = verify_clock_values(&dcfclks);
 
@@ -1540,8 +1532,6 @@ void dcn_bw_update_from_pplib(struct dc *dc)
dc->dcn_soc->dcfclkv_max0p9 = dcfclks.data[dcfclks.num_levels - 
1].clocks_in_khz / 1000.0;
} else
BREAK_TO_DEBUGGER();
-
-   DC_FP_END();
 }
 
 void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
@@ -1556,11 +1546,9 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
if (!pp || !pp->set_wm_ranges)
return;
 
-   DC_FP_START();
min_fclk_khz = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 * 
100 / 32;
min_dcfclk_khz = dc->dcn_soc->dcfclkv_min0p65 * 1000;
socclk_khz = dc->dcn_soc->socclk 

[PATCH] drm/amd/display: DCN3.1: don't mark as kernel-doc

2022-03-26 Thread Randy Dunlap
There is no need for this one static function to be marked as
kernel-doc notation.

Avoid this doc build warning:

warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer 
Documentation/doc-guide/kernel-doc.rst
 * Enable CRTC

Fixes: 110d3968fe95 ("drm/amd/display: Add DCN3.1 OPTC")
Signed-off-by: Randy Dunlap 
Cc: Alex Deucher 
Cc: Nicholas Kazlauskas 
Cc: amd-...@lists.freedesktop.org
Cc: Christian König 
Cc: "Pan, Xinhui" 
Cc: Harry Wentland 
Cc: Leo Li 
Cc: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- linux-next-20220325.orig/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
+++ linux-next-20220325/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
@@ -91,8 +91,7 @@ static void optc31_set_odm_combine(struc
optc1->opp_count = opp_cnt;
 }
 
-/**
- * Enable CRTC
+/*
  * Enable CRTC - call ASIC Control Object to enable Timing generator.
  */
 static bool optc31_enable_crtc(struct timing_generator *optc)


[PATCH] drm: sti: don't use kernel-doc markers

2022-03-26 Thread Randy Dunlap
Don't mark static functions as kernel-doc.

Prevents multiple kernel-doc build warnings:

drivers/gpu/drm/sti/sti_hdmi.c:187: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * HDMI interrupt handler threaded
drivers/gpu/drm/sti/sti_hdmi.c:219: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * HDMI interrupt handler
drivers/gpu/drm/sti/sti_hdmi.c:241: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Set hdmi active area depending on the drm display mode selected
drivers/gpu/drm/sti/sti_hdmi.c:262: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Overall hdmi configuration
drivers/gpu/drm/sti/sti_hdmi.c:340: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Helper to concatenate infoframe in 32 bits word
drivers/gpu/drm/sti/sti_hdmi.c:357: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Helper to write info frame
drivers/gpu/drm/sti/sti_hdmi.c:427: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Prepare and configure the AVI infoframe
drivers/gpu/drm/sti/sti_hdmi.c:470: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Prepare and configure the AUDIO infoframe
drivers/gpu/drm/sti/sti_hdmi.c:555: warning: This comment starts with '/**', 
but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Software reset of the hdmi subsystem

Fixes: 5402626c83a2 ("drm: sti: add HDMI driver")
Signed-off-by: Randy Dunlap 
Cc: Aditya Srivastava 
Cc: Benjamin Gaignard 
Cc: Alain Volmat 
Cc: David Airlie 
Cc: Daniel Vetter 
---
 drivers/gpu/drm/sti/sti_hdmi.c |   20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

--- linux-next-20220325.orig/drivers/gpu/drm/sti/sti_hdmi.c
+++ linux-next-20220325/drivers/gpu/drm/sti/sti_hdmi.c
@@ -183,7 +183,7 @@ void hdmi_write(struct sti_hdmi *hdmi, u
writel(val, hdmi->regs + offset);
 }
 
-/**
+/*
  * HDMI interrupt handler threaded
  *
  * @irq: irq number
@@ -215,7 +215,7 @@ static irqreturn_t hdmi_irq_thread(int i
return IRQ_HANDLED;
 }
 
-/**
+/*
  * HDMI interrupt handler
  *
  * @irq: irq number
@@ -237,7 +237,7 @@ static irqreturn_t hdmi_irq(int irq, voi
return IRQ_WAKE_THREAD;
 }
 
-/**
+/*
  * Set hdmi active area depending on the drm display mode selected
  *
  * @hdmi: pointer on the hdmi internal structure
@@ -258,7 +258,7 @@ static void hdmi_active_area(struct sti_
hdmi_write(hdmi, ymax, HDMI_ACTIVE_VID_YMAX);
 }
 
-/**
+/*
  * Overall hdmi configuration
  *
  * @hdmi: pointer on the hdmi internal structure
@@ -336,7 +336,7 @@ static void hdmi_infoframe_reset(struct
hdmi_write(hdmi, 0x0, pack_offset + i);
 }
 
-/**
+/*
  * Helper to concatenate infoframe in 32 bits word
  *
  * @ptr: pointer on the hdmi internal structure
@@ -353,7 +353,7 @@ static inline unsigned int hdmi_infofram
return value;
 }
 
-/**
+/*
  * Helper to write info frame
  *
  * @hdmi: pointer on the hdmi internal structure
@@ -423,7 +423,7 @@ static void hdmi_infoframe_write_infopac
hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
 }
 
-/**
+/*
  * Prepare and configure the AVI infoframe
  *
  * AVI infoframe are transmitted at least once per two video field and
@@ -466,7 +466,7 @@ static int hdmi_avi_infoframe_config(str
return 0;
 }
 
-/**
+/*
  * Prepare and configure the AUDIO infoframe
  *
  * AUDIO infoframe are transmitted once per frame and
@@ -551,7 +551,7 @@ static int hdmi_vendor_infoframe_config(
 
 #define HDMI_TIMEOUT_SWRESET  100   /*milliseconds */
 
-/**
+/*
  * Software reset of the hdmi subsystem
  *
  * @hdmi: pointer on the hdmi internal structure
@@ -785,7 +785,7 @@ static void sti_hdmi_disable(struct drm_
cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
 }
 
-/**
+/*
  * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
  * clocks. None-coherent clocks means that audio and TMDS clocks have not the
  * same source (drifts between clocks). In this case assumption is that CTS is


[PATCH] virtio-gpu: fix a missing check to avoid NULL dereference

2022-03-26 Thread Xiaomeng Tong
'cache_ent' could be set NULL inside virtio_gpu_cmd_get_capset()
and it will lead to a NULL dereference by a lately use of it
(i.e., ptr = cache_ent->caps_cache). Fix it with a NULL check.

Fixes: 62fb7a5e10962 ("virtio-gpu: add 3d/virgl support")
Signed-off-by: Xiaomeng Tong 
---
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index c708bab555c6..b0f1c4d8fd23 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -579,8 +579,10 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device 
*dev,
spin_unlock(&vgdev->display_info_lock);
 
/* not in cache - need to talk to hw */
-   virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
+   ret = virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
  &cache_ent);
+   if (ret)
+   return ret;
virtio_gpu_notify(vgdev);
 
 copy_exit:

base-commit: f443e374ae131c168a065ea1748feac6b2e76613
-- 
2.17.1



[PATCH] gma500: fix an incorrect NULL check on list iterator

2022-03-26 Thread Xiaomeng Tong
The bug is here:
return crtc;

The list iterator value 'crtc' will *always* be set and non-NULL by
list_for_each_entry(), so it is incorrect to assume that the iterator
value will be NULL if the list is empty or no element is found.

To fix the bug, return 'crtc' when found, otherwise return NULL.

Cc: sta...@vger.kernel.org
fixes: 89c78134cc54d ("gma500: Add Poulsbo support")
Signed-off-by: Xiaomeng Tong 
---
 drivers/gpu/drm/gma500/psb_intel_display.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c 
b/drivers/gpu/drm/gma500/psb_intel_display.c
index d5f95212934e..42d1a733e124 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -535,14 +535,15 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
 
 struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
 {
-   struct drm_crtc *crtc = NULL;
+   struct drm_crtc *crtc;
 
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
+
if (gma_crtc->pipe == pipe)
-   break;
+   return crtc;
}
-   return crtc;
+   return NULL;
 }
 
 int gma_connector_clones(struct drm_device *dev, int type_mask)
-- 
2.17.1



[PATCH] device: fix missing check on list iterator

2022-03-26 Thread Xiaomeng Tong
The bug is here:
lo = pstate->base.domain[domain->name];

The list iterator 'pstate' will point to a bogus position containing
HEAD if the list is empty or no element is found. This case should
be checked before any use of the iterator, otherwise it will lead
to a invalid memory access.

To fix this bug, add an check. Use a new value 'iter' as the list
iterator, while use the old value 'pstate' as a dedicated variable
to point to the found element.

Cc: sta...@vger.kernel.org
Fixes: 9838366c1597d ("drm/nouveau/device: initial control object class, with 
pstate control methods")
Signed-off-by: Xiaomeng Tong 
---
 drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
index ce774579c89d..6b768635e8ba 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -72,7 +72,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void 
*data, u32 size)
} *args = data;
struct nvkm_clk *clk = ctrl->device->clk;
const struct nvkm_domain *domain;
-   struct nvkm_pstate *pstate;
+   struct nvkm_pstate *pstate = NULL, *iter;
struct nvkm_cstate *cstate;
int i = 0, j = -1;
u32 lo, hi;
@@ -103,11 +103,16 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, 
void *data, u32 size)
return -EINVAL;
 
if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) {
-   list_for_each_entry(pstate, &clk->states, head) {
-   if (i++ == args->v0.state)
+   list_for_each_entry(iter, &clk->states, head) {
+   if (i++ == args->v0.state) {
+   pstate = iter;
break;
+   }
}
 
+   if (!pstate)
+   return -EINVAL;
+
lo = pstate->base.domain[domain->name];
hi = lo;
list_for_each_entry(cstate, &pstate->list, head) {
-- 
2.17.1



[PATCH] omapdrm: fix missing check on list iterator

2022-03-26 Thread Xiaomeng Tong
The bug is here:
bus_flags = connector->display_info.bus_flags;

The list iterator 'connector-' will point to a bogus position containing
HEAD if the list is empty or no element is found. This case must
be checked before any use of the iterator, otherwise it will lead
to a invalid memory access.

To fix this bug, add an check. Use a new value 'iter' as the list
iterator, while use the old value 'connector' as a dedicated variable
to point to the found element.

Cc: sta...@vger.kernel.org
Fixes: ("drm/omap: Add support for drm_panel")
Signed-off-by: Xiaomeng Tong 
---
 drivers/gpu/drm/omapdrm/omap_encoder.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 4dd05bc732da..d648ab4223b1 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -76,14 +76,16 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
struct omap_dss_device *output = omap_encoder->output;
struct drm_device *dev = encoder->dev;
-   struct drm_connector *connector;
+   struct drm_connector *connector = NULL, *iter;
struct drm_bridge *bridge;
struct videomode vm = { 0 };
u32 bus_flags;
 
-   list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-   if (connector->encoder == encoder)
+   list_for_each_entry(iter, &dev->mode_config.connector_list, head) {
+   if (iter->encoder == encoder) {
+   connector = iter;
break;
+   }
}
 
drm_display_mode_to_videomode(adjusted_mode, &vm);
@@ -106,8 +108,10 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
omap_encoder_update_videomode_flags(&vm, bus_flags);
}
 
-   bus_flags = connector->display_info.bus_flags;
-   omap_encoder_update_videomode_flags(&vm, bus_flags);
+   if (connector) {
+   bus_flags = connector->display_info.bus_flags;
+   omap_encoder_update_videomode_flags(&vm, bus_flags);
+   }
 
/* Set timings for all devices in the display pipeline. */
dss_mgr_set_timings(output, &vm);
-- 
2.17.1



Re: [PATCH] device: fix missing check on list iterator

2022-03-26 Thread Guenter Roeck

On 3/26/22 22:31, Xiaomeng Tong wrote:

The bug is here:
lo = pstate->base.domain[domain->name];

The list iterator 'pstate' will point to a bogus position containing
HEAD if the list is empty or no element is found. This case should
be checked before any use of the iterator, otherwise it will lead
to a invalid memory access.

To fix this bug, add an check. Use a new value 'iter' as the list
iterator, while use the old value 'pstate' as a dedicated variable
to point to the found element.

Cc: sta...@vger.kernel.org
Fixes: 9838366c1597d ("drm/nouveau/device: initial control object class, with pstate 
control methods")
Signed-off-by: Xiaomeng Tong 
---
  drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c | 11 ---
  1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
index ce774579c89d..6b768635e8ba 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -72,7 +72,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void 
*data, u32 size)
} *args = data;
struct nvkm_clk *clk = ctrl->device->clk;
const struct nvkm_domain *domain;
-   struct nvkm_pstate *pstate;
+   struct nvkm_pstate *pstate = NULL, *iter;
struct nvkm_cstate *cstate;
int i = 0, j = -1;
u32 lo, hi;
@@ -103,11 +103,16 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, 
void *data, u32 size)
return -EINVAL;
  
  	if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) {

-   list_for_each_entry(pstate, &clk->states, head) {
-   if (i++ == args->v0.state)
+   list_for_each_entry(iter, &clk->states, head) {
+   if (i++ == args->v0.state) {
+   pstate = iter;


Is iter and the assignment really necessary ? Unless I am missing something,
list_for_each_entry() always assigns pos (pstate/iter), even if the list is
empty. If nothing is found, pstate would be NULL at the end, so


break;
+   }
}
  
+		if (!pstate)

+   return -EINVAL;
+

... just this check should do to cover both the "not found" and "list empty"
cases.

Thanks,
Guenter


lo = pstate->base.domain[domain->name];
hi = lo;
list_for_each_entry(cstate, &pstate->list, head) {




[PATCH] stm: ltdc: fix two incorrect NULL checks on list iterator

2022-03-26 Thread Xiaomeng Tong
The two bugs are here:
if (encoder) {
if (bridge && bridge->timings)

The list iterator value 'encoder/bridge' will *always* be set and
non-NULL by drm_for_each_encoder()/list_for_each_entry(), so it is
incorrect to assume that the iterator value will be NULL if the
list is empty or no element is found.

To fix the bug, use a new variable '*_iter' as the list iterator,
while use the old variable 'encoder/bridge' as a dedicated pointer
to point to the found element.

Cc: sta...@vger.kernel.org
Fixes: 99e360442f223 ("drm/stm: Fix bus_flags handling")
Signed-off-by: Xiaomeng Tong 
---
 drivers/gpu/drm/stm/ltdc.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index dbdee954692a..d6124aa873e5 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -528,8 +528,8 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct drm_device *ddev = crtc->dev;
struct drm_connector_list_iter iter;
struct drm_connector *connector = NULL;
-   struct drm_encoder *encoder = NULL;
-   struct drm_bridge *bridge = NULL;
+   struct drm_encoder *encoder = NULL, *en_iter;
+   struct drm_bridge *bridge = NULL, *br_iter;
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
u32 total_width, total_height;
@@ -538,15 +538,19 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
int ret;
 
/* get encoder from crtc */
-   drm_for_each_encoder(encoder, ddev)
-   if (encoder->crtc == crtc)
+   drm_for_each_encoder(en_iter, ddev)
+   if (en_iter->crtc == crtc) {
+   encoder = en_iter;
break;
+   }
 
if (encoder) {
/* get bridge from encoder */
-   list_for_each_entry(bridge, &encoder->bridge_chain, chain_node)
-   if (bridge->encoder == encoder)
+   list_for_each_entry(br_iter, &encoder->bridge_chain, chain_node)
+   if (br_iter->encoder == encoder) {
+   bridge = br_iter;
break;
+   }
 
/* Get the connector from encoder */
drm_connector_list_iter_begin(ddev, &iter);
-- 
2.17.1



[PATCH] tilcdc: tilcdc_external: fix an incorrect NULL check on list iterator

2022-03-26 Thread Xiaomeng Tong
The bug is here:
if (!encoder) {

The list iterator value 'encoder' will *always* be set and non-NULL
by list_for_each_entry(), so it is incorrect to assume that the
iterator value will be NULL if the list is empty or no element
is found.

To fix the bug, use a new variable 'iter' as the list iterator,
while use the original variable 'encoder' as a dedicated pointer
to point to the found element.

Cc: sta...@vger.kernel.org
Fixes: ec9eab097a500 ("drm/tilcdc: Add drm bridge support for attaching drm 
bridge drivers")
Signed-off-by: Xiaomeng Tong 
---
 drivers/gpu/drm/tilcdc/tilcdc_external.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c 
b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 7594cf6e186e..3b86d002ef62 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -60,11 +60,13 @@ struct drm_connector *tilcdc_encoder_find_connector(struct 
drm_device *ddev,
 int tilcdc_add_component_encoder(struct drm_device *ddev)
 {
struct tilcdc_drm_private *priv = ddev->dev_private;
-   struct drm_encoder *encoder;
+   struct drm_encoder *encoder = NULL, *iter;
 
-   list_for_each_entry(encoder, &ddev->mode_config.encoder_list, head)
-   if (encoder->possible_crtcs & (1 << priv->crtc->index))
+   list_for_each_entry(iter, &ddev->mode_config.encoder_list, head)
+   if (iter->possible_crtcs & (1 << priv->crtc->index)) {
+   encoder = iter;
break;
+   }
 
if (!encoder) {
dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__);
-- 
2.17.1