diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index 8999fcebde6a..064843ab6866 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -155,3 +155,5 @@ config PCIE_EDR
 	  the PCI Firmware Specification r3.2.  Enable this if you want to
 	  support hybrid DPC model which uses both firmware and OS to
 	  implement DPC.
+
+source "drivers/pci/pcie/pwrseq/Kconfig"
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index 8de4ed5f98f1..ace91384113d 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_PCIE_PME)		+= pme.o
 obj-$(CONFIG_PCIE_DPC)		+= dpc.o
 obj-$(CONFIG_PCIE_PTM)		+= ptm.o
 obj-$(CONFIG_PCIE_EDR)		+= edr.o
+
+obj-$(CONFIG_PCIEPORTBUS)	+= pwrseq/
diff --git a/drivers/pci/pcie/pwrseq/Kconfig b/drivers/pci/pcie/pwrseq/Kconfig
new file mode 100644
index 000000000000..010e31f432c9
--- /dev/null
+++ b/drivers/pci/pcie/pwrseq/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menuconfig PCIE_PWRSEQ
+	bool "PCIe Power Sequencing support"
+	depends on PCIEPORTBUS
+	help
+	  Say yes here to enable support for PCIe power sequencing
+	  drivers.
diff --git a/drivers/pci/pcie/pwrseq/Makefile b/drivers/pci/pcie/pwrseq/Makefile
new file mode 100644
index 000000000000..da99566594f6
--- /dev/null
+++ b/drivers/pci/pcie/pwrseq/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_PCIE_PWRSEQ)		+= pwrseq.o
diff --git a/drivers/pci/pcie/pwrseq/pwrseq.c b/drivers/pci/pcie/pwrseq/pwrseq.c
new file mode 100644
index 000000000000..c4f7958074c9
--- /dev/null
+++ b/drivers/pci/pcie/pwrseq/pwrseq.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pcie-pwrseq.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+
+static int pcie_pwrseq_notify(struct notifier_block *nb, unsigned long action,
+			      void *data)
+{
+	struct pcie_pwrseq *pwrseq = container_of(nb, struct pcie_pwrseq, nb);
+	struct device *dev = data;
+
+	if (dev_fwnode(dev) != dev_fwnode(pwrseq->dev))
+		return NOTIFY_DONE;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		device_set_of_node_from_dev(dev, pwrseq->dev);
+		break;
+	case BUS_NOTIFY_BOUND_DRIVER:
+		pwrseq->link = device_link_add(dev, pwrseq->dev,
+					       DL_FLAG_AUTOREMOVE_CONSUMER);
+		if (!pwrseq->link)
+			dev_err(pwrseq->dev, "Failed to add device link\n");
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		device_link_del(pwrseq->link);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+int pcie_pwrseq_device_enable(struct pcie_pwrseq *pwrseq)
+{
+	if (!pwrseq->dev)
+		return -ENODEV;
+
+	pwrseq->nb.notifier_call = pcie_pwrseq_notify;
+	bus_register_notifier(&pci_bus_type, &pwrseq->nb);
+
+	pci_lock_rescan_remove();
+	pci_rescan_bus(to_pci_dev(pwrseq->dev->parent)->bus);
+	pci_unlock_rescan_remove();
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pcie_pwrseq_device_enable);
+
+void pcie_pwrseq_device_disable(struct pcie_pwrseq *pwrseq)
+{
+	bus_unregister_notifier(&pci_bus_type, &pwrseq->nb);
+}
+EXPORT_SYMBOL_GPL(pcie_pwrseq_device_disable);
+
+static void devm_pcie_pwrseq_device_disable(void *data)
+{
+	struct pcie_pwrseq *pwrseq = data;
+
+	pcie_pwrseq_device_disable(pwrseq);
+}
+
+int devm_pcie_pwrseq_device_enable(struct device *dev,
+				   struct pcie_pwrseq *pwrseq)
+{
+	int ret;
+
+	ret = pcie_pwrseq_device_enable(pwrseq);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, devm_pcie_pwrseq_device_disable,
+					pwrseq);
+}
+EXPORT_SYMBOL_GPL(devm_pcie_pwrseq_device_enable);
diff --git a/include/linux/pcie-pwrseq.h b/include/linux/pcie-pwrseq.h
new file mode 100644
index 000000000000..6abb5796754e
--- /dev/null
+++ b/include/linux/pcie-pwrseq.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#ifndef __PCIE_PWRSEQ_H__
+#define __PCIE_PWRSEQ_H__
+
+#include <linux/notifier.h>
+
+struct device;
+
+struct pcie_pwrseq {
+	struct notifier_block nb;
+	struct device *dev;
+	struct device_link *link;
+};
+
+int pcie_pwrseq_device_enable(struct pcie_pwrseq *pwrseq);
+void pcie_pwrseq_device_disable(struct pcie_pwrseq *pwrseq);
+int devm_pcie_pwrseq_device_enable(struct device *dev,
+				   struct pcie_pwrseq *pwrseq);
+
+#endif /* __PCIE_PWRSEQ_H__ */
