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

Commit 0791e98d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/irq: Standardize on CONFIG_SPARSE_IRQ=y
  x86, ioapic: Clean up ioapic/apic_id usage
  x86, ioapic: Factor out print_IO_APIC() to only print one io apic
  x86, ioapic: Print out irte with right ioapic index
  x86, ioapic: Split up setup_ioapic_entry()
  x86, ioapic: Pass struct irq_attr * to setup_ioapic_irq()
  apic, i386/bigsmp: Fix false warnings regarding logical APIC ID mismatches
parents edb34a4d 141d55e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ config X86
	select HAVE_TEXT_POKE_SMP
	select HAVE_GENERIC_HARDIRQS
	select HAVE_SPARSE_IRQ
	select SPARSE_IRQ
	select GENERIC_FIND_FIRST_BIT
	select GENERIC_IRQ_PROBE
	select GENERIC_PENDING_IRQ if SMP
+1 −1
Original line number Diff line number Diff line
@@ -495,7 +495,7 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert)
	return;
}

extern struct apic *generic_bigsmp_probe(void);
extern void generic_bigsmp_probe(void);


#ifdef CONFIG_X86_LOCAL_APIC
+2 −10
Original line number Diff line number Diff line
@@ -160,19 +160,11 @@ static inline int invalid_vm86_irq(int irq)
#define IO_APIC_VECTOR_LIMIT		( 32 * MAX_IO_APICS )

#ifdef CONFIG_X86_IO_APIC
# ifdef CONFIG_SPARSE_IRQ
# define CPU_VECTOR_LIMIT		(64 * NR_CPUS)
# define NR_IRQS					\
	(CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ?	\
		(NR_VECTORS + CPU_VECTOR_LIMIT)  :	\
		(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
# else
#  define CPU_VECTOR_LIMIT		(32 * NR_CPUS)
#  define NR_IRQS					\
	(CPU_VECTOR_LIMIT < IO_APIC_VECTOR_LIMIT ?	\
		(NR_VECTORS + CPU_VECTOR_LIMIT)  :	\
		(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
# endif
#else /* !CONFIG_X86_IO_APIC: */
# define NR_IRQS			NR_IRQS_LEGACY
#endif
+16 −4
Original line number Diff line number Diff line
@@ -255,12 +255,24 @@ static struct apic apic_bigsmp = {
	.x86_32_early_logical_apicid	= bigsmp_early_logical_apicid,
};

struct apic * __init generic_bigsmp_probe(void)
void __init generic_bigsmp_probe(void)
{
	if (probe_bigsmp())
		return &apic_bigsmp;
	unsigned int cpu;

	return NULL;
	if (!probe_bigsmp())
		return;

	apic = &apic_bigsmp;

	for_each_possible_cpu(cpu) {
		if (early_per_cpu(x86_cpu_to_logical_apicid,
				  cpu) == BAD_APICID)
			continue;
		early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
			bigsmp_early_logical_apicid(cpu);
	}

	pr_info("Overriding APIC driver with %s\n", apic_bigsmp.name);
}

apic_driver(apic_bigsmp);
+197 −197
Original line number Diff line number Diff line
@@ -92,21 +92,21 @@ static struct ioapic {
	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
} ioapics[MAX_IO_APICS];

#define mpc_ioapic_ver(id)		ioapics[id].mp_config.apicver
#define mpc_ioapic_ver(ioapic_idx)	ioapics[ioapic_idx].mp_config.apicver

int mpc_ioapic_id(int id)
int mpc_ioapic_id(int ioapic_idx)
{
	return ioapics[id].mp_config.apicid;
	return ioapics[ioapic_idx].mp_config.apicid;
}

unsigned int mpc_ioapic_addr(int id)
unsigned int mpc_ioapic_addr(int ioapic_idx)
{
	return ioapics[id].mp_config.apicaddr;
	return ioapics[ioapic_idx].mp_config.apicaddr;
}

struct mp_ioapic_gsi *mp_ioapic_gsi_routing(int id)
struct mp_ioapic_gsi *mp_ioapic_gsi_routing(int ioapic_idx)
{
	return &ioapics[id].gsi_config;
	return &ioapics[ioapic_idx].gsi_config;
}

int nr_ioapics;
@@ -186,11 +186,7 @@ static struct irq_pin_list *alloc_irq_pin_list(int 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];
#else
static struct irq_cfg irq_cfgx[NR_IRQS];
#endif

int __init arch_early_irq_init(void)
{
@@ -234,7 +230,6 @@ int __init arch_early_irq_init(void)
	return 0;
}

#ifdef CONFIG_SPARSE_IRQ
static struct irq_cfg *irq_cfg(unsigned int irq)
{
	return irq_get_chip_data(irq);
@@ -269,22 +264,6 @@ static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
	kfree(cfg);
}

#else

struct irq_cfg *irq_cfg(unsigned int irq)
{
	return irq < nr_irqs ? irq_cfgx + irq : NULL;
}

static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node)
{
	return irq_cfgx + irq;
}

static inline void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) { }

#endif

static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
{
	int res = irq_alloc_desc_at(at, node);
@@ -802,13 +781,13 @@ int restore_ioapic_entries(void)
/*
 * Find the IRQ entry number of a certain pin.
 */
static int find_irq_entry(int apic, int pin, int type)
static int find_irq_entry(int ioapic_idx, int pin, int type)
{
	int i;

	for (i = 0; i < mp_irq_entries; i++)
		if (mp_irqs[i].irqtype == type &&
		    (mp_irqs[i].dstapic == mpc_ioapic_id(apic) ||
		    (mp_irqs[i].dstapic == mpc_ioapic_id(ioapic_idx) ||
		     mp_irqs[i].dstapic == MP_APIC_ALL) &&
		    mp_irqs[i].dstirq == pin)
			return i;
@@ -847,12 +826,13 @@ static int __init find_isa_irq_apic(int irq, int type)
		    (mp_irqs[i].srcbusirq == irq))
			break;
	}

	if (i < mp_irq_entries) {
		int apic;
		for(apic = 0; apic < nr_ioapics; apic++) {
			if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic)
				return apic;
		}
		int ioapic_idx;

		for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
			if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic)
				return ioapic_idx;
	}

	return -1;
@@ -1067,7 +1047,7 @@ static int pin_2_irq(int idx, int apic, int pin)
int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
				struct io_apic_irq_attr *irq_attr)
{
	int apic, i, best_guess = -1;
	int ioapic_idx, i, best_guess = -1;

