From a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 5 Aug 2026 07:52:36 -0700 Subject: workqueue: skip the node_nr_active update for non-unbound workqueues apply_wqattrs_commit() updates node_nr_active->max unconditionally. wq->node_nr_active[] is only allocated for unbound workqueues, so guard the call before per-cpu workqueues start using this path. No functional change: only unbound workqueues reach apply_wqattrs_*() today. Signed-off-by: Breno Leitao Signed-off-by: Tejun Heo --- drivers/pci/controller/pci-host-common.c | 110 +++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 drivers/pci/controller/pci-host-common.c (limited to 'drivers/pci/controller/pci-host-common.c') diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c new file mode 100644 index 000000000..d6258c1cf --- /dev/null +++ b/drivers/pci/controller/pci-host-common.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common library for PCI host controller drivers + * + * Copyright (C) 2014 ARM Limited + * + * Author: Will Deacon + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pci-host-common.h" + +static void gen_pci_unmap_cfg(void *ptr) +{ + pci_ecam_free((struct pci_config_window *)ptr); +} + +struct pci_config_window *pci_host_common_ecam_create(struct device *dev, + struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops) +{ + int err; + struct resource cfgres; + struct resource_entry *bus; + struct pci_config_window *cfg; + + err = of_address_to_resource(dev->of_node, 0, &cfgres); + if (err) { + dev_err(dev, "missing or malformed \"reg\" property\n"); + return ERR_PTR(err); + } + + bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); + if (!bus) + return ERR_PTR(-ENODEV); + + cfg = pci_ecam_create(dev, &cfgres, bus->res, ops); + if (IS_ERR(cfg)) + return cfg; + + err = devm_add_action_or_reset(dev, gen_pci_unmap_cfg, cfg); + if (err) + return ERR_PTR(err); + + return cfg; +} +EXPORT_SYMBOL_GPL(pci_host_common_ecam_create); + +int pci_host_common_init(struct platform_device *pdev, + struct pci_host_bridge *bridge, + const struct pci_ecam_ops *ops) +{ + struct device *dev = &pdev->dev; + struct pci_config_window *cfg; + + of_pci_check_probe_only(); + + platform_set_drvdata(pdev, bridge); + + /* Parse and map our Configuration Space windows */ + cfg = pci_host_common_ecam_create(dev, bridge, ops); + if (IS_ERR(cfg)) + return PTR_ERR(cfg); + + bridge->sysdata = cfg; + bridge->ops = (struct pci_ops *)&ops->pci_ops; + bridge->enable_device = ops->enable_device; + bridge->disable_device = ops->disable_device; + bridge->msi_domain = true; + + return pci_host_probe(bridge); +} +EXPORT_SYMBOL_GPL(pci_host_common_init); + +int pci_host_common_probe(struct platform_device *pdev) +{ + const struct pci_ecam_ops *ops; + struct pci_host_bridge *bridge; + + ops = of_device_get_match_data(&pdev->dev); + if (!ops) + return -ENODEV; + + bridge = devm_pci_alloc_host_bridge(&pdev->dev, 0); + if (!bridge) + return -ENOMEM; + + return pci_host_common_init(pdev, bridge, ops); +} +EXPORT_SYMBOL_GPL(pci_host_common_probe); + +void pci_host_common_remove(struct platform_device *pdev) +{ + struct pci_host_bridge *bridge = platform_get_drvdata(pdev); + + pci_lock_rescan_remove(); + pci_stop_root_bus(bridge->bus); + pci_remove_root_bus(bridge->bus); + pci_unlock_rescan_remove(); +} +EXPORT_SYMBOL_GPL(pci_host_common_remove); + +MODULE_DESCRIPTION("Common library for PCI host controller drivers"); +MODULE_LICENSE("GPL v2"); -- cgit v1.3.1