Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f4a739c authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86: find nr_irqs_gsi with mp_ioapic_routing



Impact: find right nr_irqs_gsi on some systems.

One test-system has gap between gsi's:

[    0.000000] ACPI: IOAPIC (id[0x04] address[0xfec00000] gsi_base[0])
[    0.000000] IOAPIC[0]: apic_id 4, version 0, address 0xfec00000, GSI 0-23
[    0.000000] ACPI: IOAPIC (id[0x05] address[0xfeafd000] gsi_base[48])
[    0.000000] IOAPIC[1]: apic_id 5, version 0, address 0xfeafd000, GSI 48-54
[    0.000000] ACPI: IOAPIC (id[0x06] address[0xfeafc000] gsi_base[56])
[    0.000000] IOAPIC[2]: apic_id 6, version 0, address 0xfeafc000, GSI 56-62
...
[    0.000000] nr_irqs_gsi: 38

So nr_irqs_gsi is not right. some irq for MSI will overwrite with io_apic.

need to get that with acpi_probe_gsi when acpi io_apic is used

Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent e736ad54
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
				   u32 gsi);
extern void mp_config_acpi_legacy_irqs(void);
extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low);
extern int acpi_probe_gsi(void);
#ifdef CONFIG_X86_IO_APIC
extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
				u32 gsi, int triggering, int polarity);
@@ -71,6 +72,11 @@ mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
	return 0;
}
#endif
#else /* !CONFIG_ACPI: */
static inline int acpi_probe_gsi(void)
{
	return 0;
}
#endif /* CONFIG_ACPI */

#define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
+23 −0
Original line number Diff line number Diff line
@@ -973,6 +973,29 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
	nr_ioapics++;
}

int __init acpi_probe_gsi(void)
{
	int idx;
	int gsi;
	int max_gsi = 0;

	if (acpi_disabled)
		return 0;

	if (!acpi_ioapic)
		return 0;

	max_gsi = 0;
	for (idx = 0; idx < nr_ioapics; idx++) {
		gsi = mp_ioapic_routing[idx].gsi_end;

		if (gsi > max_gsi)
			max_gsi = gsi;
	}

	return max_gsi + 1;
}

static void assign_to_mp_irq(struct mp_config_intsrc *m,
				    struct mp_config_intsrc *mp_irq)
{
+15 −5
Original line number Diff line number Diff line
@@ -3841,9 +3841,16 @@ int __init io_apic_get_redir_entries (int ioapic)

void __init probe_nr_irqs_gsi(void)
{
	int idx;
	int nr = 0;

	nr = acpi_probe_gsi();
	if (nr > nr_irqs_gsi) {
		nr_irqs_gsi = nr;
	} else {
		/* for acpi=off or acpi is not compiled in */
		int idx;

		nr = 0;
		for (idx = 0; idx < nr_ioapics; idx++)
			nr += io_apic_get_redir_entries(idx) + 1;

@@ -3851,6 +3858,9 @@ void __init probe_nr_irqs_gsi(void)
			nr_irqs_gsi = nr;
	}

	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}

/* --------------------------------------------------------------------------
                          ACPI-based IOAPIC Configuration
   -------------------------------------------------------------------------- */