Merge git://git.kernel.org/pub/scm/linux/kernel/git/czankel/xtensa-2.6
[linux-2.6] / arch / x86 / kernel / uv_irq.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * SGI UV IRQ functions
7  *
8  * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
9  */
10
11 #include <linux/module.h>
12 #include <linux/irq.h>
13
14 #include <asm/apic.h>
15 #include <asm/uv/uv_irq.h>
16
17 static void uv_noop(unsigned int irq)
18 {
19 }
20
21 static unsigned int uv_noop_ret(unsigned int irq)
22 {
23         return 0;
24 }
25
26 static void uv_ack_apic(unsigned int irq)
27 {
28         ack_APIC_irq();
29 }
30
31 struct irq_chip uv_irq_chip = {
32         .name           = "UV-CORE",
33         .startup        = uv_noop_ret,
34         .shutdown       = uv_noop,
35         .enable         = uv_noop,
36         .disable        = uv_noop,
37         .ack            = uv_noop,
38         .mask           = uv_noop,
39         .unmask         = uv_noop,
40         .eoi            = uv_ack_apic,
41         .end            = uv_noop,
42 };
43
44 /*
45  * Set up a mapping of an available irq and vector, and enable the specified
46  * MMR that defines the MSI that is to be sent to the specified CPU when an
47  * interrupt is raised.
48  */
49 int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
50                  unsigned long mmr_offset)
51 {
52         int irq;
53         int ret;
54
55         irq = create_irq();
56         if (irq <= 0)
57                 return -EBUSY;
58
59         ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
60         if (ret != irq)
61                 destroy_irq(irq);
62
63         return ret;
64 }
65 EXPORT_SYMBOL_GPL(uv_setup_irq);
66
67 /*
68  * Tear down a mapping of an irq and vector, and disable the specified MMR that
69  * defined the MSI that was to be sent to the specified CPU when an interrupt
70  * was raised.
71  *
72  * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
73  */
74 void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
75 {
76         arch_disable_uv_irq(mmr_blade, mmr_offset);
77         destroy_irq(irq);
78 }
79 EXPORT_SYMBOL_GPL(uv_teardown_irq);