	apic_printk(APIC_DEBUG,
		    "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
@@ -1080,8 +1060,8 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
	for (i = 0; i < mp_irq_entries; i++) {
		int lbus = mp_irqs[i].srcbus;

		for (apic = 0; apic < nr_ioapics; apic++)
			if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic ||
		for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
			if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic ||
			    mp_irqs[i].dstapic == MP_APIC_ALL)
				break;

@@ -1089,13 +1069,13 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
		    !mp_irqs[i].irqtype &&
		    (bus == lbus) &&
		    (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
			int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
			int irq = pin_2_irq(i, ioapic_idx, mp_irqs[i].dstirq);

			if (!(apic || IO_APIC_IRQ(irq)))
			if (!(ioapic_idx || IO_APIC_IRQ(irq)))
				continue;

			if (pin == (mp_irqs[i].srcbusirq & 3)) {
				set_io_apic_irq_attr(irq_attr, apic,
				set_io_apic_irq_attr(irq_attr, ioapic_idx,
						     mp_irqs[i].dstirq,
						     irq_trigger(i),
						     irq_polarity(i));
@@ -1106,7 +1086,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
			 * best-guess fuzzy result for broken mptables.
			 */
			if (best_guess < 0) {
				set_io_apic_irq_attr(irq_attr, apic,
				set_io_apic_irq_attr(irq_attr, ioapic_idx,
						     mp_irqs[i].dstirq,
						     irq_trigger(i),
						     irq_polarity(i));
@@ -1344,77 +1324,100 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg,
				      fasteoi ? "fasteoi" : "edge");
}

static int setup_ioapic_entry(int apic_id, int irq,
			      struct IO_APIC_route_entry *entry,
			      unsigned int destination, int trigger,
			      int polarity, int vector, int pin)
{
	/*
	 * add it to the IO-APIC irq-routing table:
	 */
	memset(entry,0,sizeof(*entry));

	if (intr_remapping_enabled) {
		struct intel_iommu *iommu = map_ioapic_to_ir(apic_id);
		struct irte irte;
		struct IR_IO_APIC_route_entry *ir_entry =
			(struct IR_IO_APIC_route_entry *) entry;
static int setup_ir_ioapic_entry(int irq,
			      struct IR_IO_APIC_route_entry *entry,
			      unsigned int destination, int vector,
			      struct io_apic_irq_attr *attr)
{
	int index;
	struct irte irte;
	int ioapic_id = mpc_ioapic_id(attr->ioapic);
	struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id);

		if (!iommu)
			panic("No mapping iommu for ioapic %d\n", apic_id);
	if (!iommu) {
		pr_warn("No mapping iommu for ioapic %d\n", ioapic_id);
		return -ENODEV;
	}

	index = alloc_irte(iommu, irq, 1);
		if (index < 0)
			panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
	if (index < 0) {
		pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id);
		return -ENOMEM;
	}

	prepare_irte(&irte, vector, destination);

	/* Set source-id of interrupt request */
		set_ioapic_sid(&irte, apic_id);
	set_ioapic_sid(&irte, ioapic_id);

	modify_irte(irq, &irte);

		ir_entry->index2 = (index >> 15) & 0x1;
		ir_entry->zero = 0;
		ir_entry->format = 1;
		ir_entry->index = (index & 0x7fff);
		/*
		 * IO-APIC RTE will be configured with virtual vector.
		 * irq handler will do the explicit EOI to the io-apic.
		 */
		ir_entry->vector = pin;

	apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: "
		"Set IRTE entry (P:%d FPD:%d Dst_Mode:%d "
		"Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X "
		"Avail:%X Vector:%02X Dest:%08X "
		"SID:%04X SQ:%X SVT:%X)\n",
			apic_id, irte.present, irte.fpd, irte.dst_mode,
		attr->ioapic, irte.present, irte.fpd, irte.dst_mode,
		irte.redir_hint, irte.trigger_mode, irte.dlvry_mode,
		irte.avail, irte.vector, irte.dest_id,
		irte.sid, irte.sq, irte.svt);
	} else {

	memset(entry, 0, sizeof(*entry));

	entry->index2	= (index >> 15) & 0x1;
	entry->zero	= 0;
	entry->format	= 1;
	entry->index	= (index & 0x7fff);
	/*
	 * IO-APIC RTE will be configured with virtual vector.
	 * irq handler will do the explicit EOI to the io-apic.
	 */
	entry->vector	= attr->ioapic_pin;
	entry->mask	= 0;			/* enable IRQ */
	entry->trigger	= attr->trigger;
	entry->polarity	= attr->polarity;

	/* Mask level triggered irqs.
	 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
	 */
	if (attr->trigger)
		entry->mask = 1;

	return 0;
}

static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
			       unsigned int destination, int vector,
			       struct io_apic_irq_attr *attr)
{
	if (intr_remapping_enabled)
		return setup_ir_ioapic_entry(irq,
			 (struct IR_IO_APIC_route_entry *)entry,
			 destination, vector, attr);

	memset(entry, 0, sizeof(*entry));

	entry->delivery_mode = apic->irq_delivery_mode;
	entry->dest_mode     = apic->irq_dest_mode;
	entry->dest	     = destination;
	entry->vector	     = vector;
	}

	entry->mask	     = 0;			/* enable IRQ */
	entry->trigger = trigger;
	entry->polarity = polarity;
	entry->trigger	     = attr->trigger;
	entry->polarity	     = attr->polarity;

	/* Mask level triggered irqs.
	/*
	 * Mask level triggered irqs.
	 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
	 */
	if (trigger)
	if (attr->trigger)
		entry->mask = 1;

	return 0;
}

static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq,
			     struct irq_cfg *cfg, int trigger, int polarity)
static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
				struct io_apic_irq_attr *attr)
{
	struct IO_APIC_route_entry entry;
	unsigned int dest;
@@ -1437,49 +1440,48 @@ static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq,
	apic_printk(APIC_VERBOSE,KERN_DEBUG
		    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
		    "IRQ %d Mode:%i Active:%i Dest:%d)\n",
		    apic_id, mpc_ioapic_id(apic_id), pin, cfg->vector,
		    irq, trigger, polarity, dest);

