* Re: [PATCH v1 1/6] dt-bindings: leds: Document TI LM3533 LED controller
From: Jonathan Cameron @ 2026-05-17 13:44 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, David Lechner, Nuno Sá,
Andy Shevchenko, Helge Deller, dri-devel, linux-leds, devicetree,
linux-kernel, linux-iio, linux-fbdev
In-Reply-To: <20260517074306.30937-2-clamor95@gmail.com>
On Sun, 17 May 2026 10:43:01 +0300
Svyatoslav Ryhel <clamor95@gmail.com> wrote:
> Document the LM3533 - a complete power source for backlight, keypad and
> indicator LEDs in smartphone handsets. The high-voltage inductive boost
> converter provides the power for two series LED strings display backlight
> and keypad functions.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Hi Svyatoslav,
I focused on the ALS part.. A few comments.
> +# see ti,lm3533.yaml for an example
> diff --git a/Documentation/devicetree/bindings/leds/ti,lm3533.yaml b/Documentation/devicetree/bindings/leds/ti,lm3533.yaml
> new file mode 100644
> index 000000000000..2e200f172400
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/ti,lm3533.yaml
> @@ -0,0 +1,190 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/ti,lm3533.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI LM3533 Complete Lighting Power Solution
> +
> +description: >
> + The LM3533 is a complete power source for backlight, keypad, and indicator LEDs
> + in smartphone handsets. The high-voltage inductive boost converter provides the
> + power for two high voltage series LED strings for display backlight and four low
> + voltage control banks for individual LEDs. Additionally, LM3533 features an ALS
> + sensor support.
Mention it is an interface for an external ALS.
> + light-sensor:
> + type: object
> + additionalProperties: false
> +
> + properties:
> + compatible:
> + const: ti,lm3533-als
> +
> + interrupts:
> + maxItems: 1
> +
> + ti,resistor-ohm:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + Internal configuration resister value when ALS is in Analog Sensor
> + mode and PWM mode is disabled.
Good to note why this is a firmware thing rather than a userspace controlled
thing. I looked it up, it's because expectation is the input is a current from
the external analog ALS and these are used to convert it to a voltage with target
range.
> + minimum: 1575
> + maximum: 200000
> +
> + ti,pwm-mode:
> + type: boolean
> + description:
> + Switch for mode in which ALS is running. If this property is set
> + then ALS is running in PWM mode, internal resistor value is set to
> + high-impedance (0) and ti,resistor-ohm property is ignored.
I'd mention the ALS is an external device - so this is saying what interface thing
thing connected is using.
> +
> + required:
> + - compatible
> +
> + anyOf:
> + - required:
> + - ti,resistor-ohm
> + - required:
> + - ti,pwm-mode
> +
> +patternProperties:
> + "^backlight@[01]$":
> + $ref: /schemas/leds/backlight/ti,lm3533-backlight.yaml#
> +
> + "^led@[2-5]$":
> + $ref: /schemas/leds/ti,lm3533-leds.yaml#
> +
> +required:
> + - compatible
> + - reg
> + - light-sensor
> + - backlight@0
> + - backlight@1
Similar for the led nodes.
> + - led@2
> + - led@3
> + - led@4
> + - led@5
Curious - why are all the led nodes required? What if some aren't wired to anything?
> +
> +additionalProperties: false
^ permalink raw reply
* Re: [PATCH v1 1/6] dt-bindings: leds: Document TI LM3533 LED controller
From: Svyatoslav Ryhel @ 2026-05-17 14:26 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, David Lechner, Nuno Sá,
Andy Shevchenko, Helge Deller, dri-devel, linux-leds, devicetree,
linux-kernel, linux-iio, linux-fbdev
In-Reply-To: <20260517144453.61cc210c@jic23-huawei>
нд, 17 трав. 2026 р. о 16:45 Jonathan Cameron <jic23@kernel.org> пише:
>
> On Sun, 17 May 2026 10:43:01 +0300
> Svyatoslav Ryhel <clamor95@gmail.com> wrote:
>
> > Document the LM3533 - a complete power source for backlight, keypad and
> > indicator LEDs in smartphone handsets. The high-voltage inductive boost
> > converter provides the power for two series LED strings display backlight
> > and keypad functions.
> >
> > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> Hi Svyatoslav,
>
> I focused on the ALS part.. A few comments.
>
> > +# see ti,lm3533.yaml for an example
> > diff --git a/Documentation/devicetree/bindings/leds/ti,lm3533.yaml b/Documentation/devicetree/bindings/leds/ti,lm3533.yaml
> > new file mode 100644
> > index 000000000000..2e200f172400
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/leds/ti,lm3533.yaml
> > @@ -0,0 +1,190 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/leds/ti,lm3533.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: TI LM3533 Complete Lighting Power Solution
> > +
> > +description: >
> > + The LM3533 is a complete power source for backlight, keypad, and indicator LEDs
> > + in smartphone handsets. The high-voltage inductive boost converter provides the
> > + power for two high voltage series LED strings for display backlight and four low
> > + voltage control banks for individual LEDs. Additionally, LM3533 features an ALS
> > + sensor support.
> Mention it is an interface for an external ALS.
>
Noted, thank you!
> > + light-sensor:
> > + type: object
> > + additionalProperties: false
> > +
> > + properties:
> > + compatible:
> > + const: ti,lm3533-als
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + ti,resistor-ohm:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description:
> > + Internal configuration resister value when ALS is in Analog Sensor
> > + mode and PWM mode is disabled.
>
> Good to note why this is a firmware thing rather than a userspace controlled
> thing. I looked it up, it's because expectation is the input is a current from
> the external analog ALS and these are used to convert it to a voltage with target
> range.
>
I will include your explanation.
> > + minimum: 1575
> > + maximum: 200000
> > +
> > + ti,pwm-mode:
> > + type: boolean
> > + description:
> > + Switch for mode in which ALS is running. If this property is set
> > + then ALS is running in PWM mode, internal resistor value is set to
> > + high-impedance (0) and ti,resistor-ohm property is ignored.
> I'd mention the ALS is an external device - so this is saying what interface thing
> thing connected is using.
>
Noted
> > +
> > + required:
> > + - compatible
> > +
> > + anyOf:
> > + - required:
> > + - ti,resistor-ohm
> > + - required:
> > + - ti,pwm-mode
> > +
> > +patternProperties:
> > + "^backlight@[01]$":
> > + $ref: /schemas/leds/backlight/ti,lm3533-backlight.yaml#
> > +
> > + "^led@[2-5]$":
> > + $ref: /schemas/leds/ti,lm3533-leds.yaml#
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - light-sensor
> > + - backlight@0
> > + - backlight@1
>
> Similar for the led nodes.
>
> > + - led@2
> > + - led@3
> > + - led@4
> > + - led@5
>
> Curious - why are all the led nodes required? What if some aren't wired to anything?
>
This is limitations of mfd devices. If it has subnodes, all subnodes
must be present to reflect mfd composition. Unused nodes should be
disabled.
However, I have asked Lee if he is fine if I will program dynamic mfd
composition based on the device tree. If he is fine, "required"
props/nodes list will be reduced.
> > +
> > +additionalProperties: false
>
^ permalink raw reply
* Re: [PATCH v1 2/6] mfd: lm3533: Convert to use OF bindings
From: Lee Jones @ 2026-05-18 9:28 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Daniel Thompson, Jingoo Han, Rob Herring, Pavel Machek,
Krzysztof Kozlowski, Conor Dooley, David Lechner,
Jonathan Cameron, Nuno Sá, Helge Deller, dri-devel,
linux-leds, devicetree, linux-kernel, linux-iio, linux-fbdev,
Andy Shevchenko
In-Reply-To: <CAPVz0n3gLYXab4H+DihfTkdBkGPqTvmoFVY1Cwuafd70KPtYbA@mail.gmail.com>
On Sun, 17 May 2026, Svyatoslav Ryhel wrote:
> нд, 17 трав. 2026 р. о 10:43 Svyatoslav Ryhel <clamor95@gmail.com> пише:
> >
> > Since there are no users of this driver via platform data, remove the
> > platform data support and switch to using Device Tree bindings.
> > Additionally, optimize functions used only by platform data.
> >
> > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> > ---
> > drivers/iio/light/lm3533-als.c | 123 +++++--------
> > drivers/leds/leds-lm3533.c | 60 ++++---
> > drivers/mfd/lm3533-core.c | 257 +++++++++-------------------
> > drivers/video/backlight/lm3533_bl.c | 52 ++++--
> > include/linux/mfd/lm3533.h | 51 +-----
> > 5 files changed, 202 insertions(+), 341 deletions(-)
Please snip replies.
[...]
> > -static int lm3533_device_led_init(struct lm3533 *lm3533)
> > -{
> > - struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
> > - int i;
> > - int ret;
> > -
> > - if (!pdata->leds || pdata->num_leds == 0)
> > - return 0;
> > -
> > - if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs))
> > - pdata->num_leds = ARRAY_SIZE(lm3533_led_devs);
> > -
> > - for (i = 0; i < pdata->num_leds; ++i) {
> > - lm3533_led_devs[i].platform_data = &pdata->leds[i];
> > - lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]);
> > + dev_err(dev, "failed to set boost ovp\n");
> > + goto err_disable;
> > }
> >
> > - ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
> > - pdata->num_leds, NULL, 0, NULL);
> > + ret = devm_mfd_add_devices(dev, 0, lm3533_child_devices,
> > + ARRAY_SIZE(lm3533_child_devices),
> > + NULL, 0, NULL);
>
> Question to Lee Jones. Would you find acceptable if the driver will
> build cell list dynamically based on the nodes in the device tree?
> This is LED controller after all, not all leds can be populated and
> same LED control bank can be linked to all LVLEDs for example.
>
> If you are ok, would this implementation satisfy you?
Generally not. Create the non-dynamical information statically
(obviously not 'const'), then you can add dynamic data as you go.
> struct mfd_cell lm3533_cells[LM3533_CELLS_MAX];
> u32 count = 0, reg;
> int ret;
>
> device_for_each_child_node_scoped(lm3533->dev, child) {
> if (!fwnode_device_is_available(child))
> continue;
>
> if (count >= LM3533_CELLS_MAX)
> break;
>
> if (fwnode_device_is_compatible(child, "ti,lm3533-als")) {
> lm3533_cells[count].name = "lm3533-als";
> lm3533_cells[count].id = PLATFORM_DEVID_NONE;
> lm3533_cells[count].of_compatible = "ti,lm3533-als";
>
> lm3533->have_als = true;
> }
>
> if (fwnode_device_is_compatible(child, "ti,lm3533-backlight")) {
> ret = fwnode_property_read_u32(child, "reg", ®);
> if (ret || reg > LM3533_HVLED_ID_MAX) {
> dev_err(dev, "invalid backlight reg %d\n", reg);
> continue;
> }
>
> lm3533_cells[count].name = "lm3533-backlight";
> lm3533_cells[count].id = reg;
> lm3533_cells[count].of_compatible =
> "ti,lm3533-backlight";
>
> lm3533->have_backlights = true;
> }
>
> if (fwnode_device_is_compatible(child, "ti,lm3533-leds")) {
> ret = fwnode_property_read_u32(child, "reg", ®);
> if (ret || reg < LM3533_HVLED_ID_MAX ||
> reg > LM3533_LVLED_ID_MAX) {
> dev_err(dev, "invalid LED reg %d\n", reg);
> continue;
> }
>
> lm3533_cells[count].name = "lm3533-leds";
> lm3533_cells[count].id = reg - LM3533_HVLED_ID_MAX;
> lm3533_cells[count].of_compatible = "ti,lm3533-leds";
>
> lm3533->have_leds = true;
> }
>
> count++;
> }
>
> > if (ret) {
> > - dev_err(lm3533->dev, "failed to add LED devices\n");
> > - return ret;
> > - }
> > -
> > - lm3533->have_leds = 1;
> > -
> > - return 0;
> > -}
[...]
--
Lee Jones
^ permalink raw reply
* Re: [PATCH v1 2/6] mfd: lm3533: Convert to use OF bindings
From: Svyatoslav Ryhel @ 2026-05-18 9:51 UTC (permalink / raw)
To: Lee Jones
Cc: Daniel Thompson, Jingoo Han, Rob Herring, Pavel Machek,
Krzysztof Kozlowski, Conor Dooley, David Lechner,
Jonathan Cameron, Nuno Sá, Helge Deller, dri-devel,
linux-leds, devicetree, linux-kernel, linux-iio, linux-fbdev,
Andy Shevchenko
In-Reply-To: <20260518092833.GR305027@google.com>
пн, 18 трав. 2026 р. о 12:28 Lee Jones <lee@kernel.org> пише:
>
> On Sun, 17 May 2026, Svyatoslav Ryhel wrote:
>
> > нд, 17 трав. 2026 р. о 10:43 Svyatoslav Ryhel <clamor95@gmail.com> пише:
> > >
> > > Since there are no users of this driver via platform data, remove the
> > > platform data support and switch to using Device Tree bindings.
> > > Additionally, optimize functions used only by platform data.
> > >
> > > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> > > ---
> > > drivers/iio/light/lm3533-als.c | 123 +++++--------
> > > drivers/leds/leds-lm3533.c | 60 ++++---
> > > drivers/mfd/lm3533-core.c | 257 +++++++++-------------------
> > > drivers/video/backlight/lm3533_bl.c | 52 ++++--
> > > include/linux/mfd/lm3533.h | 51 +-----
> > > 5 files changed, 202 insertions(+), 341 deletions(-)
>
> Please snip replies.
>
> [...]
>
> > > -static int lm3533_device_led_init(struct lm3533 *lm3533)
> > > -{
> > > - struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
> > > - int i;
> > > - int ret;
> > > -
> > > - if (!pdata->leds || pdata->num_leds == 0)
> > > - return 0;
> > > -
> > > - if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs))
> > > - pdata->num_leds = ARRAY_SIZE(lm3533_led_devs);
> > > -
> > > - for (i = 0; i < pdata->num_leds; ++i) {
> > > - lm3533_led_devs[i].platform_data = &pdata->leds[i];
> > > - lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]);
> > > + dev_err(dev, "failed to set boost ovp\n");
> > > + goto err_disable;
> > > }
> > >
> > > - ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
> > > - pdata->num_leds, NULL, 0, NULL);
> > > + ret = devm_mfd_add_devices(dev, 0, lm3533_child_devices,
> > > + ARRAY_SIZE(lm3533_child_devices),
> > > + NULL, 0, NULL);
> >
> > Question to Lee Jones. Would you find acceptable if the driver will
> > build cell list dynamically based on the nodes in the device tree?
> > This is LED controller after all, not all leds can be populated and
> > same LED control bank can be linked to all LVLEDs for example.
> >
> > If you are ok, would this implementation satisfy you?
>
> Generally not. Create the non-dynamical information statically
> (obviously not 'const'), then you can add dynamic data as you go.
>
Hm, code I have proposed below creates mfd_cell structure with 7 cells
(max amount of children), and fills each slot with devices described
in the device tree. This seems to fit your expectation. LM3533 is
basically a LED controller but it is set as mfd and IMHO would be
undesirable to create dummy devices.
> > struct mfd_cell lm3533_cells[LM3533_CELLS_MAX];
> > u32 count = 0, reg;
> > int ret;
> >
> > device_for_each_child_node_scoped(lm3533->dev, child) {
> > if (!fwnode_device_is_available(child))
> > continue;
> >
> > if (count >= LM3533_CELLS_MAX)
> > break;
> >
> > if (fwnode_device_is_compatible(child, "ti,lm3533-als")) {
> > lm3533_cells[count].name = "lm3533-als";
> > lm3533_cells[count].id = PLATFORM_DEVID_NONE;
> > lm3533_cells[count].of_compatible = "ti,lm3533-als";
> >
> > lm3533->have_als = true;
> > }
> >
> > if (fwnode_device_is_compatible(child, "ti,lm3533-backlight")) {
> > ret = fwnode_property_read_u32(child, "reg", ®);
> > if (ret || reg > LM3533_HVLED_ID_MAX) {
> > dev_err(dev, "invalid backlight reg %d\n", reg);
> > continue;
> > }
> >
> > lm3533_cells[count].name = "lm3533-backlight";
> > lm3533_cells[count].id = reg;
> > lm3533_cells[count].of_compatible =
> > "ti,lm3533-backlight";
> >
> > lm3533->have_backlights = true;
> > }
> >
> > if (fwnode_device_is_compatible(child, "ti,lm3533-leds")) {
> > ret = fwnode_property_read_u32(child, "reg", ®);
> > if (ret || reg < LM3533_HVLED_ID_MAX ||
> > reg > LM3533_LVLED_ID_MAX) {
> > dev_err(dev, "invalid LED reg %d\n", reg);
> > continue;
> > }
> >
> > lm3533_cells[count].name = "lm3533-leds";
> > lm3533_cells[count].id = reg - LM3533_HVLED_ID_MAX;
> > lm3533_cells[count].of_compatible = "ti,lm3533-leds";
> >
> > lm3533->have_leds = true;
> > }
> >
> > count++;
> > }
> >
> > > if (ret) {
> > > - dev_err(lm3533->dev, "failed to add LED devices\n");
> > > - return ret;
> > > - }
> > > -
> > > - lm3533->have_leds = 1;
> > > -
> > > - return 0;
> > > -}
>
> [...]
>
> --
> Lee Jones
^ permalink raw reply
* [PATCH] backlight: Use named initializers for arrays of i2c_device_data
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-18 11:12 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han
Cc: Michael Hennerich, Helge Deller, Junjie Cao, Jianhua Lu,
Flavio Suligoi, dri-devel, linux-fbdev, linux-kernel
While being less compact, using named initializers allows to more easily
see which members of the structs are assigned which value without having
to lookup the declaration of the struct. And it's also more robust
against changes to the struct definition.
The mentioned robustness is relevant for a planned change to struct
i2c_device_id that replaces .driver_data by an anonymous union.
While touching all these arrays, unify usage of whitespace in the list
terminator.
This patch doesn't modify the compiled arrays, only their representation
in source form benefits. The former was confirmed with x86 and arm64
builds.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
Hello,
the mentioned change to i2c_device_id is the following:
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 23ff24080dfd..aebd3a5e90af 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -477,7 +477,11 @@ struct rpmsg_device_id {
struct i2c_device_id {
char name[I2C_NAME_SIZE];
- kernel_ulong_t driver_data; /* Data private to the driver */
+ union {
+ /* Data private to the driver */
+ kernel_ulong_t driver_data;
+ const void *driver_data_ptr;
+ };
};
/* pci_epf */
and this requires that .driver_data is assigned via a named initializer
for static data. This requirement isn't a bad one because named
initializers are also much better readable than list initializers.
The union added to struct i2c_device_id enables further cleanups like:
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index 0123ca8157a8..dfb0b07500a7 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -207,8 +207,8 @@ struct ad5398_current_data_format {
static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
static const struct i2c_device_id ad5398_id[] = {
- { .name = "ad5398", .driver_data = (kernel_ulong_t)&df_10_4_120 },
- { .name = "ad5821", .driver_data = (kernel_ulong_t)&df_10_4_120 },
+ { .name = "ad5398", .driver_data_ptr = &df_10_4_120 },
+ { .name = "ad5821", .driver_data_ptr = &df_10_4_120 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);
@@ -219,8 +219,7 @@ static int ad5398_probe(struct i2c_client *client)
struct regulator_init_data *init_data = dev_get_platdata(&client->dev);
struct regulator_config config = { };
struct ad5398_chip_info *chip;
- const struct ad5398_current_data_format *df =
- (struct ad5398_current_data_format *)id->driver_data;
+ const struct ad5398_current_data_format *df = id->driver_data;
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
that are an improvement for readability (again!) and it keeps some
properties of the pointers (here: being const) without having to pay
attention for that. (I didn't find a backlight driver that benefits, so
this is "only" a regulator driver example.)
My additional motivation for this effort is CHERI[1]. This is a hardware
extension that uses 128 bit pointers but unsigned long is still 64 bit.
So with CHERI you cannot store pointers in unsigned long variables.
Best regards
Uwe
[1] https://cheri-alliance.org/discover-cheri/
https://lwn.net/Articles/1037974/
---
drivers/video/backlight/adp8860_bl.c | 6 +++---
drivers/video/backlight/adp8870_bl.c | 2 +-
drivers/video/backlight/arcxcnn_bl.c | 2 +-
drivers/video/backlight/aw99706.c | 2 +-
drivers/video/backlight/bd6107.c | 2 +-
drivers/video/backlight/ktz8866.c | 4 ++--
drivers/video/backlight/lm3509_bl.c | 4 ++--
drivers/video/backlight/lm3630a_bl.c | 4 ++--
drivers/video/backlight/lm3639_bl.c | 4 ++--
drivers/video/backlight/lp855x_bl.c | 14 +++++++-------
drivers/video/backlight/lv5207lp.c | 2 +-
drivers/video/backlight/mp3309c.c | 2 +-
12 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index d4bbd7a7406b..09dd67702431 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -790,9 +790,9 @@ static SIMPLE_DEV_PM_OPS(adp8860_i2c_pm_ops, adp8860_i2c_suspend,
adp8860_i2c_resume);
static const struct i2c_device_id adp8860_id[] = {
- { "adp8860", adp8860 },
- { "adp8861", adp8861 },
- { "adp8863", adp8863 },
+ { .name = "adp8860", .driver_data = adp8860 },
+ { .name = "adp8861", .driver_data = adp8861 },
+ { .name = "adp8863", .driver_data = adp8863 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adp8860_id);
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index e09e20492e7c..d009f2c8a11d 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -962,7 +962,7 @@ static SIMPLE_DEV_PM_OPS(adp8870_i2c_pm_ops, adp8870_i2c_suspend,
adp8870_i2c_resume);
static const struct i2c_device_id adp8870_id[] = {
- { "adp8870" },
+ { .name = "adp8870" },
{ }
};
MODULE_DEVICE_TABLE(i2c, adp8870_id);
diff --git a/drivers/video/backlight/arcxcnn_bl.c b/drivers/video/backlight/arcxcnn_bl.c
index 1d5a570cfe02..f46eeab02e90 100644
--- a/drivers/video/backlight/arcxcnn_bl.c
+++ b/drivers/video/backlight/arcxcnn_bl.c
@@ -382,7 +382,7 @@ static const struct of_device_id arcxcnn_dt_ids[] = {
MODULE_DEVICE_TABLE(of, arcxcnn_dt_ids);
static const struct i2c_device_id arcxcnn_ids[] = {
- {"arc2c0608", ARC2C0608},
+ { .name = "arc2c0608", .driver_data = ARC2C0608 },
{ }
};
MODULE_DEVICE_TABLE(i2c, arcxcnn_ids);
diff --git a/drivers/video/backlight/aw99706.c b/drivers/video/backlight/aw99706.c
index 938f352aaab7..18299faf06ad 100644
--- a/drivers/video/backlight/aw99706.c
+++ b/drivers/video/backlight/aw99706.c
@@ -443,7 +443,7 @@ static int aw99706_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(aw99706_pm_ops, aw99706_suspend, aw99706_resume);
static const struct i2c_device_id aw99706_ids[] = {
- { "aw99706" },
+ { .name = "aw99706" },
{ }
};
MODULE_DEVICE_TABLE(i2c, aw99706_ids);
diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c
index 74567af84e97..6778b4030b02 100644
--- a/drivers/video/backlight/bd6107.c
+++ b/drivers/video/backlight/bd6107.c
@@ -179,7 +179,7 @@ static void bd6107_remove(struct i2c_client *client)
}
static const struct i2c_device_id bd6107_ids[] = {
- { "bd6107" },
+ { .name = "bd6107" },
{ }
};
MODULE_DEVICE_TABLE(i2c, bd6107_ids);
diff --git a/drivers/video/backlight/ktz8866.c b/drivers/video/backlight/ktz8866.c
index 351c2b4d63ed..53c1301dbb8c 100644
--- a/drivers/video/backlight/ktz8866.c
+++ b/drivers/video/backlight/ktz8866.c
@@ -179,8 +179,8 @@ static void ktz8866_remove(struct i2c_client *client)
}
static const struct i2c_device_id ktz8866_ids[] = {
- { "ktz8866" },
- {}
+ { .name = "ktz8866" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, ktz8866_ids);
diff --git a/drivers/video/backlight/lm3509_bl.c b/drivers/video/backlight/lm3509_bl.c
index 24e1a19ff72d..53136c5e1460 100644
--- a/drivers/video/backlight/lm3509_bl.c
+++ b/drivers/video/backlight/lm3509_bl.c
@@ -311,8 +311,8 @@ static void lm3509_remove(struct i2c_client *client)
}
static const struct i2c_device_id lm3509_id[] = {
- { LM3509_NAME },
- {}
+ { .name = LM3509_NAME },
+ { }
};
MODULE_DEVICE_TABLE(i2c, lm3509_id);
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index 37651c2b9393..8f49e59ce374 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -596,8 +596,8 @@ static void lm3630a_remove(struct i2c_client *client)
}
static const struct i2c_device_id lm3630a_id[] = {
- { LM3630A_NAME },
- {}
+ { .name = LM3630A_NAME },
+ { }
};
MODULE_DEVICE_TABLE(i2c, lm3630a_id);
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
index 37ccc631c498..ea748b80b737 100644
--- a/drivers/video/backlight/lm3639_bl.c
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -403,8 +403,8 @@ static void lm3639_remove(struct i2c_client *client)
}
static const struct i2c_device_id lm3639_id[] = {
- { LM3639_NAME },
- {}
+ { .name = LM3639_NAME },
+ { }
};
MODULE_DEVICE_TABLE(i2c, lm3639_id);
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index d191560ce285..43a2123d3a4d 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -570,13 +570,13 @@ static const struct of_device_id lp855x_dt_ids[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, lp855x_dt_ids);
static const struct i2c_device_id lp855x_ids[] = {
- {"lp8550", LP8550},
- {"lp8551", LP8551},
- {"lp8552", LP8552},
- {"lp8553", LP8553},
- {"lp8555", LP8555},
- {"lp8556", LP8556},
- {"lp8557", LP8557},
+ { .name = "lp8550", .driver_data = LP8550 },
+ { .name = "lp8551", .driver_data = LP8551 },
+ { .name = "lp8552", .driver_data = LP8552 },
+ { .name = "lp8553", .driver_data = LP8553 },
+ { .name = "lp8555", .driver_data = LP8555 },
+ { .name = "lp8556", .driver_data = LP8556 },
+ { .name = "lp8557", .driver_data = LP8557 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp855x_ids);
diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c
index a205f004eab2..e643ab9c3536 100644
--- a/drivers/video/backlight/lv5207lp.c
+++ b/drivers/video/backlight/lv5207lp.c
@@ -131,7 +131,7 @@ static void lv5207lp_remove(struct i2c_client *client)
}
static const struct i2c_device_id lv5207lp_ids[] = {
- { "lv5207lp" },
+ { .name = "lv5207lp" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lv5207lp_ids);
diff --git a/drivers/video/backlight/mp3309c.c b/drivers/video/backlight/mp3309c.c
index 9337110ce6e5..413cfe27dfd9 100644
--- a/drivers/video/backlight/mp3309c.c
+++ b/drivers/video/backlight/mp3309c.c
@@ -400,7 +400,7 @@ static const struct of_device_id mp3309c_match_table[] = {
MODULE_DEVICE_TABLE(of, mp3309c_match_table);
static const struct i2c_device_id mp3309c_id[] = {
- { "mp3309c" },
+ { .name = "mp3309c" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mp3309c_id);
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
--
2.47.3
^ permalink raw reply related
* [PATCH v1] fbdev: Use named initializers for struct i2c_device_id
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-18 16:08 UTC (permalink / raw)
To: Helge Deller
Cc: Kees Cook, Abdun Nihaal, linux-fbdev, dri-devel, linux-kernel
While being less compact, using named initializers allows to more easily
see which members of the structs are assigned which value without having
to lookup the declaration of the struct. And it's also more robust
against changes to the struct definition.
While touching all these arrays, unify usage of whitespace in the list
terminator.
This patch doesn't modify the compiled arrays, only their representation
in source form benefits. The former was confirmed with x86 and arm64
builds.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
Hello,
this patch is part of a bigger quest to use named initializers for
mainly struct i2c_device_id::driver_data to be able to modify
i2c_device_id. See e.g.
https://lore.kernel.org/all/20260518111203.639603-2-u.kleine-koenig@baylibre.com/
for the details.
This patch here isn't critical for this quest, as no driver makes use of
.driver_data, so apart from the better readability this is only about
consistency with other subsystems.
Best regards
Uwe
drivers/video/fbdev/matrox/matroxfb_maven.c | 2 +-
drivers/video/fbdev/ssd1307fb.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/video/fbdev/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c
index 2ea65da6075c..fe057a0b57ec 100644
--- a/drivers/video/fbdev/matrox/matroxfb_maven.c
+++ b/drivers/video/fbdev/matrox/matroxfb_maven.c
@@ -1282,7 +1282,7 @@ static void maven_remove(struct i2c_client *client)
}
static const struct i2c_device_id maven_id[] = {
- { "maven" },
+ { .name = "maven" },
{ }
};
MODULE_DEVICE_TABLE(i2c, maven_id);
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 83dd31fa1fab..644b8d97b381 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -784,10 +784,10 @@ static void ssd1307fb_remove(struct i2c_client *client)
}
static const struct i2c_device_id ssd1307fb_i2c_id[] = {
- { "ssd1305fb" },
- { "ssd1306fb" },
- { "ssd1307fb" },
- { "ssd1309fb" },
+ { .name = "ssd1305fb" },
+ { .name = "ssd1306fb" },
+ { .name = "ssd1307fb" },
+ { .name = "ssd1309fb" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id);
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
--
2.47.3
^ permalink raw reply related
* Re: [PATCH] fbdev: chipsfb: add missing MODULE_DESCRIPTION() macro
From: Rahman Mahmutović @ 2026-05-18 16:14 UTC (permalink / raw)
To: linux-fbdev; +Cc: deller, dri-devel, linux-kernel
In-Reply-To: <20260509131831.1073-1-mahmutovicrahman5@gmail.com>
Hi Helge,
Can you check my patches and let me know if any changes are needed?
Thanks,
Rahman Mahmutović
^ permalink raw reply
* Re: [PATCH] fbdev: sunxvr2500: replace printk with device-aware logging functions
From: Rahman Mahmutović @ 2026-05-18 16:15 UTC (permalink / raw)
To: linux-fbdev; +Cc: deller, dri-devel, linux-kernel
In-Reply-To: <20260509135759.1391-1-mahmutovicrahman5@gmail.com>
Hi Helge,
Can you check my patches and let me know if any changes are needed?
Thanks,
Rahman Mahmutović
^ permalink raw reply
* fbdev: iterator used after loop end in fb_deferred_io_pageref_get?
From: Maoyi Xie @ 2026-05-18 19:04 UTC (permalink / raw)
To: jayalk, simona, deller; +Cc: linux-fbdev, dri-devel, linux-kernel
Hi all,
While reading drivers/video/fbdev/core/fb_defio.c I noticed
something that looks like a past the end iterator pattern.
I would appreciate it if you could take a look and let me
know whether this is a real issue, and whether it is worth
fixing.
The site is fb_deferred_io_pageref_get() (linux-7.1-rc1,
around line 203):
list_for_each_entry(cur, &fbdefio_state->pagereflist, list) {
if (cur->offset > pageref->offset)
break;
}
pos = &cur->list;
When the loop walks all entries without break, cur has gone
one step past the last entry. &cur->list then aliases
&fbdefio_state->pagereflist (the list head) via container_of
offset cancellation, so pos equals the head and the
subsequent list_add_tail(&pageref->list, pos) lands at the
list tail. That is the intended behaviour, but the access
is undefined per C11.
Jakob Koschel cleaned up many such sites in 2022, for example
commits 99d8ae4ec8a (tracing: Remove usage of list iterator
variable after the loop), 2966a9918df (clockevents: Use dedicated
list iterator variable) and dc1acd5c946 (dlm: replace usage of
found with dedicated list iterator variable). This site in
fb_defio was not covered.
A candidate fix would move the pos = &cur->list assignment
inside the break arm, so pos is only overwritten when the
loop actually finds a position. The default value of pos
(set earlier in the function to &fbdefio_state->pagereflist)
already covers the loop fall through case. The observable
behaviour is unchanged.
If this is intentional or already known, please disregard.
Otherwise, I am happy to send a [PATCH] or to leave the fix
to you. Thank you for your time, and sorry for the noise if
this is not actually worth fixing or has already been spotted.
Thanks,
Maoyi Xie
https://maoyixie.com/
^ permalink raw reply
* [PATCH] fbdev: imxfb: Use of_device_get_match_data()
From: Rosen Penev @ 2026-05-18 21:13 UTC (permalink / raw)
To: linux-fbdev
Cc: Sascha Hauer, Pengutronix Kernel Team, Helge Deller, Frank Li,
Fabio Estevam,
moderated list:FREESCALE IMX / MXC FRAMEBUFFER DRIVER,
open list:FRAMEBUFFER LAYER,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, open list
Use of_device_get_match_data() to fetch the platform ID entry directly
instead of open-coding an of_match_device() lookup. No NULL check is
needed as every compatible string has a corresponding data section.
This also lets the driver drop the of_device.h include.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/video/fbdev/imxfb.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index a077bf346bdf..7a021da0a32a 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -30,7 +30,6 @@
#include <linux/lcd.h>
#include <linux/math64.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/bitfield.h>
#include <linux/regulator/consumer.h>
@@ -880,7 +879,6 @@ static int imxfb_probe(struct platform_device *pdev)
struct lcd_device *lcd;
struct fb_info *info;
struct imx_fb_videomode *m;
- const struct of_device_id *of_id;
struct device_node *display_np;
int ret, i;
int bytes_per_pixel;
@@ -891,9 +889,7 @@ static int imxfb_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
- if (of_id)
- pdev->id_entry = of_id->data;
+ pdev->id_entry = of_device_get_match_data(&pdev->dev);
info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
if (!info)
--
2.54.0
^ permalink raw reply related
* [PATCH] fbdev: atmel_lcdfb: Use of_device_get_match_data()
From: Rosen Penev @ 2026-05-19 0:36 UTC (permalink / raw)
To: linux-fbdev
Cc: Nicolas Ferre, Helge Deller, Alexandre Belloni, Claudiu Beznea,
open list:FRAMEBUFFER LAYER,
moderated list:ARM/Microchip (AT91) SoC support, open list
Use of_device_get_match_data() to retrieve the driver match data instead
of open-coding the OF match lookup and dereferencing match->data.
This also removes the deprecated of_device.h include from the driver.
No need for NULL check as every compatible has a corresponding data
component.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/video/fbdev/atmel_lcdfb.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index 9dfbc5310210..87406a5a2dcf 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -21,7 +21,6 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <video/of_videomode.h>
#include <video/of_display_timing.h>
#include <linux/regulator/consumer.h>
@@ -56,7 +55,7 @@ struct atmel_lcdfb_info {
struct atmel_lcdfb_pdata pdata;
- struct atmel_lcdfb_config *config;
+ const struct atmel_lcdfb_config *config;
struct regulator *reg_lcd;
};
@@ -930,8 +929,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
int ret;
int i;
- sinfo->config = (struct atmel_lcdfb_config*)
- of_match_device(atmel_lcdfb_dt_ids, dev)->data;
+ sinfo->config = of_device_get_match_data(dev);
display_np = of_parse_phandle(np, "display", 0);
if (!display_np) {
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] ARM: move Risc PC-specific <asm/hardware/iomd.h> header into mach-rpc
From: Helge Deller @ 2026-05-19 6:51 UTC (permalink / raw)
To: Ethan Nelson-Moore, linux-arm-kernel, linux-i2c, linux-input,
linux-fbdev
Cc: Russell King, Andi Shyti, Dmitry Torokhov, Kees Cook
In-Reply-To: <20260510031100.255248-1-enelsonmoore@gmail.com>
On 5/10/26 05:10, Ethan Nelson-Moore wrote:
> The <asm/hardware/iomd.h> header is specific to the IOMD chip used on
> the Risc PC. Move it into mach-rpc to avoid polluting asm/hardware/
> with machine-specific headers.
>
> Also take the opportunity to remove a comment with the file path from
> the header, which is bad style.
>
> Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
> ---
> MAINTAINERS | 1 -
> arch/arm/mach-rpc/dma.c | 2 +-
> arch/arm/{include/asm/hardware => mach-rpc/include/mach}/iomd.h | 2 --
> arch/arm/mach-rpc/irq.c | 2 +-
> arch/arm/mach-rpc/riscpc.c | 2 +-
> arch/arm/mach-rpc/time.c | 2 +-
> drivers/i2c/busses/i2c-acorn.c | 2 +-
> drivers/input/mouse/rpcmouse.c | 2 +-
> drivers/input/serio/rpckbd.c | 2 +-
> drivers/video/fbdev/acornfb.h | 2 +-
Regarding the fbdev change:
Acked-by: Helge Deller <deller@gmx.de>
I assume this patch is pushed via the arm tree?
Helge
^ permalink raw reply
* Re: [PATCH] ARM: mach-rpc: fix zImage build after recent font-related changes
From: Helge Deller @ 2026-05-19 6:56 UTC (permalink / raw)
To: Ethan Nelson-Moore, linux-arm-kernel, linux-fbdev
Cc: Russell King, Thomas Zimmermann, Kees Cook
In-Reply-To: <20260510023941.190396-1-enelsonmoore@gmail.com>
On 5/10/26 04:39, Ethan Nelson-Moore wrote:
> The text display code used in the Risc PC kernel image decompression
> code uses arch/arm/boot/compressed/font.c, which includes
> lib/fonts/font_acorn_8x8.c, which further includes <linux/font.h>.
>
> Since commit 97df8960240a ("lib/fonts: Provide helpers for calculating
> glyph pitch and size") <linux/font.h> contains inline functions that
> require __do_div64, which is not linked into the ARM kernel
> decompressor. This makes Risc PC zImages fail to build.
>
> Resolve this issue in the least intrusive way possible by preventing
> the inclusion of <linux/font.h> (and the definition of a struct that
> relies on it) when the decompressor is being built.
I don't think we really require 64-bit integer support/division in the
font code, as 32-bit should be sufficient.
Can't you try to find out where this 64-bit division is done, and fix
this instead?
Helge
> Fixes: 97df8960240a ("lib/fonts: Provide helpers for calculating glyph pitch and size")
> Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
> ---
> arch/arm/boot/compressed/Makefile | 6 +++++-
> lib/fonts/font_acorn_8x8.c | 2 ++
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> index a159120d1e42..0e198a6ce447 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -157,4 +157,8 @@ $(obj)/piggy_data: $(obj)/../Image FORCE
>
> $(obj)/piggy.o: $(obj)/piggy_data
>
> -CFLAGS_font.o := -Dstatic=
> +# Defining _VIDEO_FONT_H prevents including <linux/font.h>, which contains
> +# inline functions that require __do_div64, which is not linked into the
> +# decompressor. OMIT_FONT_DESC is used in lib/fonts/font_acorn_8x8.c to omit the
> +# definition of the font's font_desc structure, which requires <linux/font.h>.
> +CFLAGS_font.o := -Dstatic= -D_VIDEO_FONT_H -DOMIT_FONT_DESC
> diff --git a/lib/fonts/font_acorn_8x8.c b/lib/fonts/font_acorn_8x8.c
> index 36c51016769d..6b5291c23fc8 100644
> --- a/lib/fonts/font_acorn_8x8.c
> +++ b/lib/fonts/font_acorn_8x8.c
> @@ -265,6 +265,7 @@ static const struct font_data acorndata_8x8 = {
> /* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> } };
>
> +#ifndef OMIT_FONT_DESC /* Used by arch/arm/boot/compressed/Makefile */
> const struct font_desc font_acorn_8x8 = {
> .idx = ACORN8x8_IDX,
> .name = "Acorn8x8",
> @@ -278,3 +279,4 @@ const struct font_desc font_acorn_8x8 = {
> .pref = 0,
> #endif
> };
> +#endif /* OMIT_FONT_DESC */
^ permalink raw reply
* Re: [PATCH 00/14] fbdev: fix various memory leaks
From: Helge Deller @ 2026-05-19 7:11 UTC (permalink / raw)
To: Abdun Nihaal, Javier Martinez Canillas, Thomas Zimmermann,
Benjamin Herrenschmidt, Andrew Morton, Sebastian Siewior,
Florian Tobias Schandinat, Ondrej Zary, Antonino Daplas,
Paul Mundt, Krzysztof Helt, Tomi Valkeinen, Michal Januszewski,
Heiko Schocher, Peter Jones
Cc: linux-fbdev, dri-devel, linux-kernel, stable
In-Reply-To: <20260514-fbdev-v1-0-b3a2474fa720@cse.iitm.ac.in>
On 5/14/26 10:24, Abdun Nihaal wrote:
> This patchset fixes some memory leak issues present in fbdev drivers.
>
> Since commit 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct")
> fb_deferred_io_init() allocated memory for pagerefs and returned an
> error code, but the existing drivers which call fb_deferred_io_init()
> were not updated to do cleanup. The first three commits address this.
> - fbdev: hecubafb: fix potential memory leak in hecubafb_probe()
> - fbdev: broadsheetfb: fix potential memory leak in broadsheetfb_probe()
> - fbdev: metronomefb: fix potential memory leak in metronomefb_probe()
>
> Probe functions that call fb_add_videomode() or fb_videomode_to_modelist()
> sometimes did not call fb_destry_modelist() to free the allocated
> memory. The following patches address this issue.
> - fbdev: radeon: fix potential memory leak in radeonfb_pci_register()
> - fbdev: carminefb: fix potential memory leak in alloc_carmine_fb()
> - fbdev: i740fb: fix potential memory leak in i740fb_probe()
> - fbdev: nvidia: fix potential memory leak in nvidiafb_probe()
> - fbdev: s3fb: fix potential memory leak in s3_pci_probe()
> - fbdev: tdfxfb: fix potential memory leak in tdfxfb_probe()
> - fbdev: tridentfb: fix potential memory leak in trident_pci_probe()
> - fbdev: uvesafb: fix potential memory leak in uvesafb_probe()
>
> Since commit 73ce73c30ba9 ("fbdev: Transfer video= option strings to caller; clarify ownership")
> the fb_get_options() function transfers ownership of the memory
> allocated for options, and so the caller is expected to free it. The
> following two patches address this issue.
> - fbdev: efifb: fix memory leak in efifb_probe()
> - fbdev: vesafb: fix memory leak in vesafb_probe()
>
> The following commit fixes a simple memory leak.
> - fbdev: sm501fb: fix potential memory leak in sm501fb_probe()
>
> All the patches were only compile tested.
> The issues were found using static analysis.
>
> Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
> ---
> Abdun Nihaal (14):
> fbdev: hecubafb: fix potential memory leak in hecubafb_probe()
> fbdev: broadsheetfb: fix potential memory leak in broadsheetfb_probe()
> fbdev: metronomefb: fix potential memory leak in metronomefb_probe()
> fbdev: radeon: fix potential memory leak in radeonfb_pci_register()
> fbdev: carminefb: fix potential memory leak in alloc_carmine_fb()
> fbdev: i740fb: fix potential memory leak in i740fb_probe()
> fbdev: nvidia: fix potential memory leak in nvidiafb_probe()
> fbdev: s3fb: fix potential memory leak in s3_pci_probe()
> fbdev: tdfxfb: fix potential memory leak in tdfxfb_probe()
> fbdev: tridentfb: fix potential memory leak in trident_pci_probe()
> fbdev: uvesafb: fix potential memory leak in uvesafb_probe()
> fbdev: efifb: fix memory leak in efifb_probe()
> fbdev: vesafb: fix memory leak in vesafb_probe()
> fbdev: sm501fb: fix potential memory leak in sm501fb_probe()
>
> drivers/video/fbdev/aty/radeon_base.c | 1 +
> drivers/video/fbdev/broadsheetfb.c | 8 ++++++--
> drivers/video/fbdev/carminefb.c | 1 +
> drivers/video/fbdev/efifb.c | 1 +
> drivers/video/fbdev/hecubafb.c | 6 +++++-
> drivers/video/fbdev/i740fb.c | 1 +
> drivers/video/fbdev/metronomefb.c | 8 ++++++--
> drivers/video/fbdev/nvidia/nvidia.c | 1 +
> drivers/video/fbdev/s3fb.c | 1 +
> drivers/video/fbdev/sm501fb.c | 3 +++
> drivers/video/fbdev/tdfxfb.c | 1 +
> drivers/video/fbdev/tridentfb.c | 1 +
> drivers/video/fbdev/uvesafb.c | 4 ++--
> drivers/video/fbdev/vesafb.c | 1 +
> 14 files changed, 31 insertions(+), 7 deletions(-)
I applied the whole series to the fbdev git tree.
Thanks a lot !
Helge
^ permalink raw reply
* Re: [PATCH] fbcon: Use correct type for vc_resize() return value
From: Helge Deller @ 2026-05-19 7:18 UTC (permalink / raw)
To: Jiacheng Yu; +Cc: dri-devel, linux-fbdev, linux-kernel
In-Reply-To: <40ec54e6-78fb-400f-bb10-c277287162fb@suse.de>
On 5/15/26 09:12, Thomas Zimmermann wrote:
>
>
> Am 14.05.26 um 11:19 schrieb Jiacheng Yu:
>> The return value of vc_resize() is int, but fbcon_set_disp() stores it
>> in an unsigned long variable. While the !ret check happens to work
>> correctly by coincidence (negative values become large positive values),
>> the types should match. Use int instead.
>>
>> Eliminates the following W=3 warning:
>>
>> drivers/video/fbdev/core/fbcon.c: In function 'fbcon_set_disp':
>> drivers/video/fbdev/core/fbcon.c:1494:14: warning: implicit conversion from 'int' to 'unsigned long' [-Wconversion]
>>
>> Fixes: af0db3c1f898 ("fbdev: Fix vmalloc out-of-bounds write in fast_imageblit")
>> Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com>
>
> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
applied to fbdev git tree.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH] fbdev: chipsfb: add missing MODULE_DESCRIPTION() macro
From: Helge Deller @ 2026-05-19 7:34 UTC (permalink / raw)
To: Rahman Mahmutović, linux-fbdev; +Cc: dri-devel, linux-kernel
In-Reply-To: <20260509131831.1073-1-mahmutovicrahman5@gmail.com>
On 5/9/26 15:18, Rahman Mahmutović wrote:
> The chipsfb driver is missing the MODULE_DESCRIPTION macro which
> is required for all kernel modules.
>
> Assisted-by: Claude:claude-sonnet-4-6
> Signed-off-by: Rahman Mahmutović <mahmutovicrahman5@gmail.com>
> ---
> drivers/video/fbdev/chipsfb.c | 1 +
> 1 file changed, 1 insertion(+)
applied.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH v1] fbdev: Use named initializers for struct i2c_device_id
From: Helge Deller @ 2026-05-19 7:28 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: linux-fbdev, dri-devel, linux-kernel
In-Reply-To: <20260518160808.802423-2-u.kleine-koenig@baylibre.com>
On 5/18/26 18:08, Uwe Kleine-König (The Capable Hub) wrote:
> While being less compact, using named initializers allows to more easily
> see which members of the structs are assigned which value without having
> to lookup the declaration of the struct. And it's also more robust
> against changes to the struct definition.
>
..
> drivers/video/fbdev/matrox/matroxfb_maven.c | 2 +-
> drivers/video/fbdev/ssd1307fb.c | 8 ++++----
> 2 files changed, 5 insertions(+), 5 deletions(-)
applied to fbdev git tree.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH] fbdev: sunxvr2500: replace printk with device-aware logging functions
From: Helge Deller @ 2026-05-19 7:40 UTC (permalink / raw)
To: Rahman Mahmutović, linux-fbdev; +Cc: dri-devel, linux-kernel
In-Reply-To: <20260509135759.1391-1-mahmutovicrahman5@gmail.com>
On 5/9/26 15:57, Rahman Mahmutović wrote:
> Replace all printk() calls with appropriate device-aware logging
> functions to properly associate log messages with the PCI device.
>
> - Use pci_err() for errors where struct pci_dev is available
> - Use pci_info() for info messages where struct pci_dev is available
> - Use dev_err() for errors where only struct fb_info is available
>
> Remove redundant 's3d:' prefix and pci_name() calls as device-aware
> functions include device identification automatically.
>
> Assisted-by: Claude:claude-sonnet-4-6
> Signed-off-by: Rahman Mahmutović <mahmutovicrahman5@gmail.com>
> ---
> drivers/video/fbdev/sunxvr2500.c | 19 +++++++------------
> 1 file changed, 7 insertions(+), 12 deletions(-)
applied.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH] video: fbdev: remove Hercules monochrome ISA graphics adapter driver
From: Helge Deller @ 2026-05-19 7:49 UTC (permalink / raw)
To: Thomas Zimmermann, Ethan Nelson-Moore, linux-fbdev
In-Reply-To: <00b7e7f2-98e2-45af-b3c6-43140443cbe9@suse.de>
On 5/8/26 14:08, Thomas Zimmermann wrote:
> Am 03.05.26 um 06:56 schrieb Ethan Nelson-Moore:
>> The hgafb supports graphics adapters compatible with the Hercules
>> adapter from 1984. These were ISA cards or onboard devices that
>> supported monochrome 720x348 graphics. This driver was created in 1999
>> by Ferenc Bakonyi. In the entire Git history (since Linux 2.6.12-rc2),
>> there has only been one commit in 2010 which indicated that the driver
>> was in use, commit 529ed806d454 ("video: Fix the HGA framebuffer
>> driver"). The commit message states:
>> Only tested with fbcon, since most fbdev-based software appears
>> to only support 12bpp and up. It does not appear that this driver has
>> worked for at least the entire 2.6.x series, perhaps since 2002.
>> Given the age and limited capabilities of the hardware and the lack of
>> users, remove this driver and move the former maintainer to CREDITS.
>>
>> Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
>
> Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
applied to fbdev git tree.
This driver is now 27 years old, the card was developed 44 years ago,
and since we don't support i386 or i486 CPUs any longer, it's
really unlikely someone still uses this card.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH] fbdev: imxfb: Use of_device_get_match_data()
From: Helge Deller @ 2026-05-19 7:52 UTC (permalink / raw)
To: Rosen Penev, linux-fbdev
Cc: Sascha Hauer, Pengutronix Kernel Team, Frank Li, Fabio Estevam,
moderated list:FREESCALE IMX / MXC FRAMEBUFFER DRIVER,
open list:FRAMEBUFFER LAYER,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, open list
In-Reply-To: <20260518211303.10777-1-rosenp@gmail.com>
On 5/18/26 23:13, Rosen Penev wrote:
> Use of_device_get_match_data() to fetch the platform ID entry directly
> instead of open-coding an of_match_device() lookup. No NULL check is
> needed as every compatible string has a corresponding data section.
>
> This also lets the driver drop the of_device.h include.
>
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/video/fbdev/imxfb.c | 6 +-----
> 1 file changed, 1 insertion(+), 5 deletions(-)
applied.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH] fbcon: don't suspend/resume when vc is graphics mode
From: Helge Deller @ 2026-05-19 8:10 UTC (permalink / raw)
To: yaolu, tzimmermann, simona; +Cc: dri-devel, linux-fbdev, linux-kernel
In-Reply-To: <20260430060137.131107-1-yaolu@kylinos.cn>
Hello Lu,
On 4/30/26 08:01, yaolu@kylinos.cn wrote:
> From: Lu Yao <yaolu@kylinos.cn>
>
> Don't need to do suspend/resume for fbcon in graphic mode.
>
> Doing this may cause error, eg:
> At the beginning, starting the Xorg with single screen and then an
> external screen was plugged in. After logging out in Xorg, fbdev
> info may using screen which is connected later on for info always
> using first connected connector in list in func 'drm_setup_crtcs_fb'.
> Then, S3 executed, fbcon found that the information did not match
> and do atomic to switch fb. However, Xorg will not re-bind the crtc
> fb but continues doing ioctl. At this time, the fb is incorrect.
Do you still have the possibility to test this issue?
> Signed-off-by: Lu Yao <yaolu@kylinos.cn>
> ---
> drivers/video/fbdev/core/fbcon.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
> index b0e3e765360d..450e690d0bd2 100644
> --- a/drivers/video/fbdev/core/fbcon.c
> +++ b/drivers/video/fbdev/core/fbcon.c
> @@ -2602,8 +2602,9 @@ void fbcon_suspended(struct fb_info *info)
> return;
> vc = vc_cons[par->currcon].d;
>
> - /* Clear cursor, restore saved data */
> - fbcon_cursor(vc, false);
> + /* Don't need to clear cursor and restore saved data in graphic mode */
> + if (vc->vc_mode != KD_GRAPHICS)
> + fbcon_cursor(vc, false);
I think checking for "== KD_TEXT" is probably better.
And, maybe using con_is_visible(vc).
So:
+ if (con_is_visible(vc) && (vc->vc_mode == KD_TEXT))
+ fbcon_cursor(vc, false);
> void fbcon_resumed(struct fb_info *info)
> @@ -2615,7 +2616,9 @@ void fbcon_resumed(struct fb_info *info)
> return;
> vc = vc_cons[par->currcon].d;
>
> - update_screen(vc);
> + /* Graphics mode is managed by userspace */
> + if (vc->vc_mode != KD_GRAPHICS)
here the same check as above... ?
Helge
^ permalink raw reply
* Re: [PATCH v2 2/2] backlight: Add SY7758 6-channel High Efficiency LED Driver support
From: Neil Armstrong @ 2026-05-19 8:14 UTC (permalink / raw)
To: Daniel Thompson
Cc: Lee Jones, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Helge Deller, dri-devel,
linux-leds, devicetree, linux-kernel, linux-fbdev, KancyJoe
In-Reply-To: <agdJnpz9O00lywRm@aspen.lan>
Hi,
On 5/15/26 18:28, Daniel Thompson wrote:
> On Thu, Apr 30, 2026 at 11:47:16AM +0200, Neil Armstrong wrote:
>> From: KancyJoe <kancy2333@outlook.com>
>>
>> Implement support for the Silergy SY7758 6-channel High Efficiency LED
>> Driver used for backlight brightness control in the Ayaneo Pocket S2
>> dual-DSI panel.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> Signed-off-by: KancyJoe <kancy2333@outlook.com>
>> ---
>> drivers/video/backlight/Kconfig | 8 +
>> drivers/video/backlight/Makefile | 1 +
>> drivers/video/backlight/sy7758.c | 311 +++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 320 insertions(+)
>> <snip>
>> diff --git a/drivers/video/backlight/sy7758.c b/drivers/video/backlight/sy7758.c
>> new file mode 100644
>> index 000000000000..9b2d3bbb4ded
>> --- /dev/null
>> +++ b/drivers/video/backlight/sy7758.c
>> @@ -0,0 +1,311 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Silergy SY7758 6-channel High Efficiency LED Driver
>> + *
>> + * Copyright (C) 2025 Kancy Joe <kancy2333@outlook.com>
>> + * Copyright (C) 2026 Linaro Limited
>> + * Author: Neil Armstrong <neil.armstrong@linaro.org>
>
> I'm a bit confused by this comment. The git author and the
> MODULE_AUTHOR() is Kancy Joe. What does this comment signify?
I'll fix this in v3
>
>
>> + */
>> <snip>
>> +/* OTP memory */
>> +#define REG_OTP_CFG98 0x98
>> +#define REG_OTP_CFG9E 0x9E
>> +#define REG_OTP_CFG0 0xA0
>> +#define REG_OTP_CFG1 0xA1
>> +#define REG_OTP_CFG2 0xA2
>> +#define REG_OTP_CFG3 0xA3
>> +#define REG_OTP_CFG4 0xA4
>> +#define REG_OTP_CFG5 0xA5
>> +#define REG_OTP_CFG6 0xA6
>> +#define REG_OTP_CFG7 0xA7
>> +#define REG_OTP_CFG9 0xA9
>> +#define REG_OTP_CFGA 0xAA
>> +#define REG_OTP_CFGE 0xAE
>
> There seems to be a lot of unused macros here, especially
> combined with the unused bitfields that tell us how to interpret
> the values.
>
> Do we need them?
I'll drop those
>
>
>> <snip>
>> +static int sy7758_probe(struct i2c_client *client)
>> +{
>> + struct backlight_properties props = { };
>> + struct device *dev = &client->dev;
>> + struct sy7758 *sydev;
>> + unsigned int dev_id;
>> + int ret;
>> +
>> + sydev = devm_kzalloc(dev, sizeof(*sydev), GFP_KERNEL);
>> + if (!sydev)
>> + return -ENOMEM;
>> +
>> + i2c_set_clientdata(client, sydev);
>> +
>> + /* Initialize regmap */
>> + sydev->client = client;
>> + sydev->regmap = devm_regmap_init_i2c(client, &sy7758_regmap_config);
>> + if (IS_ERR(sydev->regmap))
>> + return dev_err_probe(dev, PTR_ERR(sydev->regmap),
>> + "failed to init regmap\n");
>> +
>> + /* Get and enable regulators */
>> + ret = devm_regulator_get_enable(dev, "vddio");
>> + if (ret)
>> + return dev_err_probe(dev, ret, "failed to get regulator\n");
>> +
>> + usleep_range(100, 200);
>
> Any reason not to use fsleep() here?
Thanks, I'll switch to fsleep
>
>
>> + /* Get enable GPIO and set to high */
>> + sydev->gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
>> + if (IS_ERR(sydev->gpio))
>> + return dev_err_probe(dev, PTR_ERR(sydev->gpio),
>> + "failed to get enable GPIO\n");
>> +
>> + /* Let some time for HW to settle */
>> + usleep_range(10000, 11000);
>
> And here?
>
>
>> +
>> + /* try read and check device id */
>> + ret = regmap_read(sydev->regmap, REG_DEV_ID, &dev_id);
>> + if (ret < 0)
>> + return dev_err_probe(dev, ret, "failed to read device id\n");
>> + if (dev_id != 0x63) {
>> + dev_err(dev, "unexpected device id: 0x%02x\n", dev_id);
>> + return -ENODEV;
>> + }
>> +
>> + /* Initialize and set default brightness */
>> + ret = sy7758_init(sydev);
>> + if (ret)
>> + return ret;
>> +
>> + props.type = BACKLIGHT_RAW;
>> + props.max_brightness = MAX_BRIGHTNESS;
>> + props.brightness = DEFAULT_BRIGHTNESS;
>> + props.scale = BACKLIGHT_SCALE_LINEAR;
>> +
>> + sydev->bl = devm_backlight_device_register(dev, "sy7758-backlight",
>> + dev, sydev, &sy7758_backlight_ops,
>> + &props);
>> + if (IS_ERR(sydev->bl))
>> + return dev_err_probe(dev, PTR_ERR(sydev->bl),
>> + "failed to register backlight device\n");
>> +
>> + return backlight_update_status(sydev->bl);
>> +}
>
>
> Daniel.
Thanks,
Neil
^ permalink raw reply
* [PATCH v3 0/2] backlight: Add SY7758 6-channel High Efficiency LED Driver support
From: Neil Armstrong @ 2026-05-19 8:43 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Helge Deller
Cc: dri-devel, linux-leds, devicetree, linux-kernel, linux-fbdev,
KancyJoe, Neil Armstrong, Krzysztof Kozlowski
Implement support for the Silergy SY7758 6-channel High Efficiency LED Driver
used for backlight brightness control in the Ayaneo Pocket S2 dual-DSI panel.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
Changes in v3:
- Dropped unused macros
- Added second autho entry to match header and commit message
- Move my signof at the end
- Switched to flseep()
- Link to v2: https://patch.msgid.link/20260430-topic-sm8650-ayaneo-pocket-s2-sy7758-v2-0-308140640de9@linaro.org
Changes in v2:
- Fixed bindings subject and removed "|"
- Added review tag
- Added higher delay before reading ID from HW (100us was too short)
- Removed probe defer if i2c read fails
- Link to v1: https://patch.msgid.link/20260428-topic-sm8650-ayaneo-pocket-s2-sy7758-v1-0-0caade5fdb32@linaro.org
---
KancyJoe (1):
backlight: Add SY7758 6-channel High Efficiency LED Driver support
Neil Armstrong (1):
dt-bindings: leds: backlight: document the SY7758 6-channel High Efficiency LED Driver
.../bindings/leds/backlight/silergy,sy7758.yaml | 53 +++++
drivers/video/backlight/Kconfig | 8 +
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/sy7758.c | 259 +++++++++++++++++++++
4 files changed, 321 insertions(+)
---
base-commit: 39704f00f747aba3144289870b5fd8ac230a9aaf
change-id: 20260428-topic-sm8650-ayaneo-pocket-s2-sy7758-3081ee7f1e25
Best regards,
--
Neil Armstrong <neil.armstrong@linaro.org>
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: leds: backlight: document the SY7758 6-channel High Efficiency LED Driver
From: Neil Armstrong @ 2026-05-19 8:43 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Helge Deller
Cc: dri-devel, linux-leds, devicetree, linux-kernel, linux-fbdev,
KancyJoe, Neil Armstrong, Krzysztof Kozlowski
In-Reply-To: <20260519-topic-sm8650-ayaneo-pocket-s2-sy7758-v3-0-ec8194bbc885@linaro.org>
Document the Silergy SY7758 6-channel High Efficiency LED Driver
used for backlight brightness control.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
.../bindings/leds/backlight/silergy,sy7758.yaml | 53 ++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/Documentation/devicetree/bindings/leds/backlight/silergy,sy7758.yaml b/Documentation/devicetree/bindings/leds/backlight/silergy,sy7758.yaml
new file mode 100644
index 000000000000..80e978d691c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/backlight/silergy,sy7758.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/backlight/silergy,sy7758.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Silergy SY7758 6-channel High Efficiency LED Driver
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+
+description:
+ Silergy SY7758 is a high efficiency 6-channels LED backlight
+ driver with I2C brightness control.
+
+allOf:
+ - $ref: common.yaml#
+
+properties:
+ compatible:
+ const: silergy,sy7758
+
+ reg:
+ maxItems: 1
+
+ vddio-supply: true
+
+ enable-gpios:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - vddio-supply
+ - enable-gpios
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ backlight@11 {
+ compatible = "silergy,sy7758";
+ reg = <0x11>;
+ vddio-supply = <&bl_vddio>;
+ enable-gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+ };
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/2] backlight: Add SY7758 6-channel High Efficiency LED Driver support
From: Neil Armstrong @ 2026-05-19 8:43 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Helge Deller
Cc: dri-devel, linux-leds, devicetree, linux-kernel, linux-fbdev,
KancyJoe, Neil Armstrong
In-Reply-To: <20260519-topic-sm8650-ayaneo-pocket-s2-sy7758-v3-0-ec8194bbc885@linaro.org>
From: KancyJoe <kancy2333@outlook.com>
Implement support for the Silergy SY7758 6-channel High Efficiency LED
Driver used for backlight brightness control in the Ayaneo Pocket S2
dual-DSI panel.
Signed-off-by: KancyJoe <kancy2333@outlook.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
drivers/video/backlight/Kconfig | 8 ++
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/sy7758.c | 259 +++++++++++++++++++++++++++++++++++++++
3 files changed, 268 insertions(+)
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index a7a3fbaf7c29..052ac80c8213 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -207,6 +207,14 @@ config BACKLIGHT_KTZ8866
Say Y to enable the backlight driver for the Kinetic KTZ8866
found in Xiaomi Mi Pad 5 series.
+config BACKLIGHT_SY7758
+ tristate "Backlight Driver for Silergy SY7758"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say Y to enable the backlight driver for the Silergy SY7758
+ backlight controller found in Ayaneo Socket S2.
+
config BACKLIGHT_LM3533
tristate "Backlight Driver for LM3533"
depends on MFD_LM3533
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 794820a98ed4..39ef588b1cf2 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_QCOM_WLED) += qcom-wled.o
obj-$(CONFIG_BACKLIGHT_RT4831) += rt4831-backlight.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
+obj-$(CONFIG_BACKLIGHT_SY7758) += sy7758.o
obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
diff --git a/drivers/video/backlight/sy7758.c b/drivers/video/backlight/sy7758.c
new file mode 100644
index 000000000000..a6087e687b64
--- /dev/null
+++ b/drivers/video/backlight/sy7758.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Silergy SY7758 6-channel High Efficiency LED Driver
+ *
+ * Copyright (C) 2025 Kancy Joe <kancy2333@outlook.com>
+ * Copyright (C) 2026 Linaro Limited
+ * Author: Neil Armstrong <neil.armstrong@linaro.org>
+ */
+#include <linux/backlight.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/err.h>
+#include <linux/bits.h>
+#include <linux/regmap.h>
+#include <linux/bitfield.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+
+#define DEFAULT_BRIGHTNESS 1024
+#define MAX_BRIGHTNESS 4080
+#define REG_MAX 0xAE
+
+/* Registers */
+#define REG_DEV_CTL 0x01
+#define REG_DEV_ID 0x03
+#define REG_BRT_12BIT_L 0x10
+#define REG_BRT_12BIT_H 0x11
+
+/* OTP memory */
+#define REG_OTP_CFG0 0xA0
+#define REG_OTP_CFG1 0xA1
+#define REG_OTP_CFG2 0xA2
+#define REG_OTP_CFG5 0xA5
+#define REG_OTP_CFG9 0xA9
+
+/* Fields */
+#define BIT_DEV_CTL_FAST BIT(7)
+#define MSK_DEV_CTL_BRT_MODE GENMASK(2, 1)
+#define BIT_DEV_CTL_BL_CTLB BIT(0)
+
+#define MSK_BRT_12BIT_L GENMASK(7, 0)
+#define MSK_BRT_12BIT_H GENMASK(3, 0)
+#define MSK_LED_ENABLE GENMASK(5, 0)
+
+#define MSK_CFG0_CURRENT_LOW GENMASK(7, 0)
+
+#define BIT_CFG1_PDET_STDBY BIT(7)
+#define MSK_CFG1_CURRENT_MAX GENMASK(6, 4)
+#define MSK_CFG1_CURRENT_HIGH GENMASK(3, 0)
+
+#define BIT_CFG2_UVLO_EN BIT(5)
+#define BIT_CFG2_UVLO_TH BIT(4)
+#define BIT_CFG2_BL_ON BIT(3)
+#define BIT_CFG2_ISET_EN BIT(2)
+#define BIT_CFG2_BST_ESET_EN BIT(1)
+
+#define BIT_CFG5_PWM_DIRECT BIT(7)
+#define MSK_CFG5_PS_MODE GENMASK(6, 4)
+#define MSK_CFG5_PWM_FREQ GENMASK(3, 0)
+
+#define MSK_CFG9_VBST_MAX GENMASK(7, 5)
+#define BIT_CFG9_JUMP_EN BIT(4)
+#define MSK_CFG9_JUMP_TH GENMASK(3, 2)
+#define MSK_CFG9_JUMP_VOLTAGE GENMASK(1, 0)
+
+struct sy7758 {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct gpio_desc *gpio;
+ struct backlight_device *bl;
+};
+
+static const struct regmap_config sy7758_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_MAX,
+};
+
+static int sy7758_backlight_update_status(struct backlight_device *backlight_dev)
+{
+ struct sy7758 *sydev = bl_get_data(backlight_dev);
+ unsigned int brightness = backlight_get_brightness(backlight_dev);
+ int ret;
+
+ ret = regmap_write(sydev->regmap, REG_BRT_12BIT_L,
+ FIELD_PREP(MSK_BRT_12BIT_L,
+ brightness & 0xff));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_BRT_12BIT_H,
+ FIELD_PREP(MSK_BRT_12BIT_H,
+ (brightness >> 8) & 0xf));
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct backlight_ops sy7758_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = sy7758_backlight_update_status,
+};
+
+static int sy7758_init(struct sy7758 *sydev)
+{
+ int ret = 0;
+
+ ret = regmap_write(sydev->regmap, REG_DEV_CTL,
+ BIT_DEV_CTL_FAST | BIT_DEV_CTL_BL_CTLB |
+ FIELD_PREP(MSK_DEV_CTL_BRT_MODE, 2));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_BRT_12BIT_L,
+ FIELD_PREP(MSK_BRT_12BIT_L,
+ DEFAULT_BRIGHTNESS & 0xff));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_BRT_12BIT_H,
+ FIELD_PREP(MSK_BRT_12BIT_H,
+ (DEFAULT_BRIGHTNESS >> 8)));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_OTP_CFG5,
+ FIELD_PREP(MSK_CFG5_PS_MODE, 6) |
+ FIELD_PREP(MSK_CFG5_PWM_FREQ, 4));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_OTP_CFG0,
+ FIELD_PREP(MSK_CFG0_CURRENT_LOW, 85));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_OTP_CFG1,
+ BIT_CFG1_PDET_STDBY |
+ FIELD_PREP(MSK_CFG1_CURRENT_MAX, 1) |
+ FIELD_PREP(MSK_CFG1_CURRENT_HIGH, 10));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_OTP_CFG9,
+ FIELD_PREP(MSK_CFG9_VBST_MAX, 4));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(sydev->regmap, REG_OTP_CFG2,
+ BIT_CFG2_BL_ON | BIT_CFG2_UVLO_EN);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int sy7758_probe(struct i2c_client *client)
+{
+ struct backlight_properties props = { };
+ struct device *dev = &client->dev;
+ struct sy7758 *sydev;
+ unsigned int dev_id;
+ int ret;
+
+ sydev = devm_kzalloc(dev, sizeof(*sydev), GFP_KERNEL);
+ if (!sydev)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, sydev);
+
+ /* Initialize regmap */
+ sydev->client = client;
+ sydev->regmap = devm_regmap_init_i2c(client, &sy7758_regmap_config);
+ if (IS_ERR(sydev->regmap))
+ return dev_err_probe(dev, PTR_ERR(sydev->regmap),
+ "failed to init regmap\n");
+
+ /* Get and enable regulators */
+ ret = devm_regulator_get_enable(dev, "vddio");
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get regulator\n");
+
+ fsleep(100);
+
+ /* Get enable GPIO and set to high */
+ sydev->gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(sydev->gpio))
+ return dev_err_probe(dev, PTR_ERR(sydev->gpio),
+ "failed to get enable GPIO\n");
+
+ /* Let some time for HW to settle */
+ fsleep(10000);
+
+ /* try read and check device id */
+ ret = regmap_read(sydev->regmap, REG_DEV_ID, &dev_id);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "failed to read device id\n");
+ if (dev_id != 0x63) {
+ dev_err(dev, "unexpected device id: 0x%02x\n", dev_id);
+ return -ENODEV;
+ }
+
+ /* Initialize and set default brightness */
+ ret = sy7758_init(sydev);
+ if (ret)
+ return ret;
+
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = MAX_BRIGHTNESS;
+ props.brightness = DEFAULT_BRIGHTNESS;
+ props.scale = BACKLIGHT_SCALE_LINEAR;
+
+ sydev->bl = devm_backlight_device_register(dev, "sy7758-backlight",
+ dev, sydev, &sy7758_backlight_ops,
+ &props);
+ if (IS_ERR(sydev->bl))
+ return dev_err_probe(dev, PTR_ERR(sydev->bl),
+ "failed to register backlight device\n");
+
+ return backlight_update_status(sydev->bl);
+}
+
+static void sy7758_remove(struct i2c_client *client)
+{
+ struct sy7758 *sydev = i2c_get_clientdata(client);
+
+ backlight_disable(sydev->bl);
+}
+
+static const struct i2c_device_id sy7758_ids[] = {
+ { "sy7758" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, sy7758_ids);
+
+static const struct of_device_id sy7758_match_table[] = {
+ { .compatible = "silergy,sy7758", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, sy7758_match_table);
+
+static struct i2c_driver sy7758_driver = {
+ .driver = {
+ .name = "sy7758",
+ .of_match_table = sy7758_match_table,
+ },
+ .probe = sy7758_probe,
+ .remove = sy7758_remove,
+ .id_table = sy7758_ids,
+};
+
+module_i2c_driver(sy7758_driver);
+
+MODULE_DESCRIPTION("Silergy SY7758 Backlight Driver");
+MODULE_AUTHOR("Kancy Joe <kancy2333@outlook.com>");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox