2 * Copyright (C) 2016 Broadcom
3 * Author: Jayachandran C <jchandra@broadcom.com>
4 * Copyright (C) 2016 Semihalf
5 * Author: Tomasz Nowicki <tn@semihalf.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2, as
9 * published by the Free Software Foundation (the "GPL").
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License version 2 (GPLv2) for more details.
16 * You should have received a copy of the GNU General Public License
17 * version 2 (GPLv2) along with this source code.
20 #define pr_fmt(fmt) "ACPI: " fmt
22 #include <linux/kernel.h>
23 #include <linux/pci.h>
24 #include <linux/pci-acpi.h>
26 /* Structure to hold entries from the MCFG table */
28 struct list_head list
;
35 /* List to save MCFG entries */
36 static LIST_HEAD(pci_mcfg_list
);
38 phys_addr_t
pci_mcfg_lookup(u16 seg
, struct resource
*bus_res
)
43 * We expect exact match, unless MCFG entry end bus covers more than
44 * specified by caller.
46 list_for_each_entry(e
, &pci_mcfg_list
, list
) {
47 if (e
->segment
== seg
&& e
->bus_start
== bus_res
->start
&&
48 e
->bus_end
>= bus_res
->end
)
55 static __init
int pci_mcfg_parse(struct acpi_table_header
*header
)
57 struct acpi_table_mcfg
*mcfg
;
58 struct acpi_mcfg_allocation
*mptr
;
59 struct mcfg_entry
*e
, *arr
;
62 if (header
->length
< sizeof(struct acpi_table_mcfg
))
65 n
= (header
->length
- sizeof(struct acpi_table_mcfg
)) /
66 sizeof(struct acpi_mcfg_allocation
);
67 mcfg
= (struct acpi_table_mcfg
*)header
;
68 mptr
= (struct acpi_mcfg_allocation
*) &mcfg
[1];
70 arr
= kcalloc(n
, sizeof(*arr
), GFP_KERNEL
);
74 for (i
= 0, e
= arr
; i
< n
; i
++, mptr
++, e
++) {
75 e
->segment
= mptr
->pci_segment
;
76 e
->addr
= mptr
->address
;
77 e
->bus_start
= mptr
->start_bus_number
;
78 e
->bus_end
= mptr
->end_bus_number
;
79 list_add(&e
->list
, &pci_mcfg_list
);
82 pr_info("MCFG table detected, %d entries\n", n
);
86 /* Interface called by ACPI - parse and save MCFG table */
87 void __init
pci_mmcfg_late_init(void)
89 int err
= acpi_table_parse(ACPI_SIG_MCFG
, pci_mcfg_parse
);
91 pr_err("Failed to parse MCFG (%d)\n", err
);