Skip to contentSkip to conversation

Add support for CH1115 Controller

PATCH Superseded Nicolás Antinori 3 participants 8 messages Aug 7 – Aug 13

Subsystems (3)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

cover Add support for CH1115 Controller

This series add support for the CH1115 Controller [1]. It is a monochrome dot matrix OLED controller that supports several interfaces such as SPI and I2C.

This driver only supports the I2C interface, but all common parts could easily be put into a common file to be used with other interfaces. I only have I2C to test with.

This is the first driver I write. The work is based on the driver located at:
- drivers/gpu/drm/sitronix/st7571-i2c.c
- drivers/gpu/drm/sitronix/st7571.c

Tested with Raspberry Pi 3b+.

Thanks,
Nicolás

[1] https://datasheet4u.com/download/1576606/CH1115.html

Nicolás Antinori (3):
dt-bindings: display: add Chipwealth CH1115 OLED Controller drm/ch1115: add support for Chipwealth CH1115 OLED controller
MAINTAINERS: add entry for Chipwealth CH1115 OLED Controller

 .../bindings/display/chipwealth,ch1115.yaml   |  73 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |   6 +
 drivers/gpu/drm/Kconfig                       |   1 +
 drivers/gpu/drm/Makefile                      |   1 +
 drivers/gpu/drm/chipwealth/Kconfig            |  16 +
 drivers/gpu/drm/chipwealth/Makefile           |   3 +
 drivers/gpu/drm/chipwealth/ch1115.c           | 828 ++++++++++++++++++
 8 files changed, 930 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml
 create mode 100644 drivers/gpu/drm/chipwealth/Kconfig
 create mode 100644 drivers/gpu/drm/chipwealth/Makefile
 create mode 100644 drivers/gpu/drm/chipwealth/ch1115.c

--
2.47.3

#1 lore raw

PATCH 1/3 dt-bindings: display: add Chipwealth CH1115 OLED controller

Chipwealth CH1115 is a controller for monochrome dot matrix OLED panels.

---
 .../bindings/display/chipwealth,ch1115.yaml   | 73 +++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 2 files changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +73 -0
new file mode 100644
index 000000000000..29d55da85d21
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/chipwealth,ch1115.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Chipwealth CH1115 Display Controller
+
+maintainers:
+  - Nicolás Antinori <[email protected]>
+
+description:
+  Chipwealth CH1115 is a controller for monochrome dot matrix OLED
+  panels.
+
+  https://datasheet4u.com/download/1576606/CH1115.html
+
+allOf:
+  - $ref: panel/panel-common.yaml#
+
+properties:
+  compatible:
+    const: chipwealth,ch1115
+
+  reg:
+    maxItems: 1
+
+  invert:
+    type: boolean
+    description:
+      Display pixels are inverted, i.e. 0 is white and 1 is black.
+
+  width-mm: true
+  height-mm: true
+  panel-timing: true
+
+required:
+  - compatible
+  - reg
+  - width-mm
+  - height-mm
+  - panel-timing
+  - first-page
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      status = "okay";
+
+      display@3c {
+        compatible = "chipwealth,ch1115";
+        reg = <0x3c>;
+        width-mm = <12>;
+        height-mm = <8>;
+        contrast = <127>;
+        first-page = <1>;
+        panel-timing {
+          clock-frequency = <0>;
+          hactive = <88>;
+          vactive = <48>;
+          hfront-porch = <0>;
+          hback-porch = <0>;
+          hsync-len = <0>;
+          vsync-len = <0>;
+          vfront-porch = <0>;
+          vback-porch = <0>;
+        };
+      };
+    };
Documentation/devicetree/bindings/vendor-prefixes.yaml +2 -0
index d2ba67c4c8e0..1d158ac83ce9 100644
@@ -325,6 +325,8 @@ patternProperties:
     description: ChipOne
   "^chipspark,.*":
     description: ChipSPARK
+  "^chipwealth,.*":
+    description: Chip Wealth Technology, Ltd.
   "^chongzhou,.*":
     description: Shenzhen Chongzhou Electronic Technology Co., Ltd
   "^chrontel,.*":

--
2.47.3

#2 lore raw

