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

Commit d004e4d3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-apic-cleanups-for-linus' of...

Merge branch 'x86-apic-cleanups-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-apic-cleanups-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: apic: Cleanup and simplify setup_local_APIC()
  x86: Further simplify mp_irq info handling
  x86: Unify 3 similar ways of saving mp_irqs info
  x86, ioapic: Avoid writing io_apic id if already correct
  x86, x2apic: Don't map lapic addr for preenabled x2apic systems
  x86, sfi: Use register_lapic_address()
  x86, apic: Use register_lapic_address() in init_apic_mapping()
  x86, apic: Remove early_init_lapic_mapping()
  x86, apic: Unify identical register_lapic_address() functions
parents 128283a4 1c2a48cf
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -234,6 +234,7 @@ extern void init_bsp_APIC(void);
extern void setup_local_APIC(void);
extern void setup_local_APIC(void);
extern void end_local_APIC_setup(void);
extern void end_local_APIC_setup(void);
extern void init_apic_mappings(void);
extern void init_apic_mappings(void);
void register_lapic_address(unsigned long address);
extern void setup_boot_APIC_clock(void);
extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void);
extern int APIC_init_uniprocessor(void);
@@ -244,7 +245,6 @@ extern int apic_force_enable(void);
 * On 32bit this is mach-xxx local
 * On 32bit this is mach-xxx local
 */
 */
#ifdef CONFIG_X86_64
#ifdef CONFIG_X86_64
extern void early_init_lapic_mapping(void);
extern int apic_is_clustered_box(void);
extern int apic_is_clustered_box(void);
#else
#else
static inline int apic_is_clustered_box(void)
static inline int apic_is_clustered_box(void)
+3 −0
Original line number Original line Diff line number Diff line
@@ -169,6 +169,7 @@ extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);


extern int get_nr_irqs_gsi(void);
extern int get_nr_irqs_gsi(void);

extern void setup_ioapic_ids_from_mpc(void);
extern void setup_ioapic_ids_from_mpc(void);
extern void setup_ioapic_ids_from_mpc_nocheck(void);
extern void setup_ioapic_ids_from_mpc_nocheck(void);


@@ -183,6 +184,8 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void __init pre_init_apic_IRQ0(void);
extern void __init pre_init_apic_IRQ0(void);


extern void mp_save_irq(struct mpc_intsrc *m);

#else  /* !CONFIG_X86_IO_APIC */
#else  /* !CONFIG_X86_IO_APIC */


#define io_apic_assign_pci_irqs 0
#define io_apic_assign_pci_irqs 0
+5 −43
Original line number Original line Diff line number Diff line
@@ -852,18 +852,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
 * returns 0 on success, < 0 on error
 * returns 0 on success, < 0 on error
 */
 */


static void __init acpi_register_lapic_address(unsigned long address)
{
	mp_lapic_addr = address;

	set_fixmap_nocache(FIX_APIC_BASE, address);
	if (boot_cpu_physical_apicid == -1U) {
		boot_cpu_physical_apicid  = read_apic_id();
		apic_version[boot_cpu_physical_apicid] =
			 GET_APIC_VERSION(apic_read(APIC_LVR));
	}
}

static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
{
{
	int count;
	int count;
@@ -885,7 +873,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
		return count;
		return count;
	}
	}


	acpi_register_lapic_address(acpi_lapic_addr);
	register_lapic_address(acpi_lapic_addr);


	return count;
	return count;
}
}
@@ -912,7 +900,7 @@ static int __init acpi_parse_madt_lapic_entries(void)
		return count;
		return count;
	}
	}


	acpi_register_lapic_address(acpi_lapic_addr);
	register_lapic_address(acpi_lapic_addr);


	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
				      acpi_parse_sapic, MAX_LOCAL_APIC);
				      acpi_parse_sapic, MAX_LOCAL_APIC);
@@ -954,32 +942,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
extern int es7000_plat;
extern int es7000_plat;
#endif
#endif


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

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