		    attr->ioapic, mpc_ioapic_id(attr->ioapic), attr->ioapic_pin,
		    cfg->vector, irq, attr->trigger, attr->polarity, dest);

	if (setup_ioapic_entry(mpc_ioapic_id(apic_id), irq, &entry,
			       dest, trigger, polarity, cfg->vector, pin)) {
		printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
		       mpc_ioapic_id(apic_id), pin);
	if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) {
		pr_warn("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
			mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
		__clear_irq_vector(irq, cfg);

		return;
	}

	ioapic_register_intr(irq, cfg, trigger);
	ioapic_register_intr(irq, cfg, attr->trigger);
	if (irq < legacy_pic->nr_legacy_irqs)
		legacy_pic->mask(irq);

	ioapic_write_entry(apic_id, pin, entry);
	ioapic_write_entry(attr->ioapic, attr->ioapic_pin, entry);
}

static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin)
static bool __init io_apic_pin_not_connected(int idx, int ioapic_idx, int pin)
{
	if (idx != -1)
		return false;

	apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n",
		    mpc_ioapic_id(apic_id), pin);
		    mpc_ioapic_id(ioapic_idx), pin);
	return true;
}

static void __init __io_apic_setup_irqs(unsigned int apic_id)
static void __init __io_apic_setup_irqs(unsigned int ioapic_idx)
{
	int idx, node = cpu_to_node(0);
	struct io_apic_irq_attr attr;
	unsigned int pin, irq;

	for (pin = 0; pin < ioapics[apic_id].nr_registers; pin++) {
		idx = find_irq_entry(apic_id, pin, mp_INT);
		if (io_apic_pin_not_connected(idx, apic_id, pin))
	for (pin = 0; pin < ioapics[ioapic_idx].nr_registers; pin++) {
		idx = find_irq_entry(ioapic_idx, pin, mp_INT);
		if (io_apic_pin_not_connected(idx, ioapic_idx, pin))
			continue;

		irq = pin_2_irq(idx, apic_id, pin);
		irq = pin_2_irq(idx, ioapic_idx, pin);

		if ((apic_id > 0) && (irq > 16))
		if ((ioapic_idx > 0) && (irq > 16))
			continue;

		/*
@@ -1487,10 +1489,10 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id)
		 * installed and if it returns 1:
		 */
		if (apic->multi_timer_check &&
		    apic->multi_timer_check(apic_id, irq))
		    apic->multi_timer_check(ioapic_idx, irq))
			continue;

		set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx),
		set_io_apic_irq_attr(&attr, ioapic_idx, pin, irq_trigger(idx),
				     irq_polarity(idx));

		io_apic_setup_irq_pin(irq, node, &attr);
@@ -1499,12 +1501,12 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id)

