* [PATCH v5 07/14] mfd: lm3533: Use dev_groups in struct device_driver
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Instead of creating and removing the device sysfs attributes directly
during probe and remove of the driver, respectively, use dev_groups in
struct device_driver to point to the attribute definitions and let the
core take care of creating and removing them.
No intentional functional impact.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/mfd/lm3533-core.c | 16 ++++++----------
drivers/video/backlight/lm3533_bl.c | 22 ++++++++--------------
2 files changed, 14 insertions(+), 24 deletions(-)
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index 45e7f7481aa0..b03a3ae96c10 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -296,6 +296,11 @@ static struct attribute_group lm3533_attribute_group = {
.attrs = lm3533_attributes
};
+static const struct attribute_group *lm3533_attribute_groups[] = {
+ &lm3533_attribute_group,
+ NULL,
+};
+
static int lm3533_device_als_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
@@ -416,16 +421,8 @@ static int lm3533_device_init(struct lm3533 *lm3533)
lm3533_device_bl_init(lm3533);
lm3533_device_led_init(lm3533);
- ret = sysfs_create_group(&lm3533->dev->kobj, &lm3533_attribute_group);
- if (ret < 0) {
- dev_err(lm3533->dev, "failed to create sysfs attributes\n");
- goto err_unregister;
- }
-
return 0;
-err_unregister:
- mfd_remove_devices(lm3533->dev);
err_disable:
lm3533_disable(lm3533);
@@ -436,8 +433,6 @@ static void lm3533_device_exit(struct lm3533 *lm3533)
{
dev_dbg(lm3533->dev, "%s\n", __func__);
- sysfs_remove_group(&lm3533->dev->kobj, &lm3533_attribute_group);
-
mfd_remove_devices(lm3533->dev);
lm3533_disable(lm3533);
}
@@ -532,6 +527,7 @@ MODULE_DEVICE_TABLE(i2c, lm3533_i2c_ids);
static struct i2c_driver lm3533_i2c_driver = {
.driver = {
.name = "lm3533",
+ .dev_groups = lm3533_attribute_groups,
},
.id_table = lm3533_i2c_ids,
.probe = lm3533_i2c_probe,
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 4d6f68033480..9ef171d3aaea 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -237,6 +237,11 @@ static struct attribute_group lm3533_bl_attribute_group = {
.attrs = lm3533_bl_attributes
};
+static const struct attribute_group *lm3533_bl_attribute_groups[] = {
+ &lm3533_bl_attribute_group,
+ NULL,
+};
+
static int lm3533_bl_setup(struct lm3533_bl *bl,
struct lm3533_bl_platform_data *pdata)
{
@@ -304,28 +309,17 @@ static int lm3533_bl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bl);
- ret = sysfs_create_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to create sysfs attributes\n");
- return ret;
- }
-
backlight_update_status(bd);
ret = lm3533_bl_setup(bl, pdata);
if (ret)
- goto err_sysfs_remove;
+ return ret;
ret = lm3533_ctrlbank_enable(&bl->cb);
if (ret)
- goto err_sysfs_remove;
+ return ret;
return 0;
-
-err_sysfs_remove:
- sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
-
- return ret;
}
static void lm3533_bl_remove(struct platform_device *pdev)
@@ -339,7 +333,6 @@ static void lm3533_bl_remove(struct platform_device *pdev)
bd->props.brightness = 0;
lm3533_ctrlbank_disable(&bl->cb);
- sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
}
#ifdef CONFIG_PM_SLEEP
@@ -377,6 +370,7 @@ static struct platform_driver lm3533_bl_driver = {
.driver = {
.name = "lm3533-backlight",
.pm = &lm3533_bl_pm_ops,
+ .dev_groups = lm3533_bl_attribute_groups,
},
.probe = lm3533_bl_probe,
.remove = lm3533_bl_remove,
--
2.53.0
^ permalink raw reply related
* [PATCH v5 08/14] mfd: lm3533: Convert to use OF bindings
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-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.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Daniel Thompson (RISCstar) <danielt@kernel.org> #for backlight
---
drivers/iio/light/lm3533-als.c | 67 +++++---
drivers/leds/leds-lm3533.c | 50 ++++--
drivers/mfd/lm3533-core.c | 236 ++++++++++++----------------
drivers/mfd/lm3533-ctrlbank.c | 5 -
drivers/video/backlight/lm3533_bl.c | 55 +++++--
include/linux/mfd/lm3533.h | 52 +-----
6 files changed, 220 insertions(+), 245 deletions(-)
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index 69bac1b202f1..80f8fa700263 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -16,16 +16,19 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/mfd/core.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/units.h>
#include <linux/mfd/lm3533.h>
-#define LM3533_ALS_RESISTOR_MIN 1
-#define LM3533_ALS_RESISTOR_MAX 127
+#define LM3533_ALS_RESISTOR_MIN_OHMS 1575
+#define LM3533_ALS_RESISTOR_MAX_OHMS 200000
#define LM3533_ALS_CHANNEL_CURRENT_MAX 2
#define LM3533_ALS_THRESH_MAX 3
#define LM3533_ALS_ZONE_MAX 4
@@ -57,6 +60,9 @@ struct lm3533_als {
atomic_t zone;
struct mutex thresh_mutex;
+
+ u32 r_select;
+ bool pwm_mode;
};
@@ -403,7 +409,7 @@ static ssize_t show_thresh_either_en(struct device *dev,
int enable;
int ret;
- if (als->irq) {
+ if (als->irq > 0) {
ret = lm3533_als_get_int_mode(indio_dev, &enable);
if (ret)
return ret;
@@ -425,7 +431,7 @@ static ssize_t store_thresh_either_en(struct device *dev,
u8 zone;
int ret;
- if (!als->irq)
+ if (als->irq <= 0)
return -EBUSY;
if (kstrtoul(buf, 0, &enable))
@@ -708,29 +714,38 @@ static const struct attribute_group lm3533_als_attribute_group = {
.attrs = lm3533_als_attributes
};
-static int lm3533_als_setup(struct lm3533_als *als,
- const struct lm3533_als_platform_data *pdata)
+static int lm3533_als_setup(struct lm3533_als *als)
{
struct device *dev = &als->pdev->dev;
int ret;
+ als->pwm_mode = device_property_read_bool(dev, "ti,pwm-mode");
+
ret = regmap_assign_bits(als->regmap, LM3533_REG_ALS_CONF,
- LM3533_ALS_INPUT_MODE_MASK, pdata->pwm_mode);
+ LM3533_ALS_INPUT_MODE_MASK, als->pwm_mode);
if (ret)
return dev_err_probe(dev, ret, "failed to set input mode %d\n",
- pdata->pwm_mode);
+ als->pwm_mode);
/* Bail out when in PWM-mode */
- if (pdata->pwm_mode)
+ if (als->pwm_mode)
return 0;
- if (pdata->r_select < LM3533_ALS_RESISTOR_MIN ||
- pdata->r_select > LM3533_ALS_RESISTOR_MAX)
+ ret = device_property_read_u32(dev, "ti,resistor-ohms",
+ &als->r_select);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to ger resistor value\n");
+
+ if (als->r_select < LM3533_ALS_RESISTOR_MIN_OHMS ||
+ als->r_select > LM3533_ALS_RESISTOR_MAX_OHMS)
return dev_err_probe(dev, -EINVAL,
"invalid resistor value\n");
+ als->r_select = DIV_ROUND_UP(2 * MICRO, 10 * als->r_select);
+
ret = regmap_write(als->regmap, LM3533_REG_ALS_RESISTOR_SELECT,
- pdata->r_select);
+ als->r_select);
if (ret)
return dev_err_probe(dev, ret, "failed to set resistor\n");
@@ -793,7 +808,6 @@ static const struct iio_info lm3533_als_info = {
static int lm3533_als_probe(struct platform_device *pdev)
{
- const struct lm3533_als_platform_data *pdata;
struct lm3533 *lm3533;
struct lm3533_als *als;
struct iio_dev *indio_dev;
@@ -803,12 +817,6 @@ static int lm3533_als_probe(struct platform_device *pdev)
if (!lm3533)
return -EINVAL;
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
if (!indio_dev)
return -ENOMEM;
@@ -817,25 +825,27 @@ static int lm3533_als_probe(struct platform_device *pdev)
indio_dev->channels = lm3533_als_channels;
indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels);
indio_dev->name = dev_name(&pdev->dev);
- iio_device_set_parent(indio_dev, pdev->dev.parent);
indio_dev->modes = INDIO_DIRECT_MODE;
als = iio_priv(indio_dev);
als->regmap = lm3533->regmap;
als->pdev = pdev;
- als->irq = lm3533->irq;
+ als->irq = platform_get_irq_optional(pdev, 0);
+ if (als->irq == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
atomic_set(&als->zone, 0);
mutex_init(&als->thresh_mutex);
platform_set_drvdata(pdev, indio_dev);
- if (als->irq) {
+ if (als->irq > 0) {
ret = lm3533_als_setup_irq(als, indio_dev);
if (ret)
return ret;
}
- ret = lm3533_als_setup(als, pdata);
+ ret = lm3533_als_setup(als);
if (ret)
goto err_free_irq;
@@ -854,7 +864,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
err_disable:
lm3533_als_disable(als);
err_free_irq:
- if (als->irq)
+ if (als->irq > 0)
free_irq(als->irq, indio_dev);
return ret;
@@ -868,13 +878,20 @@ static void lm3533_als_remove(struct platform_device *pdev)
lm3533_als_set_int_mode(indio_dev, false);
iio_device_unregister(indio_dev);
lm3533_als_disable(als);
- if (als->irq)
+ if (als->irq > 0)
free_irq(als->irq, indio_dev);
}
+static const struct of_device_id lm3533_als_match_table[] = {
+ { .compatible = "ti,lm3533-als" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lm3533_als_match_table);
+
static struct platform_driver lm3533_als_driver = {
.driver = {
.name = "lm3533-als",
+ .of_match_table = lm3533_als_match_table,
},
.probe = lm3533_als_probe,
.remove = lm3533_als_remove,
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index 0cb0585eb960..ed810c23f30f 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -10,8 +10,10 @@
#include <linux/module.h>
#include <linux/leds.h>
#include <linux/mfd/core.h>
+#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -50,6 +52,9 @@ struct lm3533_led {
struct mutex mutex;
unsigned long flags;
+ u32 max_current;
+ u32 pwm;
+
bool have_als;
};
@@ -616,22 +621,20 @@ static const struct attribute_group *lm3533_led_attribute_groups[] = {
NULL
};
-static int lm3533_led_setup(struct lm3533_led *led,
- struct lm3533_led_platform_data *pdata)
+static int lm3533_led_setup(struct lm3533_led *led)
{
int ret;
- ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
+ ret = lm3533_ctrlbank_set_max_current(&led->cb, led->max_current);
if (ret)
return ret;
- return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
+ return lm3533_ctrlbank_set_pwm(&led->cb, led->pwm);
}
static int lm3533_led_probe(struct platform_device *pdev)
{
struct lm3533 *lm3533;
- struct lm3533_led_platform_data *pdata;
struct lm3533_led *led;
int ret;
@@ -641,12 +644,6 @@ static int lm3533_led_probe(struct platform_device *pdev)
if (!lm3533)
return -EINVAL;
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
return -EINVAL;
@@ -659,8 +656,6 @@ static int lm3533_led_probe(struct platform_device *pdev)
led->regmap = lm3533->regmap;
led->have_als = lm3533->have_als;
- led->cdev.name = pdata->name;
- led->cdev.default_trigger = pdata->default_trigger;
led->cdev.brightness_set_blocking = lm3533_led_set;
led->cdev.brightness_get = lm3533_led_get;
led->cdev.blink_set = lm3533_led_blink_set;
@@ -668,6 +663,15 @@ static int lm3533_led_probe(struct platform_device *pdev)
led->cdev.groups = lm3533_led_attribute_groups;
led->id = pdev->id;
+ led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%d",
+ pdev->name, led->id);
+ if (!led->cdev.name)
+ return -ENOMEM;
+
+ led->cdev.default_trigger = "none";
+ device_property_read_string(&pdev->dev, "linux,default-trigger",
+ &led->cdev.default_trigger);
+
mutex_init(&led->mutex);
/* The class framework makes a callback to get brightness during
@@ -680,15 +684,22 @@ static int lm3533_led_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, led);
- ret = led_classdev_register(pdev->dev.parent, &led->cdev);
+ ret = led_classdev_register(&pdev->dev, &led->cdev);
if (ret) {
- dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
+ dev_err(&pdev->dev, "failed to register LED %d\n", led->id);
return ret;
}
led->cb.dev = led->cdev.dev;
- ret = lm3533_led_setup(led, pdata);
+ device_property_read_u32(&pdev->dev, "led-max-microamp",
+ &led->max_current);
+ led->max_current = clamp(led->max_current, LM3533_MAX_CURRENT_MIN,
+ LM3533_MAX_CURRENT_MAX);
+
+ device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &led->pwm);
+
+ ret = lm3533_led_setup(led);
if (ret)
goto err_deregister;
@@ -725,9 +736,16 @@ static void lm3533_led_shutdown(struct platform_device *pdev)
lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */
}
+static const struct of_device_id lm3533_led_match_table[] = {
+ { .compatible = "ti,lm3533-leds" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lm3533_led_match_table);
+
static struct platform_driver lm3533_led_driver = {
.driver = {
.name = "lm3533-leds",
+ .of_match_table = lm3533_led_match_table,
},
.probe = lm3533_led_probe,
.remove = lm3533_led_remove,
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index b03a3ae96c10..a5aa7da9668b 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -14,19 +14,26 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/mfd/core.h>
+#include <linux/mod_devicetable.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/units.h>
#include <linux/mfd/lm3533.h>
#define LM3533_BOOST_OVP_MASK 0x06
#define LM3533_BOOST_OVP_SHIFT 1
+#define LM3533_BOOST_OVP_MIN (16 * MICRO)
+#define LM3533_BOOST_OVP_MAX (40 * MICRO)
#define LM3533_BOOST_FREQ_MASK 0x01
#define LM3533_BOOST_FREQ_SHIFT 0
+#define LM3533_BOOST_FREQ_MIN (500 * HZ_PER_KHZ)
+#define LM3533_BOOST_FREQ_MAX (1000 * HZ_PER_KHZ)
#define LM3533_BL_ID_MASK 1
#define LM3533_LED_ID_MASK 3
@@ -35,6 +42,7 @@
#define LM3533_HVLED_ID_MAX 2
#define LM3533_LVLED_ID_MAX 5
+#define LM3533_CELLS_MAX 7
#define LM3533_REG_OUTPUT_CONF1 0x10
#define LM3533_REG_OUTPUT_CONF2 0x11
@@ -42,44 +50,6 @@
#define LM3533_REG_MAX 0xb2
-
-static struct mfd_cell lm3533_als_devs[] = {
- {
- .name = "lm3533-als",
- .id = -1,
- },
-};
-
-static struct mfd_cell lm3533_bl_devs[] = {
- {
- .name = "lm3533-backlight",
- .id = 0,
- },
- {
- .name = "lm3533-backlight",
- .id = 1,
- },
-};
-
-static struct mfd_cell lm3533_led_devs[] = {
- {
- .name = "lm3533-leds",
- .id = 0,
- },
- {
- .name = "lm3533-leds",
- .id = 1,
- },
- {
- .name = "lm3533-leds",
- .id = 2,
- },
- {
- .name = "lm3533-leds",
- .id = 3,
- },
-};
-
/*
* HVLED output config -- output hvled controlled by backlight bl
*/
@@ -301,125 +271,91 @@ static const struct attribute_group *lm3533_attribute_groups[] = {
NULL,
};
-static int lm3533_device_als_init(struct lm3533 *lm3533)
-{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
- int ret;
-
- if (!pdata->als)
- return 0;
-
- lm3533_als_devs[0].platform_data = pdata->als;
- lm3533_als_devs[0].pdata_size = sizeof(*pdata->als);
-
- ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL,
- 0, NULL);
- if (ret) {
- dev_err(lm3533->dev, "failed to add ALS device\n");
- return ret;
- }
-
- lm3533->have_als = 1;
-
- return 0;
-}
-
-static int lm3533_device_bl_init(struct lm3533 *lm3533)
-{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
- int i;
- int ret;
-
- if (!pdata->backlights || pdata->num_backlights == 0)
- return 0;
-
- if (pdata->num_backlights > ARRAY_SIZE(lm3533_bl_devs))
- pdata->num_backlights = ARRAY_SIZE(lm3533_bl_devs);
-
- for (i = 0; i < pdata->num_backlights; ++i) {
- lm3533_bl_devs[i].platform_data = &pdata->backlights[i];
- lm3533_bl_devs[i].pdata_size = sizeof(pdata->backlights[i]);
- }
-
- ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs,
- pdata->num_backlights, NULL, 0, NULL);
- if (ret) {
- dev_err(lm3533->dev, "failed to add backlight devices\n");
- return ret;
- }
-
- lm3533->have_backlights = 1;
-
- return 0;
-}
-
-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]);
- }
-
- ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
- pdata->num_leds, NULL, 0, NULL);
- if (ret) {
- dev_err(lm3533->dev, "failed to add LED devices\n");
- return ret;
- }
-
- lm3533->have_leds = 1;
-
- return 0;
-}
-
static int lm3533_device_init(struct lm3533 *lm3533)
{
- struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
+ struct device *dev = lm3533->dev;
+ struct mfd_cell *lm3533_devices;
+ u32 count = 0, reg, nchilds;
int ret;
- dev_dbg(lm3533->dev, "%s\n", __func__);
+ nchilds = device_get_child_node_count(dev);
+ if (!nchilds || nchilds > LM3533_CELLS_MAX)
+ return dev_err_probe(dev, -ENODEV,
+ "num of child nodes is not supported\n");
- if (!pdata) {
- dev_err(lm3533->dev, "no platform data\n");
- return -EINVAL;
- }
+ lm3533_devices = devm_kcalloc(dev, nchilds, sizeof(*lm3533_devices),
+ GFP_KERNEL);
+ if (!lm3533_devices)
+ return -ENOMEM;
- lm3533->hwen = devm_gpiod_get(lm3533->dev, NULL, GPIOD_OUT_LOW);
- if (IS_ERR(lm3533->hwen))
- return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen), "failed to request HWEN GPIO\n");
- gpiod_set_consumer_name(lm3533->hwen, "lm3533-hwen");
+ device_for_each_child_node_scoped(dev, child) {
+ if (count >= nchilds)
+ break;
+
+ if (fwnode_device_is_compatible(child, "ti,lm3533-als")) {
+ lm3533_devices[count].name = "lm3533-als";
+ lm3533_devices[count].of_compatible = "ti,lm3533-als";
+ lm3533_devices[count].id = PLATFORM_DEVID_NONE;
+
+ lm3533->have_als = true;
+ count++;
+ } else 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 node %pfw\n", child);
+ continue;
+ }
+
+ lm3533_devices[count].name = "lm3533-backlight";
+ lm3533_devices[count].of_compatible = "ti,lm3533-backlight";
+ lm3533_devices[count].id = reg;
+ lm3533_devices[count].of_reg = reg;
+ lm3533_devices[count].use_of_reg = true;
+
+ lm3533->have_backlights = true;
+ count++;
+ } else 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 node %pfw\n", child);
+ continue;
+ }
+
+ lm3533_devices[count].name = "lm3533-leds";
+ lm3533_devices[count].of_compatible = "ti,lm3533-leds";
+ lm3533_devices[count].id = reg - LM3533_HVLED_ID_MAX;
+ lm3533_devices[count].of_reg = reg;
+ lm3533_devices[count].use_of_reg = true;
+
+ lm3533->have_leds = true;
+ count++;
+ }
+ }
lm3533_enable(lm3533);
ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM,
LM3533_BOOST_FREQ_MASK,
- pdata->boost_freq << LM3533_BOOST_FREQ_SHIFT);
+ lm3533->boost_freq << LM3533_BOOST_FREQ_SHIFT);
if (ret) {
- dev_err(lm3533->dev, "failed to set boost frequency\n");
+ dev_err(dev, "failed to set boost frequency\n");
goto err_disable;
}
ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM,
LM3533_BOOST_OVP_MASK,
- pdata->boost_ovp << LM3533_BOOST_OVP_SHIFT);
+ lm3533->boost_ovp << LM3533_BOOST_OVP_SHIFT);
if (ret) {
- dev_err(lm3533->dev, "failed to set boost ovp\n");
+ dev_err(dev, "failed to set boost ovp\n");
goto err_disable;
}
- lm3533_device_als_init(lm3533);
- lm3533_device_bl_init(lm3533);
- lm3533_device_led_init(lm3533);
+ ret = mfd_add_devices(dev, 0, lm3533_devices, count, NULL, 0, NULL);
+ if (ret) {
+ dev_err(dev, "failed to add MFD devices: %d\n", ret);
+ goto err_disable;
+ }
return 0;
@@ -504,7 +440,26 @@ static int lm3533_i2c_probe(struct i2c_client *i2c)
return PTR_ERR(lm3533->regmap);
lm3533->dev = &i2c->dev;
- lm3533->irq = i2c->irq;
+
+ lm3533->hwen = devm_gpiod_get_optional(lm3533->dev, "enable",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(lm3533->hwen))
+ return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen),
+ "failed to get HWEN GPIO\n");
+
+ device_property_read_u32(lm3533->dev, "ti,boost-ovp-microvolt",
+ &lm3533->boost_ovp);
+
+ lm3533->boost_ovp = clamp(lm3533->boost_ovp, LM3533_BOOST_OVP_MIN,
+ LM3533_BOOST_OVP_MAX);
+ lm3533->boost_ovp = lm3533->boost_ovp / (8 * MICRO) - 2;
+
+ device_property_read_u32(lm3533->dev, "ti,boost-freq-hz",
+ &lm3533->boost_freq);
+
+ lm3533->boost_freq = clamp(lm3533->boost_freq, LM3533_BOOST_FREQ_MIN,
+ LM3533_BOOST_FREQ_MAX);
+ lm3533->boost_freq = lm3533->boost_freq / (500 * KILO) - 1;
return lm3533_device_init(lm3533);
}
@@ -518,6 +473,12 @@ static void lm3533_i2c_remove(struct i2c_client *i2c)
lm3533_device_exit(lm3533);
}
+static const struct of_device_id lm3533_match_table[] = {
+ { .compatible = "ti,lm3533" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lm3533_match_table);
+
static const struct i2c_device_id lm3533_i2c_ids[] = {
{ "lm3533" },
{ }
@@ -528,6 +489,7 @@ static struct i2c_driver lm3533_i2c_driver = {
.driver = {
.name = "lm3533",
.dev_groups = lm3533_attribute_groups,
+ .of_match_table = lm3533_match_table,
},
.id_table = lm3533_i2c_ids,
.probe = lm3533_i2c_probe,
diff --git a/drivers/mfd/lm3533-ctrlbank.c b/drivers/mfd/lm3533-ctrlbank.c
index 91e13cfa3cf0..3aab8ece4e8c 100644
--- a/drivers/mfd/lm3533-ctrlbank.c
+++ b/drivers/mfd/lm3533-ctrlbank.c
@@ -13,11 +13,6 @@
#include <linux/mfd/lm3533.h>
-
-#define LM3533_MAX_CURRENT_MIN 5000
-#define LM3533_MAX_CURRENT_MAX 29800
-#define LM3533_MAX_CURRENT_STEP 800
-
#define LM3533_PWM_MAX 0x3f
#define LM3533_REG_PWM_BASE 0x14
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 9ef171d3aaea..2c24647fc17a 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -9,7 +9,9 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/backlight.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -29,6 +31,9 @@ struct lm3533_bl {
struct backlight_device *bd;
int id;
+ u32 max_current;
+ u32 pwm;
+
bool have_als;
};
@@ -242,25 +247,25 @@ static const struct attribute_group *lm3533_bl_attribute_groups[] = {
NULL,
};
-static int lm3533_bl_setup(struct lm3533_bl *bl,
- struct lm3533_bl_platform_data *pdata)
+static int lm3533_bl_setup(struct lm3533_bl *bl)
{
int ret;
- ret = lm3533_ctrlbank_set_max_current(&bl->cb, pdata->max_current);
+ ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current);
if (ret)
return ret;
- return lm3533_ctrlbank_set_pwm(&bl->cb, pdata->pwm);
+ return lm3533_ctrlbank_set_pwm(&bl->cb, bl->pwm);
}
static int lm3533_bl_probe(struct platform_device *pdev)
{
struct lm3533 *lm3533;
- struct lm3533_bl_platform_data *pdata;
struct lm3533_bl *bl;
struct backlight_device *bd;
struct backlight_properties props;
+ char *name = NULL;
+ u32 default_brightness = LM3533_BL_MAX_BRIGHTNESS;
int ret;
dev_dbg(&pdev->dev, "%s\n", __func__);
@@ -269,12 +274,6 @@ static int lm3533_bl_probe(struct platform_device *pdev)
if (!lm3533)
return -EINVAL;
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
if (pdev->id < 0 || pdev->id >= LM3533_HVCTRLBANK_COUNT) {
dev_err(&pdev->dev, "illegal backlight id %d\n", pdev->id);
return -EINVAL;
@@ -292,13 +291,21 @@ static int lm3533_bl_probe(struct platform_device *pdev)
bl->cb.id = lm3533_bl_get_ctrlbank_id(bl);
bl->cb.dev = NULL; /* until registered */
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%d",
+ pdev->name, pdev->id);
+ if (!name)
+ return -ENOMEM;
+
+ device_property_read_u32(&pdev->dev, "default-brightness",
+ &default_brightness);
+
memset(&props, 0, sizeof(props));
props.type = BACKLIGHT_RAW;
props.max_brightness = LM3533_BL_MAX_BRIGHTNESS;
- props.brightness = pdata->default_brightness;
- bd = devm_backlight_device_register(&pdev->dev, pdata->name,
- pdev->dev.parent, bl, &lm3533_bl_ops,
- &props);
+ props.brightness = default_brightness;
+
+ bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev,
+ bl, &lm3533_bl_ops, &props);
if (IS_ERR(bd)) {
dev_err(&pdev->dev, "failed to register backlight device\n");
return PTR_ERR(bd);
@@ -309,12 +316,19 @@ static int lm3533_bl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bl);
- backlight_update_status(bd);
+ device_property_read_u32(&pdev->dev, "led-max-microamp",
+ &bl->max_current);
+ bl->max_current = clamp(bl->max_current, LM3533_MAX_CURRENT_MIN,
+ LM3533_MAX_CURRENT_MAX);
- ret = lm3533_bl_setup(bl, pdata);
+ device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &bl->pwm);
+
+ ret = lm3533_bl_setup(bl);
if (ret)
return ret;
+ backlight_update_status(bd);
+
ret = lm3533_ctrlbank_enable(&bl->cb);
if (ret)
return ret;
@@ -366,11 +380,18 @@ static void lm3533_bl_shutdown(struct platform_device *pdev)
lm3533_ctrlbank_disable(&bl->cb);
}
+static const struct of_device_id lm3533_bl_match_table[] = {
+ { .compatible = "ti,lm3533-backlight" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lm3533_bl_match_table);
+
static struct platform_driver lm3533_bl_driver = {
.driver = {
.name = "lm3533-backlight",
.pm = &lm3533_bl_pm_ops,
.dev_groups = lm3533_bl_attribute_groups,
+ .of_match_table = lm3533_bl_match_table,
},
.probe = lm3533_bl_probe,
.remove = lm3533_bl_remove,
diff --git a/include/linux/mfd/lm3533.h b/include/linux/mfd/lm3533.h
index 74cfb52c3bd1..5710e88da45d 100644
--- a/include/linux/mfd/lm3533.h
+++ b/include/linux/mfd/lm3533.h
@@ -15,6 +15,10 @@
#define LM3533_ATTR_RW(_name) \
DEVICE_ATTR(_name, S_IRUGO | S_IWUSR , show_##_name, store_##_name)
+#define LM3533_MAX_CURRENT_MIN 5000
+#define LM3533_MAX_CURRENT_MAX 29800
+#define LM3533_MAX_CURRENT_STEP 800
+
struct device;
struct gpio_desc;
struct regmap;
@@ -25,7 +29,9 @@ struct lm3533 {
struct regmap *regmap;
struct gpio_desc *hwen;
- int irq;
+
+ u32 boost_ovp;
+ u32 boost_freq;
unsigned have_als:1;
unsigned have_backlights:1;
@@ -38,50 +44,6 @@ struct lm3533_ctrlbank {
int id;
};
-struct lm3533_als_platform_data {
- unsigned pwm_mode:1; /* PWM input mode (default analog) */
- u8 r_select; /* 1 - 127 (ignored in PWM-mode) */
-};
-
-struct lm3533_bl_platform_data {
- char *name;
- u16 max_current; /* 5000 - 29800 uA (800 uA step) */
- u8 default_brightness; /* 0 - 255 */
- u8 pwm; /* 0 - 0x3f */
-};
-
-struct lm3533_led_platform_data {
- char *name;
- const char *default_trigger;
- u16 max_current; /* 5000 - 29800 uA (800 uA step) */
- u8 pwm; /* 0 - 0x3f */
-};
-
-enum lm3533_boost_freq {
- LM3533_BOOST_FREQ_500KHZ,
- LM3533_BOOST_FREQ_1000KHZ,
-};
-
-enum lm3533_boost_ovp {
- LM3533_BOOST_OVP_16V,
- LM3533_BOOST_OVP_24V,
- LM3533_BOOST_OVP_32V,
- LM3533_BOOST_OVP_40V,
-};
-
-struct lm3533_platform_data {
- enum lm3533_boost_ovp boost_ovp;
- enum lm3533_boost_freq boost_freq;
-
- struct lm3533_als_platform_data *als;
-
- struct lm3533_bl_platform_data *backlights;
- int num_backlights;
-
- struct lm3533_led_platform_data *leds;
- int num_leds;
-};
-
int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb);
int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb);
--
2.53.0
^ permalink raw reply related
* [PATCH v5 09/14] mfd: lm3533: Add support for VIN power supply
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Add support for 2.7V-5.5V VIN power supply.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/mfd/lm3533-core.c | 23 +++++++++++++++++++++--
include/linux/mfd/lm3533.h | 2 ++
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index a5aa7da9668b..4b5d94e9ed27 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -17,6 +17,7 @@
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -113,14 +114,25 @@ static int lm3533_set_lvled_config(struct lm3533 *lm3533, u8 lvled, u8 led)
return ret;
}
-static void lm3533_enable(struct lm3533 *lm3533)
+static int lm3533_enable(struct lm3533 *lm3533)
{
+ int ret;
+
+ ret = regulator_enable(lm3533->vin_supply);
+ if (ret) {
+ dev_err(lm3533->dev, "failed to enable vin power supply\n");
+ return ret;
+ }
+
gpiod_set_value(lm3533->hwen, 1);
+
+ return 0;
}
static void lm3533_disable(struct lm3533 *lm3533)
{
gpiod_set_value(lm3533->hwen, 0);
+ regulator_disable(lm3533->vin_supply);
}
enum lm3533_attribute_type {
@@ -333,7 +345,9 @@ static int lm3533_device_init(struct lm3533 *lm3533)
}
}
- lm3533_enable(lm3533);
+ ret = lm3533_enable(lm3533);
+ if (ret)
+ return ret;
ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM,
LM3533_BOOST_FREQ_MASK,
@@ -447,6 +461,11 @@ static int lm3533_i2c_probe(struct i2c_client *i2c)
return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen),
"failed to get HWEN GPIO\n");
+ lm3533->vin_supply = devm_regulator_get(lm3533->dev, "vin");
+ if (IS_ERR(lm3533->vin_supply))
+ return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->vin_supply),
+ "failed to get vin-supply\n");
+
device_property_read_u32(lm3533->dev, "ti,boost-ovp-microvolt",
&lm3533->boost_ovp);
diff --git a/include/linux/mfd/lm3533.h b/include/linux/mfd/lm3533.h
index 5710e88da45d..8f72dd41e8f0 100644
--- a/include/linux/mfd/lm3533.h
+++ b/include/linux/mfd/lm3533.h
@@ -22,6 +22,7 @@
struct device;
struct gpio_desc;
struct regmap;
+struct regulator;
struct lm3533 {
struct device *dev;
@@ -29,6 +30,7 @@ struct lm3533 {
struct regmap *regmap;
struct gpio_desc *hwen;
+ struct regulator *vin_supply;
u32 boost_ovp;
u32 boost_freq;
--
2.53.0
^ permalink raw reply related
* [PATCH v5 10/14] mfd: lm3533: Set DMA mask
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Missing coherent_dma_mask assigning triggers the following warning in
dmesg:
[ 3.287872] platform lm3533-backlight.0: DMA mask not set
Since this warning might be elevated to an error in the future, set
coherent_dma_mask to zero because both the core and cells do not utilize
DMA.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/mfd/lm3533-core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index 4b5d94e9ed27..db8581d1b073 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -480,6 +480,10 @@ static int lm3533_i2c_probe(struct i2c_client *i2c)
LM3533_BOOST_FREQ_MAX);
lm3533->boost_freq = lm3533->boost_freq / (500 * KILO) - 1;
+ /* LM3533 and child devices do not use DMA */
+ i2c->dev.coherent_dma_mask = 0;
+ i2c->dev.dma_mask = &i2c->dev.coherent_dma_mask;
+
return lm3533_device_init(lm3533);
}
--
2.53.0
^ permalink raw reply related
* [PATCH v5 11/14] video: backlight: lm3533_bl: Improve logic of sysfs functions
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Simplify the sysfs logic of properties by switching to macros and proper
regmap helpers.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Daniel Thompson (RISCstar) <danielt@kernel.org>
---
drivers/video/backlight/lm3533_bl.c | 62 ++++++++++-------------------
1 file changed, 22 insertions(+), 40 deletions(-)
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 2c24647fc17a..9eb0db640948 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -23,6 +23,8 @@
#define LM3533_BL_MAX_BRIGHTNESS 255
#define LM3533_REG_CTRLBANK_AB_BCONF 0x1a
+#define CTRLBANK_AB_BCONF_ALS(n) BIT(2 * (n))
+#define CTRLBANK_AB_BCONF_MODE(n) BIT(2 * (n) + 1)
struct lm3533_bl {
@@ -85,88 +87,68 @@ static ssize_t show_als_channel(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
}
-static ssize_t show_als_en(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t show_als_en(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct lm3533_bl *bl = dev_get_drvdata(dev);
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
- u32 val;
- u8 mask;
- bool enable;
int ret;
- ret = regmap_read(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, &val);
- if (ret)
+ ret = regmap_test_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
+ CTRLBANK_AB_BCONF_ALS(ctrlbank));
+ if (ret < 0)
return ret;
- mask = 1 << (2 * ctrlbank);
- enable = val & mask;
-
- return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
+ return scnprintf(buf, PAGE_SIZE, "%d\n", ret);
}
-static ssize_t store_als_en(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+static ssize_t store_als_en(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct lm3533_bl *bl = dev_get_drvdata(dev);
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
int enable;
- u8 mask;
int ret;
if (kstrtoint(buf, 0, &enable))
return -EINVAL;
- mask = 1 << (2 * ctrlbank);
-
ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
- mask, enable);
+ CTRLBANK_AB_BCONF_ALS(ctrlbank), enable);
if (ret)
return ret;
return len;
}
-static ssize_t show_linear(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t show_linear(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct lm3533_bl *bl = dev_get_drvdata(dev);
- u32 val;
- u8 mask;
- int linear;
+ int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
int ret;
- ret = regmap_read(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, &val);
- if (ret)
+ ret = regmap_test_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
+ CTRLBANK_AB_BCONF_MODE(ctrlbank));
+ if (ret < 0)
return ret;
- mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1);
-
- if (val & mask)
- linear = 1;
- else
- linear = 0;
-
- return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
+ return scnprintf(buf, PAGE_SIZE, "%x\n", ret);
}
-static ssize_t store_linear(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+static ssize_t store_linear(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct lm3533_bl *bl = dev_get_drvdata(dev);
+ int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
unsigned long linear;
- u8 mask;
int ret;
if (kstrtoul(buf, 0, &linear))
return -EINVAL;
- mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1);
-
ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
- mask, linear);
+ CTRLBANK_AB_BCONF_MODE(ctrlbank), linear);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related
* [PATCH v5 12/14] video: backlight: lm3533_bl: Set initial mapping mode from DT
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Add support to obtain the initial mapping mode from DT instead of leaving
it unconfigured.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Daniel Thompson (RISCstar) <danielt@kernel.org>
---
drivers/video/backlight/lm3533_bl.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 9eb0db640948..d003d5802508 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -37,6 +37,7 @@ struct lm3533_bl {
u32 pwm;
bool have_als;
+ bool linear;
};
@@ -231,8 +232,14 @@ static const struct attribute_group *lm3533_bl_attribute_groups[] = {
static int lm3533_bl_setup(struct lm3533_bl *bl)
{
+ int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
int ret;
+ ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
+ CTRLBANK_AB_BCONF_MODE(ctrlbank), bl->linear);
+ if (ret)
+ return ret;
+
ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current);
if (ret)
return ret;
@@ -286,6 +293,9 @@ static int lm3533_bl_probe(struct platform_device *pdev)
props.max_brightness = LM3533_BL_MAX_BRIGHTNESS;
props.brightness = default_brightness;
+ bl->linear = device_property_read_bool(&pdev->dev,
+ "ti,linear-mapping-mode");
+
bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev,
bl, &lm3533_bl_ops, &props);
if (IS_ERR(bd)) {
--
2.53.0
^ permalink raw reply related
* [PATCH v5 13/14] video: backlight: lm3533_bl: Implement backlight_scale property
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Since the device supports linear and non-linear modes, implement the
backlight_scale property to describe this state.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Daniel Thompson (RISCstar) <danielt@kernel.org>
---
drivers/video/backlight/lm3533_bl.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index d003d5802508..c99fc68cb669 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -142,6 +142,7 @@ static ssize_t store_linear(struct device *dev, struct device_attribute *attr,
{
struct lm3533_bl *bl = dev_get_drvdata(dev);
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
+ struct backlight_device *bd = bl->bd;
unsigned long linear;
int ret;
@@ -153,6 +154,9 @@ static ssize_t store_linear(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
+ bd->props.scale = linear ? BACKLIGHT_SCALE_LINEAR :
+ BACKLIGHT_SCALE_NON_LINEAR;
+
return len;
}
@@ -295,6 +299,8 @@ static int lm3533_bl_probe(struct platform_device *pdev)
bl->linear = device_property_read_bool(&pdev->dev,
"ti,linear-mapping-mode");
+ props.scale = bl->linear ? BACKLIGHT_SCALE_LINEAR :
+ BACKLIGHT_SCALE_NON_LINEAR;
bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev,
bl, &lm3533_bl_ops, &props);
--
2.53.0
^ permalink raw reply related
* [PATCH v5 14/14] video: leds: backlight: lm3533: Support getting LED sources from DT
From: Svyatoslav Ryhel @ 2026-06-17 8:00 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Svyatoslav Ryhel
Cc: Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-1-clamor95@gmail.com>
Add Control Bank to HVLED/LVLED muxing support based on the led-sources
defined in the device tree.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/leds/leds-lm3533.c | 60 +++++++++++++++++++++++++++++
drivers/video/backlight/lm3533_bl.c | 45 ++++++++++++++++++++++
2 files changed, 105 insertions(+)
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index ed810c23f30f..9e07953814fd 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -27,6 +27,11 @@
#define LM3533_ALS_CHANNEL_LV_MIN 1
#define LM3533_ALS_CHANNEL_LV_MAX 2
+#define LM3533_REG_OUTPUT_CONF1 0x10
+#define OUTPUT_CONF1_SHIFT 2
+#define OUTPUT_LVLED_MASK 0x3
+#define LM3533_REG_OUTPUT_CONF2 0x11
+#define OUTPUT_CONF2_SHIFT 6
#define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b
#define LM3533_REG_PATTERN_ENABLE 0x28
#define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71
@@ -55,6 +60,9 @@ struct lm3533_led {
u32 max_current;
u32 pwm;
+ int num_leds;
+ u32 leds[LM3533_LVCTRLBANK_MAX];
+
bool have_als;
};
@@ -623,8 +631,36 @@ static const struct attribute_group *lm3533_led_attribute_groups[] = {
static int lm3533_led_setup(struct lm3533_led *led)
{
+ u32 output_cfg_shift = 0;
+ u32 output_cfg_val = 0;
+ u32 output_cfg_mask = 0;
int ret;
+ if (led->num_leds) {
+ for (int i = 0; i < led->num_leds; i++) {
+ if (led->leds[i] >= LM3533_LVCTRLBANK_MAX)
+ continue;
+
+ output_cfg_shift = led->leds[i] * 2;
+ output_cfg_val |= led->id << output_cfg_shift;
+ output_cfg_mask |= OUTPUT_LVLED_MASK << output_cfg_shift;
+ }
+
+ /* LVLED1, LVLED2 and LVLED3 */
+ ret = regmap_update_bits(led->regmap, LM3533_REG_OUTPUT_CONF1,
+ output_cfg_mask << OUTPUT_CONF1_SHIFT,
+ output_cfg_val << OUTPUT_CONF1_SHIFT);
+ if (ret)
+ return ret;
+
+ /* LVLED4 and LVLED5 */
+ ret = regmap_update_bits(led->regmap, LM3533_REG_OUTPUT_CONF2,
+ output_cfg_mask >> OUTPUT_CONF2_SHIFT,
+ output_cfg_val >> OUTPUT_CONF2_SHIFT);
+ if (ret)
+ return ret;
+ }
+
ret = lm3533_ctrlbank_set_max_current(&led->cb, led->max_current);
if (ret)
return ret;
@@ -699,6 +735,30 @@ static int lm3533_led_probe(struct platform_device *pdev)
device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &led->pwm);
+ /*
+ * If led-sources property is not set then either this Control Bank uses
+ * its default LVLED or is not linked to any LVLED at all.
+ */
+ led->num_leds = device_property_count_u32(&pdev->dev, "led-sources");
+ if (led->num_leds > LM3533_LVCTRLBANK_MAX) {
+ dev_err(&pdev->dev, "num of LED sources exceeds max %d: %d\n",
+ LM3533_LVCTRLBANK_MAX, led->num_leds);
+ ret = -EINVAL;
+ goto err_deregister;
+ }
+
+ if (led->num_leds < 0)
+ led->num_leds = 0;
+
+ if (led->num_leds > 0) {
+ ret = device_property_read_u32_array(&pdev->dev, "led-sources",
+ led->leds, led->num_leds);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get led-sources\n");
+ goto err_deregister;
+ }
+ }
+
ret = lm3533_led_setup(led);
if (ret)
goto err_deregister;
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index c99fc68cb669..b3e5b3042d34 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -7,6 +7,7 @@
* Author: Johan Hovold <jhovold@gmail.com>
*/
+#include <linux/bits.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mod_devicetable.h>
@@ -22,6 +23,7 @@
#define LM3533_HVCTRLBANK_COUNT 2
#define LM3533_BL_MAX_BRIGHTNESS 255
+#define LM3533_REG_OUTPUT_CONF1 0x10
#define LM3533_REG_CTRLBANK_AB_BCONF 0x1a
#define CTRLBANK_AB_BCONF_ALS(n) BIT(2 * (n))
#define CTRLBANK_AB_BCONF_MODE(n) BIT(2 * (n) + 1)
@@ -36,6 +38,9 @@ struct lm3533_bl {
u32 max_current;
u32 pwm;
+ int num_leds;
+ u32 led_strings[LM3533_HVCTRLBANK_COUNT];
+
bool have_als;
bool linear;
};
@@ -237,6 +242,8 @@ static const struct attribute_group *lm3533_bl_attribute_groups[] = {
static int lm3533_bl_setup(struct lm3533_bl *bl)
{
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
+ u32 output_cfg_val = 0;
+ u32 output_cfg_mask = 0;
int ret;
ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
@@ -244,6 +251,21 @@ static int lm3533_bl_setup(struct lm3533_bl *bl)
if (ret)
return ret;
+ if (bl->num_leds) {
+ for (int i = 0; i < bl->num_leds; i++) {
+ if (bl->led_strings[i] >= LM3533_HVCTRLBANK_COUNT)
+ continue;
+
+ output_cfg_val |= ctrlbank << bl->led_strings[i];
+ output_cfg_mask |= BIT(bl->led_strings[i]);
+ }
+
+ ret = regmap_update_bits(bl->regmap, LM3533_REG_OUTPUT_CONF1,
+ output_cfg_mask, output_cfg_val);
+ if (ret)
+ return ret;
+ }
+
ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current);
if (ret)
return ret;
@@ -321,6 +343,29 @@ static int lm3533_bl_probe(struct platform_device *pdev)
device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &bl->pwm);
+ /*
+ * If led-sources property is not set then either this Control Bank uses
+ * its default HVLED or is not linked to any HVLED at all.
+ */
+ bl->num_leds = device_property_count_u32(&pdev->dev, "led-sources");
+ if (bl->num_leds > LM3533_HVCTRLBANK_COUNT) {
+ dev_err(&pdev->dev, "num of LED sources %d exceeds max %d\n",
+ bl->num_leds, LM3533_HVCTRLBANK_COUNT);
+ return -EINVAL;
+ }
+
+ if (bl->num_leds < 0)
+ bl->num_leds = 0;
+
+ if (bl->num_leds > 0) {
+ ret = device_property_read_u32_array(&pdev->dev, "led-sources",
+ bl->led_strings,
+ bl->num_leds);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to get led-sources\n");
+ }
+
ret = lm3533_bl_setup(bl);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related
* [PATCH] firmware: sysfb: Mark CONFIG_SYSFB_SIMPLEFB as deprecated
From: Thomas Zimmermann @ 2026-06-17 8:17 UTC (permalink / raw)
To: javierm, sima, airlied
Cc: dri-devel, linux-fbdev, linux-kernel, Thomas Zimmermann
Mark CONFIG_SYSFB_SIMPLEFB as deprecated. Enabling it allows to
run simpledrm and simplefb on EFI/VESA framebuffers. Doing this
is discouraged in favor of using efidrm and vesadrm.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/firmware/Kconfig | 33 ++++++++++++---------------------
1 file changed, 12 insertions(+), 21 deletions(-)
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index bbd2155d8483..b4e705abdc8f 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -184,32 +184,23 @@ config SYSFB
select SCREEN_INFO
config SYSFB_SIMPLEFB
- bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
+ bool "Mark VGA/VBE/EFI FB as generic system framebuffer (deprecated)"
depends on X86 || EFI
select SYSFB
help
Firmwares often provide initial graphics framebuffers so the BIOS,
bootloader or kernel can show basic video-output during boot for
- user-guidance and debugging. Historically, x86 used the VESA BIOS
- Extensions and EFI-framebuffers for this, which are mostly limited
- to x86 BIOS or EFI systems.
- This option, if enabled, marks VGA/VBE/EFI framebuffers as generic
- framebuffers so the new generic system-framebuffer drivers can be
- used instead. If the framebuffer is not compatible with the generic
- modes, it is advertised as fallback platform framebuffer so legacy
- drivers like efifb, vesafb and uvesafb can pick it up.
- If this option is not selected, all system framebuffers are always
- marked as fallback platform framebuffers as usual.
-
- Note: Legacy fbdev drivers, including vesafb, efifb, uvesafb, will
- not be able to pick up generic system framebuffers if this option
- is selected. You are highly encouraged to enable simplefb as
- replacement if you select this option. simplefb can correctly deal
- with generic system framebuffers. But you should still keep vesafb
- and others enabled as fallback if a system framebuffer is
- incompatible with simplefb.
-
- If unsure, say Y.
+ user-guidance and debugging.
+
+ This option, if enabled, marks VBE/EFI framebuffers as system
+ framebuffers so the generic simpledrm driver can be used. If the
+ framebuffer is not compatible with the generic modes, it is
+ advertised as fallback platform framebuffer so regular drivers like
+ efidrm, vesadrm can pick it up.
+
+ This option is deprecated and will be removed in the near future. If
+ unsure, say N and select efidrm, vesadrm instead. The dedicated DRM
+ drivers provide the same functionality plus additional features.
config TH1520_AON_PROTOCOL
tristate "Always-On firmware protocol"
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] firmware: sysfb: Mark CONFIG_SYSFB_SIMPLEFB as deprecated
From: Javier Martinez Canillas @ 2026-06-17 8:46 UTC (permalink / raw)
To: Thomas Zimmermann, sima, airlied
Cc: dri-devel, linux-fbdev, linux-kernel, Thomas Zimmermann
In-Reply-To: <20260617081810.218168-1-tzimmermann@suse.de>
Thomas Zimmermann <tzimmermann@suse.de> writes:
Hello Thomas,
Thanks for the patch.
> Mark CONFIG_SYSFB_SIMPLEFB as deprecated. Enabling it allows to
> run simpledrm and simplefb on EFI/VESA framebuffers. Doing this
> is discouraged in favor of using efidrm and vesadrm.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Do you know what the policy is for removal? For example,
how many Linux releases should we wait for this to go away?
--
Best regards,
Javier Martinez Canillas
Core Platforms
Red Hat
^ permalink raw reply
* Re: [PATCH] firmware: sysfb: Mark CONFIG_SYSFB_SIMPLEFB as deprecated
From: Thomas Zimmermann @ 2026-06-17 8:57 UTC (permalink / raw)
To: Javier Martinez Canillas, sima, airlied
Cc: dri-devel, linux-fbdev, linux-kernel
In-Reply-To: <877bnxzh9s.fsf@ocarina.mail-host-address-is-not-set>
Hi
Am 17.06.26 um 10:46 schrieb Javier Martinez Canillas:
> Thomas Zimmermann <tzimmermann@suse.de> writes:
>
> Hello Thomas,
>
> Thanks for the patch.
>
>> Mark CONFIG_SYSFB_SIMPLEFB as deprecated. Enabling it allows to
>> run simpledrm and simplefb on EFI/VESA framebuffers. Doing this
>> is discouraged in favor of using efidrm and vesadrm.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
>> ---
> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Thanks. The sashiko bot detected some inconsistencies in the docs, so
there will be a v2 of this patch.
>
> Do you know what the policy is for removal? For example,
> how many Linux releases should we wait for this to go away?
IDK. I'd wait for 2 or 3 releases after this lands and then remove it.
It's a small change with a clear upgrade patch after all.
Best regards
Thomas
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply
* [PATCH v1] fbdev: vga16fb: Drop unused assignment of platform_device_id driver data
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-17 9:44 UTC (permalink / raw)
To: Helge Deller
Cc: Ard Biesheuvel, Javier Garcia, Vivek BalachandharTN,
Thomas Zimmermann, linux-fbdev, dri-devel, linux-kernel
The driver explicitly sets the .driver_data member of struct
platform_device_id to zero without relying on that value. Drop these
unused assignments.
While touching this array unify spacing and usage of commas and use
named initializers for .name.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
drivers/video/fbdev/vga16fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c
index 22085d3668e8..cdd6b8de0ceb 100644
--- a/drivers/video/fbdev/vga16fb.c
+++ b/drivers/video/fbdev/vga16fb.c
@@ -1421,8 +1421,8 @@ static void vga16fb_remove(struct platform_device *dev)
}
static const struct platform_device_id vga16fb_driver_id_table[] = {
- {"ega-framebuffer", 0},
- {"vga-framebuffer", 0},
+ { .name = "ega-framebuffer" },
+ { .name = "vga-framebuffer" },
{ }
};
MODULE_DEVICE_TABLE(platform, vga16fb_driver_id_table);
base-commit: 4fa3f5fabb30bf00d7475d5a33459ea83d639bf9
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v5 02/14] mfd: lm3533: Remove driver specific regmap wrappers
From: Andy Shevchenko @ 2026-06-17 10:32 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Helge Deller,
Johan Hovold, dri-devel, linux-leds, devicetree, linux-kernel,
linux-iio, linux-fbdev
In-Reply-To: <20260617080031.99156-3-clamor95@gmail.com>
On Wed, Jun 17, 2026 at 11:00:19AM +0300, Svyatoslav Ryhel wrote:
> Remove driver-specific regmap wrappers in favor of using regmap helpers
> directly.
OK, let's go with this variant.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Some side notes below for the record.
...
> struct lm3533_led *led = to_lm3533_led(led_cdev);
> unsigned enable;
Oh, besides using the old way of declaring unsigned int, it most likely
just needs to be kstrtobool().
> u8 reg;
> - u8 mask;
> - u8 val;
> int ret;
>
> if (kstrtouint(buf, 0, &enable))
> return -EINVAL;
We should unshadow error codes (it may return more than -EINVAL).
> reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
> - mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
>
> - if (enable)
> - val = mask;
> - else
> - val = 0;
> -
...
> - if (kstrtou8(buf, 0, &val))
> + if (kstrtou32(buf, 0, &val))
> return -EINVAL;
Like in the previous case we should unshadow error codes.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH] firmware: sysfb: Mark CONFIG_SYSFB_SIMPLEFB as deprecated
From: Julian Braha @ 2026-06-17 16:45 UTC (permalink / raw)
To: Thomas Zimmermann, javierm, sima, airlied
Cc: dri-devel, linux-fbdev, linux-kernel
In-Reply-To: <20260617081810.218168-1-tzimmermann@suse.de>
Hi Thomas,
On 6/17/26 09:17, Thomas Zimmermann wrote:
> Mark CONFIG_SYSFB_SIMPLEFB as deprecated. Enabling it allows to
> config SYSFB_SIMPLEFB
> - bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
> + bool "Mark VGA/VBE/EFI FB as generic system framebuffer (deprecated)"
In v2, I think it also makes sense to add the 'transitional' attribute
to the Kconfig entry to help phase it out.
Also see this patch message for an explanation of 'transitional':
https://lore.kernel.org/all/20250923213422.1105654-2-kees@kernel.org/
- Julian Braha
^ permalink raw reply
* [PATCH] fbcon: Avoid OOB font access if console rotation fails
From: HAN Ruidong via B4 Relay @ 2026-06-18 6:30 UTC (permalink / raw)
To: Andrew Morton, Antonino Daplas, stable
Cc: dri-devel, linux-fbdev, linux-kernel, Thomas Zimmermann,
Helge Deller, HAN Ruidong
From: HAN Ruidong <rdhan@smu.edu.sg>
[ Upstream commit e4ef723d8975a2694cc90733a6b888a5e2841842 ]
Clear the font buffer if the reallocation during console rotation fails
in fbcon_rotate_font(). The putcs implementations for the rotated buffer
will return early in this case. See [1] for an example.
Currently, fbcon_rotate_font() keeps the old buffer, which is too small
for the rotated font. Printing to the rotated console with a high-enough
character code will overflow the font buffer.
v2:
- fix typos in commit message
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 6cc50e1c5b57 ("[PATCH] fbcon: Console Rotation - Add support to rotate font bitmap")
Cc: stable@vger.kernel.org # v2.6.15+
Link: https://elixir.bootlin.com/linux/v6.19/source/drivers/video/fbdev/core/fbcon_ccw.c#L144 # [1]
Signed-off-by: Helge Deller <deller@gmx.de>
[ renamed `par` to `ops` to match the v5.15 local pointer name ]
Signed-off-by: HAN Ruidong <rdhan@smu.edu.sg>
---
drivers/video/fbdev/core/fbcon_rotate.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index ec3c883400f7..4a06e71ae443 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -46,6 +46,10 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
info->fbops->fb_sync(info);
if (ops->fd_size < d_cellsize * len) {
+ kfree(ops->fontbuffer);
+ ops->fontbuffer = NULL;
+ ops->fd_size = 0;
+
dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
if (dst == NULL) {
@@ -54,7 +58,6 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
}
ops->fd_size = d_cellsize * len;
- kfree(ops->fontbuffer);
ops->fontbuffer = dst;
}
---
base-commit: dc027a595035729e290c0adffae363a653acde7c
change-id: 20260618-prep-base-v5-15-209-596d47c98637
Best regards,
--
HAN Ruidong <rdhan@smu.edu.sg>
^ permalink raw reply related
* Re: [PATCH] firmware: sysfb: Mark CONFIG_SYSFB_SIMPLEFB as deprecated
From: Thomas Zimmermann @ 2026-06-18 7:21 UTC (permalink / raw)
To: Julian Braha, javierm, sima, airlied; +Cc: dri-devel, linux-fbdev, linux-kernel
In-Reply-To: <7da7d892-3b3c-4f83-b3b0-93eafe14e15e@gmail.com>
Hi
Am 17.06.26 um 18:45 schrieb Julian Braha:
> Hi Thomas,
>
> On 6/17/26 09:17, Thomas Zimmermann wrote:
>> Mark CONFIG_SYSFB_SIMPLEFB as deprecated. Enabling it allows to
>> config SYSFB_SIMPLEFB
>> - bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
>> + bool "Mark VGA/VBE/EFI FB as generic system framebuffer (deprecated)"
> In v2, I think it also makes sense to add the 'transitional' attribute
> to the Kconfig entry to help phase it out.
>
> Also see this patch message for an explanation of 'transitional':
> https://lore.kernel.org/all/20250923213422.1105654-2-kees@kernel.org/
Thanks for this pointer; I wasn't aware of this feature. This will be
really useful to not accidentally leave users without display output.
I've played with the option, but it does not work are purely as shown in
the example. I think it's because EFIDRM and VESADRM are existing
options. So they already have a value.
What I did instead was to add new internal config options. They depend
on the now-transitional SYSFB_SIMPLEFB and select the correct drivers.
Once SYSFB_SIMPLEFB goes away, these options can go away as well.
Best regards
Thomas
>
> - Julian Braha
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply
* Re: [PATCH] fbcon: Avoid OOB font access if console rotation fails
From: Greg KH @ 2026-06-18 10:35 UTC (permalink / raw)
To: rdhan
Cc: Andrew Morton, Antonino Daplas, stable, dri-devel, linux-fbdev,
linux-kernel, Thomas Zimmermann, Helge Deller
In-Reply-To: <20260618-prep-base-v5-15-209-v1-1-cfcf596dca7a@smu.edu.sg>
On Thu, Jun 18, 2026 at 02:30:17PM +0800, HAN Ruidong via B4 Relay wrote:
> From: HAN Ruidong <rdhan@smu.edu.sg>
>
> [ Upstream commit e4ef723d8975a2694cc90733a6b888a5e2841842 ]
>
> Clear the font buffer if the reallocation during console rotation fails
> in fbcon_rotate_font(). The putcs implementations for the rotated buffer
> will return early in this case. See [1] for an example.
>
> Currently, fbcon_rotate_font() keeps the old buffer, which is too small
> for the rotated font. Printing to the rotated console with a high-enough
> character code will overflow the font buffer.
>
> v2:
> - fix typos in commit message
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> Fixes: 6cc50e1c5b57 ("[PATCH] fbcon: Console Rotation - Add support to rotate font bitmap")
> Cc: stable@vger.kernel.org # v2.6.15+
> Link: https://elixir.bootlin.com/linux/v6.19/source/drivers/video/fbdev/core/fbcon_ccw.c#L144 # [1]
> Signed-off-by: Helge Deller <deller@gmx.de>
> [ renamed `par` to `ops` to match the v5.15 local pointer name ]
> Signed-off-by: HAN Ruidong <rdhan@smu.edu.sg>
> ---
> drivers/video/fbdev/core/fbcon_rotate.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
What stable tree(s) is this for?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v3] staging: sm750fb: rename pv_reg to io_base
From: neha arora @ 2026-06-20 7:43 UTC (permalink / raw)
To: Dan Carpenter
Cc: sudipm.mukherjee, teddy.wang, gregkh, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <CAOWJOpt2CW=-zybOrPr2pwfPVQFcd+j3YoNP+rMyAar_2kJtbw@mail.gmail.com>
Hi everyone,
After further investigation, and feedback from maintainers, I have
concluded that porting DRM to the SM750, will cause a huge performance
regression as DRM has no interface for 2D acceleration, making the CPU
do graphics, which is slow, the only way to expose 2D acceleration is
custom IOCTLs, which is not preferable.
So, it is best to keep using the fbdev stack for the SM750.
Regards,
Onish
On Wed, Jun 17, 2026 at 8:30 AM neha arora <neharora23587@gmail.com> wrote:
>
> Hi Dan,
>
> Please disregard my previous patch submission.
>
> I am currently working on a complete rewrite of the sm750fb staging
> driver into a modern, KMS-based DRM driver (sm750drm). Because this
> is a complete architectural overhaul, I am building it outside the
> staging tree structure.
>
> Once the sm750drm driver framework is stable and ready for a RFC
> (Request for Comments), I will submit the entire new subsystem patch series
> directly to the dri-devel mailing list and CC you.
>
> Thank you for your review and your time!
>
> Regards,
> Onish
>
>
> On Mon, Jun 15, 2026 at 12:34 PM Dan Carpenter <error27@gmail.com> wrote:
> >
> > On Sun, Jun 14, 2026 at 12:45:05AM +0530, neha arora wrote:
> > > Hi everyone,
> > >
> > > Just following up on this patch to ensure it didn't get lost in the queue.
> > > Please let me know if any changes or a V4 are needed.
> > >
> >
> > It doesn't apply to linux-next. Did you work against the lastest
> > devel-next tree?
> >
> > regards,
> > dan carpenter
> >
^ permalink raw reply
* [syzbot] Monthly fbdev report (Jun 2026)
From: syzbot @ 2026-06-20 12:32 UTC (permalink / raw)
To: deller, dri-devel, linux-fbdev, linux-kernel, syzkaller-bugs
Hello fbdev maintainers/developers,
This is a 31-day syzbot report for the fbdev subsystem.
All related reports/information can be found at:
https://syzkaller.appspot.com/upstream/s/fbdev
During the period, 1 new issues were detected and 0 were fixed.
In total, 5 issues are still open and 29 have already been fixed.
Some of the still happening issues:
Ref Crashes Repro Title
<1> 5429 Yes KASAN: vmalloc-out-of-bounds Write in imageblit (6)
https://syzkaller.appspot.com/bug?extid=5a40432dfe8f86ee657a
<2> 1600 Yes KASAN: slab-out-of-bounds Read in fbcon_prepare_logo
https://syzkaller.appspot.com/bug?extid=0c815b25cdb3678e7083
<3> 271 No KASAN: vmalloc-out-of-bounds Write in fillrect
https://syzkaller.appspot.com/bug?extid=7a63ce155648954e749b
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
To disable reminders for individual bugs, reply with the following command:
#syz set <Ref> no-reminders
To change bug's subsystems, reply with:
#syz set <Ref> subsystems: new-subsystem
You may send multiple commands in a single email message.
^ permalink raw reply
* [PATCH] staging: sm750fb: make g_fbmode array const
From: Arnav Kapoor @ 2026-06-21 4:44 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman,
open list:STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER,
open list:STAGING SUBSYSTEM, open list
Cc: Arnav Kapoor,
open list:STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER,
open list:STAGING SUBSYSTEM, open list
From: arnavk23 <kapoorarnav43@gmail.com>
checkpatch complains that a static const char * array should
probably be static const char * const.
Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
Signed-off-by: arnavk23 <kapoorarnav43@gmail.com>
---
drivers/staging/sm750fb/sm750.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 9f3e3d37e..19c3da654 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -33,7 +33,7 @@
static int g_hwcursor = 1;
static int g_noaccel;
static int g_nomtrr;
-static const char *g_fbmode[] = {NULL, NULL};
+static const char * const g_fbmode[] = {NULL, NULL};
static const char *g_def_fbmode = "1024x768-32@60";
static char *g_settings;
static int g_dualview;
--
2.53.0
^ permalink raw reply related
* [staging] staging: sm750fb: rename pvMem to vram and pvReg to reg
From: Arnav Kapoor @ 2026-06-21 4:50 UTC (permalink / raw)
To: Greg Kroah-Hartman, Sudip Mukherjee, Teddy Wang
Cc: linux-staging, linux-fbdev, linux-kernel, Arnav Kapoor
Fix CamelCase issues reported by checkpatch.
Signed-off-by: arnavk23 <kapoorarnav43@gmail.com>
Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
---
drivers/staging/sm750fb/sm750.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 19c3da654..125ad1062 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -622,26 +622,26 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
output->paths = sm750_pnc;
crtc->channel = sm750_primary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->vram;
break;
case sm750_simul_sec:
output->paths = sm750_pnc;
crtc->channel = sm750_secondary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->vram;
break;
case sm750_dual_normal:
if (par->index == 0) {
output->paths = sm750_panel;
crtc->channel = sm750_primary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->vram;
} else {
output->paths = sm750_crt;
crtc->channel = sm750_secondary;
/* not consider of padding stuffs for o_screen,need fix */
crtc->o_screen = sm750_dev->vidmem_size >> 1;
- crtc->v_screen = sm750_dev->pvMem + crtc->o_screen;
+ crtc->v_screen = sm750_dev->vram + crtc->o_screen;
}
break;
case sm750_dual_swap:
@@ -649,7 +649,7 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
output->paths = sm750_panel;
crtc->channel = sm750_secondary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->vram;
} else {
output->paths = sm750_crt;
crtc->channel = sm750_primary;
@@ -657,7 +657,7 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
* need fix
*/
crtc->o_screen = sm750_dev->vidmem_size >> 1;
- crtc->v_screen = sm750_dev->pvMem + crtc->o_screen;
+ crtc->v_screen = sm750_dev->vram + crtc->o_screen;
}
break;
default:
@@ -755,13 +755,13 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
* must be set after crtc member initialized
*/
crtc->cursor.offset = crtc->o_screen + crtc->vidmem_size - 1024;
- crtc->cursor.mmio = sm750_dev->pvReg +
+ crtc->cursor.mmio = sm750_dev->reg +
0x800f0 + (int)crtc->channel * 0x140;
crtc->cursor.max_h = 64;
crtc->cursor.max_w = 64;
crtc->cursor.size = crtc->cursor.max_h * crtc->cursor.max_w * 2 / 8;
- crtc->cursor.vstart = sm750_dev->pvMem + crtc->cursor.offset;
+ crtc->cursor.vstart = sm750_dev->vram + crtc->cursor.offset;
memset_io(crtc->cursor.vstart, 0, crtc->cursor.size);
if (!g_hwcursor)
@@ -1028,7 +1028,7 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
sm750_dev->mtrr.vram = arch_phys_wc_add(sm750_dev->vidmem_start,
sm750_dev->vidmem_size);
- memset_io(sm750_dev->pvMem, 0, sm750_dev->vidmem_size);
+ memset_io(sm750_dev->vram, 0, sm750_dev->vidmem_size);
pci_set_drvdata(pdev, sm750_dev);
@@ -1059,8 +1059,8 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)
sm750fb_framebuffer_release(sm750_dev);
arch_phys_wc_del(sm750_dev->mtrr.vram);
- iounmap(sm750_dev->pvReg);
- iounmap(sm750_dev->pvMem);
+ iounmap(sm750_dev->reg);
+ iounmap(sm750_dev->vram);
pci_release_region(pdev, 1);
kfree(g_settings);
}
--
2.53.0
^ permalink raw reply related
* [staging] staging: sm750fb: fix remaining CamelCase issues
From: Arnav Kapoor @ 2026-06-21 4:53 UTC (permalink / raw)
To: Greg Kroah-Hartman, Sudip Mukherjee, Teddy Wang
Cc: linux-staging, linux-fbdev, linux-kernel, Arnav Kapoor
Rename the remaining CamelCase variables and constants to follow
kernel coding style:
- powerMode → power_mode
- setAllEngOff → set_all_eng_off
- resetMemory → reset_memory
- sm750_doubleTFT → SM750_DOUBLE_TFT
- sm750_dualTFT → SM750_DUAL_TFT
Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
---
drivers/staging/sm750fb/sm750.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 125ad1062..f034d3278 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -859,9 +859,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
sm750_dev->init_parm.chip_clk = 0;
sm750_dev->init_parm.mem_clk = 0;
sm750_dev->init_parm.master_clk = 0;
- sm750_dev->init_parm.powerMode = 0;
- sm750_dev->init_parm.setAllEngOff = 0;
- sm750_dev->init_parm.resetMemory = 1;
+ sm750_dev->init_parm.power_mode = 0;
+ sm750_dev->init_parm.set_all_eng_off = 0;
+ sm750_dev->init_parm.reset_memory = 1;
/* defaultly turn g_hwcursor on for both view */
g_hwcursor = 3;
@@ -880,9 +880,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
} else if (!strncmp(opt, "nocrt", strlen("nocrt"))) {
sm750_dev->nocrt = 1;
} else if (!strncmp(opt, "36bit", strlen("36bit"))) {
- sm750_dev->pnltype = sm750_doubleTFT;
+ sm750_dev->pnltype = SM750_DOUBLE_TFT;
} else if (!strncmp(opt, "18bit", strlen("18bit"))) {
- sm750_dev->pnltype = sm750_dualTFT;
+ sm750_dev->pnltype = SM750_DUAL_TFT;
} else if (!strncmp(opt, "24bit", strlen("24bit"))) {
sm750_dev->pnltype = sm750_24TFT;
} else if (!strncmp(opt, "nohwc0", strlen("nohwc0"))) {
--
2.53.0
^ permalink raw reply related
* [PATCH] staging: fbtft: fix parenthesis alignment in fb_tinylcd.c
From: Aditya Chari @ 2026-06-21 6:29 UTC (permalink / raw)
To: andy, gregkh
Cc: dri-devel, linux-fbdev, linux-staging, linux-kernel, Aditya Chari
Fix a checkpatch.pl
CHECK:PARENTHESIS_ALIGNMENT warning by aligning the wrapped
argument list of write_reg() with the line above it.
Signed-off-by: Aditya Chari <adi25charis@gmail.com>
---
drivers/staging/fbtft/fb_tinylcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c
index afa8f1c74..d58b12472 100644
--- a/drivers/staging/fbtft/fb_tinylcd.c
+++ b/drivers/staging/fbtft/fb_tinylcd.c
@@ -38,7 +38,7 @@ static int init_display(struct fbtft_par *par)
write_reg(par, 0xE5, 0x00);
write_reg(par, 0xF0, 0x36, 0xA5, 0x53);
write_reg(par, 0xE0, 0x00, 0x35, 0x33, 0x00, 0x00, 0x00,
- 0x00, 0x35, 0x33, 0x00, 0x00, 0x00);
+ 0x00, 0x35, 0x33, 0x00, 0x00, 0x00);
write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, 0x55);
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
fsleep(250);
--
2.53.0
^ permalink raw reply related
* [PATCH] video: fbdev: pm2fb: unwind WC setup on probe failure
From: Haoxiang Li @ 2026-06-21 7:19 UTC (permalink / raw)
To: deller; +Cc: linux-fbdev, linux-kernel, Haoxiang Li
Add arch_phys_wc_del() on error path to keep the
write-combining setup balanced when later probe
steps fail.
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
---
drivers/video/fbdev/pm2fb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index f34429829b7d..82408503c281 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -1711,6 +1711,7 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_exit_both:
kfree(info->pixmap.addr);
err_exit_pixmap:
+ arch_phys_wc_del(default_par->wc_cookie);
iounmap(info->screen_base);
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
err_exit_mmio:
--
2.25.1
^ permalink raw reply related
* [PATCH] video: hpfb: Unregister DIO driver on init failure
From: Haoxiang Li @ 2026-06-22 6:49 UTC (permalink / raw)
To: deller; +Cc: linux-fbdev, dri-devel, linux-kernel, Haoxiang Li
hpfb_init() registers the DIO driver via dio_register_driver().
If a later error occurs, the function returns directly without
unregistering the DIO driver. Unregister the DIO driver before
returning from these error paths.
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
---
drivers/video/fbdev/hpfb.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/hpfb.c b/drivers/video/fbdev/hpfb.c
index a1144b150982..1405712e5b4f 100644
--- a/drivers/video/fbdev/hpfb.c
+++ b/drivers/video/fbdev/hpfb.c
@@ -407,10 +407,13 @@ static int __init hpfb_init(void)
err = copy_from_kernel_nofault(&i, (unsigned char *)INTFBVADDR + DIO_IDOFF, 1);
if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) {
- if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat"))
+ if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat")) {
+ dio_unregister_driver(&hpfb_driver);
return -EBUSY;
+ }
printk(KERN_INFO "Internal Topcat found (secondary id %02x)\n", sid);
if (hpfb_init_one(INTFBPADDR, INTFBVADDR)) {
+ dio_unregister_driver(&hpfb_driver);
return -ENOMEM;
}
}
--
2.25.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