* [PATCH v4 1/3] serdev: handle devices without an ACPI or device tree node
2026-10-24 2:29 [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node ChunAn Wu
@ 2026-10-24 2:29 ` ChunAn Wu
2026-10-24 4:09 ` sashiko-bot
2026-10-24 2:29 ` [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching ChunAn Wu
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: ChunAn Wu @ 2026-10-24 2:29 UTC (permalink / raw)
To: linux-serial, platform-driver-x86
Cc: linux-kernel, markus.probst, gregkh, jirislaby, hansg,
ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
Serdev clients instantiated by a driver have no ACPI companion and no
device tree node. Their modalias read returns -ENODEV, their add uevent
is suppressed, and they cannot be driver-matched, so creators force a
bind with device_driver_attach().
Resolve both TODOs in the serdev core by modelling matching on the SPI
bus: let the creator pass a modalias to serdev_device_add() and give
struct serdev_device_driver an id_table. ACPI and OF are still tried
first; clients without their own modalias keep returning -ENODEV. The
device name, derived from the controller, is unchanged.
Split struct serdev_device_id and its defines into a new
include/linux/device-id/serdev.h, following the pattern already used by
the SPI and I2C buses.
Signed-off-by: ChunAn Wu <an.wu@canonical.com>
---
MAINTAINERS | 1 +
.../platform/x86/x86-android-tablets/core.c | 2 +-
drivers/power/sequencing/pwrseq-pcie-m2.c | 2 +-
drivers/tty/serdev/core.c | 65 ++++++++++++++-----
include/linux/device-id/serdev.h | 19 ++++++
include/linux/serdev.h | 12 +++-
6 files changed, 82 insertions(+), 19 deletions(-)
create mode 100644 include/linux/device-id/serdev.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 917f3f72e31b..06e67aa5d9b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24905,6 +24905,7 @@ L: linux-serial@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/serial/serial.yaml
F: drivers/tty/serdev/
+F: include/linux/device-id/serdev.h
F: include/linux/serdev.h
F: rust/helpers/serdev.c
F: rust/kernel/serdev.rs
diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
index cfff7f5eac5d..853aa6ff5d50 100644
--- a/drivers/platform/x86/x86-android-tablets/core.c
+++ b/drivers/platform/x86/x86-android-tablets/core.c
@@ -317,7 +317,7 @@ static __init int x86_instantiate_serdev(const struct x86_dev_info *dev_info, in
ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
acpi_device_set_enumerated(serdev_adev);
- ret = serdev_device_add(serdev);
+ ret = serdev_device_add(serdev, NULL);
if (ret) {
dev_err(&serdev->dev, "error %d adding serdev\n", ret);
serdev_device_put(serdev);
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index e42e85f47629..e0482f2ef39f 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -309,7 +309,7 @@ static int pwrseq_pcie_m2_create_serdev_one(struct pwrseq_pcie_m2_ctx *ctx,
if (ret)
goto err_free_serdev;
- ret = serdev_device_add(pci_dev->serdev);
+ ret = serdev_device_add(pci_dev->serdev, NULL);
if (ret) {
dev_err(dev, "Failed to add serdev for PCI device (%s): %d\n",
pci_name(pdev), ret);
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 7500efcdfc21..45175403bd55 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -29,13 +29,21 @@ static DEFINE_IDA(ctrl_ida);
static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ const struct serdev_device *serdev = to_serdev_device(dev);
int len;
len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1);
if (len != -ENODEV)
return len;
- return of_device_modalias(dev, buf, PAGE_SIZE);
+ len = of_device_modalias(dev, buf, PAGE_SIZE);
+ if (len != -ENODEV)
+ return len;
+
+ if (!serdev->modalias[0])
+ return -ENODEV;
+
+ return sysfs_emit(buf, "%s%s\n", SERDEV_MODULE_PREFIX, serdev->modalias);
}
static DEVICE_ATTR_RO(modalias);
@@ -47,15 +55,22 @@ ATTRIBUTE_GROUPS(serdev_device);
static int serdev_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
+ const struct serdev_device *serdev = to_serdev_device(dev);
int rc;
- /* TODO: platform modalias */
-
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
- return of_device_uevent_modalias(dev, env);
+ rc = of_device_uevent_modalias(dev, env);
+ if (rc != -ENODEV)
+ return rc;
+
+ if (!serdev->modalias[0])
+ return -ENODEV;
+
+ return add_uevent_var(env, "MODALIAS=%s%s", SERDEV_MODULE_PREFIX,
+ serdev->modalias);
}
static void serdev_device_release(struct device *dev)
@@ -70,11 +85,6 @@ static const struct device_type serdev_device_type = {
.release = serdev_device_release,
};
-static bool is_serdev_device(const struct device *dev)
-{
- return dev->type == &serdev_device_type;
-}
-
static void serdev_ctrl_release(struct device *dev)
{
struct serdev_controller *ctrl = to_serdev_controller(dev);
@@ -86,28 +96,51 @@ static const struct device_type serdev_ctrl_type = {
.release = serdev_ctrl_release,
};
+static const struct serdev_device_id *serdev_match_id(const struct serdev_device_id *id,
+ const char *modalias)
+{
+ if (!id || !modalias[0])
+ return NULL;
+
+ while (id->name[0]) {
+ if (!strcmp(modalias, id->name))
+ return id;
+ id++;
+ }
+
+ return NULL;
+}
+
static int serdev_device_match(struct device *dev, const struct device_driver *drv)
{
- if (!is_serdev_device(dev))
- return 0;
+ const struct serdev_device *serdev = to_serdev_device(dev);
+ const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv);
- /* TODO: platform matching */
if (acpi_driver_match_device(dev, drv))
return 1;
- return of_driver_match_device(dev, drv);
+ if (of_driver_match_device(dev, drv))
+ return 1;
+
+ return !!serdev_match_id(sdrv->id_table, serdev->modalias);
}
/**
* serdev_device_add() - add a device previously constructed via serdev_device_alloc()
* @serdev: serdev_device to be added
+ * @modalias: Driver name or alias, used to match devices which have neither
+ * an ACPI companion nor a device tree node. NULL for devices
+ * enumerated from firmware.
*/
-int serdev_device_add(struct serdev_device *serdev)
+int serdev_device_add(struct serdev_device *serdev, const char *modalias)
{
struct serdev_controller *ctrl = serdev->ctrl;
struct device *parent = serdev->dev.parent;
int err;
+ if (modalias)
+ strscpy(serdev->modalias, modalias);
+
dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr);
/* Only a single slave device is currently supported. */
@@ -553,7 +586,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
device_set_node(&serdev->dev, of_fwnode_handle(node));
- err = serdev_device_add(serdev);
+ err = serdev_device_add(serdev, NULL);
if (err) {
dev_err(&serdev->dev,
"failure adding device. status %pe\n",
@@ -707,7 +740,7 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
ACPI_COMPANION_SET(&serdev->dev, adev);
acpi_device_set_enumerated(adev);
- err = serdev_device_add(serdev);
+ err = serdev_device_add(serdev, NULL);
if (err) {
dev_err(&serdev->dev,
"failure adding ACPI serdev device. status %pe\n",
diff --git a/include/linux/device-id/serdev.h b/include/linux/device-id/serdev.h
new file mode 100644
index 000000000000..96644953cece
--- /dev/null
+++ b/include/linux/device-id/serdev.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LINUX_DEVICE_ID_SERDEV_H
+#define LINUX_DEVICE_ID_SERDEV_H
+
+#ifdef __KERNEL__
+typedef unsigned long kernel_ulong_t;
+#endif
+
+/* serdev */
+
+#define SERDEV_NAME_SIZE 40
+#define SERDEV_MODULE_PREFIX "serial:"
+
+struct serdev_device_id {
+ char name[SERDEV_NAME_SIZE];
+ kernel_ulong_t driver_data; /* Data private to the driver */
+};
+
+#endif /* ifndef LINUX_DEVICE_ID_SERDEV_H */
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index b6c3d957ec15..96a441abc1ac 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -7,7 +7,9 @@
#include <linux/types.h>
#include <linux/device.h>
+#include <linux/device-id/serdev.h>
#include <linux/iopoll.h>
+#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/termios.h>
#include <linux/delay.h>
@@ -35,6 +37,10 @@ struct serdev_device_ops {
* struct serdev_device - Basic representation of an serdev device
* @dev: Driver model representation of the device.
* @nr: Device number on serdev bus.
+ * @modalias: Name of the driver to use with this device, or the alias
+ * for it. Empty for devices enumerated from firmware, which
+ * are identified through their ACPI companion or their device
+ * tree node instead. See serdev_device_add().
* @ctrl: serdev controller managing this device.
* @ops: Device operations.
* @write_comp: Completion used by serdev_device_write() internally
@@ -43,6 +49,7 @@ struct serdev_device_ops {
struct serdev_device {
struct device dev;
int nr;
+ char modalias[SERDEV_NAME_SIZE];
struct serdev_controller *ctrl;
const struct serdev_device_ops *ops;
struct completion write_comp;
@@ -55,12 +62,15 @@ struct serdev_device {
* struct serdev_device_driver - serdev slave device driver
* @driver: serdev device drivers should initialize name field of this
* structure.
+ * @id_table: List of serdev devices supported by this driver, used to
+ * match devices which are not enumerated from firmware.
* @probe: binds this driver to a serdev device.
* @remove: unbinds this driver from the serdev device.
* @shutdown: shut down this serdev device.
*/
struct serdev_device_driver {
struct device_driver driver;
+ const struct serdev_device_id *id_table;
int (*probe)(struct serdev_device *);
void (*remove)(struct serdev_device *);
void (*shutdown)(struct serdev_device *);
@@ -158,7 +168,7 @@ static inline void serdev_controller_put(struct serdev_controller *ctrl)
}
struct serdev_device *serdev_device_alloc(struct serdev_controller *);
-int serdev_device_add(struct serdev_device *);
+int serdev_device_add(struct serdev_device *serdev, const char *modalias);
void serdev_device_remove(struct serdev_device *);
struct serdev_controller *serdev_controller_alloc(struct device *host,
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 1/3] serdev: handle devices without an ACPI or device tree node
2026-10-24 2:29 ` [PATCH v4 1/3] " ChunAn Wu
@ 2026-10-24 4:09 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-24 4:09 UTC (permalink / raw)
To: ChunAn Wu, linux-serial
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] serdev: type confusion and OOB read in serdev_device_match() for controllers
- [Medium] serdev: missing mod_devicetable and file2alias wiring for serdev_device_id
- [Low] serdev: unupdated serdev_device_add() callers break build at this commit
--
commit 1b3d9973e0d0ff0b39b8ad4f9814e44ecd6e06a9
Author: ChunAn Wu <an.wu@canonical.com>
serdev: handle devices without an ACPI or device tree node
This commit adds modalias and id_table support to the serdev bus so that
serdev client devices instantiated without an ACPI companion or device tree
node can emit uevents and match against serdev device drivers. It also moves
struct serdev_device_id into include/linux/device-id/serdev.h.
> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index 7500efcdfc218..45175403bd551 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
[ ... ]
> @@ -70,11 +85,6 @@ static const struct device_type serdev_device_type = {
> .release = serdev_device_release,
> };
>
> -static bool is_serdev_device(const struct device *dev)
> -{
> - return dev->type == &serdev_device_type;
> -}
> -
> static void serdev_ctrl_release(struct device *dev)
> {
> struct serdev_controller *ctrl = to_serdev_controller(dev);
> @@ -86,28 +96,51 @@ static const struct device_type serdev_ctrl_type = {
> .release = serdev_ctrl_release,
> };
>
> +static const struct serdev_device_id *serdev_match_id(const struct serdev_device_id *id,
> + const char *modalias)
> +{
> + if (!id || !modalias[0])
> + return NULL;
> +
> + while (id->name[0]) {
> + if (!strcmp(modalias, id->name))
> + return id;
> + id++;
> + }
> +
> + return NULL;
> +}
> +
> static int serdev_device_match(struct device *dev, const struct device_driver *drv)
> {
> - if (!is_serdev_device(dev))
> - return 0;
> + const struct serdev_device *serdev = to_serdev_device(dev);
> + const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv);
>
> - /* TODO: platform matching */
> if (acpi_driver_match_device(dev, drv))
> return 1;
>
> - return of_driver_match_device(dev, drv);
> + if (of_driver_match_device(dev, drv))
> + return 1;
> +
> + return !!serdev_match_id(sdrv->id_table, serdev->modalias);
> }
[Severity: High]
Is it safe to remove the is_serdev_device(dev) check from
serdev_device_match()?
Unlike the SPI bus where controllers are registered on a class rather than
spi_bus_type, serdev registers both struct serdev_controller and struct
serdev_device onto serdev_bus_type:
drivers/tty/serdev/core.c:serdev_controller_alloc() {
device_initialize(&ctrl->dev);
ctrl->dev.type = &serdev_ctrl_type;
ctrl->dev.bus = &serdev_bus_type;
ctrl->dev.parent = parent;
ctrl->host = host;
device_set_node(&ctrl->dev, dev_fwnode(host));
}
Commit 7ee69102dbc4ee ("serdev: only match serdev devices") added the
is_serdev_device(dev) check so controller devices on serdev_bus_type are
ignored during driver matching.
Without that check, when serdev_device_match() is called with dev pointing to
&ctrl->dev, it first evaluates acpi_driver_match_device() and
of_driver_match_device() against the controller's fwnode, which could match
and probe a struct serdev_controller as a struct serdev_device.
If neither firmware match succeeds, serdev_device_match() casts &ctrl->dev via
to_serdev_device(dev) and passes serdev->modalias to serdev_match_id(). In
struct serdev_device, modalias[SERDEV_NAME_SIZE] starts at offset
sizeof(struct device) + sizeof(int), which in struct serdev_controller aliases
the upper bytes of ctrl->host, followed by ctrl->nr, ctrl->serdev, ctrl->ops,
and extends 12 bytes past the end of struct serdev_controller on 64-bit
platforms. Because the upper bytes of the kernel pointer ctrl->host are
non-zero, modalias[0] is non-zero and strcmp(modalias, id->name) will read out
of bounds past struct serdev_controller when sdrv->id_table is set.
> diff --git a/include/linux/device-id/serdev.h b/include/linux/device-id/serdev.h
> new file mode 100644
> index 0000000000000..96644953ceced
> --- /dev/null
> +++ b/include/linux/device-id/serdev.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef LINUX_DEVICE_ID_SERDEV_H
> +#define LINUX_DEVICE_ID_SERDEV_H
> +
> +#ifdef __KERNEL__
> +typedef unsigned long kernel_ulong_t;
> +#endif
> +
> +/* serdev */
> +
> +#define SERDEV_NAME_SIZE 40
> +#define SERDEV_MODULE_PREFIX "serial:"
> +
> +struct serdev_device_id {
> + char name[SERDEV_NAME_SIZE];
> + kernel_ulong_t driver_data; /* Data private to the driver */
> +};
> +
> +#endif /* ifndef LINUX_DEVICE_ID_SERDEV_H */
[Severity: Medium]
Should struct serdev_device_id also be wired up in
include/linux/mod_devicetable.h, scripts/mod/devicetable-offsets.c, and
scripts/mod/file2alias.c?
serdev_device_uevent() emits MODALIAS=serial:<modalias> to userspace, and this
header follows the include/linux/device-id/ pattern used by modpost. However,
without including device-id/serdev.h in include/linux/mod_devicetable.h and
adding the corresponding DEVID(serdev_device_id) and devtable[] entries in
scripts/mod/, MODULE_DEVICE_TABLE(serdev, ...) is silently ignored by
handle_moddevtable() and no serial:<name> aliases are generated for module
autoloading.
> diff --git a/include/linux/serdev.h b/include/linux/serdev.h
> index b6c3d957ec155..96a441abc1ace 100644
> --- a/include/linux/serdev.h
> +++ b/include/linux/serdev.h
[ ... ]
> @@ -158,7 +168,7 @@ static inline void serdev_controller_put(struct serdev_controller *ctrl)
> }
>
> struct serdev_device *serdev_device_alloc(struct serdev_controller *);
> -int serdev_device_add(struct serdev_device *);
> +int serdev_device_add(struct serdev_device *serdev, const char *modalias);
> void serdev_device_remove(struct serdev_device *);
[Severity: Low]
Does changing the signature of serdev_device_add() here break the build for
bisecting before the follow-up patches in the series?
Two callers in drivers/platform/x86/ still pass a single argument at this
commit:
drivers/platform/x86/dell/dell-uart-backlight.c:dell_uart_bl_pdev_probe() {
...
ret = serdev_device_add(serdev);
}
drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c:yt2_1380_fc_pdev_probe() {
...
ret = serdev_device_add(serdev);
}
Those two callers are updated to pass KBUILD_MODNAME in the subsequent commits
"platform/x86: dell-uart-backlight: Bind through normal serdev matching" and
"platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Bind through normal
serdev matching", but at this commit (and the next commit for
yoga-tab2-pro-1380-fastcharger.c) building with CONFIG_DELL_UART_BACKLIGHT or
CONFIG_YOGA_TAB2_PRO_1380_FASTCHARGER enabled fails with too few arguments to
serdev_device_add(). Could those callers be updated to pass NULL in this
commit so every patch in the series builds cleanly?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261024022930.2704030-1-an.wu@canonical.com?part=1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 2:29 [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node ChunAn Wu
2026-10-24 2:29 ` [PATCH v4 1/3] " ChunAn Wu
@ 2026-10-24 2:29 ` ChunAn Wu
2026-10-24 2:35 ` sashiko-bot
` (2 more replies)
2026-10-24 2:29 ` [PATCH v4 3/3] platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: " ChunAn Wu
` (2 subsequent siblings)
4 siblings, 3 replies; 14+ messages in thread
From: ChunAn Wu @ 2026-10-24 2:29 UTC (permalink / raw)
To: linux-serial, platform-driver-x86
Cc: linux-kernel, markus.probst, gregkh, jirislaby, hansg,
ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
The driver creates a serdev client without firmware metadata and
force-attaches its driver to it.
Pass the modalias to serdev_device_add() and give the serdev driver a
matching id_table, so that the serdev core binds the two through normal
matching, then drop the manual attachment.
The client now also reports a "serial:dell_uart_backlight" modalias to
userspace instead of failing with -ENODEV. A failing serdev probe no
longer propagates out of the platform probe; as for any other bus, the
client is simply left unbound.
Signed-off-by: ChunAn Wu <an.wu@canonical.com>
---
.../platform/x86/dell/dell-uart-backlight.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
index f323a667dc2d..9b8ef91bb0a2 100644
--- a/drivers/platform/x86/dell/dell-uart-backlight.c
+++ b/drivers/platform/x86/dell/dell-uart-backlight.c
@@ -325,11 +325,17 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
return PTR_ERR_OR_ZERO(dell_bl->bl);
}
+static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
+ { KBUILD_MODNAME },
+ { }
+};
+
static struct serdev_device_driver dell_uart_bl_serdev_driver = {
.probe = dell_uart_bl_serdev_probe,
.driver = {
.name = KBUILD_MODNAME,
},
+ .id_table = dell_uart_bl_serdev_id,
};
static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
@@ -354,7 +360,7 @@ static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
if (!serdev)
return -ENOMEM;
- ret = serdev_device_add(serdev);
+ ret = serdev_device_add(serdev, KBUILD_MODNAME);
if (ret) {
dev_err(&pdev->dev, "error %d adding serdev\n", ret);
serdev_device_put(serdev);
@@ -365,20 +371,10 @@ static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
if (ret)
goto err_remove_serdev;
- /*
- * serdev device <-> driver matching relies on OF or ACPI matches and
- * neither is available here, manually bind the driver.
- */
- ret = device_driver_attach(&dell_uart_bl_serdev_driver.driver, &serdev->dev);
- if (ret)
- goto err_unregister_serdev_driver;
-
/* So that dell_uart_bl_pdev_remove() can remove the serdev */
platform_set_drvdata(pdev, serdev);
return 0;
-err_unregister_serdev_driver:
- serdev_device_driver_unregister(&dell_uart_bl_serdev_driver);
err_remove_serdev:
serdev_device_remove(serdev);
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 2:29 ` [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching ChunAn Wu
@ 2026-10-24 2:35 ` sashiko-bot
2026-10-24 11:59 ` kernel test robot
2026-10-24 17:42 ` kernel test robot
2 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-24 2:35 UTC (permalink / raw)
To: ChunAn Wu, linux-serial
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] platform/x86: dell-uart-backlight: use of nonexistent serdev modalias API
--
commit 6fdb948003156a6919ba6eb5db62dfc9148ff2fc
Author: ChunAn Wu <an.wu@canonical.com>
platform/x86: dell-uart-backlight: Bind through normal serdev matching
This patch converts dell-uart-backlight from manual device_driver_attach()
binding to serdev id_table and modalias matching via serdev_device_add().
> diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
> index f323a667dc2d2..9b8ef91bb0a20 100644
> --- a/drivers/platform/x86/dell/dell-uart-backlight.c
> +++ b/drivers/platform/x86/dell/dell-uart-backlight.c
> @@ -325,11 +325,17 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
> return PTR_ERR_OR_ZERO(dell_bl->bl);
> }
>
> +static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
> + { KBUILD_MODNAME },
> + { }
> +};
> +
> static struct serdev_device_driver dell_uart_bl_serdev_driver = {
> .probe = dell_uart_bl_serdev_probe,
> .driver = {
> .name = KBUILD_MODNAME,
> },
> + .id_table = dell_uart_bl_serdev_id,
> };
>
> static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
> @@ -354,7 +360,7 @@ static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
> if (!serdev)
> return -ENOMEM;
>
> - ret = serdev_device_add(serdev);
> + ret = serdev_device_add(serdev, KBUILD_MODNAME);
> if (ret) {
> dev_err(&pdev->dev, "error %d adding serdev\n", ret);
> serdev_device_put(serdev);
> @@ -365,20 +371,10 @@ static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
> if (ret)
> goto err_remove_serdev;
>
> - /*
> - * serdev device <-> driver matching relies on OF or ACPI matches and
> - * neither is available here, manually bind the driver.
> - */
> - ret = device_driver_attach(&dell_uart_bl_serdev_driver.driver, &serdev->dev);
> - if (ret)
> - goto err_unregister_serdev_driver;
[Severity: High]
Does this depend on a prerequisite patch adding modalias and id_table support
to the serdev core?
When building with CONFIG_DELL_UART_BACKLIGHT enabled, compilation fails in
drivers/platform/x86/dell/dell-uart-backlight.c because:
1. dell_uart_bl_serdev_id uses struct serdev_device_id, which is not defined
in include/linux/serdev.h or include/linux/mod_devicetable.h.
2. dell_uart_bl_serdev_driver initializes .id_table, which does not exist in
include/linux/serdev.h:
struct serdev_device_driver {
struct device_driver driver;
int (*probe)(struct serdev_device *);
void (*remove)(struct serdev_device *);
void (*shutdown)(struct serdev_device *);
};
3. dell_uart_bl_pdev_probe() passes two arguments to serdev_device_add(),
whereas drivers/tty/serdev/core.c defines it with a single parameter:
int serdev_device_add(struct serdev_device *serdev)
In addition, serdev_device_match() in drivers/tty/serdev/core.c only matches
via ACPI and OF:
static int serdev_device_match(struct device *dev, const struct device_driver *drv)
{
if (!is_serdev_device(dev))
return 0;
/* TODO: platform matching */
if (acpi_driver_match_device(dev, drv))
return 1;
return of_driver_match_device(dev, drv);
}
Without serdev id_table matching in the core, removing device_driver_attach()
from dell_uart_bl_pdev_probe() also leaves dell_uart_bl_serdev_driver unable
to bind when probing Dell UART backlight systems.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261024022930.2704030-3-an.wu@canonical.com?part=1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 2:29 ` [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching ChunAn Wu
2026-10-24 2:35 ` sashiko-bot
@ 2026-10-24 11:59 ` kernel test robot
2026-10-24 12:03 ` Markus Probst
2026-10-24 17:42 ` kernel test robot
2 siblings, 1 reply; 14+ messages in thread
From: kernel test robot @ 2026-10-24 11:59 UTC (permalink / raw)
To: ChunAn Wu, linux-serial, platform-driver-x86
Cc: oe-kbuild-all, linux-kernel, markus.probst, gregkh, jirislaby,
hansg, ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
Hi ChunAn,
kernel test robot noticed the following build errors:
[auto build test ERROR on driver-core/driver-core-testing]
[also build test ERROR on driver-core/driver-core-next driver-core/driver-core-linus linus/master v7.3 next-20261022]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/ChunAn-Wu/platform-x86-dell-uart-backlight-Bind-through-normal-serdev-matching/20261024-102929
base: driver-core/driver-core-testing
patch link: https://lore.kernel.org/r/20261024022930.2704030-3-an.wu%40canonical.com
patch subject: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
config: i386-randconfig-1007-20261024 (https://download.01.org/0day-ci/archive/20261024/202610241920.GJiRENj2-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261024/202610241920.GJiRENj2-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610241920.GJiRENj2-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
>> drivers/platform/x86/dell/dell-uart-backlight.c:328:38: error: array type has incomplete element type 'struct serdev_device_id'
328 | static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
| ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/platform/x86/dell/dell-uart-backlight.c:338:10: error: 'struct serdev_device_driver' has no member named 'id_table'
338 | .id_table = dell_uart_bl_serdev_id,
| ^~~~~~~~
drivers/platform/x86/dell/dell-uart-backlight.c: In function 'dell_uart_bl_pdev_probe':
>> drivers/platform/x86/dell/dell-uart-backlight.c:363:15: error: too many arguments to function 'serdev_device_add'
363 | ret = serdev_device_add(serdev, KBUILD_MODNAME);
| ^~~~~~~~~~~~~~~~~
In file included from drivers/platform/x86/dell/dell-uart-backlight.c:19:
include/linux/serdev.h:161:5: note: declared here
161 | int serdev_device_add(struct serdev_device *);
| ^~~~~~~~~~~~~~~~~
drivers/platform/x86/dell/dell-uart-backlight.c: At top level:
>> drivers/platform/x86/dell/dell-uart-backlight.c:328:38: warning: 'dell_uart_bl_serdev_id' defined but not used [-Wunused-variable]
328 | static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
| ^~~~~~~~~~~~~~~~~~~~~~
vim +328 drivers/platform/x86/dell/dell-uart-backlight.c
327
> 328 static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
329 { KBUILD_MODNAME },
330 { }
331 };
332
333 static struct serdev_device_driver dell_uart_bl_serdev_driver = {
334 .probe = dell_uart_bl_serdev_probe,
335 .driver = {
336 .name = KBUILD_MODNAME,
337 },
> 338 .id_table = dell_uart_bl_serdev_id,
339 };
340
341 static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
342 {
343 enum acpi_backlight_type bl_type;
344 struct serdev_device *serdev;
345 struct device *ctrl_dev;
346 int ret;
347
348 bl_type = acpi_video_get_backlight_type();
349 if (bl_type != acpi_backlight_dell_uart) {
350 dev_dbg(&pdev->dev, "Not loading (ACPI backlight type = %d)\n", bl_type);
351 return -ENODEV;
352 }
353
354 ctrl_dev = get_serdev_controller("DELL0501", NULL, 0, "serial0");
355 if (IS_ERR(ctrl_dev))
356 return PTR_ERR(ctrl_dev);
357
358 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
359 put_device(ctrl_dev);
360 if (!serdev)
361 return -ENOMEM;
362
> 363 ret = serdev_device_add(serdev, KBUILD_MODNAME);
364 if (ret) {
365 dev_err(&pdev->dev, "error %d adding serdev\n", ret);
366 serdev_device_put(serdev);
367 return ret;
368 }
369
370 ret = serdev_device_driver_register(&dell_uart_bl_serdev_driver);
371 if (ret)
372 goto err_remove_serdev;
373
374 /* So that dell_uart_bl_pdev_remove() can remove the serdev */
375 platform_set_drvdata(pdev, serdev);
376 return 0;
377
378 err_remove_serdev:
379 serdev_device_remove(serdev);
380 return ret;
381 }
382
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 11:59 ` kernel test robot
@ 2026-10-24 12:03 ` Markus Probst
0 siblings, 0 replies; 14+ messages in thread
From: Markus Probst @ 2026-10-24 12:03 UTC (permalink / raw)
To: kernel test robot, ChunAn Wu, linux-serial, platform-driver-x86
Cc: oe-kbuild-all, linux-kernel, gregkh, jirislaby, hansg,
ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
[-- Attachment #1: Type: text/plain, Size: 5336 bytes --]
On Sat, 2026-10-24 at 19:59 +0800, kernel test robot wrote:
> Hi ChunAn,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on driver-core/driver-core-testing]
> [also build test ERROR on driver-core/driver-core-next driver-core/driver-core-linus linus/master v7.3 next-20261022]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/ChunAn-Wu/platform-x86-dell-uart-backlight-Bind-through-normal-serdev-matching/20261024-102929
> base: driver-core/driver-core-testing
> patch link: https://lore.kernel.org/r/20261024022930.2704030-3-an.wu%40canonical.com
> patch subject: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
> config: i386-randconfig-1007-20261024 (https://download.01.org/0day-ci/archive/20261024/202610241920.GJiRENj2-lkp@intel.com/config)
> compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261024/202610241920.GJiRENj2-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes: https://lore.kernel.org/oe-kbuild-all/202610241920.GJiRENj2-lkp@intel.com/
>
> All error/warnings (new ones prefixed by >>):
>
> > > drivers/platform/x86/dell/dell-uart-backlight.c:328:38: error: array type has incomplete element type 'struct serdev_device_id'
> 328 | static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
> | ^~~~~~~~~~~~~~~~~~~~~~
> > > drivers/platform/x86/dell/dell-uart-backlight.c:338:10: error: 'struct serdev_device_driver' has no member named 'id_table'
> 338 | .id_table = dell_uart_bl_serdev_id,
> | ^~~~~~~~
> drivers/platform/x86/dell/dell-uart-backlight.c: In function 'dell_uart_bl_pdev_probe':
> > > drivers/platform/x86/dell/dell-uart-backlight.c:363:15: error: too many arguments to function 'serdev_device_add'
> 363 | ret = serdev_device_add(serdev, KBUILD_MODNAME);
> | ^~~~~~~~~~~~~~~~~
> In file included from drivers/platform/x86/dell/dell-uart-backlight.c:19:
> include/linux/serdev.h:161:5: note: declared here
> 161 | int serdev_device_add(struct serdev_device *);
> | ^~~~~~~~~~~~~~~~~
> drivers/platform/x86/dell/dell-uart-backlight.c: At top level:
> > > drivers/platform/x86/dell/dell-uart-backlight.c:328:38: warning: 'dell_uart_bl_serdev_id' defined but not used [-Wunused-variable]
> 328 | static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
> | ^~~~~~~~~~~~~~~~~~~~~~
>
>
> vim +328 drivers/platform/x86/dell/dell-uart-backlight.c
>
> 327
> > 328 static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
> 329 { KBUILD_MODNAME },
> 330 { }
> 331 };
> 332
> 333 static struct serdev_device_driver dell_uart_bl_serdev_driver = {
> 334 .probe = dell_uart_bl_serdev_probe,
> 335 .driver = {
> 336 .name = KBUILD_MODNAME,
> 337 },
> > 338 .id_table = dell_uart_bl_serdev_id,
> 339 };
> 340
> 341 static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
> 342 {
> 343 enum acpi_backlight_type bl_type;
> 344 struct serdev_device *serdev;
> 345 struct device *ctrl_dev;
> 346 int ret;
> 347
> 348 bl_type = acpi_video_get_backlight_type();
> 349 if (bl_type != acpi_backlight_dell_uart) {
> 350 dev_dbg(&pdev->dev, "Not loading (ACPI backlight type = %d)\n", bl_type);
> 351 return -ENODEV;
> 352 }
> 353
> 354 ctrl_dev = get_serdev_controller("DELL0501", NULL, 0, "serial0");
> 355 if (IS_ERR(ctrl_dev))
> 356 return PTR_ERR(ctrl_dev);
> 357
> 358 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
> 359 put_device(ctrl_dev);
> 360 if (!serdev)
> 361 return -ENOMEM;
> 362
> > 363 ret = serdev_device_add(serdev, KBUILD_MODNAME);
> 364 if (ret) {
> 365 dev_err(&pdev->dev, "error %d adding serdev\n", ret);
> 366 serdev_device_put(serdev);
> 367 return ret;
> 368 }
> 369
> 370 ret = serdev_device_driver_register(&dell_uart_bl_serdev_driver);
> 371 if (ret)
> 372 goto err_remove_serdev;
> 373
> 374 /* So that dell_uart_bl_pdev_remove() can remove the serdev */
> 375 platform_set_drvdata(pdev, serdev);
> 376 return 0;
> 377
> 378 err_remove_serdev:
> 379 serdev_device_remove(serdev);
> 380 return ret;
> 381 }
> 382
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
Because of the missing "2/3" in the subject line it likely has applied
it as first patch. I assume that was by mistake, given you also resent
the same patch again with the correct subject line.
Anyway, this report should be meaningless.
Thanks
- Markus Probst
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 870 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 2:29 ` [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching ChunAn Wu
2026-10-24 2:35 ` sashiko-bot
2026-10-24 11:59 ` kernel test robot
@ 2026-10-24 17:42 ` kernel test robot
2 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2026-10-24 17:42 UTC (permalink / raw)
To: ChunAn Wu, linux-serial, platform-driver-x86
Cc: llvm, oe-kbuild-all, linux-kernel, markus.probst, gregkh,
jirislaby, hansg, ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
Hi ChunAn,
kernel test robot noticed the following build errors:
[auto build test ERROR on driver-core/driver-core-testing]
[also build test ERROR on driver-core/driver-core-next driver-core/driver-core-linus linus/master v7.3 next-20261023]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/ChunAn-Wu/platform-x86-dell-uart-backlight-Bind-through-normal-serdev-matching/20261024-102929
base: driver-core/driver-core-testing
patch link: https://lore.kernel.org/r/20261024022930.2704030-3-an.wu%40canonical.com
patch subject: [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching
config: x86_64-randconfig-1014-20261024 (https://download.01.org/0day-ci/archive/20261025/202610250118.t0UAW41j-lkp@intel.com/config)
compiler: clang version 22.1.8 (https://github.com/llvm/llvm-project ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261025/202610250118.t0UAW41j-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610250118.t0UAW41j-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/platform/x86/dell/dell-uart-backlight.c:328:60: error: array has incomplete element type 'const struct serdev_device_id'
328 | static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
| ^
drivers/platform/x86/dell/dell-uart-backlight.c:328:21: note: forward declaration of 'struct serdev_device_id'
328 | static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
| ^
>> drivers/platform/x86/dell/dell-uart-backlight.c:363:34: error: too many arguments to function call, expected 1, have 2
363 | ret = serdev_device_add(serdev, KBUILD_MODNAME);
| ~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~
<command line>:8:24: note: expanded from macro 'KBUILD_MODNAME'
8 | #define KBUILD_MODNAME "dell_uart_backlight"
| ^~~~~~~~~~~~~~~~~~~~~
include/linux/serdev.h:161:5: note: 'serdev_device_add' declared here
161 | int serdev_device_add(struct serdev_device *);
| ^ ~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
vim +328 drivers/platform/x86/dell/dell-uart-backlight.c
327
> 328 static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
329 { KBUILD_MODNAME },
330 { }
331 };
332
333 static struct serdev_device_driver dell_uart_bl_serdev_driver = {
334 .probe = dell_uart_bl_serdev_probe,
335 .driver = {
336 .name = KBUILD_MODNAME,
337 },
338 .id_table = dell_uart_bl_serdev_id,
339 };
340
341 static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
342 {
343 enum acpi_backlight_type bl_type;
344 struct serdev_device *serdev;
345 struct device *ctrl_dev;
346 int ret;
347
348 bl_type = acpi_video_get_backlight_type();
349 if (bl_type != acpi_backlight_dell_uart) {
350 dev_dbg(&pdev->dev, "Not loading (ACPI backlight type = %d)\n", bl_type);
351 return -ENODEV;
352 }
353
354 ctrl_dev = get_serdev_controller("DELL0501", NULL, 0, "serial0");
355 if (IS_ERR(ctrl_dev))
356 return PTR_ERR(ctrl_dev);
357
358 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
359 put_device(ctrl_dev);
360 if (!serdev)
361 return -ENOMEM;
362
> 363 ret = serdev_device_add(serdev, KBUILD_MODNAME);
364 if (ret) {
365 dev_err(&pdev->dev, "error %d adding serdev\n", ret);
366 serdev_device_put(serdev);
367 return ret;
368 }
369
370 ret = serdev_device_driver_register(&dell_uart_bl_serdev_driver);
371 if (ret)
372 goto err_remove_serdev;
373
374 /* So that dell_uart_bl_pdev_remove() can remove the serdev */
375 platform_set_drvdata(pdev, serdev);
376 return 0;
377
378 err_remove_serdev:
379 serdev_device_remove(serdev);
380 return ret;
381 }
382
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 3/3] platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Bind through normal serdev matching
2026-10-24 2:29 [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node ChunAn Wu
2026-10-24 2:29 ` [PATCH v4 1/3] " ChunAn Wu
2026-10-24 2:29 ` [PATCH v4] platform/x86: dell-uart-backlight: Bind through normal serdev matching ChunAn Wu
@ 2026-10-24 2:29 ` ChunAn Wu
2026-10-24 4:07 ` sashiko-bot
2026-10-24 3:50 ` [PATCH v4 2/3] platform/x86: dell-uart-backlight: " ChunAn Wu
2026-10-24 8:40 ` [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node An Wu
4 siblings, 1 reply; 14+ messages in thread
From: ChunAn Wu @ 2026-10-24 2:29 UTC (permalink / raw)
To: linux-serial, platform-driver-x86
Cc: linux-kernel, markus.probst, gregkh, jirislaby, hansg,
ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
The software-node-backed serdev client cannot be matched through ACPI or
device tree and is force-attached to its driver.
Pass the modalias to serdev_device_add() and give the serdev driver a
matching id_table, so that the serdev core binds the two through normal
matching. Deferred probing is then handled by the driver core, so the
-EAGAIN translation is no longer needed.
A failing serdev probe no longer propagates out of the platform probe;
as for any other bus, the client is simply left unbound.
Signed-off-by: ChunAn Wu <an.wu@canonical.com>
---
.../lenovo/yoga-tab2-pro-1380-fastcharger.c | 25 +++++++------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c b/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
index 8551ab4d2c7d..d0bd9d4e3137 100644
--- a/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
+++ b/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
@@ -219,11 +219,17 @@ static int yt2_1380_fc_serdev_probe(struct serdev_device *serdev)
return 0;
}
+static const struct serdev_device_id yt2_1380_fc_serdev_id[] = {
+ { KBUILD_MODNAME },
+ { }
+};
+
static struct serdev_device_driver yt2_1380_fc_serdev_driver = {
.probe = yt2_1380_fc_serdev_probe,
.driver = {
.name = KBUILD_MODNAME,
},
+ .id_table = yt2_1380_fc_serdev_id,
};
static const struct pinctrl_map yt2_1380_fc_pinctrl_map[] = {
@@ -260,25 +266,12 @@ static int yt2_1380_fc_pdev_probe(struct platform_device *pdev)
/* The fwnode is a managed node, so it will be auto-put on serdev_device_put() */
fwnode_handle_get(dev_fwnode(&serdev->dev));
- ret = serdev_device_add(serdev);
+ ret = serdev_device_add(serdev, KBUILD_MODNAME);
if (ret) {
serdev_device_put(serdev);
return dev_err_probe(&pdev->dev, ret, "adding serdev\n");
}
- /*
- * serdev device <-> driver matching relies on OF or ACPI matches and
- * neither is available here, manually bind the driver.
- */
- ret = device_driver_attach(&yt2_1380_fc_serdev_driver.driver, &serdev->dev);
- if (ret) {
- /* device_driver_attach() maps EPROBE_DEFER to EAGAIN, map it back */
- serdev_device_remove(serdev);
- return dev_err_probe(&pdev->dev,
- (ret == -EAGAIN) ? -EPROBE_DEFER : ret,
- "attaching serdev driver\n");
- }
-
/* So that yt2_1380_fc_pdev_remove() can remove the serdev */
platform_set_drvdata(pdev, serdev);
return 0;
@@ -305,8 +298,8 @@ static int __init yt2_1380_fc_module_init(void)
int ret;
/*
- * serdev driver MUST be registered first because pdev driver calls
- * device_driver_attach() on the serdev, serdev-driver pair.
+ * serdev driver MUST be registered first so that the serdev device
+ * created by the pdev probe binds to it via the id_table match.
*/
ret = serdev_device_driver_register(&yt2_1380_fc_serdev_driver);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 3/3] platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Bind through normal serdev matching
2026-10-24 2:29 ` [PATCH v4 3/3] platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: " ChunAn Wu
@ 2026-10-24 4:07 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-24 4:07 UTC (permalink / raw)
To: ChunAn Wu, linux-serial
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] serdev: type confusion in serdev_device_match() via driver id_table
--
commit bc4039918b4164f5e3178978c756b91d89a4bde7
Author: ChunAn Wu <an.wu@canonical.com>
platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Bind through normal serdev matching
This commit switches the Lenovo Yoga Tab 2 Pro 1380 fastcharger driver from
manual driver attachment via device_driver_attach() to standard serdev modalias
matching by passing KBUILD_MODNAME to serdev_device_add() and adding an
id_table to yt2_1380_fc_serdev_driver.
> diff --git a/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c b/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
> index 8551ab4d2c7db..d0bd9d4e3137c 100644
> --- a/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
> +++ b/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
> @@ -219,11 +219,17 @@ static int yt2_1380_fc_serdev_probe(struct serdev_device *serdev)
> return 0;
> }
>
> +static const struct serdev_device_id yt2_1380_fc_serdev_id[] = {
> + { KBUILD_MODNAME },
> + { }
> +};
> +
> static struct serdev_device_driver yt2_1380_fc_serdev_driver = {
> .probe = yt2_1380_fc_serdev_probe,
> .driver = {
> .name = KBUILD_MODNAME,
> },
> + .id_table = yt2_1380_fc_serdev_id,
> };
[Severity: High]
Does adding id_table to yt2_1380_fc_serdev_driver trigger a type confusion and
out-of-bounds read in serdev_device_match() when matching against
serdev_controller devices on serdev_bus_type?
In drivers/tty/serdev/core.c, serdev_controller_alloc() places controller
devices on serdev_bus_type:
device_initialize(&ctrl->dev);
ctrl->dev.type = &serdev_ctrl_type;
ctrl->dev.bus = &serdev_bus_type;
When yt2_1380_fc_module_init() calls serdev_device_driver_register() for
yt2_1380_fc_serdev_driver (or when a new serdev_controller is added), the
driver core runs serdev_device_match() against every device on
serdev_bus_type, including struct serdev_controller instances:
static int serdev_device_match(struct device *dev, const struct device_driver *drv)
{
const struct serdev_device *serdev = to_serdev_device(dev);
const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv);
if (acpi_driver_match_device(dev, drv))
return 1;
if (of_driver_match_device(dev, drv))
return 1;
return !!serdev_match_id(sdrv->id_table, serdev->modalias);
}
Because serdev_device_match() does not check is_serdev_device(dev) before
casting dev with to_serdev_device(dev), and yt2_1380_fc_serdev_driver has no
ACPI or OF match table, serdev_device_match() falls through to
serdev_match_id(sdrv->id_table, serdev->modalias) on struct serdev_controller
devices.
In struct serdev_device, modalias[SERDEV_NAME_SIZE] starts at offset
sizeof(struct device) + 4, which in struct serdev_controller overlaps the
struct device *host pointer, ctrl->nr, ctrl->serdev, ctrl->ops, and extends 12
bytes past sizeof(struct serdev_controller). When the overlapping byte at
modalias[0] is non-zero, serdev_match_id() passes that non-string memory and
trailing out-of-bounds bytes to strcmp().
Should serdev_device_match() verify is_serdev_device(dev) before casting dev
to struct serdev_device?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261024022930.2704030-1-an.wu@canonical.com?part=3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 2/3] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 2:29 [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node ChunAn Wu
` (2 preceding siblings ...)
2026-10-24 2:29 ` [PATCH v4 3/3] platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: " ChunAn Wu
@ 2026-10-24 3:50 ` ChunAn Wu
2026-10-24 4:02 ` sashiko-bot
2026-10-24 8:40 ` [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node An Wu
4 siblings, 1 reply; 14+ messages in thread
From: ChunAn Wu @ 2026-10-24 3:50 UTC (permalink / raw)
To: an.wu
Cc: derekjohn.clark, gregkh, hansg, ilpo.jarvinen, jirislaby,
linux-kernel, linux-serial, markus.probst, mpearson-lenovo,
platform-driver-x86
The driver creates a serdev client without firmware metadata and
force-attaches its driver to it.
Pass the modalias to serdev_device_add() and give the serdev driver a
matching id_table, so that the serdev core binds the two through normal
matching, then drop the manual attachment.
The client now also reports a "serial:dell_uart_backlight" modalias to
userspace instead of failing with -ENODEV. A failing serdev probe no
longer propagates out of the platform probe; as for any other bus, the
client is simply left unbound.
Signed-off-by: ChunAn Wu <an.wu@canonical.com>
---
.../platform/x86/dell/dell-uart-backlight.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
index f323a667dc2d..9b8ef91bb0a2 100644
--- a/drivers/platform/x86/dell/dell-uart-backlight.c
+++ b/drivers/platform/x86/dell/dell-uart-backlight.c
@@ -325,11 +325,17 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
return PTR_ERR_OR_ZERO(dell_bl->bl);
}
+static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
+ { KBUILD_MODNAME },
+ { }
+};
+
static struct serdev_device_driver dell_uart_bl_serdev_driver = {
.probe = dell_uart_bl_serdev_probe,
.driver = {
.name = KBUILD_MODNAME,
},
+ .id_table = dell_uart_bl_serdev_id,
};
static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
@@ -354,7 +360,7 @@ static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
if (!serdev)
return -ENOMEM;
- ret = serdev_device_add(serdev);
+ ret = serdev_device_add(serdev, KBUILD_MODNAME);
if (ret) {
dev_err(&pdev->dev, "error %d adding serdev\n", ret);
serdev_device_put(serdev);
@@ -365,20 +371,10 @@ static int dell_uart_bl_pdev_probe(struct platform_device *pdev)
if (ret)
goto err_remove_serdev;
- /*
- * serdev device <-> driver matching relies on OF or ACPI matches and
- * neither is available here, manually bind the driver.
- */
- ret = device_driver_attach(&dell_uart_bl_serdev_driver.driver, &serdev->dev);
- if (ret)
- goto err_unregister_serdev_driver;
-
/* So that dell_uart_bl_pdev_remove() can remove the serdev */
platform_set_drvdata(pdev, serdev);
return 0;
-err_unregister_serdev_driver:
- serdev_device_driver_unregister(&dell_uart_bl_serdev_driver);
err_remove_serdev:
serdev_device_remove(serdev);
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 2/3] platform/x86: dell-uart-backlight: Bind through normal serdev matching
2026-10-24 3:50 ` [PATCH v4 2/3] platform/x86: dell-uart-backlight: " ChunAn Wu
@ 2026-10-24 4:02 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-24 4:02 UTC (permalink / raw)
To: ChunAn Wu; +Cc: linux-serial
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] platform/x86: dell-uart-backlight: type confusion in serdev_device_match()
--
commit 845cea88ea8fd97f6d009ac4a558f36871acb863
Author: ChunAn Wu <an.wu@canonical.com>
platform/x86: dell-uart-backlight: Bind through normal serdev matching
This commit switches the dell-uart-backlight driver from manually binding
its serdev client via device_driver_attach() to passing a modalias to
serdev_device_add() and matching via a serdev_device_id table.
> diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
> index f323a667dc2d2..9b8ef91bb0a20 100644
> --- a/drivers/platform/x86/dell/dell-uart-backlight.c
> +++ b/drivers/platform/x86/dell/dell-uart-backlight.c
> @@ -325,11 +325,17 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
> return PTR_ERR_OR_ZERO(dell_bl->bl);
> }
>
> +static const struct serdev_device_id dell_uart_bl_serdev_id[] = {
> + { KBUILD_MODNAME },
> + { }
> +};
> +
> static struct serdev_device_driver dell_uart_bl_serdev_driver = {
> .probe = dell_uart_bl_serdev_probe,
> .driver = {
> .name = KBUILD_MODNAME,
> },
> + .id_table = dell_uart_bl_serdev_id,
> };
[Severity: High]
Does adding id_table to dell_uart_bl_serdev_driver trigger a type confusion
and out-of-bounds read in serdev_device_match() when
dell_uart_bl_pdev_probe() calls serdev_device_driver_register()?
Both struct serdev_controller and struct serdev_device are registered on
serdev_bus_type:
drivers/tty/serdev/core.c:serdev_controller_alloc() {
...
device_initialize(&ctrl->dev);
ctrl->dev.type = &serdev_ctrl_type;
ctrl->dev.bus = &serdev_bus_type;
ctrl->dev.parent = parent;
ctrl->host = host;
device_set_node(&ctrl->dev, dev_fwnode(host));
...
}
Earlier in the series, commit 1b3d9973e0d0 ("serdev: handle devices without
an ACPI or device tree node") removed the is_serdev_device(dev) check from
serdev_device_match(), leaving an unconditional cast via to_serdev_device():
drivers/tty/serdev/core.c:serdev_device_match() {
const struct serdev_device *serdev = to_serdev_device(dev);
const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv);
if (acpi_driver_match_device(dev, drv))
return 1;
if (of_driver_match_device(dev, drv))
return 1;
return !!serdev_match_id(sdrv->id_table, serdev->modalias);
}
When dell_uart_bl_pdev_probe() calls:
serdev_device_driver_register(&dell_uart_bl_serdev_driver)
-> driver_register()
-> bus_add_driver()
-> driver_attach()
-> serdev_device_match()
the driver core iterates over every device on serdev_bus_type, including
the struct serdev_controller instance ("serial0").
Because dell_uart_bl_serdev_driver has no ACPI or OF match table and sets a
non-NULL id_table, serdev_device_match() reaches
serdev_match_id(sdrv->id_table, serdev->modalias) with serdev pointing to a
struct serdev_controller.
In struct serdev_device, modalias is at offset sizeof(struct device) + 4
and is 40 bytes long. In struct serdev_controller, that offset overlaps
struct device *host, unsigned int nr, struct serdev_device *serdev,
const struct serdev_controller_ops *ops, and extends 12 bytes past the end
of struct serdev_controller, passing those bytes into strcmp(modalias,
id->name) in serdev_match_id().
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261024022930.2704030-1-an.wu@canonical.com?part=2
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node
2026-10-24 2:29 [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node ChunAn Wu
` (3 preceding siblings ...)
2026-10-24 3:50 ` [PATCH v4 2/3] platform/x86: dell-uart-backlight: " ChunAn Wu
@ 2026-10-24 8:40 ` An Wu
2026-10-24 11:48 ` Markus Probst
4 siblings, 1 reply; 14+ messages in thread
From: An Wu @ 2026-10-24 8:40 UTC (permalink / raw)
To: linux-serial, platform-driver-x86
Cc: linux-kernel, markus.probst, gregkh, jirislaby, hansg,
ilpo.jarvinen, mpearson-lenovo, derekjohn.clark
Hi Makus
According to sashiko:
'''
In drivers/tty/serdev/core.c, serdev_controller_alloc() places controller
devices on serdev_bus_type:
device_initialize(&ctrl->dev);
ctrl->dev.type = &serdev_ctrl_type;
ctrl->dev.bus = &serdev_bus_type;
When yt2_1380_fc_module_init() calls serdev_device_driver_register() for
yt2_1380_fc_serdev_driver (or when a new serdev_controller is added), the
driver core runs serdev_device_match() against every device on
serdev_bus_type, including struct serdev_controller instances:
static int serdev_device_match(struct device *dev, const struct
device_driver *drv)
{
const struct serdev_device *serdev = to_serdev_device(dev);
const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv);
if (acpi_driver_match_device(dev, drv))
return 1;
if (of_driver_match_device(dev, drv))
return 1;
return !!serdev_match_id(sdrv->id_table, serdev->modalias);
}
Because serdev_device_match() does not check is_serdev_device(dev) before
casting dev with to_serdev_device(dev), and yt2_1380_fc_serdev_driver has no
ACPI or OF match table, serdev_device_match() falls through to
serdev_match_id(sdrv->id_table, serdev->modalias) on struct serdev_controller
devices.
In struct serdev_device, modalias[SERDEV_NAME_SIZE] starts at offset
sizeof(struct device) + 4, which in struct serdev_controller overlaps the
struct device *host pointer, ctrl->nr, ctrl->serdev, ctrl->ops, and extends 12
bytes past sizeof(struct serdev_controller). When the overlapping byte at
modalias[0] is non-zero, serdev_match_id() passes that non-string memory and
trailing out-of-bounds bytes to strcmp().
Should serdev_device_match() verify is_serdev_device(dev) before casting dev
to struct serdev_device?
'''
If we remove is_serdev_device could cause some problem due to the
serdev_controller could also
run into this function and "serdev_match_id(sdrv->id_table,
serdev->modalias);" can be a potential risk.
I will add the "is_serdev_device" back and send v5 out.
BR
An
On Sat, Oct 24, 2026 at 10:29 AM ChunAn Wu <an.wu@canonical.com> wrote:
>
> Driver-created serdev clients without an ACPI companion or device tree
> node currently have no modalias and cannot be matched to a driver:
> their modalias sysfs read returns -ENODEV and their creators force a
> bind with device_driver_attach().
>
> Backlight function on dell-uart-backlight is not affected: that class
> device is registered independently and gets its own add uevent. The
> user-visible breakage is the failing modalias read on an existing
> serdev child -- Checkbox dkms_info_attachment aborts with
> "OSError: [Errno 19] No such device".
>
> Resolve the two long-standing serdev-core TODOs by letting the creator
> pass a modalias to serdev_device_add() and giving the serdev driver an
> id_table, modelled on the SPI bus. ACPI and OF match first and are
> unchanged. Convert dell-uart-backlight and the Lenovo Yoga Tab 2 Pro
> fastcharger to this path and drop their force-attach workarounds.
>
> Changes in v4:
> - Patch 1: drop the dead is_serdev_device() guard from the match
> callback, and dereference serdev once at the top
> - Patch 1: drop the "large enough" comment on SERDEV_NAME_SIZE
> - Patch 1: in struct serdev_device_driver, place id_table right under
> driver, next to driver->of_match_table and driver->acpi_match_table
> - Patch 1: merge serdev_device_set_modalias() into serdev_device_add()
> so the modalias is set at the only point where forgetting it would
> matter; internal firmware callers pass NULL
> - All three patches: tightened commit messages and moved the v2/v3
> changelog narrative out of Patch 1 into this cover letter
>
> Changes in v3:
> - Rename struct serdev_device::name to ::modalias; dev_name() is
> unchanged
> - Model matching on the SPI bus: add struct serdev_device_id and
> id_table; drop driver->name matching
> - Add serdev_device_set_modalias() helper and SERDEV_MODULE_PREFIX
> - No MODULE_DEVICE_TABLE(serdev, ...) support: both in-tree
> firmware-less clients are created by the same module that provides
> their driver, so udev has nothing to autoload
>
> Changes in v2:
> - Instead of silently returning success with no modalias, use a
> creator-supplied name as a "serial:<name>" modalias fallback and as
> the matching key, so clients can bind through normal serdev matching
>
> v3: https://lore.kernel.org/lkml/20261023052717.2577234-1-an.wu@canonical.com/
> v2: https://lore.kernel.org/lkml/20261022032842.2492572-1-an.wu@canonical.com/
> v1: https://lore.kernel.org/lkml/20261021092124.2306053-1-an.wu@canonical.com/
>
> ChunAn Wu (3):
> serdev: handle devices without an ACPI or device tree node
> platform/x86: dell-uart-backlight: Bind through normal serdev matching
> platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Bind through
> normal serdev matching
>
> MAINTAINERS | 1 +
> .../platform/x86/dell/dell-uart-backlight.c | 33 ++++------
> .../lenovo/yoga-tab2-pro-1380-fastcharger.c | 25 +++----
> .../platform/x86/x86-android-tablets/core.c | 2 +-
> drivers/power/sequencing/pwrseq-pcie-m2.c | 2 +-
> drivers/tty/serdev/core.c | 65 ++++++++++++++-----
> include/linux/device-id/serdev.h | 19 ++++++
> include/linux/serdev.h | 12 +++-
> 8 files changed, 105 insertions(+), 54 deletions(-)
> create mode 100644 include/linux/device-id/serdev.h
>
>
> base-commit: 9e947d96915af63e28896caae85a81b74855621b
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node
2026-10-24 8:40 ` [PATCH v4 0/3] serdev: handle devices without an ACPI or device tree node An Wu
@ 2026-10-24 11:48 ` Markus Probst
0 siblings, 0 replies; 14+ messages in thread
From: Markus Probst @ 2026-10-24 11:48 UTC (permalink / raw)
To: An Wu, linux-serial, platform-driver-x86
Cc: linux-kernel, gregkh, jirislaby, hansg, ilpo.jarvinen,
mpearson-lenovo, derekjohn.clark
[-- Attachment #1: Type: text/plain, Size: 6121 bytes --]
On Sat, 2026-10-24 at 16:40 +0800, An Wu wrote:
> Hi Makus
> According to sashiko:
> '''
> In drivers/tty/serdev/core.c, serdev_controller_alloc() places controller
> devices on serdev_bus_type:
>
> device_initialize(&ctrl->dev);
> ctrl->dev.type = &serdev_ctrl_type;
> ctrl->dev.bus = &serdev_bus_type;
>
> When yt2_1380_fc_module_init() calls serdev_device_driver_register() for
> yt2_1380_fc_serdev_driver (or when a new serdev_controller is added), the
> driver core runs serdev_device_match() against every device on
> serdev_bus_type, including struct serdev_controller instances:
>
> static int serdev_device_match(struct device *dev, const struct
> device_driver *drv)
> {
> const struct serdev_device *serdev = to_serdev_device(dev);
> const struct serdev_device_driver *sdrv = to_serdev_device_driver(drv);
>
> if (acpi_driver_match_device(dev, drv))
> return 1;
>
> if (of_driver_match_device(dev, drv))
> return 1;
>
> return !!serdev_match_id(sdrv->id_table, serdev->modalias);
> }
>
> Because serdev_device_match() does not check is_serdev_device(dev) before
> casting dev with to_serdev_device(dev), and yt2_1380_fc_serdev_driver has no
> ACPI or OF match table, serdev_device_match() falls through to
> serdev_match_id(sdrv->id_table, serdev->modalias) on struct serdev_controller
> devices.
>
> In struct serdev_device, modalias[SERDEV_NAME_SIZE] starts at offset
> sizeof(struct device) + 4, which in struct serdev_controller overlaps the
> struct device *host pointer, ctrl->nr, ctrl->serdev, ctrl->ops, and extends 12
> bytes past sizeof(struct serdev_controller). When the overlapping byte at
> modalias[0] is non-zero, serdev_match_id() passes that non-string memory and
> trailing out-of-bounds bytes to strcmp().
>
> Should serdev_device_match() verify is_serdev_device(dev) before casting dev
> to struct serdev_device?
> '''
>
> If we remove is_serdev_device could cause some problem due to the
> serdev_controller could also
> run into this function and "serdev_match_id(sdrv->id_table,
> serdev->modalias);" can be a potential risk.
>
> I will add the "is_serdev_device" back and send v5 out.
Your right, I missed that.
Thanks
- Markus Probst
>
> BR
> An
>
>
> On Sat, Oct 24, 2026 at 10:29 AM ChunAn Wu <an.wu@canonical.com> wrote:
> >
> > Driver-created serdev clients without an ACPI companion or device tree
> > node currently have no modalias and cannot be matched to a driver:
> > their modalias sysfs read returns -ENODEV and their creators force a
> > bind with device_driver_attach().
> >
> > Backlight function on dell-uart-backlight is not affected: that class
> > device is registered independently and gets its own add uevent. The
> > user-visible breakage is the failing modalias read on an existing
> > serdev child -- Checkbox dkms_info_attachment aborts with
> > "OSError: [Errno 19] No such device".
> >
> > Resolve the two long-standing serdev-core TODOs by letting the creator
> > pass a modalias to serdev_device_add() and giving the serdev driver an
> > id_table, modelled on the SPI bus. ACPI and OF match first and are
> > unchanged. Convert dell-uart-backlight and the Lenovo Yoga Tab 2 Pro
> > fastcharger to this path and drop their force-attach workarounds.
> >
> > Changes in v4:
> > - Patch 1: drop the dead is_serdev_device() guard from the match
> > callback, and dereference serdev once at the top
> > - Patch 1: drop the "large enough" comment on SERDEV_NAME_SIZE
> > - Patch 1: in struct serdev_device_driver, place id_table right under
> > driver, next to driver->of_match_table and driver->acpi_match_table
> > - Patch 1: merge serdev_device_set_modalias() into serdev_device_add()
> > so the modalias is set at the only point where forgetting it would
> > matter; internal firmware callers pass NULL
> > - All three patches: tightened commit messages and moved the v2/v3
> > changelog narrative out of Patch 1 into this cover letter
> >
> > Changes in v3:
> > - Rename struct serdev_device::name to ::modalias; dev_name() is
> > unchanged
> > - Model matching on the SPI bus: add struct serdev_device_id and
> > id_table; drop driver->name matching
> > - Add serdev_device_set_modalias() helper and SERDEV_MODULE_PREFIX
> > - No MODULE_DEVICE_TABLE(serdev, ...) support: both in-tree
> > firmware-less clients are created by the same module that provides
> > their driver, so udev has nothing to autoload
> >
> > Changes in v2:
> > - Instead of silently returning success with no modalias, use a
> > creator-supplied name as a "serial:<name>" modalias fallback and as
> > the matching key, so clients can bind through normal serdev matching
> >
> > v3: https://lore.kernel.org/lkml/20261023052717.2577234-1-an.wu@canonical.com/
> > v2: https://lore.kernel.org/lkml/20261022032842.2492572-1-an.wu@canonical.com/
> > v1: https://lore.kernel.org/lkml/20261021092124.2306053-1-an.wu@canonical.com/
> >
> > ChunAn Wu (3):
> > serdev: handle devices without an ACPI or device tree node
> > platform/x86: dell-uart-backlight: Bind through normal serdev matching
> > platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Bind through
> > normal serdev matching
> >
> > MAINTAINERS | 1 +
> > .../platform/x86/dell/dell-uart-backlight.c | 33 ++++------
> > .../lenovo/yoga-tab2-pro-1380-fastcharger.c | 25 +++----
> > .../platform/x86/x86-android-tablets/core.c | 2 +-
> > drivers/power/sequencing/pwrseq-pcie-m2.c | 2 +-
> > drivers/tty/serdev/core.c | 65 ++++++++++++++-----
> > include/linux/device-id/serdev.h | 19 ++++++
> > include/linux/serdev.h | 12 +++-
> > 8 files changed, 105 insertions(+), 54 deletions(-)
> > create mode 100644 include/linux/device-id/serdev.h
> >
> >
> > base-commit: 9e947d96915af63e28896caae85a81b74855621b
> > --
> > 2.34.1
> >
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 870 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread