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

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
...@@ -64,6 +64,7 @@ config X86 ...@@ -64,6 +64,7 @@ config X86
select HAVE_TEXT_POKE_SMP select HAVE_TEXT_POKE_SMP
select HAVE_GENERIC_HARDIRQS select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ select HAVE_SPARSE_IRQ
select SPARSE_IRQ
select GENERIC_FIND_FIRST_BIT select GENERIC_FIND_FIRST_BIT
select GENERIC_IRQ_PROBE select GENERIC_IRQ_PROBE
select GENERIC_PENDING_IRQ if SMP select GENERIC_PENDING_IRQ if SMP
......
...@@ -495,7 +495,7 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert) ...@@ -495,7 +495,7 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert)
return; return;
} }
extern struct apic *generic_bigsmp_probe(void); extern void generic_bigsmp_probe(void);
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
......
...@@ -160,19 +160,11 @@ static inline int invalid_vm86_irq(int irq) ...@@ -160,19 +160,11 @@ static inline int invalid_vm86_irq(int irq)
#define IO_APIC_VECTOR_LIMIT ( 32 * MAX_IO_APICS ) #define IO_APIC_VECTOR_LIMIT ( 32 * MAX_IO_APICS )
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
# ifdef CONFIG_SPARSE_IRQ # define CPU_VECTOR_LIMIT (64 * NR_CPUS)
# define CPU_VECTOR_LIMIT (64 * NR_CPUS) # define NR_IRQS \
# define NR_IRQS \
(CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \ (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \
(NR_VECTORS + CPU_VECTOR_LIMIT) : \ (NR_VECTORS + CPU_VECTOR_LIMIT) : \
(NR_VECTORS + IO_APIC_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: */ #else /* !CONFIG_X86_IO_APIC: */
# define NR_IRQS NR_IRQS_LEGACY # define NR_IRQS NR_IRQS_LEGACY
#endif #endif
......
...@@ -255,12 +255,24 @@ static struct apic apic_bigsmp = { ...@@ -255,12 +255,24 @@ static struct apic apic_bigsmp = {
.x86_32_early_logical_apicid = bigsmp_early_logical_apicid, .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()) unsigned int cpu;
return &apic_bigsmp;
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); apic_driver(apic_bigsmp);
...@@ -92,21 +92,21 @@ static struct ioapic { ...@@ -92,21 +92,21 @@ static struct ioapic {
DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
} ioapics[MAX_IO_APICS]; } 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; int nr_ioapics;
...@@ -186,11 +186,7 @@ static struct irq_pin_list *alloc_irq_pin_list(int node) ...@@ -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. */ /* 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]; 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) int __init arch_early_irq_init(void)
{ {
...@@ -234,7 +230,6 @@ int __init arch_early_irq_init(void) ...@@ -234,7 +230,6 @@ int __init arch_early_irq_init(void)
return 0; return 0;
} }
#ifdef CONFIG_SPARSE_IRQ
static struct irq_cfg *irq_cfg(unsigned int irq) static struct irq_cfg *irq_cfg(unsigned int irq)
{ {
return irq_get_chip_data(irq); return irq_get_chip_data(irq);
...@@ -269,22 +264,6 @@ static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) ...@@ -269,22 +264,6 @@ static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
kfree(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) static struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node)
{ {
int res = irq_alloc_desc_at(at, node); int res = irq_alloc_desc_at(at, node);
...@@ -802,13 +781,13 @@ int restore_ioapic_entries(void) ...@@ -802,13 +781,13 @@ int restore_ioapic_entries(void)
/* /*
* Find the IRQ entry number of a certain pin. * 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; int i;
for (i = 0; i < mp_irq_entries; i++) for (i = 0; i < mp_irq_entries; i++)
if (mp_irqs[i].irqtype == type && 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].dstapic == MP_APIC_ALL) &&
mp_irqs[i].dstirq == pin) mp_irqs[i].dstirq == pin)
return i; return i;
...@@ -847,12 +826,13 @@ static int __init find_isa_irq_apic(int irq, int type) ...@@ -847,12 +826,13 @@ static int __init find_isa_irq_apic(int irq, int type)
(mp_irqs[i].srcbusirq == irq)) (mp_irqs[i].srcbusirq == irq))
break; break;
} }
if (i < mp_irq_entries) { if (i < mp_irq_entries) {
int apic; int ioapic_idx;
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++)
return apic; if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic)
} return ioapic_idx;
} }
return -1; return -1;
...@@ -1067,7 +1047,7 @@ static int pin_2_irq(int idx, int apic, int pin) ...@@ -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, int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
struct io_apic_irq_attr *irq_attr) struct io_apic_irq_attr *irq_attr)
{ {
int apic, i, best_guess = -1; int ioapic_idx, i, best_guess = -1;
apic_printk(APIC_DEBUG, apic_printk(APIC_DEBUG,
"querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n", "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, ...@@ -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++) { for (i = 0; i < mp_irq_entries; i++) {
int lbus = mp_irqs[i].srcbus; int lbus = mp_irqs[i].srcbus;
for (apic = 0; apic < nr_ioapics; apic++) for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic || if (mpc_ioapic_id(ioapic_idx) == mp_irqs[i].dstapic ||
mp_irqs[i].dstapic == MP_APIC_ALL) mp_irqs[i].dstapic == MP_APIC_ALL)
break; break;
...@@ -1089,13 +1069,13 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, ...@@ -1089,13 +1069,13 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
!mp_irqs[i].irqtype && !mp_irqs[i].irqtype &&
(bus == lbus) && (bus == lbus) &&
(slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) { (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; continue;
if (pin == (mp_irqs[i].srcbusirq & 3)) { 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, mp_irqs[i].dstirq,
irq_trigger(i), irq_trigger(i),
irq_polarity(i)); irq_polarity(i));
...@@ -1106,7 +1086,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, ...@@ -1106,7 +1086,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
* best-guess fuzzy result for broken mptables. * best-guess fuzzy result for broken mptables.
*/ */
if (best_guess < 0) { 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, mp_irqs[i].dstirq,
irq_trigger(i), irq_trigger(i),
irq_polarity(i)); irq_polarity(i));
...@@ -1344,77 +1324,100 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, ...@@ -1344,77 +1324,100 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg,
fasteoi ? "fasteoi" : "edge"); fasteoi ? "fasteoi" : "edge");
} }
static int setup_ioapic_entry(int apic_id, int irq,
struct IO_APIC_route_entry *entry, static int setup_ir_ioapic_entry(int irq,
unsigned int destination, int trigger, struct IR_IO_APIC_route_entry *entry,
int polarity, int vector, int pin) unsigned int destination, int vector,
struct io_apic_irq_attr *attr)
{ {
/* int index;
* add it to the IO-APIC irq-routing table: struct irte irte;
*/ int ioapic_id = mpc_ioapic_id(attr->ioapic);
memset(entry,0,sizeof(*entry)); struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id);
if (intr_remapping_enabled) { if (!iommu) {
struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); pr_warn("No mapping iommu for ioapic %d\n", ioapic_id);
struct irte irte; return -ENODEV;
struct IR_IO_APIC_route_entry *ir_entry = }
(struct IR_IO_APIC_route_entry *) entry;
int index;
if (!iommu) index = alloc_irte(iommu, irq, 1);
panic("No mapping iommu for ioapic %d\n", apic_id); if (index < 0) {
pr_warn("Failed to allocate IRTE for ioapic %d\n", ioapic_id);
return -ENOMEM;
}
index = alloc_irte(iommu, irq, 1); prepare_irte(&irte, vector, destination);
if (index < 0)
panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
prepare_irte(&irte, vector, destination); /* Set source-id of interrupt request */
set_ioapic_sid(&irte, ioapic_id);
/* Set source-id of interrupt request */ modify_irte(irq, &irte);
set_ioapic_sid(&irte, apic_id);
modify_irte(irq, &irte); 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",
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);
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;
ir_entry->index2 = (index >> 15) & 0x1; /* Mask level triggered irqs.
ir_entry->zero = 0; * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
ir_entry->format = 1; */
ir_entry->index = (index & 0x7fff); if (attr->trigger)
/* entry->mask = 1;
* IO-APIC RTE will be configured with virtual vector.
* irq handler will do the explicit EOI to the io-apic. return 0;
*/ }
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,
irte.redir_hint, irte.trigger_mode, irte.dlvry_mode,
irte.avail, irte.vector, irte.dest_id,
irte.sid, irte.sq, irte.svt);
} else {
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 */ static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
entry->trigger = trigger; unsigned int destination, int vector,
entry->polarity = polarity; 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);
/* Mask level triggered irqs. 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 = attr->trigger;
entry->polarity = attr->polarity;
/*
* Mask level triggered irqs.
* Use IRQ_DELAYED_DISABLE for edge triggered irqs. * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
*/ */
if (trigger) if (attr->trigger)
entry->mask = 1; entry->mask = 1;
return 0; return 0;
} }
static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq, static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
struct irq_cfg *cfg, int trigger, int polarity) struct io_apic_irq_attr *attr)
{ {
struct IO_APIC_route_entry entry; struct IO_APIC_route_entry entry;
unsigned int dest; unsigned int dest;
...@@ -1437,49 +1440,48 @@ static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq, ...@@ -1437,49 +1440,48 @@ static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq,
apic_printk(APIC_VERBOSE,KERN_DEBUG apic_printk(APIC_VERBOSE,KERN_DEBUG
"IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
"IRQ %d Mode:%i Active:%i Dest:%d)\n", "IRQ %d Mode:%i Active:%i Dest:%d)\n",
apic_id, mpc_ioapic_id(apic_id), pin, cfg->vector, attr->ioapic, mpc_ioapic_id(attr->ioapic), attr->ioapic_pin,
irq, trigger, polarity, dest); cfg->vector, irq, attr->trigger, attr->polarity, dest);
if (setup_ioapic_entry(mpc_ioapic_id(apic_id), irq, &entry, if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) {
dest, trigger, polarity, cfg->vector, pin)) { pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n",
printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
mpc_ioapic_id(apic_id), pin);
__clear_irq_vector(irq, cfg); __clear_irq_vector(irq, cfg);
return; return;
} }
ioapic_register_intr(irq, cfg, trigger); ioapic_register_intr(irq, cfg, attr->trigger);
if (irq < legacy_pic->nr_legacy_irqs) if (irq < legacy_pic->nr_legacy_irqs)
legacy_pic->mask(irq); 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) if (idx != -1)
return false; return false;
apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", 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; 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); int idx, node = cpu_to_node(0);
struct io_apic_irq_attr attr; struct io_apic_irq_attr attr;
unsigned int pin, irq; unsigned int pin, irq;
for (pin = 0; pin < ioapics[apic_id].nr_registers; pin++) { for (pin = 0; pin < ioapics[ioapic_idx].nr_registers; pin++) {
idx = find_irq_entry(apic_id, pin, mp_INT); idx = find_irq_entry(ioapic_idx, pin, mp_INT);
if (io_apic_pin_not_connected(idx, apic_id, pin)) if (io_apic_pin_not_connected(idx, ioapic_idx, pin))
continue; 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; continue;
/* /*
...@@ -1487,10 +1489,10 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id) ...@@ -1487,10 +1489,10 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id)
* installed and if it returns 1: * installed and if it returns 1:
*/ */
if (apic->multi_timer_check && if (apic->multi_timer_check &&
apic->multi_timer_check(apic_id, irq)) apic->multi_timer_check(ioapic_idx, irq))
continue; 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)); irq_polarity(idx));
io_apic_setup_irq_pin(irq, node, &attr); io_apic_setup_irq_pin(irq, node, &attr);
...@@ -1499,12 +1501,12 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id) ...@@ -1499,12 +1501,12 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id)
static void __init setup_IO_APIC_irqs(void) 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"); apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
for (apic_id = 0; apic_id < nr_ioapics; apic_id++) for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
__io_apic_setup_irqs(apic_id); __io_apic_setup_irqs(ioapic_idx);
} }
/* /*
...@@ -1514,28 +1516,28 @@ static void __init setup_IO_APIC_irqs(void) ...@@ -1514,28 +1516,28 @@ static void __init setup_IO_APIC_irqs(void)
*/ */
void setup_IO_APIC_irq_extra(u32 gsi) 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; struct io_apic_irq_attr attr;
/* /*
* Convert 'gsi' to 'ioapic.pin'. * Convert 'gsi' to 'ioapic.pin'.
*/ */
apic_id = mp_find_ioapic(gsi); ioapic_idx = mp_find_ioapic(gsi);
if (apic_id < 0) if (ioapic_idx < 0)
return; return;
pin = mp_find_ioapic_pin(apic_id, gsi); pin = mp_find_ioapic_pin(ioapic_idx, gsi);
idx = find_irq_entry(apic_id, pin, mp_INT); idx = find_irq_entry(ioapic_idx, pin, mp_INT);
if (idx == -1) if (idx == -1)
return; 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 */ /* 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; 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)); irq_polarity(idx));
io_apic_setup_irq_pin_once(irq, node, &attr); io_apic_setup_irq_pin_once(irq, node, &attr);
...@@ -1544,8 +1546,8 @@ void setup_IO_APIC_irq_extra(u32 gsi) ...@@ -1544,8 +1546,8 @@ void setup_IO_APIC_irq_extra(u32 gsi)
/* /*
* Set up the timer pin, possibly with the 8259A-master behind. * 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, static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,
int vector) unsigned int pin, int vector)
{ {
struct IO_APIC_route_entry entry; struct IO_APIC_route_entry entry;
...@@ -1576,45 +1578,29 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, ...@@ -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: * 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(int ioapic_idx)
__apicdebuginit(void) print_IO_APIC(void)
{ {
int apic, i; int i;
union IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
union IO_APIC_reg_01 reg_01; union IO_APIC_reg_01 reg_01;
union IO_APIC_reg_02 reg_02; union IO_APIC_reg_02 reg_02;
union IO_APIC_reg_03 reg_03; union IO_APIC_reg_03 reg_03;
unsigned long flags; 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); raw_spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(apic, 0); reg_00.raw = io_apic_read(ioapic_idx, 0);
reg_01.raw = io_apic_read(apic, 1); reg_01.raw = io_apic_read(ioapic_idx, 1);
if (reg_01.bits.version >= 0x10) 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) 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); raw_spin_unlock_irqrestore(&ioapic_lock, flags);
printk("\n"); 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 ".... register #00: %08X\n", reg_00.raw);
printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID);
printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type);
...@@ -1664,7 +1650,7 @@ __apicdebuginit(void) print_IO_APIC(void) ...@@ -1664,7 +1650,7 @@ __apicdebuginit(void) print_IO_APIC(void)
struct IO_APIC_route_entry entry; struct IO_APIC_route_entry entry;
struct IR_IO_APIC_route_entry *ir_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; ir_entry = (struct IR_IO_APIC_route_entry *) &entry;
printk(KERN_DEBUG " %02x %04X ", printk(KERN_DEBUG " %02x %04X ",
i, i,
...@@ -1685,7 +1671,7 @@ __apicdebuginit(void) print_IO_APIC(void) ...@@ -1685,7 +1671,7 @@ __apicdebuginit(void) print_IO_APIC(void)
} else { } else {
struct IO_APIC_route_entry entry; struct IO_APIC_route_entry entry;
entry = ioapic_read_entry(apic, i); entry = ioapic_read_entry(ioapic_idx, i);
printk(KERN_DEBUG " %02x %02X ", printk(KERN_DEBUG " %02x %02X ",
i, i,
entry.dest entry.dest
...@@ -1703,7 +1689,28 @@ __apicdebuginit(void) print_IO_APIC(void) ...@@ -1703,7 +1689,28 @@ __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"); printk(KERN_DEBUG "IRQ to pin mappings:\n");
for_each_active_irq(irq) { for_each_active_irq(irq) {
...@@ -1722,8 +1729,6 @@ __apicdebuginit(void) print_IO_APIC(void) ...@@ -1722,8 +1729,6 @@ __apicdebuginit(void) print_IO_APIC(void)
} }
printk(KERN_INFO ".................................... done.\n"); printk(KERN_INFO ".................................... done.\n");
return;
} }
__apicdebuginit(void) print_APIC_field(int base) __apicdebuginit(void) print_APIC_field(int base)
...@@ -1917,7 +1922,7 @@ __apicdebuginit(int) print_ICs(void) ...@@ -1917,7 +1922,7 @@ __apicdebuginit(int) print_ICs(void)
return 0; return 0;
print_local_APICs(show_lapic); print_local_APICs(show_lapic);
print_IO_APIC(); print_IO_APICs();
return 0; return 0;
} }
...@@ -2042,7 +2047,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) ...@@ -2042,7 +2047,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
{ {
union IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
physid_mask_t phys_id_present_map; physid_mask_t phys_id_present_map;
int apic_id; int ioapic_idx;
int i; int i;
unsigned char old_id; unsigned char old_id;
unsigned long flags; unsigned long flags;
...@@ -2056,21 +2061,20 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) ...@@ -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. * 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 */ /* Read the register 0 value */
raw_spin_lock_irqsave(&ioapic_lock, flags); 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); 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", 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", printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
reg_00.bits.ID); 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) ...@@ -2079,9 +2083,9 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
* 'stuck on smp_invalidate_needed IPI wait' messages. * 'stuck on smp_invalidate_needed IPI wait' messages.
*/ */
if (apic->check_apicid_used(&phys_id_present_map, 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", 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++) for (i = 0; i < get_physical_broadcast(); i++)
if (!physid_isset(i, phys_id_present_map)) if (!physid_isset(i, phys_id_present_map))
break; break;
...@@ -2090,14 +2094,14 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) ...@@ -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", printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
i); i);
physid_set(i, phys_id_present_map); physid_set(i, phys_id_present_map);
ioapics[apic_id].mp_config.apicid = i; ioapics[ioapic_idx].mp_config.apicid = i;
} else { } else {
physid_mask_t tmp; 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); &tmp);
apic_printk(APIC_VERBOSE, "Setting %d in the " apic_printk(APIC_VERBOSE, "Setting %d in the "
"phys_id_present_map\n", "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); physids_or(phys_id_present_map, phys_id_present_map, tmp);
} }
...@@ -2105,35 +2109,35 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) ...@@ -2105,35 +2109,35 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
* We need to adjust the IRQ routing table * We need to adjust the IRQ routing table
* if the ID changed. * 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++) for (i = 0; i < mp_irq_entries; i++)
if (mp_irqs[i].dstapic == old_id) if (mp_irqs[i].dstapic == old_id)
mp_irqs[i].dstapic mp_irqs[i].dstapic
= mpc_ioapic_id(apic_id); = mpc_ioapic_id(ioapic_idx);
/* /*
* Update the ID register according to the right value * Update the ID register according to the right value
* from the MPC table if they are different. * 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; 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 ...",
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); 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); raw_spin_unlock_irqrestore(&ioapic_lock, flags);
/* /*
* Sanity check * Sanity check
*/ */
raw_spin_lock_irqsave(&ioapic_lock, flags); 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); 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"); printk("could not set ID!\n");
else else
apic_printk(APIC_VERBOSE, " ok.\n"); apic_printk(APIC_VERBOSE, " ok.\n");
...@@ -3001,27 +3005,26 @@ static int __init io_apic_bug_finalize(void) ...@@ -3001,27 +3005,26 @@ static int __init io_apic_bug_finalize(void)
late_initcall(io_apic_bug_finalize); 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; unsigned long flags;
union IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
raw_spin_lock_irqsave(&ioapic_lock, flags); raw_spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(ioapic_id, 0); reg_00.raw = io_apic_read(ioapic_idx, 0);
if (reg_00.bits.ID != mpc_ioapic_id(ioapic_id)) { if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx)) {
reg_00.bits.ID = mpc_ioapic_id(ioapic_id); reg_00.bits.ID = mpc_ioapic_id(ioapic_idx);
io_apic_write(ioapic_id, 0, reg_00.raw); io_apic_write(ioapic_idx, 0, reg_00.raw);
} }
raw_spin_unlock_irqrestore(&ioapic_lock, flags); raw_spin_unlock_irqrestore(&ioapic_lock, flags);
} }
static void ioapic_resume(void) static void ioapic_resume(void)
{ {
int ioapic_id; int ioapic_idx;
for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--) for (ioapic_idx = nr_ioapics - 1; ioapic_idx >= 0; ioapic_idx--)
resume_ioapic_id(ioapic_id); resume_ioapic_id(ioapic_idx);
restore_ioapic_entries(); restore_ioapic_entries();
} }
...@@ -3558,26 +3561,25 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) ...@@ -3558,26 +3561,25 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr)
return -EINVAL; return -EINVAL;
ret = __add_pin_to_irq_node(cfg, node, attr->ioapic, attr->ioapic_pin); ret = __add_pin_to_irq_node(cfg, node, attr->ioapic, attr->ioapic_pin);
if (!ret) if (!ret)
setup_ioapic_irq(attr->ioapic, attr->ioapic_pin, irq, cfg, setup_ioapic_irq(irq, cfg, attr);
attr->trigger, attr->polarity);
return ret; return ret;
} }
int io_apic_setup_irq_pin_once(unsigned int irq, int node, int io_apic_setup_irq_pin_once(unsigned int irq, int node,
struct io_apic_irq_attr *attr) 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; int ret;
/* Avoid redundant programming */ /* 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", pr_debug("Pin %d-%d already programmed\n",
mpc_ioapic_id(id), pin); mpc_ioapic_id(ioapic_idx), pin);
return 0; return 0;
} }
ret = io_apic_setup_irq_pin(irq, node, attr); ret = io_apic_setup_irq_pin(irq, node, attr);
if (!ret) if (!ret)
set_bit(pin, ioapics[id].pin_programmed); set_bit(pin, ioapics[ioapic_idx].pin_programmed);
return ret; return ret;
} }
...@@ -3613,7 +3615,6 @@ int get_nr_irqs_gsi(void) ...@@ -3613,7 +3615,6 @@ int get_nr_irqs_gsi(void)
return nr_irqs_gsi; return nr_irqs_gsi;
} }
#ifdef CONFIG_SPARSE_IRQ
int __init arch_probe_nr_irqs(void) int __init arch_probe_nr_irqs(void)
{ {
int nr; int nr;
...@@ -3633,7 +3634,6 @@ int __init arch_probe_nr_irqs(void) ...@@ -3633,7 +3634,6 @@ int __init arch_probe_nr_irqs(void)
return NR_IRQS_LEGACY; return NR_IRQS_LEGACY;
} }
#endif
int io_apic_set_pci_routing(struct device *dev, int irq, int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr) struct io_apic_irq_attr *irq_attr)
......
...@@ -200,14 +200,8 @@ void __init default_setup_apic_routing(void) ...@@ -200,14 +200,8 @@ void __init default_setup_apic_routing(void)
* - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
*/ */
if (!cmdline_apic && apic == &apic_default) { if (!cmdline_apic && apic == &apic_default)
struct apic *bigsmp = generic_bigsmp_probe(); generic_bigsmp_probe();
if (bigsmp) {
apic = bigsmp;
printk(KERN_INFO "Overriding APIC driver with %s\n",
apic->name);
}
}
#endif #endif
if (apic->setup_apic_routing) if (apic->setup_apic_routing)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment