linux/drivers/acpi/pci_root.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 40 $)
 *
 *  Copyright (C) 2001, 2002 Andy Grover <[email protected]>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
 */

#define pr_fmt(fmt)

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/dmar.h>
#include <linux/acpi.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/platform_data/x86/apple.h>
#include "internal.h"

#define ACPI_PCI_ROOT_CLASS
#define ACPI_PCI_ROOT_DEVICE_NAME
static int acpi_pci_root_add(struct acpi_device *device,
			     const struct acpi_device_id *not_used);
static void acpi_pci_root_remove(struct acpi_device *device);

static int acpi_pci_root_scan_dependent(struct acpi_device *adev)
{}

#define ACPI_PCIE_REQ_SUPPORT

static const struct acpi_device_id root_device_ids[] =;

static struct acpi_scan_handler pci_root_handler =;

/**
 * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
 * @handle:  the ACPI CA node in question.
 *
 * Note: we could make this API take a struct acpi_device * instead, but
 * for now, it's more convenient to operate on an acpi_handle.
 */
int acpi_is_root_bridge(acpi_handle handle)
{}
EXPORT_SYMBOL_GPL();

static acpi_status
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{}

static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
					     struct resource *res)
{}

struct pci_osc_bit_struct {};

static struct pci_osc_bit_struct pci_osc_support_bit[] =;

static struct pci_osc_bit_struct pci_osc_control_bit[] =;

static struct pci_osc_bit_struct cxl_osc_support_bit[] =;

static struct pci_osc_bit_struct cxl_osc_control_bit[] =;

static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word,
			    struct pci_osc_bit_struct *table, int size)
{}

static void decode_osc_support(struct acpi_pci_root *root, char *msg, u32 word)
{}

static void decode_osc_control(struct acpi_pci_root *root, char *msg, u32 word)
{}

static void decode_cxl_osc_support(struct acpi_pci_root *root, char *msg, u32 word)
{}

static void decode_cxl_osc_control(struct acpi_pci_root *root, char *msg, u32 word)
{}

static inline bool is_pcie(struct acpi_pci_root *root)
{}

static inline bool is_cxl(struct acpi_pci_root *root)
{}

static u8 pci_osc_uuid_str[] =;
static u8 cxl_osc_uuid_str[] =;

static char *to_uuid(struct acpi_pci_root *root)
{}

static int cap_length(struct acpi_pci_root *root)
{}

static acpi_status acpi_pci_run_osc(struct acpi_pci_root *root,
				    const u32 *capbuf, u32 *pci_control,
				    u32 *cxl_control)
{}

static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 support,
				      u32 *control, u32 cxl_support,
				      u32 *cxl_control)
{}

struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
{}
EXPORT_SYMBOL_GPL();

/**
 * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev
 * @handle: the handle in question
 *
 * Given an ACPI CA handle, the desired PCI device is located in the
 * list of PCI devices.
 *
 * If the device is found, its reference count is increased and this
 * function returns a pointer to its data structure.  The caller must
 * decrement the reference count by calling pci_dev_put().
 * If no device is found, %NULL is returned.
 */
struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
{}
EXPORT_SYMBOL_GPL();

/**
 * acpi_pci_osc_control_set - Request control of PCI root _OSC features.
 * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
 * @mask: Mask of _OSC bits to request control of, place to store control mask.
 * @support: _OSC supported capability.
 * @cxl_mask: Mask of CXL _OSC control bits, place to store control mask.
 * @cxl_support: CXL _OSC supported capability.
 *
 * Run _OSC query for @mask and if that is successful, compare the returned
 * mask of control bits with @req.  If all of the @req bits are set in the
 * returned mask, run _OSC request for it.
 *
 * The variable at the @mask address may be modified regardless of whether or
 * not the function returns success.  On success it will contain the mask of
 * _OSC bits the BIOS has granted control of, but its contents are meaningless
 * on failure.
 **/
static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask,
					    u32 support, u32 *cxl_mask,
					    u32 cxl_support)
{}

static u32 calculate_support(void)
{}

/*
 * Background on hotplug support, and making it depend on only
 * CONFIG_HOTPLUG_PCI_PCIE vs. also considering CONFIG_MEMORY_HOTPLUG:
 *
 * CONFIG_ACPI_HOTPLUG_MEMORY does depend on CONFIG_MEMORY_HOTPLUG, but
 * there is no existing _OSC for memory hotplug support. The reason is that
 * ACPI memory hotplug requires the OS to acknowledge / coordinate with
 * memory plug events via a scan handler. On the CXL side the equivalent
 * would be if Linux supported the Mechanical Retention Lock [1], or
 * otherwise had some coordination for the driver of a PCI device
 * undergoing hotplug to be consulted on whether the hotplug should
 * proceed or not.
 *
 * The concern is that if Linux says no to supporting CXL hotplug then
 * the BIOS may say no to giving the OS hotplug control of any other PCIe
 * device. So the question here is not whether hotplug is enabled, it's
 * whether it is handled natively by the at all OS, and if
 * CONFIG_HOTPLUG_PCI_PCIE is enabled then the answer is "yes".
 *
 * Otherwise, the plan for CXL coordinated remove, since the kernel does
 * not support blocking hotplug, is to require the memory device to be
 * disabled before hotplug is attempted. When CONFIG_MEMORY_HOTPLUG is
 * disabled that step will fail and the remove attempt cancelled by the
 * user. If that is not honored and the card is removed anyway then it
 * does not matter if CONFIG_MEMORY_HOTPLUG is enabled or not, it will
 * cause a crash and other badness.
 *
 * Therefore, just say yes to CXL hotplug and require removal to
 * be coordinated by userspace unless and until the kernel grows better
 * mechanisms for doing "managed" removal of devices in consultation with
 * the driver.
 *
 * [1]: https://lore.kernel.org/all/[email protected]/
 */
static u32 calculate_cxl_support(void)
{}

static u32 calculate_control(void)
{}

static u32 calculate_cxl_control(void)
{}

static bool os_control_query_checks(struct acpi_pci_root *root, u32 support)
{}

static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm)
{}

static int acpi_pci_root_add(struct acpi_device *device,
			     const struct acpi_device_id *not_used)
{}

static void acpi_pci_root_remove(struct acpi_device *device)
{}

/*
 * Following code to support acpi_pci_root_create() is copied from
 * arch/x86/pci/acpi.c and modified so it could be reused by x86, IA64
 * and ARM64.
 */
static void acpi_pci_root_validate_resources(struct device *dev,
					     struct list_head *resources,
					     unsigned long type)
{}

static void acpi_pci_root_remap_iospace(struct fwnode_handle *fwnode,
			struct resource_entry *entry)
{}

int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
{}

static void pci_acpi_root_add_resources(struct acpi_pci_root_info *info)
{}

static void __acpi_pci_root_release_info(struct acpi_pci_root_info *info)
{}

static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
{}

struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
				     struct acpi_pci_root_ops *ops,
				     struct acpi_pci_root_info *info,
				     void *sysdata)
{}

void __init acpi_pci_root_init(void)
{}