// SPDX-License-Identifier: GPL-2.0 /* * Primary to Sideband (P2SB) bridge access support * * Copyright (c) 2017, 2021-2022 Intel Corporation. * * Authors: Andy Shevchenko <[email protected]> * Jonathan Yong <[email protected]> */ #include <linux/bits.h> #include <linux/export.h> #include <linux/pci.h> #include <linux/platform_data/x86/p2sb.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h> #define P2SBC … #define P2SBC_HIDE … #define P2SB_DEVFN_DEFAULT … #define P2SB_DEVFN_GOLDMONT … #define SPI_DEVFN_GOLDMONT … static const struct x86_cpu_id p2sb_cpu_ids[] = …; /* * Cache BAR0 of P2SB device functions 0 to 7. * TODO: The constant 8 is the number of functions that PCI specification * defines. Same definitions exist tree-wide. Unify this definition and * the other definitions then move to include/uapi/linux/pci.h. */ #define NR_P2SB_RES_CACHE … struct p2sb_res_cache { … }; static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE]; static void p2sb_get_devfn(unsigned int *devfn) { … } static bool p2sb_valid_resource(const struct resource *res) { … } /* Copy resource from the first BAR of the device in question */ static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) { … } static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn) { … } static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) { … } static struct pci_bus *p2sb_get_bus(struct pci_bus *bus) { … } static int p2sb_cache_resources(void) { … } /** * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR * @bus: PCI bus to communicate with * @devfn: PCI slot and function to communicate with * @mem: memory resource to be filled in * * If @bus is NULL, the bus 0 in domain 0 will be used. * If @devfn is 0, it will be replaced by devfn of the P2SB device. * * Caller must provide a valid pointer to @mem. * * Return: * 0 on success or appropriate errno value on error. */ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) { … } EXPORT_SYMBOL_GPL(…); static int __init p2sb_fs_init(void) { … } /* * pci_rescan_remove_lock() can not be locked in sysfs PCI bus rescan path * because of deadlock. To avoid the deadlock, access P2SB devices with the lock * at an early step in kernel initialization and cache required resources. * * We want to run as early as possible. If the P2SB was assigned a bad BAR, * we'll need to wait on pcibios_assign_resources() to fix it. So, our list of * initcall dependencies looks something like this: * * ... * subsys_initcall (pci_subsys_init) * fs_initcall (pcibios_assign_resources) */ fs_initcall_sync(p2sb_fs_init);