* [PATCH v2 01/10] serdev: Convert to_serdev_*() helpers to macros and use container_of_const()
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 13:47 ` Bartosz Golaszewski
2025-11-25 14:45 ` [PATCH v2 02/10] serdev: Add serdev device based driver match support Manivannan Sadhasivam via B4 Relay
` (9 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
If these helpers receive the 'const struct device' pointer, then the const
qualifier will get dropped, leading to below warning:
warning: passing argument 1 of ‘to_serdev_device_driver’ discards 'const'
qualifier from pointer target type [-Wdiscarded-qualifiers]
This is not an issue as of now, but with the future commits adding serdev
device based driver matching, this warning will get triggered. Hence,
convert these helpers to macros so that the qualifier get preserved and
also use container_of_const() as container_of() is deprecated.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
include/linux/serdev.h | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 34562eb99931..ecde0ad3e248 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -49,10 +49,7 @@ struct serdev_device {
struct mutex write_lock;
};
-static inline struct serdev_device *to_serdev_device(struct device *d)
-{
- return container_of(d, struct serdev_device, dev);
-}
+#define to_serdev_device(d) container_of_const(d, struct serdev_device, dev)
/**
* struct serdev_device_driver - serdev slave device driver
@@ -67,10 +64,7 @@ struct serdev_device_driver {
void (*remove)(struct serdev_device *);
};
-static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d)
-{
- return container_of(d, struct serdev_device_driver, driver);
-}
+#define to_serdev_device_driver(d) container_of_const(d, struct serdev_device_driver, driver)
enum serdev_parity {
SERDEV_PARITY_NONE,
@@ -111,10 +105,7 @@ struct serdev_controller {
const struct serdev_controller_ops *ops;
};
-static inline struct serdev_controller *to_serdev_controller(struct device *d)
-{
- return container_of(d, struct serdev_controller, dev);
-}
+#define to_serdev_controller(d) container_of_const(d, struct serdev_controller, dev)
static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev)
{
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 01/10] serdev: Convert to_serdev_*() helpers to macros and use container_of_const()
2025-11-25 14:45 ` [PATCH v2 01/10] serdev: Convert to_serdev_*() helpers to macros and use container_of_const() Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 13:47 ` Bartosz Golaszewski
0 siblings, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 13:47 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski, Manivannan Sadhasivam via B4 Relay,
linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov
On Tue, 25 Nov 2025 15:45:05 +0100, Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> If these helpers receive the 'const struct device' pointer, then the const
> qualifier will get dropped, leading to below warning:
>
> warning: passing argument 1 of ‘to_serdev_device_driver’ discards 'const'
> qualifier from pointer target type [-Wdiscarded-qualifiers]
>
> This is not an issue as of now, but with the future commits adding serdev
> device based driver matching, this warning will get triggered. Hence,
> convert these helpers to macros so that the qualifier get preserved and
> also use container_of_const() as container_of() is deprecated.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 02/10] serdev: Add serdev device based driver match support
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
2025-11-25 14:45 ` [PATCH v2 01/10] serdev: Convert to_serdev_*() helpers to macros and use container_of_const() Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 14:32 ` Bartosz Golaszewski
2025-11-25 14:45 ` [PATCH v2 03/10] serdev: Allow passing the serdev device name to serdev_device_add() Manivannan Sadhasivam via B4 Relay
` (8 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Add support to match serdev devices with serdev drivers based on the serdev
ID table defined in serdev_device_driver::id_table.
The matching function, serdev_driver_match_device() uses the serdev device
name to match against the entries in serdev_device_driver::id_table.
If there is no serdev id_table for the driver, then serdev_device_match()
will fallback to ACPI and DT based matching.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/tty/serdev/core.c | 23 ++++++++++++++++++++++-
include/linux/mod_devicetable.h | 7 +++++++
include/linux/serdev.h | 4 ++++
scripts/mod/devicetable-offsets.c | 3 +++
4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index b33e708cb245..2b5582cd5063 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -85,12 +85,33 @@ static const struct device_type serdev_ctrl_type = {
.release = serdev_ctrl_release,
};
+static int serdev_driver_match_device(struct device *dev, const struct device_driver *drv)
+{
+ const struct serdev_device_driver *serdev_drv = to_serdev_device_driver(drv);
+ struct serdev_device *serdev = to_serdev_device(dev);
+ const struct serdev_device_id *id;
+
+ if (!serdev_drv->id_table)
+ return 0;
+
+ for (id = serdev_drv->id_table; id->name[0]; id++) {
+ if (!strcmp(dev_name(dev), id->name)) {
+ serdev->id = id;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static int serdev_device_match(struct device *dev, const struct device_driver *drv)
{
if (!is_serdev_device(dev))
return 0;
- /* TODO: platform matching */
+ if (serdev_driver_match_device(dev, drv))
+ return 1;
+
if (acpi_driver_match_device(dev, drv))
return 1;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 6077972e8b45..70c54c4bedba 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -976,4 +976,11 @@ struct coreboot_device_id {
kernel_ulong_t driver_data;
};
+#define SERDEV_NAME_SIZE 32
+
+struct serdev_device_id {
+ const char name[SERDEV_NAME_SIZE];
+ kernel_ulong_t driver_data;
+};
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index ecde0ad3e248..aca92e0ee6e7 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -39,6 +39,7 @@ struct serdev_device_ops {
* @ops: Device operations.
* @write_comp Completion used by serdev_device_write() internally
* @write_lock Lock to serialize access when writing data
+ * @id: serdev device ID entry
*/
struct serdev_device {
struct device dev;
@@ -47,6 +48,7 @@ struct serdev_device {
const struct serdev_device_ops *ops;
struct completion write_comp;
struct mutex write_lock;
+ const struct serdev_device_id *id;
};
#define to_serdev_device(d) container_of_const(d, struct serdev_device, dev)
@@ -55,11 +57,13 @@ struct serdev_device {
* struct serdev_device_driver - serdev slave device driver
* @driver: serdev device drivers should initialize name field of this
* structure.
+ * @id_table: serdev device ID table
* @probe: binds this driver to a serdev device.
* @remove: unbinds this driver from the 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 *);
};
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index d3d00e85edf7..c1bfa8eddc4d 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -280,5 +280,8 @@ int main(void)
DEVID(coreboot_device_id);
DEVID_FIELD(coreboot_device_id, tag);
+ DEVID(serdev_device_id);
+ DEVID_FIELD(serdev_device_id, name);
+
return 0;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 02/10] serdev: Add serdev device based driver match support
2025-11-25 14:45 ` [PATCH v2 02/10] serdev: Add serdev device based driver match support Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 14:32 ` Bartosz Golaszewski
0 siblings, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 14:32 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Manivannan Sadhasivam via B4 Relay, linux-serial, linux-kernel,
linux-kbuild, platform-driver-x86, linux-pci, devicetree,
linux-arm-msm, linux-bluetooth, linux-pm, Stephan Gerhold,
Dmitry Baryshkov, Rob Herring, Greg Kroah-Hartman, Jiri Slaby,
Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
On Tue, 25 Nov 2025 15:45:06 +0100, Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Add support to match serdev devices with serdev drivers based on the serdev
> ID table defined in serdev_device_driver::id_table.
>
> The matching function, serdev_driver_match_device() uses the serdev device
> name to match against the entries in serdev_device_driver::id_table.
>
> If there is no serdev id_table for the driver, then serdev_device_match()
> will fallback to ACPI and DT based matching.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/tty/serdev/core.c | 23 ++++++++++++++++++++++-
> include/linux/mod_devicetable.h | 7 +++++++
> include/linux/serdev.h | 4 ++++
> scripts/mod/devicetable-offsets.c | 3 +++
> 4 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index b33e708cb245..2b5582cd5063 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
> @@ -85,12 +85,33 @@ static const struct device_type serdev_ctrl_type = {
> .release = serdev_ctrl_release,
> };
>
> +static int serdev_driver_match_device(struct device *dev, const struct device_driver *drv)
> +{
> + const struct serdev_device_driver *serdev_drv = to_serdev_device_driver(drv);
> + struct serdev_device *serdev = to_serdev_device(dev);
> + const struct serdev_device_id *id;
> +
> + if (!serdev_drv->id_table)
> + return 0;
> +
> + for (id = serdev_drv->id_table; id->name[0]; id++) {
> + if (!strcmp(dev_name(dev), id->name)) {
> + serdev->id = id;
> + return 1;
> + }
> + }
> +
> + return 0;
> +}
> +
I don't know if Rob agrees with me but I would very much prefer to see
software-node-based approach instead of an ID table matching.
Could you in the pwrseq driver, create a software node for the serdev device
you allocate, set its "compatible" to "qcom,wcn7850-bt" and match against it
here?
This has several benefits: if you ever need to pass more properties to the
serdev devices, you already have a medium for that and you can also leave
serdev_device_add() alone. You're comparing the entire name here - what if
someone sets device's ID to some value and the name will be "WCN7850.2"?
You could also drop the serdev_id field from struct serdev_device. For matching
you could even reuse the of_device_id from the device driver.
Which also makes me think that maybe we should finally think about a generic,
fwnode-based device driver matching in the driver model...
Bartosz
> static int serdev_device_match(struct device *dev, const struct device_driver *drv)
> {
> if (!is_serdev_device(dev))
> return 0;
>
> - /* TODO: platform matching */
> + if (serdev_driver_match_device(dev, drv))
> + return 1;
> +
> if (acpi_driver_match_device(dev, drv))
> return 1;
>
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 6077972e8b45..70c54c4bedba 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -976,4 +976,11 @@ struct coreboot_device_id {
> kernel_ulong_t driver_data;
> };
>
> +#define SERDEV_NAME_SIZE 32
> +
> +struct serdev_device_id {
> + const char name[SERDEV_NAME_SIZE];
> + kernel_ulong_t driver_data;
> +};
> +
> #endif /* LINUX_MOD_DEVICETABLE_H */
> diff --git a/include/linux/serdev.h b/include/linux/serdev.h
> index ecde0ad3e248..aca92e0ee6e7 100644
> --- a/include/linux/serdev.h
> +++ b/include/linux/serdev.h
> @@ -39,6 +39,7 @@ struct serdev_device_ops {
> * @ops: Device operations.
> * @write_comp Completion used by serdev_device_write() internally
> * @write_lock Lock to serialize access when writing data
> + * @id: serdev device ID entry
> */
> struct serdev_device {
> struct device dev;
> @@ -47,6 +48,7 @@ struct serdev_device {
> const struct serdev_device_ops *ops;
> struct completion write_comp;
> struct mutex write_lock;
> + const struct serdev_device_id *id;
> };
>
> #define to_serdev_device(d) container_of_const(d, struct serdev_device, dev)
> @@ -55,11 +57,13 @@ struct serdev_device {
> * struct serdev_device_driver - serdev slave device driver
> * @driver: serdev device drivers should initialize name field of this
> * structure.
> + * @id_table: serdev device ID table
> * @probe: binds this driver to a serdev device.
> * @remove: unbinds this driver from the 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 *);
> };
> diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
> index d3d00e85edf7..c1bfa8eddc4d 100644
> --- a/scripts/mod/devicetable-offsets.c
> +++ b/scripts/mod/devicetable-offsets.c
> @@ -280,5 +280,8 @@ int main(void)
> DEVID(coreboot_device_id);
> DEVID_FIELD(coreboot_device_id, tag);
>
> + DEVID(serdev_device_id);
> + DEVID_FIELD(serdev_device_id, name);
> +
> return 0;
> }
>
> --
> 2.48.1
>
>
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 03/10] serdev: Allow passing the serdev device name to serdev_device_add()
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
2025-11-25 14:45 ` [PATCH v2 01/10] serdev: Convert to_serdev_*() helpers to macros and use container_of_const() Manivannan Sadhasivam via B4 Relay
2025-11-25 14:45 ` [PATCH v2 02/10] serdev: Add serdev device based driver match support Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 9:14 ` Bartosz Golaszewski
2025-11-25 14:45 ` [PATCH v2 04/10] serdev: Add an API to find the serdev controller associated with the devicetree node Manivannan Sadhasivam via B4 Relay
` (7 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Instead of always setting the serdev device name from 'struct device' name,
allow the callers to pass an optional name and set it as the serdev device
name.
This will be used by the future callers passing the serdev device ID as the
name.
Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/platform/x86/dell/dell-uart-backlight.c | 2 +-
.../platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c | 2 +-
drivers/platform/x86/x86-android-tablets/core.c | 2 +-
drivers/tty/serdev/core.c | 13 +++++++++----
include/linux/serdev.h | 2 +-
5 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
index f323a667dc2d..f076cfac2bc5 100644
--- a/drivers/platform/x86/dell/dell-uart-backlight.c
+++ b/drivers/platform/x86/dell/dell-uart-backlight.c
@@ -354,7 +354,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, NULL);
if (ret) {
dev_err(&pdev->dev, "error %d adding serdev\n", ret);
serdev_device_put(serdev);
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..5e568fe1162d 100644
--- a/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
+++ b/drivers/platform/x86/lenovo/yoga-tab2-pro-1380-fastcharger.c
@@ -260,7 +260,7 @@ 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, NULL);
if (ret) {
serdev_device_put(serdev);
return dev_err_probe(&pdev->dev, ret, "adding serdev\n");
diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
index 6588fae30356..96140f5d4f79 100644
--- a/drivers/platform/x86/x86-android-tablets/core.c
+++ b/drivers/platform/x86/x86-android-tablets/core.c
@@ -316,7 +316,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/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 2b5582cd5063..76b89dd0720f 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -121,14 +121,19 @@ static int serdev_device_match(struct device *dev, const struct device_driver *d
/**
* serdev_device_add() - add a device previously constructed via serdev_device_alloc()
* @serdev: serdev_device to be added
+ * @name: name of the serdev device (optional)
*/
-int serdev_device_add(struct serdev_device *serdev)
+int serdev_device_add(struct serdev_device *serdev, const char *name)
+
{
struct serdev_controller *ctrl = serdev->ctrl;
struct device *parent = serdev->dev.parent;
int err;
- dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr);
+ if (name)
+ dev_set_name(&serdev->dev, "%s", name);
+ else
+ dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr);
/* Only a single slave device is currently supported. */
if (ctrl->serdev) {
@@ -544,7 +549,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",
@@ -692,7 +697,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/serdev.h b/include/linux/serdev.h
index aca92e0ee6e7..ffc6eb13f44b 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -160,7 +160,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 *name);
void serdev_device_remove(struct serdev_device *);
struct serdev_controller *serdev_controller_alloc(struct device *host,
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 03/10] serdev: Allow passing the serdev device name to serdev_device_add()
2025-11-25 14:45 ` [PATCH v2 03/10] serdev: Allow passing the serdev device name to serdev_device_add() Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 9:14 ` Bartosz Golaszewski
0 siblings, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 9:14 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov
On Tue, Nov 25, 2025 at 3:45 PM Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> wrote:
>
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Instead of always setting the serdev device name from 'struct device' name,
> allow the callers to pass an optional name and set it as the serdev device
> name.
>
> This will be used by the future callers passing the serdev device ID as the
> name.
>
> Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
Instead of modifying the existing callers with an unneeded argument,
I'd suggest adding a new call - serdev_device_add_full() or something
like that - that takes more arguments and make the existing function
wrap it.
Bart
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 04/10] serdev: Add an API to find the serdev controller associated with the devicetree node
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (2 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 03/10] serdev: Allow passing the serdev device name to serdev_device_add() Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 13:52 ` Bartosz Golaszewski
2025-11-25 14:45 ` [PATCH v2 05/10] serdev: Add modalias support for serdev client devices Manivannan Sadhasivam via B4 Relay
` (6 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Add of_find_serdev_controller_by_node() API to find the serdev controller
device associated with the devicetree node.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/tty/serdev/core.c | 16 ++++++++++++++++
include/linux/serdev.h | 9 +++++++++
2 files changed, 25 insertions(+)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 76b89dd0720f..f90095cb778f 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -530,6 +530,22 @@ struct serdev_controller *serdev_controller_alloc(struct device *host,
}
EXPORT_SYMBOL_GPL(serdev_controller_alloc);
+/**
+ * of_find_serdev_controller_by_node() - Find the serdev controller associated
+ * with the devicetree node
+ * @node: Devicetree node
+ *
+ * Return: Pointer to the serdev controller associated with the node. NULL if
+ * the controller is not found.
+ */
+struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
+{
+ struct device *dev = bus_find_device_by_of_node(&serdev_bus_type, node);
+
+ return (dev && dev->type == &serdev_ctrl_type) ? to_serdev_controller(dev) : NULL;
+}
+EXPORT_SYMBOL_GPL(of_find_serdev_controller_by_node);
+
static int of_serdev_register_devices(struct serdev_controller *ctrl)
{
struct device_node *node;
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index ffc6eb13f44b..fa235c92592a 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -337,4 +337,13 @@ static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
}
#endif /* CONFIG_ACPI */
+#ifdef CONFIG_OF
+struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node);
+#else
+struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF */
+
#endif /*_LINUX_SERDEV_H */
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 04/10] serdev: Add an API to find the serdev controller associated with the devicetree node
2025-11-25 14:45 ` [PATCH v2 04/10] serdev: Add an API to find the serdev controller associated with the devicetree node Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 13:52 ` Bartosz Golaszewski
0 siblings, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 13:52 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Manivannan Sadhasivam via B4 Relay, linux-serial, linux-kernel,
linux-kbuild, platform-driver-x86, linux-pci, devicetree,
linux-arm-msm, linux-bluetooth, linux-pm, Stephan Gerhold,
Dmitry Baryshkov, Rob Herring, Greg Kroah-Hartman, Jiri Slaby,
Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
On Tue, 25 Nov 2025 15:45:08 +0100, Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Add of_find_serdev_controller_by_node() API to find the serdev controller
> device associated with the devicetree node.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/tty/serdev/core.c | 16 ++++++++++++++++
> include/linux/serdev.h | 9 +++++++++
> 2 files changed, 25 insertions(+)
>
> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index 76b89dd0720f..f90095cb778f 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
> @@ -530,6 +530,22 @@ struct serdev_controller *serdev_controller_alloc(struct device *host,
> }
> EXPORT_SYMBOL_GPL(serdev_controller_alloc);
>
> +/**
> + * of_find_serdev_controller_by_node() - Find the serdev controller associated
> + * with the devicetree node
> + * @node: Devicetree node
> + *
> + * Return: Pointer to the serdev controller associated with the node. NULL if
> + * the controller is not found.
> + */
> +struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
> +{
> + struct device *dev = bus_find_device_by_of_node(&serdev_bus_type, node);
> +
> + return (dev && dev->type == &serdev_ctrl_type) ? to_serdev_controller(dev) : NULL;
> +}
> +EXPORT_SYMBOL_GPL(of_find_serdev_controller_by_node);
> +
> static int of_serdev_register_devices(struct serdev_controller *ctrl)
> {
> struct device_node *node;
> diff --git a/include/linux/serdev.h b/include/linux/serdev.h
> index ffc6eb13f44b..fa235c92592a 100644
> --- a/include/linux/serdev.h
> +++ b/include/linux/serdev.h
> @@ -337,4 +337,13 @@ static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares,
> }
> #endif /* CONFIG_ACPI */
>
> +#ifdef CONFIG_OF
You can make it independent from OF if you base the code on fwnode like:
struct serdev_controller find_serdev_controller_by_fwnode(struct
fwnode_handle *fwnode);
{
struct device *dev = bus_find_device_by_fwnode(&serdev_bus_type, node);
(...)
}
Users can always convert OF nodes to firmware nodes.
Bart
> +struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node);
> +#else
> +struct serdev_controller *of_find_serdev_controller_by_node(struct device_node *node)
> +{
> + return NULL;
> +}
> +#endif /* CONFIG_OF */
> +
> #endif /*_LINUX_SERDEV_H */
>
> --
> 2.48.1
>
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 05/10] serdev: Add modalias support for serdev client devices
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (3 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 04/10] serdev: Add an API to find the serdev controller associated with the devicetree node Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-25 14:45 ` [PATCH v2 06/10] dt-bindings: serial: Document the graph port Manivannan Sadhasivam via B4 Relay
` (5 subsequent siblings)
10 siblings, 0 replies; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Add modlias support to serdev so that the serdev client driver can be
autoloaded by udev when the serdev client device gets created.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/tty/serdev/core.c | 15 +++++++++++----
include/linux/mod_devicetable.h | 1 +
scripts/mod/file2alias.c | 8 ++++++++
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index f90095cb778f..8c2a40a537d9 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -34,7 +34,11 @@ static ssize_t modalias_show(struct device *dev,
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;
+
+ return sysfs_emit(buf, SERDEV_DEVICE_MODALIAS_FMT "\n", dev_name(dev));
}
static DEVICE_ATTR_RO(modalias);
@@ -48,13 +52,16 @@ static int serdev_device_uevent(const struct device *dev, struct kobj_uevent_env
{
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;
+
+ return add_uevent_var(env, "MODALIAS=" SERDEV_DEVICE_MODALIAS_FMT,
+ dev_name(dev));
}
static void serdev_device_release(struct device *dev)
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 70c54c4bedba..dad9637cf285 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -976,6 +976,7 @@ struct coreboot_device_id {
kernel_ulong_t driver_data;
};
+#define SERDEV_DEVICE_MODALIAS_FMT "serdev:%s"
#define SERDEV_NAME_SIZE 32
struct serdev_device_id {
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index b3333560b95e..27e9f7c718c4 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1371,6 +1371,13 @@ static void do_coreboot_entry(struct module *mod, void *symval)
module_alias_printf(mod, false, "coreboot:t%08X", tag);
}
+/* Looks like: serdev:S */
+static void do_serdev_entry(struct module *mod, void *symval)
+{
+ DEF_FIELD_ADDR(symval, serdev_device_id, name);
+ module_alias_printf(mod, false, SERDEV_DEVICE_MODALIAS_FMT, *name);
+}
+
/* Does namelen bytes of name exactly match the symbol? */
static bool sym_is(const char *name, unsigned namelen, const char *symbol)
{
@@ -1467,6 +1474,7 @@ static const struct devtable devtable[] = {
{"usb", SIZE_usb_device_id, do_usb_entry_multi},
{"pnp", SIZE_pnp_device_id, do_pnp_device_entry},
{"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry},
+ {"serdev", SIZE_serdev_device_id, do_serdev_entry},
};
/* Create MODULE_ALIAS() statements.
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 06/10] dt-bindings: serial: Document the graph port
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (4 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 05/10] serdev: Add modalias support for serdev client devices Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-25 14:45 ` [PATCH v2 07/10] serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used Manivannan Sadhasivam via B4 Relay
` (4 subsequent siblings)
10 siblings, 0 replies; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
A serial controller could be connected to an external connector like PCIe
M.2 for controlling the serial interface of the card. Hence, document the
OF graph port.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
Documentation/devicetree/bindings/serial/serial.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/serial.yaml b/Documentation/devicetree/bindings/serial/serial.yaml
index 6aa9cfae417b..96eb1de8771e 100644
--- a/Documentation/devicetree/bindings/serial/serial.yaml
+++ b/Documentation/devicetree/bindings/serial/serial.yaml
@@ -87,6 +87,9 @@ properties:
description:
TX FIFO threshold configuration (in bytes).
+ port:
+ $ref: /schemas/graph.yaml#/properties/port
+
patternProperties:
"^(bluetooth|bluetooth-gnss|embedded-controller|gnss|gps|mcu|onewire)$":
if:
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH v2 07/10] serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (5 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 06/10] dt-bindings: serial: Document the graph port Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 13:48 ` Bartosz Golaszewski
2025-11-25 14:45 ` [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector Manivannan Sadhasivam via B4 Relay
` (3 subsequent siblings)
10 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
If an external connector like M.2 is connected to the serdev controller
in DT, then the serdev devices may be created dynamically by the connector
driver. So do not return -ENODEV from of_serdev_register_devices() if the
static nodes are not found and the graph node is used.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/tty/serdev/core.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 8c2a40a537d9..fba7b98026bb 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/of_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
@@ -581,7 +582,13 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
} else
found = true;
}
- if (!found)
+
+ /*
+ * When the serdev controller is connected to an external connector like
+ * M.2 in DT, then the serdev devices may be created dynamically by the
+ * connector driver.
+ */
+ if (!found && !of_graph_is_present(ctrl->dev.of_node))
return -ENODEV;
return 0;
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 07/10] serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used
2025-11-25 14:45 ` [PATCH v2 07/10] serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 13:48 ` Bartosz Golaszewski
0 siblings, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 13:48 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Manivannan Sadhasivam via B4 Relay, linux-serial, linux-kernel,
linux-kbuild, platform-driver-x86, linux-pci, devicetree,
linux-arm-msm, linux-bluetooth, linux-pm, Stephan Gerhold,
Dmitry Baryshkov, Rob Herring, Greg Kroah-Hartman, Jiri Slaby,
Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
On Tue, 25 Nov 2025 15:45:11 +0100, Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> If an external connector like M.2 is connected to the serdev controller
> in DT, then the serdev devices may be created dynamically by the connector
> driver. So do not return -ENODEV from of_serdev_register_devices() if the
> static nodes are not found and the graph node is used.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/tty/serdev/core.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index 8c2a40a537d9..fba7b98026bb 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
> @@ -12,6 +12,7 @@
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/of.h>
> +#include <linux/of_graph.h>
> #include <linux/of_device.h>
> #include <linux/pm_domain.h>
> #include <linux/pm_runtime.h>
> @@ -581,7 +582,13 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
> } else
> found = true;
> }
> - if (!found)
> +
> + /*
> + * When the serdev controller is connected to an external connector like
> + * M.2 in DT, then the serdev devices may be created dynamically by the
> + * connector driver.
> + */
> + if (!found && !of_graph_is_present(ctrl->dev.of_node))
> return -ENODEV;
>
> return 0;
>
> --
> 2.48.1
>
>
>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (6 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 07/10] serdev: Do not return -ENODEV from of_serdev_register_devices() if external connector is used Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-25 17:43 ` Frank Li
` (2 more replies)
2025-11-25 14:45 ` [PATCH v2 09/10] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card Manivannan Sadhasivam via B4 Relay
` (2 subsequent siblings)
10 siblings, 3 replies; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Add the devicetree binding for PCIe M.2 Mechanical Key E connector defined
in the PCI Express M.2 Specification, r4.0, sec 5.1.2. This connector
provides interfaces like PCIe or SDIO to attach the WiFi devices to the
host machine, USB or UART+PCM interfaces to attach the Bluetooth (BT)
devices along with additional interfaces like I2C for NFC solution. At any
point of time, the connector can only support either PCIe or SDIO as the
WiFi interface and USB or UART as the BT interface.
The connector provides a primary power supply of 3.3v, along with an
optional 1.8v VIO supply for the Adapter I/O buffer circuitry operating at
1.8v sideband signaling.
The connector also supplies optional signals in the form of GPIOs for fine
grained power management.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
.../bindings/connector/pcie-m2-e-connector.yaml | 178 +++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 179 insertions(+)
diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
new file mode 100644
index 000000000000..fe2c9a943a21
--- /dev/null
+++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/connector/pcie-m2-e-connector.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PCIe M.2 Mechanical Key E Connector
+
+maintainers:
+ - Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+description:
+ A PCIe M.2 E connector node represents a physical PCIe M.2 Mechanical Key E
+ connector. Mechanical Key E connectors are used to connect Wireless
+ Connectivity devices including combinations of Wi-Fi, BT, NFC to the host
+ machine over interfaces like PCIe/SDIO, USB/UART+PCM, and I2C.
+
+properties:
+ compatible:
+ const: pcie-m2-e-connector
+
+ vpcie3v3-supply:
+ description: A phandle to the regulator for 3.3v supply.
+
+ vpcie1v8-supply:
+ description: A phandle to the regulator for VIO 1.8v supply.
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ description: OF graph bindings modeling the interfaces exposed on the
+ connector. Since a single connector can have multiple interfaces, every
+ interface has an assigned OF graph port number as described below.
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Connector interfaces for Wi-Fi
+
+ properties:
+ endpoint@0:
+ $ref: /schemas/graph.yaml#/properties/endpoint
+ description: PCIe interface
+
+ endpoint@1:
+ $ref: /schemas/graph.yaml#/properties/endpoint
+ description: SDIO interface
+
+ anyOf:
+ - required:
+ - endpoint@0
+ - required:
+ - endpoint@1
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Connector interfaces for BT
+
+ properties:
+ endpoint@0:
+ $ref: /schemas/graph.yaml#/properties/endpoint
+ description: USB 2.0 interface
+
+ endpoint@1:
+ $ref: /schemas/graph.yaml#/properties/endpoint
+ description: UART interface
+
+ anyOf:
+ - required:
+ - endpoint@0
+ - required:
+ - endpoint@1
+
+ port@2:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: PCM/I2S interface
+
+ port@3:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: I2C interface
+
+ oneOf:
+ - required:
+ - port@0
+
+ clocks:
+ description: 32.768 KHz Suspend Clock (SUSCLK) input from the host system to
+ the M.2 card. Refer, PCI Express M.2 Specification r4.0, sec 3.1.12.1 for
+ more details.
+ maxItems: 1
+
+ w-disable1-gpios:
+ description: GPIO controlled connection to W_DISABLE1# signal. This signal
+ is used by the system to disable WiFi radio in the M.2 card. Refer, PCI
+ Express M.2 Specification r4.0, sec 3.1.12.3 for more details.
+ maxItems: 1
+
+ w-disable2-gpios:
+ description: GPIO controlled connection to W_DISABLE2# signal. This signal
+ is used by the system to disable BT radio in the M.2 card. Refer, PCI
+ Express M.2 Specification r4.0, sec 3.1.12.3 for more details.
+ maxItems: 1
+
+ viocfg-gpios:
+ description: GPIO controlled connection to IO voltage configuration
+ (VIO_CFG) signal. This signal is used by the M.2 card to indicate to the
+ host system that the card supports an independent IO voltage domain for
+ the sideband signals. Refer, PCI Express M.2 Specification r4.0, sec
+ 3.1.15.1 for more details.
+ maxItems: 1
+
+ uim-power-src-gpios:
+ description: GPIO controlled connection to UIM_POWER_SRC signal. This signal
+ is used when the NFC solution is implemented and receives the power output
+ from WWAN_UIM_PWR signal of the another WWAN M.2 card. Refer, PCI Express
+ M.2 Specification r4.0, sec 3.1.11.1 for more details.
+ maxItems: 1
+
+ uim-power-snk-gpios:
+ description: GPIO controlled connection to UIM_POWER_SNK signal. This signal
+ is used when the NFC solution is implemented and supplies power to the
+ Universal Integrated Circuit Card (UICC). Refer, PCI Express M.2
+ Specification r4.0, sec 3.1.11.2 for more details.
+ maxItems: 1
+
+ uim-swp-gpios:
+ description: GPIO controlled connection to UIM_SWP signal. This signal is
+ used when the NFC solution is implemented and implements the Single Wire
+ Protocol (SWP) interface to the UICC. Refer, PCI Express M.2 Specification
+ r4.0, sec 3.1.11.3 for more details.
+ maxItems: 1
+
+required:
+ - compatible
+ - vpcie3v3-supply
+
+additionalProperties: false
+
+examples:
+ # PCI M.2 Key E connector for Wi-Fi/BT with PCIe/UART interfaces
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ connector {
+ compatible = "pcie-m2-e-connector";
+ vpcie3v3-supply = <&vreg_wcn_3p3>;
+ vpcie1v8-supply = <&vreg_l15b_1p8>;
+ w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0>;
+
+ endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&pcie4_port0_ep>;
+ };
+ };
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <1>;
+
+ endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&uart14_ep>;
+ };
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 9b3f689d1f50..f707f29d0a37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20478,6 +20478,7 @@ PCIE M.2 POWER SEQUENCING
M: Manivannan Sadhasivam <mani@kernel.org>
L: linux-pci@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
F: Documentation/devicetree/bindings/connector/pcie-m2-m-connector.yaml
F: drivers/power/sequencing/pwrseq-pcie-m2.c
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector
2025-11-25 14:45 ` [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 17:43 ` Frank Li
2025-11-26 2:38 ` Sherry Sun
2025-12-08 20:28 ` Rob Herring
2 siblings, 0 replies; 23+ messages in thread
From: Frank Li @ 2025-11-25 17:43 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski, linux-serial, linux-kernel, linux-kbuild,
platform-driver-x86, linux-pci, devicetree, linux-arm-msm,
linux-bluetooth, linux-pm, Stephan Gerhold, Dmitry Baryshkov
On Tue, Nov 25, 2025 at 08:15:12PM +0530, Manivannan Sadhasivam wrote:
> Add the devicetree binding for PCIe M.2 Mechanical Key E connector defined
> in the PCI Express M.2 Specification, r4.0, sec 5.1.2. This connector
> provides interfaces like PCIe or SDIO to attach the WiFi devices to the
> host machine, USB or UART+PCM interfaces to attach the Bluetooth (BT)
> devices along with additional interfaces like I2C for NFC solution. At any
> point of time, the connector can only support either PCIe or SDIO as the
> WiFi interface and USB or UART as the BT interface.
>
> The connector provides a primary power supply of 3.3v, along with an
> optional 1.8v VIO supply for the Adapter I/O buffer circuitry operating at
> 1.8v sideband signaling.
>
> The connector also supplies optional signals in the form of GPIOs for fine
> grained power management.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> .../bindings/connector/pcie-m2-e-connector.yaml | 178 +++++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 179 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
> new file mode 100644
> index 000000000000..fe2c9a943a21
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
> @@ -0,0 +1,178 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/connector/pcie-m2-e-connector.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PCIe M.2 Mechanical Key E Connector
> +
...
> +
> +required:
> + - compatible
> + - vpcie3v3-supply
I think need ports
> +
> +additionalProperties: false
> +
> +examples:
> + # PCI M.2 Key E connector for Wi-Fi/BT with PCIe/UART interfaces
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> +
> + connector {
> + compatible = "pcie-m2-e-connector";
> + vpcie3v3-supply = <&vreg_wcn_3p3>;
> + vpcie1v8-supply = <&vreg_l15b_1p8>;
> + w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>;
> + w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + reg = <0>;
reg should be before #address-cells = <1>; and no empty line between
these.
Frank
> +
> + endpoint@0 {
> + reg = <0>;
> + remote-endpoint = <&pcie4_port0_ep>;
> + };
> + };
> +
> + port@1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + reg = <1>;
> +
> + endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&uart14_ep>;
> + };
> + };
> + };
> + };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9b3f689d1f50..f707f29d0a37 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20478,6 +20478,7 @@ PCIE M.2 POWER SEQUENCING
> M: Manivannan Sadhasivam <mani@kernel.org>
> L: linux-pci@vger.kernel.org
> S: Maintained
> +F: Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
> F: Documentation/devicetree/bindings/connector/pcie-m2-m-connector.yaml
> F: drivers/power/sequencing/pwrseq-pcie-m2.c
>
>
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 23+ messages in thread* RE: [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector
2025-11-25 14:45 ` [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector Manivannan Sadhasivam via B4 Relay
2025-11-25 17:43 ` Frank Li
@ 2025-11-26 2:38 ` Sherry Sun
2025-12-08 20:28 ` Rob Herring
2 siblings, 0 replies; 23+ messages in thread
From: Sherry Sun @ 2025-11-26 2:38 UTC (permalink / raw)
To: manivannan.sadhasivam@oss.qualcomm.com, Rob Herring,
Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor, Nicolas Schier,
Hans de Goede, Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
Cc: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kbuild@vger.kernel.org, platform-driver-x86@vger.kernel.org,
linux-pci@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-bluetooth@vger.kernel.org,
linux-pm@vger.kernel.org, Stephan Gerhold, Dmitry Baryshkov
> -----Original Message-----
> From: Manivannan Sadhasivam via B4 Relay
> <devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org>
> Sent: Tuesday, November 25, 2025 10:45 PM
> To: Rob Herring <robh@kernel.org>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Jiri Slaby <jirislaby@kernel.org>; Nathan
> Chancellor <nathan@kernel.org>; Nicolas Schier <nicolas.schier@linux.dev>;
> Hans de Goede <hansg@kernel.org>; Ilpo Järvinen
> <ilpo.jarvinen@linux.intel.com>; Mark Pearson <mpearson-
> lenovo@squebb.ca>; Derek J. Clark <derekjohn.clark@gmail.com>;
> Manivannan Sadhasivam <mani@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Marcel
> Holtmann <marcel@holtmann.org>; Luiz Augusto von Dentz
> <luiz.dentz@gmail.com>; Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: linux-serial@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> kbuild@vger.kernel.org; platform-driver-x86@vger.kernel.org; linux-
> pci@vger.kernel.org; devicetree@vger.kernel.org; linux-arm-
> msm@vger.kernel.org; linux-bluetooth@vger.kernel.org; linux-
> pm@vger.kernel.org; Stephan Gerhold <stephan.gerhold@linaro.org>; Dmitry
> Baryshkov <dmitry.baryshkov@oss.qualcomm.com>; Manivannan
> Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> Subject: [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical
> Key E connector
>
> From: Manivannan Sadhasivam
> <manivannan.sadhasivam@oss.qualcomm.com>
>
> Add the devicetree binding for PCIe M.2 Mechanical Key E connector defined
> in the PCI Express M.2 Specification, r4.0, sec 5.1.2. This connector provides
> interfaces like PCIe or SDIO to attach the WiFi devices to the host machine,
> USB or UART+PCM interfaces to attach the Bluetooth (BT) devices along with
> additional interfaces like I2C for NFC solution. At any point of time, the
> connector can only support either PCIe or SDIO as the WiFi interface and USB
> or UART as the BT interface.
>
> The connector provides a primary power supply of 3.3v, along with an
> optional 1.8v VIO supply for the Adapter I/O buffer circuitry operating at 1.8v
> sideband signaling.
>
> The connector also supplies optional signals in the form of GPIOs for fine
> grained power management.
>
> Signed-off-by: Manivannan Sadhasivam
> <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> .../bindings/connector/pcie-m2-e-connector.yaml | 178
> +++++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 179 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-
> connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-
> connector.yaml
> new file mode 100644
> index 000000000000..fe2c9a943a21
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-
> connector.ya
> +++ ml
> @@ -0,0 +1,178 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> +---
> +$id:
> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevice
> +tree.org%2Fschemas%2Fconnector%2Fpcie-m2-e-
> connector.yaml%23&data=05%7C
> +02%7Csherry.sun%40nxp.com%7C22ea3ba76ac749b69bee08de2c314c73%7
> C686ea1d3
> +bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638996787414741474%7CUnkno
> wn%7CTWFpb
> +GZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> MiIsIkFO
> +IjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Y8y5ctS7QJzaMZ
> wdY%2FAnr
> +FqydRTUumh3hRBDMtK%2B8Y4%3D&reserved=0
> +$schema:
> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevice
> +tree.org%2Fmeta-
> schemas%2Fcore.yaml%23&data=05%7C02%7Csherry.sun%40nxp.
> +com%7C22ea3ba76ac749b69bee08de2c314c73%7C686ea1d3bc2b4c6fa92cd
> 99c5c3016
> +35%7C0%7C0%7C638996787414756341%7CUnknown%7CTWFpbGZsb3d8ey
> JFbXB0eU1hcGk
> +iOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIj
> oyfQ
> +%3D%3D%7C0%7C%7C%7C&sdata=z9JeuCv1%2BkOH%2FjQcV2hpwgfuMJykj
> 1SFgn4EzkHSK
> +0Q%3D&reserved=0
> +
> +title: PCIe M.2 Mechanical Key E Connector
> +
> +maintainers:
> + - Manivannan Sadhasivam
> <manivannan.sadhasivam@oss.qualcomm.com>
> +
> +description:
> + A PCIe M.2 E connector node represents a physical PCIe M.2 Mechanical
> +Key E
> + connector. Mechanical Key E connectors are used to connect Wireless
> + Connectivity devices including combinations of Wi-Fi, BT, NFC to the
> +host
> + machine over interfaces like PCIe/SDIO, USB/UART+PCM, and I2C.
> +
> +properties:
> + compatible:
> + const: pcie-m2-e-connector
> +
> + vpcie3v3-supply:
> + description: A phandle to the regulator for 3.3v supply.
> +
> + vpcie1v8-supply:
> + description: A phandle to the regulator for VIO 1.8v supply.
> +
> + ports:
> + $ref: /schemas/graph.yaml#/properties/ports
> + description: OF graph bindings modeling the interfaces exposed on the
> + connector. Since a single connector can have multiple interfaces, every
> + interface has an assigned OF graph port number as described below.
> +
> + properties:
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: Connector interfaces for Wi-Fi
> +
> + properties:
> + endpoint@0:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: PCIe interface
> +
> + endpoint@1:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: SDIO interface
> +
> + anyOf:
> + - required:
> + - endpoint@0
> + - required:
> + - endpoint@1
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: Connector interfaces for BT
> +
> + properties:
> + endpoint@0:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: USB 2.0 interface
> +
> + endpoint@1:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: UART interface
> +
> + anyOf:
> + - required:
> + - endpoint@0
> + - required:
> + - endpoint@1
> +
> + port@2:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: PCM/I2S interface
> +
> + port@3:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: I2C interface
> +
> + oneOf:
> + - required:
> + - port@0
> +
> + clocks:
> + description: 32.768 KHz Suspend Clock (SUSCLK) input from the host
> system to
> + the M.2 card. Refer, PCI Express M.2 Specification r4.0, sec 3.1.12.1 for
> + more details.
> + maxItems: 1
> +
> + w-disable1-gpios:
> + description: GPIO controlled connection to W_DISABLE1# signal. This
> signal
> + is used by the system to disable WiFi radio in the M.2 card. Refer, PCI
> + Express M.2 Specification r4.0, sec 3.1.12.3 for more details.
> + maxItems: 1
> +
> + w-disable2-gpios:
> + description: GPIO controlled connection to W_DISABLE2# signal. This
> signal
> + is used by the system to disable BT radio in the M.2 card. Refer, PCI
> + Express M.2 Specification r4.0, sec 3.1.12.3 for more details.
> + maxItems: 1
> +
> + viocfg-gpios:
> + description: GPIO controlled connection to IO voltage configuration
> + (VIO_CFG) signal. This signal is used by the M.2 card to indicate to the
> + host system that the card supports an independent IO voltage domain for
> + the sideband signals. Refer, PCI Express M.2 Specification r4.0, sec
> + 3.1.15.1 for more details.
> + maxItems: 1
> +
> + uim-power-src-gpios:
> + description: GPIO controlled connection to UIM_POWER_SRC signal. This
> signal
> + is used when the NFC solution is implemented and receives the power
> output
> + from WWAN_UIM_PWR signal of the another WWAN M.2 card. Refer,
> PCI Express
> + M.2 Specification r4.0, sec 3.1.11.1 for more details.
> + maxItems: 1
> +
> + uim-power-snk-gpios:
> + description: GPIO controlled connection to UIM_POWER_SNK signal. This
> signal
> + is used when the NFC solution is implemented and supplies power to the
> + Universal Integrated Circuit Card (UICC). Refer, PCI Express M.2
> + Specification r4.0, sec 3.1.11.2 for more details.
> + maxItems: 1
> +
> + uim-swp-gpios:
> + description: GPIO controlled connection to UIM_SWP signal. This signal is
> + used when the NFC solution is implemented and implements the Single
> Wire
> + Protocol (SWP) interface to the UICC. Refer, PCI Express M.2 Specification
> + r4.0, sec 3.1.11.3 for more details.
> + maxItems: 1
> +
> +required:
> + - compatible
> + - vpcie3v3-supply
Hi Mani,
I am wondering if vpcie3v3-supply property is necessary here, consider the following real board designs on our i.MX platforms.
1. M.2 power always on, it connected to board VDD_3V3, no control gpio. Should we not configure the vpcie3v3-supply or add the fake regulator like the one below?
reg_m2_pwr: regulator-m2-pwr {
compatible = "regulator-fixed";
regulator-max-microvolt = <3300000>;
regulator-min-microvolt = <3300000>;
regulator-name = " M.2-power";
};
2. M.2 power regulator reuses w_disable1# gpio for control. Should we use the vpcie3v3-supply or w-disable1-gpios to control this?
Best Regards
Sherry
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector
2025-11-25 14:45 ` [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector Manivannan Sadhasivam via B4 Relay
2025-11-25 17:43 ` Frank Li
2025-11-26 2:38 ` Sherry Sun
@ 2025-12-08 20:28 ` Rob Herring
2 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2025-12-08 20:28 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor, Nicolas Schier,
Hans de Goede, Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski,
linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov
On Tue, Nov 25, 2025 at 08:15:12PM +0530, Manivannan Sadhasivam wrote:
> Add the devicetree binding for PCIe M.2 Mechanical Key E connector defined
> in the PCI Express M.2 Specification, r4.0, sec 5.1.2. This connector
> provides interfaces like PCIe or SDIO to attach the WiFi devices to the
> host machine, USB or UART+PCM interfaces to attach the Bluetooth (BT)
> devices along with additional interfaces like I2C for NFC solution. At any
> point of time, the connector can only support either PCIe or SDIO as the
> WiFi interface and USB or UART as the BT interface.
AFAICT, there's no muxing of interfaces. Maybe that's a defacto
limitation on x86 systems? There's no reason to encode that into the
binding if the pins aren't mux'ed on the connector.
>
> The connector provides a primary power supply of 3.3v, along with an
> optional 1.8v VIO supply for the Adapter I/O buffer circuitry operating at
> 1.8v sideband signaling.
>
> The connector also supplies optional signals in the form of GPIOs for fine
> grained power management.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> .../bindings/connector/pcie-m2-e-connector.yaml | 178 +++++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 179 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
> new file mode 100644
> index 000000000000..fe2c9a943a21
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
> @@ -0,0 +1,178 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/connector/pcie-m2-e-connector.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PCIe M.2 Mechanical Key E Connector
> +
> +maintainers:
> + - Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> +
> +description:
> + A PCIe M.2 E connector node represents a physical PCIe M.2 Mechanical Key E
> + connector. Mechanical Key E connectors are used to connect Wireless
> + Connectivity devices including combinations of Wi-Fi, BT, NFC to the host
> + machine over interfaces like PCIe/SDIO, USB/UART+PCM, and I2C.
> +
> +properties:
> + compatible:
> + const: pcie-m2-e-connector
> +
> + vpcie3v3-supply:
> + description: A phandle to the regulator for 3.3v supply.
> +
> + vpcie1v8-supply:
> + description: A phandle to the regulator for VIO 1.8v supply.
> +
> + ports:
> + $ref: /schemas/graph.yaml#/properties/ports
> + description: OF graph bindings modeling the interfaces exposed on the
> + connector. Since a single connector can have multiple interfaces, every
> + interface has an assigned OF graph port number as described below.
> +
> + properties:
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: Connector interfaces for Wi-Fi
> +
> + properties:
> + endpoint@0:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: PCIe interface
> +
> + endpoint@1:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: SDIO interface
> +
> + anyOf:
> + - required:
> + - endpoint@0
> + - required:
> + - endpoint@1
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: Connector interfaces for BT
> +
> + properties:
> + endpoint@0:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: USB 2.0 interface
> +
> + endpoint@1:
> + $ref: /schemas/graph.yaml#/properties/endpoint
> + description: UART interface
> +
> + anyOf:
> + - required:
> + - endpoint@0
> + - required:
> + - endpoint@1
> +
> + port@2:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: PCM/I2S interface
Does this work with any existing DAI bindings? Or conflict with the
audio graph card binding?
> +
> + port@3:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: I2C interface
Like the other one, use i2c-parent.
> +
> + oneOf:
> + - required:
> + - port@0
> +
> + clocks:
> + description: 32.768 KHz Suspend Clock (SUSCLK) input from the host system to
> + the M.2 card. Refer, PCI Express M.2 Specification r4.0, sec 3.1.12.1 for
> + more details.
> + maxItems: 1
> +
> + w-disable1-gpios:
> + description: GPIO controlled connection to W_DISABLE1# signal. This signal
> + is used by the system to disable WiFi radio in the M.2 card. Refer, PCI
> + Express M.2 Specification r4.0, sec 3.1.12.3 for more details.
> + maxItems: 1
> +
> + w-disable2-gpios:
> + description: GPIO controlled connection to W_DISABLE2# signal. This signal
> + is used by the system to disable BT radio in the M.2 card. Refer, PCI
> + Express M.2 Specification r4.0, sec 3.1.12.3 for more details.
> + maxItems: 1
> +
> + viocfg-gpios:
> + description: GPIO controlled connection to IO voltage configuration
> + (VIO_CFG) signal. This signal is used by the M.2 card to indicate to the
> + host system that the card supports an independent IO voltage domain for
> + the sideband signals. Refer, PCI Express M.2 Specification r4.0, sec
> + 3.1.15.1 for more details.
> + maxItems: 1
> +
> + uim-power-src-gpios:
> + description: GPIO controlled connection to UIM_POWER_SRC signal. This signal
> + is used when the NFC solution is implemented and receives the power output
> + from WWAN_UIM_PWR signal of the another WWAN M.2 card. Refer, PCI Express
> + M.2 Specification r4.0, sec 3.1.11.1 for more details.
> + maxItems: 1
> +
> + uim-power-snk-gpios:
> + description: GPIO controlled connection to UIM_POWER_SNK signal. This signal
> + is used when the NFC solution is implemented and supplies power to the
> + Universal Integrated Circuit Card (UICC). Refer, PCI Express M.2
> + Specification r4.0, sec 3.1.11.2 for more details.
> + maxItems: 1
> +
> + uim-swp-gpios:
> + description: GPIO controlled connection to UIM_SWP signal. This signal is
> + used when the NFC solution is implemented and implements the Single Wire
> + Protocol (SWP) interface to the UICC. Refer, PCI Express M.2 Specification
> + r4.0, sec 3.1.11.3 for more details.
> + maxItems: 1
> +
> +required:
> + - compatible
> + - vpcie3v3-supply
> +
> +additionalProperties: false
> +
> +examples:
> + # PCI M.2 Key E connector for Wi-Fi/BT with PCIe/UART interfaces
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> +
> + connector {
> + compatible = "pcie-m2-e-connector";
> + vpcie3v3-supply = <&vreg_wcn_3p3>;
> + vpcie1v8-supply = <&vreg_l15b_1p8>;
> + w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>;
> + w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + reg = <0>;
> +
> + endpoint@0 {
> + reg = <0>;
> + remote-endpoint = <&pcie4_port0_ep>;
> + };
> + };
> +
> + port@1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + reg = <1>;
> +
> + endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&uart14_ep>;
> + };
> + };
> + };
> + };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9b3f689d1f50..f707f29d0a37 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20478,6 +20478,7 @@ PCIE M.2 POWER SEQUENCING
> M: Manivannan Sadhasivam <mani@kernel.org>
> L: linux-pci@vger.kernel.org
> S: Maintained
> +F: Documentation/devicetree/bindings/connector/pcie-m2-e-connector.yaml
> F: Documentation/devicetree/bindings/connector/pcie-m2-m-connector.yaml
> F: drivers/power/sequencing/pwrseq-pcie-m2.c
>
>
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 09/10] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (7 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 08/10] dt-bindings: connector: Add PCIe M.2 Mechanical Key E connector Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 13:49 ` Bartosz Golaszewski
2025-11-25 14:45 ` [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors Manivannan Sadhasivam via B4 Relay
2025-11-25 19:57 ` [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Stephan Gerhold
10 siblings, 1 reply; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
The WCN7850 PCIe M.2 card connected to the UART controller exposes the
'WCN7850' serdev device and is controlled using the pwrseq framework.
Hence, add support for it in the driver. It reuses the existing
'qca_soc_data_wcn7850' driver data.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/bluetooth/hci_qca.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4cff4d9be313..35d08b455e40 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -26,6 +26,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
@@ -2344,6 +2345,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
qcadev->serdev_hu.serdev = serdev;
data = device_get_match_data(&serdev->dev);
+ if (!data && serdev->id)
+ data = (const struct qca_device_data *) serdev->id->driver_data;
+
serdev_device_set_drvdata(serdev, qcadev);
device_property_read_string_array(&serdev->dev, "firmware-name",
qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name));
@@ -2384,6 +2388,14 @@ static int qca_serdev_probe(struct serdev_device *serdev)
case QCA_WCN6855:
case QCA_WCN7850:
case QCA_WCN6750:
+ if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+ qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev,
+ "uart");
+ if (IS_ERR(qcadev->bt_power->pwrseq))
+ return PTR_ERR(qcadev->bt_power->pwrseq);
+ break;
+ }
+
if (!device_property_present(&serdev->dev, "enable-gpios")) {
/*
* Backward compatibility with old DT sources. If the
@@ -2740,6 +2752,12 @@ static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match);
#endif
+static const struct serdev_device_id qca_bluetooth_serdev_match[] = {
+ { "WCN7850", (kernel_ulong_t)&qca_soc_data_wcn7850 },
+ { },
+};
+MODULE_DEVICE_TABLE(serdev, qca_bluetooth_serdev_match);
+
#ifdef CONFIG_DEV_COREDUMP
static void hciqca_coredump(struct device *dev)
{
@@ -2756,6 +2774,7 @@ static void hciqca_coredump(struct device *dev)
static struct serdev_device_driver qca_serdev_driver = {
.probe = qca_serdev_probe,
.remove = qca_serdev_remove,
+ .id_table = qca_bluetooth_serdev_match,
.driver = {
.name = "hci_uart_qca",
.of_match_table = of_match_ptr(qca_bluetooth_of_match),
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 09/10] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card
2025-11-25 14:45 ` [PATCH v2 09/10] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 13:49 ` Bartosz Golaszewski
0 siblings, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 13:49 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Manivannan Sadhasivam via B4 Relay, linux-serial, linux-kernel,
linux-kbuild, platform-driver-x86, linux-pci, devicetree,
linux-arm-msm, linux-bluetooth, linux-pm, Stephan Gerhold,
Dmitry Baryshkov, Rob Herring, Greg Kroah-Hartman, Jiri Slaby,
Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
On Tue, 25 Nov 2025 15:45:13 +0100, Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> The WCN7850 PCIe M.2 card connected to the UART controller exposes the
> 'WCN7850' serdev device and is controlled using the pwrseq framework.
>
> Hence, add support for it in the driver. It reuses the existing
> 'qca_soc_data_wcn7850' driver data.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (8 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 09/10] Bluetooth: hci_qca: Add support for WCN7850 PCIe M.2 card Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 14:45 ` Manivannan Sadhasivam via B4 Relay
2025-11-27 14:37 ` Bartosz Golaszewski
2025-11-29 14:31 ` Krzysztof Kozlowski
2025-11-25 19:57 ` [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Stephan Gerhold
10 siblings, 2 replies; 23+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-11-25 14:45 UTC (permalink / raw)
To: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov, Manivannan Sadhasivam
From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Add support for handling the power sequence of the PCIe M.2 Key E
connectors. These connectors are used to attach the Wireless Connectivity
devices to the host machine including combinations of WiFi, BT, NFC using
interfaces such as PCIe/SDIO for WiFi, USB/UART for BT and I2C for NFC.
Currently, this driver supports only the PCIe interface for WiFi and UART
interface for BT. The driver also only supports driving the 3.3v/1.8v power
supplies and W_DISABLE{1/2}# GPIOs. The optional signals of the Key E
connectors are not currently supported.
For supporting Bluetooth over the non-discoverable UART interface, the
driver currently creates the serdev interface after enumerating the PCIe
interface. This is mandatory since the device ID is only known after the
PCIe enumeration and the ID is used for creating the serdev device.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/power/sequencing/Kconfig | 1 +
drivers/power/sequencing/pwrseq-pcie-m2.c | 205 +++++++++++++++++++++++++++++-
2 files changed, 199 insertions(+), 7 deletions(-)
diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index f5fff84566ba..29bd204319cc 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -38,6 +38,7 @@ config POWER_SEQUENCING_TH1520_GPU
config POWER_SEQUENCING_PCIE_M2
tristate "PCIe M.2 connector power sequencing driver"
depends on OF || COMPILE_TEST
+ depends on PCI
help
Say Y here to enable the power sequencing driver for PCIe M.2
connectors. This driver handles the power sequencing for the M.2
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index 4835d099d967..c2cc129f6917 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -5,14 +5,17 @@
*/
#include <linux/device.h>
+#include <linux/gpio/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
+#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/provider.h>
#include <linux/regulator/consumer.h>
+#include <linux/serdev.h>
#include <linux/slab.h>
struct pwrseq_pcie_m2_pdata {
@@ -25,17 +28,20 @@ struct pwrseq_pcie_m2_ctx {
const struct pwrseq_pcie_m2_pdata *pdata;
struct regulator_bulk_data *regs;
size_t num_vregs;
+ struct gpio_desc *w_disable1_gpio;
+ struct gpio_desc *w_disable2_gpio;
struct notifier_block nb;
+ struct device *dev;
};
-static int pwrseq_pcie_m2_m_vregs_enable(struct pwrseq_device *pwrseq)
+static int pwrseq_pcie_m2_vregs_enable(struct pwrseq_device *pwrseq)
{
struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
return regulator_bulk_enable(ctx->num_vregs, ctx->regs);
}
-static int pwrseq_pcie_m2_m_vregs_disable(struct pwrseq_device *pwrseq)
+static int pwrseq_pcie_m2_vregs_disable(struct pwrseq_device *pwrseq)
{
struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
@@ -44,18 +50,84 @@ static int pwrseq_pcie_m2_m_vregs_disable(struct pwrseq_device *pwrseq)
static const struct pwrseq_unit_data pwrseq_pcie_m2_vregs_unit_data = {
.name = "regulators-enable",
- .enable = pwrseq_pcie_m2_m_vregs_enable,
- .disable = pwrseq_pcie_m2_m_vregs_disable,
+ .enable = pwrseq_pcie_m2_vregs_enable,
+ .disable = pwrseq_pcie_m2_vregs_disable,
};
-static const struct pwrseq_unit_data *pwrseq_pcie_m2_m_unit_deps[] = {
+static const struct pwrseq_unit_data *pwrseq_pcie_m2_unit_deps[] = {
&pwrseq_pcie_m2_vregs_unit_data,
NULL
};
+static int pwrseq_pci_m2_e_uart_enable(struct pwrseq_device *pwrseq)
+{
+ struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+ return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
+}
+
+static int pwrseq_pci_m2_e_uart_disable(struct pwrseq_device *pwrseq)
+{
+ struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+ return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_uart_unit_data = {
+ .name = "uart-enable",
+ .deps = pwrseq_pcie_m2_unit_deps,
+ .enable = pwrseq_pci_m2_e_uart_enable,
+ .disable = pwrseq_pci_m2_e_uart_disable,
+};
+
+static int pwrseq_pci_m2_e_pcie_enable(struct pwrseq_device *pwrseq)
+{
+ struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+ return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 0);
+}
+
+static int pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device *pwrseq)
+{
+ struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+ return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 1);
+}
+
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_pcie_unit_data = {
+ .name = "pcie-enable",
+ .deps = pwrseq_pcie_m2_unit_deps,
+ .enable = pwrseq_pci_m2_e_pcie_enable,
+ .disable = pwrseq_pci_m2_e_pcie_disable,
+};
+
static const struct pwrseq_unit_data pwrseq_pcie_m2_m_pcie_unit_data = {
.name = "pcie-enable",
- .deps = pwrseq_pcie_m2_m_unit_deps,
+ .deps = pwrseq_pcie_m2_unit_deps,
+};
+
+static int pwrseq_pcie_m2_e_pwup_delay(struct pwrseq_device *pwrseq)
+{
+ /*
+ * FIXME: This delay is only required for some Qcom WLAN/BT cards like
+ * WCN7850 and not for all devices. But currently, there is no way to
+ * identify the device model before enumeration.
+ */
+ msleep(50);
+
+ return 0;
+}
+
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_uart_target_data = {
+ .name = "uart",
+ .unit = &pwrseq_pcie_m2_e_uart_unit_data,
+ .post_enable = pwrseq_pcie_m2_e_pwup_delay,
+};
+
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_pcie_target_data = {
+ .name = "pcie",
+ .unit = &pwrseq_pcie_m2_e_pcie_unit_data,
+ .post_enable = pwrseq_pcie_m2_e_pwup_delay,
};
static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
@@ -63,11 +135,21 @@ static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
.unit = &pwrseq_pcie_m2_m_pcie_unit_data,
};
+static const struct pwrseq_target_data *pwrseq_pcie_m2_e_targets[] = {
+ &pwrseq_pcie_m2_e_pcie_target_data,
+ &pwrseq_pcie_m2_e_uart_target_data,
+ NULL
+};
+
static const struct pwrseq_target_data *pwrseq_pcie_m2_m_targets[] = {
&pwrseq_pcie_m2_m_pcie_target_data,
NULL
};
+static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_e_of_data = {
+ .targets = pwrseq_pcie_m2_e_targets,
+};
+
static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_m_of_data = {
.targets = pwrseq_pcie_m2_m_targets,
};
@@ -92,6 +174,96 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
return PWRSEQ_NO_MATCH;
}
+static int pwrseq_m2_pcie_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct pwrseq_pcie_m2_ctx *ctx = container_of(nb, struct pwrseq_pcie_m2_ctx, nb);
+ struct pci_dev *pdev = to_pci_dev(data);
+ struct device_node *pci_remote __free(device_node) = NULL;
+ struct device_node *serdev_remote __free(device_node) = NULL;
+ struct serdev_controller *serdev_ctrl;
+ struct serdev_device *serdev;
+ struct device *dev = ctx->dev;
+ int ret;
+
+ /*
+ * Check whether the PCI device is associated with this M.2 connector or
+ * not, by comparing the OF node of the PCI device parent and the Port 0
+ * (PCIe) remote node parent OF node.
+ */
+ pci_remote = of_graph_get_remote_node(dev_of_node(ctx->dev), 0, 0);
+ if (!pci_remote || (pci_remote != pdev->dev.parent->of_node))
+ return NOTIFY_DONE;
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ /* Create serdev device for WCN7850 */
+ if (pdev->vendor == PCI_VENDOR_ID_QCOM && pdev->device == 0x1107) {
+ serdev_remote = of_graph_get_remote_node(dev_of_node(ctx->dev), 1, 1);
+ if (!serdev_remote)
+ return NOTIFY_DONE;
+
+ serdev_ctrl = of_find_serdev_controller_by_node(serdev_remote);
+ if (!serdev_ctrl)
+ return NOTIFY_DONE;
+
+ serdev = serdev_device_alloc(serdev_ctrl);
+ if (!serdev)
+ return NOTIFY_BAD;
+
+ ret = serdev_device_add(serdev, "WCN7850");
+ if (ret) {
+ dev_err(dev, "Failed to add serdev for WCN7850: %d\n", ret);
+ serdev_device_put(serdev);
+ return NOTIFY_BAD;
+ }
+ }
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static bool pwrseq_pcie_m2_check_remote_node(struct device *dev, u8 port, u8 endpoint,
+ const char *node)
+{
+ struct device_node *remote __free(device_node) = NULL;
+
+ remote = of_graph_get_remote_node(dev_of_node(dev), port, endpoint);
+ if (remote && of_node_name_eq(remote, node))
+ return true;
+
+ return false;
+}
+
+/*
+ * If the connector exposes a non-discoverable bus like UART, the respective
+ * protocol device needs to be created manually with the help of the notifier
+ * of the discoverable bus like PCIe.
+ */
+static int pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx *ctx, struct device *dev)
+{
+ int ret;
+
+ /*
+ * Register a PCI notifier for Key E connector that has PCIe as Port
+ * 0/Endpoint 0 interface and Serial as Port 1/Endpoint 1 interface.
+ */
+ if (pwrseq_pcie_m2_check_remote_node(dev, 1, 1, "serial")) {
+ if (pwrseq_pcie_m2_check_remote_node(dev, 0, 0, "pcie")) {
+ ctx->dev = dev;
+ ctx->nb.notifier_call = pwrseq_m2_pcie_notify;
+ ret = bus_register_notifier(&pci_bus_type, &ctx->nb);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register notifier for serdev\n");
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -119,6 +291,16 @@ static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
return dev_err_probe(dev, ret,
"Failed to get all regulators\n");
+ ctx->w_disable1_gpio = devm_gpiod_get_optional(dev, "w-disable1", GPIOD_OUT_HIGH);
+ if (IS_ERR(ctx->w_disable1_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->w_disable1_gpio),
+ "Failed to get the W_DISABLE_1# GPIO\n");
+
+ ctx->w_disable2_gpio = devm_gpiod_get_optional(dev, "w-disable2", GPIOD_OUT_HIGH);
+ if (IS_ERR(ctx->w_disable2_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->w_disable2_gpio),
+ "Failed to get the W_DISABLE_2# GPIO\n");
+
ctx->num_vregs = ret;
config.parent = dev;
@@ -134,14 +316,23 @@ static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
"Failed to register the power sequencer\n");
}
- return 0;
+ /*
+ * Register a notifier for creating protocol devices for
+ * non-discoverable busses like UART.
+ */
+ return pwrseq_pcie_m2_register_notifier(ctx, dev);
}
+
static const struct of_device_id pwrseq_pcie_m2_of_match[] = {
{
.compatible = "pcie-m2-m-connector",
.data = &pwrseq_pcie_m2_m_of_data,
},
+ {
+ .compatible = "pcie-m2-e-connector",
+ .data = &pwrseq_pcie_m2_e_of_data,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, pwrseq_pcie_m2_of_match);
--
2.48.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors
2025-11-25 14:45 ` [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors Manivannan Sadhasivam via B4 Relay
@ 2025-11-27 14:37 ` Bartosz Golaszewski
2025-11-29 14:31 ` Krzysztof Kozlowski
1 sibling, 0 replies; 23+ messages in thread
From: Bartosz Golaszewski @ 2025-11-27 14:37 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Manivannan Sadhasivam via B4 Relay, linux-serial, linux-kernel,
linux-kbuild, platform-driver-x86, linux-pci, devicetree,
linux-arm-msm, linux-bluetooth, linux-pm, Stephan Gerhold,
Dmitry Baryshkov, Rob Herring, Greg Kroah-Hartman, Jiri Slaby,
Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
On Tue, 25 Nov 2025 15:45:14 +0100, Manivannan Sadhasivam via B4 Relay
<devnull+manivannan.sadhasivam.oss.qualcomm.com@kernel.org> said:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
> Add support for handling the power sequence of the PCIe M.2 Key E
> connectors. These connectors are used to attach the Wireless Connectivity
> devices to the host machine including combinations of WiFi, BT, NFC using
> interfaces such as PCIe/SDIO for WiFi, USB/UART for BT and I2C for NFC.
>
> Currently, this driver supports only the PCIe interface for WiFi and UART
> interface for BT. The driver also only supports driving the 3.3v/1.8v power
> supplies and W_DISABLE{1/2}# GPIOs. The optional signals of the Key E
> connectors are not currently supported.
>
> For supporting Bluetooth over the non-discoverable UART interface, the
> driver currently creates the serdev interface after enumerating the PCIe
> interface. This is mandatory since the device ID is only known after the
> PCIe enumeration and the ID is used for creating the serdev device.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> drivers/power/sequencing/Kconfig | 1 +
> drivers/power/sequencing/pwrseq-pcie-m2.c | 205 +++++++++++++++++++++++++++++-
> 2 files changed, 199 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
> index f5fff84566ba..29bd204319cc 100644
> --- a/drivers/power/sequencing/Kconfig
> +++ b/drivers/power/sequencing/Kconfig
> @@ -38,6 +38,7 @@ config POWER_SEQUENCING_TH1520_GPU
> config POWER_SEQUENCING_PCIE_M2
> tristate "PCIe M.2 connector power sequencing driver"
> depends on OF || COMPILE_TEST
> + depends on PCI
> help
> Say Y here to enable the power sequencing driver for PCIe M.2
> connectors. This driver handles the power sequencing for the M.2
> diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
> index 4835d099d967..c2cc129f6917 100644
> --- a/drivers/power/sequencing/pwrseq-pcie-m2.c
> +++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
> @@ -5,14 +5,17 @@
> */
>
I think you're missing linux/err.h here.
> #include <linux/device.h>
> +#include <linux/gpio/consumer.h>
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_graph.h>
> #include <linux/of_platform.h>
> +#include <linux/pci.h>
> #include <linux/platform_device.h>
> #include <linux/pwrseq/provider.h>
> #include <linux/regulator/consumer.h>
> +#include <linux/serdev.h>
> #include <linux/slab.h>
(snip)
>
> +static int pwrseq_m2_pcie_notify(struct notifier_block *nb, unsigned long action,
> + void *data)
> +{
> + struct pwrseq_pcie_m2_ctx *ctx = container_of(nb, struct pwrseq_pcie_m2_ctx, nb);
> + struct pci_dev *pdev = to_pci_dev(data);
> + struct device_node *pci_remote __free(device_node) = NULL;
> + struct device_node *serdev_remote __free(device_node) = NULL;
> + struct serdev_controller *serdev_ctrl;
> + struct serdev_device *serdev;
> + struct device *dev = ctx->dev;
> + int ret;
> +
> + /*
> + * Check whether the PCI device is associated with this M.2 connector or
> + * not, by comparing the OF node of the PCI device parent and the Port 0
> + * (PCIe) remote node parent OF node.
> + */
> + pci_remote = of_graph_get_remote_node(dev_of_node(ctx->dev), 0, 0);
> + if (!pci_remote || (pci_remote != pdev->dev.parent->of_node))
> + return NOTIFY_DONE;
> +
> + switch (action) {
> + case BUS_NOTIFY_ADD_DEVICE:
> + /* Create serdev device for WCN7850 */
> + if (pdev->vendor == PCI_VENDOR_ID_QCOM && pdev->device == 0x1107) {
> + serdev_remote = of_graph_get_remote_node(dev_of_node(ctx->dev), 1, 1);
> + if (!serdev_remote)
> + return NOTIFY_DONE;
> +
> + serdev_ctrl = of_find_serdev_controller_by_node(serdev_remote);
> + if (!serdev_ctrl)
> + return NOTIFY_DONE;
> +
> + serdev = serdev_device_alloc(serdev_ctrl);
> + if (!serdev)
> + return NOTIFY_BAD;
> +
This is where you'd add the software node I wrote about under another patch
from this series.
> + ret = serdev_device_add(serdev, "WCN7850");
> + if (ret) {
> + dev_err(dev, "Failed to add serdev for WCN7850: %d\n", ret);
> + serdev_device_put(serdev);
If you're touching serdev code in the same series, maybe you could define
a cleanup action for serdev devices and use it here?
> + return NOTIFY_BAD;
> + }
> + }
> + break;
> + }
> +
> + return NOTIFY_OK;
> +}
> +
> +static bool pwrseq_pcie_m2_check_remote_node(struct device *dev, u8 port, u8 endpoint,
> + const char *node)
> +{
> + struct device_node *remote __free(device_node) = NULL;
> +
> + remote = of_graph_get_remote_node(dev_of_node(dev), port, endpoint);
I'd do it like this to follow the convention of initializing automatic
variables at definition.
struct device_node *remote __free(device_node) =
of_graph_get_remote_node(dev_of_node(dev), port, endpoint);
> + if (remote && of_node_name_eq(remote, node))
> + return true;
> +
> + return false;
> +}
> +
> +/*
> + * If the connector exposes a non-discoverable bus like UART, the respective
> + * protocol device needs to be created manually with the help of the notifier
> + * of the discoverable bus like PCIe.
> + */
> +static int pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx *ctx, struct device *dev)
> +{
> + int ret;
> +
> + /*
> + * Register a PCI notifier for Key E connector that has PCIe as Port
> + * 0/Endpoint 0 interface and Serial as Port 1/Endpoint 1 interface.
> + */
> + if (pwrseq_pcie_m2_check_remote_node(dev, 1, 1, "serial")) {
> + if (pwrseq_pcie_m2_check_remote_node(dev, 0, 0, "pcie")) {
> + ctx->dev = dev;
> + ctx->nb.notifier_call = pwrseq_m2_pcie_notify;
> + ret = bus_register_notifier(&pci_bus_type, &ctx->nb);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to register notifier for serdev\n");
> + return ret;
> + }
return dev_err_probe() and save three lines?
> + }
> + }
> +
> + return 0;
> +}
> +
Bart
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors
2025-11-25 14:45 ` [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors Manivannan Sadhasivam via B4 Relay
2025-11-27 14:37 ` Bartosz Golaszewski
@ 2025-11-29 14:31 ` Krzysztof Kozlowski
1 sibling, 0 replies; 23+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-29 14:31 UTC (permalink / raw)
To: manivannan.sadhasivam, Rob Herring, Greg Kroah-Hartman,
Jiri Slaby, Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Manivannan Sadhasivam, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski
Cc: linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
Stephan Gerhold, Dmitry Baryshkov
On 25/11/2025 15:45, Manivannan Sadhasivam via B4 Relay wrote:
> static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_m_of_data = {
> .targets = pwrseq_pcie_m2_m_targets,
> };
> @@ -92,6 +174,96 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
> return PWRSEQ_NO_MATCH;
> }
>
> +static int pwrseq_m2_pcie_notify(struct notifier_block *nb, unsigned long action,
> + void *data)
> +{
> + struct pwrseq_pcie_m2_ctx *ctx = container_of(nb, struct pwrseq_pcie_m2_ctx, nb);
> + struct pci_dev *pdev = to_pci_dev(data);
> + struct device_node *pci_remote __free(device_node) = NULL;
This is an undesired syntax explicitly documented as one to avoid. You
need here proper assignment, not NULL. Please don't use cleanup.h if you
do not intend to follow it because it does not make the code simpler.
> + struct device_node *serdev_remote __free(device_node) = NULL;
This is even worse. Instead of making it local scope, you have automatic
cleanup for entire function with completely redundant constructor.
Please, use cleanup.h only if you really want to follow its spirit.
Otherwise it does not make the code easier.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree
2025-11-25 14:45 [PATCH v2 00/10] Add support for handling PCIe M.2 Key E connectors in devicetree Manivannan Sadhasivam via B4 Relay
` (9 preceding siblings ...)
2025-11-25 14:45 ` [PATCH v2 10/10] power: sequencing: pcie-m2: Add support for PCIe M.2 Key E connectors Manivannan Sadhasivam via B4 Relay
@ 2025-11-25 19:57 ` Stephan Gerhold
10 siblings, 0 replies; 23+ messages in thread
From: Stephan Gerhold @ 2025-11-25 19:57 UTC (permalink / raw)
To: manivannan.sadhasivam
Cc: Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
Derek J. Clark, Manivannan Sadhasivam, Krzysztof Kozlowski,
Conor Dooley, Marcel Holtmann, Luiz Augusto von Dentz,
Bartosz Golaszewski, linux-serial, linux-kernel, linux-kbuild,
platform-driver-x86, linux-pci, devicetree, linux-arm-msm,
linux-bluetooth, linux-pm, Dmitry Baryshkov
On Tue, Nov 25, 2025 at 08:15:04PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> This series is the continuation of the series [1] that added the initial support
> for the PCIe M.2 connectors. This series extends it by adding support for Key E
> connectors. These connectors are used to connect the Wireless Connectivity
> devices such as WiFi, BT, NFC and GNSS devices to the host machine over
> interfaces such as PCIe/SDIO, USB/UART and NFC. This series adds support for
> connectors that expose PCIe interface for WiFi and UART interface for BT. Other
> interfaces are left for future improvements.
>
> Serdev device support for BT
> ============================
>
> Adding support for the PCIe interface was mostly straightforward and a lot
> similar to the previous Key M connector. But adding UART interface has proved to
> be tricky. This is mostly because of the fact UART is a non-discoverable bus,
> unlike PCIe which is discoverable. So this series relied on the PCI notifier to
> create the serdev device for UART/BT. This means the PCIe interface will be
> brought up first and after the PCIe device enumeration, the serdev device will
> be created by the pwrseq driver. This logic is necessary since the connector
> driver and DT node don't describe the device, but just the connector. So to make
> the connector interface Plug and Play, the connector driver uses the PCIe device
> ID to identify the card and creates the serdev device. This logic could be
> extended in the future to support more M.2 cards. Even if the M.2 card uses SDIO
> interface for connecting WLAN, a SDIO notifier could be added to create the
> serdev device.
>
> Open questions
> ==============
>
> Though this series adds the relevant functionality for handling the M.2 Key M
> connectors, there are still a few open questions exists on the design.
>
> 1. I've used the M.2 card model name as the serdev device name. This is found
> out by comparing the PCIe VID:PID in the notifier. Is this approach acceptable?
> I did not use the PID as the serdev name since it will vary if the SDIO
> interface is used in the future.
>
> 2. PCIe client drivers of some M.2 WLAN cards like the Qcom QCA6390, rely on
> the PCIe device DT node to extract properties such as
> 'qcom,calibration-variant', 'firmware-name', etc... For those drivers, should we
> add the PCIe DT node in the Root Port in conjunction with the Port node as
> below?
>
> pcie@0 {
> wifi@0 {
> compatible = "pci17cb,1103";
> ...
> qcom,calibration-variant = "LE_X13S";
> };
>
> port {
> pcie4_port0_ep: endpoint {
> remote-endpoint = <&m2_e_pcie_ep>;
> };
> };
> };
>
> This will also require marking the PMU supplies optional in the relevant ath
> bindings for M.2 cards.
>
> 3. Some M.2 cards require specific power up sequence like delays between
> regulator/GPIO and such. For instance, the WCN7850 card supported in this series
> requires 50ms delay between powering up an interface and driving it. I've just
> hardcoded the delay in the driver, but it is a pure hack. Since the pwrseq
> driver doesn't know anything about the device it is dealing with before powering
> it ON, how should it handle the device specific power requirements? Should we
> hardcode the device specific property in the connector node? But then, it will
> no longer become a generic M.2 connector and sort of defeats the purpose of the
> connector binding.
>
> I hope to address these questions with the help of the relevant subsystem
> maintainers and the community.
>
> Testing
> =======
>
> This series, together with the devicetree changes [2] was tested on the
> Qualcomm X1e based Lenovo Thinkpad T14s Laptop which has the WCN7850 WLAN/BT M.2
> card connected over PCIe and UART.
>
> [2] https://github.com/Mani-Sadhasivam/linux/commit/acbee74a5c90fc8839bb7b6f326c677ee1c0d89c
Thanks for working on describing the M.2 connectors properly in the
device tree!
I haven't had time to look into this in detail yet, but a quick look at
the dt-bindings and examples looks good to me! Thanks for keeping the
bindings as generic as possible.
I have a small nitpick for the specific example you have here: The
Lenovo ThinkPad T14s does not actually have a "M.2 Mechanical Key E
connector". If you look at a picture of the mainboard [1], the WLAN/BT
module is "soldered-down" (look on the right, on the right side next to
the large copper bracket). In the M.2 specification, "soldered-down"
modules do not have a "key", they have a specific pinout that is
followed (see section 5.4). The power sequencing etc and the set of pins
is quite similar/the same though.
My notes (from a few months ago) suggest the T14s probably uses a
non-standard M.2 Type 1620 LGA pinout. I don't remember the exact chain
of thought behind that, but you can find similarly looking modules with
this type, e.g. https://www.sparklan.com/product/wnsq-290be/. There is a
1620 *BGA* pinout in the M.2 specification, but a 1620 *LGA* pinout does
not exist there. Interestingly, in the block diagram of the module in
the link above this type is called *Q*M.2 1620 LGA 168 pin, as if this
is some Qualcomm-specific form factor.
A real mechanical key E connector can be found e.g. in the X1E CRD, X1E
Devkit, or I think some of the X1E-based HP laptops (would need to check
which one exactly).
I'm not sure if it's really appropriate modeling the "soldered-down"
variant as "Mechanical Key E connector" in the DT. We might need
a separate compatible for this. Do you have any thoughts about that?
Thanks,
Stephan
[1]: https://www.notebookcheck.com/fileadmin/_processed_/d/c/csm_DSC_0003_aadae1ddd2.jpg
^ permalink raw reply [flat|nested] 23+ messages in thread