Skip to content

Commit 4188eac

Browse files
allenpaistyhicks
authored andcommitted
Hyper-V: pci: arm64: Allow use arch-specific pci sysdata
Currently, if an architecture selects CONFIG_PCI_DOMAINS_GENERIC, the 'sysdata' in bus and bridge will be treated as struct pci_config_window, which is created by generic ECAM using the data from of or acpi. However, for a virtualized PCI bus, there might be no enough data in of or acpi table to create a pci_config_window. This is similar to the case where CONFIG_PCI_DOMAINS_GENERIC=n, IOW, architectures use their own structure for sysdata, so no of or apci table lookup is required. In order to enable Hyper-V's virtual PCI (which doesn't have acpi table entry) on ARM64 (which selects CONFIG_PCI_DOMAINS_GENERIC), we introduce arch-specific pci sysdata (similar to the one for x86) for ARM64, and allow the core PCI code to detect the type of sysdata at the runtime. The latter is achieved by adding a pci_ops::use_arch_sysdata field. Signed-off-by: Sunil Muthuswamy <[email protected]> Signed-off-by: Boqun Feng (Microsoft) <[email protected]> Signed-off-by: Allen Pais <[email protected]>
1 parent 0d0cc65 commit 4188eac

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

arch/arm64/include/asm/pci.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@
2222

2323
extern int isa_dma_bridge_buggy;
2424

25+
struct pci_sysdata {
26+
int domain; /* PCI domain */
27+
int node; /* NUMA Node */
28+
#ifdef CONFIG_ACPI
29+
struct acpi_device *companion; /* ACPI companion device */
30+
#endif
31+
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
32+
void *fwnode; /* IRQ domain for MSI assignment */
33+
#endif
34+
};
35+
2536
#ifdef CONFIG_PCI
2637
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
2738
{
@@ -31,8 +42,29 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
3142

3243
static inline int pci_proc_domain(struct pci_bus *bus)
3344
{
45+
if (bus->ops->use_arch_sysdata)
46+
return pci_domain_nr(bus);
47+
3448
return 1;
3549
}
50+
51+
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
52+
static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
53+
{
54+
struct pci_sysdata *sd = bus->sysdata;
55+
56+
if (bus->ops->use_arch_sysdata)
57+
return sd->fwnode;
58+
59+
/*
60+
* bus->sysdata is not struct pci_sysdata, fwnode should be able to
61+
* be queried from of/acpi.
62+
*/
63+
return NULL;
64+
}
65+
#define pci_root_bus_fwnode _pci_root_bus_fwnode
66+
#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
67+
3668
#endif /* CONFIG_PCI */
3769

3870
#endif /* __ASM_PCI_H */

arch/arm64/kernel/pci.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,24 @@ struct acpi_pci_generic_root_info {
7474
int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
7575
{
7676
struct pci_config_window *cfg = bus->sysdata;
77-
struct acpi_device *adev = to_acpi_device(cfg->parent);
78-
struct acpi_pci_root *root = acpi_driver_data(adev);
77+
struct pci_sysdata *sd = bus->sysdata;
78+
struct acpi_device *adev;
79+
struct acpi_pci_root *root;
80+
81+
/* struct pci_sysdata has domain nr in it */
82+
if (bus->ops->use_arch_sysdata)
83+
return sd->domain;
84+
85+
/* or pci_config_window is used as sysdata */
86+
adev = to_acpi_device(cfg->parent);
87+
root = acpi_driver_data(adev);
7988

8089
return root->segment;
8190
}
8291

8392
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
8493
{
85-
if (!acpi_disabled) {
94+
if (!acpi_disabled && !bridge->ops->use_arch_sysdata) {
8695
struct pci_config_window *cfg = bridge->bus->sysdata;
8796
struct acpi_device *adev = to_acpi_device(cfg->parent);
8897
struct device *bus_dev = &bridge->bus->dev;

include/linux/pci.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,9 @@ struct pci_ops {
734734
void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where);
735735
int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
736736
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
737+
#ifdef CONFIG_PCI_DOMAINS_GENERIC
738+
int use_arch_sysdata; /* ->sysdata is arch-specific */
739+
#endif
737740
};
738741

739742
/*

0 commit comments

Comments
 (0)