1 From: Dean Nelson <dcn@sgi.com>
2 Date: Thu, 2 Oct 2008 17:18:21 +0000 (-0500)
3 Subject: x86, UV: add uv_setup_irq() and uv_teardown_irq() functions, v3
4 X-Git-Tag: v2.6.28-rc1~80^2~27
5 X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4173a0e7371ece227559b44943c6fd456ee470d1
8 x86, UV: add uv_setup_irq() and uv_teardown_irq() functions, v3
10 Provide a means for UV interrupt MMRs to be setup with the message to be sent
11 when an MSI is raised.
13 Signed-off-by: Dean Nelson <dcn@sgi.com>
14 Signed-off-by: Ingo Molnar <mingo@elte.hu>
15 Acked-by: Bernhard Walle <bwalle@suse.de>
18 arch/x86/kernel/Makefile | 2 -
19 arch/x86/kernel/io_apic_64.c | 68 +++++++++++++++++++++++++++++++++++++
20 arch/x86/kernel/uv_irq.c | 79 +++++++++++++++++++++++++++++++++++++++++++
21 include/asm-x86/uv/uv_irq.h | 36 +++++++++++++++++++
22 4 files changed, 184 insertions(+), 1 deletion(-)
24 --- a/arch/x86/kernel/Makefile
25 +++ b/arch/x86/kernel/Makefile
26 @@ -106,7 +106,7 @@ ifeq ($(CONFIG_X86_64),y)
28 obj-y += genx2apic_cluster.o
29 obj-y += genx2apic_phys.o
31 + obj-y += bios_uv.o uv_irq.o
32 obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
33 obj-$(CONFIG_AUDIT) += audit_64.o
35 --- a/arch/x86/kernel/io_apic_64.c
36 +++ b/arch/x86/kernel/io_apic_64.c
38 #include <asm/msidef.h>
39 #include <asm/hypertransport.h>
40 #include <asm/irq_remapping.h>
41 +#include <asm/uv/uv_hub.h>
42 +#include <asm/uv/uv_irq.h>
45 #include <mach_apic.h>
46 @@ -2787,6 +2789,72 @@ int arch_setup_ht_irq(unsigned int irq,
48 #endif /* CONFIG_HT_IRQ */
52 + * Re-target the irq to the specified CPU and enable the specified MMR located
53 + * on the specified blade to allow the sending of MSIs to the specified CPU.
55 +int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
56 + unsigned long mmr_offset)
58 + const cpumask_t *eligible_cpu = get_cpu_mask(cpu);
59 + struct irq_cfg *cfg;
61 + unsigned long mmr_value;
62 + struct uv_IO_APIC_route_entry *entry;
63 + unsigned long flags;
66 + err = assign_irq_vector(irq, eligible_cpu);
70 + spin_lock_irqsave(&vector_lock, flags);
71 + set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
73 + spin_unlock_irqrestore(&vector_lock, flags);
75 + cfg = &irq_cfg[irq];
78 + entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
79 + BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
81 + entry->vector = cfg->vector;
82 + entry->delivery_mode = INT_DELIVERY_MODE;
83 + entry->dest_mode = INT_DEST_MODE;
84 + entry->polarity = 0;
87 + entry->dest = cpu_mask_to_apicid(eligible_cpu);
89 + mmr_pnode = uv_blade_to_pnode(mmr_blade);
90 + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
96 + * Disable the specified MMR located on the specified blade so that MSIs are
97 + * longer allowed to be sent.
99 +void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
101 + unsigned long mmr_value;
102 + struct uv_IO_APIC_route_entry *entry;
106 + entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
107 + BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
111 + mmr_pnode = uv_blade_to_pnode(mmr_blade);
112 + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
114 +#endif /* CONFIG_X86_64 */
116 /* --------------------------------------------------------------------------
117 ACPI-based IOAPIC Configuration
118 -------------------------------------------------------------------------- */
120 +++ b/arch/x86/kernel/uv_irq.c
123 + * This file is subject to the terms and conditions of the GNU General Public
124 + * License. See the file "COPYING" in the main directory of this archive
125 + * for more details.
127 + * SGI UV IRQ functions
129 + * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
132 +#include <linux/module.h>
133 +#include <linux/irq.h>
135 +#include <asm/apic.h>
136 +#include <asm/uv/uv_irq.h>
138 +static void uv_noop(unsigned int irq)
142 +static unsigned int uv_noop_ret(unsigned int irq)
147 +static void uv_ack_apic(unsigned int irq)
152 +struct irq_chip uv_irq_chip = {
154 + .startup = uv_noop_ret,
155 + .shutdown = uv_noop,
157 + .disable = uv_noop,
161 + .eoi = uv_ack_apic,
166 + * Set up a mapping of an available irq and vector, and enable the specified
167 + * MMR that defines the MSI that is to be sent to the specified CPU when an
168 + * interrupt is raised.
170 +int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
171 + unsigned long mmr_offset)
176 + irq = create_irq();
180 + ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
186 +EXPORT_SYMBOL_GPL(uv_setup_irq);
189 + * Tear down a mapping of an irq and vector, and disable the specified MMR that
190 + * defined the MSI that was to be sent to the specified CPU when an interrupt
193 + * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
195 +void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
197 + arch_disable_uv_irq(mmr_blade, mmr_offset);
200 +EXPORT_SYMBOL_GPL(uv_teardown_irq);
202 +++ b/include/asm-x86/uv/uv_irq.h
205 + * This file is subject to the terms and conditions of the GNU General Public
206 + * License. See the file "COPYING" in the main directory of this archive
207 + * for more details.
209 + * SGI UV IRQ definitions
211 + * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
214 +#ifndef _ASM_X86_UV_UV_IRQ_H
215 +#define _ASM_X86_UV_UV_IRQ_H
217 +/* If a generic version of this structure gets defined, eliminate this one. */
218 +struct uv_IO_APIC_route_entry {
222 + delivery_status : 1,
231 +extern struct irq_chip uv_irq_chip;
233 +extern int arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long);
234 +extern void arch_disable_uv_irq(int, unsigned long);
236 +extern int uv_setup_irq(char *, int, int, unsigned long);
237 +extern void uv_teardown_irq(unsigned int, int, unsigned long);
239 +#endif /* _ASM_X86_UV_UV_IRQ_H */