static void __init setup_IO_APIC_irqs(void)
{
	unsigned int apic_id;
	unsigned int ioapic_idx;

	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");

	for (apic_id = 0; apic_id < nr_ioapics; apic_id++)
		__io_apic_setup_irqs(apic_id);
	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
		__io_apic_setup_irqs(ioapic_idx);
}

/*
@@ -1514,28 +1516,28 @@ static void __init setup_IO_APIC_irqs(void)
 */
void setup_IO_APIC_irq_extra(u32 gsi)
{
	int apic_id = 0, pin, idx, irq, node = cpu_to_node(0);
	int ioapic_idx = 0, pin, idx, irq, node = cpu_to_node(0);
	struct io_apic_irq_attr attr;

	/*
	 * Convert 'gsi' to 'ioapic.pin'.
	 */
	apic_id = mp_find_ioapic(gsi);
	if (apic_id < 0)
	ioapic_idx = mp_find_ioapic(gsi);
	if (ioapic_idx < 0)
		return;

	pin = mp_find_ioapic_pin(apic_id, gsi);
	idx = find_irq_entry(apic_id, pin, mp_INT);
	pin = mp_find_ioapic_pin(ioapic_idx, gsi);
	idx = find_irq_entry(ioapic_idx, pin, mp_INT);
	if (idx == -1)
		return;

	irq = pin_2_irq(idx, apic_id, pin);
	irq = pin_2_irq(idx, ioapic_idx, pin);

	/* Only handle the non legacy irqs on secondary ioapics */
	if (apic_id == 0 || irq < NR_IRQS_LEGACY)
	if (ioapic_idx == 0 || irq < NR_IRQS_LEGACY)
		return;

	set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx),
	set_io_apic_irq_attr(&attr, ioapic_idx, pin, irq_trigger(idx),
			     irq_polarity(idx));

	io_apic_setup_irq_pin_once(irq, node, &attr);