Re: [PATCH 1/3] dt-bindings: display: add Chipwealth CH1115 OLED controller

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The device tree schema is structurally unsatisfiable and introduces hardware-specific properties…

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The device tree schema is structurally unsatisfiable and introduces hardware-specific properties without vendor prefixes. first-page is mandated by the required list but is not defined in the properties block. Because additionalProperties: false is used, any device tree node including first-page is rejected, while any node omitting it fails the required check. Additionally, contrast is used in the examples but missing from properties. Finally, invert, first-page, and contrast are custom properties that must include a vendor prefix (e.g., chipwealth,invert) to avoid polluting the global namespace. --

--- Patch [1]: [PATCH 1/3] dt-bindings: display: add Chipwealth CH1115 OLED controller --- commit 77e215ca91e888007e7e74fb225f1cb55be392a1
Author: Nicolás Antinori <[email protected]>

dt-bindings: display: add Chipwealth CH1115 OLED controller

This commit adds the device tree binding for the Chipwealth CH1115 monochrome dot matrix OLED panel controller.

Quoted 5 lines
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +0 -0
new file mode 100644
index 0000000000000..29d55da85d219

[ ... ]

Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml line 31

Quoted 11 lines
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +11 -0
+properties:
+  compatible:
+    const: chipwealth,ch1115
+
+  reg:
+    maxItems: 1
+
+  invert:
+    type: boolean
+    description:
+      Display pixels are inverted, i.e. 0 is white and 1 is black.

[Severity: Medium]
Should this property have a vendor prefix (e.g., chipwealth,invert)? Custom hardware-specific properties typically require vendor prefixes to avoid polluting the global namespace.

Quoted 4 lines
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +4 -0
+
+  width-mm: true
+  height-mm: true
+  panel-timing: true

Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml line 45

Quoted 10 lines
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +10 -0
+
+required:
+  - compatible
+  - reg
+  - width-mm
+  - height-mm
+  - panel-timing
+  - first-page
+
+additionalProperties: false

[Severity: Medium]
Is first-page missing from the properties block? Because it is explicitly mandated by the required list but not defined in properties,
additionalProperties: false will forbid it, making the schema unsatisfiable for any device tree node.

Quoted 5 lines
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +5 -0
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;

Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml line 60