static void save_mp_irq(struct mpc_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)
void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
{
{
	int ioapic;
	int ioapic;
@@ -1010,7 +972,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
	mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
	mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
	mp_irq.dstirq = pin;	/* INTIN# */
	mp_irq.dstirq = pin;	/* INTIN# */


	save_mp_irq(&mp_irq);
	mp_save_irq(&mp_irq);


	isa_irq_to_gsi[bus_irq] = gsi;
	isa_irq_to_gsi[bus_irq] = gsi;
}
}
@@ -1085,7 +1047,7 @@ void __init mp_config_acpi_legacy_irqs(void)
		mp_irq.srcbusirq = i; /* Identity mapped */
		mp_irq.srcbusirq = i; /* Identity mapped */
		mp_irq.dstirq = pin;
		mp_irq.dstirq = pin;


		save_mp_irq(&mp_irq);
		mp_save_irq(&mp_irq);
	}
	}
}
}


@@ -1122,7 +1084,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
	mp_irq.dstapic = mp_ioapics[ioapic].apicid;
	mp_irq.dstapic = mp_ioapics[ioapic].apicid;
	mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
	mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);


	save_mp_irq(&mp_irq);
	mp_save_irq(&mp_irq);
#endif
#endif
	return 0;
	return 0;
}
}
+26 −38
Original line number Original line Diff line number Diff line
@@ -1191,12 +1191,15 @@ static void __cpuinit lapic_setup_esr(void)
			oldvalue, value);
			oldvalue, value);
}
}



/**
/**
 * setup_local_APIC - setup the local APIC
 * setup_local_APIC - setup the local APIC
 *
 * Used to setup local APIC while initializing BSP or bringin up APs.
 * Always called with preemption disabled.
 */
 */
void __cpuinit setup_local_APIC(void)
void __cpuinit setup_local_APIC(void)
{
{
	int cpu = smp_processor_id();
	unsigned int value, queued;
	unsigned int value, queued;
	int i, j, acked = 0;
	int i, j, acked = 0;
	unsigned long long tsc = 0, ntsc;
	unsigned long long tsc = 0, ntsc;
@@ -1221,8 +1224,6 @@ void __cpuinit setup_local_APIC(void)
#endif
#endif
	perf_events_lapic_init();
	perf_events_lapic_init();


	preempt_disable();

	/*
	/*
	 * Double-check whether this APIC is really registered.
	 * Double-check whether this APIC is really registered.
	 * This is meaningless in clustered apic mode, so we skip it.
	 * This is meaningless in clustered apic mode, so we skip it.
@@ -1338,21 +1339,19 @@ void __cpuinit setup_local_APIC(void)
	 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
	 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
	 */
	 */
	value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
	value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
	if (!smp_processor_id() && (pic_mode || !value)) {
	if (!cpu && (pic_mode || !value)) {
		value = APIC_DM_EXTINT;
		value = APIC_DM_EXTINT;
		apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
		apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
				smp_processor_id());
	} else {
	} else {
		value = APIC_DM_EXTINT | APIC_LVT_MASKED;
		value = APIC_DM_EXTINT | APIC_LVT_MASKED;
		apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
		apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);
				smp_processor_id());
	}
	}
	apic_write(APIC_LVT0, value);
	apic_write(APIC_LVT0, value);


	/*
	/*
	 * only the BP should see the LINT1 NMI signal, obviously.
	 * only the BP should see the LINT1 NMI signal, obviously.
	 */
	 */
	if (!smp_processor_id())
	if (!cpu)
		value = APIC_DM_NMI;
		value = APIC_DM_NMI;
	else
	else
		value = APIC_DM_NMI | APIC_LVT_MASKED;
		value = APIC_DM_NMI | APIC_LVT_MASKED;
@@ -1360,11 +1359,9 @@ void __cpuinit setup_local_APIC(void)
		value |= APIC_LVT_LEVEL_TRIGGER;
		value |= APIC_LVT_LEVEL_TRIGGER;
	apic_write(APIC_LVT1, value);
	apic_write(APIC_LVT1, value);


	preempt_enable();