@@ -1544,8 +1546,8 @@ void setup_IO_APIC_irq_extra(u32 gsi)
/*
 * Set up the timer pin, possibly with the 8259A-master behind.
 */
static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,
					int vector)
static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
					 unsigned int pin, int vector)
{
	struct IO_APIC_route_entry entry;

@@ -1576,45 +1578,29 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,
	/*
	 * Add it to the IO-APIC irq-routing table:
	 */
	ioapic_write_entry(apic_id, pin, entry);
	ioapic_write_entry(ioapic_idx, pin, entry);
}


__apicdebuginit(void) print_IO_APIC(void)
__apicdebuginit(void) print_IO_APIC(int ioapic_idx)
{
	int apic, i;
	int i;
	union IO_APIC_reg_00 reg_00;
	union IO_APIC_reg_01 reg_01;
	union IO_APIC_reg_02 reg_02;
	union IO_APIC_reg_03 reg_03;
	unsigned long flags;
	struct irq_cfg *cfg;
	unsigned int irq;

	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
	for (i = 0; i < nr_ioapics; i++)
		printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
		       mpc_ioapic_id(i), ioapics[i].nr_registers);

	/*
	 * We are a bit conservative about what we expect.  We have to
	 * know about every hardware change ASAP.
	 */
	printk(KERN_INFO "testing the IO APIC.......................\n");

	for (apic = 0; apic < nr_ioapics; apic++) {

	raw_spin_lock_irqsave(&ioapic_lock, flags);
	reg_00.raw = io_apic_read(apic, 0);
	reg_01.raw = io_apic_read(apic, 1);
	reg_00.raw = io_apic_read(ioapic_idx, 0);
	reg_01.raw = io_apic_read(ioapic_idx, 1);
	if (reg_01.bits.version >= 0x10)
		reg_02.raw = io_apic_read(apic, 2);
		reg_02.raw = io_apic_read(ioapic_idx, 2);
	if (reg_01.bits.version >= 0x20)
		reg_03.raw = io_apic_read(apic, 3);
		reg_03.raw = io_apic_read(ioapic_idx, 3);
	raw_spin_unlock_irqrestore(&ioapic_lock, flags);

	printk("\n");
	printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(apic));
	printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(ioapic_idx));
	printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
	printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
	printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
@@ -1664,7 +1650,7 @@ __apicdebuginit(void) print_IO_APIC(void)
			struct IO_APIC_route_entry entry;
			struct IR_IO_APIC_route_entry *ir_entry;

			entry = ioapic_read_entry(apic, i);
			entry = ioapic_read_entry(ioapic_idx, i);
			ir_entry = (struct IR_IO_APIC_route_entry *) &entry;
			printk(KERN_DEBUG " %02x %04X ",
				i,
@@ -1685,7 +1671,7 @@ __apicdebuginit(void) print_IO_APIC(void)
		} else {
			struct IO_APIC_route_entry entry;

			entry = ioapic_read_entry(apic, i);
			entry = ioapic_read_entry(ioapic_idx, i);
			printk(KERN_DEBUG " %02x %02X  ",
				i,
				entry.dest
@@ -1705,6 +1691,27 @@ __apicdebuginit(void) print_IO_APIC(void)
	}
}

