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 Diff line number Diff line
@@ -234,6 +234,7 @@ extern void init_bsp_APIC(void);
extern void setup_local_APIC(void);
extern void end_local_APIC_setup(void);
extern void init_apic_mappings(void);
void register_lapic_address(unsigned long address);
extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void);
@@ -244,7 +245,6 @@ extern int apic_force_enable(void);
 * On 32bit this is mach-xxx local
 */
#ifdef CONFIG_X86_64
extern void early_init_lapic_mapping(void);
extern int apic_is_clustered_box(void);
#else
static inline int apic_is_clustered_box(void)
+3 −0
Original line number 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 get_nr_irqs_gsi(void);

extern void setup_ioapic_ids_from_mpc(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);
extern void __init pre_init_apic_IRQ0(void);

extern void mp_save_irq(struct mpc_intsrc *m);

#else  /* !CONFIG_X86_IO_APIC */

#define io_apic_assign_pci_irqs 0
+5 −43
Original line number 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
 */

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)
{
	int count;
@@ -885,7 +873,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
		return count;
	}

	acpi_register_lapic_address(acpi_lapic_addr);
	register_lapic_address(acpi_lapic_addr);

	return count;
}
@@ -912,7 +900,7 @@ static int __init acpi_parse_madt_lapic_entries(void)
		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,
				      acpi_parse_sapic, MAX_LOCAL_APIC);
@@ -954,32 +942,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
extern int es7000_plat;
#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)
{
	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.dstirq = pin;	/* INTIN# */

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

	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.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.dstirq = mp_find_ioapic_pin(ioapic, gsi);

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


/**
 * 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)
{
	int cpu = smp_processor_id();
	unsigned int value, queued;
	int i, j, acked = 0;
	unsigned long long tsc = 0, ntsc;
@@ -1221,8 +1224,6 @@ void __cpuinit setup_local_APIC(void)
#endif
	perf_events_lapic_init();

	preempt_disable();

	/*
	 * Double-check whether this APIC is really registered.
	 * 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
	 */
	value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
	if (!smp_processor_id() && (pic_mode || !value)) {
	if (!cpu && (pic_mode || !value)) {
		value = APIC_DM_EXTINT;
		apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
				smp_processor_id());
		apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
	} else {
		value = APIC_DM_EXTINT | APIC_LVT_MASKED;
		apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
				smp_processor_id());
		apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);
	}
	apic_write(APIC_LVT0, value);

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

	preempt_enable();

#ifdef CONFIG_X86_MCE_INTEL
	/* Recheck CMCI information after local APIC is up on CPU #0 */
	if (smp_processor_id() == 0)
	if (!cpu)
		cmci_recheck();
#endif
}
@@ -1633,28 +1630,6 @@ static int __init detect_init_APIC(void)
}
#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
 */
@@ -1680,10 +1655,7 @@ void __init init_apic_mappings(void)
		 * acpi_register_lapic_address()
		 */
		if (!acpi_lapic && !smp_found_config)
			set_fixmap_nocache(FIX_APIC_BASE, apic_phys);

		apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
					APIC_BASE, apic_phys);
			register_lapic_address(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
 * a UP kernel.
+26 −2
Original line number Diff line number Diff line
@@ -125,6 +125,26 @@ static int __init parse_noapic(char *str)
}
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 {
	int apic, pin;
	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);
}


/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
#ifdef CONFIG_SPARSE_IRQ
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;

		/*
		 * Read the right value from the MPC table and
		 * write it into the ID register.
		 * Update the ID register according to the right value
		 * 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
			"...changing IO-APIC physical APIC ID to %d ...",
			mp_ioapics[apic_id].apicid);
Loading