[PATCH v3 4/9] x86, pci, acpi: Move arch-agnostic MMCONFIG (aka ECAM) and ACPI code out of arch/x86/ directory
Tomasz Nowicki
tomasz.nowicki at linaro.org
Mon Mar 16 07:38:17 PDT 2015
On 13.03.2015 17:35, Mark Salter wrote:
> On Tue, 2015-03-10 at 12:35 +0100, Tomasz Nowicki wrote:
>> ECAM standard and MCFG table are architecture independent and it makes
>> sense to share common code across all architectures. Both are going to
>> corresponding files - ecam.c and mcfg.c
>>
>> While we are here, rename pci_parse_mcfg to acpi_parse_mcfg.
>> We already have acpi_parse_mcfg prototype which is used nowhere.
>> At the same time, we need pci_parse_mcfg been global so acpi_parse_mcfg
>> can be used perfectly here.
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>> ---
>> arch/x86/Kconfig | 2 +
>> arch/x86/include/asm/pci_x86.h | 33 -----
>> arch/x86/pci/acpi.c | 1 +
>> arch/x86/pci/mmconfig-shared.c | 296 +----------------------------------------
>> arch/x86/pci/mmconfig_32.c | 1 +
>> arch/x86/pci/mmconfig_64.c | 1 +
>> arch/x86/pci/numachip.c | 1 +
>> drivers/acpi/Makefile | 1 +
>> drivers/acpi/mcfg.c | 81 +++++++++++
>> drivers/pci/Kconfig | 4 +
>> drivers/pci/Makefile | 5 +
>> drivers/pci/ecam.c | 243 +++++++++++++++++++++++++++++++++
>> include/linux/ecam.h | 51 +++++++
>> 13 files changed, 394 insertions(+), 326 deletions(-)
>> create mode 100644 drivers/acpi/mcfg.c
>> create mode 100644 drivers/pci/ecam.c
>> create mode 100644 include/linux/ecam.h
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index c2fb8a8..dd926f4 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -2276,6 +2276,7 @@ config PCI_DIRECT
>>
>> config PCI_MMCONFIG
>> def_bool y
>> + select PCI_ECAM
>> depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY)
>>
>> config PCI_OLPC
>> @@ -2293,6 +2294,7 @@ config PCI_DOMAINS
>>
>> config PCI_MMCONFIG
>> bool "Support mmconfig PCI config space access"
>> + select PCI_ECAM
>> depends on X86_64 && PCI && ACPI
>>
>> config PCI_CNB20LE_QUIRK
>> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
>> index c57c225..e8a237f 100644
>> --- a/arch/x86/include/asm/pci_x86.h
>> +++ b/arch/x86/include/asm/pci_x86.h
>> @@ -122,41 +122,8 @@ extern int pci_legacy_init(void);
>> extern void pcibios_fixup_irqs(void);
>>
>> /* pci-mmconfig.c */
>> -
>> -/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
>> -#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
>> -
>> -struct pci_mmcfg_region {
>> - struct list_head list;
>> - struct resource res;
>> - u64 address;
>> - char __iomem *virt;
>> - u16 segment;
>> - u8 start_bus;
>> - u8 end_bus;
>> - char name[PCI_MMCFG_RESOURCE_NAME_LEN];
>> -};
>> -
>> -struct pci_mmcfg_mmio_ops {
>> - u32 (*read)(int len, void __iomem *addr);
>> - void (*write)(int len, void __iomem *addr, u32 value);
>> -};
>> -
>> -extern int __init pci_mmcfg_arch_init(void);
>> -extern void __init pci_mmcfg_arch_free(void);
>> -extern int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg);
>> -extern void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg);
>> extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
>> phys_addr_t addr);
>> -extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
>> -extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
>> -extern u32 pci_mmio_read(int len, void __iomem *addr);
>> -extern void pci_mmio_write(int len, void __iomem *addr, u32 value);
>> -extern void pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops);
>> -
>> -extern struct list_head pci_mmcfg_list;
>> -
>> -#define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20)
>>
>> /*
>> * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
>> diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
>> index 6ac2738..5dfccef 100644
>> --- a/arch/x86/pci/acpi.c
>> +++ b/arch/x86/pci/acpi.c
>> @@ -4,6 +4,7 @@
>> #include <linux/irq.h>
>> #include <linux/dmi.h>
>> #include <linux/slab.h>
>> +#include <linux/ecam.h>
>> #include <asm/numa.h>
>> #include <asm/pci_x86.h>
>>
>> diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
>> index 685cd4c..5064302 100644
>> --- a/arch/x86/pci/mmconfig-shared.c
>> +++ b/arch/x86/pci/mmconfig-shared.c
>> @@ -18,6 +18,7 @@
>> #include <linux/slab.h>
>> #include <linux/mutex.h>
>> #include <linux/rculist.h>
>> +#include <linux/ecam.h>
>> #include <asm/e820.h>
>> #include <asm/pci_x86.h>
>> #include <asm/acpi.h>
>> @@ -27,52 +28,6 @@
>> /* Indicate if the mmcfg resources have been placed into the resource table. */
>> static bool pci_mmcfg_running_state;
>> static bool pci_mmcfg_arch_init_failed;
>> -static DEFINE_MUTEX(pci_mmcfg_lock);
>> -
>> -LIST_HEAD(pci_mmcfg_list);
>> -
>> -static u32
>> -pci_mmconfig_generic_read(int len, void __iomem *addr)
>> -{
>> - u32 data = 0;
>> -
>> - switch (len) {
>> - case 1:
>> - data = readb(addr);
>> - break;
>> - case 2:
>> - data = readw(addr);
>> - break;
>> - case 4:
>> - data = readl(addr);
>> - break;
>> - }
>> -
>> - return data;
>> -}
>> -
>> -static void
>> -pci_mmconfig_generic_write(int len, void __iomem *addr, u32 value)
>> -{
>> - switch (len) {
>> - case 1:
>> - writeb(value, addr);
>> - break;
>> - case 2:
>> - writew(value, addr);
>> - break;
>> - case 4:
>> - writel(value, addr);
>> - break;
>> - }
>> -}
>> -
>> -static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_default = {
>> - .read = pci_mmconfig_generic_read,
>> - .write = pci_mmconfig_generic_write,
>> -};
>> -
>> -static struct pci_mmcfg_mmio_ops *pci_mmcfg_mmio = &pci_mmcfg_mmio_default;
>>
>> static u32
>> pci_mmconfig_amd_read(int len, void __iomem *addr)
>> @@ -115,128 +70,6 @@ static struct pci_mmcfg_mmio_ops pci_mmcfg_mmio_amd_fam10h = {
>> .write = pci_mmconfig_amd_write,
>> };
>>
>> -void
>> -pci_mmconfig_register_mmio(struct pci_mmcfg_mmio_ops *ops)
>> -{
>> - pci_mmcfg_mmio = ops;
>> -}
>> -
>> -u32
>> -pci_mmio_read(int len, void __iomem *addr)
>> -{
>> - if (!pci_mmcfg_mmio) {
>> - pr_err("PCI config space has no accessors !");
>> - return 0;
>> - }
>> -
>> - return pci_mmcfg_mmio->read(len, addr);
>> -}
>> -
>> -void
>> -pci_mmio_write(int len, void __iomem *addr, u32 value)
>> -{
>> - if (!pci_mmcfg_mmio) {
>> - pr_err("PCI config space has no accessors !");
>> - return;
>> - }
>> -
>> - pci_mmcfg_mmio->write(len, addr, value);
>> -}
>> -
>> -static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
>> -{
>> - if (cfg->res.parent)
>> - release_resource(&cfg->res);
>> - list_del(&cfg->list);
>> - kfree(cfg);
>> -}
>> -
>> -static void __init free_all_mmcfg(void)
>> -{
>> - struct pci_mmcfg_region *cfg, *tmp;
>> -
>> - pci_mmcfg_arch_free();
>> - list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
>> - pci_mmconfig_remove(cfg);
>> -}
>> -
>> -static void list_add_sorted(struct pci_mmcfg_region *new)
>> -{
>> - struct pci_mmcfg_region *cfg;
>> -
>> - /* keep list sorted by segment and starting bus number */
>> - list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
>> - if (cfg->segment > new->segment ||
>> - (cfg->segment == new->segment &&
>> - cfg->start_bus >= new->start_bus)) {
>> - list_add_tail_rcu(&new->list, &cfg->list);
>> - return;
>> - }
>> - }
>> - list_add_tail_rcu(&new->list, &pci_mmcfg_list);
>> -}
>> -
>> -static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
>> - int end, u64 addr)
>> -{
>> - struct pci_mmcfg_region *new;
>> - struct resource *res;
>> -
>> - if (addr == 0)
>> - return NULL;
>> -
>> - new = kzalloc(sizeof(*new), GFP_KERNEL);
>> - if (!new)
>> - return NULL;
>> -
>> - new->address = addr;
>> - new->segment = segment;
>> - new->start_bus = start;
>> - new->end_bus = end;
>> -
>> - res = &new->res;
>> - res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
>> - res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
>> - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
>> - snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
>> - "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
>> - res->name = new->name;
>> -
>> - return new;
>> -}
>> -
>> -static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
>> - int end, u64 addr)
>> -{
>> - struct pci_mmcfg_region *new;
>> -
>> - new = pci_mmconfig_alloc(segment, start, end, addr);
>> - if (new) {
>> - mutex_lock(&pci_mmcfg_lock);
>> - list_add_sorted(new);
>> - mutex_unlock(&pci_mmcfg_lock);
>> -
>> - pr_info(PREFIX
>> - "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
>> - "(base %#lx)\n",
>> - segment, start, end, &new->res, (unsigned long)addr);
>> - }
>> -
>> - return new;
>> -}
>> -
>> -struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
>> -{
>> - struct pci_mmcfg_region *cfg;
>> -
>> - list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
>> - if (cfg->segment == segment &&
>> - cfg->start_bus <= bus && bus <= cfg->end_bus)
>> - return cfg;
>> -
>> - return NULL;
>> -}
>> -
>> static const char *__init pci_mmcfg_e7520(void)
>> {
>> u32 win;
>> @@ -657,73 +490,6 @@ static void __init pci_mmcfg_reject_broken(int early)
>> }
>> }
>>
>> -static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
>> - struct acpi_mcfg_allocation *cfg)
>> -{
>> - int year;
>> -
>> - if (cfg->address < 0xFFFFFFFF)
>> - return 0;
>> -
>> - if (!strncmp(mcfg->header.oem_id, "SGI", 3))
>> - return 0;
>> -
>> - if (mcfg->header.revision >= 1) {
>> - if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
>> - year >= 2010)
>> - return 0;
>> - }
>> -
>> - pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
>> - "is above 4GB, ignored\n", cfg->pci_segment,
>> - cfg->start_bus_number, cfg->end_bus_number, cfg->address);
>> - return -EINVAL;
>> -}
>
> This looks very arch-specific. Shouldn't this be only generic checks
> with some hook for architectures to add arch-specific checks?
Yes, you are right it should go to arch specific call. Thanks.
Tomasz
More information about the linux-arm-kernel
mailing list