Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, apic: Move SGI UV functionality out of generic IO-APIC code

Move UV specific functionality out of the generic IO-APIC code.

Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
LKML-Reference: <20091013203236.GD20543@sgi.com>
[ Cleaned up the code some more in their new places. ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by

Dimitri Sivanich and committed by
Ingo Molnar
9338ad6f 6c2c5029

+145 -154
+23 -6
arch/x86/include/asm/hw_irq.h
··· 79 79 int ioapic, int ioapic_pin, 80 80 int trigger, int polarity) 81 81 { 82 - irq_attr->ioapic = ioapic; 83 - irq_attr->ioapic_pin = ioapic_pin; 84 - irq_attr->trigger = trigger; 85 - irq_attr->polarity = polarity; 82 + irq_attr->ioapic = ioapic; 83 + irq_attr->ioapic_pin = ioapic_pin; 84 + irq_attr->trigger = trigger; 85 + irq_attr->polarity = polarity; 86 86 } 87 87 88 - extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, 89 - struct io_apic_irq_attr *irq_attr); 88 + /* 89 + * This is performance-critical, we want to do it O(1) 90 + * 91 + * Most irqs are mapped 1:1 with pins. 92 + */ 93 + struct irq_cfg { 94 + struct irq_pin_list *irq_2_pin; 95 + cpumask_var_t domain; 96 + cpumask_var_t old_domain; 97 + unsigned move_cleanup_count; 98 + u8 vector; 99 + u8 move_in_progress : 1; 100 + }; 101 + 102 + extern struct irq_cfg *irq_cfg(unsigned int); 103 + extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *); 104 + extern void send_cleanup_vector(struct irq_cfg *); 105 + extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *); 106 + extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr); 90 107 extern void setup_ioapic_dest(void); 91 108 92 109 extern void enable_IO_APIC(void);
-7
arch/x86/include/asm/uv/uv_irq.h
··· 31 31 UV_AFFINITY_CPU 32 32 }; 33 33 34 - extern struct irq_chip uv_irq_chip; 35 - 36 - extern int 37 - arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long, int); 38 - extern void arch_disable_uv_irq(int, unsigned long); 39 - extern int uv_set_irq_affinity(unsigned int, const struct cpumask *); 40 - 41 34 extern int uv_irq_2_mmr_info(int, unsigned long *, int *); 42 35 extern int uv_setup_irq(char *, int, int, unsigned long, int); 43 36 extern void uv_teardown_irq(unsigned int);
+5 -135
arch/x86/kernel/apic/io_apic.c
··· 60 60 #include <asm/irq_remapping.h> 61 61 #include <asm/hpet.h> 62 62 #include <asm/hw_irq.h> 63 - #include <asm/uv/uv_hub.h> 64 - #include <asm/uv/uv_irq.h> 65 63 66 64 #include <asm/apic.h> 67 65 ··· 138 140 return pin; 139 141 } 140 142 141 - /* 142 - * This is performance-critical, we want to do it O(1) 143 - * 144 - * Most irqs are mapped 1:1 with pins. 145 - */ 146 - struct irq_cfg { 147 - struct irq_pin_list *irq_2_pin; 148 - cpumask_var_t domain; 149 - cpumask_var_t old_domain; 150 - unsigned move_cleanup_count; 151 - u8 vector; 152 - u8 move_in_progress : 1; 153 - }; 154 - 155 143 /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ 156 144 #ifdef CONFIG_SPARSE_IRQ 157 145 static struct irq_cfg irq_cfgx[] = { ··· 193 209 } 194 210 195 211 #ifdef CONFIG_SPARSE_IRQ 196 - static struct irq_cfg *irq_cfg(unsigned int irq) 212 + struct irq_cfg *irq_cfg(unsigned int irq) 197 213 { 198 214 struct irq_cfg *cfg = NULL; 199 215 struct irq_desc *desc; ··· 345 361 /* end for move_irq_desc */ 346 362 347 363 #else 348 - static struct irq_cfg *irq_cfg(unsigned int irq) 364 + struct irq_cfg *irq_cfg(unsigned int irq) 349 365 { 350 366 return irq < nr_irqs ? irq_cfgx + irq : NULL; 351 367 } ··· 1221 1237 return err; 1222 1238 } 1223 1239 1224 - static int 1225 - assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) 1240 + int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) 1226 1241 { 1227 1242 int err; 1228 1243 unsigned long flags; ··· 2228 2245 */ 2229 2246 2230 2247 #ifdef CONFIG_SMP 2231 - static void send_cleanup_vector(struct irq_cfg *cfg) 2248 + void send_cleanup_vector(struct irq_cfg *cfg) 2232 2249 { 2233 2250 cpumask_var_t cleanup_mask; 2234 2251 ··· 2272 2289 } 2273 2290 } 2274 2291 2275 - static int 2276 - assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask); 2277 - 2278 2292 /* 2279 2293 * Either sets desc->affinity to a valid value, and returns 2280 2294 * ->cpu_mask_to_apicid of that, or returns BAD_APICID and 2281 2295 * leaves desc->affinity untouched. 2282 2296 */ 2283 - static unsigned int 2297 + unsigned int 2284 2298 set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) 2285 2299 { 2286 2300 struct irq_cfg *cfg; ··· 3704 3724 return err; 3705 3725 } 3706 3726 #endif /* CONFIG_HT_IRQ */ 3707 - 3708 - #ifdef CONFIG_X86_UV 3709 - /* 3710 - * Re-target the irq to the specified CPU and enable the specified MMR located 3711 - * on the specified blade to allow the sending of MSIs to the specified CPU. 3712 - */ 3713 - int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, 3714 - unsigned long mmr_offset, int restrict) 3715 - { 3716 - const struct cpumask *eligible_cpu = cpumask_of(cpu); 3717 - struct irq_desc *desc = irq_to_desc(irq); 3718 - struct irq_cfg *cfg; 3719 - int mmr_pnode; 3720 - unsigned long mmr_value; 3721 - struct uv_IO_APIC_route_entry *entry; 3722 - unsigned long flags; 3723 - int err; 3724 - 3725 - BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); 3726 - 3727 - cfg = irq_cfg(irq); 3728 - 3729 - err = assign_irq_vector(irq, cfg, eligible_cpu); 3730 - if (err != 0) 3731 - return err; 3732 - 3733 - if (restrict == UV_AFFINITY_CPU) 3734 - desc->status |= IRQ_NO_BALANCING; 3735 - else 3736 - desc->status |= IRQ_MOVE_PCNTXT; 3737 - 3738 - spin_lock_irqsave(&vector_lock, flags); 3739 - set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq, 3740 - irq_name); 3741 - spin_unlock_irqrestore(&vector_lock, flags); 3742 - 3743 - mmr_value = 0; 3744 - entry = (struct uv_IO_APIC_route_entry *)&mmr_value; 3745 - entry->vector = cfg->vector; 3746 - entry->delivery_mode = apic->irq_delivery_mode; 3747 - entry->dest_mode = apic->irq_dest_mode; 3748 - entry->polarity = 0; 3749 - entry->trigger = 0; 3750 - entry->mask = 0; 3751 - entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); 3752 - 3753 - mmr_pnode = uv_blade_to_pnode(mmr_blade); 3754 - uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); 3755 - 3756 - if (cfg->move_in_progress) 3757 - send_cleanup_vector(cfg); 3758 - 3759 - return irq; 3760 - } 3761 - 3762 - /* 3763 - * Disable the specified MMR located on the specified blade so that MSIs are 3764 - * longer allowed to be sent. 3765 - */ 3766 - void arch_disable_uv_irq(int mmr_pnode, unsigned long mmr_offset) 3767 - { 3768 - unsigned long mmr_value; 3769 - struct uv_IO_APIC_route_entry *entry; 3770 - 3771 - BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); 3772 - 3773 - mmr_value = 0; 3774 - entry = (struct uv_IO_APIC_route_entry *)&mmr_value; 3775 - entry->mask = 1; 3776 - 3777 - uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); 3778 - } 3779 - 3780 - int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask) 3781 - { 3782 - struct irq_desc *desc = irq_to_desc(irq); 3783 - struct irq_cfg *cfg = desc->chip_data; 3784 - unsigned int dest; 3785 - unsigned long mmr_value; 3786 - struct uv_IO_APIC_route_entry *entry; 3787 - unsigned long mmr_offset; 3788 - unsigned mmr_pnode; 3789 - 3790 - dest = set_desc_affinity(desc, mask); 3791 - if (dest == BAD_APICID) 3792 - return -1; 3793 - 3794 - mmr_value = 0; 3795 - entry = (struct uv_IO_APIC_route_entry *)&mmr_value; 3796 - 3797 - entry->vector = cfg->vector; 3798 - entry->delivery_mode = apic->irq_delivery_mode; 3799 - entry->dest_mode = apic->irq_dest_mode; 3800 - entry->polarity = 0; 3801 - entry->trigger = 0; 3802 - entry->mask = 0; 3803 - entry->dest = dest; 3804 - 3805 - /* Get previously stored MMR and pnode of hub sourcing interrupts */ 3806 - if (uv_irq_2_mmr_info(irq, &mmr_offset, &mmr_pnode)) 3807 - return -1; 3808 - 3809 - uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); 3810 - 3811 - if (cfg->move_in_progress) 3812 - send_cleanup_vector(cfg); 3813 - 3814 - return 0; 3815 - } 3816 - #endif /* CONFIG_X86_64 */ 3817 3727 3818 3728 int __init io_apic_get_redir_entries (int ioapic) 3819 3729 {
+117 -6
arch/x86/kernel/uv_irq.c
··· 18 18 19 19 /* MMR offset and pnode of hub sourcing interrupts for a given irq */ 20 20 struct uv_irq_2_mmr_pnode{ 21 - struct rb_node list; 22 - unsigned long offset; 23 - int pnode; 24 - int irq; 21 + struct rb_node list; 22 + unsigned long offset; 23 + int pnode; 24 + int irq; 25 25 }; 26 - static spinlock_t uv_irq_lock; 27 - static struct rb_root uv_irq_root; 26 + 27 + static spinlock_t uv_irq_lock; 28 + static struct rb_root uv_irq_root; 29 + 30 + static int uv_set_irq_affinity(unsigned int, const struct cpumask *); 28 31 29 32 static void uv_noop(unsigned int irq) 30 33 { ··· 132 129 } 133 130 spin_unlock_irqrestore(&uv_irq_lock, irqflags); 134 131 return -1; 132 + } 133 + 134 + /* 135 + * Re-target the irq to the specified CPU and enable the specified MMR located 136 + * on the specified blade to allow the sending of MSIs to the specified CPU. 137 + */ 138 + static int 139 + arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, 140 + unsigned long mmr_offset, int restrict) 141 + { 142 + const struct cpumask *eligible_cpu = cpumask_of(cpu); 143 + struct irq_desc *desc = irq_to_desc(irq); 144 + struct irq_cfg *cfg; 145 + int mmr_pnode; 146 + unsigned long mmr_value; 147 + struct uv_IO_APIC_route_entry *entry; 148 + int err; 149 + 150 + BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != 151 + sizeof(unsigned long)); 152 + 153 + cfg = irq_cfg(irq); 154 + 155 + err = assign_irq_vector(irq, cfg, eligible_cpu); 156 + if (err != 0) 157 + return err; 158 + 159 + if (restrict == UV_AFFINITY_CPU) 160 + desc->status |= IRQ_NO_BALANCING; 161 + else 162 + desc->status |= IRQ_MOVE_PCNTXT; 163 + 164 + set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq, 165 + irq_name); 166 + 167 + mmr_value = 0; 168 + entry = (struct uv_IO_APIC_route_entry *)&mmr_value; 169 + entry->vector = cfg->vector; 170 + entry->delivery_mode = apic->irq_delivery_mode; 171 + entry->dest_mode = apic->irq_dest_mode; 172 + entry->polarity = 0; 173 + entry->trigger = 0; 174 + entry->mask = 0; 175 + entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); 176 + 177 + mmr_pnode = uv_blade_to_pnode(mmr_blade); 178 + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); 179 + 180 + if (cfg->move_in_progress) 181 + send_cleanup_vector(cfg); 182 + 183 + return irq; 184 + } 185 + 186 + /* 187 + * Disable the specified MMR located on the specified blade so that MSIs are 188 + * longer allowed to be sent. 189 + */ 190 + static void arch_disable_uv_irq(int mmr_pnode, unsigned long mmr_offset) 191 + { 192 + unsigned long mmr_value; 193 + struct uv_IO_APIC_route_entry *entry; 194 + 195 + BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != 196 + sizeof(unsigned long)); 197 + 198 + mmr_value = 0; 199 + entry = (struct uv_IO_APIC_route_entry *)&mmr_value; 200 + entry->mask = 1; 201 + 202 + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); 203 + } 204 + 205 + static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask) 206 + { 207 + struct irq_desc *desc = irq_to_desc(irq); 208 + struct irq_cfg *cfg = desc->chip_data; 209 + unsigned int dest; 210 + unsigned long mmr_value; 211 + struct uv_IO_APIC_route_entry *entry; 212 + unsigned long mmr_offset; 213 + unsigned mmr_pnode; 214 + 215 + dest = set_desc_affinity(desc, mask); 216 + if (dest == BAD_APICID) 217 + return -1; 218 + 219 + mmr_value = 0; 220 + entry = (struct uv_IO_APIC_route_entry *)&mmr_value; 221 + 222 + entry->vector = cfg->vector; 223 + entry->delivery_mode = apic->irq_delivery_mode; 224 + entry->dest_mode = apic->irq_dest_mode; 225 + entry->polarity = 0; 226 + entry->trigger = 0; 227 + entry->mask = 0; 228 + entry->dest = dest; 229 + 230 + /* Get previously stored MMR and pnode of hub sourcing interrupts */ 231 + if (uv_irq_2_mmr_info(irq, &mmr_offset, &mmr_pnode)) 232 + return -1; 233 + 234 + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); 235 + 236 + if (cfg->move_in_progress) 237 + send_cleanup_vector(cfg); 238 + 239 + return 0; 135 240 } 136 241 137 242 /*