diff options
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_dma_5xx.c | 7 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 578 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cplbinit.c | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbinit.c | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbmgr.c | 12 | ||||
-rw-r--r-- | arch/blackfin/kernel/ipipe.c | 176 | ||||
-rw-r--r-- | arch/blackfin/kernel/irqchip.c | 22 | ||||
-rw-r--r-- | arch/blackfin/kernel/kgdb_test.c | 9 | ||||
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 5 | ||||
-rw-r--r-- | arch/blackfin/kernel/reboot.c | 30 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 22 | ||||
-rw-r--r-- | arch/blackfin/kernel/time.c | 5 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 39 |
14 files changed, 383 insertions, 536 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 38a233374f07..fd4d4328a0f2 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile | |||
@@ -21,5 +21,9 @@ obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o | |||
21 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | 21 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o |
22 | obj-$(CONFIG_MODULES) += module.o | 22 | obj-$(CONFIG_MODULES) += module.o |
23 | obj-$(CONFIG_KGDB) += kgdb.o | 23 | obj-$(CONFIG_KGDB) += kgdb.o |
24 | obj-$(CONFIG_KGDB_TESTCASE) += kgdb_test.o | 24 | obj-$(CONFIG_KGDB_TESTS) += kgdb_test.o |
25 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 25 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
26 | |||
27 | # the kgdb test puts code into L2 and without linker | ||
28 | # relaxation, we need to force long calls to/from it | ||
29 | CFLAGS_kgdb_test.o := -mlong-calls -O0 | ||
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 07e02c0d1c07..8531693fb48d 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -249,6 +249,13 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u | |||
249 | 249 | ||
250 | spin_lock_irqsave(&mdma_lock, flags); | 250 | spin_lock_irqsave(&mdma_lock, flags); |
251 | 251 | ||
252 | /* Force a sync in case a previous config reset on this channel | ||
253 | * occurred. This is needed so subsequent writes to DMA registers | ||
254 | * are not spuriously lost/corrupted. Do it under irq lock and | ||
255 | * without the anomaly version (because we are atomic already). | ||
256 | */ | ||
257 | __builtin_bfin_ssync(); | ||
258 | |||
252 | if (bfin_read_MDMA_S0_CONFIG()) | 259 | if (bfin_read_MDMA_S0_CONFIG()) |
253 | while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) | 260 | while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) |
254 | continue; | 261 | continue; |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 4c14331978f6..51dac55c524a 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -27,59 +27,6 @@ | |||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* | ||
31 | * Number BF537/6/4 BF561 BF533/2/1 BF549/8/4/2 | ||
32 | * | ||
33 | * GPIO_0 PF0 PF0 PF0 PA0...PJ13 | ||
34 | * GPIO_1 PF1 PF1 PF1 | ||
35 | * GPIO_2 PF2 PF2 PF2 | ||
36 | * GPIO_3 PF3 PF3 PF3 | ||
37 | * GPIO_4 PF4 PF4 PF4 | ||
38 | * GPIO_5 PF5 PF5 PF5 | ||
39 | * GPIO_6 PF6 PF6 PF6 | ||
40 | * GPIO_7 PF7 PF7 PF7 | ||
41 | * GPIO_8 PF8 PF8 PF8 | ||
42 | * GPIO_9 PF9 PF9 PF9 | ||
43 | * GPIO_10 PF10 PF10 PF10 | ||
44 | * GPIO_11 PF11 PF11 PF11 | ||
45 | * GPIO_12 PF12 PF12 PF12 | ||
46 | * GPIO_13 PF13 PF13 PF13 | ||
47 | * GPIO_14 PF14 PF14 PF14 | ||
48 | * GPIO_15 PF15 PF15 PF15 | ||
49 | * GPIO_16 PG0 PF16 | ||
50 | * GPIO_17 PG1 PF17 | ||
51 | * GPIO_18 PG2 PF18 | ||
52 | * GPIO_19 PG3 PF19 | ||
53 | * GPIO_20 PG4 PF20 | ||
54 | * GPIO_21 PG5 PF21 | ||
55 | * GPIO_22 PG6 PF22 | ||
56 | * GPIO_23 PG7 PF23 | ||
57 | * GPIO_24 PG8 PF24 | ||
58 | * GPIO_25 PG9 PF25 | ||
59 | * GPIO_26 PG10 PF26 | ||
60 | * GPIO_27 PG11 PF27 | ||
61 | * GPIO_28 PG12 PF28 | ||
62 | * GPIO_29 PG13 PF29 | ||
63 | * GPIO_30 PG14 PF30 | ||
64 | * GPIO_31 PG15 PF31 | ||
65 | * GPIO_32 PH0 PF32 | ||
66 | * GPIO_33 PH1 PF33 | ||
67 | * GPIO_34 PH2 PF34 | ||
68 | * GPIO_35 PH3 PF35 | ||
69 | * GPIO_36 PH4 PF36 | ||
70 | * GPIO_37 PH5 PF37 | ||
71 | * GPIO_38 PH6 PF38 | ||
72 | * GPIO_39 PH7 PF39 | ||
73 | * GPIO_40 PH8 PF40 | ||
74 | * GPIO_41 PH9 PF41 | ||
75 | * GPIO_42 PH10 PF42 | ||
76 | * GPIO_43 PH11 PF43 | ||
77 | * GPIO_44 PH12 PF44 | ||
78 | * GPIO_45 PH13 PF45 | ||
79 | * GPIO_46 PH14 PF46 | ||
80 | * GPIO_47 PH15 PF47 | ||
81 | */ | ||
82 | |||
83 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
84 | #include <linux/module.h> | 31 | #include <linux/module.h> |
85 | #include <linux/err.h> | 32 | #include <linux/err.h> |
@@ -119,62 +66,61 @@ enum { | |||
119 | #define AWA_DUMMY_READ(...) do { } while (0) | 66 | #define AWA_DUMMY_READ(...) do { } while (0) |
120 | #endif | 67 | #endif |
121 | 68 | ||
69 | static struct gpio_port_t * const gpio_array[] = { | ||
122 | #if defined(BF533_FAMILY) || defined(BF538_FAMILY) | 70 | #if defined(BF533_FAMILY) || defined(BF538_FAMILY) |
123 | static struct gpio_port_t *gpio_bankb[] = { | ||
124 | (struct gpio_port_t *) FIO_FLAG_D, | 71 | (struct gpio_port_t *) FIO_FLAG_D, |
125 | }; | 72 | #elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) |
126 | #endif | ||
127 | |||
128 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) | ||
129 | static struct gpio_port_t *gpio_bankb[] = { | ||
130 | (struct gpio_port_t *) PORTFIO, | 73 | (struct gpio_port_t *) PORTFIO, |
131 | (struct gpio_port_t *) PORTGIO, | 74 | (struct gpio_port_t *) PORTGIO, |
132 | (struct gpio_port_t *) PORTHIO, | 75 | (struct gpio_port_t *) PORTHIO, |
76 | #elif defined(BF561_FAMILY) | ||
77 | (struct gpio_port_t *) FIO0_FLAG_D, | ||
78 | (struct gpio_port_t *) FIO1_FLAG_D, | ||
79 | (struct gpio_port_t *) FIO2_FLAG_D, | ||
80 | #elif defined(BF548_FAMILY) | ||
81 | (struct gpio_port_t *)PORTA_FER, | ||
82 | (struct gpio_port_t *)PORTB_FER, | ||
83 | (struct gpio_port_t *)PORTC_FER, | ||
84 | (struct gpio_port_t *)PORTD_FER, | ||
85 | (struct gpio_port_t *)PORTE_FER, | ||
86 | (struct gpio_port_t *)PORTF_FER, | ||
87 | (struct gpio_port_t *)PORTG_FER, | ||
88 | (struct gpio_port_t *)PORTH_FER, | ||
89 | (struct gpio_port_t *)PORTI_FER, | ||
90 | (struct gpio_port_t *)PORTJ_FER, | ||
91 | #else | ||
92 | # error no gpio arrays defined | ||
93 | #endif | ||
133 | }; | 94 | }; |
134 | 95 | ||
135 | static unsigned short *port_fer[] = { | 96 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) |
97 | static unsigned short * const port_fer[] = { | ||
136 | (unsigned short *) PORTF_FER, | 98 | (unsigned short *) PORTF_FER, |
137 | (unsigned short *) PORTG_FER, | 99 | (unsigned short *) PORTG_FER, |
138 | (unsigned short *) PORTH_FER, | 100 | (unsigned short *) PORTH_FER, |
139 | }; | 101 | }; |
140 | #endif | ||
141 | 102 | ||
142 | #if defined(BF527_FAMILY) || defined(BF518_FAMILY) | 103 | # if !defined(BF537_FAMILY) |
143 | static unsigned short *port_mux[] = { | 104 | static unsigned short * const port_mux[] = { |
144 | (unsigned short *) PORTF_MUX, | 105 | (unsigned short *) PORTF_MUX, |
145 | (unsigned short *) PORTG_MUX, | 106 | (unsigned short *) PORTG_MUX, |
146 | (unsigned short *) PORTH_MUX, | 107 | (unsigned short *) PORTH_MUX, |
147 | }; | 108 | }; |
148 | 109 | ||
149 | static const | 110 | static const |
150 | u8 pmux_offset[][16] = | 111 | u8 pmux_offset[][16] = { |
151 | {{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ | 112 | # if defined(BF527_FAMILY) |
152 | { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ | 113 | { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ |
153 | { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ | 114 | { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ |
154 | }; | 115 | { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ |
155 | #endif | 116 | # elif defined(BF518_FAMILY) |
156 | 117 | { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */ | |
157 | #ifdef BF561_FAMILY | 118 | { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */ |
158 | static struct gpio_port_t *gpio_bankb[] = { | 119 | { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */ |
159 | (struct gpio_port_t *) FIO0_FLAG_D, | 120 | # endif |
160 | (struct gpio_port_t *) FIO1_FLAG_D, | ||
161 | (struct gpio_port_t *) FIO2_FLAG_D, | ||
162 | }; | 121 | }; |
163 | #endif | 122 | # endif |
164 | 123 | ||
165 | #ifdef BF548_FAMILY | ||
166 | static struct gpio_port_t *gpio_array[] = { | ||
167 | (struct gpio_port_t *)PORTA_FER, | ||
168 | (struct gpio_port_t *)PORTB_FER, | ||
169 | (struct gpio_port_t *)PORTC_FER, | ||
170 | (struct gpio_port_t *)PORTD_FER, | ||
171 | (struct gpio_port_t *)PORTE_FER, | ||
172 | (struct gpio_port_t *)PORTF_FER, | ||
173 | (struct gpio_port_t *)PORTG_FER, | ||
174 | (struct gpio_port_t *)PORTH_FER, | ||
175 | (struct gpio_port_t *)PORTI_FER, | ||
176 | (struct gpio_port_t *)PORTJ_FER, | ||
177 | }; | ||
178 | #endif | 124 | #endif |
179 | 125 | ||
180 | static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; | 126 | static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; |
@@ -188,35 +134,9 @@ static struct str_ident { | |||
188 | } str_ident[MAX_RESOURCES]; | 134 | } str_ident[MAX_RESOURCES]; |
189 | 135 | ||
190 | #if defined(CONFIG_PM) | 136 | #if defined(CONFIG_PM) |
191 | #if defined(CONFIG_BF54x) | ||
192 | static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; | ||
193 | #else | ||
194 | static unsigned short wakeup_map[GPIO_BANK_NUM]; | ||
195 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | ||
196 | static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; | 137 | static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; |
197 | |||
198 | #ifdef BF533_FAMILY | ||
199 | static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB}; | ||
200 | #endif | ||
201 | |||
202 | #ifdef BF537_FAMILY | ||
203 | static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; | ||
204 | #endif | ||
205 | |||
206 | #ifdef BF538_FAMILY | ||
207 | static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB}; | ||
208 | #endif | 138 | #endif |
209 | 139 | ||
210 | #if defined(BF527_FAMILY) || defined(BF518_FAMILY) | ||
211 | static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB}; | ||
212 | #endif | ||
213 | |||
214 | #ifdef BF561_FAMILY | ||
215 | static unsigned int sic_iwr_irqs[] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; | ||
216 | #endif | ||
217 | #endif | ||
218 | #endif /* CONFIG_PM */ | ||
219 | |||
220 | inline int check_gpio(unsigned gpio) | 140 | inline int check_gpio(unsigned gpio) |
221 | { | 141 | { |
222 | #if defined(BF548_FAMILY) | 142 | #if defined(BF548_FAMILY) |
@@ -330,9 +250,10 @@ static struct { | |||
330 | {.res = P_SPI0_SSEL3, .offset = 0}, | 250 | {.res = P_SPI0_SSEL3, .offset = 0}, |
331 | }; | 251 | }; |
332 | 252 | ||
333 | static void portmux_setup(unsigned short per, unsigned short function) | 253 | static void portmux_setup(unsigned short per) |
334 | { | 254 | { |
335 | u16 y, offset, muxreg; | 255 | u16 y, offset, muxreg; |
256 | u16 function = P_FUNCT2MUX(per); | ||
336 | 257 | ||
337 | for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) { | 258 | for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) { |
338 | if (port_mux_lut[y].res == per) { | 259 | if (port_mux_lut[y].res == per) { |
@@ -353,30 +274,33 @@ static void portmux_setup(unsigned short per, unsigned short function) | |||
353 | } | 274 | } |
354 | } | 275 | } |
355 | #elif defined(BF548_FAMILY) | 276 | #elif defined(BF548_FAMILY) |
356 | inline void portmux_setup(unsigned short portno, unsigned short function) | 277 | inline void portmux_setup(unsigned short per) |
357 | { | 278 | { |
358 | u32 pmux; | 279 | u32 pmux; |
280 | u16 ident = P_IDENT(per); | ||
281 | u16 function = P_FUNCT2MUX(per); | ||
359 | 282 | ||
360 | pmux = gpio_array[gpio_bank(portno)]->port_mux; | 283 | pmux = gpio_array[gpio_bank(ident)]->port_mux; |
361 | 284 | ||
362 | pmux &= ~(0x3 << (2 * gpio_sub_n(portno))); | 285 | pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); |
363 | pmux |= (function & 0x3) << (2 * gpio_sub_n(portno)); | 286 | pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); |
364 | 287 | ||
365 | gpio_array[gpio_bank(portno)]->port_mux = pmux; | 288 | gpio_array[gpio_bank(ident)]->port_mux = pmux; |
366 | } | 289 | } |
367 | 290 | ||
368 | inline u16 get_portmux(unsigned short portno) | 291 | inline u16 get_portmux(unsigned short per) |
369 | { | 292 | { |
370 | u32 pmux; | 293 | u32 pmux; |
294 | u16 ident = P_IDENT(per); | ||
371 | 295 | ||
372 | pmux = gpio_array[gpio_bank(portno)]->port_mux; | 296 | pmux = gpio_array[gpio_bank(ident)]->port_mux; |
373 | 297 | ||
374 | return (pmux >> (2 * gpio_sub_n(portno)) & 0x3); | 298 | return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); |
375 | } | 299 | } |
376 | #elif defined(BF527_FAMILY) || defined(BF518_FAMILY) | 300 | #elif defined(BF527_FAMILY) || defined(BF518_FAMILY) |
377 | inline void portmux_setup(unsigned short portno, unsigned short function) | 301 | inline void portmux_setup(unsigned short per) |
378 | { | 302 | { |
379 | u16 pmux, ident = P_IDENT(portno); | 303 | u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per); |
380 | u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; | 304 | u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; |
381 | 305 | ||
382 | pmux = *port_mux[gpio_bank(ident)]; | 306 | pmux = *port_mux[gpio_bank(ident)]; |
@@ -424,90 +348,71 @@ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ | |||
424 | unsigned long flags; \ | 348 | unsigned long flags; \ |
425 | local_irq_save_hw(flags); \ | 349 | local_irq_save_hw(flags); \ |
426 | if (arg) \ | 350 | if (arg) \ |
427 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ | 351 | gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ |
428 | else \ | 352 | else \ |
429 | gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ | 353 | gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ |
430 | AWA_DUMMY_READ(name); \ | 354 | AWA_DUMMY_READ(name); \ |
431 | local_irq_restore_hw(flags); \ | 355 | local_irq_restore_hw(flags); \ |
432 | } \ | 356 | } \ |
433 | EXPORT_SYMBOL(set_gpio_ ## name); | 357 | EXPORT_SYMBOL(set_gpio_ ## name); |
434 | 358 | ||
435 | SET_GPIO(dir) | 359 | SET_GPIO(dir) /* set_gpio_dir() */ |
436 | SET_GPIO(inen) | 360 | SET_GPIO(inen) /* set_gpio_inen() */ |
437 | SET_GPIO(polar) | 361 | SET_GPIO(polar) /* set_gpio_polar() */ |
438 | SET_GPIO(edge) | 362 | SET_GPIO(edge) /* set_gpio_edge() */ |
439 | SET_GPIO(both) | 363 | SET_GPIO(both) /* set_gpio_both() */ |
440 | 364 | ||
441 | 365 | ||
442 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
443 | #define SET_GPIO_SC(name) \ | 366 | #define SET_GPIO_SC(name) \ |
444 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ | 367 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
445 | { \ | 368 | { \ |
446 | unsigned long flags; \ | 369 | unsigned long flags; \ |
447 | local_irq_save_hw(flags); \ | 370 | if (ANOMALY_05000311 || ANOMALY_05000323) \ |
448 | if (arg) \ | 371 | local_irq_save_hw(flags); \ |
449 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | ||
450 | else \ | ||
451 | gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ | ||
452 | AWA_DUMMY_READ(name); \ | ||
453 | local_irq_restore_hw(flags); \ | ||
454 | } \ | ||
455 | EXPORT_SYMBOL(set_gpio_ ## name); | ||
456 | #else | ||
457 | #define SET_GPIO_SC(name) \ | ||
458 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ | ||
459 | { \ | ||
460 | if (arg) \ | 372 | if (arg) \ |
461 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | 373 | gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ |
462 | else \ | 374 | else \ |
463 | gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ | 375 | gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ |
376 | if (ANOMALY_05000311 || ANOMALY_05000323) { \ | ||
377 | AWA_DUMMY_READ(name); \ | ||
378 | local_irq_restore_hw(flags); \ | ||
379 | } \ | ||
464 | } \ | 380 | } \ |
465 | EXPORT_SYMBOL(set_gpio_ ## name); | 381 | EXPORT_SYMBOL(set_gpio_ ## name); |
466 | #endif | ||
467 | 382 | ||
468 | SET_GPIO_SC(maska) | 383 | SET_GPIO_SC(maska) |
469 | SET_GPIO_SC(maskb) | 384 | SET_GPIO_SC(maskb) |
470 | SET_GPIO_SC(data) | 385 | SET_GPIO_SC(data) |
471 | 386 | ||
472 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
473 | void set_gpio_toggle(unsigned gpio) | 387 | void set_gpio_toggle(unsigned gpio) |
474 | { | 388 | { |
475 | unsigned long flags; | 389 | unsigned long flags; |
476 | local_irq_save_hw(flags); | 390 | if (ANOMALY_05000311 || ANOMALY_05000323) |
477 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | 391 | local_irq_save_hw(flags); |
478 | AWA_DUMMY_READ(toggle); | 392 | gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); |
479 | local_irq_restore_hw(flags); | 393 | if (ANOMALY_05000311 || ANOMALY_05000323) { |
480 | } | 394 | AWA_DUMMY_READ(toggle); |
481 | #else | 395 | local_irq_restore_hw(flags); |
482 | void set_gpio_toggle(unsigned gpio) | 396 | } |
483 | { | ||
484 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | ||
485 | } | 397 | } |
486 | #endif | ||
487 | EXPORT_SYMBOL(set_gpio_toggle); | 398 | EXPORT_SYMBOL(set_gpio_toggle); |
488 | 399 | ||
489 | 400 | ||
490 | /*Set current PORT date (16-bit word)*/ | 401 | /*Set current PORT date (16-bit word)*/ |
491 | 402 | ||
492 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
493 | #define SET_GPIO_P(name) \ | 403 | #define SET_GPIO_P(name) \ |
494 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ | 404 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ |
495 | { \ | 405 | { \ |
496 | unsigned long flags; \ | 406 | unsigned long flags; \ |
497 | local_irq_save_hw(flags); \ | 407 | if (ANOMALY_05000311 || ANOMALY_05000323) \ |
498 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | 408 | local_irq_save_hw(flags); \ |
499 | AWA_DUMMY_READ(name); \ | 409 | gpio_array[gpio_bank(gpio)]->name = arg; \ |
500 | local_irq_restore_hw(flags); \ | 410 | if (ANOMALY_05000311 || ANOMALY_05000323) { \ |
411 | AWA_DUMMY_READ(name); \ | ||
412 | local_irq_restore_hw(flags); \ | ||
413 | } \ | ||
501 | } \ | 414 | } \ |
502 | EXPORT_SYMBOL(set_gpiop_ ## name); | 415 | EXPORT_SYMBOL(set_gpiop_ ## name); |
503 | #else | ||
504 | #define SET_GPIO_P(name) \ | ||
505 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ | ||
506 | { \ | ||
507 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | ||
508 | } \ | ||
509 | EXPORT_SYMBOL(set_gpiop_ ## name); | ||
510 | #endif | ||
511 | 416 | ||
512 | SET_GPIO_P(data) | 417 | SET_GPIO_P(data) |
513 | SET_GPIO_P(dir) | 418 | SET_GPIO_P(dir) |
@@ -519,27 +424,21 @@ SET_GPIO_P(maska) | |||
519 | SET_GPIO_P(maskb) | 424 | SET_GPIO_P(maskb) |
520 | 425 | ||
521 | /* Get a specific bit */ | 426 | /* Get a specific bit */ |
522 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
523 | #define GET_GPIO(name) \ | 427 | #define GET_GPIO(name) \ |
524 | unsigned short get_gpio_ ## name(unsigned gpio) \ | 428 | unsigned short get_gpio_ ## name(unsigned gpio) \ |
525 | { \ | 429 | { \ |
526 | unsigned long flags; \ | 430 | unsigned long flags; \ |
527 | unsigned short ret; \ | 431 | unsigned short ret; \ |
528 | local_irq_save_hw(flags); \ | 432 | if (ANOMALY_05000311 || ANOMALY_05000323) \ |
529 | ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ | 433 | local_irq_save_hw(flags); \ |
530 | AWA_DUMMY_READ(name); \ | 434 | ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ |
531 | local_irq_restore_hw(flags); \ | 435 | if (ANOMALY_05000311 || ANOMALY_05000323) { \ |
436 | AWA_DUMMY_READ(name); \ | ||
437 | local_irq_restore_hw(flags); \ | ||
438 | } \ | ||
532 | return ret; \ | 439 | return ret; \ |
533 | } \ | 440 | } \ |
534 | EXPORT_SYMBOL(get_gpio_ ## name); | 441 | EXPORT_SYMBOL(get_gpio_ ## name); |
535 | #else | ||
536 | #define GET_GPIO(name) \ | ||
537 | unsigned short get_gpio_ ## name(unsigned gpio) \ | ||
538 | { \ | ||
539 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ | ||
540 | } \ | ||
541 | EXPORT_SYMBOL(get_gpio_ ## name); | ||
542 | #endif | ||
543 | 442 | ||
544 | GET_GPIO(data) | 443 | GET_GPIO(data) |
545 | GET_GPIO(dir) | 444 | GET_GPIO(dir) |
@@ -552,27 +451,21 @@ GET_GPIO(maskb) | |||
552 | 451 | ||
553 | /*Get current PORT date (16-bit word)*/ | 452 | /*Get current PORT date (16-bit word)*/ |
554 | 453 | ||
555 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
556 | #define GET_GPIO_P(name) \ | 454 | #define GET_GPIO_P(name) \ |
557 | unsigned short get_gpiop_ ## name(unsigned gpio) \ | 455 | unsigned short get_gpiop_ ## name(unsigned gpio) \ |
558 | { \ | 456 | { \ |
559 | unsigned long flags; \ | 457 | unsigned long flags; \ |
560 | unsigned short ret; \ | 458 | unsigned short ret; \ |
561 | local_irq_save_hw(flags); \ | 459 | if (ANOMALY_05000311 || ANOMALY_05000323) \ |
562 | ret = (gpio_bankb[gpio_bank(gpio)]->name); \ | 460 | local_irq_save_hw(flags); \ |
563 | AWA_DUMMY_READ(name); \ | 461 | ret = (gpio_array[gpio_bank(gpio)]->name); \ |
564 | local_irq_restore_hw(flags); \ | 462 | if (ANOMALY_05000311 || ANOMALY_05000323) { \ |
463 | AWA_DUMMY_READ(name); \ | ||
464 | local_irq_restore_hw(flags); \ | ||
465 | } \ | ||
565 | return ret; \ | 466 | return ret; \ |
566 | } \ | 467 | } \ |
567 | EXPORT_SYMBOL(get_gpiop_ ## name); | 468 | EXPORT_SYMBOL(get_gpiop_ ## name); |
568 | #else | ||
569 | #define GET_GPIO_P(name) \ | ||
570 | unsigned short get_gpiop_ ## name(unsigned gpio) \ | ||
571 | { \ | ||
572 | return (gpio_bankb[gpio_bank(gpio)]->name);\ | ||
573 | } \ | ||
574 | EXPORT_SYMBOL(get_gpiop_ ## name); | ||
575 | #endif | ||
576 | 469 | ||
577 | GET_GPIO_P(data) | 470 | GET_GPIO_P(data) |
578 | GET_GPIO_P(dir) | 471 | GET_GPIO_P(dir) |
@@ -585,6 +478,26 @@ GET_GPIO_P(maskb) | |||
585 | 478 | ||
586 | 479 | ||
587 | #ifdef CONFIG_PM | 480 | #ifdef CONFIG_PM |
481 | |||
482 | static unsigned short wakeup_map[GPIO_BANK_NUM]; | ||
483 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | ||
484 | |||
485 | static const unsigned int sic_iwr_irqs[] = { | ||
486 | #if defined(BF533_FAMILY) | ||
487 | IRQ_PROG_INTB | ||
488 | #elif defined(BF537_FAMILY) | ||
489 | IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX | ||
490 | #elif defined(BF538_FAMILY) | ||
491 | IRQ_PORTF_INTB | ||
492 | #elif defined(BF527_FAMILY) || defined(BF518_FAMILY) | ||
493 | IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB | ||
494 | #elif defined(BF561_FAMILY) | ||
495 | IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB | ||
496 | #else | ||
497 | # error no SIC_IWR defined | ||
498 | #endif | ||
499 | }; | ||
500 | |||
588 | /*********************************************************** | 501 | /*********************************************************** |
589 | * | 502 | * |
590 | * FUNCTIONS: Blackfin PM Setup API | 503 | * FUNCTIONS: Blackfin PM Setup API |
@@ -669,18 +582,18 @@ u32 bfin_pm_standby_setup(void) | |||
669 | mask = wakeup_map[gpio_bank(i)]; | 582 | mask = wakeup_map[gpio_bank(i)]; |
670 | bank = gpio_bank(i); | 583 | bank = gpio_bank(i); |
671 | 584 | ||
672 | gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; | 585 | gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; |
673 | gpio_bankb[bank]->maskb = 0; | 586 | gpio_array[bank]->maskb = 0; |
674 | 587 | ||
675 | if (mask) { | 588 | if (mask) { |
676 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) | 589 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) |
677 | gpio_bank_saved[bank].fer = *port_fer[bank]; | 590 | gpio_bank_saved[bank].fer = *port_fer[bank]; |
678 | #endif | 591 | #endif |
679 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | 592 | gpio_bank_saved[bank].inen = gpio_array[bank]->inen; |
680 | gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; | 593 | gpio_bank_saved[bank].polar = gpio_array[bank]->polar; |
681 | gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; | 594 | gpio_bank_saved[bank].dir = gpio_array[bank]->dir; |
682 | gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; | 595 | gpio_bank_saved[bank].edge = gpio_array[bank]->edge; |
683 | gpio_bank_saved[bank].both = gpio_bankb[bank]->both; | 596 | gpio_bank_saved[bank].both = gpio_array[bank]->both; |
684 | gpio_bank_saved[bank].reserved = | 597 | gpio_bank_saved[bank].reserved = |
685 | reserved_gpio_map[bank]; | 598 | reserved_gpio_map[bank]; |
686 | 599 | ||
@@ -700,7 +613,7 @@ u32 bfin_pm_standby_setup(void) | |||
700 | } | 613 | } |
701 | 614 | ||
702 | bfin_internal_set_wake(sic_iwr_irqs[bank], 1); | 615 | bfin_internal_set_wake(sic_iwr_irqs[bank], 1); |
703 | gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; | 616 | gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; |
704 | } | 617 | } |
705 | } | 618 | } |
706 | 619 | ||
@@ -721,18 +634,18 @@ void bfin_pm_standby_restore(void) | |||
721 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) | 634 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) |
722 | *port_fer[bank] = gpio_bank_saved[bank].fer; | 635 | *port_fer[bank] = gpio_bank_saved[bank].fer; |
723 | #endif | 636 | #endif |
724 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | 637 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; |
725 | gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; | 638 | gpio_array[bank]->dir = gpio_bank_saved[bank].dir; |
726 | gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; | 639 | gpio_array[bank]->polar = gpio_bank_saved[bank].polar; |
727 | gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; | 640 | gpio_array[bank]->edge = gpio_bank_saved[bank].edge; |
728 | gpio_bankb[bank]->both = gpio_bank_saved[bank].both; | 641 | gpio_array[bank]->both = gpio_bank_saved[bank].both; |
729 | 642 | ||
730 | reserved_gpio_map[bank] = | 643 | reserved_gpio_map[bank] = |
731 | gpio_bank_saved[bank].reserved; | 644 | gpio_bank_saved[bank].reserved; |
732 | bfin_internal_set_wake(sic_iwr_irqs[bank], 0); | 645 | bfin_internal_set_wake(sic_iwr_irqs[bank], 0); |
733 | } | 646 | } |
734 | 647 | ||
735 | gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; | 648 | gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; |
736 | } | 649 | } |
737 | AWA_DUMMY_READ(maskb); | 650 | AWA_DUMMY_READ(maskb); |
738 | } | 651 | } |
@@ -745,21 +658,21 @@ void bfin_gpio_pm_hibernate_suspend(void) | |||
745 | bank = gpio_bank(i); | 658 | bank = gpio_bank(i); |
746 | 659 | ||
747 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) | 660 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) |
748 | gpio_bank_saved[bank].fer = *port_fer[bank]; | 661 | gpio_bank_saved[bank].fer = *port_fer[bank]; |
749 | #if defined(BF527_FAMILY) || defined(BF518_FAMILY) | 662 | #if defined(BF527_FAMILY) || defined(BF518_FAMILY) |
750 | gpio_bank_saved[bank].mux = *port_mux[bank]; | 663 | gpio_bank_saved[bank].mux = *port_mux[bank]; |
751 | #else | 664 | #else |
752 | if (bank == 0) | 665 | if (bank == 0) |
753 | gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); | 666 | gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); |
754 | #endif | 667 | #endif |
755 | #endif | 668 | #endif |
756 | gpio_bank_saved[bank].data = gpio_bankb[bank]->data; | 669 | gpio_bank_saved[bank].data = gpio_array[bank]->data; |
757 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | 670 | gpio_bank_saved[bank].inen = gpio_array[bank]->inen; |
758 | gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; | 671 | gpio_bank_saved[bank].polar = gpio_array[bank]->polar; |
759 | gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; | 672 | gpio_bank_saved[bank].dir = gpio_array[bank]->dir; |
760 | gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; | 673 | gpio_bank_saved[bank].edge = gpio_array[bank]->edge; |
761 | gpio_bank_saved[bank].both = gpio_bankb[bank]->both; | 674 | gpio_bank_saved[bank].both = gpio_array[bank]->both; |
762 | gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; | 675 | gpio_bank_saved[bank].maska = gpio_array[bank]->maska; |
763 | } | 676 | } |
764 | 677 | ||
765 | AWA_DUMMY_READ(maska); | 678 | AWA_DUMMY_READ(maska); |
@@ -770,27 +683,27 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
770 | int i, bank; | 683 | int i, bank; |
771 | 684 | ||
772 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 685 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
773 | bank = gpio_bank(i); | 686 | bank = gpio_bank(i); |
774 | 687 | ||
775 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) | 688 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) |
776 | #if defined(BF527_FAMILY) || defined(BF518_FAMILY) | 689 | #if defined(BF527_FAMILY) || defined(BF518_FAMILY) |
777 | *port_mux[bank] = gpio_bank_saved[bank].mux; | 690 | *port_mux[bank] = gpio_bank_saved[bank].mux; |
778 | #else | 691 | #else |
779 | if (bank == 0) | 692 | if (bank == 0) |
780 | bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); | 693 | bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); |
781 | #endif | 694 | #endif |
782 | *port_fer[bank] = gpio_bank_saved[bank].fer; | 695 | *port_fer[bank] = gpio_bank_saved[bank].fer; |
783 | #endif | 696 | #endif |
784 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | 697 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; |
785 | gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; | 698 | gpio_array[bank]->dir = gpio_bank_saved[bank].dir; |
786 | gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; | 699 | gpio_array[bank]->polar = gpio_bank_saved[bank].polar; |
787 | gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; | 700 | gpio_array[bank]->edge = gpio_bank_saved[bank].edge; |
788 | gpio_bankb[bank]->both = gpio_bank_saved[bank].both; | 701 | gpio_array[bank]->both = gpio_bank_saved[bank].both; |
789 | 702 | ||
790 | gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data | 703 | gpio_array[bank]->data_set = gpio_bank_saved[bank].data |
791 | | gpio_bank_saved[bank].dir; | 704 | | gpio_bank_saved[bank].dir; |
792 | 705 | ||
793 | gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; | 706 | gpio_array[bank]->maska = gpio_bank_saved[bank].maska; |
794 | } | 707 | } |
795 | AWA_DUMMY_READ(maska); | 708 | AWA_DUMMY_READ(maska); |
796 | } | 709 | } |
@@ -817,12 +730,12 @@ void bfin_gpio_pm_hibernate_suspend(void) | |||
817 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 730 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
818 | bank = gpio_bank(i); | 731 | bank = gpio_bank(i); |
819 | 732 | ||
820 | gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; | 733 | gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; |
821 | gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; | 734 | gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; |
822 | gpio_bank_saved[bank].data = gpio_array[bank]->port_data; | 735 | gpio_bank_saved[bank].data = gpio_array[bank]->data; |
823 | gpio_bank_saved[bank].data = gpio_array[bank]->port_data; | 736 | gpio_bank_saved[bank].data = gpio_array[bank]->data; |
824 | gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; | 737 | gpio_bank_saved[bank].inen = gpio_array[bank]->inen; |
825 | gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; | 738 | gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; |
826 | } | 739 | } |
827 | } | 740 | } |
828 | 741 | ||
@@ -831,21 +744,21 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
831 | int i, bank; | 744 | int i, bank; |
832 | 745 | ||
833 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | 746 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { |
834 | bank = gpio_bank(i); | 747 | bank = gpio_bank(i); |
835 | 748 | ||
836 | gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; | 749 | gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; |
837 | gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; | 750 | gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; |
838 | gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; | 751 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; |
839 | gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; | 752 | gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; |
840 | gpio_array[bank]->port_set = gpio_bank_saved[bank].data | 753 | gpio_array[bank]->data_set = gpio_bank_saved[bank].data |
841 | | gpio_bank_saved[bank].dir; | 754 | | gpio_bank_saved[bank].dir; |
842 | } | 755 | } |
843 | } | 756 | } |
844 | #endif | 757 | #endif |
845 | 758 | ||
846 | unsigned short get_gpio_dir(unsigned gpio) | 759 | unsigned short get_gpio_dir(unsigned gpio) |
847 | { | 760 | { |
848 | return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio))); | 761 | return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); |
849 | } | 762 | } |
850 | EXPORT_SYMBOL(get_gpio_dir); | 763 | EXPORT_SYMBOL(get_gpio_dir); |
851 | 764 | ||
@@ -905,9 +818,7 @@ int peripheral_request(unsigned short per, const char *label) | |||
905 | */ | 818 | */ |
906 | 819 | ||
907 | #ifdef BF548_FAMILY | 820 | #ifdef BF548_FAMILY |
908 | u16 funct = get_portmux(ident); | 821 | if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { |
909 | |||
910 | if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) { | ||
911 | #else | 822 | #else |
912 | if (!(per & P_MAYSHARE)) { | 823 | if (!(per & P_MAYSHARE)) { |
913 | #endif | 824 | #endif |
@@ -931,11 +842,7 @@ int peripheral_request(unsigned short per, const char *label) | |||
931 | anyway: | 842 | anyway: |
932 | reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); | 843 | reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); |
933 | 844 | ||
934 | #ifdef BF548_FAMILY | 845 | portmux_setup(per); |
935 | portmux_setup(ident, P_FUNCT2MUX(per)); | ||
936 | #else | ||
937 | portmux_setup(per, P_FUNCT2MUX(per)); | ||
938 | #endif | ||
939 | port_setup(ident, PERIPHERAL_USAGE); | 846 | port_setup(ident, PERIPHERAL_USAGE); |
940 | 847 | ||
941 | local_irq_restore_hw(flags); | 848 | local_irq_restore_hw(flags); |
@@ -977,9 +884,6 @@ void peripheral_free(unsigned short per) | |||
977 | if (!(per & P_DEFINED)) | 884 | if (!(per & P_DEFINED)) |
978 | return; | 885 | return; |
979 | 886 | ||
980 | if (check_gpio(ident) < 0) | ||
981 | return; | ||
982 | |||
983 | local_irq_save_hw(flags); | 887 | local_irq_save_hw(flags); |
984 | 888 | ||
985 | if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { | 889 | if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { |
@@ -1056,9 +960,15 @@ int bfin_gpio_request(unsigned gpio, const char *label) | |||
1056 | local_irq_restore_hw(flags); | 960 | local_irq_restore_hw(flags); |
1057 | return -EBUSY; | 961 | return -EBUSY; |
1058 | } | 962 | } |
1059 | if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) | 963 | if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1060 | printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" | 964 | printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" |
1061 | " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); | 965 | " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); |
966 | } | ||
967 | #ifndef BF548_FAMILY | ||
968 | else { /* Reset POLAR setting when acquiring a gpio for the first time */ | ||
969 | set_gpio_polar(gpio, 0); | ||
970 | } | ||
971 | #endif | ||
1062 | 972 | ||
1063 | reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); | 973 | reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); |
1064 | set_label(gpio, label); | 974 | set_label(gpio, label); |
@@ -1078,6 +988,8 @@ void bfin_gpio_free(unsigned gpio) | |||
1078 | if (check_gpio(gpio) < 0) | 988 | if (check_gpio(gpio) < 0) |
1079 | return; | 989 | return; |
1080 | 990 | ||
991 | might_sleep(); | ||
992 | |||
1081 | local_irq_save_hw(flags); | 993 | local_irq_save_hw(flags); |
1082 | 994 | ||
1083 | if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | 995 | if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { |
@@ -1158,8 +1070,16 @@ void bfin_gpio_irq_free(unsigned gpio) | |||
1158 | local_irq_restore_hw(flags); | 1070 | local_irq_restore_hw(flags); |
1159 | } | 1071 | } |
1160 | 1072 | ||
1161 | 1073 | static inline void __bfin_gpio_direction_input(unsigned gpio) | |
1074 | { | ||
1162 | #ifdef BF548_FAMILY | 1075 | #ifdef BF548_FAMILY |
1076 | gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); | ||
1077 | #else | ||
1078 | gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); | ||
1079 | #endif | ||
1080 | gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); | ||
1081 | } | ||
1082 | |||
1163 | int bfin_gpio_direction_input(unsigned gpio) | 1083 | int bfin_gpio_direction_input(unsigned gpio) |
1164 | { | 1084 | { |
1165 | unsigned long flags; | 1085 | unsigned long flags; |
@@ -1170,125 +1090,85 @@ int bfin_gpio_direction_input(unsigned gpio) | |||
1170 | } | 1090 | } |
1171 | 1091 | ||
1172 | local_irq_save_hw(flags); | 1092 | local_irq_save_hw(flags); |
1173 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); | 1093 | __bfin_gpio_direction_input(gpio); |
1174 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); | 1094 | AWA_DUMMY_READ(inen); |
1175 | local_irq_restore_hw(flags); | 1095 | local_irq_restore_hw(flags); |
1176 | 1096 | ||
1177 | return 0; | 1097 | return 0; |
1178 | } | 1098 | } |
1179 | EXPORT_SYMBOL(bfin_gpio_direction_input); | 1099 | EXPORT_SYMBOL(bfin_gpio_direction_input); |
1180 | 1100 | ||
1181 | int bfin_gpio_direction_output(unsigned gpio, int value) | 1101 | void bfin_gpio_irq_prepare(unsigned gpio) |
1182 | { | 1102 | { |
1103 | #ifdef BF548_FAMILY | ||
1183 | unsigned long flags; | 1104 | unsigned long flags; |
1105 | #endif | ||
1184 | 1106 | ||
1185 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | 1107 | port_setup(gpio, GPIO_USAGE); |
1186 | gpio_error(gpio); | ||
1187 | return -EINVAL; | ||
1188 | } | ||
1189 | 1108 | ||
1109 | #ifdef BF548_FAMILY | ||
1190 | local_irq_save_hw(flags); | 1110 | local_irq_save_hw(flags); |
1191 | gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); | 1111 | __bfin_gpio_direction_input(gpio); |
1192 | gpio_set_value(gpio, value); | ||
1193 | gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); | ||
1194 | local_irq_restore_hw(flags); | 1112 | local_irq_restore_hw(flags); |
1195 | 1113 | #endif | |
1196 | return 0; | ||
1197 | } | 1114 | } |
1198 | EXPORT_SYMBOL(bfin_gpio_direction_output); | ||
1199 | 1115 | ||
1200 | void bfin_gpio_set_value(unsigned gpio, int arg) | 1116 | void bfin_gpio_set_value(unsigned gpio, int arg) |
1201 | { | 1117 | { |
1202 | if (arg) | 1118 | if (arg) |
1203 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); | 1119 | gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); |
1204 | else | 1120 | else |
1205 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); | 1121 | gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); |
1206 | } | 1122 | } |
1207 | EXPORT_SYMBOL(bfin_gpio_set_value); | 1123 | EXPORT_SYMBOL(bfin_gpio_set_value); |
1208 | 1124 | ||
1209 | int bfin_gpio_get_value(unsigned gpio) | 1125 | int bfin_gpio_direction_output(unsigned gpio, int value) |
1210 | { | ||
1211 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); | ||
1212 | } | ||
1213 | EXPORT_SYMBOL(bfin_gpio_get_value); | ||
1214 | |||
1215 | void bfin_gpio_irq_prepare(unsigned gpio) | ||
1216 | { | 1126 | { |
1217 | unsigned long flags; | 1127 | unsigned long flags; |
1218 | 1128 | ||
1219 | port_setup(gpio, GPIO_USAGE); | 1129 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1130 | gpio_error(gpio); | ||
1131 | return -EINVAL; | ||
1132 | } | ||
1220 | 1133 | ||
1221 | local_irq_save_hw(flags); | 1134 | local_irq_save_hw(flags); |
1222 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); | ||
1223 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); | ||
1224 | local_irq_restore_hw(flags); | ||
1225 | } | ||
1226 | 1135 | ||
1136 | gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); | ||
1137 | gpio_set_value(gpio, value); | ||
1138 | #ifdef BF548_FAMILY | ||
1139 | gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); | ||
1227 | #else | 1140 | #else |
1141 | gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); | ||
1142 | #endif | ||
1143 | |||
1144 | AWA_DUMMY_READ(dir); | ||
1145 | local_irq_restore_hw(flags); | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | EXPORT_SYMBOL(bfin_gpio_direction_output); | ||
1228 | 1150 | ||
1229 | int bfin_gpio_get_value(unsigned gpio) | 1151 | int bfin_gpio_get_value(unsigned gpio) |
1230 | { | 1152 | { |
1153 | #ifdef BF548_FAMILY | ||
1154 | return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); | ||
1155 | #else | ||
1231 | unsigned long flags; | 1156 | unsigned long flags; |
1232 | int ret; | ||
1233 | 1157 | ||
1234 | if (unlikely(get_gpio_edge(gpio))) { | 1158 | if (unlikely(get_gpio_edge(gpio))) { |
1159 | int ret; | ||
1235 | local_irq_save_hw(flags); | 1160 | local_irq_save_hw(flags); |
1236 | set_gpio_edge(gpio, 0); | 1161 | set_gpio_edge(gpio, 0); |
1237 | ret = get_gpio_data(gpio); | 1162 | ret = get_gpio_data(gpio); |
1238 | set_gpio_edge(gpio, 1); | 1163 | set_gpio_edge(gpio, 1); |
1239 | local_irq_restore_hw(flags); | 1164 | local_irq_restore_hw(flags); |
1240 | |||
1241 | return ret; | 1165 | return ret; |
1242 | } else | 1166 | } else |
1243 | return get_gpio_data(gpio); | 1167 | return get_gpio_data(gpio); |
1168 | #endif | ||
1244 | } | 1169 | } |
1245 | EXPORT_SYMBOL(bfin_gpio_get_value); | 1170 | EXPORT_SYMBOL(bfin_gpio_get_value); |
1246 | 1171 | ||
1247 | |||
1248 | int bfin_gpio_direction_input(unsigned gpio) | ||
1249 | { | ||
1250 | unsigned long flags; | ||
1251 | |||
1252 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | ||
1253 | gpio_error(gpio); | ||
1254 | return -EINVAL; | ||
1255 | } | ||
1256 | |||
1257 | local_irq_save_hw(flags); | ||
1258 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); | ||
1259 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); | ||
1260 | AWA_DUMMY_READ(inen); | ||
1261 | local_irq_restore_hw(flags); | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | EXPORT_SYMBOL(bfin_gpio_direction_input); | ||
1266 | |||
1267 | int bfin_gpio_direction_output(unsigned gpio, int value) | ||
1268 | { | ||
1269 | unsigned long flags; | ||
1270 | |||
1271 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | ||
1272 | gpio_error(gpio); | ||
1273 | return -EINVAL; | ||
1274 | } | ||
1275 | |||
1276 | local_irq_save_hw(flags); | ||
1277 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); | ||
1278 | |||
1279 | if (value) | ||
1280 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | ||
1281 | else | ||
1282 | gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); | ||
1283 | |||
1284 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); | ||
1285 | AWA_DUMMY_READ(dir); | ||
1286 | local_irq_restore_hw(flags); | ||
1287 | |||
1288 | return 0; | ||
1289 | } | ||
1290 | EXPORT_SYMBOL(bfin_gpio_direction_output); | ||
1291 | |||
1292 | /* If we are booting from SPI and our board lacks a strong enough pull up, | 1172 | /* If we are booting from SPI and our board lacks a strong enough pull up, |
1293 | * the core can reset and execute the bootrom faster than the resistor can | 1173 | * the core can reset and execute the bootrom faster than the resistor can |
1294 | * pull the signal logically high. To work around this (common) error in | 1174 | * pull the signal logically high. To work around this (common) error in |
@@ -1299,23 +1179,15 @@ EXPORT_SYMBOL(bfin_gpio_direction_output); | |||
1299 | * lives here as we need to force all the GPIO states w/out going through | 1179 | * lives here as we need to force all the GPIO states w/out going through |
1300 | * BUG() checks and such. | 1180 | * BUG() checks and such. |
1301 | */ | 1181 | */ |
1302 | void bfin_gpio_reset_spi0_ssel1(void) | 1182 | void bfin_reset_boot_spi_cs(unsigned short pin) |
1303 | { | 1183 | { |
1304 | u16 gpio = P_IDENT(P_SPI0_SSEL1); | 1184 | unsigned short gpio = P_IDENT(pin); |
1305 | |||
1306 | port_setup(gpio, GPIO_USAGE); | 1185 | port_setup(gpio, GPIO_USAGE); |
1307 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | 1186 | gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); |
1308 | AWA_DUMMY_READ(data_set); | 1187 | AWA_DUMMY_READ(data_set); |
1309 | udelay(1); | 1188 | udelay(1); |
1310 | } | 1189 | } |
1311 | 1190 | ||
1312 | void bfin_gpio_irq_prepare(unsigned gpio) | ||
1313 | { | ||
1314 | port_setup(gpio, GPIO_USAGE); | ||
1315 | } | ||
1316 | |||
1317 | #endif /*BF548_FAMILY */ | ||
1318 | |||
1319 | #if defined(CONFIG_PROC_FS) | 1191 | #if defined(CONFIG_PROC_FS) |
1320 | static int gpio_proc_read(char *buf, char **start, off_t offset, | 1192 | static int gpio_proc_read(char *buf, char **start, off_t offset, |
1321 | int len, int *unused_i, void *unused_v) | 1193 | int len, int *unused_i, void *unused_v) |
@@ -1369,11 +1241,7 @@ int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) | |||
1369 | 1241 | ||
1370 | void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) | 1242 | void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) |
1371 | { | 1243 | { |
1372 | #ifdef BF548_FAMILY | ||
1373 | return bfin_gpio_set_value(gpio, value); | 1244 | return bfin_gpio_set_value(gpio, value); |
1374 | #else | ||
1375 | return set_gpio_data(gpio, value); | ||
1376 | #endif | ||
1377 | } | 1245 | } |
1378 | 1246 | ||
1379 | int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) | 1247 | int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) |
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index bdb958486e76..3e329a6ce041 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c | |||
@@ -63,10 +63,8 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) | |||
63 | dcplb_tbl[cpu][i_d].addr = 0; | 63 | dcplb_tbl[cpu][i_d].addr = 0; |
64 | dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; | 64 | dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; |
65 | 65 | ||
66 | #if 0 | ||
67 | icplb_tbl[cpu][i_i].addr = 0; | 66 | icplb_tbl[cpu][i_i].addr = 0; |
68 | icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB; | 67 | icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; |
69 | #endif | ||
70 | 68 | ||
71 | /* Cover kernel memory with 4M pages. */ | 69 | /* Cover kernel memory with 4M pages. */ |
72 | addr = 0; | 70 | addr = 0; |
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 0e28f7595733..d6c067782e63 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c | |||
@@ -53,9 +53,13 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) | |||
53 | 53 | ||
54 | i_d = i_i = 0; | 54 | i_d = i_i = 0; |
55 | 55 | ||
56 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO | ||
56 | /* Set up the zero page. */ | 57 | /* Set up the zero page. */ |
57 | d_tbl[i_d].addr = 0; | 58 | d_tbl[i_d].addr = 0; |
58 | d_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; | 59 | d_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; |
60 | i_tbl[i_i].addr = 0; | ||
61 | i_tbl[i_i++].data = SDRAM_OOPS | PAGE_SIZE_1KB; | ||
62 | #endif | ||
59 | 63 | ||
60 | /* Cover kernel memory with 4M pages. */ | 64 | /* Cover kernel memory with 4M pages. */ |
61 | addr = 0; | 65 | addr = 0; |
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index 376249ab2694..8cbb47c7b663 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c | |||
@@ -163,12 +163,14 @@ MGR_ATTR static int icplb_miss(int cpu) | |||
163 | nr_icplb_supv_miss[cpu]++; | 163 | nr_icplb_supv_miss[cpu]++; |
164 | 164 | ||
165 | base = 0; | 165 | base = 0; |
166 | for (idx = 0; idx < icplb_nr_bounds; idx++) { | 166 | idx = 0; |
167 | do { | ||
167 | eaddr = icplb_bounds[idx].eaddr; | 168 | eaddr = icplb_bounds[idx].eaddr; |
168 | if (addr < eaddr) | 169 | if (addr < eaddr) |
169 | break; | 170 | break; |
170 | base = eaddr; | 171 | base = eaddr; |
171 | } | 172 | } while (++idx < icplb_nr_bounds); |
173 | |||
172 | if (unlikely(idx == icplb_nr_bounds)) | 174 | if (unlikely(idx == icplb_nr_bounds)) |
173 | return CPLB_NO_ADDR_MATCH; | 175 | return CPLB_NO_ADDR_MATCH; |
174 | 176 | ||
@@ -208,12 +210,14 @@ MGR_ATTR static int dcplb_miss(int cpu) | |||
208 | nr_dcplb_supv_miss[cpu]++; | 210 | nr_dcplb_supv_miss[cpu]++; |
209 | 211 | ||
210 | base = 0; | 212 | base = 0; |
211 | for (idx = 0; idx < dcplb_nr_bounds; idx++) { | 213 | idx = 0; |
214 | do { | ||
212 | eaddr = dcplb_bounds[idx].eaddr; | 215 | eaddr = dcplb_bounds[idx].eaddr; |
213 | if (addr < eaddr) | 216 | if (addr < eaddr) |
214 | break; | 217 | break; |
215 | base = eaddr; | 218 | base = eaddr; |
216 | } | 219 | } while (++idx < dcplb_nr_bounds); |
220 | |||
217 | if (unlikely(idx == dcplb_nr_bounds)) | 221 | if (unlikely(idx == dcplb_nr_bounds)) |
218 | return CPLB_NO_ADDR_MATCH; | 222 | return CPLB_NO_ADDR_MATCH; |
219 | 223 | ||
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index 339be5a3ae6a..a5de8d45424c 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c | |||
@@ -35,14 +35,8 @@ | |||
35 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
36 | #include <asm/io.h> | 36 | #include <asm/io.h> |
37 | 37 | ||
38 | static int create_irq_threads; | ||
39 | |||
40 | DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); | 38 | DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); |
41 | 39 | ||
42 | static DEFINE_PER_CPU(unsigned long, pending_irqthread_mask); | ||
43 | |||
44 | static DEFINE_PER_CPU(int [IVG13 + 1], pending_irq_count); | ||
45 | |||
46 | asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); | 40 | asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); |
47 | 41 | ||
48 | static void __ipipe_no_irqtail(void); | 42 | static void __ipipe_no_irqtail(void); |
@@ -93,6 +87,7 @@ void __ipipe_enable_pipeline(void) | |||
93 | */ | 87 | */ |
94 | void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) | 88 | void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) |
95 | { | 89 | { |
90 | struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr(); | ||
96 | struct ipipe_domain *this_domain, *next_domain; | 91 | struct ipipe_domain *this_domain, *next_domain; |
97 | struct list_head *head, *pos; | 92 | struct list_head *head, *pos; |
98 | int m_ack, s = -1; | 93 | int m_ack, s = -1; |
@@ -104,7 +99,6 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) | |||
104 | * interrupt. | 99 | * interrupt. |
105 | */ | 100 | */ |
106 | m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR); | 101 | m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR); |
107 | |||
108 | this_domain = ipipe_current_domain; | 102 | this_domain = ipipe_current_domain; |
109 | 103 | ||
110 | if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) | 104 | if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) |
@@ -114,49 +108,28 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) | |||
114 | next_domain = list_entry(head, struct ipipe_domain, p_link); | 108 | next_domain = list_entry(head, struct ipipe_domain, p_link); |
115 | if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { | 109 | if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { |
116 | if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) | 110 | if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) |
117 | next_domain->irqs[irq].acknowledge(irq, irq_desc + irq); | 111 | next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq)); |
118 | if (test_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags)) | 112 | if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status)) |
119 | s = __test_and_set_bit(IPIPE_STALL_FLAG, | 113 | s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status); |
120 | &ipipe_root_cpudom_var(status)); | ||
121 | __ipipe_dispatch_wired(next_domain, irq); | 114 | __ipipe_dispatch_wired(next_domain, irq); |
122 | goto finalize; | 115 | goto out; |
123 | return; | ||
124 | } | 116 | } |
125 | } | 117 | } |
126 | 118 | ||
127 | /* Ack the interrupt. */ | 119 | /* Ack the interrupt. */ |
128 | 120 | ||
129 | pos = head; | 121 | pos = head; |
130 | |||
131 | while (pos != &__ipipe_pipeline) { | 122 | while (pos != &__ipipe_pipeline) { |
132 | next_domain = list_entry(pos, struct ipipe_domain, p_link); | 123 | next_domain = list_entry(pos, struct ipipe_domain, p_link); |
133 | /* | ||
134 | * For each domain handling the incoming IRQ, mark it | ||
135 | * as pending in its log. | ||
136 | */ | ||
137 | if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) { | 124 | if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) { |
138 | /* | ||
139 | * Domains that handle this IRQ are polled for | ||
140 | * acknowledging it by decreasing priority | ||
141 | * order. The interrupt must be made pending | ||
142 | * _first_ in the domain's status flags before | ||
143 | * the PIC is unlocked. | ||
144 | */ | ||
145 | __ipipe_set_irq_pending(next_domain, irq); | 125 | __ipipe_set_irq_pending(next_domain, irq); |
146 | |||
147 | if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) { | 126 | if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) { |
148 | next_domain->irqs[irq].acknowledge(irq, irq_desc + irq); | 127 | next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq)); |
149 | m_ack = 1; | 128 | m_ack = 1; |
150 | } | 129 | } |
151 | } | 130 | } |
152 | |||
153 | /* | ||
154 | * If the domain does not want the IRQ to be passed | ||
155 | * down the interrupt pipe, exit the loop now. | ||
156 | */ | ||
157 | if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control)) | 131 | if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control)) |
158 | break; | 132 | break; |
159 | |||
160 | pos = next_domain->p_link.next; | 133 | pos = next_domain->p_link.next; |
161 | } | 134 | } |
162 | 135 | ||
@@ -166,18 +139,24 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) | |||
166 | * immediately to the current domain if the interrupt has been | 139 | * immediately to the current domain if the interrupt has been |
167 | * marked as 'sticky'. This search does not go beyond the | 140 | * marked as 'sticky'. This search does not go beyond the |
168 | * current domain in the pipeline. We also enforce the | 141 | * current domain in the pipeline. We also enforce the |
169 | * additional root stage lock (blackfin-specific). */ | 142 | * additional root stage lock (blackfin-specific). |
143 | */ | ||
144 | if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status)) | ||
145 | s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status); | ||
170 | 146 | ||
171 | if (test_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags)) | 147 | /* |
172 | s = __test_and_set_bit(IPIPE_STALL_FLAG, | 148 | * If the interrupt preempted the head domain, then do not |
173 | &ipipe_root_cpudom_var(status)); | 149 | * even try to walk the pipeline, unless an interrupt is |
174 | finalize: | 150 | * pending for it. |
151 | */ | ||
152 | if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) && | ||
153 | ipipe_head_cpudom_var(irqpend_himask) == 0) | ||
154 | goto out; | ||
175 | 155 | ||
176 | __ipipe_walk_pipeline(head); | 156 | __ipipe_walk_pipeline(head); |
177 | 157 | out: | |
178 | if (!s) | 158 | if (!s) |
179 | __clear_bit(IPIPE_STALL_FLAG, | 159 | __clear_bit(IPIPE_STALL_FLAG, &p->status); |
180 | &ipipe_root_cpudom_var(status)); | ||
181 | } | 160 | } |
182 | 161 | ||
183 | int __ipipe_check_root(void) | 162 | int __ipipe_check_root(void) |
@@ -187,7 +166,7 @@ int __ipipe_check_root(void) | |||
187 | 166 | ||
188 | void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) | 167 | void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) |
189 | { | 168 | { |
190 | struct irq_desc *desc = irq_desc + irq; | 169 | struct irq_desc *desc = irq_to_desc(irq); |
191 | int prio = desc->ic_prio; | 170 | int prio = desc->ic_prio; |
192 | 171 | ||
193 | desc->depth = 0; | 172 | desc->depth = 0; |
@@ -199,7 +178,7 @@ EXPORT_SYMBOL(__ipipe_enable_irqdesc); | |||
199 | 178 | ||
200 | void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) | 179 | void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) |
201 | { | 180 | { |
202 | struct irq_desc *desc = irq_desc + irq; | 181 | struct irq_desc *desc = irq_to_desc(irq); |
203 | int prio = desc->ic_prio; | 182 | int prio = desc->ic_prio; |
204 | 183 | ||
205 | if (ipd != &ipipe_root && | 184 | if (ipd != &ipipe_root && |
@@ -236,15 +215,18 @@ int __ipipe_syscall_root(struct pt_regs *regs) | |||
236 | { | 215 | { |
237 | unsigned long flags; | 216 | unsigned long flags; |
238 | 217 | ||
239 | /* We need to run the IRQ tail hook whenever we don't | 218 | /* |
219 | * We need to run the IRQ tail hook whenever we don't | ||
240 | * propagate a syscall to higher domains, because we know that | 220 | * propagate a syscall to higher domains, because we know that |
241 | * important operations might be pending there (e.g. Xenomai | 221 | * important operations might be pending there (e.g. Xenomai |
242 | * deferred rescheduling). */ | 222 | * deferred rescheduling). |
223 | */ | ||
243 | 224 | ||
244 | if (!__ipipe_syscall_watched_p(current, regs->orig_p0)) { | 225 | if (regs->orig_p0 < NR_syscalls) { |
245 | void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; | 226 | void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; |
246 | hook(); | 227 | hook(); |
247 | return 0; | 228 | if ((current->flags & PF_EVNOTIFY) == 0) |
229 | return 0; | ||
248 | } | 230 | } |
249 | 231 | ||
250 | /* | 232 | /* |
@@ -312,112 +294,46 @@ int ipipe_trigger_irq(unsigned irq) | |||
312 | { | 294 | { |
313 | unsigned long flags; | 295 | unsigned long flags; |
314 | 296 | ||
297 | #ifdef CONFIG_IPIPE_DEBUG | ||
315 | if (irq >= IPIPE_NR_IRQS || | 298 | if (irq >= IPIPE_NR_IRQS || |
316 | (ipipe_virtual_irq_p(irq) | 299 | (ipipe_virtual_irq_p(irq) |
317 | && !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map))) | 300 | && !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map))) |
318 | return -EINVAL; | 301 | return -EINVAL; |
302 | #endif | ||
319 | 303 | ||
320 | local_irq_save_hw(flags); | 304 | local_irq_save_hw(flags); |
321 | |||
322 | __ipipe_handle_irq(irq, NULL); | 305 | __ipipe_handle_irq(irq, NULL); |
323 | |||
324 | local_irq_restore_hw(flags); | 306 | local_irq_restore_hw(flags); |
325 | 307 | ||
326 | return 1; | 308 | return 1; |
327 | } | 309 | } |
328 | 310 | ||
329 | /* Move Linux IRQ to threads. */ | 311 | asmlinkage void __ipipe_sync_root(void) |
330 | |||
331 | static int do_irqd(void *__desc) | ||
332 | { | 312 | { |
333 | struct irq_desc *desc = __desc; | 313 | unsigned long flags; |
334 | unsigned irq = desc - irq_desc; | ||
335 | int thrprio = desc->thr_prio; | ||
336 | int thrmask = 1 << thrprio; | ||
337 | int cpu = smp_processor_id(); | ||
338 | cpumask_t cpumask; | ||
339 | |||
340 | sigfillset(¤t->blocked); | ||
341 | current->flags |= PF_NOFREEZE; | ||
342 | cpumask = cpumask_of_cpu(cpu); | ||
343 | set_cpus_allowed(current, cpumask); | ||
344 | ipipe_setscheduler_root(current, SCHED_FIFO, 50 + thrprio); | ||
345 | |||
346 | while (!kthread_should_stop()) { | ||
347 | local_irq_disable(); | ||
348 | if (!(desc->status & IRQ_SCHEDULED)) { | ||
349 | set_current_state(TASK_INTERRUPTIBLE); | ||
350 | resched: | ||
351 | local_irq_enable(); | ||
352 | schedule(); | ||
353 | local_irq_disable(); | ||
354 | } | ||
355 | __set_current_state(TASK_RUNNING); | ||
356 | /* | ||
357 | * If higher priority interrupt servers are ready to | ||
358 | * run, reschedule immediately. We need this for the | ||
359 | * GPIO demux IRQ handler to unmask the interrupt line | ||
360 | * _last_, after all GPIO IRQs have run. | ||
361 | */ | ||
362 | if (per_cpu(pending_irqthread_mask, cpu) & ~(thrmask|(thrmask-1))) | ||
363 | goto resched; | ||
364 | if (--per_cpu(pending_irq_count[thrprio], cpu) == 0) | ||
365 | per_cpu(pending_irqthread_mask, cpu) &= ~thrmask; | ||
366 | desc->status &= ~IRQ_SCHEDULED; | ||
367 | desc->thr_handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); | ||
368 | local_irq_enable(); | ||
369 | } | ||
370 | __set_current_state(TASK_RUNNING); | ||
371 | return 0; | ||
372 | } | ||
373 | 314 | ||
374 | static void kick_irqd(unsigned irq, void *cookie) | 315 | BUG_ON(irqs_disabled()); |
375 | { | ||
376 | struct irq_desc *desc = irq_desc + irq; | ||
377 | int thrprio = desc->thr_prio; | ||
378 | int thrmask = 1 << thrprio; | ||
379 | int cpu = smp_processor_id(); | ||
380 | |||
381 | if (!(desc->status & IRQ_SCHEDULED)) { | ||
382 | desc->status |= IRQ_SCHEDULED; | ||
383 | per_cpu(pending_irqthread_mask, cpu) |= thrmask; | ||
384 | ++per_cpu(pending_irq_count[thrprio], cpu); | ||
385 | wake_up_process(desc->thread); | ||
386 | } | ||
387 | } | ||
388 | 316 | ||
389 | int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc) | 317 | local_irq_save_hw(flags); |
390 | { | ||
391 | if (desc->thread || !create_irq_threads) | ||
392 | return 0; | ||
393 | |||
394 | desc->thread = kthread_create(do_irqd, desc, "IRQ %d", irq); | ||
395 | if (desc->thread == NULL) { | ||
396 | printk(KERN_ERR "irqd: could not create IRQ thread %d!\n", irq); | ||
397 | return -ENOMEM; | ||
398 | } | ||
399 | 318 | ||
400 | wake_up_process(desc->thread); | 319 | clear_thread_flag(TIF_IRQ_SYNC); |
401 | 320 | ||
402 | desc->thr_handler = ipipe_root_domain->irqs[irq].handler; | 321 | if (ipipe_root_cpudom_var(irqpend_himask) != 0) |
403 | ipipe_root_domain->irqs[irq].handler = &kick_irqd; | 322 | __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY); |
404 | 323 | ||
405 | return 0; | 324 | local_irq_restore_hw(flags); |
406 | } | 325 | } |
407 | 326 | ||
408 | void __init ipipe_init_irq_threads(void) | 327 | void ___ipipe_sync_pipeline(unsigned long syncmask) |
409 | { | 328 | { |
410 | unsigned irq; | 329 | struct ipipe_domain *ipd = ipipe_current_domain; |
411 | struct irq_desc *desc; | ||
412 | |||
413 | create_irq_threads = 1; | ||
414 | 330 | ||
415 | for (irq = 0; irq < NR_IRQS; irq++) { | 331 | if (ipd == ipipe_root_domain) { |
416 | desc = irq_desc + irq; | 332 | if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) |
417 | if (desc->action != NULL || | 333 | return; |
418 | (desc->status & IRQ_NOREQUEST) != 0) | ||
419 | ipipe_start_irq_thread(irq, desc); | ||
420 | } | 334 | } |
335 | |||
336 | __ipipe_sync_stage(syncmask); | ||
421 | } | 337 | } |
422 | 338 | ||
423 | EXPORT_SYMBOL(show_stack); | 339 | EXPORT_SYMBOL(show_stack); |
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index ab8209cbbad0..7fd126564846 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #include <asm/trace.h> | 37 | #include <asm/trace.h> |
38 | #include <asm/pda.h> | ||
38 | 39 | ||
39 | static atomic_t irq_err_count; | 40 | static atomic_t irq_err_count; |
40 | static spinlock_t irq_controller_lock; | 41 | static spinlock_t irq_controller_lock; |
@@ -91,8 +92,13 @@ int show_interrupts(struct seq_file *p, void *v) | |||
91 | seq_putc(p, '\n'); | 92 | seq_putc(p, '\n'); |
92 | skip: | 93 | skip: |
93 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 94 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
94 | } else if (i == NR_IRQS) | 95 | } else if (i == NR_IRQS) { |
96 | seq_printf(p, "NMI: "); | ||
97 | for_each_online_cpu(j) | ||
98 | seq_printf(p, "%10u ", cpu_pda[j].__nmi_count); | ||
99 | seq_printf(p, " CORE Non Maskable Interrupt\n"); | ||
95 | seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); | 100 | seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); |
101 | } | ||
96 | return 0; | 102 | return 0; |
97 | } | 103 | } |
98 | 104 | ||
@@ -138,11 +144,15 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
138 | #endif | 144 | #endif |
139 | generic_handle_irq(irq); | 145 | generic_handle_irq(irq); |
140 | 146 | ||
141 | #ifndef CONFIG_IPIPE /* Useless and bugous over the I-pipe: IRQs are threaded. */ | 147 | #ifndef CONFIG_IPIPE |
142 | /* If we're the only interrupt running (ignoring IRQ15 which is for | 148 | /* |
143 | syscalls), lower our priority to IRQ14 so that softirqs run at | 149 | * If we're the only interrupt running (ignoring IRQ15 which |
144 | that level. If there's another, lower-level interrupt, irq_exit | 150 | * is for syscalls), lower our priority to IRQ14 so that |
145 | will defer softirqs to that. */ | 151 | * softirqs run at that level. If there's another, |
152 | * lower-level interrupt, irq_exit will defer softirqs to | ||
153 | * that. If the interrupt pipeline is enabled, we are already | ||
154 | * running at IRQ14 priority, so we don't need this code. | ||
155 | */ | ||
146 | CSYNC(); | 156 | CSYNC(); |
147 | pending = bfin_read_IPEND() & ~0x8000; | 157 | pending = bfin_read_IPEND() & ~0x8000; |
148 | other_ints = pending & (pending - 1); | 158 | other_ints = pending & (pending - 1); |
diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c index 3dba9c17304a..dbcf3e45cb0b 100644 --- a/arch/blackfin/kernel/kgdb_test.c +++ b/arch/blackfin/kernel/kgdb_test.c | |||
@@ -20,6 +20,7 @@ | |||
20 | static char cmdline[256]; | 20 | static char cmdline[256]; |
21 | static unsigned long len; | 21 | static unsigned long len; |
22 | 22 | ||
23 | #ifndef CONFIG_SMP | ||
23 | static int num1 __attribute__((l1_data)); | 24 | static int num1 __attribute__((l1_data)); |
24 | 25 | ||
25 | void kgdb_l1_test(void) __attribute__((l1_text)); | 26 | void kgdb_l1_test(void) __attribute__((l1_text)); |
@@ -32,6 +33,8 @@ void kgdb_l1_test(void) | |||
32 | printk(KERN_ALERT "L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); | 33 | printk(KERN_ALERT "L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); |
33 | return ; | 34 | return ; |
34 | } | 35 | } |
36 | #endif | ||
37 | |||
35 | #if L2_LENGTH | 38 | #if L2_LENGTH |
36 | 39 | ||
37 | static int num2 __attribute__((l2)); | 40 | static int num2 __attribute__((l2)); |
@@ -59,10 +62,12 @@ int kgdb_test(char *name, int len, int count, int z) | |||
59 | static int test_proc_output(char *buf) | 62 | static int test_proc_output(char *buf) |
60 | { | 63 | { |
61 | kgdb_test("hello world!", 12, 0x55, 0x10); | 64 | kgdb_test("hello world!", 12, 0x55, 0x10); |
65 | #ifndef CONFIG_SMP | ||
62 | kgdb_l1_test(); | 66 | kgdb_l1_test(); |
63 | #if L2_LENGTH | 67 | #endif |
68 | #if L2_LENGTH | ||
64 | kgdb_l2_test(); | 69 | kgdb_l2_test(); |
65 | #endif | 70 | #endif |
66 | 71 | ||
67 | return 0; | 72 | return 0; |
68 | } | 73 | } |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 594e325b40e4..d76618db50df 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/asm-offsets.h> | 45 | #include <asm/asm-offsets.h> |
46 | #include <asm/dma.h> | 46 | #include <asm/dma.h> |
47 | #include <asm/fixed_code.h> | 47 | #include <asm/fixed_code.h> |
48 | #include <asm/cacheflush.h> | ||
48 | #include <asm/mem_map.h> | 49 | #include <asm/mem_map.h> |
49 | 50 | ||
50 | #define TEXT_OFFSET 0 | 51 | #define TEXT_OFFSET 0 |
@@ -240,7 +241,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
240 | 241 | ||
241 | } else if (addr >= FIXED_CODE_START | 242 | } else if (addr >= FIXED_CODE_START |
242 | && addr + sizeof(tmp) <= FIXED_CODE_END) { | 243 | && addr + sizeof(tmp) <= FIXED_CODE_END) { |
243 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); | 244 | copy_from_user_page(0, 0, 0, &tmp, (const void *)(addr), sizeof(tmp)); |
244 | copied = sizeof(tmp); | 245 | copied = sizeof(tmp); |
245 | 246 | ||
246 | } else | 247 | } else |
@@ -320,7 +321,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
320 | 321 | ||
321 | } else if (addr >= FIXED_CODE_START | 322 | } else if (addr >= FIXED_CODE_START |
322 | && addr + sizeof(data) <= FIXED_CODE_END) { | 323 | && addr + sizeof(data) <= FIXED_CODE_END) { |
323 | memcpy((void *)(addr), &data, sizeof(data)); | 324 | copy_to_user_page(0, 0, 0, (void *)(addr), &data, sizeof(data)); |
324 | copied = sizeof(data); | 325 | copied = sizeof(data); |
325 | 326 | ||
326 | } else | 327 | } else |
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c index eeee8cb43360..53d08dee8531 100644 --- a/arch/blackfin/kernel/reboot.c +++ b/arch/blackfin/kernel/reboot.c | |||
@@ -20,8 +20,8 @@ | |||
20 | * reset while the Core B bit (on dual core parts) is cleared by | 20 | * reset while the Core B bit (on dual core parts) is cleared by |
21 | * the core reset. | 21 | * the core reset. |
22 | */ | 22 | */ |
23 | __attribute__((l1_text)) | 23 | __attribute__ ((__l1_text__, __noreturn__)) |
24 | static void _bfin_reset(void) | 24 | static void bfin_reset(void) |
25 | { | 25 | { |
26 | /* Wait for completion of "system" events such as cache line | 26 | /* Wait for completion of "system" events such as cache line |
27 | * line fills so that we avoid infinite stalls later on as | 27 | * line fills so that we avoid infinite stalls later on as |
@@ -30,7 +30,11 @@ static void _bfin_reset(void) | |||
30 | */ | 30 | */ |
31 | __builtin_bfin_ssync(); | 31 | __builtin_bfin_ssync(); |
32 | 32 | ||
33 | while (1) { | 33 | /* The bootrom checks to see how it was reset and will |
34 | * automatically perform a software reset for us when | ||
35 | * it starts executing after the core reset. | ||
36 | */ | ||
37 | if (ANOMALY_05000353 || ANOMALY_05000386) { | ||
34 | /* Initiate System software reset. */ | 38 | /* Initiate System software reset. */ |
35 | bfin_write_SWRST(0x7); | 39 | bfin_write_SWRST(0x7); |
36 | 40 | ||
@@ -50,6 +54,11 @@ static void _bfin_reset(void) | |||
50 | /* Clear System software reset */ | 54 | /* Clear System software reset */ |
51 | bfin_write_SWRST(0); | 55 | bfin_write_SWRST(0); |
52 | 56 | ||
57 | /* The BF526 ROM will crash during reset */ | ||
58 | #if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) | ||
59 | bfin_read_SWRST(); | ||
60 | #endif | ||
61 | |||
53 | /* Wait for the SWRST write to complete. Cannot rely on SSYNC | 62 | /* Wait for the SWRST write to complete. Cannot rely on SSYNC |
54 | * though as the System state is all reset now. | 63 | * though as the System state is all reset now. |
55 | */ | 64 | */ |
@@ -60,22 +69,11 @@ static void _bfin_reset(void) | |||
60 | : "a" (15 * 1) | 69 | : "a" (15 * 1) |
61 | : "LC1", "LB1", "LT1" | 70 | : "LC1", "LB1", "LT1" |
62 | ); | 71 | ); |
72 | } | ||
63 | 73 | ||
74 | while (1) | ||
64 | /* Issue core reset */ | 75 | /* Issue core reset */ |
65 | asm("raise 1"); | 76 | asm("raise 1"); |
66 | } | ||
67 | } | ||
68 | |||
69 | static void bfin_reset(void) | ||
70 | { | ||
71 | if (ANOMALY_05000353 || ANOMALY_05000386) | ||
72 | _bfin_reset(); | ||
73 | else | ||
74 | /* the bootrom checks to see how it was reset and will | ||
75 | * automatically perform a software reset for us when | ||
76 | * it starts executing boot | ||
77 | */ | ||
78 | asm("raise 1;"); | ||
79 | } | 77 | } |
80 | 78 | ||
81 | __attribute__((weak)) | 79 | __attribute__((weak)) |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index b2a811347b65..a58687bdee6a 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -60,7 +60,7 @@ void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, | |||
60 | #define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ | 60 | #define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ |
61 | #define BFIN_MEMMAP_RAM 1 | 61 | #define BFIN_MEMMAP_RAM 1 |
62 | #define BFIN_MEMMAP_RESERVED 2 | 62 | #define BFIN_MEMMAP_RESERVED 2 |
63 | struct bfin_memmap { | 63 | static struct bfin_memmap { |
64 | int nr_map; | 64 | int nr_map; |
65 | struct bfin_memmap_entry { | 65 | struct bfin_memmap_entry { |
66 | unsigned long long addr; /* start of memory segment */ | 66 | unsigned long long addr; /* start of memory segment */ |
@@ -824,7 +824,15 @@ void __init setup_arch(char **cmdline_p) | |||
824 | flash_probe(); | 824 | flash_probe(); |
825 | #endif | 825 | #endif |
826 | 826 | ||
827 | printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); | ||
828 | |||
829 | /* Newer parts mirror SWRST bits in SYSCR */ | ||
830 | #if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \ | ||
831 | defined(CONFIG_BF538) || defined(CONFIG_BF539) | ||
827 | _bfin_swrst = bfin_read_SWRST(); | 832 | _bfin_swrst = bfin_read_SWRST(); |
833 | #else | ||
834 | _bfin_swrst = bfin_read_SYSCR(); | ||
835 | #endif | ||
828 | 836 | ||
829 | #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT | 837 | #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT |
830 | bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); | 838 | bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); |
@@ -853,7 +861,7 @@ void __init setup_arch(char **cmdline_p) | |||
853 | else if (_bfin_swrst & RESET_SOFTWARE) | 861 | else if (_bfin_swrst & RESET_SOFTWARE) |
854 | printk(KERN_NOTICE "Reset caused by Software reset\n"); | 862 | printk(KERN_NOTICE "Reset caused by Software reset\n"); |
855 | 863 | ||
856 | printk(KERN_INFO "Blackfin support (C) 2004-2008 Analog Devices, Inc.\n"); | 864 | printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n"); |
857 | if (bfin_compiled_revid() == 0xffff) | 865 | if (bfin_compiled_revid() == 0xffff) |
858 | printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); | 866 | printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); |
859 | else if (bfin_compiled_revid() == -1) | 867 | else if (bfin_compiled_revid() == -1) |
@@ -881,6 +889,10 @@ void __init setup_arch(char **cmdline_p) | |||
881 | CPU, bfin_revid()); | 889 | CPU, bfin_revid()); |
882 | } | 890 | } |
883 | 891 | ||
892 | /* We can't run on BF548-0.1 due to ANOMALY 05000448 */ | ||
893 | if (bfin_cpuid() == 0x27de && bfin_revid() == 1) | ||
894 | panic("You can't run on this processor due to 05000448\n"); | ||
895 | |||
884 | printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); | 896 | printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); |
885 | 897 | ||
886 | printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", | 898 | printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", |
@@ -1133,12 +1145,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1133 | icache_size = 0; | 1145 | icache_size = 0; |
1134 | 1146 | ||
1135 | seq_printf(m, "cache size\t: %d KB(L1 icache) " | 1147 | seq_printf(m, "cache size\t: %d KB(L1 icache) " |
1136 | "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", | 1148 | "%d KB(L1 dcache%s) %d KB(L2 cache)\n", |
1137 | icache_size, dcache_size, | 1149 | icache_size, dcache_size, |
1138 | #if defined CONFIG_BFIN_WB | 1150 | #if defined CONFIG_BFIN_WB |
1139 | "wb" | 1151 | "-wb" |
1140 | #elif defined CONFIG_BFIN_WT | 1152 | #elif defined CONFIG_BFIN_WT |
1141 | "wt" | 1153 | "-wt" |
1142 | #endif | 1154 | #endif |
1143 | "", 0); | 1155 | "", 0); |
1144 | 1156 | ||
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index 172b4c588467..1bbacfbd4c5d 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c | |||
@@ -134,7 +134,10 @@ irqreturn_t timer_interrupt(int irq, void *dummy) | |||
134 | 134 | ||
135 | write_seqlock(&xtime_lock); | 135 | write_seqlock(&xtime_lock); |
136 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE) | 136 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE) |
137 | /* FIXME: Here TIMIL0 is not set when IPIPE enabled, why? */ | 137 | /* |
138 | * TIMIL0 is latched in __ipipe_grab_irq() when the I-Pipe is | ||
139 | * enabled. | ||
140 | */ | ||
138 | if (get_gptimer_status(0) & TIMER_STATUS_TIMIL0) { | 141 | if (get_gptimer_status(0) & TIMER_STATUS_TIMIL0) { |
139 | #endif | 142 | #endif |
140 | do_timer(1); | 143 | do_timer(1); |
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 5b0667da8d05..ffe7fb53eccb 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -673,6 +673,14 @@ static void decode_instruction(unsigned short *address) | |||
673 | verbose_printk("RTI"); | 673 | verbose_printk("RTI"); |
674 | else if (opcode == 0x0012) | 674 | else if (opcode == 0x0012) |
675 | verbose_printk("RTX"); | 675 | verbose_printk("RTX"); |
676 | else if (opcode == 0x0013) | ||
677 | verbose_printk("RTN"); | ||
678 | else if (opcode == 0x0014) | ||
679 | verbose_printk("RTE"); | ||
680 | else if (opcode == 0x0025) | ||
681 | verbose_printk("EMUEXCPT"); | ||
682 | else if (opcode == 0x0040 && opcode <= 0x0047) | ||
683 | verbose_printk("STI R%i", opcode & 7); | ||
676 | else if (opcode >= 0x0050 && opcode <= 0x0057) | 684 | else if (opcode >= 0x0050 && opcode <= 0x0057) |
677 | verbose_printk("JUMP (P%i)", opcode & 7); | 685 | verbose_printk("JUMP (P%i)", opcode & 7); |
678 | else if (opcode >= 0x0060 && opcode <= 0x0067) | 686 | else if (opcode >= 0x0060 && opcode <= 0x0067) |
@@ -681,6 +689,10 @@ static void decode_instruction(unsigned short *address) | |||
681 | verbose_printk("CALL (PC+P%i)", opcode & 7); | 689 | verbose_printk("CALL (PC+P%i)", opcode & 7); |
682 | else if (opcode >= 0x0080 && opcode <= 0x0087) | 690 | else if (opcode >= 0x0080 && opcode <= 0x0087) |
683 | verbose_printk("JUMP (PC+P%i)", opcode & 7); | 691 | verbose_printk("JUMP (PC+P%i)", opcode & 7); |
692 | else if (opcode >= 0x0090 && opcode <= 0x009F) | ||
693 | verbose_printk("RAISE 0x%x", opcode & 0xF); | ||
694 | else if (opcode >= 0x00A0 && opcode <= 0x00AF) | ||
695 | verbose_printk("EXCPT 0x%x", opcode & 0xF); | ||
684 | else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) | 696 | else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) |
685 | verbose_printk("IF !CC JUMP"); | 697 | verbose_printk("IF !CC JUMP"); |
686 | else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) | 698 | else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) |
@@ -820,11 +832,8 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
820 | decode_address(buf, (unsigned int)stack); | 832 | decode_address(buf, (unsigned int)stack); |
821 | printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); | 833 | printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); |
822 | 834 | ||
823 | addr = (unsigned int *)((unsigned int)stack & ~0x3F); | ||
824 | |||
825 | /* First thing is to look for a frame pointer */ | 835 | /* First thing is to look for a frame pointer */ |
826 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; | 836 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { |
827 | addr < endstack; addr++, i++) { | ||
828 | if (*addr & 0x1) | 837 | if (*addr & 0x1) |
829 | continue; | 838 | continue; |
830 | ins_addr = (unsigned short *)*addr; | 839 | ins_addr = (unsigned short *)*addr; |
@@ -834,7 +843,8 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
834 | 843 | ||
835 | if (fp) { | 844 | if (fp) { |
836 | /* Let's check to see if it is a frame pointer */ | 845 | /* Let's check to see if it is a frame pointer */ |
837 | while (fp >= (addr - 1) && fp < endstack && fp) | 846 | while (fp >= (addr - 1) && fp < endstack |
847 | && fp && ((unsigned int) fp & 0x3) == 0) | ||
838 | fp = (unsigned int *)*fp; | 848 | fp = (unsigned int *)*fp; |
839 | if (fp == 0 || fp == endstack) { | 849 | if (fp == 0 || fp == endstack) { |
840 | fp = addr - 1; | 850 | fp = addr - 1; |
@@ -1052,8 +1062,9 @@ void show_regs(struct pt_regs *fp) | |||
1052 | char buf [150]; | 1062 | char buf [150]; |
1053 | struct irqaction *action; | 1063 | struct irqaction *action; |
1054 | unsigned int i; | 1064 | unsigned int i; |
1055 | unsigned long flags; | 1065 | unsigned long flags = 0; |
1056 | unsigned int cpu = smp_processor_id(); | 1066 | unsigned int cpu = smp_processor_id(); |
1067 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); | ||
1057 | 1068 | ||
1058 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); | 1069 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); |
1059 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 1070 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
@@ -1073,17 +1084,22 @@ void show_regs(struct pt_regs *fp) | |||
1073 | } | 1084 | } |
1074 | verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", | 1085 | verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", |
1075 | fp->seqstat & SEQSTAT_EXCAUSE); | 1086 | fp->seqstat & SEQSTAT_EXCAUSE); |
1076 | for (i = 6; i <= 15 ; i++) { | 1087 | for (i = 2; i <= 15 ; i++) { |
1077 | if (fp->ipend & (1 << i)) { | 1088 | if (fp->ipend & (1 << i)) { |
1078 | decode_address(buf, bfin_read32(EVT0 + 4*i)); | 1089 | if (i != 4) { |
1079 | verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); | 1090 | decode_address(buf, bfin_read32(EVT0 + 4*i)); |
1091 | verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); | ||
1092 | } else | ||
1093 | verbose_printk(KERN_NOTICE " interrupts disabled\n"); | ||
1080 | } | 1094 | } |
1081 | } | 1095 | } |
1082 | 1096 | ||
1083 | /* if no interrupts are going off, don't print this out */ | 1097 | /* if no interrupts are going off, don't print this out */ |
1084 | if (fp->ipend & ~0x3F) { | 1098 | if (fp->ipend & ~0x3F) { |
1085 | for (i = 0; i < (NR_IRQS - 1); i++) { | 1099 | for (i = 0; i < (NR_IRQS - 1); i++) { |
1086 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 1100 | if (!in_atomic) |
1101 | spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
1102 | |||
1087 | action = irq_desc[i].action; | 1103 | action = irq_desc[i].action; |
1088 | if (!action) | 1104 | if (!action) |
1089 | goto unlock; | 1105 | goto unlock; |
@@ -1096,7 +1112,8 @@ void show_regs(struct pt_regs *fp) | |||
1096 | } | 1112 | } |
1097 | verbose_printk("\n"); | 1113 | verbose_printk("\n"); |
1098 | unlock: | 1114 | unlock: |
1099 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 1115 | if (!in_atomic) |
1116 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
1100 | } | 1117 | } |
1101 | } | 1118 | } |
1102 | 1119 | ||