summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/entry.S4
-rw-r--r--arch/sparc64/kernel/irq.c98
-rw-r--r--arch/sparc64/kernel/setup.c6
-rw-r--r--include/asm-sparc64/cpudata.h6
-rw-r--r--include/asm-sparc64/irq.h3
5 files changed, 58 insertions, 59 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:
#ifdef CONFIG_SMP
.globl hard_smp_processor_id
hard_smp_processor_id:
+#endif
+ .globl real_hard_smp_processor_id
+real_hard_smp_processor_id:
__GET_CPUID(%o0)
retl
nop
-#endif
/* %o0: devhandle
* %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:
return 0;
}
+extern unsigned long real_hard_smp_processor_id(void);
+
+static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid)
+{
+ unsigned int tid;
+
+ if (this_is_starfire) {
+ tid = starfire_translate(imap, cpuid);
+ tid <<= IMAP_TID_SHIFT;
+ tid &= IMAP_TID_UPA;
+ } else {
+ if (tlb_type == cheetah || tlb_type == cheetah_plus) {
+ unsigned long ver;
+
+ __asm__ ("rdpr %%ver, %0" : "=r" (ver));
+ if ((ver >> 32UL) == __JALAPENO_ID ||
+ (ver >> 32UL) == __SERRANO_ID) {
+ tid = cpuid << IMAP_TID_SHIFT;
+ tid &= IMAP_TID_JBUS;
+ } else {
+ unsigned int a = cpuid & 0x1f;
+ unsigned int n = (cpuid >> 5) & 0x1f;
+
+ tid = ((a << IMAP_AID_SHIFT) |
+ (n << IMAP_NID_SHIFT));
+ tid &= (IMAP_AID_SAFARI |
+ IMAP_NID_SAFARI);;
+ }
+ } else {
+ tid = cpuid << IMAP_TID_SHIFT;
+ tid &= IMAP_TID_UPA;
+ }
+ }
+
+ return tid;
+}
+
/* Now these are always passed a true fully specified sun4u INO. */
void enable_irq(unsigned int irq)
{
struct ino_bucket *bucket = __bucket(irq);
- unsigned long imap;
+ unsigned long imap, cpuid;
imap = bucket->imap;
if (imap == 0UL)
@@ -150,54 +187,25 @@ void enable_irq(unsigned int irq)
preempt_disable();
+ /* This gets the physical processor ID, even on uniprocessor,
+ * so we can always program the interrupt target correctly.
+ */
+ cpuid = real_hard_smp_processor_id();
+
if (tlb_type == hypervisor) {
unsigned int ino = __irq_ino(irq);
- int cpu = hard_smp_processor_id();
int err;
- err = sun4v_intr_settarget(ino, cpu);
+ err = sun4v_intr_settarget(ino, cpuid);
if (err != HV_EOK)
- printk("sun4v_intr_settarget(%x,%d): err(%d)\n",
- ino, cpu, err);
+ printk("sun4v_intr_settarget(%x,%lu): err(%d)\n",
+ ino, cpuid, err);
err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
if (err != HV_EOK)
printk("sun4v_intr_setenabled(%x): err(%d)\n",
ino, err);
} else {
- unsigned long tid;
-
- if (tlb_type == cheetah || tlb_type == cheetah_plus) {
- unsigned long ver;
-
- __asm__ ("rdpr %%ver, %0" : "=r" (ver));
- if ((ver >> 32) == __JALAPENO_ID ||
- (ver >> 32) == __SERRANO_ID) {
- /* We set it to our JBUS ID. */
- __asm__ __volatile__("ldxa [%%g0] %1, %0"
- : "=r" (tid)
- : "i" (ASI_JBUS_CONFIG));
- tid = ((tid & (0x1fUL<<17)) << 9);
- tid &= IMAP_TID_JBUS;
- } else {
- /* We set it to our Safari AID. */
- __asm__ __volatile__("ldxa [%%g0] %1, %0"
- : "=r" (tid)
- : "i"(ASI_SAFARI_CONFIG));
- tid = ((tid & (0x3ffUL<<17)) << 9);
- tid &= IMAP_AID_SAFARI;
- }
- } else if (this_is_starfire == 0) {
- /* We set it to our UPA MID. */
- __asm__ __volatile__("ldxa [%%g0] %1, %0"
- : "=r" (tid)
- : "i" (ASI_UPA_CONFIG));
- tid = ((tid & UPA_CONFIG_MID) << 9);
- tid &= IMAP_TID_UPA;
- } else {
- tid = (starfire_translate(imap,
- smp_processor_id()) << 26);
- tid &= IMAP_TID_UPA;
- }
+ unsigned int tid = sun4u_compute_tid(imap, cpuid);
/* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product
* 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)
sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
} else {
unsigned long imap = bucket->imap;
- unsigned int tid;
+ unsigned int tid = sun4u_compute_tid(imap, goal_cpu);
- if (tlb_type == cheetah || tlb_type == cheetah_plus) {
- tid = goal_cpu << 26;
- tid &= IMAP_AID_SAFARI;
- } else if (this_is_starfire == 0) {
- tid = goal_cpu << 26;
- tid &= IMAP_TID_UPA;
- } else {
- tid = (starfire_translate(imap, goal_cpu) << 26);
- tid &= IMAP_TID_UPA;
- }
upa_writel(tid | IMAP_VALID, imap);
}
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 };
static void __init per_cpu_patch(void)
{
-#ifdef CONFIG_SMP
struct cpuid_patch_entry *p;
unsigned long ver;
int is_jbus;
@@ -233,8 +232,8 @@ static void __init per_cpu_patch(void)
is_jbus = 0;
if (tlb_type != hypervisor) {
__asm__ ("rdpr %%ver, %0" : "=r" (ver));
- is_jbus = ((ver >> 32) == __JALAPENO_ID ||
- (ver >> 32) == __SERRANO_ID);
+ is_jbus = ((ver >> 32UL) == __JALAPENO_ID ||
+ (ver >> 32UL) == __SERRANO_ID);
}
p = &__cpuid_patch;
@@ -279,7 +278,6 @@ static void __init per_cpu_patch(void)
p++;
}
-#endif
}
static void __init sun4v_patch(void)
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h
index 771aa94dfd95..84656f1895cd 100644
--- a/include/asm-sparc64/cpudata.h
+++ b/include/asm-sparc64/cpudata.h
@@ -80,7 +80,6 @@ extern struct trap_per_cpu trap_block[NR_CPUS];
extern void init_cur_cpu_trap(struct thread_info *);
extern void setup_tba(void);
-#ifdef CONFIG_SMP
struct cpuid_patch_entry {
unsigned int addr;
unsigned int cheetah_safari[4];
@@ -89,7 +88,6 @@ struct cpuid_patch_entry {
unsigned int sun4v[4];
};
extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
-#endif
struct sun4v_1insn_patch_entry {
unsigned int addr;
@@ -123,8 +121,6 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
#include <asm/scratchpad.h>
-#ifdef CONFIG_SMP
-
#define __GET_CPUID(REG) \
/* Spitfire implementation (default). */ \
661: ldxa [%g0] ASI_UPA_CONFIG, REG; \
@@ -156,6 +152,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
nop; \
.previous;
+#ifdef CONFIG_SMP
+
#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
__GET_CPUID(TMP) \
sethi %hi(trap_block), DEST; \
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
index 529a9df1ad43..de33d6e1afb5 100644
--- a/include/asm-sparc64/irq.h
+++ b/include/asm-sparc64/irq.h
@@ -72,8 +72,11 @@ struct ino_bucket {
#define IMAP_VALID 0x80000000 /* IRQ Enabled */
#define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */
#define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */
+#define IMAP_TID_SHIFT 26
#define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */
+#define IMAP_AID_SHIFT 26
#define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */
+#define IMAP_NID_SHIFT 21
#define IMAP_IGN 0x000007c0 /* IRQ Group Number */
#define IMAP_INO 0x0000003f /* IRQ Number */
#define IMAP_INR 0x000007ff /* Full interrupt number*/
OpenPOWER on IntegriCloud