Quoted 10 lines
Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml new file +10 -0
+      #size-cells = <0>;
+      status = "okay";
+
+      display@3c {
+        compatible = "chipwealth,ch1115";
+        reg = <0x3c>;
+        width-mm = <12>;
+        height-mm = <8>;
+        contrast = <127>;
+        first-page = <1>;

[Severity: Medium]
Are contrast and first-page intended to be defined in this schema? They are used here in the example but missing from the properties block, which will cause dt_binding_check to fail. As with invert, do these custom properties need vendor prefixes?

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#3 lore raw

Re: [PATCH 1/3] dt-bindings: display: add Chipwealth CH1115 OLED controller

In reply to Nicolás Antinori
Quoted 9 lines · Nicolás Antinori

Chipwealth CH1115 is a controller for monochrome dot matrix OLED panels.

---
 .../bindings/display/chipwealth,ch1115.yaml   | 73 +++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 2 files changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/display/chipwealth,ch1115.example.dtb: display@3c (chipwealth,ch1115): 'contrast', 'first-page' do not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/display/chipwealth,ch1115.yaml
Documentation/devicetree/bindings/display/chipwealth,ch1115.example.dtb: display@3c (chipwealth,ch1115): contrast: b'\x00\x00\x00\x7f' is not of type 'object', 'integer', 'array', 'boolean', 'null'
from schema $id: http://devicetree.org/schemas/dt-core.yaml
Documentation/devicetree/bindings/display/chipwealth,ch1115.example.dtb: display@3c (chipwealth,ch1115): first-page: b'\x00\x00\x00\x01' is not of type 'object', 'integer', 'array', 'boolean', 'null'
from schema $id: http://devicetree.org/schemas/dt-core.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.kernel.org/project/devicetree/patch/cf9b02d618db4eca88e2d32b4bf779011fcd550d.1786110720.git.nico.antinori.7@gmail.com

The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema.

#4 lore raw

Re: [PATCH 1/3] dt-bindings: display: add Chipwealth CH1115 OLED controller

Hello Rob,

Quoted 24 lines · Rob Herring (Arm)
Quoted 9 lines · Nicolás Antinori

Chipwealth CH1115 is a controller for monochrome dot matrix OLED panels.

---
 .../bindings/display/chipwealth,ch1115.yaml   | 73 +++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 2 files changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/display/chipwealth,ch1115.example.dtb: display@3c (chipwealth,ch1115): 'contrast', 'first-page' do not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/display/chipwealth,ch1115.yaml
Documentation/devicetree/bindings/display/chipwealth,ch1115.example.dtb: display@3c (chipwealth,ch1115): contrast: b'\x00\x00\x00\x7f' is not of type 'object', 'integer', 'array', 'boolean', 'null'
from schema $id: http://devicetree.org/schemas/dt-core.yaml
Documentation/devicetree/bindings/display/chipwealth,ch1115.example.dtb: display@3c (chipwealth,ch1115): first-page: b'\x00\x00\x00\x01' is not of type 'object', 'integer', 'array', 'boolean', 'null'
from schema $id: http://devicetree.org/schemas/dt-core.yaml

Quoted 6 lines

doc reference errors (make refcheckdocs):

See https://patchwork.kernel.org/project/devicetree/patch/cf9b02d618db4eca88e2d32b4bf779011fcd550d.1786110720.git.nico.antinori.7@gmail.com

The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch.

The patch is based in 7.2-rc6, I am going to rebase it to rc1 in v2 (or wait until rc1 of 7.3, depending on how much it takes me to solve some observations found by sashiko).

Thank you for the clarifications!

#5 lore raw

PATCH 2/3 drm/ch1115: add support for Chipwealth CH1115 OLED controller

In reply to Nicolás Antinori

Chipwealth CH1115 is a controller for monochrome dot matrix OLED panels.

Add DRM support for this chip using i2c bus.

---
 drivers/gpu/drm/Kconfig             |   1 +
 drivers/gpu/drm/Makefile            |   1 +
 drivers/gpu/drm/chipwealth/Kconfig  |  16 +
 drivers/gpu/drm/chipwealth/Makefile |   3 +
 drivers/gpu/drm/chipwealth/ch1115.c | 828 ++++++++++++++++++++++++++++
 5 files changed, 849 insertions(+)
 create mode 100644 drivers/gpu/drm/chipwealth/Kconfig
 create mode 100644 drivers/gpu/drm/chipwealth/Makefile
 create mode 100644 drivers/gpu/drm/chipwealth/ch1115.c
drivers/gpu/drm/Kconfig +1 -0
index ba242a8318a8..7aa3ca225434 100644
@@ -307,6 +307,7 @@ source "drivers/gpu/drm/aspeed/Kconfig"
 source "drivers/gpu/drm/ast/Kconfig"
 source "drivers/gpu/drm/atmel-hlcdc/Kconfig"
 source "drivers/gpu/drm/bridge/Kconfig"
+source "drivers/gpu/drm/chipwealth/Kconfig"
 source "drivers/gpu/drm/etnaviv/Kconfig"
 source "drivers/gpu/drm/exynos/Kconfig"
 source "drivers/gpu/drm/fsl-dcu/Kconfig"
drivers/gpu/drm/Makefile +1 -0
index 58c8729ab5a9..9ef738f549ec 100644
@@ -238,6 +238,7 @@ obj-$(CONFIG_DRM_SPRD) += sprd/
 obj-$(CONFIG_DRM_LOONGSON) += loongson/
 obj-$(CONFIG_DRM_POWERVR) += imagination/
 obj-$(CONFIG_DRM_VERISILICON_DC) += verisilicon/
+obj-y			+= chipwealth/
 
 # Ensure drm headers are self-contained and pass kernel-doc
 hdrtest-files := \
drivers/gpu/drm/chipwealth/Kconfig new file +16 -0
new file mode 100644
index 000000000000..f94af7525c0b
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config DRM_CH1115
+	tristate "DRM support for Ch1115 OLED panels (I2C BUS)"
+	depends on DRM && I2C
+	select DRM_CLIENT_SELECTION
+	select DRM_GEM_SHMEM_HELPER
+	select DRM_KMS_HELPER
+	select REGMAP_I2C
+	select VIDEOMODE_HELPERS
+	help
+	  Chipwealth CH1115 is a controller for monochrome dot matrix OLED
+	  panels.
+
+	  DRM Driver for Ch1115 OLED panels connected via I2C.
+
+	  If M is selected the module will be called ch1115.
drivers/gpu/drm/chipwealth/Makefile new file +3 -0
new file mode 100644
index 000000000000..f9907dc494a1
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_DRM_CH1115)		+= ch1115.o
drivers/gpu/drm/chipwealth/ch1115.c new file +828 -0

828 lines not on this page · raw message

--
2.47.3

#6 lore raw

