diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2015-07-22 01:21:09 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-07-28 10:36:24 -0600 |
commit | abab912813169e9f24e12b9a0a993b0c6060c808 (patch) | |
tree | 7f578d1fe98aca74dee812131ab44156028d0820 /arch/x86/lib/mpspec.c | |
parent | a2771943415c41b7a730e89e8eba9a43a4fa3fad (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.c | 24 |
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); } |