aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/Makefile5
-rw-r--r--arch/blackfin/mach-common/clock.h27
-rw-r--r--arch/blackfin/mach-common/clocks-init.c153
-rw-r--r--arch/blackfin/mach-common/cpufreq.c46
-rw-r--r--arch/blackfin/mach-common/dpmc_modes.S606
-rw-r--r--arch/blackfin/mach-common/entry.S7
-rw-r--r--arch/blackfin/mach-common/head.S2
-rw-r--r--arch/blackfin/mach-common/ints-priority.c423
-rw-r--r--arch/blackfin/mach-common/pm.c62
-rw-r--r--arch/blackfin/mach-common/smp.c19
10 files changed, 688 insertions, 662 deletions
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index ff299f24aba0..75f0ba29ebb9 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -6,7 +6,10 @@ obj-y := \
6 cache.o cache-c.o entry.o head.o \ 6 cache.o cache-c.o entry.o head.o \
7 interrupt.o arch_checks.o ints-priority.o 7 interrupt.o arch_checks.o ints-priority.o
8 8
9obj-$(CONFIG_PM) += pm.o dpmc_modes.o 9obj-$(CONFIG_PM) += pm.o
10ifneq ($(CONFIG_BF60x),y)
11obj-$(CONFIG_PM) += dpmc_modes.o
12endif
10obj-$(CONFIG_CPU_FREQ) += cpufreq.o 13obj-$(CONFIG_CPU_FREQ) += cpufreq.o
11obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o 14obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
12obj-$(CONFIG_SMP) += smp.o 15obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/blackfin/mach-common/clock.h b/arch/blackfin/mach-common/clock.h
new file mode 100644
index 000000000000..645ff460a1f2
--- /dev/null
+++ b/arch/blackfin/mach-common/clock.h
@@ -0,0 +1,27 @@
1#ifndef __MACH_COMMON_CLKDEV_H
2#define __MACH_COMMON_CLKDEV_H
3
4#include <linux/clk.h>
5
6struct clk_ops {
7 unsigned long (*get_rate)(struct clk *clk);
8 unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
9 int (*set_rate)(struct clk *clk, unsigned long rate);
10 int (*enable)(struct clk *clk);
11 int (*disable)(struct clk *clk);
12};
13
14struct clk {
15 const char *name;
16 unsigned long rate;
17 spinlock_t lock;
18 u32 flags;
19 const struct clk_ops *ops;
20 const struct params *params;
21 void __iomem *reg;
22 u32 mask;
23 u32 shift;
24};
25
26#endif
27
diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c
index d5cfe611b778..7ad2407d1571 100644
--- a/arch/blackfin/mach-common/clocks-init.c
+++ b/arch/blackfin/mach-common/clocks-init.c
@@ -15,10 +15,121 @@
15#include <asm/mem_init.h> 15#include <asm/mem_init.h>
16#include <asm/dpmc.h> 16#include <asm/dpmc.h>
17 17
18#ifdef CONFIG_BF60x
19#define CSEL_P 0
20#define S0SEL_P 5
21#define SYSSEL_P 8
22#define S1SEL_P 13
23#define DSEL_P 16
24#define OSEL_P 22
25#define ALGN_P 29
26#define UPDT_P 30
27#define LOCK_P 31
28
29#define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF)
30#define CGU_DIV_VAL \
31 ((CONFIG_CCLK_DIV << CSEL_P) | \
32 (CONFIG_SCLK_DIV << SYSSEL_P) | \
33 (CONFIG_SCLK0_DIV << S0SEL_P) | \
34 (CONFIG_SCLK1_DIV << S1SEL_P) | \
35 (CONFIG_DCLK_DIV << DSEL_P))
36
37#define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000)
38#if ((CONFIG_BFIN_DCLK != 125) && \
39 (CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \
40 (CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \
41 (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250))
42#error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz"
43#endif
44struct ddr_config {
45 u32 ddr_clk;
46 u32 dmc_ddrctl;
47 u32 dmc_ddrcfg;
48 u32 dmc_ddrtr0;
49 u32 dmc_ddrtr1;
50 u32 dmc_ddrtr2;
51 u32 dmc_ddrmr;
52 u32 dmc_ddrmr1;
53};
54
55struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = {
56 [0] = {
57 .ddr_clk = 125,
58 .dmc_ddrctl = 0x00000904,
59 .dmc_ddrcfg = 0x00000422,
60 .dmc_ddrtr0 = 0x20705212,
61 .dmc_ddrtr1 = 0x201003CF,
62 .dmc_ddrtr2 = 0x00320107,
63 .dmc_ddrmr = 0x00000422,
64 .dmc_ddrmr1 = 0x4,
65 },
66 [1] = {
67 .ddr_clk = 133,
68 .dmc_ddrctl = 0x00000904,
69 .dmc_ddrcfg = 0x00000422,
70 .dmc_ddrtr0 = 0x20806313,
71 .dmc_ddrtr1 = 0x2013040D,
72 .dmc_ddrtr2 = 0x00320108,
73 .dmc_ddrmr = 0x00000632,
74 .dmc_ddrmr1 = 0x4,
75 },
76 [2] = {
77 .ddr_clk = 150,
78 .dmc_ddrctl = 0x00000904,
79 .dmc_ddrcfg = 0x00000422,
80 .dmc_ddrtr0 = 0x20A07323,
81 .dmc_ddrtr1 = 0x20160492,
82 .dmc_ddrtr2 = 0x00320209,
83 .dmc_ddrmr = 0x00000632,
84 .dmc_ddrmr1 = 0x4,
85 },
86 [3] = {
87 .ddr_clk = 166,
88 .dmc_ddrctl = 0x00000904,
89 .dmc_ddrcfg = 0x00000422,
90 .dmc_ddrtr0 = 0x20A07323,
91 .dmc_ddrtr1 = 0x2016050E,
92 .dmc_ddrtr2 = 0x00320209,
93 .dmc_ddrmr = 0x00000632,
94 .dmc_ddrmr1 = 0x4,
95 },
96 [4] = {
97 .ddr_clk = 200,
98 .dmc_ddrctl = 0x00000904,
99 .dmc_ddrcfg = 0x00000422,
100 .dmc_ddrtr0 = 0x20a07323,
101 .dmc_ddrtr1 = 0x2016050f,
102 .dmc_ddrtr2 = 0x00320509,
103 .dmc_ddrmr = 0x00000632,
104 .dmc_ddrmr1 = 0x4,
105 },
106 [5] = {
107 .ddr_clk = 225,
108 .dmc_ddrctl = 0x00000904,
109 .dmc_ddrcfg = 0x00000422,
110 .dmc_ddrtr0 = 0x20E0A424,
111 .dmc_ddrtr1 = 0x302006DB,
112 .dmc_ddrtr2 = 0x0032020D,
113 .dmc_ddrmr = 0x00000842,
114 .dmc_ddrmr1 = 0x4,
115 },
116 [6] = {
117 .ddr_clk = 250,
118 .dmc_ddrctl = 0x00000904,
119 .dmc_ddrcfg = 0x00000422,
120 .dmc_ddrtr0 = 0x20E0A424,
121 .dmc_ddrtr1 = 0x3020079E,
122 .dmc_ddrtr2 = 0x0032020D,
123 .dmc_ddrmr = 0x00000842,
124 .dmc_ddrmr1 = 0x4,
125 },
126};
127#else
18#define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ 128#define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */
19#define PLL_CTL_VAL \ 129#define PLL_CTL_VAL \
20 (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ 130 (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \
21 (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) 131 (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000))
132#endif
22 133
23__attribute__((l1_text)) 134__attribute__((l1_text))
24static void do_sync(void) 135static void do_sync(void)
@@ -33,6 +144,44 @@ void init_clocks(void)
33 * in the middle of reprogramming things, and that'll screw us up. 144 * in the middle of reprogramming things, and that'll screw us up.
34 * For example, any automatic DMAs left by U-Boot for splash screens. 145 * For example, any automatic DMAs left by U-Boot for splash screens.
35 */ 146 */
147
148#ifdef CONFIG_BF60x
149 int i, dlldatacycle, dll_ctl;
150 bfin_write32(CGU0_DIV, CGU_DIV_VAL);
151 bfin_write32(CGU0_CTL, CGU_CTL_VAL);
152 while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4))
153 continue;
154
155 bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P));
156 while (bfin_read32(CGU0_STAT) & (1 << 3))
157 continue;
158
159 for (i = 0; i < 7; i++) {
160 if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) {
161 bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg);
162 bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0);
163 bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1);
164 bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2);
165 bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr);
166 bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1);
167 bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl);
168 break;
169 }
170 }
171
172 do_sync();
173 while (!(bfin_read_DDR0_STAT() & 0x4))
174 continue;
175
176 dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20;
177 dll_ctl = bfin_read_DDR0_DLLCTL();
178 dll_ctl &= 0x0ff;
179 bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8));
180
181 do_sync();
182 while (!(bfin_read_DDR0_STAT() & 0x2000))
183 continue;
184#else
36 size_t i; 185 size_t i;
37 for (i = 0; i < MAX_DMA_CHANNELS; ++i) { 186 for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
38 struct dma_register *dma = dma_io_base_addr[i]; 187 struct dma_register *dma = dma_io_base_addr[i];
@@ -91,6 +240,8 @@ void init_clocks(void)
91 bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE); 240 bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);
92#endif 241#endif
93#endif 242#endif
243#endif
94 do_sync(); 244 do_sync();
95 bfin_read16(0); 245 bfin_read16(0);
246
96} 247}
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 2e6eefd812f4..6e87dc13f6bf 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/clk.h>
13#include <linux/cpufreq.h> 14#include <linux/cpufreq.h>
14#include <linux/fs.h> 15#include <linux/fs.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
@@ -17,6 +18,7 @@
17#include <asm/time.h> 18#include <asm/time.h>
18#include <asm/dpmc.h> 19#include <asm/dpmc.h>
19 20
21
20/* this is the table of CCLK frequencies, in Hz */ 22/* this is the table of CCLK frequencies, in Hz */
21/* .index is the entry in the auxiliary dpm_state_table[] */ 23/* .index is the entry in the auxiliary dpm_state_table[] */
22static struct cpufreq_frequency_table bfin_freq_table[] = { 24static struct cpufreq_frequency_table bfin_freq_table[] = {
@@ -67,12 +69,22 @@ static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk)
67#else 69#else
68 min_cclk = sclk; 70 min_cclk = sclk;
69#endif 71#endif
72
73#ifndef CONFIG_BF60x
70 csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); 74 csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
75#else
76 csel = bfin_read32(CGU0_DIV) & 0x1F;
77#endif
71 78
72 for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { 79 for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
73 bfin_freq_table[index].frequency = cclk >> index; 80 bfin_freq_table[index].frequency = cclk >> index;
81#ifndef CONFIG_BF60x
74 dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ 82 dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
75 dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; 83 dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1;
84#else
85 dpm_state_table[index].csel = csel;
86 dpm_state_table[index].tscale = TIME_SCALE >> index;
87#endif
76 88
77 pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", 89 pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
78 bfin_freq_table[index].frequency, 90 bfin_freq_table[index].frequency,
@@ -99,14 +111,34 @@ static unsigned int bfin_getfreq_khz(unsigned int cpu)
99 return get_cclk() / 1000; 111 return get_cclk() / 1000;
100} 112}
101 113
114#ifdef CONFIG_BF60x
115unsigned long cpu_set_cclk(int cpu, unsigned long new)
116{
117 struct clk *clk;
118 int ret;
119
120 clk = clk_get(NULL, "CCLK");
121 if (IS_ERR(clk))
122 return -ENODEV;
123
124 ret = clk_set_rate(clk, new);
125 clk_put(clk);
126 return ret;
127}
128#endif
129
102static int bfin_target(struct cpufreq_policy *poli, 130static int bfin_target(struct cpufreq_policy *poli,
103 unsigned int target_freq, unsigned int relation) 131 unsigned int target_freq, unsigned int relation)
104{ 132{
105 unsigned int index, plldiv, cpu; 133#ifndef CONFIG_BF60x
134 unsigned int plldiv;
135#endif
136 unsigned int index, cpu;
106 unsigned long flags, cclk_hz; 137 unsigned long flags, cclk_hz;
107 struct cpufreq_freqs freqs; 138 struct cpufreq_freqs freqs;
108 static unsigned long lpj_ref; 139 static unsigned long lpj_ref;
109 static unsigned int lpj_ref_freq; 140 static unsigned int lpj_ref_freq;
141 int ret = 0;
110 142
111#if defined(CONFIG_CYCLES_CLOCKSOURCE) 143#if defined(CONFIG_CYCLES_CLOCKSOURCE)
112 cycles_t cycles; 144 cycles_t cycles;
@@ -134,9 +166,17 @@ static int bfin_target(struct cpufreq_policy *poli,
134 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 166 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
135 if (cpu == CPUFREQ_CPU) { 167 if (cpu == CPUFREQ_CPU) {
136 flags = hard_local_irq_save(); 168 flags = hard_local_irq_save();
169#ifndef CONFIG_BF60x
137 plldiv = (bfin_read_PLL_DIV() & SSEL) | 170 plldiv = (bfin_read_PLL_DIV() & SSEL) |
138 dpm_state_table[index].csel; 171 dpm_state_table[index].csel;
139 bfin_write_PLL_DIV(plldiv); 172 bfin_write_PLL_DIV(plldiv);
173#else
174 ret = cpu_set_cclk(cpu, freqs.new * 1000);
175 if (ret != 0) {
176 pr_debug("cpufreq set freq failed %d\n", ret);
177 break;
178 }
179#endif
140 on_each_cpu(bfin_adjust_core_timer, &index, 1); 180 on_each_cpu(bfin_adjust_core_timer, &index, 1);
141#if defined(CONFIG_CYCLES_CLOCKSOURCE) 181#if defined(CONFIG_CYCLES_CLOCKSOURCE)
142 cycles = get_cycles(); 182 cycles = get_cycles();
@@ -161,7 +201,7 @@ static int bfin_target(struct cpufreq_policy *poli,
161 } 201 }
162 202
163 pr_debug("cpufreq: done\n"); 203 pr_debug("cpufreq: done\n");
164 return 0; 204 return ret;
165} 205}
166 206
167static int bfin_verify_speed(struct cpufreq_policy *policy) 207static int bfin_verify_speed(struct cpufreq_policy *policy)
@@ -169,7 +209,7 @@ static int bfin_verify_speed(struct cpufreq_policy *policy)
169 return cpufreq_frequency_table_verify(policy, bfin_freq_table); 209 return cpufreq_frequency_table_verify(policy, bfin_freq_table);
170} 210}
171 211
172static int __init __bfin_cpu_init(struct cpufreq_policy *policy) 212static int __bfin_cpu_init(struct cpufreq_policy *policy)
173{ 213{
174 214
175 unsigned long cclk, sclk; 215 unsigned long cclk, sclk;
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S
index 1c534d298de4..de99f3aac2c5 100644
--- a/arch/blackfin/mach-common/dpmc_modes.S
+++ b/arch/blackfin/mach-common/dpmc_modes.S
@@ -10,7 +10,6 @@
10#include <asm/dpmc.h> 10#include <asm/dpmc.h>
11 11
12.section .l1.text 12.section .l1.text
13
14ENTRY(_sleep_mode) 13ENTRY(_sleep_mode)
15 [--SP] = (R7:4, P5:3); 14 [--SP] = (R7:4, P5:3);
16 [--SP] = RETS; 15 [--SP] = RETS;
@@ -43,6 +42,9 @@ ENTRY(_sleep_mode)
43 BITCLR (R7, 5); 42 BITCLR (R7, 5);
44 w[p0] = R7.L; 43 w[p0] = R7.L;
45 IDLE; 44 IDLE;
45
46 bfin_init_pm_bench_cycles;
47
46 call _test_pll_locked; 48 call _test_pll_locked;
47 49
48 RETS = [SP++]; 50 RETS = [SP++];
@@ -58,12 +60,13 @@ ENDPROC(_sleep_mode)
58 * 60 *
59 * We accept just one argument -- the value to write to VR_CTL. 61 * We accept just one argument -- the value to write to VR_CTL.
60 */ 62 */
63
61ENTRY(_hibernate_mode) 64ENTRY(_hibernate_mode)
62 /* Save/setup the regs we need early for minor pipeline optimization */ 65 /* Save/setup the regs we need early for minor pipeline optimization */
63 R4 = R0; 66 R4 = R0;
67
64 P3.H = hi(VR_CTL); 68 P3.H = hi(VR_CTL);
65 P3.L = lo(VR_CTL); 69 P3.L = lo(VR_CTL);
66
67 /* Disable all wakeup sources */ 70 /* Disable all wakeup sources */
68 R0 = IWR_DISABLE_ALL; 71 R0 = IWR_DISABLE_ALL;
69 R1 = IWR_DISABLE_ALL; 72 R1 = IWR_DISABLE_ALL;
@@ -74,6 +77,9 @@ ENTRY(_hibernate_mode)
74 77
75 /* Finally, we climb into our cave to hibernate */ 78 /* Finally, we climb into our cave to hibernate */
76 W[P3] = R4.L; 79 W[P3] = R4.L;
80
81 bfin_init_pm_bench_cycles;
82
77 CLI R2; 83 CLI R2;
78 IDLE; 84 IDLE;
79.Lforever: 85.Lforever:
@@ -158,6 +164,8 @@ ENTRY(_sleep_deeper)
158 SSYNC; 164 SSYNC;
159 IDLE; 165 IDLE;
160 166
167 bfin_init_pm_bench_cycles;
168
161 call _test_pll_locked; 169 call _test_pll_locked;
162 170
163 P0.H = hi(PLL_DIV); 171 P0.H = hi(PLL_DIV);
@@ -276,327 +284,10 @@ ENTRY(_test_pll_locked)
276ENDPROC(_test_pll_locked) 284ENDPROC(_test_pll_locked)
277 285
278.section .text 286.section .text
279
280#define PM_REG0 R7
281#define PM_REG1 R6
282#define PM_REG2 R5
283#define PM_REG3 R4
284#define PM_REG4 R3
285#define PM_REG5 R2
286#define PM_REG6 R1
287#define PM_REG7 R0
288#define PM_REG8 P5
289#define PM_REG9 P4
290#define PM_REG10 P3
291#define PM_REG11 P2
292#define PM_REG12 P1
293#define PM_REG13 P0
294
295#define PM_REGSET0 R7:7
296#define PM_REGSET1 R7:6
297#define PM_REGSET2 R7:5
298#define PM_REGSET3 R7:4
299#define PM_REGSET4 R7:3
300#define PM_REGSET5 R7:2
301#define PM_REGSET6 R7:1
302#define PM_REGSET7 R7:0
303#define PM_REGSET8 R7:0, P5:5
304#define PM_REGSET9 R7:0, P5:4
305#define PM_REGSET10 R7:0, P5:3
306#define PM_REGSET11 R7:0, P5:2
307#define PM_REGSET12 R7:0, P5:1
308#define PM_REGSET13 R7:0, P5:0
309
310#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))];
311#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n;
312#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n);
313#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++];
314#define PM_PUSH(n, x) PM_REG##n = [FP++];
315#define PM_POP(n, x) [FP--] = PM_REG##n;
316#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE)
317#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE)
318#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE)
319#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE)
320#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE)
321#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE)
322
323ENTRY(_do_hibernate) 287ENTRY(_do_hibernate)
324 /* 288 bfin_cpu_reg_save;
325 * Save the core regs early so we can blow them away when 289 bfin_sys_mmr_save;
326 * saving/restoring MMR states 290 bfin_core_mmr_save;
327 */
328 [--sp] = (R7:0, P5:0);
329 [--sp] = fp;
330 [--sp] = usp;
331
332 [--sp] = i0;
333 [--sp] = i1;
334 [--sp] = i2;
335 [--sp] = i3;
336
337 [--sp] = m0;
338 [--sp] = m1;
339 [--sp] = m2;
340 [--sp] = m3;
341
342 [--sp] = l0;
343 [--sp] = l1;
344 [--sp] = l2;
345 [--sp] = l3;
346
347 [--sp] = b0;
348 [--sp] = b1;
349 [--sp] = b2;
350 [--sp] = b3;
351 [--sp] = a0.x;
352 [--sp] = a0.w;
353 [--sp] = a1.x;
354 [--sp] = a1.w;
355
356 [--sp] = LC0;
357 [--sp] = LC1;
358 [--sp] = LT0;
359 [--sp] = LT1;
360 [--sp] = LB0;
361 [--sp] = LB1;
362
363 /* We can't push RETI directly as that'll change IPEND[4] */
364 r7 = RETI;
365 [--sp] = RETS;
366 [--sp] = ASTAT;
367 [--sp] = CYCLES;
368 [--sp] = CYCLES2;
369 [--sp] = SYSCFG;
370 [--sp] = RETX;
371 [--sp] = SEQSTAT;
372 [--sp] = r7;
373
374 /* Save first func arg in M3 */
375 M3 = R0;
376
377 /* Save system MMRs */
378 FP.H = hi(SYSMMR_BASE);
379 FP.L = lo(SYSMMR_BASE);
380
381#ifdef SIC_IMASK0
382 PM_SYS_PUSH(0, SIC_IMASK0)
383 PM_SYS_PUSH(1, SIC_IMASK1)
384# ifdef SIC_IMASK2
385 PM_SYS_PUSH(2, SIC_IMASK2)
386# endif
387#else
388 PM_SYS_PUSH(0, SIC_IMASK)
389#endif
390#ifdef SIC_IAR0
391 PM_SYS_PUSH(3, SIC_IAR0)
392 PM_SYS_PUSH(4, SIC_IAR1)
393 PM_SYS_PUSH(5, SIC_IAR2)
394#endif
395#ifdef SIC_IAR3
396 PM_SYS_PUSH(6, SIC_IAR3)
397#endif
398#ifdef SIC_IAR4
399 PM_SYS_PUSH(7, SIC_IAR4)
400 PM_SYS_PUSH(8, SIC_IAR5)
401 PM_SYS_PUSH(9, SIC_IAR6)
402#endif
403#ifdef SIC_IAR7
404 PM_SYS_PUSH(10, SIC_IAR7)
405#endif
406#ifdef SIC_IAR8
407 PM_SYS_PUSH(11, SIC_IAR8)
408 PM_SYS_PUSH(12, SIC_IAR9)
409 PM_SYS_PUSH(13, SIC_IAR10)
410#endif
411 PM_PUSH_SYNC(13)
412#ifdef SIC_IAR11
413 PM_SYS_PUSH(0, SIC_IAR11)
414#endif
415
416#ifdef SIC_IWR
417 PM_SYS_PUSH(1, SIC_IWR)
418#endif
419#ifdef SIC_IWR0
420 PM_SYS_PUSH(1, SIC_IWR0)
421#endif
422#ifdef SIC_IWR1
423 PM_SYS_PUSH(2, SIC_IWR1)
424#endif
425#ifdef SIC_IWR2
426 PM_SYS_PUSH(3, SIC_IWR2)
427#endif
428
429#ifdef PINT0_ASSIGN
430 PM_SYS_PUSH(4, PINT0_MASK_SET)
431 PM_SYS_PUSH(5, PINT1_MASK_SET)
432 PM_SYS_PUSH(6, PINT2_MASK_SET)
433 PM_SYS_PUSH(7, PINT3_MASK_SET)
434 PM_SYS_PUSH(8, PINT0_ASSIGN)
435 PM_SYS_PUSH(9, PINT1_ASSIGN)
436 PM_SYS_PUSH(10, PINT2_ASSIGN)
437 PM_SYS_PUSH(11, PINT3_ASSIGN)
438 PM_SYS_PUSH(12, PINT0_INVERT_SET)
439 PM_SYS_PUSH(13, PINT1_INVERT_SET)
440 PM_PUSH_SYNC(13)
441 PM_SYS_PUSH(0, PINT2_INVERT_SET)
442 PM_SYS_PUSH(1, PINT3_INVERT_SET)
443 PM_SYS_PUSH(2, PINT0_EDGE_SET)
444 PM_SYS_PUSH(3, PINT1_EDGE_SET)
445 PM_SYS_PUSH(4, PINT2_EDGE_SET)
446 PM_SYS_PUSH(5, PINT3_EDGE_SET)
447#endif
448
449 PM_SYS_PUSH16(6, SYSCR)
450
451 PM_SYS_PUSH16(7, EBIU_AMGCTL)
452 PM_SYS_PUSH(8, EBIU_AMBCTL0)
453 PM_SYS_PUSH(9, EBIU_AMBCTL1)
454#ifdef EBIU_FCTL
455 PM_SYS_PUSH(10, EBIU_MBSCTL)
456 PM_SYS_PUSH(11, EBIU_MODE)
457 PM_SYS_PUSH(12, EBIU_FCTL)
458 PM_PUSH_SYNC(12)
459#else
460 PM_PUSH_SYNC(9)
461#endif
462
463 /* Save Core MMRs */
464 I0.H = hi(COREMMR_BASE);
465 I0.L = lo(COREMMR_BASE);
466 I1 = I0;
467 I2 = I0;
468 I3 = I0;
469 B0 = I0;
470 B1 = I0;
471 B2 = I0;
472 B3 = I0;
473 I1.L = lo(DCPLB_ADDR0);
474 I2.L = lo(DCPLB_DATA0);
475 I3.L = lo(ICPLB_ADDR0);
476 B0.L = lo(ICPLB_DATA0);
477 B1.L = lo(EVT2);
478 B2.L = lo(IMASK);
479 B3.L = lo(TCNTL);
480
481 /* DCPLB Addr */
482 FP = I1;
483 PM_PUSH(0, DCPLB_ADDR0)
484 PM_PUSH(1, DCPLB_ADDR1)
485 PM_PUSH(2, DCPLB_ADDR2)
486 PM_PUSH(3, DCPLB_ADDR3)
487 PM_PUSH(4, DCPLB_ADDR4)
488 PM_PUSH(5, DCPLB_ADDR5)
489 PM_PUSH(6, DCPLB_ADDR6)
490 PM_PUSH(7, DCPLB_ADDR7)
491 PM_PUSH(8, DCPLB_ADDR8)
492 PM_PUSH(9, DCPLB_ADDR9)
493 PM_PUSH(10, DCPLB_ADDR10)
494 PM_PUSH(11, DCPLB_ADDR11)
495 PM_PUSH(12, DCPLB_ADDR12)
496 PM_PUSH(13, DCPLB_ADDR13)
497 PM_PUSH_SYNC(13)
498 PM_PUSH(0, DCPLB_ADDR14)
499 PM_PUSH(1, DCPLB_ADDR15)
500
501 /* DCPLB Data */
502 FP = I2;
503 PM_PUSH(2, DCPLB_DATA0)
504 PM_PUSH(3, DCPLB_DATA1)
505 PM_PUSH(4, DCPLB_DATA2)
506 PM_PUSH(5, DCPLB_DATA3)
507 PM_PUSH(6, DCPLB_DATA4)
508 PM_PUSH(7, DCPLB_DATA5)
509 PM_PUSH(8, DCPLB_DATA6)
510 PM_PUSH(9, DCPLB_DATA7)
511 PM_PUSH(10, DCPLB_DATA8)
512 PM_PUSH(11, DCPLB_DATA9)
513 PM_PUSH(12, DCPLB_DATA10)
514 PM_PUSH(13, DCPLB_DATA11)
515 PM_PUSH_SYNC(13)
516 PM_PUSH(0, DCPLB_DATA12)
517 PM_PUSH(1, DCPLB_DATA13)
518 PM_PUSH(2, DCPLB_DATA14)
519 PM_PUSH(3, DCPLB_DATA15)
520
521 /* ICPLB Addr */
522 FP = I3;
523 PM_PUSH(4, ICPLB_ADDR0)
524 PM_PUSH(5, ICPLB_ADDR1)
525 PM_PUSH(6, ICPLB_ADDR2)
526 PM_PUSH(7, ICPLB_ADDR3)
527 PM_PUSH(8, ICPLB_ADDR4)
528 PM_PUSH(9, ICPLB_ADDR5)
529 PM_PUSH(10, ICPLB_ADDR6)
530 PM_PUSH(11, ICPLB_ADDR7)
531 PM_PUSH(12, ICPLB_ADDR8)
532 PM_PUSH(13, ICPLB_ADDR9)
533 PM_PUSH_SYNC(13)
534 PM_PUSH(0, ICPLB_ADDR10)
535 PM_PUSH(1, ICPLB_ADDR11)
536 PM_PUSH(2, ICPLB_ADDR12)
537 PM_PUSH(3, ICPLB_ADDR13)
538 PM_PUSH(4, ICPLB_ADDR14)
539 PM_PUSH(5, ICPLB_ADDR15)
540
541 /* ICPLB Data */
542 FP = B0;
543 PM_PUSH(6, ICPLB_DATA0)
544 PM_PUSH(7, ICPLB_DATA1)
545 PM_PUSH(8, ICPLB_DATA2)
546 PM_PUSH(9, ICPLB_DATA3)
547 PM_PUSH(10, ICPLB_DATA4)
548 PM_PUSH(11, ICPLB_DATA5)
549 PM_PUSH(12, ICPLB_DATA6)
550 PM_PUSH(13, ICPLB_DATA7)
551 PM_PUSH_SYNC(13)
552 PM_PUSH(0, ICPLB_DATA8)
553 PM_PUSH(1, ICPLB_DATA9)
554 PM_PUSH(2, ICPLB_DATA10)
555 PM_PUSH(3, ICPLB_DATA11)
556 PM_PUSH(4, ICPLB_DATA12)
557 PM_PUSH(5, ICPLB_DATA13)
558 PM_PUSH(6, ICPLB_DATA14)
559 PM_PUSH(7, ICPLB_DATA15)
560
561 /* Event Vectors */
562 FP = B1;
563 PM_PUSH(8, EVT2)
564 PM_PUSH(9, EVT3)
565 FP += 4; /* EVT4 */
566 PM_PUSH(10, EVT5)
567 PM_PUSH(11, EVT6)
568 PM_PUSH(12, EVT7)
569 PM_PUSH(13, EVT8)
570 PM_PUSH_SYNC(13)
571 PM_PUSH(0, EVT9)
572 PM_PUSH(1, EVT10)
573 PM_PUSH(2, EVT11)
574 PM_PUSH(3, EVT12)
575 PM_PUSH(4, EVT13)
576 PM_PUSH(5, EVT14)
577 PM_PUSH(6, EVT15)
578
579 /* CEC */
580 FP = B2;
581 PM_PUSH(7, IMASK)
582 FP += 4; /* IPEND */
583 PM_PUSH(8, ILAT)
584 PM_PUSH(9, IPRIO)
585
586 /* Core Timer */
587 FP = B3;
588 PM_PUSH(10, TCNTL)
589 PM_PUSH(11, TPERIOD)
590 PM_PUSH(12, TSCALE)
591 PM_PUSH(13, TCOUNT)
592 PM_PUSH_SYNC(13)
593
594 /* Misc non-contiguous registers */
595 FP = I0;
596 PM_CORE_PUSH(0, DMEM_CONTROL);
597 PM_CORE_PUSH(1, IMEM_CONTROL);
598 PM_CORE_PUSH(2, TBUFCTL);
599 PM_PUSH_SYNC(2)
600 291
601 /* Setup args to hibernate mode early for pipeline optimization */ 292 /* Setup args to hibernate mode early for pipeline optimization */
602 R0 = M3; 293 R0 = M3;
@@ -618,274 +309,9 @@ ENTRY(_do_hibernate)
618 309
619.Lpm_resume_here: 310.Lpm_resume_here:
620 311
621 /* Restore Core MMRs */ 312 bfin_core_mmr_restore;
622 I0.H = hi(COREMMR_BASE); 313 bfin_sys_mmr_restore;
623 I0.L = lo(COREMMR_BASE); 314 bfin_cpu_reg_restore;
624 I1 = I0;
625 I2 = I0;
626 I3 = I0;
627 B0 = I0;
628 B1 = I0;
629 B2 = I0;
630 B3 = I0;
631 I1.L = lo(DCPLB_ADDR15);
632 I2.L = lo(DCPLB_DATA15);
633 I3.L = lo(ICPLB_ADDR15);
634 B0.L = lo(ICPLB_DATA15);
635 B1.L = lo(EVT15);
636 B2.L = lo(IPRIO);
637 B3.L = lo(TCOUNT);
638
639 /* Misc non-contiguous registers */
640 FP = I0;
641 PM_POP_SYNC(2)
642 PM_CORE_POP(2, TBUFCTL)
643 PM_CORE_POP(1, IMEM_CONTROL)
644 PM_CORE_POP(0, DMEM_CONTROL)
645
646 /* Core Timer */
647 PM_POP_SYNC(13)
648 FP = B3;
649 PM_POP(13, TCOUNT)
650 PM_POP(12, TSCALE)
651 PM_POP(11, TPERIOD)
652 PM_POP(10, TCNTL)
653
654 /* CEC */
655 FP = B2;
656 PM_POP(9, IPRIO)
657 PM_POP(8, ILAT)
658 FP += -4; /* IPEND */
659 PM_POP(7, IMASK)
660
661 /* Event Vectors */
662 FP = B1;
663 PM_POP(6, EVT15)
664 PM_POP(5, EVT14)
665 PM_POP(4, EVT13)
666 PM_POP(3, EVT12)
667 PM_POP(2, EVT11)
668 PM_POP(1, EVT10)
669 PM_POP(0, EVT9)
670 PM_POP_SYNC(13)
671 PM_POP(13, EVT8)
672 PM_POP(12, EVT7)
673 PM_POP(11, EVT6)
674 PM_POP(10, EVT5)
675 FP += -4; /* EVT4 */
676 PM_POP(9, EVT3)
677 PM_POP(8, EVT2)
678
679 /* ICPLB Data */
680 FP = B0;
681 PM_POP(7, ICPLB_DATA15)
682 PM_POP(6, ICPLB_DATA14)
683 PM_POP(5, ICPLB_DATA13)
684 PM_POP(4, ICPLB_DATA12)
685 PM_POP(3, ICPLB_DATA11)
686 PM_POP(2, ICPLB_DATA10)
687 PM_POP(1, ICPLB_DATA9)
688 PM_POP(0, ICPLB_DATA8)
689 PM_POP_SYNC(13)
690 PM_POP(13, ICPLB_DATA7)
691 PM_POP(12, ICPLB_DATA6)
692 PM_POP(11, ICPLB_DATA5)
693 PM_POP(10, ICPLB_DATA4)
694 PM_POP(9, ICPLB_DATA3)
695 PM_POP(8, ICPLB_DATA2)
696 PM_POP(7, ICPLB_DATA1)
697 PM_POP(6, ICPLB_DATA0)
698
699 /* ICPLB Addr */
700 FP = I3;
701 PM_POP(5, ICPLB_ADDR15)
702 PM_POP(4, ICPLB_ADDR14)
703 PM_POP(3, ICPLB_ADDR13)
704 PM_POP(2, ICPLB_ADDR12)
705 PM_POP(1, ICPLB_ADDR11)
706 PM_POP(0, ICPLB_ADDR10)
707 PM_POP_SYNC(13)
708 PM_POP(13, ICPLB_ADDR9)
709 PM_POP(12, ICPLB_ADDR8)
710 PM_POP(11, ICPLB_ADDR7)
711 PM_POP(10, ICPLB_ADDR6)
712 PM_POP(9, ICPLB_ADDR5)
713 PM_POP(8, ICPLB_ADDR4)
714 PM_POP(7, ICPLB_ADDR3)
715 PM_POP(6, ICPLB_ADDR2)
716 PM_POP(5, ICPLB_ADDR1)
717 PM_POP(4, ICPLB_ADDR0)
718
719 /* DCPLB Data */
720 FP = I2;
721 PM_POP(3, DCPLB_DATA15)
722 PM_POP(2, DCPLB_DATA14)
723 PM_POP(1, DCPLB_DATA13)
724 PM_POP(0, DCPLB_DATA12)
725 PM_POP_SYNC(13)
726 PM_POP(13, DCPLB_DATA11)
727 PM_POP(12, DCPLB_DATA10)
728 PM_POP(11, DCPLB_DATA9)
729 PM_POP(10, DCPLB_DATA8)
730 PM_POP(9, DCPLB_DATA7)
731 PM_POP(8, DCPLB_DATA6)
732 PM_POP(7, DCPLB_DATA5)
733 PM_POP(6, DCPLB_DATA4)
734 PM_POP(5, DCPLB_DATA3)
735 PM_POP(4, DCPLB_DATA2)
736 PM_POP(3, DCPLB_DATA1)
737 PM_POP(2, DCPLB_DATA0)
738
739 /* DCPLB Addr */
740 FP = I1;
741 PM_POP(1, DCPLB_ADDR15)
742 PM_POP(0, DCPLB_ADDR14)
743 PM_POP_SYNC(13)
744 PM_POP(13, DCPLB_ADDR13)
745 PM_POP(12, DCPLB_ADDR12)
746 PM_POP(11, DCPLB_ADDR11)
747 PM_POP(10, DCPLB_ADDR10)
748 PM_POP(9, DCPLB_ADDR9)
749 PM_POP(8, DCPLB_ADDR8)
750 PM_POP(7, DCPLB_ADDR7)
751 PM_POP(6, DCPLB_ADDR6)
752 PM_POP(5, DCPLB_ADDR5)
753 PM_POP(4, DCPLB_ADDR4)
754 PM_POP(3, DCPLB_ADDR3)
755 PM_POP(2, DCPLB_ADDR2)
756 PM_POP(1, DCPLB_ADDR1)
757 PM_POP(0, DCPLB_ADDR0)
758
759 /* Restore System MMRs */
760 FP.H = hi(SYSMMR_BASE);
761 FP.L = lo(SYSMMR_BASE);
762
763#ifdef EBIU_FCTL
764 PM_POP_SYNC(12)
765 PM_SYS_POP(12, EBIU_FCTL)
766 PM_SYS_POP(11, EBIU_MODE)
767 PM_SYS_POP(10, EBIU_MBSCTL)
768#else
769 PM_POP_SYNC(9)
770#endif
771 PM_SYS_POP(9, EBIU_AMBCTL1)
772 PM_SYS_POP(8, EBIU_AMBCTL0)
773 PM_SYS_POP16(7, EBIU_AMGCTL)
774
775 PM_SYS_POP16(6, SYSCR)
776
777#ifdef PINT0_ASSIGN
778 PM_SYS_POP(5, PINT3_EDGE_SET)
779 PM_SYS_POP(4, PINT2_EDGE_SET)
780 PM_SYS_POP(3, PINT1_EDGE_SET)
781 PM_SYS_POP(2, PINT0_EDGE_SET)
782 PM_SYS_POP(1, PINT3_INVERT_SET)
783 PM_SYS_POP(0, PINT2_INVERT_SET)
784 PM_POP_SYNC(13)
785 PM_SYS_POP(13, PINT1_INVERT_SET)
786 PM_SYS_POP(12, PINT0_INVERT_SET)
787 PM_SYS_POP(11, PINT3_ASSIGN)
788 PM_SYS_POP(10, PINT2_ASSIGN)
789 PM_SYS_POP(9, PINT1_ASSIGN)
790 PM_SYS_POP(8, PINT0_ASSIGN)
791 PM_SYS_POP(7, PINT3_MASK_SET)
792 PM_SYS_POP(6, PINT2_MASK_SET)
793 PM_SYS_POP(5, PINT1_MASK_SET)
794 PM_SYS_POP(4, PINT0_MASK_SET)
795#endif
796
797#ifdef SIC_IWR2
798 PM_SYS_POP(3, SIC_IWR2)
799#endif
800#ifdef SIC_IWR1
801 PM_SYS_POP(2, SIC_IWR1)
802#endif
803#ifdef SIC_IWR0
804 PM_SYS_POP(1, SIC_IWR0)
805#endif
806#ifdef SIC_IWR
807 PM_SYS_POP(1, SIC_IWR)
808#endif
809
810#ifdef SIC_IAR11
811 PM_SYS_POP(0, SIC_IAR11)
812#endif
813 PM_POP_SYNC(13)
814#ifdef SIC_IAR8
815 PM_SYS_POP(13, SIC_IAR10)
816 PM_SYS_POP(12, SIC_IAR9)
817 PM_SYS_POP(11, SIC_IAR8)
818#endif
819#ifdef SIC_IAR7
820 PM_SYS_POP(10, SIC_IAR7)
821#endif
822#ifdef SIC_IAR6
823 PM_SYS_POP(9, SIC_IAR6)
824 PM_SYS_POP(8, SIC_IAR5)
825 PM_SYS_POP(7, SIC_IAR4)
826#endif
827#ifdef SIC_IAR3
828 PM_SYS_POP(6, SIC_IAR3)
829#endif
830#ifdef SIC_IAR0
831 PM_SYS_POP(5, SIC_IAR2)
832 PM_SYS_POP(4, SIC_IAR1)
833 PM_SYS_POP(3, SIC_IAR0)
834#endif
835#ifdef SIC_IMASK0
836# ifdef SIC_IMASK2
837 PM_SYS_POP(2, SIC_IMASK2)
838# endif
839 PM_SYS_POP(1, SIC_IMASK1)
840 PM_SYS_POP(0, SIC_IMASK0)
841#else
842 PM_SYS_POP(0, SIC_IMASK)
843#endif
844
845 /* Restore Core Registers */
846 RETI = [sp++];
847 SEQSTAT = [sp++];
848 RETX = [sp++];
849 SYSCFG = [sp++];
850 CYCLES2 = [sp++];
851 CYCLES = [sp++];
852 ASTAT = [sp++];
853 RETS = [sp++];
854
855 LB1 = [sp++];
856 LB0 = [sp++];
857 LT1 = [sp++];
858 LT0 = [sp++];
859 LC1 = [sp++];
860 LC0 = [sp++];
861
862 a1.w = [sp++];
863 a1.x = [sp++];
864 a0.w = [sp++];
865 a0.x = [sp++];
866 b3 = [sp++];
867 b2 = [sp++];
868 b1 = [sp++];
869 b0 = [sp++];
870
871 l3 = [sp++];
872 l2 = [sp++];
873 l1 = [sp++];
874 l0 = [sp++];
875
876 m3 = [sp++];
877 m2 = [sp++];
878 m1 = [sp++];
879 m0 = [sp++];
880
881 i3 = [sp++];
882 i2 = [sp++];
883 i1 = [sp++];
884 i0 = [sp++];
885
886 usp = [sp++];
887 fp = [sp++];
888 (R7:0, P5:0) = [sp++];
889 315
890 [--sp] = RETI; /* Clear Global Interrupt Disable */ 316 [--sp] = RETI; /* Clear Global Interrupt Disable */
891 SP += 4; 317 SP += 4;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 4698a9800522..04c2fbe41a7f 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -711,8 +711,6 @@ ENTRY(_system_call)
711 jump .Lresume_userspace_1; 711 jump .Lresume_userspace_1;
712 712
713.Lsyscall_sigpending: 713.Lsyscall_sigpending:
714 cc = BITTST(r7, TIF_RESTORE_SIGMASK);
715 if cc jump .Lsyscall_do_signals;
716 cc = BITTST(r7, TIF_SIGPENDING); 714 cc = BITTST(r7, TIF_SIGPENDING);
717 if cc jump .Lsyscall_do_signals; 715 if cc jump .Lsyscall_do_signals;
718 cc = BITTST(r7, TIF_NOTIFY_RESUME); 716 cc = BITTST(r7, TIF_NOTIFY_RESUME);
@@ -1141,7 +1139,8 @@ ENTRY(_schedule_and_signal_from_int)
1141 sti r0; 1139 sti r0;
1142 1140
1143 /* finish the userspace "atomic" functions for it */ 1141 /* finish the userspace "atomic" functions for it */
1144 r1 = FIXED_CODE_END; 1142 r1.l = lo(FIXED_CODE_END);
1143 r1.h = hi(FIXED_CODE_END);
1145 r2 = [sp + PT_PC]; 1144 r2 = [sp + PT_PC];
1146 cc = r1 <= r2; 1145 cc = r1 <= r2;
1147 if cc jump .Lresume_userspace (bp); 1146 if cc jump .Lresume_userspace (bp);
@@ -1376,7 +1375,7 @@ END(_ex_table)
1376ENTRY(_sys_call_table) 1375ENTRY(_sys_call_table)
1377 .long _sys_restart_syscall /* 0 */ 1376 .long _sys_restart_syscall /* 0 */
1378 .long _sys_exit 1377 .long _sys_exit
1379 .long _sys_fork 1378 .long _sys_ni_syscall /* fork */
1380 .long _sys_read 1379 .long _sys_read
1381 .long _sys_write 1380 .long _sys_write
1382 .long _sys_open /* 5 */ 1381 .long _sys_open /* 5 */
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index 8b4d98854403..31515f0146f9 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -210,14 +210,12 @@ ENDPROC(__start)
210ENTRY(_real_start) 210ENTRY(_real_start)
211 /* Enable nested interrupts */ 211 /* Enable nested interrupts */
212 [--sp] = reti; 212 [--sp] = reti;
213
214 /* watchdog off for now */ 213 /* watchdog off for now */
215 p0.l = lo(WDOG_CTL); 214 p0.l = lo(WDOG_CTL);
216 p0.h = hi(WDOG_CTL); 215 p0.h = hi(WDOG_CTL);
217 r0 = 0xAD6(z); 216 r0 = 0xAD6(z);
218 w[p0] = r0; 217 w[p0] = r0;
219 ssync; 218 ssync;
220
221 /* Pass the u-boot arguments to the global value command line */ 219 /* Pass the u-boot arguments to the global value command line */
222 R0 = R7; 220 R0 = R7;
223 call _cmdline_init; 221 call _cmdline_init;
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 332dace6af34..2729cba715b0 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -16,6 +16,8 @@
16#include <linux/seq_file.h> 16#include <linux/seq_file.h>
17#include <linux/irq.h> 17#include <linux/irq.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/syscore_ops.h>
20#include <asm/delay.h>
19#ifdef CONFIG_IPIPE 21#ifdef CONFIG_IPIPE
20#include <linux/ipipe.h> 22#include <linux/ipipe.h>
21#endif 23#endif
@@ -25,7 +27,11 @@
25#include <asm/irq_handler.h> 27#include <asm/irq_handler.h>
26#include <asm/dpmc.h> 28#include <asm/dpmc.h>
27 29
28#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) 30#ifndef CONFIG_BF60x
31# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
32#else
33# define SIC_SYSIRQ(irq) ((irq) - IVG15)
34#endif
29 35
30/* 36/*
31 * NOTES: 37 * NOTES:
@@ -50,6 +56,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
50unsigned vr_wakeup; 56unsigned vr_wakeup;
51#endif 57#endif
52 58
59#ifndef CONFIG_BF60x
53static struct ivgx { 60static struct ivgx {
54 /* irq number for request_irq, available in mach-bf5xx/irq.h */ 61 /* irq number for request_irq, available in mach-bf5xx/irq.h */
55 unsigned int irqno; 62 unsigned int irqno;
@@ -78,7 +85,8 @@ static void __init search_IAR(void)
78 85
79 for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { 86 for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) {
80 int irqn; 87 int irqn;
81 u32 iar = bfin_read32((unsigned long *)SIC_IAR0 + 88 u32 iar =
89 bfin_read32((unsigned long *)SIC_IAR0 +
82#if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ 90#if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \
83 defined(CONFIG_BF538) || defined(CONFIG_BF539) 91 defined(CONFIG_BF538) || defined(CONFIG_BF539)
84 ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) 92 ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4))
@@ -86,7 +94,6 @@ static void __init search_IAR(void)
86 (irqN >> 3) 94 (irqN >> 3)
87#endif 95#endif
88 ); 96 );
89
90 for (irqn = irqN; irqn < irqN + 4; ++irqn) { 97 for (irqn = irqN; irqn < irqN + 4; ++irqn) {
91 int iar_shift = (irqn & 7) * 4; 98 int iar_shift = (irqn & 7) * 4;
92 if (ivg == (0xf & (iar >> iar_shift))) { 99 if (ivg == (0xf & (iar >> iar_shift))) {
@@ -99,11 +106,11 @@ static void __init search_IAR(void)
99 } 106 }
100 } 107 }
101} 108}
109#endif
102 110
103/* 111/*
104 * This is for core internal IRQs 112 * This is for core internal IRQs
105 */ 113 */
106
107void bfin_ack_noop(struct irq_data *d) 114void bfin_ack_noop(struct irq_data *d)
108{ 115{
109 /* Dummy function. */ 116 /* Dummy function. */
@@ -136,21 +143,21 @@ static void bfin_core_unmask_irq(struct irq_data *d)
136void bfin_internal_mask_irq(unsigned int irq) 143void bfin_internal_mask_irq(unsigned int irq)
137{ 144{
138 unsigned long flags = hard_local_irq_save(); 145 unsigned long flags = hard_local_irq_save();
139 146#ifndef CONFIG_BF60x
140#ifdef SIC_IMASK0 147#ifdef SIC_IMASK0
141 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; 148 unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
142 unsigned mask_bit = SIC_SYSIRQ(irq) % 32; 149 unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
143 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & 150 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
144 ~(1 << mask_bit)); 151 ~(1 << mask_bit));
145# ifdef CONFIG_SMP 152# if defined(CONFIG_SMP) || defined(CONFIG_ICC)
146 bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & 153 bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) &
147 ~(1 << mask_bit)); 154 ~(1 << mask_bit));
148# endif 155# endif
149#else 156#else
150 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & 157 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
151 ~(1 << SIC_SYSIRQ(irq))); 158 ~(1 << SIC_SYSIRQ(irq)));
159#endif /* end of SIC_IMASK0 */
152#endif 160#endif
153
154 hard_local_irq_restore(flags); 161 hard_local_irq_restore(flags);
155} 162}
156 163
@@ -160,7 +167,7 @@ static void bfin_internal_mask_irq_chip(struct irq_data *d)
160} 167}
161 168
162#ifdef CONFIG_SMP 169#ifdef CONFIG_SMP
163static void bfin_internal_unmask_irq_affinity(unsigned int irq, 170void bfin_internal_unmask_irq_affinity(unsigned int irq,
164 const struct cpumask *affinity) 171 const struct cpumask *affinity)
165#else 172#else
166void bfin_internal_unmask_irq(unsigned int irq) 173void bfin_internal_unmask_irq(unsigned int irq)
@@ -168,6 +175,7 @@ void bfin_internal_unmask_irq(unsigned int irq)
168{ 175{
169 unsigned long flags = hard_local_irq_save(); 176 unsigned long flags = hard_local_irq_save();
170 177
178#ifndef CONFIG_BF60x
171#ifdef SIC_IMASK0 179#ifdef SIC_IMASK0
172 unsigned mask_bank = SIC_SYSIRQ(irq) / 32; 180 unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
173 unsigned mask_bit = SIC_SYSIRQ(irq) % 32; 181 unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
@@ -175,22 +183,239 @@ void bfin_internal_unmask_irq(unsigned int irq)
175 if (cpumask_test_cpu(0, affinity)) 183 if (cpumask_test_cpu(0, affinity))
176# endif 184# endif
177 bfin_write_SIC_IMASK(mask_bank, 185 bfin_write_SIC_IMASK(mask_bank,
178 bfin_read_SIC_IMASK(mask_bank) | 186 bfin_read_SIC_IMASK(mask_bank) |
179 (1 << mask_bit)); 187 (1 << mask_bit));
180# ifdef CONFIG_SMP 188# ifdef CONFIG_SMP
181 if (cpumask_test_cpu(1, affinity)) 189 if (cpumask_test_cpu(1, affinity))
182 bfin_write_SICB_IMASK(mask_bank, 190 bfin_write_SICB_IMASK(mask_bank,
183 bfin_read_SICB_IMASK(mask_bank) | 191 bfin_read_SICB_IMASK(mask_bank) |
184 (1 << mask_bit)); 192 (1 << mask_bit));
185# endif 193# endif
186#else 194#else
187 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 195 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
188 (1 << SIC_SYSIRQ(irq))); 196 (1 << SIC_SYSIRQ(irq)));
197#endif
189#endif 198#endif
199 hard_local_irq_restore(flags);
200}
201
202#ifdef CONFIG_BF60x
203static void bfin_sec_preflow_handler(struct irq_data *d)
204{
205 unsigned long flags = hard_local_irq_save();
206 unsigned int sid = SIC_SYSIRQ(d->irq);
207
208 bfin_write_SEC_SCI(0, SEC_CSID, sid);
209
210 hard_local_irq_restore(flags);
211}
212
213static void bfin_sec_mask_ack_irq(struct irq_data *d)
214{
215 unsigned long flags = hard_local_irq_save();
216 unsigned int sid = SIC_SYSIRQ(d->irq);
217
218 bfin_write_SEC_SCI(0, SEC_CSID, sid);
190 219
191 hard_local_irq_restore(flags); 220 hard_local_irq_restore(flags);
192} 221}
193 222
223static void bfin_sec_unmask_irq(struct irq_data *d)
224{
225 unsigned long flags = hard_local_irq_save();
226 unsigned int sid = SIC_SYSIRQ(d->irq);
227
228 bfin_write32(SEC_END, sid);
229
230 hard_local_irq_restore(flags);
231}
232
233static void bfin_sec_enable_ssi(unsigned int sid)
234{
235 unsigned long flags = hard_local_irq_save();
236 uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
237
238 reg_sctl |= SEC_SCTL_SRC_EN;
239 bfin_write_SEC_SCTL(sid, reg_sctl);
240
241 hard_local_irq_restore(flags);
242}
243
244static void bfin_sec_disable_ssi(unsigned int sid)
245{
246 unsigned long flags = hard_local_irq_save();
247 uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
248
249 reg_sctl &= ((uint32_t)~SEC_SCTL_SRC_EN);
250 bfin_write_SEC_SCTL(sid, reg_sctl);
251
252 hard_local_irq_restore(flags);
253}
254
255static void bfin_sec_set_ssi_coreid(unsigned int sid, unsigned int coreid)
256{
257 unsigned long flags = hard_local_irq_save();
258 uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
259
260 reg_sctl &= ((uint32_t)~SEC_SCTL_CTG);
261 bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 20) & SEC_SCTL_CTG));
262
263 hard_local_irq_restore(flags);
264}
265
266static void bfin_sec_enable_sci(unsigned int sid)
267{
268 unsigned long flags = hard_local_irq_save();
269 uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
270
271 if (sid == SIC_SYSIRQ(IRQ_WATCH0))
272 reg_sctl |= SEC_SCTL_FAULT_EN;
273 else
274 reg_sctl |= SEC_SCTL_INT_EN;
275 bfin_write_SEC_SCTL(sid, reg_sctl);
276
277 hard_local_irq_restore(flags);
278}
279
280static void bfin_sec_disable_sci(unsigned int sid)
281{
282 unsigned long flags = hard_local_irq_save();
283 uint32_t reg_sctl = bfin_read_SEC_SCTL(sid);
284
285 reg_sctl &= ((uint32_t)~SEC_SCTL_INT_EN);
286 bfin_write_SEC_SCTL(sid, reg_sctl);
287
288 hard_local_irq_restore(flags);
289}
290
291static void bfin_sec_enable(struct irq_data *d)
292{
293 unsigned long flags = hard_local_irq_save();
294 unsigned int sid = SIC_SYSIRQ(d->irq);
295
296 bfin_sec_enable_sci(sid);
297 bfin_sec_enable_ssi(sid);
298
299 hard_local_irq_restore(flags);
300}
301
302static void bfin_sec_disable(struct irq_data *d)
303{
304 unsigned long flags = hard_local_irq_save();
305 unsigned int sid = SIC_SYSIRQ(d->irq);
306
307 bfin_sec_disable_sci(sid);
308 bfin_sec_disable_ssi(sid);
309
310 hard_local_irq_restore(flags);
311}
312
313static void bfin_sec_raise_irq(unsigned int sid)
314{
315 unsigned long flags = hard_local_irq_save();
316
317 bfin_write32(SEC_RAISE, sid);
318
319 hard_local_irq_restore(flags);
320}
321
322static void init_software_driven_irq(void)
323{
324 bfin_sec_set_ssi_coreid(34, 0);
325 bfin_sec_set_ssi_coreid(35, 1);
326 bfin_sec_set_ssi_coreid(36, 0);
327 bfin_sec_set_ssi_coreid(37, 1);
328}
329
330void bfin_sec_resume(void)
331{
332 bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
333 udelay(100);
334 bfin_write_SEC_GCTL(SEC_GCTL_EN);
335 bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN);
336}
337
338void handle_sec_sfi_fault(uint32_t gstat)
339{
340
341}
342
343void handle_sec_sci_fault(uint32_t gstat)
344{
345 uint32_t core_id;
346 uint32_t cstat;
347
348 core_id = gstat & SEC_GSTAT_SCI;
349 cstat = bfin_read_SEC_SCI(core_id, SEC_CSTAT);
350 if (cstat & SEC_CSTAT_ERR) {
351 switch (cstat & SEC_CSTAT_ERRC) {
352 case SEC_CSTAT_ACKERR:
353 printk(KERN_DEBUG "sec ack err\n");
354 break;
355 default:
356 printk(KERN_DEBUG "sec sci unknow err\n");
357 }
358 }
359
360}
361
362void handle_sec_ssi_fault(uint32_t gstat)
363{
364 uint32_t sid;
365 uint32_t sstat;
366
367 sid = gstat & SEC_GSTAT_SID;
368 sstat = bfin_read_SEC_SSTAT(sid);
369
370}
371
372void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
373{
374 uint32_t sec_gstat;
375
376 raw_spin_lock(&desc->lock);
377
378 sec_gstat = bfin_read32(SEC_GSTAT);
379 if (sec_gstat & SEC_GSTAT_ERR) {
380
381 switch (sec_gstat & SEC_GSTAT_ERRC) {
382 case 0:
383 handle_sec_sfi_fault(sec_gstat);
384 break;
385 case SEC_GSTAT_SCIERR:
386 handle_sec_sci_fault(sec_gstat);
387 break;
388 case SEC_GSTAT_SSIERR:
389 handle_sec_ssi_fault(sec_gstat);
390 break;
391 }
392
393
394 }
395
396 raw_spin_unlock(&desc->lock);
397}
398
399static int sec_suspend(void)
400{
401 return 0;
402}
403
404static void sec_resume(void)
405{
406 bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
407 udelay(100);
408 bfin_write_SEC_GCTL(SEC_GCTL_EN);
409 bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN);
410}
411
412static struct syscore_ops sec_pm_syscore_ops = {
413 .suspend = sec_suspend,
414 .resume = sec_resume,
415};
416
417#endif
418
194#ifdef CONFIG_SMP 419#ifdef CONFIG_SMP
195static void bfin_internal_unmask_irq_chip(struct irq_data *d) 420static void bfin_internal_unmask_irq_chip(struct irq_data *d)
196{ 421{
@@ -212,7 +437,7 @@ static void bfin_internal_unmask_irq_chip(struct irq_data *d)
212} 437}
213#endif 438#endif
214 439
215#ifdef CONFIG_PM 440#if defined(CONFIG_PM) && !defined(CONFIG_BF60x)
216int bfin_internal_set_wake(unsigned int irq, unsigned int state) 441int bfin_internal_set_wake(unsigned int irq, unsigned int state)
217{ 442{
218 u32 bank, bit, wakeup = 0; 443 u32 bank, bit, wakeup = 0;
@@ -271,22 +496,20 @@ static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state)
271 return bfin_internal_set_wake(d->irq, state); 496 return bfin_internal_set_wake(d->irq, state);
272} 497}
273#else 498#else
499# define bfin_internal_set_wake(irq, state)
274# define bfin_internal_set_wake_chip NULL 500# define bfin_internal_set_wake_chip NULL
275#endif 501#endif
276 502
277static struct irq_chip bfin_core_irqchip = { 503static struct irq_chip bfin_core_irqchip = {
278 .name = "CORE", 504 .name = "CORE",
279 .irq_ack = bfin_ack_noop,
280 .irq_mask = bfin_core_mask_irq, 505 .irq_mask = bfin_core_mask_irq,
281 .irq_unmask = bfin_core_unmask_irq, 506 .irq_unmask = bfin_core_unmask_irq,
282}; 507};
283 508
284static struct irq_chip bfin_internal_irqchip = { 509static struct irq_chip bfin_internal_irqchip = {
285 .name = "INTN", 510 .name = "INTN",
286 .irq_ack = bfin_ack_noop,
287 .irq_mask = bfin_internal_mask_irq_chip, 511 .irq_mask = bfin_internal_mask_irq_chip,
288 .irq_unmask = bfin_internal_unmask_irq_chip, 512 .irq_unmask = bfin_internal_unmask_irq_chip,
289 .irq_mask_ack = bfin_internal_mask_irq_chip,
290 .irq_disable = bfin_internal_mask_irq_chip, 513 .irq_disable = bfin_internal_mask_irq_chip,
291 .irq_enable = bfin_internal_unmask_irq_chip, 514 .irq_enable = bfin_internal_unmask_irq_chip,
292#ifdef CONFIG_SMP 515#ifdef CONFIG_SMP
@@ -295,6 +518,18 @@ static struct irq_chip bfin_internal_irqchip = {
295 .irq_set_wake = bfin_internal_set_wake_chip, 518 .irq_set_wake = bfin_internal_set_wake_chip,
296}; 519};
297 520
521#ifdef CONFIG_BF60x
522static struct irq_chip bfin_sec_irqchip = {
523 .name = "SEC",
524 .irq_mask_ack = bfin_sec_mask_ack_irq,
525 .irq_mask = bfin_sec_mask_ack_irq,
526 .irq_unmask = bfin_sec_unmask_irq,
527 .irq_eoi = bfin_sec_unmask_irq,
528 .irq_disable = bfin_sec_disable,
529 .irq_enable = bfin_sec_enable,
530};
531#endif
532
298void bfin_handle_irq(unsigned irq) 533void bfin_handle_irq(unsigned irq)
299{ 534{
300#ifdef CONFIG_IPIPE 535#ifdef CONFIG_IPIPE
@@ -396,8 +631,6 @@ int bfin_mac_status_set_wake(struct irq_data *d, unsigned int state)
396 631
397static struct irq_chip bfin_mac_status_irqchip = { 632static struct irq_chip bfin_mac_status_irqchip = {
398 .name = "MACST", 633 .name = "MACST",
399 .irq_ack = bfin_ack_noop,
400 .irq_mask_ack = bfin_mac_status_mask_irq,
401 .irq_mask = bfin_mac_status_mask_irq, 634 .irq_mask = bfin_mac_status_mask_irq,
402 .irq_unmask = bfin_mac_status_unmask_irq, 635 .irq_unmask = bfin_mac_status_unmask_irq,
403 .irq_set_wake = bfin_mac_status_set_wake, 636 .irq_set_wake = bfin_mac_status_set_wake,
@@ -421,15 +654,15 @@ void bfin_demux_mac_status_irq(unsigned int int_err_irq,
421 } else { 654 } else {
422 bfin_mac_status_ack_irq(irq); 655 bfin_mac_status_ack_irq(irq);
423 pr_debug("IRQ %d:" 656 pr_debug("IRQ %d:"
424 " MASKED MAC ERROR INTERRUPT ASSERTED\n", 657 " MASKED MAC ERROR INTERRUPT ASSERTED\n",
425 irq); 658 irq);
426 } 659 }
427 } else 660 } else
428 printk(KERN_ERR 661 printk(KERN_ERR
429 "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" 662 "%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
430 " INTERRUPT ASSERTED BUT NO SOURCE FOUND" 663 " INTERRUPT ASSERTED BUT NO SOURCE FOUND"
431 "(EMAC_SYSTAT=0x%X)\n", 664 "(EMAC_SYSTAT=0x%X)\n",
432 __func__, __FILE__, __LINE__, status); 665 __func__, __FILE__, __LINE__, status);
433} 666}
434#endif 667#endif
435 668
@@ -583,7 +816,7 @@ static void bfin_demux_gpio_block(unsigned int irq)
583} 816}
584 817
585void bfin_demux_gpio_irq(unsigned int inta_irq, 818void bfin_demux_gpio_irq(unsigned int inta_irq,
586 struct irq_desc *desc) 819 struct irq_desc *desc)
587{ 820{
588 unsigned int irq; 821 unsigned int irq;
589 822
@@ -635,9 +868,15 @@ void bfin_demux_gpio_irq(unsigned int inta_irq,
635 868
636#else 869#else
637 870
871# ifndef CONFIG_BF60x
638#define NR_PINT_SYS_IRQS 4 872#define NR_PINT_SYS_IRQS 4
639#define NR_PINT_BITS 32
640#define NR_PINTS 160 873#define NR_PINTS 160
874# else
875#define NR_PINT_SYS_IRQS 6
876#define NR_PINTS 112
877#endif
878
879#define NR_PINT_BITS 32
641#define IRQ_NOT_AVAIL 0xFF 880#define IRQ_NOT_AVAIL 0xFF
642 881
643#define PINT_2_BANK(x) ((x) >> 5) 882#define PINT_2_BANK(x) ((x) >> 5)
@@ -652,8 +891,13 @@ static struct bfin_pint_regs * const pint[NR_PINT_SYS_IRQS] = {
652 (struct bfin_pint_regs *)PINT1_MASK_SET, 891 (struct bfin_pint_regs *)PINT1_MASK_SET,
653 (struct bfin_pint_regs *)PINT2_MASK_SET, 892 (struct bfin_pint_regs *)PINT2_MASK_SET,
654 (struct bfin_pint_regs *)PINT3_MASK_SET, 893 (struct bfin_pint_regs *)PINT3_MASK_SET,
894#ifdef CONFIG_BF60x
895 (struct bfin_pint_regs *)PINT4_MASK_SET,
896 (struct bfin_pint_regs *)PINT5_MASK_SET,
897#endif
655}; 898};
656 899
900#ifndef CONFIG_BF60x
657inline unsigned int get_irq_base(u32 bank, u8 bmap) 901inline unsigned int get_irq_base(u32 bank, u8 bmap)
658{ 902{
659 unsigned int irq_base; 903 unsigned int irq_base;
@@ -666,6 +910,16 @@ inline unsigned int get_irq_base(u32 bank, u8 bmap)
666 910
667 return irq_base; 911 return irq_base;
668} 912}
913#else
914inline unsigned int get_irq_base(u32 bank, u8 bmap)
915{
916 unsigned int irq_base;
917
918 irq_base = IRQ_PA0 + bank * 16 + bmap * 16;
919
920 return irq_base;
921}
922#endif
669 923
670 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ 924 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
671void init_pint_lut(void) 925void init_pint_lut(void)
@@ -854,6 +1108,14 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
854 case 1: 1108 case 1:
855 pint_irq = IRQ_PINT1; 1109 pint_irq = IRQ_PINT1;
856 break; 1110 break;
1111#ifdef CONFIG_BF60x
1112 case 4:
1113 pint_irq = IRQ_PINT4;
1114 break;
1115 case 5:
1116 pint_irq = IRQ_PINT5;
1117 break;
1118#endif
857 default: 1119 default:
858 return -EINVAL; 1120 return -EINVAL;
859 } 1121 }
@@ -867,10 +1129,21 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
867#endif 1129#endif
868 1130
869void bfin_demux_gpio_irq(unsigned int inta_irq, 1131void bfin_demux_gpio_irq(unsigned int inta_irq,
870 struct irq_desc *desc) 1132 struct irq_desc *desc)
871{ 1133{
872 u32 bank, pint_val; 1134 u32 bank, pint_val;
873 u32 request, irq; 1135 u32 request, irq;
1136 u32 level_mask;
1137 int umask = 0;
1138 struct irq_chip *chip = irq_desc_get_chip(desc);
1139
1140 if (chip->irq_mask_ack) {
1141 chip->irq_mask_ack(&desc->irq_data);
1142 } else {
1143 chip->irq_mask(&desc->irq_data);
1144 if (chip->irq_ack)
1145 chip->irq_ack(&desc->irq_data);
1146 }
874 1147
875 switch (inta_irq) { 1148 switch (inta_irq) {
876 case IRQ_PINT0: 1149 case IRQ_PINT0:
@@ -885,6 +1158,14 @@ void bfin_demux_gpio_irq(unsigned int inta_irq,
885 case IRQ_PINT1: 1158 case IRQ_PINT1:
886 bank = 1; 1159 bank = 1;
887 break; 1160 break;
1161#ifdef CONFIG_BF60x
1162 case IRQ_PINT4:
1163 bank = 4;
1164 break;
1165 case IRQ_PINT5:
1166 bank = 5;
1167 break;
1168#endif
888 default: 1169 default:
889 return; 1170 return;
890 } 1171 }
@@ -893,15 +1174,23 @@ void bfin_demux_gpio_irq(unsigned int inta_irq,
893 1174
894 request = pint[bank]->request; 1175 request = pint[bank]->request;
895 1176
1177 level_mask = pint[bank]->edge_set & request;
1178
896 while (request) { 1179 while (request) {
897 if (request & 1) { 1180 if (request & 1) {
898 irq = pint2irq_lut[pint_val] + SYS_IRQS; 1181 irq = pint2irq_lut[pint_val] + SYS_IRQS;
1182 if (level_mask & PINT_BIT(pint_val)) {
1183 umask = 1;
1184 chip->irq_unmask(&desc->irq_data);
1185 }
899 bfin_handle_irq(irq); 1186 bfin_handle_irq(irq);
900 } 1187 }
901 pint_val++; 1188 pint_val++;
902 request >>= 1; 1189 request >>= 1;
903 } 1190 }
904 1191
1192 if (!umask)
1193 chip->irq_unmask(&desc->irq_data);
905} 1194}
906#endif 1195#endif
907 1196
@@ -951,6 +1240,7 @@ int __init init_arch_irq(void)
951 int irq; 1240 int irq;
952 unsigned long ilat = 0; 1241 unsigned long ilat = 0;
953 1242
1243#ifndef CONFIG_BF60x
954 /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ 1244 /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
955#ifdef SIC_IMASK0 1245#ifdef SIC_IMASK0
956 bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); 1246 bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
@@ -958,13 +1248,16 @@ int __init init_arch_irq(void)
958# ifdef SIC_IMASK2 1248# ifdef SIC_IMASK2
959 bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); 1249 bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
960# endif 1250# endif
961# ifdef CONFIG_SMP 1251# if defined(CONFIG_SMP) || defined(CONFIG_ICC)
962 bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); 1252 bfin_write_SICB_IMASK0(SIC_UNMASK_ALL);
963 bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); 1253 bfin_write_SICB_IMASK1(SIC_UNMASK_ALL);
964# endif 1254# endif
965#else 1255#else
966 bfin_write_SIC_IMASK(SIC_UNMASK_ALL); 1256 bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
967#endif 1257#endif
1258#else /* CONFIG_BF60x */
1259 bfin_write_SEC_GCTL(SEC_GCTL_RESET);
1260#endif
968 1261
969 local_irq_disable(); 1262 local_irq_disable();
970 1263
@@ -974,6 +1267,10 @@ int __init init_arch_irq(void)
974 pint[1]->assign = CONFIG_PINT1_ASSIGN; 1267 pint[1]->assign = CONFIG_PINT1_ASSIGN;
975 pint[2]->assign = CONFIG_PINT2_ASSIGN; 1268 pint[2]->assign = CONFIG_PINT2_ASSIGN;
976 pint[3]->assign = CONFIG_PINT3_ASSIGN; 1269 pint[3]->assign = CONFIG_PINT3_ASSIGN;
1270# ifdef CONFIG_BF60x
1271 pint[4]->assign = CONFIG_PINT4_ASSIGN;
1272 pint[5]->assign = CONFIG_PINT5_ASSIGN;
1273# endif
977# endif 1274# endif
978 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ 1275 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
979 init_pint_lut(); 1276 init_pint_lut();
@@ -986,6 +1283,7 @@ int __init init_arch_irq(void)
986 irq_set_chip(irq, &bfin_internal_irqchip); 1283 irq_set_chip(irq, &bfin_internal_irqchip);
987 1284
988 switch (irq) { 1285 switch (irq) {
1286#ifndef CONFIG_BF60x
989#if BFIN_GPIO_PINT 1287#if BFIN_GPIO_PINT
990 case IRQ_PINT0: 1288 case IRQ_PINT0:
991 case IRQ_PINT1: 1289 case IRQ_PINT1:
@@ -1015,12 +1313,13 @@ int __init init_arch_irq(void)
1015 bfin_demux_mac_status_irq); 1313 bfin_demux_mac_status_irq);
1016 break; 1314 break;
1017#endif 1315#endif
1018#ifdef CONFIG_SMP 1316#if defined(CONFIG_SMP) || defined(CONFIG_ICC)
1019 case IRQ_SUPPLE_0: 1317 case IRQ_SUPPLE_0:
1020 case IRQ_SUPPLE_1: 1318 case IRQ_SUPPLE_1:
1021 irq_set_handler(irq, handle_percpu_irq); 1319 irq_set_handler(irq, handle_percpu_irq);
1022 break; 1320 break;
1023#endif 1321#endif
1322#endif
1024 1323
1025#ifdef CONFIG_TICKSOURCE_CORETMR 1324#ifdef CONFIG_TICKSOURCE_CORETMR
1026 case IRQ_CORETMR: 1325 case IRQ_CORETMR:
@@ -1050,7 +1349,8 @@ int __init init_arch_irq(void)
1050 1349
1051 init_mach_irq(); 1350 init_mach_irq();
1052 1351
1053#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) 1352#ifndef CONFIG_BF60x
1353#if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) && !defined(CONFIG_BF60x)
1054 for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) 1354 for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
1055 irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, 1355 irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip,
1056 handle_level_irq); 1356 handle_level_irq);
@@ -1060,7 +1360,28 @@ int __init init_arch_irq(void)
1060 irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) 1360 irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
1061 irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, 1361 irq_set_chip_and_handler(irq, &bfin_gpio_irqchip,
1062 handle_level_irq); 1362 handle_level_irq);
1063 1363#else
1364 for (irq = BFIN_IRQ(0); irq <= SYS_IRQS; irq++) {
1365 if (irq < CORE_IRQS) {
1366 irq_set_chip(irq, &bfin_sec_irqchip);
1367 __irq_set_handler(irq, handle_sec_fault, 0, NULL);
1368 } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) {
1369 irq_set_chip(irq, &bfin_sec_irqchip);
1370 irq_set_chained_handler(irq, bfin_demux_gpio_irq);
1371 } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) {
1372 irq_set_chip(irq, &bfin_sec_irqchip);
1373 irq_set_handler(irq, handle_percpu_irq);
1374 } else {
1375 irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
1376 handle_fasteoi_irq);
1377 __irq_set_preflow_handler(irq, bfin_sec_preflow_handler);
1378 }
1379 }
1380 for (irq = GPIO_IRQ_BASE;
1381 irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
1382 irq_set_chip_and_handler(irq, &bfin_gpio_irqchip,
1383 handle_level_irq);
1384#endif
1064 bfin_write_IMASK(0); 1385 bfin_write_IMASK(0);
1065 CSYNC(); 1386 CSYNC();
1066 ilat = bfin_read_ILAT(); 1387 ilat = bfin_read_ILAT();
@@ -1072,14 +1393,17 @@ int __init init_arch_irq(void)
1072 /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, 1393 /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx,
1073 * local_irq_enable() 1394 * local_irq_enable()
1074 */ 1395 */
1396#ifndef CONFIG_BF60x
1075 program_IAR(); 1397 program_IAR();
1076 /* Therefore it's better to setup IARs before interrupts enabled */ 1398 /* Therefore it's better to setup IARs before interrupts enabled */
1077 search_IAR(); 1399 search_IAR();
1078 1400
1079 /* Enable interrupts IVG7-15 */ 1401 /* Enable interrupts IVG7-15 */
1080 bfin_irq_flags |= IMASK_IVG15 | 1402 bfin_irq_flags |= IMASK_IVG15 |
1081 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | 1403 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
1082 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; 1404 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
1405
1406 bfin_sti(bfin_irq_flags);
1083 1407
1084 /* This implicitly covers ANOMALY_05000171 1408 /* This implicitly covers ANOMALY_05000171
1085 * Boot-ROM code modifies SICA_IWRx wakeup registers 1409 * Boot-ROM code modifies SICA_IWRx wakeup registers
@@ -1103,7 +1427,23 @@ int __init init_arch_irq(void)
1103#else 1427#else
1104 bfin_write_SIC_IWR(IWR_DISABLE_ALL); 1428 bfin_write_SIC_IWR(IWR_DISABLE_ALL);
1105#endif 1429#endif
1430#else /* CONFIG_BF60x */
1431 /* Enable interrupts IVG7-15 */
1432 bfin_irq_flags |= IMASK_IVG15 |
1433 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
1434 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
1106 1435
1436
1437 bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN);
1438 bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0));
1439 bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0));
1440 bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET);
1441 udelay(100);
1442 bfin_write_SEC_GCTL(SEC_GCTL_EN);
1443 bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN);
1444 init_software_driven_irq();
1445 register_syscore_ops(&sec_pm_syscore_ops);
1446#endif
1107 return 0; 1447 return 0;
1108} 1448}
1109 1449
@@ -1112,13 +1452,14 @@ __attribute__((l1_text))
1112#endif 1452#endif
1113static int vec_to_irq(int vec) 1453static int vec_to_irq(int vec)
1114{ 1454{
1455#ifndef CONFIG_BF60x
1115 struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; 1456 struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
1116 struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; 1457 struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
1117 unsigned long sic_status[3]; 1458 unsigned long sic_status[3];
1118 1459#endif
1119 if (likely(vec == EVT_IVTMR_P)) 1460 if (likely(vec == EVT_IVTMR_P))
1120 return IRQ_CORETMR; 1461 return IRQ_CORETMR;
1121 1462#ifndef CONFIG_BF60x
1122#ifdef SIC_ISR 1463#ifdef SIC_ISR
1123 sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); 1464 sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
1124#else 1465#else
@@ -1147,6 +1488,10 @@ static int vec_to_irq(int vec)
1147#endif 1488#endif
1148 return ivg->irqno; 1489 return ivg->irqno;
1149 } 1490 }
1491#else
1492 /* for bf60x read */
1493 return BFIN_IRQ(bfin_read_SEC_SCI(0, SEC_CSID));
1494#endif /* end of CONFIG_BF60x */
1150} 1495}
1151 1496
1152#ifdef CONFIG_DO_IRQ_L1 1497#ifdef CONFIG_DO_IRQ_L1
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 3c648a077e75..ca6655e0d653 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -19,20 +19,33 @@
19#include <asm/gpio.h> 19#include <asm/gpio.h>
20#include <asm/dma.h> 20#include <asm/dma.h>
21#include <asm/dpmc.h> 21#include <asm/dpmc.h>
22#include <asm/pm.h>
22 23
24#ifdef CONFIG_BF60x
25struct bfin_cpu_pm_fns *bfin_cpu_pm;
26#endif
23 27
24void bfin_pm_suspend_standby_enter(void) 28void bfin_pm_suspend_standby_enter(void)
25{ 29{
30#ifndef CONFIG_BF60x
26 bfin_pm_standby_setup(); 31 bfin_pm_standby_setup();
32#endif
27 33
28#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER 34#ifdef CONFIG_BF60x
29 sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); 35 bfin_cpu_pm->enter(PM_SUSPEND_STANDBY);
30#else 36#else
37# ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
38 sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
39# else
31 sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); 40 sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
41# endif
32#endif 42#endif
33 43
44#ifndef CONFIG_BF60x
34 bfin_pm_standby_restore(); 45 bfin_pm_standby_restore();
46#endif
35 47
48#ifndef CONFIG_BF60x
36#ifdef SIC_IWR0 49#ifdef SIC_IWR0
37 bfin_write_SIC_IWR0(IWR_DISABLE_ALL); 50 bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
38# ifdef SIC_IWR1 51# ifdef SIC_IWR1
@@ -52,6 +65,8 @@ void bfin_pm_suspend_standby_enter(void)
52#else 65#else
53 bfin_write_SIC_IWR(IWR_DISABLE_ALL); 66 bfin_write_SIC_IWR(IWR_DISABLE_ALL);
54#endif 67#endif
68
69#endif
55} 70}
56 71
57int bf53x_suspend_l1_mem(unsigned char *memptr) 72int bf53x_suspend_l1_mem(unsigned char *memptr)
@@ -83,10 +98,13 @@ int bf53x_resume_l1_mem(unsigned char *memptr)
83} 98}
84 99
85#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) 100#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
101# ifdef CONFIG_BF60x
102__attribute__((l1_text))
103# endif
86static void flushinv_all_dcache(void) 104static void flushinv_all_dcache(void)
87{ 105{
88 u32 way, bank, subbank, set; 106 register u32 way, bank, subbank, set;
89 u32 status, addr; 107 register u32 status, addr;
90 u32 dmem_ctl = bfin_read_DMEM_CONTROL(); 108 u32 dmem_ctl = bfin_read_DMEM_CONTROL();
91 109
92 for (bank = 0; bank < 2; ++bank) { 110 for (bank = 0; bank < 2; ++bank) {
@@ -133,6 +151,7 @@ int bfin_pm_suspend_mem_enter(void)
133 return -ENOMEM; 151 return -ENOMEM;
134 } 152 }
135 153
154#ifndef CONFIG_BF60x
136 wakeup = bfin_read_VR_CTL() & ~FREQ; 155 wakeup = bfin_read_VR_CTL() & ~FREQ;
137 wakeup |= SCKELOW; 156 wakeup |= SCKELOW;
138 157
@@ -142,6 +161,7 @@ int bfin_pm_suspend_mem_enter(void)
142#ifdef CONFIG_PM_BFIN_WAKE_GP 161#ifdef CONFIG_PM_BFIN_WAKE_GP
143 wakeup |= GPWE; 162 wakeup |= GPWE;
144#endif 163#endif
164#endif
145 165
146 ret = blackfin_dma_suspend(); 166 ret = blackfin_dma_suspend();
147 167
@@ -159,7 +179,11 @@ int bfin_pm_suspend_mem_enter(void)
159 _disable_icplb(); 179 _disable_icplb();
160 bf53x_suspend_l1_mem(memptr); 180 bf53x_suspend_l1_mem(memptr);
161 181
182#ifndef CONFIG_BF60x
162 do_hibernate(wakeup | vr_wakeup); /* See you later! */ 183 do_hibernate(wakeup | vr_wakeup); /* See you later! */
184#else
185 bfin_cpu_pm->enter(PM_SUSPEND_MEM);
186#endif
163 187
164 bf53x_resume_l1_mem(memptr); 188 bf53x_resume_l1_mem(memptr);
165 189
@@ -223,9 +247,39 @@ static int bfin_pm_enter(suspend_state_t state)
223 return 0; 247 return 0;
224} 248}
225 249
250#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
251void bfin_pm_end(void)
252{
253 u32 cycle, cycle2;
254 u64 usec64;
255 u32 usec;
256
257 __asm__ __volatile__ (
258 "1: %0 = CYCLES2\n"
259 "%1 = CYCLES\n"
260 "%2 = CYCLES2\n"
261 "CC = %2 == %0\n"
262 "if ! CC jump 1b\n"
263 : "=d,a" (cycle2), "=d,a" (cycle), "=d,a" (usec) : : "CC"
264 );
265
266 usec64 = ((u64)cycle2 << 32) + cycle;
267 do_div(usec64, get_cclk() / USEC_PER_SEC);
268 usec = usec64;
269 if (usec == 0)
270 usec = 1;
271
272 pr_info("PM: resume of kernel completes after %ld msec %03ld usec\n",
273 usec / USEC_PER_MSEC, usec % USEC_PER_MSEC);
274}
275#endif
276
226static const struct platform_suspend_ops bfin_pm_ops = { 277static const struct platform_suspend_ops bfin_pm_ops = {
227 .enter = bfin_pm_enter, 278 .enter = bfin_pm_enter,
228 .valid = bfin_pm_valid, 279 .valid = bfin_pm_valid,
280#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
281 .end = bfin_pm_end,
282#endif
229}; 283};
230 284
231static int __init bfin_pm_init(void) 285static int __init bfin_pm_init(void)
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index ac8f8a43158c..00bbe672b3b3 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -340,27 +340,10 @@ void smp_send_stop(void)
340 return; 340 return;
341} 341}
342 342
343int __cpuinit __cpu_up(unsigned int cpu) 343int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
344{ 344{
345 int ret; 345 int ret;
346 struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu);
347 struct task_struct *idle = ci->idle;
348 346
349 if (idle) {
350 free_task(idle);
351 idle = NULL;
352 }
353
354 if (!idle) {
355 idle = fork_idle(cpu);
356 if (IS_ERR(idle)) {
357 printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
358 return PTR_ERR(idle);
359 }
360 ci->idle = idle;
361 } else {
362 init_idle(idle, cpu);
363 }
364 secondary_stack = task_stack_page(idle) + THREAD_SIZE; 347 secondary_stack = task_stack_page(idle) + THREAD_SIZE;
365 348
366 ret = platform_boot_secondary(cpu, idle); 349 ret = platform_boot_secondary(cpu, idle);