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

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

x86: update mptable fix with no ioapic v2



if the system doesn't have ioapic, we don't need to store entries for mptable
update

also let mp_config_acpi_gsi not call func in mpparse
so later could decouple mpparse with acpi more easily

Reported-by: default avatarDaniel Exner <dex@dragonslave.de>
Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Daniel Exner <dex@dragonslave.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 95a71a45
Loading
Loading
Loading
Loading
+56 −31
Original line number Diff line number Diff line
@@ -960,10 +960,37 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
	nr_ioapics++;
}

static void assign_to_mp_irq(struct mp_config_intsrc *m,
				    struct mp_config_intsrc *mp_irq)
{
	memcpy(mp_irq, m, sizeof(struct mp_config_intsrc));
}

static int mp_irq_cmp(struct mp_config_intsrc *mp_irq,
				struct mp_config_intsrc *m)
{
	return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc));
}

static void save_mp_irq(struct mp_config_intsrc *m)
{
	int i;

	for (i = 0; i < mp_irq_entries; i++) {
		if (!mp_irq_cmp(&mp_irqs[i], m))
			return;
	}

	assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
	if (++mp_irq_entries == MAX_IRQ_SOURCES)
		panic("Max # of irq sources exceeded!!\n");
}

void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
{
	int ioapic;
	int pin;
	struct mp_config_intsrc mp_irq;

	/*
	 * Convert 'gsi' to 'ioapic.pin'.
@@ -981,18 +1008,15 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
	if ((bus_irq == 0) && (trigger == 3))
		trigger = 1;

	mp_irqs[mp_irq_entries].mp_type = MP_INTSRC;
	mp_irqs[mp_irq_entries].mp_irqtype = mp_INT;
	mp_irqs[mp_irq_entries].mp_irqflag = (trigger << 2) | polarity;
	mp_irqs[mp_irq_entries].mp_srcbus = MP_ISA_BUS;
	mp_irqs[mp_irq_entries].mp_srcbusirq = bus_irq;	/* IRQ */
	mp_irqs[mp_irq_entries].mp_dstapic =
			mp_ioapics[ioapic].mp_apicid;	/* APIC ID */
	mp_irqs[mp_irq_entries].mp_dstirq = pin;	/* INTIN# */

	if (++mp_irq_entries == MAX_IRQ_SOURCES)
		panic("Max # of irq sources exceeded!!\n");
	mp_irq.mp_type = MP_INTSRC;
	mp_irq.mp_irqtype = mp_INT;
	mp_irq.mp_irqflag = (trigger << 2) | polarity;
	mp_irq.mp_srcbus = MP_ISA_BUS;
	mp_irq.mp_srcbusirq = bus_irq;	/* IRQ */
	mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */
	mp_irq.mp_dstirq = pin;	/* INTIN# */

	save_mp_irq(&mp_irq);
}

void __init mp_config_acpi_legacy_irqs(void)
@@ -1000,6 +1024,7 @@ void __init mp_config_acpi_legacy_irqs(void)
	int i;
	int ioapic;
	unsigned int dstapic;
	struct mp_config_intsrc mp_irq;

#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
	/*
@@ -1052,16 +1077,15 @@ void __init mp_config_acpi_legacy_irqs(void)
			continue;	/* IRQ already used */
		}

		mp_irqs[mp_irq_entries].mp_type = MP_INTSRC;
		mp_irqs[mp_irq_entries].mp_irqflag = 0;	/* Conforming */
		mp_irqs[mp_irq_entries].mp_srcbus = MP_ISA_BUS;
		mp_irqs[mp_irq_entries].mp_dstapic = dstapic;
		mp_irqs[mp_irq_entries].mp_irqtype = mp_INT;
		mp_irqs[mp_irq_entries].mp_srcbusirq = i; /* Identity mapped */
		mp_irqs[mp_irq_entries].mp_dstirq = i;
		mp_irq.mp_type = MP_INTSRC;
		mp_irq.mp_irqflag = 0;	/* Conforming */
		mp_irq.mp_srcbus = MP_ISA_BUS;
		mp_irq.mp_dstapic = dstapic;
		mp_irq.mp_irqtype = mp_INT;
		mp_irq.mp_srcbusirq = i; /* Identity mapped */
		mp_irq.mp_dstirq = i;

		if (++mp_irq_entries == MAX_IRQ_SOURCES)
			panic("Max # of irq sources exceeded!!\n");
		save_mp_irq(&mp_irq);
	}
}

@@ -1169,25 +1193,26 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
			u32 gsi, int triggering, int polarity)
{
	struct mpc_config_intsrc intsrc;
#ifdef CONFIG_X86_MPPARSE
	struct mp_config_intsrc mp_irq;
	int ioapic;

	if (!enable_update_mptable)
	if (!acpi_ioapic)
		return 0;

	/* print the entry should happen on mptable identically */
	intsrc.mpc_type = MP_INTSRC;
	intsrc.mpc_irqtype = mp_INT;
	intsrc.mpc_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
	mp_irq.mp_type = MP_INTSRC;
	mp_irq.mp_irqtype = mp_INT;
	mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
				(polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
	intsrc.mpc_srcbus = number;
	intsrc.mpc_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
	mp_irq.mp_srcbus = number;
	mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
	ioapic = mp_find_ioapic(gsi);
	intsrc.mpc_dstapic = mp_ioapic_routing[ioapic].apic_id;
	intsrc.mpc_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;

	MP_intsrc_info(&intsrc);
	mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id;
	mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;

	save_mp_irq(&mp_irq);
#endif
	return 0;
}

+9 −10
Original line number Diff line number Diff line
@@ -34,8 +34,6 @@
#include <mach_mpparse.h>
#endif

int enable_update_mptable;

/*
 * Checksum an MP configuration block.
 */
@@ -246,7 +244,7 @@ static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq)
		mp_irq->mp_srcbusirq, mp_irq->mp_dstapic, mp_irq->mp_dstirq);
}

static void assign_to_mp_irq(struct mpc_config_intsrc *m,
static void __init assign_to_mp_irq(struct mpc_config_intsrc *m,
				    struct mp_config_intsrc *mp_irq)
{
	mp_irq->mp_dstapic = m->mpc_dstapic;
@@ -270,7 +268,7 @@ static void __init assign_to_mpc_intsrc(struct mp_config_intsrc *mp_irq,
	m->mpc_dstirq = mp_irq->mp_dstirq;
}

static int mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
static int __init mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
					struct mpc_config_intsrc *m)
{
	if (mp_irq->mp_dstapic != m->mpc_dstapic)
@@ -291,13 +289,12 @@ static int mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
	return 0;
}

void MP_intsrc_info(struct mpc_config_intsrc *m)
static void __init MP_intsrc_info(struct mpc_config_intsrc *m)
{
	int i;

	print_MP_intsrc_info(m);

	if (enable_update_mptable)
	for (i = 0; i < mp_irq_entries; i++) {
		if (!mp_irq_mpc_intsrc_cmp(&mp_irqs[i], m))
			return;
@@ -1113,6 +1110,8 @@ static int __init replace_intsrc_all(struct mp_config_table *mpc,
	return 0;
}

static int __initdata enable_update_mptable;

static int __init update_mptable_setup(char *str)
{
	enable_update_mptable = 1;
+0 −2
Original line number Diff line number Diff line
@@ -59,9 +59,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 void MP_intsrc_info(struct mpc_config_intsrc *m);
#ifdef CONFIG_X86_IO_APIC
extern int enable_update_mptable;
extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
				u32 gsi, int triggering, int polarity);
#else