Re: [PATCH 2/3] drm/ch1115: add support for Chipwealth CH1115 OLED controller

Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider: - [High] Atomic display callbacks perform I2C transfers, violating atomic context requirements. - [High]…

Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:
- [High] Atomic display callbacks perform I2C transfers, violating atomic context requirements.
- [High] Partial updates cause severe display corruption because damaged rectangles are indexed using absolute full-screen coordinates.
- [High] Out-of-bounds kernel heap read in ch1115_clear_screen() when panel width is less than 128.
- [High] Missing drm_atomic_helper_shutdown() in driver remove causes Use-After-Free and memory leaks.
- [High] Heap buffer overflow in ch1115_prepare_buffer() when width is not a multiple of 8.
- [High] Encoder atomic hooks lack drm_dev_enter(), allowing Use-After-Free of devres-managed regmap.
- [Medium] Custom regmap_bus write callback returns a positive value on success, violating the API.
- [Medium] drm_gem_fb_begin_cpu_access() is called in the atomic_update hook and drops the frame on failure.
- [Medium] Logic error truncates bytes_per_row, causing incorrect coordinate transformation for unaligned widths. --

--- Patch [2]: [PATCH 2/3] drm/ch1115: add support for Chipwealth CH1115 OLED controller --- commit d7850b556d1f4d53fa2e329467ad049cae1d80a9
Author: Nicolás Antinori <[email protected]>

drm/ch1115: add support for Chipwealth CH1115 OLED controller

This commit adds DRM support for the Chipwealth CH1115 monochrome dot matrix OLED controller. It uses the I2C bus to interface with the panel and regmap for command writing.

Quoted 5 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
new file mode 100644
index 0000000000000..0ff5d3d9a7cdc

[ ... ]

Quoted 4 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
@@ -151,19 +151,19 @@ static int ch1115_clear_screen(struct ch1115_device *ch1115)
 	int ret;
 	int y = 0;
 	char *row = ch1115->row;

drivers/gpu/drm/chipwealth/ch1115.c static int ch1115_clear_screen(struct ch1115_device *ch1115) · line 163

Quoted 10 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 
 	for (int i = ch1115->x_start_offset; i < ch1115->width; i++)
 		row[i] = 0x00;
 
 	do {
 		ret = ch1115_set_position(ch1115, ch1115->x_start_offset, y);
 		if (ret < 0)
 			return ret;
 
 		ret = ch1115_draw_screen(ch1115, row + ch1115->x_start_offset, ch1115->width);

[Severity: High]
Could this cause an out-of-bounds read if the panel width is less than 128?

The row buffer is allocated exactly ch1115->width bytes during probe. If the panel width is 96, x_start_offset is 32. The code zeroes bytes 32 to 95, then calls ch1115_draw_screen() instructing I2C to read width (96) bytes starting at row + 32.

This would read 32 bytes past the end of the allocated buffer and leak adjacent kernel heap memory to the display.

Quoted 2 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 		if (ret < 0)
 			return ret;

[ ... ]

drivers/gpu/drm/chipwealth/ch1115.c static void ch1115_prepare_buffer(struct ch1115_device *ch1115, · line 246

Quoted 13 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
@@ -235,13 +235,13 @@ static void ch1115_prepare_buffer(struct ch1115_device *ch1115,
 				  const struct iosys_map *vmap,
 				  struct drm_framebuffer *fb,
 				  struct drm_rect *rect,
 				  struct drm_format_conv_state *fmtcnv_state)
 {
 	unsigned int dst_pitch;
 	struct iosys_map dst;
 
 	dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8);
 	iosys_map_set_vaddr(&dst, ch1115->hwbuf);
 
 	drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);

[Severity: High]
Can this write past the end of the hwbuf allocation if the display width is not a multiple of 8?

The hwbuf is allocated in ch1115_probe() as ch1115->pages * ch1115->width. For a width of 125, this allocates 1000 bytes. However, drm_fb_xrgb8888_to_mono() uses a destination pitch rounded up to the nearest byte, which would be 16 bytes per line.

Writing 64 lines at 16 bytes per line totals 1024 bytes, resulting in a 24-byte heap buffer overflow.

Quoted 6 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 }

