aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/irq.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-17 11:38:06 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:13:24 -0500
commitebd8c56c5ae154e2c6cfb7453a76a4e7265b2377 (patch)
tree155df85100a1316ac103dcaed140d20ddc72c855 /arch/sparc64/kernel/irq.c
parent101d5c18a928ef82b6c7bf99a9eaa536b5ccf593 (diff)
[SPARC64]: Fix uniprocessor IRQ targetting on SUN4V.
We need to use the real hardware processor ID when targetting interrupts, not the "define to 0" thing the uniprocessor build gives us. Also, fill in the Node-ID and Agent-ID fields properly on sun4u/Safari. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r--arch/sparc64/kernel/irq.c98
1 files changed, 48 insertions, 50 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index bb0bb34555da..712b16cdd5fb 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -138,11 +138,48 @@ out_unlock:
138 return 0; 138 return 0;
139} 139}
140 140
141extern unsigned long real_hard_smp_processor_id(void);
142
143static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid)
144{
145 unsigned int tid;
146
147 if (this_is_starfire) {
148 tid = starfire_translate(imap, cpuid);
149 tid <<= IMAP_TID_SHIFT;
150 tid &= IMAP_TID_UPA;
151 } else {
152 if (tlb_type == cheetah || tlb_type == cheetah_plus) {
153 unsigned long ver;
154
155 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
156 if ((ver >> 32UL) == __JALAPENO_ID ||
157 (ver >> 32UL) == __SERRANO_ID) {
158 tid = cpuid << IMAP_TID_SHIFT;
159 tid &= IMAP_TID_JBUS;
160 } else {
161 unsigned int a = cpuid & 0x1f;
162 unsigned int n = (cpuid >> 5) & 0x1f;
163
164 tid = ((a << IMAP_AID_SHIFT) |
165 (n << IMAP_NID_SHIFT));
166 tid &= (IMAP_AID_SAFARI |
167 IMAP_NID_SAFARI);;
168 }
169 } else {
170 tid = cpuid << IMAP_TID_SHIFT;
171 tid &= IMAP_TID_UPA;
172 }
173 }
174
175 return tid;
176}
177
141/* Now these are always passed a true fully specified sun4u INO. */ 178/* Now these are always passed a true fully specified sun4u INO. */
142void enable_irq(unsigned int irq) 179void enable_irq(unsigned int irq)
143{ 180{
144 struct ino_bucket *bucket = __bucket(irq); 181 struct ino_bucket *bucket = __bucket(irq);
145 unsigned long imap; 182 unsigned long imap, cpuid;
146 183
147 imap = bucket->imap; 184 imap = bucket->imap;
148 if (imap == 0UL) 185 if (imap == 0UL)
@@ -150,54 +187,25 @@ void enable_irq(unsigned int irq)
150 187
151 preempt_disable(); 188 preempt_disable();
152 189
190 /* This gets the physical processor ID, even on uniprocessor,
191 * so we can always program the interrupt target correctly.
192 */
193 cpuid = real_hard_smp_processor_id();
194
153 if (tlb_type == hypervisor) { 195 if (tlb_type == hypervisor) {
154 unsigned int ino = __irq_ino(irq); 196 unsigned int ino = __irq_ino(irq);
155 int cpu = hard_smp_processor_id();
156 int err; 197 int err;
157 198
158 err = sun4v_intr_settarget(ino, cpu); 199 err = sun4v_intr_settarget(ino, cpuid);
159 if (err != HV_EOK) 200 if (err != HV_EOK)
160 printk("sun4v_intr_settarget(%x,%d): err(%d)\n", 201 printk("sun4v_intr_settarget(%x,%lu): err(%d)\n",
161 ino, cpu, err); 202 ino, cpuid, err);
162 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); 203 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
163 if (err != HV_EOK) 204 if (err != HV_EOK)
164 printk("sun4v_intr_setenabled(%x): err(%d)\n", 205 printk("sun4v_intr_setenabled(%x): err(%d)\n",
165 ino, err); 206 ino, err);
166 } else { 207 } else {
167 unsigned long tid; 208 unsigned int tid = sun4u_compute_tid(imap, cpuid);
168
169 if (tlb_type == cheetah || tlb_type == cheetah_plus) {
170 unsigned long ver;
171
172 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
173 if ((ver >> 32) == __JALAPENO_ID ||
174 (ver >> 32) == __SERRANO_ID) {
175 /* We set it to our JBUS ID. */
176 __asm__ __volatile__("ldxa [%%g0] %1, %0"
177 : "=r" (tid)
178 : "i" (ASI_JBUS_CONFIG));
179 tid = ((tid & (0x1fUL<<17)) << 9);
180 tid &= IMAP_TID_JBUS;
181 } else {
182 /* We set it to our Safari AID. */
183 __asm__ __volatile__("ldxa [%%g0] %1, %0"
184 : "=r" (tid)
185 : "i"(ASI_SAFARI_CONFIG));
186 tid = ((tid & (0x3ffUL<<17)) << 9);
187 tid &= IMAP_AID_SAFARI;
188 }
189 } else if (this_is_starfire == 0) {
190 /* We set it to our UPA MID. */
191 __asm__ __volatile__("ldxa [%%g0] %1, %0"
192 : "=r" (tid)
193 : "i" (ASI_UPA_CONFIG));
194 tid = ((tid & UPA_CONFIG_MID) << 9);
195 tid &= IMAP_TID_UPA;
196 } else {
197 tid = (starfire_translate(imap,
198 smp_processor_id()) << 26);
199 tid &= IMAP_TID_UPA;
200 }
201 209
202 /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product 210 /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product
203 * of this SYSIO's preconfigured IGN in the SYSIO Control 211 * of this SYSIO's preconfigured IGN in the SYSIO Control
@@ -817,18 +825,8 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
817 sun4v_intr_setenabled(ino, HV_INTR_ENABLED); 825 sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
818 } else { 826 } else {
819 unsigned long imap = bucket->imap; 827 unsigned long imap = bucket->imap;
820 unsigned int tid; 828 unsigned int tid = sun4u_compute_tid(imap, goal_cpu);
821 829
822 if (tlb_type == cheetah || tlb_type == cheetah_plus) {
823 tid = goal_cpu << 26;
824 tid &= IMAP_AID_SAFARI;
825 } else if (this_is_starfire == 0) {
826 tid = goal_cpu << 26;
827 tid &= IMAP_TID_UPA;
828 } else {
829 tid = (starfire_translate(imap, goal_cpu) << 26);
830 tid &= IMAP_TID_UPA;
831 }
832 upa_writel(tid | IMAP_VALID, imap); 830 upa_writel(tid | IMAP_VALID, imap);
833 } 831 }
834 832