Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / arch / ia64 / kernel / msi_ia64.c
blobd59715326d7c4068294892a38dfac1d9015160d4
1 /*
2 * MSI hooks for standard x86 apic
3 */
5 #include <linux/pci.h>
6 #include <linux/irq.h>
7 #include <linux/msi.h>
8 #include <asm/smp.h>
11 * Shifts for APIC-based data
14 #define MSI_DATA_VECTOR_SHIFT 0
15 #define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
16 #define MSI_DATA_VECTOR_MASK 0xffffff00
18 #define MSI_DATA_DELIVERY_SHIFT 8
19 #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
20 #define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
22 #define MSI_DATA_LEVEL_SHIFT 14
23 #define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
24 #define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
26 #define MSI_DATA_TRIGGER_SHIFT 15
27 #define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
28 #define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
31 * Shift/mask fields for APIC-based bus address
34 #define MSI_TARGET_CPU_SHIFT 4
35 #define MSI_ADDR_HEADER 0xfee00000
37 #define MSI_ADDR_DESTID_MASK 0xfff0000f
38 #define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
40 #define MSI_ADDR_DESTMODE_SHIFT 2
41 #define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
42 #define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
44 #define MSI_ADDR_REDIRECTION_SHIFT 3
45 #define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
46 #define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
48 static struct irq_chip ia64_msi_chip;
50 #ifdef CONFIG_SMP
51 static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
53 struct msi_msg msg;
54 u32 addr, data;
55 int cpu = first_cpu(cpu_mask);
57 if (!cpu_online(cpu))
58 return;
60 <<<<<<< HEAD:arch/ia64/kernel/msi_ia64.c
61 if (reassign_irq_vector(irq, cpu))
62 =======
63 if (irq_prepare_move(irq, cpu))
64 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/msi_ia64.c
65 return;
67 read_msi_msg(irq, &msg);
69 addr = msg.address_lo;
70 addr &= MSI_ADDR_DESTID_MASK;
71 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
72 msg.address_lo = addr;
74 data = msg.data;
75 data &= MSI_DATA_VECTOR_MASK;
76 data |= MSI_DATA_VECTOR(irq_to_vector(irq));
77 msg.data = data;
79 write_msi_msg(irq, &msg);
80 irq_desc[irq].affinity = cpumask_of_cpu(cpu);
82 #endif /* CONFIG_SMP */
84 int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
86 struct msi_msg msg;
87 unsigned long dest_phys_id;
88 int irq, vector;
89 cpumask_t mask;
91 irq = create_irq();
92 if (irq < 0)
93 return irq;
95 set_irq_msi(irq, desc);
96 cpus_and(mask, irq_to_domain(irq), cpu_online_map);
97 dest_phys_id = cpu_physical_id(first_cpu(mask));
98 vector = irq_to_vector(irq);
100 msg.address_hi = 0;
101 msg.address_lo =
102 MSI_ADDR_HEADER |
103 MSI_ADDR_DESTMODE_PHYS |
104 MSI_ADDR_REDIRECTION_CPU |
105 MSI_ADDR_DESTID_CPU(dest_phys_id);
107 msg.data =
108 MSI_DATA_TRIGGER_EDGE |
109 MSI_DATA_LEVEL_ASSERT |
110 MSI_DATA_DELIVERY_FIXED |
111 MSI_DATA_VECTOR(vector);
113 write_msi_msg(irq, &msg);
114 set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
116 return 0;
119 void ia64_teardown_msi_irq(unsigned int irq)
121 destroy_irq(irq);
124 static void ia64_ack_msi_irq(unsigned int irq)
126 <<<<<<< HEAD:arch/ia64/kernel/msi_ia64.c
127 =======
128 irq_complete_move(irq);
129 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/msi_ia64.c
130 move_native_irq(irq);
131 ia64_eoi();
134 static int ia64_msi_retrigger_irq(unsigned int irq)
136 unsigned int vector = irq_to_vector(irq);
137 ia64_resend_irq(vector);
139 return 1;
143 * Generic ops used on most IA64 platforms.
145 static struct irq_chip ia64_msi_chip = {
146 .name = "PCI-MSI",
147 .mask = mask_msi_irq,
148 .unmask = unmask_msi_irq,
149 .ack = ia64_ack_msi_irq,
150 #ifdef CONFIG_SMP
151 .set_affinity = ia64_set_msi_irq_affinity,
152 #endif
153 .retrigger = ia64_msi_retrigger_irq,
157 int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
159 if (platform_setup_msi_irq)
160 return platform_setup_msi_irq(pdev, desc);
162 return ia64_setup_msi_irq(pdev, desc);
165 void arch_teardown_msi_irq(unsigned int irq)
167 if (platform_teardown_msi_irq)
168 return platform_teardown_msi_irq(irq);
170 return ia64_teardown_msi_irq(irq);