aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/common
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2013-02-21 06:51:33 -0500
committerRalf Baechle <ralf@linux-mips.org>2013-02-21 06:51:33 -0500
commit8bfc245f9ad7bd4e461179e4e7852ef99b8b6144 (patch)
tree0ad091f645fbc8318634599d278966a53d3922ee /arch/mips/netlogic/common
parent612663a974065c3445e641d046769fe4c55a6438 (diff)
parent535237cecab2b078114be712c67e89a0db61965f (diff)
Merge branch 'mips-next-3.9' of git://git.linux-mips.org/pub/scm/john/linux-john into mips-for-linux-next
Diffstat (limited to 'arch/mips/netlogic/common')
-rw-r--r--arch/mips/netlogic/common/irq.c41
-rw-r--r--arch/mips/netlogic/common/smp.c8
-rw-r--r--arch/mips/netlogic/common/smpboot.S6
-rw-r--r--arch/mips/netlogic/common/time.c56
4 files changed, 82 insertions, 29 deletions
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
index 780832e391ff..9f84c60bf535 100644
--- a/arch/mips/netlogic/common/irq.c
+++ b/arch/mips/netlogic/common/irq.c
@@ -105,21 +105,23 @@ static void xlp_pic_disable(struct irq_data *d)
105static void xlp_pic_mask_ack(struct irq_data *d) 105static void xlp_pic_mask_ack(struct irq_data *d)
106{ 106{
107 struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); 107 struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
108 uint64_t mask = 1ull << pd->picirq;
109 108
110 write_c0_eirr(mask); /* ack by writing EIRR */ 109 clear_c0_eimr(pd->picirq);
110 ack_c0_eirr(pd->picirq);
111} 111}
112 112
113static void xlp_pic_unmask(struct irq_data *d) 113static void xlp_pic_unmask(struct irq_data *d)
114{ 114{
115 struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); 115 struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
116 116
117 if (!pd) 117 BUG_ON(!pd);
118 return;
119 118
120 if (pd->extra_ack) 119 if (pd->extra_ack)
121 pd->extra_ack(d); 120 pd->extra_ack(d);
122 121
122 /* re-enable the intr on this cpu */
123 set_c0_eimr(pd->picirq);
124
123 /* Ack is a single write, no need to lock */ 125 /* Ack is a single write, no need to lock */
124 nlm_pic_ack(pd->node->picbase, pd->irt); 126 nlm_pic_ack(pd->node->picbase, pd->irt);
125} 127}
@@ -134,32 +136,17 @@ static struct irq_chip xlp_pic = {
134 136
135static void cpuintr_disable(struct irq_data *d) 137static void cpuintr_disable(struct irq_data *d)
136{ 138{
137 uint64_t eimr; 139 clear_c0_eimr(d->irq);
138 uint64_t mask = 1ull << d->irq;
139
140 eimr = read_c0_eimr();
141 write_c0_eimr(eimr & ~mask);
142} 140}
143 141
144static void cpuintr_enable(struct irq_data *d) 142static void cpuintr_enable(struct irq_data *d)
145{ 143{
146 uint64_t eimr; 144 set_c0_eimr(d->irq);
147 uint64_t mask = 1ull << d->irq;
148
149 eimr = read_c0_eimr();
150 write_c0_eimr(eimr | mask);
151} 145}
152 146
153static void cpuintr_ack(struct irq_data *d) 147static void cpuintr_ack(struct irq_data *d)
154{ 148{
155 uint64_t mask = 1ull << d->irq; 149 ack_c0_eirr(d->irq);
156
157 write_c0_eirr(mask);
158}
159
160static void cpuintr_nop(struct irq_data *d)
161{
162 WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
163} 150}
164 151
165/* 152/*
@@ -170,9 +157,9 @@ struct irq_chip nlm_cpu_intr = {
170 .name = "XLP-CPU-INTR", 157 .name = "XLP-CPU-INTR",
171 .irq_enable = cpuintr_enable, 158 .irq_enable = cpuintr_enable,
172 .irq_disable = cpuintr_disable, 159 .irq_disable = cpuintr_disable,
173 .irq_mask = cpuintr_nop, 160 .irq_mask = cpuintr_disable,
174 .irq_ack = cpuintr_nop, 161 .irq_ack = cpuintr_ack,
175 .irq_eoi = cpuintr_ack, 162 .irq_eoi = cpuintr_enable,
176}; 163};
177 164
178static void __init nlm_init_percpu_irqs(void) 165static void __init nlm_init_percpu_irqs(void)
@@ -230,7 +217,7 @@ static void nlm_init_node_irqs(int node)
230 nlm_setup_pic_irq(node, i, i, irt); 217 nlm_setup_pic_irq(node, i, i, irt);
231 /* set interrupts to first cpu in node */ 218 /* set interrupts to first cpu in node */
232 nlm_pic_init_irt(nodep->picbase, irt, i, 219 nlm_pic_init_irt(nodep->picbase, irt, i,
233 node * NLM_CPUS_PER_NODE); 220 node * NLM_CPUS_PER_NODE, 0);
234 irqmask |= (1ull << i); 221 irqmask |= (1ull << i);
235 } 222 }
236 nodep->irqmask = irqmask; 223 nodep->irqmask = irqmask;
@@ -265,7 +252,7 @@ asmlinkage void plat_irq_dispatch(void)
265 int i, node; 252 int i, node;
266 253
267 node = nlm_nodeid(); 254 node = nlm_nodeid();
268 eirr = read_c0_eirr() & read_c0_eimr(); 255 eirr = read_c0_eirr_and_eimr();
269 256
270 i = __ilog2_u64(eirr); 257 i = __ilog2_u64(eirr);
271 if (i == -1) 258 if (i == -1)
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index a080d9ee3cd7..2bb95dcfe20a 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -84,15 +84,19 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
84/* IRQ_IPI_SMP_FUNCTION Handler */ 84/* IRQ_IPI_SMP_FUNCTION Handler */
85void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) 85void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
86{ 86{
87 write_c0_eirr(1ull << irq); 87 clear_c0_eimr(irq);
88 ack_c0_eirr(irq);
88 smp_call_function_interrupt(); 89 smp_call_function_interrupt();
90 set_c0_eimr(irq);
89} 91}
90 92
91/* IRQ_IPI_SMP_RESCHEDULE handler */ 93/* IRQ_IPI_SMP_RESCHEDULE handler */
92void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) 94void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
93{ 95{
94 write_c0_eirr(1ull << irq); 96 clear_c0_eimr(irq);
97 ack_c0_eirr(irq);
95 scheduler_ipi(); 98 scheduler_ipi();
99 set_c0_eimr(irq);
96} 100}
97 101
98/* 102/*
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index 280ff5855ef7..026517488584 100644
--- a/arch/mips/netlogic/common/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -69,6 +69,12 @@
69#endif 69#endif
70 mtcr t1, t0 70 mtcr t1, t0
71 71
72 li t0, ICU_DEFEATURE
73 mfcr t1, t0
74 ori t1, 0x1000 /* Enable Icache partitioning */
75 mtcr t1, t0
76
77
72#ifdef XLP_AX_WORKAROUND 78#ifdef XLP_AX_WORKAROUND
73 li t0, SCHED_DEFEATURE 79 li t0, SCHED_DEFEATURE
74 lui t1, 0x0100 /* Disable BRU accepting ALU ops */ 80 lui t1, 0x0100 /* Disable BRU accepting ALU ops */
diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c
index bd3e498157ff..5c56555380bb 100644
--- a/arch/mips/netlogic/common/time.c
+++ b/arch/mips/netlogic/common/time.c
@@ -35,17 +35,73 @@
35#include <linux/init.h> 35#include <linux/init.h>
36 36
37#include <asm/time.h> 37#include <asm/time.h>
38#include <asm/cpu-features.h>
39
38#include <asm/netlogic/interrupt.h> 40#include <asm/netlogic/interrupt.h>
39#include <asm/netlogic/common.h> 41#include <asm/netlogic/common.h>
42#include <asm/netlogic/haldefs.h>
43#include <asm/netlogic/common.h>
44
45#if defined(CONFIG_CPU_XLP)
46#include <asm/netlogic/xlp-hal/iomap.h>
47#include <asm/netlogic/xlp-hal/xlp.h>
48#include <asm/netlogic/xlp-hal/pic.h>
49#elif defined(CONFIG_CPU_XLR)
50#include <asm/netlogic/xlr/iomap.h>
51#include <asm/netlogic/xlr/pic.h>
52#include <asm/netlogic/xlr/xlr.h>
53#else
54#error "Unknown CPU"
55#endif
40 56
41unsigned int __cpuinit get_c0_compare_int(void) 57unsigned int __cpuinit get_c0_compare_int(void)
42{ 58{
43 return IRQ_TIMER; 59 return IRQ_TIMER;
44} 60}
45 61
62static cycle_t nlm_get_pic_timer(struct clocksource *cs)
63{
64 uint64_t picbase = nlm_get_node(0)->picbase;
65
66 return ~nlm_pic_read_timer(picbase, PIC_CLOCK_TIMER);
67}
68
69static cycle_t nlm_get_pic_timer32(struct clocksource *cs)
70{
71 uint64_t picbase = nlm_get_node(0)->picbase;
72
73 return ~nlm_pic_read_timer32(picbase, PIC_CLOCK_TIMER);
74}
75
76static struct clocksource csrc_pic = {
77 .name = "PIC",
78 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
79};
80
81static void nlm_init_pic_timer(void)
82{
83 uint64_t picbase = nlm_get_node(0)->picbase;
84
85 nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
86 if (current_cpu_data.cputype == CPU_XLR) {
87 csrc_pic.mask = CLOCKSOURCE_MASK(32);
88 csrc_pic.read = nlm_get_pic_timer32;
89 } else {
90 csrc_pic.mask = CLOCKSOURCE_MASK(64);
91 csrc_pic.read = nlm_get_pic_timer;
92 }
93 csrc_pic.rating = 1000;
94 clocksource_register_hz(&csrc_pic, PIC_CLK_HZ);
95}
96
46void __init plat_time_init(void) 97void __init plat_time_init(void)
47{ 98{
99 nlm_init_pic_timer();
48 mips_hpt_frequency = nlm_get_cpu_frequency(); 100 mips_hpt_frequency = nlm_get_cpu_frequency();
101 if (current_cpu_type() == CPU_XLR)
102 preset_lpj = mips_hpt_frequency / (3 * HZ);
103 else
104 preset_lpj = mips_hpt_frequency / (2 * HZ);
49 pr_info("MIPS counter frequency [%ld]\n", 105 pr_info("MIPS counter frequency [%ld]\n",
50 (unsigned long)mips_hpt_frequency); 106 (unsigned long)mips_hpt_frequency);
51} 107}