__apicdebuginit(void) print_IO_APICs(void)
{
	int ioapic_idx;
	struct irq_cfg *cfg;
	unsigned int irq;

	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
		printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
		       mpc_ioapic_id(ioapic_idx),
		       ioapics[ioapic_idx].nr_registers);

	/*
	 * We are a bit conservative about what we expect.  We have to
	 * know about every hardware change ASAP.
	 */
	printk(KERN_INFO "testing the IO APIC.......................\n");

	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
		print_IO_APIC(ioapic_idx);

	printk(KERN_DEBUG "IRQ to pin mappings:\n");
	for_each_active_irq(irq) {
		struct irq_pin_list *entry;
@@ -1722,8 +1729,6 @@ __apicdebuginit(void) print_IO_APIC(void)
	}

	printk(KERN_INFO ".................................... done.\n");

	return;
}

__apicdebuginit(void) print_APIC_field(int base)
@@ -1917,7 +1922,7 @@ __apicdebuginit(int) print_ICs(void)
		return 0;

	print_local_APICs(show_lapic);
	print_IO_APIC();
	print_IO_APICs();

	return 0;
}
@@ -2042,7 +2047,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
{
	union IO_APIC_reg_00 reg_00;
	physid_mask_t phys_id_present_map;
	int apic_id;
	int ioapic_idx;
	int i;
	unsigned char old_id;
	unsigned long flags;
@@ -2056,21 +2061,20 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
	/*
	 * Set the IOAPIC ID to the value stored in the MPC table.
	 */
	for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {

	for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) {
		/* Read the register 0 value */
		raw_spin_lock_irqsave(&ioapic_lock, flags);
		reg_00.raw = io_apic_read(apic_id, 0);
		reg_00.raw = io_apic_read(ioapic_idx, 0);
		raw_spin_unlock_irqrestore(&ioapic_lock, flags);

		old_id = mpc_ioapic_id(apic_id);
		old_id = mpc_ioapic_id(ioapic_idx);

		if (mpc_ioapic_id(apic_id) >= get_physical_broadcast()) {
		if (mpc_ioapic_id(ioapic_idx) >= get_physical_broadcast()) {
			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
				apic_id, mpc_ioapic_id(apic_id));
				ioapic_idx, mpc_ioapic_id(ioapic_idx));
			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
				reg_00.bits.ID);
			ioapics[apic_id].mp_config.apicid = reg_00.bits.ID;
			ioapics[ioapic_idx].mp_config.apicid = reg_00.bits.ID;
		}

		/*
@@ -2079,9 +2083,9 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
		 * 'stuck on smp_invalidate_needed IPI wait' messages.
		 */
		if (apic->check_apicid_used(&phys_id_present_map,
					    mpc_ioapic_id(apic_id))) {
					    mpc_ioapic_id(ioapic_idx))) {
			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
				apic_id, mpc_ioapic_id(apic_id));
				ioapic_idx, mpc_ioapic_id(ioapic_idx));
			for (i = 0; i < get_physical_broadcast(); i++)
				if (!physid_isset(i, phys_id_present_map))
					break;
@@ -2090,14 +2094,14 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
				i);
			physid_set(i, phys_id_present_map);
			ioapics[apic_id].mp_config.apicid = i;
			ioapics[ioapic_idx].mp_config.apicid = i;
		} else {
			physid_mask_t tmp;
			apic->apicid_to_cpu_present(mpc_ioapic_id(apic_id),
			apic->apicid_to_cpu_present(mpc_ioapic_id(ioapic_idx),
						    &tmp);
			apic_printk(APIC_VERBOSE, "Setting %d in the "
					"phys_id_present_map\n",
					mpc_ioapic_id(apic_id));
					mpc_ioapic_id(ioapic_idx));
			physids_or(phys_id_present_map, phys_id_present_map, tmp);
		}

