From patchwork Wed May 29 16:40:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679269 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B80AB1C6B2; Wed, 29 May 2024 16:41:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000899; cv=none; b=DA0UPUH+hqAcdwK6iVsRB/JoGi/ZFu0AbexdNG67ZlhEvkBqySatl4YQdCAl+Iu8LZBGBWarpq/YMYQJOXtzY+pTRW0aETuJZKeIZZRNq6o4c/SaRndy5kBbsyBliaPGBPg2zbb90PQY+P+qFXE9EQ2VgAkQDNuIyS/x85ZuM58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000899; c=relaxed/simple; bh=KyioEzZkMBKwpJONrLRvPEWUM/G6oi76nlR6eiaKuhw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j5O0jKr6haQQkmjdC80cPRQ/3D/Wq4RzeC3zRjYnFA+txLygTpKqCv2bHKsdMR3Nlv/Snk8Z6BWz/0SG1hbfqlFKYMY93WYItSeqsOVI68rwK28dpPDe1k2lueMO2MFhyhEEsBRdsRrxwIPtrg6lTiMvwtVrPtLB+IK3/JKE9mY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.216]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFVn3777z67l0C; Thu, 30 May 2024 00:40:33 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id 590F8140447; Thu, 30 May 2024 00:41:34 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:41:33 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 1/9] pci: pcie: Drop priv_data from struct pcie_device and use dev_get/set_drvdata() instead. Date: Wed, 29 May 2024 17:40:55 +0100 Message-ID: <20240529164103.31671-2-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) struct device has a driver_data pointer for the same purpose as the priv_data in struct pcie_device, so use that via the embedded struct device instead. This will simplify moving to a different approach to the pcie_device handling. Signed-off-by: Jonathan Cameron --- drivers/pci/hotplug/pciehp_core.c | 12 ++++++------ drivers/pci/hotplug/pciehp_hpc.c | 2 +- drivers/pci/pcie/aer.c | 8 ++++---- drivers/pci/pcie/pme.c | 13 +++++++------ drivers/pci/pcie/portdrv.h | 11 ----------- 5 files changed, 18 insertions(+), 28 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index ddd55ad97a58..8e8d88f0d501 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -202,7 +202,7 @@ static int pciehp_probe(struct pcie_device *dev) pci_err(dev->port, "Controller initialization failed\n"); return -ENODEV; } - set_service_data(dev, ctrl); + dev_set_drvdata(&dev->device, ctrl); /* Setup the slot information structures */ rc = init_slot(ctrl); @@ -243,7 +243,7 @@ static int pciehp_probe(struct pcie_device *dev) static void pciehp_remove(struct pcie_device *dev) { - struct controller *ctrl = get_service_data(dev); + struct controller *ctrl = dev_get_drvdata(&dev->device); pci_hp_del(&ctrl->hotplug_slot); pcie_shutdown_notification(ctrl); @@ -267,7 +267,7 @@ static void pciehp_disable_interrupt(struct pcie_device *dev) * immediately when the downstream link goes down. */ if (pme_is_native(dev)) - pcie_disable_interrupt(get_service_data(dev)); + pcie_disable_interrupt(dev_get_drvdata(&dev->device)); } #ifdef CONFIG_PM_SLEEP @@ -286,7 +286,7 @@ static int pciehp_suspend(struct pcie_device *dev) static int pciehp_resume_noirq(struct pcie_device *dev) { - struct controller *ctrl = get_service_data(dev); + struct controller *ctrl = dev_get_drvdata(&dev->device); /* pci_restore_state() just wrote to the Slot Control register */ ctrl->cmd_started = jiffies; @@ -302,7 +302,7 @@ static int pciehp_resume_noirq(struct pcie_device *dev) static int pciehp_resume(struct pcie_device *dev) { - struct controller *ctrl = get_service_data(dev); + struct controller *ctrl = dev_get_drvdata(&dev->device); if (pme_is_native(dev)) pcie_enable_interrupt(ctrl); @@ -320,7 +320,7 @@ static int pciehp_runtime_suspend(struct pcie_device *dev) static int pciehp_runtime_resume(struct pcie_device *dev) { - struct controller *ctrl = get_service_data(dev); + struct controller *ctrl = dev_get_drvdata(&dev->device); /* pci_restore_state() just wrote to the Slot Control register */ ctrl->cmd_started = jiffies; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index b1d0a1b3917d..3e12ec4a2671 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -871,7 +871,7 @@ void pcie_disable_interrupt(struct controller *ctrl) */ int pciehp_slot_reset(struct pcie_device *dev) { - struct controller *ctrl = get_service_data(dev); + struct controller *ctrl = dev_get_drvdata(&dev->device); if (ctrl->state != ON_STATE) return 0; diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index ac6293c24976..189b50e4bc8d 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1328,7 +1328,7 @@ static void aer_isr_one_error(struct aer_rpc *rpc, static irqreturn_t aer_isr(int irq, void *context) { struct pcie_device *dev = (struct pcie_device *)context; - struct aer_rpc *rpc = get_service_data(dev); + struct aer_rpc *rpc = dev_get_drvdata(&dev->device); struct aer_err_source e_src; if (kfifo_is_empty(&rpc->aer_fifo)) @@ -1349,7 +1349,7 @@ static irqreturn_t aer_isr(int irq, void *context) static irqreturn_t aer_irq(int irq, void *context) { struct pcie_device *pdev = (struct pcie_device *)context; - struct aer_rpc *rpc = get_service_data(pdev); + struct aer_rpc *rpc = dev_get_drvdata(&pdev->device); struct pci_dev *rp = rpc->rpd; int aer = rp->aer_cap; struct aer_err_source e_src = {}; @@ -1448,7 +1448,7 @@ static void aer_disable_rootport(struct aer_rpc *rpc) */ static void aer_remove(struct pcie_device *dev) { - struct aer_rpc *rpc = get_service_data(dev); + struct aer_rpc *rpc = dev_get_drvdata(&dev->device); aer_disable_rootport(rpc); } @@ -1482,7 +1482,7 @@ static int aer_probe(struct pcie_device *dev) rpc->rpd = port; INIT_KFIFO(rpc->aer_fifo); - set_service_data(dev, rpc); + dev_set_drvdata(&dev->device, rpc); status = devm_request_threaded_irq(device, dev->irq, aer_irq, aer_isr, IRQF_SHARED, "aerdrv", dev); diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index a2daebd9806c..2e23f131ed3e 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -265,13 +265,14 @@ static void pcie_pme_work_fn(struct work_struct *work) */ static irqreturn_t pcie_pme_irq(int irq, void *context) { + struct pcie_device *srv = context; struct pci_dev *port; struct pcie_pme_service_data *data; u32 rtsta; unsigned long flags; - port = ((struct pcie_device *)context)->port; - data = get_service_data((struct pcie_device *)context); + port = srv->port; + data = dev_get_drvdata(&srv->device); spin_lock_irqsave(&data->lock, flags); pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); @@ -342,7 +343,7 @@ static int pcie_pme_probe(struct pcie_device *srv) spin_lock_init(&data->lock); INIT_WORK(&data->work, pcie_pme_work_fn); data->srv = srv; - set_service_data(srv, data); + dev_set_drvdata(&srv->device, data); pcie_pme_interrupt_enable(port, false); pcie_clear_root_pme_status(port); @@ -391,7 +392,7 @@ static void pcie_pme_disable_interrupt(struct pci_dev *port, */ static int pcie_pme_suspend(struct pcie_device *srv) { - struct pcie_pme_service_data *data = get_service_data(srv); + struct pcie_pme_service_data *data = dev_get_drvdata(&srv->device); struct pci_dev *port = srv->port; bool wakeup; int ret; @@ -422,7 +423,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) */ static int pcie_pme_resume(struct pcie_device *srv) { - struct pcie_pme_service_data *data = get_service_data(srv); + struct pcie_pme_service_data *data = dev_get_drvdata(&srv->device); spin_lock_irq(&data->lock); if (data->noirq) { @@ -445,7 +446,7 @@ static int pcie_pme_resume(struct pcie_device *srv) */ static void pcie_pme_remove(struct pcie_device *srv) { - struct pcie_pme_service_data *data = get_service_data(srv); + struct pcie_pme_service_data *data = dev_get_drvdata(&srv->device); pcie_pme_disable_interrupt(srv->port, data); free_irq(srv->irq, srv); diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 12c89ea0313b..344b796a8579 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -58,21 +58,10 @@ struct pcie_device { int irq; /* Service IRQ/MSI/MSI-X Vector */ struct pci_dev *port; /* Root/Upstream/Downstream Port */ u32 service; /* Port service this device represents */ - void *priv_data; /* Service Private Data */ struct device device; /* Generic Device Interface */ }; #define to_pcie_device(d) container_of(d, struct pcie_device, device) -static inline void set_service_data(struct pcie_device *dev, void *data) -{ - dev->priv_data = data; -} - -static inline void *get_service_data(struct pcie_device *dev) -{ - return dev->priv_data; -} - struct pcie_port_service_driver { const char *name; int (*probe)(struct pcie_device *dev); From patchwork Wed May 29 16:40:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679270 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54B8F1C6B2; Wed, 29 May 2024 16:42:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000929; cv=none; b=KqcT9UQnf/8/0KrYhde8M9YE+BZ+a45OrmCV3cj5iEJgFi6svY7dD+3jbYALKxvLoXdi+1bZJdpWkHhwaTq+XOslWXBPEUie/Jq+wWGakQdGF2P6ig0WinYmO92OOISHNiy+hoXb83/JM6OTjBG+psWCS46uONM2j99B/kLATNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000929; c=relaxed/simple; bh=SG00POVN9C9ZbN4FA2bmaSh5sb1jAehMGHbe44RBbWw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XCXvSmbXJYEtzgFNAXQQQIb1Vfyv7A8d8X90REpkS0Go+xdIDgCP8zssr0qRso0Dvp5RJXtYTorN1obPvIcHqW0QUmmFTxgSPyCalsF8C8F+Zvt/7L4OYpZLSmma0iovY+OsW86xfuMqCBYjPwdUCoQgMUp+jJdaUYLQHkfUTDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.31]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFWN1n8bz67NNV; Thu, 30 May 2024 00:41:04 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id 29FD51400CA; Thu, 30 May 2024 00:42:05 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:42:04 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 2/9] pci: portdrv: Drop driver field for port type. Date: Wed, 29 May 2024 17:40:56 +0100 Message-ID: <20240529164103.31671-3-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) Always set to PCIE_ANY_PORT so no information. Drop PCIE_ANY_PORT definition as well as not used for anything else. Signed-off-by: Jonathan Cameron --- drivers/pci/hotplug/pciehp_core.c | 1 - drivers/pci/pci-driver.c | 4 ---- drivers/pci/pcie/aer.c | 1 - drivers/pci/pcie/dpc.c | 1 - drivers/pci/pcie/pme.c | 1 - drivers/pci/pcie/portdrv.h | 4 ---- 6 files changed, 12 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 8e8d88f0d501..be666771c6e3 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -337,7 +337,6 @@ static int pciehp_runtime_resume(struct pcie_device *dev) static struct pcie_port_service_driver hpdriver_portdrv = { .name = "pciehp", - .port_type = PCIE_ANY_PORT, .service = PCIE_PORT_SERVICE_HP, .probe = pciehp_probe, diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index af2996d0d17f..cd84c0cb80a4 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1702,10 +1702,6 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) if (driver->service != pciedev->service) return 0; - if (driver->port_type != PCIE_ANY_PORT && - driver->port_type != pci_pcie_type(pciedev->port)) - return 0; - return 1; } diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 189b50e4bc8d..e07c5bf71372 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1557,7 +1557,6 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) static struct pcie_port_service_driver aerdriver = { .name = "aer", - .port_type = PCIE_ANY_PORT, .service = PCIE_PORT_SERVICE_AER, .probe = aer_probe, diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index a668820696dc..130e00bfd1e1 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -462,7 +462,6 @@ static void dpc_remove(struct pcie_device *dev) static struct pcie_port_service_driver dpcdriver = { .name = "dpc", - .port_type = PCIE_ANY_PORT, .service = PCIE_PORT_SERVICE_DPC, .probe = dpc_probe, .remove = dpc_remove, diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 2e23f131ed3e..dc6b1f5fbe48 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -456,7 +456,6 @@ static void pcie_pme_remove(struct pcie_device *srv) static struct pcie_port_service_driver pcie_pme_driver = { .name = "pcie_pme", - .port_type = PCIE_ANY_PORT, .service = PCIE_PORT_SERVICE_PME, .probe = pcie_pme_probe, diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 344b796a8579..ea320fb026e6 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -51,9 +51,6 @@ int pcie_dpc_init(void); static inline int pcie_dpc_init(void) { return 0; } #endif -/* Port Type */ -#define PCIE_ANY_PORT (~0) - struct pcie_device { int irq; /* Service IRQ/MSI/MSI-X Vector */ struct pci_dev *port; /* Root/Upstream/Downstream Port */ @@ -74,7 +71,6 @@ struct pcie_port_service_driver { int (*slot_reset)(struct pcie_device *dev); - int port_type; /* Type of the port this driver can handle */ u32 service; /* Port service this device represents */ struct device_driver driver; From patchwork Wed May 29 16:40:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679271 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68A7E1C6B2; Wed, 29 May 2024 16:42:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000960; cv=none; b=FlRUk455UI5hNw+fVj/7UJhTLxVkbCCWafYB7/HxvkG4xkGgqi7Rihd/J3quOZwmakFCAOFsIYLZTsRb0LEv0ZBNswu2SXb8ZpUe+tDDu9u5P7fwARnBHMlKPoPvp2aZ9XoaAUPW/tk9VQ3jTw8X1ug3VvPTmeXtnCELWeyacjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000960; c=relaxed/simple; bh=RTHc/HEBgmVVjWIG8E4iWxyoIyhLqsEP/2is1gPmRGA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VDI0lRONmUG+OiKmvHJ8uzcY8zJbbREPGejEggibhNyB/ZBunWCM0M700q9QhrUYSTjEyT9kBQ4J4xPL2bO7M7V88NTL7YgZTsPtXc1zCTuumODrrEUPGlvGcoAYI6JeyT9nBLPNCXX1Bj+v2+FjKidcammcxBpYeY8GsZELiBo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.231]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFSX3L1Bz6JBHF; Thu, 30 May 2024 00:38:36 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id F15DE140CB1; Thu, 30 May 2024 00:42:35 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:42:35 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= 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 Message-ID: <20240529164103.31671-4-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) 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 --- 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, From patchwork Wed May 29 16:40:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679272 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D3D8181BA7; Wed, 29 May 2024 16:43:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000991; cv=none; b=WLIPigFmBoycTRocMn6ir0tFH8NSHitdwkvq3pNCC+76lJ+ab0KikPUQVGNHJR3YNxFBHXv4EkATA0FCwsi2UCNKYQifu3NQMaJlOdw0aritR75uGJlt55frLYBpT9b8WSJ9l0WULVlldNW55xnlNB3orydZNCnqMJPcwsq+JDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717000991; c=relaxed/simple; bh=Pg7dtSeZRbGiEEo/2LMdLmfJSSsQRJspheIXnTlwNLA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P6eXQPEXJdBOfLpZljVtf7XJxAQtM5lhPzD4YFVinjEw6a7Uc+pBlssQnG5rJ+yiPmChyXm0GD727YmPnBPU4gPAdS6o7UeFX0uGMFXOYNPC0hl98dhOllyqov/IWdiKIKnWzYCdzuFk758ncNiKiBDQdaeBgAk2IdgYOzjDPUg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.31]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFSr5GLnz6K5Xn; Thu, 30 May 2024 00:38:52 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id E762B1400CA; Thu, 30 May 2024 00:43:06 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:43:06 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 4/9] auxiliary_bus: expose auxiliary_bus_type Date: Wed, 29 May 2024 17:40:58 +0100 Message-ID: <20240529164103.31671-5-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) In the PCI portdrv shutdown we need to find and remove any auxiliary devices before pci_free_irq_vectors() is called. Allowing the bus type to be accessed means we can just use the device types on the auxbus to do this without having to keep yet another list of what is registered. Signed-off-by: Jonathan Cameron --- drivers/base/auxiliary.c | 2 +- include/linux/auxiliary_bus.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index d3a2c40c2f12..5bde62918dad 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -244,7 +244,7 @@ static void auxiliary_bus_shutdown(struct device *dev) auxdrv->shutdown(auxdev); } -static const struct bus_type auxiliary_bus_type = { +const struct bus_type auxiliary_bus_type = { .name = "auxiliary", .probe = auxiliary_bus_probe, .remove = auxiliary_bus_remove, diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h index de21d9d24a95..465b5ac2862e 100644 --- a/include/linux/auxiliary_bus.h +++ b/include/linux/auxiliary_bus.h @@ -248,4 +248,5 @@ struct auxiliary_device *auxiliary_find_device(struct device *start, const void *data, int (*match)(struct device *dev, const void *data)); +extern const struct bus_type auxiliary_bus_type; #endif /* _AUXILIARY_BUS_H_ */ From patchwork Wed May 29 16:40:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679273 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 782E2181BA7; Wed, 29 May 2024 16:43:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001022; cv=none; b=eWyeNzUkL7+spmyr6UMDtTb7mbHO+tdmJJrCBvH0ALeqaGdNbFokDncUWw66UGmiq0947dSyicEHcaSpq8TEjcTmMi1t/ozY0c06a65j0Hvb2KOX2yEPP2nmo/1fBygtKlpimtkcVIg6G5aVZ2hWDaZm7Ne1no7zEYWgFYk3GnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001022; c=relaxed/simple; bh=jIeGdYFx30PYF6XG4P8ur737aTM5Kur2xUWLRLVoQ84=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ao5fAAfuyvlL4B0lRPiOT1oUOhhxaXxgCRh/SCGerWSVgLxqeDmjg2W1uWYC2/RNBJomNTgJtj3XnsQRoo+iGYxUgCdKXQQAevc9vhICKpSFSAzhHhwFQGCtuKsBJCLbzZ+jFkktcaZq7ObqyhLgJbu8OjesDNHzlmkgnbIwk1Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.216]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFY85w1Vz6K9Jr; Thu, 30 May 2024 00:42:36 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id B79EF140CF4; Thu, 30 May 2024 00:43:37 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:43:37 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 5/9] pci: pcie: portdrv: Add a auxiliary_bus Date: Wed, 29 May 2024 17:40:59 +0100 Message-ID: <20240529164103.31671-6-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) Nothing registered on this bus yet, but it will provide an extensible means to register child devices that may use drivers that are present at portdrv probe time, or due to other dependencies only become present later. The existing pci_express sysfs bus is not suitable for cases like the CXL PMU where there may be 0-N independent instances on each port. Note that the portdrv must know how to query any msi/msix interrupt numbers so that it can enable sufficient vectors before the auxiliary devices are added that make use fo these interrupts. Signed-off-by: Jonathan Cameron --- drivers/pci/pcie/Kconfig | 1 + drivers/pci/pcie/portdrv.c | 118 +++++++++++++++++++++++++++++++++++-- drivers/pci/pcie/portdrv.h | 13 ++++ 3 files changed, 127 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 17919b99fa66..840f87eb4b28 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -4,6 +4,7 @@ # config PCIEPORTBUS bool "PCI Express Port Bus support" + select AUXILIARY_BUS default y if USB4 help This enables PCI Express Port Bus support. Users can then enable diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 7f053bab7745..6314da76de9f 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -6,12 +6,14 @@ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) */ +#include #include #include #include #include #include #include +#include #include #include #include @@ -208,6 +210,7 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask) /** * get_port_device_capability - discover capabilities of a PCI Express port * @dev: PCI Express port to examine + * @aux_dev_list: Auxiliary devices to create after interrupt vectors resoved. * * The capabilities are read from the port's PCI Express configuration registers * as described in PCI Express Base Specification 1.0a sections 7.8.2, 7.8.9 and @@ -215,7 +218,8 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask) * * Return value: Bitmask of discovered port capabilities */ -static int get_port_device_capability(struct pci_dev *dev) +static int get_port_device_capability(struct pci_dev *dev, + struct list_head *aux_dev_list) { struct pci_host_bridge *host = pci_find_host_bridge(dev->bus); int services = 0; @@ -317,6 +321,20 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) return 0; } +static void pcie_port_auxdev_delete(void *p_ad) +{ + struct pcie_port_aux_dev *pcie_adev = p_ad; + + auxiliary_device_delete(&pcie_adev->adev); +} + +static void pcie_port_auxdev_uninit(void *p_ad) +{ + struct pcie_port_aux_dev *pcie_adev = p_ad; + + auxiliary_device_uninit(&pcie_adev->adev); +} + static int remove_iter(struct device *dev, void *data) { if (dev->bus == &pcie_port_bus_type) @@ -324,6 +342,15 @@ static int remove_iter(struct device *dev, void *data) return 0; } +static int aux_remove_iter(struct device *dev, void *data) +{ + if (dev->bus == &auxiliary_bus_type) { + auxiliary_device_delete(to_auxiliary_dev(dev)); + auxiliary_device_uninit(to_auxiliary_dev(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 @@ -338,6 +365,20 @@ static void pcie_port_device_remove(void *d) device_for_each_child(&dev->dev, NULL, remove_iter); } +/* Should be called when device created to ensure resource cleanup */ +int devm_pcie_port_aux_dev_init(struct device *dev, + struct pcie_port_aux_dev *pcie_adev) +{ + int status; + + status = auxiliary_device_init(&pcie_adev->adev); + if (status) + return status; + + return devm_add_action_or_reset(dev, pcie_port_auxdev_uninit, + pcie_adev); +} + /** * pcie_port_device_register - register PCI Express port * @dev: PCI Express port to register @@ -349,6 +390,8 @@ static int pcie_port_device_register(struct pci_dev *dev) { int status, capabilities, i, nr_service; int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; + struct pcie_port_aux_dev *pcie_adev; + LIST_HEAD(aux_dev_list); /* Enable PCI Express port device */ status = pcim_enable_device(dev); @@ -356,8 +399,8 @@ static int pcie_port_device_register(struct pci_dev *dev) return status; /* Get and check PCI Express port services */ - capabilities = get_port_device_capability(dev); - if (!capabilities) + capabilities = get_port_device_capability(dev, &aux_dev_list); + if (!capabilities && list_empty(&aux_dev_list)) return 0; pci_set_master(dev); @@ -385,6 +428,33 @@ static int pcie_port_device_register(struct pci_dev *dev) if (!pcie_device_init(dev, service, irqs[i])) nr_service++; } + + /* + * Register auxiliary bus device found earlier. + * This is done after PCI irq vectors have been requested + * so the indidividual drivers may use their IRQs immediately. + */ + list_for_each_entry(pcie_adev, &aux_dev_list, node) { + status = auxiliary_device_add(&pcie_adev->adev); + if (status) + return status; + + status = devm_add_action_or_reset(&dev->dev, + pcie_port_auxdev_delete, + pcie_adev); + if (status) + return status; + + if (pcie_adev->optional) { + nr_service++; /* Need to register even if no one is ready yet */ + } else { + device_lock(&pcie_adev->adev.dev); + if (pcie_adev->adev.dev.driver) + nr_service++; + device_unlock(&pcie_adev->adev.dev); + } + } + if (!nr_service) return -ENODEV; /* Why carry on if nothing supported? */ @@ -408,6 +478,31 @@ static int pcie_port_device_iter(struct device *dev, void *data) return 0; } +static int pcie_port_adev_resume_iter(struct device *dev, void *data) +{ + if ((dev->bus == &auxiliary_bus_type) && dev->driver) { + struct auxiliary_driver *adrv = to_auxiliary_drv(dev->driver); + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + if (adrv->resume) + adrv->resume(adev); + } + return 0; +} + +static int pcie_port_adev_suspend_iter(struct device *dev, void *data) +{ + if ((dev->bus == &auxiliary_bus_type) && dev->driver) { + struct auxiliary_driver *adrv = to_auxiliary_drv(dev->driver); + struct auxiliary_device *adev = to_auxiliary_dev(dev); + pm_message_t pm = {}; + + if (adrv->suspend) + adrv->suspend(adev, pm); + } + return 0; +} + #ifdef CONFIG_PM /** * pcie_port_device_suspend - suspend port services associated with a PCIe port @@ -415,8 +510,13 @@ static int pcie_port_device_iter(struct device *dev, void *data) */ static int pcie_port_device_suspend(struct device *dev) { + int ret; size_t off = offsetof(struct pcie_port_service_driver, suspend); - return device_for_each_child(dev, &off, pcie_port_device_iter); + ret = device_for_each_child(dev, &off, pcie_port_device_iter); + if (ret) + return ret; + + return device_for_each_child(dev, NULL, pcie_port_adev_suspend_iter); } static int pcie_port_device_resume_noirq(struct device *dev) @@ -431,7 +531,14 @@ static int pcie_port_device_resume_noirq(struct device *dev) */ static int pcie_port_device_resume(struct device *dev) { - size_t off = offsetof(struct pcie_port_service_driver, resume); + int ret; + size_t off; + + ret = device_for_each_child(dev, NULL, pcie_port_adev_resume_iter); + if (ret) + return ret; + + off = offsetof(struct pcie_port_service_driver, resume); return device_for_each_child(dev, &off, pcie_port_device_iter); } @@ -732,6 +839,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, static void pcie_portdrv_shutdown(struct pci_dev *dev) { pcie_portdrv_runtime_pm_disable(dev); + device_for_each_child(&dev->dev, NULL, aux_remove_iter); pcie_port_device_remove(dev); pci_free_irq_vectors(dev); } diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index ea320fb026e6..243a6c9e9bf1 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -9,6 +9,7 @@ #ifndef _PORTDRV_H_ #define _PORTDRV_H_ +#include #include /* Service Type */ @@ -51,6 +52,18 @@ int pcie_dpc_init(void); static inline int pcie_dpc_init(void) { return 0; } #endif +struct pcie_port_aux_dev { + struct auxiliary_device adev; + u64 addr; + struct list_head node; + bool optional; /* Drivers may not yet be available */ +}; +#define to_pcie_port_aux_dev(adev)\ + container_of(adev, struct pcie_port_aux_dev, adev) + +int devm_pcie_port_aux_dev_init(struct device *dev, + struct pcie_port_aux_dev *pcie_adev); + struct pcie_device { int irq; /* Service IRQ/MSI/MSI-X Vector */ struct pci_dev *port; /* Root/Upstream/Downstream Port */ From patchwork Wed May 29 16:41:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679274 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8E0E1836CE; Wed, 29 May 2024 16:44:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001052; cv=none; b=N9IbuiKbP51yEQIRGyCSAerQ+WS5p+d+AGGBQ+ePkBHQUhbnOMjoeJtN1oFGGqBVQh7l67EekMOmEFrUkePKuo1FFtGrpdXWxVdKwWL9pBdkUABX2zXOz0HcYpJ11vzlAVhkP5lX9ebq9FWdtWGQvlGniiKjTyMeSx95o5yu/S4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001052; c=relaxed/simple; bh=wrm5GeYkst4lwVJAHdOczrKLGYE1ebDvPZ1eFKGYzWY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qvfN/oAVdT+IZ+xvhXwdVnCmhnsnM8EUtT7gRzha8a1ul/XL0OcV3emu8mmVg98062OiQlewT6wQcJgUfbUw9OARIw1oHTOAKKXq3t4lVajI0/uYoYnDqi6SyFU0rDb/IdyqLj0GxqbbrsFM/dkwkg2tgvbAeFuTaeYZzLDbjAA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.31]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFV24Z0Rz6K5sQ; Thu, 30 May 2024 00:39:54 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id D0A97140B2A; Thu, 30 May 2024 00:44:08 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:44:08 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 6/9] cxl: Move CPMU register definitions to header Date: Wed, 29 May 2024 17:41:00 +0100 Message-ID: <20240529164103.31671-7-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) To do probing for maximum interrupt, the PCIe port driver needs to access a few of these. Keep them all together by moving htem all to driver/cxl/pmu.h. Signed-off-by: Jonathan Cameron --- drivers/cxl/pmu.h | 54 ++++++++++++++++++++++++++++++++++++++++++ drivers/perf/cxl_pmu.c | 54 ------------------------------------------ 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/cxl/pmu.h b/drivers/cxl/pmu.h index b1e9bcd9f28c..a69ac6facad6 100644 --- a/drivers/cxl/pmu.h +++ b/drivers/cxl/pmu.h @@ -25,4 +25,58 @@ struct cxl_pmu_regs; int devm_cxl_pmu_add(struct device *parent, struct cxl_pmu_regs *regs, int assoc_id, int idx, enum cxl_pmu_type type); +#define CXL_PMU_CAP_REG 0x0 +#define CXL_PMU_CAP_NUM_COUNTERS_MSK GENMASK_ULL(5, 0) +#define CXL_PMU_CAP_COUNTER_WIDTH_MSK GENMASK_ULL(15, 8) +#define CXL_PMU_CAP_NUM_EVN_CAP_REG_SUP_MSK GENMASK_ULL(24, 20) +#define CXL_PMU_CAP_FILTERS_SUP_MSK GENMASK_ULL(39, 32) +#define CXL_PMU_FILTER_HDM BIT(0) +#define CXL_PMU_FILTER_CHAN_RANK_BANK BIT(1) +#define CXL_PMU_CAP_MSI_N_MSK GENMASK_ULL(47, 44) +#define CXL_PMU_CAP_WRITEABLE_WHEN_FROZEN BIT_ULL(48) +#define CXL_PMU_CAP_FREEZE BIT_ULL(49) +#define CXL_PMU_CAP_INT BIT_ULL(50) +#define CXL_PMU_CAP_VERSION_MSK GENMASK_ULL(63, 60) + +#define CXL_PMU_OVERFLOW_REG 0x10 +#define CXL_PMU_FREEZE_REG 0x18 +#define CXL_PMU_EVENT_CAP_REG(n) (0x100 + 8 * (n)) +#define CXL_PMU_EVENT_CAP_SUPPORTED_EVENTS_MSK GENMASK_ULL(31, 0) +#define CXL_PMU_EVENT_CAP_GROUP_ID_MSK GENMASK_ULL(47, 32) +#define CXL_PMU_EVENT_CAP_VENDOR_ID_MSK GENMASK_ULL(63, 48) + +#define CXL_PMU_COUNTER_CFG_REG(n) (0x200 + 8 * (n)) +#define CXL_PMU_COUNTER_CFG_TYPE_MSK GENMASK_ULL(1, 0) +#define CXL_PMU_COUNTER_CFG_TYPE_FREE_RUN 0 +#define CXL_PMU_COUNTER_CFG_TYPE_FIXED_FUN 1 +#define CXL_PMU_COUNTER_CFG_TYPE_CONFIGURABLE 2 +#define CXL_PMU_COUNTER_CFG_ENABLE BIT_ULL(8) +#define CXL_PMU_COUNTER_CFG_INT_ON_OVRFLW BIT_ULL(9) +#define CXL_PMU_COUNTER_CFG_FREEZE_ON_OVRFLW BIT_ULL(10) +#define CXL_PMU_COUNTER_CFG_EDGE BIT_ULL(11) +#define CXL_PMU_COUNTER_CFG_INVERT BIT_ULL(12) +#define CXL_PMU_COUNTER_CFG_THRESHOLD_MSK GENMASK_ULL(23, 16) +#define CXL_PMU_COUNTER_CFG_EVENTS_MSK GENMASK_ULL(55, 24) +#define CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK GENMASK_ULL(63, 59) + +#define CXL_PMU_FILTER_CFG_REG(n, f) (0x400 + 4 * ((f) + (n) * 8)) +#define CXL_PMU_FILTER_CFG_VALUE_MSK GENMASK(31, 0) + +#define CXL_PMU_COUNTER_REG(n) (0xc00 + 8 * (n)) + +/* CXL rev 3.0 Table 13-5 Events under CXL Vendor ID */ +#define CXL_PMU_GID_CLOCK_TICKS 0x00 +#define CXL_PMU_GID_D2H_REQ 0x0010 +#define CXL_PMU_GID_D2H_RSP 0x0011 +#define CXL_PMU_GID_H2D_REQ 0x0012 +#define CXL_PMU_GID_H2D_RSP 0x0013 +#define CXL_PMU_GID_CACHE_DATA 0x0014 +#define CXL_PMU_GID_M2S_REQ 0x0020 +#define CXL_PMU_GID_M2S_RWD 0x0021 +#define CXL_PMU_GID_M2S_BIRSP 0x0022 +#define CXL_PMU_GID_S2M_BISNP 0x0023 +#define CXL_PMU_GID_S2M_NDR 0x0024 +#define CXL_PMU_GID_S2M_DRS 0x0025 +#define CXL_PMU_GID_DDR 0x8000 + #endif diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c index 1f93a66eff5b..65a8437ee236 100644 --- a/drivers/perf/cxl_pmu.c +++ b/drivers/perf/cxl_pmu.c @@ -24,60 +24,6 @@ #include "../cxl/cxl.h" #include "../cxl/pmu.h" -#define CXL_PMU_CAP_REG 0x0 -#define CXL_PMU_CAP_NUM_COUNTERS_MSK GENMASK_ULL(5, 0) -#define CXL_PMU_CAP_COUNTER_WIDTH_MSK GENMASK_ULL(15, 8) -#define CXL_PMU_CAP_NUM_EVN_CAP_REG_SUP_MSK GENMASK_ULL(24, 20) -#define CXL_PMU_CAP_FILTERS_SUP_MSK GENMASK_ULL(39, 32) -#define CXL_PMU_FILTER_HDM BIT(0) -#define CXL_PMU_FILTER_CHAN_RANK_BANK BIT(1) -#define CXL_PMU_CAP_MSI_N_MSK GENMASK_ULL(47, 44) -#define CXL_PMU_CAP_WRITEABLE_WHEN_FROZEN BIT_ULL(48) -#define CXL_PMU_CAP_FREEZE BIT_ULL(49) -#define CXL_PMU_CAP_INT BIT_ULL(50) -#define CXL_PMU_CAP_VERSION_MSK GENMASK_ULL(63, 60) - -#define CXL_PMU_OVERFLOW_REG 0x10 -#define CXL_PMU_FREEZE_REG 0x18 -#define CXL_PMU_EVENT_CAP_REG(n) (0x100 + 8 * (n)) -#define CXL_PMU_EVENT_CAP_SUPPORTED_EVENTS_MSK GENMASK_ULL(31, 0) -#define CXL_PMU_EVENT_CAP_GROUP_ID_MSK GENMASK_ULL(47, 32) -#define CXL_PMU_EVENT_CAP_VENDOR_ID_MSK GENMASK_ULL(63, 48) - -#define CXL_PMU_COUNTER_CFG_REG(n) (0x200 + 8 * (n)) -#define CXL_PMU_COUNTER_CFG_TYPE_MSK GENMASK_ULL(1, 0) -#define CXL_PMU_COUNTER_CFG_TYPE_FREE_RUN 0 -#define CXL_PMU_COUNTER_CFG_TYPE_FIXED_FUN 1 -#define CXL_PMU_COUNTER_CFG_TYPE_CONFIGURABLE 2 -#define CXL_PMU_COUNTER_CFG_ENABLE BIT_ULL(8) -#define CXL_PMU_COUNTER_CFG_INT_ON_OVRFLW BIT_ULL(9) -#define CXL_PMU_COUNTER_CFG_FREEZE_ON_OVRFLW BIT_ULL(10) -#define CXL_PMU_COUNTER_CFG_EDGE BIT_ULL(11) -#define CXL_PMU_COUNTER_CFG_INVERT BIT_ULL(12) -#define CXL_PMU_COUNTER_CFG_THRESHOLD_MSK GENMASK_ULL(23, 16) -#define CXL_PMU_COUNTER_CFG_EVENTS_MSK GENMASK_ULL(55, 24) -#define CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK GENMASK_ULL(63, 59) - -#define CXL_PMU_FILTER_CFG_REG(n, f) (0x400 + 4 * ((f) + (n) * 8)) -#define CXL_PMU_FILTER_CFG_VALUE_MSK GENMASK(31, 0) - -#define CXL_PMU_COUNTER_REG(n) (0xc00 + 8 * (n)) - -/* CXL rev 3.0 Table 13-5 Events under CXL Vendor ID */ -#define CXL_PMU_GID_CLOCK_TICKS 0x00 -#define CXL_PMU_GID_D2H_REQ 0x0010 -#define CXL_PMU_GID_D2H_RSP 0x0011 -#define CXL_PMU_GID_H2D_REQ 0x0012 -#define CXL_PMU_GID_H2D_RSP 0x0013 -#define CXL_PMU_GID_CACHE_DATA 0x0014 -#define CXL_PMU_GID_M2S_REQ 0x0020 -#define CXL_PMU_GID_M2S_RWD 0x0021 -#define CXL_PMU_GID_M2S_BIRSP 0x0022 -#define CXL_PMU_GID_S2M_BISNP 0x0023 -#define CXL_PMU_GID_S2M_NDR 0x0024 -#define CXL_PMU_GID_S2M_DRS 0x0025 -#define CXL_PMU_GID_DDR 0x8000 - static int cxl_pmu_cpuhp_state_num; struct cxl_pmu_ev_cap { From patchwork Wed May 29 16:41:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679275 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA020181BA7; Wed, 29 May 2024 16:44:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001083; cv=none; b=WhgcEEfF1Jqo+XnuvuP8HKmC9pjJyldKrNxs0ladn4cgS4n8kTkpjgv0ByiXilV1+l37JLkFpwN83+3s0hyOPNcAzDCmc+VYI33Aok4By2K5wjthEd9QGFZYZfLwLPoiEY/qc/vKJnHw/plazU0l8KUGxMJm5BwIogronqpnyqg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001083; c=relaxed/simple; bh=leFT2CK5MV9zoLorRvAhV9bHUS93Y8WwaVWkNr6Kq+Q=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pHIDCJCkqkg3rV462vfi6lhZfCzG6it4kWyyf2w106ZpC7TZh+l3mbQoZEjNEkSXuo6ps6wiOsmsL6bOsy78uDh0k3SohQxUQS1kxKTfCWsIwlvgexkYVEWJMA4h8MpY5N5OxguXanW//vTqZIbCpJPV6R8lzp/scrFBFE5MTmk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.231]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFVw2SKpz6JBHx; Thu, 30 May 2024 00:40:40 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id D0DA1140B33; Thu, 30 May 2024 00:44:39 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:44:39 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 7/9] pci: pcie/cxl: Register an auxiliary device for each CPMU instance Date: Wed, 29 May 2024 17:41:01 +0100 Message-ID: <20240529164103.31671-8-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) As CXL PMU instances can be found in root and switch ports and they want to use an interrupt they must be hung of the portdrv instance. Use the new auxiliary bus to do this. Signed-off-by: Jonathan Cameron --- drivers/pci/pcie/Kconfig | 9 +++ drivers/pci/pcie/Makefile | 1 + drivers/pci/pcie/cxlpmu.c | 129 +++++++++++++++++++++++++++++++++++++ drivers/pci/pcie/portdrv.c | 11 +++- drivers/pci/pcie/portdrv.h | 11 ++++ 5 files changed, 160 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 840f87eb4b28..8f43fdec333d 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -156,3 +156,12 @@ 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. + +config PCIE_CXL_PMU + bool "CXL performance monitoring units on RP and Switch Ports" + depends on AUXILIARY_BUS + help + CXL root ports, switch upstream and switch downstream ports may + have one or more CXL PMU devices. Enable this option to look + for these and register a device to which the cxl_pmu driver + may bind \ No newline at end of file diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index 6461aa93fe76..037959bf91bb 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile @@ -13,3 +13,4 @@ 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_PCIE_CXL_PMU) += cxlpmu.o diff --git a/drivers/pci/pcie/cxlpmu.c b/drivers/pci/pcie/cxlpmu.c new file mode 100644 index 000000000000..7716663e567c --- /dev/null +++ b/drivers/pci/pcie/cxlpmu.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Discovery of presence of CXL PMU instances and the maximum irqnum. + * Registers a auxiliary_device to which a driver can bind after the + * CXL bus is available and new devices can be added to ti. + */ +#include +#include +#include +#include +#include + +#include "portdrv.h" +#include "../../cxl/cxl.h" +#include "../../cxl/cxlpci.h" +#include "../../cxl/pmu.h" + +static DEFINE_IDA(pcie_cxl_pmu_ida); +static void cpmu_adev_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + ida_free(&pcie_cxl_pmu_ida, adev->id); +} + +int pcie_cxl_pmu_get_irqs(struct pci_dev *dev, u32 *max_irq, + struct list_head *aux_dev_list) +{ + u32 regblocks, regloc_size; + int i, regloc, ret; + bool found = false; + + regloc = pci_find_dvsec_capability(dev, PCI_VENDOR_ID_CXL, + CXL_DVSEC_REG_LOCATOR); + if (!regloc) + return -ENODEV; + + pci_read_config_dword(dev, regloc + PCI_DVSEC_HEADER1, ®loc_size); + regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size); + + regloc += CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET; + regblocks = (regloc_size - CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET) / 8; + + for (i = 0; i < regblocks; i++, regloc += 8) { + u32 reg_lo, reg_hi; + u8 reg_type; + struct resource *res; + void __iomem *base; + u64 offset, val; + int bar; + + pci_read_config_dword(dev, regloc, ®_lo); + reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, + reg_lo); + if (reg_type != CXL_REGLOC_RBI_PMU) + continue; + + found = true; + /* Now we need to map just enough to get the irq */ + bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo); + pci_read_config_dword(dev, regloc + 4, ®_hi); + + offset = ((u64) reg_hi << 32) | + (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK); + if (offset > pci_resource_len(dev, bar)) { + pci_warn(dev, "CPMU BAR%d: %pr: too small\n", + bar, &dev->resource[bar]); + continue; + } + /* + * Map only the CPMU region because other parts are in control + * of the CXL port driver. + */ + res = request_mem_region(pci_resource_start(dev, bar) + offset, + CXL_PMU_REGMAP_SIZE, NULL); + if (!res) { + pci_err(dev, "CPMU: could not map\n"); + continue; + } + + base = ioremap(pci_resource_start(dev, bar) + offset, + CXL_PMU_REGMAP_SIZE); + if (!base) { + pci_err(dev, "CPU: ioremap fail\n"); + release_mem_region(res->start, resource_size(res)); + continue; + } + if (max_irq) { + val = readq(base + CXL_PMU_CAP_REG); + if (FIELD_GET(CXL_PMU_CAP_INT, val)) + *max_irq = max(*max_irq, + (u32)FIELD_GET(CXL_PMU_CAP_MSI_N_MSK, val)); + } + iounmap(base); + release_mem_region(res->start, resource_size(res)); + + if (aux_dev_list) { + struct pcie_port_aux_dev *pcie_adev; + int id; + + pcie_adev = devm_kzalloc(&dev->dev, sizeof(*pcie_adev), + GFP_KERNEL); + if (!pcie_adev) + return -ENOMEM; + + /* Cleanup handled by release after devm_pcie_port_aux_dev_init() */ + id = ida_alloc(&pcie_cxl_pmu_ida, GFP_KERNEL); + if (id < 0) + return -ENOMEM; + + pcie_adev->adev.name = "cpmu"; + pcie_adev->adev.id = id; + pcie_adev->adev.dev.parent = &dev->dev; + pcie_adev->adev.dev.release = cpmu_adev_release; + pcie_adev->addr = pci_resource_start(dev, bar) + offset; + pcie_adev->optional = true; + + ret = devm_pcie_port_aux_dev_init(&dev->dev, pcie_adev); + if (ret) + return ret; + + list_add(&pcie_adev->node, aux_dev_list); + } + } + if (!found) + return -ENODEV; + + return 0; +} diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 6314da76de9f..7274ee55a8c3 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -59,7 +59,7 @@ static void release_pcie_device(struct device *dev) static int pcie_message_numbers(struct pci_dev *dev, int mask, u32 *pme, u32 *aer, u32 *dpc) { - u32 nvec = 0, pos; + u32 nvec = 0, pos, max_cpmu = 0; u16 reg16; /* @@ -100,6 +100,9 @@ static int pcie_message_numbers(struct pci_dev *dev, int mask, } } + if (!pcie_cxl_pmu_get_irqs(dev, &max_cpmu, NULL)) + nvec = max(nvec, max_cpmu + 1); + return nvec; } @@ -278,6 +281,12 @@ static int get_port_device_capability(struct pci_dev *dev, services |= PCIE_PORT_SERVICE_BWNOTIF; } + if (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM || + pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM || + pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { + pcie_cxl_pmu_get_irqs(dev, NULL, aux_dev_list); + } + return services; } diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 243a6c9e9bf1..8fe6fad7b24a 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -52,6 +52,17 @@ int pcie_dpc_init(void); static inline int pcie_dpc_init(void) { return 0; } #endif +struct list_head; +#ifdef CONFIG_PCIE_CXL_PMU +int pcie_cxl_pmu_get_irqs(struct pci_dev *dev, u32 *max_irq, struct list_head *aux_dev_list); +#else +static inline int pcie_cxl_pmu_get_irqs(struct pci_dev *dev, u32 *max_irq, + struct list_head *aux_dev_list) +{ + return 0; +} +#endif + struct pcie_port_aux_dev { struct auxiliary_device adev; u64 addr; From patchwork Wed May 29 16:41:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679276 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99A9A15B129; Wed, 29 May 2024 16:45:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001114; cv=none; b=pPuTSCnpqK1Iyk9krQ/fqckbsZrZtLzgnkXe7n3ER3MmfzDIYmrXOhF/P4BkmO4NvXTU5bP59DsD89kEXrdR8YD4IVr7tOVJh2TAryNYAqKJOEpvkFA6BJ7h+JfkuG9ZWp1KB/C8FxaOlWOMyRPtqO+pBrQMjCNc9mZQMomS4x4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001114; c=relaxed/simple; bh=3Tb4ptQFGDmSvVIucXkDrYQAhOZWM+3uTZBilsMTdwQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ruoWbiyit7AcGSHkQIKFoowsVq2j+6NJO0ezTBSzcE7V4CyogPnimrtlRMFWrUB9wTGsHgVkyUkg6RxVJiqrlwHwAvzUqjvkdw2ijllNoSekI+wuToLCgNplqTxI/Jf6aKu0Tjd9+VSEGliXAotd5FUEDRK4DdvaKn4jm5CymhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.231]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFWW0Cg7z6J9mb; Thu, 30 May 2024 00:41:11 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id 87A8C140B33; Thu, 30 May 2024 00:45:10 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:45:10 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 8/9] perf: cxl: Make the cpmu driver also work with auxiliary_devices Date: Wed, 29 May 2024 17:41:02 +0100 Message-ID: <20240529164103.31671-9-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) CXL PMUs can be found both in endpoints (already supported) and in switch usp/dsp and root ports. Those ports are all handled by pcie/portdrv which will register auxiliary_devices rather than devices on the CXL bus. Make the CXL PMU driver register an auxiliary driver as well as the existing one for device on /sys/bus/cxl. There is no particular need for this driver to register early or to deal with particularly compact kernel configurations, so just make it dependent on both bus drivers. Signed-off-by: Jonathan Cameron --- drivers/perf/Kconfig | 1 + drivers/perf/cxl_pmu.c | 99 +++++++++++++++++++++++++++++++++++------- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig index 7526a9e714fa..4b7893a03a4c 100644 --- a/drivers/perf/Kconfig +++ b/drivers/perf/Kconfig @@ -255,6 +255,7 @@ source "drivers/perf/amlogic/Kconfig" config CXL_PMU tristate "CXL Performance Monitoring Unit" depends on CXL_BUS + depends on AUXILIARY_BUS help Support performance monitoring as defined in CXL rev 3.0 section 13.2: Performance Monitoring. CXL components may have diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c index 65a8437ee236..30b2aad556ad 100644 --- a/drivers/perf/cxl_pmu.c +++ b/drivers/perf/cxl_pmu.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include +#include "../pci/pcie/portdrv.h" #include "../cxl/cxlpci.h" #include "../cxl/cxl.h" #include "../cxl/pmu.h" @@ -753,13 +755,12 @@ static void cxl_pmu_cpuhp_remove(void *_info) cpuhp_state_remove_instance_nocalls(cxl_pmu_cpuhp_state_num, &info->node); } -static int cxl_pmu_probe(struct device *dev) +static int __cxl_pmu_probe(struct device *dev, const char *dev_name, + void __iomem *base) { - struct cxl_pmu *pmu = to_cxl_pmu(dev); struct pci_dev *pdev = to_pci_dev(dev->parent); struct cxl_pmu_info *info; char *irq_name; - char *dev_name; int rc, irq; info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); @@ -767,10 +768,10 @@ static int cxl_pmu_probe(struct device *dev) return -ENOMEM; dev_set_drvdata(dev, info); + INIT_LIST_HEAD(&info->event_caps_fixed); INIT_LIST_HEAD(&info->event_caps_configurable); - - info->base = pmu->base; + info->base = base; info->on_cpu = -1; rc = cxl_pmu_parse_caps(dev, info); @@ -782,15 +783,6 @@ static int cxl_pmu_probe(struct device *dev) if (!info->hw_events) return -ENOMEM; - switch (pmu->type) { - case CXL_PMU_MEMDEV: - dev_name = devm_kasprintf(dev, GFP_KERNEL, "cxl_pmu_mem%d.%d", - pmu->assoc_id, pmu->index); - break; - } - if (!dev_name) - return -ENOMEM; - info->pmu = (struct pmu) { .name = dev_name, .parent = dev, @@ -843,6 +835,60 @@ static int cxl_pmu_probe(struct device *dev) return rc; return 0; + +} + +static int cxl_pmu_port_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + + struct pcie_port_aux_dev *pcie_adev = to_pcie_port_aux_dev(adev); + struct device *parent = adev->dev.parent; + struct pci_dev *pdev = to_pci_dev(parent); + struct device *dev = &adev->dev; + char *dev_name; + void __iomem *base; + struct resource *res; + + /* + * Map only the CPMU region because other parts are in control + * of the CXL port driver. + */ + res = devm_request_mem_region(&adev->dev, pcie_adev->addr, + CXL_PMU_REGMAP_SIZE, NULL); + if (!res) { + pci_err(pdev, "CPMU: could not map\n"); + return -ENOMEM; + } + + base = devm_ioremap(&adev->dev, pcie_adev->addr, CXL_PMU_REGMAP_SIZE); + if (!base) { + pci_err(pdev, "CPU: ioremap fail\n"); + return -ENOMEM; + } + dev_name = devm_kasprintf(dev, GFP_KERNEL, "cxl_pmu_port%d", + adev->id); + if (!dev_name) + return -ENOMEM; + + return __cxl_pmu_probe(dev, dev_name, base); +} + +static int cxl_pmu_probe(struct device *dev) +{ + struct cxl_pmu *pmu = to_cxl_pmu(dev); + char *dev_name; + + switch (pmu->type) { + case CXL_PMU_MEMDEV: + dev_name = devm_kasprintf(dev, GFP_KERNEL, "cxl_pmu_mem%d.%d", + pmu->assoc_id, pmu->index); + break; + } + if (!dev_name) + return -ENOMEM; + + return __cxl_pmu_probe(dev, dev_name, pmu->base); } static struct cxl_driver cxl_pmu_driver = { @@ -851,6 +897,17 @@ static struct cxl_driver cxl_pmu_driver = { .id = CXL_DEVICE_PMU, }; +static const struct auxiliary_device_id cxl_port_pmu_ids[] = { + { .name = "pcieportdrv.cpmu" }, + { } +}; + +static struct auxiliary_driver cxl_port_pmu_driver = { + .name = "cxl_port_pmu", + .probe = cxl_pmu_port_probe, + .id_table = cxl_port_pmu_ids, +}; + static int cxl_pmu_online_cpu(unsigned int cpu, struct hlist_node *node) { struct cxl_pmu_info *info = hlist_entry_safe(node, struct cxl_pmu_info, node); @@ -907,13 +964,25 @@ static __init int cxl_pmu_init(void) rc = cxl_driver_register(&cxl_pmu_driver); if (rc) - cpuhp_remove_multi_state(cxl_pmu_cpuhp_state_num); + goto cleanup_hp; + + rc = auxiliary_driver_register(&cxl_port_pmu_driver); + if (rc) + goto unregister_cxl_driver; + + return 0; + +unregister_cxl_driver: + cxl_driver_unregister(&cxl_pmu_driver); +cleanup_hp: + cpuhp_remove_multi_state(cxl_pmu_cpuhp_state_num); return rc; } static __exit void cxl_pmu_exit(void) { + auxiliary_driver_unregister(&cxl_port_pmu_driver); cxl_driver_unregister(&cxl_pmu_driver); cpuhp_remove_multi_state(cxl_pmu_cpuhp_state_num); } From patchwork Wed May 29 16:41:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13679277 X-Patchwork-Delegate: bhelgaas@google.com Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C10042A96; Wed, 29 May 2024 16:45:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.176.79.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001145; cv=none; b=d6rh5Qhbir5pYkemMp6NFBelLWZ1xdG4594Ooh0iW4Ko6OCYZexvhzXohAPGWKeUwYF3Bcgf6Od6P9uo4jNqFDzFxKL/ieM9vZQQ2rPeYYllWhZ+OZjIZ96XRuIUFlQE/jggsT96Gc6B9pZgtEyCW3zg/h8D2/8jN0hUU9aJ4Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717001145; c=relaxed/simple; bh=4LwIbzkwgQpF6y04LHoBoQ42AbWEmnEEuHP5SFsAzU8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZtI44JSCsijWpGhdNDQ1V7wWKvCT/LGIHGa1GBHAuoKv8VENv54jqERqWMNC0sOG2AR9Cs4Ah8W/TmS8EB/lnc/K4LNqouBWoDLIMWFQFU71mYwjNfZbw3HhSWirtNOyWoR3cydis/DERdK9W/M5by7gpYzKSKNRGtftkC/Dn9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=185.176.79.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.18.186.231]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4VqFbX37Bgz67l0C; Thu, 30 May 2024 00:44:40 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id 594C314038F; Thu, 30 May 2024 00:45:41 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 29 May 2024 17:45:40 +0100 From: Jonathan Cameron To: Mahesh J Salgaonkar , Bjorn Helgaas , , CC: Davidlohr Bueso , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams , Will Deacon , Mark Rutland , Lorenzo Pieralisi , , , Kuppuswamy Sathyanarayanan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [RFC PATCH 9/9] pci: pcie: portdrv: aer: Switch to auxiliary_bus Date: Wed, 29 May 2024 17:41:03 +0100 Message-ID: <20240529164103.31671-10-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> References: <20240529164103.31671-1-Jonathan.Cameron@huawei.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To lhrpeml500005.china.huawei.com (7.191.163.240) Not sure if this is a good idea or not. (probably not!) Is it useful to add a bus device for a feature that there is only ever one of? Maybe or perhaps better option is to convert this to directly called library code rather than a device + separate driver. Signed-off-by: Jonathan Cameron --- Discussion of options / why in the cover letter. drivers/pci/pcie/aer.c | 67 +++++++++++++++++++++++++------------- drivers/pci/pcie/portdrv.c | 34 ++++++++++++++++--- 2 files changed, 75 insertions(+), 26 deletions(-) diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index e07c5bf71372..2df996d80849 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -15,6 +15,7 @@ #define pr_fmt(fmt) "AER: " fmt #define dev_fmt pr_fmt +#include #include #include #include @@ -1327,8 +1328,9 @@ static void aer_isr_one_error(struct aer_rpc *rpc, */ static irqreturn_t aer_isr(int irq, void *context) { - struct pcie_device *dev = (struct pcie_device *)context; - struct aer_rpc *rpc = dev_get_drvdata(&dev->device); + struct pcie_port_aux_dev *pcie_adev = context; + struct device *dev = &pcie_adev->adev.dev; + struct aer_rpc *rpc = dev_get_drvdata(dev); struct aer_err_source e_src; if (kfifo_is_empty(&rpc->aer_fifo)) @@ -1348,8 +1350,9 @@ static irqreturn_t aer_isr(int irq, void *context) */ static irqreturn_t aer_irq(int irq, void *context) { - struct pcie_device *pdev = (struct pcie_device *)context; - struct aer_rpc *rpc = dev_get_drvdata(&pdev->device); + struct pcie_port_aux_dev *pcie_adev = context; + struct device *dev = &pcie_adev->adev.dev; + struct aer_rpc *rpc = dev_get_drvdata(dev); struct pci_dev *rp = rpc->rpd; int aer = rp->aer_cap; struct aer_err_source e_src = {}; @@ -1442,58 +1445,74 @@ static void aer_disable_rootport(struct aer_rpc *rpc) /** * aer_remove - clean up resources - * @dev: pointer to the pcie_dev data structure + * @adev: pointer to the auxiliary device within the pcie_port_aux_dev * * Invoked when PCI Express bus unloads or AER probe fails. */ -static void aer_remove(struct pcie_device *dev) +static void aer_remove(struct auxiliary_device *adev) { - struct aer_rpc *rpc = dev_get_drvdata(&dev->device); - + struct aer_rpc *rpc = dev_get_drvdata(&adev->dev); aer_disable_rootport(rpc); } /** * aer_probe - initialize resources - * @dev: pointer to the pcie_dev data structure + * @adev: pointer to the auxiliary device within the pcie_port_aux_dev + * @id: id table entry that matched. * * Invoked when PCI Express bus loads AER service driver. */ -static int aer_probe(struct pcie_device *dev) +static int aer_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) { + struct pcie_port_aux_dev *pcie_adev = to_pcie_port_aux_dev(adev); int status; struct aer_rpc *rpc; - struct device *device = &dev->device; - struct pci_dev *port = dev->port; + struct device *dev = &adev->dev; + struct pci_dev *port = to_pci_dev(dev->parent); + u32 pos, reg32; + int irq_num, irq; BUILD_BUG_ON(ARRAY_SIZE(aer_correctable_error_string) < AER_MAX_TYPEOF_COR_ERRS); BUILD_BUG_ON(ARRAY_SIZE(aer_uncorrectable_error_string) < AER_MAX_TYPEOF_UNCOR_ERRS); + pos = port->aer_cap; + if (pos) { + pci_read_config_dword(port, pos + PCI_ERR_ROOT_STATUS, + ®32); + irq_num = FIELD_GET(PCI_ERR_ROOT_AER_IRQ, reg32); + /* To check - is this sufficient to detect legacy case? */ + if (pci_dev_msi_enabled(port)) + irq = pci_irq_vector(port, irq_num); + else + irq = pci_irq_vector(port, 0); + } + /* Limit to Root Ports or Root Complex Event Collectors */ if ((pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC) && (pci_pcie_type(port) != PCI_EXP_TYPE_ROOT_PORT)) return -ENODEV; - rpc = devm_kzalloc(device, sizeof(struct aer_rpc), GFP_KERNEL); + rpc = devm_kzalloc(dev, sizeof(struct aer_rpc), GFP_KERNEL); if (!rpc) return -ENOMEM; rpc->rpd = port; INIT_KFIFO(rpc->aer_fifo); - dev_set_drvdata(&dev->device, rpc); + dev_set_drvdata(&adev->dev, rpc); - status = devm_request_threaded_irq(device, dev->irq, aer_irq, aer_isr, - IRQF_SHARED, "aerdrv", dev); + status = devm_request_threaded_irq(dev, irq, aer_irq, aer_isr, + IRQF_SHARED, "aerdrv", pcie_adev); if (status) { - pci_err(port, "request AER IRQ %d failed\n", dev->irq); + pci_err(port, "request AER IRQ %d failed\n", irq); return status; } cxl_rch_enable_rcec(port); aer_enable_rootport(rpc); - pci_info(port, "enabled with IRQ %d\n", dev->irq); + pci_info(port, "enabled with IRQ %d\n", irq); return 0; } @@ -1555,12 +1574,16 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) return rc ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; } -static struct pcie_port_service_driver aerdriver = { - .name = "aer", - .service = PCIE_PORT_SERVICE_AER, +static const struct auxiliary_device_id aer_ids[] = { + { .name = "pcieportdrv.aer" }, + { } +}; +static struct auxiliary_driver aerdriver = { + .name = "aer", .probe = aer_probe, .remove = aer_remove, + .id_table = aer_ids, }; /** @@ -1572,5 +1595,5 @@ int __init pcie_aer_init(void) { if (!pci_aer_available()) return -ENXIO; - return pcie_port_service_register(&aerdriver); + return auxiliary_driver_register(&aerdriver); } diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 7274ee55a8c3..14aedce3be3b 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -162,9 +162,6 @@ static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask) irqs[PCIE_PORT_SERVICE_BWNOTIF_SHIFT] = pcie_irq; } - if (mask & PCIE_PORT_SERVICE_AER) - irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pci_irq_vector(dev, aer); - if (mask & PCIE_PORT_SERVICE_DPC) irqs[PCIE_PORT_SERVICE_DPC_SHIFT] = pci_irq_vector(dev, dpc); @@ -210,6 +207,15 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask) return 0; } +DEFINE_IDA(pcie_portdrv_aer_ida); + +static void pcie_port_aer_adev_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + ida_free(&pcie_portdrv_aer_ida, adev->id); +} + /** * get_port_device_capability - discover capabilities of a PCI Express port * @dev: PCI Express port to examine @@ -245,8 +251,28 @@ static int get_port_device_capability(struct pci_dev *dev, if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT || pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC) && dev->aer_cap && pci_aer_available() && - (pcie_ports_native || host->native_aer)) + (pcie_ports_native || host->native_aer)) { + struct pcie_port_aux_dev *pcie_adev; + int id, ret; + + pcie_adev = devm_kzalloc(&dev->dev, sizeof(*pcie_adev), GFP_KERNEL); + if (!pcie_adev) + return -ENOMEM; + + id = ida_alloc(&pcie_portdrv_aer_ida, GFP_KERNEL); + if (id < 0) + return id; + pcie_adev->adev.name = "aer"; + pcie_adev->adev.id = id; + pcie_adev->adev.dev.parent = &dev->dev; + pcie_adev->adev.dev.release = pcie_port_aer_adev_release; + + ret = devm_pcie_port_aux_dev_init(&dev->dev, pcie_adev); + if (ret) + return ret; + list_add(&pcie_adev->node, aux_dev_list); services |= PCIE_PORT_SERVICE_AER; + } #endif /* Root Ports and Root Complex Event Collectors may generate PMEs */