diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/irq.c | 98 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 6 |
3 files changed, 53 insertions, 55 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index f5c8a293979f..bd332e41532f 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -1692,10 +1692,12 @@ __flushw_user: | |||
1692 | #ifdef CONFIG_SMP | 1692 | #ifdef CONFIG_SMP |
1693 | .globl hard_smp_processor_id | 1693 | .globl hard_smp_processor_id |
1694 | hard_smp_processor_id: | 1694 | hard_smp_processor_id: |
1695 | #endif | ||
1696 | .globl real_hard_smp_processor_id | ||
1697 | real_hard_smp_processor_id: | ||
1695 | __GET_CPUID(%o0) | 1698 | __GET_CPUID(%o0) |
1696 | retl | 1699 | retl |
1697 | nop | 1700 | nop |
1698 | #endif | ||
1699 | 1701 | ||
1700 | /* %o0: devhandle | 1702 | /* %o0: devhandle |
1701 | * %o1: devino | 1703 | * %o1: devino |
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 | ||
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 9b0c409d5b6a..77066f1bbe2f 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -222,7 +222,6 @@ static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; | |||
222 | 222 | ||
223 | static void __init per_cpu_patch(void) | 223 | static void __init per_cpu_patch(void) |
224 | { | 224 | { |
225 | #ifdef CONFIG_SMP | ||
226 | struct cpuid_patch_entry *p; | 225 | struct cpuid_patch_entry *p; |
227 | unsigned long ver; | 226 | unsigned long ver; |
228 | int is_jbus; | 227 | int is_jbus; |
@@ -233,8 +232,8 @@ static void __init per_cpu_patch(void) | |||
233 | is_jbus = 0; | 232 | is_jbus = 0; |
234 | if (tlb_type != hypervisor) { | 233 | if (tlb_type != hypervisor) { |
235 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); | 234 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); |
236 | is_jbus = ((ver >> 32) == __JALAPENO_ID || | 235 | is_jbus = ((ver >> 32UL) == __JALAPENO_ID || |
237 | (ver >> 32) == __SERRANO_ID); | 236 | (ver >> 32UL) == __SERRANO_ID); |
238 | } | 237 | } |
239 | 238 | ||
240 | p = &__cpuid_patch; | 239 | p = &__cpuid_patch; |
@@ -279,7 +278,6 @@ static void __init per_cpu_patch(void) | |||
279 | 278 | ||
280 | p++; | 279 | p++; |
281 | } | 280 | } |
282 | #endif | ||
283 | } | 281 | } |
284 | 282 | ||
285 | static void __init sun4v_patch(void) | 283 | static void __init sun4v_patch(void) |