@@ -2105,35 +2109,35 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
		 * We need to adjust the IRQ routing table
		 * if the ID changed.
		 */
		if (old_id != mpc_ioapic_id(apic_id))
		if (old_id != mpc_ioapic_id(ioapic_idx))
			for (i = 0; i < mp_irq_entries; i++)
				if (mp_irqs[i].dstapic == old_id)
					mp_irqs[i].dstapic
						= mpc_ioapic_id(apic_id);
						= mpc_ioapic_id(ioapic_idx);

		/*
		 * Update the ID register according to the right value
		 * from the MPC table if they are different.
		 */
		if (mpc_ioapic_id(apic_id) == reg_00.bits.ID)
		if (mpc_ioapic_id(ioapic_idx) == reg_00.bits.ID)
			continue;

		apic_printk(APIC_VERBOSE, KERN_INFO
			"...changing IO-APIC physical APIC ID to %d ...",
			mpc_ioapic_id(apic_id));
			mpc_ioapic_id(ioapic_idx));

		reg_00.bits.ID = mpc_ioapic_id(apic_id);
		reg_00.bits.ID = mpc_ioapic_id(ioapic_idx);
		raw_spin_lock_irqsave(&ioapic_lock, flags);
		io_apic_write(apic_id, 0, reg_00.raw);
		io_apic_write(ioapic_idx, 0, reg_00.raw);
		raw_spin_unlock_irqrestore(&ioapic_lock, flags);

		/*
		 * Sanity check
		 */
		raw_spin_lock_irqsave(&ioapic_lock, flags);
		reg_00.raw = io_apic_read(apic_id, 0);
		reg_00.raw = io_apic_read(ioapic_idx, 0);
		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
		if (reg_00.bits.ID != mpc_ioapic_id(apic_id))
		if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx))
			printk("could not set ID!\n");
		else
			apic_printk(APIC_VERBOSE, " ok.\n");
@@ -3001,27 +3005,26 @@ static int __init io_apic_bug_finalize(void)

late_initcall(io_apic_bug_finalize);

static void resume_ioapic_id(int ioapic_id)
static void resume_ioapic_id(int ioapic_idx)
{
	unsigned long flags;
	union IO_APIC_reg_00 reg_00;


	raw_spin_lock_irqsave(&ioapic_lock, flags);
	reg_00.raw = io_apic_read(ioapic_id, 0);
	if (reg_00.bits.ID != mpc_ioapic_id(ioapic_id)) {
		reg_00.bits.ID = mpc_ioapic_id(ioapic_id);
		io_apic_write(ioapic_id, 0, reg_00.raw);
	reg_00.raw = io_apic_read(ioapic_idx, 0);
	if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx)) {
		reg_00.bits.ID = mpc_ioapic_id(ioapic_idx);
		io_apic_write(ioapic_idx, 0, reg_00.raw);
	}
	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
}

static void ioapic_resume(void)
{
	int ioapic_id;
	int ioapic_idx;

	for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--)
		resume_ioapic_id(ioapic_id);
	for (ioapic_idx = nr_ioapics - 1; ioapic_idx >= 0; ioapic_idx--)
		resume_ioapic_id(ioapic_idx);

	restore_ioapic_entries();
}
@@ -3558,26 +3561,25 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
		return -EINVAL;
	ret = __add_pin_to_irq_node(cfg, node, attr->ioapic, attr->ioapic_pin);
	if (!ret)
		setup_ioapic_irq(attr->ioapic, attr->ioapic_pin, irq, cfg,
				 attr->trigger, attr->polarity);
		setup_ioapic_irq(irq, cfg, attr);
	return ret;
}

int io_apic_setup_irq_pin_once(unsigned int irq, int node,
			       struct io_apic_irq_attr *attr)
{
	unsigned int id = attr->ioapic, pin = attr->ioapic_pin;
	unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin;
	int ret;

	/* Avoid redundant programming */
	if (test_bit(pin, ioapics[id].pin_programmed)) {
	if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) {
		pr_debug("Pin %d-%d already programmed\n",
			 mpc_ioapic_id(id), pin);
			 mpc_ioapic_id(ioapic_idx), pin);
		return 0;
	}
	ret = io_apic_setup_irq_pin(irq, node, attr);
	if (!ret)
		set_bit(pin, ioapics[id].pin_programmed);
		set_bit(pin, ioapics[ioapic_idx].pin_programmed);
	return ret;
}

@@ -3613,7 +3615,6 @@ int get_nr_irqs_gsi(void)
	return nr_irqs_gsi;
}

#ifdef CONFIG_SPARSE_IRQ
int __init arch_probe_nr_irqs(void)
{
	int nr;
@@ -3633,7 +3634,6 @@ int __init arch_probe_nr_irqs(void)

	return NR_IRQS_LEGACY;
}
#endif

int io_apic_set_pci_routing(struct device *dev, int irq,
			    struct io_apic_irq_attr *irq_attr)
Loading