#ifdef CONFIG_X86_MCE_INTEL
#ifdef CONFIG_X86_MCE_INTEL
	/* Recheck CMCI information after local APIC is up on CPU #0 */
	/* Recheck CMCI information after local APIC is up on CPU #0 */
	if (smp_processor_id() == 0)
	if (!cpu)
		cmci_recheck();
		cmci_recheck();
#endif
#endif
}
}
@@ -1633,28 +1630,6 @@ static int __init detect_init_APIC(void)
}
}
#endif
#endif


#ifdef CONFIG_X86_64
void __init early_init_lapic_mapping(void)
{
	/*
	 * If no local APIC can be found then go out
	 * : it means there is no mpatable and MADT
	 */
	if (!smp_found_config)
		return;

	set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
	apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
		    APIC_BASE, mp_lapic_addr);

	/*
	 * Fetch the APIC ID of the BSP in case we have a
	 * default configuration (or the MP table is broken).
	 */
	boot_cpu_physical_apicid = read_apic_id();
}
#endif

/**
/**
 * init_apic_mappings - initialize APIC mappings
 * init_apic_mappings - initialize APIC mappings
 */
 */
@@ -1680,10 +1655,7 @@ void __init init_apic_mappings(void)
		 * acpi_register_lapic_address()
		 * acpi_register_lapic_address()
		 */
		 */
		if (!acpi_lapic && !smp_found_config)
		if (!acpi_lapic && !smp_found_config)
			set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
			register_lapic_address(apic_phys);

		apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
					APIC_BASE, apic_phys);
	}
	}


	/*
	/*
@@ -1705,6 +1677,22 @@ void __init init_apic_mappings(void)
	}
	}
}
}


void __init register_lapic_address(unsigned long address)
{
	mp_lapic_addr = address;

	if (!x2apic_mode) {
		set_fixmap_nocache(FIX_APIC_BASE, address);
		apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
			    APIC_BASE, mp_lapic_addr);
	}
	if (boot_cpu_physical_apicid == -1U) {
		boot_cpu_physical_apicid  = read_apic_id();
		apic_version[boot_cpu_physical_apicid] =
			 GET_APIC_VERSION(apic_read(APIC_LVR));
	}
}

/*
/*
 * This initializes the IO-APIC and APIC hardware if this is
 * This initializes the IO-APIC and APIC hardware if this is
 * a UP kernel.
 * a UP kernel.
+26 −2
Original line number Original line Diff line number Diff line
@@ -125,6 +125,26 @@ static int __init parse_noapic(char *str)
}
}
early_param("noapic", parse_noapic);
early_param("noapic", parse_noapic);


/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */
void mp_save_irq(struct mpc_intsrc *m)
{
	int i;

	apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
		" IRQ %02x, APIC ID %x, APIC INT %02x\n",
		m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus,
		m->srcbusirq, m->dstapic, m->dstirq);

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

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

struct irq_pin_list {
struct irq_pin_list {
	int apic, pin;
	int apic, pin;
	struct irq_pin_list *next;
	struct irq_pin_list *next;
@@ -135,6 +155,7 @@ static struct irq_pin_list *alloc_irq_pin_list(int node)
	return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);
	return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);
}
}



/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
#ifdef CONFIG_SPARSE_IRQ
#ifdef CONFIG_SPARSE_IRQ
static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
@@ -2006,9 +2027,12 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
						= mp_ioapics[apic_id].apicid;
						= mp_ioapics[apic_id].apicid;


		/*
		/*
		 * Read the right value from the MPC table and
		 * Update the ID register according to the right value
		 * write it into the ID register.
		 * from the MPC table if they are different.
		 */
		 */
		if (mp_ioapics[apic_id].apicid == reg_00.bits.ID)
			continue;

		apic_printk(APIC_VERBOSE, KERN_INFO
		apic_printk(APIC_VERBOSE, KERN_INFO
			"...changing IO-APIC physical APIC ID to %d ...",
			"...changing IO-APIC physical APIC ID to %d ...",
			mp_ioapics[apic_id].apicid);
			mp_ioapics[apic_id].apicid);
Loading