summaryrefslogtreecommitdiff
path: root/arch/x86/lib/mpspec.c
diff options
context:
space:
mode:
authorBin Meng <bmeng.cn@gmail.com>2015-07-22 01:21:09 -0700
committerSimon Glass <sjg@chromium.org>2015-07-28 10:36:24 -0600
commitabab912813169e9f24e12b9a0a993b0c6060c808 (patch)
tree7f578d1fe98aca74dee812131ab44156028d0820 /arch/x86/lib/mpspec.c
parenta2771943415c41b7a730e89e8eba9a43a4fa3fad (diff)
x86: mpspec: Allow platform to determine how PIRQ is connected to I/O APIC
Currently during writing MP table I/O interrupt assignment entry, we assume the PIRQ is directly mapped to I/O APIC INTPIN#16-23, which however is not always the case on some platforms. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/x86/lib/mpspec.c')
-rw-r--r--arch/x86/lib/mpspec.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/arch/x86/lib/mpspec.c b/arch/x86/lib/mpspec.c
index f16fbcbb0d..9b2a59b911 100644
--- a/arch/x86/lib/mpspec.c
+++ b/arch/x86/lib/mpspec.c
@@ -269,6 +269,13 @@ static bool check_dup_entry(struct mpc_config_intsrc *intsrc_base,
return (i == entry_num) ? false : true;
}
+/* TODO: move this to driver model */
+__weak int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
+{
+ /* PIRQ[A-H] are connected to I/O APIC INTPIN#16-23 */
+ return pirq + 16;
+}
+
static int mptable_add_intsrc(struct mp_config_table *mc,
int bus_isa, int apicid)
{
@@ -304,24 +311,27 @@ static int mptable_add_intsrc(struct mp_config_table *mc,
for (i = 0; i < count; i++) {
struct pirq_routing pr;
+ int bus, dev, func;
+ int dstirq;
pr.bdf = fdt_addr_to_cpu(cell[0]);
pr.pin = fdt_addr_to_cpu(cell[1]);
pr.pirq = fdt_addr_to_cpu(cell[2]);
+ bus = PCI_BUS(pr.bdf);
+ dev = PCI_DEV(pr.bdf);
+ func = PCI_FUNC(pr.bdf);
if (check_dup_entry(intsrc_base, intsrc_entries,
- PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), pr.pin)) {
+ bus, dev, pr.pin)) {
debug("found entry for bus %d device %d INT%c, skipping\n",
- PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
- 'A' + pr.pin - 1);
+ bus, dev, 'A' + pr.pin - 1);
cell += sizeof(struct pirq_routing) / sizeof(u32);
continue;
}
- /* PIRQ[A-H] are always connected to I/O APIC INTPIN#16-23 */
- mp_write_pci_intsrc(mc, MP_INT, PCI_BUS(pr.bdf),
- PCI_DEV(pr.bdf), pr.pin, apicid,
- pr.pirq + 16);
+ dstirq = mp_determine_pci_dstirq(bus, dev, func, pr.pirq);
+ mp_write_pci_intsrc(mc, MP_INT, bus, dev, pr.pin,
+ apicid, dstirq);
intsrc_entries++;
cell += sizeof(struct pirq_routing) / sizeof(u32);
}