Loading arch/x86/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -811,7 +811,7 @@ config X86_LOCAL_APIC config X86_IO_APIC def_bool y depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC config X86_VISWS_APIC def_bool y Loading arch/x86/include/asm/apicdef.h +12 −0 Original line number Diff line number Diff line Loading @@ -426,4 +426,16 @@ struct local_apic { #else #define BAD_APICID 0xFFFFu #endif enum ioapic_irq_destination_types { dest_Fixed = 0, dest_LowestPrio = 1, dest_SMI = 2, dest__reserved_1 = 3, dest_NMI = 4, dest_INIT = 5, dest__reserved_2 = 6, dest_ExtINT = 7 }; #endif /* _ASM_X86_APICDEF_H */ arch/x86/include/asm/io_apic.h +28 −16 Original line number Diff line number Diff line Loading @@ -63,17 +63,6 @@ union IO_APIC_reg_03 { } __attribute__ ((packed)) bits; }; enum ioapic_irq_destination_types { dest_Fixed = 0, dest_LowestPrio = 1, dest_SMI = 2, dest__reserved_1 = 3, dest_NMI = 4, dest_INIT = 5, dest__reserved_2 = 6, dest_ExtINT = 7 }; struct IO_APIC_route_entry { __u32 vector : 8, delivery_mode : 3, /* 000: FIXED Loading Loading @@ -106,6 +95,10 @@ struct IR_IO_APIC_route_entry { index : 15; } __attribute__ ((packed)); #define IOAPIC_AUTO -1 #define IOAPIC_EDGE 0 #define IOAPIC_LEVEL 1 #ifdef CONFIG_X86_IO_APIC /* Loading Loading @@ -150,11 +143,6 @@ extern int timer_through_8259; #define io_apic_assign_pci_irqs \ (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) extern u8 io_apic_unique_id(u8 id); extern int io_apic_get_unique_id(int ioapic, int apic_id); extern int io_apic_get_version(int ioapic); extern int io_apic_get_redir_entries(int ioapic); struct io_apic_irq_attr; extern int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr); Loading @@ -162,6 +150,8 @@ void setup_IO_APIC_irq_extra(u32 gsi); extern void ioapic_and_gsi_init(void); extern void ioapic_insert_resources(void); int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr); extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); Loading @@ -186,6 +176,8 @@ extern void __init pre_init_apic_IRQ0(void); extern void mp_save_irq(struct mpc_intsrc *m); extern void disable_ioapic_support(void); #else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0 Loading @@ -199,6 +191,26 @@ static inline int mp_find_ioapic(u32 gsi) { return 0; } struct io_apic_irq_attr; static inline int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr) { return 0; } static inline struct IO_APIC_route_entry **alloc_ioapic_entries(void) { return NULL; } static inline void free_ioapic_entries(struct IO_APIC_route_entry **ent) { } static inline int save_IO_APIC_setup(struct IO_APIC_route_entry **ent) { return -ENOMEM; } static inline void mask_IO_APIC_setup(struct IO_APIC_route_entry **ent) { } static inline int restore_IO_APIC_setup(struct IO_APIC_route_entry **ent) { return -ENOMEM; } static inline void mp_save_irq(struct mpc_intsrc *m) { }; static inline void disable_ioapic_support(void) { } #endif #endif /* _ASM_X86_IO_APIC_H */ arch/x86/kernel/apic/apic.c +3 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <asm/i8259.h> #include <asm/proto.h> #include <asm/apic.h> #include <asm/io_apic.h> #include <asm/desc.h> #include <asm/hpet.h> #include <asm/idle.h> Loading Loading @@ -1209,7 +1210,7 @@ void __cpuinit setup_local_APIC(void) rdtscll(tsc); if (disable_apic) { arch_disable_smp_support(); disable_ioapic_support(); return; } Loading Loading @@ -1448,7 +1449,7 @@ int __init enable_IR(void) void __init enable_IR_x2apic(void) { unsigned long flags; struct IO_APIC_route_entry **ioapic_entries = NULL; struct IO_APIC_route_entry **ioapic_entries; int ret, x2apic_enabled = 0; int dmar_table_init_ret; Loading arch/x86/kernel/apic/io_apic.c +109 −156 Original line number Diff line number Diff line Loading @@ -108,7 +108,10 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); int skip_ioapic_setup; void arch_disable_smp_support(void) /** * disable_ioapic_support() - disables ioapic support at runtime */ void disable_ioapic_support(void) { #ifdef CONFIG_PCI noioapicquirk = 1; Loading @@ -120,11 +123,14 @@ void arch_disable_smp_support(void) static int __init parse_noapic(char *str) { /* disable IO-APIC */ arch_disable_smp_support(); disable_ioapic_support(); return 0; } early_param("noapic", parse_noapic); static int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ void mp_save_irq(struct mpc_intsrc *m) { Loading Loading @@ -818,7 +824,7 @@ static int EISA_ELCR(unsigned int irq) #define default_MCA_trigger(idx) (1) #define default_MCA_polarity(idx) default_ISA_polarity(idx) static int MPBIOS_polarity(int idx) static int irq_polarity(int idx) { int bus = mp_irqs[idx].srcbus; int polarity; Loading Loading @@ -860,7 +866,7 @@ static int MPBIOS_polarity(int idx) return polarity; } static int MPBIOS_trigger(int idx) static int irq_trigger(int idx) { int bus = mp_irqs[idx].srcbus; int trigger; Loading Loading @@ -932,16 +938,6 @@ static int MPBIOS_trigger(int idx) return trigger; } static inline int irq_polarity(int idx) { return MPBIOS_polarity(idx); } static inline int irq_trigger(int idx) { return MPBIOS_trigger(idx); } static int pin_2_irq(int idx, int apic, int pin) { int irq; Loading Loading @@ -1220,10 +1216,6 @@ void __setup_vector_irq(int cpu) static struct irq_chip ioapic_chip; static struct irq_chip ir_ioapic_chip; #define IOAPIC_AUTO -1 #define IOAPIC_EDGE 0 #define IOAPIC_LEVEL 1 #ifdef CONFIG_X86_32 static inline int IO_APIC_irq_trigger(int irq) { Loading Loading @@ -1385,33 +1377,26 @@ static struct { DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); } mp_ioapic_routing[MAX_IO_APICS]; static void __init setup_IO_APIC_irqs(void) static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin) { int apic_id, pin, idx, irq, notcon = 0; int node = cpu_to_node(0); struct irq_cfg *cfg; if (idx != -1) return false; apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", mp_ioapics[apic_id].apicid, pin); return true; } static void __init __io_apic_setup_irqs(unsigned int apic_id) { int idx, node = cpu_to_node(0); struct io_apic_irq_attr attr; unsigned int pin, irq; for (apic_id = 0; apic_id < nr_ioapics; apic_id++) for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { idx = find_irq_entry(apic_id, pin, mp_INT); if (idx == -1) { if (!notcon) { notcon = 1; apic_printk(APIC_VERBOSE, KERN_DEBUG " %d-%d", mp_ioapics[apic_id].apicid, pin); } else apic_printk(APIC_VERBOSE, " %d-%d", mp_ioapics[apic_id].apicid, pin); if (io_apic_pin_not_connected(idx, apic_id, pin)) continue; } if (notcon) { apic_printk(APIC_VERBOSE, " (apicid-pin) not connected\n"); notcon = 0; } irq = pin_2_irq(idx, apic_id, pin); Loading @@ -1426,22 +1411,21 @@ static void __init setup_IO_APIC_irqs(void) apic->multi_timer_check(apic_id, irq)) continue; cfg = alloc_irq_and_cfg_at(irq, node); if (!cfg) continue; add_pin_to_irq_node(cfg, node, apic_id, pin); /* * don't mark it in pin_programmed, so later acpi could * set it correctly when irq < 16 */ setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx), set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), irq_polarity(idx)); io_apic_setup_irq_pin(irq, node, &attr); } } if (notcon) apic_printk(APIC_VERBOSE, " (apicid-pin) not connected\n"); static void __init setup_IO_APIC_irqs(void) { unsigned int apic_id; 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); } /* Loading @@ -1452,7 +1436,7 @@ 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); struct irq_cfg *cfg; struct io_apic_irq_attr attr; /* * Convert 'gsi' to 'ioapic.pin'. Loading @@ -1472,21 +1456,10 @@ void setup_IO_APIC_irq_extra(u32 gsi) if (apic_id == 0 || irq < NR_IRQS_LEGACY) return; cfg = alloc_irq_and_cfg_at(irq, node); if (!cfg) return; add_pin_to_irq_node(cfg, node, apic_id, pin); if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { pr_debug("Pin %d-%d already programmed\n", mp_ioapics[apic_id].apicid, pin); return; } set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), irq_polarity(idx)); setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx), irq_polarity(idx)); io_apic_setup_irq_pin_once(irq, node, &attr); } /* Loading Loading @@ -3605,7 +3578,40 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) } #endif /* CONFIG_HT_IRQ */ int __init io_apic_get_redir_entries (int ioapic) int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) { struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); int ret; if (!cfg) 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); return ret; } static 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; int ret; /* Avoid redundant programming */ if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) { pr_debug("Pin %d-%d already programmed\n", mp_ioapics[id].apicid, pin); return 0; } ret = io_apic_setup_irq_pin(irq, node, attr); if (!ret) set_bit(pin, mp_ioapic_routing[id].pin_programmed); return ret; } static int __init io_apic_get_redir_entries(int ioapic) { union IO_APIC_reg_01 reg_01; unsigned long flags; Loading Loading @@ -3659,96 +3665,24 @@ int __init arch_probe_nr_irqs(void) } #endif static 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 irq_cfg *cfg; int node; int ioapic, pin; int trigger, polarity; ioapic = irq_attr->ioapic; if (!IO_APIC_IRQ(irq)) { apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", ioapic); irq_attr->ioapic); return -EINVAL; } if (dev) node = dev_to_node(dev); else node = cpu_to_node(0); cfg = alloc_irq_and_cfg_at(irq, node); if (!cfg) return 0; pin = irq_attr->ioapic_pin; trigger = irq_attr->trigger; polarity = irq_attr->polarity; /* * IRQs < 16 are already in the irq_2_pin[] map */ if (irq >= legacy_pic->nr_legacy_irqs) { if (__add_pin_to_irq_node(cfg, node, ioapic, pin)) { printk(KERN_INFO "can not add pin %d for irq %d\n", pin, irq); return 0; } } setup_ioapic_irq(ioapic, pin, irq, cfg, trigger, polarity); return 0; } int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr) { int ioapic, pin; /* * Avoid pin reprogramming. PRTs typically include entries * with redundant pin->gsi mappings (but unique PCI devices); * we only program the IOAPIC on the first. */ ioapic = irq_attr->ioapic; pin = irq_attr->ioapic_pin; if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) { pr_debug("Pin %d-%d already programmed\n", mp_ioapics[ioapic].apicid, pin); return 0; } set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed); node = dev ? dev_to_node(dev) : cpu_to_node(0); return __io_apic_set_pci_routing(dev, irq, irq_attr); return io_apic_setup_irq_pin_once(irq, node, irq_attr); } u8 __init io_apic_unique_id(u8 id) { #ifdef CONFIG_X86_32 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) return io_apic_get_unique_id(nr_ioapics, id); else return id; #else int i; DECLARE_BITMAP(used, 256); bitmap_zero(used, 256); for (i = 0; i < nr_ioapics; i++) { struct mpc_ioapic *ia = &mp_ioapics[i]; __set_bit(ia->apicid, used); } if (!test_bit(id, used)) return id; return find_first_zero_bit(used, 256); #endif } #ifdef CONFIG_X86_32 int __init io_apic_get_unique_id(int ioapic, int apic_id) static int __init io_apic_get_unique_id(int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; static physid_mask_t apic_id_map = PHYSID_MASK_NONE; Loading Loading @@ -3821,9 +3755,33 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) return apic_id; } static u8 __init io_apic_unique_id(u8 id) { if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) return io_apic_get_unique_id(nr_ioapics, id); else return id; } #else static u8 __init io_apic_unique_id(u8 id) { int i; DECLARE_BITMAP(used, 256); bitmap_zero(used, 256); for (i = 0; i < nr_ioapics; i++) { struct mpc_ioapic *ia = &mp_ioapics[i]; __set_bit(ia->apicid, used); } if (!test_bit(id, used)) return id; return find_first_zero_bit(used, 256); } #endif int __init io_apic_get_version(int ioapic) static int __init io_apic_get_version(int ioapic) { union IO_APIC_reg_01 reg_01; unsigned long flags; Loading Loading @@ -4026,7 +3984,7 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi) return gsi - mp_gsi_routing[ioapic].gsi_base; } static int bad_ioapic(unsigned long address) static __init int bad_ioapic(unsigned long address) { if (nr_ioapics >= MAX_IO_APICS) { printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " Loading Loading @@ -4086,20 +4044,15 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) /* Enable IOAPIC early just for system timer */ void __init pre_init_apic_IRQ0(void) { struct irq_cfg *cfg; struct io_apic_irq_attr attr = { 0, 0, 0, 0 }; printk(KERN_INFO "Early APIC setup for system timer0\n"); #ifndef CONFIG_SMP physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); #endif /* Make sure the irq descriptor is set up */ cfg = alloc_irq_and_cfg_at(0, 0); setup_local_APIC(); add_pin_to_irq_node(cfg, 0, 0, 0); io_apic_setup_irq_pin(0, 0, &attr); set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); setup_ioapic_irq(0, 0, 0, cfg, 0, 0); } Loading
arch/x86/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -811,7 +811,7 @@ config X86_LOCAL_APIC config X86_IO_APIC def_bool y depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC config X86_VISWS_APIC def_bool y Loading
arch/x86/include/asm/apicdef.h +12 −0 Original line number Diff line number Diff line Loading @@ -426,4 +426,16 @@ struct local_apic { #else #define BAD_APICID 0xFFFFu #endif enum ioapic_irq_destination_types { dest_Fixed = 0, dest_LowestPrio = 1, dest_SMI = 2, dest__reserved_1 = 3, dest_NMI = 4, dest_INIT = 5, dest__reserved_2 = 6, dest_ExtINT = 7 }; #endif /* _ASM_X86_APICDEF_H */
arch/x86/include/asm/io_apic.h +28 −16 Original line number Diff line number Diff line Loading @@ -63,17 +63,6 @@ union IO_APIC_reg_03 { } __attribute__ ((packed)) bits; }; enum ioapic_irq_destination_types { dest_Fixed = 0, dest_LowestPrio = 1, dest_SMI = 2, dest__reserved_1 = 3, dest_NMI = 4, dest_INIT = 5, dest__reserved_2 = 6, dest_ExtINT = 7 }; struct IO_APIC_route_entry { __u32 vector : 8, delivery_mode : 3, /* 000: FIXED Loading Loading @@ -106,6 +95,10 @@ struct IR_IO_APIC_route_entry { index : 15; } __attribute__ ((packed)); #define IOAPIC_AUTO -1 #define IOAPIC_EDGE 0 #define IOAPIC_LEVEL 1 #ifdef CONFIG_X86_IO_APIC /* Loading Loading @@ -150,11 +143,6 @@ extern int timer_through_8259; #define io_apic_assign_pci_irqs \ (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) extern u8 io_apic_unique_id(u8 id); extern int io_apic_get_unique_id(int ioapic, int apic_id); extern int io_apic_get_version(int ioapic); extern int io_apic_get_redir_entries(int ioapic); struct io_apic_irq_attr; extern int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr); Loading @@ -162,6 +150,8 @@ void setup_IO_APIC_irq_extra(u32 gsi); extern void ioapic_and_gsi_init(void); extern void ioapic_insert_resources(void); int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr); extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); Loading @@ -186,6 +176,8 @@ extern void __init pre_init_apic_IRQ0(void); extern void mp_save_irq(struct mpc_intsrc *m); extern void disable_ioapic_support(void); #else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0 Loading @@ -199,6 +191,26 @@ static inline int mp_find_ioapic(u32 gsi) { return 0; } struct io_apic_irq_attr; static inline int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr) { return 0; } static inline struct IO_APIC_route_entry **alloc_ioapic_entries(void) { return NULL; } static inline void free_ioapic_entries(struct IO_APIC_route_entry **ent) { } static inline int save_IO_APIC_setup(struct IO_APIC_route_entry **ent) { return -ENOMEM; } static inline void mask_IO_APIC_setup(struct IO_APIC_route_entry **ent) { } static inline int restore_IO_APIC_setup(struct IO_APIC_route_entry **ent) { return -ENOMEM; } static inline void mp_save_irq(struct mpc_intsrc *m) { }; static inline void disable_ioapic_support(void) { } #endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/kernel/apic/apic.c +3 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <asm/i8259.h> #include <asm/proto.h> #include <asm/apic.h> #include <asm/io_apic.h> #include <asm/desc.h> #include <asm/hpet.h> #include <asm/idle.h> Loading Loading @@ -1209,7 +1210,7 @@ void __cpuinit setup_local_APIC(void) rdtscll(tsc); if (disable_apic) { arch_disable_smp_support(); disable_ioapic_support(); return; } Loading Loading @@ -1448,7 +1449,7 @@ int __init enable_IR(void) void __init enable_IR_x2apic(void) { unsigned long flags; struct IO_APIC_route_entry **ioapic_entries = NULL; struct IO_APIC_route_entry **ioapic_entries; int ret, x2apic_enabled = 0; int dmar_table_init_ret; Loading
arch/x86/kernel/apic/io_apic.c +109 −156 Original line number Diff line number Diff line Loading @@ -108,7 +108,10 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); int skip_ioapic_setup; void arch_disable_smp_support(void) /** * disable_ioapic_support() - disables ioapic support at runtime */ void disable_ioapic_support(void) { #ifdef CONFIG_PCI noioapicquirk = 1; Loading @@ -120,11 +123,14 @@ void arch_disable_smp_support(void) static int __init parse_noapic(char *str) { /* disable IO-APIC */ arch_disable_smp_support(); disable_ioapic_support(); return 0; } early_param("noapic", parse_noapic); static int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ void mp_save_irq(struct mpc_intsrc *m) { Loading Loading @@ -818,7 +824,7 @@ static int EISA_ELCR(unsigned int irq) #define default_MCA_trigger(idx) (1) #define default_MCA_polarity(idx) default_ISA_polarity(idx) static int MPBIOS_polarity(int idx) static int irq_polarity(int idx) { int bus = mp_irqs[idx].srcbus; int polarity; Loading Loading @@ -860,7 +866,7 @@ static int MPBIOS_polarity(int idx) return polarity; } static int MPBIOS_trigger(int idx) static int irq_trigger(int idx) { int bus = mp_irqs[idx].srcbus; int trigger; Loading Loading @@ -932,16 +938,6 @@ static int MPBIOS_trigger(int idx) return trigger; } static inline int irq_polarity(int idx) { return MPBIOS_polarity(idx); } static inline int irq_trigger(int idx) { return MPBIOS_trigger(idx); } static int pin_2_irq(int idx, int apic, int pin) { int irq; Loading Loading @@ -1220,10 +1216,6 @@ void __setup_vector_irq(int cpu) static struct irq_chip ioapic_chip; static struct irq_chip ir_ioapic_chip; #define IOAPIC_AUTO -1 #define IOAPIC_EDGE 0 #define IOAPIC_LEVEL 1 #ifdef CONFIG_X86_32 static inline int IO_APIC_irq_trigger(int irq) { Loading Loading @@ -1385,33 +1377,26 @@ static struct { DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); } mp_ioapic_routing[MAX_IO_APICS]; static void __init setup_IO_APIC_irqs(void) static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin) { int apic_id, pin, idx, irq, notcon = 0; int node = cpu_to_node(0); struct irq_cfg *cfg; if (idx != -1) return false; apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", mp_ioapics[apic_id].apicid, pin); return true; } static void __init __io_apic_setup_irqs(unsigned int apic_id) { int idx, node = cpu_to_node(0); struct io_apic_irq_attr attr; unsigned int pin, irq; for (apic_id = 0; apic_id < nr_ioapics; apic_id++) for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { idx = find_irq_entry(apic_id, pin, mp_INT); if (idx == -1) { if (!notcon) { notcon = 1; apic_printk(APIC_VERBOSE, KERN_DEBUG " %d-%d", mp_ioapics[apic_id].apicid, pin); } else apic_printk(APIC_VERBOSE, " %d-%d", mp_ioapics[apic_id].apicid, pin); if (io_apic_pin_not_connected(idx, apic_id, pin)) continue; } if (notcon) { apic_printk(APIC_VERBOSE, " (apicid-pin) not connected\n"); notcon = 0; } irq = pin_2_irq(idx, apic_id, pin); Loading @@ -1426,22 +1411,21 @@ static void __init setup_IO_APIC_irqs(void) apic->multi_timer_check(apic_id, irq)) continue; cfg = alloc_irq_and_cfg_at(irq, node); if (!cfg) continue; add_pin_to_irq_node(cfg, node, apic_id, pin); /* * don't mark it in pin_programmed, so later acpi could * set it correctly when irq < 16 */ setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx), set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), irq_polarity(idx)); io_apic_setup_irq_pin(irq, node, &attr); } } if (notcon) apic_printk(APIC_VERBOSE, " (apicid-pin) not connected\n"); static void __init setup_IO_APIC_irqs(void) { unsigned int apic_id; 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); } /* Loading @@ -1452,7 +1436,7 @@ 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); struct irq_cfg *cfg; struct io_apic_irq_attr attr; /* * Convert 'gsi' to 'ioapic.pin'. Loading @@ -1472,21 +1456,10 @@ void setup_IO_APIC_irq_extra(u32 gsi) if (apic_id == 0 || irq < NR_IRQS_LEGACY) return; cfg = alloc_irq_and_cfg_at(irq, node); if (!cfg) return; add_pin_to_irq_node(cfg, node, apic_id, pin); if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { pr_debug("Pin %d-%d already programmed\n", mp_ioapics[apic_id].apicid, pin); return; } set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); set_io_apic_irq_attr(&attr, apic_id, pin, irq_trigger(idx), irq_polarity(idx)); setup_ioapic_irq(apic_id, pin, irq, cfg, irq_trigger(idx), irq_polarity(idx)); io_apic_setup_irq_pin_once(irq, node, &attr); } /* Loading Loading @@ -3605,7 +3578,40 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) } #endif /* CONFIG_HT_IRQ */ int __init io_apic_get_redir_entries (int ioapic) int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) { struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); int ret; if (!cfg) 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); return ret; } static 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; int ret; /* Avoid redundant programming */ if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) { pr_debug("Pin %d-%d already programmed\n", mp_ioapics[id].apicid, pin); return 0; } ret = io_apic_setup_irq_pin(irq, node, attr); if (!ret) set_bit(pin, mp_ioapic_routing[id].pin_programmed); return ret; } static int __init io_apic_get_redir_entries(int ioapic) { union IO_APIC_reg_01 reg_01; unsigned long flags; Loading Loading @@ -3659,96 +3665,24 @@ int __init arch_probe_nr_irqs(void) } #endif static 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 irq_cfg *cfg; int node; int ioapic, pin; int trigger, polarity; ioapic = irq_attr->ioapic; if (!IO_APIC_IRQ(irq)) { apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", ioapic); irq_attr->ioapic); return -EINVAL; } if (dev) node = dev_to_node(dev); else node = cpu_to_node(0); cfg = alloc_irq_and_cfg_at(irq, node); if (!cfg) return 0; pin = irq_attr->ioapic_pin; trigger = irq_attr->trigger; polarity = irq_attr->polarity; /* * IRQs < 16 are already in the irq_2_pin[] map */ if (irq >= legacy_pic->nr_legacy_irqs) { if (__add_pin_to_irq_node(cfg, node, ioapic, pin)) { printk(KERN_INFO "can not add pin %d for irq %d\n", pin, irq); return 0; } } setup_ioapic_irq(ioapic, pin, irq, cfg, trigger, polarity); return 0; } int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr) { int ioapic, pin; /* * Avoid pin reprogramming. PRTs typically include entries * with redundant pin->gsi mappings (but unique PCI devices); * we only program the IOAPIC on the first. */ ioapic = irq_attr->ioapic; pin = irq_attr->ioapic_pin; if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) { pr_debug("Pin %d-%d already programmed\n", mp_ioapics[ioapic].apicid, pin); return 0; } set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed); node = dev ? dev_to_node(dev) : cpu_to_node(0); return __io_apic_set_pci_routing(dev, irq, irq_attr); return io_apic_setup_irq_pin_once(irq, node, irq_attr); } u8 __init io_apic_unique_id(u8 id) { #ifdef CONFIG_X86_32 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) return io_apic_get_unique_id(nr_ioapics, id); else return id; #else int i; DECLARE_BITMAP(used, 256); bitmap_zero(used, 256); for (i = 0; i < nr_ioapics; i++) { struct mpc_ioapic *ia = &mp_ioapics[i]; __set_bit(ia->apicid, used); } if (!test_bit(id, used)) return id; return find_first_zero_bit(used, 256); #endif } #ifdef CONFIG_X86_32 int __init io_apic_get_unique_id(int ioapic, int apic_id) static int __init io_apic_get_unique_id(int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; static physid_mask_t apic_id_map = PHYSID_MASK_NONE; Loading Loading @@ -3821,9 +3755,33 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) return apic_id; } static u8 __init io_apic_unique_id(u8 id) { if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) return io_apic_get_unique_id(nr_ioapics, id); else return id; } #else static u8 __init io_apic_unique_id(u8 id) { int i; DECLARE_BITMAP(used, 256); bitmap_zero(used, 256); for (i = 0; i < nr_ioapics; i++) { struct mpc_ioapic *ia = &mp_ioapics[i]; __set_bit(ia->apicid, used); } if (!test_bit(id, used)) return id; return find_first_zero_bit(used, 256); } #endif int __init io_apic_get_version(int ioapic) static int __init io_apic_get_version(int ioapic) { union IO_APIC_reg_01 reg_01; unsigned long flags; Loading Loading @@ -4026,7 +3984,7 @@ int mp_find_ioapic_pin(int ioapic, u32 gsi) return gsi - mp_gsi_routing[ioapic].gsi_base; } static int bad_ioapic(unsigned long address) static __init int bad_ioapic(unsigned long address) { if (nr_ioapics >= MAX_IO_APICS) { printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " Loading Loading @@ -4086,20 +4044,15 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) /* Enable IOAPIC early just for system timer */ void __init pre_init_apic_IRQ0(void) { struct irq_cfg *cfg; struct io_apic_irq_attr attr = { 0, 0, 0, 0 }; printk(KERN_INFO "Early APIC setup for system timer0\n"); #ifndef CONFIG_SMP physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); #endif /* Make sure the irq descriptor is set up */ cfg = alloc_irq_and_cfg_at(0, 0); setup_local_APIC(); add_pin_to_irq_node(cfg, 0, 0, 0); io_apic_setup_irq_pin(0, 0, &attr); set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); setup_ioapic_irq(0, 0, 0, cfg, 0, 0); }