From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Mahesh J Salgaonkar <mahesh@linux.ibm.com>,
Bjorn Helgaas <bhelgaas@google.com>, <linux-cxl@vger.kernel.org>,
<linux-pci@vger.kernel.org>
Cc: "Davidlohr Bueso" <dave@stgolabs.net>,
"Dave Jiang" <dave.jiang@intel.com>,
"Alison Schofield" <alison.schofield@intel.com>,
"Vishal Verma" <vishal.l.verma@intel.com>,
"Ira Weiny" <ira.weiny@intel.com>,
"Dan Williams" <dan.j.williams@intel.com>,
"Will Deacon" <will@kernel.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
linuxarm@huawei.com, terry.bowman@amd.com,
"Kuppuswamy Sathyanarayanan"
<sathyanarayanan.kuppuswamy@linux.intel.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
Subject: [RFC PATCH 3/9] pci: pcie: portdrv: Use managed device handling to simplify error and remove flows.
Date: Wed, 29 May 2024 17:40:57 +0100 [thread overview]
Message-ID: <20240529164103.31671-4-Jonathan.Cameron@huawei.com> (raw)
In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com>
Intent here is to end with a simpler setup for the forthcomming
auxilliary_bus setup and tear down by enabling that to safely
use device managed calls.
One change here is that if none of the service drivers load, rather
than just disabling intterrupts etc this fails the portdrv probe and
relies on automated cleanup.
The shutdown callback still needs to manually call much of the
no automated flow, so directly call the same functions registered
with devm_add_action_or_reset() or unwinding the automated
cleanup of elements such as pci_free_irq_vectors().
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
drivers/pci/pcie/portdrv.c | 91 ++++++++++++++++++--------------------
1 file changed, 42 insertions(+), 49 deletions(-)
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index bb65dfe43409..7f053bab7745 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -317,6 +317,27 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
return 0;
}
+static int remove_iter(struct device *dev, void *data)
+{
+ if (dev->bus == &pcie_port_bus_type)
+ device_unregister(dev);
+ return 0;
+}
+
+/**
+ * pcie_port_device_remove - unregister PCI Express port service devices
+ * @d: PCI Express port the service devices to unregister are associated with
+ *
+ * Remove PCI Express port service devices associated with given port and
+ * disable MSI-X or MSI for the port.
+ */
+static void pcie_port_device_remove(void *d)
+{
+ struct pci_dev *dev = d;
+
+ device_for_each_child(&dev->dev, NULL, remove_iter);
+}
+
/**
* pcie_port_device_register - register PCI Express port
* @dev: PCI Express port to register
@@ -330,7 +351,7 @@ static int pcie_port_device_register(struct pci_dev *dev)
int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
/* Enable PCI Express port device */
- status = pci_enable_device(dev);
+ status = pcim_enable_device(dev);
if (status)
return status;
@@ -351,7 +372,7 @@ static int pcie_port_device_register(struct pci_dev *dev)
if (status) {
capabilities &= PCIE_PORT_SERVICE_HP;
if (!capabilities)
- goto error_disable;
+ return status;
}
/* Allocate child services if any */
@@ -365,15 +386,9 @@ static int pcie_port_device_register(struct pci_dev *dev)
nr_service++;
}
if (!nr_service)
- goto error_cleanup_irqs;
+ return -ENODEV; /* Why carry on if nothing supported? */
return 0;
-
-error_cleanup_irqs:
- pci_free_irq_vectors(dev);
-error_disable:
- pci_disable_device(dev);
- return status;
}
typedef int (*pcie_callback_t)(struct pcie_device *);
@@ -441,13 +456,6 @@ static int pcie_port_device_runtime_resume(struct device *dev)
}
#endif /* PM */
-static int remove_iter(struct device *dev, void *data)
-{
- if (dev->bus == &pcie_port_bus_type)
- device_unregister(dev);
- return 0;
-}
-
static int find_service_iter(struct device *device, void *data)
{
struct pcie_port_service_driver *service_driver;
@@ -491,19 +499,6 @@ struct device *pcie_port_find_device(struct pci_dev *dev,
}
EXPORT_SYMBOL_GPL(pcie_port_find_device);
-/**
- * pcie_port_device_remove - unregister PCI Express port service devices
- * @dev: PCI Express port the service devices to unregister are associated with
- *
- * Remove PCI Express port service devices associated with given port and
- * disable MSI-X or MSI for the port.
- */
-static void pcie_port_device_remove(struct pci_dev *dev)
-{
- device_for_each_child(&dev->dev, NULL, remove_iter);
- pci_free_irq_vectors(dev);
-}
-
/**
* pcie_port_probe_service - probe driver for given PCI Express port service
* @dev: PCI Express port service device to probe against
@@ -669,6 +664,17 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
#define PCIE_PORTDRV_PM_OPS NULL
#endif /* !PM */
+static void pcie_portdrv_runtime_pm_disable(void *d)
+{
+ struct pci_dev *dev = d;
+
+ if (pci_bridge_d3_possible(dev)) {
+ pm_runtime_forbid(&dev->dev);
+ pm_runtime_get_noresume(&dev->dev);
+ pm_runtime_dont_use_autosuspend(&dev->dev);
+ }
+}
+
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
* @dev: PCI-Express port device being probed
@@ -697,6 +703,11 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
if (status)
return status;
+ status = devm_add_action_or_reset(&dev->dev, pcie_port_device_remove,
+ dev);
+ if (status)
+ return status;
+
pci_save_state(dev);
dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE |
@@ -718,28 +729,11 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
return 0;
}
-static void pcie_portdrv_remove(struct pci_dev *dev)
-{
- if (pci_bridge_d3_possible(dev)) {
- pm_runtime_forbid(&dev->dev);
- pm_runtime_get_noresume(&dev->dev);
- pm_runtime_dont_use_autosuspend(&dev->dev);
- }
-
- pcie_port_device_remove(dev);
-
- pci_disable_device(dev);
-}
-
static void pcie_portdrv_shutdown(struct pci_dev *dev)
{
- if (pci_bridge_d3_possible(dev)) {
- pm_runtime_forbid(&dev->dev);
- pm_runtime_get_noresume(&dev->dev);
- pm_runtime_dont_use_autosuspend(&dev->dev);
- }
-
+ pcie_portdrv_runtime_pm_disable(dev);
pcie_port_device_remove(dev);
+ pci_free_irq_vectors(dev);
}
static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
@@ -789,7 +783,6 @@ static struct pci_driver pcie_portdriver = {
.id_table = &port_pci_ids[0],
.probe = pcie_portdrv_probe,
- .remove = pcie_portdrv_remove,
.shutdown = pcie_portdrv_shutdown,
.err_handler = &pcie_portdrv_err_handler,
--
2.39.2
next prev parent reply other threads:[~2024-05-29 16:42 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-29 16:40 [RFC PATCH 0/9] pci: portdrv: Add auxiliary bus and register CXL PMUs (and aer) Jonathan Cameron
2024-05-29 16:40 ` [RFC PATCH 1/9] pci: pcie: Drop priv_data from struct pcie_device and use dev_get/set_drvdata() instead Jonathan Cameron
2024-05-29 16:40 ` [RFC PATCH 2/9] pci: portdrv: Drop driver field for port type Jonathan Cameron
2024-05-29 16:40 ` Jonathan Cameron [this message]
2024-05-29 16:40 ` [RFC PATCH 4/9] auxiliary_bus: expose auxiliary_bus_type Jonathan Cameron
2024-05-29 16:40 ` [RFC PATCH 5/9] pci: pcie: portdrv: Add a auxiliary_bus Jonathan Cameron
2024-05-29 16:41 ` [RFC PATCH 6/9] cxl: Move CPMU register definitions to header Jonathan Cameron
2024-05-29 16:41 ` [RFC PATCH 7/9] pci: pcie/cxl: Register an auxiliary device for each CPMU instance Jonathan Cameron
2024-05-29 16:41 ` [RFC PATCH 8/9] perf: cxl: Make the cpmu driver also work with auxiliary_devices Jonathan Cameron
2024-05-29 16:41 ` [RFC PATCH 9/9] pci: pcie: portdrv: aer: Switch to auxiliary_bus Jonathan Cameron
2024-06-05 18:04 ` [RFC PATCH 0/9] pci: portdrv: Add auxiliary bus and register CXL PMUs (and aer) Bjorn Helgaas
2024-06-05 19:44 ` Jonathan Cameron
2024-06-06 12:57 ` Jonathan Cameron
2024-06-06 13:21 ` Lukas Wunner
2024-08-23 11:05 ` Jonathan Cameron
2024-08-28 21:11 ` Thomas Gleixner
2024-08-29 12:17 ` Jonathan Cameron
2024-09-05 11:23 ` Jonathan Cameron
2024-09-06 10:11 ` Thomas Gleixner
2024-09-06 17:18 ` Jonathan Cameron
2024-09-10 16:47 ` Jonathan Cameron
2024-09-10 17:37 ` Jonathan Cameron
2024-09-10 20:04 ` Thomas Gleixner
2024-09-12 16:37 ` Jonathan Cameron
2024-09-12 17:34 ` Jonathan Cameron
2024-09-13 16:24 ` Thomas Gleixner
2024-06-17 7:03 ` Ilpo Järvinen
2024-07-04 16:14 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240529164103.31671-4-Jonathan.Cameron@huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=alison.schofield@intel.com \
--cc=bhelgaas@google.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linuxarm@huawei.com \
--cc=lpieralisi@kernel.org \
--cc=mahesh@linux.ibm.com \
--cc=mark.rutland@arm.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=terry.bowman@amd.com \
--cc=vishal.l.verma@intel.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox