* [PATCH v7 1/2] PCI/pwrctrl: Add support for handling PCIe M.2 connectors
2026-01-28 15:37 [PATCH v7 0/2] PCI: Add initial support for handling PCIe M.2 connectors in devicetree Manivannan Sadhasivam
@ 2026-01-28 15:37 ` Manivannan Sadhasivam
2026-01-28 15:37 ` [PATCH v7 2/2] PCI/pwrctrl: Create pwrctrl device if the graph port is found Manivannan Sadhasivam
2026-01-28 16:54 ` [PATCH v7 0/2] PCI: Add initial support for handling PCIe M.2 connectors in devicetree Bjorn Helgaas
2 siblings, 0 replies; 4+ messages in thread
From: Manivannan Sadhasivam @ 2026-01-28 15:37 UTC (permalink / raw)
To: Bjorn Helgaas, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Damien Le Moal, Niklas Cassel, Linus Walleij, Bartosz Golaszewski
Cc: linux-kernel, linux-pci, devicetree, linux-arm-msm,
Stephan Gerhold, Dmitry Baryshkov, linux-pm, linux-ide,
Manivannan Sadhasivam, Bartosz Golaszewski
Add support for handling the PCIe M.2 connectors as Power Sequencing
devices. These connectors are exposed as the Power Sequencing devices
as they often support multiple interfaces like PCIe/SATA, USB/UART to the
host machine and each interfaces could be driven by different client
drivers at the same time.
This driver handles the PCIe interface of these connectors. It first checks
for the presence of the graph port in the Root Port node with the help of
of_graph_is_present() API, if present, it acquires/poweres ON the
corresponding pwrseq device.
Once the pwrseq device is powered ON, the driver will skip parsing the Root
Port/Slot resources and registers with the pwrctrl framework.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/pci/pwrctrl/Kconfig | 1 +
drivers/pci/pwrctrl/slot.c | 31 +++++++++++++++++++++++++++----
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pwrctrl/Kconfig b/drivers/pci/pwrctrl/Kconfig
index e0f999f299bb..cd3aa15bad00 100644
--- a/drivers/pci/pwrctrl/Kconfig
+++ b/drivers/pci/pwrctrl/Kconfig
@@ -13,6 +13,7 @@ config PCI_PWRCTRL_PWRSEQ
config PCI_PWRCTRL_SLOT
tristate "PCI Power Control driver for PCI slots"
+ select POWER_SEQUENCING
select PCI_PWRCTRL
help
Say Y here to enable the PCI Power Control driver to control the power
diff --git a/drivers/pci/pwrctrl/slot.c b/drivers/pci/pwrctrl/slot.c
index 44eccbca793c..082af81efe25 100644
--- a/drivers/pci/pwrctrl/slot.c
+++ b/drivers/pci/pwrctrl/slot.c
@@ -8,8 +8,10 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/pci-pwrctrl.h>
#include <linux/platform_device.h>
+#include <linux/pwrseq/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -18,6 +20,7 @@ struct slot_pwrctrl {
struct regulator_bulk_data *supplies;
int num_supplies;
struct clk *clk;
+ struct pwrseq_desc *pwrseq;
};
static int slot_pwrctrl_power_on(struct pci_pwrctrl *pwrctrl)
@@ -26,6 +29,11 @@ static int slot_pwrctrl_power_on(struct pci_pwrctrl *pwrctrl)
struct slot_pwrctrl, pwrctrl);
int ret;
+ if (slot->pwrseq) {
+ pwrseq_power_on(slot->pwrseq);
+ return 0;
+ }
+
ret = regulator_bulk_enable(slot->num_supplies, slot->supplies);
if (ret < 0) {
dev_err(slot->pwrctrl.dev, "Failed to enable slot regulators\n");
@@ -40,6 +48,11 @@ static int slot_pwrctrl_power_off(struct pci_pwrctrl *pwrctrl)
struct slot_pwrctrl *slot = container_of(pwrctrl,
struct slot_pwrctrl, pwrctrl);
+ if (slot->pwrseq) {
+ pwrseq_power_off(slot->pwrseq);
+ return 0;
+ }
+
regulator_bulk_disable(slot->num_supplies, slot->supplies);
clk_disable_unprepare(slot->clk);
@@ -64,6 +77,15 @@ static int slot_pwrctrl_probe(struct platform_device *pdev)
if (!slot)
return -ENOMEM;
+ if (of_graph_is_present(dev_of_node(dev))) {
+ slot->pwrseq = devm_pwrseq_get(dev, "pcie");
+ if (IS_ERR(slot->pwrseq))
+ return dev_err_probe(dev, PTR_ERR(slot->pwrseq),
+ "Failed to get the power sequencer\n");
+
+ goto skip_resources;
+ }
+
ret = of_regulator_bulk_get_all(dev, dev_of_node(dev),
&slot->supplies);
if (ret < 0) {
@@ -73,19 +95,20 @@ static int slot_pwrctrl_probe(struct platform_device *pdev)
slot->num_supplies = ret;
- ret = devm_add_action_or_reset(dev, devm_slot_pwrctrl_release, slot);
- if (ret)
- return ret;
-
slot->clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(slot->clk)) {
return dev_err_probe(dev, PTR_ERR(slot->clk),
"Failed to enable slot clock\n");
}
+skip_resources:
slot->pwrctrl.power_on = slot_pwrctrl_power_on;
slot->pwrctrl.power_off = slot_pwrctrl_power_off;
+ ret = devm_add_action_or_reset(dev, devm_slot_pwrctrl_release, slot);
+ if (ret)
+ return ret;
+
pci_pwrctrl_init(&slot->pwrctrl, dev);
ret = devm_pci_pwrctrl_device_set_ready(dev, &slot->pwrctrl);
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v7 2/2] PCI/pwrctrl: Create pwrctrl device if the graph port is found
2026-01-28 15:37 [PATCH v7 0/2] PCI: Add initial support for handling PCIe M.2 connectors in devicetree Manivannan Sadhasivam
2026-01-28 15:37 ` [PATCH v7 1/2] PCI/pwrctrl: Add support for handling PCIe M.2 connectors Manivannan Sadhasivam
@ 2026-01-28 15:37 ` Manivannan Sadhasivam
2026-01-28 16:54 ` [PATCH v7 0/2] PCI: Add initial support for handling PCIe M.2 connectors in devicetree Bjorn Helgaas
2 siblings, 0 replies; 4+ messages in thread
From: Manivannan Sadhasivam @ 2026-01-28 15:37 UTC (permalink / raw)
To: Bjorn Helgaas, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Damien Le Moal, Niklas Cassel, Linus Walleij, Bartosz Golaszewski
Cc: linux-kernel, linux-pci, devicetree, linux-arm-msm,
Stephan Gerhold, Dmitry Baryshkov, linux-pm, linux-ide,
Manivannan Sadhasivam, Bartosz Golaszewski
The devicetree node of the PCIe Root Port/Slot could have the graph port
to link the PCIe M.2 connector node. Since the M.2 connectors are modelled
as Power Sequencing devices, they need to be controlled by the pwrctrl
driver as like the Root Port/Slot supplies.
Hence, create the pwrctrl device if the graph port is found in the node.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
drivers/pci/pwrctrl/core.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
index 1b91375738a0..6f7dea6746e0 100644
--- a/drivers/pci/pwrctrl/core.c
+++ b/drivers/pci/pwrctrl/core.c
@@ -9,6 +9,7 @@
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/pci-pwrctrl.h>
@@ -295,10 +296,10 @@ static int pci_pwrctrl_create_device(struct device_node *np,
/*
* Check whether the pwrctrl device really needs to be created or not.
- * This is decided based on at least one of the power supplies being
- * defined in the devicetree node of the device.
+ * This is decided based on at least one of the power supplies defined
+ * in the devicetree node of the device or the graph property.
*/
- if (!of_pci_supply_present(np)) {
+ if (!of_pci_supply_present(np) && !of_graph_is_present(np)) {
dev_dbg(parent, "Skipping OF node: %s\n", np->name);
return 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v7 0/2] PCI: Add initial support for handling PCIe M.2 connectors in devicetree
2026-01-28 15:37 [PATCH v7 0/2] PCI: Add initial support for handling PCIe M.2 connectors in devicetree Manivannan Sadhasivam
2026-01-28 15:37 ` [PATCH v7 1/2] PCI/pwrctrl: Add support for handling PCIe M.2 connectors Manivannan Sadhasivam
2026-01-28 15:37 ` [PATCH v7 2/2] PCI/pwrctrl: Create pwrctrl device if the graph port is found Manivannan Sadhasivam
@ 2026-01-28 16:54 ` Bjorn Helgaas
2 siblings, 0 replies; 4+ messages in thread
From: Bjorn Helgaas @ 2026-01-28 16:54 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Damien Le Moal, Niklas Cassel, Linus Walleij, Bartosz Golaszewski,
linux-kernel, linux-pci, devicetree, linux-arm-msm,
Stephan Gerhold, Dmitry Baryshkov, linux-pm, linux-ide,
Bartosz Golaszewski
On Wed, Jan 28, 2026 at 09:07:14PM +0530, Manivannan Sadhasivam wrote:
> Hi,
>
> This series is an initial attempt to support the PCIe M.2 connectors in the
> kernel and devicetree binding. The PCIe M.2 connectors as defined in the PCI
> Express M.2 Specification are widely used in Notebooks/Tablet form factors (even
> in PCs). On the ACPI platforms, power to these connectors are mostly handled by
> the firmware/BIOS and the kernel never bothered to directly power manage them as
> like other PCIe connectors. But on the devicetree platforms, the kernel needs to
> power manage these connectors with the help of the devicetree description. But
> so far, there is no proper representation of the M.2 connectors in devicetree
> binding. This forced the developers to fake the M.2 connectors as PMU nodes [1]
> and fixed regulators in devicetree.
>
> So to properly support the M.2 connectors in devicetree platforms, this series
> introduces the devicetree binding for Mechanical Key M connector as an example
> and also the corresponding pwrseq driver and PCI changes in kernel to driver the
> connector.
>
> The Mechanical Key M connector is used to connect SSDs to the host machine over
> PCIe/SATA interfaces. Due to the hardware constraints, this series only adds
> support for driving the PCIe interface of the connector in the kernel.
>
> Also, the optional interfaces supported by the Key M connectors are not
> supported in the driver and left for the future enhancements.
>
> Testing
> =======
>
> This series, together with the devicetree changes [2] [3] were tested on the
> Qualcomm X1e based Lenovo Thinkpad T14s Laptop which has the NVMe SSD connected
> over PCIe.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts?h=v6.18-rc4&id=d09ab685a8f51ba412d37305ea62628a01cbea57
> [2] https://github.com/Mani-Sadhasivam/linux/commit/40120d02219f34d2040ffa6328f0d406b1e4c04d
> [3] https://github.com/Mani-Sadhasivam/linux/commit/ff6c3075836cc794a3700b0ec6a4a9eb21d14c6f
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
> Changes in v7:
> - Dropped the pwrseq and binding patches as they got applied
> - Rebased on top of pci/pwrctrl branch
> - Link to v6: https://lore.kernel.org/r/20260122-pci-m2-v6-0-575da9f97239@oss.qualcomm.com
>
> Changes in v6:
> - Used 'ports' to describe interfaces instead of endpoints in the binding
> - Added GPIOs and USB to the example in binding
> - Incorporated minor comments in the pwrseq driver
> - Dropped the ata binding patch as it got applied
> - Link to v5: https://lore.kernel.org/r/20260107-pci-m2-v5-0-8173d8a72641@oss.qualcomm.com
>
> Changes in v5:
> - used of_node_get() and devm_action to free regulators
> - Link to v4: https://lore.kernel.org/r/20251228-pci-m2-v4-0-5684868b0d5f@oss.qualcomm.com
>
> Changes in v4:
> - Added graph property to SATA in this series and PCI to dtschema:
> https://github.com/devicetree-org/dt-schema/pull/180
> - Used 'i2c-parent' instead of SMBus port
> - Reworded the -gpios property description
> - Rebased on top of v6.19-rc1
> - Link to v3: https://lore.kernel.org/r/20251125-pci-m2-v3-0-c528042aea47@oss.qualcomm.com
>
> Changes in v3:
> - Changed the VIO supply name as per dtschema
> - Added explicit endpoint properties to port 0 node for host I/F
> - Used scope based cleanup for OF node in pwrseq driver
> - Collected review tags
> - Link to v2: https://lore.kernel.org/r/20251108-pci-m2-v2-0-e8bc4d7bf42d@oss.qualcomm.com
>
> Changes in v2:
> - Incorporated comments from Bartosz and Frank for pwrseq and dt-binding
> patches, especially adding the pwrseq match() code.
> - Link to v1: https://lore.kernel.org/r/20251105-pci-m2-v1-0-84b5f1f1e5e8@oss.qualcomm.com
>
> ---
> Manivannan Sadhasivam (2):
> PCI/pwrctrl: Add support for handling PCIe M.2 connectors
> PCI/pwrctrl: Create pwrctrl device if the graph port is found
>
> drivers/pci/pwrctrl/Kconfig | 1 +
> drivers/pci/pwrctrl/core.c | 7 ++++---
> drivers/pci/pwrctrl/slot.c | 31 +++++++++++++++++++++++++++----
> 3 files changed, 32 insertions(+), 7 deletions(-)
> ---
> base-commit: 3e7f562e20ee87a25e104ef4fce557d39d62fa85
> change-id: 20251103-pci-m2-7633631b6faa
>
> Best regards,
> --
> Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>
Applied to pci/pwrctrl for v6.20, thanks!
^ permalink raw reply [flat|nested] 4+ messages in thread