diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-17 11:38:06 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:13:24 -0500 |
commit | ebd8c56c5ae154e2c6cfb7453a76a4e7265b2377 (patch) | |
tree | 155df85100a1316ac103dcaed140d20ddc72c855 /arch/sparc64/kernel/irq.c | |
parent | 101d5c18a928ef82b6c7bf99a9eaa536b5ccf593 (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.c | 98 |
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 | ||
141 | extern unsigned long real_hard_smp_processor_id(void); | ||
142 | |||
143 | static 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. */ |
142 | void enable_irq(unsigned int irq) | 179 | void 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 | ||