static inline u8 ch1115_transform_xy(const char *p, int x, int y, u8 bytes_per_row) {

drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	int xrest = x % 8;
 	u8 result = 0;

[ ... ]

drivers/gpu/drm/chipwealth/ch1115.c

Quoted 6 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	x = x / 8;
 	y = (y / 8) * 8;
 
 	for (int i = 0; i < 8; i++) {
 		int row_idx = y + i;
 		u8 byte = p[row_idx * bytes_per_row + x];

[Severity: Medium]
Does the bytes_per_row calculation handle unaligned widths correctly?

In probe, bytes_per_row is calculated using integer division (ch1115->width / 8). If the width is not a multiple of 8, this truncates the value. Since drm_fb_xrgb8888_to_mono() writes to hwbuf using a pitch rounded up to the next byte, using the truncated bytes_per_row here reads from incorrect offsets and distorts the image.

[Severity: High]
Additionally, can partial updates cause display corruption and out-of-bounds reads here?

When a partial update occurs, ch1115_prepare_buffer() copies only the damaged rectangle into the start of hwbuf. But ch1115_transform_xy() uses absolute screen coordinates (x and y) and the full-screen pitch to index into the buffer.

This mismatch causes the code to read past the converted damage data into uninitialized or stale heap memory.

Quoted 4 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 		u8 bit = (byte >> xrest) & 1;
 
 		result |= (bit << i);
 	}

[ ... ]

Quoted 17 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
@@ -367,16 +367,16 @@ static void ch1115_primary_plane_helper_atomic_update(struct drm_plane *plane,
 						      struct drm_atomic_commit *state)
 {
 	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
 	struct drm_framebuffer *fb = plane_state->fb;
 	struct drm_atomic_helper_damage_iter iter;
 	struct drm_device *dev = plane->dev;
 	struct drm_rect damage;
 	struct ch1115_device *ch1115 = drm_to_ch1115(plane->dev);
 	int ret, idx;
 
 	if (!fb)
 		return;
 
 	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);

drivers/gpu/drm/chipwealth/ch1115.c

Quoted 2 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	if (ret)
 		return;

[Severity: Medium]
Is it safe to return early from this void function if CPU access fails?

If drm_gem_fb_begin_cpu_access() fails (for example, if interrupted by a signal while waiting for fences), returning early drops the frame entirely.

Since this happens in the atomic update callback after the point of no return, userspace is never notified of the error, breaking synchronization between the software state and the display. Should this preparation step be moved to the prepare_fb hook instead?

drivers/gpu/drm/chipwealth/ch1115.c

Quoted 12 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	if (!drm_dev_enter(dev, &idx))
 		goto out_drm_gem_fb_end_cpu_access;
 
 	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
 	drm_atomic_for_each_plane_damage(&iter, &damage) {
 		ch1115_prepare_buffer(ch1115,
 				      &shadow_plane_state->data[0],
 				      fb, &damage,
 				      &shadow_plane_state->fmtcnv_state);
 
 		ch1115_fb_update_rect(fb, &damage);

[Severity: High]
Will this sleep in an atomic context?

The DRM subsystem requires that plane atomic update callbacks execute without sleeping. However, ch1115_fb_update_rect() directly calls ch1115_set_position() and ch1115_draw_screen(), which perform I2C transfers using regmap_bulk_write().

These I2C operations acquire mutexes and sleep, which can lead to kernel splats or deadlocks.

Quoted 1 line

}

[ ... ]

drivers/gpu/drm/chipwealth/ch1115.c static void ch1115_encoder_atomic_enable(struct drm_encoder *encoder, · line 505

Quoted 7 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
@@ -500,16 +500,16 @@ static void ch1115_encoder_atomic_enable(struct drm_encoder *encoder,
 					 struct drm_atomic_commit *state)
 {
 	struct drm_device *drm = encoder->dev;
 	struct ch1115_device *ch1115 = drm_to_ch1115(drm);
 
 	ch1115_oled_init(ch1115);

[Severity: High]
Could this callback cause a sleep in atomic context or a use-after-free?

Like the plane update callback, the encoder atomic enable and disable hooks must not sleep, but this function calls ch1115_oled_init() and ch1115_send_command_list(), which perform blocking I2C transfers.

Furthermore, these encoder callbacks access the regmap without the protection of drm_dev_enter() and drm_dev_exit(). Because drm_dev_unplug() allows existing file descriptors to remain open, userspace might trigger a modeset after the device is unbound and devres has freed the regmap, leading to a use-after-free.

Quoted 12 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	u8 command = CH1115_CMD_ON;
 
 	ch1115_send_command_list(ch1115, &command, 1);
 }
 
 static void ch1115_encoder_atomic_disable(struct drm_encoder *encoder,
 					  struct drm_atomic_commit *state)
 {
 	struct drm_device *drm = encoder->dev;
 	struct ch1115_device *ch1115 = drm_to_ch1115(drm);

drivers/gpu/drm/chipwealth/ch1115.c

Quoted 3 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	u8 command = CH1115_CMD_OFF;
 
 	ch1115_send_command_list(ch1115, &command, 1);

[Severity: High]
Could this disable hook also cause a use-after-free?

Similarly to the enable callback, this hook accesses the devres-managed regmap without checking drm_dev_enter().

Quoted 1 line

}

[ ... ]

Quoted 18 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
@@ -589,17 +589,17 @@ static int ch1115_regmap_read(void *context, const void *reg_buf,
 			      size_t reg_size, void *val_buf, size_t val_size)
 {
 	return -EOPNOTSUPP;
 }
 
 static int ch1115_regmap_write(void *context, const void *data, size_t count)
 {
 	struct i2c_client *client = context;
 	struct ch1115_device *ch1115 = i2c_get_clientdata(client);
 	int ret;
 
 	struct i2c_msg msg = {
 		.addr = ch1115->client->addr,
 		.len = count,
 		.buf = (u8 *)data,
 	};
 

drivers/gpu/drm/chipwealth/ch1115.c

Quoted 3 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 	ret = i2c_transfer(ch1115->client->adapter, &msg, 1);
 
 	return ret;

[Severity: Medium]
Does this regmap bus write callback return the correct success value?

The regmap_bus API expects a return value of 0 on success. However, i2c_transfer() returns the number of messages executed, which is 1 on success. Returning a positive value from this callback violates the API contract, even if the driver's own callers currently mask the issue by only checking for negative error codes.

Quoted 1 line

}

[ ... ]

Quoted 27 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
@@ -758,26 +758,26 @@ static int ch1115_probe(struct i2c_client *client)
 	ret = drm_dev_register(&ch1115->dev, 0);
 	if (ret)
 		return dev_err_probe(&client->dev, ret,
 				     "Failed to register DRM device\n");
 
 	drm_client_setup(&ch1115->dev, NULL);
 
 	return 0;
 }
 
 static void ch1115_remove(struct i2c_client *client)
 {
 	struct ch1115_device *ch1115 = i2c_get_clientdata(client);
 	int ret;
 
 	u8 cmd_list[] = {
 		CH1115_CMD_OFF,
 
 		CH1115_CMD_ALL_ON,
 
 		CH1115_CMD_DC_DC,
 		CH1115_VAL_DC_DC_OFF,
 	};
 
 	ret = ch1115_send_command_list(ch1115, cmd_list, ARRAY_SIZE(cmd_list));
 	if (ret < 0)

drivers/gpu/drm/chipwealth/ch1115.c

Quoted 5 lines
drivers/gpu/drm/chipwealth/ch1115.c new file +0 -0
 		dev_err(&client->dev, "There was an error executing the shutdown commands");
 
 	usleep_range(10000, 15000);
 
 	drm_dev_unplug(&ch1115->dev);

[Severity: High]
Should this function call drm_atomic_helper_shutdown() before unplugging?

Without shutting down the atomic helpers, CRTCs and planes remain active and pinned framebuffers are leaked. It also leaves deferred non-blocking atomic commits running in workqueues.

When the remove function returns, devres cleans up memory like hwbuf, row, and regmap, which can cause a use-after-free if a background commit continues executing.

Quoted 1 line

}

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
#7 lore raw

PATCH 3/3 MAINTAINERS: add entry for Chipwealth CH1115 OLED controller

In reply to Nicolás Antinori

Add MAINTAINERS entry for the Chipwealth CH1115 dot matrix OLED controller.

---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)
MAINTAINERS +6 -0
index b09b0ee33f5d..8430e4f4cad3 100644
@@ -8590,6 +8590,12 @@ T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
 F:	Documentation/devicetree/bindings/display/panel/samsung,lms380kf01.yaml
 F:	drivers/gpu/drm/panel/panel-widechips-ws2401.c
 
+DRM DRIVER FOR CHIPWEALTH CH1115 PANELS
+M:	Nicolás Antinori <[email protected]>
+S:	Maintained
+F:	Documentation/devicetree/bindings/display/chipwealth,ch1115.yaml
+F:	drivers/gpu/drm/chipwealth/ch1115.c
+
 DRM DRIVERS
 M:	David Airlie <[email protected]>
 M:	Simona Vetter <[email protected]>

--
2.47.3