diff options
Diffstat (limited to 'arch/cris')
124 files changed, 13323 insertions, 6754 deletions
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index ff078e60e76d..8456bc8efb7c 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
@@ -13,10 +13,6 @@ config ZONE_DMA | |||
13 | bool | 13 | bool |
14 | default y | 14 | default y |
15 | 15 | ||
16 | config NO_DMA | ||
17 | bool | ||
18 | default y | ||
19 | |||
20 | config RWSEM_GENERIC_SPINLOCK | 16 | config RWSEM_GENERIC_SPINLOCK |
21 | bool | 17 | bool |
22 | default y | 18 | default y |
@@ -24,6 +20,10 @@ config RWSEM_GENERIC_SPINLOCK | |||
24 | config RWSEM_XCHGADD_ALGORITHM | 20 | config RWSEM_XCHGADD_ALGORITHM |
25 | bool | 21 | bool |
26 | 22 | ||
23 | config GENERIC_IOMAP | ||
24 | bool | ||
25 | default y | ||
26 | |||
27 | config ARCH_HAS_ILOG2_U32 | 27 | config ARCH_HAS_ILOG2_U32 |
28 | bool | 28 | bool |
29 | default n | 29 | default n |
@@ -44,13 +44,13 @@ config GENERIC_CALIBRATE_DELAY | |||
44 | bool | 44 | bool |
45 | default y | 45 | default y |
46 | 46 | ||
47 | config IRQ_PER_CPU | ||
48 | bool | ||
49 | default y | ||
50 | |||
51 | config NO_IOPORT | 47 | config NO_IOPORT |
52 | def_bool y | 48 | def_bool y |
53 | 49 | ||
50 | config FORCE_MAX_ZONEORDER | ||
51 | int | ||
52 | default 6 | ||
53 | |||
54 | config CRIS | 54 | config CRIS |
55 | bool | 55 | bool |
56 | default y | 56 | default y |
@@ -97,17 +97,15 @@ config ETRAX_FAST_TIMER | |||
97 | timers). | 97 | timers). |
98 | This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled. | 98 | This is needed if CONFIG_ETRAX_SERIAL_FAST_TIMER is enabled. |
99 | 99 | ||
100 | config PREEMPT | 100 | config ETRAX_KMALLOCED_MODULES |
101 | bool "Preemptible Kernel" | 101 | bool "Enable module allocation with kmalloc" |
102 | help | 102 | help |
103 | This option reduces the latency of the kernel when reacting to | 103 | Enable module allocation with kmalloc instead of vmalloc. |
104 | real-time or interactive events by allowing a low priority process to | 104 | |
105 | be preempted even if it is in kernel mode executing a system call. | 105 | config OOM_REBOOT |
106 | This allows applications to run more reliably even when the system is | 106 | bool "Enable reboot at out of memory" |
107 | under load. | ||
108 | 107 | ||
109 | Say Y here if you are building a kernel for a desktop, embedded | 108 | source "kernel/Kconfig.preempt" |
110 | or real-time system. Say N if you are unsure. | ||
111 | 109 | ||
112 | source mm/Kconfig | 110 | source mm/Kconfig |
113 | 111 | ||
@@ -134,24 +132,124 @@ config SVINTO_SIM | |||
134 | help | 132 | help |
135 | Support the xsim ETRAX Simulator. | 133 | Support the xsim ETRAX Simulator. |
136 | 134 | ||
135 | config ETRAXFS | ||
136 | bool "ETRAX-FS-V32" | ||
137 | help | ||
138 | Support CRIS V32. | ||
139 | |||
140 | config CRIS_MACH_ARTPEC3 | ||
141 | bool "ARTPEC-3" | ||
142 | help | ||
143 | Support Axis ARTPEC-3. | ||
144 | |||
137 | endchoice | 145 | endchoice |
138 | 146 | ||
147 | config ETRAX_VCS_SIM | ||
148 | bool "VCS Simulator" | ||
149 | help | ||
150 | Setup hardware to be run in the VCS simulator. | ||
151 | |||
139 | config ETRAX_ARCH_V10 | 152 | config ETRAX_ARCH_V10 |
140 | bool | 153 | bool |
141 | default y if ETRAX100LX || ETRAX100LX_V2 | 154 | default y if ETRAX100LX || ETRAX100LX_V2 |
142 | default n if !(ETRAX100LX || ETRAX100LX_V2) | 155 | default n if !(ETRAX100LX || ETRAX100LX_V2) |
143 | 156 | ||
157 | config ETRAX_ARCH_V32 | ||
158 | bool | ||
159 | default y if (ETRAXFS || CRIS_MACH_ARTPEC3) | ||
160 | default n if !(ETRAXFS || CRIS_MACH_ARTPEC3) | ||
161 | |||
144 | config ETRAX_DRAM_SIZE | 162 | config ETRAX_DRAM_SIZE |
145 | int "DRAM size (dec, in MB)" | 163 | int "DRAM size (dec, in MB)" |
146 | default "8" | 164 | default "8" |
147 | help | 165 | help |
148 | Size of DRAM (decimal in MB) typically 2, 8 or 16. | 166 | Size of DRAM (decimal in MB) typically 2, 8 or 16. |
149 | 167 | ||
168 | config ETRAX_VMEM_SIZE | ||
169 | int "Video memory size (dec, in MB)" | ||
170 | depends on ETRAX_ARCH_V32 && !ETRAXFS | ||
171 | default 8 if !ETRAXFS | ||
172 | help | ||
173 | Size of Video accessible memory (decimal, in MB). | ||
174 | |||
150 | config ETRAX_FLASH_BUSWIDTH | 175 | config ETRAX_FLASH_BUSWIDTH |
151 | int "Buswidth of flash in bytes" | 176 | int "Buswidth of NOR flash in bytes" |
152 | default "2" | 177 | default "2" |
153 | help | 178 | help |
154 | Width in bytes of the Flash bus (1, 2 or 4). Is usually 2. | 179 | Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2. |
180 | |||
181 | config ETRAX_NANDFLASH_BUSWIDTH | ||
182 | int "Buswidth of NAND flash in bytes" | ||
183 | default "1" | ||
184 | help | ||
185 | Width in bytes of the NAND flash (1 or 2). | ||
186 | |||
187 | config ETRAX_FLASH1_SIZE | ||
188 | int "FLASH1 size (dec, in MB. 0 = Unknown)" | ||
189 | default "0" | ||
190 | |||
191 | choice | ||
192 | prompt "Product debug-port" | ||
193 | default ETRAX_DEBUG_PORT0 | ||
194 | |||
195 | config ETRAX_DEBUG_PORT0 | ||
196 | bool "Serial-0" | ||
197 | help | ||
198 | Choose a serial port for the ETRAX debug console. Default to | ||
199 | port 0. | ||
200 | |||
201 | config ETRAX_DEBUG_PORT1 | ||
202 | bool "Serial-1" | ||
203 | help | ||
204 | Use serial port 1 for the console. | ||
205 | |||
206 | config ETRAX_DEBUG_PORT2 | ||
207 | bool "Serial-2" | ||
208 | help | ||
209 | Use serial port 2 for the console. | ||
210 | |||
211 | config ETRAX_DEBUG_PORT3 | ||
212 | bool "Serial-3" | ||
213 | help | ||
214 | Use serial port 3 for the console. | ||
215 | |||
216 | config ETRAX_DEBUG_PORT_NULL | ||
217 | bool "disabled" | ||
218 | help | ||
219 | Disable serial-port debugging. | ||
220 | |||
221 | endchoice | ||
222 | |||
223 | choice | ||
224 | prompt "Kernel GDB port" | ||
225 | depends on ETRAX_KGDB | ||
226 | default ETRAX_KGDB_PORT0 | ||
227 | help | ||
228 | Choose a serial port for kernel debugging. NOTE: This port should | ||
229 | not be enabled under Drivers for built-in interfaces (as it has its | ||
230 | own initialization code) and should not be the same as the debug port. | ||
231 | |||
232 | config ETRAX_KGDB_PORT0 | ||
233 | bool "Serial-0" | ||
234 | help | ||
235 | Use serial port 0 for kernel debugging. | ||
236 | |||
237 | config ETRAX_KGDB_PORT1 | ||
238 | bool "Serial-1" | ||
239 | help | ||
240 | Use serial port 1 for kernel debugging. | ||
241 | |||
242 | config ETRAX_KGDB_PORT2 | ||
243 | bool "Serial-2" | ||
244 | help | ||
245 | Use serial port 2 for kernel debugging. | ||
246 | |||
247 | config ETRAX_KGDB_PORT3 | ||
248 | bool "Serial-3" | ||
249 | help | ||
250 | Use serial port 3 for kernel debugging. | ||
251 | |||
252 | endchoice | ||
155 | 253 | ||
156 | source arch/cris/arch-v10/Kconfig | 254 | source arch/cris/arch-v10/Kconfig |
157 | source arch/cris/arch-v32/Kconfig | 255 | source arch/cris/arch-v32/Kconfig |
@@ -165,6 +263,387 @@ menu "Drivers for built-in interfaces" | |||
165 | source arch/cris/arch-v10/drivers/Kconfig | 263 | source arch/cris/arch-v10/drivers/Kconfig |
166 | source arch/cris/arch-v32/drivers/Kconfig | 264 | source arch/cris/arch-v32/drivers/Kconfig |
167 | 265 | ||
266 | config ETRAX_AXISFLASHMAP | ||
267 | bool "Axis flash-map support" | ||
268 | select MTD | ||
269 | select MTD_CFI | ||
270 | select MTD_CFI_AMDSTD | ||
271 | select MTD_JEDECPROBE if ETRAX_ARCH_V32 | ||
272 | select MTD_CHAR | ||
273 | select MTD_BLOCK | ||
274 | select MTD_PARTITIONS | ||
275 | select MTD_CONCAT | ||
276 | select MTD_COMPLEX_MAPPINGS | ||
277 | help | ||
278 | This option enables MTD mapping of flash devices. Needed to use | ||
279 | flash memories. If unsure, say Y. | ||
280 | |||
281 | config ETRAX_RTC | ||
282 | bool "Real Time Clock support" | ||
283 | depends on ETRAX_I2C | ||
284 | help | ||
285 | Enables drivers for the Real-Time Clock battery-backed chips on | ||
286 | some products. The kernel reads the time when booting, and | ||
287 | the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a | ||
288 | rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc | ||
289 | device. You can check the time with cat /proc/rtc, but | ||
290 | normal time reading should be done using libc function time and | ||
291 | friends. | ||
292 | |||
293 | choice | ||
294 | prompt "RTC chip" | ||
295 | depends on ETRAX_RTC | ||
296 | default ETRAX_PCF8563 if ETRAX_ARCH_V32 | ||
297 | default ETRAX_DS1302 if ETRAX_ARCH_V10 | ||
298 | |||
299 | config ETRAX_DS1302 | ||
300 | depends on ETRAX_ARCH_V10 | ||
301 | bool "DS1302" | ||
302 | help | ||
303 | Enables the driver for the DS1302 Real-Time Clock battery-backed | ||
304 | chip on some products. | ||
305 | |||
306 | config ETRAX_PCF8563 | ||
307 | bool "PCF8563" | ||
308 | help | ||
309 | Enables the driver for the PCF8563 Real-Time Clock battery-backed | ||
310 | chip on some products. | ||
311 | |||
312 | endchoice | ||
313 | |||
314 | config ETRAX_SYNCHRONOUS_SERIAL | ||
315 | bool "Synchronous serial-port support" | ||
316 | help | ||
317 | Select this to enable the synchronous serial port driver. | ||
318 | |||
319 | config ETRAX_SYNCHRONOUS_SERIAL_PORT0 | ||
320 | bool "Synchronous serial port 0 enabled" | ||
321 | depends on ETRAX_SYNCHRONOUS_SERIAL | ||
322 | help | ||
323 | Enabled synchronous serial port 0. | ||
324 | |||
325 | config ETRAX_SYNCHRONOUS_SERIAL0_DMA | ||
326 | bool "Enable DMA on synchronous serial port 0." | ||
327 | depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0 | ||
328 | help | ||
329 | A synchronous serial port can run in manual or DMA mode. | ||
330 | Selecting this option will make it run in DMA mode. | ||
331 | |||
332 | config ETRAX_SYNCHRONOUS_SERIAL_PORT1 | ||
333 | bool "Synchronous serial port 1 enabled" | ||
334 | depends on ETRAX_SYNCHRONOUS_SERIAL && (ETRAXFS || ETRAX_ARCH_V10) | ||
335 | help | ||
336 | Enabled synchronous serial port 1. | ||
337 | |||
338 | config ETRAX_SYNCHRONOUS_SERIAL1_DMA | ||
339 | bool "Enable DMA on synchronous serial port 1." | ||
340 | depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1 | ||
341 | help | ||
342 | A synchronous serial port can run in manual or DMA mode. | ||
343 | Selecting this option will make it run in DMA mode. | ||
344 | |||
345 | choice | ||
346 | prompt "Network LED behavior" | ||
347 | depends on ETRAX_ETHERNET | ||
348 | default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | ||
349 | |||
350 | config ETRAX_NETWORK_LED_ON_WHEN_LINK | ||
351 | bool "LED_on_when_link" | ||
352 | help | ||
353 | Selecting LED_on_when_link will light the LED when there is a | ||
354 | connection and will flash off when there is activity. | ||
355 | |||
356 | Selecting LED_on_when_activity will light the LED only when | ||
357 | there is activity. | ||
358 | |||
359 | This setting will also affect the behaviour of other activity LEDs | ||
360 | e.g. Bluetooth. | ||
361 | |||
362 | config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | ||
363 | bool "LED_on_when_activity" | ||
364 | help | ||
365 | Selecting LED_on_when_link will light the LED when there is a | ||
366 | connection and will flash off when there is activity. | ||
367 | |||
368 | Selecting LED_on_when_activity will light the LED only when | ||
369 | there is activity. | ||
370 | |||
371 | This setting will also affect the behaviour of other activity LEDs | ||
372 | e.g. Bluetooth. | ||
373 | |||
374 | endchoice | ||
375 | |||
376 | choice | ||
377 | prompt "Ser0 DMA out channel" | ||
378 | depends on ETRAX_SERIAL_PORT0 | ||
379 | default ETRAX_SERIAL_PORT0_DMA6_OUT if ETRAX_ARCH_V32 | ||
380 | default ETRAX_SERIAL_PORT0_NO_DMA_OUT if ETRAX_ARCH_V10 | ||
381 | |||
382 | config ETRAX_SERIAL_PORT0_NO_DMA_OUT | ||
383 | bool "Ser0 uses no DMA for output" | ||
384 | help | ||
385 | Do not use DMA for ser0 output. | ||
386 | |||
387 | config ETRAX_SERIAL_PORT0_DMA6_OUT | ||
388 | bool "Ser0 uses DMA6 for output" | ||
389 | depends on ETRAXFS | ||
390 | help | ||
391 | Enables the DMA6 output channel for ser0 (ttyS0). | ||
392 | If you do not enable DMA, an interrupt for each character will be | ||
393 | used when transmitting data. | ||
394 | Normally you want to use DMA, unless you use the DMA channel for | ||
395 | something else. | ||
396 | |||
397 | config ETRAX_SERIAL_PORT0_DMA0_OUT | ||
398 | bool "Ser0 uses DMA0 for output" | ||
399 | depends on CRIS_MACH_ARTPEC3 | ||
400 | help | ||
401 | Enables the DMA0 output channel for ser0 (ttyS0). | ||
402 | If you do not enable DMA, an interrupt for each character will be | ||
403 | used when transmitting data. | ||
404 | Normally you want to use DMA, unless you use the DMA channel for | ||
405 | something else. | ||
406 | |||
407 | endchoice | ||
408 | |||
409 | choice | ||
410 | prompt "Ser0 DMA in channel " | ||
411 | depends on ETRAX_SERIAL_PORT0 | ||
412 | default ETRAX_SERIAL_PORT0_NO_DMA_IN if ETRAX_ARCH_V32 | ||
413 | default ETRAX_SERIAL_PORT0_DMA7_IN if ETRAX_ARCH_V10 | ||
414 | help | ||
415 | What DMA channel to use for ser0. | ||
416 | |||
417 | config ETRAX_SERIAL_PORT0_NO_DMA_IN | ||
418 | bool "Ser0 uses no DMA for input" | ||
419 | help | ||
420 | Do not use DMA for ser0 input. | ||
421 | |||
422 | config ETRAX_SERIAL_PORT0_DMA7_IN | ||
423 | bool "Ser0 uses DMA7 for input" | ||
424 | depends on ETRAXFS | ||
425 | help | ||
426 | Enables the DMA7 input channel for ser0 (ttyS0). | ||
427 | If you do not enable DMA, an interrupt for each character will be | ||
428 | used when receiving data. | ||
429 | Normally you want to use DMA, unless you use the DMA channel for | ||
430 | something else. | ||
431 | |||
432 | config ETRAX_SERIAL_PORT0_DMA1_IN | ||
433 | bool "Ser0 uses DMA1 for input" | ||
434 | depends on CRIS_MACH_ARTPEC3 | ||
435 | help | ||
436 | Enables the DMA1 input channel for ser0 (ttyS0). | ||
437 | If you do not enable DMA, an interrupt for each character will be | ||
438 | used when receiveing data. | ||
439 | Normally you want to use DMA, unless you use the DMA channel for | ||
440 | something else. | ||
441 | |||
442 | endchoice | ||
443 | |||
444 | choice | ||
445 | prompt "Ser1 DMA in channel " | ||
446 | depends on ETRAX_SERIAL_PORT1 | ||
447 | default ETRAX_SERIAL_PORT1_NO_DMA_IN if ETRAX_ARCH_V32 | ||
448 | default ETRAX_SERIAL_PORT1_DMA9_IN if ETRAX_ARCH_V10 | ||
449 | help | ||
450 | What DMA channel to use for ser1. | ||
451 | |||
452 | config ETRAX_SERIAL_PORT1_NO_DMA_IN | ||
453 | bool "Ser1 uses no DMA for input" | ||
454 | help | ||
455 | Do not use DMA for ser1 input. | ||
456 | |||
457 | config ETRAX_SERIAL_PORT1_DMA5_IN | ||
458 | bool "Ser1 uses DMA5 for input" | ||
459 | depends on ETRAX_ARCH_V32 | ||
460 | help | ||
461 | Enables the DMA5 input channel for ser1 (ttyS1). | ||
462 | If you do not enable DMA, an interrupt for each character will be | ||
463 | used when receiving data. | ||
464 | Normally you want this on, unless you use the DMA channel for | ||
465 | something else. | ||
466 | |||
467 | config ETRAX_SERIAL_PORT1_DMA9_IN | ||
468 | depends on ETRAX_ARCH_V10 | ||
469 | bool "Ser1 uses DMA9 for input" | ||
470 | |||
471 | endchoice | ||
472 | |||
473 | |||
474 | choice | ||
475 | prompt "Ser1 DMA out channel" | ||
476 | depends on ETRAX_SERIAL_PORT1 | ||
477 | default ETRAX_SERIAL_PORT1_NO_DMA_OUT if ETRAX_ARCH_V32 | ||
478 | default ETRAX_SERIAL_PORT1_DMA8_OUT if ETRAX_ARCH_V10 | ||
479 | help | ||
480 | What DMA channel to use for ser1. | ||
481 | |||
482 | config ETRAX_SERIAL_PORT1_NO_DMA_OUT | ||
483 | bool "Ser1 uses no DMA for output" | ||
484 | help | ||
485 | Do not use DMA for ser1 output. | ||
486 | |||
487 | config ETRAX_SERIAL_PORT1_DMA8_OUT | ||
488 | depends on ETRAX_ARCH_V10 | ||
489 | bool "Ser1 uses DMA8 for output" | ||
490 | |||
491 | config ETRAX_SERIAL_PORT1_DMA4_OUT | ||
492 | depends on ETRAX_ARCH_V32 | ||
493 | bool "Ser1 uses DMA4 for output" | ||
494 | help | ||
495 | Enables the DMA4 output channel for ser1 (ttyS1). | ||
496 | If you do not enable DMA, an interrupt for each character will be | ||
497 | used when transmitting data. | ||
498 | Normally you want this on, unless you use the DMA channel for | ||
499 | something else. | ||
500 | |||
501 | endchoice | ||
502 | |||
503 | choice | ||
504 | prompt "Ser2 DMA out channel" | ||
505 | depends on ETRAX_SERIAL_PORT2 | ||
506 | default ETRAX_SERIAL_PORT2_NO_DMA_OUT if ETRAX_ARCH_V32 | ||
507 | default ETRAX_SERIAL_PORT2_DMA2_OUT if ETRAX_ARCH_V10 | ||
508 | |||
509 | config ETRAX_SERIAL_PORT2_NO_DMA_OUT | ||
510 | bool "Ser2 uses no DMA for output" | ||
511 | help | ||
512 | Do not use DMA for ser2 output. | ||
513 | |||
514 | config ETRAX_SERIAL_PORT2_DMA2_OUT | ||
515 | bool "Ser2 uses DMA2 for output" | ||
516 | depends on ETRAXFS || ETRAX_ARCH_V10 | ||
517 | help | ||
518 | Enables the DMA2 output channel for ser2 (ttyS2). | ||
519 | If you do not enable DMA, an interrupt for each character will be | ||
520 | used when transmitting data. | ||
521 | Normally you want to use DMA, unless you use the DMA channel for | ||
522 | something else. | ||
523 | |||
524 | config ETRAX_SERIAL_PORT2_DMA6_OUT | ||
525 | bool "Ser2 uses DMA6 for output" | ||
526 | depends on CRIS_MACH_ARTPEC3 | ||
527 | help | ||
528 | Enables the DMA6 output channel for ser2 (ttyS2). | ||
529 | If you do not enable DMA, an interrupt for each character will be | ||
530 | used when transmitting data. | ||
531 | Normally you want to use DMA, unless you use the DMA channel for | ||
532 | something else. | ||
533 | |||
534 | endchoice | ||
535 | |||
536 | choice | ||
537 | prompt "Ser2 DMA in channel" | ||
538 | depends on ETRAX_SERIAL_PORT2 | ||
539 | default ETRAX_SERIAL_PORT2_NO_DMA_IN if ETRAX_ARCH_V32 | ||
540 | default ETRAX_SERIAL_PORT2_DMA3_IN if ETRAX_ARCH_V10 | ||
541 | help | ||
542 | What DMA channel to use for ser2. | ||
543 | |||
544 | config ETRAX_SERIAL_PORT2_NO_DMA_IN | ||
545 | bool "Ser2 uses no DMA for input" | ||
546 | help | ||
547 | Do not use DMA for ser2 input. | ||
548 | |||
549 | config ETRAX_SERIAL_PORT2_DMA3_IN | ||
550 | bool "Ser2 uses DMA3 for input" | ||
551 | depends on ETRAXFS || ETRAX_ARCH_V10 | ||
552 | help | ||
553 | Enables the DMA3 input channel for ser2 (ttyS2). | ||
554 | If you do not enable DMA, an interrupt for each character will be | ||
555 | used when receiving data. | ||
556 | Normally you want to use DMA, unless you use the DMA channel for | ||
557 | something else. | ||
558 | |||
559 | config ETRAX_SERIAL_PORT2_DMA7_IN | ||
560 | bool "Ser2 uses DMA7 for input" | ||
561 | depends on CRIS_MACH_ARTPEC3 | ||
562 | help | ||
563 | Enables the DMA7 input channel for ser2 (ttyS2). | ||
564 | If you do not enable DMA, an interrupt for each character will be | ||
565 | used when receiveing data. | ||
566 | Normally you want to use DMA, unless you use the DMA channel for | ||
567 | something else. | ||
568 | |||
569 | endchoice | ||
570 | |||
571 | choice | ||
572 | prompt "Ser3 DMA in channel" | ||
573 | depends on ETRAX_SERIAL_PORT3 | ||
574 | default ETRAX_SERIAL_PORT3_NO_DMA_IN if ETRAX_ARCH_V32 | ||
575 | default ETRAX_SERIAL_PORT3_DMA5_IN if ETRAX_ARCH_V10 | ||
576 | help | ||
577 | What DMA channel to use for ser3. | ||
578 | |||
579 | config ETRAX_SERIAL_PORT3_NO_DMA_IN | ||
580 | bool "Ser3 uses no DMA for input" | ||
581 | help | ||
582 | Do not use DMA for ser3 input. | ||
583 | |||
584 | config ETRAX_SERIAL_PORT3_DMA5_IN | ||
585 | depends on ETRAX_ARCH_V10 | ||
586 | bool "DMA 5" | ||
587 | |||
588 | config ETRAX_SERIAL_PORT3_DMA9_IN | ||
589 | bool "Ser3 uses DMA9 for input" | ||
590 | depends on ETRAXFS | ||
591 | help | ||
592 | Enables the DMA9 input channel for ser3 (ttyS3). | ||
593 | If you do not enable DMA, an interrupt for each character will be | ||
594 | used when receiving data. | ||
595 | Normally you want to use DMA, unless you use the DMA channel for | ||
596 | something else. | ||
597 | |||
598 | config ETRAX_SERIAL_PORT3_DMA3_IN | ||
599 | bool "Ser3 uses DMA3 for input" | ||
600 | depends on CRIS_MACH_ARTPEC3 | ||
601 | help | ||
602 | Enables the DMA3 input channel for ser3 (ttyS3). | ||
603 | If you do not enable DMA, an interrupt for each character will be | ||
604 | used when receiveing data. | ||
605 | Normally you want to use DMA, unless you use the DMA channel for | ||
606 | something else. | ||
607 | |||
608 | endchoice | ||
609 | |||
610 | choice | ||
611 | prompt "Ser3 DMA out channel" | ||
612 | depends on ETRAX_SERIAL_PORT3 | ||
613 | default ETRAX_SERIAL_PORT3_NO_DMA_OUT if ETRAX_ARCH_V32 | ||
614 | default ETRAX_SERIAL_PORT3_DMA4_OUT if ETRAX_ARCH_V10 | ||
615 | |||
616 | config ETRAX_SERIAL_PORT3_NO_DMA_OUT | ||
617 | bool "Ser3 uses no DMA for output" | ||
618 | help | ||
619 | Do not use DMA for ser3 output. | ||
620 | |||
621 | config ETRAX_SERIAL_PORT3_DMA4_OUT | ||
622 | depends on ETRAX_ARCH_V10 | ||
623 | bool "DMA 4" | ||
624 | |||
625 | config ETRAX_SERIAL_PORT3_DMA8_OUT | ||
626 | bool "Ser3 uses DMA8 for output" | ||
627 | depends on ETRAXFS | ||
628 | help | ||
629 | Enables the DMA8 output channel for ser3 (ttyS3). | ||
630 | If you do not enable DMA, an interrupt for each character will be | ||
631 | used when transmitting data. | ||
632 | Normally you want to use DMA, unless you use the DMA channel for | ||
633 | something else. | ||
634 | |||
635 | config ETRAX_SERIAL_PORT3_DMA2_OUT | ||
636 | bool "Ser3 uses DMA2 for output" | ||
637 | depends on CRIS_MACH_ARTPEC3 | ||
638 | help | ||
639 | Enables the DMA2 output channel for ser3 (ttyS3). | ||
640 | If you do not enable DMA, an interrupt for each character will be | ||
641 | used when transmitting data. | ||
642 | Normally you want to use DMA, unless you use the DMA channel for | ||
643 | something else. | ||
644 | |||
645 | endchoice | ||
646 | |||
168 | endmenu | 647 | endmenu |
169 | 648 | ||
170 | source "drivers/base/Kconfig" | 649 | source "drivers/base/Kconfig" |
@@ -178,22 +657,10 @@ source "drivers/pnp/Kconfig" | |||
178 | 657 | ||
179 | source "drivers/block/Kconfig" | 658 | source "drivers/block/Kconfig" |
180 | 659 | ||
181 | source "drivers/md/Kconfig" | ||
182 | |||
183 | source "drivers/ide/Kconfig" | 660 | source "drivers/ide/Kconfig" |
184 | 661 | ||
185 | source "drivers/scsi/Kconfig" | ||
186 | |||
187 | source "drivers/ieee1394/Kconfig" | ||
188 | |||
189 | source "drivers/message/i2o/Kconfig" | ||
190 | |||
191 | source "drivers/net/Kconfig" | 662 | source "drivers/net/Kconfig" |
192 | 663 | ||
193 | source "drivers/isdn/Kconfig" | ||
194 | |||
195 | source "drivers/telephony/Kconfig" | ||
196 | |||
197 | source "drivers/i2c/Kconfig" | 664 | source "drivers/i2c/Kconfig" |
198 | 665 | ||
199 | source "drivers/rtc/Kconfig" | 666 | source "drivers/rtc/Kconfig" |
@@ -205,17 +672,8 @@ source "drivers/input/Kconfig" | |||
205 | 672 | ||
206 | source "drivers/char/Kconfig" | 673 | source "drivers/char/Kconfig" |
207 | 674 | ||
208 | #source drivers/misc/Config.in | ||
209 | source "drivers/media/Kconfig" | ||
210 | |||
211 | source "fs/Kconfig" | 675 | source "fs/Kconfig" |
212 | 676 | ||
213 | source "sound/Kconfig" | ||
214 | |||
215 | source "drivers/pcmcia/Kconfig" | ||
216 | |||
217 | source "drivers/pci/Kconfig" | ||
218 | |||
219 | source "drivers/usb/Kconfig" | 677 | source "drivers/usb/Kconfig" |
220 | 678 | ||
221 | source "arch/cris/Kconfig.debug" | 679 | source "arch/cris/Kconfig.debug" |
diff --git a/arch/cris/Makefile b/arch/cris/Makefile index e6bf00c262e0..838cd2ae03ae 100644 --- a/arch/cris/Makefile +++ b/arch/cris/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile,v 1.28 2005/03/17 10:44:37 larsv Exp $ | 1 | # |
2 | # cris/Makefile | 2 | # cris/Makefile |
3 | # | 3 | # |
4 | # This file is included by the global makefile so that you can add your own | 4 | # This file is included by the global makefile so that you can add your own |
@@ -10,28 +10,36 @@ | |||
10 | # License. See the file "COPYING" in the main directory of this archive | 10 | # License. See the file "COPYING" in the main directory of this archive |
11 | # for more details. | 11 | # for more details. |
12 | 12 | ||
13 | # A bug in ld prevents us from having a (constant-value) symbol in a | ||
14 | # "ORIGIN =" or "LENGTH =" expression. | ||
15 | |||
16 | arch-y := v10 | 13 | arch-y := v10 |
17 | arch-$(CONFIG_ETRAX_ARCH_V10) := v10 | 14 | arch-$(CONFIG_ETRAX_ARCH_V10) := v10 |
18 | arch-$(CONFIG_ETRAX_ARCH_V32) := v32 | 15 | arch-$(CONFIG_ETRAX_ARCH_V32) := v32 |
19 | 16 | ||
20 | # No config avaiable for make clean etc | 17 | # No config available for make clean etc |
18 | mach-y := fs | ||
19 | mach-$(CONFIG_CRIS_MACH_ARTPEC3) := a3 | ||
20 | mach-$(CONFIG_ETRAXFS) := fs | ||
21 | |||
21 | ifneq ($(arch-y),) | 22 | ifneq ($(arch-y),) |
22 | SARCH := arch-$(arch-y) | 23 | SARCH := arch-$(arch-y) |
23 | else | 24 | else |
24 | SARCH := | 25 | SARCH := |
25 | endif | 26 | endif |
26 | 27 | ||
28 | ifneq ($(mach-y),) | ||
29 | MACH := mach-$(mach-y) | ||
30 | else | ||
31 | MACH := | ||
32 | endif | ||
33 | |||
27 | LD = $(CROSS_COMPILE)ld -mcrislinux | 34 | LD = $(CROSS_COMPILE)ld -mcrislinux |
28 | 35 | ||
29 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 36 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
30 | 37 | ||
31 | CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE) | 38 | CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE) |
32 | KBUILD_AFLAGS += -mlinux | ||
33 | 39 | ||
34 | KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe | 40 | KBUILD_AFLAGS += -mlinux -march=$(arch-y) -Iinclude/asm/arch/mach -Iinclude/asm/arch |
41 | |||
42 | KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe -Iinclude/asm/arch/mach -Iinclude/asm/arch | ||
35 | 43 | ||
36 | ifdef CONFIG_FRAME_POINTER | 44 | ifdef CONFIG_FRAME_POINTER |
37 | KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g | 45 | KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g |
@@ -44,6 +52,9 @@ LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libgcc.a) | |||
44 | 52 | ||
45 | core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ | 53 | core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ |
46 | core-y += arch/$(ARCH)/$(SARCH)/kernel/ arch/$(ARCH)/$(SARCH)/mm/ | 54 | core-y += arch/$(ARCH)/$(SARCH)/kernel/ arch/$(ARCH)/$(SARCH)/mm/ |
55 | ifdef CONFIG_ETRAX_ARCH_V32 | ||
56 | core-y += arch/$(ARCH)/$(SARCH)/$(MACH)/ | ||
57 | endif | ||
47 | drivers-y += arch/$(ARCH)/$(SARCH)/drivers/ | 58 | drivers-y += arch/$(ARCH)/$(SARCH)/drivers/ |
48 | libs-y += arch/$(ARCH)/$(SARCH)/lib/ $(LIBGCC) | 59 | libs-y += arch/$(ARCH)/$(SARCH)/lib/ $(LIBGCC) |
49 | 60 | ||
@@ -52,79 +63,69 @@ SRC_ARCH = $(srctree)/arch/$(ARCH) | |||
52 | # cris object files path | 63 | # cris object files path |
53 | OBJ_ARCH = $(objtree)/arch/$(ARCH) | 64 | OBJ_ARCH = $(objtree)/arch/$(ARCH) |
54 | 65 | ||
55 | target_boot_arch_dir = $(OBJ_ARCH)/$(SARCH)/boot | 66 | boot := arch/$(ARCH)/boot |
56 | target_boot_dir = $(OBJ_ARCH)/boot | 67 | MACHINE := arch/$(ARCH)/$(SARCH) |
57 | src_boot_dir = $(SRC_ARCH)/boot | ||
58 | target_compressed_dir = $(OBJ_ARCH)/boot/compressed | ||
59 | src_compressed_dir = $(SRC_ARCH)/boot/compressed | ||
60 | target_rescue_dir = $(OBJ_ARCH)/boot/rescue | ||
61 | src_rescue_dir = $(SRC_ARCH)/boot/rescue | ||
62 | |||
63 | export target_boot_arch_dir target_boot_dir src_boot_dir target_compressed_dir src_compressed_dir target_rescue_dir src_rescue_dir | ||
64 | |||
65 | vmlinux.bin: vmlinux | ||
66 | $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux.bin | ||
67 | |||
68 | timage: vmlinux.bin | ||
69 | cat vmlinux.bin cramfs.img >timage | ||
70 | |||
71 | simimage: timage | ||
72 | cp vmlinux.bin simvmlinux.bin | ||
73 | |||
74 | # the following will remake timage without compiling the kernel | ||
75 | # it does of course require that all object files exist... | ||
76 | |||
77 | cramfs: | ||
78 | ## cramfs - Creates a cramfs image | ||
79 | mkcramfs -b 8192 -m romfs_meta.txt root cramfs.img | ||
80 | cat vmlinux.bin cramfs.img >timage | ||
81 | 68 | ||
82 | clinux: vmlinux.bin decompress.bin rescue.bin | 69 | all: zImage |
83 | 70 | ||
84 | decompress.bin: $(target_boot_dir) | 71 | zImage Image: vmlinux |
85 | @$(MAKE) -f $(src_compressed_dir)/Makefile $(target_compressed_dir)/decompress.bin | 72 | $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ |
86 | 73 | ||
87 | $(target_rescue_dir)/rescue.bin: $(target_boot_dir) | 74 | archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch FORCE |
88 | @$(MAKE) -f $(src_rescue_dir)/Makefile $(target_rescue_dir)/rescue.bin | ||
89 | |||
90 | zImage: $(target_boot_dir) vmlinux.bin $(target_rescue_dir)/rescue.bin | ||
91 | ## zImage - Compressed kernel (gzip) | ||
92 | @$(MAKE) -f $(src_boot_dir)/Makefile zImage | ||
93 | |||
94 | $(target_boot_dir): $(target_boot_arch_dir) | ||
95 | ln -sfn $< $@ | ||
96 | |||
97 | $(target_boot_arch_dir): | ||
98 | mkdir -p $@ | ||
99 | |||
100 | compressed: zImage | ||
101 | |||
102 | archmrproper: | ||
103 | archclean: | ||
104 | @if [ -d arch/$(ARCH)/boot ]; then \ | ||
105 | $(MAKE) $(clean)=arch/$(ARCH)/boot ; \ | ||
106 | fi | ||
107 | rm -f timage vmlinux.bin decompress.bin rescue.bin cramfs.img | ||
108 | rm -rf $(LD_SCRIPT).tmp | ||
109 | |||
110 | archprepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch | ||
111 | 75 | ||
112 | # Create some links to make all tools happy | 76 | # Create some links to make all tools happy |
113 | $(SRC_ARCH)/.links: | 77 | $(SRC_ARCH)/.links: |
114 | @rm -rf $(SRC_ARCH)/drivers | 78 | @rm -rf $(SRC_ARCH)/drivers |
115 | @ln -sfn $(SRC_ARCH)/$(SARCH)/drivers $(SRC_ARCH)/drivers | 79 | @ln -sfn $(SARCH)/drivers $(SRC_ARCH)/drivers |
116 | @rm -rf $(SRC_ARCH)/boot | 80 | @rm -rf $(SRC_ARCH)/boot |
117 | @ln -sfn $(SRC_ARCH)/$(SARCH)/boot $(SRC_ARCH)/boot | 81 | @ln -sfn $(SARCH)/boot $(SRC_ARCH)/boot |
118 | @rm -rf $(SRC_ARCH)/lib | 82 | @rm -rf $(SRC_ARCH)/lib |
119 | @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib | 83 | @ln -sfn $(SARCH)/lib $(SRC_ARCH)/lib |
120 | @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch | 84 | @rm -f $(SRC_ARCH)/arch/mach |
121 | @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S | 85 | @rm -rf $(SRC_ARCH)/arch |
122 | @ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c | 86 | @ln -sfn $(SARCH) $(SRC_ARCH)/arch |
87 | ifdef CONFIG_ETRAX_ARCH_V32 | ||
88 | @ln -sfn ../$(SARCH)/$(MACH) $(SRC_ARCH)/arch/mach | ||
89 | endif | ||
90 | @rm -rf $(SRC_ARCH)/kernel/vmlinux.lds.S | ||
91 | @ln -sfn ../$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S | ||
92 | @rm -rf $(SRC_ARCH)/kernel/asm-offsets.c | ||
93 | @ln -sfn ../$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c | ||
123 | @touch $@ | 94 | @touch $@ |
124 | 95 | ||
125 | # Create link to sub arch includes | 96 | # Create link to sub arch includes |
126 | $(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h) | 97 | $(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h) |
127 | @echo ' Making $(srctree)/include/asm-$(ARCH)/arch -> $(srctree)/include/asm-$(ARCH)/$(SARCH) symlink' | 98 | @echo ' SYMLINK include/asm-$(ARCH)/arch -> include/asm-$(ARCH)/$(SARCH)' |
128 | @rm -f include/asm-$(ARCH)/arch | 99 | @rm -f $(srctree)/include/asm-$(ARCH)/arch/mach |
129 | @ln -sf $(srctree)/include/asm-$(ARCH)/$(SARCH) $(srctree)/include/asm-$(ARCH)/arch | 100 | @rm -f $(srctree)/include/asm-$(ARCH)/arch |
101 | @ln -sf $(SARCH) $(srctree)/include/asm-$(ARCH)/arch | ||
102 | ifdef CONFIG_ETRAX_ARCH_V32 | ||
103 | @ln -sf $(MACH) $(srctree)/include/asm-$(ARCH)/arch/mach | ||
104 | endif | ||
130 | @touch $@ | 105 | @touch $@ |
106 | |||
107 | archclean: | ||
108 | $(Q)if [ -e arch/$(ARCH)/boot ]; then \ | ||
109 | $(MAKE) $(clean)=arch/$(ARCH)/boot; \ | ||
110 | fi | ||
111 | |||
112 | CLEAN_FILES += \ | ||
113 | $(MACHINE)/boot/zImage \ | ||
114 | $(MACHINE)/boot/compressed/decompress.bin \ | ||
115 | $(MACHINE)/boot/compressed/piggy.gz \ | ||
116 | $(MACHINE)/boot/rescue/rescue.bin \ | ||
117 | $(SRC_ARCH)/.links \ | ||
118 | $(srctree)/include/asm-$(ARCH)/.arch | ||
119 | |||
120 | MRPROPER_FILES += \ | ||
121 | $(SRC_ARCH)/drivers \ | ||
122 | $(SRC_ARCH)/boot \ | ||
123 | $(SRC_ARCH)/lib \ | ||
124 | $(SRC_ARCH)/arch \ | ||
125 | $(SRC_ARCH)/kernel/vmlinux.lds.S \ | ||
126 | $(SRC_ARCH)/kernel/asm-offsets.c | ||
127 | |||
128 | define archhelp | ||
129 | echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' | ||
130 | echo '* Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' | ||
131 | endef | ||
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig index 1d61faec77cd..adc164e99339 100644 --- a/arch/cris/arch-v10/Kconfig +++ b/arch/cris/arch-v10/Kconfig | |||
@@ -1,5 +1,7 @@ | |||
1 | if ETRAX_ARCH_V10 | 1 | if ETRAX_ARCH_V10 |
2 | 2 | ||
3 | menu "CRIS v10 options" | ||
4 | |||
3 | # ETRAX 100LX v1 has a MMU "feature" requiring a low mapping | 5 | # ETRAX 100LX v1 has a MMU "feature" requiring a low mapping |
4 | config CRIS_LOW_MAP | 6 | config CRIS_LOW_MAP |
5 | bool | 7 | bool |
@@ -228,69 +230,6 @@ config ETRAX_LED12R | |||
228 | For products with only one or two controllable LEDs, | 230 | For products with only one or two controllable LEDs, |
229 | set this to same as CONFIG_ETRAX_LED1G (normally 2). | 231 | set this to same as CONFIG_ETRAX_LED1G (normally 2). |
230 | 232 | ||
231 | choice | ||
232 | prompt "Product debug-port" | ||
233 | depends on ETRAX_ARCH_V10 | ||
234 | default ETRAX_DEBUG_PORT0 | ||
235 | |||
236 | config ETRAX_DEBUG_PORT0 | ||
237 | bool "Serial-0" | ||
238 | help | ||
239 | Choose a serial port for the ETRAX debug console. Default to | ||
240 | port 0. | ||
241 | |||
242 | config ETRAX_DEBUG_PORT1 | ||
243 | bool "Serial-1" | ||
244 | help | ||
245 | Use serial port 1 for the console. | ||
246 | |||
247 | config ETRAX_DEBUG_PORT2 | ||
248 | bool "Serial-2" | ||
249 | help | ||
250 | Use serial port 2 for the console. | ||
251 | |||
252 | config ETRAX_DEBUG_PORT3 | ||
253 | bool "Serial-3" | ||
254 | help | ||
255 | Use serial port 3 for the console. | ||
256 | |||
257 | config ETRAX_DEBUG_PORT_NULL | ||
258 | bool "disabled" | ||
259 | help | ||
260 | Disable serial-port debugging. | ||
261 | |||
262 | endchoice | ||
263 | |||
264 | choice | ||
265 | prompt "Kernel GDB port" | ||
266 | depends on ETRAX_KGDB | ||
267 | default ETRAX_KGDB_PORT0 | ||
268 | help | ||
269 | Choose a serial port for kernel debugging. NOTE: This port should | ||
270 | not be enabled under Drivers for built-in interfaces (as it has its | ||
271 | own initialization code) and should not be the same as the debug port. | ||
272 | |||
273 | config ETRAX_KGDB_PORT0 | ||
274 | bool "Serial-0" | ||
275 | help | ||
276 | Use serial port 0 for kernel debugging. | ||
277 | |||
278 | config ETRAX_KGDB_PORT1 | ||
279 | bool "Serial-1" | ||
280 | help | ||
281 | Use serial port 1 for kernel debugging. | ||
282 | |||
283 | config ETRAX_KGDB_PORT2 | ||
284 | bool "Serial-2" | ||
285 | help | ||
286 | Use serial port 2 for kernel debugging. | ||
287 | |||
288 | config ETRAX_KGDB_PORT3 | ||
289 | bool "Serial-3" | ||
290 | help | ||
291 | Use serial port 3 for kernel debugging. | ||
292 | |||
293 | endchoice | ||
294 | 233 | ||
295 | choice | 234 | choice |
296 | prompt "Product rescue-port" | 235 | prompt "Product rescue-port" |
@@ -454,4 +393,6 @@ config ETRAX_POWERBUTTON_BIT | |||
454 | help | 393 | help |
455 | Configure where power button is connected. | 394 | Configure where power button is connected. |
456 | 395 | ||
396 | endmenu | ||
397 | |||
457 | endif | 398 | endif |
diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/arch-v10/boot/Makefile index e5b105851108..20c83a53caf3 100644 --- a/arch/cris/arch-v10/boot/Makefile +++ b/arch/cris/arch-v10/boot/Makefile | |||
@@ -1,13 +1,21 @@ | |||
1 | # | 1 | # |
2 | # arch/cris/boot/Makefile | 2 | # arch/cris/arch-v10/boot/Makefile |
3 | # | 3 | # |
4 | target = $(target_boot_dir) | ||
5 | src = $(src_boot_dir) | ||
6 | 4 | ||
7 | zImage: compressed/vmlinuz | 5 | OBJCOPY = objcopy-cris |
6 | OBJCOPYFLAGS = -O binary --remove-section=.bss | ||
8 | 7 | ||
9 | compressed/vmlinuz: | 8 | subdir- := compressed rescue |
10 | @$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz | 9 | targets := Image |
11 | 10 | ||
12 | clean: | 11 | $(obj)/Image: vmlinux FORCE |
13 | @$(MAKE) -f $(src)/compressed/Makefile clean | 12 | $(call if_changed,objcopy) |
13 | @echo ' Kernel: $@ is ready' | ||
14 | |||
15 | $(obj)/compressed/vmlinux: $(obj)/Image FORCE | ||
16 | $(Q)$(MAKE) $(build)=$(obj)/compressed $@ | ||
17 | $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin | ||
18 | |||
19 | $(obj)/zImage: $(obj)/compressed/vmlinux | ||
20 | @cp $< $@ | ||
21 | @echo ' Kernel: $@ is ready' | ||
diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile index 6584a44820f4..4a031cb27eb9 100644 --- a/arch/cris/arch-v10/boot/compressed/Makefile +++ b/arch/cris/arch-v10/boot/compressed/Makefile | |||
@@ -1,45 +1,35 @@ | |||
1 | # | 1 | # |
2 | # create a compressed vmlinuz image from the binary vmlinux.bin file | 2 | # arch/cris/arch-v10/boot/compressed/Makefile |
3 | # | 3 | # |
4 | target = $(target_compressed_dir) | ||
5 | src = $(src_compressed_dir) | ||
6 | 4 | ||
7 | CC = gcc-cris -melf $(LINUXINCLUDE) | 5 | CC = gcc-cris -melf $(LINUXINCLUDE) |
8 | CFLAGS = -O2 | 6 | ccflags-y += -O2 |
9 | LD = ld-cris | 7 | LD = ld-cris |
8 | ldflags-y += -T $(obj)/decompress.ld | ||
9 | OBJECTS = $(obj)/head.o $(obj)/misc.o | ||
10 | OBJCOPY = objcopy-cris | 10 | OBJCOPY = objcopy-cris |
11 | OBJCOPYFLAGS = -O binary --remove-section=.bss | 11 | OBJCOPYFLAGS = -O binary --remove-section=.bss |
12 | OBJECTS = $(target)/head.o $(target)/misc.o | ||
13 | 12 | ||
14 | # files to compress | 13 | quiet_cmd_image = BUILD $@ |
15 | SYSTEM = $(objtree)/vmlinux.bin | 14 | cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@ |
16 | 15 | ||
17 | all: $(target_compressed_dir)/vmlinuz | 16 | targets := vmlinux piggy.gz decompress.o decompress.bin |
18 | 17 | ||
19 | $(target)/decompress.bin: $(OBJECTS) | 18 | $(obj)/decompress.o: $(OBJECTS) FORCE |
20 | $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS) | 19 | $(call if_changed,ld) |
21 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin | ||
22 | 20 | ||
23 | # Create vmlinuz image in top-level build directory | 21 | $(obj)/decompress.bin: $(obj)/decompress.o FORCE |
24 | $(target_compressed_dir)/vmlinuz: $(target) piggy.img $(target)/decompress.bin | 22 | $(call if_changed,objcopy) |
25 | @echo " COMPR vmlinux.bin --> vmlinuz" | ||
26 | @cat $(target)/decompress.bin piggy.img > $(target_compressed_dir)/vmlinuz | ||
27 | @rm -f piggy.img | ||
28 | 23 | ||
29 | $(target)/head.o: $(src)/head.S | 24 | $(obj)/head.o: $(obj)/head.S .config |
30 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $@ | 25 | @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@ |
31 | 26 | ||
32 | $(target)/misc.o: $(src)/misc.c | 27 | $(obj)/misc.o: $(obj)/misc.c .config |
33 | $(CC) -D__KERNEL__ -c $< -o $@ | 28 | @$(CC) -D__KERNEL__ -c $< -o $@ |
34 | 29 | ||
35 | # gzip the kernel image | 30 | $(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE |
31 | $(call if_changed,image) | ||
36 | 32 | ||
37 | piggy.img: $(SYSTEM) | 33 | $(obj)/piggy.gz: $(obj)/../Image FORCE |
38 | @cat $(SYSTEM) | gzip -f -9 > piggy.img | 34 | $(call if_changed,gzip) |
39 | |||
40 | $(target): | ||
41 | mkdir -p $(target) | ||
42 | |||
43 | clean: | ||
44 | rm -f piggy.img $(objtree)/vmlinuz | ||
45 | 35 | ||
diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c index e205d2e7e089..9a43ab19391e 100644 --- a/arch/cris/arch-v10/boot/compressed/misc.c +++ b/arch/cris/arch-v10/boot/compressed/misc.c | |||
@@ -1,15 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * misc.c | 2 | * misc.c |
3 | * | 3 | * |
4 | * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $ | 4 | * This is a collection of several routines from gzip-1.0.3 |
5 | * | ||
6 | * This is a collection of several routines from gzip-1.0.3 | ||
7 | * adapted for Linux. | 5 | * adapted for Linux. |
8 | * | 6 | * |
9 | * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 | 7 | * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 |
10 | * puts by Nick Holloway 1993, better puts by Martin Mares 1995 | 8 | * puts by Nick Holloway 1993, better puts by Martin Mares 1995 |
11 | * adaptation for Linux/CRIS Axis Communications AB, 1999 | 9 | * adaptation for Linux/CRIS Axis Communications AB, 1999 |
12 | * | 10 | * |
13 | */ | 11 | */ |
14 | 12 | ||
15 | /* where the piggybacked kernel image expects itself to live. | 13 | /* where the piggybacked kernel image expects itself to live. |
diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile index 8be9b3130312..2e5045b9e19c 100644 --- a/arch/cris/arch-v10/boot/rescue/Makefile +++ b/arch/cris/arch-v10/boot/rescue/Makefile | |||
@@ -1,56 +1,38 @@ | |||
1 | # | 1 | # |
2 | # Makefile for rescue code | 2 | # Makefile for rescue (bootstrap) code |
3 | # | 3 | # |
4 | target = $(target_rescue_dir) | ||
5 | src = $(src_rescue_dir) | ||
6 | 4 | ||
7 | CC = gcc-cris -mlinux $(LINUXINCLUDE) | 5 | CC = gcc-cris -mlinux $(LINUXINCLUDE) |
8 | CFLAGS = -O2 | 6 | ccflags-y += -O2 |
7 | asflags-y += -traditional | ||
9 | LD = gcc-cris -mlinux -nostdlib | 8 | LD = gcc-cris -mlinux -nostdlib |
9 | ldflags-y += -T $(obj)/rescue.ld | ||
10 | OBJCOPY = objcopy-cris | 10 | OBJCOPY = objcopy-cris |
11 | OBJCOPYFLAGS = -O binary --remove-section=.bss | 11 | OBJCOPYFLAGS = -O binary --remove-section=.bss |
12 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o | ||
13 | OBJECT := $(obj)/head.o | ||
12 | 14 | ||
13 | all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin | 15 | targets := rescue.o rescue.bin |
14 | 16 | ||
15 | $(target)/rescue.bin: $(target) $(target)/head.o | 17 | $(obj)/rescue.o: $(OBJECT) FORCE |
16 | $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o | 18 | $(call if_changed,ld) |
17 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin | ||
18 | # Place a copy in top-level build directory | ||
19 | cp -p $(target)/rescue.bin $(objtree) | ||
20 | 19 | ||
21 | $(target)/testrescue.bin: $(target) $(target)/testrescue.o | 20 | $(obj)/rescue.bin: $(obj)/rescue.o FORCE |
22 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/testrescue.o tr.bin | 21 | $(call if_changed,objcopy) |
22 | cp -p $(obj)/rescue.bin $(objtree) | ||
23 | |||
24 | $(obj)/testrescue.bin: $(obj)/testrescue.o | ||
25 | $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin | ||
23 | # Pad it to 784 bytes | 26 | # Pad it to 784 bytes |
24 | dd if=/dev/zero of=tmp2423 bs=1 count=784 | 27 | dd if=/dev/zero of=tmp2423 bs=1 count=784 |
25 | cat tr.bin tmp2423 >testrescue_tmp.bin | 28 | cat tr.bin tmp2423 >testrescue_tmp.bin |
26 | dd if=testrescue_tmp.bin of=$(target)/testrescue.bin bs=1 count=784 | 29 | dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784 |
27 | rm tr.bin tmp2423 testrescue_tmp.bin | 30 | rm tr.bin tmp2423 testrescue_tmp.bin |
28 | 31 | ||
29 | $(target)/kimagerescue.bin: $(target) $(target)/kimagerescue.o | 32 | $(obj)/kimagerescue.bin: $(obj)/kimagerescue.o |
30 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/kimagerescue.o ktr.bin | 33 | $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin |
31 | # Pad it to 784 bytes, that's what the rescue loader expects | 34 | # Pad it to 784 bytes, that's what the rescue loader expects |
32 | dd if=/dev/zero of=tmp2423 bs=1 count=784 | 35 | dd if=/dev/zero of=tmp2423 bs=1 count=784 |
33 | cat ktr.bin tmp2423 >kimagerescue_tmp.bin | 36 | cat ktr.bin tmp2423 >kimagerescue_tmp.bin |
34 | dd if=kimagerescue_tmp.bin of=$(target)/kimagerescue.bin bs=1 count=784 | 37 | dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784 |
35 | rm ktr.bin tmp2423 kimagerescue_tmp.bin | 38 | rm ktr.bin tmp2423 kimagerescue_tmp.bin |
36 | |||
37 | $(target): | ||
38 | mkdir -p $(target) | ||
39 | |||
40 | $(target)/head.o: $(src)/head.S | ||
41 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o | ||
42 | |||
43 | $(target)/testrescue.o: $(src)/testrescue.S | ||
44 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o | ||
45 | |||
46 | $(target)/kimagerescue.o: $(src)/kimagerescue.S | ||
47 | $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o | ||
48 | |||
49 | clean: | ||
50 | rm -f $(target)/*.o $(target)/*.bin | ||
51 | |||
52 | fastdep: | ||
53 | |||
54 | modules: | ||
55 | |||
56 | modules-install: | ||
diff --git a/arch/cris/arch-v10/boot/rescue/head.S b/arch/cris/arch-v10/boot/rescue/head.S index f223cc0c00bb..6ba7be8ac4a0 100644 --- a/arch/cris/arch-v10/boot/rescue/head.S +++ b/arch/cris/arch-v10/boot/rescue/head.S | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: head.S,v 1.7 2005/03/07 12:11:06 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * Rescue code, made to reside at the beginning of the | 2 | * Rescue code, made to reside at the beginning of the |
4 | * flash-memory. when it starts, it checks a partition | 3 | * flash-memory. when it starts, it checks a partition |
5 | * table at the first sector after the rescue sector. | 4 | * table at the first sector after the rescue sector. |
@@ -23,20 +22,20 @@ | |||
23 | * Partition table format: | 22 | * Partition table format: |
24 | * | 23 | * |
25 | * Code transparency: | 24 | * Code transparency: |
26 | * | 25 | * |
27 | * 2 bytes [opcode 'nop'] | 26 | * 2 bytes [opcode 'nop'] |
28 | * 2 bytes [opcode 'di'] | 27 | * 2 bytes [opcode 'di'] |
29 | * 4 bytes [opcode 'ba <offset>', 8-bit or 16-bit version] | 28 | * 4 bytes [opcode 'ba <offset>', 8-bit or 16-bit version] |
30 | * 2 bytes [opcode 'nop', delay slot] | 29 | * 2 bytes [opcode 'nop', delay slot] |
31 | * | 30 | * |
32 | * Table validation (at +10): | 31 | * Table validation (at +10): |
33 | * | 32 | * |
34 | * 2 bytes [magic/version word for partitiontable - 0xef, 0xbe] | 33 | * 2 bytes [magic/version word for partitiontable - 0xef, 0xbe] |
35 | * 2 bytes [length of all entries plus the end marker] | 34 | * 2 bytes [length of all entries plus the end marker] |
36 | * 4 bytes [checksum for the partitiontable itself] | 35 | * 4 bytes [checksum for the partitiontable itself] |
37 | * | 36 | * |
38 | * Entries, each with the following format, last has offset -1: | 37 | * Entries, each with the following format, last has offset -1: |
39 | * | 38 | * |
40 | * 4 bytes [offset in bytes, from start of flash] | 39 | * 4 bytes [offset in bytes, from start of flash] |
41 | * 4 bytes [length in bytes of partition] | 40 | * 4 bytes [length in bytes of partition] |
42 | * 4 bytes [checksum, simple longword sum] | 41 | * 4 bytes [checksum, simple longword sum] |
@@ -47,9 +46,9 @@ | |||
47 | * End marker | 46 | * End marker |
48 | * | 47 | * |
49 | * 4 bytes [-1] | 48 | * 4 bytes [-1] |
50 | * | 49 | * |
51 | * 10 bytes [0, padding] | 50 | * 10 bytes [0, padding] |
52 | * | 51 | * |
53 | * Bit 0 in flags signifies RW or RO. The rescue code only bothers | 52 | * Bit 0 in flags signifies RW or RO. The rescue code only bothers |
54 | * to check the checksum for RO partitions, since the others will | 53 | * to check the checksum for RO partitions, since the others will |
55 | * change their data without updating the checksums. A 1 in bit 0 | 54 | * change their data without updating the checksums. A 1 in bit 0 |
@@ -59,26 +58,29 @@ | |||
59 | * | 58 | * |
60 | * During the wait for serial input, the status LED will flash so the | 59 | * During the wait for serial input, the status LED will flash so the |
61 | * user knows something went wrong. | 60 | * user knows something went wrong. |
62 | * | 61 | * |
63 | * Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB | 62 | * Copyright (C) 1999-2007 Axis Communications AB |
64 | */ | 63 | */ |
65 | 64 | ||
65 | #ifdef CONFIG_ETRAX_AXISFLASHMAP | ||
66 | |||
66 | #define ASSEMBLER_MACROS_ONLY | 67 | #define ASSEMBLER_MACROS_ONLY |
67 | #include <asm/arch/sv_addr_ag.h> | 68 | #include <asm/arch/sv_addr_ag.h> |
68 | 69 | ||
69 | ;; The partitiontable is looked for at the first sector after the boot | 70 | ;; The partitiontable is looked for at the first sector after the boot |
70 | ;; sector. Sector size is 65536 bytes in all flashes we use. | 71 | ;; sector. Sector size is 65536 bytes in all flashes we use. |
71 | 72 | ||
72 | #define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR | 73 | #define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR |
73 | #define PTABLE_MAGIC 0xbeef | 74 | #define PTABLE_MAGIC 0xbeef |
74 | 75 | ||
75 | ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0. | 76 | ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0. |
76 | ;; That is not where we put our downloaded serial boot-code. The length is | 77 | ;; That is not where we put our downloaded serial boot-code. |
77 | ;; enough for downloading code that loads the rest of itself (after | 78 | ;; The length is enough for downloading code that loads the rest |
78 | ;; having setup the DRAM etc). It is the same length as the on-chip | 79 | ;; of itself (after having setup the DRAM etc). |
79 | ;; ROM loads, so the same host loader can be used to load a rescued | 80 | ;; It is the same length as the on-chip ROM loads, so the same |
80 | ;; product as well as one booted through the Etrax serial boot code. | 81 | ;; host loader can be used to load a rescued product as well as |
81 | 82 | ;; one booted through the Etrax serial boot code. | |
83 | |||
82 | #define CODE_START 0x40000000 | 84 | #define CODE_START 0x40000000 |
83 | #define CODE_LENGTH 784 | 85 | #define CODE_LENGTH 784 |
84 | 86 | ||
@@ -102,7 +104,7 @@ | |||
102 | #define SERRECC R_SERIAL2_REC_CTRL | 104 | #define SERRECC R_SERIAL2_REC_CTRL |
103 | #define SERRDAT R_SERIAL2_REC_DATA | 105 | #define SERRDAT R_SERIAL2_REC_DATA |
104 | #define SERSTAT R_SERIAL2_STATUS | 106 | #define SERSTAT R_SERIAL2_STATUS |
105 | #endif | 107 | #endif |
106 | #ifdef CONFIG_ETRAX_RESCUE_SER3 | 108 | #ifdef CONFIG_ETRAX_RESCUE_SER3 |
107 | #define SERXOFF R_SERIAL3_XOFF | 109 | #define SERXOFF R_SERIAL3_XOFF |
108 | #define SERBAUD R_SERIAL3_BAUD | 110 | #define SERBAUD R_SERIAL3_BAUD |
@@ -115,60 +117,61 @@ | |||
115 | #define RAM_INIT_MAGIC 0x56902387 | 117 | #define RAM_INIT_MAGIC 0x56902387 |
116 | 118 | ||
117 | .text | 119 | .text |
118 | 120 | ||
119 | ;; This is the entry point of the rescue code | 121 | ;; This is the entry point of the rescue code |
120 | ;; 0x80000000 if loaded in flash (as it should be) | 122 | ;; 0x80000000 if loaded in flash (as it should be) |
121 | ;; since etrax actually starts at address 2 when booting from flash, we | 123 | ;; Since etrax actually starts at address 2 when booting from flash, we |
122 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di | 124 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di |
123 | 125 | ||
124 | nop | 126 | nop |
125 | di | 127 | di |
126 | 128 | ||
127 | jump in_cache ; enter cached area instead | 129 | jump in_cache ; enter cached area instead |
128 | in_cache: | 130 | in_cache: |
129 | 131 | ||
130 | 132 | ||
131 | ;; first put a jump test to give a possibility of upgrading the rescue code | 133 | ;; First put a jump test to give a possibility of upgrading the |
132 | ;; without erasing/reflashing the sector. we put a longword of -1 here and if | 134 | ;; rescue code without erasing/reflashing the sector. |
133 | ;; it is not -1, we jump using the value as jump target. since we can always | 135 | ;; We put a longword of -1 here and if it is not -1, we jump using |
134 | ;; change 1's to 0's without erasing the sector, it is possible to add new | 136 | ;; the value as jump target. Since we can always change 1's to 0's |
137 | ;; without erasing the sector, it is possible to add new | ||
135 | ;; code after this and altering the jumptarget in an upgrade. | 138 | ;; code after this and altering the jumptarget in an upgrade. |
136 | 139 | ||
137 | jtcd: move.d [jumptarget], $r0 | 140 | jtcd: move.d [jumptarget], $r0 |
138 | cmp.d 0xffffffff, $r0 | 141 | cmp.d 0xffffffff, $r0 |
139 | beq no_newjump | 142 | beq no_newjump |
140 | nop | 143 | nop |
141 | 144 | ||
142 | jump [$r0] | 145 | jump [$r0] |
143 | 146 | ||
144 | jumptarget: | 147 | jumptarget: |
145 | .dword 0xffffffff ; can be overwritten later to insert new code | 148 | .dword 0xffffffff ; can be overwritten later to insert new code |
146 | 149 | ||
147 | no_newjump: | 150 | no_newjump: |
148 | #ifdef CONFIG_ETRAX_ETHERNET | 151 | #ifdef CONFIG_ETRAX_ETHERNET |
149 | ;; Start MII clock to make sure it is running when tranceiver is reset | 152 | ;; Start MII clock to make sure it is running when tranceiver is reset |
150 | move.d 0x3, $r0 ; enable = on, phy = mii_clk | 153 | move.d 0x3, $r0 ; enable = on, phy = mii_clk |
151 | move.d $r0, [R_NETWORK_GEN_CONFIG] | 154 | move.d $r0, [R_NETWORK_GEN_CONFIG] |
152 | #endif | 155 | #endif |
153 | 156 | ||
154 | ;; We need to setup the bus registers before we start using the DRAM | 157 | ;; We need to setup the bus registers before we start using the DRAM |
155 | #include "../../lib/dram_init.S" | 158 | #include "../../lib/dram_init.S" |
156 | 159 | ||
157 | ;; we now should go through the checksum-table and check the listed | 160 | ;; we now should go through the checksum-table and check the listed |
158 | ;; partitions for errors. | 161 | ;; partitions for errors. |
159 | 162 | ||
160 | move.d PTABLE_START, $r3 | 163 | move.d PTABLE_START, $r3 |
161 | move.d [$r3], $r0 | 164 | move.d [$r3], $r0 |
162 | cmp.d NOP_DI, $r0 ; make sure the nop/di is there... | 165 | cmp.d NOP_DI, $r0 ; make sure the nop/di is there... |
163 | bne do_rescue | 166 | bne do_rescue |
164 | nop | 167 | nop |
165 | 168 | ||
166 | ;; skip the code transparency block (10 bytes). | 169 | ;; skip the code transparency block (10 bytes). |
167 | 170 | ||
168 | addq 10, $r3 | 171 | addq 10, $r3 |
169 | 172 | ||
170 | ;; check for correct magic | 173 | ;; check for correct magic |
171 | 174 | ||
172 | move.w [$r3+], $r0 | 175 | move.w [$r3+], $r0 |
173 | cmp.w PTABLE_MAGIC, $r0 | 176 | cmp.w PTABLE_MAGIC, $r0 |
174 | bne do_rescue ; didn't recognize - trig rescue | 177 | bne do_rescue ; didn't recognize - trig rescue |
@@ -186,11 +189,11 @@ no_newjump: | |||
186 | cmp.d $r0, $r4 | 189 | cmp.d $r0, $r4 |
187 | bne do_rescue ; didn't match - trig rescue | 190 | bne do_rescue ; didn't match - trig rescue |
188 | nop | 191 | nop |
189 | 192 | ||
190 | ;; ptable is ok. validate each entry. | 193 | ;; ptable is ok. validate each entry. |
191 | 194 | ||
192 | moveq -1, $r7 | 195 | moveq -1, $r7 |
193 | 196 | ||
194 | ploop: move.d [$r3+], $r1 ; partition offset (from ptable start) | 197 | ploop: move.d [$r3+], $r1 ; partition offset (from ptable start) |
195 | bne notfirst ; check if it is the partition containing ptable | 198 | bne notfirst ; check if it is the partition containing ptable |
196 | nop ; yes.. | 199 | nop ; yes.. |
@@ -199,7 +202,7 @@ ploop: move.d [$r3+], $r1 ; partition offset (from ptable start) | |||
199 | sub.d $r8, $r2 ; minus the ptable length | 202 | sub.d $r8, $r2 ; minus the ptable length |
200 | ba bosse | 203 | ba bosse |
201 | nop | 204 | nop |
202 | notfirst: | 205 | notfirst: |
203 | cmp.d -1, $r1 ; the end of the ptable ? | 206 | cmp.d -1, $r1 ; the end of the ptable ? |
204 | beq flash_ok ; if so, the flash is validated | 207 | beq flash_ok ; if so, the flash is validated |
205 | move.d [$r3+], $r2 ; partition length | 208 | move.d [$r3+], $r2 ; partition length |
@@ -213,47 +216,46 @@ bosse: move.d [$r3+], $r5 ; checksum | |||
213 | bpl 1f | 216 | bpl 1f |
214 | nop | 217 | nop |
215 | move.d $r1, $r7 ; remember boot partition offset | 218 | move.d $r1, $r7 ; remember boot partition offset |
216 | 1: | 219 | 1: |
217 | |||
218 | add.d PTABLE_START, $r1 | 220 | add.d PTABLE_START, $r1 |
219 | 221 | ||
220 | jsr checksum ; checksum the partition | 222 | jsr checksum ; checksum the partition |
221 | 223 | ||
222 | cmp.d $r0, $r5 | 224 | cmp.d $r0, $r5 |
223 | beq ploop ; checksums matched, go to next entry | 225 | beq ploop ; checksums matched, go to next entry |
224 | nop | 226 | nop |
225 | 227 | ||
226 | ;; otherwise fall through to the rescue code. | 228 | ;; otherwise fall through to the rescue code. |
227 | 229 | ||
228 | do_rescue: | 230 | do_rescue: |
229 | ;; setup port PA and PB default initial directions and data | 231 | ;; setup port PA and PB default initial directions and data |
230 | ;; (so we can flash LEDs, and so that DTR and others are set) | 232 | ;; (so we can flash LEDs, and so that DTR and others are set) |
231 | 233 | ||
232 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 | 234 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 |
233 | move.b $r0, [R_PORT_PA_DIR] | 235 | move.b $r0, [R_PORT_PA_DIR] |
234 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 | 236 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 |
235 | move.b $r0, [R_PORT_PA_DATA] | 237 | move.b $r0, [R_PORT_PA_DATA] |
236 | 238 | ||
237 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 | 239 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 |
238 | move.b $r0, [R_PORT_PB_DIR] | 240 | move.b $r0, [R_PORT_PB_DIR] |
239 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 | 241 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 |
240 | move.b $r0, [R_PORT_PB_DATA] | 242 | move.b $r0, [R_PORT_PB_DATA] |
241 | 243 | ||
242 | ;; setup the serial port at 115200 baud | 244 | ;; setup the serial port at 115200 baud |
243 | 245 | ||
244 | moveq 0, $r0 | 246 | moveq 0, $r0 |
245 | move.d $r0, [SERXOFF] | 247 | move.d $r0, [SERXOFF] |
246 | 248 | ||
247 | move.b 0x99, $r0 | 249 | move.b 0x99, $r0 |
248 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive | 250 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive |
249 | 251 | ||
250 | move.b 0x40, $r0 ; rec enable | 252 | move.b 0x40, $r0 ; rec enable |
251 | move.b $r0, [SERRECC] | 253 | move.b $r0, [SERRECC] |
252 | 254 | ||
253 | moveq 0, $r1 ; "timer" to clock out a LED red flash | 255 | moveq 0, $r1 ; "timer" to clock out a LED red flash |
254 | move.d CODE_START, $r3 ; destination counter | 256 | move.d CODE_START, $r3 ; destination counter |
255 | movu.w CODE_LENGTH, $r4; length | 257 | movu.w CODE_LENGTH, $r4; length |
256 | 258 | ||
257 | wait_ser: | 259 | wait_ser: |
258 | addq 1, $r1 | 260 | addq 1, $r1 |
259 | #ifndef CONFIG_ETRAX_NO_LEDS | 261 | #ifndef CONFIG_ETRAX_NO_LEDS |
@@ -272,20 +274,20 @@ wait_ser: | |||
272 | nop | 274 | nop |
273 | 1: not $r0 ; clear bit | 275 | 1: not $r0 ; clear bit |
274 | and.d $r0, $r2 | 276 | and.d $r0, $r2 |
275 | 2: | 277 | 2: |
276 | #ifdef CONFIG_ETRAX_PA_LEDS | 278 | #ifdef CONFIG_ETRAX_PA_LEDS |
277 | move.b $r2, [R_PORT_PA_DATA] | 279 | move.b $r2, [R_PORT_PA_DATA] |
278 | #endif | 280 | #endif |
279 | #ifdef CONFIG_ETRAX_PB_LEDS | 281 | #ifdef CONFIG_ETRAX_PB_LEDS |
280 | move.b $r2, [R_PORT_PB_DATA] | 282 | move.b $r2, [R_PORT_PB_DATA] |
281 | #endif | 283 | #endif |
282 | #ifdef CONFIG_ETRAX_90000000_LEDS | 284 | #ifdef CONFIG_ETRAX_90000000_LEDS |
283 | move.b $r2, [0x90000000] | 285 | move.b $r2, [0x90000000] |
284 | #endif | 286 | #endif |
285 | #endif | 287 | #endif |
286 | 288 | ||
287 | ;; check if we got something on the serial port | 289 | ;; check if we got something on the serial port |
288 | 290 | ||
289 | move.b [SERSTAT], $r0 | 291 | move.b [SERSTAT], $r0 |
290 | btstq 0, $r0 ; data_avail | 292 | btstq 0, $r0 ; data_avail |
291 | bpl wait_ser | 293 | bpl wait_ser |
@@ -295,14 +297,15 @@ wait_ser: | |||
295 | 297 | ||
296 | move.b [SERRDAT], $r0 | 298 | move.b [SERRDAT], $r0 |
297 | move.b $r0, [$r3+] | 299 | move.b $r0, [$r3+] |
298 | 300 | ||
299 | subq 1, $r4 ; decrease length | 301 | subq 1, $r4 ; decrease length |
300 | bne wait_ser | 302 | bne wait_ser |
301 | nop | 303 | nop |
302 | 304 | ||
303 | ;; jump into downloaded code | 305 | ;; jump into downloaded code |
304 | 306 | ||
305 | move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is initialized | 307 | move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is |
308 | ; initialized | ||
306 | jump CODE_START | 309 | jump CODE_START |
307 | 310 | ||
308 | flash_ok: | 311 | flash_ok: |
@@ -313,7 +316,8 @@ flash_ok: | |||
313 | nop | 316 | nop |
314 | move.d PTABLE_START, $r7; otherwise use the ptable start | 317 | move.d PTABLE_START, $r7; otherwise use the ptable start |
315 | 1: | 318 | 1: |
316 | move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is initialized | 319 | move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is |
320 | ; initialized | ||
317 | jump $r7 ; boot! | 321 | jump $r7 ; boot! |
318 | 322 | ||
319 | 323 | ||
@@ -327,7 +331,8 @@ checksum: | |||
327 | moveq 0, $r0 | 331 | moveq 0, $r0 |
328 | moveq CONFIG_ETRAX_FLASH1_SIZE, $r6 | 332 | moveq CONFIG_ETRAX_FLASH1_SIZE, $r6 |
329 | 333 | ||
330 | ;; If the first physical flash memory is exceeded wrap to the second one. | 334 | ;; If the first physical flash memory is exceeded wrap to the |
335 | ;; second one | ||
331 | btstq 26, $r1 ; Are we addressing first flash? | 336 | btstq 26, $r1 ; Are we addressing first flash? |
332 | bpl 1f | 337 | bpl 1f |
333 | nop | 338 | nop |
@@ -351,3 +356,5 @@ checksum: | |||
351 | 3: move.d MEM_CSE1_START, $r1 ; wrap to second flash | 356 | 3: move.d MEM_CSE1_START, $r1 ; wrap to second flash |
352 | ba 2b | 357 | ba 2b |
353 | nop | 358 | nop |
359 | |||
360 | #endif | ||
diff --git a/arch/cris/arch-v10/boot/rescue/kimagerescue.S b/arch/cris/arch-v10/boot/rescue/kimagerescue.S index cbccd6316d39..55eeff8bb08e 100644 --- a/arch/cris/arch-v10/boot/rescue/kimagerescue.S +++ b/arch/cris/arch-v10/boot/rescue/kimagerescue.S | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: kimagerescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | 1 | /* |
2 | * | ||
3 | * Rescue code to be prepended on a kimage and copied to the | 2 | * Rescue code to be prepended on a kimage and copied to the |
4 | * rescue serial port. | 3 | * rescue serial port. |
5 | * This is called from the rescue code, it will copy received data to | 4 | * This is called from the rescue code, it will copy received data to |
@@ -7,13 +6,13 @@ | |||
7 | */ | 6 | */ |
8 | 7 | ||
9 | #define ASSEMBLER_MACROS_ONLY | 8 | #define ASSEMBLER_MACROS_ONLY |
10 | #include <asm/sv_addr_ag.h> | 9 | #include <asm/arch/sv_addr_ag.h> |
11 | 10 | ||
12 | #define CODE_START 0x40004000 | 11 | #define CODE_START 0x40004000 |
13 | #define CODE_LENGTH 784 | 12 | #define CODE_LENGTH 784 |
14 | #define TIMEOUT_VALUE 1000 | 13 | #define TIMEOUT_VALUE 1000 |
15 | 14 | ||
16 | 15 | ||
17 | #ifdef CONFIG_ETRAX_RESCUE_SER0 | 16 | #ifdef CONFIG_ETRAX_RESCUE_SER0 |
18 | #define SERXOFF R_SERIAL0_XOFF | 17 | #define SERXOFF R_SERIAL0_XOFF |
19 | #define SERBAUD R_SERIAL0_BAUD | 18 | #define SERBAUD R_SERIAL0_BAUD |
@@ -34,7 +33,7 @@ | |||
34 | #define SERRECC R_SERIAL2_REC_CTRL | 33 | #define SERRECC R_SERIAL2_REC_CTRL |
35 | #define SERRDAT R_SERIAL2_REC_DATA | 34 | #define SERRDAT R_SERIAL2_REC_DATA |
36 | #define SERSTAT R_SERIAL2_STATUS | 35 | #define SERSTAT R_SERIAL2_STATUS |
37 | #endif | 36 | #endif |
38 | #ifdef CONFIG_ETRAX_RESCUE_SER3 | 37 | #ifdef CONFIG_ETRAX_RESCUE_SER3 |
39 | #define SERXOFF R_SERIAL3_XOFF | 38 | #define SERXOFF R_SERIAL3_XOFF |
40 | #define SERBAUD R_SERIAL3_BAUD | 39 | #define SERBAUD R_SERIAL3_BAUD |
@@ -48,54 +47,55 @@ | |||
48 | ;; 0x80000000 if loaded in flash (as it should be) | 47 | ;; 0x80000000 if loaded in flash (as it should be) |
49 | ;; since etrax actually starts at address 2 when booting from flash, we | 48 | ;; since etrax actually starts at address 2 when booting from flash, we |
50 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di | 49 | ;; put a nop (2 bytes) here first so we dont accidentally skip the di |
51 | 50 | ||
52 | nop | 51 | nop |
53 | di | 52 | di |
54 | #ifndef CONFIG_SVINTO_SIM | 53 | #ifndef CONFIG_SVINTO_SIM |
55 | ;; setup port PA and PB default initial directions and data | 54 | ;; setup port PA and PB default initial directions and data |
56 | ;; (so we can flash LEDs, and so that DTR and others are set) | 55 | ;; (so we can flash LEDs, and so that DTR and others are set) |
57 | 56 | ||
58 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 | 57 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0 |
59 | move.b $r0, [R_PORT_PA_DIR] | 58 | move.b $r0, [R_PORT_PA_DIR] |
60 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 | 59 | move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0 |
61 | move.b $r0, [R_PORT_PA_DATA] | 60 | move.b $r0, [R_PORT_PA_DATA] |
62 | 61 | ||
63 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 | 62 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0 |
64 | move.b $r0, [R_PORT_PB_DIR] | 63 | move.b $r0, [R_PORT_PB_DIR] |
65 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 | 64 | move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0 |
66 | move.b $r0, [R_PORT_PB_DATA] | 65 | move.b $r0, [R_PORT_PB_DATA] |
67 | 66 | ||
68 | ;; We need to setup the bus registers before we start using the DRAM | 67 | ;; We need to setup the bus registers before we start using the DRAM |
69 | #include "../../lib/dram_init.S" | 68 | #include "../../lib/dram_init.S" |
70 | 69 | ||
71 | #endif | 70 | #endif |
72 | ;; Setup the stack to a suitably high address. | 71 | ;; Setup the stack to a suitably high address. |
73 | ;; We assume 8 MB is the minimum DRAM in an eLinux | 72 | ;; We assume 8 MB is the minimum DRAM in an eLinux |
74 | ;; product and put the sp at the top for now. | 73 | ;; product and put the sp at the top for now. |
75 | 74 | ||
76 | move.d 0x40800000, $sp | 75 | move.d 0x40800000, $sp |
77 | 76 | ||
78 | ;; setup the serial port at 115200 baud | 77 | ;; setup the serial port at 115200 baud |
79 | 78 | ||
80 | moveq 0, $r0 | 79 | moveq 0, $r0 |
81 | move.d $r0, [SERXOFF] | 80 | move.d $r0, [SERXOFF] |
82 | 81 | ||
83 | move.b 0x99, $r0 | 82 | move.b 0x99, $r0 |
84 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive | 83 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit |
84 | ; and receive | ||
85 | 85 | ||
86 | move.b 0x40, $r0 ; rec enable | 86 | move.b 0x40, $r0 ; rec enable |
87 | move.b $r0, [SERRECC] | 87 | move.b $r0, [SERRECC] |
88 | 88 | ||
89 | 89 | ||
90 | moveq 0, $r1 ; "timer" to clock out a LED red flash | 90 | moveq 0, $r1 ; "timer" to clock out a LED red flash |
91 | move.d CODE_START, $r3 ; destination counter | 91 | move.d CODE_START, $r3 ; destination counter |
92 | move.d CODE_LENGTH, $r4 ; length | 92 | move.d CODE_LENGTH, $r4 ; length |
93 | move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump | 93 | move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump |
94 | 94 | ||
95 | wait_ser: | 95 | wait_ser: |
96 | addq 1, $r1 | 96 | addq 1, $r1 |
97 | subq 1, $r5 ; decrease timeout | 97 | subq 1, $r5 ; decrease timeout |
98 | beq jump_start ; timed out | 98 | beq jump_start ; timed out |
99 | nop | 99 | nop |
100 | #ifndef CONFIG_ETRAX_NO_LEDS | 100 | #ifndef CONFIG_ETRAX_NO_LEDS |
101 | #ifdef CONFIG_ETRAX_PA_LEDS | 101 | #ifdef CONFIG_ETRAX_PA_LEDS |
@@ -111,21 +111,21 @@ wait_ser: | |||
111 | or.d $r0, $r2 ; set bit | 111 | or.d $r0, $r2 ; set bit |
112 | ba 2f | 112 | ba 2f |
113 | nop | 113 | nop |
114 | 1: not $r0 ; clear bit | 114 | 1: not $r0 ; clear bit |
115 | and.d $r0, $r2 | 115 | and.d $r0, $r2 |
116 | 2: | 116 | 2: |
117 | #ifdef CONFIG_ETRAX_PA_LEDS | 117 | #ifdef CONFIG_ETRAX_PA_LEDS |
118 | move.b $r2, [R_PORT_PA_DATA] | 118 | move.b $r2, [R_PORT_PA_DATA] |
119 | #endif | 119 | #endif |
120 | #ifdef CONFIG_ETRAX_PB_LEDS | 120 | #ifdef CONFIG_ETRAX_PB_LEDS |
121 | move.b $r2, [R_PORT_PB_DATA] | 121 | move.b $r2, [R_PORT_PB_DATA] |
122 | #endif | 122 | #endif |
123 | #endif | 123 | #endif |
124 | 124 | ||
125 | ;; check if we got something on the serial port | 125 | ;; check if we got something on the serial port |
126 | 126 | ||
127 | move.b [SERSTAT], $r0 | 127 | move.b [SERSTAT], $r0 |
128 | btstq 0, $r0 ; data_avail | 128 | btstq 0, $r0 ; data_avail |
129 | bpl wait_ser | 129 | bpl wait_ser |
130 | nop | 130 | nop |
131 | 131 | ||
@@ -134,7 +134,7 @@ wait_ser: | |||
134 | move.b [SERRDAT], $r0 | 134 | move.b [SERRDAT], $r0 |
135 | move.b $r0, [$r3+] | 135 | move.b $r0, [$r3+] |
136 | move.d TIMEOUT_VALUE, $r5 ; reset "timeout" | 136 | move.d TIMEOUT_VALUE, $r5 ; reset "timeout" |
137 | subq 1, $r4 ; decrease length | 137 | subq 1, $r4 ; decrease length |
138 | bne wait_ser | 138 | bne wait_ser |
139 | nop | 139 | nop |
140 | jump_start: | 140 | jump_start: |
diff --git a/arch/cris/arch-v10/boot/rescue/testrescue.S b/arch/cris/arch-v10/boot/rescue/testrescue.S index 566a9f341254..2d937f9afe23 100644 --- a/arch/cris/arch-v10/boot/rescue/testrescue.S +++ b/arch/cris/arch-v10/boot/rescue/testrescue.S | |||
@@ -1,13 +1,12 @@ | |||
1 | /* $Id: testrescue.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | 1 | /* |
2 | * | ||
3 | * Simple testcode to download by the rescue block. | 2 | * Simple testcode to download by the rescue block. |
4 | * Just lits some LEDs to show it was downloaded correctly. | 3 | * Just lights some LEDs to show it was downloaded correctly. |
5 | * | 4 | * |
6 | * Copyright (C) 1999 Axis Communications AB | 5 | * Copyright (C) 1999 Axis Communications AB |
7 | */ | 6 | */ |
8 | 7 | ||
9 | #define ASSEMBLER_MACROS_ONLY | 8 | #define ASSEMBLER_MACROS_ONLY |
10 | #include <asm/sv_addr_ag.h> | 9 | #include <asm/arch/sv_addr_ag.h> |
11 | 10 | ||
12 | .text | 11 | .text |
13 | 12 | ||
@@ -16,11 +15,10 @@ | |||
16 | moveq -1, $r2 | 15 | moveq -1, $r2 |
17 | move.b $r2, [R_PORT_PA_DIR] | 16 | move.b $r2, [R_PORT_PA_DIR] |
18 | moveq 0, $r2 | 17 | moveq 0, $r2 |
19 | move.b $r2, [R_PORT_PA_DATA] | 18 | move.b $r2, [R_PORT_PA_DATA] |
20 | 19 | ||
21 | endless: | 20 | endless: |
22 | nop | 21 | nop |
23 | ba endless | 22 | ba endless |
24 | nop | 23 | nop |
25 | 24 | ||
26 | |||
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 96740ef497d4..58f5864a6680 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig | |||
@@ -9,37 +9,6 @@ config ETRAX_ETHERNET | |||
9 | This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet | 9 | This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet |
10 | controller. | 10 | controller. |
11 | 11 | ||
12 | choice | ||
13 | prompt "Network LED behavior" | ||
14 | depends on ETRAX_ETHERNET | ||
15 | default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | ||
16 | |||
17 | config ETRAX_NETWORK_LED_ON_WHEN_LINK | ||
18 | bool "LED_on_when_link" | ||
19 | help | ||
20 | Selecting LED_on_when_link will light the LED when there is a | ||
21 | connection and will flash off when there is activity. | ||
22 | |||
23 | Selecting LED_on_when_activity will light the LED only when | ||
24 | there is activity. | ||
25 | |||
26 | This setting will also affect the behaviour of other activity LEDs | ||
27 | e.g. Bluetooth. | ||
28 | |||
29 | config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | ||
30 | bool "LED_on_when_activity" | ||
31 | help | ||
32 | Selecting LED_on_when_link will light the LED when there is a | ||
33 | connection and will flash off when there is activity. | ||
34 | |||
35 | Selecting LED_on_when_activity will light the LED only when | ||
36 | there is activity. | ||
37 | |||
38 | This setting will also affect the behaviour of other activity LEDs | ||
39 | e.g. Bluetooth. | ||
40 | |||
41 | endchoice | ||
42 | |||
43 | config ETRAX_SERIAL | 12 | config ETRAX_SERIAL |
44 | bool "Serial-port support" | 13 | bool "Serial-port support" |
45 | depends on ETRAX_ARCH_V10 | 14 | depends on ETRAX_ARCH_V10 |
@@ -84,32 +53,6 @@ config ETRAX_SERIAL_PORT0 | |||
84 | the same DMA channels. | 53 | the same DMA channels. |
85 | 54 | ||
86 | choice | 55 | choice |
87 | prompt "Ser0 DMA out assignment" | ||
88 | depends on ETRAX_SERIAL_PORT0 | ||
89 | default ETRAX_SERIAL_PORT0_DMA6_OUT | ||
90 | |||
91 | config ETRAX_SERIAL_PORT0_NO_DMA_OUT | ||
92 | bool "No DMA out" | ||
93 | |||
94 | config ETRAX_SERIAL_PORT0_DMA6_OUT | ||
95 | bool "DMA 6" | ||
96 | |||
97 | endchoice | ||
98 | |||
99 | choice | ||
100 | prompt "Ser0 DMA in assignment" | ||
101 | depends on ETRAX_SERIAL_PORT0 | ||
102 | default ETRAX_SERIAL_PORT0_DMA7_IN | ||
103 | |||
104 | config ETRAX_SERIAL_PORT0_NO_DMA_IN | ||
105 | bool "No DMA in" | ||
106 | |||
107 | config ETRAX_SERIAL_PORT0_DMA7_IN | ||
108 | bool "DMA 7" | ||
109 | |||
110 | endchoice | ||
111 | |||
112 | choice | ||
113 | prompt "Ser0 DTR, RI, DSR and CD assignment" | 56 | prompt "Ser0 DTR, RI, DSR and CD assignment" |
114 | depends on ETRAX_SERIAL_PORT0 | 57 | depends on ETRAX_SERIAL_PORT0 |
115 | default ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE | 58 | default ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE |
@@ -198,32 +141,6 @@ config ETRAX_SERIAL_PORT1 | |||
198 | Enables the ETRAX 100 serial driver for ser1 (ttyS1). | 141 | Enables the ETRAX 100 serial driver for ser1 (ttyS1). |
199 | 142 | ||
200 | choice | 143 | choice |
201 | prompt "Ser1 DMA out assignment" | ||
202 | depends on ETRAX_SERIAL_PORT1 | ||
203 | default ETRAX_SERIAL_PORT1_DMA8_OUT | ||
204 | |||
205 | config ETRAX_SERIAL_PORT1_NO_DMA_OUT | ||
206 | bool "No DMA out" | ||
207 | |||
208 | config ETRAX_SERIAL_PORT1_DMA8_OUT | ||
209 | bool "DMA 8" | ||
210 | |||
211 | endchoice | ||
212 | |||
213 | choice | ||
214 | prompt "Ser1 DMA in assignment" | ||
215 | depends on ETRAX_SERIAL_PORT1 | ||
216 | default ETRAX_SERIAL_PORT1_DMA9_IN | ||
217 | |||
218 | config ETRAX_SERIAL_PORT1_NO_DMA_IN | ||
219 | bool "No DMA in" | ||
220 | |||
221 | config ETRAX_SERIAL_PORT1_DMA9_IN | ||
222 | bool "DMA 9" | ||
223 | |||
224 | endchoice | ||
225 | |||
226 | choice | ||
227 | prompt "Ser1 DTR, RI, DSR and CD assignment" | 144 | prompt "Ser1 DTR, RI, DSR and CD assignment" |
228 | depends on ETRAX_SERIAL_PORT1 | 145 | depends on ETRAX_SERIAL_PORT1 |
229 | default ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE | 146 | default ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE |
@@ -315,32 +232,6 @@ config ETRAX_SERIAL_PORT2 | |||
315 | Enables the ETRAX 100 serial driver for ser2 (ttyS2). | 232 | Enables the ETRAX 100 serial driver for ser2 (ttyS2). |
316 | 233 | ||
317 | choice | 234 | choice |
318 | prompt "Ser2 DMA out assignment" | ||
319 | depends on ETRAX_SERIAL_PORT2 | ||
320 | default ETRAX_SERIAL_PORT2_DMA2_OUT | ||
321 | |||
322 | config ETRAX_SERIAL_PORT2_NO_DMA_OUT | ||
323 | bool "No DMA out" | ||
324 | |||
325 | config ETRAX_SERIAL_PORT2_DMA2_OUT | ||
326 | bool "DMA 2" | ||
327 | |||
328 | endchoice | ||
329 | |||
330 | choice | ||
331 | prompt "Ser2 DMA in assignment" | ||
332 | depends on ETRAX_SERIAL_PORT2 | ||
333 | default ETRAX_SERIAL_PORT2_DMA3_IN | ||
334 | |||
335 | config ETRAX_SERIAL_PORT2_NO_DMA_IN | ||
336 | bool "No DMA in" | ||
337 | |||
338 | config ETRAX_SERIAL_PORT2_DMA3_IN | ||
339 | bool "DMA 3" | ||
340 | |||
341 | endchoice | ||
342 | |||
343 | choice | ||
344 | prompt "Ser2 DTR, RI, DSR and CD assignment" | 235 | prompt "Ser2 DTR, RI, DSR and CD assignment" |
345 | depends on ETRAX_SERIAL_PORT2 | 236 | depends on ETRAX_SERIAL_PORT2 |
346 | default ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE | 237 | default ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE |
@@ -429,32 +320,6 @@ config ETRAX_SERIAL_PORT3 | |||
429 | Enables the ETRAX 100 serial driver for ser3 (ttyS3). | 320 | Enables the ETRAX 100 serial driver for ser3 (ttyS3). |
430 | 321 | ||
431 | choice | 322 | choice |
432 | prompt "Ser3 DMA out assignment" | ||
433 | depends on ETRAX_SERIAL_PORT3 | ||
434 | default ETRAX_SERIAL_PORT3_DMA4_OUT | ||
435 | |||
436 | config ETRAX_SERIAL_PORT3_NO_DMA_OUT | ||
437 | bool "No DMA out" | ||
438 | |||
439 | config ETRAX_SERIAL_PORT3_DMA4_OUT | ||
440 | bool "DMA 4" | ||
441 | |||
442 | endchoice | ||
443 | |||
444 | choice | ||
445 | prompt "Ser3 DMA in assignment" | ||
446 | depends on ETRAX_SERIAL_PORT3 | ||
447 | default ETRAX_SERIAL_PORT3_DMA5_IN | ||
448 | |||
449 | config ETRAX_SERIAL_PORT3_NO_DMA_IN | ||
450 | bool "No DMA in" | ||
451 | |||
452 | config ETRAX_SERIAL_PORT3_DMA5_IN | ||
453 | bool "DMA 5" | ||
454 | |||
455 | endchoice | ||
456 | |||
457 | choice | ||
458 | prompt "Ser3 DTR, RI, DSR and CD assignment" | 323 | prompt "Ser3 DTR, RI, DSR and CD assignment" |
459 | depends on ETRAX_SERIAL_PORT3 | 324 | depends on ETRAX_SERIAL_PORT3 |
460 | default ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE | 325 | default ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE |
@@ -563,21 +428,6 @@ config ETRAX_USB_HOST_PORT2 | |||
563 | depends on ETRAX_USB_HOST | 428 | depends on ETRAX_USB_HOST |
564 | default n | 429 | default n |
565 | 430 | ||
566 | config ETRAX_AXISFLASHMAP | ||
567 | bool "Axis flash-map support" | ||
568 | depends on ETRAX_ARCH_V10 | ||
569 | select MTD | ||
570 | select MTD_CFI | ||
571 | select MTD_CFI_AMDSTD | ||
572 | select MTD_CHAR | ||
573 | select MTD_BLOCK | ||
574 | select MTD_PARTITIONS | ||
575 | select MTD_CONCAT | ||
576 | select MTD_COMPLEX_MAPPINGS | ||
577 | help | ||
578 | This option enables MTD mapping of flash devices. Needed to use | ||
579 | flash memories. If unsure, say Y. | ||
580 | |||
581 | config ETRAX_PTABLE_SECTOR | 431 | config ETRAX_PTABLE_SECTOR |
582 | int "Byte-offset of partition table sector" | 432 | int "Byte-offset of partition table sector" |
583 | depends on ETRAX_AXISFLASHMAP | 433 | depends on ETRAX_AXISFLASHMAP |
@@ -731,37 +581,6 @@ config ETRAX_PB_CHANGEABLE_BITS | |||
731 | Bit set = changeable. | 581 | Bit set = changeable. |
732 | You probably want 00 here. | 582 | You probably want 00 here. |
733 | 583 | ||
734 | config ETRAX_RTC | ||
735 | bool "Real Time Clock support" | ||
736 | depends on ETRAX_ARCH_V10 | ||
737 | help | ||
738 | Enables drivers for the Real-Time Clock battery-backed chips on | ||
739 | some products. The kernel reads the time when booting, and | ||
740 | the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a | ||
741 | rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc | ||
742 | device, major 121. You can check the time with cat /proc/rtc, but | ||
743 | normal time reading should be done using libc function time and | ||
744 | friends. | ||
745 | |||
746 | choice | ||
747 | prompt "RTC chip" | ||
748 | depends on ETRAX_RTC | ||
749 | default ETRAX_DS1302 | ||
750 | |||
751 | config ETRAX_DS1302 | ||
752 | bool "DS1302" | ||
753 | help | ||
754 | Enables the driver for the DS1302 Real-Time Clock battery-backed | ||
755 | chip on some products. | ||
756 | |||
757 | config ETRAX_PCF8563 | ||
758 | bool "PCF8563" | ||
759 | help | ||
760 | Enables the driver for the PCF8563 Real-Time Clock battery-backed | ||
761 | chip on some products. | ||
762 | |||
763 | endchoice | ||
764 | |||
765 | config ETRAX_DS1302_RST_ON_GENERIC_PORT | 584 | config ETRAX_DS1302_RST_ON_GENERIC_PORT |
766 | bool "DS1302 RST on Generic Port" | 585 | bool "DS1302 RST on Generic Port" |
767 | depends on ETRAX_DS1302 | 586 | depends on ETRAX_DS1302 |
diff --git a/arch/cris/arch-v10/drivers/Makefile b/arch/cris/arch-v10/drivers/Makefile index 20258e36f384..44bf2e88c26e 100644 --- a/arch/cris/arch-v10/drivers/Makefile +++ b/arch/cris/arch-v10/drivers/Makefile | |||
@@ -2,11 +2,11 @@ | |||
2 | # Makefile for Etrax-specific drivers | 2 | # Makefile for Etrax-specific drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o | 5 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o |
6 | obj-$(CONFIG_ETRAX_I2C) += i2c.o | 6 | obj-$(CONFIG_ETRAX_I2C) += i2c.o |
7 | obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o | 7 | obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o |
8 | obj-$(CONFIG_ETRAX_GPIO) += gpio.o | 8 | obj-$(CONFIG_ETRAX_GPIO) += gpio.o |
9 | obj-$(CONFIG_ETRAX_DS1302) += ds1302.o | 9 | obj-$(CONFIG_ETRAX_DS1302) += ds1302.o |
10 | obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o | 10 | obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o |
11 | 11 | obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o | |
12 | 12 | ||
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c index ea3cf2e39a14..b3bdda93ffef 100644 --- a/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/arch/cris/arch-v10/drivers/axisflashmap.c | |||
@@ -10,129 +10,6 @@ | |||
10 | * tells us what other partitions to define. If there isn't, we use a default | 10 | * tells us what other partitions to define. If there isn't, we use a default |
11 | * partition split defined below. | 11 | * partition split defined below. |
12 | * | 12 | * |
13 | * $Log: axisflashmap.c,v $ | ||
14 | * Revision 1.11 2004/11/15 10:27:14 starvik | ||
15 | * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>). | ||
16 | * | ||
17 | * Revision 1.10 2004/08/16 12:37:22 starvik | ||
18 | * Merge of Linux 2.6.8 | ||
19 | * | ||
20 | * Revision 1.8 2004/05/14 07:58:03 starvik | ||
21 | * Merge of changes from 2.4 | ||
22 | * | ||
23 | * Revision 1.6 2003/07/04 08:27:37 starvik | ||
24 | * Merge of Linux 2.5.74 | ||
25 | * | ||
26 | * Revision 1.5 2002/12/11 13:13:57 starvik | ||
27 | * Added arch/ to v10 specific includes | ||
28 | * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
29 | * | ||
30 | * Revision 1.4 2002/11/20 11:56:10 starvik | ||
31 | * Merge of Linux 2.5.48 | ||
32 | * | ||
33 | * Revision 1.3 2002/11/13 14:54:13 starvik | ||
34 | * Copied from linux 2.4 | ||
35 | * | ||
36 | * Revision 1.28 2002/10/01 08:08:43 jonashg | ||
37 | * The first partition ends at the start of the partition table. | ||
38 | * | ||
39 | * Revision 1.27 2002/08/21 09:23:13 jonashg | ||
40 | * Speling. | ||
41 | * | ||
42 | * Revision 1.26 2002/08/21 08:35:20 jonashg | ||
43 | * Cosmetic change to printouts. | ||
44 | * | ||
45 | * Revision 1.25 2002/08/21 08:15:42 jonashg | ||
46 | * Made it compile even without CONFIG_MTD_CONCAT defined. | ||
47 | * | ||
48 | * Revision 1.24 2002/08/20 13:12:35 jonashg | ||
49 | * * New approach to probing. Probe cse0 and cse1 separately and (mtd)concat | ||
50 | * the results. | ||
51 | * * Removed compile time tests concerning how the mtdram driver has been | ||
52 | * configured. The user will know about the misconfiguration at runtime | ||
53 | * instead. (The old approach made it impossible to use mtdram for anything | ||
54 | * else than RAM boot). | ||
55 | * | ||
56 | * Revision 1.23 2002/05/13 12:12:28 johana | ||
57 | * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and | ||
58 | * be informative at runtime. | ||
59 | * | ||
60 | * Revision 1.22 2002/05/13 10:24:44 johana | ||
61 | * Added #if checks on MTDRAM CONFIG | ||
62 | * | ||
63 | * Revision 1.21 2002/05/06 16:05:20 johana | ||
64 | * Removed debug printout. | ||
65 | * | ||
66 | * Revision 1.20 2002/05/06 16:03:00 johana | ||
67 | * No more cramfs as root hack in generic code. | ||
68 | * It's handled by axisflashmap using mtdram. | ||
69 | * | ||
70 | * Revision 1.19 2002/03/15 17:10:28 bjornw | ||
71 | * Changed comment about cached access since we changed this before | ||
72 | * | ||
73 | * Revision 1.18 2002/03/05 17:06:15 jonashg | ||
74 | * Try amd_flash probe before cfi_probe since amd_flash driver can handle two | ||
75 | * (or more) flash chips of different model and the cfi driver cannot. | ||
76 | * | ||
77 | * Revision 1.17 2001/11/12 19:42:38 pkj | ||
78 | * Fixed compiler warnings. | ||
79 | * | ||
80 | * Revision 1.16 2001/11/08 11:18:58 jonashg | ||
81 | * Always read from uncached address to avoid problems with flushing | ||
82 | * cachelines after write and MTD-erase. No performance loss have been | ||
83 | * seen yet. | ||
84 | * | ||
85 | * Revision 1.15 2001/10/19 12:41:04 jonashg | ||
86 | * Name of probe has changed in MTD. | ||
87 | * | ||
88 | * Revision 1.14 2001/09/21 07:14:10 jonashg | ||
89 | * Made root filesystem (cramfs) use mtdblock driver when booting from flash. | ||
90 | * | ||
91 | * Revision 1.13 2001/08/15 13:57:35 jonashg | ||
92 | * Entire MTD updated to the linux 2.4.7 version. | ||
93 | * | ||
94 | * Revision 1.12 2001/06/11 09:50:30 jonashg | ||
95 | * Oops, 2MB is 0x200000 bytes. | ||
96 | * | ||
97 | * Revision 1.11 2001/06/08 11:39:44 jonashg | ||
98 | * Changed sizes and offsets in axis_default_partitions to use | ||
99 | * CONFIG_ETRAX_PTABLE_SECTOR. | ||
100 | * | ||
101 | * Revision 1.10 2001/05/29 09:42:03 jonashg | ||
102 | * Use macro for end marker length instead of sizeof. | ||
103 | * | ||
104 | * Revision 1.9 2001/05/29 08:52:52 jonashg | ||
105 | * Gave names to the magic fours (size of the ptable end marker). | ||
106 | * | ||
107 | * Revision 1.8 2001/05/28 15:36:20 jonashg | ||
108 | * * Removed old comment about ptable location in flash (it's a CONFIG_ option). | ||
109 | * * Variable ptable was initialized twice to the same value. | ||
110 | * | ||
111 | * Revision 1.7 2001/04/05 13:41:46 markusl | ||
112 | * Updated according to review remarks | ||
113 | * | ||
114 | * Revision 1.6 2001/03/07 09:21:21 bjornw | ||
115 | * No need to waste .data | ||
116 | * | ||
117 | * Revision 1.5 2001/03/06 16:27:01 jonashg | ||
118 | * Probe the entire flash area for flash devices. | ||
119 | * | ||
120 | * Revision 1.4 2001/02/23 12:47:15 bjornw | ||
121 | * Uncached flash in LOW_MAP moved from 0xe to 0x8 | ||
122 | * | ||
123 | * Revision 1.3 2001/02/16 12:11:45 jonashg | ||
124 | * MTD driver amd_flash is now included in MTD CVS repository. | ||
125 | * (It's now in drivers/mtd). | ||
126 | * | ||
127 | * Revision 1.2 2001/02/09 11:12:22 jonashg | ||
128 | * Support for AMD compatible non-CFI flash chips. | ||
129 | * Only tested with Toshiba TC58FVT160 so far. | ||
130 | * | ||
131 | * Revision 1.1 2001/01/12 17:01:18 bjornw | ||
132 | * * Added axisflashmap.c, a physical mapping for MTD that reads and understands | ||
133 | * Axis partition-table format. | ||
134 | * | ||
135 | * | ||
136 | */ | 13 | */ |
137 | 14 | ||
138 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -235,7 +112,7 @@ static struct map_info map_cse1 = { | |||
235 | }; | 112 | }; |
236 | 113 | ||
237 | /* If no partition-table was found, we use this default-set. */ | 114 | /* If no partition-table was found, we use this default-set. */ |
238 | #define MAX_PARTITIONS 7 | 115 | #define MAX_PARTITIONS 7 |
239 | #define NUM_DEFAULT_PARTITIONS 3 | 116 | #define NUM_DEFAULT_PARTITIONS 3 |
240 | 117 | ||
241 | /* | 118 | /* |
@@ -300,6 +177,15 @@ static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { | |||
300 | }, | 177 | }, |
301 | }; | 178 | }; |
302 | 179 | ||
180 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE | ||
181 | /* Main flash device */ | ||
182 | static struct mtd_partition main_partition = { | ||
183 | .name = "main", | ||
184 | .size = 0, | ||
185 | .offset = 0 | ||
186 | }; | ||
187 | #endif | ||
188 | |||
303 | /* | 189 | /* |
304 | * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash | 190 | * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash |
305 | * chips in that order (because the amd_flash-driver is faster). | 191 | * chips in that order (because the amd_flash-driver is faster). |
@@ -316,15 +202,14 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) | |||
316 | mtd_cs = do_map_probe("cfi_probe", map_cs); | 202 | mtd_cs = do_map_probe("cfi_probe", map_cs); |
317 | #endif | 203 | #endif |
318 | #ifdef CONFIG_MTD_JEDECPROBE | 204 | #ifdef CONFIG_MTD_JEDECPROBE |
319 | if (!mtd_cs) { | 205 | if (!mtd_cs) |
320 | mtd_cs = do_map_probe("jedec_probe", map_cs); | 206 | mtd_cs = do_map_probe("jedec_probe", map_cs); |
321 | } | ||
322 | #endif | 207 | #endif |
323 | 208 | ||
324 | return mtd_cs; | 209 | return mtd_cs; |
325 | } | 210 | } |
326 | 211 | ||
327 | /* | 212 | /* |
328 | * Probe each chip select individually for flash chips. If there are chips on | 213 | * Probe each chip select individually for flash chips. If there are chips on |
329 | * both cse0 and cse1, the mtd_info structs will be concatenated to one struct | 214 | * both cse0 and cse1, the mtd_info structs will be concatenated to one struct |
330 | * so that MTD partitions can cross chip boundries. | 215 | * so that MTD partitions can cross chip boundries. |
@@ -351,7 +236,7 @@ static struct mtd_info *flash_probe(void) | |||
351 | if (mtd_cse0 && mtd_cse1) { | 236 | if (mtd_cse0 && mtd_cse1) { |
352 | #ifdef CONFIG_MTD_CONCAT | 237 | #ifdef CONFIG_MTD_CONCAT |
353 | struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; | 238 | struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; |
354 | 239 | ||
355 | /* Since the concatenation layer adds a small overhead we | 240 | /* Since the concatenation layer adds a small overhead we |
356 | * could try to figure out if the chips in cse0 and cse1 are | 241 | * could try to figure out if the chips in cse0 and cse1 are |
357 | * identical and reprobe the whole cse0+cse1 window. But since | 242 | * identical and reprobe the whole cse0+cse1 window. But since |
@@ -372,7 +257,7 @@ static struct mtd_info *flash_probe(void) | |||
372 | 257 | ||
373 | /* The best we can do now is to only use what we found | 258 | /* The best we can do now is to only use what we found |
374 | * at cse0. | 259 | * at cse0. |
375 | */ | 260 | */ |
376 | mtd_cse = mtd_cse0; | 261 | mtd_cse = mtd_cse0; |
377 | map_destroy(mtd_cse1); | 262 | map_destroy(mtd_cse1); |
378 | } | 263 | } |
@@ -395,7 +280,7 @@ static int __init init_axis_flash(void) | |||
395 | struct partitiontable_head *ptable_head = NULL; | 280 | struct partitiontable_head *ptable_head = NULL; |
396 | struct partitiontable_entry *ptable; | 281 | struct partitiontable_entry *ptable; |
397 | int use_default_ptable = 1; /* Until proven otherwise. */ | 282 | int use_default_ptable = 1; /* Until proven otherwise. */ |
398 | const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n"; | 283 | const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n"; |
399 | 284 | ||
400 | if (!(mymtd = flash_probe())) { | 285 | if (!(mymtd = flash_probe())) { |
401 | /* There's no reason to use this module if no flash chip can | 286 | /* There's no reason to use this module if no flash chip can |
@@ -435,7 +320,7 @@ static int __init init_axis_flash(void) | |||
435 | unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; | 320 | unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR; |
436 | unsigned char *p; | 321 | unsigned char *p; |
437 | unsigned long csum = 0; | 322 | unsigned long csum = 0; |
438 | 323 | ||
439 | ptable = (struct partitiontable_entry *) | 324 | ptable = (struct partitiontable_entry *) |
440 | ((unsigned long)ptable_head + sizeof(*ptable_head)); | 325 | ((unsigned long)ptable_head + sizeof(*ptable_head)); |
441 | 326 | ||
@@ -490,6 +375,16 @@ static int __init init_axis_flash(void) | |||
490 | pidx++; | 375 | pidx++; |
491 | } | 376 | } |
492 | 377 | ||
378 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE | ||
379 | if (mymtd) { | ||
380 | main_partition.size = mymtd->size; | ||
381 | err = add_mtd_partitions(mymtd, &main_partition, 1); | ||
382 | if (err) | ||
383 | panic("axisflashmap: Could not initialize " | ||
384 | "partition for whole main mtd device!\n"); | ||
385 | } | ||
386 | #endif | ||
387 | |||
493 | if (mymtd) { | 388 | if (mymtd) { |
494 | if (use_default_ptable) { | 389 | if (use_default_ptable) { |
495 | printk(KERN_INFO " Using default partition table.\n"); | 390 | printk(KERN_INFO " Using default partition table.\n"); |
@@ -499,9 +394,8 @@ static int __init init_axis_flash(void) | |||
499 | err = add_mtd_partitions(mymtd, axis_partitions, pidx); | 394 | err = add_mtd_partitions(mymtd, axis_partitions, pidx); |
500 | } | 395 | } |
501 | 396 | ||
502 | if (err) { | 397 | if (err) |
503 | panic("axisflashmap could not add MTD partitions!\n"); | 398 | panic("axisflashmap could not add MTD partitions!\n"); |
504 | } | ||
505 | } | 399 | } |
506 | 400 | ||
507 | if (!romfs_in_flash) { | 401 | if (!romfs_in_flash) { |
@@ -515,25 +409,24 @@ static int __init init_axis_flash(void) | |||
515 | #else | 409 | #else |
516 | struct mtd_info *mtd_ram; | 410 | struct mtd_info *mtd_ram; |
517 | 411 | ||
518 | mtd_ram = kmalloc(sizeof(struct mtd_info), | 412 | mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); |
519 | GFP_KERNEL); | 413 | if (!mtd_ram) |
520 | if (!mtd_ram) { | ||
521 | panic("axisflashmap couldn't allocate memory for " | 414 | panic("axisflashmap couldn't allocate memory for " |
522 | "mtd_info!\n"); | 415 | "mtd_info!\n"); |
523 | } | ||
524 | 416 | ||
525 | printk(KERN_INFO " Adding RAM partition for romfs image:\n"); | 417 | printk(KERN_INFO " Adding RAM partition for romfs image:\n"); |
526 | printk(pmsg, pidx, romfs_start, romfs_length); | 418 | printk(pmsg, pidx, (unsigned)romfs_start, |
527 | 419 | (unsigned)romfs_length); | |
528 | err = mtdram_init_device(mtd_ram, (void*)romfs_start, | 420 | |
529 | romfs_length, "romfs"); | 421 | err = mtdram_init_device(mtd_ram, |
530 | if (err) { | 422 | (void *)romfs_start, |
423 | romfs_length, | ||
424 | "romfs"); | ||
425 | if (err) | ||
531 | panic("axisflashmap could not initialize MTD RAM " | 426 | panic("axisflashmap could not initialize MTD RAM " |
532 | "device!\n"); | 427 | "device!\n"); |
533 | } | ||
534 | #endif | 428 | #endif |
535 | } | 429 | } |
536 | |||
537 | return err; | 430 | return err; |
538 | } | 431 | } |
539 | 432 | ||
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c index 1d1936a18133..c9aa3904be05 100644 --- a/arch/cris/arch-v10/drivers/ds1302.c +++ b/arch/cris/arch-v10/drivers/ds1302.c | |||
@@ -333,7 +333,7 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
333 | ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); | 333 | ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); |
334 | return 0; | 334 | return 0; |
335 | } | 335 | } |
336 | case RTC_VLOW_RD: | 336 | case RTC_VL_READ: |
337 | { | 337 | { |
338 | /* TODO: | 338 | /* TODO: |
339 | * Implement voltage low detection support | 339 | * Implement voltage low detection support |
@@ -342,7 +342,7 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
342 | " is not supported\n"); | 342 | " is not supported\n"); |
343 | return 0; | 343 | return 0; |
344 | } | 344 | } |
345 | case RTC_VLOW_SET: | 345 | case RTC_VL_CLR: |
346 | { | 346 | { |
347 | /* TODO: | 347 | /* TODO: |
348 | * Nothing to do since Voltage Low detection is not supported | 348 | * Nothing to do since Voltage Low detection is not supported |
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index be35a70798aa..f1cac9dc75b8 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c | |||
@@ -19,77 +19,6 @@ | |||
19 | *! Sep 03 1999 Edgar Iglesias Added bail-out stuff if we get interrupted | 19 | *! Sep 03 1999 Edgar Iglesias Added bail-out stuff if we get interrupted |
20 | *! in the spin-lock. | 20 | *! in the spin-lock. |
21 | *! | 21 | *! |
22 | *! $Log: eeprom.c,v $ | ||
23 | *! Revision 1.12 2005/06/19 17:06:46 starvik | ||
24 | *! Merge of Linux 2.6.12. | ||
25 | *! | ||
26 | *! Revision 1.11 2005/01/26 07:14:46 starvik | ||
27 | *! Applied diff from kernel janitors (Nish Aravamudan). | ||
28 | *! | ||
29 | *! Revision 1.10 2003/09/11 07:29:48 starvik | ||
30 | *! Merge of Linux 2.6.0-test5 | ||
31 | *! | ||
32 | *! Revision 1.9 2003/07/04 08:27:37 starvik | ||
33 | *! Merge of Linux 2.5.74 | ||
34 | *! | ||
35 | *! Revision 1.8 2003/04/09 05:20:47 starvik | ||
36 | *! Merge of Linux 2.5.67 | ||
37 | *! | ||
38 | *! Revision 1.6 2003/02/10 07:19:28 starvik | ||
39 | *! Removed misplaced ; | ||
40 | *! | ||
41 | *! Revision 1.5 2002/12/11 13:13:57 starvik | ||
42 | *! Added arch/ to v10 specific includes | ||
43 | *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
44 | *! | ||
45 | *! Revision 1.4 2002/11/20 11:56:10 starvik | ||
46 | *! Merge of Linux 2.5.48 | ||
47 | *! | ||
48 | *! Revision 1.3 2002/11/18 13:16:06 starvik | ||
49 | *! Linux 2.5 port of latest 2.4 drivers | ||
50 | *! | ||
51 | *! Revision 1.8 2001/06/15 13:24:29 jonashg | ||
52 | *! * Added verification of pointers from userspace in read and write. | ||
53 | *! * Made busy counter volatile. | ||
54 | *! * Added define for initial write delay. | ||
55 | *! * Removed warnings by using loff_t instead of unsigned long. | ||
56 | *! | ||
57 | *! Revision 1.7 2001/06/14 15:26:54 jonashg | ||
58 | *! Removed test because condition is always true. | ||
59 | *! | ||
60 | *! Revision 1.6 2001/06/14 15:18:20 jonashg | ||
61 | *! Kb -> kB (makes quite a difference if you don't know if you have 2k or 16k). | ||
62 | *! | ||
63 | *! Revision 1.5 2001/06/14 14:39:51 jonashg | ||
64 | *! Forgot to use name when registering the driver. | ||
65 | *! | ||
66 | *! Revision 1.4 2001/06/14 14:35:47 jonashg | ||
67 | *! * Gave driver a name and used it in printk's. | ||
68 | *! * Cleanup. | ||
69 | *! | ||
70 | *! Revision 1.3 2001/03/19 16:04:46 markusl | ||
71 | *! Fixed init of fops struct | ||
72 | *! | ||
73 | *! Revision 1.2 2001/03/19 10:35:07 markusl | ||
74 | *! 2.4 port of eeprom driver | ||
75 | *! | ||
76 | *! Revision 1.8 2000/05/18 10:42:25 edgar | ||
77 | *! Make sure to end write cycle on _every_ write | ||
78 | *! | ||
79 | *! Revision 1.7 2000/01/17 17:41:01 johana | ||
80 | *! Adjusted probing and return -ENOSPC when writing outside EEPROM | ||
81 | *! | ||
82 | *! Revision 1.6 2000/01/17 15:50:36 johana | ||
83 | *! Added adaptive timing adjustments and fixed autoprobing for 2k and 16k(?) | ||
84 | *! EEPROMs | ||
85 | *! | ||
86 | *! Revision 1.5 1999/09/03 15:07:37 edgar | ||
87 | *! Added bail-out check to the spinlock | ||
88 | *! | ||
89 | *! Revision 1.4 1999/09/03 12:11:17 bjornw | ||
90 | *! Proper atomicity (need to use spinlocks, not if's). users -> busy. | ||
91 | *! | ||
92 | *! | ||
93 | *! (c) 1999 Axis Communications AB, Lund, Sweden | 22 | *! (c) 1999 Axis Communications AB, Lund, Sweden |
94 | *!*****************************************************************************/ | 23 | *!*****************************************************************************/ |
95 | 24 | ||
@@ -103,10 +32,10 @@ | |||
103 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
104 | #include "i2c.h" | 33 | #include "i2c.h" |
105 | 34 | ||
106 | #define D(x) | 35 | #define D(x) |
107 | 36 | ||
108 | /* If we should use adaptive timing or not: */ | 37 | /* If we should use adaptive timing or not: */ |
109 | //#define EEPROM_ADAPTIVE_TIMING | 38 | /* #define EEPROM_ADAPTIVE_TIMING */ |
110 | 39 | ||
111 | #define EEPROM_MAJOR_NR 122 /* use a LOCAL/EXPERIMENTAL major for now */ | 40 | #define EEPROM_MAJOR_NR 122 /* use a LOCAL/EXPERIMENTAL major for now */ |
112 | #define EEPROM_MINOR_NR 0 | 41 | #define EEPROM_MINOR_NR 0 |
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index 0d347a705835..68a998bd1069 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c | |||
@@ -1,138 +1,11 @@ | |||
1 | /* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * Etrax general port I/O device | 2 | * Etrax general port I/O device |
4 | * | 3 | * |
5 | * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB | 4 | * Copyright (c) 1999-2007 Axis Communications AB |
6 | * | 5 | * |
7 | * Authors: Bjorn Wesen (initial version) | 6 | * Authors: Bjorn Wesen (initial version) |
8 | * Ola Knutsson (LED handling) | 7 | * Ola Knutsson (LED handling) |
9 | * Johan Adolfsson (read/set directions, write, port G) | 8 | * Johan Adolfsson (read/set directions, write, port G) |
10 | * | ||
11 | * $Log: gpio.c,v $ | ||
12 | * Revision 1.17 2005/06/19 17:06:46 starvik | ||
13 | * Merge of Linux 2.6.12. | ||
14 | * | ||
15 | * Revision 1.16 2005/03/07 13:02:29 starvik | ||
16 | * Protect driver global states with spinlock | ||
17 | * | ||
18 | * Revision 1.15 2005/01/05 06:08:55 starvik | ||
19 | * No need to do local_irq_disable after local_irq_save. | ||
20 | * | ||
21 | * Revision 1.14 2004/12/13 12:21:52 starvik | ||
22 | * Added I/O and DMA allocators from Linux 2.4 | ||
23 | * | ||
24 | * Revision 1.12 2004/08/24 07:19:59 starvik | ||
25 | * Whitespace cleanup | ||
26 | * | ||
27 | * Revision 1.11 2004/05/14 07:58:03 starvik | ||
28 | * Merge of changes from 2.4 | ||
29 | * | ||
30 | * Revision 1.9 2003/09/11 07:29:48 starvik | ||
31 | * Merge of Linux 2.6.0-test5 | ||
32 | * | ||
33 | * Revision 1.8 2003/07/04 08:27:37 starvik | ||
34 | * Merge of Linux 2.5.74 | ||
35 | * | ||
36 | * Revision 1.7 2003/01/10 07:44:07 starvik | ||
37 | * init_ioremap is now called by kernel before drivers are initialized | ||
38 | * | ||
39 | * Revision 1.6 2002/12/11 13:13:57 starvik | ||
40 | * Added arch/ to v10 specific includes | ||
41 | * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
42 | * | ||
43 | * Revision 1.5 2002/11/20 11:56:11 starvik | ||
44 | * Merge of Linux 2.5.48 | ||
45 | * | ||
46 | * Revision 1.4 2002/11/18 10:10:05 starvik | ||
47 | * Linux 2.5 port of latest gpio.c from Linux 2.4 | ||
48 | * | ||
49 | * Revision 1.20 2002/10/16 21:16:24 johana | ||
50 | * Added support for PA high level interrupt. | ||
51 | * That gives 2ms response time with iodtest for high levels and 2-12 ms | ||
52 | * response time on low levels if the check is not made in | ||
53 | * process.c:cpu_idle() as well. | ||
54 | * | ||
55 | * Revision 1.19 2002/10/14 18:27:33 johana | ||
56 | * Implemented alarm handling so select() now works. | ||
57 | * Latency is around 6-9 ms with a etrax_gpio_wake_up_check() in | ||
58 | * cpu_idle(). | ||
59 | * Otherwise I get 15-18 ms (same as doing the poll in userspace - | ||
60 | * but less overhead). | ||
61 | * TODO? Perhaps we should add the check in IMMEDIATE_BH (or whatever it | ||
62 | * is in 2.4) as well? | ||
63 | * TODO? Perhaps call request_irq()/free_irq() only when needed? | ||
64 | * Increased version to 2.5 | ||
65 | * | ||
66 | * Revision 1.18 2002/10/11 15:02:00 johana | ||
67 | * Mask inverted 8 bit value in setget_input(). | ||
68 | * | ||
69 | * Revision 1.17 2002/06/17 15:53:01 johana | ||
70 | * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT | ||
71 | * that take a pointer as argument and thus can handle 32 bit ports (G) | ||
72 | * correctly. | ||
73 | * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT. | ||
74 | * (especially if Port G bit 31 is used) | ||
75 | * | ||
76 | * Revision 1.16 2002/06/17 09:59:51 johana | ||
77 | * Returning 32 bit values in the ioctl return value doesn't work if bit | ||
78 | * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF. | ||
79 | * A new set of ioctl's will be added. | ||
80 | * | ||
81 | * Revision 1.15 2002/05/06 13:19:13 johana | ||
82 | * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well. | ||
83 | * | ||
84 | * Revision 1.14 2002/04/12 12:01:53 johana | ||
85 | * Use global r_port_g_data_shadow. | ||
86 | * Moved gpio_init_port_g() closer to gpio_init() and marked it __init. | ||
87 | * | ||
88 | * Revision 1.13 2002/04/10 12:03:55 johana | ||
89 | * Added support for port G /dev/gpiog (minor 3). | ||
90 | * Changed indentation on switch cases. | ||
91 | * Fixed other spaces to tabs. | ||
92 | * | ||
93 | * Revision 1.12 2001/11/12 19:42:15 pkj | ||
94 | * * Corrected return values from gpio_leds_ioctl(). | ||
95 | * * Fixed compiler warnings. | ||
96 | * | ||
97 | * Revision 1.11 2001/10/30 14:39:12 johana | ||
98 | * Added D() around gpio_write printk. | ||
99 | * | ||
100 | * Revision 1.10 2001/10/25 10:24:42 johana | ||
101 | * Added IO_CFG_WRITE_MODE ioctl and write method that can do fast | ||
102 | * bittoggling in the kernel. (This speeds up programming an FPGA with 450kB | ||
103 | * from ~60 seconds to 4 seconds). | ||
104 | * Added save_flags/cli/restore_flags in ioctl. | ||
105 | * | ||
106 | * Revision 1.9 2001/05/04 14:16:07 matsfg | ||
107 | * Corrected spelling error | ||
108 | * | ||
109 | * Revision 1.8 2001/04/27 13:55:26 matsfg | ||
110 | * Moved initioremap. | ||
111 | * Turns off all LEDS on init. | ||
112 | * Added support for shutdown and powerbutton. | ||
113 | * | ||
114 | * Revision 1.7 2001/04/04 13:30:08 matsfg | ||
115 | * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping | ||
116 | * | ||
117 | * Revision 1.6 2001/03/26 16:03:06 bjornw | ||
118 | * Needs linux/config.h | ||
119 | * | ||
120 | * Revision 1.5 2001/03/26 14:22:03 bjornw | ||
121 | * Namechange of some config options | ||
122 | * | ||
123 | * Revision 1.4 2001/02/27 13:52:48 bjornw | ||
124 | * malloc.h -> slab.h | ||
125 | * | ||
126 | * Revision 1.3 2001/01/24 15:06:48 bjornw | ||
127 | * gpio_wq correct type | ||
128 | * | ||
129 | * Revision 1.2 2001/01/18 16:07:30 bjornw | ||
130 | * 2.4 port | ||
131 | * | ||
132 | * Revision 1.1 2001/01/18 15:55:16 bjornw | ||
133 | * Verbatim copy of etraxgpio.c from elinux 2.0 added | ||
134 | * | ||
135 | * | ||
136 | */ | 9 | */ |
137 | 10 | ||
138 | 11 | ||
@@ -165,7 +38,7 @@ static int dp_cnt; | |||
165 | #else | 38 | #else |
166 | #define DP(x) | 39 | #define DP(x) |
167 | #endif | 40 | #endif |
168 | 41 | ||
169 | static char gpio_name[] = "etrax gpio"; | 42 | static char gpio_name[] = "etrax gpio"; |
170 | 43 | ||
171 | #if 0 | 44 | #if 0 |
@@ -173,9 +46,9 @@ static wait_queue_head_t *gpio_wq; | |||
173 | #endif | 46 | #endif |
174 | 47 | ||
175 | static int gpio_ioctl(struct inode *inode, struct file *file, | 48 | static int gpio_ioctl(struct inode *inode, struct file *file, |
176 | unsigned int cmd, unsigned long arg); | 49 | unsigned int cmd, unsigned long arg); |
177 | static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | 50 | static ssize_t gpio_write(struct file *file, const char __user *buf, |
178 | loff_t *off); | 51 | size_t count, loff_t *off); |
179 | static int gpio_open(struct inode *inode, struct file *filp); | 52 | static int gpio_open(struct inode *inode, struct file *filp); |
180 | static int gpio_release(struct inode *inode, struct file *filp); | 53 | static int gpio_release(struct inode *inode, struct file *filp); |
181 | static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait); | 54 | static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait); |
@@ -201,22 +74,22 @@ struct gpio_private { | |||
201 | 74 | ||
202 | /* linked list of alarms to check for */ | 75 | /* linked list of alarms to check for */ |
203 | 76 | ||
204 | static struct gpio_private *alarmlist = 0; | 77 | static struct gpio_private *alarmlist; |
205 | 78 | ||
206 | static int gpio_some_alarms = 0; /* Set if someone uses alarm */ | 79 | static int gpio_some_alarms; /* Set if someone uses alarm */ |
207 | static unsigned long gpio_pa_irq_enabled_mask = 0; | 80 | static unsigned long gpio_pa_irq_enabled_mask; |
208 | 81 | ||
209 | static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */ | 82 | static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */ |
210 | 83 | ||
211 | /* Port A and B use 8 bit access, but Port G is 32 bit */ | 84 | /* Port A and B use 8 bit access, but Port G is 32 bit */ |
212 | #define NUM_PORTS (GPIO_MINOR_B+1) | 85 | #define NUM_PORTS (GPIO_MINOR_B+1) |
213 | 86 | ||
214 | static volatile unsigned char *ports[NUM_PORTS] = { | 87 | static volatile unsigned char *ports[NUM_PORTS] = { |
215 | R_PORT_PA_DATA, | 88 | R_PORT_PA_DATA, |
216 | R_PORT_PB_DATA, | 89 | R_PORT_PB_DATA, |
217 | }; | 90 | }; |
218 | static volatile unsigned char *shads[NUM_PORTS] = { | 91 | static volatile unsigned char *shads[NUM_PORTS] = { |
219 | &port_pa_data_shadow, | 92 | &port_pa_data_shadow, |
220 | &port_pb_data_shadow | 93 | &port_pb_data_shadow |
221 | }; | 94 | }; |
222 | 95 | ||
@@ -236,29 +109,29 @@ static volatile unsigned char *shads[NUM_PORTS] = { | |||
236 | #endif | 109 | #endif |
237 | 110 | ||
238 | 111 | ||
239 | static unsigned char changeable_dir[NUM_PORTS] = { | 112 | static unsigned char changeable_dir[NUM_PORTS] = { |
240 | CONFIG_ETRAX_PA_CHANGEABLE_DIR, | 113 | CONFIG_ETRAX_PA_CHANGEABLE_DIR, |
241 | CONFIG_ETRAX_PB_CHANGEABLE_DIR | 114 | CONFIG_ETRAX_PB_CHANGEABLE_DIR |
242 | }; | 115 | }; |
243 | static unsigned char changeable_bits[NUM_PORTS] = { | 116 | static unsigned char changeable_bits[NUM_PORTS] = { |
244 | CONFIG_ETRAX_PA_CHANGEABLE_BITS, | 117 | CONFIG_ETRAX_PA_CHANGEABLE_BITS, |
245 | CONFIG_ETRAX_PB_CHANGEABLE_BITS | 118 | CONFIG_ETRAX_PB_CHANGEABLE_BITS |
246 | }; | 119 | }; |
247 | 120 | ||
248 | static volatile unsigned char *dir[NUM_PORTS] = { | 121 | static volatile unsigned char *dir[NUM_PORTS] = { |
249 | R_PORT_PA_DIR, | 122 | R_PORT_PA_DIR, |
250 | R_PORT_PB_DIR | 123 | R_PORT_PB_DIR |
251 | }; | 124 | }; |
252 | 125 | ||
253 | static volatile unsigned char *dir_shadow[NUM_PORTS] = { | 126 | static volatile unsigned char *dir_shadow[NUM_PORTS] = { |
254 | &port_pa_dir_shadow, | 127 | &port_pa_dir_shadow, |
255 | &port_pb_dir_shadow | 128 | &port_pb_dir_shadow |
256 | }; | 129 | }; |
257 | 130 | ||
258 | /* All bits in port g that can change dir. */ | 131 | /* All bits in port g that can change dir. */ |
259 | static const unsigned long int changeable_dir_g_mask = 0x01FFFF01; | 132 | static const unsigned long int changeable_dir_g_mask = 0x01FFFF01; |
260 | 133 | ||
261 | /* Port G is 32 bit, handle it special, some bits are both inputs | 134 | /* Port G is 32 bit, handle it special, some bits are both inputs |
262 | and outputs at the same time, only some of the bits can change direction | 135 | and outputs at the same time, only some of the bits can change direction |
263 | and some of them in groups of 8 bit. */ | 136 | and some of them in groups of 8 bit. */ |
264 | static unsigned long changeable_dir_g; | 137 | static unsigned long changeable_dir_g; |
@@ -269,18 +142,17 @@ static unsigned long dir_g_shadow; /* 1=output */ | |||
269 | #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B) | 142 | #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B) |
270 | 143 | ||
271 | 144 | ||
272 | 145 | static unsigned int gpio_poll(struct file *file, poll_table *wait) | |
273 | static unsigned int | ||
274 | gpio_poll(struct file *file, | ||
275 | poll_table *wait) | ||
276 | { | 146 | { |
277 | unsigned int mask = 0; | 147 | unsigned int mask = 0; |
278 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 148 | struct gpio_private *priv = file->private_data; |
279 | unsigned long data; | 149 | unsigned long data; |
280 | spin_lock(&gpio_lock); | 150 | unsigned long flags; |
151 | |||
152 | spin_lock_irqsave(&gpio_lock, flags); | ||
153 | |||
281 | poll_wait(file, &priv->alarm_wq, wait); | 154 | poll_wait(file, &priv->alarm_wq, wait); |
282 | if (priv->minor == GPIO_MINOR_A) { | 155 | if (priv->minor == GPIO_MINOR_A) { |
283 | unsigned long flags; | ||
284 | unsigned long tmp; | 156 | unsigned long tmp; |
285 | data = *R_PORT_PA_DATA; | 157 | data = *R_PORT_PA_DATA; |
286 | /* PA has support for high level interrupt - | 158 | /* PA has support for high level interrupt - |
@@ -288,27 +160,25 @@ gpio_poll(struct file *file, | |||
288 | */ | 160 | */ |
289 | tmp = ~data & priv->highalarm & 0xFF; | 161 | tmp = ~data & priv->highalarm & 0xFF; |
290 | tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); | 162 | tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); |
291 | local_irq_save(flags); | 163 | |
292 | gpio_pa_irq_enabled_mask |= tmp; | 164 | gpio_pa_irq_enabled_mask |= tmp; |
293 | *R_IRQ_MASK1_SET = tmp; | 165 | *R_IRQ_MASK1_SET = tmp; |
294 | local_irq_restore(flags); | ||
295 | |||
296 | } else if (priv->minor == GPIO_MINOR_B) | 166 | } else if (priv->minor == GPIO_MINOR_B) |
297 | data = *R_PORT_PB_DATA; | 167 | data = *R_PORT_PB_DATA; |
298 | else if (priv->minor == GPIO_MINOR_G) | 168 | else if (priv->minor == GPIO_MINOR_G) |
299 | data = *R_PORT_G_DATA; | 169 | data = *R_PORT_G_DATA; |
300 | else { | 170 | else { |
301 | spin_unlock(&gpio_lock); | 171 | mask = 0; |
302 | return 0; | 172 | goto out; |
303 | } | 173 | } |
304 | 174 | ||
305 | if ((data & priv->highalarm) || | 175 | if ((data & priv->highalarm) || |
306 | (~data & priv->lowalarm)) { | 176 | (~data & priv->lowalarm)) { |
307 | mask = POLLIN|POLLRDNORM; | 177 | mask = POLLIN|POLLRDNORM; |
308 | } | 178 | } |
309 | 179 | ||
310 | spin_unlock(&gpio_lock); | 180 | out: |
311 | 181 | spin_unlock_irqrestore(&gpio_lock, flags); | |
312 | DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); | 182 | DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); |
313 | 183 | ||
314 | return mask; | 184 | return mask; |
@@ -316,16 +186,19 @@ gpio_poll(struct file *file, | |||
316 | 186 | ||
317 | int etrax_gpio_wake_up_check(void) | 187 | int etrax_gpio_wake_up_check(void) |
318 | { | 188 | { |
319 | struct gpio_private *priv = alarmlist; | 189 | struct gpio_private *priv; |
320 | unsigned long data = 0; | 190 | unsigned long data = 0; |
321 | int ret = 0; | 191 | int ret = 0; |
322 | spin_lock(&gpio_lock); | 192 | unsigned long flags; |
193 | |||
194 | spin_lock_irqsave(&gpio_lock, flags); | ||
195 | priv = alarmlist; | ||
323 | while (priv) { | 196 | while (priv) { |
324 | if (USE_PORTS(priv)) { | 197 | if (USE_PORTS(priv)) |
325 | data = *priv->port; | 198 | data = *priv->port; |
326 | } else if (priv->minor == GPIO_MINOR_G) { | 199 | else if (priv->minor == GPIO_MINOR_G) |
327 | data = *R_PORT_G_DATA; | 200 | data = *R_PORT_G_DATA; |
328 | } | 201 | |
329 | if ((data & priv->highalarm) || | 202 | if ((data & priv->highalarm) || |
330 | (~data & priv->lowalarm)) { | 203 | (~data & priv->lowalarm)) { |
331 | DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor)); | 204 | DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor)); |
@@ -334,12 +207,12 @@ int etrax_gpio_wake_up_check(void) | |||
334 | } | 207 | } |
335 | priv = priv->next; | 208 | priv = priv->next; |
336 | } | 209 | } |
337 | spin_unlock(&gpio_lock); | 210 | spin_unlock_irqrestore(&gpio_lock, flags); |
338 | return ret; | 211 | return ret; |
339 | } | 212 | } |
340 | 213 | ||
341 | static irqreturn_t | 214 | static irqreturn_t |
342 | gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 215 | gpio_poll_timer_interrupt(int irq, void *dev_id) |
343 | { | 216 | { |
344 | if (gpio_some_alarms) { | 217 | if (gpio_some_alarms) { |
345 | etrax_gpio_wake_up_check(); | 218 | etrax_gpio_wake_up_check(); |
@@ -349,10 +222,13 @@ gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
349 | } | 222 | } |
350 | 223 | ||
351 | static irqreturn_t | 224 | static irqreturn_t |
352 | gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 225 | gpio_interrupt(int irq, void *dev_id) |
353 | { | 226 | { |
354 | unsigned long tmp; | 227 | unsigned long tmp; |
355 | spin_lock(&gpio_lock); | 228 | unsigned long flags; |
229 | |||
230 | spin_lock_irqsave(&gpio_lock, flags); | ||
231 | |||
356 | /* Find what PA interrupts are active */ | 232 | /* Find what PA interrupts are active */ |
357 | tmp = (*R_IRQ_READ1); | 233 | tmp = (*R_IRQ_READ1); |
358 | 234 | ||
@@ -363,75 +239,70 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
363 | *R_IRQ_MASK1_CLR = tmp; | 239 | *R_IRQ_MASK1_CLR = tmp; |
364 | gpio_pa_irq_enabled_mask &= ~tmp; | 240 | gpio_pa_irq_enabled_mask &= ~tmp; |
365 | 241 | ||
366 | spin_unlock(&gpio_lock); | 242 | spin_unlock_irqrestore(&gpio_lock, flags); |
367 | 243 | ||
368 | if (gpio_some_alarms) { | 244 | if (gpio_some_alarms) |
369 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); | 245 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); |
370 | } | 246 | |
371 | return IRQ_NONE; | 247 | return IRQ_NONE; |
372 | } | 248 | } |
373 | 249 | ||
250 | static void gpio_write_bit(struct gpio_private *priv, | ||
251 | unsigned char data, int bit) | ||
252 | { | ||
253 | *priv->port = *priv->shadow &= ~(priv->clk_mask); | ||
254 | if (data & 1 << bit) | ||
255 | *priv->port = *priv->shadow |= priv->data_mask; | ||
256 | else | ||
257 | *priv->port = *priv->shadow &= ~(priv->data_mask); | ||
258 | |||
259 | /* For FPGA: min 5.0ns (DCC) before CCLK high */ | ||
260 | *priv->port = *priv->shadow |= priv->clk_mask; | ||
261 | } | ||
374 | 262 | ||
375 | static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | 263 | static void gpio_write_byte(struct gpio_private *priv, unsigned char data) |
376 | loff_t *off) | ||
377 | { | 264 | { |
378 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 265 | int i; |
379 | unsigned char data, clk_mask, data_mask, write_msb; | ||
380 | unsigned long flags; | ||
381 | 266 | ||
382 | spin_lock(&gpio_lock); | 267 | if (priv->write_msb) |
268 | for (i = 7; i >= 0; i--) | ||
269 | gpio_write_bit(priv, data, i); | ||
270 | else | ||
271 | for (i = 0; i <= 7; i++) | ||
272 | gpio_write_bit(priv, data, i); | ||
273 | } | ||
383 | 274 | ||
275 | static ssize_t gpio_write(struct file *file, const char __user *buf, | ||
276 | size_t count, loff_t *off) | ||
277 | { | ||
278 | struct gpio_private *priv = file->private_data; | ||
279 | unsigned long flags; | ||
384 | ssize_t retval = count; | 280 | ssize_t retval = count; |
385 | if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { | 281 | |
386 | retval = -EFAULT; | 282 | if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) |
387 | goto out; | 283 | return -EFAULT; |
388 | } | 284 | |
389 | 285 | if (!access_ok(VERIFY_READ, buf, count)) | |
390 | if (!access_ok(VERIFY_READ, buf, count)) { | 286 | return -EFAULT; |
391 | retval = -EFAULT; | 287 | |
392 | goto out; | 288 | spin_lock_irqsave(&gpio_lock, flags); |
393 | } | 289 | |
394 | clk_mask = priv->clk_mask; | ||
395 | data_mask = priv->data_mask; | ||
396 | /* It must have been configured using the IO_CFG_WRITE_MODE */ | 290 | /* It must have been configured using the IO_CFG_WRITE_MODE */ |
397 | /* Perhaps a better error code? */ | 291 | /* Perhaps a better error code? */ |
398 | if (clk_mask == 0 || data_mask == 0) { | 292 | if (priv->clk_mask == 0 || priv->data_mask == 0) { |
399 | retval = -EPERM; | 293 | retval = -EPERM; |
400 | goto out; | 294 | goto out; |
401 | } | 295 | } |
402 | write_msb = priv->write_msb; | 296 | |
403 | D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); | 297 | D(printk(KERN_DEBUG "gpio_write: %02X to data 0x%02X " |
404 | while (count--) { | 298 | "clk 0x%02X msb: %i\n", |
405 | int i; | 299 | count, priv->data_mask, priv->clk_mask, priv->write_msb)); |
406 | data = *buf++; | 300 | |
407 | if (priv->write_msb) { | 301 | while (count--) |
408 | for (i = 7; i >= 0;i--) { | 302 | gpio_write_byte(priv, *buf++); |
409 | local_irq_save(flags); | 303 | |
410 | *priv->port = *priv->shadow &= ~clk_mask; | ||
411 | if (data & 1<<i) | ||
412 | *priv->port = *priv->shadow |= data_mask; | ||
413 | else | ||
414 | *priv->port = *priv->shadow &= ~data_mask; | ||
415 | /* For FPGA: min 5.0ns (DCC) before CCLK high */ | ||
416 | *priv->port = *priv->shadow |= clk_mask; | ||
417 | local_irq_restore(flags); | ||
418 | } | ||
419 | } else { | ||
420 | for (i = 0; i <= 7;i++) { | ||
421 | local_irq_save(flags); | ||
422 | *priv->port = *priv->shadow &= ~clk_mask; | ||
423 | if (data & 1<<i) | ||
424 | *priv->port = *priv->shadow |= data_mask; | ||
425 | else | ||
426 | *priv->port = *priv->shadow &= ~data_mask; | ||
427 | /* For FPGA: min 5.0ns (DCC) before CCLK high */ | ||
428 | *priv->port = *priv->shadow |= clk_mask; | ||
429 | local_irq_restore(flags); | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | out: | 304 | out: |
434 | spin_unlock(&gpio_lock); | 305 | spin_unlock_irqrestore(&gpio_lock, flags); |
435 | return retval; | 306 | return retval; |
436 | } | 307 | } |
437 | 308 | ||
@@ -442,22 +313,20 @@ gpio_open(struct inode *inode, struct file *filp) | |||
442 | { | 313 | { |
443 | struct gpio_private *priv; | 314 | struct gpio_private *priv; |
444 | int p = iminor(inode); | 315 | int p = iminor(inode); |
316 | unsigned long flags; | ||
445 | 317 | ||
446 | if (p > GPIO_MINOR_LAST) | 318 | if (p > GPIO_MINOR_LAST) |
447 | return -EINVAL; | 319 | return -EINVAL; |
448 | 320 | ||
449 | priv = kmalloc(sizeof(struct gpio_private), | 321 | priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL); |
450 | GFP_KERNEL); | ||
451 | 322 | ||
452 | if (!priv) | 323 | if (!priv) |
453 | return -ENOMEM; | 324 | return -ENOMEM; |
454 | 325 | ||
455 | priv->minor = p; | 326 | priv->minor = p; |
456 | 327 | ||
457 | /* initialize the io/alarm struct and link it into our alarmlist */ | 328 | /* initialize the io/alarm struct */ |
458 | 329 | ||
459 | priv->next = alarmlist; | ||
460 | alarmlist = priv; | ||
461 | if (USE_PORTS(priv)) { /* A and B */ | 330 | if (USE_PORTS(priv)) { /* A and B */ |
462 | priv->port = ports[p]; | 331 | priv->port = ports[p]; |
463 | priv->shadow = shads[p]; | 332 | priv->shadow = shads[p]; |
@@ -480,7 +349,13 @@ gpio_open(struct inode *inode, struct file *filp) | |||
480 | priv->data_mask = 0; | 349 | priv->data_mask = 0; |
481 | init_waitqueue_head(&priv->alarm_wq); | 350 | init_waitqueue_head(&priv->alarm_wq); |
482 | 351 | ||
483 | filp->private_data = (void *)priv; | 352 | filp->private_data = priv; |
353 | |||
354 | /* link it into our alarmlist */ | ||
355 | spin_lock_irqsave(&gpio_lock, flags); | ||
356 | priv->next = alarmlist; | ||
357 | alarmlist = priv; | ||
358 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
484 | 359 | ||
485 | return 0; | 360 | return 0; |
486 | } | 361 | } |
@@ -490,11 +365,12 @@ gpio_release(struct inode *inode, struct file *filp) | |||
490 | { | 365 | { |
491 | struct gpio_private *p; | 366 | struct gpio_private *p; |
492 | struct gpio_private *todel; | 367 | struct gpio_private *todel; |
368 | unsigned long flags; | ||
493 | 369 | ||
494 | spin_lock(&gpio_lock); | 370 | spin_lock_irqsave(&gpio_lock, flags); |
495 | 371 | ||
496 | p = alarmlist; | 372 | p = alarmlist; |
497 | todel = (struct gpio_private *)filp->private_data; | 373 | todel = filp->private_data; |
498 | 374 | ||
499 | /* unlink from alarmlist and free the private structure */ | 375 | /* unlink from alarmlist and free the private structure */ |
500 | 376 | ||
@@ -512,123 +388,114 @@ gpio_release(struct inode *inode, struct file *filp) | |||
512 | while (p) { | 388 | while (p) { |
513 | if (p->highalarm | p->lowalarm) { | 389 | if (p->highalarm | p->lowalarm) { |
514 | gpio_some_alarms = 1; | 390 | gpio_some_alarms = 1; |
515 | spin_unlock(&gpio_lock); | 391 | goto out; |
516 | return 0; | ||
517 | } | 392 | } |
518 | p = p->next; | 393 | p = p->next; |
519 | } | 394 | } |
520 | gpio_some_alarms = 0; | 395 | gpio_some_alarms = 0; |
521 | spin_unlock(&gpio_lock); | 396 | out: |
397 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
522 | return 0; | 398 | return 0; |
523 | } | 399 | } |
524 | 400 | ||
525 | /* Main device API. ioctl's to read/set/clear bits, as well as to | 401 | /* Main device API. ioctl's to read/set/clear bits, as well as to |
526 | * set alarms to wait for using a subsequent select(). | 402 | * set alarms to wait for using a subsequent select(). |
527 | */ | 403 | */ |
528 | |||
529 | unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) | 404 | unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) |
530 | { | 405 | { |
531 | /* Set direction 0=unchanged 1=input, | 406 | /* Set direction 0=unchanged 1=input, |
532 | * return mask with 1=input | 407 | * return mask with 1=input */ |
533 | */ | ||
534 | unsigned long flags; | ||
535 | if (USE_PORTS(priv)) { | 408 | if (USE_PORTS(priv)) { |
536 | local_irq_save(flags); | 409 | *priv->dir = *priv->dir_shadow &= |
537 | *priv->dir = *priv->dir_shadow &= | ||
538 | ~((unsigned char)arg & priv->changeable_dir); | 410 | ~((unsigned char)arg & priv->changeable_dir); |
539 | local_irq_restore(flags); | ||
540 | return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ | 411 | return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ |
541 | } else if (priv->minor == GPIO_MINOR_G) { | 412 | } |
542 | /* We must fiddle with R_GEN_CONFIG to change dir */ | 413 | |
543 | local_irq_save(flags); | 414 | if (priv->minor != GPIO_MINOR_G) |
544 | if (((arg & dir_g_in_bits) != arg) && | 415 | return 0; |
545 | (arg & changeable_dir_g)) { | 416 | |
546 | arg &= changeable_dir_g; | 417 | /* We must fiddle with R_GEN_CONFIG to change dir */ |
547 | /* Clear bits in genconfig to set to input */ | 418 | if (((arg & dir_g_in_bits) != arg) && |
548 | if (arg & (1<<0)) { | 419 | (arg & changeable_dir_g)) { |
549 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir); | 420 | arg &= changeable_dir_g; |
550 | dir_g_in_bits |= (1<<0); | 421 | /* Clear bits in genconfig to set to input */ |
551 | dir_g_out_bits &= ~(1<<0); | 422 | if (arg & (1<<0)) { |
552 | } | 423 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir); |
553 | if ((arg & 0x0000FF00) == 0x0000FF00) { | 424 | dir_g_in_bits |= (1<<0); |
554 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir); | 425 | dir_g_out_bits &= ~(1<<0); |
555 | dir_g_in_bits |= 0x0000FF00; | ||
556 | dir_g_out_bits &= ~0x0000FF00; | ||
557 | } | ||
558 | if ((arg & 0x00FF0000) == 0x00FF0000) { | ||
559 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir); | ||
560 | dir_g_in_bits |= 0x00FF0000; | ||
561 | dir_g_out_bits &= ~0x00FF0000; | ||
562 | } | ||
563 | if (arg & (1<<24)) { | ||
564 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir); | ||
565 | dir_g_in_bits |= (1<<24); | ||
566 | dir_g_out_bits &= ~(1<<24); | ||
567 | } | ||
568 | D(printk(KERN_INFO "gpio: SETINPUT on port G set " | ||
569 | "genconfig to 0x%08lX " | ||
570 | "in_bits: 0x%08lX " | ||
571 | "out_bits: 0x%08lX\n", | ||
572 | (unsigned long)genconfig_shadow, | ||
573 | dir_g_in_bits, dir_g_out_bits)); | ||
574 | *R_GEN_CONFIG = genconfig_shadow; | ||
575 | /* Must be a >120 ns delay before writing this again */ | ||
576 | |||
577 | } | 426 | } |
578 | local_irq_restore(flags); | 427 | if ((arg & 0x0000FF00) == 0x0000FF00) { |
579 | return dir_g_in_bits; | 428 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir); |
429 | dir_g_in_bits |= 0x0000FF00; | ||
430 | dir_g_out_bits &= ~0x0000FF00; | ||
431 | } | ||
432 | if ((arg & 0x00FF0000) == 0x00FF0000) { | ||
433 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir); | ||
434 | dir_g_in_bits |= 0x00FF0000; | ||
435 | dir_g_out_bits &= ~0x00FF0000; | ||
436 | } | ||
437 | if (arg & (1<<24)) { | ||
438 | genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir); | ||
439 | dir_g_in_bits |= (1<<24); | ||
440 | dir_g_out_bits &= ~(1<<24); | ||
441 | } | ||
442 | D(printk(KERN_DEBUG "gpio: SETINPUT on port G set " | ||
443 | "genconfig to 0x%08lX " | ||
444 | "in_bits: 0x%08lX " | ||
445 | "out_bits: 0x%08lX\n", | ||
446 | (unsigned long)genconfig_shadow, | ||
447 | dir_g_in_bits, dir_g_out_bits)); | ||
448 | *R_GEN_CONFIG = genconfig_shadow; | ||
449 | /* Must be a >120 ns delay before writing this again */ | ||
450 | |||
580 | } | 451 | } |
581 | return 0; | 452 | return dir_g_in_bits; |
582 | } /* setget_input */ | 453 | } /* setget_input */ |
583 | 454 | ||
584 | unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) | 455 | unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) |
585 | { | 456 | { |
586 | unsigned long flags; | ||
587 | if (USE_PORTS(priv)) { | 457 | if (USE_PORTS(priv)) { |
588 | local_irq_save(flags); | 458 | *priv->dir = *priv->dir_shadow |= |
589 | *priv->dir = *priv->dir_shadow |= | 459 | ((unsigned char)arg & priv->changeable_dir); |
590 | ((unsigned char)arg & priv->changeable_dir); | ||
591 | local_irq_restore(flags); | ||
592 | return *priv->dir_shadow; | 460 | return *priv->dir_shadow; |
593 | } else if (priv->minor == GPIO_MINOR_G) { | 461 | } |
594 | /* We must fiddle with R_GEN_CONFIG to change dir */ | 462 | if (priv->minor != GPIO_MINOR_G) |
595 | local_irq_save(flags); | 463 | return 0; |
596 | if (((arg & dir_g_out_bits) != arg) && | 464 | |
597 | (arg & changeable_dir_g)) { | 465 | /* We must fiddle with R_GEN_CONFIG to change dir */ |
598 | /* Set bits in genconfig to set to output */ | 466 | if (((arg & dir_g_out_bits) != arg) && |
599 | if (arg & (1<<0)) { | 467 | (arg & changeable_dir_g)) { |
600 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir); | 468 | /* Set bits in genconfig to set to output */ |
601 | dir_g_out_bits |= (1<<0); | 469 | if (arg & (1<<0)) { |
602 | dir_g_in_bits &= ~(1<<0); | 470 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir); |
603 | } | 471 | dir_g_out_bits |= (1<<0); |
604 | if ((arg & 0x0000FF00) == 0x0000FF00) { | 472 | dir_g_in_bits &= ~(1<<0); |
605 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir); | ||
606 | dir_g_out_bits |= 0x0000FF00; | ||
607 | dir_g_in_bits &= ~0x0000FF00; | ||
608 | } | ||
609 | if ((arg & 0x00FF0000) == 0x00FF0000) { | ||
610 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir); | ||
611 | dir_g_out_bits |= 0x00FF0000; | ||
612 | dir_g_in_bits &= ~0x00FF0000; | ||
613 | } | ||
614 | if (arg & (1<<24)) { | ||
615 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir); | ||
616 | dir_g_out_bits |= (1<<24); | ||
617 | dir_g_in_bits &= ~(1<<24); | ||
618 | } | ||
619 | D(printk(KERN_INFO "gpio: SETOUTPUT on port G set " | ||
620 | "genconfig to 0x%08lX " | ||
621 | "in_bits: 0x%08lX " | ||
622 | "out_bits: 0x%08lX\n", | ||
623 | (unsigned long)genconfig_shadow, | ||
624 | dir_g_in_bits, dir_g_out_bits)); | ||
625 | *R_GEN_CONFIG = genconfig_shadow; | ||
626 | /* Must be a >120 ns delay before writing this again */ | ||
627 | } | 473 | } |
628 | local_irq_restore(flags); | 474 | if ((arg & 0x0000FF00) == 0x0000FF00) { |
629 | return dir_g_out_bits & 0x7FFFFFFF; | 475 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir); |
476 | dir_g_out_bits |= 0x0000FF00; | ||
477 | dir_g_in_bits &= ~0x0000FF00; | ||
478 | } | ||
479 | if ((arg & 0x00FF0000) == 0x00FF0000) { | ||
480 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g16_23dir); | ||
481 | dir_g_out_bits |= 0x00FF0000; | ||
482 | dir_g_in_bits &= ~0x00FF0000; | ||
483 | } | ||
484 | if (arg & (1<<24)) { | ||
485 | genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir); | ||
486 | dir_g_out_bits |= (1<<24); | ||
487 | dir_g_in_bits &= ~(1<<24); | ||
488 | } | ||
489 | D(printk(KERN_INFO "gpio: SETOUTPUT on port G set " | ||
490 | "genconfig to 0x%08lX " | ||
491 | "in_bits: 0x%08lX " | ||
492 | "out_bits: 0x%08lX\n", | ||
493 | (unsigned long)genconfig_shadow, | ||
494 | dir_g_in_bits, dir_g_out_bits)); | ||
495 | *R_GEN_CONFIG = genconfig_shadow; | ||
496 | /* Must be a >120 ns delay before writing this again */ | ||
630 | } | 497 | } |
631 | return 0; | 498 | return dir_g_out_bits & 0x7FFFFFFF; |
632 | } /* setget_output */ | 499 | } /* setget_output */ |
633 | 500 | ||
634 | static int | 501 | static int |
@@ -642,12 +509,11 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
642 | unsigned long val; | 509 | unsigned long val; |
643 | int ret = 0; | 510 | int ret = 0; |
644 | 511 | ||
645 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 512 | struct gpio_private *priv = file->private_data; |
646 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) { | 513 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) |
647 | return -EINVAL; | 514 | return -EINVAL; |
648 | } | ||
649 | 515 | ||
650 | spin_lock(&gpio_lock); | 516 | spin_lock_irqsave(&gpio_lock, flags); |
651 | 517 | ||
652 | switch (_IOC_NR(cmd)) { | 518 | switch (_IOC_NR(cmd)) { |
653 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ | 519 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ |
@@ -659,7 +525,6 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
659 | } | 525 | } |
660 | break; | 526 | break; |
661 | case IO_SETBITS: | 527 | case IO_SETBITS: |
662 | local_irq_save(flags); | ||
663 | // set changeable bits with a 1 in arg | 528 | // set changeable bits with a 1 in arg |
664 | if (USE_PORTS(priv)) { | 529 | if (USE_PORTS(priv)) { |
665 | *priv->port = *priv->shadow |= | 530 | *priv->port = *priv->shadow |= |
@@ -667,10 +532,8 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
667 | } else if (priv->minor == GPIO_MINOR_G) { | 532 | } else if (priv->minor == GPIO_MINOR_G) { |
668 | *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits); | 533 | *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits); |
669 | } | 534 | } |
670 | local_irq_restore(flags); | ||
671 | break; | 535 | break; |
672 | case IO_CLRBITS: | 536 | case IO_CLRBITS: |
673 | local_irq_save(flags); | ||
674 | // clear changeable bits with a 1 in arg | 537 | // clear changeable bits with a 1 in arg |
675 | if (USE_PORTS(priv)) { | 538 | if (USE_PORTS(priv)) { |
676 | *priv->port = *priv->shadow &= | 539 | *priv->port = *priv->shadow &= |
@@ -678,7 +541,6 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
678 | } else if (priv->minor == GPIO_MINOR_G) { | 541 | } else if (priv->minor == GPIO_MINOR_G) { |
679 | *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits); | 542 | *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits); |
680 | } | 543 | } |
681 | local_irq_restore(flags); | ||
682 | break; | 544 | break; |
683 | case IO_HIGHALARM: | 545 | case IO_HIGHALARM: |
684 | // set alarm when bits with 1 in arg go high | 546 | // set alarm when bits with 1 in arg go high |
@@ -698,6 +560,8 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
698 | /* Must update gpio_some_alarms */ | 560 | /* Must update gpio_some_alarms */ |
699 | struct gpio_private *p = alarmlist; | 561 | struct gpio_private *p = alarmlist; |
700 | int some_alarms; | 562 | int some_alarms; |
563 | spin_lock_irq(&gpio_lock); | ||
564 | p = alarmlist; | ||
701 | some_alarms = 0; | 565 | some_alarms = 0; |
702 | while (p) { | 566 | while (p) { |
703 | if (p->highalarm | p->lowalarm) { | 567 | if (p->highalarm | p->lowalarm) { |
@@ -707,6 +571,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
707 | p = p->next; | 571 | p = p->next; |
708 | } | 572 | } |
709 | gpio_some_alarms = some_alarms; | 573 | gpio_some_alarms = some_alarms; |
574 | spin_unlock_irq(&gpio_lock); | ||
710 | } | 575 | } |
711 | break; | 576 | break; |
712 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ | 577 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ |
@@ -766,7 +631,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
766 | } else if (priv->minor == GPIO_MINOR_G) { | 631 | } else if (priv->minor == GPIO_MINOR_G) { |
767 | val = *R_PORT_G_DATA; | 632 | val = *R_PORT_G_DATA; |
768 | } | 633 | } |
769 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 634 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) |
770 | ret = -EFAULT; | 635 | ret = -EFAULT; |
771 | break; | 636 | break; |
772 | case IO_READ_OUTBITS: | 637 | case IO_READ_OUTBITS: |
@@ -776,33 +641,32 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
776 | } else if (priv->minor == GPIO_MINOR_G) { | 641 | } else if (priv->minor == GPIO_MINOR_G) { |
777 | val = port_g_data_shadow; | 642 | val = port_g_data_shadow; |
778 | } | 643 | } |
779 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 644 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) |
780 | ret = -EFAULT; | 645 | ret = -EFAULT; |
781 | break; | 646 | break; |
782 | case IO_SETGET_INPUT: | 647 | case IO_SETGET_INPUT: |
783 | /* bits set in *arg is set to input, | 648 | /* bits set in *arg is set to input, |
784 | * *arg updated with current input pins. | 649 | * *arg updated with current input pins. |
785 | */ | 650 | */ |
786 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | 651 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) |
787 | { | 652 | { |
788 | ret = -EFAULT; | 653 | ret = -EFAULT; |
789 | break; | 654 | break; |
790 | } | 655 | } |
791 | val = setget_input(priv, val); | 656 | val = setget_input(priv, val); |
792 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 657 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) |
793 | ret = -EFAULT; | 658 | ret = -EFAULT; |
794 | break; | 659 | break; |
795 | case IO_SETGET_OUTPUT: | 660 | case IO_SETGET_OUTPUT: |
796 | /* bits set in *arg is set to output, | 661 | /* bits set in *arg is set to output, |
797 | * *arg updated with current output pins. | 662 | * *arg updated with current output pins. |
798 | */ | 663 | */ |
799 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | 664 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) { |
800 | { | ||
801 | ret = -EFAULT; | 665 | ret = -EFAULT; |
802 | break; | 666 | break; |
803 | } | 667 | } |
804 | val = setget_output(priv, val); | 668 | val = setget_output(priv, val); |
805 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 669 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) |
806 | ret = -EFAULT; | 670 | ret = -EFAULT; |
807 | break; | 671 | break; |
808 | default: | 672 | default: |
@@ -812,7 +676,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
812 | ret = -EINVAL; | 676 | ret = -EINVAL; |
813 | } /* switch */ | 677 | } /* switch */ |
814 | 678 | ||
815 | spin_unlock(&gpio_lock); | 679 | spin_unlock_irqrestore(&gpio_lock, flags); |
816 | return ret; | 680 | return ret; |
817 | } | 681 | } |
818 | 682 | ||
@@ -824,18 +688,18 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | |||
824 | 688 | ||
825 | switch (_IOC_NR(cmd)) { | 689 | switch (_IOC_NR(cmd)) { |
826 | case IO_LEDACTIVE_SET: | 690 | case IO_LEDACTIVE_SET: |
827 | green = ((unsigned char) arg) & 1; | 691 | green = ((unsigned char)arg) & 1; |
828 | red = (((unsigned char) arg) >> 1) & 1; | 692 | red = (((unsigned char)arg) >> 1) & 1; |
829 | LED_ACTIVE_SET_G(green); | 693 | CRIS_LED_ACTIVE_SET_G(green); |
830 | LED_ACTIVE_SET_R(red); | 694 | CRIS_LED_ACTIVE_SET_R(red); |
831 | break; | 695 | break; |
832 | 696 | ||
833 | case IO_LED_SETBIT: | 697 | case IO_LED_SETBIT: |
834 | LED_BIT_SET(arg); | 698 | CRIS_LED_BIT_SET(arg); |
835 | break; | 699 | break; |
836 | 700 | ||
837 | case IO_LED_CLRBIT: | 701 | case IO_LED_CLRBIT: |
838 | LED_BIT_CLR(arg); | 702 | CRIS_LED_BIT_CLR(arg); |
839 | break; | 703 | break; |
840 | 704 | ||
841 | default: | 705 | default: |
@@ -845,7 +709,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | |||
845 | return 0; | 709 | return 0; |
846 | } | 710 | } |
847 | 711 | ||
848 | const struct file_operations gpio_fops = { | 712 | static const struct file_operations gpio_fops = { |
849 | .owner = THIS_MODULE, | 713 | .owner = THIS_MODULE, |
850 | .poll = gpio_poll, | 714 | .poll = gpio_poll, |
851 | .ioctl = gpio_ioctl, | 715 | .ioctl = gpio_ioctl, |
@@ -854,16 +718,18 @@ const struct file_operations gpio_fops = { | |||
854 | .release = gpio_release, | 718 | .release = gpio_release, |
855 | }; | 719 | }; |
856 | 720 | ||
857 | 721 | static void ioif_watcher(const unsigned int gpio_in_available, | |
858 | void ioif_watcher(const unsigned int gpio_in_available, | 722 | const unsigned int gpio_out_available, |
859 | const unsigned int gpio_out_available, | 723 | const unsigned char pa_available, |
860 | const unsigned char pa_available, | 724 | const unsigned char pb_available) |
861 | const unsigned char pb_available) | ||
862 | { | 725 | { |
863 | unsigned long int flags; | 726 | unsigned long int flags; |
864 | D(printk("gpio.c: ioif_watcher called\n")); | 727 | |
865 | D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n", | 728 | D(printk(KERN_DEBUG "gpio.c: ioif_watcher called\n")); |
866 | gpio_in_available, gpio_out_available, pa_available, pb_available)); | 729 | D(printk(KERN_DEBUG "gpio.c: G in: 0x%08x G out: 0x%08x " |
730 | "PA: 0x%02x PB: 0x%02x\n", | ||
731 | gpio_in_available, gpio_out_available, | ||
732 | pa_available, pb_available)); | ||
867 | 733 | ||
868 | spin_lock_irqsave(&gpio_lock, flags); | 734 | spin_lock_irqsave(&gpio_lock, flags); |
869 | 735 | ||
@@ -872,7 +738,7 @@ void ioif_watcher(const unsigned int gpio_in_available, | |||
872 | 738 | ||
873 | /* Initialise the dir_g_shadow etc. depending on genconfig */ | 739 | /* Initialise the dir_g_shadow etc. depending on genconfig */ |
874 | /* 0=input 1=output */ | 740 | /* 0=input 1=output */ |
875 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) | 741 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) |
876 | dir_g_shadow |= (1 << 0); | 742 | dir_g_shadow |= (1 << 0); |
877 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out)) | 743 | if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out)) |
878 | dir_g_shadow |= 0x0000FF00; | 744 | dir_g_shadow |= 0x0000FF00; |
@@ -884,7 +750,8 @@ void ioif_watcher(const unsigned int gpio_in_available, | |||
884 | changeable_dir_g = changeable_dir_g_mask; | 750 | changeable_dir_g = changeable_dir_g_mask; |
885 | changeable_dir_g &= dir_g_out_bits; | 751 | changeable_dir_g &= dir_g_out_bits; |
886 | changeable_dir_g &= dir_g_in_bits; | 752 | changeable_dir_g &= dir_g_in_bits; |
887 | /* Correct the bits that can change direction */ | 753 | |
754 | /* Correct the bits that can change direction */ | ||
888 | dir_g_out_bits &= ~changeable_dir_g; | 755 | dir_g_out_bits &= ~changeable_dir_g; |
889 | dir_g_out_bits |= dir_g_shadow; | 756 | dir_g_out_bits |= dir_g_shadow; |
890 | dir_g_in_bits &= ~changeable_dir_g; | 757 | dir_g_in_bits &= ~changeable_dir_g; |
@@ -892,7 +759,8 @@ void ioif_watcher(const unsigned int gpio_in_available, | |||
892 | 759 | ||
893 | spin_unlock_irqrestore(&gpio_lock, flags); | 760 | spin_unlock_irqrestore(&gpio_lock, flags); |
894 | 761 | ||
895 | printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", | 762 | printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX " |
763 | "val: %08lX\n", | ||
896 | dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); | 764 | dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); |
897 | printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n", | 765 | printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n", |
898 | dir_g_shadow, changeable_dir_g); | 766 | dir_g_shadow, changeable_dir_g); |
@@ -900,16 +768,12 @@ void ioif_watcher(const unsigned int gpio_in_available, | |||
900 | 768 | ||
901 | /* main driver initialization routine, called from mem.c */ | 769 | /* main driver initialization routine, called from mem.c */ |
902 | 770 | ||
903 | static __init int | 771 | static int __init gpio_init(void) |
904 | gpio_init(void) | ||
905 | { | 772 | { |
906 | int res; | 773 | int res; |
907 | #if defined (CONFIG_ETRAX_CSP0_LEDS) | 774 | #if defined (CONFIG_ETRAX_CSP0_LEDS) |
908 | int i; | 775 | int i; |
909 | #endif | 776 | #endif |
910 | printk("gpio init\n"); | ||
911 | |||
912 | /* do the formalities */ | ||
913 | 777 | ||
914 | res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops); | 778 | res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops); |
915 | if (res < 0) { | 779 | if (res < 0) { |
@@ -919,43 +783,45 @@ gpio_init(void) | |||
919 | 783 | ||
920 | /* Clear all leds */ | 784 | /* Clear all leds */ |
921 | #if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) | 785 | #if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) |
922 | LED_NETWORK_SET(0); | 786 | CRIS_LED_NETWORK_SET(0); |
923 | LED_ACTIVE_SET(0); | 787 | CRIS_LED_ACTIVE_SET(0); |
924 | LED_DISK_READ(0); | 788 | CRIS_LED_DISK_READ(0); |
925 | LED_DISK_WRITE(0); | 789 | CRIS_LED_DISK_WRITE(0); |
926 | 790 | ||
927 | #if defined (CONFIG_ETRAX_CSP0_LEDS) | 791 | #if defined (CONFIG_ETRAX_CSP0_LEDS) |
928 | for (i = 0; i < 32; i++) { | 792 | for (i = 0; i < 32; i++) |
929 | LED_BIT_SET(i); | 793 | CRIS_LED_BIT_SET(i); |
930 | } | ||
931 | #endif | 794 | #endif |
932 | 795 | ||
933 | #endif | 796 | #endif |
934 | /* The I/O interface allocation watcher will be called when | 797 | /* The I/O interface allocation watcher will be called when |
935 | * registering it. */ | 798 | * registering it. */ |
936 | if (cris_io_interface_register_watcher(ioif_watcher)){ | 799 | if (cris_io_interface_register_watcher(ioif_watcher)){ |
937 | printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n"); | 800 | printk(KERN_WARNING "gpio_init: Failed to install IO " |
801 | "if allocator watcher\n"); | ||
938 | } | 802 | } |
939 | 803 | ||
940 | printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n"); | 804 | printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 " |
805 | "Axis Communications AB\n"); | ||
941 | /* We call etrax_gpio_wake_up_check() from timer interrupt and | 806 | /* We call etrax_gpio_wake_up_check() from timer interrupt and |
942 | * from cpu_idle() in kernel/process.c | 807 | * from cpu_idle() in kernel/process.c |
943 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms | 808 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms |
944 | * in some tests. | 809 | * in some tests. |
945 | */ | 810 | */ |
946 | if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, | 811 | res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, |
947 | IRQF_SHARED | IRQF_DISABLED,"gpio poll", NULL)) { | 812 | IRQF_SHARED | IRQF_DISABLED, "gpio poll", gpio_name); |
813 | if (res) { | ||
948 | printk(KERN_CRIT "err: timer0 irq for gpio\n"); | 814 | printk(KERN_CRIT "err: timer0 irq for gpio\n"); |
815 | return res; | ||
949 | } | 816 | } |
950 | if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt, | 817 | res = request_irq(PA_IRQ_NBR, gpio_interrupt, |
951 | IRQF_SHARED | IRQF_DISABLED,"gpio PA", NULL)) { | 818 | IRQF_SHARED | IRQF_DISABLED, "gpio PA", gpio_name); |
819 | if (res) | ||
952 | printk(KERN_CRIT "err: PA irq for gpio\n"); | 820 | printk(KERN_CRIT "err: PA irq for gpio\n"); |
953 | } | ||
954 | |||
955 | 821 | ||
956 | return res; | 822 | return res; |
957 | } | 823 | } |
958 | 824 | ||
959 | /* this makes sure that gpio_init is called during kernel boot */ | 825 | /* this makes sure that gpio_init is called during kernel boot */ |
960 | |||
961 | module_init(gpio_init); | 826 | module_init(gpio_init); |
827 | |||
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index aca81ddaf60f..d6d22067d0c8 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c | |||
@@ -6,85 +6,9 @@ | |||
6 | *! kernel modules (i2c_writereg/readreg) and from userspace using | 6 | *! kernel modules (i2c_writereg/readreg) and from userspace using |
7 | *! ioctl()'s | 7 | *! ioctl()'s |
8 | *! | 8 | *! |
9 | *! Nov 30 1998 Torbjorn Eliasson Initial version. | 9 | *! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN |
10 | *! Bjorn Wesen Elinux kernel version. | ||
11 | *! Jan 14 2000 Johan Adolfsson Fixed PB shadow register stuff - | ||
12 | *! don't use PB_I2C if DS1302 uses same bits, | ||
13 | *! use PB. | ||
14 | *! $Log: i2c.c,v $ | ||
15 | *! Revision 1.13 2005/03/07 13:13:07 starvik | ||
16 | *! Added spinlocks to protect states etc | ||
17 | *! | ||
18 | *! Revision 1.12 2005/01/05 06:11:22 starvik | ||
19 | *! No need to do local_irq_disable after local_irq_save. | ||
20 | *! | ||
21 | *! Revision 1.11 2004/12/13 12:21:52 starvik | ||
22 | *! Added I/O and DMA allocators from Linux 2.4 | ||
23 | *! | ||
24 | *! Revision 1.9 2004/08/24 06:49:14 starvik | ||
25 | *! Whitespace cleanup | ||
26 | *! | ||
27 | *! Revision 1.8 2004/06/08 08:48:26 starvik | ||
28 | *! Removed unused code | ||
29 | *! | ||
30 | *! Revision 1.7 2004/05/28 09:26:59 starvik | ||
31 | *! Modified I2C initialization to work in 2.6. | ||
32 | *! | ||
33 | *! Revision 1.6 2004/05/14 07:58:03 starvik | ||
34 | *! Merge of changes from 2.4 | ||
35 | *! | ||
36 | *! Revision 1.4 2002/12/11 13:13:57 starvik | ||
37 | *! Added arch/ to v10 specific includes | ||
38 | *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) | ||
39 | *! | ||
40 | *! Revision 1.3 2002/11/20 11:56:11 starvik | ||
41 | *! Merge of Linux 2.5.48 | ||
42 | *! | ||
43 | *! Revision 1.2 2002/11/18 13:16:06 starvik | ||
44 | *! Linux 2.5 port of latest 2.4 drivers | ||
45 | *! | ||
46 | *! Revision 1.9 2002/10/31 15:32:26 starvik | ||
47 | *! Update Port B register and shadow even when running with hardware support | ||
48 | *! to avoid glitches when reading bits | ||
49 | *! Never set direction to out in i2c_inbyte | ||
50 | *! Removed incorrect clock toggling at end of i2c_inbyte | ||
51 | *! | ||
52 | *! Revision 1.8 2002/08/13 06:31:53 starvik | ||
53 | *! Made SDA and SCL line configurable | ||
54 | *! Modified i2c_inbyte to work with PCF8563 | ||
55 | *! | ||
56 | *! Revision 1.7 2001/04/04 13:11:36 markusl | ||
57 | *! Updated according to review remarks | ||
58 | *! | ||
59 | *! Revision 1.6 2001/03/19 12:43:00 markusl | ||
60 | *! Made some symbols unstatic (used by the eeprom driver) | ||
61 | *! | ||
62 | *! Revision 1.5 2001/02/27 13:52:48 bjornw | ||
63 | *! malloc.h -> slab.h | ||
64 | *! | ||
65 | *! Revision 1.4 2001/02/15 07:17:40 starvik | ||
66 | *! Corrected usage if port_pb_i2c_shadow | ||
67 | *! | ||
68 | *! Revision 1.3 2001/01/26 17:55:13 bjornw | ||
69 | *! * Made I2C_USES_PB_NOT_PB_I2C a CONFIG option instead of assigning it | ||
70 | *! magically. Config.in needs to set it for the options that need it, like | ||
71 | *! Dallas 1302 support. Actually, it should be default since it screws up | ||
72 | *! the PB bits even if you don't use I2C.. | ||
73 | *! * Include linux/config.h to get the above | ||
74 | *! | ||
75 | *! Revision 1.2 2001/01/18 15:49:30 bjornw | ||
76 | *! 2.4 port of I2C including some cleanups (untested of course) | ||
77 | *! | ||
78 | *! Revision 1.1 2001/01/18 15:35:25 bjornw | ||
79 | *! Verbatim copy of the Etrax i2c driver, 2.0 elinux version | ||
80 | *! | ||
81 | *! | ||
82 | *! --------------------------------------------------------------------------- | ||
83 | *! | ||
84 | *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN | ||
85 | *! | 10 | *! |
86 | *!***************************************************************************/ | 11 | *!***************************************************************************/ |
87 | /* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */ | ||
88 | 12 | ||
89 | /****************** INCLUDE FILES SECTION ***********************************/ | 13 | /****************** INCLUDE FILES SECTION ***********************************/ |
90 | 14 | ||
@@ -622,7 +546,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
622 | * last received byte needs to be nacked | 546 | * last received byte needs to be nacked |
623 | * instead of acked | 547 | * instead of acked |
624 | */ | 548 | */ |
625 | i2c_sendack(); | 549 | i2c_sendnack(); |
626 | /* | 550 | /* |
627 | * end sequence | 551 | * end sequence |
628 | */ | 552 | */ |
@@ -708,6 +632,7 @@ i2c_init(void) | |||
708 | if (!first) { | 632 | if (!first) { |
709 | return res; | 633 | return res; |
710 | } | 634 | } |
635 | first = 0; | ||
711 | 636 | ||
712 | /* Setup and enable the Port B I2C interface */ | 637 | /* Setup and enable the Port B I2C interface */ |
713 | 638 | ||
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c index c263b8232dbc..52103d16dc6c 100644 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ b/arch/cris/arch-v10/drivers/pcf8563.c | |||
@@ -8,14 +8,13 @@ | |||
8 | * low detector are also provided. All address and data are transferred | 8 | * low detector are also provided. All address and data are transferred |
9 | * serially via two-line bidirectional I2C-bus. Maximum bus speed is | 9 | * serially via two-line bidirectional I2C-bus. Maximum bus speed is |
10 | * 400 kbits/s. The built-in word address register is incremented | 10 | * 400 kbits/s. The built-in word address register is incremented |
11 | * automatically after each written or read bute. | 11 | * automatically after each written or read byte. |
12 | * | 12 | * |
13 | * Copyright (c) 2002, Axis Communications AB | 13 | * Copyright (c) 2002-2007, Axis Communications AB |
14 | * All rights reserved. | 14 | * All rights reserved. |
15 | * | 15 | * |
16 | * Author: Tobias Anderberg <tobiasa@axis.com>. | 16 | * Author: Tobias Anderberg <tobiasa@axis.com>. |
17 | * | 17 | * |
18 | * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $ | ||
19 | */ | 18 | */ |
20 | 19 | ||
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -27,19 +26,19 @@ | |||
27 | #include <linux/ioctl.h> | 26 | #include <linux/ioctl.h> |
28 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
29 | #include <linux/bcd.h> | 28 | #include <linux/bcd.h> |
30 | #include <linux/capability.h> | 29 | #include <linux/mutex.h> |
31 | 30 | ||
32 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
33 | #include <asm/system.h> | 32 | #include <asm/system.h> |
34 | #include <asm/io.h> | 33 | #include <asm/io.h> |
35 | #include <asm/arch/svinto.h> | ||
36 | #include <asm/rtc.h> | 34 | #include <asm/rtc.h> |
35 | |||
37 | #include "i2c.h" | 36 | #include "i2c.h" |
38 | 37 | ||
39 | #define PCF8563_MAJOR 121 /* Local major number. */ | 38 | #define PCF8563_MAJOR 121 /* Local major number. */ |
40 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ | 39 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ |
41 | #define PCF8563_NAME "PCF8563" | 40 | #define PCF8563_NAME "PCF8563" |
42 | #define DRIVER_VERSION "$Revision: 1.11 $" | 41 | #define DRIVER_VERSION "$Revision: 1.24 $" |
43 | 42 | ||
44 | /* I2C bus slave registers. */ | 43 | /* I2C bus slave registers. */ |
45 | #define RTC_I2C_READ 0xa3 | 44 | #define RTC_I2C_READ 0xa3 |
@@ -49,71 +48,88 @@ | |||
49 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) | 48 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) |
50 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) | 49 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) |
51 | 50 | ||
52 | static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */ | 51 | static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ |
53 | 52 | ||
54 | static const unsigned char days_in_month[] = | 53 | static const unsigned char days_in_month[] = |
55 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | 54 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
56 | 55 | ||
57 | int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 56 | int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
58 | 57 | ||
58 | /* Cache VL bit value read at driver init since writing the RTC_SECOND | ||
59 | * register clears the VL status. | ||
60 | */ | ||
61 | static int voltage_low; | ||
62 | |||
59 | static const struct file_operations pcf8563_fops = { | 63 | static const struct file_operations pcf8563_fops = { |
60 | .owner = THIS_MODULE, | 64 | .owner = THIS_MODULE, |
61 | .ioctl = pcf8563_ioctl, | 65 | .ioctl = pcf8563_ioctl, |
62 | }; | 66 | }; |
63 | 67 | ||
64 | unsigned char | 68 | unsigned char |
65 | pcf8563_readreg(int reg) | 69 | pcf8563_readreg(int reg) |
66 | { | 70 | { |
67 | unsigned char res = i2c_readreg(RTC_I2C_READ, reg); | 71 | unsigned char res = rtc_read(reg); |
68 | 72 | ||
69 | /* The PCF8563 does not return 0 for unimplemented bits */ | 73 | /* The PCF8563 does not return 0 for unimplemented bits. */ |
70 | switch(reg) | 74 | switch (reg) { |
71 | { | 75 | case RTC_SECONDS: |
72 | case RTC_SECONDS: | 76 | case RTC_MINUTES: |
73 | case RTC_MINUTES: | 77 | res &= 0x7F; |
74 | res &= 0x7f; | 78 | break; |
75 | break; | 79 | case RTC_HOURS: |
76 | case RTC_HOURS: | 80 | case RTC_DAY_OF_MONTH: |
77 | case RTC_DAY_OF_MONTH: | 81 | res &= 0x3F; |
78 | res &= 0x3f; | 82 | break; |
79 | break; | 83 | case RTC_WEEKDAY: |
80 | case RTC_MONTH: | 84 | res &= 0x07; |
81 | res = (res & 0x1f) - 1; /* PCF8563 returns month in range 1-12 */ | 85 | break; |
82 | break; | 86 | case RTC_MONTH: |
87 | res &= 0x1F; | ||
88 | break; | ||
89 | case RTC_CONTROL1: | ||
90 | res &= 0xA8; | ||
91 | break; | ||
92 | case RTC_CONTROL2: | ||
93 | res &= 0x1F; | ||
94 | break; | ||
95 | case RTC_CLOCKOUT_FREQ: | ||
96 | case RTC_TIMER_CONTROL: | ||
97 | res &= 0x83; | ||
98 | break; | ||
83 | } | 99 | } |
84 | return res; | 100 | return res; |
85 | } | 101 | } |
86 | 102 | ||
87 | void | 103 | void |
88 | pcf8563_writereg(int reg, unsigned char val) | 104 | pcf8563_writereg(int reg, unsigned char val) |
89 | { | 105 | { |
90 | #ifdef CONFIG_ETRAX_RTC_READONLY | ||
91 | if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR)) | ||
92 | return; | ||
93 | #endif | ||
94 | |||
95 | rtc_write(reg, val); | 106 | rtc_write(reg, val); |
96 | } | 107 | } |
97 | 108 | ||
98 | void | 109 | void |
99 | get_rtc_time(struct rtc_time *tm) | 110 | get_rtc_time(struct rtc_time *tm) |
100 | { | 111 | { |
101 | tm->tm_sec = rtc_read(RTC_SECONDS); | 112 | tm->tm_sec = rtc_read(RTC_SECONDS); |
102 | tm->tm_min = rtc_read(RTC_MINUTES); | 113 | tm->tm_min = rtc_read(RTC_MINUTES); |
103 | tm->tm_hour = rtc_read(RTC_HOURS); | 114 | tm->tm_hour = rtc_read(RTC_HOURS); |
104 | tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH); | 115 | tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH); |
105 | tm->tm_mon = rtc_read(RTC_MONTH); | 116 | tm->tm_wday = rtc_read(RTC_WEEKDAY); |
117 | tm->tm_mon = rtc_read(RTC_MONTH); | ||
106 | tm->tm_year = rtc_read(RTC_YEAR); | 118 | tm->tm_year = rtc_read(RTC_YEAR); |
107 | 119 | ||
108 | if (tm->tm_sec & 0x80) | 120 | if (tm->tm_sec & 0x80) { |
109 | printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME); | 121 | printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time " |
122 | "information is no longer guaranteed!\n", PCF8563_NAME); | ||
123 | } | ||
110 | 124 | ||
111 | tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0); | 125 | tm->tm_year = BCD_TO_BIN(tm->tm_year) + |
112 | tm->tm_sec &= 0x7f; | 126 | ((tm->tm_mon & 0x80) ? 100 : 0); |
113 | tm->tm_min &= 0x7f; | 127 | tm->tm_sec &= 0x7F; |
114 | tm->tm_hour &= 0x3f; | 128 | tm->tm_min &= 0x7F; |
115 | tm->tm_mday &= 0x3f; | 129 | tm->tm_hour &= 0x3F; |
116 | tm->tm_mon &= 0x1f; | 130 | tm->tm_mday &= 0x3F; |
131 | tm->tm_wday &= 0x07; /* Not coded in BCD. */ | ||
132 | tm->tm_mon &= 0x1F; | ||
117 | 133 | ||
118 | BCD_TO_BIN(tm->tm_sec); | 134 | BCD_TO_BIN(tm->tm_sec); |
119 | BCD_TO_BIN(tm->tm_min); | 135 | BCD_TO_BIN(tm->tm_min); |
@@ -126,17 +142,24 @@ get_rtc_time(struct rtc_time *tm) | |||
126 | int __init | 142 | int __init |
127 | pcf8563_init(void) | 143 | pcf8563_init(void) |
128 | { | 144 | { |
129 | int ret; | 145 | static int res; |
130 | 146 | static int first = 1; | |
131 | if ((ret = i2c_init())) { | 147 | |
132 | printk(KERN_CRIT "pcf8563_init: failed to init i2c\n"); | 148 | if (!first) |
133 | return ret; | 149 | return res; |
150 | first = 0; | ||
151 | |||
152 | /* Initiate the i2c protocol. */ | ||
153 | res = i2c_init(); | ||
154 | if (res < 0) { | ||
155 | printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n"); | ||
156 | return res; | ||
134 | } | 157 | } |
135 | 158 | ||
136 | /* | 159 | /* |
137 | * First of all we need to reset the chip. This is done by | 160 | * First of all we need to reset the chip. This is done by |
138 | * clearing control1, control2 and clk freq, clear the | 161 | * clearing control1, control2 and clk freq and resetting |
139 | * Voltage Low bit, and resetting all alarms. | 162 | * all alarms. |
140 | */ | 163 | */ |
141 | if (rtc_write(RTC_CONTROL1, 0x00) < 0) | 164 | if (rtc_write(RTC_CONTROL1, 0x00) < 0) |
142 | goto err; | 165 | goto err; |
@@ -147,34 +170,36 @@ pcf8563_init(void) | |||
147 | if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) | 170 | if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0) |
148 | goto err; | 171 | goto err; |
149 | 172 | ||
150 | /* Clear the VL bit in the seconds register. */ | 173 | if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0) |
151 | ret = rtc_read(RTC_SECONDS); | ||
152 | |||
153 | if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0) | ||
154 | goto err; | 174 | goto err; |
155 | 175 | ||
156 | /* Reset the alarms. */ | 176 | /* Reset the alarms. */ |
157 | if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0) | 177 | if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0) |
158 | goto err; | 178 | goto err; |
159 | 179 | ||
160 | if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0) | 180 | if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0) |
161 | goto err; | 181 | goto err; |
162 | 182 | ||
163 | if (rtc_write(RTC_DAY_ALARM, 0x00) < 0) | 183 | if (rtc_write(RTC_DAY_ALARM, 0x80) < 0) |
164 | goto err; | 184 | goto err; |
165 | 185 | ||
166 | if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0) | 186 | if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) |
167 | goto err; | 187 | goto err; |
168 | 188 | ||
169 | /* Check for low voltage, and warn about it.. */ | 189 | /* Check for low voltage, and warn about it. */ |
170 | if (rtc_read(RTC_SECONDS) & 0x80) | 190 | if (rtc_read(RTC_SECONDS) & 0x80) { |
171 | printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME); | 191 | voltage_low = 1; |
172 | 192 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable " | |
173 | return 0; | 193 | "date/time information is no longer guaranteed!\n", |
194 | PCF8563_NAME); | ||
195 | } | ||
196 | |||
197 | return res; | ||
174 | 198 | ||
175 | err: | 199 | err: |
176 | printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); | 200 | printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); |
177 | return -1; | 201 | res = -1; |
202 | return res; | ||
178 | } | 203 | } |
179 | 204 | ||
180 | void __exit | 205 | void __exit |
@@ -187,8 +212,8 @@ pcf8563_exit(void) | |||
187 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because | 212 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because |
188 | * POSIX says so! | 213 | * POSIX says so! |
189 | */ | 214 | */ |
190 | int | 215 | int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, |
191 | pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) | 216 | unsigned long arg) |
192 | { | 217 | { |
193 | /* Some sanity checks. */ | 218 | /* Some sanity checks. */ |
194 | if (_IOC_TYPE(cmd) != RTC_MAGIC) | 219 | if (_IOC_TYPE(cmd) != RTC_MAGIC) |
@@ -198,124 +223,146 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
198 | return -ENOTTY; | 223 | return -ENOTTY; |
199 | 224 | ||
200 | switch (cmd) { | 225 | switch (cmd) { |
201 | case RTC_RD_TIME: | 226 | case RTC_RD_TIME: |
202 | { | 227 | { |
203 | struct rtc_time tm; | 228 | struct rtc_time tm; |
204 | |||
205 | spin_lock(&rtc_lock); | ||
206 | get_rtc_time(&tm); | ||
207 | |||
208 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) { | ||
209 | spin_unlock(&rtc_lock); | ||
210 | return -EFAULT; | ||
211 | } | ||
212 | |||
213 | spin_unlock(&rtc_lock); | ||
214 | return 0; | ||
215 | } | ||
216 | break; | ||
217 | case RTC_SET_TIME: | ||
218 | { | ||
219 | #ifdef CONFIG_ETRAX_RTC_READONLY | ||
220 | return -EPERM; | ||
221 | #else | ||
222 | int leap; | ||
223 | int century; | ||
224 | struct rtc_time tm; | ||
225 | |||
226 | memset(&tm, 0, sizeof (struct rtc_time)); | ||
227 | if (!capable(CAP_SYS_TIME)) | ||
228 | return -EPERM; | ||
229 | |||
230 | if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time))) | ||
231 | return -EFAULT; | ||
232 | |||
233 | /* Convert from struct tm to struct rtc_time. */ | ||
234 | tm.tm_year += 1900; | ||
235 | tm.tm_mon += 1; | ||
236 | |||
237 | leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0; | ||
238 | |||
239 | /* Perform some sanity checks. */ | ||
240 | if ((tm.tm_year < 1970) || | ||
241 | (tm.tm_mon > 12) || | ||
242 | (tm.tm_mday == 0) || | ||
243 | (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || | ||
244 | (tm.tm_hour >= 24) || | ||
245 | (tm.tm_min >= 60) || | ||
246 | (tm.tm_sec >= 60)) | ||
247 | return -EINVAL; | ||
248 | |||
249 | century = (tm.tm_year >= 2000) ? 0x80 : 0; | ||
250 | tm.tm_year = tm.tm_year % 100; | ||
251 | |||
252 | BIN_TO_BCD(tm.tm_year); | ||
253 | BIN_TO_BCD(tm.tm_mday); | ||
254 | BIN_TO_BCD(tm.tm_hour); | ||
255 | BIN_TO_BCD(tm.tm_min); | ||
256 | BIN_TO_BCD(tm.tm_sec); | ||
257 | tm.tm_mon |= century; | ||
258 | |||
259 | spin_lock(&rtc_lock); | ||
260 | |||
261 | rtc_write(RTC_YEAR, tm.tm_year); | ||
262 | rtc_write(RTC_MONTH, tm.tm_mon); | ||
263 | rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); | ||
264 | rtc_write(RTC_HOURS, tm.tm_hour); | ||
265 | rtc_write(RTC_MINUTES, tm.tm_min); | ||
266 | rtc_write(RTC_SECONDS, tm.tm_sec); | ||
267 | |||
268 | spin_unlock(&rtc_lock); | ||
269 | |||
270 | return 0; | ||
271 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ | ||
272 | } | ||
273 | |||
274 | case RTC_VLOW_RD: | ||
275 | { | ||
276 | int vl_bit = 0; | ||
277 | |||
278 | if (rtc_read(RTC_SECONDS) & 0x80) { | ||
279 | vl_bit = 1; | ||
280 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable " | ||
281 | "date/time information is no longer guaranteed!\n", | ||
282 | PCF8563_NAME); | ||
283 | } | ||
284 | if (copy_to_user((int *) arg, &vl_bit, sizeof(int))) | ||
285 | return -EFAULT; | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | 229 | ||
290 | case RTC_VLOW_SET: | 230 | mutex_lock(&rtc_lock); |
291 | { | 231 | memset(&tm, 0, sizeof tm); |
292 | /* Clear the VL bit in the seconds register */ | 232 | get_rtc_time(&tm); |
293 | int ret = rtc_read(RTC_SECONDS); | ||
294 | 233 | ||
295 | rtc_write(RTC_SECONDS, (ret & 0x7F)); | 234 | if (copy_to_user((struct rtc_time *) arg, &tm, |
235 | sizeof tm)) { | ||
236 | spin_unlock(&rtc_lock); | ||
237 | return -EFAULT; | ||
238 | } | ||
239 | |||
240 | mutex_unlock(&rtc_lock); | ||
296 | 241 | ||
297 | return 0; | 242 | return 0; |
243 | } | ||
244 | case RTC_SET_TIME: | ||
245 | { | ||
246 | int leap; | ||
247 | int year; | ||
248 | int century; | ||
249 | struct rtc_time tm; | ||
250 | |||
251 | memset(&tm, 0, sizeof tm); | ||
252 | if (!capable(CAP_SYS_TIME)) | ||
253 | return -EPERM; | ||
254 | |||
255 | if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm)) | ||
256 | return -EFAULT; | ||
257 | |||
258 | /* Convert from struct tm to struct rtc_time. */ | ||
259 | tm.tm_year += 1900; | ||
260 | tm.tm_mon += 1; | ||
261 | |||
262 | /* | ||
263 | * Check if tm.tm_year is a leap year. A year is a leap | ||
264 | * year if it is divisible by 4 but not 100, except | ||
265 | * that years divisible by 400 _are_ leap years. | ||
266 | */ | ||
267 | year = tm.tm_year; | ||
268 | leap = (tm.tm_mon == 2) && | ||
269 | ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); | ||
270 | |||
271 | /* Perform some sanity checks. */ | ||
272 | if ((tm.tm_year < 1970) || | ||
273 | (tm.tm_mon > 12) || | ||
274 | (tm.tm_mday == 0) || | ||
275 | (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || | ||
276 | (tm.tm_wday >= 7) || | ||
277 | (tm.tm_hour >= 24) || | ||
278 | (tm.tm_min >= 60) || | ||
279 | (tm.tm_sec >= 60)) | ||
280 | return -EINVAL; | ||
281 | |||
282 | century = (tm.tm_year >= 2000) ? 0x80 : 0; | ||
283 | tm.tm_year = tm.tm_year % 100; | ||
284 | |||
285 | BIN_TO_BCD(tm.tm_year); | ||
286 | BIN_TO_BCD(tm.tm_mon); | ||
287 | BIN_TO_BCD(tm.tm_mday); | ||
288 | BIN_TO_BCD(tm.tm_hour); | ||
289 | BIN_TO_BCD(tm.tm_min); | ||
290 | BIN_TO_BCD(tm.tm_sec); | ||
291 | tm.tm_mon |= century; | ||
292 | |||
293 | mutex_lock(&rtc_lock); | ||
294 | |||
295 | rtc_write(RTC_YEAR, tm.tm_year); | ||
296 | rtc_write(RTC_MONTH, tm.tm_mon); | ||
297 | rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ | ||
298 | rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); | ||
299 | rtc_write(RTC_HOURS, tm.tm_hour); | ||
300 | rtc_write(RTC_MINUTES, tm.tm_min); | ||
301 | rtc_write(RTC_SECONDS, tm.tm_sec); | ||
302 | |||
303 | mutex_unlock(&rtc_lock); | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | case RTC_VL_READ: | ||
308 | if (voltage_low) { | ||
309 | printk(KERN_ERR "%s: RTC Voltage Low - " | ||
310 | "reliable date/time information is no " | ||
311 | "longer guaranteed!\n", PCF8563_NAME); | ||
298 | } | 312 | } |
299 | 313 | ||
300 | default: | 314 | if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) |
301 | return -ENOTTY; | 315 | return -EFAULT; |
316 | return 0; | ||
317 | |||
318 | case RTC_VL_CLR: | ||
319 | { | ||
320 | /* Clear the VL bit in the seconds register in case | ||
321 | * the time has not been set already (which would | ||
322 | * have cleared it). This does not really matter | ||
323 | * because of the cached voltage_low value but do it | ||
324 | * anyway for consistency. */ | ||
325 | |||
326 | int ret = rtc_read(RTC_SECONDS); | ||
327 | |||
328 | rtc_write(RTC_SECONDS, (ret & 0x7F)); | ||
329 | |||
330 | /* Clear the cached value. */ | ||
331 | voltage_low = 0; | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | default: | ||
336 | return -ENOTTY; | ||
302 | } | 337 | } |
303 | 338 | ||
304 | return 0; | 339 | return 0; |
305 | } | 340 | } |
306 | 341 | ||
307 | static int __init | 342 | static int __init pcf8563_register(void) |
308 | pcf8563_register(void) | ||
309 | { | 343 | { |
310 | pcf8563_init(); | 344 | if (pcf8563_init() < 0) { |
345 | printk(KERN_INFO "%s: Unable to initialize Real-Time Clock " | ||
346 | "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); | ||
347 | return -1; | ||
348 | } | ||
349 | |||
311 | if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { | 350 | if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { |
312 | printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n", | 351 | printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n", |
313 | PCF8563_NAME, PCF8563_MAJOR); | 352 | PCF8563_NAME, PCF8563_MAJOR); |
314 | return -1; | 353 | return -1; |
315 | } | 354 | } |
316 | 355 | ||
317 | printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); | 356 | printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, |
318 | return 0; | 357 | DRIVER_VERSION); |
358 | |||
359 | /* Check for low voltage, and warn about it. */ | ||
360 | if (voltage_low) { | ||
361 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " | ||
362 | "information is no longer guaranteed!\n", PCF8563_NAME); | ||
363 | } | ||
364 | |||
365 | return 0; | ||
319 | } | 366 | } |
320 | 367 | ||
321 | module_init(pcf8563_register); | 368 | module_init(pcf8563_register); |
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c new file mode 100644 index 000000000000..069546e342c5 --- /dev/null +++ b/arch/cris/arch-v10/drivers/sync_serial.c | |||
@@ -0,0 +1,1441 @@ | |||
1 | /* | ||
2 | * Simple synchronous serial port driver for ETRAX 100LX. | ||
3 | * | ||
4 | * Synchronous serial ports are used for continuous streamed data like audio. | ||
5 | * The default setting for this driver is compatible with the STA 013 MP3 | ||
6 | * decoder. The driver can easily be tuned to fit other audio encoder/decoders | ||
7 | * and SPI | ||
8 | * | ||
9 | * Copyright (c) 2001-2008 Axis Communications AB | ||
10 | * | ||
11 | * Author: Mikael Starvik, Johan Adolfsson | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/major.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/poll.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/timer.h> | ||
25 | #include <asm/irq.h> | ||
26 | #include <asm/dma.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/arch/svinto.h> | ||
29 | #include <asm/uaccess.h> | ||
30 | #include <asm/system.h> | ||
31 | #include <asm/sync_serial.h> | ||
32 | #include <asm/arch/io_interface_mux.h> | ||
33 | |||
34 | /* The receiver is a bit tricky beacuse of the continuous stream of data.*/ | ||
35 | /* */ | ||
36 | /* Three DMA descriptors are linked together. Each DMA descriptor is */ | ||
37 | /* responsible for port->bufchunk of a common buffer. */ | ||
38 | /* */ | ||
39 | /* +---------------------------------------------+ */ | ||
40 | /* | +----------+ +----------+ +----------+ | */ | ||
41 | /* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+ */ | ||
42 | /* +----------+ +----------+ +----------+ */ | ||
43 | /* | | | */ | ||
44 | /* v v v */ | ||
45 | /* +-------------------------------------+ */ | ||
46 | /* | BUFFER | */ | ||
47 | /* +-------------------------------------+ */ | ||
48 | /* |<- data_avail ->| */ | ||
49 | /* readp writep */ | ||
50 | /* */ | ||
51 | /* If the application keeps up the pace readp will be right after writep.*/ | ||
52 | /* If the application can't keep the pace we have to throw away data. */ | ||
53 | /* The idea is that readp should be ready with the data pointed out by */ | ||
54 | /* Descr[i] when the DMA has filled in Descr[i+1]. */ | ||
55 | /* Otherwise we will discard */ | ||
56 | /* the rest of the data pointed out by Descr1 and set readp to the start */ | ||
57 | /* of Descr2 */ | ||
58 | |||
59 | #define SYNC_SERIAL_MAJOR 125 | ||
60 | |||
61 | /* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */ | ||
62 | /* words can be handled */ | ||
63 | #define IN_BUFFER_SIZE 12288 | ||
64 | #define IN_DESCR_SIZE 256 | ||
65 | #define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE) | ||
66 | #define OUT_BUFFER_SIZE 4096 | ||
67 | |||
68 | #define DEFAULT_FRAME_RATE 0 | ||
69 | #define DEFAULT_WORD_RATE 7 | ||
70 | |||
71 | /* NOTE: Enabling some debug will likely cause overrun or underrun, | ||
72 | * especially if manual mode is use. | ||
73 | */ | ||
74 | #define DEBUG(x) | ||
75 | #define DEBUGREAD(x) | ||
76 | #define DEBUGWRITE(x) | ||
77 | #define DEBUGPOLL(x) | ||
78 | #define DEBUGRXINT(x) | ||
79 | #define DEBUGTXINT(x) | ||
80 | |||
81 | /* Define some macros to access ETRAX 100 registers */ | ||
82 | #define SETF(var, reg, field, val) \ | ||
83 | do { \ | ||
84 | var = (var & ~IO_MASK_(reg##_, field##_)) | \ | ||
85 | IO_FIELD_(reg##_, field##_, val); \ | ||
86 | } while (0) | ||
87 | |||
88 | #define SETS(var, reg, field, val) \ | ||
89 | do { \ | ||
90 | var = (var & ~IO_MASK_(reg##_, field##_)) | \ | ||
91 | IO_STATE_(reg##_, field##_, _##val); \ | ||
92 | } while (0) | ||
93 | |||
94 | struct sync_port { | ||
95 | /* Etrax registers and bits*/ | ||
96 | const volatile unsigned *const status; | ||
97 | volatile unsigned *const ctrl_data; | ||
98 | volatile unsigned *const output_dma_first; | ||
99 | volatile unsigned char *const output_dma_cmd; | ||
100 | volatile unsigned char *const output_dma_clr_irq; | ||
101 | volatile unsigned *const input_dma_first; | ||
102 | volatile unsigned char *const input_dma_cmd; | ||
103 | volatile unsigned *const input_dma_descr; | ||
104 | /* 8*4 */ | ||
105 | volatile unsigned char *const input_dma_clr_irq; | ||
106 | volatile unsigned *const data_out; | ||
107 | const volatile unsigned *const data_in; | ||
108 | char data_avail_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ | ||
109 | char transmitter_ready_bit; /* In R_IRQ_MASK1_RD/SET/CLR */ | ||
110 | char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */ | ||
111 | |||
112 | char output_dma_bit; /* In R_IRQ_MASK2_RD */ | ||
113 | /* End of fields initialised in array */ | ||
114 | char started; /* 1 if port has been started */ | ||
115 | char port_nbr; /* Port 0 or 1 */ | ||
116 | char busy; /* 1 if port is busy */ | ||
117 | |||
118 | char enabled; /* 1 if port is enabled */ | ||
119 | char use_dma; /* 1 if port uses dma */ | ||
120 | char tr_running; | ||
121 | |||
122 | char init_irqs; | ||
123 | |||
124 | /* Register shadow */ | ||
125 | unsigned int ctrl_data_shadow; | ||
126 | /* Remaining bytes for current transfer */ | ||
127 | volatile unsigned int out_count; | ||
128 | /* Current position in out_buffer */ | ||
129 | unsigned char *outp; | ||
130 | /* 16*4 */ | ||
131 | /* Next byte to be read by application */ | ||
132 | volatile unsigned char *volatile readp; | ||
133 | /* Next byte to be written by etrax */ | ||
134 | volatile unsigned char *volatile writep; | ||
135 | |||
136 | unsigned int in_buffer_size; | ||
137 | unsigned int inbufchunk; | ||
138 | struct etrax_dma_descr out_descr __attribute__ ((aligned(32))); | ||
139 | struct etrax_dma_descr in_descr[NUM_IN_DESCR] __attribute__ ((aligned(32))); | ||
140 | unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32))); | ||
141 | unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32))); | ||
142 | unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32))); | ||
143 | struct etrax_dma_descr *next_rx_desc; | ||
144 | struct etrax_dma_descr *prev_rx_desc; | ||
145 | int full; | ||
146 | |||
147 | wait_queue_head_t out_wait_q; | ||
148 | wait_queue_head_t in_wait_q; | ||
149 | }; | ||
150 | |||
151 | |||
152 | static int etrax_sync_serial_init(void); | ||
153 | static void initialize_port(int portnbr); | ||
154 | static inline int sync_data_avail(struct sync_port *port); | ||
155 | |||
156 | static int sync_serial_open(struct inode *inode, struct file *file); | ||
157 | static int sync_serial_release(struct inode *inode, struct file *file); | ||
158 | static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); | ||
159 | |||
160 | static int sync_serial_ioctl(struct inode *inode, struct file *file, | ||
161 | unsigned int cmd, unsigned long arg); | ||
162 | static ssize_t sync_serial_write(struct file *file, const char *buf, | ||
163 | size_t count, loff_t *ppos); | ||
164 | static ssize_t sync_serial_read(struct file *file, char *buf, | ||
165 | size_t count, loff_t *ppos); | ||
166 | |||
167 | #if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ | ||
168 | defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ | ||
169 | (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ | ||
170 | defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))) | ||
171 | #define SYNC_SER_DMA | ||
172 | #endif | ||
173 | |||
174 | static void send_word(struct sync_port *port); | ||
175 | static void start_dma(struct sync_port *port, const char *data, int count); | ||
176 | static void start_dma_in(struct sync_port *port); | ||
177 | #ifdef SYNC_SER_DMA | ||
178 | static irqreturn_t tr_interrupt(int irq, void *dev_id); | ||
179 | static irqreturn_t rx_interrupt(int irq, void *dev_id); | ||
180 | #endif | ||
181 | #if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ | ||
182 | !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ | ||
183 | (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ | ||
184 | !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))) | ||
185 | #define SYNC_SER_MANUAL | ||
186 | #endif | ||
187 | #ifdef SYNC_SER_MANUAL | ||
188 | static irqreturn_t manual_interrupt(int irq, void *dev_id); | ||
189 | #endif | ||
190 | |||
191 | /* The ports */ | ||
192 | static struct sync_port ports[] = { | ||
193 | { | ||
194 | .status = R_SYNC_SERIAL1_STATUS, | ||
195 | .ctrl_data = R_SYNC_SERIAL1_CTRL, | ||
196 | .output_dma_first = R_DMA_CH8_FIRST, | ||
197 | .output_dma_cmd = R_DMA_CH8_CMD, | ||
198 | .output_dma_clr_irq = R_DMA_CH8_CLR_INTR, | ||
199 | .input_dma_first = R_DMA_CH9_FIRST, | ||
200 | .input_dma_cmd = R_DMA_CH9_CMD, | ||
201 | .input_dma_descr = R_DMA_CH9_DESCR, | ||
202 | .input_dma_clr_irq = R_DMA_CH9_CLR_INTR, | ||
203 | .data_out = R_SYNC_SERIAL1_TR_DATA, | ||
204 | .data_in = R_SYNC_SERIAL1_REC_DATA, | ||
205 | .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_data), | ||
206 | .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser1_ready), | ||
207 | .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma9_descr), | ||
208 | .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma8_eop), | ||
209 | .init_irqs = 1, | ||
210 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA) | ||
211 | .use_dma = 1, | ||
212 | #else | ||
213 | .use_dma = 0, | ||
214 | #endif | ||
215 | }, | ||
216 | { | ||
217 | .status = R_SYNC_SERIAL3_STATUS, | ||
218 | .ctrl_data = R_SYNC_SERIAL3_CTRL, | ||
219 | .output_dma_first = R_DMA_CH4_FIRST, | ||
220 | .output_dma_cmd = R_DMA_CH4_CMD, | ||
221 | .output_dma_clr_irq = R_DMA_CH4_CLR_INTR, | ||
222 | .input_dma_first = R_DMA_CH5_FIRST, | ||
223 | .input_dma_cmd = R_DMA_CH5_CMD, | ||
224 | .input_dma_descr = R_DMA_CH5_DESCR, | ||
225 | .input_dma_clr_irq = R_DMA_CH5_CLR_INTR, | ||
226 | .data_out = R_SYNC_SERIAL3_TR_DATA, | ||
227 | .data_in = R_SYNC_SERIAL3_REC_DATA, | ||
228 | .data_avail_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_data), | ||
229 | .transmitter_ready_bit = IO_BITNR(R_IRQ_MASK1_RD, ser3_ready), | ||
230 | .input_dma_descr_bit = IO_BITNR(R_IRQ_MASK2_RD, dma5_descr), | ||
231 | .output_dma_bit = IO_BITNR(R_IRQ_MASK2_RD, dma4_eop), | ||
232 | .init_irqs = 1, | ||
233 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA) | ||
234 | .use_dma = 1, | ||
235 | #else | ||
236 | .use_dma = 0, | ||
237 | #endif | ||
238 | } | ||
239 | }; | ||
240 | |||
241 | /* Register shadows */ | ||
242 | static unsigned sync_serial_prescale_shadow; | ||
243 | |||
244 | #define NUMBER_OF_PORTS 2 | ||
245 | |||
246 | static struct file_operations sync_serial_fops = { | ||
247 | .owner = THIS_MODULE, | ||
248 | .write = sync_serial_write, | ||
249 | .read = sync_serial_read, | ||
250 | .poll = sync_serial_poll, | ||
251 | .ioctl = sync_serial_ioctl, | ||
252 | .open = sync_serial_open, | ||
253 | .release = sync_serial_release | ||
254 | }; | ||
255 | |||
256 | static int __init etrax_sync_serial_init(void) | ||
257 | { | ||
258 | ports[0].enabled = 0; | ||
259 | ports[1].enabled = 0; | ||
260 | |||
261 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) | ||
262 | if (cris_request_io_interface(if_sync_serial_1, "sync_ser1")) { | ||
263 | printk(KERN_CRIT "ETRAX100LX sync_serial: " | ||
264 | "Could not allocate IO group for port %d\n", 0); | ||
265 | return -EBUSY; | ||
266 | } | ||
267 | #endif | ||
268 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) | ||
269 | if (cris_request_io_interface(if_sync_serial_3, "sync_ser3")) { | ||
270 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) | ||
271 | cris_free_io_interface(if_sync_serial_1); | ||
272 | #endif | ||
273 | printk(KERN_CRIT "ETRAX100LX sync_serial: " | ||
274 | "Could not allocate IO group for port %d\n", 1); | ||
275 | return -EBUSY; | ||
276 | } | ||
277 | #endif | ||
278 | |||
279 | if (register_chrdev(SYNC_SERIAL_MAJOR, "sync serial", | ||
280 | &sync_serial_fops) < 0) { | ||
281 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) | ||
282 | cris_free_io_interface(if_sync_serial_3); | ||
283 | #endif | ||
284 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) | ||
285 | cris_free_io_interface(if_sync_serial_1); | ||
286 | #endif | ||
287 | printk("unable to get major for synchronous serial port\n"); | ||
288 | return -EBUSY; | ||
289 | } | ||
290 | |||
291 | /* Deselect synchronous serial ports while configuring. */ | ||
292 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async); | ||
293 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async); | ||
294 | *R_GEN_CONFIG_II = gen_config_ii_shadow; | ||
295 | |||
296 | /* Initialize Ports */ | ||
297 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) | ||
298 | ports[0].enabled = 1; | ||
299 | SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra); | ||
300 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync); | ||
301 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA) | ||
302 | ports[0].use_dma = 1; | ||
303 | #else | ||
304 | ports[0].use_dma = 0; | ||
305 | #endif | ||
306 | initialize_port(0); | ||
307 | #endif | ||
308 | |||
309 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) | ||
310 | ports[1].enabled = 1; | ||
311 | SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser3, ss3extra); | ||
312 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync); | ||
313 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA) | ||
314 | ports[1].use_dma = 1; | ||
315 | #else | ||
316 | ports[1].use_dma = 0; | ||
317 | #endif | ||
318 | initialize_port(1); | ||
319 | #endif | ||
320 | |||
321 | *R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */ | ||
322 | |||
323 | /* Set up timing */ | ||
324 | *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow = ( | ||
325 | IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec) | | ||
326 | IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u1, external) | | ||
327 | IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) | | ||
328 | IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) | | ||
329 | IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) | | ||
330 | IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate, | ||
331 | DEFAULT_FRAME_RATE) | | ||
332 | IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, DEFAULT_WORD_RATE) | | ||
333 | IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal)); | ||
334 | |||
335 | /* Select synchronous ports */ | ||
336 | *R_GEN_CONFIG_II = gen_config_ii_shadow; | ||
337 | |||
338 | printk(KERN_INFO "ETRAX 100LX synchronous serial port driver\n"); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static void __init initialize_port(int portnbr) | ||
343 | { | ||
344 | struct sync_port *port = &ports[portnbr]; | ||
345 | |||
346 | DEBUG(printk(KERN_DEBUG "Init sync serial port %d\n", portnbr)); | ||
347 | |||
348 | port->started = 0; | ||
349 | port->port_nbr = portnbr; | ||
350 | port->busy = 0; | ||
351 | port->tr_running = 0; | ||
352 | |||
353 | port->out_count = 0; | ||
354 | port->outp = port->out_buffer; | ||
355 | |||
356 | port->readp = port->flip; | ||
357 | port->writep = port->flip; | ||
358 | port->in_buffer_size = IN_BUFFER_SIZE; | ||
359 | port->inbufchunk = IN_DESCR_SIZE; | ||
360 | port->next_rx_desc = &port->in_descr[0]; | ||
361 | port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1]; | ||
362 | port->prev_rx_desc->ctrl = d_eol; | ||
363 | |||
364 | init_waitqueue_head(&port->out_wait_q); | ||
365 | init_waitqueue_head(&port->in_wait_q); | ||
366 | |||
367 | port->ctrl_data_shadow = | ||
368 | IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz) | | ||
369 | IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | | ||
370 | IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore) | | ||
371 | IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) | | ||
372 | IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal) | | ||
373 | IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word) | | ||
374 | IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on) | | ||
375 | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal) | | ||
376 | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped) | | ||
377 | IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb) | | ||
378 | IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable) | | ||
379 | IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit) | | ||
380 | IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8) | | ||
381 | IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8) | | ||
382 | IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled) | | ||
383 | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg) | | ||
384 | IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)| | ||
385 | IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)| | ||
386 | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal) | | ||
387 | IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) | | ||
388 | IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)| | ||
389 | IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high); | ||
390 | |||
391 | if (port->use_dma) | ||
392 | port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, | ||
393 | dma_enable, on); | ||
394 | else | ||
395 | port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, | ||
396 | dma_enable, off); | ||
397 | |||
398 | *port->ctrl_data = port->ctrl_data_shadow; | ||
399 | } | ||
400 | |||
401 | static inline int sync_data_avail(struct sync_port *port) | ||
402 | { | ||
403 | int avail; | ||
404 | unsigned char *start; | ||
405 | unsigned char *end; | ||
406 | |||
407 | start = (unsigned char *)port->readp; /* cast away volatile */ | ||
408 | end = (unsigned char *)port->writep; /* cast away volatile */ | ||
409 | /* 0123456789 0123456789 | ||
410 | * ----- - ----- | ||
411 | * ^rp ^wp ^wp ^rp | ||
412 | */ | ||
413 | if (end >= start) | ||
414 | avail = end - start; | ||
415 | else | ||
416 | avail = port->in_buffer_size - (start - end); | ||
417 | return avail; | ||
418 | } | ||
419 | |||
420 | static inline int sync_data_avail_to_end(struct sync_port *port) | ||
421 | { | ||
422 | int avail; | ||
423 | unsigned char *start; | ||
424 | unsigned char *end; | ||
425 | |||
426 | start = (unsigned char *)port->readp; /* cast away volatile */ | ||
427 | end = (unsigned char *)port->writep; /* cast away volatile */ | ||
428 | /* 0123456789 0123456789 | ||
429 | * ----- ----- | ||
430 | * ^rp ^wp ^wp ^rp | ||
431 | */ | ||
432 | |||
433 | if (end >= start) | ||
434 | avail = end - start; | ||
435 | else | ||
436 | avail = port->flip + port->in_buffer_size - start; | ||
437 | return avail; | ||
438 | } | ||
439 | |||
440 | |||
441 | static int sync_serial_open(struct inode *inode, struct file *file) | ||
442 | { | ||
443 | int dev = MINOR(inode->i_rdev); | ||
444 | struct sync_port *port; | ||
445 | int mode; | ||
446 | |||
447 | DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); | ||
448 | |||
449 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { | ||
450 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); | ||
451 | return -ENODEV; | ||
452 | } | ||
453 | port = &ports[dev]; | ||
454 | /* Allow open this device twice (assuming one reader and one writer) */ | ||
455 | if (port->busy == 2) { | ||
456 | DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); | ||
457 | return -EBUSY; | ||
458 | } | ||
459 | if (port->init_irqs) { | ||
460 | if (port->use_dma) { | ||
461 | if (port == &ports[0]) { | ||
462 | #ifdef SYNC_SER_DMA | ||
463 | if (request_irq(24, tr_interrupt, 0, | ||
464 | "synchronous serial 1 dma tr", | ||
465 | &ports[0])) { | ||
466 | printk(KERN_CRIT "Can't alloc " | ||
467 | "sync serial port 1 IRQ"); | ||
468 | return -EBUSY; | ||
469 | } else if (request_irq(25, rx_interrupt, 0, | ||
470 | "synchronous serial 1 dma rx", | ||
471 | &ports[0])) { | ||
472 | free_irq(24, &port[0]); | ||
473 | printk(KERN_CRIT "Can't alloc " | ||
474 | "sync serial port 1 IRQ"); | ||
475 | return -EBUSY; | ||
476 | } else if (cris_request_dma(8, | ||
477 | "synchronous serial 1 dma tr", | ||
478 | DMA_VERBOSE_ON_ERROR, | ||
479 | dma_ser1)) { | ||
480 | free_irq(24, &port[0]); | ||
481 | free_irq(25, &port[0]); | ||
482 | printk(KERN_CRIT "Can't alloc " | ||
483 | "sync serial port 1 " | ||
484 | "TX DMA channel"); | ||
485 | return -EBUSY; | ||
486 | } else if (cris_request_dma(9, | ||
487 | "synchronous serial 1 dma rec", | ||
488 | DMA_VERBOSE_ON_ERROR, | ||
489 | dma_ser1)) { | ||
490 | cris_free_dma(8, NULL); | ||
491 | free_irq(24, &port[0]); | ||
492 | free_irq(25, &port[0]); | ||
493 | printk(KERN_CRIT "Can't alloc " | ||
494 | "sync serial port 1 " | ||
495 | "RX DMA channel"); | ||
496 | return -EBUSY; | ||
497 | } | ||
498 | #endif | ||
499 | RESET_DMA(8); WAIT_DMA(8); | ||
500 | RESET_DMA(9); WAIT_DMA(9); | ||
501 | *R_DMA_CH8_CLR_INTR = | ||
502 | IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, | ||
503 | do) | | ||
504 | IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, | ||
505 | do); | ||
506 | *R_DMA_CH9_CLR_INTR = | ||
507 | IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, | ||
508 | do) | | ||
509 | IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr, | ||
510 | do); | ||
511 | *R_IRQ_MASK2_SET = | ||
512 | IO_STATE(R_IRQ_MASK2_SET, dma8_eop, | ||
513 | set) | | ||
514 | IO_STATE(R_IRQ_MASK2_SET, dma9_descr, | ||
515 | set); | ||
516 | } else if (port == &ports[1]) { | ||
517 | #ifdef SYNC_SER_DMA | ||
518 | if (request_irq(20, tr_interrupt, 0, | ||
519 | "synchronous serial 3 dma tr", | ||
520 | &ports[1])) { | ||
521 | printk(KERN_CRIT "Can't alloc " | ||
522 | "sync serial port 3 IRQ"); | ||
523 | return -EBUSY; | ||
524 | } else if (request_irq(21, rx_interrupt, 0, | ||
525 | "synchronous serial 3 dma rx", | ||
526 | &ports[1])) { | ||
527 | free_irq(20, &ports[1]); | ||
528 | printk(KERN_CRIT "Can't alloc " | ||
529 | "sync serial port 3 IRQ"); | ||
530 | return -EBUSY; | ||
531 | } else if (cris_request_dma(4, | ||
532 | "synchronous serial 3 dma tr", | ||
533 | DMA_VERBOSE_ON_ERROR, | ||
534 | dma_ser3)) { | ||
535 | free_irq(21, &ports[1]); | ||
536 | free_irq(20, &ports[1]); | ||
537 | printk(KERN_CRIT "Can't alloc " | ||
538 | "sync serial port 3 " | ||
539 | "TX DMA channel"); | ||
540 | return -EBUSY; | ||
541 | } else if (cris_request_dma(5, | ||
542 | "synchronous serial 3 dma rec", | ||
543 | DMA_VERBOSE_ON_ERROR, | ||
544 | dma_ser3)) { | ||
545 | cris_free_dma(4, NULL); | ||
546 | free_irq(21, &ports[1]); | ||
547 | free_irq(20, &ports[1]); | ||
548 | printk(KERN_CRIT "Can't alloc " | ||
549 | "sync serial port 3 " | ||
550 | "RX DMA channel"); | ||
551 | return -EBUSY; | ||
552 | } | ||
553 | #endif | ||
554 | RESET_DMA(4); WAIT_DMA(4); | ||
555 | RESET_DMA(5); WAIT_DMA(5); | ||
556 | *R_DMA_CH4_CLR_INTR = | ||
557 | IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, | ||
558 | do) | | ||
559 | IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, | ||
560 | do); | ||
561 | *R_DMA_CH5_CLR_INTR = | ||
562 | IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop, | ||
563 | do) | | ||
564 | IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr, | ||
565 | do); | ||
566 | *R_IRQ_MASK2_SET = | ||
567 | IO_STATE(R_IRQ_MASK2_SET, dma4_eop, | ||
568 | set) | | ||
569 | IO_STATE(R_IRQ_MASK2_SET, dma5_descr, | ||
570 | set); | ||
571 | } | ||
572 | start_dma_in(port); | ||
573 | port->init_irqs = 0; | ||
574 | } else { /* !port->use_dma */ | ||
575 | #ifdef SYNC_SER_MANUAL | ||
576 | if (port == &ports[0]) { | ||
577 | if (request_irq(8, | ||
578 | manual_interrupt, | ||
579 | IRQF_SHARED | IRQF_DISABLED, | ||
580 | "synchronous serial manual irq", | ||
581 | &ports[0])) { | ||
582 | printk(KERN_CRIT "Can't alloc " | ||
583 | "sync serial manual irq"); | ||
584 | return -EBUSY; | ||
585 | } | ||
586 | } else if (port == &ports[1]) { | ||
587 | if (request_irq(8, | ||
588 | manual_interrupt, | ||
589 | IRQF_SHARED | IRQF_DISABLED, | ||
590 | "synchronous serial manual irq", | ||
591 | &ports[1])) { | ||
592 | printk(KERN_CRIT "Can't alloc " | ||
593 | "sync serial manual irq"); | ||
594 | return -EBUSY; | ||
595 | } | ||
596 | } | ||
597 | port->init_irqs = 0; | ||
598 | #else | ||
599 | panic("sync_serial: Manual mode not supported.\n"); | ||
600 | #endif /* SYNC_SER_MANUAL */ | ||
601 | } | ||
602 | } /* port->init_irqs */ | ||
603 | |||
604 | port->busy++; | ||
605 | /* Start port if we use it as input */ | ||
606 | mode = IO_EXTRACT(R_SYNC_SERIAL1_CTRL, mode, port->ctrl_data_shadow); | ||
607 | if (mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_input) || | ||
608 | mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_input) || | ||
609 | mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, master_bidir) || | ||
610 | mode == IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, mode, slave_bidir)) { | ||
611 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, | ||
612 | running); | ||
613 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, | ||
614 | enable); | ||
615 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, | ||
616 | enable); | ||
617 | port->started = 1; | ||
618 | *port->ctrl_data = port->ctrl_data_shadow; | ||
619 | if (!port->use_dma) | ||
620 | *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; | ||
621 | DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); | ||
622 | } | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int sync_serial_release(struct inode *inode, struct file *file) | ||
627 | { | ||
628 | int dev = MINOR(inode->i_rdev); | ||
629 | struct sync_port *port; | ||
630 | |||
631 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { | ||
632 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); | ||
633 | return -ENODEV; | ||
634 | } | ||
635 | port = &ports[dev]; | ||
636 | if (port->busy) | ||
637 | port->busy--; | ||
638 | if (!port->busy) | ||
639 | *R_IRQ_MASK1_CLR = ((1 << port->data_avail_bit) | | ||
640 | (1 << port->transmitter_ready_bit)); | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | |||
646 | |||
647 | static unsigned int sync_serial_poll(struct file *file, poll_table *wait) | ||
648 | { | ||
649 | int dev = MINOR(file->f_dentry->d_inode->i_rdev); | ||
650 | unsigned int mask = 0; | ||
651 | struct sync_port *port; | ||
652 | DEBUGPOLL(static unsigned int prev_mask = 0); | ||
653 | |||
654 | port = &ports[dev]; | ||
655 | poll_wait(file, &port->out_wait_q, wait); | ||
656 | poll_wait(file, &port->in_wait_q, wait); | ||
657 | /* Some room to write */ | ||
658 | if (port->out_count < OUT_BUFFER_SIZE) | ||
659 | mask |= POLLOUT | POLLWRNORM; | ||
660 | /* At least an inbufchunk of data */ | ||
661 | if (sync_data_avail(port) >= port->inbufchunk) | ||
662 | mask |= POLLIN | POLLRDNORM; | ||
663 | |||
664 | DEBUGPOLL(if (mask != prev_mask) | ||
665 | printk(KERN_DEBUG "sync_serial_poll: mask 0x%08X %s %s\n", | ||
666 | mask, | ||
667 | mask & POLLOUT ? "POLLOUT" : "", | ||
668 | mask & POLLIN ? "POLLIN" : ""); | ||
669 | prev_mask = mask; | ||
670 | ); | ||
671 | return mask; | ||
672 | } | ||
673 | |||
674 | static int sync_serial_ioctl(struct inode *inode, struct file *file, | ||
675 | unsigned int cmd, unsigned long arg) | ||
676 | { | ||
677 | int return_val = 0; | ||
678 | unsigned long flags; | ||
679 | |||
680 | int dev = MINOR(file->f_dentry->d_inode->i_rdev); | ||
681 | struct sync_port *port; | ||
682 | |||
683 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { | ||
684 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); | ||
685 | return -1; | ||
686 | } | ||
687 | port = &ports[dev]; | ||
688 | |||
689 | local_irq_save(flags); | ||
690 | /* Disable port while changing config */ | ||
691 | if (dev) { | ||
692 | if (port->use_dma) { | ||
693 | RESET_DMA(4); WAIT_DMA(4); | ||
694 | port->tr_running = 0; | ||
695 | port->out_count = 0; | ||
696 | port->outp = port->out_buffer; | ||
697 | *R_DMA_CH4_CLR_INTR = | ||
698 | IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | | ||
699 | IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); | ||
700 | } | ||
701 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async); | ||
702 | } else { | ||
703 | if (port->use_dma) { | ||
704 | RESET_DMA(8); WAIT_DMA(8); | ||
705 | port->tr_running = 0; | ||
706 | port->out_count = 0; | ||
707 | port->outp = port->out_buffer; | ||
708 | *R_DMA_CH8_CLR_INTR = | ||
709 | IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | | ||
710 | IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); | ||
711 | } | ||
712 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async); | ||
713 | } | ||
714 | *R_GEN_CONFIG_II = gen_config_ii_shadow; | ||
715 | local_irq_restore(flags); | ||
716 | |||
717 | switch (cmd) { | ||
718 | case SSP_SPEED: | ||
719 | if (GET_SPEED(arg) == CODEC) { | ||
720 | if (dev) | ||
721 | SETS(sync_serial_prescale_shadow, | ||
722 | R_SYNC_SERIAL_PRESCALE, clk_sel_u3, | ||
723 | codec); | ||
724 | else | ||
725 | SETS(sync_serial_prescale_shadow, | ||
726 | R_SYNC_SERIAL_PRESCALE, clk_sel_u1, | ||
727 | codec); | ||
728 | |||
729 | SETF(sync_serial_prescale_shadow, | ||
730 | R_SYNC_SERIAL_PRESCALE, prescaler, | ||
731 | GET_FREQ(arg)); | ||
732 | SETF(sync_serial_prescale_shadow, | ||
733 | R_SYNC_SERIAL_PRESCALE, frame_rate, | ||
734 | GET_FRAME_RATE(arg)); | ||
735 | SETF(sync_serial_prescale_shadow, | ||
736 | R_SYNC_SERIAL_PRESCALE, word_rate, | ||
737 | GET_WORD_RATE(arg)); | ||
738 | } else { | ||
739 | SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
740 | tr_baud, GET_SPEED(arg)); | ||
741 | if (dev) | ||
742 | SETS(sync_serial_prescale_shadow, | ||
743 | R_SYNC_SERIAL_PRESCALE, clk_sel_u3, | ||
744 | baudrate); | ||
745 | else | ||
746 | SETS(sync_serial_prescale_shadow, | ||
747 | R_SYNC_SERIAL_PRESCALE, clk_sel_u1, | ||
748 | baudrate); | ||
749 | } | ||
750 | break; | ||
751 | case SSP_MODE: | ||
752 | if (arg > 5) | ||
753 | return -EINVAL; | ||
754 | if (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT) | ||
755 | *R_IRQ_MASK1_CLR = 1 << port->data_avail_bit; | ||
756 | else if (!port->use_dma) | ||
757 | *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; | ||
758 | SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); | ||
759 | break; | ||
760 | case SSP_FRAME_SYNC: | ||
761 | if (arg & NORMAL_SYNC) | ||
762 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
763 | f_synctype, normal); | ||
764 | else if (arg & EARLY_SYNC) | ||
765 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
766 | f_synctype, early); | ||
767 | |||
768 | if (arg & BIT_SYNC) | ||
769 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
770 | f_syncsize, bit); | ||
771 | else if (arg & WORD_SYNC) | ||
772 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
773 | f_syncsize, word); | ||
774 | else if (arg & EXTENDED_SYNC) | ||
775 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
776 | f_syncsize, extended); | ||
777 | |||
778 | if (arg & SYNC_ON) | ||
779 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
780 | f_sync, on); | ||
781 | else if (arg & SYNC_OFF) | ||
782 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
783 | f_sync, off); | ||
784 | |||
785 | if (arg & WORD_SIZE_8) | ||
786 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
787 | wordsize, size8bit); | ||
788 | else if (arg & WORD_SIZE_12) | ||
789 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
790 | wordsize, size12bit); | ||
791 | else if (arg & WORD_SIZE_16) | ||
792 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
793 | wordsize, size16bit); | ||
794 | else if (arg & WORD_SIZE_24) | ||
795 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
796 | wordsize, size24bit); | ||
797 | else if (arg & WORD_SIZE_32) | ||
798 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
799 | wordsize, size32bit); | ||
800 | |||
801 | if (arg & BIT_ORDER_MSB) | ||
802 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
803 | bitorder, msb); | ||
804 | else if (arg & BIT_ORDER_LSB) | ||
805 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
806 | bitorder, lsb); | ||
807 | |||
808 | if (arg & FLOW_CONTROL_ENABLE) | ||
809 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
810 | flow_ctrl, enabled); | ||
811 | else if (arg & FLOW_CONTROL_DISABLE) | ||
812 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
813 | flow_ctrl, disabled); | ||
814 | |||
815 | if (arg & CLOCK_NOT_GATED) | ||
816 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
817 | clk_mode, normal); | ||
818 | else if (arg & CLOCK_GATED) | ||
819 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
820 | clk_mode, gated); | ||
821 | |||
822 | break; | ||
823 | case SSP_IPOLARITY: | ||
824 | /* NOTE!! negedge is considered NORMAL */ | ||
825 | if (arg & CLOCK_NORMAL) | ||
826 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
827 | clk_polarity, neg); | ||
828 | else if (arg & CLOCK_INVERT) | ||
829 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
830 | clk_polarity, pos); | ||
831 | |||
832 | if (arg & FRAME_NORMAL) | ||
833 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
834 | frame_polarity, normal); | ||
835 | else if (arg & FRAME_INVERT) | ||
836 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
837 | frame_polarity, inverted); | ||
838 | |||
839 | if (arg & STATUS_NORMAL) | ||
840 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
841 | status_polarity, normal); | ||
842 | else if (arg & STATUS_INVERT) | ||
843 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
844 | status_polarity, inverted); | ||
845 | break; | ||
846 | case SSP_OPOLARITY: | ||
847 | if (arg & CLOCK_NORMAL) | ||
848 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
849 | clk_driver, normal); | ||
850 | else if (arg & CLOCK_INVERT) | ||
851 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
852 | clk_driver, inverted); | ||
853 | |||
854 | if (arg & FRAME_NORMAL) | ||
855 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
856 | frame_driver, normal); | ||
857 | else if (arg & FRAME_INVERT) | ||
858 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
859 | frame_driver, inverted); | ||
860 | |||
861 | if (arg & STATUS_NORMAL) | ||
862 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
863 | status_driver, normal); | ||
864 | else if (arg & STATUS_INVERT) | ||
865 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
866 | status_driver, inverted); | ||
867 | break; | ||
868 | case SSP_SPI: | ||
869 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, | ||
870 | disabled); | ||
871 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, | ||
872 | msb); | ||
873 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, | ||
874 | size8bit); | ||
875 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); | ||
876 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, | ||
877 | word); | ||
878 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, | ||
879 | normal); | ||
880 | if (arg & SPI_SLAVE) { | ||
881 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
882 | frame_polarity, inverted); | ||
883 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
884 | clk_polarity, neg); | ||
885 | SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
886 | mode, SLAVE_INPUT); | ||
887 | } else { | ||
888 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
889 | frame_driver, inverted); | ||
890 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
891 | clk_driver, inverted); | ||
892 | SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, | ||
893 | mode, MASTER_OUTPUT); | ||
894 | } | ||
895 | break; | ||
896 | case SSP_INBUFCHUNK: | ||
897 | #if 0 | ||
898 | if (arg > port->in_buffer_size/NUM_IN_DESCR) | ||
899 | return -EINVAL; | ||
900 | port->inbufchunk = arg; | ||
901 | /* Make sure in_buffer_size is a multiple of inbufchunk */ | ||
902 | port->in_buffer_size = | ||
903 | (port->in_buffer_size/port->inbufchunk) * | ||
904 | port->inbufchunk; | ||
905 | DEBUG(printk(KERN_DEBUG "inbufchunk %i in_buffer_size: %i\n", | ||
906 | port->inbufchunk, port->in_buffer_size)); | ||
907 | if (port->use_dma) { | ||
908 | if (port->port_nbr == 0) { | ||
909 | RESET_DMA(9); | ||
910 | WAIT_DMA(9); | ||
911 | } else { | ||
912 | RESET_DMA(5); | ||
913 | WAIT_DMA(5); | ||
914 | } | ||
915 | start_dma_in(port); | ||
916 | } | ||
917 | #endif | ||
918 | break; | ||
919 | default: | ||
920 | return_val = -1; | ||
921 | } | ||
922 | /* Make sure we write the config without interruption */ | ||
923 | local_irq_save(flags); | ||
924 | /* Set config and enable port */ | ||
925 | *port->ctrl_data = port->ctrl_data_shadow; | ||
926 | nop(); nop(); nop(); nop(); | ||
927 | *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow; | ||
928 | nop(); nop(); nop(); nop(); | ||
929 | if (dev) | ||
930 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync); | ||
931 | else | ||
932 | SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync); | ||
933 | |||
934 | *R_GEN_CONFIG_II = gen_config_ii_shadow; | ||
935 | /* Reset DMA. At readout from serial port the data could be shifted | ||
936 | * one byte if not resetting DMA. | ||
937 | */ | ||
938 | if (port->use_dma) { | ||
939 | if (port->port_nbr == 0) { | ||
940 | RESET_DMA(9); | ||
941 | WAIT_DMA(9); | ||
942 | } else { | ||
943 | RESET_DMA(5); | ||
944 | WAIT_DMA(5); | ||
945 | } | ||
946 | start_dma_in(port); | ||
947 | } | ||
948 | local_irq_restore(flags); | ||
949 | return return_val; | ||
950 | } | ||
951 | |||
952 | |||
953 | static ssize_t sync_serial_write(struct file *file, const char *buf, | ||
954 | size_t count, loff_t *ppos) | ||
955 | { | ||
956 | int dev = MINOR(file->f_dentry->d_inode->i_rdev); | ||
957 | DECLARE_WAITQUEUE(wait, current); | ||
958 | struct sync_port *port; | ||
959 | unsigned long flags; | ||
960 | unsigned long c, c1; | ||
961 | unsigned long free_outp; | ||
962 | unsigned long outp; | ||
963 | unsigned long out_buffer; | ||
964 | |||
965 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { | ||
966 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); | ||
967 | return -ENODEV; | ||
968 | } | ||
969 | port = &ports[dev]; | ||
970 | |||
971 | DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu (%d/%d)\n", | ||
972 | port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE)); | ||
973 | /* Space to end of buffer */ | ||
974 | /* | ||
975 | * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE | ||
976 | * outp^ +out_count | ||
977 | * ^free_outp | ||
978 | * out_buffer 45<- c ->0123OUT_BUFFER_SIZE | ||
979 | * +out_count outp^ | ||
980 | * free_outp | ||
981 | * | ||
982 | */ | ||
983 | |||
984 | /* Read variables that may be updated by interrupts */ | ||
985 | local_irq_save(flags); | ||
986 | if (count > OUT_BUFFER_SIZE - port->out_count) | ||
987 | count = OUT_BUFFER_SIZE - port->out_count; | ||
988 | |||
989 | outp = (unsigned long)port->outp; | ||
990 | free_outp = outp + port->out_count; | ||
991 | local_irq_restore(flags); | ||
992 | out_buffer = (unsigned long)port->out_buffer; | ||
993 | |||
994 | /* Find out where and how much to write */ | ||
995 | if (free_outp >= out_buffer + OUT_BUFFER_SIZE) | ||
996 | free_outp -= OUT_BUFFER_SIZE; | ||
997 | if (free_outp >= outp) | ||
998 | c = out_buffer + OUT_BUFFER_SIZE - free_outp; | ||
999 | else | ||
1000 | c = outp - free_outp; | ||
1001 | if (c > count) | ||
1002 | c = count; | ||
1003 | |||
1004 | DEBUGWRITE(printk(KERN_DEBUG "w op %08lX fop %08lX c %lu\n", | ||
1005 | outp, free_outp, c)); | ||
1006 | if (copy_from_user((void *)free_outp, buf, c)) | ||
1007 | return -EFAULT; | ||
1008 | |||
1009 | if (c != count) { | ||
1010 | buf += c; | ||
1011 | c1 = count - c; | ||
1012 | DEBUGWRITE(printk(KERN_DEBUG "w2 fi %lu c %lu c1 %lu\n", | ||
1013 | free_outp-out_buffer, c, c1)); | ||
1014 | if (copy_from_user((void *)out_buffer, buf, c1)) | ||
1015 | return -EFAULT; | ||
1016 | } | ||
1017 | local_irq_save(flags); | ||
1018 | port->out_count += count; | ||
1019 | local_irq_restore(flags); | ||
1020 | |||
1021 | /* Make sure transmitter/receiver is running */ | ||
1022 | if (!port->started) { | ||
1023 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, | ||
1024 | running); | ||
1025 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, | ||
1026 | enable); | ||
1027 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, | ||
1028 | enable); | ||
1029 | port->started = 1; | ||
1030 | } | ||
1031 | |||
1032 | *port->ctrl_data = port->ctrl_data_shadow; | ||
1033 | |||
1034 | if (file->f_flags & O_NONBLOCK) { | ||
1035 | local_irq_save(flags); | ||
1036 | if (!port->tr_running) { | ||
1037 | if (!port->use_dma) { | ||
1038 | /* Start sender by writing data */ | ||
1039 | send_word(port); | ||
1040 | /* and enable transmitter ready IRQ */ | ||
1041 | *R_IRQ_MASK1_SET = 1 << | ||
1042 | port->transmitter_ready_bit; | ||
1043 | } else | ||
1044 | start_dma(port, | ||
1045 | (unsigned char *volatile)port->outp, c); | ||
1046 | } | ||
1047 | local_irq_restore(flags); | ||
1048 | DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu NB\n", | ||
1049 | port->port_nbr, count)); | ||
1050 | return count; | ||
1051 | } | ||
1052 | |||
1053 | /* Sleep until all sent */ | ||
1054 | add_wait_queue(&port->out_wait_q, &wait); | ||
1055 | set_current_state(TASK_INTERRUPTIBLE); | ||
1056 | local_irq_save(flags); | ||
1057 | if (!port->tr_running) { | ||
1058 | if (!port->use_dma) { | ||
1059 | /* Start sender by writing data */ | ||
1060 | send_word(port); | ||
1061 | /* and enable transmitter ready IRQ */ | ||
1062 | *R_IRQ_MASK1_SET = 1 << port->transmitter_ready_bit; | ||
1063 | } else | ||
1064 | start_dma(port, port->outp, c); | ||
1065 | } | ||
1066 | local_irq_restore(flags); | ||
1067 | schedule(); | ||
1068 | set_current_state(TASK_RUNNING); | ||
1069 | remove_wait_queue(&port->out_wait_q, &wait); | ||
1070 | if (signal_pending(current)) | ||
1071 | return -EINTR; | ||
1072 | |||
1073 | DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n", port->port_nbr, count)); | ||
1074 | return count; | ||
1075 | } | ||
1076 | |||
1077 | static ssize_t sync_serial_read(struct file *file, char *buf, | ||
1078 | size_t count, loff_t *ppos) | ||
1079 | { | ||
1080 | int dev = MINOR(file->f_dentry->d_inode->i_rdev); | ||
1081 | int avail; | ||
1082 | struct sync_port *port; | ||
1083 | unsigned char *start; | ||
1084 | unsigned char *end; | ||
1085 | unsigned long flags; | ||
1086 | |||
1087 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { | ||
1088 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); | ||
1089 | return -ENODEV; | ||
1090 | } | ||
1091 | port = &ports[dev]; | ||
1092 | |||
1093 | DEBUGREAD(printk(KERN_DEBUG "R%d c %d ri %lu wi %lu /%lu\n", | ||
1094 | dev, count, port->readp - port->flip, | ||
1095 | port->writep - port->flip, port->in_buffer_size)); | ||
1096 | |||
1097 | if (!port->started) { | ||
1098 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, | ||
1099 | running); | ||
1100 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, | ||
1101 | enable); | ||
1102 | SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, | ||
1103 | enable); | ||
1104 | port->started = 1; | ||
1105 | } | ||
1106 | *port->ctrl_data = port->ctrl_data_shadow; | ||
1107 | |||
1108 | /* Calculate number of available bytes */ | ||
1109 | /* Save pointers to avoid that they are modified by interrupt */ | ||
1110 | local_irq_save(flags); | ||
1111 | start = (unsigned char *)port->readp; /* cast away volatile */ | ||
1112 | end = (unsigned char *)port->writep; /* cast away volatile */ | ||
1113 | local_irq_restore(flags); | ||
1114 | while (start == end && !port->full) { | ||
1115 | /* No data */ | ||
1116 | if (file->f_flags & O_NONBLOCK) | ||
1117 | return -EAGAIN; | ||
1118 | |||
1119 | interruptible_sleep_on(&port->in_wait_q); | ||
1120 | if (signal_pending(current)) | ||
1121 | return -EINTR; | ||
1122 | |||
1123 | local_irq_save(flags); | ||
1124 | start = (unsigned char *)port->readp; /* cast away volatile */ | ||
1125 | end = (unsigned char *)port->writep; /* cast away volatile */ | ||
1126 | local_irq_restore(flags); | ||
1127 | } | ||
1128 | |||
1129 | /* Lazy read, never return wrapped data. */ | ||
1130 | if (port->full) | ||
1131 | avail = port->in_buffer_size; | ||
1132 | else if (end > start) | ||
1133 | avail = end - start; | ||
1134 | else | ||
1135 | avail = port->flip + port->in_buffer_size - start; | ||
1136 | |||
1137 | count = count > avail ? avail : count; | ||
1138 | if (copy_to_user(buf, start, count)) | ||
1139 | return -EFAULT; | ||
1140 | /* Disable interrupts while updating readp */ | ||
1141 | local_irq_save(flags); | ||
1142 | port->readp += count; | ||
1143 | if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */ | ||
1144 | port->readp = port->flip; | ||
1145 | port->full = 0; | ||
1146 | local_irq_restore(flags); | ||
1147 | DEBUGREAD(printk(KERN_DEBUG "r %d\n", count)); | ||
1148 | return count; | ||
1149 | } | ||
1150 | |||
1151 | static void send_word(struct sync_port *port) | ||
1152 | { | ||
1153 | switch (IO_EXTRACT(R_SYNC_SERIAL1_CTRL, wordsize, | ||
1154 | port->ctrl_data_shadow)) { | ||
1155 | case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): | ||
1156 | port->out_count--; | ||
1157 | *port->data_out = *port->outp++; | ||
1158 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | ||
1159 | port->outp = port->out_buffer; | ||
1160 | break; | ||
1161 | case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): | ||
1162 | { | ||
1163 | int data = (*port->outp++) << 8; | ||
1164 | data |= *port->outp++; | ||
1165 | port->out_count -= 2; | ||
1166 | *port->data_out = data; | ||
1167 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | ||
1168 | port->outp = port->out_buffer; | ||
1169 | break; | ||
1170 | } | ||
1171 | case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): | ||
1172 | port->out_count -= 2; | ||
1173 | *port->data_out = *(unsigned short *)port->outp; | ||
1174 | port->outp += 2; | ||
1175 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | ||
1176 | port->outp = port->out_buffer; | ||
1177 | break; | ||
1178 | case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): | ||
1179 | port->out_count -= 3; | ||
1180 | *port->data_out = *(unsigned int *)port->outp; | ||
1181 | port->outp += 3; | ||
1182 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | ||
1183 | port->outp = port->out_buffer; | ||
1184 | break; | ||
1185 | case IO_STATE_VALUE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): | ||
1186 | port->out_count -= 4; | ||
1187 | *port->data_out = *(unsigned int *)port->outp; | ||
1188 | port->outp += 4; | ||
1189 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | ||
1190 | port->outp = port->out_buffer; | ||
1191 | break; | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | |||
1196 | static void start_dma(struct sync_port *port, const char *data, int count) | ||
1197 | { | ||
1198 | port->tr_running = 1; | ||
1199 | port->out_descr.hw_len = 0; | ||
1200 | port->out_descr.next = 0; | ||
1201 | port->out_descr.ctrl = d_eol | d_eop; /* No d_wait to avoid glitches */ | ||
1202 | port->out_descr.sw_len = count; | ||
1203 | port->out_descr.buf = virt_to_phys(data); | ||
1204 | port->out_descr.status = 0; | ||
1205 | |||
1206 | *port->output_dma_first = virt_to_phys(&port->out_descr); | ||
1207 | *port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); | ||
1208 | DEBUGTXINT(printk(KERN_DEBUG "dma %08lX c %d\n", | ||
1209 | (unsigned long)data, count)); | ||
1210 | } | ||
1211 | |||
1212 | static void start_dma_in(struct sync_port *port) | ||
1213 | { | ||
1214 | int i; | ||
1215 | unsigned long buf; | ||
1216 | port->writep = port->flip; | ||
1217 | |||
1218 | if (port->writep > port->flip + port->in_buffer_size) { | ||
1219 | panic("Offset too large in sync serial driver\n"); | ||
1220 | return; | ||
1221 | } | ||
1222 | buf = virt_to_phys(port->in_buffer); | ||
1223 | for (i = 0; i < NUM_IN_DESCR; i++) { | ||
1224 | port->in_descr[i].sw_len = port->inbufchunk; | ||
1225 | port->in_descr[i].ctrl = d_int; | ||
1226 | port->in_descr[i].next = virt_to_phys(&port->in_descr[i+1]); | ||
1227 | port->in_descr[i].buf = buf; | ||
1228 | port->in_descr[i].hw_len = 0; | ||
1229 | port->in_descr[i].status = 0; | ||
1230 | port->in_descr[i].fifo_len = 0; | ||
1231 | buf += port->inbufchunk; | ||
1232 | prepare_rx_descriptor(&port->in_descr[i]); | ||
1233 | } | ||
1234 | /* Link the last descriptor to the first */ | ||
1235 | port->in_descr[i-1].next = virt_to_phys(&port->in_descr[0]); | ||
1236 | port->in_descr[i-1].ctrl |= d_eol; | ||
1237 | port->next_rx_desc = &port->in_descr[0]; | ||
1238 | port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1]; | ||
1239 | *port->input_dma_first = virt_to_phys(port->next_rx_desc); | ||
1240 | *port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start); | ||
1241 | } | ||
1242 | |||
1243 | #ifdef SYNC_SER_DMA | ||
1244 | static irqreturn_t tr_interrupt(int irq, void *dev_id) | ||
1245 | { | ||
1246 | unsigned long ireg = *R_IRQ_MASK2_RD; | ||
1247 | struct etrax_dma_descr *descr; | ||
1248 | unsigned int sentl; | ||
1249 | int handled = 0; | ||
1250 | int i; | ||
1251 | |||
1252 | for (i = 0; i < NUMBER_OF_PORTS; i++) { | ||
1253 | struct sync_port *port = &ports[i]; | ||
1254 | if (!port->enabled || !port->use_dma) | ||
1255 | continue; | ||
1256 | |||
1257 | /* IRQ active for the port? */ | ||
1258 | if (!(ireg & (1 << port->output_dma_bit))) | ||
1259 | continue; | ||
1260 | |||
1261 | handled = 1; | ||
1262 | |||
1263 | /* Clear IRQ */ | ||
1264 | *port->output_dma_clr_irq = | ||
1265 | IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | | ||
1266 | IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do); | ||
1267 | |||
1268 | descr = &port->out_descr; | ||
1269 | if (!(descr->status & d_stop)) | ||
1270 | sentl = descr->sw_len; | ||
1271 | else | ||
1272 | /* Otherwise find amount of data sent here */ | ||
1273 | sentl = descr->hw_len; | ||
1274 | |||
1275 | port->out_count -= sentl; | ||
1276 | port->outp += sentl; | ||
1277 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | ||
1278 | port->outp = port->out_buffer; | ||
1279 | if (port->out_count) { | ||
1280 | int c = port->out_buffer + OUT_BUFFER_SIZE - port->outp; | ||
1281 | if (c > port->out_count) | ||
1282 | c = port->out_count; | ||
1283 | DEBUGTXINT(printk(KERN_DEBUG | ||
1284 | "tx_int DMAWRITE %i %i\n", sentl, c)); | ||
1285 | start_dma(port, port->outp, c); | ||
1286 | } else { | ||
1287 | DEBUGTXINT(printk(KERN_DEBUG | ||
1288 | "tx_int DMA stop %i\n", sentl)); | ||
1289 | port->tr_running = 0; | ||
1290 | } | ||
1291 | /* wake up the waiting process */ | ||
1292 | wake_up_interruptible(&port->out_wait_q); | ||
1293 | } | ||
1294 | return IRQ_RETVAL(handled); | ||
1295 | } /* tr_interrupt */ | ||
1296 | |||
1297 | static irqreturn_t rx_interrupt(int irq, void *dev_id) | ||
1298 | { | ||
1299 | unsigned long ireg = *R_IRQ_MASK2_RD; | ||
1300 | int i; | ||
1301 | int handled = 0; | ||
1302 | |||
1303 | for (i = 0; i < NUMBER_OF_PORTS; i++) { | ||
1304 | struct sync_port *port = &ports[i]; | ||
1305 | |||
1306 | if (!port->enabled || !port->use_dma) | ||
1307 | continue; | ||
1308 | |||
1309 | if (!(ireg & (1 << port->input_dma_descr_bit))) | ||
1310 | continue; | ||
1311 | |||
1312 | /* Descriptor interrupt */ | ||
1313 | handled = 1; | ||
1314 | while (*port->input_dma_descr != | ||
1315 | virt_to_phys(port->next_rx_desc)) { | ||
1316 | if (port->writep + port->inbufchunk > port->flip + | ||
1317 | port->in_buffer_size) { | ||
1318 | int first_size = port->flip + | ||
1319 | port->in_buffer_size - port->writep; | ||
1320 | memcpy(port->writep, | ||
1321 | phys_to_virt(port->next_rx_desc->buf), | ||
1322 | first_size); | ||
1323 | memcpy(port->flip, | ||
1324 | phys_to_virt(port->next_rx_desc->buf + | ||
1325 | first_size), | ||
1326 | port->inbufchunk - first_size); | ||
1327 | port->writep = port->flip + | ||
1328 | port->inbufchunk - first_size; | ||
1329 | } else { | ||
1330 | memcpy(port->writep, | ||
1331 | phys_to_virt(port->next_rx_desc->buf), | ||
1332 | port->inbufchunk); | ||
1333 | port->writep += port->inbufchunk; | ||
1334 | if (port->writep >= port->flip | ||
1335 | + port->in_buffer_size) | ||
1336 | port->writep = port->flip; | ||
1337 | } | ||
1338 | if (port->writep == port->readp) | ||
1339 | port->full = 1; | ||
1340 | prepare_rx_descriptor(port->next_rx_desc); | ||
1341 | port->next_rx_desc->ctrl |= d_eol; | ||
1342 | port->prev_rx_desc->ctrl &= ~d_eol; | ||
1343 | port->prev_rx_desc = phys_to_virt((unsigned) | ||
1344 | port->next_rx_desc); | ||
1345 | port->next_rx_desc = phys_to_virt((unsigned) | ||
1346 | port->next_rx_desc->next); | ||
1347 | /* Wake up the waiting process */ | ||
1348 | wake_up_interruptible(&port->in_wait_q); | ||
1349 | *port->input_dma_cmd = IO_STATE(R_DMA_CH1_CMD, | ||
1350 | cmd, restart); | ||
1351 | /* DMA has reached end of descriptor */ | ||
1352 | *port->input_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, | ||
1353 | clr_descr, do); | ||
1354 | } | ||
1355 | } | ||
1356 | return IRQ_RETVAL(handled); | ||
1357 | } /* rx_interrupt */ | ||
1358 | #endif /* SYNC_SER_DMA */ | ||
1359 | |||
1360 | #ifdef SYNC_SER_MANUAL | ||
1361 | static irqreturn_t manual_interrupt(int irq, void *dev_id) | ||
1362 | { | ||
1363 | int i; | ||
1364 | int handled = 0; | ||
1365 | |||
1366 | for (i = 0; i < NUMBER_OF_PORTS; i++) { | ||
1367 | struct sync_port *port = &ports[i]; | ||
1368 | |||
1369 | if (!port->enabled || port->use_dma) | ||
1370 | continue; | ||
1371 | |||
1372 | /* Data received? */ | ||
1373 | if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit)) { | ||
1374 | handled = 1; | ||
1375 | /* Read data */ | ||
1376 | switch (port->ctrl_data_shadow & | ||
1377 | IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize)) { | ||
1378 | case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit): | ||
1379 | *port->writep++ = | ||
1380 | *(volatile char *)port->data_in; | ||
1381 | break; | ||
1382 | case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit): | ||
1383 | { | ||
1384 | int data = *(unsigned short *)port->data_in; | ||
1385 | *port->writep = (data & 0x0ff0) >> 4; | ||
1386 | *(port->writep + 1) = data & 0x0f; | ||
1387 | port->writep += 2; | ||
1388 | break; | ||
1389 | } | ||
1390 | case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit): | ||
1391 | *(unsigned short *)port->writep = | ||
1392 | *(volatile unsigned short *)port->data_in; | ||
1393 | port->writep += 2; | ||
1394 | break; | ||
1395 | case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit): | ||
1396 | *(unsigned int *)port->writep = *port->data_in; | ||
1397 | port->writep += 3; | ||
1398 | break; | ||
1399 | case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit): | ||
1400 | *(unsigned int *)port->writep = *port->data_in; | ||
1401 | port->writep += 4; | ||
1402 | break; | ||
1403 | } | ||
1404 | |||
1405 | /* Wrap? */ | ||
1406 | if (port->writep >= port->flip + port->in_buffer_size) | ||
1407 | port->writep = port->flip; | ||
1408 | if (port->writep == port->readp) { | ||
1409 | /* Receive buffer overrun, discard oldest */ | ||
1410 | port->readp++; | ||
1411 | /* Wrap? */ | ||
1412 | if (port->readp >= port->flip + | ||
1413 | port->in_buffer_size) | ||
1414 | port->readp = port->flip; | ||
1415 | } | ||
1416 | if (sync_data_avail(port) >= port->inbufchunk) { | ||
1417 | /* Wake up application */ | ||
1418 | wake_up_interruptible(&port->in_wait_q); | ||
1419 | } | ||
1420 | } | ||
1421 | |||
1422 | /* Transmitter ready? */ | ||
1423 | if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) { | ||
1424 | if (port->out_count > 0) { | ||
1425 | /* More data to send */ | ||
1426 | send_word(port); | ||
1427 | } else { | ||
1428 | /* Transmission finished */ | ||
1429 | /* Turn off IRQ */ | ||
1430 | *R_IRQ_MASK1_CLR = 1 << | ||
1431 | port->transmitter_ready_bit; | ||
1432 | /* Wake up application */ | ||
1433 | wake_up_interruptible(&port->out_wait_q); | ||
1434 | } | ||
1435 | } | ||
1436 | } | ||
1437 | return IRQ_RETVAL(handled); | ||
1438 | } | ||
1439 | #endif | ||
1440 | |||
1441 | module_init(etrax_sync_serial_init); | ||
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 93679a48c791..04d5eee2c90c 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* Serialport functions for debugging | 1 | /* Serialport functions for debugging |
2 | * | 2 | * |
3 | * Copyright (c) 2000 Axis Communications AB | 3 | * Copyright (c) 2000-2007 Axis Communications AB |
4 | * | 4 | * |
5 | * Authors: Bjorn Wesen | 5 | * Authors: Bjorn Wesen |
6 | * | 6 | * |
@@ -11,96 +11,6 @@ | |||
11 | * enableDebugIRQ() | 11 | * enableDebugIRQ() |
12 | * init_etrax_debug() | 12 | * init_etrax_debug() |
13 | * | 13 | * |
14 | * $Log: debugport.c,v $ | ||
15 | * Revision 1.27 2005/06/10 10:34:14 starvik | ||
16 | * Real console support | ||
17 | * | ||
18 | * Revision 1.26 2005/06/07 07:06:07 starvik | ||
19 | * Added LF->CR translation to make ETRAX customers happy. | ||
20 | * | ||
21 | * Revision 1.25 2005/03/08 08:56:47 mikaelam | ||
22 | * Do only set index as port->index if port is defined, otherwise use the index from the command line | ||
23 | * | ||
24 | * Revision 1.24 2005/01/19 10:26:33 mikaelam | ||
25 | * Return the cris serial driver in console device driver callback function | ||
26 | * | ||
27 | * Revision 1.23 2005/01/14 10:12:17 starvik | ||
28 | * KGDB on separate port. | ||
29 | * Console fixes from 2.4. | ||
30 | * | ||
31 | * Revision 1.22 2005/01/11 16:06:13 starvik | ||
32 | * typo | ||
33 | * | ||
34 | * Revision 1.21 2005/01/11 13:49:14 starvik | ||
35 | * Added raw_printk to be used where we don't trust the console. | ||
36 | * | ||
37 | * Revision 1.20 2004/12/27 11:18:32 starvik | ||
38 | * Merge of Linux 2.6.10 (not functional yet). | ||
39 | * | ||
40 | * Revision 1.19 2004/10/21 07:26:16 starvik | ||
41 | * Made it possible to specify console settings on kernel command line. | ||
42 | * | ||
43 | * Revision 1.18 2004/10/19 13:07:37 starvik | ||
44 | * Merge of Linux 2.6.9 | ||
45 | * | ||
46 | * Revision 1.17 2004/09/29 10:33:46 starvik | ||
47 | * Resolved a dealock when printing debug from kernel. | ||
48 | * | ||
49 | * Revision 1.16 2004/08/24 06:12:19 starvik | ||
50 | * Whitespace cleanup | ||
51 | * | ||
52 | * Revision 1.15 2004/08/16 12:37:19 starvik | ||
53 | * Merge of Linux 2.6.8 | ||
54 | * | ||
55 | * Revision 1.14 2004/05/17 13:11:29 starvik | ||
56 | * Disable DMA until real serial driver is up | ||
57 | * | ||
58 | * Revision 1.13 2004/05/14 07:58:01 starvik | ||
59 | * Merge of changes from 2.4 | ||
60 | * | ||
61 | * Revision 1.12 2003/09/11 07:29:49 starvik | ||
62 | * Merge of Linux 2.6.0-test5 | ||
63 | * | ||
64 | * Revision 1.11 2003/07/07 09:53:36 starvik | ||
65 | * Revert all the 2.5.74 merge changes to make the console work again | ||
66 | * | ||
67 | * Revision 1.9 2003/02/17 17:07:23 starvik | ||
68 | * Solved the problem with corrupted debug output (from Linux 2.4) | ||
69 | * * Wait until DMA, FIFO and pipe is empty before and after transmissions | ||
70 | * * Buffer data until a FIFO flush can be triggered. | ||
71 | * | ||
72 | * Revision 1.8 2003/01/22 06:48:36 starvik | ||
73 | * Fixed warnings issued by GCC 3.2.1 | ||
74 | * | ||
75 | * Revision 1.7 2002/12/12 08:26:32 starvik | ||
76 | * Don't use C-comments inside CVS comments | ||
77 | * | ||
78 | * Revision 1.6 2002/12/11 15:42:02 starvik | ||
79 | * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/ | ||
80 | * | ||
81 | * Revision 1.5 2002/11/20 06:58:03 starvik | ||
82 | * Compiles with kgdb | ||
83 | * | ||
84 | * Revision 1.4 2002/11/19 14:35:24 starvik | ||
85 | * Changes from linux 2.4 | ||
86 | * Changed struct initializer syntax to the currently preferred notation | ||
87 | * | ||
88 | * Revision 1.3 2002/11/06 09:47:03 starvik | ||
89 | * Modified for new interrupt macros | ||
90 | * | ||
91 | * Revision 1.2 2002/01/21 15:21:50 bjornw | ||
92 | * Update for kdev_t changes | ||
93 | * | ||
94 | * Revision 1.6 2001/04/17 13:58:39 orjanf | ||
95 | * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB. | ||
96 | * | ||
97 | * Revision 1.5 2001/03/26 14:22:05 bjornw | ||
98 | * Namechange of some config options | ||
99 | * | ||
100 | * Revision 1.4 2000/10/06 12:37:26 bjornw | ||
101 | * Use physical addresses when talking to DMA | ||
102 | * | ||
103 | * | ||
104 | */ | 14 | */ |
105 | 15 | ||
106 | #include <linux/console.h> | 16 | #include <linux/console.h> |
@@ -112,6 +22,8 @@ | |||
112 | #include <asm/arch/svinto.h> | 22 | #include <asm/arch/svinto.h> |
113 | #include <asm/io.h> /* Get SIMCOUT. */ | 23 | #include <asm/io.h> /* Get SIMCOUT. */ |
114 | 24 | ||
25 | extern void reset_watchdog(void); | ||
26 | |||
115 | struct dbg_port | 27 | struct dbg_port |
116 | { | 28 | { |
117 | unsigned int index; | 29 | unsigned int index; |
@@ -188,7 +100,9 @@ struct dbg_port ports[]= | |||
188 | } | 100 | } |
189 | }; | 101 | }; |
190 | 102 | ||
103 | #ifdef CONFIG_ETRAX_SERIAL | ||
191 | extern struct tty_driver *serial_driver; | 104 | extern struct tty_driver *serial_driver; |
105 | #endif | ||
192 | 106 | ||
193 | struct dbg_port* port = | 107 | struct dbg_port* port = |
194 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) | 108 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) |
@@ -368,11 +282,12 @@ console_write_direct(struct console *co, const char *buf, unsigned int len) | |||
368 | { | 282 | { |
369 | int i; | 283 | int i; |
370 | unsigned long flags; | 284 | unsigned long flags; |
371 | local_irq_save(flags); | ||
372 | 285 | ||
373 | if (!port) | 286 | if (!port) |
374 | return; | 287 | return; |
375 | 288 | ||
289 | local_irq_save(flags); | ||
290 | |||
376 | /* Send data */ | 291 | /* Send data */ |
377 | for (i = 0; i < len; i++) { | 292 | for (i = 0; i < len; i++) { |
378 | /* LF -> CRLF */ | 293 | /* LF -> CRLF */ |
@@ -386,26 +301,16 @@ console_write_direct(struct console *co, const char *buf, unsigned int len) | |||
386 | ; | 301 | ; |
387 | *port->write = buf[i]; | 302 | *port->write = buf[i]; |
388 | } | 303 | } |
389 | local_irq_restore(flags); | ||
390 | } | ||
391 | 304 | ||
392 | int raw_printk(const char *fmt, ...) | 305 | /* |
393 | { | 306 | * Feed the watchdog, otherwise it will reset the chip during boot. |
394 | static char buf[1024]; | 307 | * The time to send an ordinary boot message line (10-90 chars) |
395 | int printed_len; | 308 | * varies between 1-8ms at 115200. What makes up for the additional |
396 | static int first = 1; | 309 | * 90ms that allows the watchdog to bite? |
397 | if (first) { | 310 | */ |
398 | /* Force reinitialization of the port to get manual mode. */ | 311 | reset_watchdog(); |
399 | port->started = 0; | 312 | |
400 | start_port(port); | 313 | local_irq_restore(flags); |
401 | first = 0; | ||
402 | } | ||
403 | va_list args; | ||
404 | va_start(args, fmt); | ||
405 | printed_len = vsnprintf(buf, sizeof(buf), fmt, args); | ||
406 | va_end(args); | ||
407 | console_write_direct(NULL, buf, strlen(buf)); | ||
408 | return printed_len; | ||
409 | } | 314 | } |
410 | 315 | ||
411 | static void | 316 | static void |
@@ -500,6 +405,7 @@ console_setup(struct console *co, char *options) | |||
500 | return 0; | 405 | return 0; |
501 | } | 406 | } |
502 | 407 | ||
408 | |||
503 | /* This is a dummy serial device that throws away anything written to it. | 409 | /* This is a dummy serial device that throws away anything written to it. |
504 | * This is used when no debug output is wanted. | 410 | * This is used when no debug output is wanted. |
505 | */ | 411 | */ |
@@ -555,7 +461,13 @@ etrax_console_device(struct console* co, int *index) | |||
555 | { | 461 | { |
556 | if (port) | 462 | if (port) |
557 | *index = port->index; | 463 | *index = port->index; |
464 | else | ||
465 | *index = 0; | ||
466 | #ifdef CONFIG_ETRAX_SERIAL | ||
558 | return port ? serial_driver : &dummy_driver; | 467 | return port ? serial_driver : &dummy_driver; |
468 | #else | ||
469 | return &dummy_driver; | ||
470 | #endif | ||
559 | } | 471 | } |
560 | 472 | ||
561 | static struct console sercons = { | 473 | static struct console sercons = { |
diff --git a/arch/cris/arch-v10/kernel/dma.c b/arch/cris/arch-v10/kernel/dma.c index e9a0311b141d..eb1fa0d2b49f 100644 --- a/arch/cris/arch-v10/kernel/dma.c +++ b/arch/cris/arch-v10/kernel/dma.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* Wrapper for DMA channel allocator that updates DMA client muxing. | 1 | /* Wrapper for DMA channel allocator that updates DMA client muxing. |
2 | * Copyright 2004, Axis Communications AB | 2 | * Copyright 2004-2007, Axis Communications AB |
3 | * $Id: dma.c,v 1.1 2004/12/13 12:21:51 starvik Exp $ | ||
4 | */ | 3 | */ |
5 | 4 | ||
6 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index d1361dc119e2..3a65f322ae07 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S | |||
@@ -1,252 +1,9 @@ | |||
1 | /* $Id: entry.S,v 1.28 2005/06/20 05:06:30 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/entry.S | 2 | * linux/arch/cris/entry.S |
4 | * | 3 | * |
5 | * Copyright (C) 2000, 2001, 2002 Axis Communications AB | 4 | * Copyright (C) 2000, 2001, 2002 Axis Communications AB |
6 | * | 5 | * |
7 | * Authors: Bjorn Wesen (bjornw@axis.com) | 6 | * Authors: Bjorn Wesen (bjornw@axis.com) |
8 | * | ||
9 | * $Log: entry.S,v $ | ||
10 | * Revision 1.28 2005/06/20 05:06:30 starvik | ||
11 | * Remove unnecessary diff to kernel.org tree | ||
12 | * | ||
13 | * Revision 1.27 2005/03/04 08:16:16 starvik | ||
14 | * Merge of Linux 2.6.11. | ||
15 | * | ||
16 | * Revision 1.26 2005/01/11 13:49:47 starvik | ||
17 | * Added NMI handler. | ||
18 | * | ||
19 | * Revision 1.25 2004/12/27 11:18:32 starvik | ||
20 | * Merge of Linux 2.6.10 (not functional yet). | ||
21 | * | ||
22 | * Revision 1.24 2004/12/22 10:41:23 starvik | ||
23 | * Updates to make v10 compile with the latest SMP aware generic code (even | ||
24 | * though v10 will never have SMP). | ||
25 | * | ||
26 | * Revision 1.23 2004/10/19 13:07:37 starvik | ||
27 | * Merge of Linux 2.6.9 | ||
28 | * | ||
29 | * Revision 1.22 2004/06/21 10:29:55 starvik | ||
30 | * Merge of Linux 2.6.7 | ||
31 | * | ||
32 | * Revision 1.21 2004/06/09 05:30:27 starvik | ||
33 | * Clean up multiple interrupt handling. | ||
34 | * Prevent interrupts from interrupting each other. | ||
35 | * Handle all active interrupts. | ||
36 | * | ||
37 | * Revision 1.20 2004/06/08 08:55:32 starvik | ||
38 | * Removed unused code | ||
39 | * | ||
40 | * Revision 1.19 2004/06/04 11:56:15 starvik | ||
41 | * Implemented page table lookup for refills in assembler for improved performance. | ||
42 | * | ||
43 | * Revision 1.18 2004/05/11 12:28:25 starvik | ||
44 | * Merge of Linux 2.6.6 | ||
45 | * | ||
46 | * Revision 1.17 2003/09/11 07:29:49 starvik | ||
47 | * Merge of Linux 2.6.0-test5 | ||
48 | * | ||
49 | * Revision 1.16 2003/07/04 08:27:41 starvik | ||
50 | * Merge of Linux 2.5.74 | ||
51 | * | ||
52 | * Revision 1.15 2003/04/09 07:32:55 starvik | ||
53 | * resume should return task_struct, not thread_info | ||
54 | * | ||
55 | * Revision 1.14 2003/04/09 05:20:44 starvik | ||
56 | * Merge of Linux 2.5.67 | ||
57 | * | ||
58 | * Revision 1.13 2002/12/11 15:42:02 starvik | ||
59 | * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/*.c | ||
60 | * | ||
61 | * Revision 1.12 2002/12/10 09:00:10 starvik | ||
62 | * Merge of Linux 2.5.51 | ||
63 | * | ||
64 | * Revision 1.11 2002/12/05 07:53:10 starvik | ||
65 | * Corrected constants used with btstq | ||
66 | * | ||
67 | * Revision 1.10 2002/11/27 08:45:10 starvik | ||
68 | * pid is in task_struct, not thread_info | ||
69 | * | ||
70 | * Revision 1.9 2002/11/26 09:52:05 starvik | ||
71 | * Added preemptive kernel scheduling (if CONFIG_PREEMPT) | ||
72 | * | ||
73 | * Revision 1.8 2002/11/20 11:56:11 starvik | ||
74 | * Merge of Linux 2.5.48 | ||
75 | * | ||
76 | * Revision 1.7 2002/11/18 13:02:42 starvik | ||
77 | * Added fourth parameter to do_notify_resume | ||
78 | * Minor cleanup | ||
79 | * | ||
80 | * Revision 1.6 2002/11/11 10:37:50 starvik | ||
81 | * Use new asm-offset defines | ||
82 | * Modified for new location of current->work etc | ||
83 | * Removed SYMBOL_NAME from syscalls | ||
84 | * Added some new syscalls | ||
85 | * | ||
86 | * Revision 1.5 2002/11/05 06:45:11 starvik | ||
87 | * Merge of Linux 2.5.45 | ||
88 | * | ||
89 | * Revision 1.4 2002/02/05 15:41:31 bjornw | ||
90 | * Rewritten to conform better to current 2.5 code (similar to arch/i386) | ||
91 | * | ||
92 | * Revision 1.3 2002/01/21 15:22:20 bjornw | ||
93 | * NICE_DOGGY fix from 2.4 arch/cris | ||
94 | * | ||
95 | * Revision 1.37 2001/12/07 17:03:55 bjornw | ||
96 | * Call a c-hook called watchdog_bite_hook instead of show_registers directly | ||
97 | * | ||
98 | * Revision 1.36 2001/11/22 13:36:36 bjornw | ||
99 | * * In ret_from_intr, check regs->dccr for usermode reentrance instead of | ||
100 | * DCCR explicitly (because the latter might not reflect current reality) | ||
101 | * * In mmu_bus_fault, set $r9 _after_ calling the C-code instead of before | ||
102 | * since $r9 is call-clobbered and is potentially needed afterwards | ||
103 | * | ||
104 | * Revision 1.35 2001/10/30 17:10:15 bjornw | ||
105 | * Add some syscalls | ||
106 | * | ||
107 | * Revision 1.34 2001/10/01 14:45:03 bjornw | ||
108 | * Removed underscores and added register prefixes | ||
109 | * | ||
110 | * Revision 1.33 2001/08/21 13:48:01 jonashg | ||
111 | * Added fix by HP to avoid oops when doing a hard_reset_now. | ||
112 | * | ||
113 | * Revision 1.32 2001/08/14 04:32:02 hp | ||
114 | * In _resume, add comment why R9 is saved; don't sound like it's call-saved. | ||
115 | * | ||
116 | * Revision 1.31 2001/07/25 16:07:42 bjornw | ||
117 | * softirq_active/mask -> softirq_pending only | ||
118 | * | ||
119 | * Revision 1.30 2001/07/05 01:03:32 hp | ||
120 | * - include asm/errno.h to get ENOSYS. | ||
121 | * - Use ENOSYS, not local constant LENOSYS; tweak comments. | ||
122 | * - Explain why .include, not #include is used. | ||
123 | * - Make oops-register-dump if watchdog bits and it's not expected. | ||
124 | * - Don't jsr, use jump _hard_reset_now, and skip spurious nop. | ||
125 | * - Use correct section attribute for section .rodata. | ||
126 | * - Adjust sys_ni_syscall fill number. | ||
127 | * | ||
128 | * Revision 1.29 2001/06/25 14:07:00 hp | ||
129 | * Fix review comment. | ||
130 | * * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of | ||
131 | * magic numbers. Add comment that -traditional must not be used. | ||
132 | * * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation. | ||
133 | * Correct and update comment. | ||
134 | * * Makefile (.S.o): Don't use -traditional. Add comment why the | ||
135 | * toplevel rule can't be used (now that there's a reason). | ||
136 | * | ||
137 | * Revision 1.28 2001/06/21 02:00:40 hp | ||
138 | * * entry.S: Include asm/unistd.h. | ||
139 | * (_sys_call_table): Use section .rodata, not .data. | ||
140 | * (_kernel_thread): Move from... | ||
141 | * * process.c: ... here. | ||
142 | * * entryoffsets.c (VAL): Break out from... | ||
143 | * (OF): Use VAL. | ||
144 | * (LCLONE_VM): New asmified value from CLONE_VM. | ||
145 | * | ||
146 | * Revision 1.27 2001/05/29 11:25:27 markusl | ||
147 | * In case of "spurious_interrupt", do hard_reset instead of hanging system in a loop... | ||
148 | * | ||
149 | * Revision 1.26 2001/05/15 15:46:03 bjornw | ||
150 | * Include config.h now that we use some CONFIG_ options | ||
151 | * | ||
152 | * Revision 1.25 2001/05/15 05:38:47 hp | ||
153 | * Tweaked code in _ret_from_sys_call | ||
154 | * | ||
155 | * Revision 1.24 2001/05/15 05:27:49 hp | ||
156 | * Save r9 in r1 over function call rather than on stack. | ||
157 | * | ||
158 | * Revision 1.23 2001/05/15 05:10:00 hp | ||
159 | * Generate entry.S structure offsets from C | ||
160 | * | ||
161 | * Revision 1.22 2001/04/17 13:58:39 orjanf | ||
162 | * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB. | ||
163 | * | ||
164 | * Revision 1.21 2001/04/17 11:33:29 orjanf | ||
165 | * Updated according to review: | ||
166 | * * Included asm/sv_addr_ag.h to get macro for internal register. | ||
167 | * * Corrected comment regarding system call argument passing. | ||
168 | * * Removed comment about instruction being in a delay slot. | ||
169 | * * Added comment about SYMBOL_NAME macro. | ||
170 | * | ||
171 | * Revision 1.20 2001/04/12 08:51:07 hp | ||
172 | * - Add entry for sys_fcntl64. In fact copy last piece from i386 including ... | ||
173 | * - .rept to fill table to safe state with sys_ni_syscall. | ||
174 | * | ||
175 | * Revision 1.19 2001/04/04 09:43:32 orjanf | ||
176 | * * Moved do_sigtrap from traps.c to entry.S. | ||
177 | * * LTASK_PID need not be global anymore. | ||
178 | * | ||
179 | * Revision 1.18 2001/03/26 09:25:02 markusl | ||
180 | * Updated after review, should now handle USB interrupts correctly. | ||
181 | * | ||
182 | * Revision 1.17 2001/03/21 16:12:55 bjornw | ||
183 | * * Always make room for the cpu status record in the frame, in order to | ||
184 | * use the same framelength and layout for both mmu busfaults and normal | ||
185 | * irqs. No need to check for the explicit CRIS_FRAME_FIXUP type anymore. | ||
186 | * * Fixed bug with using addq for popping the stack in the epilogue - it | ||
187 | * destroyed the flag register. Use instructions that don't affect the | ||
188 | * flag register instead. | ||
189 | * * Removed write to R_PORT_PA_DATA during spurious_interrupt | ||
190 | * | ||
191 | * Revision 1.16 2001/03/20 19:43:02 bjornw | ||
192 | * * Get rid of esp0 setting | ||
193 | * * Give a 7th argument to a systemcall - the stackframe | ||
194 | * | ||
195 | * Revision 1.15 2001/03/05 13:14:30 bjornw | ||
196 | * Spelling fix | ||
197 | * | ||
198 | * Revision 1.14 2001/02/23 08:36:36 perf | ||
199 | * New ABI; syscallnr=r9, arg5=mof, arg6=srp. | ||
200 | * Corrected tracesys call check. | ||
201 | * | ||
202 | * Revision 1.13 2001/02/15 08:40:55 perf | ||
203 | * H-P by way of perf; | ||
204 | * - (_system_call): Don't read system call function address into r1. | ||
205 | * - (RBFExit): There is no such thing as a null pop. Adjust sp by addq. | ||
206 | * - (_system_call): Don't use r10 and don't save and restore it. | ||
207 | * - (THREAD_ESP0): New constant. | ||
208 | * - (_system_call): Inline set_esp0. | ||
209 | * | ||
210 | * Revision 1.12 2001/01/31 17:56:25 orjanf | ||
211 | * Added definition of LTASK_PID and made it global. | ||
212 | * | ||
213 | * Revision 1.11 2001/01/10 21:13:29 bjornw | ||
214 | * SYMBOL_NAME is defined incorrectly for the compiler options we currently use | ||
215 | * | ||
216 | * Revision 1.10 2000/12/18 23:47:56 bjornw | ||
217 | * * Added syscall trace support (ptrace), completely untested of course | ||
218 | * * Removed redundant check for NULL entries in syscall_table | ||
219 | * | ||
220 | * Revision 1.9 2000/11/21 16:40:51 bjornw | ||
221 | * * New frame type used when an SBFS frame needs to be popped without | ||
222 | * actually restarting the instruction | ||
223 | * * Enable interrupts in signal_return (they did so in x86, I hope it's a good | ||
224 | * idea) | ||
225 | * | ||
226 | * Revision 1.8 2000/11/17 16:53:35 bjornw | ||
227 | * Added detection of frame-type in Rexit, so that mmu_bus_fault can | ||
228 | * use ret_from_intr in the return-path to check for signals (like SEGV) | ||
229 | * and other foul things that might have occurred during the fault. | ||
230 | * | ||
231 | * Revision 1.7 2000/10/06 15:04:28 bjornw | ||
232 | * Include mof in register savings | ||
233 | * | ||
234 | * Revision 1.6 2000/09/12 16:02:44 bjornw | ||
235 | * Linux-2.4.0-test7 derived updates | ||
236 | * | ||
237 | * Revision 1.5 2000/08/17 15:35:15 bjornw | ||
238 | * 2.4.0-test6 changed local_irq_count and friends API | ||
239 | * | ||
240 | * Revision 1.4 2000/08/02 13:59:30 bjornw | ||
241 | * Removed olduname and uname from the syscall list | ||
242 | * | ||
243 | * Revision 1.3 2000/07/31 13:32:58 bjornw | ||
244 | * * Export ret_from_intr | ||
245 | * * _resume updated (prev/last tjohejsan) | ||
246 | * * timer_interrupt obsolete | ||
247 | * * SIGSEGV detection in mmu_bus_fault temporarily disabled | ||
248 | * | ||
249 | * | ||
250 | */ | 7 | */ |
251 | 8 | ||
252 | /* | 9 | /* |
@@ -1167,9 +924,11 @@ sys_call_table: | |||
1167 | .long sys_epoll_pwait | 924 | .long sys_epoll_pwait |
1168 | .long sys_utimensat /* 320 */ | 925 | .long sys_utimensat /* 320 */ |
1169 | .long sys_signalfd | 926 | .long sys_signalfd |
1170 | .long sys_ni_syscall | 927 | .long sys_timerfd_create |
1171 | .long sys_eventfd | 928 | .long sys_eventfd |
1172 | .long sys_fallocate | 929 | .long sys_fallocate |
930 | .long sys_timerfd_settime /* 325 */ | ||
931 | .long sys_timerfd_gettime | ||
1173 | 932 | ||
1174 | /* | 933 | /* |
1175 | * NOTE!! This doesn't have to be exact - we just have | 934 | * NOTE!! This doesn't have to be exact - we just have |
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c index c1a3a2100ee7..31ff35cff02c 100644 --- a/arch/cris/arch-v10/kernel/fasttimer.c +++ b/arch/cris/arch-v10/kernel/fasttimer.c | |||
@@ -31,15 +31,12 @@ | |||
31 | 31 | ||
32 | #define DEBUG_LOG_INCLUDED | 32 | #define DEBUG_LOG_INCLUDED |
33 | #define FAST_TIMER_LOG | 33 | #define FAST_TIMER_LOG |
34 | //#define FAST_TIMER_TEST | 34 | /* #define FAST_TIMER_TEST */ |
35 | 35 | ||
36 | #define FAST_TIMER_SANITY_CHECKS | 36 | #define FAST_TIMER_SANITY_CHECKS |
37 | 37 | ||
38 | #ifdef FAST_TIMER_SANITY_CHECKS | 38 | #ifdef FAST_TIMER_SANITY_CHECKS |
39 | #define SANITYCHECK(x) x | ||
40 | static int sanity_failed; | 39 | static int sanity_failed; |
41 | #else | ||
42 | #define SANITYCHECK(x) | ||
43 | #endif | 40 | #endif |
44 | 41 | ||
45 | #define D1(x) | 42 | #define D1(x) |
@@ -226,23 +223,19 @@ void start_one_shot_timer(struct fast_timer *t, | |||
226 | do_gettimeofday_fast(&t->tv_set); | 223 | do_gettimeofday_fast(&t->tv_set); |
227 | tmp = fast_timer_list; | 224 | tmp = fast_timer_list; |
228 | 225 | ||
229 | SANITYCHECK({ /* Check so this is not in the list already... */ | 226 | #ifdef FAST_TIMER_SANITY_CHECKS |
230 | while (tmp != NULL) | 227 | /* Check so this is not in the list already... */ |
231 | { | 228 | while (tmp != NULL) { |
232 | if (tmp == t) | 229 | if (tmp == t) { |
233 | { | 230 | printk(KERN_WARNING "timer name: %s data: " |
234 | printk(KERN_WARNING | 231 | "0x%08lX already in list!\n", name, data); |
235 | "timer name: %s data: 0x%08lX already in list!\n", name, data); | 232 | sanity_failed++; |
236 | sanity_failed++; | 233 | goto done; |
237 | goto done; | 234 | } else |
238 | } | 235 | tmp = tmp->next; |
239 | else | 236 | } |
240 | { | 237 | tmp = fast_timer_list; |
241 | tmp = tmp->next; | 238 | #endif |
242 | } | ||
243 | } | ||
244 | tmp = fast_timer_list; | ||
245 | }); | ||
246 | 239 | ||
247 | t->delay_us = delay_us; | 240 | t->delay_us = delay_us; |
248 | t->function = function; | 241 | t->function = function; |
diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S index d946d8b8d277..96344afc4ebc 100644 --- a/arch/cris/arch-v10/kernel/head.S +++ b/arch/cris/arch-v10/kernel/head.S | |||
@@ -1,186 +1,10 @@ | |||
1 | /* $Id: head.S,v 1.10 2005/06/20 05:12:54 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * Head of the kernel - alter with care | 2 | * Head of the kernel - alter with care |
4 | * | 3 | * |
5 | * Copyright (C) 2000, 2001 Axis Communications AB | 4 | * Copyright (C) 2000, 2001 Axis Communications AB |
6 | * | 5 | * |
7 | * Authors: Bjorn Wesen (bjornw@axis.com) | 6 | * Authors: Bjorn Wesen (bjornw@axis.com) |
8 | * | 7 | * |
9 | * $Log: head.S,v $ | ||
10 | * Revision 1.10 2005/06/20 05:12:54 starvik | ||
11 | * Remove unnecessary diff to kernel.org tree | ||
12 | * | ||
13 | * Revision 1.9 2004/12/13 12:21:51 starvik | ||
14 | * Added I/O and DMA allocators from Linux 2.4 | ||
15 | * | ||
16 | * Revision 1.8 2004/11/22 11:41:14 starvik | ||
17 | * Kernel command line may be supplied to kernel. Not used by Axis but may | ||
18 | * be used by customers. | ||
19 | * | ||
20 | * Revision 1.7 2004/05/14 07:58:01 starvik | ||
21 | * Merge of changes from 2.4 | ||
22 | * | ||
23 | * Revision 1.6 2003/04/28 05:31:46 starvik | ||
24 | * Added section attributes | ||
25 | * | ||
26 | * Revision 1.5 2002/12/11 15:42:02 starvik | ||
27 | * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/*.c | ||
28 | * | ||
29 | * Revision 1.4 2002/11/07 09:00:44 starvik | ||
30 | * Names changed for init sections | ||
31 | * init_task_union -> init_thread_union | ||
32 | * | ||
33 | * Revision 1.3 2002/02/05 15:38:23 bjornw | ||
34 | * Oops.. non-CRAMFS_MAGIC should jump over the copying, not into it... | ||
35 | * | ||
36 | * Revision 1.2 2001/12/18 13:35:19 bjornw | ||
37 | * Applied the 2.4.13->2.4.16 CRIS patch to 2.5.1 (is a copy of 2.4.15). | ||
38 | * | ||
39 | * Revision 1.43 2001/11/08 15:09:43 starvik | ||
40 | * Only start MII clock if Ethernet is configured | ||
41 | * | ||
42 | * Revision 1.42 2001/11/08 14:37:34 starvik | ||
43 | * Start MII clock early to make sure that it is running at tranceiver reset | ||
44 | * | ||
45 | * Revision 1.41 2001/10/29 14:55:58 pkj | ||
46 | * Corrected pa$r0 to par0. | ||
47 | * | ||
48 | * Revision 1.40 2001/10/03 14:59:57 pkj | ||
49 | * Added support for resetting the Bluetooth hardware. | ||
50 | * | ||
51 | * Revision 1.39 2001/10/01 14:45:03 bjornw | ||
52 | * Removed underscores and added register prefixes | ||
53 | * | ||
54 | * Revision 1.38 2001/09/21 07:14:11 jonashg | ||
55 | * Made root filesystem (cramfs) use mtdblock driver when booting from flash. | ||
56 | * | ||
57 | * Revision 1.37 2001/09/11 13:44:29 orjanf | ||
58 | * Decouple usage of serial ports for debug and kgdb. | ||
59 | * | ||
60 | * Revision 1.36 2001/06/29 12:39:31 pkj | ||
61 | * Added support for mirroring the first flash to just below the | ||
62 | * second one, to make them look consecutive to cramfs. | ||
63 | * | ||
64 | * Revision 1.35 2001/06/25 14:07:00 hp | ||
65 | * Fix review comment. | ||
66 | * * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of | ||
67 | * magic numbers. Add comment that -traditional must not be used. | ||
68 | * * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation. | ||
69 | * Correct and update comment. | ||
70 | * * Makefile (.S.o): Don't use -traditional. Add comment why the | ||
71 | * toplevel rule can't be used (now that there's a reason). | ||
72 | * | ||
73 | * Revision 1.34 2001/05/15 07:08:14 hp | ||
74 | * Tweak "notice" to reflect that both r8 r9 are used | ||
75 | * | ||
76 | * Revision 1.33 2001/05/15 06:40:05 hp | ||
77 | * Put bulk of code in .text.init, data in .data.init | ||
78 | * | ||
79 | * Revision 1.32 2001/05/15 06:18:56 hp | ||
80 | * Execute review comment: s/bcc/bhs/g; s/bcs/blo/g | ||
81 | * | ||
82 | * Revision 1.31 2001/05/15 06:08:40 hp | ||
83 | * Add sentence about autodetecting the bit31-MMU-bug | ||
84 | * | ||
85 | * Revision 1.30 2001/05/15 06:00:05 hp | ||
86 | * Update comment: LOW_MAP is not forced on xsim anymore. | ||
87 | * | ||
88 | * Revision 1.29 2001/04/18 12:51:59 orjanf | ||
89 | * * Reverted review change regarding the use of bcs/bcc. | ||
90 | * * Removed non-working LED-clearing code. | ||
91 | * | ||
92 | * Revision 1.28 2001/04/17 13:58:39 orjanf | ||
93 | * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB. | ||
94 | * | ||
95 | * Revision 1.27 2001/04/17 11:42:35 orjanf | ||
96 | * Changed according to review: | ||
97 | * * Added comment explaining memory map bug. | ||
98 | * * Changed bcs and bcc to blo and bhs, respectively. | ||
99 | * * Removed mentioning of Stallone and Olga boards. | ||
100 | * | ||
101 | * Revision 1.26 2001/04/06 12:31:07 jonashg | ||
102 | * Check for cramfs in flash before RAM instead of RAM before flash. | ||
103 | * | ||
104 | * Revision 1.25 2001/04/04 06:23:53 starvik | ||
105 | * Initialize DRAM if not already initialized | ||
106 | * | ||
107 | * Revision 1.24 2001/04/03 11:12:00 starvik | ||
108 | * Removed dram init (done by rescue or etrax100boot | ||
109 | * Corrected include | ||
110 | * | ||
111 | * Revision 1.23 2001/04/03 09:53:03 starvik | ||
112 | * Include hw_settings.S | ||
113 | * | ||
114 | * Revision 1.22 2001/03/26 14:23:26 bjornw | ||
115 | * Namechange of some config options | ||
116 | * | ||
117 | * Revision 1.21 2001/03/08 12:14:41 bjornw | ||
118 | * * Config name for ETRAX IDE was renamed | ||
119 | * * Removed G27 auto-setting when JULIETTE is chosen (need to make this | ||
120 | * a new config option later) | ||
121 | * | ||
122 | * Revision 1.20 2001/02/23 12:47:56 bjornw | ||
123 | * MMU regs during LOW_MAP updated to reflect a newer reality | ||
124 | * | ||
125 | * Revision 1.19 2001/02/19 11:12:07 bjornw | ||
126 | * Changed comment header format | ||
127 | * | ||
128 | * Revision 1.18 2001/02/15 07:25:38 starvik | ||
129 | * Added support for synchronous serial ports | ||
130 | * | ||
131 | * Revision 1.17 2001/02/08 15:53:13 starvik | ||
132 | * Last commit removed some important ifdefs | ||
133 | * | ||
134 | * Revision 1.16 2001/02/08 15:20:38 starvik | ||
135 | * Include dram_init.S as inline | ||
136 | * | ||
137 | * Revision 1.15 2001/01/29 18:12:01 bjornw | ||
138 | * Corrected some comments | ||
139 | * | ||
140 | * Revision 1.14 2001/01/29 13:11:29 starvik | ||
141 | * Include dram_init.S (with DRAM/SDRAM initialization) | ||
142 | * | ||
143 | * Revision 1.13 2001/01/23 14:54:57 markusl | ||
144 | * Updated for USB | ||
145 | * i.e. added r_gen_config settings | ||
146 | * | ||
147 | * Revision 1.12 2001/01/19 16:16:29 perf | ||
148 | * Added temporary mapping of 0x0c->0x0c to avoid flash loading confusion. | ||
149 | * Renamed serial options from ETRAX100 to ETRAX. | ||
150 | * | ||
151 | * Revision 1.11 2001/01/16 16:31:38 bjornw | ||
152 | * * Changed name and semantics of running_from_flash to romfs_in_flash, | ||
153 | * set by head.S to indicate to setup.c whether there is a cramfs image | ||
154 | * after the kernels BSS or not. Should work for all three boot-cases | ||
155 | * (DRAM with cramfs in DRAM, DRAM with cramfs in flash (compressed boot), | ||
156 | * and flash with cramfs in flash) | ||
157 | * | ||
158 | * Revision 1.10 2001/01/16 14:12:21 bjornw | ||
159 | * * Check for cramfs start passed in r9 from the decompressor, if all other | ||
160 | * cramfs options fail (if we boot from DRAM but don't find a cramfs image | ||
161 | * after the kernel in DRAM, it is probably still in the flash) | ||
162 | * * Check magic in cramfs detection when booting from flash directly | ||
163 | * | ||
164 | * Revision 1.9 2001/01/15 17:17:02 bjornw | ||
165 | * * Corrected the code that detects the cramfs lengths | ||
166 | * * Added a comment saying that the above does not work due to other | ||
167 | * reasons.. | ||
168 | * | ||
169 | * Revision 1.8 2001/01/15 16:27:51 jonashg | ||
170 | * Made boot after flashing work. | ||
171 | * * end destination is __vmlinux_end in RAM. | ||
172 | * * _romfs_start moved because of virtual memory. | ||
173 | * | ||
174 | * Revision 1.7 2000/11/21 13:55:29 bjornw | ||
175 | * Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type | ||
176 | * | ||
177 | * Revision 1.6 2000/10/06 12:36:55 bjornw | ||
178 | * Forgot swapper_pg_dir when changing memory map.. | ||
179 | * | ||
180 | * Revision 1.5 2000/10/04 16:49:30 bjornw | ||
181 | * * Fixed memory mapping in LX | ||
182 | * * Check for cramfs instead of romfs | ||
183 | * | ||
184 | */ | 8 | */ |
185 | 9 | ||
186 | #define ASSEMBLER_MACROS_ONLY | 10 | #define ASSEMBLER_MACROS_ONLY |
@@ -595,11 +419,17 @@ no_command_line: | |||
595 | 419 | ||
596 | moveq 0,$r0 | 420 | moveq 0,$r0 |
597 | 421 | ||
422 | ;; Select or disable serial port 2 | ||
423 | #ifdef CONFIG_ETRAX_SERIAL_PORT2 | ||
424 | or.d IO_STATE (R_GEN_CONFIG, ser2, select),$r0 | ||
425 | #else | ||
426 | or.d IO_STATE (R_GEN_CONFIG, ser2, disable),$r0 | ||
427 | #endif | ||
428 | |||
598 | ;; Init interfaces (disable them). | 429 | ;; Init interfaces (disable them). |
599 | or.d IO_STATE (R_GEN_CONFIG, scsi0, disable) \ | 430 | or.d IO_STATE (R_GEN_CONFIG, scsi0, disable) \ |
600 | | IO_STATE (R_GEN_CONFIG, ata, disable) \ | 431 | | IO_STATE (R_GEN_CONFIG, ata, disable) \ |
601 | | IO_STATE (R_GEN_CONFIG, par0, disable) \ | 432 | | IO_STATE (R_GEN_CONFIG, par0, disable) \ |
602 | | IO_STATE (R_GEN_CONFIG, ser2, disable) \ | ||
603 | | IO_STATE (R_GEN_CONFIG, mio, disable) \ | 433 | | IO_STATE (R_GEN_CONFIG, mio, disable) \ |
604 | | IO_STATE (R_GEN_CONFIG, scsi1, disable) \ | 434 | | IO_STATE (R_GEN_CONFIG, scsi1, disable) \ |
605 | | IO_STATE (R_GEN_CONFIG, scsi0w, disable) \ | 435 | | IO_STATE (R_GEN_CONFIG, scsi0w, disable) \ |
@@ -801,6 +631,41 @@ no_command_line: | |||
801 | | IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),$r0 | 631 | | IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),$r0 |
802 | move.b $r0,[R_SERIAL1_TR_CTRL] | 632 | move.b $r0,[R_SERIAL1_TR_CTRL] |
803 | 633 | ||
634 | #ifdef CONFIG_ETRAX_SERIAL_PORT2 | ||
635 | ;; setup the serial port 2 at 115200 baud for debug purposes | ||
636 | |||
637 | moveq IO_STATE (R_SERIAL2_XOFF, tx_stop, enable) \ | ||
638 | | IO_STATE (R_SERIAL2_XOFF, auto_xoff, disable) \ | ||
639 | | IO_FIELD (R_SERIAL2_XOFF, xoff_char, 0),$r0 | ||
640 | move.d $r0,[R_SERIAL2_XOFF] | ||
641 | |||
642 | ; 115.2kbaud for both transmit and receive | ||
643 | move.b IO_STATE (R_SERIAL2_BAUD, tr_baud, c115k2Hz) \ | ||
644 | | IO_STATE (R_SERIAL2_BAUD, rec_baud, c115k2Hz),$r0 | ||
645 | move.b $r0,[R_SERIAL2_BAUD] | ||
646 | |||
647 | ; Set up and enable the serial2 receiver. | ||
648 | move.b IO_STATE (R_SERIAL2_REC_CTRL, dma_err, stop) \ | ||
649 | | IO_STATE (R_SERIAL2_REC_CTRL, rec_enable, enable) \ | ||
650 | | IO_STATE (R_SERIAL2_REC_CTRL, rts_, active) \ | ||
651 | | IO_STATE (R_SERIAL2_REC_CTRL, sampling, middle) \ | ||
652 | | IO_STATE (R_SERIAL2_REC_CTRL, rec_stick_par, normal) \ | ||
653 | | IO_STATE (R_SERIAL2_REC_CTRL, rec_par, even) \ | ||
654 | | IO_STATE (R_SERIAL2_REC_CTRL, rec_par_en, disable) \ | ||
655 | | IO_STATE (R_SERIAL2_REC_CTRL, rec_bitnr, rec_8bit),$r0 | ||
656 | move.b $r0,[R_SERIAL2_REC_CTRL] | ||
657 | |||
658 | ; Set up and enable the serial2 transmitter. | ||
659 | move.b IO_FIELD (R_SERIAL2_TR_CTRL, txd, 0) \ | ||
660 | | IO_STATE (R_SERIAL2_TR_CTRL, tr_enable, enable) \ | ||
661 | | IO_STATE (R_SERIAL2_TR_CTRL, auto_cts, disabled) \ | ||
662 | | IO_STATE (R_SERIAL2_TR_CTRL, stop_bits, one_bit) \ | ||
663 | | IO_STATE (R_SERIAL2_TR_CTRL, tr_stick_par, normal) \ | ||
664 | | IO_STATE (R_SERIAL2_TR_CTRL, tr_par, even) \ | ||
665 | | IO_STATE (R_SERIAL2_TR_CTRL, tr_par_en, disable) \ | ||
666 | | IO_STATE (R_SERIAL2_TR_CTRL, tr_bitnr, tr_8bit),$r0 | ||
667 | move.b $r0,[R_SERIAL2_TR_CTRL] | ||
668 | #endif | ||
804 | 669 | ||
805 | #ifdef CONFIG_ETRAX_SERIAL_PORT3 | 670 | #ifdef CONFIG_ETRAX_SERIAL_PORT3 |
806 | ;; setup the serial port 3 at 115200 baud for debug purposes | 671 | ;; setup the serial port 3 at 115200 baud for debug purposes |
diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c index f3b327d4ed9c..add98e0941b5 100644 --- a/arch/cris/arch-v10/kernel/io_interface_mux.c +++ b/arch/cris/arch-v10/kernel/io_interface_mux.c | |||
@@ -1,10 +1,9 @@ | |||
1 | /* IO interface mux allocator for ETRAX100LX. | 1 | /* IO interface mux allocator for ETRAX100LX. |
2 | * Copyright 2004, Axis Communications AB | 2 | * Copyright 2004-2007, Axis Communications AB |
3 | * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $ | ||
4 | */ | 3 | */ |
5 | 4 | ||
6 | 5 | ||
7 | /* C.f. ETRAX100LX Designer's Reference 20.9 */ | 6 | /* C.f. ETRAX100LX Designer's Reference chapter 19.9 */ |
8 | 7 | ||
9 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
10 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
@@ -45,17 +44,39 @@ struct watcher | |||
45 | struct if_group | 44 | struct if_group |
46 | { | 45 | { |
47 | enum io_if_group group; | 46 | enum io_if_group group; |
48 | unsigned char used; | 47 | /* name - the name of the group 'A' to 'F' */ |
49 | enum cris_io_interface owner; | 48 | char *name; |
49 | /* used - a bit mask of all pins in the group in the order listed | ||
50 | * in the tables in 19.9.1 to 19.9.6. Note that no | ||
51 | * distinction is made between in, out and in/out pins. */ | ||
52 | unsigned int used; | ||
50 | }; | 53 | }; |
51 | 54 | ||
52 | 55 | ||
53 | struct interface | 56 | struct interface |
54 | { | 57 | { |
55 | enum cris_io_interface ioif; | 58 | enum cris_io_interface ioif; |
59 | /* name - the name of the interface */ | ||
60 | char *name; | ||
61 | /* groups - OR'ed together io_if_group flags describing what pin groups | ||
62 | * the interface uses pins in. */ | ||
56 | unsigned char groups; | 63 | unsigned char groups; |
64 | /* used - set when the interface is allocated. */ | ||
57 | unsigned char used; | 65 | unsigned char used; |
58 | char *owner; | 66 | char *owner; |
67 | /* group_a through group_f - bit masks describing what pins in the | ||
68 | * pin groups the interface uses. */ | ||
69 | unsigned int group_a; | ||
70 | unsigned int group_b; | ||
71 | unsigned int group_c; | ||
72 | unsigned int group_d; | ||
73 | unsigned int group_e; | ||
74 | unsigned int group_f; | ||
75 | |||
76 | /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the | ||
77 | * GPIO ports the interface uses. This could be reconstucted using | ||
78 | * the group_X masks and a table of what pins the GPIO ports use, | ||
79 | * but that would be messy. */ | ||
59 | unsigned int gpio_g_in; | 80 | unsigned int gpio_g_in; |
60 | unsigned int gpio_g_out; | 81 | unsigned int gpio_g_out; |
61 | unsigned char gpio_b; | 82 | unsigned char gpio_b; |
@@ -64,26 +85,32 @@ struct interface | |||
64 | static struct if_group if_groups[6] = { | 85 | static struct if_group if_groups[6] = { |
65 | { | 86 | { |
66 | .group = group_a, | 87 | .group = group_a, |
88 | .name = "A", | ||
67 | .used = 0, | 89 | .used = 0, |
68 | }, | 90 | }, |
69 | { | 91 | { |
70 | .group = group_b, | 92 | .group = group_b, |
93 | .name = "B", | ||
71 | .used = 0, | 94 | .used = 0, |
72 | }, | 95 | }, |
73 | { | 96 | { |
74 | .group = group_c, | 97 | .group = group_c, |
98 | .name = "C", | ||
75 | .used = 0, | 99 | .used = 0, |
76 | }, | 100 | }, |
77 | { | 101 | { |
78 | .group = group_d, | 102 | .group = group_d, |
103 | .name = "D", | ||
79 | .used = 0, | 104 | .used = 0, |
80 | }, | 105 | }, |
81 | { | 106 | { |
82 | .group = group_e, | 107 | .group = group_e, |
108 | .name = "E", | ||
83 | .used = 0, | 109 | .used = 0, |
84 | }, | 110 | }, |
85 | { | 111 | { |
86 | .group = group_f, | 112 | .group = group_f, |
113 | .name = "F", | ||
87 | .used = 0, | 114 | .used = 0, |
88 | } | 115 | } |
89 | }; | 116 | }; |
@@ -94,14 +121,32 @@ static struct interface interfaces[] = { | |||
94 | /* Begin Non-multiplexed interfaces */ | 121 | /* Begin Non-multiplexed interfaces */ |
95 | { | 122 | { |
96 | .ioif = if_eth, | 123 | .ioif = if_eth, |
124 | .name = "ethernet", | ||
97 | .groups = 0, | 125 | .groups = 0, |
126 | |||
127 | .group_a = 0, | ||
128 | .group_b = 0, | ||
129 | .group_c = 0, | ||
130 | .group_d = 0, | ||
131 | .group_e = 0, | ||
132 | .group_f = 0, | ||
133 | |||
98 | .gpio_g_in = 0, | 134 | .gpio_g_in = 0, |
99 | .gpio_g_out = 0, | 135 | .gpio_g_out = 0, |
100 | .gpio_b = 0 | 136 | .gpio_b = 0 |
101 | }, | 137 | }, |
102 | { | 138 | { |
103 | .ioif = if_serial_0, | 139 | .ioif = if_serial_0, |
140 | .name = "serial_0", | ||
104 | .groups = 0, | 141 | .groups = 0, |
142 | |||
143 | .group_a = 0, | ||
144 | .group_b = 0, | ||
145 | .group_c = 0, | ||
146 | .group_d = 0, | ||
147 | .group_e = 0, | ||
148 | .group_f = 0, | ||
149 | |||
105 | .gpio_g_in = 0, | 150 | .gpio_g_in = 0, |
106 | .gpio_g_out = 0, | 151 | .gpio_g_out = 0, |
107 | .gpio_b = 0 | 152 | .gpio_b = 0 |
@@ -109,172 +154,385 @@ static struct interface interfaces[] = { | |||
109 | /* End Non-multiplexed interfaces */ | 154 | /* End Non-multiplexed interfaces */ |
110 | { | 155 | { |
111 | .ioif = if_serial_1, | 156 | .ioif = if_serial_1, |
157 | .name = "serial_1", | ||
112 | .groups = group_e, | 158 | .groups = group_e, |
159 | |||
160 | .group_a = 0, | ||
161 | .group_b = 0, | ||
162 | .group_c = 0, | ||
163 | .group_d = 0, | ||
164 | .group_e = 0x0f, | ||
165 | .group_f = 0, | ||
166 | |||
113 | .gpio_g_in = 0x00000000, | 167 | .gpio_g_in = 0x00000000, |
114 | .gpio_g_out = 0x00000000, | 168 | .gpio_g_out = 0x00000000, |
115 | .gpio_b = 0x00 | 169 | .gpio_b = 0x00 |
116 | }, | 170 | }, |
117 | { | 171 | { |
118 | .ioif = if_serial_2, | 172 | .ioif = if_serial_2, |
173 | .name = "serial_2", | ||
119 | .groups = group_b, | 174 | .groups = group_b, |
175 | |||
176 | .group_a = 0, | ||
177 | .group_b = 0x0f, | ||
178 | .group_c = 0, | ||
179 | .group_d = 0, | ||
180 | .group_e = 0, | ||
181 | .group_f = 0, | ||
182 | |||
120 | .gpio_g_in = 0x000000c0, | 183 | .gpio_g_in = 0x000000c0, |
121 | .gpio_g_out = 0x000000c0, | 184 | .gpio_g_out = 0x000000c0, |
122 | .gpio_b = 0x00 | 185 | .gpio_b = 0x00 |
123 | }, | 186 | }, |
124 | { | 187 | { |
125 | .ioif = if_serial_3, | 188 | .ioif = if_serial_3, |
189 | .name = "serial_3", | ||
126 | .groups = group_c, | 190 | .groups = group_c, |
191 | |||
192 | .group_a = 0, | ||
193 | .group_b = 0, | ||
194 | .group_c = 0x0f, | ||
195 | .group_d = 0, | ||
196 | .group_e = 0, | ||
197 | .group_f = 0, | ||
198 | |||
127 | .gpio_g_in = 0xc0000000, | 199 | .gpio_g_in = 0xc0000000, |
128 | .gpio_g_out = 0xc0000000, | 200 | .gpio_g_out = 0xc0000000, |
129 | .gpio_b = 0x00 | 201 | .gpio_b = 0x00 |
130 | }, | 202 | }, |
131 | { | 203 | { |
132 | .ioif = if_sync_serial_1, | 204 | .ioif = if_sync_serial_1, |
133 | .groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3 | 205 | .name = "sync_serial_1", |
134 | can be used simultaneously */ | 206 | .groups = group_e | group_f, |
207 | |||
208 | .group_a = 0, | ||
209 | .group_b = 0, | ||
210 | .group_c = 0, | ||
211 | .group_d = 0, | ||
212 | .group_e = 0x0f, | ||
213 | .group_f = 0x10, | ||
214 | |||
135 | .gpio_g_in = 0x00000000, | 215 | .gpio_g_in = 0x00000000, |
136 | .gpio_g_out = 0x00000000, | 216 | .gpio_g_out = 0x00000000, |
137 | .gpio_b = 0x10 | 217 | .gpio_b = 0x10 |
138 | }, | 218 | }, |
139 | { | 219 | { |
140 | .ioif = if_sync_serial_3, | 220 | .ioif = if_sync_serial_3, |
221 | .name = "sync_serial_3", | ||
141 | .groups = group_c | group_f, | 222 | .groups = group_c | group_f, |
223 | |||
224 | .group_a = 0, | ||
225 | .group_b = 0, | ||
226 | .group_c = 0x0f, | ||
227 | .group_d = 0, | ||
228 | .group_e = 0, | ||
229 | .group_f = 0x80, | ||
230 | |||
142 | .gpio_g_in = 0xc0000000, | 231 | .gpio_g_in = 0xc0000000, |
143 | .gpio_g_out = 0xc0000000, | 232 | .gpio_g_out = 0xc0000000, |
144 | .gpio_b = 0x80 | 233 | .gpio_b = 0x80 |
145 | }, | 234 | }, |
146 | { | 235 | { |
147 | .ioif = if_shared_ram, | 236 | .ioif = if_shared_ram, |
237 | .name = "shared_ram", | ||
148 | .groups = group_a, | 238 | .groups = group_a, |
239 | |||
240 | .group_a = 0x7f8ff, | ||
241 | .group_b = 0, | ||
242 | .group_c = 0, | ||
243 | .group_d = 0, | ||
244 | .group_e = 0, | ||
245 | .group_f = 0, | ||
246 | |||
149 | .gpio_g_in = 0x0000ff3e, | 247 | .gpio_g_in = 0x0000ff3e, |
150 | .gpio_g_out = 0x0000ff38, | 248 | .gpio_g_out = 0x0000ff38, |
151 | .gpio_b = 0x00 | 249 | .gpio_b = 0x00 |
152 | }, | 250 | }, |
153 | { | 251 | { |
154 | .ioif = if_shared_ram_w, | 252 | .ioif = if_shared_ram_w, |
253 | .name = "shared_ram_w", | ||
155 | .groups = group_a | group_d, | 254 | .groups = group_a | group_d, |
255 | |||
256 | .group_a = 0x7f8ff, | ||
257 | .group_b = 0, | ||
258 | .group_c = 0, | ||
259 | .group_d = 0xff, | ||
260 | .group_e = 0, | ||
261 | .group_f = 0, | ||
262 | |||
156 | .gpio_g_in = 0x00ffff3e, | 263 | .gpio_g_in = 0x00ffff3e, |
157 | .gpio_g_out = 0x00ffff38, | 264 | .gpio_g_out = 0x00ffff38, |
158 | .gpio_b = 0x00 | 265 | .gpio_b = 0x00 |
159 | }, | 266 | }, |
160 | { | 267 | { |
161 | .ioif = if_par_0, | 268 | .ioif = if_par_0, |
269 | .name = "par_0", | ||
162 | .groups = group_a, | 270 | .groups = group_a, |
271 | |||
272 | .group_a = 0x7fbff, | ||
273 | .group_b = 0, | ||
274 | .group_c = 0, | ||
275 | .group_d = 0, | ||
276 | .group_e = 0, | ||
277 | .group_f = 0, | ||
278 | |||
163 | .gpio_g_in = 0x0000ff3e, | 279 | .gpio_g_in = 0x0000ff3e, |
164 | .gpio_g_out = 0x0000ff3e, | 280 | .gpio_g_out = 0x0000ff3e, |
165 | .gpio_b = 0x00 | 281 | .gpio_b = 0x00 |
166 | }, | 282 | }, |
167 | { | 283 | { |
168 | .ioif = if_par_1, | 284 | .ioif = if_par_1, |
285 | .name = "par_1", | ||
169 | .groups = group_d, | 286 | .groups = group_d, |
287 | |||
288 | .group_a = 0, | ||
289 | .group_b = 0, | ||
290 | .group_c = 0, | ||
291 | .group_d = 0x7feff, | ||
292 | .group_e = 0, | ||
293 | .group_f = 0, | ||
294 | |||
170 | .gpio_g_in = 0x3eff0000, | 295 | .gpio_g_in = 0x3eff0000, |
171 | .gpio_g_out = 0x3eff0000, | 296 | .gpio_g_out = 0x3eff0000, |
172 | .gpio_b = 0x00 | 297 | .gpio_b = 0x00 |
173 | }, | 298 | }, |
174 | { | 299 | { |
175 | .ioif = if_par_w, | 300 | .ioif = if_par_w, |
301 | .name = "par_w", | ||
176 | .groups = group_a | group_d, | 302 | .groups = group_a | group_d, |
303 | |||
304 | .group_a = 0x7fbff, | ||
305 | .group_b = 0, | ||
306 | .group_c = 0, | ||
307 | .group_d = 0xff, | ||
308 | .group_e = 0, | ||
309 | .group_f = 0, | ||
310 | |||
177 | .gpio_g_in = 0x00ffff3e, | 311 | .gpio_g_in = 0x00ffff3e, |
178 | .gpio_g_out = 0x00ffff3e, | 312 | .gpio_g_out = 0x00ffff3e, |
179 | .gpio_b = 0x00 | 313 | .gpio_b = 0x00 |
180 | }, | 314 | }, |
181 | { | 315 | { |
182 | .ioif = if_scsi8_0, | 316 | .ioif = if_scsi8_0, |
183 | .groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1 | 317 | .name = "scsi8_0", |
184 | can be used simultaneously */ | 318 | .groups = group_a | group_b | group_f, |
319 | |||
320 | .group_a = 0x7ffff, | ||
321 | .group_b = 0x0f, | ||
322 | .group_c = 0, | ||
323 | .group_d = 0, | ||
324 | .group_e = 0, | ||
325 | .group_f = 0x10, | ||
326 | |||
185 | .gpio_g_in = 0x0000ffff, | 327 | .gpio_g_in = 0x0000ffff, |
186 | .gpio_g_out = 0x0000ffff, | 328 | .gpio_g_out = 0x0000ffff, |
187 | .gpio_b = 0x10 | 329 | .gpio_b = 0x10 |
188 | }, | 330 | }, |
189 | { | 331 | { |
190 | .ioif = if_scsi8_1, | 332 | .ioif = if_scsi8_1, |
191 | .groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1 | 333 | .name = "scsi8_1", |
192 | can be used simultaneously */ | 334 | .groups = group_c | group_d | group_f, |
335 | |||
336 | .group_a = 0, | ||
337 | .group_b = 0, | ||
338 | .group_c = 0x0f, | ||
339 | .group_d = 0x7ffff, | ||
340 | .group_e = 0, | ||
341 | .group_f = 0x80, | ||
342 | |||
193 | .gpio_g_in = 0xffff0000, | 343 | .gpio_g_in = 0xffff0000, |
194 | .gpio_g_out = 0xffff0000, | 344 | .gpio_g_out = 0xffff0000, |
195 | .gpio_b = 0x80 | 345 | .gpio_b = 0x80 |
196 | }, | 346 | }, |
197 | { | 347 | { |
198 | .ioif = if_scsi_w, | 348 | .ioif = if_scsi_w, |
349 | .name = "scsi_w", | ||
199 | .groups = group_a | group_b | group_d | group_f, | 350 | .groups = group_a | group_b | group_d | group_f, |
351 | |||
352 | .group_a = 0x7ffff, | ||
353 | .group_b = 0x0f, | ||
354 | .group_c = 0, | ||
355 | .group_d = 0x601ff, | ||
356 | .group_e = 0, | ||
357 | .group_f = 0x90, | ||
358 | |||
200 | .gpio_g_in = 0x01ffffff, | 359 | .gpio_g_in = 0x01ffffff, |
201 | .gpio_g_out = 0x07ffffff, | 360 | .gpio_g_out = 0x07ffffff, |
202 | .gpio_b = 0x80 | 361 | .gpio_b = 0x80 |
203 | }, | 362 | }, |
204 | { | 363 | { |
205 | .ioif = if_ata, | 364 | .ioif = if_ata, |
365 | .name = "ata", | ||
206 | .groups = group_a | group_b | group_c | group_d, | 366 | .groups = group_a | group_b | group_c | group_d, |
367 | |||
368 | .group_a = 0x7ffff, | ||
369 | .group_b = 0x0f, | ||
370 | .group_c = 0x0f, | ||
371 | .group_d = 0x7cfff, | ||
372 | .group_e = 0, | ||
373 | .group_f = 0, | ||
374 | |||
207 | .gpio_g_in = 0xf9ffffff, | 375 | .gpio_g_in = 0xf9ffffff, |
208 | .gpio_g_out = 0xffffffff, | 376 | .gpio_g_out = 0xffffffff, |
209 | .gpio_b = 0x80 | 377 | .gpio_b = 0x80 |
210 | }, | 378 | }, |
211 | { | 379 | { |
212 | .ioif = if_csp, | 380 | .ioif = if_csp, |
213 | .groups = group_f, /* if_csp and if_i2c can be used simultaneously */ | 381 | .name = "csp", |
382 | .groups = group_f, | ||
383 | |||
384 | .group_a = 0, | ||
385 | .group_b = 0, | ||
386 | .group_c = 0, | ||
387 | .group_d = 0, | ||
388 | .group_e = 0, | ||
389 | .group_f = 0xfc, | ||
390 | |||
214 | .gpio_g_in = 0x00000000, | 391 | .gpio_g_in = 0x00000000, |
215 | .gpio_g_out = 0x00000000, | 392 | .gpio_g_out = 0x00000000, |
216 | .gpio_b = 0xfc | 393 | .gpio_b = 0xfc |
217 | }, | 394 | }, |
218 | { | 395 | { |
219 | .ioif = if_i2c, | 396 | .ioif = if_i2c, |
220 | .groups = group_f, /* if_csp and if_i2c can be used simultaneously */ | 397 | .name = "i2c", |
398 | .groups = group_f, | ||
399 | |||
400 | .group_a = 0, | ||
401 | .group_b = 0, | ||
402 | .group_c = 0, | ||
403 | .group_d = 0, | ||
404 | .group_e = 0, | ||
405 | .group_f = 0x03, | ||
406 | |||
221 | .gpio_g_in = 0x00000000, | 407 | .gpio_g_in = 0x00000000, |
222 | .gpio_g_out = 0x00000000, | 408 | .gpio_g_out = 0x00000000, |
223 | .gpio_b = 0x03 | 409 | .gpio_b = 0x03 |
224 | }, | 410 | }, |
225 | { | 411 | { |
226 | .ioif = if_usb_1, | 412 | .ioif = if_usb_1, |
413 | .name = "usb_1", | ||
227 | .groups = group_e | group_f, | 414 | .groups = group_e | group_f, |
415 | |||
416 | .group_a = 0, | ||
417 | .group_b = 0, | ||
418 | .group_c = 0, | ||
419 | .group_d = 0, | ||
420 | .group_e = 0x0f, | ||
421 | .group_f = 0x2c, | ||
422 | |||
228 | .gpio_g_in = 0x00000000, | 423 | .gpio_g_in = 0x00000000, |
229 | .gpio_g_out = 0x00000000, | 424 | .gpio_g_out = 0x00000000, |
230 | .gpio_b = 0x2c | 425 | .gpio_b = 0x2c |
231 | }, | 426 | }, |
232 | { | 427 | { |
233 | .ioif = if_usb_2, | 428 | .ioif = if_usb_2, |
429 | .name = "usb_2", | ||
234 | .groups = group_d, | 430 | .groups = group_d, |
235 | .gpio_g_in = 0x0e000000, | 431 | |
236 | .gpio_g_out = 0x3c000000, | 432 | .group_a = 0, |
433 | .group_b = 0, | ||
434 | .group_c = 0, | ||
435 | .group_d = 0, | ||
436 | .group_e = 0x33e00, | ||
437 | .group_f = 0, | ||
438 | |||
439 | .gpio_g_in = 0x3e000000, | ||
440 | .gpio_g_out = 0x0c000000, | ||
237 | .gpio_b = 0x00 | 441 | .gpio_b = 0x00 |
238 | }, | 442 | }, |
239 | /* GPIO pins */ | 443 | /* GPIO pins */ |
240 | { | 444 | { |
241 | .ioif = if_gpio_grp_a, | 445 | .ioif = if_gpio_grp_a, |
446 | .name = "gpio_a", | ||
242 | .groups = group_a, | 447 | .groups = group_a, |
448 | |||
449 | .group_a = 0, | ||
450 | .group_b = 0, | ||
451 | .group_c = 0, | ||
452 | .group_d = 0, | ||
453 | .group_e = 0, | ||
454 | .group_f = 0, | ||
455 | |||
243 | .gpio_g_in = 0x0000ff3f, | 456 | .gpio_g_in = 0x0000ff3f, |
244 | .gpio_g_out = 0x0000ff3f, | 457 | .gpio_g_out = 0x0000ff3f, |
245 | .gpio_b = 0x00 | 458 | .gpio_b = 0x00 |
246 | }, | 459 | }, |
247 | { | 460 | { |
248 | .ioif = if_gpio_grp_b, | 461 | .ioif = if_gpio_grp_b, |
462 | .name = "gpio_b", | ||
249 | .groups = group_b, | 463 | .groups = group_b, |
464 | |||
465 | .group_a = 0, | ||
466 | .group_b = 0, | ||
467 | .group_c = 0, | ||
468 | .group_d = 0, | ||
469 | .group_e = 0, | ||
470 | .group_f = 0, | ||
471 | |||
250 | .gpio_g_in = 0x000000c0, | 472 | .gpio_g_in = 0x000000c0, |
251 | .gpio_g_out = 0x000000c0, | 473 | .gpio_g_out = 0x000000c0, |
252 | .gpio_b = 0x00 | 474 | .gpio_b = 0x00 |
253 | }, | 475 | }, |
254 | { | 476 | { |
255 | .ioif = if_gpio_grp_c, | 477 | .ioif = if_gpio_grp_c, |
478 | .name = "gpio_c", | ||
256 | .groups = group_c, | 479 | .groups = group_c, |
480 | |||
481 | .group_a = 0, | ||
482 | .group_b = 0, | ||
483 | .group_c = 0, | ||
484 | .group_d = 0, | ||
485 | .group_e = 0, | ||
486 | .group_f = 0, | ||
487 | |||
257 | .gpio_g_in = 0xc0000000, | 488 | .gpio_g_in = 0xc0000000, |
258 | .gpio_g_out = 0xc0000000, | 489 | .gpio_g_out = 0xc0000000, |
259 | .gpio_b = 0x00 | 490 | .gpio_b = 0x00 |
260 | }, | 491 | }, |
261 | { | 492 | { |
262 | .ioif = if_gpio_grp_d, | 493 | .ioif = if_gpio_grp_d, |
494 | .name = "gpio_d", | ||
263 | .groups = group_d, | 495 | .groups = group_d, |
496 | |||
497 | .group_a = 0, | ||
498 | .group_b = 0, | ||
499 | .group_c = 0, | ||
500 | .group_d = 0, | ||
501 | .group_e = 0, | ||
502 | .group_f = 0, | ||
503 | |||
264 | .gpio_g_in = 0x3fff0000, | 504 | .gpio_g_in = 0x3fff0000, |
265 | .gpio_g_out = 0x3fff0000, | 505 | .gpio_g_out = 0x3fff0000, |
266 | .gpio_b = 0x00 | 506 | .gpio_b = 0x00 |
267 | }, | 507 | }, |
268 | { | 508 | { |
269 | .ioif = if_gpio_grp_e, | 509 | .ioif = if_gpio_grp_e, |
510 | .name = "gpio_e", | ||
270 | .groups = group_e, | 511 | .groups = group_e, |
512 | |||
513 | .group_a = 0, | ||
514 | .group_b = 0, | ||
515 | .group_c = 0, | ||
516 | .group_d = 0, | ||
517 | .group_e = 0, | ||
518 | .group_f = 0, | ||
519 | |||
271 | .gpio_g_in = 0x00000000, | 520 | .gpio_g_in = 0x00000000, |
272 | .gpio_g_out = 0x00000000, | 521 | .gpio_g_out = 0x00000000, |
273 | .gpio_b = 0x00 | 522 | .gpio_b = 0x00 |
274 | }, | 523 | }, |
275 | { | 524 | { |
276 | .ioif = if_gpio_grp_f, | 525 | .ioif = if_gpio_grp_f, |
526 | .name = "gpio_f", | ||
277 | .groups = group_f, | 527 | .groups = group_f, |
528 | |||
529 | .group_a = 0, | ||
530 | .group_b = 0, | ||
531 | .group_c = 0, | ||
532 | .group_d = 0, | ||
533 | .group_e = 0, | ||
534 | .group_f = 0, | ||
535 | |||
278 | .gpio_g_in = 0x00000000, | 536 | .gpio_g_in = 0x00000000, |
279 | .gpio_g_out = 0x00000000, | 537 | .gpio_g_out = 0x00000000, |
280 | .gpio_b = 0xff | 538 | .gpio_b = 0xff |
@@ -284,11 +542,13 @@ static struct interface interfaces[] = { | |||
284 | 542 | ||
285 | static struct watcher *watchers = NULL; | 543 | static struct watcher *watchers = NULL; |
286 | 544 | ||
545 | /* The pins that are free to use in the GPIO ports. */ | ||
287 | static unsigned int gpio_in_pins = 0xffffffff; | 546 | static unsigned int gpio_in_pins = 0xffffffff; |
288 | static unsigned int gpio_out_pins = 0xffffffff; | 547 | static unsigned int gpio_out_pins = 0xffffffff; |
289 | static unsigned char gpio_pb_pins = 0xff; | 548 | static unsigned char gpio_pb_pins = 0xff; |
290 | static unsigned char gpio_pa_pins = 0xff; | 549 | static unsigned char gpio_pa_pins = 0xff; |
291 | 550 | ||
551 | /* Identifiers for the owners of the GPIO pins. */ | ||
292 | static enum cris_io_interface gpio_pa_owners[8]; | 552 | static enum cris_io_interface gpio_pa_owners[8]; |
293 | static enum cris_io_interface gpio_pb_owners[8]; | 553 | static enum cris_io_interface gpio_pb_owners[8]; |
294 | static enum cris_io_interface gpio_pg_owners[32]; | 554 | static enum cris_io_interface gpio_pg_owners[32]; |
@@ -338,13 +598,15 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id | |||
338 | struct if_group *grp; | 598 | struct if_group *grp; |
339 | unsigned char group_set; | 599 | unsigned char group_set; |
340 | unsigned long flags; | 600 | unsigned long flags; |
601 | int res = 0; | ||
341 | 602 | ||
342 | (void)cris_io_interface_init(); | 603 | (void)cris_io_interface_init(); |
343 | 604 | ||
344 | DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id)); | 605 | DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id)); |
345 | 606 | ||
346 | if ((ioif >= if_max_interfaces) || (ioif < 0)) { | 607 | if ((ioif >= if_max_interfaces) || (ioif < 0)) { |
347 | printk(KERN_CRIT "cris_request_io_interface: Bad interface %u submitted for %s\n", | 608 | printk(KERN_CRIT "cris_request_io_interface: Bad interface " |
609 | "%u submitted for %s\n", | ||
348 | ioif, | 610 | ioif, |
349 | device_id); | 611 | device_id); |
350 | return -EINVAL; | 612 | return -EINVAL; |
@@ -353,59 +615,69 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id | |||
353 | local_irq_save(flags); | 615 | local_irq_save(flags); |
354 | 616 | ||
355 | if (interfaces[ioif].used) { | 617 | if (interfaces[ioif].used) { |
356 | local_irq_restore(flags); | 618 | printk(KERN_CRIT "cris_io_interface: Cannot allocate interface " |
357 | printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n", | 619 | "%s for %s, in use by %s\n", |
620 | interfaces[ioif].name, | ||
358 | device_id, | 621 | device_id, |
359 | interfaces[ioif].owner); | 622 | interfaces[ioif].owner); |
360 | return -EBUSY; | 623 | res = -EBUSY; |
624 | goto exit; | ||
361 | } | 625 | } |
362 | 626 | ||
363 | /* Check that all required groups are free before allocating, */ | 627 | /* Check that all required pins in the used groups are free |
628 | * before allocating. */ | ||
364 | group_set = interfaces[ioif].groups; | 629 | group_set = interfaces[ioif].groups; |
365 | while (NULL != (grp = get_group(group_set))) { | 630 | while (NULL != (grp = get_group(group_set))) { |
366 | if (grp->used) { | 631 | unsigned int if_group_use = 0; |
367 | if (grp->group == group_f) { | 632 | |
368 | if ((if_sync_serial_1 == ioif) || | 633 | switch (grp->group) { |
369 | (if_sync_serial_3 == ioif)) { | 634 | case group_a: |
370 | if ((grp->owner != if_sync_serial_1) && | 635 | if_group_use = interfaces[ioif].group_a; |
371 | (grp->owner != if_sync_serial_3)) { | 636 | break; |
372 | local_irq_restore(flags); | 637 | case group_b: |
373 | return -EBUSY; | 638 | if_group_use = interfaces[ioif].group_b; |
374 | } | 639 | break; |
375 | } else if ((if_scsi8_0 == ioif) || | 640 | case group_c: |
376 | (if_scsi8_1 == ioif)) { | 641 | if_group_use = interfaces[ioif].group_c; |
377 | if ((grp->owner != if_scsi8_0) && | 642 | break; |
378 | (grp->owner != if_scsi8_1)) { | 643 | case group_d: |
379 | local_irq_restore(flags); | 644 | if_group_use = interfaces[ioif].group_d; |
380 | return -EBUSY; | 645 | break; |
381 | } | 646 | case group_e: |
382 | } | 647 | if_group_use = interfaces[ioif].group_e; |
383 | } else { | 648 | break; |
384 | local_irq_restore(flags); | 649 | case group_f: |
385 | return -EBUSY; | 650 | if_group_use = interfaces[ioif].group_f; |
386 | } | 651 | break; |
652 | default: | ||
653 | BUG_ON(1); | ||
387 | } | 654 | } |
655 | |||
656 | if (if_group_use & grp->used) { | ||
657 | printk(KERN_INFO "cris_request_io_interface: group " | ||
658 | "%s needed by %s not available\n", | ||
659 | grp->name, interfaces[ioif].name); | ||
660 | res = -EBUSY; | ||
661 | goto exit; | ||
662 | } | ||
663 | |||
388 | group_set = clear_group_from_set(group_set, grp); | 664 | group_set = clear_group_from_set(group_set, grp); |
389 | } | 665 | } |
390 | 666 | ||
391 | /* Are the required GPIO pins available too? */ | 667 | /* Are the required GPIO pins available too? */ |
392 | if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) || | 668 | if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != |
393 | ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) || | 669 | interfaces[ioif].gpio_g_in) || |
394 | ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) { | 670 | ((interfaces[ioif].gpio_g_out & gpio_out_pins) != |
395 | local_irq_restore(flags); | 671 | interfaces[ioif].gpio_g_out) || |
396 | printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n", | 672 | ((interfaces[ioif].gpio_b & gpio_pb_pins) != |
397 | ioif); | 673 | interfaces[ioif].gpio_b)) { |
398 | return -EBUSY; | 674 | printk(KERN_CRIT "cris_request_io_interface: Could not get " |
399 | } | 675 | "required pins for interface %u\n", ioif); |
400 | 676 | res = -EBUSY; | |
401 | /* All needed I/O pins and pin groups are free, allocate. */ | 677 | goto exit; |
402 | group_set = interfaces[ioif].groups; | ||
403 | while (NULL != (grp = get_group(group_set))) { | ||
404 | grp->used = 1; | ||
405 | grp->owner = ioif; | ||
406 | group_set = clear_group_from_set(group_set, grp); | ||
407 | } | 678 | } |
408 | 679 | ||
680 | /* Check which registers need to be reconfigured. */ | ||
409 | gens = genconfig_shadow; | 681 | gens = genconfig_shadow; |
410 | gens_ii = gen_config_ii_shadow; | 682 | gens_ii = gen_config_ii_shadow; |
411 | 683 | ||
@@ -495,9 +767,43 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id | |||
495 | set_gen_config = 0; | 767 | set_gen_config = 0; |
496 | break; | 768 | break; |
497 | default: | 769 | default: |
498 | panic("cris_request_io_interface: Bad interface %u submitted for %s\n", | 770 | printk(KERN_INFO "cris_request_io_interface: Bad interface " |
499 | ioif, | 771 | "%u submitted for %s\n", |
500 | device_id); | 772 | ioif, device_id); |
773 | res = -EBUSY; | ||
774 | goto exit; | ||
775 | } | ||
776 | |||
777 | /* All needed I/O pins and pin groups are free, allocate. */ | ||
778 | group_set = interfaces[ioif].groups; | ||
779 | while (NULL != (grp = get_group(group_set))) { | ||
780 | unsigned int if_group_use = 0; | ||
781 | |||
782 | switch (grp->group) { | ||
783 | case group_a: | ||
784 | if_group_use = interfaces[ioif].group_a; | ||
785 | break; | ||
786 | case group_b: | ||
787 | if_group_use = interfaces[ioif].group_b; | ||
788 | break; | ||
789 | case group_c: | ||
790 | if_group_use = interfaces[ioif].group_c; | ||
791 | break; | ||
792 | case group_d: | ||
793 | if_group_use = interfaces[ioif].group_d; | ||
794 | break; | ||
795 | case group_e: | ||
796 | if_group_use = interfaces[ioif].group_e; | ||
797 | break; | ||
798 | case group_f: | ||
799 | if_group_use = interfaces[ioif].group_f; | ||
800 | break; | ||
801 | default: | ||
802 | BUG_ON(1); | ||
803 | } | ||
804 | grp->used |= if_group_use; | ||
805 | |||
806 | group_set = clear_group_from_set(group_set, grp); | ||
501 | } | 807 | } |
502 | 808 | ||
503 | interfaces[ioif].used = 1; | 809 | interfaces[ioif].used = 1; |
@@ -516,25 +822,28 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id | |||
516 | *R_GEN_CONFIG_II = gen_config_ii_shadow; | 822 | *R_GEN_CONFIG_II = gen_config_ii_shadow; |
517 | } | 823 | } |
518 | 824 | ||
519 | DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | 825 | DBG(printk(KERN_DEBUG "GPIO pins: available before: " |
520 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | 826 | "g_in=0x%08x g_out=0x%08x pb=0x%02x\n", |
521 | DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | 827 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); |
522 | interfaces[ioif].gpio_g_in, | 828 | DBG(printk(KERN_DEBUG |
523 | interfaces[ioif].gpio_g_out, | 829 | "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", |
524 | interfaces[ioif].gpio_b)); | 830 | interfaces[ioif].gpio_g_in, |
831 | interfaces[ioif].gpio_g_out, | ||
832 | interfaces[ioif].gpio_b)); | ||
525 | 833 | ||
526 | gpio_in_pins &= ~interfaces[ioif].gpio_g_in; | 834 | gpio_in_pins &= ~interfaces[ioif].gpio_g_in; |
527 | gpio_out_pins &= ~interfaces[ioif].gpio_g_out; | 835 | gpio_out_pins &= ~interfaces[ioif].gpio_g_out; |
528 | gpio_pb_pins &= ~interfaces[ioif].gpio_b; | 836 | gpio_pb_pins &= ~interfaces[ioif].gpio_b; |
529 | 837 | ||
530 | DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n", | 838 | DBG(printk(KERN_DEBUG "GPIO pins: available after: " |
531 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | 839 | "g_in=0x%08x g_out=0x%08x pb=0x%02x\n", |
840 | gpio_in_pins, gpio_out_pins, gpio_pb_pins)); | ||
532 | 841 | ||
842 | exit: | ||
533 | local_irq_restore(flags); | 843 | local_irq_restore(flags); |
534 | 844 | if (res == 0) | |
535 | notify_watchers(); | 845 | notify_watchers(); |
536 | 846 | return res; | |
537 | return 0; | ||
538 | } | 847 | } |
539 | 848 | ||
540 | 849 | ||
@@ -560,43 +869,35 @@ void cris_free_io_interface(enum cris_io_interface ioif) | |||
560 | } | 869 | } |
561 | group_set = interfaces[ioif].groups; | 870 | group_set = interfaces[ioif].groups; |
562 | while (NULL != (grp = get_group(group_set))) { | 871 | while (NULL != (grp = get_group(group_set))) { |
563 | if (grp->group == group_f) { | 872 | unsigned int if_group_use = 0; |
564 | switch (ioif) | 873 | |
565 | { | 874 | switch (grp->group) { |
566 | case if_sync_serial_1: | 875 | case group_a: |
567 | if ((grp->owner == if_sync_serial_1) && | 876 | if_group_use = interfaces[ioif].group_a; |
568 | interfaces[if_sync_serial_3].used) { | 877 | break; |
569 | grp->owner = if_sync_serial_3; | 878 | case group_b: |
570 | } else | 879 | if_group_use = interfaces[ioif].group_b; |
571 | grp->used = 0; | 880 | break; |
572 | break; | 881 | case group_c: |
573 | case if_sync_serial_3: | 882 | if_group_use = interfaces[ioif].group_c; |
574 | if ((grp->owner == if_sync_serial_3) && | 883 | break; |
575 | interfaces[if_sync_serial_1].used) { | 884 | case group_d: |
576 | grp->owner = if_sync_serial_1; | 885 | if_group_use = interfaces[ioif].group_d; |
577 | } else | 886 | break; |
578 | grp->used = 0; | 887 | case group_e: |
579 | break; | 888 | if_group_use = interfaces[ioif].group_e; |
580 | case if_scsi8_0: | 889 | break; |
581 | if ((grp->owner == if_scsi8_0) && | 890 | case group_f: |
582 | interfaces[if_scsi8_1].used) { | 891 | if_group_use = interfaces[ioif].group_f; |
583 | grp->owner = if_scsi8_1; | 892 | break; |
584 | } else | 893 | default: |
585 | grp->used = 0; | 894 | BUG_ON(1); |
586 | break; | ||
587 | case if_scsi8_1: | ||
588 | if ((grp->owner == if_scsi8_1) && | ||
589 | interfaces[if_scsi8_0].used) { | ||
590 | grp->owner = if_scsi8_0; | ||
591 | } else | ||
592 | grp->used = 0; | ||
593 | break; | ||
594 | default: | ||
595 | grp->used = 0; | ||
596 | } | ||
597 | } else { | ||
598 | grp->used = 0; | ||
599 | } | 895 | } |
896 | |||
897 | if ((grp->used & if_group_use) != if_group_use) | ||
898 | BUG_ON(1); | ||
899 | grp->used = grp->used & ~if_group_use; | ||
900 | |||
600 | group_set = clear_group_from_set(group_set, grp); | 901 | group_set = clear_group_from_set(group_set, grp); |
601 | } | 902 | } |
602 | interfaces[ioif].used = 0; | 903 | interfaces[ioif].used = 0; |
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index e06ab0050d37..65ed803dae6f 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: irq.c,v 1.4 2005/01/04 12:22:28 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/kernel/irq.c | 2 | * linux/arch/cris/kernel/irq.c |
4 | * | 3 | * |
5 | * Copyright (c) 2000-2002 Axis Communications AB | 4 | * Copyright (c) 2000-2002 Axis Communications AB |
@@ -18,10 +17,6 @@ | |||
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 18 | #include <linux/init.h> |
20 | 19 | ||
21 | /* From kgdb.c. */ | ||
22 | extern void kgdb_init(void); | ||
23 | extern void breakpoint(void); | ||
24 | |||
25 | #define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); | 20 | #define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); |
26 | #define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); | 21 | #define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); |
27 | 22 | ||
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index 77f4b1423725..a3ca55150745 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c | |||
@@ -17,66 +17,8 @@ | |||
17 | *! Jun 17 1999 Hendrik Ruijter Added gdb 4.18 support. 'X', 'qC' and 'qL'. | 17 | *! Jun 17 1999 Hendrik Ruijter Added gdb 4.18 support. 'X', 'qC' and 'qL'. |
18 | *! Jul 21 1999 Bjorn Wesen eLinux port | 18 | *! Jul 21 1999 Bjorn Wesen eLinux port |
19 | *! | 19 | *! |
20 | *! $Log: kgdb.c,v $ | ||
21 | *! Revision 1.6 2005/01/14 10:12:17 starvik | ||
22 | *! KGDB on separate port. | ||
23 | *! Console fixes from 2.4. | ||
24 | *! | ||
25 | *! Revision 1.5 2004/10/07 13:59:08 starvik | ||
26 | *! Corrected call to set_int_vector | ||
27 | *! | ||
28 | *! Revision 1.4 2003/04/09 05:20:44 starvik | ||
29 | *! Merge of Linux 2.5.67 | ||
30 | *! | ||
31 | *! Revision 1.3 2003/01/21 19:11:08 starvik | ||
32 | *! Modified include path for new dir layout | ||
33 | *! | ||
34 | *! Revision 1.2 2002/11/19 14:35:24 starvik | ||
35 | *! Changes from linux 2.4 | ||
36 | *! Changed struct initializer syntax to the currently preferred notation | ||
37 | *! | ||
38 | *! Revision 1.1 2001/12/17 13:59:27 bjornw | ||
39 | *! Initial revision | ||
40 | *! | ||
41 | *! Revision 1.6 2001/10/09 13:10:03 matsfg | ||
42 | *! Added $ on registers and removed some underscores | ||
43 | *! | ||
44 | *! Revision 1.5 2001/04/17 13:58:39 orjanf | ||
45 | *! * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB. | ||
46 | *! | ||
47 | *! Revision 1.4 2001/02/23 13:45:19 bjornw | ||
48 | *! config.h check | ||
49 | *! | ||
50 | *! Revision 1.3 2001/01/31 18:08:23 orjanf | ||
51 | *! Removed kgdb_handle_breakpoint from being the break 8 handler. | ||
52 | *! | ||
53 | *! Revision 1.2 2001/01/12 14:22:25 orjanf | ||
54 | *! Updated kernel debugging support to work with ETRAX 100LX. | ||
55 | *! | ||
56 | *! Revision 1.1 2000/07/10 16:25:21 bjornw | ||
57 | *! Initial revision | ||
58 | *! | ||
59 | *! Revision 1.1.1.1 1999/12/03 14:57:31 bjornw | ||
60 | *! * Initial version of arch/cris, the latest CRIS architecture with an MMU. | ||
61 | *! Mostly copied from arch/etrax100 with appropriate renames of files. | ||
62 | *! The mm/ subdir is copied from arch/i386. | ||
63 | *! This does not compile yet at all. | ||
64 | *! | ||
65 | *! | ||
66 | *! Revision 1.4 1999/07/22 17:25:25 bjornw | ||
67 | *! Dont wait for + in putpacket if we havent hit the initial breakpoint yet. Added a kgdb_init function which sets up the break and irq vectors. | ||
68 | *! | ||
69 | *! Revision 1.3 1999/07/21 19:51:18 bjornw | ||
70 | *! Check if the interrupting char is a ctrl-C, ignore otherwise. | ||
71 | *! | ||
72 | *! Revision 1.2 1999/07/21 18:09:39 bjornw | ||
73 | *! Ported to eLinux architecture, and added some kgdb documentation. | ||
74 | *! | ||
75 | *! | ||
76 | *!--------------------------------------------------------------------------- | 20 | *!--------------------------------------------------------------------------- |
77 | *! | 21 | *! |
78 | *! $Id: kgdb.c,v 1.6 2005/01/14 10:12:17 starvik Exp $ | ||
79 | *! | ||
80 | *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN | 22 | *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN |
81 | *! | 23 | *! |
82 | *!**************************************************************************/ | 24 | *!**************************************************************************/ |
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index 1a3760c94f85..53117f07cc1a 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: process.c,v 1.12 2004/12/27 11:18:32 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/kernel/process.c | 2 | * linux/arch/cris/kernel/process.c |
4 | * | 3 | * |
5 | * Copyright (C) 1995 Linus Torvalds | 4 | * Copyright (C) 1995 Linus Torvalds |
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index b570ae9b6cad..ee505b2eb4db 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c | |||
@@ -65,6 +65,7 @@ void | |||
65 | ptrace_disable(struct task_struct *child) | 65 | ptrace_disable(struct task_struct *child) |
66 | { | 66 | { |
67 | /* Todo - pending singlesteps? */ | 67 | /* Todo - pending singlesteps? */ |
68 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
68 | } | 69 | } |
69 | 70 | ||
70 | /* | 71 | /* |
diff --git a/arch/cris/arch-v10/kernel/shadows.c b/arch/cris/arch-v10/kernel/shadows.c index 326178aef6ee..2454a0b02f54 100644 --- a/arch/cris/arch-v10/kernel/shadows.c +++ b/arch/cris/arch-v10/kernel/shadows.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: shadows.c,v 1.2 2004/12/13 12:21:51 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * Various shadow registers. Defines for these are in include/asm-etrax100/io.h | 2 | * Various shadow registers. Defines for these are in include/asm-etrax100/io.h |
4 | */ | 3 | */ |
5 | 4 | ||
diff --git a/arch/cris/arch-v10/kernel/traps.c b/arch/cris/arch-v10/kernel/traps.c index 4becc1bcced9..9eada5d8893b 100644 --- a/arch/cris/arch-v10/kernel/traps.c +++ b/arch/cris/arch-v10/kernel/traps.c | |||
@@ -1,13 +1,10 @@ | |||
1 | /* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $ | 1 | /* |
2 | * Helper functions for trap handlers | ||
2 | * | 3 | * |
3 | * linux/arch/cris/arch-v10/traps.c | 4 | * Copyright (C) 2000-2007, Axis Communications AB. |
4 | * | 5 | * |
5 | * Heler functions for trap handlers | 6 | * Authors: Bjorn Wesen |
6 | * | 7 | * Hans-Peter Nilsson |
7 | * Copyright (C) 2000-2002 Axis Communications AB | ||
8 | * | ||
9 | * Authors: Bjorn Wesen | ||
10 | * Hans-Peter Nilsson | ||
11 | * | 8 | * |
12 | */ | 9 | */ |
13 | 10 | ||
@@ -15,124 +12,119 @@ | |||
15 | #include <asm/uaccess.h> | 12 | #include <asm/uaccess.h> |
16 | #include <asm/arch/sv_addr_ag.h> | 13 | #include <asm/arch/sv_addr_ag.h> |
17 | 14 | ||
18 | extern int raw_printk(const char *fmt, ...); | 15 | void |
19 | 16 | show_registers(struct pt_regs *regs) | |
20 | void | ||
21 | show_registers(struct pt_regs * regs) | ||
22 | { | 17 | { |
23 | /* We either use rdusp() - the USP register, which might not | 18 | /* |
24 | correspond to the current process for all cases we're called, | 19 | * It's possible to use either the USP register or current->thread.usp. |
25 | or we use the current->thread.usp, which is not up to date for | 20 | * USP might not correspond to the current process for all cases this |
26 | the current process. Experience shows we want the USP | 21 | * function is called, and current->thread.usp isn't up to date for the |
27 | register. */ | 22 | * current process. Experience shows that using USP is the way to go. |
23 | */ | ||
28 | unsigned long usp = rdusp(); | 24 | unsigned long usp = rdusp(); |
29 | 25 | ||
30 | raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", | 26 | printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", |
31 | regs->irp, regs->srp, regs->dccr, usp, regs->mof ); | 27 | regs->irp, regs->srp, regs->dccr, usp, regs->mof); |
32 | raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", | 28 | |
29 | printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", | ||
33 | regs->r0, regs->r1, regs->r2, regs->r3); | 30 | regs->r0, regs->r1, regs->r2, regs->r3); |
34 | raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", | 31 | |
32 | printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", | ||
35 | regs->r4, regs->r5, regs->r6, regs->r7); | 33 | regs->r4, regs->r5, regs->r6, regs->r7); |
36 | raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", | 34 | |
35 | printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", | ||
37 | regs->r8, regs->r9, regs->r10, regs->r11); | 36 | regs->r8, regs->r9, regs->r10, regs->r11); |
38 | raw_printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", | 37 | |
39 | regs->r12, regs->r13, regs->orig_r10, regs); | 38 | printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", |
40 | raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); | 39 | regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs); |
41 | raw_printk("Process %s (pid: %d, stackpage=%08lx)\n", | 40 | |
41 | printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); | ||
42 | |||
43 | printk("Process %s (pid: %d, stackpage=%08lx)\n", | ||
42 | current->comm, current->pid, (unsigned long)current); | 44 | current->comm, current->pid, (unsigned long)current); |
43 | 45 | ||
44 | /* | 46 | /* |
45 | * When in-kernel, we also print out the stack and code at the | 47 | * When in-kernel, we also print out the stack and code at the |
46 | * time of the fault.. | 48 | * time of the fault.. |
47 | */ | 49 | */ |
48 | if (! user_mode(regs)) { | 50 | if (!user_mode(regs)) { |
49 | int i; | 51 | int i; |
50 | 52 | ||
51 | show_stack(NULL, (unsigned long*)usp); | 53 | show_stack(NULL, (unsigned long *)usp); |
52 | 54 | ||
53 | /* Dump kernel stack if the previous dump wasn't one. */ | 55 | /* |
56 | * If the previous stack-dump wasn't a kernel one, dump the | ||
57 | * kernel stack now. | ||
58 | */ | ||
54 | if (usp != 0) | 59 | if (usp != 0) |
55 | show_stack (NULL, NULL); | 60 | show_stack(NULL, NULL); |
56 | 61 | ||
57 | raw_printk("\nCode: "); | 62 | printk("\nCode: "); |
58 | if(regs->irp < PAGE_OFFSET) | 63 | |
59 | goto bad; | 64 | if (regs->irp < PAGE_OFFSET) |
60 | 65 | goto bad_value; | |
61 | /* Often enough the value at regs->irp does not point to | 66 | |
62 | the interesting instruction, which is most often the | 67 | /* |
63 | _previous_ instruction. So we dump at an offset large | 68 | * Quite often the value at regs->irp doesn't point to the |
64 | enough that instruction decoding should be in sync at | 69 | * interesting instruction, which often is the previous |
65 | the interesting point, but small enough to fit on a row | 70 | * instruction. So dump at an offset large enough that the |
66 | (sort of). We point out the regs->irp location in a | 71 | * instruction decoding should be in sync at the interesting |
67 | ksymoops-friendly way by wrapping the byte for that | 72 | * point, but small enough to fit on a row. The regs->irp |
68 | address in parentheses. */ | 73 | * location is pointed out in a ksymoops-friendly way by |
69 | for(i = -12; i < 12; i++) | 74 | * wrapping the byte for that address in parenthesises. |
70 | { | 75 | */ |
71 | unsigned char c; | 76 | for (i = -12; i < 12; i++) { |
72 | if(__get_user(c, &((unsigned char*)regs->irp)[i])) { | 77 | unsigned char c; |
73 | bad: | 78 | |
74 | raw_printk(" Bad IP value."); | 79 | if (__get_user(c, &((unsigned char *)regs->irp)[i])) { |
75 | break; | 80 | bad_value: |
76 | } | 81 | printk(" Bad IP value."); |
82 | break; | ||
83 | } | ||
77 | 84 | ||
78 | if (i == 0) | 85 | if (i == 0) |
79 | raw_printk("(%02x) ", c); | 86 | printk("(%02x) ", c); |
80 | else | 87 | else |
81 | raw_printk("%02x ", c); | 88 | printk("%02x ", c); |
82 | } | 89 | } |
83 | raw_printk("\n"); | 90 | printk("\n"); |
84 | } | 91 | } |
85 | } | 92 | } |
86 | 93 | ||
87 | /* Called from entry.S when the watchdog has bitten | ||
88 | * We print out something resembling an oops dump, and if | ||
89 | * we have the nice doggy development flag set, we halt here | ||
90 | * instead of rebooting. | ||
91 | */ | ||
92 | |||
93 | extern void reset_watchdog(void); | ||
94 | extern void stop_watchdog(void); | ||
95 | |||
96 | |||
97 | void | 94 | void |
98 | watchdog_bite_hook(struct pt_regs *regs) | 95 | arch_enable_nmi(void) |
99 | { | 96 | { |
100 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 97 | asm volatile ("setf m"); |
101 | local_irq_disable(); | ||
102 | stop_watchdog(); | ||
103 | show_registers(regs); | ||
104 | while(1) /* nothing */; | ||
105 | #else | ||
106 | show_registers(regs); | ||
107 | #endif | ||
108 | } | 98 | } |
109 | 99 | ||
110 | /* This is normally the 'Oops' routine */ | 100 | extern void (*nmi_handler)(struct pt_regs *); |
111 | void | 101 | void handle_nmi(struct pt_regs *regs) |
112 | die_if_kernel(const char * str, struct pt_regs * regs, long err) | ||
113 | { | 102 | { |
114 | if(user_mode(regs)) | 103 | if (nmi_handler) |
115 | return; | 104 | nmi_handler(regs); |
116 | 105 | ||
117 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 106 | /* Wait until nmi is no longer active. (We enable NMI immediately after |
118 | /* This printout might take too long and trigger the | 107 | returning from this function, and we don't want it happening while |
119 | * watchdog normally. If we're in the nice doggy | 108 | exiting from the NMI interrupt handler.) */ |
120 | * development mode, stop the watchdog during printout. | 109 | while (*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active)) |
121 | */ | 110 | ; |
122 | stop_watchdog(); | ||
123 | #endif | ||
124 | |||
125 | raw_printk("%s: %04lx\n", str, err & 0xffff); | ||
126 | |||
127 | show_registers(regs); | ||
128 | |||
129 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | ||
130 | reset_watchdog(); | ||
131 | #endif | ||
132 | do_exit(SIGSEGV); | ||
133 | } | 111 | } |
134 | 112 | ||
135 | void arch_enable_nmi(void) | 113 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
114 | void | ||
115 | handle_BUG(struct pt_regs *regs) | ||
136 | { | 116 | { |
137 | asm volatile("setf m"); | 117 | struct bug_frame f; |
118 | unsigned char c; | ||
119 | unsigned long irp = regs->irp; | ||
120 | |||
121 | if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f)) | ||
122 | return; | ||
123 | if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC) | ||
124 | return; | ||
125 | if (__get_user(c, f.filename)) | ||
126 | f.filename = "<bad filename>"; | ||
127 | |||
128 | printk("kernel BUG at %s:%d!\n", f.filename, f.line); | ||
138 | } | 129 | } |
130 | #endif | ||
diff --git a/arch/cris/arch-v10/lib/checksum.S b/arch/cris/arch-v10/lib/checksum.S index 85c48f0a9ec2..7d552f4bd5ae 100644 --- a/arch/cris/arch-v10/lib/checksum.S +++ b/arch/cris/arch-v10/lib/checksum.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: checksum.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | 1 | /* |
2 | * A fast checksum routine using movem | 2 | * A fast checksum routine using movem |
3 | * Copyright (c) 1998-2001 Axis Communications AB | 3 | * Copyright (c) 1998-2001 Axis Communications AB |
4 | * | 4 | * |
@@ -61,8 +61,6 @@ _mloop: movem [$r10+],$r9 ; read 10 longwords | |||
61 | 61 | ||
62 | ax | 62 | ax |
63 | addq 0,$r12 | 63 | addq 0,$r12 |
64 | ax ; do it again, since we might have generated a carry | ||
65 | addq 0,$r12 | ||
66 | 64 | ||
67 | subq 10*4,$r11 | 65 | subq 10*4,$r11 |
68 | bge _mloop | 66 | bge _mloop |
@@ -88,10 +86,6 @@ _word_loop: | |||
88 | lsrq 16,$r13 ; r13 = checksum >> 16 | 86 | lsrq 16,$r13 ; r13 = checksum >> 16 |
89 | and.d $r9,$r12 ; checksum = checksum & 0xffff | 87 | and.d $r9,$r12 ; checksum = checksum & 0xffff |
90 | add.d $r13,$r12 ; checksum += r13 | 88 | add.d $r13,$r12 ; checksum += r13 |
91 | move.d $r12,$r13 ; do the same again, maybe we got a carry last add | ||
92 | lsrq 16,$r13 | ||
93 | and.d $r9,$r12 | ||
94 | add.d $r13,$r12 | ||
95 | 89 | ||
96 | _no_fold: | 90 | _no_fold: |
97 | cmpq 2,$r11 | 91 | cmpq 2,$r11 |
diff --git a/arch/cris/arch-v10/lib/checksumcopy.S b/arch/cris/arch-v10/lib/checksumcopy.S index 35cbffb306fd..540db8a5f849 100644 --- a/arch/cris/arch-v10/lib/checksumcopy.S +++ b/arch/cris/arch-v10/lib/checksumcopy.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: checksumcopy.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ | 1 | /* |
2 | * A fast checksum+copy routine using movem | 2 | * A fast checksum+copy routine using movem |
3 | * Copyright (c) 1998, 2001 Axis Communications AB | 3 | * Copyright (c) 1998, 2001 Axis Communications AB |
4 | * | 4 | * |
@@ -67,8 +67,6 @@ _mloop: movem [$r10+],$r9 ; read 10 longwords | |||
67 | 67 | ||
68 | ax | 68 | ax |
69 | addq 0,$r13 | 69 | addq 0,$r13 |
70 | ax ; do it again, since we might have generated a carry | ||
71 | addq 0,$r13 | ||
72 | 70 | ||
73 | subq 10*4,$r12 | 71 | subq 10*4,$r12 |
74 | bge _mloop | 72 | bge _mloop |
@@ -91,10 +89,6 @@ _word_loop: | |||
91 | lsrq 16,$r9 ; r0 = checksum >> 16 | 89 | lsrq 16,$r9 ; r0 = checksum >> 16 |
92 | and.d 0xffff,$r13 ; checksum = checksum & 0xffff | 90 | and.d 0xffff,$r13 ; checksum = checksum & 0xffff |
93 | add.d $r9,$r13 ; checksum += r0 | 91 | add.d $r9,$r13 ; checksum += r0 |
94 | move.d $r13,$r9 ; do the same again, maybe we got a carry last add | ||
95 | lsrq 16,$r9 | ||
96 | and.d 0xffff,$r13 | ||
97 | add.d $r9,$r13 | ||
98 | 92 | ||
99 | _no_fold: | 93 | _no_fold: |
100 | cmpq 2,$r12 | 94 | cmpq 2,$r12 |
diff --git a/arch/cris/arch-v10/lib/dram_init.S b/arch/cris/arch-v10/lib/dram_init.S index 6a6bdfd6984d..b9190ff7d0a4 100644 --- a/arch/cris/arch-v10/lib/dram_init.S +++ b/arch/cris/arch-v10/lib/dram_init.S | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: dram_init.S,v 1.4 2003/09/22 09:21:59 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * DRAM/SDRAM initialization - alter with care | 2 | * DRAM/SDRAM initialization - alter with care |
4 | * This file is intended to be included from other assembler files | 3 | * This file is intended to be included from other assembler files |
5 | * | 4 | * |
@@ -8,60 +7,7 @@ | |||
8 | * | 7 | * |
9 | * Copyright (C) 2000, 2001 Axis Communications AB | 8 | * Copyright (C) 2000, 2001 Axis Communications AB |
10 | * | 9 | * |
11 | * Authors: Mikael Starvik (starvik@axis.com) | 10 | * Authors: Mikael Starvik (starvik@axis.com) |
12 | * | ||
13 | * $Log: dram_init.S,v $ | ||
14 | * Revision 1.4 2003/09/22 09:21:59 starvik | ||
15 | * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx | ||
16 | * so we need to mask off 12 bits. | ||
17 | * | ||
18 | * Revision 1.3 2003/03/31 09:38:37 starvik | ||
19 | * Corrected calculation of end of sdram init commands | ||
20 | * | ||
21 | * Revision 1.2 2002/11/19 13:33:29 starvik | ||
22 | * Changes from Linux 2.4 | ||
23 | * | ||
24 | * Revision 1.13 2002/10/30 07:42:28 starvik | ||
25 | * Always read SDRAM command sequence from flash | ||
26 | * | ||
27 | * Revision 1.12 2002/08/09 11:37:37 orjanf | ||
28 | * Added double initialization work-around for Samsung SDRAMs. | ||
29 | * | ||
30 | * Revision 1.11 2002/06/04 11:43:21 starvik | ||
31 | * Check if mrs_data is specified in kernelconfig (necessary for MCM) | ||
32 | * | ||
33 | * Revision 1.10 2001/10/04 12:00:21 martinnn | ||
34 | * Added missing underscores. | ||
35 | * | ||
36 | * Revision 1.9 2001/10/01 14:47:35 bjornw | ||
37 | * Added register prefixes and removed underscores | ||
38 | * | ||
39 | * Revision 1.8 2001/05/15 07:12:45 hp | ||
40 | * Copy warning from head.S about r8 and r9 | ||
41 | * | ||
42 | * Revision 1.7 2001/04/18 12:05:39 bjornw | ||
43 | * Fixed comments, and explicitly include config.h to be sure its there | ||
44 | * | ||
45 | * Revision 1.6 2001/04/10 06:20:16 starvik | ||
46 | * Delay should be 200us, not 200ns | ||
47 | * | ||
48 | * Revision 1.5 2001/04/09 06:01:13 starvik | ||
49 | * Added support for 100 MHz SDRAMs | ||
50 | * | ||
51 | * Revision 1.4 2001/03/26 14:24:01 bjornw | ||
52 | * Namechange of some config options | ||
53 | * | ||
54 | * Revision 1.3 2001/03/23 08:29:41 starvik | ||
55 | * Corrected calculation of mrs_data | ||
56 | * | ||
57 | * Revision 1.2 2001/02/08 15:20:00 starvik | ||
58 | * Corrected SDRAM initialization | ||
59 | * Should now be included as inline | ||
60 | * | ||
61 | * Revision 1.1 2001/01/29 13:08:02 starvik | ||
62 | * Initial version | ||
63 | * This file should be included from all assembler files that needs to | ||
64 | * initialize DRAM/SDRAM. | ||
65 | * | 11 | * |
66 | */ | 12 | */ |
67 | 13 | ||
diff --git a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c index 497634a64829..1734b467efa6 100644 --- a/arch/cris/arch-v10/lib/old_checksum.c +++ b/arch/cris/arch-v10/lib/old_checksum.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: old_checksum.c,v 1.3 2003/10/27 08:04:32 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * INET An implementation of the TCP/IP protocol suite for the LINUX | 2 | * INET An implementation of the TCP/IP protocol suite for the LINUX |
4 | * operating system. INET is implemented using the BSD Socket | 3 | * operating system. INET is implemented using the BSD Socket |
5 | * interface as the means of communication with the user level. | 4 | * interface as the means of communication with the user level. |
diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c index fe2615022b97..65504fd80928 100644 --- a/arch/cris/arch-v10/mm/fault.c +++ b/arch/cris/arch-v10/mm/fault.c | |||
@@ -4,10 +4,10 @@ | |||
4 | * Low level bus fault handler | 4 | * Low level bus fault handler |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * Copyright (C) 2000, 2001 Axis Communications AB | 7 | * Copyright (C) 2000-2007 Axis Communications AB |
8 | * | ||
9 | * Authors: Bjorn Wesen | ||
8 | * | 10 | * |
9 | * Authors: Bjorn Wesen | ||
10 | * | ||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
@@ -60,7 +60,7 @@ handle_mmu_bus_fault(struct pt_regs *regs) | |||
60 | #ifdef DEBUG | 60 | #ifdef DEBUG |
61 | page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); | 61 | page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); |
62 | acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); | 62 | acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); |
63 | inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); | 63 | inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); |
64 | index = IO_EXTRACT(R_TLB_SELECT, index, select); | 64 | index = IO_EXTRACT(R_TLB_SELECT, index, select); |
65 | #endif | 65 | #endif |
66 | miss = IO_EXTRACT(R_MMU_CAUSE, miss_excp, cause); | 66 | miss = IO_EXTRACT(R_MMU_CAUSE, miss_excp, cause); |
@@ -84,12 +84,13 @@ handle_mmu_bus_fault(struct pt_regs *regs) | |||
84 | local_irq_disable(); | 84 | local_irq_disable(); |
85 | pmd = (pmd_t *)(pgd + pgd_index(address)); | 85 | pmd = (pmd_t *)(pgd + pgd_index(address)); |
86 | if (pmd_none(*pmd)) | 86 | if (pmd_none(*pmd)) |
87 | return; | 87 | goto exit; |
88 | pte = *pte_offset_kernel(pmd, address); | 88 | pte = *pte_offset_kernel(pmd, address); |
89 | if (!pte_present(pte)) | 89 | if (!pte_present(pte)) |
90 | return; | 90 | goto exit; |
91 | *R_TLB_SELECT = select; | 91 | *R_TLB_SELECT = select; |
92 | *R_TLB_HI = cause; | 92 | *R_TLB_HI = cause; |
93 | *R_TLB_LO = pte_val(pte); | 93 | *R_TLB_LO = pte_val(pte); |
94 | exit: | ||
94 | local_irq_restore(flags); | 95 | local_irq_restore(flags); |
95 | } | 96 | } |
diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c index 7d9fec88dee5..6baf5bd209e7 100644 --- a/arch/cris/arch-v10/mm/tlb.c +++ b/arch/cris/arch-v10/mm/tlb.c | |||
@@ -4,8 +4,8 @@ | |||
4 | * Low level TLB handling | 4 | * Low level TLB handling |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * Copyright (C) 2000-2002 Axis Communications AB | 7 | * Copyright (C) 2000-2007 Axis Communications AB |
8 | * | 8 | * |
9 | * Authors: Bjorn Wesen (bjornw@axis.com) | 9 | * Authors: Bjorn Wesen (bjornw@axis.com) |
10 | * | 10 | * |
11 | */ | 11 | */ |
@@ -39,7 +39,7 @@ flush_tlb_all(void) | |||
39 | unsigned long flags; | 39 | unsigned long flags; |
40 | 40 | ||
41 | /* the vpn of i & 0xf is so we dont write similar TLB entries | 41 | /* the vpn of i & 0xf is so we dont write similar TLB entries |
42 | * in the same 4-way entry group. details.. | 42 | * in the same 4-way entry group. details... |
43 | */ | 43 | */ |
44 | 44 | ||
45 | local_irq_save(flags); | 45 | local_irq_save(flags); |
@@ -47,7 +47,7 @@ flush_tlb_all(void) | |||
47 | *R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) ); | 47 | *R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) ); |
48 | *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | | 48 | *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | |
49 | IO_FIELD(R_TLB_HI, vpn, i & 0xf ) ); | 49 | IO_FIELD(R_TLB_HI, vpn, i & 0xf ) ); |
50 | 50 | ||
51 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | | 51 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | |
52 | IO_STATE(R_TLB_LO, valid, no ) | | 52 | IO_STATE(R_TLB_LO, valid, no ) | |
53 | IO_STATE(R_TLB_LO, kernel,no ) | | 53 | IO_STATE(R_TLB_LO, kernel,no ) | |
@@ -71,10 +71,10 @@ flush_tlb_mm(struct mm_struct *mm) | |||
71 | 71 | ||
72 | if(page_id == NO_CONTEXT) | 72 | if(page_id == NO_CONTEXT) |
73 | return; | 73 | return; |
74 | 74 | ||
75 | /* mark the TLB entries that match the page_id as invalid. | 75 | /* mark the TLB entries that match the page_id as invalid. |
76 | * here we could also check the _PAGE_GLOBAL bit and NOT flush | 76 | * here we could also check the _PAGE_GLOBAL bit and NOT flush |
77 | * global pages. is it worth the extra I/O ? | 77 | * global pages. is it worth the extra I/O ? |
78 | */ | 78 | */ |
79 | 79 | ||
80 | local_irq_save(flags); | 80 | local_irq_save(flags); |
@@ -83,7 +83,7 @@ flush_tlb_mm(struct mm_struct *mm) | |||
83 | if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) { | 83 | if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) { |
84 | *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | | 84 | *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | |
85 | IO_FIELD(R_TLB_HI, vpn, i & 0xf ) ); | 85 | IO_FIELD(R_TLB_HI, vpn, i & 0xf ) ); |
86 | 86 | ||
87 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | | 87 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | |
88 | IO_STATE(R_TLB_LO, valid, no ) | | 88 | IO_STATE(R_TLB_LO, valid, no ) | |
89 | IO_STATE(R_TLB_LO, kernel,no ) | | 89 | IO_STATE(R_TLB_LO, kernel,no ) | |
@@ -96,9 +96,7 @@ flush_tlb_mm(struct mm_struct *mm) | |||
96 | 96 | ||
97 | /* invalidate a single page */ | 97 | /* invalidate a single page */ |
98 | 98 | ||
99 | void | 99 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) |
100 | flush_tlb_page(struct vm_area_struct *vma, | ||
101 | unsigned long addr) | ||
102 | { | 100 | { |
103 | struct mm_struct *mm = vma->vm_mm; | 101 | struct mm_struct *mm = vma->vm_mm; |
104 | int page_id = mm->context.page_id; | 102 | int page_id = mm->context.page_id; |
@@ -113,7 +111,7 @@ flush_tlb_page(struct vm_area_struct *vma, | |||
113 | addr &= PAGE_MASK; /* perhaps not necessary */ | 111 | addr &= PAGE_MASK; /* perhaps not necessary */ |
114 | 112 | ||
115 | /* invalidate those TLB entries that match both the mm context | 113 | /* invalidate those TLB entries that match both the mm context |
116 | * and the virtual address requested | 114 | * and the virtual address requested |
117 | */ | 115 | */ |
118 | 116 | ||
119 | local_irq_save(flags); | 117 | local_irq_save(flags); |
@@ -125,7 +123,7 @@ flush_tlb_page(struct vm_area_struct *vma, | |||
125 | (tlb_hi & PAGE_MASK) == addr) { | 123 | (tlb_hi & PAGE_MASK) == addr) { |
126 | *R_TLB_HI = IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | | 124 | *R_TLB_HI = IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | |
127 | addr; /* same addr as before works. */ | 125 | addr; /* same addr as before works. */ |
128 | 126 | ||
129 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | | 127 | *R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no ) | |
130 | IO_STATE(R_TLB_LO, valid, no ) | | 128 | IO_STATE(R_TLB_LO, valid, no ) | |
131 | IO_STATE(R_TLB_LO, kernel,no ) | | 129 | IO_STATE(R_TLB_LO, kernel,no ) | |
@@ -144,7 +142,7 @@ dump_tlb_all(void) | |||
144 | { | 142 | { |
145 | int i; | 143 | int i; |
146 | unsigned long flags; | 144 | unsigned long flags; |
147 | 145 | ||
148 | printk("TLB dump. LO is: pfn | reserved | global | valid | kernel | we |\n"); | 146 | printk("TLB dump. LO is: pfn | reserved | global | valid | kernel | we |\n"); |
149 | 147 | ||
150 | local_save_flags(flags); | 148 | local_save_flags(flags); |
@@ -172,27 +170,29 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm) | |||
172 | 170 | ||
173 | /* called in schedule() just before actually doing the switch_to */ | 171 | /* called in schedule() just before actually doing the switch_to */ |
174 | 172 | ||
175 | void | 173 | void switch_mm(struct mm_struct *prev, struct mm_struct *next, |
176 | switch_mm(struct mm_struct *prev, struct mm_struct *next, | 174 | struct task_struct *tsk) |
177 | struct task_struct *tsk) | ||
178 | { | 175 | { |
179 | /* make sure we have a context */ | 176 | if (prev != next) { |
177 | /* make sure we have a context */ | ||
178 | get_mmu_context(next); | ||
180 | 179 | ||
181 | get_mmu_context(next); | 180 | /* remember the pgd for the fault handlers |
181 | * this is similar to the pgd register in some other CPU's. | ||
182 | * we need our own copy of it because current and active_mm | ||
183 | * might be invalid at points where we still need to derefer | ||
184 | * the pgd. | ||
185 | */ | ||
182 | 186 | ||
183 | /* remember the pgd for the fault handlers | 187 | per_cpu(current_pgd, smp_processor_id()) = next->pgd; |
184 | * this is similar to the pgd register in some other CPU's. | ||
185 | * we need our own copy of it because current and active_mm | ||
186 | * might be invalid at points where we still need to derefer | ||
187 | * the pgd. | ||
188 | */ | ||
189 | 188 | ||
190 | per_cpu(current_pgd, smp_processor_id()) = next->pgd; | 189 | /* switch context in the MMU */ |
191 | 190 | ||
192 | /* switch context in the MMU */ | 191 | D(printk(KERN_DEBUG "switching mmu_context to %d (%p)\n", |
193 | 192 | next->context, next)); | |
194 | D(printk("switching mmu_context to %d (%p)\n", next->context, next)); | ||
195 | 193 | ||
196 | *R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT, page_id, next->context.page_id); | 194 | *R_MMU_CONTEXT = IO_FIELD(R_MMU_CONTEXT, |
195 | page_id, next->context.page_id); | ||
196 | } | ||
197 | } | 197 | } |
198 | 198 | ||
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig index d8acaa920e1c..005ed2b3f7f4 100644 --- a/arch/cris/arch-v32/Kconfig +++ b/arch/cris/arch-v32/Kconfig | |||
@@ -1,27 +1,73 @@ | |||
1 | if ETRAX_ARCH_V32 | 1 | if ETRAX_ARCH_V32 |
2 | 2 | ||
3 | source arch/cris/arch-v32/mach-fs/Kconfig | ||
4 | source arch/cris/arch-v32/mach-a3/Kconfig | ||
5 | |||
6 | source drivers/cpufreq/Kconfig | ||
7 | |||
3 | config ETRAX_DRAM_VIRTUAL_BASE | 8 | config ETRAX_DRAM_VIRTUAL_BASE |
4 | hex | 9 | hex |
5 | depends on ETRAX_ARCH_V32 | 10 | depends on ETRAX_ARCH_V32 |
6 | default "c0000000" | 11 | default "c0000000" |
7 | 12 | ||
8 | config ETRAX_LED1G | 13 | choice |
9 | string "First green LED bit" | 14 | prompt "Nbr of Ethernet LED groups" |
10 | depends on ETRAX_ARCH_V32 | 15 | depends on ETRAX_ARCH_V32 |
16 | default ETRAX_NBR_LED_GRP_ONE | ||
17 | help | ||
18 | Select how many Ethernet LED groups that can be used. Usually one per Ethernet | ||
19 | interface is a good choice. | ||
20 | |||
21 | config ETRAX_NBR_LED_GRP_ZERO | ||
22 | bool "Use zero LED groups" | ||
23 | help | ||
24 | Select this if you do not want any Ethernet LEDs. | ||
25 | |||
26 | config ETRAX_NBR_LED_GRP_ONE | ||
27 | bool "Use one LED group" | ||
28 | help | ||
29 | Select this if you want one Ethernet LED group. This LED group | ||
30 | can be used for one or more Ethernet interfaces. However, it is | ||
31 | recomended that each Ethernet interface use a dedicated LED group. | ||
32 | |||
33 | config ETRAX_NBR_LED_GRP_TWO | ||
34 | bool "Use two LED groups" | ||
35 | help | ||
36 | Select this if you want two Ethernet LED groups. This is the | ||
37 | best choice if you have more than one Ethernet interface and | ||
38 | would like to have separate LEDs for the interfaces. | ||
39 | |||
40 | endchoice | ||
41 | |||
42 | config ETRAX_LED_G_NET0 | ||
43 | string "Ethernet LED group 0 green LED bit" | ||
44 | depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO) | ||
11 | default "PA3" | 45 | default "PA3" |
12 | help | 46 | help |
13 | Bit to use for the first green LED (network LED). | 47 | Bit to use for the green LED in Ethernet LED group 0. |
14 | Most Axis products use bit A3 here. | ||
15 | 48 | ||
16 | config ETRAX_LED1R | 49 | config ETRAX_LED_R_NET0 |
17 | string "First red LED bit" | 50 | string "Ethernet LED group 0 red LED bit" |
18 | depends on ETRAX_ARCH_V32 | 51 | depends on ETRAX_ARCH_V32 && (ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO) |
19 | default "PA4" | 52 | default "PA4" |
20 | help | 53 | help |
21 | Bit to use for the first red LED (network LED). | 54 | Bit to use for the red LED in Ethernet LED group 0. |
22 | Most Axis products use bit A4 here. | ||
23 | 55 | ||
24 | config ETRAX_LED2G | 56 | config ETRAX_LED_G_NET1 |
57 | string "Ethernet group 1 green LED bit" | ||
58 | depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO | ||
59 | default "" | ||
60 | help | ||
61 | Bit to use for the green LED in Ethernet LED group 1. | ||
62 | |||
63 | config ETRAX_LED_R_NET1 | ||
64 | string "Ethernet group 1 red LED bit" | ||
65 | depends on ETRAX_ARCH_V32 && ETRAX_NBR_LED_GRP_TWO | ||
66 | default "" | ||
67 | help | ||
68 | Bit to use for the red LED in Ethernet LED group 1. | ||
69 | |||
70 | config ETRAX_V32_LED2G | ||
25 | string "Second green LED bit" | 71 | string "Second green LED bit" |
26 | depends on ETRAX_ARCH_V32 | 72 | depends on ETRAX_ARCH_V32 |
27 | default "PA5" | 73 | default "PA5" |
@@ -29,7 +75,7 @@ config ETRAX_LED2G | |||
29 | Bit to use for the first green LED (status LED). | 75 | Bit to use for the first green LED (status LED). |
30 | Most Axis products use bit A5 here. | 76 | Most Axis products use bit A5 here. |
31 | 77 | ||
32 | config ETRAX_LED2R | 78 | config ETRAX_V32_LED2R |
33 | string "Second red LED bit" | 79 | string "Second red LED bit" |
34 | depends on ETRAX_ARCH_V32 | 80 | depends on ETRAX_ARCH_V32 |
35 | default "PA6" | 81 | default "PA6" |
@@ -37,7 +83,7 @@ config ETRAX_LED2R | |||
37 | Bit to use for the first red LED (network LED). | 83 | Bit to use for the first red LED (network LED). |
38 | Most Axis products use bit A6 here. | 84 | Most Axis products use bit A6 here. |
39 | 85 | ||
40 | config ETRAX_LED3G | 86 | config ETRAX_V32_LED3G |
41 | string "Third green LED bit" | 87 | string "Third green LED bit" |
42 | depends on ETRAX_ARCH_V32 | 88 | depends on ETRAX_ARCH_V32 |
43 | default "PA7" | 89 | default "PA7" |
@@ -45,7 +91,7 @@ config ETRAX_LED3G | |||
45 | Bit to use for the first green LED (drive/power LED). | 91 | Bit to use for the first green LED (drive/power LED). |
46 | Most Axis products use bit A7 here. | 92 | Most Axis products use bit A7 here. |
47 | 93 | ||
48 | config ETRAX_LED3R | 94 | config ETRAX_V32_LED3R |
49 | string "Third red LED bit" | 95 | string "Third red LED bit" |
50 | depends on ETRAX_ARCH_V32 | 96 | depends on ETRAX_ARCH_V32 |
51 | default "PA7" | 97 | default "PA7" |
@@ -54,39 +100,6 @@ config ETRAX_LED3R | |||
54 | Most Axis products use bit A7 here. | 100 | Most Axis products use bit A7 here. |
55 | 101 | ||
56 | choice | 102 | choice |
57 | prompt "Product debug-port" | ||
58 | depends on ETRAX_ARCH_V32 | ||
59 | default ETRAX_DEBUG_PORT0 | ||
60 | |||
61 | config ETRAX_DEBUG_PORT0 | ||
62 | bool "Serial-0" | ||
63 | help | ||
64 | Choose a serial port for the ETRAX debug console. Default to | ||
65 | port 0. | ||
66 | |||
67 | config ETRAX_DEBUG_PORT1 | ||
68 | bool "Serial-1" | ||
69 | help | ||
70 | Use serial port 1 for the console. | ||
71 | |||
72 | config ETRAX_DEBUG_PORT2 | ||
73 | bool "Serial-2" | ||
74 | help | ||
75 | Use serial port 2 for the console. | ||
76 | |||
77 | config ETRAX_DEBUG_PORT3 | ||
78 | bool "Serial-3" | ||
79 | help | ||
80 | Use serial port 3 for the console. | ||
81 | |||
82 | config ETRAX_DEBUG_PORT_NULL | ||
83 | bool "disabled" | ||
84 | help | ||
85 | Disable serial-port debugging. | ||
86 | |||
87 | endchoice | ||
88 | |||
89 | choice | ||
90 | prompt "Kernel GDB port" | 103 | prompt "Kernel GDB port" |
91 | depends on ETRAX_KGDB | 104 | depends on ETRAX_KGDB |
92 | default ETRAX_KGDB_PORT0 | 105 | default ETRAX_KGDB_PORT0 |
@@ -95,25 +108,11 @@ choice | |||
95 | not be enabled under Drivers for built-in interfaces (as it has its | 108 | not be enabled under Drivers for built-in interfaces (as it has its |
96 | own initialization code) and should not be the same as the debug port. | 109 | own initialization code) and should not be the same as the debug port. |
97 | 110 | ||
98 | config ETRAX_KGDB_PORT0 | 111 | config ETRAX_KGDB_PORT4 |
99 | bool "Serial-0" | 112 | bool "Serial-4" |
100 | help | 113 | depends on ETRAX_SERIAL_PORTS = 5 |
101 | Use serial port 0 for kernel debugging. | ||
102 | |||
103 | config ETRAX_KGDB_PORT1 | ||
104 | bool "Serial-1" | ||
105 | help | ||
106 | Use serial port 1 for kernel debugging. | ||
107 | |||
108 | config ETRAX_KGDB_PORT2 | ||
109 | bool "Serial-2" | ||
110 | help | ||
111 | Use serial port 2 for kernel debugging. | ||
112 | |||
113 | config ETRAX_KGDB_PORT3 | ||
114 | bool "Serial-3" | ||
115 | help | 114 | help |
116 | Use serial port 3 for kernel debugging. | 115 | Use serial port 4 for kernel debugging. |
117 | 116 | ||
118 | endchoice | 117 | endchoice |
119 | 118 | ||
diff --git a/arch/cris/arch-v32/boot/Makefile b/arch/cris/arch-v32/boot/Makefile index 26f293ab9617..3f91349c5f12 100644 --- a/arch/cris/arch-v32/boot/Makefile +++ b/arch/cris/arch-v32/boot/Makefile | |||
@@ -1,14 +1,21 @@ | |||
1 | # | 1 | # |
2 | # arch/cris/arch-v32/boot/Makefile | 2 | # arch/cris/arch-v32/boot/Makefile |
3 | # | 3 | # |
4 | target = $(target_boot_dir) | ||
5 | src = $(src_boot_dir) | ||
6 | 4 | ||
7 | zImage: compressed/vmlinuz | 5 | OBJCOPY = objcopy-cris |
6 | OBJCOPYFLAGS = -O binary -R .note -R .comment | ||
8 | 7 | ||
9 | compressed/vmlinuz: $(objtree)/vmlinux | 8 | subdir- := compressed rescue |
10 | @$(MAKE) -f $(src)/compressed/Makefile $(objtree)/vmlinuz | 9 | targets := Image |
11 | 10 | ||
12 | clean: | 11 | $(obj)/Image: vmlinux FORCE |
13 | rm -f zImage tools/build compressed/vmlinux.out | 12 | $(call if_changed,objcopy) |
14 | @$(MAKE) -f $(src)/compressed/Makefile clean | 13 | @echo ' Kernel: $@ is ready' |
14 | |||
15 | $(obj)/compressed/vmlinux: $(obj)/Image FORCE | ||
16 | $(Q)$(MAKE) $(build)=$(obj)/compressed $@ | ||
17 | $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin | ||
18 | |||
19 | $(obj)/zImage: $(obj)/compressed/vmlinux | ||
20 | @cp $< $@ | ||
21 | @echo ' Kernel: $@ is ready' | ||
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile index 609692f9d5eb..2c8c2c3039c5 100644 --- a/arch/cris/arch-v32/boot/compressed/Makefile +++ b/arch/cris/arch-v32/boot/compressed/Makefile | |||
@@ -1,41 +1,30 @@ | |||
1 | # | 1 | # |
2 | # lx25/arch/cris/arch-v32/boot/compressed/Makefile | 2 | # arch/cris/arch-v32/boot/compressed/Makefile |
3 | # | 3 | # |
4 | # create a compressed vmlinux image from the original vmlinux files and romfs | ||
5 | # | ||
6 | |||
7 | target = $(target_compressed_dir) | ||
8 | src = $(src_compressed_dir) | ||
9 | 4 | ||
10 | CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE) | 5 | CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE) |
11 | CFLAGS = -O2 | 6 | asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch |
7 | ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch | ||
12 | LD = gcc-cris -mlinux -march=v32 -nostdlib | 8 | LD = gcc-cris -mlinux -march=v32 -nostdlib |
9 | ldflags-y += -T $(obj)/decompress.ld | ||
10 | obj-y = head.o misc.o | ||
11 | OBJECTS = $(obj)/head.o $(obj)/misc.o | ||
13 | OBJCOPY = objcopy-cris | 12 | OBJCOPY = objcopy-cris |
14 | OBJCOPYFLAGS = -O binary --remove-section=.bss | 13 | OBJCOPYFLAGS = -O binary --remove-section=.bss |
15 | OBJECTS = $(target)/head.o $(target)/misc.o | ||
16 | |||
17 | # files to compress | ||
18 | SYSTEM = $(objtree)/vmlinux.bin | ||
19 | |||
20 | all: vmlinuz | ||
21 | |||
22 | $(target)/decompress.bin: $(OBJECTS) | ||
23 | $(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS) | ||
24 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin | ||
25 | 14 | ||
26 | $(objtree)/vmlinuz: $(target) piggy.img $(target)/decompress.bin | 15 | quiet_cmd_image = BUILD $@ |
27 | cat $(target)/decompress.bin piggy.img > $(objtree)/vmlinuz | 16 | cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@ |
28 | rm -f piggy.img | ||
29 | cp $(objtree)/vmlinuz $(src) | ||
30 | 17 | ||
31 | $(target)/head.o: $(src)/head.S | 18 | targets := vmlinux piggy.gz decompress.o decompress.bin |
32 | $(CC) -D__ASSEMBLY__ -c $< -o $@ | ||
33 | 19 | ||
34 | # gzip the kernel image | 20 | $(obj)/decompress.o: $(OBJECTS) FORCE |
21 | $(call if_changed,ld) | ||
35 | 22 | ||
36 | piggy.img: $(SYSTEM) | 23 | $(obj)/decompress.bin: $(obj)/decompress.o FORCE |
37 | cat $(SYSTEM) | gzip -f -9 > piggy.img | 24 | $(call if_changed,objcopy) |
38 | 25 | ||
39 | clean: | 26 | $(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE |
40 | rm -f piggy.img $(objtree)/vmlinuz vmlinuz.o decompress.o decompress.bin $(OBJECTS) | 27 | $(call if_changed,image) |
41 | 28 | ||
29 | $(obj)/piggy.gz: $(obj)/../Image FORCE | ||
30 | $(call if_changed,gzip) | ||
diff --git a/arch/cris/arch-v32/boot/compressed/README b/arch/cris/arch-v32/boot/compressed/README index e33691d15c57..182c5d75784b 100644 --- a/arch/cris/arch-v32/boot/compressed/README +++ b/arch/cris/arch-v32/boot/compressed/README | |||
@@ -1,6 +1,5 @@ | |||
1 | Creation of the self-extracting compressed kernel image (vmlinuz) | 1 | Creation of the self-extracting compressed kernel image (vmlinuz) |
2 | ----------------------------------------------------------------- | 2 | ----------------------------------------------------------------- |
3 | $Id: README,v 1.1 2003/08/21 09:37:03 johana Exp $ | ||
4 | 3 | ||
5 | This can be slightly confusing because it's a process with many steps. | 4 | This can be slightly confusing because it's a process with many steps. |
6 | 5 | ||
diff --git a/arch/cris/arch-v32/boot/compressed/head.S b/arch/cris/arch-v32/boot/compressed/head.S index 34cea10a8998..f86208caf32d 100644 --- a/arch/cris/arch-v32/boot/compressed/head.S +++ b/arch/cris/arch-v32/boot/compressed/head.S | |||
@@ -2,13 +2,12 @@ | |||
2 | * Code that sets up the DRAM registers, calls the | 2 | * Code that sets up the DRAM registers, calls the |
3 | * decompressor to unpack the piggybacked kernel, and jumps. | 3 | * decompressor to unpack the piggybacked kernel, and jumps. |
4 | * | 4 | * |
5 | * Copyright (C) 1999 - 2003, Axis Communications AB | 5 | * Copyright (C) 1999 - 2006, Axis Communications AB |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define ASSEMBLER_MACROS_ONLY | 8 | #define ASSEMBLER_MACROS_ONLY |
9 | #include <asm/arch/hwregs/asm/reg_map_asm.h> | 9 | #include <hwregs/asm/reg_map_asm.h> |
10 | #include <asm/arch/hwregs/asm/gio_defs_asm.h> | 10 | #include <asm/arch/mach/startup.inc> |
11 | #include <asm/arch/hwregs/asm/config_defs_asm.h> | ||
12 | 11 | ||
13 | #define RAM_INIT_MAGIC 0x56902387 | 12 | #define RAM_INIT_MAGIC 0x56902387 |
14 | #define COMMAND_LINE_MAGIC 0x87109563 | 13 | #define COMMAND_LINE_MAGIC 0x87109563 |
@@ -22,114 +21,49 @@ start: | |||
22 | di | 21 | di |
23 | 22 | ||
24 | ;; Start clocks for used blocks. | 23 | ;; Start clocks for used blocks. |
25 | move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1 | 24 | START_CLOCKS |
26 | move.d [$r1], $r0 | 25 | |
27 | or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \ | 26 | ;; Initialize the DRAM registers. |
28 | REG_STATE(config, rw_clk_ctrl, bif, yes) | \ | ||
29 | REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0 | ||
30 | move.d $r0, [$r1] | ||
31 | |||
32 | ;; If booting from NAND flash we first have to copy some | ||
33 | ;; data from NAND flash to internal RAM to get the code | ||
34 | ;; that initializes the SDRAM. Lets copy 20 KB. This | ||
35 | ;; code executes at 0x38010000 if booting from NAND and | ||
36 | ;; we are guaranted that at least 0x200 bytes are good so | ||
37 | ;; lets start from there. The first 8192 bytes in the nand | ||
38 | ;; flash is spliced with zeroes and is thus 16384 bytes. | ||
39 | move.d 0x38010200, $r10 | ||
40 | move.d 0x14200, $r11 ; Start offset in NAND flash 0x10200 + 16384 | ||
41 | move.d 0x5000, $r12 ; Length of copy | ||
42 | |||
43 | ;; Before this code the tools add a partitiontable so the PC | ||
44 | ;; has an offset from the linked address. | ||
45 | offset1: | ||
46 | lapcq ., $r13 ; get PC | ||
47 | add.d first_copy_complete-offset1, $r13 | ||
48 | |||
49 | #include "../../lib/nand_init.S" | ||
50 | |||
51 | first_copy_complete: | ||
52 | ;; Initialze the DRAM registers. | ||
53 | cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? | 27 | cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? |
54 | beq dram_init_finished | 28 | beq dram_init_finished |
55 | nop | 29 | nop |
56 | 30 | ||
57 | #include "../../lib/dram_init.S" | 31 | #include "../../mach/dram_init.S" |
58 | 32 | ||
59 | dram_init_finished: | 33 | dram_init_finished: |
60 | lapcq ., $r13 ; get PC | ||
61 | add.d second_copy_complete-dram_init_finished, $r13 | ||
62 | |||
63 | move.d REG_ADDR(config, regi_config, r_bootsel), $r0 | ||
64 | move.d [$r0], $r0 | ||
65 | and.d REG_MASK(config, r_bootsel, boot_mode), $r0 | ||
66 | cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0 | ||
67 | bne second_copy_complete ; No NAND boot | ||
68 | nop | ||
69 | |||
70 | ;; Copy 2MB from NAND flash to SDRAM (at 2-4MB into the SDRAM) | ||
71 | move.d 0x40204000, $r10 | ||
72 | move.d 0x8000, $r11 | ||
73 | move.d 0x200000, $r12 | ||
74 | ba copy_nand_to_ram | ||
75 | nop | ||
76 | second_copy_complete: | ||
77 | |||
78 | ;; Initiate the PA port. | ||
79 | move.d CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0 | ||
80 | move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r1 | ||
81 | move.d $r0, [$r1] | ||
82 | |||
83 | move.d CONFIG_ETRAX_DEF_GIO_PA_OE, $r0 | ||
84 | move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r1 | ||
85 | move.d $r0, [$r1] | ||
86 | 34 | ||
35 | GIO_INIT | ||
87 | ;; Setup the stack to a suitably high address. | 36 | ;; Setup the stack to a suitably high address. |
88 | ;; We assume 8 MB is the minimum DRAM and put | 37 | ;; We assume 8 MB is the minimum DRAM and put |
89 | ;; the SP at the top for now. | 38 | ;; the SP at the top for now. |
90 | 39 | ||
91 | move.d 0x40800000, $sp | 40 | move.d 0x40800000, $sp |
92 | 41 | ||
93 | ;; Figure out where the compressed piggyback image is | 42 | ;; Figure out where the compressed piggyback image is. |
94 | ;; in the flash (since we wont try to copy it to DRAM | 43 | ;; It is either in [NOR] flash (we don't want to copy it |
95 | ;; before unpacking). It is at _edata, but in flash. | 44 | ;; to DRAM before unpacking), or copied to DRAM |
45 | ;; by the [NAND] flash boot loader. | ||
46 | ;; The piggyback image is at _edata, but relative to where the | ||
47 | ;; image is actually located in memory, not where it is linked | ||
48 | ;; (the decompressor is linked at 0x40700000+ and runs there). | ||
96 | ;; Use (_edata - herami) as offset to the current PC. | 49 | ;; Use (_edata - herami) as offset to the current PC. |
97 | 50 | ||
98 | move.d REG_ADDR(config, regi_config, r_bootsel), $r0 | ||
99 | move.d [$r0], $r0 | ||
100 | and.d REG_MASK(config, r_bootsel, boot_mode), $r0 | ||
101 | cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0 | ||
102 | beq hereami2 | ||
103 | nop | ||
104 | hereami: | 51 | hereami: |
105 | lapcq ., $r5 ; get PC | 52 | lapcq ., $r5 ; get PC |
106 | and.d 0x7fffffff, $r5 ; strip any non-cache bit | 53 | and.d 0x7fffffff, $r5 ; strip any non-cache bit |
107 | move.d $r5, $r0 ; save for later - flash address of 'herami' | 54 | move.d $r5, $r0 ; source address of 'herami' |
108 | add.d _edata, $r5 | 55 | add.d _edata, $r5 |
109 | sub.d hereami, $r5 ; r5 = flash address of '_edata' | 56 | sub.d hereami, $r5 ; r5 = flash address of '_edata' |
110 | move.d hereami, $r1 ; destination | 57 | move.d hereami, $r1 ; destination |
111 | ba 2f | 58 | |
112 | nop | ||
113 | hereami2: | ||
114 | lapcq ., $r5 ; get PC | ||
115 | and.d 0x00ffffff, $r5 ; strip any non-cache bit | ||
116 | move.d $r5, $r6 | ||
117 | or.d 0x40200000, $r6 | ||
118 | move.d $r6, $r0 ; save for later - flash address of 'herami' | ||
119 | add.d _edata, $r5 | ||
120 | sub.d hereami2, $r5 ; r5 = flash address of '_edata' | ||
121 | add.d 0x40200000, $r5 | ||
122 | move.d hereami2, $r1 ; destination | ||
123 | 2: | ||
124 | ;; Copy text+data to DRAM | 59 | ;; Copy text+data to DRAM |
125 | 60 | ||
126 | move.d _edata, $r2 ; end destination | 61 | move.d _edata, $r2 ; end destination |
127 | 1: move.w [$r0+], $r3 | 62 | 1: move.w [$r0+], $r3 ; from herami+ source |
128 | move.w $r3, [$r1+] | 63 | move.w $r3, [$r1+] ; to hereami+ destination (linked address) |
129 | cmp.d $r2, $r1 | 64 | cmp.d $r2, $r1 ; finish when destination == _edata |
130 | bcs 1b | 65 | bcs 1b |
131 | nop | 66 | nop |
132 | |||
133 | move.d input_data, $r0 ; for the decompressor | 67 | move.d input_data, $r0 ; for the decompressor |
134 | move.d $r5, [$r0] ; for the decompressor | 68 | move.d $r5, [$r0] ; for the decompressor |
135 | 69 | ||
@@ -144,16 +78,24 @@ hereami2: | |||
144 | nop | 78 | nop |
145 | 79 | ||
146 | ;; Save command line magic and address. | 80 | ;; Save command line magic and address. |
147 | move.d _cmd_line_magic, $r12 | 81 | move.d _cmd_line_magic, $r0 |
148 | move.d $r10, [$r12] | 82 | move.d $r10, [$r0] |
149 | move.d _cmd_line_addr, $r12 | 83 | move.d _cmd_line_addr, $r0 |
150 | move.d $r11, [$r12] | 84 | move.d $r11, [$r0] |
85 | |||
86 | ;; Save boot source indicator | ||
87 | move.d _boot_source, $r0 | ||
88 | move.d $r12, [$r0] | ||
151 | 89 | ||
152 | ;; Do the decompression and save compressed size in _inptr | 90 | ;; Do the decompression and save compressed size in _inptr |
153 | 91 | ||
154 | jsr decompress_kernel | 92 | jsr decompress_kernel |
155 | nop | 93 | nop |
156 | 94 | ||
95 | ;; Restore boot source indicator | ||
96 | move.d _boot_source, $r12 | ||
97 | move.d [$r12], $r12 | ||
98 | |||
157 | ;; Restore command line magic and address. | 99 | ;; Restore command line magic and address. |
158 | move.d _cmd_line_magic, $r10 | 100 | move.d _cmd_line_magic, $r10 |
159 | move.d [$r10], $r10 | 101 | move.d [$r10], $r10 |
@@ -166,11 +108,10 @@ hereami2: | |||
166 | move.d [$r0], $r9 ; flash address of compressed kernel | 108 | move.d [$r0], $r9 ; flash address of compressed kernel |
167 | move.d inptr, $r0 | 109 | move.d inptr, $r0 |
168 | add.d [$r0], $r9 ; size of compressed kernel | 110 | add.d [$r0], $r9 ; size of compressed kernel |
169 | cmp.d 0x40200000, $r9 | 111 | cmp.d 0x40000000, $r9 ; image in DRAM ? |
170 | blo enter_kernel | 112 | blo enter_kernel ; no, must be [NOR] flash, jump |
171 | nop | 113 | nop ; delay slot |
172 | sub.d 0x40200000, $r9 | 114 | and.d 0x001fffff, $r9 ; assume compressed kernel was < 2M |
173 | add.d 0x4000, $r9 | ||
174 | 115 | ||
175 | enter_kernel: | 116 | enter_kernel: |
176 | ;; Enter the decompressed kernel | 117 | ;; Enter the decompressed kernel |
@@ -186,7 +127,7 @@ _cmd_line_magic: | |||
186 | .dword 0 | 127 | .dword 0 |
187 | _cmd_line_addr: | 128 | _cmd_line_addr: |
188 | .dword 0 | 129 | .dword 0 |
189 | is_nand_boot: | 130 | _boot_source: |
190 | .dword 0 | 131 | .dword 0 |
191 | 132 | ||
192 | #include "../../lib/hw_settings.S" | 133 | #include "../../mach/hw_settings.S" |
diff --git a/arch/cris/arch-v32/boot/compressed/misc.c b/arch/cris/arch-v32/boot/compressed/misc.c index 0169ba1ca9c9..55b2695c5d70 100644 --- a/arch/cris/arch-v32/boot/compressed/misc.c +++ b/arch/cris/arch-v32/boot/compressed/misc.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * misc.c | 2 | * misc.c |
3 | * | 3 | * |
4 | * $Id: misc.c,v 1.8 2005/04/24 18:34:29 starvik Exp $ | ||
5 | * | ||
6 | * This is a collection of several routines from gzip-1.0.3 | 4 | * This is a collection of several routines from gzip-1.0.3 |
7 | * adapted for Linux. | 5 | * adapted for Linux. |
8 | * | 6 | * |
@@ -22,9 +20,13 @@ | |||
22 | 20 | ||
23 | 21 | ||
24 | #include <linux/types.h> | 22 | #include <linux/types.h> |
25 | #include <asm/arch/hwregs/reg_rdwr.h> | 23 | #include <hwregs/reg_rdwr.h> |
26 | #include <asm/arch/hwregs/reg_map.h> | 24 | #include <hwregs/reg_map.h> |
27 | #include <asm/arch/hwregs/ser_defs.h> | 25 | #include <hwregs/ser_defs.h> |
26 | #include <hwregs/pinmux_defs.h> | ||
27 | #ifdef CONFIG_CRIS_MACH_ARTPEC3 | ||
28 | #include <hwregs/clkgen_defs.h> | ||
29 | #endif | ||
28 | 30 | ||
29 | /* | 31 | /* |
30 | * gzip declarations | 32 | * gzip declarations |
@@ -85,7 +87,6 @@ static unsigned outcnt = 0; /* bytes in output buffer */ | |||
85 | # define Tracecv(c,x) | 87 | # define Tracecv(c,x) |
86 | #endif | 88 | #endif |
87 | 89 | ||
88 | static int fill_inbuf(void); | ||
89 | static void flush_window(void); | 90 | static void flush_window(void); |
90 | static void error(char *m); | 91 | static void error(char *m); |
91 | static void gzip_mark(void **); | 92 | static void gzip_mark(void **); |
@@ -186,6 +187,8 @@ memset(void* s, int c, size_t n) | |||
186 | char *ss = (char*)s; | 187 | char *ss = (char*)s; |
187 | 188 | ||
188 | for (i=0;i<n;i++) ss[i] = c; | 189 | for (i=0;i<n;i++) ss[i] = c; |
190 | |||
191 | return s; | ||
189 | } | 192 | } |
190 | 193 | ||
191 | void* | 194 | void* |
@@ -196,6 +199,8 @@ memcpy(void* __dest, __const void* __src, | |||
196 | char *d = (char *)__dest, *s = (char *)__src; | 199 | char *d = (char *)__dest, *s = (char *)__src; |
197 | 200 | ||
198 | for (i=0;i<__n;i++) d[i] = s[i]; | 201 | for (i=0;i<__n;i++) d[i] = s[i]; |
202 | |||
203 | return __dest; | ||
199 | } | 204 | } |
200 | 205 | ||
201 | /* =========================================================================== | 206 | /* =========================================================================== |
@@ -225,15 +230,15 @@ flush_window() | |||
225 | static void | 230 | static void |
226 | error(char *x) | 231 | error(char *x) |
227 | { | 232 | { |
228 | puts("\n\n"); | 233 | puts("\r\n\n"); |
229 | puts(x); | 234 | puts(x); |
230 | puts("\n\n -- System halted\n"); | 235 | puts("\r\n\n -- System halted\n"); |
231 | 236 | ||
232 | while(1); /* Halt */ | 237 | while(1); /* Halt */ |
233 | } | 238 | } |
234 | 239 | ||
235 | void | 240 | void |
236 | setup_normal_output_buffer() | 241 | setup_normal_output_buffer(void) |
237 | { | 242 | { |
238 | output_data = (char *)KERNEL_LOAD_ADR; | 243 | output_data = (char *)KERNEL_LOAD_ADR; |
239 | } | 244 | } |
@@ -262,15 +267,17 @@ serial_setup(reg_scope_instances regi_ser) | |||
262 | rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div); | 267 | rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div); |
263 | 268 | ||
264 | tr_ctrl.stop_bits = 1; /* 2 stop bits. */ | 269 | tr_ctrl.stop_bits = 1; /* 2 stop bits. */ |
270 | tr_ctrl.en = 1; /* enable transmitter */ | ||
271 | rec_ctrl.en = 1; /* enabler receiver */ | ||
265 | 272 | ||
266 | /* | 273 | /* |
267 | * The baudrate setup is a bit fishy, but in the end the transceiver is | 274 | * The baudrate setup used to be a bit fishy, but now transmitter and |
268 | * set to 4800 and the receiver to 115200. The magic value is | 275 | * receiver are both set to the intended baud rate, 115200. |
269 | * 29.493 MHz. | 276 | * The magic value is 29.493 MHz. |
270 | */ | 277 | */ |
271 | tr_ctrl.base_freq = regk_ser_f29_493; | 278 | tr_ctrl.base_freq = regk_ser_f29_493; |
272 | rec_ctrl.base_freq = regk_ser_f29_493; | 279 | rec_ctrl.base_freq = regk_ser_f29_493; |
273 | tr_baud.div = (29493000 / 8) / 4800; | 280 | tr_baud.div = (29493000 / 8) / 115200; |
274 | rec_baud.div = (29493000 / 8) / 115200; | 281 | rec_baud.div = (29493000 / 8) / 115200; |
275 | 282 | ||
276 | REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl); | 283 | REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl); |
@@ -280,25 +287,52 @@ serial_setup(reg_scope_instances regi_ser) | |||
280 | } | 287 | } |
281 | 288 | ||
282 | void | 289 | void |
283 | decompress_kernel() | 290 | decompress_kernel(void) |
284 | { | 291 | { |
285 | char revision; | 292 | char revision; |
286 | 293 | ||
287 | /* input_data is set in head.S */ | 294 | #if defined(CONFIG_ETRAX_DEBUG_PORT1) || \ |
288 | inbuf = input_data; | 295 | defined(CONFIG_ETRAX_DEBUG_PORT2) || \ |
296 | defined(CONFIG_ETRAX_DEBUG_PORT3) | ||
297 | reg_pinmux_rw_hwprot hwprot; | ||
298 | |||
299 | #ifdef CONFIG_CRIS_MACH_ARTPEC3 | ||
300 | reg_clkgen_rw_clk_ctrl clk_ctrl; | ||
301 | |||
302 | /* Enable corresponding clock region when serial 1..3 selected */ | ||
303 | |||
304 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | ||
305 | clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; | ||
306 | REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); | ||
307 | #endif | ||
308 | |||
309 | /* pinmux setup for ports 1..3 */ | ||
310 | hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); | ||
311 | #endif | ||
289 | 312 | ||
290 | #ifdef CONFIG_ETRAX_DEBUG_PORT0 | 313 | #ifdef CONFIG_ETRAX_DEBUG_PORT0 |
291 | serial_setup(regi_ser0); | 314 | serial_setup(regi_ser0); |
292 | #endif | 315 | #endif |
293 | #ifdef CONFIG_ETRAX_DEBUG_PORT1 | 316 | #ifdef CONFIG_ETRAX_DEBUG_PORT1 |
317 | hwprot.ser1 = regk_pinmux_yes; | ||
294 | serial_setup(regi_ser1); | 318 | serial_setup(regi_ser1); |
295 | #endif | 319 | #endif |
296 | #ifdef CONFIG_ETRAX_DEBUG_PORT2 | 320 | #ifdef CONFIG_ETRAX_DEBUG_PORT2 |
321 | hwprot.ser2 = regk_pinmux_yes; | ||
297 | serial_setup(regi_ser2); | 322 | serial_setup(regi_ser2); |
298 | #endif | 323 | #endif |
299 | #ifdef CONFIG_ETRAX_DEBUG_PORT3 | 324 | #ifdef CONFIG_ETRAX_DEBUG_PORT3 |
325 | hwprot.ser3 = regk_pinmux_yes; | ||
300 | serial_setup(regi_ser3); | 326 | serial_setup(regi_ser3); |
301 | #endif | 327 | #endif |
328 | #if defined(CONFIG_ETRAX_DEBUG_PORT1) || \ | ||
329 | defined(CONFIG_ETRAX_DEBUG_PORT2) || \ | ||
330 | defined(CONFIG_ETRAX_DEBUG_PORT3) | ||
331 | REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); | ||
332 | #endif | ||
333 | |||
334 | /* input_data is set in head.S */ | ||
335 | inbuf = input_data; | ||
302 | 336 | ||
303 | setup_normal_output_buffer(); | 337 | setup_normal_output_buffer(); |
304 | 338 | ||
@@ -307,11 +341,11 @@ decompress_kernel() | |||
307 | __asm__ volatile ("move $vr,%0" : "=rm" (revision)); | 341 | __asm__ volatile ("move $vr,%0" : "=rm" (revision)); |
308 | if (revision < 32) | 342 | if (revision < 32) |
309 | { | 343 | { |
310 | puts("You need an ETRAX FS to run Linux 2.6/crisv32.\n"); | 344 | puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n"); |
311 | while(1); | 345 | while(1); |
312 | } | 346 | } |
313 | 347 | ||
314 | puts("Uncompressing Linux...\n"); | 348 | puts("Uncompressing Linux...\r\n"); |
315 | gunzip(); | 349 | gunzip(); |
316 | puts("Done. Now booting the kernel.\n"); | 350 | puts("Done. Now booting the kernel.\r\n"); |
317 | } | 351 | } |
diff --git a/arch/cris/arch-v32/boot/rescue/Makefile b/arch/cris/arch-v32/boot/rescue/Makefile index f668a8198724..c0987795dcb7 100644 --- a/arch/cris/arch-v32/boot/rescue/Makefile +++ b/arch/cris/arch-v32/boot/rescue/Makefile | |||
@@ -1,36 +1,27 @@ | |||
1 | # | 1 | # |
2 | # Makefile for rescue code | 2 | # Makefile for rescue (bootstrap) code |
3 | # | 3 | # |
4 | target = $(target_rescue_dir) | ||
5 | src = $(src_rescue_dir) | ||
6 | 4 | ||
7 | CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE) | 5 | CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE) |
8 | CFLAGS = -O2 | 6 | ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \ |
7 | -I $(srctree)/include/asm/arch | ||
8 | asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch | ||
9 | LD = gcc-cris -mlinux -march=v32 -nostdlib | 9 | LD = gcc-cris -mlinux -march=v32 -nostdlib |
10 | ldflags-y += -T $(obj)/rescue.ld | ||
11 | LDPOSTFLAGS = -lgcc | ||
10 | OBJCOPY = objcopy-cris | 12 | OBJCOPY = objcopy-cris |
11 | OBJCOPYFLAGS = -O binary --remove-section=.bss | 13 | OBJCOPYFLAGS = -O binary --remove-section=.bss |
14 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o | ||
15 | OBJECT := $(obj)/head.o | ||
12 | 16 | ||
13 | all: $(target)/rescue.bin | 17 | targets := rescue.o rescue.bin |
14 | 18 | ||
15 | rescue: rescue.bin | 19 | quiet_cmd_ldlibgcc = LD $@ |
16 | # do nothing | 20 | cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@ |
17 | 21 | ||
18 | $(target)/rescue.bin: $(target) $(target)/head.o | 22 | $(obj)/rescue.o: $(OBJECTS) FORCE |
19 | $(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o | 23 | $(call if_changed,ldlibgcc) |
20 | $(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin | ||
21 | cp -p $(target)/rescue.bin $(objtree) | ||
22 | 24 | ||
23 | $(target): | 25 | $(obj)/rescue.bin: $(obj)/rescue.o FORCE |
24 | mkdir -p $(target) | 26 | $(call if_changed,objcopy) |
25 | 27 | cp -p $(obj)/rescue.bin $(objtree) | |
26 | $(target)/head.o: $(src)/head.S | ||
27 | $(CC) -D__ASSEMBLY__ -c $< -o $*.o | ||
28 | |||
29 | clean: | ||
30 | rm -f $(target)/*.o $(target)/*.bin | ||
31 | |||
32 | fastdep: | ||
33 | |||
34 | modules: | ||
35 | |||
36 | modules-install: | ||
diff --git a/arch/cris/arch-v32/boot/rescue/head.S b/arch/cris/arch-v32/boot/rescue/head.S index 8cdb4011bc16..5f846b7700a3 100644 --- a/arch/cris/arch-v32/boot/rescue/head.S +++ b/arch/cris/arch-v32/boot/rescue/head.S | |||
@@ -1,38 +1,26 @@ | |||
1 | /* $Id: head.S,v 1.4 2004/11/01 16:10:28 starvik Exp $ | 1 | /* |
2 | * Just get started by jumping to CONFIG_ETRAX_PTABLE_SECTOR to start | ||
3 | * kernel decompressor. | ||
4 | * | ||
5 | * In practice, this only works for NOR flash (or some convoluted RAM boot) | ||
6 | * and hence is not really useful for Artpec-3, so it's Etrax FS / NOR only. | ||
2 | * | 7 | * |
3 | * This used to be the rescue code but now that is handled by the | ||
4 | * RedBoot based RFL instead. Nothing to see here, move along. | ||
5 | */ | 8 | */ |
6 | 9 | ||
7 | #include <asm/arch/hwregs/reg_map_asm.h> | 10 | #include <mach/startup.inc> |
8 | #include <asm/arch/hwregs/config_defs_asm.h> | ||
9 | 11 | ||
10 | .text | 12 | #ifdef CONFIG_ETRAX_AXISFLASHMAP |
11 | 13 | ||
12 | ;; Start clocks for used blocks. | 14 | ;; Code |
13 | move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1 | ||
14 | move.d [$r1], $r0 | ||
15 | or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \ | ||
16 | REG_STATE(config, rw_clk_ctrl, bif, yes) | \ | ||
17 | REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0 | ||
18 | move.d $r0, [$r1] | ||
19 | 15 | ||
20 | ;; Copy 68KB NAND flash to Internal RAM (if NAND boot) | 16 | .text |
21 | move.d 0x38004000, $r10 | 17 | start: |
22 | move.d 0x8000, $r11 | ||
23 | move.d 0x11000, $r12 | ||
24 | move.d copy_complete, $r13 | ||
25 | and.d 0x000fffff, $r13 | ||
26 | or.d 0x38000000, $r13 | ||
27 | 18 | ||
28 | #include "../../lib/nand_init.S" | 19 | ;; Start clocks for used blocks. |
20 | START_CLOCKS | ||
29 | 21 | ||
30 | ;; No NAND found | ||
31 | move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10 | 22 | move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10 |
32 | jump $r10 ; Jump to decompresser | 23 | jump $r10 ; Jump to decompressor |
33 | nop | 24 | nop |
34 | 25 | ||
35 | copy_complete: | 26 | #endif |
36 | move.d 0x38000000 + CONFIG_ETRAX_PTABLE_SECTOR, $r10 | ||
37 | jump $r10 ; Jump to decompresser | ||
38 | nop | ||
diff --git a/arch/cris/arch-v32/boot/rescue/rescue.ld b/arch/cris/arch-v32/boot/rescue/rescue.ld index 42b11aa122b2..8ac646bc1a2b 100644 --- a/arch/cris/arch-v32/boot/rescue/rescue.ld +++ b/arch/cris/arch-v32/boot/rescue/rescue.ld | |||
@@ -1,20 +1,43 @@ | |||
1 | /*#OUTPUT_FORMAT(elf32-us-cris) */ | ||
2 | OUTPUT_ARCH (crisv32) | ||
3 | /* Now that NAND support has been stripped, this file could be simplified, | ||
4 | * but it doesn't do any harm on the other hand so why bother. */ | ||
5 | |||
1 | MEMORY | 6 | MEMORY |
2 | { | 7 | { |
3 | flash : ORIGIN = 0x00000000, | 8 | bootblk : ORIGIN = 0x38000000, |
4 | LENGTH = 0x00100000 | 9 | LENGTH = 0x00004000 |
10 | intmem : ORIGIN = 0x38004000, | ||
11 | LENGTH = 0x00005000 | ||
5 | } | 12 | } |
6 | 13 | ||
7 | SECTIONS | 14 | SECTIONS |
8 | { | 15 | { |
9 | .text : | 16 | .text : |
10 | { | 17 | { |
11 | stext = . ; | 18 | _stext = . ; |
12 | *(.text) | 19 | *(.text) |
13 | etext = . ; | 20 | *(.init.text) |
14 | } > flash | 21 | *(.rodata) |
22 | *(.rodata.*) | ||
23 | _etext = . ; | ||
24 | } > bootblk | ||
15 | .data : | 25 | .data : |
16 | { | 26 | { |
17 | *(.data) | 27 | *(.data) |
18 | edata = . ; | 28 | _edata = . ; |
19 | } > flash | 29 | } > bootblk |
30 | .bss : | ||
31 | { | ||
32 | _bss = . ; | ||
33 | *(.bss) | ||
34 | _end = ALIGN( 0x10 ) ; | ||
35 | } > intmem | ||
36 | |||
37 | /* Get rid of stuff from EXPORT_SYMBOL(foo). */ | ||
38 | /DISCARD/ : | ||
39 | { | ||
40 | *(__ksymtab_strings) | ||
41 | *(__ksymtab) | ||
42 | } | ||
20 | } | 43 | } |
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index c329cce2a0c3..2a92cb1886ca 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig | |||
@@ -4,64 +4,102 @@ config ETRAX_ETHERNET | |||
4 | bool "Ethernet support" | 4 | bool "Ethernet support" |
5 | depends on ETRAX_ARCH_V32 | 5 | depends on ETRAX_ARCH_V32 |
6 | select NET_ETHERNET | 6 | select NET_ETHERNET |
7 | select MII | ||
7 | help | 8 | help |
8 | This option enables the ETRAX FS built-in 10/100Mbit Ethernet | 9 | This option enables the ETRAX FS built-in 10/100Mbit Ethernet |
9 | controller. | 10 | controller. |
10 | 11 | ||
11 | config ETRAX_ETHERNET_HW_CSUM | 12 | config ETRAX_NO_PHY |
12 | bool "Hardware accelerated ethernet checksum and scatter/gather" | 13 | bool "PHY not present" |
13 | depends on ETRAX_ETHERNET | 14 | depends on ETRAX_ETHERNET |
14 | depends on ETRAX_STREAMCOPROC | 15 | default N |
15 | default y | ||
16 | help | 16 | help |
17 | Hardware acceleration of checksumming and scatter/gather | 17 | This option disables all MDIO communication with an ethernet |
18 | transceiver connected to the MII interface. This option shall | ||
19 | typically be enabled if the MII interface is connected to a | ||
20 | switch. This option should normally be disabled. If enabled, | ||
21 | speed and duplex will be locked to 100 Mbit and full duplex. | ||
18 | 22 | ||
19 | config ETRAX_ETHERNET_IFACE0 | 23 | config ETRAX_ETHERNET_IFACE0 |
20 | depends on ETRAX_ETHERNET | 24 | depends on ETRAX_ETHERNET |
21 | bool "Enable network interface 0" | 25 | bool "Enable network interface 0" |
22 | 26 | ||
23 | config ETRAX_ETHERNET_IFACE1 | 27 | config ETRAX_ETHERNET_IFACE1 |
24 | depends on ETRAX_ETHERNET | 28 | depends on (ETRAX_ETHERNET && ETRAXFS) |
25 | bool "Enable network interface 1 (uses DMA6 and DMA7)" | 29 | bool "Enable network interface 1 (uses DMA6 and DMA7)" |
26 | 30 | ||
31 | config ETRAX_ETHERNET_GBIT | ||
32 | depends on (ETRAX_ETHERNET && CRIS_MACH_ARTPEC3) | ||
33 | bool "Enable gigabit Ethernet support" | ||
34 | |||
27 | choice | 35 | choice |
28 | prompt "Network LED behavior" | 36 | prompt "Eth0 led group" |
29 | depends on ETRAX_ETHERNET | 37 | depends on ETRAX_ETHERNET_IFACE0 |
30 | default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | 38 | default ETRAX_ETH0_USE_LEDGRP0 |
31 | 39 | ||
32 | config ETRAX_NETWORK_LED_ON_WHEN_LINK | 40 | config ETRAX_ETH0_USE_LEDGRP0 |
33 | bool "LED_on_when_link" | 41 | bool "Use LED grp 0" |
42 | depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO | ||
34 | help | 43 | help |
35 | Selecting LED_on_when_link will light the LED when there is a | 44 | Use LED grp 0 for eth0 |
36 | connection and will flash off when there is activity. | ||
37 | 45 | ||
38 | Selecting LED_on_when_activity will light the LED only when | 46 | config ETRAX_ETH0_USE_LEDGRP1 |
39 | there is activity. | 47 | bool "Use LED grp 1" |
40 | 48 | depends on ETRAX_NBR_LED_GRP_TWO | |
41 | This setting will also affect the behaviour of other activity LEDs | 49 | help |
42 | e.g. Bluetooth. | 50 | Use LED grp 1 for eth0 |
43 | 51 | ||
44 | config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY | 52 | config ETRAX_ETH0_USE_LEDGRPNULL |
45 | bool "LED_on_when_activity" | 53 | bool "Use no LEDs for eth0" |
46 | help | 54 | help |
47 | Selecting LED_on_when_link will light the LED when there is a | 55 | Use no LEDs for eth0 |
48 | connection and will flash off when there is activity. | 56 | endchoice |
49 | 57 | ||
50 | Selecting LED_on_when_activity will light the LED only when | 58 | choice |
51 | there is activity. | 59 | prompt "Eth1 led group" |
60 | depends on ETRAX_ETHERNET_IFACE1 | ||
61 | default ETRAX_ETH1_USE_LEDGRP1 | ||
62 | |||
63 | config ETRAX_ETH1_USE_LEDGRP0 | ||
64 | bool "Use LED grp 0" | ||
65 | depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO | ||
66 | help | ||
67 | Use LED grp 0 for eth1 | ||
52 | 68 | ||
53 | This setting will also affect the behaviour of other activity LEDs | 69 | config ETRAX_ETH1_USE_LEDGRP1 |
54 | e.g. Bluetooth. | 70 | bool "Use LED grp 1" |
71 | depends on ETRAX_NBR_LED_GRP_TWO | ||
72 | help | ||
73 | Use LED grp 1 for eth1 | ||
55 | 74 | ||
75 | config ETRAX_ETH1_USE_LEDGRPNULL | ||
76 | bool "Use no LEDs for eth1" | ||
77 | help | ||
78 | Use no LEDs for eth1 | ||
56 | endchoice | 79 | endchoice |
57 | 80 | ||
58 | config ETRAXFS_SERIAL | 81 | config ETRAXFS_SERIAL |
59 | bool "Serial-port support" | 82 | bool "Serial-port support" |
60 | depends on ETRAX_ARCH_V32 | 83 | depends on ETRAX_ARCH_V32 |
84 | select SERIAL_CORE | ||
85 | select SERIAL_CORE_CONSOLE | ||
61 | help | 86 | help |
62 | Enables the ETRAX FS serial driver for ser0 (ttyS0) | 87 | Enables the ETRAX FS serial driver for ser0 (ttyS0) |
63 | You probably want this enabled. | 88 | You probably want this enabled. |
64 | 89 | ||
90 | config ETRAX_RS485 | ||
91 | bool "RS-485 support" | ||
92 | depends on ETRAXFS_SERIAL | ||
93 | help | ||
94 | Enables support for RS-485 serial communication. | ||
95 | |||
96 | config ETRAX_RS485_DISABLE_RECEIVER | ||
97 | bool "Disable serial receiver" | ||
98 | depends on ETRAX_RS485 | ||
99 | help | ||
100 | It is necessary to disable the serial receiver to avoid serial | ||
101 | loopback. Not all products are able to do this in software only. | ||
102 | |||
65 | config ETRAX_SERIAL_PORT0 | 103 | config ETRAX_SERIAL_PORT0 |
66 | bool "Serial port 0 enabled" | 104 | bool "Serial port 0 enabled" |
67 | depends on ETRAXFS_SERIAL | 105 | depends on ETRAXFS_SERIAL |
@@ -72,50 +110,28 @@ config ETRAX_SERIAL_PORT0 | |||
72 | ser0 can use dma4 or dma6 for output and dma5 or dma7 for input. | 110 | ser0 can use dma4 or dma6 for output and dma5 or dma7 for input. |
73 | 111 | ||
74 | choice | 112 | choice |
75 | prompt "Ser0 DMA in channel " | 113 | prompt "Ser0 default port type " |
76 | depends on ETRAX_SERIAL_PORT0 | 114 | depends on ETRAX_SERIAL_PORT0 |
77 | default ETRAX_SERIAL_PORT0_NO_DMA_IN | 115 | default ETRAX_SERIAL_PORT0_TYPE_232 |
78 | help | 116 | help |
79 | What DMA channel to use for ser0. | 117 | Type of serial port. |
80 | |||
81 | 118 | ||
82 | config ETRAX_SERIAL_PORT0_NO_DMA_IN | 119 | config ETRAX_SERIAL_PORT0_TYPE_232 |
83 | bool "Ser0 uses no DMA for input" | 120 | bool "Ser0 is a RS-232 port" |
84 | help | 121 | help |
85 | Do not use DMA for ser0 input. | 122 | Configure serial port 0 to be a RS-232 port. |
86 | 123 | ||
87 | config ETRAX_SERIAL_PORT0_DMA7_IN | 124 | config ETRAX_SERIAL_PORT0_TYPE_485HD |
88 | bool "Ser0 uses DMA7 for input" | 125 | bool "Ser0 is a half duplex RS-485 port" |
89 | depends on ETRAX_SERIAL_PORT0 | 126 | depends on ETRAX_RS485 |
90 | help | ||
91 | Enables the DMA7 input channel for ser0 (ttyS0). | ||
92 | If you do not enable DMA, an interrupt for each character will be | ||
93 | used when receiving data. | ||
94 | Normally you want to use DMA, unless you use the DMA channel for | ||
95 | something else. | ||
96 | |||
97 | endchoice | ||
98 | |||
99 | choice | ||
100 | prompt "Ser0 DMA out channel" | ||
101 | depends on ETRAX_SERIAL_PORT0 | ||
102 | default ETRAX_SERIAL_PORT0_NO_DMA_OUT | ||
103 | |||
104 | config ETRAX_SERIAL_PORT0_NO_DMA_OUT | ||
105 | bool "Ser0 uses no DMA for output" | ||
106 | help | 127 | help |
107 | Do not use DMA for ser0 output. | 128 | Configure serial port 0 to be a half duplex (two wires) RS-485 port. |
108 | 129 | ||
109 | config ETRAX_SERIAL_PORT0_DMA6_OUT | 130 | config ETRAX_SERIAL_PORT0_TYPE_485FD |
110 | bool "Ser0 uses DMA6 for output" | 131 | bool "Ser0 is a full duplex RS-485 port" |
111 | depends on ETRAX_SERIAL_PORT0 | 132 | depends on ETRAX_RS485 |
112 | help | 133 | help |
113 | Enables the DMA6 output channel for ser0 (ttyS0). | 134 | Configure serial port 0 to be a full duplex (four wires) RS-485 port. |
114 | If you do not enable DMA, an interrupt for each character will be | ||
115 | used when transmitting data. | ||
116 | Normally you want to use DMA, unless you use the DMA channel for | ||
117 | something else. | ||
118 | |||
119 | endchoice | 135 | endchoice |
120 | 136 | ||
121 | config ETRAX_SER0_DTR_BIT | 137 | config ETRAX_SER0_DTR_BIT |
@@ -141,52 +157,28 @@ config ETRAX_SERIAL_PORT1 | |||
141 | Enables the ETRAX FS serial driver for ser1 (ttyS1). | 157 | Enables the ETRAX FS serial driver for ser1 (ttyS1). |
142 | 158 | ||
143 | choice | 159 | choice |
144 | prompt "Ser1 DMA in channel " | 160 | prompt "Ser1 default port type" |
145 | depends on ETRAX_SERIAL_PORT1 | 161 | depends on ETRAX_SERIAL_PORT1 |
146 | default ETRAX_SERIAL_PORT1_NO_DMA_IN | 162 | default ETRAX_SERIAL_PORT1_TYPE_232 |
147 | help | ||
148 | What DMA channel to use for ser1. | ||
149 | |||
150 | |||
151 | config ETRAX_SERIAL_PORT1_NO_DMA_IN | ||
152 | bool "Ser1 uses no DMA for input" | ||
153 | help | 163 | help |
154 | Do not use DMA for ser1 input. | 164 | Type of serial port. |
155 | 165 | ||
156 | config ETRAX_SERIAL_PORT1_DMA5_IN | 166 | config ETRAX_SERIAL_PORT1_TYPE_232 |
157 | bool "Ser1 uses DMA5 for input" | 167 | bool "Ser1 is a RS-232 port" |
158 | depends on ETRAX_SERIAL_PORT1 | ||
159 | help | 168 | help |
160 | Enables the DMA5 input channel for ser1 (ttyS1). | 169 | Configure serial port 1 to be a RS-232 port. |
161 | If you do not enable DMA, an interrupt for each character will be | ||
162 | used when receiving data. | ||
163 | Normally you want this on, unless you use the DMA channel for | ||
164 | something else. | ||
165 | |||
166 | endchoice | ||
167 | 170 | ||
168 | choice | 171 | config ETRAX_SERIAL_PORT1_TYPE_485HD |
169 | prompt "Ser1 DMA out channel " | 172 | bool "Ser1 is a half duplex RS-485 port" |
170 | depends on ETRAX_SERIAL_PORT1 | 173 | depends on ETRAX_RS485 |
171 | default ETRAX_SERIAL_PORT1_NO_DMA_OUT | ||
172 | help | ||
173 | What DMA channel to use for ser1. | ||
174 | |||
175 | config ETRAX_SERIAL_PORT1_NO_DMA_OUT | ||
176 | bool "Ser1 uses no DMA for output" | ||
177 | help | 174 | help |
178 | Do not use DMA for ser1 output. | 175 | Configure serial port 1 to be a half duplex (two wires) RS-485 port. |
179 | 176 | ||
180 | config ETRAX_SERIAL_PORT1_DMA4_OUT | 177 | config ETRAX_SERIAL_PORT1_TYPE_485FD |
181 | bool "Ser1 uses DMA4 for output" | 178 | bool "Ser1 is a full duplex RS-485 port" |
182 | depends on ETRAX_SERIAL_PORT1 | 179 | depends on ETRAX_RS485 |
183 | help | 180 | help |
184 | Enables the DMA4 output channel for ser1 (ttyS1). | 181 | Configure serial port 1 to be a full duplex (four wires) RS-485 port. |
185 | If you do not enable DMA, an interrupt for each character will be | ||
186 | used when transmitting data. | ||
187 | Normally you want this on, unless you use the DMA channel for | ||
188 | something else. | ||
189 | |||
190 | endchoice | 182 | endchoice |
191 | 183 | ||
192 | config ETRAX_SER1_DTR_BIT | 184 | config ETRAX_SER1_DTR_BIT |
@@ -212,52 +204,31 @@ config ETRAX_SERIAL_PORT2 | |||
212 | Enables the ETRAX FS serial driver for ser2 (ttyS2). | 204 | Enables the ETRAX FS serial driver for ser2 (ttyS2). |
213 | 205 | ||
214 | choice | 206 | choice |
215 | prompt "Ser2 DMA in channel " | 207 | prompt "Ser2 default port type" |
216 | depends on ETRAX_SERIAL_PORT2 | 208 | depends on ETRAX_SERIAL_PORT2 |
217 | default ETRAX_SERIAL_PORT2_NO_DMA_IN | 209 | default ETRAX_SERIAL_PORT2_TYPE_232 |
218 | help | 210 | help |
219 | What DMA channel to use for ser2. | 211 | What DMA channel to use for ser2 |
220 | 212 | ||
221 | 213 | config ETRAX_SERIAL_PORT2_TYPE_232 | |
222 | config ETRAX_SERIAL_PORT2_NO_DMA_IN | 214 | bool "Ser2 is a RS-232 port" |
223 | bool "Ser2 uses no DMA for input" | ||
224 | help | 215 | help |
225 | Do not use DMA for ser2 input. | 216 | Configure serial port 2 to be a RS-232 port. |
226 | 217 | ||
227 | config ETRAX_SERIAL_PORT2_DMA3_IN | 218 | config ETRAX_SERIAL_PORT2_TYPE_485HD |
228 | bool "Ser2 uses DMA3 for input" | 219 | bool "Ser2 is a half duplex RS-485 port" |
229 | depends on ETRAX_SERIAL_PORT2 | 220 | depends on ETRAX_RS485 |
230 | help | ||
231 | Enables the DMA3 input channel for ser2 (ttyS2). | ||
232 | If you do not enable DMA, an interrupt for each character will be | ||
233 | used when receiving data. | ||
234 | Normally you want to use DMA, unless you use the DMA channel for | ||
235 | something else. | ||
236 | |||
237 | endchoice | ||
238 | |||
239 | choice | ||
240 | prompt "Ser2 DMA out channel" | ||
241 | depends on ETRAX_SERIAL_PORT2 | ||
242 | default ETRAX_SERIAL_PORT2_NO_DMA_OUT | ||
243 | |||
244 | config ETRAX_SERIAL_PORT2_NO_DMA_OUT | ||
245 | bool "Ser2 uses no DMA for output" | ||
246 | help | 221 | help |
247 | Do not use DMA for ser2 output. | 222 | Configure serial port 2 to be a half duplex (two wires) RS-485 port. |
248 | 223 | ||
249 | config ETRAX_SERIAL_PORT2_DMA2_OUT | 224 | config ETRAX_SERIAL_PORT2_TYPE_485FD |
250 | bool "Ser2 uses DMA2 for output" | 225 | bool "Ser2 is a full duplex RS-485 port" |
251 | depends on ETRAX_SERIAL_PORT2 | 226 | depends on ETRAX_RS485 |
252 | help | 227 | help |
253 | Enables the DMA2 output channel for ser2 (ttyS2). | 228 | Configure serial port 2 to be a full duplex (four wires) RS-485 port. |
254 | If you do not enable DMA, an interrupt for each character will be | ||
255 | used when transmitting data. | ||
256 | Normally you want to use DMA, unless you use the DMA channel for | ||
257 | something else. | ||
258 | |||
259 | endchoice | 229 | endchoice |
260 | 230 | ||
231 | |||
261 | config ETRAX_SER2_DTR_BIT | 232 | config ETRAX_SER2_DTR_BIT |
262 | string "Ser 2 DTR bit (empty = not used)" | 233 | string "Ser 2 DTR bit (empty = not used)" |
263 | depends on ETRAX_SERIAL_PORT2 | 234 | depends on ETRAX_SERIAL_PORT2 |
@@ -281,71 +252,121 @@ config ETRAX_SERIAL_PORT3 | |||
281 | Enables the ETRAX FS serial driver for ser3 (ttyS3). | 252 | Enables the ETRAX FS serial driver for ser3 (ttyS3). |
282 | 253 | ||
283 | choice | 254 | choice |
284 | prompt "Ser3 DMA in channel " | 255 | prompt "Ser3 default port type" |
285 | depends on ETRAX_SERIAL_PORT3 | 256 | depends on ETRAX_SERIAL_PORT3 |
286 | default ETRAX_SERIAL_PORT3_NO_DMA_IN | 257 | default ETRAX_SERIAL_PORT3_TYPE_232 |
287 | help | 258 | help |
288 | What DMA channel to use for ser3. | 259 | What DMA channel to use for ser3. |
289 | 260 | ||
261 | config ETRAX_SERIAL_PORT3_TYPE_232 | ||
262 | bool "Ser3 is a RS-232 port" | ||
263 | help | ||
264 | Configure serial port 3 to be a RS-232 port. | ||
290 | 265 | ||
291 | config ETRAX_SERIAL_PORT3_NO_DMA_IN | 266 | config ETRAX_SERIAL_PORT3_TYPE_485HD |
292 | bool "Ser3 uses no DMA for input" | 267 | bool "Ser3 is a half duplex RS-485 port" |
268 | depends on ETRAX_RS485 | ||
293 | help | 269 | help |
294 | Do not use DMA for ser3 input. | 270 | Configure serial port 3 to be a half duplex (two wires) RS-485 port. |
295 | 271 | ||
296 | config ETRAX_SERIAL_PORT3_DMA9_IN | 272 | config ETRAX_SERIAL_PORT3_TYPE_485FD |
297 | bool "Ser3 uses DMA9 for input" | 273 | bool "Ser3 is a full duplex RS-485 port" |
274 | depends on ETRAX_RS485 | ||
275 | help | ||
276 | Configure serial port 3 to be a full duplex (four wires) RS-485 port. | ||
277 | endchoice | ||
278 | |||
279 | config ETRAX_SER3_DTR_BIT | ||
280 | string "Ser 3 DTR bit (empty = not used)" | ||
281 | depends on ETRAX_SERIAL_PORT3 | ||
282 | |||
283 | config ETRAX_SER3_RI_BIT | ||
284 | string "Ser 3 RI bit (empty = not used)" | ||
285 | depends on ETRAX_SERIAL_PORT3 | ||
286 | |||
287 | config ETRAX_SER3_DSR_BIT | ||
288 | string "Ser 3 DSR bit (empty = not used)" | ||
289 | depends on ETRAX_SERIAL_PORT3 | ||
290 | |||
291 | config ETRAX_SER3_CD_BIT | ||
292 | string "Ser 3 CD bit (empty = not used)" | ||
298 | depends on ETRAX_SERIAL_PORT3 | 293 | depends on ETRAX_SERIAL_PORT3 |
294 | |||
295 | config ETRAX_SERIAL_PORT4 | ||
296 | bool "Serial port 4 enabled" | ||
297 | depends on ETRAXFS_SERIAL && CRIS_MACH_ARTPEC3 | ||
299 | help | 298 | help |
300 | Enables the DMA9 input channel for ser3 (ttyS3). | 299 | Enables the ETRAX FS serial driver for ser4 (ttyS4). |
301 | If you do not enable DMA, an interrupt for each character will be | 300 | |
302 | used when receiving data. | 301 | choice |
303 | Normally you want to use DMA, unless you use the DMA channel for | 302 | prompt "Ser4 default port type" |
304 | something else. | 303 | depends on ETRAX_SERIAL_PORT4 |
304 | default ETRAX_SERIAL_PORT4_TYPE_232 | ||
305 | help | ||
306 | What DMA channel to use for ser4. | ||
305 | 307 | ||
308 | config ETRAX_SERIAL_PORT4_TYPE_232 | ||
309 | bool "Ser4 is a RS-232 port" | ||
310 | help | ||
311 | Configure serial port 4 to be a RS-232 port. | ||
312 | |||
313 | config ETRAX_SERIAL_PORT4_TYPE_485HD | ||
314 | bool "Ser4 is a half duplex RS-485 port" | ||
315 | depends on ETRAX_RS485 | ||
316 | help | ||
317 | Configure serial port 4 to be a half duplex (two wires) RS-485 port. | ||
318 | |||
319 | config ETRAX_SERIAL_PORT4_TYPE_485FD | ||
320 | bool "Ser4 is a full duplex RS-485 port" | ||
321 | depends on ETRAX_RS485 | ||
322 | help | ||
323 | Configure serial port 4 to be a full duplex (four wires) RS-485 port. | ||
306 | endchoice | 324 | endchoice |
307 | 325 | ||
308 | choice | 326 | choice |
309 | prompt "Ser3 DMA out channel" | 327 | prompt "Ser4 DMA in channel " |
310 | depends on ETRAX_SERIAL_PORT3 | 328 | depends on ETRAX_SERIAL_PORT4 |
311 | default ETRAX_SERIAL_PORT3_NO_DMA_OUT | 329 | default ETRAX_SERIAL_PORT4_NO_DMA_IN |
330 | help | ||
331 | What DMA channel to use for ser4. | ||
332 | |||
312 | 333 | ||
313 | config ETRAX_SERIAL_PORT3_NO_DMA_OUT | 334 | config ETRAX_SERIAL_PORT4_NO_DMA_IN |
314 | bool "Ser3 uses no DMA for output" | 335 | bool "Ser4 uses no DMA for input" |
315 | help | 336 | help |
316 | Do not use DMA for ser3 output. | 337 | Do not use DMA for ser4 input. |
317 | 338 | ||
318 | config ETRAX_SERIAL_PORT3_DMA8_OUT | 339 | config ETRAX_SERIAL_PORT4_DMA9_IN |
319 | bool "Ser3 uses DMA8 for output" | 340 | bool "Ser4 uses DMA9 for input" |
320 | depends on ETRAX_SERIAL_PORT3 | 341 | depends on ETRAX_SERIAL_PORT4 |
321 | help | 342 | help |
322 | Enables the DMA8 output channel for ser3 (ttyS3). | 343 | Enables the DMA9 input channel for ser4 (ttyS4). |
323 | If you do not enable DMA, an interrupt for each character will be | 344 | If you do not enable DMA, an interrupt for each character will be |
324 | used when transmitting data. | 345 | used when receiveing data. |
325 | Normally you want to use DMA, unless you use the DMA channel for | 346 | Normally you want to use DMA, unless you use the DMA channel for |
326 | something else. | 347 | something else. |
327 | 348 | ||
328 | endchoice | 349 | endchoice |
329 | 350 | ||
330 | config ETRAX_SER3_DTR_BIT | 351 | config ETRAX_SER4_DTR_BIT |
331 | string "Ser 3 DTR bit (empty = not used)" | 352 | string "Ser 4 DTR bit (empty = not used)" |
332 | depends on ETRAX_SERIAL_PORT3 | 353 | depends on ETRAX_SERIAL_PORT4 |
333 | 354 | ||
334 | config ETRAX_SER3_RI_BIT | 355 | config ETRAX_SER4_RI_BIT |
335 | string "Ser 3 RI bit (empty = not used)" | 356 | string "Ser 4 RI bit (empty = not used)" |
336 | depends on ETRAX_SERIAL_PORT3 | 357 | depends on ETRAX_SERIAL_PORT4 |
337 | 358 | ||
338 | config ETRAX_SER3_DSR_BIT | 359 | config ETRAX_SER4_DSR_BIT |
339 | string "Ser 3 DSR bit (empty = not used)" | 360 | string "Ser 4 DSR bit (empty = not used)" |
340 | depends on ETRAX_SERIAL_PORT3 | 361 | depends on ETRAX_SERIAL_PORT4 |
341 | 362 | ||
342 | config ETRAX_SER3_CD_BIT | 363 | config ETRAX_SER3_CD_BIT |
343 | string "Ser 3 CD bit (empty = not used)" | 364 | string "Ser 4 CD bit (empty = not used)" |
344 | depends on ETRAX_SERIAL_PORT3 | 365 | depends on ETRAX_SERIAL_PORT4 |
345 | 366 | ||
346 | config ETRAX_RS485 | 367 | config ETRAX_RS485 |
347 | bool "RS-485 support" | 368 | bool "RS-485 support" |
348 | depends on ETRAX_SERIAL | 369 | depends on ETRAXFS_SERIAL |
349 | help | 370 | help |
350 | Enables support for RS-485 serial communication. For a primer on | 371 | Enables support for RS-485 serial communication. For a primer on |
351 | RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. | 372 | RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. |
@@ -356,22 +377,6 @@ config ETRAX_RS485_DISABLE_RECEIVER | |||
356 | help | 377 | help |
357 | It is necessary to disable the serial receiver to avoid serial | 378 | It is necessary to disable the serial receiver to avoid serial |
358 | loopback. Not all products are able to do this in software only. | 379 | loopback. Not all products are able to do this in software only. |
359 | Axis 2400/2401 must disable receiver. | ||
360 | |||
361 | config ETRAX_AXISFLASHMAP | ||
362 | bool "Axis flash-map support" | ||
363 | depends on ETRAX_ARCH_V32 | ||
364 | select MTD | ||
365 | select MTD_CFI | ||
366 | select MTD_CFI_AMDSTD | ||
367 | select MTD_CHAR | ||
368 | select MTD_BLOCK | ||
369 | select MTD_PARTITIONS | ||
370 | select MTD_CONCAT | ||
371 | select MTD_COMPLEX_MAPPINGS | ||
372 | help | ||
373 | This option enables MTD mapping of flash devices. Needed to use | ||
374 | flash memories. If unsure, say Y. | ||
375 | 380 | ||
376 | config ETRAX_SYNCHRONOUS_SERIAL | 381 | config ETRAX_SYNCHRONOUS_SERIAL |
377 | bool "Synchronous serial-port support" | 382 | bool "Synchronous serial-port support" |
@@ -394,7 +399,7 @@ config ETRAX_SYNCHRONOUS_SERIAL0_DMA | |||
394 | 399 | ||
395 | config ETRAX_SYNCHRONOUS_SERIAL_PORT1 | 400 | config ETRAX_SYNCHRONOUS_SERIAL_PORT1 |
396 | bool "Synchronous serial port 1 enabled" | 401 | bool "Synchronous serial port 1 enabled" |
397 | depends on ETRAX_SYNCHRONOUS_SERIAL | 402 | depends on ETRAX_SYNCHRONOUS_SERIAL && ETRAXFS |
398 | help | 403 | help |
399 | Enabled synchronous serial port 1. | 404 | Enabled synchronous serial port 1. |
400 | 405 | ||
@@ -405,6 +410,31 @@ config ETRAX_SYNCHRONOUS_SERIAL1_DMA | |||
405 | A synchronous serial port can run in manual or DMA mode. | 410 | A synchronous serial port can run in manual or DMA mode. |
406 | Selecting this option will make it run in DMA mode. | 411 | Selecting this option will make it run in DMA mode. |
407 | 412 | ||
413 | config ETRAX_AXISFLASHMAP | ||
414 | bool "Axis flash-map support" | ||
415 | depends on ETRAX_ARCH_V32 | ||
416 | select MTD | ||
417 | select MTD_CFI | ||
418 | select MTD_CFI_AMDSTD | ||
419 | select MTD_JEDECPROBE | ||
420 | select MTD_CHAR | ||
421 | select MTD_BLOCK | ||
422 | select MTD_PARTITIONS | ||
423 | select MTD_CONCAT | ||
424 | select MTD_COMPLEX_MAPPINGS | ||
425 | help | ||
426 | This option enables MTD mapping of flash devices. Needed to use | ||
427 | flash memories. If unsure, say Y. | ||
428 | |||
429 | config ETRAX_AXISFLASHMAP_MTD0WHOLE | ||
430 | bool "MTD0 is whole boot flash device" | ||
431 | depends on ETRAX_AXISFLASHMAP | ||
432 | default N | ||
433 | help | ||
434 | When this option is not set, mtd0 refers to the first partition | ||
435 | on the boot flash device. When set, mtd0 refers to the whole | ||
436 | device, with mtd1 referring to the first partition etc. | ||
437 | |||
408 | config ETRAX_PTABLE_SECTOR | 438 | config ETRAX_PTABLE_SECTOR |
409 | int "Byte-offset of partition table sector" | 439 | int "Byte-offset of partition table sector" |
410 | depends on ETRAX_AXISFLASHMAP | 440 | depends on ETRAX_AXISFLASHMAP |
@@ -425,42 +455,32 @@ config ETRAX_NANDFLASH | |||
425 | This option enables MTD mapping of NAND flash devices. Needed to use | 455 | This option enables MTD mapping of NAND flash devices. Needed to use |
426 | NAND flash memories. If unsure, say Y. | 456 | NAND flash memories. If unsure, say Y. |
427 | 457 | ||
458 | config ETRAX_NANDBOOT | ||
459 | bool "Boot from NAND flash" | ||
460 | depends on ETRAX_NANDFLASH | ||
461 | help | ||
462 | This options enables booting from NAND flash devices. | ||
463 | Say Y if your boot code, kernel and root file system is in | ||
464 | NAND flash. Say N if they are in NOR flash. | ||
465 | |||
428 | config ETRAX_I2C | 466 | config ETRAX_I2C |
429 | bool "I2C driver" | 467 | bool "I2C driver" |
430 | depends on ETRAX_ARCH_V32 | 468 | depends on ETRAX_ARCH_V32 |
431 | help | 469 | help |
432 | This option enabled the I2C driver used by e.g. the RTC driver. | 470 | This option enables the I2C driver used by e.g. the RTC driver. |
433 | 471 | ||
434 | config ETRAX_I2C_DATA_PORT | 472 | config ETRAX_V32_I2C_DATA_PORT |
435 | string "I2C data pin" | 473 | string "I2C data pin" |
436 | depends on ETRAX_I2C | 474 | depends on ETRAX_I2C |
437 | help | 475 | help |
438 | The pin to use for I2C data. | 476 | The pin to use for I2C data. |
439 | 477 | ||
440 | config ETRAX_I2C_CLK_PORT | 478 | config ETRAX_V32_I2C_CLK_PORT |
441 | string "I2C clock pin" | 479 | string "I2C clock pin" |
442 | depends on ETRAX_I2C | 480 | depends on ETRAX_I2C |
443 | help | 481 | help |
444 | The pin to use for I2C clock. | 482 | The pin to use for I2C clock. |
445 | 483 | ||
446 | config ETRAX_RTC | ||
447 | bool "Real Time Clock support" | ||
448 | depends on ETRAX_ARCH_V32 | ||
449 | help | ||
450 | Enabled RTC support. | ||
451 | |||
452 | choice | ||
453 | prompt "RTC chip" | ||
454 | depends on ETRAX_RTC | ||
455 | default ETRAX_PCF8563 | ||
456 | |||
457 | config ETRAX_PCF8563 | ||
458 | bool "PCF8563" | ||
459 | help | ||
460 | Philips PCF8563 RTC | ||
461 | |||
462 | endchoice | ||
463 | |||
464 | config ETRAX_GPIO | 484 | config ETRAX_GPIO |
465 | bool "GPIO support" | 485 | bool "GPIO support" |
466 | depends on ETRAX_ARCH_V32 | 486 | depends on ETRAX_ARCH_V32 |
@@ -476,33 +496,36 @@ config ETRAX_GPIO | |||
476 | Remember that you need to setup the port directions appropriately in | 496 | Remember that you need to setup the port directions appropriately in |
477 | the General configuration. | 497 | the General configuration. |
478 | 498 | ||
479 | config ETRAX_PA_BUTTON_BITMASK | 499 | config ETRAX_VIRTUAL_GPIO |
480 | hex "PA-buttons bitmask" | 500 | bool "Virtual GPIO support" |
481 | depends on ETRAX_GPIO | 501 | depends on ETRAX_GPIO |
482 | default "0x02" | ||
483 | help | 502 | help |
484 | This is a bitmask (8 bits) with information about what bits on PA | 503 | Enables the virtual Etrax general port device (major 120, minor 6). |
485 | that are used for buttons. | 504 | It uses an I/O expander for the I2C-bus. |
486 | Most products has a so called TEST button on PA1, if that is true | 505 | |
487 | use 0x02 here. | 506 | config ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN |
488 | Use 00 if there are no buttons on PA. | 507 | int "Virtual GPIO interrupt pin on PA pin" |
489 | If the bitmask is <> 00 a button driver will be included in the gpio | 508 | range 0 7 |
490 | driver. ETRAX general I/O support must be enabled. | 509 | depends on ETRAX_VIRTUAL_GPIO |
510 | help | ||
511 | The pin to use on PA for virtual gpio interrupt. | ||
491 | 512 | ||
492 | config ETRAX_PA_CHANGEABLE_DIR | 513 | config ETRAX_PA_CHANGEABLE_DIR |
493 | hex "PA user changeable dir mask" | 514 | hex "PA user changeable dir mask" |
494 | depends on ETRAX_GPIO | 515 | depends on ETRAX_GPIO |
495 | default "0x00" | 516 | default "0x00" if ETRAXFS |
517 | default "0x00000000" if !ETRAXFS | ||
496 | help | 518 | help |
497 | This is a bitmask (8 bits) with information of what bits in PA that a | 519 | This is a bitmask (8 bits) with information of what bits in PA that a |
498 | user can change direction on using ioctl's. | 520 | user can change direction on using ioctl's. |
499 | Bit set = changeable. | 521 | Bit set = changeable. |
500 | You probably want 0x00 here, but it depends on your hardware. | 522 | You probably want 0 here, but it depends on your hardware. |
501 | 523 | ||
502 | config ETRAX_PA_CHANGEABLE_BITS | 524 | config ETRAX_PA_CHANGEABLE_BITS |
503 | hex "PA user changeable bits mask" | 525 | hex "PA user changeable bits mask" |
504 | depends on ETRAX_GPIO | 526 | depends on ETRAX_GPIO |
505 | default "0x00" | 527 | default "0x00" if ETRAXFS |
528 | default "0x00000000" if !ETRAXFS | ||
506 | help | 529 | help |
507 | This is a bitmask (8 bits) with information of what bits in PA | 530 | This is a bitmask (8 bits) with information of what bits in PA |
508 | that a user can change the value on using ioctl's. | 531 | that a user can change the value on using ioctl's. |
@@ -511,17 +534,19 @@ config ETRAX_PA_CHANGEABLE_BITS | |||
511 | config ETRAX_PB_CHANGEABLE_DIR | 534 | config ETRAX_PB_CHANGEABLE_DIR |
512 | hex "PB user changeable dir mask" | 535 | hex "PB user changeable dir mask" |
513 | depends on ETRAX_GPIO | 536 | depends on ETRAX_GPIO |
514 | default "0x00000" | 537 | default "0x00000" if ETRAXFS |
538 | default "0x00000000" if !ETRAXFS | ||
515 | help | 539 | help |
516 | This is a bitmask (18 bits) with information of what bits in PB | 540 | This is a bitmask (18 bits) with information of what bits in PB |
517 | that a user can change direction on using ioctl's. | 541 | that a user can change direction on using ioctl's. |
518 | Bit set = changeable. | 542 | Bit set = changeable. |
519 | You probably want 0x00000 here, but it depends on your hardware. | 543 | You probably want 0 here, but it depends on your hardware. |
520 | 544 | ||
521 | config ETRAX_PB_CHANGEABLE_BITS | 545 | config ETRAX_PB_CHANGEABLE_BITS |
522 | hex "PB user changeable bits mask" | 546 | hex "PB user changeable bits mask" |
523 | depends on ETRAX_GPIO | 547 | depends on ETRAX_GPIO |
524 | default "0x00000" | 548 | default "0x00000" if ETRAXFS |
549 | default "0x00000000" if !ETRAXFS | ||
525 | help | 550 | help |
526 | This is a bitmask (18 bits) with information of what bits in PB | 551 | This is a bitmask (18 bits) with information of what bits in PB |
527 | that a user can change the value on using ioctl's. | 552 | that a user can change the value on using ioctl's. |
@@ -530,17 +555,19 @@ config ETRAX_PB_CHANGEABLE_BITS | |||
530 | config ETRAX_PC_CHANGEABLE_DIR | 555 | config ETRAX_PC_CHANGEABLE_DIR |
531 | hex "PC user changeable dir mask" | 556 | hex "PC user changeable dir mask" |
532 | depends on ETRAX_GPIO | 557 | depends on ETRAX_GPIO |
533 | default "0x00000" | 558 | default "0x00000" if ETRAXFS |
559 | default "0x00000000" if !ETRAXFS | ||
534 | help | 560 | help |
535 | This is a bitmask (18 bits) with information of what bits in PC | 561 | This is a bitmask (18 bits) with information of what bits in PC |
536 | that a user can change direction on using ioctl's. | 562 | that a user can change direction on using ioctl's. |
537 | Bit set = changeable. | 563 | Bit set = changeable. |
538 | You probably want 0x00000 here, but it depends on your hardware. | 564 | You probably want 0 here, but it depends on your hardware. |
539 | 565 | ||
540 | config ETRAX_PC_CHANGEABLE_BITS | 566 | config ETRAX_PC_CHANGEABLE_BITS |
541 | hex "PC user changeable bits mask" | 567 | hex "PC user changeable bits mask" |
542 | depends on ETRAX_GPIO | 568 | depends on ETRAX_GPIO |
543 | default "0x00000" | 569 | default "0x00000" if ETRAXFS |
570 | default "0x00000000" if ETRAXFS | ||
544 | help | 571 | help |
545 | This is a bitmask (18 bits) with information of what bits in PC | 572 | This is a bitmask (18 bits) with information of what bits in PC |
546 | that a user can change the value on using ioctl's. | 573 | that a user can change the value on using ioctl's. |
@@ -548,7 +575,7 @@ config ETRAX_PC_CHANGEABLE_BITS | |||
548 | 575 | ||
549 | config ETRAX_PD_CHANGEABLE_DIR | 576 | config ETRAX_PD_CHANGEABLE_DIR |
550 | hex "PD user changeable dir mask" | 577 | hex "PD user changeable dir mask" |
551 | depends on ETRAX_GPIO | 578 | depends on ETRAX_GPIO && ETRAXFS |
552 | default "0x00000" | 579 | default "0x00000" |
553 | help | 580 | help |
554 | This is a bitmask (18 bits) with information of what bits in PD | 581 | This is a bitmask (18 bits) with information of what bits in PD |
@@ -558,7 +585,7 @@ config ETRAX_PD_CHANGEABLE_DIR | |||
558 | 585 | ||
559 | config ETRAX_PD_CHANGEABLE_BITS | 586 | config ETRAX_PD_CHANGEABLE_BITS |
560 | hex "PD user changeable bits mask" | 587 | hex "PD user changeable bits mask" |
561 | depends on ETRAX_GPIO | 588 | depends on ETRAX_GPIO && ETRAXFS |
562 | default "0x00000" | 589 | default "0x00000" |
563 | help | 590 | help |
564 | This is a bitmask (18 bits) with information of what bits in PD | 591 | This is a bitmask (18 bits) with information of what bits in PD |
@@ -567,7 +594,7 @@ config ETRAX_PD_CHANGEABLE_BITS | |||
567 | 594 | ||
568 | config ETRAX_PE_CHANGEABLE_DIR | 595 | config ETRAX_PE_CHANGEABLE_DIR |
569 | hex "PE user changeable dir mask" | 596 | hex "PE user changeable dir mask" |
570 | depends on ETRAX_GPIO | 597 | depends on ETRAX_GPIO && ETRAXFS |
571 | default "0x00000" | 598 | default "0x00000" |
572 | help | 599 | help |
573 | This is a bitmask (18 bits) with information of what bits in PE | 600 | This is a bitmask (18 bits) with information of what bits in PE |
@@ -577,20 +604,36 @@ config ETRAX_PE_CHANGEABLE_DIR | |||
577 | 604 | ||
578 | config ETRAX_PE_CHANGEABLE_BITS | 605 | config ETRAX_PE_CHANGEABLE_BITS |
579 | hex "PE user changeable bits mask" | 606 | hex "PE user changeable bits mask" |
580 | depends on ETRAX_GPIO | 607 | depends on ETRAX_GPIO && ETRAXFS |
581 | default "0x00000" | 608 | default "0x00000" |
582 | help | 609 | help |
583 | This is a bitmask (18 bits) with information of what bits in PE | 610 | This is a bitmask (18 bits) with information of what bits in PE |
584 | that a user can change the value on using ioctl's. | 611 | that a user can change the value on using ioctl's. |
585 | Bit set = changeable. | 612 | Bit set = changeable. |
586 | 613 | ||
614 | config ETRAX_PV_CHANGEABLE_DIR | ||
615 | hex "PV user changeable dir mask" | ||
616 | depends on ETRAX_VIRTUAL_GPIO | ||
617 | default "0x0000" | ||
618 | help | ||
619 | This is a bitmask (16 bits) with information of what bits in PV | ||
620 | that a user can change direction on using ioctl's. | ||
621 | Bit set = changeable. | ||
622 | You probably want 0x0000 here, but it depends on your hardware. | ||
623 | |||
624 | config ETRAX_PV_CHANGEABLE_BITS | ||
625 | hex "PV user changeable bits mask" | ||
626 | depends on ETRAX_VIRTUAL_GPIO | ||
627 | default "0x0000" | ||
628 | help | ||
629 | This is a bitmask (16 bits) with information of what bits in PV | ||
630 | that a user can change the value on using ioctl's. | ||
631 | Bit set = changeable. | ||
632 | |||
587 | config ETRAX_CARDBUS | 633 | config ETRAX_CARDBUS |
588 | bool "Cardbus support" | 634 | bool "Cardbus support" |
589 | depends on ETRAX_ARCH_V32 | 635 | depends on ETRAX_ARCH_V32 |
590 | select PCCARD | ||
591 | select CARDBUS | ||
592 | select HOTPLUG | 636 | select HOTPLUG |
593 | select PCCARD_NONSTATIC | ||
594 | help | 637 | help |
595 | Enabled the ETRAX Cardbus driver. | 638 | Enabled the ETRAX Cardbus driver. |
596 | 639 | ||
@@ -613,4 +656,202 @@ config ETRAX_STREAMCOPROC | |||
613 | This option enables a driver for the stream co-processor | 656 | This option enables a driver for the stream co-processor |
614 | for cryptographic operations. | 657 | for cryptographic operations. |
615 | 658 | ||
659 | source drivers/mmc/Kconfig | ||
660 | |||
661 | config ETRAX_MMC_IOP | ||
662 | tristate "MMC/SD host driver using IO-processor" | ||
663 | depends on ETRAX_ARCH_V32 && MMC | ||
664 | help | ||
665 | This option enables the SD/MMC host controller interface. | ||
666 | The host controller is implemented using the built in | ||
667 | IO-Processor. Only the SPU is used in this implementation. | ||
668 | |||
669 | config ETRAX_SPI_MMC | ||
670 | # Make this one of several "choices" (possible simultaneously but | ||
671 | # suggested uniquely) when an IOP driver emerges for "real" MMC/SD | ||
672 | # protocol support. | ||
673 | tristate | ||
674 | depends on !ETRAX_MMC_IOP | ||
675 | default MMC | ||
676 | select SPI | ||
677 | select MMC_SPI | ||
678 | select ETRAX_SPI_MMC_BOARD | ||
679 | |||
680 | # For the parts that can't be a module (due to restrictions in | ||
681 | # framework elsewhere). | ||
682 | config ETRAX_SPI_MMC_BOARD | ||
683 | boolean | ||
684 | default n | ||
685 | |||
686 | # While the board info is MMC_SPI only, the drivers are written to be | ||
687 | # independent of MMC_SPI, so we'll keep SPI non-dependent on the | ||
688 | # MMC_SPI config choices (well, except for a single depends-on-line | ||
689 | # for the board-info file until a separate non-MMC SPI board file | ||
690 | # emerges). | ||
691 | # FIXME: When that happens, we'll need to be able to ask for and | ||
692 | # configure non-MMC SPI ports together with MMC_SPI ports (if multiple | ||
693 | # SPI ports are enabled). | ||
694 | |||
695 | config SPI_ETRAX_SSER | ||
696 | tristate | ||
697 | depends on SPI_MASTER && ETRAX_ARCH_V32 && EXPERIMENTAL | ||
698 | select SPI_BITBANG | ||
699 | help | ||
700 | This enables using an synchronous serial (sser) port as a | ||
701 | SPI master controller on Axis ETRAX FS and later. The | ||
702 | driver can be configured to use any sser port. | ||
703 | |||
704 | config SPI_ETRAX_GPIO | ||
705 | tristate | ||
706 | depends on SPI_MASTER && ETRAX_ARCH_V32 && EXPERIMENTAL | ||
707 | select SPI_BITBANG | ||
708 | help | ||
709 | This enables using GPIO pins port as a SPI master controller | ||
710 | on Axis ETRAX FS and later. The driver can be configured to | ||
711 | use any GPIO pins. | ||
712 | |||
713 | config ETRAX_SPI_SSER0 | ||
714 | tristate "SPI using synchronous serial port 0 (sser0)" | ||
715 | depends on ETRAX_SPI_MMC | ||
716 | default m if MMC_SPI=m | ||
717 | default y if MMC_SPI=y | ||
718 | default y if MMC_SPI=n | ||
719 | select SPI_ETRAX_SSER | ||
720 | help | ||
721 | Say Y for an MMC/SD socket connected to synchronous serial port 0, | ||
722 | or for devices using the SPI protocol on that port. Say m if you | ||
723 | want to build it as a module, which will be named spi_crisv32_sser. | ||
724 | (You need to select MMC separately.) | ||
725 | |||
726 | config ETRAX_SPI_SSER0_DMA | ||
727 | bool "DMA for SPI on sser0 enabled" | ||
728 | depends on ETRAX_SPI_SSER0 | ||
729 | depends on !ETRAX_SERIAL_PORT1_DMA4_OUT && !ETRAX_SERIAL_PORT1_DMA5_IN | ||
730 | default y | ||
731 | help | ||
732 | Say Y if using DMA (dma4/dma5) for SPI on synchronous serial port 0. | ||
733 | |||
734 | config ETRAX_SPI_MMC_CD_SSER0_PIN | ||
735 | string "MMC/SD card detect pin for SPI on sser0" | ||
736 | depends on ETRAX_SPI_SSER0 && MMC_SPI | ||
737 | default "pd11" | ||
738 | help | ||
739 | The pin to use for SD/MMC card detect. This pin should be pulled up | ||
740 | and grounded when a card is present. If defined as " " (space), no | ||
741 | pin is selected. A card must then always be inserted for proper | ||
742 | action. | ||
743 | |||
744 | config ETRAX_SPI_MMC_WP_SSER0_PIN | ||
745 | string "MMC/SD card write-protect pin for SPI on sser0" | ||
746 | depends on ETRAX_SPI_SSER0 && MMC_SPI | ||
747 | default "pd10" | ||
748 | help | ||
749 | The pin to use for the SD/MMC write-protect signal for a memory | ||
750 | card. If defined as " " (space), the card is considered writable. | ||
751 | |||
752 | config ETRAX_SPI_SSER1 | ||
753 | tristate "SPI using synchronous serial port 1 (sser1)" | ||
754 | depends on ETRAX_SPI_MMC | ||
755 | default m if MMC_SPI=m && ETRAX_SPI_SSER0=n | ||
756 | default y if MMC_SPI=y && ETRAX_SPI_SSER0=n | ||
757 | default y if MMC_SPI=n && ETRAX_SPI_SSER0=n | ||
758 | select SPI_ETRAX_SSER | ||
759 | help | ||
760 | Say Y for an MMC/SD socket connected to synchronous serial port 1, | ||
761 | or for devices using the SPI protocol on that port. Say m if you | ||
762 | want to build it as a module, which will be named spi_crisv32_sser. | ||
763 | (You need to select MMC separately.) | ||
764 | |||
765 | config ETRAX_SPI_SSER1_DMA | ||
766 | bool "DMA for SPI on sser1 enabled" | ||
767 | depends on ETRAX_SPI_SSER1 && !ETRAX_ETHERNET_IFACE1 | ||
768 | depends on !ETRAX_SERIAL_PORT0_DMA6_OUT && !ETRAX_SERIAL_PORT0_DMA7_IN | ||
769 | default y | ||
770 | help | ||
771 | Say Y if using DMA (dma6/dma7) for SPI on synchronous serial port 1. | ||
772 | |||
773 | config ETRAX_SPI_MMC_CD_SSER1_PIN | ||
774 | string "MMC/SD card detect pin for SPI on sser1" | ||
775 | depends on ETRAX_SPI_SSER1 && MMC_SPI | ||
776 | default "pd12" | ||
777 | help | ||
778 | The pin to use for SD/MMC card detect. This pin should be pulled up | ||
779 | and grounded when a card is present. If defined as " " (space), no | ||
780 | pin is selected. A card must then always be inserted for proper | ||
781 | action. | ||
782 | |||
783 | config ETRAX_SPI_MMC_WP_SSER1_PIN | ||
784 | string "MMC/SD card write-protect pin for SPI on sser1" | ||
785 | depends on ETRAX_SPI_SSER1 && MMC_SPI | ||
786 | default "pd9" | ||
787 | help | ||
788 | The pin to use for the SD/MMC write-protect signal for a memory | ||
789 | card. If defined as " " (space), the card is considered writable. | ||
790 | |||
791 | config ETRAX_SPI_GPIO | ||
792 | tristate "Bitbanged SPI using gpio pins" | ||
793 | depends on ETRAX_SPI_MMC | ||
794 | select SPI_ETRAX_GPIO | ||
795 | default m if MMC_SPI=m && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n | ||
796 | default y if MMC_SPI=y && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n | ||
797 | default y if MMC_SPI=n && ETRAX_SPI_SSER0=n && ETRAX_SPI_SSER1=n | ||
798 | help | ||
799 | Say Y for an MMC/SD socket connected to general I/O pins (but not | ||
800 | a complete synchronous serial ports), or for devices using the SPI | ||
801 | protocol on general I/O pins. Slow and slows down the system. | ||
802 | Say m to build it as a module, which will be called spi_crisv32_gpio. | ||
803 | (You need to select MMC separately.) | ||
804 | |||
805 | # The default match that of sser0, only because that's how it was tested. | ||
806 | config ETRAX_SPI_CS_PIN | ||
807 | string "SPI chip select pin" | ||
808 | depends on ETRAX_SPI_GPIO | ||
809 | default "pc3" | ||
810 | help | ||
811 | The pin to use for SPI chip select. | ||
812 | |||
813 | config ETRAX_SPI_CLK_PIN | ||
814 | string "SPI clock pin" | ||
815 | depends on ETRAX_SPI_GPIO | ||
816 | default "pc1" | ||
817 | help | ||
818 | The pin to use for the SPI clock. | ||
819 | |||
820 | config ETRAX_SPI_DATAIN_PIN | ||
821 | string "SPI MISO (data in) pin" | ||
822 | depends on ETRAX_SPI_GPIO | ||
823 | default "pc16" | ||
824 | help | ||
825 | The pin to use for SPI data in from the device. | ||
826 | |||
827 | config ETRAX_SPI_DATAOUT_PIN | ||
828 | string "SPI MOSI (data out) pin" | ||
829 | depends on ETRAX_SPI_GPIO | ||
830 | default "pc0" | ||
831 | help | ||
832 | The pin to use for SPI data out to the device. | ||
833 | |||
834 | config ETRAX_SPI_MMC_CD_GPIO_PIN | ||
835 | string "MMC/SD card detect pin for SPI using gpio (space for none)" | ||
836 | depends on ETRAX_SPI_GPIO && MMC_SPI | ||
837 | default "pd11" | ||
838 | help | ||
839 | The pin to use for SD/MMC card detect. This pin should be pulled up | ||
840 | and grounded when a card is present. If defined as " " (space), no | ||
841 | pin is selected. A card must then always be inserted for proper | ||
842 | action. | ||
843 | |||
844 | config ETRAX_SPI_MMC_WP_GPIO_PIN | ||
845 | string "MMC/SD card write-protect pin for SPI using gpio (space for none)" | ||
846 | depends on ETRAX_SPI_GPIO && MMC_SPI | ||
847 | default "pd10" | ||
848 | help | ||
849 | The pin to use for the SD/MMC write-protect signal for a memory | ||
850 | card. If defined as " " (space), the card is considered writable. | ||
851 | |||
852 | # Avoid choices causing non-working configs by conditionalizing the inclusion. | ||
853 | if ETRAX_SPI_MMC | ||
854 | source drivers/spi/Kconfig | ||
855 | endif | ||
856 | |||
616 | endif | 857 | endif |
diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile index a359cd20ae75..e8c02437edaf 100644 --- a/arch/cris/arch-v32/drivers/Makefile +++ b/arch/cris/arch-v32/drivers/Makefile | |||
@@ -4,10 +4,11 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_ETRAX_STREAMCOPROC) += cryptocop.o | 5 | obj-$(CONFIG_ETRAX_STREAMCOPROC) += cryptocop.o |
6 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o | 6 | obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o |
7 | obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o | 7 | obj-$(CONFIG_ETRAXFS) += mach-fs/ |
8 | obj-$(CONFIG_ETRAX_GPIO) += gpio.o | 8 | obj-$(CONFIG_CRIS_MACH_ARTPEC3) += mach-a3/ |
9 | obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o | 9 | obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o |
10 | obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o | 10 | obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o |
11 | obj-$(CONFIG_ETRAX_I2C) += i2c.o | 11 | obj-$(CONFIG_ETRAX_I2C) += i2c.o |
12 | obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o | 12 | obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o |
13 | obj-$(CONFIG_PCI) += pci/ | 13 | obj-$(CONFIG_PCI) += pci/ |
14 | obj-$(CONFIG_ETRAX_SPI_MMC_BOARD) += board_mmcspi.o | ||
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c index c5ff95e18269..51e1e85df96d 100644 --- a/arch/cris/arch-v32/drivers/axisflashmap.c +++ b/arch/cris/arch-v32/drivers/axisflashmap.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Physical mapping layer for MTD using the Axis partitiontable format | 2 | * Physical mapping layer for MTD using the Axis partitiontable format |
3 | * | 3 | * |
4 | * Copyright (c) 2001, 2002, 2003 Axis Communications AB | 4 | * Copyright (c) 2001-2007 Axis Communications AB |
5 | * | 5 | * |
6 | * This file is under the GPL. | 6 | * This file is under the GPL. |
7 | * | 7 | * |
@@ -10,9 +10,6 @@ | |||
10 | * tells us what other partitions to define. If there isn't, we use a default | 10 | * tells us what other partitions to define. If there isn't, we use a default |
11 | * partition split defined below. | 11 | * partition split defined below. |
12 | * | 12 | * |
13 | * Copy of os/lx25/arch/cris/arch-v10/drivers/axisflashmap.c 1.5 | ||
14 | * with minor changes. | ||
15 | * | ||
16 | */ | 13 | */ |
17 | 14 | ||
18 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -27,7 +24,8 @@ | |||
27 | #include <linux/mtd/mtdram.h> | 24 | #include <linux/mtd/mtdram.h> |
28 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
29 | 26 | ||
30 | #include <asm/arch/hwregs/config_defs.h> | 27 | #include <linux/cramfs_fs.h> |
28 | |||
31 | #include <asm/axisflashmap.h> | 29 | #include <asm/axisflashmap.h> |
32 | #include <asm/mmu.h> | 30 | #include <asm/mmu.h> |
33 | 31 | ||
@@ -37,16 +35,24 @@ | |||
37 | #define FLASH_UNCACHED_ADDR KSEG_E | 35 | #define FLASH_UNCACHED_ADDR KSEG_E |
38 | #define FLASH_CACHED_ADDR KSEG_F | 36 | #define FLASH_CACHED_ADDR KSEG_F |
39 | 37 | ||
38 | #define PAGESIZE (512) | ||
39 | |||
40 | #if CONFIG_ETRAX_FLASH_BUSWIDTH==1 | 40 | #if CONFIG_ETRAX_FLASH_BUSWIDTH==1 |
41 | #define flash_data __u8 | 41 | #define flash_data __u8 |
42 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 | 42 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2 |
43 | #define flash_data __u16 | 43 | #define flash_data __u16 |
44 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 | 44 | #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4 |
45 | #define flash_data __u16 | 45 | #define flash_data __u32 |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | /* From head.S */ | 48 | /* From head.S */ |
49 | extern unsigned long romfs_start, romfs_length, romfs_in_flash; | 49 | extern unsigned long romfs_in_flash; /* 1 when romfs_start, _length in flash */ |
50 | extern unsigned long romfs_start, romfs_length; | ||
51 | extern unsigned long nand_boot; /* 1 when booted from nand flash */ | ||
52 | |||
53 | struct partition_name { | ||
54 | char name[6]; | ||
55 | }; | ||
50 | 56 | ||
51 | /* The master mtd for the entire flash. */ | 57 | /* The master mtd for the entire flash. */ |
52 | struct mtd_info* axisflash_mtd = NULL; | 58 | struct mtd_info* axisflash_mtd = NULL; |
@@ -112,32 +118,20 @@ static struct map_info map_cse1 = { | |||
112 | .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE | 118 | .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE |
113 | }; | 119 | }; |
114 | 120 | ||
115 | /* If no partition-table was found, we use this default-set. */ | 121 | #define MAX_PARTITIONS 7 |
116 | #define MAX_PARTITIONS 7 | 122 | #ifdef CONFIG_ETRAX_NANDBOOT |
117 | #define NUM_DEFAULT_PARTITIONS 3 | 123 | #define NUM_DEFAULT_PARTITIONS 4 |
124 | #define DEFAULT_ROOTFS_PARTITION_NO 2 | ||
125 | #define DEFAULT_MEDIA_SIZE 0x2000000 /* 32 megs */ | ||
126 | #else | ||
127 | #define NUM_DEFAULT_PARTITIONS 3 | ||
128 | #define DEFAULT_ROOTFS_PARTITION_NO (-1) | ||
129 | #define DEFAULT_MEDIA_SIZE 0x800000 /* 8 megs */ | ||
130 | #endif | ||
118 | 131 | ||
119 | /* | 132 | #if (MAX_PARTITIONS < NUM_DEFAULT_PARTITIONS) |
120 | * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the | 133 | #error MAX_PARTITIONS must be >= than NUM_DEFAULT_PARTITIONS |
121 | * size of one flash block and "filesystem"-partition needs 5 blocks to be able | 134 | #endif |
122 | * to use JFFS. | ||
123 | */ | ||
124 | static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = { | ||
125 | { | ||
126 | .name = "boot firmware", | ||
127 | .size = CONFIG_ETRAX_PTABLE_SECTOR, | ||
128 | .offset = 0 | ||
129 | }, | ||
130 | { | ||
131 | .name = "kernel", | ||
132 | .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR), | ||
133 | .offset = CONFIG_ETRAX_PTABLE_SECTOR | ||
134 | }, | ||
135 | { | ||
136 | .name = "filesystem", | ||
137 | .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR, | ||
138 | .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR) | ||
139 | } | ||
140 | }; | ||
141 | 135 | ||
142 | /* Initialize the ones normally used. */ | 136 | /* Initialize the ones normally used. */ |
143 | static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { | 137 | static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { |
@@ -178,6 +172,56 @@ static struct mtd_partition axis_partitions[MAX_PARTITIONS] = { | |||
178 | }, | 172 | }, |
179 | }; | 173 | }; |
180 | 174 | ||
175 | |||
176 | /* If no partition-table was found, we use this default-set. | ||
177 | * Default flash size is 8MB (NOR). CONFIG_ETRAX_PTABLE_SECTOR is most | ||
178 | * likely the size of one flash block and "filesystem"-partition needs | ||
179 | * to be >=5 blocks to be able to use JFFS. | ||
180 | */ | ||
181 | static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = { | ||
182 | { | ||
183 | .name = "boot firmware", | ||
184 | .size = CONFIG_ETRAX_PTABLE_SECTOR, | ||
185 | .offset = 0 | ||
186 | }, | ||
187 | { | ||
188 | .name = "kernel", | ||
189 | .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR, | ||
190 | .offset = CONFIG_ETRAX_PTABLE_SECTOR | ||
191 | }, | ||
192 | #define FILESYSTEM_SECTOR (11 * CONFIG_ETRAX_PTABLE_SECTOR) | ||
193 | #ifdef CONFIG_ETRAX_NANDBOOT | ||
194 | { | ||
195 | .name = "rootfs", | ||
196 | .size = 10 * CONFIG_ETRAX_PTABLE_SECTOR, | ||
197 | .offset = FILESYSTEM_SECTOR | ||
198 | }, | ||
199 | #undef FILESYSTEM_SECTOR | ||
200 | #define FILESYSTEM_SECTOR (21 * CONFIG_ETRAX_PTABLE_SECTOR) | ||
201 | #endif | ||
202 | { | ||
203 | .name = "rwfs", | ||
204 | .size = DEFAULT_MEDIA_SIZE - FILESYSTEM_SECTOR, | ||
205 | .offset = FILESYSTEM_SECTOR | ||
206 | } | ||
207 | }; | ||
208 | |||
209 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE | ||
210 | /* Main flash device */ | ||
211 | static struct mtd_partition main_partition = { | ||
212 | .name = "main", | ||
213 | .size = 0, | ||
214 | .offset = 0 | ||
215 | }; | ||
216 | #endif | ||
217 | |||
218 | /* Auxilliary partition if we find another flash */ | ||
219 | static struct mtd_partition aux_partition = { | ||
220 | .name = "aux", | ||
221 | .size = 0, | ||
222 | .offset = 0 | ||
223 | }; | ||
224 | |||
181 | /* | 225 | /* |
182 | * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash | 226 | * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash |
183 | * chips in that order (because the amd_flash-driver is faster). | 227 | * chips in that order (because the amd_flash-driver is faster). |
@@ -191,7 +235,7 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) | |||
191 | map_cs->name, map_cs->size, map_cs->map_priv_1); | 235 | map_cs->name, map_cs->size, map_cs->map_priv_1); |
192 | 236 | ||
193 | #ifdef CONFIG_MTD_CFI | 237 | #ifdef CONFIG_MTD_CFI |
194 | mtd_cs = do_map_probe("cfi_probe", map_cs); | 238 | mtd_cs = do_map_probe("cfi_probe", map_cs); |
195 | #endif | 239 | #endif |
196 | #ifdef CONFIG_MTD_JEDECPROBE | 240 | #ifdef CONFIG_MTD_JEDECPROBE |
197 | if (!mtd_cs) | 241 | if (!mtd_cs) |
@@ -204,7 +248,7 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) | |||
204 | /* | 248 | /* |
205 | * Probe each chip select individually for flash chips. If there are chips on | 249 | * Probe each chip select individually for flash chips. If there are chips on |
206 | * both cse0 and cse1, the mtd_info structs will be concatenated to one struct | 250 | * both cse0 and cse1, the mtd_info structs will be concatenated to one struct |
207 | * so that MTD partitions can cross chip boundaries. | 251 | * so that MTD partitions can cross chip boundries. |
208 | * | 252 | * |
209 | * The only known restriction to how you can mount your chips is that each | 253 | * The only known restriction to how you can mount your chips is that each |
210 | * chip select must hold similar flash chips. But you need external hardware | 254 | * chip select must hold similar flash chips. But you need external hardware |
@@ -216,9 +260,8 @@ static struct mtd_info *flash_probe(void) | |||
216 | { | 260 | { |
217 | struct mtd_info *mtd_cse0; | 261 | struct mtd_info *mtd_cse0; |
218 | struct mtd_info *mtd_cse1; | 262 | struct mtd_info *mtd_cse1; |
219 | struct mtd_info *mtd_nand = NULL; | ||
220 | struct mtd_info *mtd_total; | 263 | struct mtd_info *mtd_total; |
221 | struct mtd_info *mtds[3]; | 264 | struct mtd_info *mtds[2]; |
222 | int count = 0; | 265 | int count = 0; |
223 | 266 | ||
224 | if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL) | 267 | if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL) |
@@ -226,12 +269,7 @@ static struct mtd_info *flash_probe(void) | |||
226 | if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL) | 269 | if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL) |
227 | mtds[count++] = mtd_cse1; | 270 | mtds[count++] = mtd_cse1; |
228 | 271 | ||
229 | #ifdef CONFIG_ETRAX_NANDFLASH | 272 | if (!mtd_cse0 && !mtd_cse1) { |
230 | if ((mtd_nand = crisv32_nand_flash_probe()) != NULL) | ||
231 | mtds[count++] = mtd_nand; | ||
232 | #endif | ||
233 | |||
234 | if (!mtd_cse0 && !mtd_cse1 && !mtd_nand) { | ||
235 | /* No chip found. */ | 273 | /* No chip found. */ |
236 | return NULL; | 274 | return NULL; |
237 | } | 275 | } |
@@ -245,9 +283,7 @@ static struct mtd_info *flash_probe(void) | |||
245 | * So we use the MTD concatenation layer instead of further | 283 | * So we use the MTD concatenation layer instead of further |
246 | * complicating the probing procedure. | 284 | * complicating the probing procedure. |
247 | */ | 285 | */ |
248 | mtd_total = mtd_concat_create(mtds, | 286 | mtd_total = mtd_concat_create(mtds, count, "cse0+cse1"); |
249 | count, | ||
250 | "cse0+cse1+nand"); | ||
251 | #else | 287 | #else |
252 | printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " | 288 | printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " |
253 | "(mis)configuration!\n", map_cse0.name, map_cse1.name); | 289 | "(mis)configuration!\n", map_cse0.name, map_cse1.name); |
@@ -255,61 +291,162 @@ static struct mtd_info *flash_probe(void) | |||
255 | #endif | 291 | #endif |
256 | if (!mtd_total) { | 292 | if (!mtd_total) { |
257 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", | 293 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", |
258 | map_cse0.name, map_cse1.name); | 294 | map_cse0.name, map_cse1.name); |
259 | 295 | ||
260 | /* The best we can do now is to only use what we found | 296 | /* The best we can do now is to only use what we found |
261 | * at cse0. | 297 | * at cse0. */ |
262 | */ | ||
263 | mtd_total = mtd_cse0; | 298 | mtd_total = mtd_cse0; |
264 | map_destroy(mtd_cse1); | 299 | map_destroy(mtd_cse1); |
265 | } | 300 | } |
266 | } else { | 301 | } else |
267 | mtd_total = mtd_cse0? mtd_cse0 : mtd_cse1 ? mtd_cse1 : mtd_nand; | 302 | mtd_total = mtd_cse0 ? mtd_cse0 : mtd_cse1; |
268 | |||
269 | } | ||
270 | 303 | ||
271 | return mtd_total; | 304 | return mtd_total; |
272 | } | 305 | } |
273 | 306 | ||
274 | extern unsigned long crisv32_nand_boot; | ||
275 | extern unsigned long crisv32_nand_cramfs_offset; | ||
276 | |||
277 | /* | 307 | /* |
278 | * Probe the flash chip(s) and, if it succeeds, read the partition-table | 308 | * Probe the flash chip(s) and, if it succeeds, read the partition-table |
279 | * and register the partitions with MTD. | 309 | * and register the partitions with MTD. |
280 | */ | 310 | */ |
281 | static int __init init_axis_flash(void) | 311 | static int __init init_axis_flash(void) |
282 | { | 312 | { |
283 | struct mtd_info *mymtd; | 313 | struct mtd_info *main_mtd; |
314 | struct mtd_info *aux_mtd = NULL; | ||
284 | int err = 0; | 315 | int err = 0; |
285 | int pidx = 0; | 316 | int pidx = 0; |
286 | struct partitiontable_head *ptable_head = NULL; | 317 | struct partitiontable_head *ptable_head = NULL; |
287 | struct partitiontable_entry *ptable; | 318 | struct partitiontable_entry *ptable; |
288 | int use_default_ptable = 1; /* Until proven otherwise. */ | 319 | int ptable_ok = 0; |
289 | const char *pmsg = KERN_INFO " /dev/flash%d at 0x%08x, size 0x%08x\n"; | 320 | static char page[PAGESIZE]; |
290 | static char page[512]; | ||
291 | size_t len; | 321 | size_t len; |
322 | int ram_rootfs_partition = -1; /* -1 => no RAM rootfs partition */ | ||
323 | int part; | ||
324 | |||
325 | /* We need a root fs. If it resides in RAM, we need to use an | ||
326 | * MTDRAM device, so it must be enabled in the kernel config, | ||
327 | * but its size must be configured as 0 so as not to conflict | ||
328 | * with our usage. | ||
329 | */ | ||
330 | #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) | ||
331 | if (!romfs_in_flash && !nand_boot) { | ||
332 | printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " | ||
333 | "device; configure CONFIG_MTD_MTDRAM with size = 0!\n"); | ||
334 | panic("This kernel cannot boot from RAM!\n"); | ||
335 | } | ||
336 | #endif | ||
337 | |||
338 | #ifndef CONFIG_ETRAX_VCS_SIM | ||
339 | main_mtd = flash_probe(); | ||
340 | if (main_mtd) | ||
341 | printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n", | ||
342 | main_mtd->name, main_mtd->size); | ||
343 | |||
344 | #ifdef CONFIG_ETRAX_NANDFLASH | ||
345 | aux_mtd = crisv32_nand_flash_probe(); | ||
346 | if (aux_mtd) | ||
347 | printk(KERN_INFO "%s: 0x%08x bytes of NAND flash memory.\n", | ||
348 | aux_mtd->name, aux_mtd->size); | ||
349 | |||
350 | #ifdef CONFIG_ETRAX_NANDBOOT | ||
351 | { | ||
352 | struct mtd_info *tmp_mtd; | ||
292 | 353 | ||
293 | #ifndef CONFIG_ETRAXFS_SIM | 354 | printk(KERN_INFO "axisflashmap: Set to boot from NAND flash, " |
294 | mymtd = flash_probe(); | 355 | "making NAND flash primary device.\n"); |
295 | mymtd->read(mymtd, CONFIG_ETRAX_PTABLE_SECTOR, 512, &len, page); | 356 | tmp_mtd = main_mtd; |
296 | ptable_head = (struct partitiontable_head *)(page + PARTITION_TABLE_OFFSET); | 357 | main_mtd = aux_mtd; |
358 | aux_mtd = tmp_mtd; | ||
359 | } | ||
360 | #endif /* CONFIG_ETRAX_NANDBOOT */ | ||
361 | #endif /* CONFIG_ETRAX_NANDFLASH */ | ||
297 | 362 | ||
298 | if (!mymtd) { | 363 | if (!main_mtd && !aux_mtd) { |
299 | /* There's no reason to use this module if no flash chip can | 364 | /* There's no reason to use this module if no flash chip can |
300 | * be identified. Make sure that's understood. | 365 | * be identified. Make sure that's understood. |
301 | */ | 366 | */ |
302 | printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); | 367 | printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); |
303 | } else { | ||
304 | printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", | ||
305 | mymtd->name, mymtd->size); | ||
306 | axisflash_mtd = mymtd; | ||
307 | } | 368 | } |
308 | 369 | ||
309 | if (mymtd) { | 370 | #if 0 /* Dump flash memory so we can see what is going on */ |
310 | mymtd->owner = THIS_MODULE; | 371 | if (main_mtd) { |
372 | int sectoraddr, i; | ||
373 | for (sectoraddr = 0; sectoraddr < 2*65536+4096; | ||
374 | sectoraddr += PAGESIZE) { | ||
375 | main_mtd->read(main_mtd, sectoraddr, PAGESIZE, &len, | ||
376 | page); | ||
377 | printk(KERN_INFO | ||
378 | "Sector at %d (length %d):\n", | ||
379 | sectoraddr, len); | ||
380 | for (i = 0; i < PAGESIZE; i += 16) { | ||
381 | printk(KERN_INFO | ||
382 | "%02x %02x %02x %02x " | ||
383 | "%02x %02x %02x %02x " | ||
384 | "%02x %02x %02x %02x " | ||
385 | "%02x %02x %02x %02x\n", | ||
386 | page[i] & 255, page[i+1] & 255, | ||
387 | page[i+2] & 255, page[i+3] & 255, | ||
388 | page[i+4] & 255, page[i+5] & 255, | ||
389 | page[i+6] & 255, page[i+7] & 255, | ||
390 | page[i+8] & 255, page[i+9] & 255, | ||
391 | page[i+10] & 255, page[i+11] & 255, | ||
392 | page[i+12] & 255, page[i+13] & 255, | ||
393 | page[i+14] & 255, page[i+15] & 255); | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | #endif | ||
398 | |||
399 | if (main_mtd) { | ||
400 | main_mtd->owner = THIS_MODULE; | ||
401 | axisflash_mtd = main_mtd; | ||
402 | |||
403 | loff_t ptable_sector = CONFIG_ETRAX_PTABLE_SECTOR; | ||
404 | |||
405 | /* First partition (rescue) is always set to the default. */ | ||
406 | pidx++; | ||
407 | #ifdef CONFIG_ETRAX_NANDBOOT | ||
408 | /* We know where the partition table should be located, | ||
409 | * it will be in first good block after that. | ||
410 | */ | ||
411 | int blockstat; | ||
412 | do { | ||
413 | blockstat = main_mtd->block_isbad(main_mtd, | ||
414 | ptable_sector); | ||
415 | if (blockstat < 0) | ||
416 | ptable_sector = 0; /* read error */ | ||
417 | else if (blockstat) | ||
418 | ptable_sector += main_mtd->erasesize; | ||
419 | } while (blockstat && ptable_sector); | ||
420 | #endif | ||
421 | if (ptable_sector) { | ||
422 | main_mtd->read(main_mtd, ptable_sector, PAGESIZE, | ||
423 | &len, page); | ||
424 | ptable_head = &((struct partitiontable *) page)->head; | ||
425 | } | ||
426 | |||
427 | #if 0 /* Dump partition table so we can see what is going on */ | ||
428 | printk(KERN_INFO | ||
429 | "axisflashmap: flash read %d bytes at 0x%08x, data: " | ||
430 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
431 | len, CONFIG_ETRAX_PTABLE_SECTOR, | ||
432 | page[0] & 255, page[1] & 255, | ||
433 | page[2] & 255, page[3] & 255, | ||
434 | page[4] & 255, page[5] & 255, | ||
435 | page[6] & 255, page[7] & 255); | ||
436 | printk(KERN_INFO | ||
437 | "axisflashmap: partition table offset %d, data: " | ||
438 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
439 | PARTITION_TABLE_OFFSET, | ||
440 | page[PARTITION_TABLE_OFFSET+0] & 255, | ||
441 | page[PARTITION_TABLE_OFFSET+1] & 255, | ||
442 | page[PARTITION_TABLE_OFFSET+2] & 255, | ||
443 | page[PARTITION_TABLE_OFFSET+3] & 255, | ||
444 | page[PARTITION_TABLE_OFFSET+4] & 255, | ||
445 | page[PARTITION_TABLE_OFFSET+5] & 255, | ||
446 | page[PARTITION_TABLE_OFFSET+6] & 255, | ||
447 | page[PARTITION_TABLE_OFFSET+7] & 255); | ||
448 | #endif | ||
311 | } | 449 | } |
312 | pidx++; /* First partition is always set to the default. */ | ||
313 | 450 | ||
314 | if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) | 451 | if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) |
315 | && (ptable_head->size < | 452 | && (ptable_head->size < |
@@ -322,7 +459,6 @@ static int __init init_axis_flash(void) | |||
322 | /* Looks like a start, sane length and end of a | 459 | /* Looks like a start, sane length and end of a |
323 | * partition table, lets check csum etc. | 460 | * partition table, lets check csum etc. |
324 | */ | 461 | */ |
325 | int ptable_ok = 0; | ||
326 | struct partitiontable_entry *max_addr = | 462 | struct partitiontable_entry *max_addr = |
327 | (struct partitiontable_entry *) | 463 | (struct partitiontable_entry *) |
328 | ((unsigned long)ptable_head + sizeof(*ptable_head) + | 464 | ((unsigned long)ptable_head + sizeof(*ptable_head) + |
@@ -346,104 +482,170 @@ static int __init init_axis_flash(void) | |||
346 | ptable_ok = (csum == ptable_head->checksum); | 482 | ptable_ok = (csum == ptable_head->checksum); |
347 | 483 | ||
348 | /* Read the entries and use/show the info. */ | 484 | /* Read the entries and use/show the info. */ |
349 | printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", | 485 | printk(KERN_INFO "axisflashmap: " |
486 | "Found a%s partition table at 0x%p-0x%p.\n", | ||
350 | (ptable_ok ? " valid" : "n invalid"), ptable_head, | 487 | (ptable_ok ? " valid" : "n invalid"), ptable_head, |
351 | max_addr); | 488 | max_addr); |
352 | 489 | ||
353 | /* We have found a working bootblock. Now read the | 490 | /* We have found a working bootblock. Now read the |
354 | * partition table. Scan the table. It ends when | 491 | * partition table. Scan the table. It ends with 0xffffffff. |
355 | * there is 0xffffffff, that is, empty flash. | ||
356 | */ | 492 | */ |
357 | while (ptable_ok | 493 | while (ptable_ok |
358 | && ptable->offset != 0xffffffff | 494 | && ptable->offset != PARTITIONTABLE_END_MARKER |
359 | && ptable < max_addr | 495 | && ptable < max_addr |
360 | && pidx < MAX_PARTITIONS) { | 496 | && pidx < MAX_PARTITIONS - 1) { |
361 | 497 | ||
362 | axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0); | 498 | axis_partitions[pidx].offset = offset + ptable->offset; |
363 | axis_partitions[pidx].size = ptable->size; | 499 | #ifdef CONFIG_ETRAX_NANDFLASH |
364 | 500 | if (main_mtd->type == MTD_NANDFLASH) { | |
365 | printk(pmsg, pidx, axis_partitions[pidx].offset, | 501 | axis_partitions[pidx].size = |
366 | axis_partitions[pidx].size); | 502 | (((ptable+1)->offset == |
503 | PARTITIONTABLE_END_MARKER) ? | ||
504 | main_mtd->size : | ||
505 | ((ptable+1)->offset + offset)) - | ||
506 | (ptable->offset + offset); | ||
507 | |||
508 | } else | ||
509 | #endif /* CONFIG_ETRAX_NANDFLASH */ | ||
510 | axis_partitions[pidx].size = ptable->size; | ||
511 | #ifdef CONFIG_ETRAX_NANDBOOT | ||
512 | /* Save partition number of jffs2 ro partition. | ||
513 | * Needed if RAM booting or root file system in RAM. | ||
514 | */ | ||
515 | if (!nand_boot && | ||
516 | ram_rootfs_partition < 0 && /* not already set */ | ||
517 | ptable->type == PARTITION_TYPE_JFFS2 && | ||
518 | (ptable->flags & PARTITION_FLAGS_READONLY_MASK) == | ||
519 | PARTITION_FLAGS_READONLY) | ||
520 | ram_rootfs_partition = pidx; | ||
521 | #endif /* CONFIG_ETRAX_NANDBOOT */ | ||
367 | pidx++; | 522 | pidx++; |
368 | ptable++; | 523 | ptable++; |
369 | } | 524 | } |
370 | use_default_ptable = !ptable_ok; | ||
371 | } | 525 | } |
372 | 526 | ||
373 | if (romfs_in_flash) { | 527 | /* Decide whether to use default partition table. */ |
374 | /* Add an overlapping device for the root partition (romfs). */ | 528 | /* Only use default table if we actually have a device (main_mtd) */ |
375 | 529 | ||
376 | axis_partitions[pidx].name = "romfs"; | 530 | struct mtd_partition *partition = &axis_partitions[0]; |
377 | if (crisv32_nand_boot) { | 531 | if (main_mtd && !ptable_ok) { |
378 | char* data = kmalloc(1024, GFP_KERNEL); | 532 | memcpy(axis_partitions, axis_default_partitions, |
379 | int len; | 533 | sizeof(axis_default_partitions)); |
380 | int offset = crisv32_nand_cramfs_offset & ~(1024-1); | 534 | pidx = NUM_DEFAULT_PARTITIONS; |
381 | char* tmp; | 535 | ram_rootfs_partition = DEFAULT_ROOTFS_PARTITION_NO; |
382 | 536 | } | |
383 | mymtd->read(mymtd, offset, 1024, &len, data); | ||
384 | tmp = &data[crisv32_nand_cramfs_offset % 512]; | ||
385 | axis_partitions[pidx].size = *(unsigned*)(tmp + 4); | ||
386 | axis_partitions[pidx].offset = crisv32_nand_cramfs_offset; | ||
387 | kfree(data); | ||
388 | } else { | ||
389 | axis_partitions[pidx].size = romfs_length; | ||
390 | axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; | ||
391 | } | ||
392 | 537 | ||
538 | /* Add artificial partitions for rootfs if necessary */ | ||
539 | if (romfs_in_flash) { | ||
540 | /* rootfs is in directly accessible flash memory = NOR flash. | ||
541 | Add an overlapping device for the rootfs partition. */ | ||
542 | printk(KERN_INFO "axisflashmap: Adding partition for " | ||
543 | "overlapping root file system image\n"); | ||
544 | axis_partitions[pidx].size = romfs_length; | ||
545 | axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; | ||
546 | axis_partitions[pidx].name = "romfs"; | ||
393 | axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; | 547 | axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; |
394 | 548 | ram_rootfs_partition = -1; | |
395 | printk(KERN_INFO | ||
396 | " Adding readonly flash partition for romfs image:\n"); | ||
397 | printk(pmsg, pidx, axis_partitions[pidx].offset, | ||
398 | axis_partitions[pidx].size); | ||
399 | pidx++; | 549 | pidx++; |
400 | } | 550 | } else if (romfs_length && !nand_boot) { |
401 | 551 | /* romfs exists in memory, but not in flash, so must be in RAM. | |
402 | if (mymtd) { | 552 | * Configure an MTDRAM partition. */ |
403 | if (use_default_ptable) { | 553 | if (ram_rootfs_partition < 0) { |
404 | printk(KERN_INFO " Using default partition table.\n"); | 554 | /* None set yet, put it at the end */ |
405 | err = add_mtd_partitions(mymtd, axis_default_partitions, | 555 | ram_rootfs_partition = pidx; |
406 | NUM_DEFAULT_PARTITIONS); | 556 | pidx++; |
407 | } else { | ||
408 | err = add_mtd_partitions(mymtd, axis_partitions, pidx); | ||
409 | } | 557 | } |
558 | printk(KERN_INFO "axisflashmap: Adding partition for " | ||
559 | "root file system image in RAM\n"); | ||
560 | axis_partitions[ram_rootfs_partition].size = romfs_length; | ||
561 | axis_partitions[ram_rootfs_partition].offset = romfs_start; | ||
562 | axis_partitions[ram_rootfs_partition].name = "romfs"; | ||
563 | axis_partitions[ram_rootfs_partition].mask_flags |= | ||
564 | MTD_WRITEABLE; | ||
565 | } | ||
410 | 566 | ||
411 | if (err) { | 567 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE |
412 | panic("axisflashmap could not add MTD partitions!\n"); | 568 | if (main_mtd) { |
413 | } | 569 | main_partition.size = main_mtd->size; |
570 | err = add_mtd_partitions(main_mtd, &main_partition, 1); | ||
571 | if (err) | ||
572 | panic("axisflashmap: Could not initialize " | ||
573 | "partition for whole main mtd device!\n"); | ||
414 | } | 574 | } |
415 | /* CONFIG_EXTRAXFS_SIM */ | ||
416 | #endif | 575 | #endif |
417 | 576 | ||
418 | if (!romfs_in_flash) { | 577 | /* Now, register all partitions with mtd. |
419 | /* Create an RAM device for the root partition (romfs). */ | 578 | * We do this one at a time so we can slip in an MTDRAM device |
579 | * in the proper place if required. */ | ||
580 | |||
581 | for (part = 0; part < pidx; part++) { | ||
582 | if (part == ram_rootfs_partition) { | ||
583 | /* add MTDRAM partition here */ | ||
584 | struct mtd_info *mtd_ram; | ||
585 | |||
586 | mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); | ||
587 | if (!mtd_ram) | ||
588 | panic("axisflashmap: Couldn't allocate memory " | ||
589 | "for mtd_info!\n"); | ||
590 | printk(KERN_INFO "axisflashmap: Adding RAM partition " | ||
591 | "for rootfs image.\n"); | ||
592 | err = mtdram_init_device(mtd_ram, | ||
593 | (void *)partition[part].offset, | ||
594 | partition[part].size, | ||
595 | partition[part].name); | ||
596 | if (err) | ||
597 | panic("axisflashmap: Could not initialize " | ||
598 | "MTD RAM device!\n"); | ||
599 | /* JFFS2 likes to have an erasesize. Keep potential | ||
600 | * JFFS2 rootfs happy by providing one. Since image | ||
601 | * was most likely created for main mtd, use that | ||
602 | * erasesize, if available. Otherwise, make a guess. */ | ||
603 | mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize : | ||
604 | CONFIG_ETRAX_PTABLE_SECTOR); | ||
605 | } else { | ||
606 | err = add_mtd_partitions(main_mtd, &partition[part], 1); | ||
607 | if (err) | ||
608 | panic("axisflashmap: Could not add mtd " | ||
609 | "partition %d\n", part); | ||
610 | } | ||
611 | } | ||
612 | #endif /* CONFIG_EXTRAX_VCS_SIM */ | ||
613 | |||
614 | #ifdef CONFIG_ETRAX_VCS_SIM | ||
615 | /* For simulator, always use a RAM partition. | ||
616 | * The rootfs will be found after the kernel in RAM, | ||
617 | * with romfs_start and romfs_end indicating location and size. | ||
618 | */ | ||
619 | struct mtd_info *mtd_ram; | ||
620 | |||
621 | mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); | ||
622 | if (!mtd_ram) { | ||
623 | panic("axisflashmap: Couldn't allocate memory for " | ||
624 | "mtd_info!\n"); | ||
625 | } | ||
420 | 626 | ||
421 | #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0) | 627 | printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, " |
422 | /* No use trying to boot this kernel from RAM. Panic! */ | 628 | "at %u, size %u\n", |
423 | printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM " | 629 | (unsigned) romfs_start, (unsigned) romfs_length); |
424 | "device due to kernel (mis)configuration!\n"); | ||
425 | panic("This kernel cannot boot from RAM!\n"); | ||
426 | #else | ||
427 | struct mtd_info *mtd_ram; | ||
428 | 630 | ||
429 | mtd_ram = kmalloc(sizeof(struct mtd_info), | 631 | err = mtdram_init_device(mtd_ram, (void *)romfs_start, |
430 | GFP_KERNEL); | 632 | romfs_length, "romfs"); |
431 | if (!mtd_ram) { | 633 | if (err) { |
432 | panic("axisflashmap couldn't allocate memory for " | 634 | panic("axisflashmap: Could not initialize MTD RAM " |
433 | "mtd_info!\n"); | 635 | "device!\n"); |
434 | } | 636 | } |
637 | #endif /* CONFIG_EXTRAX_VCS_SIM */ | ||
435 | 638 | ||
436 | printk(KERN_INFO " Adding RAM partition for romfs image:\n"); | 639 | #ifndef CONFIG_ETRAX_VCS_SIM |
437 | printk(pmsg, pidx, romfs_start, romfs_length); | 640 | if (aux_mtd) { |
641 | aux_partition.size = aux_mtd->size; | ||
642 | err = add_mtd_partitions(aux_mtd, &aux_partition, 1); | ||
643 | if (err) | ||
644 | panic("axisflashmap: Could not initialize " | ||
645 | "aux mtd device!\n"); | ||
438 | 646 | ||
439 | err = mtdram_init_device(mtd_ram, (void*)romfs_start, | ||
440 | romfs_length, "romfs"); | ||
441 | if (err) { | ||
442 | panic("axisflashmap could not initialize MTD RAM " | ||
443 | "device!\n"); | ||
444 | } | ||
445 | #endif | ||
446 | } | 647 | } |
648 | #endif /* CONFIG_EXTRAX_VCS_SIM */ | ||
447 | 649 | ||
448 | return err; | 650 | return err; |
449 | } | 651 | } |
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index e8914d401696..9fb58202be99 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c | |||
@@ -1,8 +1,7 @@ | |||
1 | /* $Id: cryptocop.c,v 1.13 2005/04/21 17:27:55 henriken Exp $ | 1 | /* |
2 | * | ||
3 | * Stream co-processor driver for the ETRAX FS | 2 | * Stream co-processor driver for the ETRAX FS |
4 | * | 3 | * |
5 | * Copyright (C) 2003-2005 Axis Communications AB | 4 | * Copyright (C) 2003-2007 Axis Communications AB |
6 | */ | 5 | */ |
7 | 6 | ||
8 | #include <linux/init.h> | 7 | #include <linux/init.h> |
@@ -25,17 +24,29 @@ | |||
25 | #include <asm/signal.h> | 24 | #include <asm/signal.h> |
26 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
27 | 26 | ||
28 | #include <asm/arch/dma.h> | 27 | #include <dma.h> |
29 | #include <asm/arch/hwregs/dma.h> | 28 | #include <hwregs/dma.h> |
30 | #include <asm/arch/hwregs/reg_map.h> | 29 | #include <hwregs/reg_map.h> |
31 | #include <asm/arch/hwregs/reg_rdwr.h> | 30 | #include <hwregs/reg_rdwr.h> |
32 | #include <asm/arch/hwregs/intr_vect_defs.h> | 31 | #include <hwregs/intr_vect_defs.h> |
33 | 32 | ||
34 | #include <asm/arch/hwregs/strcop.h> | 33 | #include <hwregs/strcop.h> |
35 | #include <asm/arch/hwregs/strcop_defs.h> | 34 | #include <hwregs/strcop_defs.h> |
36 | #include <asm/arch/cryptocop.h> | 35 | #include <cryptocop.h> |
37 | 36 | ||
38 | 37 | #ifdef CONFIG_ETRAXFS | |
38 | #define IN_DMA 9 | ||
39 | #define OUT_DMA 8 | ||
40 | #define IN_DMA_INST regi_dma9 | ||
41 | #define OUT_DMA_INST regi_dma8 | ||
42 | #define DMA_IRQ DMA9_INTR_VECT | ||
43 | #else | ||
44 | #define IN_DMA 3 | ||
45 | #define OUT_DMA 2 | ||
46 | #define IN_DMA_INST regi_dma3 | ||
47 | #define OUT_DMA_INST regi_dma2 | ||
48 | #define DMA_IRQ DMA3_INTR_VECT | ||
49 | #endif | ||
39 | 50 | ||
40 | #define DESCR_ALLOC_PAD (31) | 51 | #define DESCR_ALLOC_PAD (31) |
41 | 52 | ||
@@ -1886,14 +1897,14 @@ static void cryptocop_do_tasklet(unsigned long unused) | |||
1886 | } | 1897 | } |
1887 | 1898 | ||
1888 | static irqreturn_t | 1899 | static irqreturn_t |
1889 | dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs) | 1900 | dma_done_interrupt(int irq, void *dev_id) |
1890 | { | 1901 | { |
1891 | struct cryptocop_prio_job *done_job; | 1902 | struct cryptocop_prio_job *done_job; |
1892 | reg_dma_rw_ack_intr ack_intr = { | 1903 | reg_dma_rw_ack_intr ack_intr = { |
1893 | .data = 1, | 1904 | .data = 1, |
1894 | }; | 1905 | }; |
1895 | 1906 | ||
1896 | REG_WR (dma, regi_dma9, rw_ack_intr, ack_intr); | 1907 | REG_WR(dma, IN_DMA_INST, rw_ack_intr, ack_intr); |
1897 | 1908 | ||
1898 | DEBUG(printk("cryptocop DMA done\n")); | 1909 | DEBUG(printk("cryptocop DMA done\n")); |
1899 | 1910 | ||
@@ -1937,7 +1948,6 @@ dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
1937 | static int init_cryptocop(void) | 1948 | static int init_cryptocop(void) |
1938 | { | 1949 | { |
1939 | unsigned long flags; | 1950 | unsigned long flags; |
1940 | reg_intr_vect_rw_mask intr_mask; | ||
1941 | reg_dma_rw_cfg dma_cfg = {.en = 1}; | 1951 | reg_dma_rw_cfg dma_cfg = {.en = 1}; |
1942 | reg_dma_rw_intr_mask intr_mask_in = {.data = regk_dma_yes}; /* Only want descriptor interrupts from the DMA in channel. */ | 1952 | reg_dma_rw_intr_mask intr_mask_in = {.data = regk_dma_yes}; /* Only want descriptor interrupts from the DMA in channel. */ |
1943 | reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 }; | 1953 | reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 }; |
@@ -1950,10 +1960,14 @@ static int init_cryptocop(void) | |||
1950 | .en = 1 | 1960 | .en = 1 |
1951 | }; | 1961 | }; |
1952 | 1962 | ||
1953 | if (request_irq(DMA9_INTR_VECT, dma_done_interrupt, 0, "stream co-processor DMA", NULL)) panic("request_irq stream co-processor irq dma9"); | 1963 | if (request_irq(DMA_IRQ, dma_done_interrupt, 0, |
1964 | "stream co-processor DMA", NULL)) | ||
1965 | panic("request_irq stream co-processor irq dma9"); | ||
1954 | 1966 | ||
1955 | (void)crisv32_request_dma(8, "strcop", DMA_PANIC_ON_ERROR, 0, dma_strp); | 1967 | (void)crisv32_request_dma(OUT_DMA, "strcop", DMA_PANIC_ON_ERROR, |
1956 | (void)crisv32_request_dma(9, "strcop", DMA_PANIC_ON_ERROR, 0, dma_strp); | 1968 | 0, dma_strp); |
1969 | (void)crisv32_request_dma(IN_DMA, "strcop", DMA_PANIC_ON_ERROR, | ||
1970 | 0, dma_strp); | ||
1957 | 1971 | ||
1958 | local_irq_save(flags); | 1972 | local_irq_save(flags); |
1959 | 1973 | ||
@@ -1963,24 +1977,19 @@ static int init_cryptocop(void) | |||
1963 | strcop_cfg.en = 1; | 1977 | strcop_cfg.en = 1; |
1964 | REG_WR(strcop, regi_strcop, rw_cfg, strcop_cfg); | 1978 | REG_WR(strcop, regi_strcop, rw_cfg, strcop_cfg); |
1965 | 1979 | ||
1966 | /* Enable DMA9 interrupt */ | ||
1967 | intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); | ||
1968 | intr_mask.dma9 = 1; | ||
1969 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | ||
1970 | |||
1971 | /* Enable DMAs. */ | 1980 | /* Enable DMAs. */ |
1972 | REG_WR(dma, regi_dma9, rw_cfg, dma_cfg); /* input DMA */ | 1981 | REG_WR(dma, IN_DMA_INST, rw_cfg, dma_cfg); /* input DMA */ |
1973 | REG_WR(dma, regi_dma8, rw_cfg, dma_cfg); /* output DMA */ | 1982 | REG_WR(dma, OUT_DMA_INST, rw_cfg, dma_cfg); /* output DMA */ |
1974 | 1983 | ||
1975 | /* Set up wordsize = 4 for DMAs. */ | 1984 | /* Set up wordsize = 4 for DMAs. */ |
1976 | DMA_WR_CMD (regi_dma8, regk_dma_set_w_size4); | 1985 | DMA_WR_CMD(OUT_DMA_INST, regk_dma_set_w_size4); |
1977 | DMA_WR_CMD (regi_dma9, regk_dma_set_w_size4); | 1986 | DMA_WR_CMD(IN_DMA_INST, regk_dma_set_w_size4); |
1978 | 1987 | ||
1979 | /* Enable interrupts. */ | 1988 | /* Enable interrupts. */ |
1980 | REG_WR(dma, regi_dma9, rw_intr_mask, intr_mask_in); | 1989 | REG_WR(dma, IN_DMA_INST, rw_intr_mask, intr_mask_in); |
1981 | 1990 | ||
1982 | /* Clear intr ack. */ | 1991 | /* Clear intr ack. */ |
1983 | REG_WR(dma, regi_dma9, rw_ack_intr, ack_intr); | 1992 | REG_WR(dma, IN_DMA_INST, rw_ack_intr, ack_intr); |
1984 | 1993 | ||
1985 | local_irq_restore(flags); | 1994 | local_irq_restore(flags); |
1986 | 1995 | ||
@@ -1991,7 +2000,6 @@ static int init_cryptocop(void) | |||
1991 | static void release_cryptocop(void) | 2000 | static void release_cryptocop(void) |
1992 | { | 2001 | { |
1993 | unsigned long flags; | 2002 | unsigned long flags; |
1994 | reg_intr_vect_rw_mask intr_mask; | ||
1995 | reg_dma_rw_cfg dma_cfg = {.en = 0}; | 2003 | reg_dma_rw_cfg dma_cfg = {.en = 0}; |
1996 | reg_dma_rw_intr_mask intr_mask_in = {0}; | 2004 | reg_dma_rw_intr_mask intr_mask_in = {0}; |
1997 | reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 }; | 2005 | reg_dma_rw_ack_intr ack_intr = {.data = 1,.in_eop = 1 }; |
@@ -1999,26 +2007,21 @@ static void release_cryptocop(void) | |||
1999 | local_irq_save(flags); | 2007 | local_irq_save(flags); |
2000 | 2008 | ||
2001 | /* Clear intr ack. */ | 2009 | /* Clear intr ack. */ |
2002 | REG_WR(dma, regi_dma9, rw_ack_intr, ack_intr); | 2010 | REG_WR(dma, IN_DMA_INST, rw_ack_intr, ack_intr); |
2003 | |||
2004 | /* Disable DMA9 interrupt */ | ||
2005 | intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); | ||
2006 | intr_mask.dma9 = 0; | ||
2007 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | ||
2008 | 2011 | ||
2009 | /* Disable DMAs. */ | 2012 | /* Disable DMAs. */ |
2010 | REG_WR(dma, regi_dma9, rw_cfg, dma_cfg); /* input DMA */ | 2013 | REG_WR(dma, IN_DMA_INST, rw_cfg, dma_cfg); /* input DMA */ |
2011 | REG_WR(dma, regi_dma8, rw_cfg, dma_cfg); /* output DMA */ | 2014 | REG_WR(dma, OUT_DMA_INST, rw_cfg, dma_cfg); /* output DMA */ |
2012 | 2015 | ||
2013 | /* Disable interrupts. */ | 2016 | /* Disable interrupts. */ |
2014 | REG_WR(dma, regi_dma9, rw_intr_mask, intr_mask_in); | 2017 | REG_WR(dma, IN_DMA_INST, rw_intr_mask, intr_mask_in); |
2015 | 2018 | ||
2016 | local_irq_restore(flags); | 2019 | local_irq_restore(flags); |
2017 | 2020 | ||
2018 | free_irq(DMA9_INTR_VECT, NULL); | 2021 | free_irq(DMA_IRQ, NULL); |
2019 | 2022 | ||
2020 | (void)crisv32_free_dma(8); | 2023 | (void)crisv32_free_dma(OUT_DMA); |
2021 | (void)crisv32_free_dma(9); | 2024 | (void)crisv32_free_dma(IN_DMA); |
2022 | } | 2025 | } |
2023 | 2026 | ||
2024 | 2027 | ||
@@ -2076,13 +2079,13 @@ static void cryptocop_job_queue_close(void) | |||
2076 | reg_dma_rw_cfg dma_out_cfg, dma_in_cfg; | 2079 | reg_dma_rw_cfg dma_out_cfg, dma_in_cfg; |
2077 | 2080 | ||
2078 | /* Stop DMA. */ | 2081 | /* Stop DMA. */ |
2079 | dma_out_cfg = REG_RD(dma, regi_dma8, rw_cfg); | 2082 | dma_out_cfg = REG_RD(dma, OUT_DMA_INST, rw_cfg); |
2080 | dma_out_cfg.en = regk_dma_no; | 2083 | dma_out_cfg.en = regk_dma_no; |
2081 | REG_WR(dma, regi_dma8, rw_cfg, dma_out_cfg); | 2084 | REG_WR(dma, OUT_DMA_INST, rw_cfg, dma_out_cfg); |
2082 | 2085 | ||
2083 | dma_in_cfg = REG_RD(dma, regi_dma9, rw_cfg); | 2086 | dma_in_cfg = REG_RD(dma, IN_DMA_INST, rw_cfg); |
2084 | dma_in_cfg.en = regk_dma_no; | 2087 | dma_in_cfg.en = regk_dma_no; |
2085 | REG_WR(dma, regi_dma9, rw_cfg, dma_in_cfg); | 2088 | REG_WR(dma, IN_DMA_INST, rw_cfg, dma_in_cfg); |
2086 | 2089 | ||
2087 | /* Disble the cryptocop. */ | 2090 | /* Disble the cryptocop. */ |
2088 | rw_cfg = REG_RD(strcop, regi_strcop, rw_cfg); | 2091 | rw_cfg = REG_RD(strcop, regi_strcop, rw_cfg); |
@@ -2226,10 +2229,11 @@ static void cryptocop_start_job(void) | |||
2226 | &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out))); | 2229 | &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out))); |
2227 | 2230 | ||
2228 | /* Start input DMA. */ | 2231 | /* Start input DMA. */ |
2229 | DMA_START_CONTEXT(regi_dma9, virt_to_phys(&pj->iop->ctx_in)); | 2232 | flush_dma_context(&pj->iop->ctx_in); |
2233 | DMA_START_CONTEXT(IN_DMA_INST, virt_to_phys(&pj->iop->ctx_in)); | ||
2230 | 2234 | ||
2231 | /* Start output DMA. */ | 2235 | /* Start output DMA. */ |
2232 | DMA_START_CONTEXT(regi_dma8, virt_to_phys(&pj->iop->ctx_out)); | 2236 | DMA_START_CONTEXT(OUT_DMA_INST, virt_to_phys(&pj->iop->ctx_out)); |
2233 | 2237 | ||
2234 | spin_unlock_irqrestore(&running_job_lock, running_job_flags); | 2238 | spin_unlock_irqrestore(&running_job_lock, running_job_flags); |
2235 | DEBUG(printk("cryptocop_start_job: exiting\n")); | 2239 | DEBUG(printk("cryptocop_start_job: exiting\n")); |
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c index f1edd2e359b2..c2fb7a5c1396 100644 --- a/arch/cris/arch-v32/drivers/i2c.c +++ b/arch/cris/arch-v32/drivers/i2c.c | |||
@@ -19,10 +19,10 @@ | |||
19 | *! | 19 | *! |
20 | *! --------------------------------------------------------------------------- | 20 | *! --------------------------------------------------------------------------- |
21 | *! | 21 | *! |
22 | *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN | 22 | *! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN |
23 | *! | 23 | *! |
24 | *!***************************************************************************/ | 24 | *!***************************************************************************/ |
25 | /* $Id: i2c.c,v 1.2 2005/05/09 15:29:49 starvik Exp $ */ | 25 | |
26 | /****************** INCLUDE FILES SECTION ***********************************/ | 26 | /****************** INCLUDE FILES SECTION ***********************************/ |
27 | 27 | ||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
@@ -79,6 +79,8 @@ static const char i2c_name[] = "i2c"; | |||
79 | 79 | ||
80 | #define i2c_delay(usecs) udelay(usecs) | 80 | #define i2c_delay(usecs) udelay(usecs) |
81 | 81 | ||
82 | static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */ | ||
83 | |||
82 | /****************** VARIABLE SECTION ************************************/ | 84 | /****************** VARIABLE SECTION ************************************/ |
83 | 85 | ||
84 | static struct crisv32_iopin cris_i2c_clk; | 86 | static struct crisv32_iopin cris_i2c_clk; |
@@ -252,6 +254,7 @@ i2c_getack(void) | |||
252 | * generate ACK clock pulse | 254 | * generate ACK clock pulse |
253 | */ | 255 | */ |
254 | i2c_clk(I2C_CLOCK_HIGH); | 256 | i2c_clk(I2C_CLOCK_HIGH); |
257 | #if 0 | ||
255 | /* | 258 | /* |
256 | * Use PORT PB instead of I2C | 259 | * Use PORT PB instead of I2C |
257 | * for input. (I2C not working) | 260 | * for input. (I2C not working) |
@@ -264,6 +267,8 @@ i2c_getack(void) | |||
264 | i2c_data(1); | 267 | i2c_data(1); |
265 | i2c_disable(); | 268 | i2c_disable(); |
266 | i2c_dir_in(); | 269 | i2c_dir_in(); |
270 | #endif | ||
271 | |||
267 | /* | 272 | /* |
268 | * now wait for ack | 273 | * now wait for ack |
269 | */ | 274 | */ |
@@ -271,11 +276,11 @@ i2c_getack(void) | |||
271 | /* | 276 | /* |
272 | * check for ack | 277 | * check for ack |
273 | */ | 278 | */ |
274 | if(i2c_getbit()) | 279 | if (i2c_getbit()) |
275 | ack = 0; | 280 | ack = 0; |
276 | i2c_delay(CLOCK_HIGH_TIME/2); | 281 | i2c_delay(CLOCK_HIGH_TIME/2); |
277 | if(!ack){ | 282 | if (!ack) { |
278 | if(!i2c_getbit()) /* receiver pulled SDA low */ | 283 | if (!i2c_getbit()) /* receiver pulld SDA low */ |
279 | ack = 1; | 284 | ack = 1; |
280 | i2c_delay(CLOCK_HIGH_TIME/2); | 285 | i2c_delay(CLOCK_HIGH_TIME/2); |
281 | } | 286 | } |
@@ -285,6 +290,7 @@ i2c_getack(void) | |||
285 | * before we enable our output. If we keep data high | 290 | * before we enable our output. If we keep data high |
286 | * and enable output, we would generate a stop condition. | 291 | * and enable output, we would generate a stop condition. |
287 | */ | 292 | */ |
293 | #if 0 | ||
288 | i2c_data(I2C_DATA_LOW); | 294 | i2c_data(I2C_DATA_LOW); |
289 | 295 | ||
290 | /* | 296 | /* |
@@ -292,6 +298,7 @@ i2c_getack(void) | |||
292 | */ | 298 | */ |
293 | i2c_enable(); | 299 | i2c_enable(); |
294 | i2c_dir_out(); | 300 | i2c_dir_out(); |
301 | #endif | ||
295 | i2c_clk(I2C_CLOCK_LOW); | 302 | i2c_clk(I2C_CLOCK_LOW); |
296 | i2c_delay(CLOCK_HIGH_TIME/4); | 303 | i2c_delay(CLOCK_HIGH_TIME/4); |
297 | /* | 304 | /* |
@@ -375,6 +382,121 @@ i2c_sendnack(void) | |||
375 | 382 | ||
376 | /*#--------------------------------------------------------------------------- | 383 | /*#--------------------------------------------------------------------------- |
377 | *# | 384 | *# |
385 | *# FUNCTION NAME: i2c_write | ||
386 | *# | ||
387 | *# DESCRIPTION : Writes a value to an I2C device | ||
388 | *# | ||
389 | *#--------------------------------------------------------------------------*/ | ||
390 | int | ||
391 | i2c_write(unsigned char theSlave, void *data, size_t nbytes) | ||
392 | { | ||
393 | int error, cntr = 3; | ||
394 | unsigned char bytes_wrote = 0; | ||
395 | unsigned char value; | ||
396 | unsigned long flags; | ||
397 | |||
398 | spin_lock_irqsave(&i2c_lock, flags); | ||
399 | |||
400 | do { | ||
401 | error = 0; | ||
402 | |||
403 | i2c_start(); | ||
404 | /* | ||
405 | * send slave address | ||
406 | */ | ||
407 | i2c_outbyte((theSlave & 0xfe)); | ||
408 | /* | ||
409 | * wait for ack | ||
410 | */ | ||
411 | if (!i2c_getack()) | ||
412 | error = 1; | ||
413 | /* | ||
414 | * send data | ||
415 | */ | ||
416 | for (bytes_wrote = 0; bytes_wrote < nbytes; bytes_wrote++) { | ||
417 | memcpy(&value, data + bytes_wrote, sizeof value); | ||
418 | i2c_outbyte(value); | ||
419 | /* | ||
420 | * now it's time to wait for ack | ||
421 | */ | ||
422 | if (!i2c_getack()) | ||
423 | error |= 4; | ||
424 | } | ||
425 | /* | ||
426 | * end byte stream | ||
427 | */ | ||
428 | i2c_stop(); | ||
429 | |||
430 | } while (error && cntr--); | ||
431 | |||
432 | i2c_delay(CLOCK_LOW_TIME); | ||
433 | |||
434 | spin_unlock_irqrestore(&i2c_lock, flags); | ||
435 | |||
436 | return -error; | ||
437 | } | ||
438 | |||
439 | /*#--------------------------------------------------------------------------- | ||
440 | *# | ||
441 | *# FUNCTION NAME: i2c_read | ||
442 | *# | ||
443 | *# DESCRIPTION : Reads a value from an I2C device | ||
444 | *# | ||
445 | *#--------------------------------------------------------------------------*/ | ||
446 | int | ||
447 | i2c_read(unsigned char theSlave, void *data, size_t nbytes) | ||
448 | { | ||
449 | unsigned char b = 0; | ||
450 | unsigned char bytes_read = 0; | ||
451 | int error, cntr = 3; | ||
452 | unsigned long flags; | ||
453 | |||
454 | spin_lock_irqsave(&i2c_lock, flags); | ||
455 | |||
456 | do { | ||
457 | error = 0; | ||
458 | memset(data, 0, nbytes); | ||
459 | /* | ||
460 | * generate start condition | ||
461 | */ | ||
462 | i2c_start(); | ||
463 | /* | ||
464 | * send slave address | ||
465 | */ | ||
466 | i2c_outbyte((theSlave | 0x01)); | ||
467 | /* | ||
468 | * wait for ack | ||
469 | */ | ||
470 | if (!i2c_getack()) | ||
471 | error = 1; | ||
472 | /* | ||
473 | * fetch data | ||
474 | */ | ||
475 | for (bytes_read = 0; bytes_read < nbytes; bytes_read++) { | ||
476 | b = i2c_inbyte(); | ||
477 | memcpy(data + bytes_read, &b, sizeof b); | ||
478 | |||
479 | if (bytes_read < (nbytes - 1)) | ||
480 | i2c_sendack(); | ||
481 | } | ||
482 | /* | ||
483 | * last received byte needs to be nacked | ||
484 | * instead of acked | ||
485 | */ | ||
486 | i2c_sendnack(); | ||
487 | /* | ||
488 | * end sequence | ||
489 | */ | ||
490 | i2c_stop(); | ||
491 | } while (error && cntr--); | ||
492 | |||
493 | spin_unlock_irqrestore(&i2c_lock, flags); | ||
494 | |||
495 | return -error; | ||
496 | } | ||
497 | |||
498 | /*#--------------------------------------------------------------------------- | ||
499 | *# | ||
378 | *# FUNCTION NAME: i2c_writereg | 500 | *# FUNCTION NAME: i2c_writereg |
379 | *# | 501 | *# |
380 | *# DESCRIPTION : Writes a value to an I2C device | 502 | *# DESCRIPTION : Writes a value to an I2C device |
@@ -387,12 +509,10 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, | |||
387 | int error, cntr = 3; | 509 | int error, cntr = 3; |
388 | unsigned long flags; | 510 | unsigned long flags; |
389 | 511 | ||
512 | spin_lock_irqsave(&i2c_lock, flags); | ||
513 | |||
390 | do { | 514 | do { |
391 | error = 0; | 515 | error = 0; |
392 | /* | ||
393 | * we don't like to be interrupted | ||
394 | */ | ||
395 | local_irq_save(flags); | ||
396 | 516 | ||
397 | i2c_start(); | 517 | i2c_start(); |
398 | /* | 518 | /* |
@@ -427,15 +547,12 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, | |||
427 | * end byte stream | 547 | * end byte stream |
428 | */ | 548 | */ |
429 | i2c_stop(); | 549 | i2c_stop(); |
430 | /* | ||
431 | * enable interrupt again | ||
432 | */ | ||
433 | local_irq_restore(flags); | ||
434 | |||
435 | } while(error && cntr--); | 550 | } while(error && cntr--); |
436 | 551 | ||
437 | i2c_delay(CLOCK_LOW_TIME); | 552 | i2c_delay(CLOCK_LOW_TIME); |
438 | 553 | ||
554 | spin_unlock_irqrestore(&i2c_lock, flags); | ||
555 | |||
439 | return -error; | 556 | return -error; |
440 | } | 557 | } |
441 | 558 | ||
@@ -453,13 +570,11 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
453 | int error, cntr = 3; | 570 | int error, cntr = 3; |
454 | unsigned long flags; | 571 | unsigned long flags; |
455 | 572 | ||
573 | spin_lock_irqsave(&i2c_lock, flags); | ||
574 | |||
456 | do { | 575 | do { |
457 | error = 0; | 576 | error = 0; |
458 | /* | 577 | /* |
459 | * we don't like to be interrupted | ||
460 | */ | ||
461 | local_irq_save(flags); | ||
462 | /* | ||
463 | * generate start condition | 578 | * generate start condition |
464 | */ | 579 | */ |
465 | i2c_start(); | 580 | i2c_start(); |
@@ -482,7 +597,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
482 | * now it's time to wait for ack | 597 | * now it's time to wait for ack |
483 | */ | 598 | */ |
484 | if(!i2c_getack()) | 599 | if(!i2c_getack()) |
485 | error = 1; | 600 | error |= 2; |
486 | /* | 601 | /* |
487 | * repeat start condition | 602 | * repeat start condition |
488 | */ | 603 | */ |
@@ -496,7 +611,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
496 | * wait for ack | 611 | * wait for ack |
497 | */ | 612 | */ |
498 | if(!i2c_getack()) | 613 | if(!i2c_getack()) |
499 | error = 1; | 614 | error |= 4; |
500 | /* | 615 | /* |
501 | * fetch register | 616 | * fetch register |
502 | */ | 617 | */ |
@@ -510,13 +625,11 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) | |||
510 | * end sequence | 625 | * end sequence |
511 | */ | 626 | */ |
512 | i2c_stop(); | 627 | i2c_stop(); |
513 | /* | ||
514 | * enable interrupt again | ||
515 | */ | ||
516 | local_irq_restore(flags); | ||
517 | 628 | ||
518 | } while(error && cntr--); | 629 | } while(error && cntr--); |
519 | 630 | ||
631 | spin_unlock_irqrestore(&i2c_lock, flags); | ||
632 | |||
520 | return b; | 633 | return b; |
521 | } | 634 | } |
522 | 635 | ||
@@ -540,7 +653,7 @@ i2c_ioctl(struct inode *inode, struct file *file, | |||
540 | unsigned int cmd, unsigned long arg) | 653 | unsigned int cmd, unsigned long arg) |
541 | { | 654 | { |
542 | if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { | 655 | if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { |
543 | return -EINVAL; | 656 | return -ENOTTY; |
544 | } | 657 | } |
545 | 658 | ||
546 | switch (_IOC_NR(cmd)) { | 659 | switch (_IOC_NR(cmd)) { |
@@ -580,31 +693,52 @@ static const struct file_operations i2c_fops = { | |||
580 | .release = i2c_release, | 693 | .release = i2c_release, |
581 | }; | 694 | }; |
582 | 695 | ||
583 | int __init | 696 | static int __init i2c_init(void) |
584 | i2c_init(void) | ||
585 | { | 697 | { |
586 | int res; | 698 | static int res; |
699 | static int first = 1; | ||
587 | 700 | ||
588 | /* Setup and enable the Port B I2C interface */ | 701 | if (!first) |
702 | return res; | ||
589 | 703 | ||
590 | crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT); | 704 | first = 0; |
591 | crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT); | 705 | |
706 | /* Setup and enable the DATA and CLK pins */ | ||
707 | |||
708 | res = crisv32_io_get_name(&cris_i2c_data, | ||
709 | CONFIG_ETRAX_V32_I2C_DATA_PORT); | ||
710 | if (res < 0) | ||
711 | return res; | ||
712 | |||
713 | res = crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_V32_I2C_CLK_PORT); | ||
714 | crisv32_io_set_dir(&cris_i2c_clk, crisv32_io_dir_out); | ||
715 | |||
716 | return res; | ||
717 | } | ||
718 | |||
719 | |||
720 | static int __init i2c_register(void) | ||
721 | { | ||
722 | int res; | ||
723 | |||
724 | res = i2c_init(); | ||
725 | if (res < 0) | ||
726 | return res; | ||
592 | 727 | ||
593 | /* register char device */ | 728 | /* register char device */ |
594 | 729 | ||
595 | res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); | 730 | res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); |
596 | if(res < 0) { | 731 | if (res < 0) { |
597 | printk(KERN_ERR "i2c: couldn't get a major number.\n"); | 732 | printk(KERN_ERR "i2c: couldn't get a major number.\n"); |
598 | return res; | 733 | return res; |
599 | } | 734 | } |
600 | 735 | ||
601 | printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); | 736 | printk(KERN_INFO |
737 | "I2C driver v2.2, (c) 1999-2007 Axis Communications AB\n"); | ||
602 | 738 | ||
603 | return 0; | 739 | return 0; |
604 | } | 740 | } |
605 | |||
606 | /* this makes sure that i2c_init is called during boot */ | 741 | /* this makes sure that i2c_init is called during boot */ |
607 | 742 | module_init(i2c_register); | |
608 | module_init(i2c_init); | ||
609 | 743 | ||
610 | /****************** END OF FILE i2c.c ********************************/ | 744 | /****************** END OF FILE i2c.c ********************************/ |
diff --git a/arch/cris/arch-v32/drivers/i2c.h b/arch/cris/arch-v32/drivers/i2c.h index bfe1a13f9f35..c073cf4ba016 100644 --- a/arch/cris/arch-v32/drivers/i2c.h +++ b/arch/cris/arch-v32/drivers/i2c.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | /* High level I2C actions */ | 4 | /* High level I2C actions */ |
5 | int __init i2c_init(void); | 5 | int __init i2c_init(void); |
6 | int i2c_write(unsigned char theSlave, void *data, size_t nbytes); | ||
7 | int i2c_read(unsigned char theSlave, void *data, size_t nbytes); | ||
6 | int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); | 8 | int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); |
7 | unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg); | 9 | unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg); |
8 | 10 | ||
diff --git a/arch/cris/arch-v32/drivers/iop_fw_load.c b/arch/cris/arch-v32/drivers/iop_fw_load.c index f4bdc1dfa320..3b3857ec1f15 100644 --- a/arch/cris/arch-v32/drivers/iop_fw_load.c +++ b/arch/cris/arch-v32/drivers/iop_fw_load.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: iop_fw_load.c,v 1.4 2005/04/07 09:27:46 larsv Exp $ | 1 | /* |
2 | * | ||
3 | * Firmware loader for ETRAX FS IO-Processor | 2 | * Firmware loader for ETRAX FS IO-Processor |
4 | * | 3 | * |
5 | * Copyright (C) 2004 Axis Communications AB | 4 | * Copyright (C) 2004 Axis Communications AB |
@@ -11,12 +10,13 @@ | |||
11 | #include <linux/device.h> | 10 | #include <linux/device.h> |
12 | #include <linux/firmware.h> | 11 | #include <linux/firmware.h> |
13 | 12 | ||
14 | #include <asm/arch/hwregs/reg_map.h> | 13 | #include <hwregs/reg_rdwr.h> |
15 | #include <asm/arch/hwregs/iop/iop_reg_space.h> | 14 | #include <hwregs/reg_map.h> |
16 | #include <asm/arch/hwregs/iop/iop_mpu_macros.h> | 15 | #include <hwregs/iop/iop_reg_space.h> |
17 | #include <asm/arch/hwregs/iop/iop_mpu_defs.h> | 16 | #include <hwregs/iop/iop_mpu_macros.h> |
18 | #include <asm/arch/hwregs/iop/iop_spu_defs.h> | 17 | #include <hwregs/iop/iop_mpu_defs.h> |
19 | #include <asm/arch/hwregs/iop/iop_sw_cpu_defs.h> | 18 | #include <hwregs/iop/iop_spu_defs.h> |
19 | #include <hwregs/iop/iop_sw_cpu_defs.h> | ||
20 | 20 | ||
21 | #define IOP_TIMEOUT 100 | 21 | #define IOP_TIMEOUT 100 |
22 | 22 | ||
diff --git a/arch/cris/arch-v32/drivers/mach-a3/Makefile b/arch/cris/arch-v32/drivers/mach-a3/Makefile new file mode 100644 index 000000000000..5c6d2a2a080e --- /dev/null +++ b/arch/cris/arch-v32/drivers/mach-a3/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for Etrax-specific drivers | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o | ||
6 | obj-$(CONFIG_ETRAX_GPIO) += gpio.o | ||
diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c new file mode 100644 index 000000000000..de107dad9f4f --- /dev/null +++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c | |||
@@ -0,0 +1,984 @@ | |||
1 | /* | ||
2 | * Artec-3 general port I/O device | ||
3 | * | ||
4 | * Copyright (c) 2007 Axis Communications AB | ||
5 | * | ||
6 | * Authors: Bjorn Wesen (initial version) | ||
7 | * Ola Knutsson (LED handling) | ||
8 | * Johan Adolfsson (read/set directions, write, port G, | ||
9 | * port to ETRAX FS. | ||
10 | * Ricard Wanderlof (PWM for Artpec-3) | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/ioport.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/string.h> | ||
22 | #include <linux/poll.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | |||
27 | #include <asm/etraxgpio.h> | ||
28 | #include <hwregs/reg_map.h> | ||
29 | #include <hwregs/reg_rdwr.h> | ||
30 | #include <hwregs/gio_defs.h> | ||
31 | #include <hwregs/intr_vect_defs.h> | ||
32 | #include <asm/io.h> | ||
33 | #include <asm/system.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/arch/mach/pinmux.h> | ||
36 | |||
37 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
38 | #include "../i2c.h" | ||
39 | |||
40 | #define VIRT_I2C_ADDR 0x40 | ||
41 | #endif | ||
42 | |||
43 | /* The following gio ports on ARTPEC-3 is available: | ||
44 | * pa 32 bits | ||
45 | * pb 32 bits | ||
46 | * pc 16 bits | ||
47 | * each port has a rw_px_dout, r_px_din and rw_px_oe register. | ||
48 | */ | ||
49 | |||
50 | #define GPIO_MAJOR 120 /* experimental MAJOR number */ | ||
51 | |||
52 | #define I2C_INTERRUPT_BITS 0x300 /* i2c0_done and i2c1_done bits */ | ||
53 | |||
54 | #define D(x) | ||
55 | |||
56 | #if 0 | ||
57 | static int dp_cnt; | ||
58 | #define DP(x) \ | ||
59 | do { \ | ||
60 | dp_cnt++; \ | ||
61 | if (dp_cnt % 1000 == 0) \ | ||
62 | x; \ | ||
63 | } while (0) | ||
64 | #else | ||
65 | #define DP(x) | ||
66 | #endif | ||
67 | |||
68 | static char gpio_name[] = "etrax gpio"; | ||
69 | |||
70 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
71 | static int virtual_gpio_ioctl(struct file *file, unsigned int cmd, | ||
72 | unsigned long arg); | ||
73 | #endif | ||
74 | static int gpio_ioctl(struct inode *inode, struct file *file, | ||
75 | unsigned int cmd, unsigned long arg); | ||
76 | static ssize_t gpio_write(struct file *file, const char __user *buf, | ||
77 | size_t count, loff_t *off); | ||
78 | static int gpio_open(struct inode *inode, struct file *filp); | ||
79 | static int gpio_release(struct inode *inode, struct file *filp); | ||
80 | static unsigned int gpio_poll(struct file *filp, | ||
81 | struct poll_table_struct *wait); | ||
82 | |||
83 | /* private data per open() of this driver */ | ||
84 | |||
85 | struct gpio_private { | ||
86 | struct gpio_private *next; | ||
87 | /* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */ | ||
88 | unsigned char clk_mask; | ||
89 | unsigned char data_mask; | ||
90 | unsigned char write_msb; | ||
91 | unsigned char pad1; | ||
92 | /* These fields are generic */ | ||
93 | unsigned long highalarm, lowalarm; | ||
94 | wait_queue_head_t alarm_wq; | ||
95 | int minor; | ||
96 | }; | ||
97 | |||
98 | static void gpio_set_alarm(struct gpio_private *priv); | ||
99 | static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg); | ||
100 | static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd, | ||
101 | unsigned long arg); | ||
102 | |||
103 | |||
104 | /* linked list of alarms to check for */ | ||
105 | |||
106 | static struct gpio_private *alarmlist; | ||
107 | |||
108 | static int wanted_interrupts; | ||
109 | |||
110 | static DEFINE_SPINLOCK(gpio_lock); | ||
111 | |||
112 | #define NUM_PORTS (GPIO_MINOR_LAST+1) | ||
113 | #define GIO_REG_RD_ADDR(reg) \ | ||
114 | (unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg) | ||
115 | #define GIO_REG_WR_ADDR(reg) \ | ||
116 | (unsigned long *)(regi_gio + REG_WR_ADDR_gio_##reg) | ||
117 | static unsigned long led_dummy; | ||
118 | static unsigned long port_d_dummy; /* Only input on Artpec-3 */ | ||
119 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
120 | static unsigned long port_e_dummy; /* Non existent on Artpec-3 */ | ||
121 | static unsigned long virtual_dummy; | ||
122 | static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE; | ||
123 | static unsigned short cached_virtual_gpio_read; | ||
124 | #endif | ||
125 | |||
126 | static unsigned long *data_out[NUM_PORTS] = { | ||
127 | GIO_REG_WR_ADDR(rw_pa_dout), | ||
128 | GIO_REG_WR_ADDR(rw_pb_dout), | ||
129 | &led_dummy, | ||
130 | GIO_REG_WR_ADDR(rw_pc_dout), | ||
131 | &port_d_dummy, | ||
132 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
133 | &port_e_dummy, | ||
134 | &virtual_dummy, | ||
135 | #endif | ||
136 | }; | ||
137 | |||
138 | static unsigned long *data_in[NUM_PORTS] = { | ||
139 | GIO_REG_RD_ADDR(r_pa_din), | ||
140 | GIO_REG_RD_ADDR(r_pb_din), | ||
141 | &led_dummy, | ||
142 | GIO_REG_RD_ADDR(r_pc_din), | ||
143 | GIO_REG_RD_ADDR(r_pd_din), | ||
144 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
145 | &port_e_dummy, | ||
146 | &virtual_dummy, | ||
147 | #endif | ||
148 | }; | ||
149 | |||
150 | static unsigned long changeable_dir[NUM_PORTS] = { | ||
151 | CONFIG_ETRAX_PA_CHANGEABLE_DIR, | ||
152 | CONFIG_ETRAX_PB_CHANGEABLE_DIR, | ||
153 | 0, | ||
154 | CONFIG_ETRAX_PC_CHANGEABLE_DIR, | ||
155 | 0, | ||
156 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
157 | 0, | ||
158 | CONFIG_ETRAX_PV_CHANGEABLE_DIR, | ||
159 | #endif | ||
160 | }; | ||
161 | |||
162 | static unsigned long changeable_bits[NUM_PORTS] = { | ||
163 | CONFIG_ETRAX_PA_CHANGEABLE_BITS, | ||
164 | CONFIG_ETRAX_PB_CHANGEABLE_BITS, | ||
165 | 0, | ||
166 | CONFIG_ETRAX_PC_CHANGEABLE_BITS, | ||
167 | 0, | ||
168 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
169 | 0, | ||
170 | CONFIG_ETRAX_PV_CHANGEABLE_BITS, | ||
171 | #endif | ||
172 | }; | ||
173 | |||
174 | static unsigned long *dir_oe[NUM_PORTS] = { | ||
175 | GIO_REG_WR_ADDR(rw_pa_oe), | ||
176 | GIO_REG_WR_ADDR(rw_pb_oe), | ||
177 | &led_dummy, | ||
178 | GIO_REG_WR_ADDR(rw_pc_oe), | ||
179 | &port_d_dummy, | ||
180 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
181 | &port_e_dummy, | ||
182 | &virtual_rw_pv_oe, | ||
183 | #endif | ||
184 | }; | ||
185 | |||
186 | static void gpio_set_alarm(struct gpio_private *priv) | ||
187 | { | ||
188 | int bit; | ||
189 | int intr_cfg; | ||
190 | int mask; | ||
191 | int pins; | ||
192 | unsigned long flags; | ||
193 | |||
194 | spin_lock_irqsave(&gpio_lock, flags); | ||
195 | intr_cfg = REG_RD_INT(gio, regi_gio, rw_intr_cfg); | ||
196 | pins = REG_RD_INT(gio, regi_gio, rw_intr_pins); | ||
197 | mask = REG_RD_INT(gio, regi_gio, rw_intr_mask) & I2C_INTERRUPT_BITS; | ||
198 | |||
199 | for (bit = 0; bit < 32; bit++) { | ||
200 | int intr = bit % 8; | ||
201 | int pin = bit / 8; | ||
202 | if (priv->minor < GPIO_MINOR_LEDS) | ||
203 | pin += priv->minor * 4; | ||
204 | else | ||
205 | pin += (priv->minor - 1) * 4; | ||
206 | |||
207 | if (priv->highalarm & (1<<bit)) { | ||
208 | intr_cfg |= (regk_gio_hi << (intr * 3)); | ||
209 | mask |= 1 << intr; | ||
210 | wanted_interrupts = mask & 0xff; | ||
211 | pins |= pin << (intr * 4); | ||
212 | } else if (priv->lowalarm & (1<<bit)) { | ||
213 | intr_cfg |= (regk_gio_lo << (intr * 3)); | ||
214 | mask |= 1 << intr; | ||
215 | wanted_interrupts = mask & 0xff; | ||
216 | pins |= pin << (intr * 4); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | REG_WR_INT(gio, regi_gio, rw_intr_cfg, intr_cfg); | ||
221 | REG_WR_INT(gio, regi_gio, rw_intr_pins, pins); | ||
222 | REG_WR_INT(gio, regi_gio, rw_intr_mask, mask); | ||
223 | |||
224 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
225 | } | ||
226 | |||
227 | static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait) | ||
228 | { | ||
229 | unsigned int mask = 0; | ||
230 | struct gpio_private *priv = file->private_data; | ||
231 | unsigned long data; | ||
232 | unsigned long tmp; | ||
233 | |||
234 | if (priv->minor >= GPIO_MINOR_PWM0 && | ||
235 | priv->minor <= GPIO_MINOR_LAST_PWM) | ||
236 | return 0; | ||
237 | |||
238 | poll_wait(file, &priv->alarm_wq, wait); | ||
239 | if (priv->minor <= GPIO_MINOR_D) { | ||
240 | data = readl(data_in[priv->minor]); | ||
241 | REG_WR_INT(gio, regi_gio, rw_ack_intr, wanted_interrupts); | ||
242 | tmp = REG_RD_INT(gio, regi_gio, rw_intr_mask); | ||
243 | tmp &= I2C_INTERRUPT_BITS; | ||
244 | tmp |= wanted_interrupts; | ||
245 | REG_WR_INT(gio, regi_gio, rw_intr_mask, tmp); | ||
246 | } else | ||
247 | return 0; | ||
248 | |||
249 | if ((data & priv->highalarm) || (~data & priv->lowalarm)) | ||
250 | mask = POLLIN|POLLRDNORM; | ||
251 | |||
252 | DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask)); | ||
253 | return mask; | ||
254 | } | ||
255 | |||
256 | static irqreturn_t gpio_interrupt(int irq, void *dev_id) | ||
257 | { | ||
258 | reg_gio_rw_intr_mask intr_mask; | ||
259 | reg_gio_r_masked_intr masked_intr; | ||
260 | reg_gio_rw_ack_intr ack_intr; | ||
261 | unsigned long flags; | ||
262 | unsigned long tmp; | ||
263 | unsigned long tmp2; | ||
264 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
265 | unsigned char enable_gpiov_ack = 0; | ||
266 | #endif | ||
267 | |||
268 | /* Find what PA interrupts are active */ | ||
269 | masked_intr = REG_RD(gio, regi_gio, r_masked_intr); | ||
270 | tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr); | ||
271 | |||
272 | /* Find those that we have enabled */ | ||
273 | spin_lock_irqsave(&gpio_lock, flags); | ||
274 | tmp &= wanted_interrupts; | ||
275 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
276 | |||
277 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
278 | /* Something changed on virtual GPIO. Interrupt is acked by | ||
279 | * reading the device. | ||
280 | */ | ||
281 | if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) { | ||
282 | i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read, | ||
283 | sizeof(cached_virtual_gpio_read)); | ||
284 | enable_gpiov_ack = 1; | ||
285 | } | ||
286 | #endif | ||
287 | |||
288 | /* Ack them */ | ||
289 | ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp); | ||
290 | REG_WR(gio, regi_gio, rw_ack_intr, ack_intr); | ||
291 | |||
292 | /* Disable those interrupts.. */ | ||
293 | intr_mask = REG_RD(gio, regi_gio, rw_intr_mask); | ||
294 | tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask); | ||
295 | tmp2 &= ~tmp; | ||
296 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
297 | /* Do not disable interrupt on virtual GPIO. Changes on virtual | ||
298 | * pins are only noticed by an interrupt. | ||
299 | */ | ||
300 | if (enable_gpiov_ack) | ||
301 | tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
302 | #endif | ||
303 | intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2); | ||
304 | REG_WR(gio, regi_gio, rw_intr_mask, intr_mask); | ||
305 | |||
306 | return IRQ_RETVAL(tmp); | ||
307 | } | ||
308 | |||
309 | static void gpio_write_bit(unsigned long *port, unsigned char data, int bit, | ||
310 | unsigned char clk_mask, unsigned char data_mask) | ||
311 | { | ||
312 | unsigned long shadow = readl(port) & ~clk_mask; | ||
313 | writel(shadow, port); | ||
314 | if (data & 1 << bit) | ||
315 | shadow |= data_mask; | ||
316 | else | ||
317 | shadow &= ~data_mask; | ||
318 | writel(shadow, port); | ||
319 | /* For FPGA: min 5.0ns (DCC) before CCLK high */ | ||
320 | shadow |= clk_mask; | ||
321 | writel(shadow, port); | ||
322 | } | ||
323 | |||
324 | static void gpio_write_byte(struct gpio_private *priv, unsigned long *port, | ||
325 | unsigned char data) | ||
326 | { | ||
327 | int i; | ||
328 | |||
329 | if (priv->write_msb) | ||
330 | for (i = 7; i >= 0; i--) | ||
331 | gpio_write_bit(port, data, i, priv->clk_mask, | ||
332 | priv->data_mask); | ||
333 | else | ||
334 | for (i = 0; i <= 7; i++) | ||
335 | gpio_write_bit(port, data, i, priv->clk_mask, | ||
336 | priv->data_mask); | ||
337 | } | ||
338 | |||
339 | |||
340 | static ssize_t gpio_write(struct file *file, const char __user *buf, | ||
341 | size_t count, loff_t *off) | ||
342 | { | ||
343 | struct gpio_private *priv = file->private_data; | ||
344 | unsigned long flags; | ||
345 | ssize_t retval = count; | ||
346 | /* Only bits 0-7 may be used for write operations but allow all | ||
347 | devices except leds... */ | ||
348 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
349 | if (priv->minor == GPIO_MINOR_V) | ||
350 | return -EFAULT; | ||
351 | #endif | ||
352 | if (priv->minor == GPIO_MINOR_LEDS) | ||
353 | return -EFAULT; | ||
354 | |||
355 | if (priv->minor >= GPIO_MINOR_PWM0 && | ||
356 | priv->minor <= GPIO_MINOR_LAST_PWM) | ||
357 | return -EFAULT; | ||
358 | |||
359 | if (!access_ok(VERIFY_READ, buf, count)) | ||
360 | return -EFAULT; | ||
361 | |||
362 | /* It must have been configured using the IO_CFG_WRITE_MODE */ | ||
363 | /* Perhaps a better error code? */ | ||
364 | if (priv->clk_mask == 0 || priv->data_mask == 0) | ||
365 | return -EPERM; | ||
366 | |||
367 | D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X " | ||
368 | "msb: %i\n", | ||
369 | count, priv->data_mask, priv->clk_mask, priv->write_msb)); | ||
370 | |||
371 | spin_lock_irqsave(&gpio_lock, flags); | ||
372 | |||
373 | while (count--) | ||
374 | gpio_write_byte(priv, data_out[priv->minor], *buf++); | ||
375 | |||
376 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
377 | return retval; | ||
378 | } | ||
379 | |||
380 | static int gpio_open(struct inode *inode, struct file *filp) | ||
381 | { | ||
382 | struct gpio_private *priv; | ||
383 | int p = iminor(inode); | ||
384 | |||
385 | if (p > GPIO_MINOR_LAST_PWM || | ||
386 | (p > GPIO_MINOR_LAST && p < GPIO_MINOR_PWM0)) | ||
387 | return -EINVAL; | ||
388 | |||
389 | priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL); | ||
390 | |||
391 | if (!priv) | ||
392 | return -ENOMEM; | ||
393 | memset(priv, 0, sizeof(*priv)); | ||
394 | |||
395 | priv->minor = p; | ||
396 | filp->private_data = priv; | ||
397 | |||
398 | /* initialize the io/alarm struct, not for PWM ports though */ | ||
399 | if (p <= GPIO_MINOR_LAST) { | ||
400 | |||
401 | priv->clk_mask = 0; | ||
402 | priv->data_mask = 0; | ||
403 | priv->highalarm = 0; | ||
404 | priv->lowalarm = 0; | ||
405 | |||
406 | init_waitqueue_head(&priv->alarm_wq); | ||
407 | |||
408 | /* link it into our alarmlist */ | ||
409 | spin_lock_irq(&gpio_lock); | ||
410 | priv->next = alarmlist; | ||
411 | alarmlist = priv; | ||
412 | spin_unlock_irq(&gpio_lock); | ||
413 | } | ||
414 | |||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static int gpio_release(struct inode *inode, struct file *filp) | ||
419 | { | ||
420 | struct gpio_private *p; | ||
421 | struct gpio_private *todel; | ||
422 | /* local copies while updating them: */ | ||
423 | unsigned long a_high, a_low; | ||
424 | |||
425 | /* prepare to free private structure */ | ||
426 | todel = filp->private_data; | ||
427 | |||
428 | /* unlink from alarmlist - only for non-PWM ports though */ | ||
429 | if (todel->minor <= GPIO_MINOR_LAST) { | ||
430 | spin_lock_irq(&gpio_lock); | ||
431 | p = alarmlist; | ||
432 | |||
433 | if (p == todel) | ||
434 | alarmlist = todel->next; | ||
435 | else { | ||
436 | while (p->next != todel) | ||
437 | p = p->next; | ||
438 | p->next = todel->next; | ||
439 | } | ||
440 | |||
441 | /* Check if there are still any alarms set */ | ||
442 | p = alarmlist; | ||
443 | a_high = 0; | ||
444 | a_low = 0; | ||
445 | while (p) { | ||
446 | if (p->minor == GPIO_MINOR_A) { | ||
447 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
448 | p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
449 | #endif | ||
450 | a_high |= p->highalarm; | ||
451 | a_low |= p->lowalarm; | ||
452 | } | ||
453 | |||
454 | p = p->next; | ||
455 | } | ||
456 | |||
457 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
458 | /* Variable 'a_low' needs to be set here again | ||
459 | * to ensure that interrupt for virtual GPIO is handled. | ||
460 | */ | ||
461 | a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
462 | #endif | ||
463 | |||
464 | spin_unlock_irq(&gpio_lock); | ||
465 | } | ||
466 | kfree(todel); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | /* Main device API. ioctl's to read/set/clear bits, as well as to | ||
472 | * set alarms to wait for using a subsequent select(). | ||
473 | */ | ||
474 | |||
475 | inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg) | ||
476 | { | ||
477 | /* Set direction 0=unchanged 1=input, | ||
478 | * return mask with 1=input | ||
479 | */ | ||
480 | unsigned long flags; | ||
481 | unsigned long dir_shadow; | ||
482 | |||
483 | spin_lock_irqsave(&gpio_lock, flags); | ||
484 | |||
485 | dir_shadow = readl(dir_oe[priv->minor]) & | ||
486 | ~(arg & changeable_dir[priv->minor]); | ||
487 | writel(dir_shadow, dir_oe[priv->minor]); | ||
488 | |||
489 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
490 | |||
491 | if (priv->minor == GPIO_MINOR_C) | ||
492 | dir_shadow ^= 0xFFFF; /* Only 16 bits */ | ||
493 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
494 | else if (priv->minor == GPIO_MINOR_V) | ||
495 | dir_shadow ^= 0xFFFF; /* Only 16 bits */ | ||
496 | #endif | ||
497 | else | ||
498 | dir_shadow ^= 0xFFFFFFFF; /* PA, PB and PD 32 bits */ | ||
499 | |||
500 | return dir_shadow; | ||
501 | |||
502 | } /* setget_input */ | ||
503 | |||
504 | static inline unsigned long setget_output(struct gpio_private *priv, | ||
505 | unsigned long arg) | ||
506 | { | ||
507 | unsigned long flags; | ||
508 | unsigned long dir_shadow; | ||
509 | |||
510 | spin_lock_irqsave(&gpio_lock, flags); | ||
511 | |||
512 | dir_shadow = readl(dir_oe[priv->minor]) | | ||
513 | (arg & changeable_dir[priv->minor]); | ||
514 | writel(dir_shadow, dir_oe[priv->minor]); | ||
515 | |||
516 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
517 | return dir_shadow; | ||
518 | } /* setget_output */ | ||
519 | |||
520 | static int gpio_ioctl(struct inode *inode, struct file *file, | ||
521 | unsigned int cmd, unsigned long arg) | ||
522 | { | ||
523 | unsigned long flags; | ||
524 | unsigned long val; | ||
525 | unsigned long shadow; | ||
526 | struct gpio_private *priv = file->private_data; | ||
527 | |||
528 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) | ||
529 | return -ENOTTY; | ||
530 | |||
531 | /* Check for special ioctl handlers first */ | ||
532 | |||
533 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
534 | if (priv->minor == GPIO_MINOR_V) | ||
535 | return virtual_gpio_ioctl(file, cmd, arg); | ||
536 | #endif | ||
537 | |||
538 | if (priv->minor == GPIO_MINOR_LEDS) | ||
539 | return gpio_leds_ioctl(cmd, arg); | ||
540 | |||
541 | if (priv->minor >= GPIO_MINOR_PWM0 && | ||
542 | priv->minor <= GPIO_MINOR_LAST_PWM) | ||
543 | return gpio_pwm_ioctl(priv, cmd, arg); | ||
544 | |||
545 | switch (_IOC_NR(cmd)) { | ||
546 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ | ||
547 | /* Read the port. */ | ||
548 | return readl(data_in[priv->minor]); | ||
549 | case IO_SETBITS: | ||
550 | spin_lock_irqsave(&gpio_lock, flags); | ||
551 | /* Set changeable bits with a 1 in arg. */ | ||
552 | shadow = readl(data_out[priv->minor]) | | ||
553 | (arg & changeable_bits[priv->minor]); | ||
554 | writel(shadow, data_out[priv->minor]); | ||
555 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
556 | break; | ||
557 | case IO_CLRBITS: | ||
558 | spin_lock_irqsave(&gpio_lock, flags); | ||
559 | /* Clear changeable bits with a 1 in arg. */ | ||
560 | shadow = readl(data_out[priv->minor]) & | ||
561 | ~(arg & changeable_bits[priv->minor]); | ||
562 | writel(shadow, data_out[priv->minor]); | ||
563 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
564 | break; | ||
565 | case IO_HIGHALARM: | ||
566 | /* Set alarm when bits with 1 in arg go high. */ | ||
567 | priv->highalarm |= arg; | ||
568 | gpio_set_alarm(priv); | ||
569 | break; | ||
570 | case IO_LOWALARM: | ||
571 | /* Set alarm when bits with 1 in arg go low. */ | ||
572 | priv->lowalarm |= arg; | ||
573 | gpio_set_alarm(priv); | ||
574 | break; | ||
575 | case IO_CLRALARM: | ||
576 | /* Clear alarm for bits with 1 in arg. */ | ||
577 | priv->highalarm &= ~arg; | ||
578 | priv->lowalarm &= ~arg; | ||
579 | gpio_set_alarm(priv); | ||
580 | break; | ||
581 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ | ||
582 | /* Read direction 0=input 1=output */ | ||
583 | return readl(dir_oe[priv->minor]); | ||
584 | |||
585 | case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */ | ||
586 | /* Set direction 0=unchanged 1=input, | ||
587 | * return mask with 1=input | ||
588 | */ | ||
589 | return setget_input(priv, arg); | ||
590 | |||
591 | case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */ | ||
592 | /* Set direction 0=unchanged 1=output, | ||
593 | * return mask with 1=output | ||
594 | */ | ||
595 | return setget_output(priv, arg); | ||
596 | |||
597 | case IO_CFG_WRITE_MODE: | ||
598 | { | ||
599 | int res = -EPERM; | ||
600 | unsigned long dir_shadow, clk_mask, data_mask, write_msb; | ||
601 | |||
602 | clk_mask = arg & 0xFF; | ||
603 | data_mask = (arg >> 8) & 0xFF; | ||
604 | write_msb = (arg >> 16) & 0x01; | ||
605 | |||
606 | /* Check if we're allowed to change the bits and | ||
607 | * the direction is correct | ||
608 | */ | ||
609 | spin_lock_irqsave(&gpio_lock, flags); | ||
610 | dir_shadow = readl(dir_oe[priv->minor]); | ||
611 | if ((clk_mask & changeable_bits[priv->minor]) && | ||
612 | (data_mask & changeable_bits[priv->minor]) && | ||
613 | (clk_mask & dir_shadow) && | ||
614 | (data_mask & dir_shadow)) { | ||
615 | priv->clk_mask = clk_mask; | ||
616 | priv->data_mask = data_mask; | ||
617 | priv->write_msb = write_msb; | ||
618 | res = 0; | ||
619 | } | ||
620 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
621 | |||
622 | return res; | ||
623 | } | ||
624 | case IO_READ_INBITS: | ||
625 | /* *arg is result of reading the input pins */ | ||
626 | val = readl(data_in[priv->minor]); | ||
627 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
628 | return -EFAULT; | ||
629 | return 0; | ||
630 | case IO_READ_OUTBITS: | ||
631 | /* *arg is result of reading the output shadow */ | ||
632 | val = *data_out[priv->minor]; | ||
633 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
634 | return -EFAULT; | ||
635 | break; | ||
636 | case IO_SETGET_INPUT: | ||
637 | /* bits set in *arg is set to input, | ||
638 | * *arg updated with current input pins. | ||
639 | */ | ||
640 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) | ||
641 | return -EFAULT; | ||
642 | val = setget_input(priv, val); | ||
643 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
644 | return -EFAULT; | ||
645 | break; | ||
646 | case IO_SETGET_OUTPUT: | ||
647 | /* bits set in *arg is set to output, | ||
648 | * *arg updated with current output pins. | ||
649 | */ | ||
650 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) | ||
651 | return -EFAULT; | ||
652 | val = setget_output(priv, val); | ||
653 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
654 | return -EFAULT; | ||
655 | break; | ||
656 | default: | ||
657 | return -EINVAL; | ||
658 | } /* switch */ | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
664 | static int virtual_gpio_ioctl(struct file *file, unsigned int cmd, | ||
665 | unsigned long arg) | ||
666 | { | ||
667 | unsigned long flags; | ||
668 | unsigned short val; | ||
669 | unsigned short shadow; | ||
670 | struct gpio_private *priv = file->private_data; | ||
671 | |||
672 | switch (_IOC_NR(cmd)) { | ||
673 | case IO_SETBITS: | ||
674 | spin_lock_irqsave(&gpio_lock, flags); | ||
675 | /* Set changeable bits with a 1 in arg. */ | ||
676 | i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
677 | shadow |= ~readl(dir_oe[priv->minor]) | | ||
678 | (arg & changeable_bits[priv->minor]); | ||
679 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
680 | spin_lock_irqrestore(&gpio_lock, flags); | ||
681 | break; | ||
682 | case IO_CLRBITS: | ||
683 | spin_lock_irqsave(&gpio_lock, flags); | ||
684 | /* Clear changeable bits with a 1 in arg. */ | ||
685 | i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
686 | shadow |= ~readl(dir_oe[priv->minor]) & | ||
687 | ~(arg & changeable_bits[priv->minor]); | ||
688 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
689 | spin_lock_irqrestore(&gpio_lock, flags); | ||
690 | break; | ||
691 | case IO_HIGHALARM: | ||
692 | /* Set alarm when bits with 1 in arg go high. */ | ||
693 | priv->highalarm |= arg; | ||
694 | break; | ||
695 | case IO_LOWALARM: | ||
696 | /* Set alarm when bits with 1 in arg go low. */ | ||
697 | priv->lowalarm |= arg; | ||
698 | break; | ||
699 | case IO_CLRALARM: | ||
700 | /* Clear alarm for bits with 1 in arg. */ | ||
701 | priv->highalarm &= ~arg; | ||
702 | priv->lowalarm &= ~arg; | ||
703 | break; | ||
704 | case IO_CFG_WRITE_MODE: | ||
705 | { | ||
706 | unsigned long dir_shadow; | ||
707 | dir_shadow = readl(dir_oe[priv->minor]); | ||
708 | |||
709 | priv->clk_mask = arg & 0xFF; | ||
710 | priv->data_mask = (arg >> 8) & 0xFF; | ||
711 | priv->write_msb = (arg >> 16) & 0x01; | ||
712 | /* Check if we're allowed to change the bits and | ||
713 | * the direction is correct | ||
714 | */ | ||
715 | if (!((priv->clk_mask & changeable_bits[priv->minor]) && | ||
716 | (priv->data_mask & changeable_bits[priv->minor]) && | ||
717 | (priv->clk_mask & dir_shadow) && | ||
718 | (priv->data_mask & dir_shadow))) { | ||
719 | priv->clk_mask = 0; | ||
720 | priv->data_mask = 0; | ||
721 | return -EPERM; | ||
722 | } | ||
723 | break; | ||
724 | } | ||
725 | case IO_READ_INBITS: | ||
726 | /* *arg is result of reading the input pins */ | ||
727 | val = cached_virtual_gpio_read & ~readl(dir_oe[priv->minor]); | ||
728 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
729 | return -EFAULT; | ||
730 | return 0; | ||
731 | |||
732 | case IO_READ_OUTBITS: | ||
733 | /* *arg is result of reading the output shadow */ | ||
734 | i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val)); | ||
735 | val &= readl(dir_oe[priv->minor]); | ||
736 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
737 | return -EFAULT; | ||
738 | break; | ||
739 | case IO_SETGET_INPUT: | ||
740 | { | ||
741 | /* bits set in *arg is set to input, | ||
742 | * *arg updated with current input pins. | ||
743 | */ | ||
744 | unsigned short input_mask = ~readl(dir_oe[priv->minor]); | ||
745 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) | ||
746 | return -EFAULT; | ||
747 | val = setget_input(priv, val); | ||
748 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
749 | return -EFAULT; | ||
750 | if ((input_mask & val) != input_mask) { | ||
751 | /* Input pins changed. All ports desired as input | ||
752 | * should be set to logic 1. | ||
753 | */ | ||
754 | unsigned short change = input_mask ^ val; | ||
755 | i2c_read(VIRT_I2C_ADDR, (void *)&shadow, | ||
756 | sizeof(shadow)); | ||
757 | shadow &= ~change; | ||
758 | shadow |= val; | ||
759 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, | ||
760 | sizeof(shadow)); | ||
761 | } | ||
762 | break; | ||
763 | } | ||
764 | case IO_SETGET_OUTPUT: | ||
765 | /* bits set in *arg is set to output, | ||
766 | * *arg updated with current output pins. | ||
767 | */ | ||
768 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) | ||
769 | return -EFAULT; | ||
770 | val = setget_output(priv, val); | ||
771 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) | ||
772 | return -EFAULT; | ||
773 | break; | ||
774 | default: | ||
775 | return -EINVAL; | ||
776 | } /* switch */ | ||
777 | return 0; | ||
778 | } | ||
779 | #endif /* CONFIG_ETRAX_VIRTUAL_GPIO */ | ||
780 | |||
781 | static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | ||
782 | { | ||
783 | unsigned char green; | ||
784 | unsigned char red; | ||
785 | |||
786 | switch (_IOC_NR(cmd)) { | ||
787 | case IO_LEDACTIVE_SET: | ||
788 | green = ((unsigned char) arg) & 1; | ||
789 | red = (((unsigned char) arg) >> 1) & 1; | ||
790 | CRIS_LED_ACTIVE_SET_G(green); | ||
791 | CRIS_LED_ACTIVE_SET_R(red); | ||
792 | break; | ||
793 | |||
794 | default: | ||
795 | return -EINVAL; | ||
796 | } /* switch */ | ||
797 | |||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | static int gpio_pwm_set_mode(unsigned long arg, int pwm_port) | ||
802 | { | ||
803 | int pinmux_pwm = pinmux_pwm0 + pwm_port; | ||
804 | int mode; | ||
805 | reg_gio_rw_pwm0_ctrl rw_pwm_ctrl = { | ||
806 | .ccd_val = 0, | ||
807 | .ccd_override = regk_gio_no, | ||
808 | .mode = regk_gio_no | ||
809 | }; | ||
810 | int allocstatus; | ||
811 | |||
812 | if (get_user(mode, &((struct io_pwm_set_mode *) arg)->mode)) | ||
813 | return -EFAULT; | ||
814 | rw_pwm_ctrl.mode = mode; | ||
815 | if (mode != PWM_OFF) | ||
816 | allocstatus = crisv32_pinmux_alloc_fixed(pinmux_pwm); | ||
817 | else | ||
818 | allocstatus = crisv32_pinmux_dealloc_fixed(pinmux_pwm); | ||
819 | if (allocstatus) | ||
820 | return allocstatus; | ||
821 | REG_WRITE(reg_gio_rw_pwm0_ctrl, REG_ADDR(gio, regi_gio, rw_pwm0_ctrl) + | ||
822 | 12 * pwm_port, rw_pwm_ctrl); | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static int gpio_pwm_set_period(unsigned long arg, int pwm_port) | ||
827 | { | ||
828 | struct io_pwm_set_period periods; | ||
829 | reg_gio_rw_pwm0_var rw_pwm_widths; | ||
830 | |||
831 | if (copy_from_user(&periods, (void __user *)arg, sizeof(periods))) | ||
832 | return -EFAULT; | ||
833 | if (periods.lo > 8191 || periods.hi > 8191) | ||
834 | return -EINVAL; | ||
835 | rw_pwm_widths.lo = periods.lo; | ||
836 | rw_pwm_widths.hi = periods.hi; | ||
837 | REG_WRITE(reg_gio_rw_pwm0_var, REG_ADDR(gio, regi_gio, rw_pwm0_var) + | ||
838 | 12 * pwm_port, rw_pwm_widths); | ||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | static int gpio_pwm_set_duty(unsigned long arg, int pwm_port) | ||
843 | { | ||
844 | unsigned int duty; | ||
845 | reg_gio_rw_pwm0_data rw_pwm_duty; | ||
846 | |||
847 | if (get_user(duty, &((struct io_pwm_set_duty *) arg)->duty)) | ||
848 | return -EFAULT; | ||
849 | if (duty > 255) | ||
850 | return -EINVAL; | ||
851 | rw_pwm_duty.data = duty; | ||
852 | REG_WRITE(reg_gio_rw_pwm0_data, REG_ADDR(gio, regi_gio, rw_pwm0_data) + | ||
853 | 12 * pwm_port, rw_pwm_duty); | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd, | ||
858 | unsigned long arg) | ||
859 | { | ||
860 | int pwm_port = priv->minor - GPIO_MINOR_PWM0; | ||
861 | |||
862 | switch (_IOC_NR(cmd)) { | ||
863 | case IO_PWM_SET_MODE: | ||
864 | return gpio_pwm_set_mode(arg, pwm_port); | ||
865 | case IO_PWM_SET_PERIOD: | ||
866 | return gpio_pwm_set_period(arg, pwm_port); | ||
867 | case IO_PWM_SET_DUTY: | ||
868 | return gpio_pwm_set_duty(arg, pwm_port); | ||
869 | default: | ||
870 | return -EINVAL; | ||
871 | } | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static const struct file_operations gpio_fops = { | ||
876 | .owner = THIS_MODULE, | ||
877 | .poll = gpio_poll, | ||
878 | .ioctl = gpio_ioctl, | ||
879 | .write = gpio_write, | ||
880 | .open = gpio_open, | ||
881 | .release = gpio_release, | ||
882 | }; | ||
883 | |||
884 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
885 | static void __init virtual_gpio_init(void) | ||
886 | { | ||
887 | reg_gio_rw_intr_cfg intr_cfg; | ||
888 | reg_gio_rw_intr_mask intr_mask; | ||
889 | unsigned short shadow; | ||
890 | |||
891 | shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */ | ||
892 | shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT; | ||
893 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
894 | |||
895 | /* Set interrupt mask and on what state the interrupt shall trigger. | ||
896 | * For virtual gpio the interrupt shall trigger on logic '0'. | ||
897 | */ | ||
898 | intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg); | ||
899 | intr_mask = REG_RD(gio, regi_gio, rw_intr_mask); | ||
900 | |||
901 | switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) { | ||
902 | case 0: | ||
903 | intr_cfg.pa0 = regk_gio_lo; | ||
904 | intr_mask.pa0 = regk_gio_yes; | ||
905 | break; | ||
906 | case 1: | ||
907 | intr_cfg.pa1 = regk_gio_lo; | ||
908 | intr_mask.pa1 = regk_gio_yes; | ||
909 | break; | ||
910 | case 2: | ||
911 | intr_cfg.pa2 = regk_gio_lo; | ||
912 | intr_mask.pa2 = regk_gio_yes; | ||
913 | break; | ||
914 | case 3: | ||
915 | intr_cfg.pa3 = regk_gio_lo; | ||
916 | intr_mask.pa3 = regk_gio_yes; | ||
917 | break; | ||
918 | case 4: | ||
919 | intr_cfg.pa4 = regk_gio_lo; | ||
920 | intr_mask.pa4 = regk_gio_yes; | ||
921 | break; | ||
922 | case 5: | ||
923 | intr_cfg.pa5 = regk_gio_lo; | ||
924 | intr_mask.pa5 = regk_gio_yes; | ||
925 | break; | ||
926 | case 6: | ||
927 | intr_cfg.pa6 = regk_gio_lo; | ||
928 | intr_mask.pa6 = regk_gio_yes; | ||
929 | break; | ||
930 | case 7: | ||
931 | intr_cfg.pa7 = regk_gio_lo; | ||
932 | intr_mask.pa7 = regk_gio_yes; | ||
933 | break; | ||
934 | } | ||
935 | |||
936 | REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg); | ||
937 | REG_WR(gio, regi_gio, rw_intr_mask, intr_mask); | ||
938 | } | ||
939 | #endif | ||
940 | |||
941 | /* main driver initialization routine, called from mem.c */ | ||
942 | |||
943 | static int __init gpio_init(void) | ||
944 | { | ||
945 | int res; | ||
946 | |||
947 | printk(KERN_INFO "ETRAX FS GPIO driver v2.7, (c) 2003-2008 " | ||
948 | "Axis Communications AB\n"); | ||
949 | |||
950 | /* do the formalities */ | ||
951 | |||
952 | res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops); | ||
953 | if (res < 0) { | ||
954 | printk(KERN_ERR "gpio: couldn't get a major number.\n"); | ||
955 | return res; | ||
956 | } | ||
957 | |||
958 | /* Clear all leds */ | ||
959 | CRIS_LED_NETWORK_GRP0_SET(0); | ||
960 | CRIS_LED_NETWORK_GRP1_SET(0); | ||
961 | CRIS_LED_ACTIVE_SET(0); | ||
962 | CRIS_LED_DISK_READ(0); | ||
963 | CRIS_LED_DISK_WRITE(0); | ||
964 | |||
965 | int res2 = request_irq(GIO_INTR_VECT, gpio_interrupt, | ||
966 | IRQF_SHARED | IRQF_DISABLED, "gpio", &alarmlist); | ||
967 | if (res2) { | ||
968 | printk(KERN_ERR "err: irq for gpio\n"); | ||
969 | return res2; | ||
970 | } | ||
971 | |||
972 | /* No IRQs by default. */ | ||
973 | REG_WR_INT(gio, regi_gio, rw_intr_pins, 0); | ||
974 | |||
975 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
976 | virtual_gpio_init(); | ||
977 | #endif | ||
978 | |||
979 | return res; | ||
980 | } | ||
981 | |||
982 | /* this makes sure that gpio_init is called during kernel boot */ | ||
983 | |||
984 | module_init(gpio_init); | ||
diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c new file mode 100644 index 000000000000..01ed0be2d0d1 --- /dev/null +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * arch/cris/arch-v32/drivers/nandflash.c | ||
3 | * | ||
4 | * Copyright (c) 2007 | ||
5 | * | ||
6 | * Derived from drivers/mtd/nand/spia.c | ||
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/slab.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mtd/mtd.h> | ||
19 | #include <linux/mtd/nand.h> | ||
20 | #include <linux/mtd/partitions.h> | ||
21 | #include <asm/arch/memmap.h> | ||
22 | #include <hwregs/reg_map.h> | ||
23 | #include <hwregs/reg_rdwr.h> | ||
24 | #include <hwregs/pio_defs.h> | ||
25 | #include <pinmux.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #define MANUAL_ALE_CLE_CONTROL 1 | ||
29 | |||
30 | #define regf_ALE a0 | ||
31 | #define regf_CLE a1 | ||
32 | #define regf_NCE ce0_n | ||
33 | |||
34 | #define CLE_BIT 10 | ||
35 | #define ALE_BIT 11 | ||
36 | #define CE_BIT 12 | ||
37 | |||
38 | struct mtd_info_wrapper { | ||
39 | struct mtd_info info; | ||
40 | struct nand_chip chip; | ||
41 | }; | ||
42 | |||
43 | /* Bitmask for control pins */ | ||
44 | #define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT)) | ||
45 | |||
46 | static struct mtd_info *crisv32_mtd; | ||
47 | /* | ||
48 | * hardware specific access to control-lines | ||
49 | */ | ||
50 | static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, | ||
51 | unsigned int ctrl) | ||
52 | { | ||
53 | unsigned long flags; | ||
54 | reg_pio_rw_dout dout; | ||
55 | struct nand_chip *this = mtd->priv; | ||
56 | |||
57 | local_irq_save(flags); | ||
58 | |||
59 | /* control bits change */ | ||
60 | if (ctrl & NAND_CTRL_CHANGE) { | ||
61 | dout = REG_RD(pio, regi_pio, rw_dout); | ||
62 | dout.regf_NCE = (ctrl & NAND_NCE) ? 0 : 1; | ||
63 | |||
64 | #if !MANUAL_ALE_CLE_CONTROL | ||
65 | if (ctrl & NAND_ALE) { | ||
66 | /* A0 = ALE high */ | ||
67 | this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio, | ||
68 | regi_pio, rw_io_access1); | ||
69 | } else if (ctrl & NAND_CLE) { | ||
70 | /* A1 = CLE high */ | ||
71 | this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio, | ||
72 | regi_pio, rw_io_access2); | ||
73 | } else { | ||
74 | /* A1 = CLE and A0 = ALE low */ | ||
75 | this->IO_ADDR_W = (void __iomem *)REG_ADDR(pio, | ||
76 | regi_pio, rw_io_access0); | ||
77 | } | ||
78 | #else | ||
79 | |||
80 | dout.regf_CLE = (ctrl & NAND_CLE) ? 1 : 0; | ||
81 | dout.regf_ALE = (ctrl & NAND_ALE) ? 1 : 0; | ||
82 | #endif | ||
83 | REG_WR(pio, regi_pio, rw_dout, dout); | ||
84 | } | ||
85 | |||
86 | /* command to chip */ | ||
87 | if (cmd != NAND_CMD_NONE) | ||
88 | writeb(cmd, this->IO_ADDR_W); | ||
89 | |||
90 | local_irq_restore(flags); | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * read device ready pin | ||
95 | */ | ||
96 | static int crisv32_device_ready(struct mtd_info *mtd) | ||
97 | { | ||
98 | reg_pio_r_din din = REG_RD(pio, regi_pio, r_din); | ||
99 | return din.rdy; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Main initialization routine | ||
104 | */ | ||
105 | struct mtd_info *__init crisv32_nand_flash_probe(void) | ||
106 | { | ||
107 | void __iomem *read_cs; | ||
108 | void __iomem *write_cs; | ||
109 | |||
110 | struct mtd_info_wrapper *wrapper; | ||
111 | struct nand_chip *this; | ||
112 | int err = 0; | ||
113 | |||
114 | reg_pio_rw_man_ctrl man_ctrl = { | ||
115 | .regf_NCE = regk_pio_yes, | ||
116 | #if MANUAL_ALE_CLE_CONTROL | ||
117 | .regf_ALE = regk_pio_yes, | ||
118 | .regf_CLE = regk_pio_yes | ||
119 | #endif | ||
120 | }; | ||
121 | reg_pio_rw_oe oe = { | ||
122 | .regf_NCE = regk_pio_yes, | ||
123 | #if MANUAL_ALE_CLE_CONTROL | ||
124 | .regf_ALE = regk_pio_yes, | ||
125 | .regf_CLE = regk_pio_yes | ||
126 | #endif | ||
127 | }; | ||
128 | reg_pio_rw_dout dout = { .regf_NCE = 1 }; | ||
129 | |||
130 | /* Allocate pio pins to pio */ | ||
131 | crisv32_pinmux_alloc_fixed(pinmux_pio); | ||
132 | /* Set up CE, ALE, CLE (ce0_n, a0, a1) for manual control and output */ | ||
133 | REG_WR(pio, regi_pio, rw_man_ctrl, man_ctrl); | ||
134 | REG_WR(pio, regi_pio, rw_dout, dout); | ||
135 | REG_WR(pio, regi_pio, rw_oe, oe); | ||
136 | |||
137 | /* Allocate memory for MTD device structure and private data */ | ||
138 | wrapper = kzalloc(sizeof(struct mtd_info_wrapper), GFP_KERNEL); | ||
139 | if (!wrapper) { | ||
140 | printk(KERN_ERR "Unable to allocate CRISv32 NAND MTD " | ||
141 | "device structure.\n"); | ||
142 | err = -ENOMEM; | ||
143 | return NULL; | ||
144 | } | ||
145 | |||
146 | read_cs = write_cs = (void __iomem *)REG_ADDR(pio, regi_pio, | ||
147 | rw_io_access0); | ||
148 | |||
149 | /* Get pointer to private data */ | ||
150 | this = &wrapper->chip; | ||
151 | crisv32_mtd = &wrapper->info; | ||
152 | |||
153 | /* Link the private data with the MTD structure */ | ||
154 | crisv32_mtd->priv = this; | ||
155 | |||
156 | /* Set address of NAND IO lines */ | ||
157 | this->IO_ADDR_R = read_cs; | ||
158 | this->IO_ADDR_W = write_cs; | ||
159 | this->cmd_ctrl = crisv32_hwcontrol; | ||
160 | this->dev_ready = crisv32_device_ready; | ||
161 | /* 20 us command delay time */ | ||
162 | this->chip_delay = 20; | ||
163 | this->ecc.mode = NAND_ECC_SOFT; | ||
164 | |||
165 | /* Enable the following for a flash based bad block table */ | ||
166 | /* this->options = NAND_USE_FLASH_BBT; */ | ||
167 | |||
168 | /* Scan to find existance of the device */ | ||
169 | if (nand_scan(crisv32_mtd, 1)) { | ||
170 | err = -ENXIO; | ||
171 | goto out_mtd; | ||
172 | } | ||
173 | |||
174 | return crisv32_mtd; | ||
175 | |||
176 | out_mtd: | ||
177 | kfree(wrapper); | ||
178 | return NULL; | ||
179 | } | ||
180 | |||
diff --git a/arch/cris/arch-v32/drivers/mach-fs/Makefile b/arch/cris/arch-v32/drivers/mach-fs/Makefile new file mode 100644 index 000000000000..5c6d2a2a080e --- /dev/null +++ b/arch/cris/arch-v32/drivers/mach-fs/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for Etrax-specific drivers | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_ETRAX_NANDFLASH) += nandflash.o | ||
6 | obj-$(CONFIG_ETRAX_GPIO) += gpio.o | ||
diff --git a/arch/cris/arch-v32/drivers/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c index d82c5c561135..7863fd4efc2b 100644 --- a/arch/cris/arch-v32/drivers/gpio.c +++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c | |||
@@ -1,68 +1,15 @@ | |||
1 | /* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * ETRAX CRISv32 general port I/O device | 2 | * ETRAX CRISv32 general port I/O device |
4 | * | 3 | * |
5 | * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB | 4 | * Copyright (c) 1999-2006 Axis Communications AB |
6 | * | 5 | * |
7 | * Authors: Bjorn Wesen (initial version) | 6 | * Authors: Bjorn Wesen (initial version) |
8 | * Ola Knutsson (LED handling) | 7 | * Ola Knutsson (LED handling) |
9 | * Johan Adolfsson (read/set directions, write, port G, | 8 | * Johan Adolfsson (read/set directions, write, port G, |
10 | * port to ETRAX FS. | 9 | * port to ETRAX FS. |
11 | * | 10 | * |
12 | * $Log: gpio.c,v $ | ||
13 | * Revision 1.16 2005/06/19 17:06:49 starvik | ||
14 | * Merge of Linux 2.6.12. | ||
15 | * | ||
16 | * Revision 1.15 2005/05/25 08:22:20 starvik | ||
17 | * Changed GPIO port order to fit packages/devices/axis-2.4. | ||
18 | * | ||
19 | * Revision 1.14 2005/04/24 18:35:08 starvik | ||
20 | * Updated with final register headers. | ||
21 | * | ||
22 | * Revision 1.13 2005/03/15 15:43:00 starvik | ||
23 | * dev_id needs to be supplied for shared IRQs. | ||
24 | * | ||
25 | * Revision 1.12 2005/03/10 17:12:00 starvik | ||
26 | * Protect alarm list with spinlock. | ||
27 | * | ||
28 | * Revision 1.11 2005/01/05 06:08:59 starvik | ||
29 | * No need to do local_irq_disable after local_irq_save. | ||
30 | * | ||
31 | * Revision 1.10 2004/11/19 08:38:31 starvik | ||
32 | * Removed old crap. | ||
33 | * | ||
34 | * Revision 1.9 2004/05/14 07:58:02 starvik | ||
35 | * Merge of changes from 2.4 | ||
36 | * | ||
37 | * Revision 1.8 2003/09/11 07:29:50 starvik | ||
38 | * Merge of Linux 2.6.0-test5 | ||
39 | * | ||
40 | * Revision 1.7 2003/07/10 13:25:46 starvik | ||
41 | * Compiles for 2.5.74 | ||
42 | * Lindented ethernet.c | ||
43 | * | ||
44 | * Revision 1.6 2003/07/04 08:27:46 starvik | ||
45 | * Merge of Linux 2.5.74 | ||
46 | * | ||
47 | * Revision 1.5 2003/06/10 08:26:37 johana | ||
48 | * Etrax -> ETRAX CRISv32 | ||
49 | * | ||
50 | * Revision 1.4 2003/06/05 14:22:48 johana | ||
51 | * Initialise some_alarms. | ||
52 | * | ||
53 | * Revision 1.3 2003/06/05 10:15:46 johana | ||
54 | * New INTR_VECT macros. | ||
55 | * Enable interrupts in global config. | ||
56 | * | ||
57 | * Revision 1.2 2003/06/03 15:52:50 johana | ||
58 | * Initial CRIS v32 version. | ||
59 | * | ||
60 | * Revision 1.1 2003/06/03 08:53:15 johana | ||
61 | * Copy of os/lx25/arch/cris/arch-v10/drivers/gpio.c version 1.7. | ||
62 | * | ||
63 | */ | 11 | */ |
64 | 12 | ||
65 | |||
66 | #include <linux/module.h> | 13 | #include <linux/module.h> |
67 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
68 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
@@ -77,14 +24,20 @@ | |||
77 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
78 | 25 | ||
79 | #include <asm/etraxgpio.h> | 26 | #include <asm/etraxgpio.h> |
80 | #include <asm/arch/hwregs/reg_map.h> | 27 | #include <hwregs/reg_map.h> |
81 | #include <asm/arch/hwregs/reg_rdwr.h> | 28 | #include <hwregs/reg_rdwr.h> |
82 | #include <asm/arch/hwregs/gio_defs.h> | 29 | #include <hwregs/gio_defs.h> |
83 | #include <asm/arch/hwregs/intr_vect_defs.h> | 30 | #include <hwregs/intr_vect_defs.h> |
84 | #include <asm/io.h> | 31 | #include <asm/io.h> |
85 | #include <asm/system.h> | 32 | #include <asm/system.h> |
86 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
87 | 34 | ||
35 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
36 | #include "../i2c.h" | ||
37 | |||
38 | #define VIRT_I2C_ADDR 0x40 | ||
39 | #endif | ||
40 | |||
88 | /* The following gio ports on ETRAX FS is available: | 41 | /* The following gio ports on ETRAX FS is available: |
89 | * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge | 42 | * pa 8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge |
90 | * pb 18 bits | 43 | * pb 18 bits |
@@ -100,7 +53,12 @@ | |||
100 | 53 | ||
101 | #if 0 | 54 | #if 0 |
102 | static int dp_cnt; | 55 | static int dp_cnt; |
103 | #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0) | 56 | #define DP(x) \ |
57 | do { \ | ||
58 | dp_cnt++; \ | ||
59 | if (dp_cnt % 1000 == 0) \ | ||
60 | x; \ | ||
61 | } while (0) | ||
104 | #else | 62 | #else |
105 | #define DP(x) | 63 | #define DP(x) |
106 | #endif | 64 | #endif |
@@ -111,13 +69,18 @@ static char gpio_name[] = "etrax gpio"; | |||
111 | static wait_queue_head_t *gpio_wq; | 69 | static wait_queue_head_t *gpio_wq; |
112 | #endif | 70 | #endif |
113 | 71 | ||
72 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
73 | static int virtual_gpio_ioctl(struct file *file, unsigned int cmd, | ||
74 | unsigned long arg); | ||
75 | #endif | ||
114 | static int gpio_ioctl(struct inode *inode, struct file *file, | 76 | static int gpio_ioctl(struct inode *inode, struct file *file, |
115 | unsigned int cmd, unsigned long arg); | 77 | unsigned int cmd, unsigned long arg); |
116 | static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | 78 | static ssize_t gpio_write(struct file *file, const char *buf, size_t count, |
117 | loff_t *off); | 79 | loff_t *off); |
118 | static int gpio_open(struct inode *inode, struct file *filp); | 80 | static int gpio_open(struct inode *inode, struct file *filp); |
119 | static int gpio_release(struct inode *inode, struct file *filp); | 81 | static int gpio_release(struct inode *inode, struct file *filp); |
120 | static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait); | 82 | static unsigned int gpio_poll(struct file *filp, |
83 | struct poll_table_struct *wait); | ||
121 | 84 | ||
122 | /* private data per open() of this driver */ | 85 | /* private data per open() of this driver */ |
123 | 86 | ||
@@ -136,18 +99,25 @@ struct gpio_private { | |||
136 | 99 | ||
137 | /* linked list of alarms to check for */ | 100 | /* linked list of alarms to check for */ |
138 | 101 | ||
139 | static struct gpio_private *alarmlist = 0; | 102 | static struct gpio_private *alarmlist; |
140 | 103 | ||
141 | static int gpio_some_alarms = 0; /* Set if someone uses alarm */ | 104 | static int gpio_some_alarms; /* Set if someone uses alarm */ |
142 | static unsigned long gpio_pa_high_alarms = 0; | 105 | static unsigned long gpio_pa_high_alarms; |
143 | static unsigned long gpio_pa_low_alarms = 0; | 106 | static unsigned long gpio_pa_low_alarms; |
144 | 107 | ||
145 | static DEFINE_SPINLOCK(alarm_lock); | 108 | static DEFINE_SPINLOCK(alarm_lock); |
146 | 109 | ||
147 | #define NUM_PORTS (GPIO_MINOR_LAST+1) | 110 | #define NUM_PORTS (GPIO_MINOR_LAST+1) |
148 | #define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg ) | 111 | #define GIO_REG_RD_ADDR(reg) \ |
149 | #define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg ) | 112 | (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg) |
113 | #define GIO_REG_WR_ADDR(reg) \ | ||
114 | (volatile unsigned long *)(regi_gio + REG_RD_ADDR_gio_##reg) | ||
150 | unsigned long led_dummy; | 115 | unsigned long led_dummy; |
116 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
117 | static unsigned long virtual_dummy; | ||
118 | static unsigned long virtual_rw_pv_oe = CONFIG_ETRAX_DEF_GIO_PV_OE; | ||
119 | static unsigned short cached_virtual_gpio_read; | ||
120 | #endif | ||
151 | 121 | ||
152 | static volatile unsigned long *data_out[NUM_PORTS] = { | 122 | static volatile unsigned long *data_out[NUM_PORTS] = { |
153 | GIO_REG_WR_ADDR(rw_pa_dout), | 123 | GIO_REG_WR_ADDR(rw_pa_dout), |
@@ -156,6 +126,9 @@ static volatile unsigned long *data_out[NUM_PORTS] = { | |||
156 | GIO_REG_WR_ADDR(rw_pc_dout), | 126 | GIO_REG_WR_ADDR(rw_pc_dout), |
157 | GIO_REG_WR_ADDR(rw_pd_dout), | 127 | GIO_REG_WR_ADDR(rw_pd_dout), |
158 | GIO_REG_WR_ADDR(rw_pe_dout), | 128 | GIO_REG_WR_ADDR(rw_pe_dout), |
129 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
130 | &virtual_dummy, | ||
131 | #endif | ||
159 | }; | 132 | }; |
160 | 133 | ||
161 | static volatile unsigned long *data_in[NUM_PORTS] = { | 134 | static volatile unsigned long *data_in[NUM_PORTS] = { |
@@ -165,6 +138,9 @@ static volatile unsigned long *data_in[NUM_PORTS] = { | |||
165 | GIO_REG_RD_ADDR(r_pc_din), | 138 | GIO_REG_RD_ADDR(r_pc_din), |
166 | GIO_REG_RD_ADDR(r_pd_din), | 139 | GIO_REG_RD_ADDR(r_pd_din), |
167 | GIO_REG_RD_ADDR(r_pe_din), | 140 | GIO_REG_RD_ADDR(r_pe_din), |
141 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
142 | &virtual_dummy, | ||
143 | #endif | ||
168 | }; | 144 | }; |
169 | 145 | ||
170 | static unsigned long changeable_dir[NUM_PORTS] = { | 146 | static unsigned long changeable_dir[NUM_PORTS] = { |
@@ -174,6 +150,9 @@ static unsigned long changeable_dir[NUM_PORTS] = { | |||
174 | CONFIG_ETRAX_PC_CHANGEABLE_DIR, | 150 | CONFIG_ETRAX_PC_CHANGEABLE_DIR, |
175 | CONFIG_ETRAX_PD_CHANGEABLE_DIR, | 151 | CONFIG_ETRAX_PD_CHANGEABLE_DIR, |
176 | CONFIG_ETRAX_PE_CHANGEABLE_DIR, | 152 | CONFIG_ETRAX_PE_CHANGEABLE_DIR, |
153 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
154 | CONFIG_ETRAX_PV_CHANGEABLE_DIR, | ||
155 | #endif | ||
177 | }; | 156 | }; |
178 | 157 | ||
179 | static unsigned long changeable_bits[NUM_PORTS] = { | 158 | static unsigned long changeable_bits[NUM_PORTS] = { |
@@ -183,6 +162,9 @@ static unsigned long changeable_bits[NUM_PORTS] = { | |||
183 | CONFIG_ETRAX_PC_CHANGEABLE_BITS, | 162 | CONFIG_ETRAX_PC_CHANGEABLE_BITS, |
184 | CONFIG_ETRAX_PD_CHANGEABLE_BITS, | 163 | CONFIG_ETRAX_PD_CHANGEABLE_BITS, |
185 | CONFIG_ETRAX_PE_CHANGEABLE_BITS, | 164 | CONFIG_ETRAX_PE_CHANGEABLE_BITS, |
165 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
166 | CONFIG_ETRAX_PV_CHANGEABLE_BITS, | ||
167 | #endif | ||
186 | }; | 168 | }; |
187 | 169 | ||
188 | static volatile unsigned long *dir_oe[NUM_PORTS] = { | 170 | static volatile unsigned long *dir_oe[NUM_PORTS] = { |
@@ -192,13 +174,14 @@ static volatile unsigned long *dir_oe[NUM_PORTS] = { | |||
192 | GIO_REG_WR_ADDR(rw_pc_oe), | 174 | GIO_REG_WR_ADDR(rw_pc_oe), |
193 | GIO_REG_WR_ADDR(rw_pd_oe), | 175 | GIO_REG_WR_ADDR(rw_pd_oe), |
194 | GIO_REG_WR_ADDR(rw_pe_oe), | 176 | GIO_REG_WR_ADDR(rw_pe_oe), |
177 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
178 | &virtual_rw_pv_oe, | ||
179 | #endif | ||
195 | }; | 180 | }; |
196 | 181 | ||
197 | 182 | ||
198 | 183 | ||
199 | static unsigned int | 184 | static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait) |
200 | gpio_poll(struct file *file, | ||
201 | poll_table *wait) | ||
202 | { | 185 | { |
203 | unsigned int mask = 0; | 186 | unsigned int mask = 0; |
204 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 187 | struct gpio_private *priv = (struct gpio_private *)file->private_data; |
@@ -210,65 +193,50 @@ gpio_poll(struct file *file, | |||
210 | unsigned long flags; | 193 | unsigned long flags; |
211 | 194 | ||
212 | local_irq_save(flags); | 195 | local_irq_save(flags); |
213 | data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din, REG_RD(gio, regi_gio, r_pa_din)); | 196 | data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din, |
197 | REG_RD(gio, regi_gio, r_pa_din)); | ||
214 | /* PA has support for interrupt | 198 | /* PA has support for interrupt |
215 | * lets activate high for those low and with highalarm set | 199 | * lets activate high for those low and with highalarm set |
216 | */ | 200 | */ |
217 | intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg); | 201 | intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg); |
218 | 202 | ||
219 | tmp = ~data & priv->highalarm & 0xFF; | 203 | tmp = ~data & priv->highalarm & 0xFF; |
220 | if (tmp & (1 << 0)) { | 204 | if (tmp & (1 << 0)) |
221 | intr_cfg.pa0 = regk_gio_hi; | 205 | intr_cfg.pa0 = regk_gio_hi; |
222 | } | 206 | if (tmp & (1 << 1)) |
223 | if (tmp & (1 << 1)) { | ||
224 | intr_cfg.pa1 = regk_gio_hi; | 207 | intr_cfg.pa1 = regk_gio_hi; |
225 | } | 208 | if (tmp & (1 << 2)) |
226 | if (tmp & (1 << 2)) { | ||
227 | intr_cfg.pa2 = regk_gio_hi; | 209 | intr_cfg.pa2 = regk_gio_hi; |
228 | } | 210 | if (tmp & (1 << 3)) |
229 | if (tmp & (1 << 3)) { | ||
230 | intr_cfg.pa3 = regk_gio_hi; | 211 | intr_cfg.pa3 = regk_gio_hi; |
231 | } | 212 | if (tmp & (1 << 4)) |
232 | if (tmp & (1 << 4)) { | ||
233 | intr_cfg.pa4 = regk_gio_hi; | 213 | intr_cfg.pa4 = regk_gio_hi; |
234 | } | 214 | if (tmp & (1 << 5)) |
235 | if (tmp & (1 << 5)) { | ||
236 | intr_cfg.pa5 = regk_gio_hi; | 215 | intr_cfg.pa5 = regk_gio_hi; |
237 | } | 216 | if (tmp & (1 << 6)) |
238 | if (tmp & (1 << 6)) { | ||
239 | intr_cfg.pa6 = regk_gio_hi; | 217 | intr_cfg.pa6 = regk_gio_hi; |
240 | } | 218 | if (tmp & (1 << 7)) |
241 | if (tmp & (1 << 7)) { | ||
242 | intr_cfg.pa7 = regk_gio_hi; | 219 | intr_cfg.pa7 = regk_gio_hi; |
243 | } | ||
244 | /* | 220 | /* |
245 | * lets activate low for those high and with lowalarm set | 221 | * lets activate low for those high and with lowalarm set |
246 | */ | 222 | */ |
247 | tmp = data & priv->lowalarm & 0xFF; | 223 | tmp = data & priv->lowalarm & 0xFF; |
248 | if (tmp & (1 << 0)) { | 224 | if (tmp & (1 << 0)) |
249 | intr_cfg.pa0 = regk_gio_lo; | 225 | intr_cfg.pa0 = regk_gio_lo; |
250 | } | 226 | if (tmp & (1 << 1)) |
251 | if (tmp & (1 << 1)) { | ||
252 | intr_cfg.pa1 = regk_gio_lo; | 227 | intr_cfg.pa1 = regk_gio_lo; |
253 | } | 228 | if (tmp & (1 << 2)) |
254 | if (tmp & (1 << 2)) { | ||
255 | intr_cfg.pa2 = regk_gio_lo; | 229 | intr_cfg.pa2 = regk_gio_lo; |
256 | } | 230 | if (tmp & (1 << 3)) |
257 | if (tmp & (1 << 3)) { | ||
258 | intr_cfg.pa3 = regk_gio_lo; | 231 | intr_cfg.pa3 = regk_gio_lo; |
259 | } | 232 | if (tmp & (1 << 4)) |
260 | if (tmp & (1 << 4)) { | ||
261 | intr_cfg.pa4 = regk_gio_lo; | 233 | intr_cfg.pa4 = regk_gio_lo; |
262 | } | 234 | if (tmp & (1 << 5)) |
263 | if (tmp & (1 << 5)) { | ||
264 | intr_cfg.pa5 = regk_gio_lo; | 235 | intr_cfg.pa5 = regk_gio_lo; |
265 | } | 236 | if (tmp & (1 << 6)) |
266 | if (tmp & (1 << 6)) { | ||
267 | intr_cfg.pa6 = regk_gio_lo; | 237 | intr_cfg.pa6 = regk_gio_lo; |
268 | } | 238 | if (tmp & (1 << 7)) |
269 | if (tmp & (1 << 7)) { | ||
270 | intr_cfg.pa7 = regk_gio_lo; | 239 | intr_cfg.pa7 = regk_gio_lo; |
271 | } | ||
272 | 240 | ||
273 | REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg); | 241 | REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg); |
274 | local_irq_restore(flags); | 242 | local_irq_restore(flags); |
@@ -277,50 +245,65 @@ gpio_poll(struct file *file, | |||
277 | else | 245 | else |
278 | return 0; | 246 | return 0; |
279 | 247 | ||
280 | if ((data & priv->highalarm) || | 248 | if ((data & priv->highalarm) || (~data & priv->lowalarm)) |
281 | (~data & priv->lowalarm)) { | ||
282 | mask = POLLIN|POLLRDNORM; | 249 | mask = POLLIN|POLLRDNORM; |
283 | } | ||
284 | 250 | ||
285 | DP(printk("gpio_poll ready: mask 0x%08X\n", mask)); | 251 | DP(printk(KERN_DEBUG "gpio_poll ready: mask 0x%08X\n", mask)); |
286 | return mask; | 252 | return mask; |
287 | } | 253 | } |
288 | 254 | ||
289 | int etrax_gpio_wake_up_check(void) | 255 | int etrax_gpio_wake_up_check(void) |
290 | { | 256 | { |
291 | struct gpio_private *priv = alarmlist; | 257 | struct gpio_private *priv; |
292 | unsigned long data = 0; | 258 | unsigned long data = 0; |
293 | int ret = 0; | 259 | unsigned long flags; |
260 | int ret = 0; | ||
261 | spin_lock_irqsave(&alarm_lock, flags); | ||
262 | priv = alarmlist; | ||
294 | while (priv) { | 263 | while (priv) { |
264 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
265 | if (priv->minor == GPIO_MINOR_V) | ||
266 | data = (unsigned long)cached_virtual_gpio_read; | ||
267 | else { | ||
268 | data = *data_in[priv->minor]; | ||
269 | if (priv->minor == GPIO_MINOR_A) | ||
270 | priv->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
271 | } | ||
272 | #else | ||
295 | data = *data_in[priv->minor]; | 273 | data = *data_in[priv->minor]; |
274 | #endif | ||
296 | if ((data & priv->highalarm) || | 275 | if ((data & priv->highalarm) || |
297 | (~data & priv->lowalarm)) { | 276 | (~data & priv->lowalarm)) { |
298 | DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor)); | 277 | DP(printk(KERN_DEBUG |
278 | "etrax_gpio_wake_up_check %i\n", priv->minor)); | ||
299 | wake_up_interruptible(&priv->alarm_wq); | 279 | wake_up_interruptible(&priv->alarm_wq); |
300 | ret = 1; | 280 | ret = 1; |
301 | } | 281 | } |
302 | priv = priv->next; | 282 | priv = priv->next; |
303 | } | 283 | } |
304 | return ret; | 284 | spin_unlock_irqrestore(&alarm_lock, flags); |
285 | return ret; | ||
305 | } | 286 | } |
306 | 287 | ||
307 | static irqreturn_t | 288 | static irqreturn_t |
308 | gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 289 | gpio_poll_timer_interrupt(int irq, void *dev_id) |
309 | { | 290 | { |
310 | if (gpio_some_alarms) { | 291 | if (gpio_some_alarms) |
311 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); | 292 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); |
312 | } | 293 | return IRQ_NONE; |
313 | return IRQ_NONE; | ||
314 | } | 294 | } |
315 | 295 | ||
316 | static irqreturn_t | 296 | static irqreturn_t |
317 | gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 297 | gpio_pa_interrupt(int irq, void *dev_id) |
318 | { | 298 | { |
319 | reg_gio_rw_intr_mask intr_mask; | 299 | reg_gio_rw_intr_mask intr_mask; |
320 | reg_gio_r_masked_intr masked_intr; | 300 | reg_gio_r_masked_intr masked_intr; |
321 | reg_gio_rw_ack_intr ack_intr; | 301 | reg_gio_rw_ack_intr ack_intr; |
322 | unsigned long tmp; | 302 | unsigned long tmp; |
323 | unsigned long tmp2; | 303 | unsigned long tmp2; |
304 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
305 | unsigned char enable_gpiov_ack = 0; | ||
306 | #endif | ||
324 | 307 | ||
325 | /* Find what PA interrupts are active */ | 308 | /* Find what PA interrupts are active */ |
326 | masked_intr = REG_RD(gio, regi_gio, r_masked_intr); | 309 | masked_intr = REG_RD(gio, regi_gio, r_masked_intr); |
@@ -331,6 +314,17 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
331 | tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms); | 314 | tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms); |
332 | spin_unlock(&alarm_lock); | 315 | spin_unlock(&alarm_lock); |
333 | 316 | ||
317 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
318 | /* Something changed on virtual GPIO. Interrupt is acked by | ||
319 | * reading the device. | ||
320 | */ | ||
321 | if (tmp & (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN)) { | ||
322 | i2c_read(VIRT_I2C_ADDR, (void *)&cached_virtual_gpio_read, | ||
323 | sizeof(cached_virtual_gpio_read)); | ||
324 | enable_gpiov_ack = 1; | ||
325 | } | ||
326 | #endif | ||
327 | |||
334 | /* Ack them */ | 328 | /* Ack them */ |
335 | ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp); | 329 | ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp); |
336 | REG_WR(gio, regi_gio, rw_ack_intr, ack_intr); | 330 | REG_WR(gio, regi_gio, rw_ack_intr, ack_intr); |
@@ -339,18 +333,24 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
339 | intr_mask = REG_RD(gio, regi_gio, rw_intr_mask); | 333 | intr_mask = REG_RD(gio, regi_gio, rw_intr_mask); |
340 | tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask); | 334 | tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask); |
341 | tmp2 &= ~tmp; | 335 | tmp2 &= ~tmp; |
336 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
337 | /* Do not disable interrupt on virtual GPIO. Changes on virtual | ||
338 | * pins are only noticed by an interrupt. | ||
339 | */ | ||
340 | if (enable_gpiov_ack) | ||
341 | tmp2 |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
342 | #endif | ||
342 | intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2); | 343 | intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2); |
343 | REG_WR(gio, regi_gio, rw_intr_mask, intr_mask); | 344 | REG_WR(gio, regi_gio, rw_intr_mask, intr_mask); |
344 | 345 | ||
345 | if (gpio_some_alarms) { | 346 | if (gpio_some_alarms) |
346 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); | 347 | return IRQ_RETVAL(etrax_gpio_wake_up_check()); |
347 | } | 348 | return IRQ_NONE; |
348 | return IRQ_NONE; | ||
349 | } | 349 | } |
350 | 350 | ||
351 | 351 | ||
352 | static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | 352 | static ssize_t gpio_write(struct file *file, const char *buf, size_t count, |
353 | loff_t *off) | 353 | loff_t *off) |
354 | { | 354 | { |
355 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 355 | struct gpio_private *priv = (struct gpio_private *)file->private_data; |
356 | unsigned char data, clk_mask, data_mask, write_msb; | 356 | unsigned char data, clk_mask, data_mask, write_msb; |
@@ -360,29 +360,31 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
360 | ssize_t retval = count; | 360 | ssize_t retval = count; |
361 | /* Only bits 0-7 may be used for write operations but allow all | 361 | /* Only bits 0-7 may be used for write operations but allow all |
362 | devices except leds... */ | 362 | devices except leds... */ |
363 | if (priv->minor == GPIO_MINOR_LEDS) { | 363 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO |
364 | if (priv->minor == GPIO_MINOR_V) | ||
365 | return -EFAULT; | ||
366 | #endif | ||
367 | if (priv->minor == GPIO_MINOR_LEDS) | ||
364 | return -EFAULT; | 368 | return -EFAULT; |
365 | } | ||
366 | 369 | ||
367 | if (!access_ok(VERIFY_READ, buf, count)) { | 370 | if (!access_ok(VERIFY_READ, buf, count)) |
368 | return -EFAULT; | 371 | return -EFAULT; |
369 | } | ||
370 | clk_mask = priv->clk_mask; | 372 | clk_mask = priv->clk_mask; |
371 | data_mask = priv->data_mask; | 373 | data_mask = priv->data_mask; |
372 | /* It must have been configured using the IO_CFG_WRITE_MODE */ | 374 | /* It must have been configured using the IO_CFG_WRITE_MODE */ |
373 | /* Perhaps a better error code? */ | 375 | /* Perhaps a better error code? */ |
374 | if (clk_mask == 0 || data_mask == 0) { | 376 | if (clk_mask == 0 || data_mask == 0) |
375 | return -EPERM; | 377 | return -EPERM; |
376 | } | ||
377 | write_msb = priv->write_msb; | 378 | write_msb = priv->write_msb; |
378 | D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); | 379 | D(printk(KERN_DEBUG "gpio_write: %lu to data 0x%02X clk 0x%02X " |
380 | "msb: %i\n", count, data_mask, clk_mask, write_msb)); | ||
379 | port = data_out[priv->minor]; | 381 | port = data_out[priv->minor]; |
380 | 382 | ||
381 | while (count--) { | 383 | while (count--) { |
382 | int i; | 384 | int i; |
383 | data = *buf++; | 385 | data = *buf++; |
384 | if (priv->write_msb) { | 386 | if (priv->write_msb) { |
385 | for (i = 7; i >= 0;i--) { | 387 | for (i = 7; i >= 0; i--) { |
386 | local_irq_save(flags); | 388 | local_irq_save(flags); |
387 | shadow = *port; | 389 | shadow = *port; |
388 | *port = shadow &= ~clk_mask; | 390 | *port = shadow &= ~clk_mask; |
@@ -395,7 +397,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
395 | local_irq_restore(flags); | 397 | local_irq_restore(flags); |
396 | } | 398 | } |
397 | } else { | 399 | } else { |
398 | for (i = 0; i <= 7;i++) { | 400 | for (i = 0; i <= 7; i++) { |
399 | local_irq_save(flags); | 401 | local_irq_save(flags); |
400 | shadow = *port; | 402 | shadow = *port; |
401 | *port = shadow &= ~clk_mask; | 403 | *port = shadow &= ~clk_mask; |
@@ -423,18 +425,16 @@ gpio_open(struct inode *inode, struct file *filp) | |||
423 | if (p > GPIO_MINOR_LAST) | 425 | if (p > GPIO_MINOR_LAST) |
424 | return -EINVAL; | 426 | return -EINVAL; |
425 | 427 | ||
426 | priv = kmalloc(sizeof(struct gpio_private), | 428 | priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL); |
427 | GFP_KERNEL); | ||
428 | 429 | ||
429 | if (!priv) | 430 | if (!priv) |
430 | return -ENOMEM; | 431 | return -ENOMEM; |
432 | memset(priv, 0, sizeof(*priv)); | ||
431 | 433 | ||
432 | priv->minor = p; | 434 | priv->minor = p; |
433 | 435 | ||
434 | /* initialize the io/alarm struct and link it into our alarmlist */ | 436 | /* initialize the io/alarm struct */ |
435 | 437 | ||
436 | priv->next = alarmlist; | ||
437 | alarmlist = priv; | ||
438 | priv->clk_mask = 0; | 438 | priv->clk_mask = 0; |
439 | priv->data_mask = 0; | 439 | priv->data_mask = 0; |
440 | priv->highalarm = 0; | 440 | priv->highalarm = 0; |
@@ -443,20 +443,30 @@ gpio_open(struct inode *inode, struct file *filp) | |||
443 | 443 | ||
444 | filp->private_data = (void *)priv; | 444 | filp->private_data = (void *)priv; |
445 | 445 | ||
446 | /* link it into our alarmlist */ | ||
447 | spin_lock_irq(&alarm_lock); | ||
448 | priv->next = alarmlist; | ||
449 | alarmlist = priv; | ||
450 | spin_unlock_irq(&alarm_lock); | ||
451 | |||
446 | return 0; | 452 | return 0; |
447 | } | 453 | } |
448 | 454 | ||
449 | static int | 455 | static int |
450 | gpio_release(struct inode *inode, struct file *filp) | 456 | gpio_release(struct inode *inode, struct file *filp) |
451 | { | 457 | { |
452 | struct gpio_private *p = alarmlist; | 458 | struct gpio_private *p; |
453 | struct gpio_private *todel = (struct gpio_private *)filp->private_data; | 459 | struct gpio_private *todel; |
454 | /* local copies while updating them: */ | 460 | /* local copies while updating them: */ |
455 | unsigned long a_high, a_low; | 461 | unsigned long a_high, a_low; |
456 | unsigned long some_alarms; | 462 | unsigned long some_alarms; |
457 | 463 | ||
458 | /* unlink from alarmlist and free the private structure */ | 464 | /* unlink from alarmlist and free the private structure */ |
459 | 465 | ||
466 | spin_lock_irq(&alarm_lock); | ||
467 | p = alarmlist; | ||
468 | todel = (struct gpio_private *)filp->private_data; | ||
469 | |||
460 | if (p == todel) { | 470 | if (p == todel) { |
461 | alarmlist = todel->next; | 471 | alarmlist = todel->next; |
462 | } else { | 472 | } else { |
@@ -468,26 +478,35 @@ gpio_release(struct inode *inode, struct file *filp) | |||
468 | kfree(todel); | 478 | kfree(todel); |
469 | /* Check if there are still any alarms set */ | 479 | /* Check if there are still any alarms set */ |
470 | p = alarmlist; | 480 | p = alarmlist; |
471 | some_alarms = 0; | 481 | some_alarms = 0; |
472 | a_high = 0; | 482 | a_high = 0; |
473 | a_low = 0; | 483 | a_low = 0; |
474 | while (p) { | 484 | while (p) { |
475 | if (p->minor == GPIO_MINOR_A) { | 485 | if (p->minor == GPIO_MINOR_A) { |
486 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
487 | p->lowalarm |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
488 | #endif | ||
476 | a_high |= p->highalarm; | 489 | a_high |= p->highalarm; |
477 | a_low |= p->lowalarm; | 490 | a_low |= p->lowalarm; |
478 | } | 491 | } |
479 | 492 | ||
480 | if (p->highalarm | p->lowalarm) { | 493 | if (p->highalarm | p->lowalarm) |
481 | some_alarms = 1; | 494 | some_alarms = 1; |
482 | } | ||
483 | p = p->next; | 495 | p = p->next; |
484 | } | 496 | } |
485 | 497 | ||
486 | spin_lock(&alarm_lock); | 498 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO |
499 | /* Variables 'some_alarms' and 'a_low' needs to be set here again | ||
500 | * to ensure that interrupt for virtual GPIO is handled. | ||
501 | */ | ||
502 | some_alarms = 1; | ||
503 | a_low |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
504 | #endif | ||
505 | |||
487 | gpio_some_alarms = some_alarms; | 506 | gpio_some_alarms = some_alarms; |
488 | gpio_pa_high_alarms = a_high; | 507 | gpio_pa_high_alarms = a_high; |
489 | gpio_pa_low_alarms = a_low; | 508 | gpio_pa_low_alarms = a_low; |
490 | spin_unlock(&alarm_lock); | 509 | spin_unlock_irq(&alarm_lock); |
491 | 510 | ||
492 | return 0; | 511 | return 0; |
493 | } | 512 | } |
@@ -496,7 +515,7 @@ gpio_release(struct inode *inode, struct file *filp) | |||
496 | * set alarms to wait for using a subsequent select(). | 515 | * set alarms to wait for using a subsequent select(). |
497 | */ | 516 | */ |
498 | 517 | ||
499 | unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) | 518 | inline unsigned long setget_input(struct gpio_private *priv, unsigned long arg) |
500 | { | 519 | { |
501 | /* Set direction 0=unchanged 1=input, | 520 | /* Set direction 0=unchanged 1=input, |
502 | * return mask with 1=input | 521 | * return mask with 1=input |
@@ -512,13 +531,17 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) | |||
512 | 531 | ||
513 | if (priv->minor == GPIO_MINOR_A) | 532 | if (priv->minor == GPIO_MINOR_A) |
514 | dir_shadow ^= 0xFF; /* Only 8 bits */ | 533 | dir_shadow ^= 0xFF; /* Only 8 bits */ |
534 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
535 | else if (priv->minor == GPIO_MINOR_V) | ||
536 | dir_shadow ^= 0xFFFF; /* Only 16 bits */ | ||
537 | #endif | ||
515 | else | 538 | else |
516 | dir_shadow ^= 0x3FFFF; /* Only 18 bits */ | 539 | dir_shadow ^= 0x3FFFF; /* Only 18 bits */ |
517 | return dir_shadow; | 540 | return dir_shadow; |
518 | 541 | ||
519 | } /* setget_input */ | 542 | } /* setget_input */ |
520 | 543 | ||
521 | unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) | 544 | inline unsigned long setget_output(struct gpio_private *priv, unsigned long arg) |
522 | { | 545 | { |
523 | unsigned long flags; | 546 | unsigned long flags; |
524 | unsigned long dir_shadow; | 547 | unsigned long dir_shadow; |
@@ -542,20 +565,22 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
542 | unsigned long val; | 565 | unsigned long val; |
543 | unsigned long shadow; | 566 | unsigned long shadow; |
544 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | 567 | struct gpio_private *priv = (struct gpio_private *)file->private_data; |
545 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) { | 568 | if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) |
546 | return -EINVAL; | 569 | return -EINVAL; |
547 | } | 570 | |
571 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
572 | if (priv->minor == GPIO_MINOR_V) | ||
573 | return virtual_gpio_ioctl(file, cmd, arg); | ||
574 | #endif | ||
548 | 575 | ||
549 | switch (_IOC_NR(cmd)) { | 576 | switch (_IOC_NR(cmd)) { |
550 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ | 577 | case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */ |
551 | // read the port | 578 | /* Read the port. */ |
552 | return *data_in[priv->minor]; | 579 | return *data_in[priv->minor]; |
553 | break; | 580 | break; |
554 | case IO_SETBITS: | 581 | case IO_SETBITS: |
555 | local_irq_save(flags); | 582 | local_irq_save(flags); |
556 | if (arg & 0x04) | 583 | /* Set changeable bits with a 1 in arg. */ |
557 | printk("GPIO SET 2\n"); | ||
558 | // set changeable bits with a 1 in arg | ||
559 | shadow = *data_out[priv->minor]; | 584 | shadow = *data_out[priv->minor]; |
560 | shadow |= (arg & changeable_bits[priv->minor]); | 585 | shadow |= (arg & changeable_bits[priv->minor]); |
561 | *data_out[priv->minor] = shadow; | 586 | *data_out[priv->minor] = shadow; |
@@ -563,46 +588,42 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
563 | break; | 588 | break; |
564 | case IO_CLRBITS: | 589 | case IO_CLRBITS: |
565 | local_irq_save(flags); | 590 | local_irq_save(flags); |
566 | if (arg & 0x04) | 591 | /* Clear changeable bits with a 1 in arg. */ |
567 | printk("GPIO CLR 2\n"); | ||
568 | // clear changeable bits with a 1 in arg | ||
569 | shadow = *data_out[priv->minor]; | 592 | shadow = *data_out[priv->minor]; |
570 | shadow &= ~(arg & changeable_bits[priv->minor]); | 593 | shadow &= ~(arg & changeable_bits[priv->minor]); |
571 | *data_out[priv->minor] = shadow; | 594 | *data_out[priv->minor] = shadow; |
572 | local_irq_restore(flags); | 595 | local_irq_restore(flags); |
573 | break; | 596 | break; |
574 | case IO_HIGHALARM: | 597 | case IO_HIGHALARM: |
575 | // set alarm when bits with 1 in arg go high | 598 | /* Set alarm when bits with 1 in arg go high. */ |
576 | priv->highalarm |= arg; | 599 | priv->highalarm |= arg; |
577 | spin_lock(&alarm_lock); | 600 | spin_lock_irqsave(&alarm_lock, flags); |
578 | gpio_some_alarms = 1; | 601 | gpio_some_alarms = 1; |
579 | if (priv->minor == GPIO_MINOR_A) { | 602 | if (priv->minor == GPIO_MINOR_A) |
580 | gpio_pa_high_alarms |= arg; | 603 | gpio_pa_high_alarms |= arg; |
581 | } | 604 | spin_unlock_irqrestore(&alarm_lock, flags); |
582 | spin_unlock(&alarm_lock); | ||
583 | break; | 605 | break; |
584 | case IO_LOWALARM: | 606 | case IO_LOWALARM: |
585 | // set alarm when bits with 1 in arg go low | 607 | /* Set alarm when bits with 1 in arg go low. */ |
586 | priv->lowalarm |= arg; | 608 | priv->lowalarm |= arg; |
587 | spin_lock(&alarm_lock); | 609 | spin_lock_irqsave(&alarm_lock, flags); |
588 | gpio_some_alarms = 1; | 610 | gpio_some_alarms = 1; |
589 | if (priv->minor == GPIO_MINOR_A) { | 611 | if (priv->minor == GPIO_MINOR_A) |
590 | gpio_pa_low_alarms |= arg; | 612 | gpio_pa_low_alarms |= arg; |
591 | } | 613 | spin_unlock_irqrestore(&alarm_lock, flags); |
592 | spin_unlock(&alarm_lock); | ||
593 | break; | 614 | break; |
594 | case IO_CLRALARM: | 615 | case IO_CLRALARM: |
595 | // clear alarm for bits with 1 in arg | 616 | /* Clear alarm for bits with 1 in arg. */ |
596 | priv->highalarm &= ~arg; | 617 | priv->highalarm &= ~arg; |
597 | priv->lowalarm &= ~arg; | 618 | priv->lowalarm &= ~arg; |
598 | spin_lock(&alarm_lock); | 619 | spin_lock_irqsave(&alarm_lock, flags); |
599 | if (priv->minor == GPIO_MINOR_A) { | 620 | if (priv->minor == GPIO_MINOR_A) { |
600 | if (gpio_pa_high_alarms & arg || | 621 | if (gpio_pa_high_alarms & arg || |
601 | gpio_pa_low_alarms & arg) { | 622 | gpio_pa_low_alarms & arg) |
602 | /* Must update the gpio_pa_*alarms masks */ | 623 | /* Must update the gpio_pa_*alarms masks */ |
603 | } | 624 | ; |
604 | } | 625 | } |
605 | spin_unlock(&alarm_lock); | 626 | spin_unlock_irqrestore(&alarm_lock, flags); |
606 | break; | 627 | break; |
607 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ | 628 | case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ |
608 | /* Read direction 0=input 1=output */ | 629 | /* Read direction 0=input 1=output */ |
@@ -633,8 +654,7 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
633 | if (!((priv->clk_mask & changeable_bits[priv->minor]) && | 654 | if (!((priv->clk_mask & changeable_bits[priv->minor]) && |
634 | (priv->data_mask & changeable_bits[priv->minor]) && | 655 | (priv->data_mask & changeable_bits[priv->minor]) && |
635 | (priv->clk_mask & dir_shadow) && | 656 | (priv->clk_mask & dir_shadow) && |
636 | (priv->data_mask & dir_shadow))) | 657 | (priv->data_mask & dir_shadow))) { |
637 | { | ||
638 | priv->clk_mask = 0; | 658 | priv->clk_mask = 0; |
639 | priv->data_mask = 0; | 659 | priv->data_mask = 0; |
640 | return -EPERM; | 660 | return -EPERM; |
@@ -644,34 +664,34 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
644 | case IO_READ_INBITS: | 664 | case IO_READ_INBITS: |
645 | /* *arg is result of reading the input pins */ | 665 | /* *arg is result of reading the input pins */ |
646 | val = *data_in[priv->minor]; | 666 | val = *data_in[priv->minor]; |
647 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 667 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) |
648 | return -EFAULT; | 668 | return -EFAULT; |
649 | return 0; | 669 | return 0; |
650 | break; | 670 | break; |
651 | case IO_READ_OUTBITS: | 671 | case IO_READ_OUTBITS: |
652 | /* *arg is result of reading the output shadow */ | 672 | /* *arg is result of reading the output shadow */ |
653 | val = *data_out[priv->minor]; | 673 | val = *data_out[priv->minor]; |
654 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 674 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) |
655 | return -EFAULT; | 675 | return -EFAULT; |
656 | break; | 676 | break; |
657 | case IO_SETGET_INPUT: | 677 | case IO_SETGET_INPUT: |
658 | /* bits set in *arg is set to input, | 678 | /* bits set in *arg is set to input, |
659 | * *arg updated with current input pins. | 679 | * *arg updated with current input pins. |
660 | */ | 680 | */ |
661 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | 681 | if (copy_from_user(&val, (unsigned long *)arg, sizeof(val))) |
662 | return -EFAULT; | 682 | return -EFAULT; |
663 | val = setget_input(priv, val); | 683 | val = setget_input(priv, val); |
664 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 684 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) |
665 | return -EFAULT; | 685 | return -EFAULT; |
666 | break; | 686 | break; |
667 | case IO_SETGET_OUTPUT: | 687 | case IO_SETGET_OUTPUT: |
668 | /* bits set in *arg is set to output, | 688 | /* bits set in *arg is set to output, |
669 | * *arg updated with current output pins. | 689 | * *arg updated with current output pins. |
670 | */ | 690 | */ |
671 | if (copy_from_user(&val, (unsigned long*)arg, sizeof(val))) | 691 | if (copy_from_user(&val, (unsigned long *)arg, sizeof(val))) |
672 | return -EFAULT; | 692 | return -EFAULT; |
673 | val = setget_output(priv, val); | 693 | val = setget_output(priv, val); |
674 | if (copy_to_user((unsigned long*)arg, &val, sizeof(val))) | 694 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) |
675 | return -EFAULT; | 695 | return -EFAULT; |
676 | break; | 696 | break; |
677 | default: | 697 | default: |
@@ -684,6 +704,133 @@ gpio_ioctl(struct inode *inode, struct file *file, | |||
684 | return 0; | 704 | return 0; |
685 | } | 705 | } |
686 | 706 | ||
707 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
708 | static int | ||
709 | virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
710 | { | ||
711 | unsigned long flags; | ||
712 | unsigned short val; | ||
713 | unsigned short shadow; | ||
714 | struct gpio_private *priv = (struct gpio_private *)file->private_data; | ||
715 | |||
716 | switch (_IOC_NR(cmd)) { | ||
717 | case IO_SETBITS: | ||
718 | local_irq_save(flags); | ||
719 | /* Set changeable bits with a 1 in arg. */ | ||
720 | i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
721 | shadow |= ~*dir_oe[priv->minor]; | ||
722 | shadow |= (arg & changeable_bits[priv->minor]); | ||
723 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
724 | local_irq_restore(flags); | ||
725 | break; | ||
726 | case IO_CLRBITS: | ||
727 | local_irq_save(flags); | ||
728 | /* Clear changeable bits with a 1 in arg. */ | ||
729 | i2c_read(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
730 | shadow |= ~*dir_oe[priv->minor]; | ||
731 | shadow &= ~(arg & changeable_bits[priv->minor]); | ||
732 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
733 | local_irq_restore(flags); | ||
734 | break; | ||
735 | case IO_HIGHALARM: | ||
736 | /* Set alarm when bits with 1 in arg go high. */ | ||
737 | priv->highalarm |= arg; | ||
738 | spin_lock(&alarm_lock); | ||
739 | gpio_some_alarms = 1; | ||
740 | spin_unlock(&alarm_lock); | ||
741 | break; | ||
742 | case IO_LOWALARM: | ||
743 | /* Set alarm when bits with 1 in arg go low. */ | ||
744 | priv->lowalarm |= arg; | ||
745 | spin_lock(&alarm_lock); | ||
746 | gpio_some_alarms = 1; | ||
747 | spin_unlock(&alarm_lock); | ||
748 | break; | ||
749 | case IO_CLRALARM: | ||
750 | /* Clear alarm for bits with 1 in arg. */ | ||
751 | priv->highalarm &= ~arg; | ||
752 | priv->lowalarm &= ~arg; | ||
753 | spin_lock(&alarm_lock); | ||
754 | spin_unlock(&alarm_lock); | ||
755 | break; | ||
756 | case IO_CFG_WRITE_MODE: | ||
757 | { | ||
758 | unsigned long dir_shadow; | ||
759 | dir_shadow = *dir_oe[priv->minor]; | ||
760 | |||
761 | priv->clk_mask = arg & 0xFF; | ||
762 | priv->data_mask = (arg >> 8) & 0xFF; | ||
763 | priv->write_msb = (arg >> 16) & 0x01; | ||
764 | /* Check if we're allowed to change the bits and | ||
765 | * the direction is correct | ||
766 | */ | ||
767 | if (!((priv->clk_mask & changeable_bits[priv->minor]) && | ||
768 | (priv->data_mask & changeable_bits[priv->minor]) && | ||
769 | (priv->clk_mask & dir_shadow) && | ||
770 | (priv->data_mask & dir_shadow))) { | ||
771 | priv->clk_mask = 0; | ||
772 | priv->data_mask = 0; | ||
773 | return -EPERM; | ||
774 | } | ||
775 | break; | ||
776 | } | ||
777 | case IO_READ_INBITS: | ||
778 | /* *arg is result of reading the input pins */ | ||
779 | val = cached_virtual_gpio_read; | ||
780 | val &= ~*dir_oe[priv->minor]; | ||
781 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) | ||
782 | return -EFAULT; | ||
783 | return 0; | ||
784 | break; | ||
785 | case IO_READ_OUTBITS: | ||
786 | /* *arg is result of reading the output shadow */ | ||
787 | i2c_read(VIRT_I2C_ADDR, (void *)&val, sizeof(val)); | ||
788 | val &= *dir_oe[priv->minor]; | ||
789 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) | ||
790 | return -EFAULT; | ||
791 | break; | ||
792 | case IO_SETGET_INPUT: | ||
793 | { | ||
794 | /* bits set in *arg is set to input, | ||
795 | * *arg updated with current input pins. | ||
796 | */ | ||
797 | unsigned short input_mask = ~*dir_oe[priv->minor]; | ||
798 | if (copy_from_user(&val, (unsigned long *)arg, sizeof(val))) | ||
799 | return -EFAULT; | ||
800 | val = setget_input(priv, val); | ||
801 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) | ||
802 | return -EFAULT; | ||
803 | if ((input_mask & val) != input_mask) { | ||
804 | /* Input pins changed. All ports desired as input | ||
805 | * should be set to logic 1. | ||
806 | */ | ||
807 | unsigned short change = input_mask ^ val; | ||
808 | i2c_read(VIRT_I2C_ADDR, (void *)&shadow, | ||
809 | sizeof(shadow)); | ||
810 | shadow &= ~change; | ||
811 | shadow |= val; | ||
812 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, | ||
813 | sizeof(shadow)); | ||
814 | } | ||
815 | break; | ||
816 | } | ||
817 | case IO_SETGET_OUTPUT: | ||
818 | /* bits set in *arg is set to output, | ||
819 | * *arg updated with current output pins. | ||
820 | */ | ||
821 | if (copy_from_user(&val, (unsigned long *)arg, sizeof(val))) | ||
822 | return -EFAULT; | ||
823 | val = setget_output(priv, val); | ||
824 | if (copy_to_user((unsigned long *)arg, &val, sizeof(val))) | ||
825 | return -EFAULT; | ||
826 | break; | ||
827 | default: | ||
828 | return -EINVAL; | ||
829 | } /* switch */ | ||
830 | return 0; | ||
831 | } | ||
832 | #endif /* CONFIG_ETRAX_VIRTUAL_GPIO */ | ||
833 | |||
687 | static int | 834 | static int |
688 | gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | 835 | gpio_leds_ioctl(unsigned int cmd, unsigned long arg) |
689 | { | 836 | { |
@@ -694,8 +841,8 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | |||
694 | case IO_LEDACTIVE_SET: | 841 | case IO_LEDACTIVE_SET: |
695 | green = ((unsigned char) arg) & 1; | 842 | green = ((unsigned char) arg) & 1; |
696 | red = (((unsigned char) arg) >> 1) & 1; | 843 | red = (((unsigned char) arg) >> 1) & 1; |
697 | LED_ACTIVE_SET_G(green); | 844 | CRIS_LED_ACTIVE_SET_G(green); |
698 | LED_ACTIVE_SET_R(red); | 845 | CRIS_LED_ACTIVE_SET_R(red); |
699 | break; | 846 | break; |
700 | 847 | ||
701 | default: | 848 | default: |
@@ -705,7 +852,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg) | |||
705 | return 0; | 852 | return 0; |
706 | } | 853 | } |
707 | 854 | ||
708 | const struct file_operations gpio_fops = { | 855 | struct file_operations gpio_fops = { |
709 | .owner = THIS_MODULE, | 856 | .owner = THIS_MODULE, |
710 | .poll = gpio_poll, | 857 | .poll = gpio_poll, |
711 | .ioctl = gpio_ioctl, | 858 | .ioctl = gpio_ioctl, |
@@ -714,6 +861,66 @@ const struct file_operations gpio_fops = { | |||
714 | .release = gpio_release, | 861 | .release = gpio_release, |
715 | }; | 862 | }; |
716 | 863 | ||
864 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO | ||
865 | static void | ||
866 | virtual_gpio_init(void) | ||
867 | { | ||
868 | reg_gio_rw_intr_cfg intr_cfg; | ||
869 | reg_gio_rw_intr_mask intr_mask; | ||
870 | unsigned short shadow; | ||
871 | |||
872 | shadow = ~virtual_rw_pv_oe; /* Input ports should be set to logic 1 */ | ||
873 | shadow |= CONFIG_ETRAX_DEF_GIO_PV_OUT; | ||
874 | i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow)); | ||
875 | |||
876 | /* Set interrupt mask and on what state the interrupt shall trigger. | ||
877 | * For virtual gpio the interrupt shall trigger on logic '0'. | ||
878 | */ | ||
879 | intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg); | ||
880 | intr_mask = REG_RD(gio, regi_gio, rw_intr_mask); | ||
881 | |||
882 | switch (CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN) { | ||
883 | case 0: | ||
884 | intr_cfg.pa0 = regk_gio_lo; | ||
885 | intr_mask.pa0 = regk_gio_yes; | ||
886 | break; | ||
887 | case 1: | ||
888 | intr_cfg.pa1 = regk_gio_lo; | ||
889 | intr_mask.pa1 = regk_gio_yes; | ||
890 | break; | ||
891 | case 2: | ||
892 | intr_cfg.pa2 = regk_gio_lo; | ||
893 | intr_mask.pa2 = regk_gio_yes; | ||
894 | break; | ||
895 | case 3: | ||
896 | intr_cfg.pa3 = regk_gio_lo; | ||
897 | intr_mask.pa3 = regk_gio_yes; | ||
898 | break; | ||
899 | case 4: | ||
900 | intr_cfg.pa4 = regk_gio_lo; | ||
901 | intr_mask.pa4 = regk_gio_yes; | ||
902 | break; | ||
903 | case 5: | ||
904 | intr_cfg.pa5 = regk_gio_lo; | ||
905 | intr_mask.pa5 = regk_gio_yes; | ||
906 | break; | ||
907 | case 6: | ||
908 | intr_cfg.pa6 = regk_gio_lo; | ||
909 | intr_mask.pa6 = regk_gio_yes; | ||
910 | break; | ||
911 | case 7: | ||
912 | intr_cfg.pa7 = regk_gio_lo; | ||
913 | intr_mask.pa7 = regk_gio_yes; | ||
914 | break; | ||
915 | } | ||
916 | |||
917 | REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg); | ||
918 | REG_WR(gio, regi_gio, rw_intr_mask, intr_mask); | ||
919 | |||
920 | gpio_pa_low_alarms |= (1 << CONFIG_ETRAX_VIRTUAL_GPIO_INTERRUPT_PA_PIN); | ||
921 | gpio_some_alarms = 1; | ||
922 | } | ||
923 | #endif | ||
717 | 924 | ||
718 | /* main driver initialization routine, called from mem.c */ | 925 | /* main driver initialization routine, called from mem.c */ |
719 | 926 | ||
@@ -721,7 +928,6 @@ static __init int | |||
721 | gpio_init(void) | 928 | gpio_init(void) |
722 | { | 929 | { |
723 | int res; | 930 | int res; |
724 | reg_intr_vect_rw_mask intr_mask; | ||
725 | 931 | ||
726 | /* do the formalities */ | 932 | /* do the formalities */ |
727 | 933 | ||
@@ -732,30 +938,30 @@ gpio_init(void) | |||
732 | } | 938 | } |
733 | 939 | ||
734 | /* Clear all leds */ | 940 | /* Clear all leds */ |
735 | LED_NETWORK_SET(0); | 941 | CRIS_LED_NETWORK_GRP0_SET(0); |
736 | LED_ACTIVE_SET(0); | 942 | CRIS_LED_NETWORK_GRP1_SET(0); |
737 | LED_DISK_READ(0); | 943 | CRIS_LED_ACTIVE_SET(0); |
738 | LED_DISK_WRITE(0); | 944 | CRIS_LED_DISK_READ(0); |
739 | 945 | CRIS_LED_DISK_WRITE(0); | |
740 | printk("ETRAX FS GPIO driver v2.5, (c) 2003-2005 Axis Communications AB\n"); | 946 | |
947 | printk(KERN_INFO "ETRAX FS GPIO driver v2.5, (c) 2003-2007 " | ||
948 | "Axis Communications AB\n"); | ||
741 | /* We call etrax_gpio_wake_up_check() from timer interrupt and | 949 | /* We call etrax_gpio_wake_up_check() from timer interrupt and |
742 | * from cpu_idle() in kernel/process.c | 950 | * from cpu_idle() in kernel/process.c |
743 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms | 951 | * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms |
744 | * in some tests. | 952 | * in some tests. |
745 | */ | 953 | */ |
746 | if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt, | 954 | if (request_irq(TIMER0_INTR_VECT, gpio_poll_timer_interrupt, |
747 | IRQF_SHARED | IRQF_DISABLED,"gpio poll", &alarmlist)) { | 955 | IRQF_SHARED | IRQF_DISABLED, "gpio poll", &alarmlist)) |
748 | printk("err: timer0 irq for gpio\n"); | 956 | printk(KERN_ERR "timer0 irq for gpio\n"); |
749 | } | 957 | |
750 | if (request_irq(GEN_IO_INTR_VECT, gpio_pa_interrupt, | 958 | if (request_irq(GIO_INTR_VECT, gpio_pa_interrupt, |
751 | IRQF_SHARED | IRQF_DISABLED,"gpio PA", &alarmlist)) { | 959 | IRQF_SHARED | IRQF_DISABLED, "gpio PA", &alarmlist)) |
752 | printk("err: PA irq for gpio\n"); | 960 | printk(KERN_ERR "PA irq for gpio\n"); |
753 | } | 961 | |
754 | /* enable the gio and timer irq in global config */ | 962 | #ifdef CONFIG_ETRAX_VIRTUAL_GPIO |
755 | intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); | 963 | virtual_gpio_init(); |
756 | intr_mask.timer = 1; | 964 | #endif |
757 | intr_mask.gen_io = 1; | ||
758 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | ||
759 | 965 | ||
760 | return res; | 966 | return res; |
761 | } | 967 | } |
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index 5ce015c6bb0d..aa01b134458a 100644 --- a/arch/cris/arch-v32/drivers/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c | |||
@@ -4,9 +4,7 @@ | |||
4 | * Copyright (c) 2004 | 4 | * Copyright (c) 2004 |
5 | * | 5 | * |
6 | * Derived from drivers/mtd/nand/spia.c | 6 | * Derived from drivers/mtd/nand/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | ||
9 | * $Id: nandflash.c,v 1.3 2005/06/01 10:57:12 starvik Exp $ | ||
10 | * | 8 | * |
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -21,10 +19,10 @@ | |||
21 | #include <linux/mtd/nand.h> | 19 | #include <linux/mtd/nand.h> |
22 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
23 | #include <asm/arch/memmap.h> | 21 | #include <asm/arch/memmap.h> |
24 | #include <asm/arch/hwregs/reg_map.h> | 22 | #include <hwregs/reg_map.h> |
25 | #include <asm/arch/hwregs/reg_rdwr.h> | 23 | #include <hwregs/reg_rdwr.h> |
26 | #include <asm/arch/hwregs/gio_defs.h> | 24 | #include <hwregs/gio_defs.h> |
27 | #include <asm/arch/hwregs/bif_core_defs.h> | 25 | #include <hwregs/bif_core_defs.h> |
28 | #include <asm/io.h> | 26 | #include <asm/io.h> |
29 | 27 | ||
30 | #define CE_BIT 4 | 28 | #define CE_BIT 4 |
@@ -32,44 +30,65 @@ | |||
32 | #define ALE_BIT 6 | 30 | #define ALE_BIT 6 |
33 | #define BY_BIT 7 | 31 | #define BY_BIT 7 |
34 | 32 | ||
35 | static struct mtd_info *crisv32_mtd = NULL; | 33 | struct mtd_info_wrapper { |
34 | struct mtd_info info; | ||
35 | struct nand_chip chip; | ||
36 | }; | ||
37 | |||
38 | /* Bitmask for control pins */ | ||
39 | #define PIN_BITMASK ((1 << CE_BIT) | (1 << CLE_BIT) | (1 << ALE_BIT)) | ||
40 | |||
41 | /* Bitmask for mtd nand control bits */ | ||
42 | #define CTRL_BITMASK (NAND_NCE | NAND_CLE | NAND_ALE) | ||
43 | |||
44 | |||
45 | static struct mtd_info *crisv32_mtd; | ||
36 | /* | 46 | /* |
37 | * hardware specific access to control-lines | 47 | * hardware specific access to control-lines |
38 | */ | 48 | */ |
39 | static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd) | 49 | static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, |
50 | unsigned int ctrl) | ||
40 | { | 51 | { |
41 | unsigned long flags; | 52 | unsigned long flags; |
42 | reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout); | 53 | reg_gio_rw_pa_dout dout; |
54 | struct nand_chip *this = mtd->priv; | ||
43 | 55 | ||
44 | local_irq_save(flags); | 56 | local_irq_save(flags); |
45 | switch(cmd){ | 57 | |
46 | case NAND_CTL_SETCLE: | 58 | /* control bits change */ |
47 | dout.data |= (1<<CLE_BIT); | 59 | if (ctrl & NAND_CTRL_CHANGE) { |
48 | break; | 60 | dout = REG_RD(gio, regi_gio, rw_pa_dout); |
49 | case NAND_CTL_CLRCLE: | 61 | dout.data &= ~PIN_BITMASK; |
50 | dout.data &= ~(1<<CLE_BIT); | 62 | |
51 | break; | 63 | #if (CE_BIT == 4 && NAND_NCE == 1 && \ |
52 | case NAND_CTL_SETALE: | 64 | CLE_BIT == 5 && NAND_CLE == 2 && \ |
53 | dout.data |= (1<<ALE_BIT); | 65 | ALE_BIT == 6 && NAND_ALE == 4) |
54 | break; | 66 | /* Pins in same order as control bits, but shifted. |
55 | case NAND_CTL_CLRALE: | 67 | * Optimize for this case; works for 2.6.18 */ |
56 | dout.data &= ~(1<<ALE_BIT); | 68 | dout.data |= ((ctrl & CTRL_BITMASK) ^ NAND_NCE) << CE_BIT; |
57 | break; | 69 | #else |
58 | case NAND_CTL_SETNCE: | 70 | /* the slow way */ |
59 | dout.data |= (1<<CE_BIT); | 71 | if (!(ctrl & NAND_NCE)) |
60 | break; | 72 | dout.data |= (1 << CE_BIT); |
61 | case NAND_CTL_CLRNCE: | 73 | if (ctrl & NAND_CLE) |
62 | dout.data &= ~(1<<CE_BIT); | 74 | dout.data |= (1 << CLE_BIT); |
63 | break; | 75 | if (ctrl & NAND_ALE) |
76 | dout.data |= (1 << ALE_BIT); | ||
77 | #endif | ||
78 | REG_WR(gio, regi_gio, rw_pa_dout, dout); | ||
64 | } | 79 | } |
65 | REG_WR(gio, regi_gio, rw_pa_dout, dout); | 80 | |
81 | /* command to chip */ | ||
82 | if (cmd != NAND_CMD_NONE) | ||
83 | writeb(cmd, this->IO_ADDR_W); | ||
84 | |||
66 | local_irq_restore(flags); | 85 | local_irq_restore(flags); |
67 | } | 86 | } |
68 | 87 | ||
69 | /* | 88 | /* |
70 | * read device ready pin | 89 | * read device ready pin |
71 | */ | 90 | */ |
72 | int crisv32_device_ready(struct mtd_info *mtd) | 91 | static int crisv32_device_ready(struct mtd_info *mtd) |
73 | { | 92 | { |
74 | reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din); | 93 | reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din); |
75 | return ((din.data & (1 << BY_BIT)) >> BY_BIT); | 94 | return ((din.data & (1 << BY_BIT)) >> BY_BIT); |
@@ -78,21 +97,23 @@ int crisv32_device_ready(struct mtd_info *mtd) | |||
78 | /* | 97 | /* |
79 | * Main initialization routine | 98 | * Main initialization routine |
80 | */ | 99 | */ |
81 | struct mtd_info* __init crisv32_nand_flash_probe (void) | 100 | struct mtd_info *__init crisv32_nand_flash_probe(void) |
82 | { | 101 | { |
83 | void __iomem *read_cs; | 102 | void __iomem *read_cs; |
84 | void __iomem *write_cs; | 103 | void __iomem *write_cs; |
85 | 104 | ||
86 | reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg); | 105 | reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, |
106 | rw_grp3_cfg); | ||
87 | reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe); | 107 | reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe); |
108 | struct mtd_info_wrapper *wrapper; | ||
88 | struct nand_chip *this; | 109 | struct nand_chip *this; |
89 | int err = 0; | 110 | int err = 0; |
90 | 111 | ||
91 | /* Allocate memory for MTD device structure and private data */ | 112 | /* Allocate memory for MTD device structure and private data */ |
92 | crisv32_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), | 113 | wrapper = kzalloc(sizeof(struct mtd_info_wrapper), GFP_KERNEL); |
93 | GFP_KERNEL); | 114 | if (!wrapper) { |
94 | if (!crisv32_mtd) { | 115 | printk(KERN_ERR "Unable to allocate CRISv32 NAND MTD " |
95 | printk ("Unable to allocate CRISv32 NAND MTD device structure.\n"); | 116 | "device structure.\n"); |
96 | err = -ENOMEM; | 117 | err = -ENOMEM; |
97 | return NULL; | 118 | return NULL; |
98 | } | 119 | } |
@@ -101,45 +122,42 @@ struct mtd_info* __init crisv32_nand_flash_probe (void) | |||
101 | write_cs = ioremap(MEM_CSP1_START | MEM_NON_CACHEABLE, 8192); | 122 | write_cs = ioremap(MEM_CSP1_START | MEM_NON_CACHEABLE, 8192); |
102 | 123 | ||
103 | if (!read_cs || !write_cs) { | 124 | if (!read_cs || !write_cs) { |
104 | printk("CRISv32 NAND ioremap failed\n"); | 125 | printk(KERN_ERR "CRISv32 NAND ioremap failed\n"); |
105 | err = -EIO; | 126 | err = -EIO; |
106 | goto out_mtd; | 127 | goto out_mtd; |
107 | } | 128 | } |
108 | 129 | ||
109 | /* Get pointer to private data */ | 130 | /* Get pointer to private data */ |
110 | this = (struct nand_chip *) (&crisv32_mtd[1]); | 131 | this = &wrapper->chip; |
132 | crisv32_mtd = &wrapper->info; | ||
111 | 133 | ||
112 | pa_oe.oe |= 1 << CE_BIT; | 134 | pa_oe.oe |= 1 << CE_BIT; |
113 | pa_oe.oe |= 1 << ALE_BIT; | 135 | pa_oe.oe |= 1 << ALE_BIT; |
114 | pa_oe.oe |= 1 << CLE_BIT; | 136 | pa_oe.oe |= 1 << CLE_BIT; |
115 | pa_oe.oe &= ~ (1 << BY_BIT); | 137 | pa_oe.oe &= ~(1 << BY_BIT); |
116 | REG_WR(gio, regi_gio, rw_pa_oe, pa_oe); | 138 | REG_WR(gio, regi_gio, rw_pa_oe, pa_oe); |
117 | 139 | ||
118 | bif_cfg.gated_csp0 = regk_bif_core_rd; | 140 | bif_cfg.gated_csp0 = regk_bif_core_rd; |
119 | bif_cfg.gated_csp1 = regk_bif_core_wr; | 141 | bif_cfg.gated_csp1 = regk_bif_core_wr; |
120 | REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg); | 142 | REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg); |
121 | 143 | ||
122 | /* Initialize structures */ | ||
123 | memset((char *) crisv32_mtd, 0, sizeof(struct mtd_info)); | ||
124 | memset((char *) this, 0, sizeof(struct nand_chip)); | ||
125 | |||
126 | /* Link the private data with the MTD structure */ | 144 | /* Link the private data with the MTD structure */ |
127 | crisv32_mtd->priv = this; | 145 | crisv32_mtd->priv = this; |
128 | 146 | ||
129 | /* Set address of NAND IO lines */ | 147 | /* Set address of NAND IO lines */ |
130 | this->IO_ADDR_R = read_cs; | 148 | this->IO_ADDR_R = read_cs; |
131 | this->IO_ADDR_W = write_cs; | 149 | this->IO_ADDR_W = write_cs; |
132 | this->hwcontrol = crisv32_hwcontrol; | 150 | this->cmd_ctrl = crisv32_hwcontrol; |
133 | this->dev_ready = crisv32_device_ready; | 151 | this->dev_ready = crisv32_device_ready; |
134 | /* 20 us command delay time */ | 152 | /* 20 us command delay time */ |
135 | this->chip_delay = 20; | 153 | this->chip_delay = 20; |
136 | this->eccmode = NAND_ECC_SOFT; | 154 | this->ecc.mode = NAND_ECC_SOFT; |
137 | 155 | ||
138 | /* Enable the following for a flash based bad block table */ | 156 | /* Enable the following for a flash based bad block table */ |
139 | this->options = NAND_USE_FLASH_BBT; | 157 | /* this->options = NAND_USE_FLASH_BBT; */ |
140 | 158 | ||
141 | /* Scan to find existence of the device */ | 159 | /* Scan to find existance of the device */ |
142 | if (nand_scan (crisv32_mtd, 1)) { | 160 | if (nand_scan(crisv32_mtd, 1)) { |
143 | err = -ENXIO; | 161 | err = -ENXIO; |
144 | goto out_ior; | 162 | goto out_ior; |
145 | } | 163 | } |
@@ -150,7 +168,7 @@ out_ior: | |||
150 | iounmap((void *)read_cs); | 168 | iounmap((void *)read_cs); |
151 | iounmap((void *)write_cs); | 169 | iounmap((void *)write_cs); |
152 | out_mtd: | 170 | out_mtd: |
153 | kfree (crisv32_mtd); | 171 | kfree(wrapper); |
154 | return NULL; | 172 | return NULL; |
155 | } | 173 | } |
156 | 174 | ||
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c index 6dbd700d3d66..53db3870ba04 100644 --- a/arch/cris/arch-v32/drivers/pcf8563.c +++ b/arch/cris/arch-v32/drivers/pcf8563.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * 400 kbits/s. The built-in word address register is incremented | 10 | * 400 kbits/s. The built-in word address register is incremented |
11 | * automatically after each written or read byte. | 11 | * automatically after each written or read byte. |
12 | * | 12 | * |
13 | * Copyright (c) 2002-2003, Axis Communications AB | 13 | * Copyright (c) 2002-2007, Axis Communications AB |
14 | * All rights reserved. | 14 | * All rights reserved. |
15 | * | 15 | * |
16 | * Author: Tobias Anderberg <tobiasa@axis.com>. | 16 | * Author: Tobias Anderberg <tobiasa@axis.com>. |
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ioctl.h> | 26 | #include <linux/ioctl.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/bcd.h> | 28 | #include <linux/bcd.h> |
29 | #include <linux/mutex.h> | ||
29 | 30 | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
@@ -37,24 +38,27 @@ | |||
37 | #define PCF8563_MAJOR 121 /* Local major number. */ | 38 | #define PCF8563_MAJOR 121 /* Local major number. */ |
38 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ | 39 | #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ |
39 | #define PCF8563_NAME "PCF8563" | 40 | #define PCF8563_NAME "PCF8563" |
40 | #define DRIVER_VERSION "$Revision: 1.1 $" | 41 | #define DRIVER_VERSION "$Revision: 1.17 $" |
41 | 42 | ||
42 | /* Two simple wrapper macros, saves a few keystrokes. */ | 43 | /* Two simple wrapper macros, saves a few keystrokes. */ |
43 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) | 44 | #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x) |
44 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) | 45 | #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y) |
45 | 46 | ||
47 | static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ | ||
48 | |||
46 | static const unsigned char days_in_month[] = | 49 | static const unsigned char days_in_month[] = |
47 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | 50 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
48 | 51 | ||
49 | int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 52 | int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
50 | int pcf8563_open(struct inode *, struct file *); | 53 | |
51 | int pcf8563_release(struct inode *, struct file *); | 54 | /* Cache VL bit value read at driver init since writing the RTC_SECOND |
55 | * register clears the VL status. | ||
56 | */ | ||
57 | static int voltage_low; | ||
52 | 58 | ||
53 | static const struct file_operations pcf8563_fops = { | 59 | static const struct file_operations pcf8563_fops = { |
54 | .owner = THIS_MODULE, | 60 | .owner = THIS_MODULE, |
55 | .ioctl = pcf8563_ioctl, | 61 | .ioctl = pcf8563_ioctl |
56 | .open = pcf8563_open, | ||
57 | .release = pcf8563_release, | ||
58 | }; | 62 | }; |
59 | 63 | ||
60 | unsigned char | 64 | unsigned char |
@@ -62,7 +66,7 @@ pcf8563_readreg(int reg) | |||
62 | { | 66 | { |
63 | unsigned char res = rtc_read(reg); | 67 | unsigned char res = rtc_read(reg); |
64 | 68 | ||
65 | /* The PCF8563 does not return 0 for unimplemented bits */ | 69 | /* The PCF8563 does not return 0 for unimplemented bits. */ |
66 | switch (reg) { | 70 | switch (reg) { |
67 | case RTC_SECONDS: | 71 | case RTC_SECONDS: |
68 | case RTC_MINUTES: | 72 | case RTC_MINUTES: |
@@ -95,11 +99,6 @@ pcf8563_readreg(int reg) | |||
95 | void | 99 | void |
96 | pcf8563_writereg(int reg, unsigned char val) | 100 | pcf8563_writereg(int reg, unsigned char val) |
97 | { | 101 | { |
98 | #ifdef CONFIG_ETRAX_RTC_READONLY | ||
99 | if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR)) | ||
100 | return; | ||
101 | #endif | ||
102 | |||
103 | rtc_write(reg, val); | 102 | rtc_write(reg, val); |
104 | } | 103 | } |
105 | 104 | ||
@@ -114,11 +113,13 @@ get_rtc_time(struct rtc_time *tm) | |||
114 | tm->tm_mon = rtc_read(RTC_MONTH); | 113 | tm->tm_mon = rtc_read(RTC_MONTH); |
115 | tm->tm_year = rtc_read(RTC_YEAR); | 114 | tm->tm_year = rtc_read(RTC_YEAR); |
116 | 115 | ||
117 | if (tm->tm_sec & 0x80) | 116 | if (tm->tm_sec & 0x80) { |
118 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " | 117 | printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time " |
119 | "information is no longer guaranteed!\n", PCF8563_NAME); | 118 | "information is no longer guaranteed!\n", PCF8563_NAME); |
119 | } | ||
120 | 120 | ||
121 | tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0); | 121 | tm->tm_year = BCD_TO_BIN(tm->tm_year) + |
122 | ((tm->tm_mon & 0x80) ? 100 : 0); | ||
122 | tm->tm_sec &= 0x7F; | 123 | tm->tm_sec &= 0x7F; |
123 | tm->tm_min &= 0x7F; | 124 | tm->tm_min &= 0x7F; |
124 | tm->tm_hour &= 0x3F; | 125 | tm->tm_hour &= 0x3F; |
@@ -137,8 +138,19 @@ get_rtc_time(struct rtc_time *tm) | |||
137 | int __init | 138 | int __init |
138 | pcf8563_init(void) | 139 | pcf8563_init(void) |
139 | { | 140 | { |
141 | static int res; | ||
142 | static int first = 1; | ||
143 | |||
144 | if (!first) | ||
145 | return res; | ||
146 | first = 0; | ||
147 | |||
140 | /* Initiate the i2c protocol. */ | 148 | /* Initiate the i2c protocol. */ |
141 | i2c_init(); | 149 | res = i2c_init(); |
150 | if (res < 0) { | ||
151 | printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n"); | ||
152 | return res; | ||
153 | } | ||
142 | 154 | ||
143 | /* | 155 | /* |
144 | * First of all we need to reset the chip. This is done by | 156 | * First of all we need to reset the chip. This is done by |
@@ -170,24 +182,20 @@ pcf8563_init(void) | |||
170 | if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) | 182 | if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0) |
171 | goto err; | 183 | goto err; |
172 | 184 | ||
173 | if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { | 185 | /* Check for low voltage, and warn about it. */ |
174 | printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n", | 186 | if (rtc_read(RTC_SECONDS) & 0x80) { |
175 | PCF8563_NAME, PCF8563_MAJOR); | 187 | voltage_low = 1; |
176 | return -1; | 188 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable " |
189 | "date/time information is no longer guaranteed!\n", | ||
190 | PCF8563_NAME); | ||
177 | } | 191 | } |
178 | 192 | ||
179 | printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); | 193 | return res; |
180 | |||
181 | /* Check for low voltage, and warn about it.. */ | ||
182 | if (rtc_read(RTC_SECONDS) & 0x80) | ||
183 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " | ||
184 | "information is no longer guaranteed!\n", PCF8563_NAME); | ||
185 | |||
186 | return 0; | ||
187 | 194 | ||
188 | err: | 195 | err: |
189 | printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); | 196 | printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME); |
190 | return -1; | 197 | res = -1; |
198 | return res; | ||
191 | } | 199 | } |
192 | 200 | ||
193 | void __exit | 201 | void __exit |
@@ -200,8 +208,8 @@ pcf8563_exit(void) | |||
200 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because | 208 | * ioctl calls for this driver. Why return -ENOTTY upon error? Because |
201 | * POSIX says so! | 209 | * POSIX says so! |
202 | */ | 210 | */ |
203 | int | 211 | int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, |
204 | pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) | 212 | unsigned long arg) |
205 | { | 213 | { |
206 | /* Some sanity checks. */ | 214 | /* Some sanity checks. */ |
207 | if (_IOC_TYPE(cmd) != RTC_MAGIC) | 215 | if (_IOC_TYPE(cmd) != RTC_MAGIC) |
@@ -211,125 +219,147 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned | |||
211 | return -ENOTTY; | 219 | return -ENOTTY; |
212 | 220 | ||
213 | switch (cmd) { | 221 | switch (cmd) { |
214 | case RTC_RD_TIME: | 222 | case RTC_RD_TIME: |
215 | { | 223 | { |
216 | struct rtc_time tm; | 224 | struct rtc_time tm; |
217 | 225 | ||
218 | memset(&tm, 0, sizeof (struct rtc_time)); | 226 | mutex_lock(&rtc_lock); |
219 | get_rtc_time(&tm); | 227 | memset(&tm, 0, sizeof tm); |
220 | 228 | get_rtc_time(&tm); | |
221 | if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) { | 229 | |
222 | return -EFAULT; | 230 | if (copy_to_user((struct rtc_time *) arg, &tm, |
223 | } | 231 | sizeof tm)) { |
224 | 232 | spin_unlock(&rtc_lock); | |
225 | return 0; | 233 | return -EFAULT; |
226 | } | 234 | } |
227 | 235 | ||
228 | case RTC_SET_TIME: | 236 | mutex_unlock(&rtc_lock); |
229 | { | 237 | |
230 | #ifdef CONFIG_ETRAX_RTC_READONLY | 238 | return 0; |
239 | } | ||
240 | case RTC_SET_TIME: | ||
241 | { | ||
242 | int leap; | ||
243 | int year; | ||
244 | int century; | ||
245 | struct rtc_time tm; | ||
246 | |||
247 | memset(&tm, 0, sizeof tm); | ||
248 | if (!capable(CAP_SYS_TIME)) | ||
231 | return -EPERM; | 249 | return -EPERM; |
232 | #else | ||
233 | int leap; | ||
234 | int year; | ||
235 | int century; | ||
236 | struct rtc_time tm; | ||
237 | |||
238 | if (!capable(CAP_SYS_TIME)) | ||
239 | return -EPERM; | ||
240 | |||
241 | if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm)) | ||
242 | return -EFAULT; | ||
243 | |||
244 | /* Convert from struct tm to struct rtc_time. */ | ||
245 | tm.tm_year += 1900; | ||
246 | tm.tm_mon += 1; | ||
247 | |||
248 | /* | ||
249 | * Check if tm.tm_year is a leap year. A year is a leap | ||
250 | * year if it is divisible by 4 but not 100, except | ||
251 | * that years divisible by 400 _are_ leap years. | ||
252 | */ | ||
253 | year = tm.tm_year; | ||
254 | leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); | ||
255 | |||
256 | /* Perform some sanity checks. */ | ||
257 | if ((tm.tm_year < 1970) || | ||
258 | (tm.tm_mon > 12) || | ||
259 | (tm.tm_mday == 0) || | ||
260 | (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || | ||
261 | (tm.tm_wday >= 7) || | ||
262 | (tm.tm_hour >= 24) || | ||
263 | (tm.tm_min >= 60) || | ||
264 | (tm.tm_sec >= 60)) | ||
265 | return -EINVAL; | ||
266 | |||
267 | century = (tm.tm_year >= 2000) ? 0x80 : 0; | ||
268 | tm.tm_year = tm.tm_year % 100; | ||
269 | |||
270 | BIN_TO_BCD(tm.tm_year); | ||
271 | BIN_TO_BCD(tm.tm_mday); | ||
272 | BIN_TO_BCD(tm.tm_hour); | ||
273 | BIN_TO_BCD(tm.tm_min); | ||
274 | BIN_TO_BCD(tm.tm_sec); | ||
275 | tm.tm_mon |= century; | ||
276 | |||
277 | rtc_write(RTC_YEAR, tm.tm_year); | ||
278 | rtc_write(RTC_MONTH, tm.tm_mon); | ||
279 | rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ | ||
280 | rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); | ||
281 | rtc_write(RTC_HOURS, tm.tm_hour); | ||
282 | rtc_write(RTC_MINUTES, tm.tm_min); | ||
283 | rtc_write(RTC_SECONDS, tm.tm_sec); | ||
284 | |||
285 | return 0; | ||
286 | #endif /* !CONFIG_ETRAX_RTC_READONLY */ | ||
287 | } | ||
288 | 250 | ||
289 | case RTC_VLOW_RD: | 251 | if (copy_from_user(&tm, (struct rtc_time *) arg, |
290 | { | 252 | sizeof tm)) |
291 | int vl_bit = 0; | 253 | return -EFAULT; |
254 | |||
255 | /* Convert from struct tm to struct rtc_time. */ | ||
256 | tm.tm_year += 1900; | ||
257 | tm.tm_mon += 1; | ||
258 | |||
259 | /* | ||
260 | * Check if tm.tm_year is a leap year. A year is a leap | ||
261 | * year if it is divisible by 4 but not 100, except | ||
262 | * that years divisible by 400 _are_ leap years. | ||
263 | */ | ||
264 | year = tm.tm_year; | ||
265 | leap = (tm.tm_mon == 2) && | ||
266 | ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); | ||
267 | |||
268 | /* Perform some sanity checks. */ | ||
269 | if ((tm.tm_year < 1970) || | ||
270 | (tm.tm_mon > 12) || | ||
271 | (tm.tm_mday == 0) || | ||
272 | (tm.tm_mday > days_in_month[tm.tm_mon] + leap) || | ||
273 | (tm.tm_wday >= 7) || | ||
274 | (tm.tm_hour >= 24) || | ||
275 | (tm.tm_min >= 60) || | ||
276 | (tm.tm_sec >= 60)) | ||
277 | return -EINVAL; | ||
278 | |||
279 | century = (tm.tm_year >= 2000) ? 0x80 : 0; | ||
280 | tm.tm_year = tm.tm_year % 100; | ||
281 | |||
282 | BIN_TO_BCD(tm.tm_year); | ||
283 | BIN_TO_BCD(tm.tm_mon); | ||
284 | BIN_TO_BCD(tm.tm_mday); | ||
285 | BIN_TO_BCD(tm.tm_hour); | ||
286 | BIN_TO_BCD(tm.tm_min); | ||
287 | BIN_TO_BCD(tm.tm_sec); | ||
288 | tm.tm_mon |= century; | ||
289 | |||
290 | mutex_lock(&rtc_lock); | ||
291 | |||
292 | rtc_write(RTC_YEAR, tm.tm_year); | ||
293 | rtc_write(RTC_MONTH, tm.tm_mon); | ||
294 | rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */ | ||
295 | rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday); | ||
296 | rtc_write(RTC_HOURS, tm.tm_hour); | ||
297 | rtc_write(RTC_MINUTES, tm.tm_min); | ||
298 | rtc_write(RTC_SECONDS, tm.tm_sec); | ||
299 | |||
300 | mutex_unlock(&rtc_lock); | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | case RTC_VL_READ: | ||
305 | if (voltage_low) | ||
306 | printk(KERN_ERR "%s: RTC Voltage Low - " | ||
307 | "reliable date/time information is no " | ||
308 | "longer guaranteed!\n", PCF8563_NAME); | ||
292 | 309 | ||
293 | if (rtc_read(RTC_SECONDS) & 0x80) { | 310 | if (copy_to_user((int *) arg, &voltage_low, sizeof(int))) |
294 | vl_bit = 1; | 311 | return -EFAULT; |
295 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable " | 312 | return 0; |
296 | "date/time information is no longer guaranteed!\n", | ||
297 | PCF8563_NAME); | ||
298 | } | ||
299 | if (copy_to_user((int *) arg, &vl_bit, sizeof(int))) | ||
300 | return -EFAULT; | ||
301 | 313 | ||
302 | return 0; | 314 | case RTC_VL_CLR: |
303 | } | 315 | { |
316 | /* Clear the VL bit in the seconds register in case | ||
317 | * the time has not been set already (which would | ||
318 | * have cleared it). This does not really matter | ||
319 | * because of the cached voltage_low value but do it | ||
320 | * anyway for consistency. */ | ||
304 | 321 | ||
305 | case RTC_VLOW_SET: | 322 | int ret = rtc_read(RTC_SECONDS); |
306 | { | ||
307 | /* Clear the VL bit in the seconds register */ | ||
308 | int ret = rtc_read(RTC_SECONDS); | ||
309 | 323 | ||
310 | rtc_write(RTC_SECONDS, (ret & 0x7F)); | 324 | rtc_write(RTC_SECONDS, (ret & 0x7F)); |
311 | 325 | ||
312 | return 0; | 326 | /* Clear the cached value. */ |
313 | } | 327 | voltage_low = 0; |
314 | 328 | ||
315 | default: | 329 | return 0; |
316 | return -ENOTTY; | 330 | } |
331 | default: | ||
332 | return -ENOTTY; | ||
317 | } | 333 | } |
318 | 334 | ||
319 | return 0; | 335 | return 0; |
320 | } | 336 | } |
321 | 337 | ||
322 | int | 338 | static int __init pcf8563_register(void) |
323 | pcf8563_open(struct inode *inode, struct file *filp) | ||
324 | { | 339 | { |
325 | return 0; | 340 | if (pcf8563_init() < 0) { |
326 | } | 341 | printk(KERN_INFO "%s: Unable to initialize Real-Time Clock " |
342 | "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); | ||
343 | return -1; | ||
344 | } | ||
345 | |||
346 | if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { | ||
347 | printk(KERN_INFO "%s: Unable to get major numer %d for RTC " | ||
348 | "device.\n", PCF8563_NAME, PCF8563_MAJOR); | ||
349 | return -1; | ||
350 | } | ||
351 | |||
352 | printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, | ||
353 | DRIVER_VERSION); | ||
354 | |||
355 | /* Check for low voltage, and warn about it. */ | ||
356 | if (voltage_low) { | ||
357 | printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time " | ||
358 | "information is no longer guaranteed!\n", PCF8563_NAME); | ||
359 | } | ||
327 | 360 | ||
328 | int | ||
329 | pcf8563_release(struct inode *inode, struct file *filp) | ||
330 | { | ||
331 | return 0; | 361 | return 0; |
332 | } | 362 | } |
333 | 363 | ||
334 | module_init(pcf8563_init); | 364 | module_init(pcf8563_register); |
335 | module_exit(pcf8563_exit); | 365 | module_exit(pcf8563_exit); |
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index d581b0a92a3f..47c377df6fb3 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Simple synchronous serial port driver for ETRAX FS. | 2 | * Simple synchronous serial port driver for ETRAX FS and Artpec-3. |
3 | * | 3 | * |
4 | * Copyright (c) 2005 Axis Communications AB | 4 | * Copyright (c) 2005 Axis Communications AB |
5 | * | 5 | * |
@@ -21,17 +21,18 @@ | |||
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | 22 | ||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | #include <asm/arch/dma.h> | 24 | #include <dma.h> |
25 | #include <asm/arch/pinmux.h> | 25 | #include <pinmux.h> |
26 | #include <asm/arch/hwregs/reg_rdwr.h> | 26 | #include <hwregs/reg_rdwr.h> |
27 | #include <asm/arch/hwregs/sser_defs.h> | 27 | #include <hwregs/sser_defs.h> |
28 | #include <asm/arch/hwregs/dma_defs.h> | 28 | #include <hwregs/dma_defs.h> |
29 | #include <asm/arch/hwregs/dma.h> | 29 | #include <hwregs/dma.h> |
30 | #include <asm/arch/hwregs/intr_vect_defs.h> | 30 | #include <hwregs/intr_vect_defs.h> |
31 | #include <asm/arch/hwregs/intr_vect.h> | 31 | #include <hwregs/intr_vect.h> |
32 | #include <asm/arch/hwregs/reg_map.h> | 32 | #include <hwregs/reg_map.h> |
33 | #include <asm/sync_serial.h> | 33 | #include <asm/sync_serial.h> |
34 | 34 | ||
35 | |||
35 | /* The receiver is a bit tricky beacuse of the continuous stream of data.*/ | 36 | /* The receiver is a bit tricky beacuse of the continuous stream of data.*/ |
36 | /* */ | 37 | /* */ |
37 | /* Three DMA descriptors are linked together. Each DMA descriptor is */ | 38 | /* Three DMA descriptors are linked together. Each DMA descriptor is */ |
@@ -63,8 +64,10 @@ | |||
63 | /* words can be handled */ | 64 | /* words can be handled */ |
64 | #define IN_BUFFER_SIZE 12288 | 65 | #define IN_BUFFER_SIZE 12288 |
65 | #define IN_DESCR_SIZE 256 | 66 | #define IN_DESCR_SIZE 256 |
66 | #define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE) | 67 | #define NBR_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE) |
67 | #define OUT_BUFFER_SIZE 4096 | 68 | |
69 | #define OUT_BUFFER_SIZE 1024*8 | ||
70 | #define NBR_OUT_DESCR 8 | ||
68 | 71 | ||
69 | #define DEFAULT_FRAME_RATE 0 | 72 | #define DEFAULT_FRAME_RATE 0 |
70 | #define DEFAULT_WORD_RATE 7 | 73 | #define DEFAULT_WORD_RATE 7 |
@@ -78,6 +81,8 @@ | |||
78 | #define DEBUGPOLL(x) | 81 | #define DEBUGPOLL(x) |
79 | #define DEBUGRXINT(x) | 82 | #define DEBUGRXINT(x) |
80 | #define DEBUGTXINT(x) | 83 | #define DEBUGTXINT(x) |
84 | #define DEBUGTRDMA(x) | ||
85 | #define DEBUGOUTBUF(x) | ||
81 | 86 | ||
82 | typedef struct sync_port | 87 | typedef struct sync_port |
83 | { | 88 | { |
@@ -97,10 +102,11 @@ typedef struct sync_port | |||
97 | int output; | 102 | int output; |
98 | int input; | 103 | int input; |
99 | 104 | ||
100 | volatile unsigned int out_count; /* Remaining bytes for current transfer */ | 105 | /* Next byte to be read by application */ |
101 | unsigned char* outp; /* Current position in out_buffer */ | 106 | volatile unsigned char *volatile readp; |
102 | volatile unsigned char* volatile readp; /* Next byte to be read by application */ | 107 | /* Next byte to be written by etrax */ |
103 | volatile unsigned char* volatile writep; /* Next byte to be written by etrax */ | 108 | volatile unsigned char *volatile writep; |
109 | |||
104 | unsigned int in_buffer_size; | 110 | unsigned int in_buffer_size; |
105 | unsigned int inbufchunk; | 111 | unsigned int inbufchunk; |
106 | unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32))); | 112 | unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32))); |
@@ -108,11 +114,30 @@ typedef struct sync_port | |||
108 | unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32))); | 114 | unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32))); |
109 | struct dma_descr_data* next_rx_desc; | 115 | struct dma_descr_data* next_rx_desc; |
110 | struct dma_descr_data* prev_rx_desc; | 116 | struct dma_descr_data* prev_rx_desc; |
117 | |||
118 | /* Pointer to the first available descriptor in the ring, | ||
119 | * unless active_tr_descr == catch_tr_descr and a dma | ||
120 | * transfer is active */ | ||
121 | struct dma_descr_data *active_tr_descr; | ||
122 | |||
123 | /* Pointer to the first allocated descriptor in the ring */ | ||
124 | struct dma_descr_data *catch_tr_descr; | ||
125 | |||
126 | /* Pointer to the descriptor with the current end-of-list */ | ||
127 | struct dma_descr_data *prev_tr_descr; | ||
111 | int full; | 128 | int full; |
112 | 129 | ||
113 | dma_descr_data in_descr[NUM_IN_DESCR] __attribute__ ((__aligned__(16))); | 130 | /* Pointer to the first byte being read by DMA |
131 | * or current position in out_buffer if not using DMA. */ | ||
132 | unsigned char *out_rd_ptr; | ||
133 | |||
134 | /* Number of bytes currently locked for being read by DMA */ | ||
135 | int out_buf_count; | ||
136 | |||
137 | dma_descr_data in_descr[NBR_IN_DESCR] __attribute__ ((__aligned__(16))); | ||
114 | dma_descr_context in_context __attribute__ ((__aligned__(32))); | 138 | dma_descr_context in_context __attribute__ ((__aligned__(32))); |
115 | dma_descr_data out_descr __attribute__ ((__aligned__(16))); | 139 | dma_descr_data out_descr[NBR_OUT_DESCR] |
140 | __attribute__ ((__aligned__(16))); | ||
116 | dma_descr_context out_context __attribute__ ((__aligned__(32))); | 141 | dma_descr_context out_context __attribute__ ((__aligned__(32))); |
117 | wait_queue_head_t out_wait_q; | 142 | wait_queue_head_t out_wait_q; |
118 | wait_queue_head_t in_wait_q; | 143 | wait_queue_head_t in_wait_q; |
@@ -143,11 +168,11 @@ static ssize_t sync_serial_read(struct file *file, char *buf, | |||
143 | #endif | 168 | #endif |
144 | 169 | ||
145 | static void send_word(sync_port* port); | 170 | static void send_word(sync_port* port); |
146 | static void start_dma(struct sync_port *port, const char* data, int count); | 171 | static void start_dma_out(struct sync_port *port, const char *data, int count); |
147 | static void start_dma_in(sync_port* port); | 172 | static void start_dma_in(sync_port* port); |
148 | #ifdef SYNC_SER_DMA | 173 | #ifdef SYNC_SER_DMA |
149 | static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs); | 174 | static irqreturn_t tr_interrupt(int irq, void *dev_id); |
150 | static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs); | 175 | static irqreturn_t rx_interrupt(int irq, void *dev_id); |
151 | #endif | 176 | #endif |
152 | 177 | ||
153 | #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ | 178 | #if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ |
@@ -157,22 +182,49 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs); | |||
157 | #define SYNC_SER_MANUAL | 182 | #define SYNC_SER_MANUAL |
158 | #endif | 183 | #endif |
159 | #ifdef SYNC_SER_MANUAL | 184 | #ifdef SYNC_SER_MANUAL |
160 | static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs); | 185 | static irqreturn_t manual_interrupt(int irq, void *dev_id); |
186 | #endif | ||
187 | |||
188 | #ifdef CONFIG_ETRAXFS /* ETRAX FS */ | ||
189 | #define OUT_DMA_NBR 4 | ||
190 | #define IN_DMA_NBR 5 | ||
191 | #define PINMUX_SSER pinmux_sser0 | ||
192 | #define SYNCSER_INST regi_sser0 | ||
193 | #define SYNCSER_INTR_VECT SSER0_INTR_VECT | ||
194 | #define OUT_DMA_INST regi_dma4 | ||
195 | #define IN_DMA_INST regi_dma5 | ||
196 | #define DMA_OUT_INTR_VECT DMA4_INTR_VECT | ||
197 | #define DMA_IN_INTR_VECT DMA5_INTR_VECT | ||
198 | #define REQ_DMA_SYNCSER dma_sser0 | ||
199 | #else /* Artpec-3 */ | ||
200 | #define OUT_DMA_NBR 6 | ||
201 | #define IN_DMA_NBR 7 | ||
202 | #define PINMUX_SSER pinmux_sser | ||
203 | #define SYNCSER_INST regi_sser | ||
204 | #define SYNCSER_INTR_VECT SSER_INTR_VECT | ||
205 | #define OUT_DMA_INST regi_dma6 | ||
206 | #define IN_DMA_INST regi_dma7 | ||
207 | #define DMA_OUT_INTR_VECT DMA6_INTR_VECT | ||
208 | #define DMA_IN_INTR_VECT DMA7_INTR_VECT | ||
209 | #define REQ_DMA_SYNCSER dma_sser | ||
161 | #endif | 210 | #endif |
162 | 211 | ||
163 | /* The ports */ | 212 | /* The ports */ |
164 | static struct sync_port ports[]= | 213 | static struct sync_port ports[]= |
165 | { | 214 | { |
166 | { | 215 | { |
167 | .regi_sser = regi_sser0, | 216 | .regi_sser = SYNCSER_INST, |
168 | .regi_dmaout = regi_dma4, | 217 | .regi_dmaout = OUT_DMA_INST, |
169 | .regi_dmain = regi_dma5, | 218 | .regi_dmain = IN_DMA_INST, |
170 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA) | 219 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA) |
171 | .use_dma = 1, | 220 | .use_dma = 1, |
172 | #else | 221 | #else |
173 | .use_dma = 0, | 222 | .use_dma = 0, |
174 | #endif | 223 | #endif |
175 | }, | 224 | } |
225 | #ifdef CONFIG_ETRAXFS | ||
226 | , | ||
227 | |||
176 | { | 228 | { |
177 | .regi_sser = regi_sser1, | 229 | .regi_sser = regi_sser1, |
178 | .regi_dmaout = regi_dma6, | 230 | .regi_dmaout = regi_dma6, |
@@ -183,9 +235,10 @@ static struct sync_port ports[]= | |||
183 | .use_dma = 0, | 235 | .use_dma = 0, |
184 | #endif | 236 | #endif |
185 | } | 237 | } |
238 | #endif | ||
186 | }; | 239 | }; |
187 | 240 | ||
188 | #define NUMBER_OF_PORTS ARRAY_SIZE(ports) | 241 | #define NBR_PORTS ARRAY_SIZE(ports) |
189 | 242 | ||
190 | static const struct file_operations sync_serial_fops = { | 243 | static const struct file_operations sync_serial_fops = { |
191 | .owner = THIS_MODULE, | 244 | .owner = THIS_MODULE, |
@@ -200,19 +253,21 @@ static const struct file_operations sync_serial_fops = { | |||
200 | static int __init etrax_sync_serial_init(void) | 253 | static int __init etrax_sync_serial_init(void) |
201 | { | 254 | { |
202 | ports[0].enabled = 0; | 255 | ports[0].enabled = 0; |
256 | #ifdef CONFIG_ETRAXFS | ||
203 | ports[1].enabled = 0; | 257 | ports[1].enabled = 0; |
204 | 258 | #endif | |
205 | if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 ) | 259 | if (register_chrdev(SYNC_SERIAL_MAJOR, "sync serial", |
206 | { | 260 | &sync_serial_fops) < 0) { |
207 | printk("unable to get major for synchronous serial port\n"); | 261 | printk(KERN_WARNING |
262 | "Unable to get major for synchronous serial port\n"); | ||
208 | return -EBUSY; | 263 | return -EBUSY; |
209 | } | 264 | } |
210 | 265 | ||
211 | /* Initialize Ports */ | 266 | /* Initialize Ports */ |
212 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) | 267 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) |
213 | if (crisv32_pinmux_alloc_fixed(pinmux_sser0)) | 268 | if (crisv32_pinmux_alloc_fixed(PINMUX_SSER)) { |
214 | { | 269 | printk(KERN_WARNING |
215 | printk("Unable to allocate pins for syncrhronous serial port 0\n"); | 270 | "Unable to alloc pins for synchronous serial port 0\n"); |
216 | return -EIO; | 271 | return -EIO; |
217 | } | 272 | } |
218 | ports[0].enabled = 1; | 273 | ports[0].enabled = 1; |
@@ -220,33 +275,40 @@ static int __init etrax_sync_serial_init(void) | |||
220 | #endif | 275 | #endif |
221 | 276 | ||
222 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) | 277 | #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) |
223 | if (crisv32_pinmux_alloc_fixed(pinmux_sser1)) | 278 | if (crisv32_pinmux_alloc_fixed(pinmux_sser1)) { |
224 | { | 279 | printk(KERN_WARNING |
225 | printk("Unable to allocate pins for syncrhronous serial port 0\n"); | 280 | "Unable to alloc pins for synchronous serial port 0\n"); |
226 | return -EIO; | 281 | return -EIO; |
227 | } | 282 | } |
228 | ports[1].enabled = 1; | 283 | ports[1].enabled = 1; |
229 | initialize_port(1); | 284 | initialize_port(1); |
230 | #endif | 285 | #endif |
231 | 286 | ||
232 | printk("ETRAX FS synchronous serial port driver\n"); | 287 | #ifdef CONFIG_ETRAXFS |
288 | printk(KERN_INFO "ETRAX FS synchronous serial port driver\n"); | ||
289 | #else | ||
290 | printk(KERN_INFO "Artpec-3 synchronous serial port driver\n"); | ||
291 | #endif | ||
233 | return 0; | 292 | return 0; |
234 | } | 293 | } |
235 | 294 | ||
236 | static void __init initialize_port(int portnbr) | 295 | static void __init initialize_port(int portnbr) |
237 | { | 296 | { |
238 | struct sync_port* port = &ports[portnbr]; | 297 | int __attribute__((unused)) i; |
298 | struct sync_port *port = &ports[portnbr]; | ||
239 | reg_sser_rw_cfg cfg = {0}; | 299 | reg_sser_rw_cfg cfg = {0}; |
240 | reg_sser_rw_frm_cfg frm_cfg = {0}; | 300 | reg_sser_rw_frm_cfg frm_cfg = {0}; |
241 | reg_sser_rw_tr_cfg tr_cfg = {0}; | 301 | reg_sser_rw_tr_cfg tr_cfg = {0}; |
242 | reg_sser_rw_rec_cfg rec_cfg = {0}; | 302 | reg_sser_rw_rec_cfg rec_cfg = {0}; |
243 | 303 | ||
244 | DEBUG(printk("Init sync serial port %d\n", portnbr)); | 304 | DEBUG(printk(KERN_DEBUG "Init sync serial port %d\n", portnbr)); |
245 | 305 | ||
246 | port->port_nbr = portnbr; | 306 | port->port_nbr = portnbr; |
247 | port->init_irqs = 1; | 307 | port->init_irqs = 1; |
248 | 308 | ||
249 | port->outp = port->out_buffer; | 309 | port->out_rd_ptr = port->out_buffer; |
310 | port->out_buf_count = 0; | ||
311 | |||
250 | port->output = 1; | 312 | port->output = 1; |
251 | port->input = 0; | 313 | port->input = 0; |
252 | 314 | ||
@@ -255,7 +317,7 @@ static void __init initialize_port(int portnbr) | |||
255 | port->in_buffer_size = IN_BUFFER_SIZE; | 317 | port->in_buffer_size = IN_BUFFER_SIZE; |
256 | port->inbufchunk = IN_DESCR_SIZE; | 318 | port->inbufchunk = IN_DESCR_SIZE; |
257 | port->next_rx_desc = &port->in_descr[0]; | 319 | port->next_rx_desc = &port->in_descr[0]; |
258 | port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1]; | 320 | port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR-1]; |
259 | port->prev_rx_desc->eol = 1; | 321 | port->prev_rx_desc->eol = 1; |
260 | 322 | ||
261 | init_waitqueue_head(&port->out_wait_q); | 323 | init_waitqueue_head(&port->out_wait_q); |
@@ -286,8 +348,13 @@ static void __init initialize_port(int portnbr) | |||
286 | tr_cfg.sample_size = 7; | 348 | tr_cfg.sample_size = 7; |
287 | tr_cfg.sh_dir = regk_sser_msbfirst; | 349 | tr_cfg.sh_dir = regk_sser_msbfirst; |
288 | tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no; | 350 | tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no; |
351 | #if 0 | ||
289 | tr_cfg.rate_ctrl = regk_sser_bulk; | 352 | tr_cfg.rate_ctrl = regk_sser_bulk; |
290 | tr_cfg.data_pin_use = regk_sser_dout; | 353 | tr_cfg.data_pin_use = regk_sser_dout; |
354 | #else | ||
355 | tr_cfg.rate_ctrl = regk_sser_iso; | ||
356 | tr_cfg.data_pin_use = regk_sser_dout; | ||
357 | #endif | ||
291 | tr_cfg.bulk_wspace = 1; | 358 | tr_cfg.bulk_wspace = 1; |
292 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); | 359 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); |
293 | 360 | ||
@@ -296,6 +363,27 @@ static void __init initialize_port(int portnbr) | |||
296 | rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no; | 363 | rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no; |
297 | rec_cfg.fifo_thr = regk_sser_inf; | 364 | rec_cfg.fifo_thr = regk_sser_inf; |
298 | REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); | 365 | REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); |
366 | |||
367 | #ifdef SYNC_SER_DMA | ||
368 | /* Setup the descriptor ring for dma out/transmit. */ | ||
369 | for (i = 0; i < NBR_OUT_DESCR; i++) { | ||
370 | port->out_descr[i].wait = 0; | ||
371 | port->out_descr[i].intr = 1; | ||
372 | port->out_descr[i].eol = 0; | ||
373 | port->out_descr[i].out_eop = 0; | ||
374 | port->out_descr[i].next = | ||
375 | (dma_descr_data *)virt_to_phys(&port->out_descr[i+1]); | ||
376 | } | ||
377 | |||
378 | /* Create a ring from the list. */ | ||
379 | port->out_descr[NBR_OUT_DESCR-1].next = | ||
380 | (dma_descr_data *)virt_to_phys(&port->out_descr[0]); | ||
381 | |||
382 | /* Setup context for traversing the ring. */ | ||
383 | port->active_tr_descr = &port->out_descr[0]; | ||
384 | port->prev_tr_descr = &port->out_descr[NBR_OUT_DESCR-1]; | ||
385 | port->catch_tr_descr = &port->out_descr[0]; | ||
386 | #endif | ||
299 | } | 387 | } |
300 | 388 | ||
301 | static inline int sync_data_avail(struct sync_port *port) | 389 | static inline int sync_data_avail(struct sync_port *port) |
@@ -311,7 +399,7 @@ static inline int sync_data_avail(struct sync_port *port) | |||
311 | * ^rp ^wp ^wp ^rp | 399 | * ^rp ^wp ^wp ^rp |
312 | */ | 400 | */ |
313 | 401 | ||
314 | if (end >= start) | 402 | if (end >= start) |
315 | avail = end - start; | 403 | avail = end - start; |
316 | else | 404 | else |
317 | avail = port->in_buffer_size - (start - end); | 405 | avail = port->in_buffer_size - (start - end); |
@@ -331,7 +419,7 @@ static inline int sync_data_avail_to_end(struct sync_port *port) | |||
331 | * ^rp ^wp ^wp ^rp | 419 | * ^rp ^wp ^wp ^rp |
332 | */ | 420 | */ |
333 | 421 | ||
334 | if (end >= start) | 422 | if (end >= start) |
335 | avail = end - start; | 423 | avail = end - start; |
336 | else | 424 | else |
337 | avail = port->flip + port->in_buffer_size - start; | 425 | avail = port->flip + port->in_buffer_size - start; |
@@ -341,66 +429,69 @@ static inline int sync_data_avail_to_end(struct sync_port *port) | |||
341 | static int sync_serial_open(struct inode *inode, struct file *file) | 429 | static int sync_serial_open(struct inode *inode, struct file *file) |
342 | { | 430 | { |
343 | int dev = iminor(inode); | 431 | int dev = iminor(inode); |
344 | sync_port* port; | 432 | sync_port *port; |
345 | reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; | 433 | reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; |
346 | reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes}; | 434 | reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes}; |
347 | 435 | ||
348 | DEBUG(printk("Open sync serial port %d\n", dev)); | 436 | DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); |
349 | 437 | ||
350 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) | 438 | if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) |
351 | { | 439 | { |
352 | DEBUG(printk("Invalid minor %d\n", dev)); | 440 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); |
353 | return -ENODEV; | 441 | return -ENODEV; |
354 | } | 442 | } |
355 | port = &ports[dev]; | 443 | port = &ports[dev]; |
356 | /* Allow open this device twice (assuming one reader and one writer) */ | 444 | /* Allow open this device twice (assuming one reader and one writer) */ |
357 | if (port->busy == 2) | 445 | if (port->busy == 2) |
358 | { | 446 | { |
359 | DEBUG(printk("Device is busy.. \n")); | 447 | DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); |
360 | return -EBUSY; | 448 | return -EBUSY; |
361 | } | 449 | } |
450 | |||
451 | |||
362 | if (port->init_irqs) { | 452 | if (port->init_irqs) { |
363 | if (port->use_dma) { | 453 | if (port->use_dma) { |
364 | if (port == &ports[0]){ | 454 | if (port == &ports[0]) { |
365 | #ifdef SYNC_SER_DMA | 455 | #ifdef SYNC_SER_DMA |
366 | if(request_irq(DMA4_INTR_VECT, | 456 | if (request_irq(DMA_OUT_INTR_VECT, |
367 | tr_interrupt, | 457 | tr_interrupt, |
368 | 0, | 458 | 0, |
369 | "synchronous serial 0 dma tr", | 459 | "synchronous serial 0 dma tr", |
370 | &ports[0])) { | 460 | &ports[0])) { |
371 | printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); | 461 | printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); |
372 | return -EBUSY; | 462 | return -EBUSY; |
373 | } else if(request_irq(DMA5_INTR_VECT, | 463 | } else if (request_irq(DMA_IN_INTR_VECT, |
374 | rx_interrupt, | 464 | rx_interrupt, |
375 | 0, | 465 | 0, |
376 | "synchronous serial 1 dma rx", | 466 | "synchronous serial 1 dma rx", |
377 | &ports[0])) { | 467 | &ports[0])) { |
378 | free_irq(DMA4_INTR_VECT, &port[0]); | 468 | free_irq(DMA_OUT_INTR_VECT, &port[0]); |
379 | printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); | 469 | printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); |
380 | return -EBUSY; | 470 | return -EBUSY; |
381 | } else if (crisv32_request_dma(SYNC_SER0_TX_DMA_NBR, | 471 | } else if (crisv32_request_dma(OUT_DMA_NBR, |
382 | "synchronous serial 0 dma tr", | 472 | "synchronous serial 0 dma tr", |
383 | DMA_VERBOSE_ON_ERROR, | 473 | DMA_VERBOSE_ON_ERROR, |
384 | 0, | 474 | 0, |
385 | dma_sser0)) { | 475 | REQ_DMA_SYNCSER)) { |
386 | free_irq(DMA4_INTR_VECT, &port[0]); | 476 | free_irq(DMA_OUT_INTR_VECT, &port[0]); |
387 | free_irq(DMA5_INTR_VECT, &port[0]); | 477 | free_irq(DMA_IN_INTR_VECT, &port[0]); |
388 | printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel"); | 478 | printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel"); |
389 | return -EBUSY; | 479 | return -EBUSY; |
390 | } else if (crisv32_request_dma(SYNC_SER0_RX_DMA_NBR, | 480 | } else if (crisv32_request_dma(IN_DMA_NBR, |
391 | "synchronous serial 0 dma rec", | 481 | "synchronous serial 0 dma rec", |
392 | DMA_VERBOSE_ON_ERROR, | 482 | DMA_VERBOSE_ON_ERROR, |
393 | 0, | 483 | 0, |
394 | dma_sser0)) { | 484 | REQ_DMA_SYNCSER)) { |
395 | crisv32_free_dma(SYNC_SER0_TX_DMA_NBR); | 485 | crisv32_free_dma(OUT_DMA_NBR); |
396 | free_irq(DMA4_INTR_VECT, &port[0]); | 486 | free_irq(DMA_OUT_INTR_VECT, &port[0]); |
397 | free_irq(DMA5_INTR_VECT, &port[0]); | 487 | free_irq(DMA_IN_INTR_VECT, &port[0]); |
398 | printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel"); | 488 | printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel"); |
399 | return -EBUSY; | 489 | return -EBUSY; |
400 | } | 490 | } |
401 | #endif | 491 | #endif |
402 | } | 492 | } |
403 | else if (port == &ports[1]){ | 493 | #ifdef CONFIG_ETRAXFS |
494 | else if (port == &ports[1]) { | ||
404 | #ifdef SYNC_SER_DMA | 495 | #ifdef SYNC_SER_DMA |
405 | if (request_irq(DMA6_INTR_VECT, | 496 | if (request_irq(DMA6_INTR_VECT, |
406 | tr_interrupt, | 497 | tr_interrupt, |
@@ -417,20 +508,22 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
417 | free_irq(DMA6_INTR_VECT, &ports[1]); | 508 | free_irq(DMA6_INTR_VECT, &ports[1]); |
418 | printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ"); | 509 | printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ"); |
419 | return -EBUSY; | 510 | return -EBUSY; |
420 | } else if (crisv32_request_dma(SYNC_SER1_TX_DMA_NBR, | 511 | } else if (crisv32_request_dma( |
421 | "synchronous serial 1 dma tr", | 512 | SYNC_SER1_TX_DMA_NBR, |
422 | DMA_VERBOSE_ON_ERROR, | 513 | "synchronous serial 1 dma tr", |
423 | 0, | 514 | DMA_VERBOSE_ON_ERROR, |
424 | dma_sser1)) { | 515 | 0, |
425 | free_irq(21, &ports[1]); | 516 | dma_sser1)) { |
426 | free_irq(20, &ports[1]); | 517 | free_irq(DMA6_INTR_VECT, &ports[1]); |
518 | free_irq(DMA7_INTR_VECT, &ports[1]); | ||
427 | printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel"); | 519 | printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel"); |
428 | return -EBUSY; | 520 | return -EBUSY; |
429 | } else if (crisv32_request_dma(SYNC_SER1_RX_DMA_NBR, | 521 | } else if (crisv32_request_dma( |
430 | "synchronous serial 3 dma rec", | 522 | SYNC_SER1_RX_DMA_NBR, |
431 | DMA_VERBOSE_ON_ERROR, | 523 | "synchronous serial 3 dma rec", |
432 | 0, | 524 | DMA_VERBOSE_ON_ERROR, |
433 | dma_sser1)) { | 525 | 0, |
526 | dma_sser1)) { | ||
434 | crisv32_free_dma(SYNC_SER1_TX_DMA_NBR); | 527 | crisv32_free_dma(SYNC_SER1_TX_DMA_NBR); |
435 | free_irq(DMA6_INTR_VECT, &ports[1]); | 528 | free_irq(DMA6_INTR_VECT, &ports[1]); |
436 | free_irq(DMA7_INTR_VECT, &ports[1]); | 529 | free_irq(DMA7_INTR_VECT, &ports[1]); |
@@ -439,14 +532,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
439 | } | 532 | } |
440 | #endif | 533 | #endif |
441 | } | 534 | } |
442 | 535 | #endif | |
443 | /* Enable DMAs */ | 536 | /* Enable DMAs */ |
444 | REG_WR(dma, port->regi_dmain, rw_cfg, cfg); | 537 | REG_WR(dma, port->regi_dmain, rw_cfg, cfg); |
445 | REG_WR(dma, port->regi_dmaout, rw_cfg, cfg); | 538 | REG_WR(dma, port->regi_dmaout, rw_cfg, cfg); |
446 | /* Enable DMA IRQs */ | 539 | /* Enable DMA IRQs */ |
447 | REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask); | 540 | REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask); |
448 | REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask); | 541 | REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask); |
449 | /* Set up wordsize = 2 for DMAs. */ | 542 | /* Set up wordsize = 1 for DMAs. */ |
450 | DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1); | 543 | DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1); |
451 | DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1); | 544 | DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1); |
452 | 545 | ||
@@ -455,7 +548,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
455 | } else { /* !port->use_dma */ | 548 | } else { /* !port->use_dma */ |
456 | #ifdef SYNC_SER_MANUAL | 549 | #ifdef SYNC_SER_MANUAL |
457 | if (port == &ports[0]) { | 550 | if (port == &ports[0]) { |
458 | if (request_irq(SSER0_INTR_VECT, | 551 | if (request_irq(SYNCSER_INTR_VECT, |
459 | manual_interrupt, | 552 | manual_interrupt, |
460 | 0, | 553 | 0, |
461 | "synchronous serial manual irq", | 554 | "synchronous serial manual irq", |
@@ -463,7 +556,9 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
463 | printk("Can't allocate sync serial manual irq"); | 556 | printk("Can't allocate sync serial manual irq"); |
464 | return -EBUSY; | 557 | return -EBUSY; |
465 | } | 558 | } |
466 | } else if (port == &ports[1]) { | 559 | } |
560 | #ifdef CONFIG_ETRAXFS | ||
561 | else if (port == &ports[1]) { | ||
467 | if (request_irq(SSER1_INTR_VECT, | 562 | if (request_irq(SSER1_INTR_VECT, |
468 | manual_interrupt, | 563 | manual_interrupt, |
469 | 0, | 564 | 0, |
@@ -473,11 +568,13 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
473 | return -EBUSY; | 568 | return -EBUSY; |
474 | } | 569 | } |
475 | } | 570 | } |
571 | #endif | ||
476 | port->init_irqs = 0; | 572 | port->init_irqs = 0; |
477 | #else | 573 | #else |
478 | panic("sync_serial: Manual mode not supported.\n"); | 574 | panic("sync_serial: Manual mode not supported.\n"); |
479 | #endif /* SYNC_SER_MANUAL */ | 575 | #endif /* SYNC_SER_MANUAL */ |
480 | } | 576 | } |
577 | |||
481 | } /* port->init_irqs */ | 578 | } /* port->init_irqs */ |
482 | 579 | ||
483 | port->busy++; | 580 | port->busy++; |
@@ -487,9 +584,9 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
487 | static int sync_serial_release(struct inode *inode, struct file *file) | 584 | static int sync_serial_release(struct inode *inode, struct file *file) |
488 | { | 585 | { |
489 | int dev = iminor(inode); | 586 | int dev = iminor(inode); |
490 | sync_port* port; | 587 | sync_port *port; |
491 | 588 | ||
492 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) | 589 | if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) |
493 | { | 590 | { |
494 | DEBUG(printk("Invalid minor %d\n", dev)); | 591 | DEBUG(printk("Invalid minor %d\n", dev)); |
495 | return -ENODEV; | 592 | return -ENODEV; |
@@ -506,17 +603,37 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait) | |||
506 | { | 603 | { |
507 | int dev = iminor(file->f_path.dentry->d_inode); | 604 | int dev = iminor(file->f_path.dentry->d_inode); |
508 | unsigned int mask = 0; | 605 | unsigned int mask = 0; |
509 | sync_port* port; | 606 | sync_port *port; |
510 | DEBUGPOLL( static unsigned int prev_mask = 0; ); | 607 | DEBUGPOLL( static unsigned int prev_mask = 0; ); |
511 | 608 | ||
512 | port = &ports[dev]; | 609 | port = &ports[dev]; |
610 | |||
611 | if (!port->started) { | ||
612 | reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg); | ||
613 | reg_sser_rw_rec_cfg rec_cfg = | ||
614 | REG_RD(sser, port->regi_sser, rw_rec_cfg); | ||
615 | cfg.en = regk_sser_yes; | ||
616 | rec_cfg.rec_en = port->input; | ||
617 | REG_WR(sser, port->regi_sser, rw_cfg, cfg); | ||
618 | REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); | ||
619 | port->started = 1; | ||
620 | } | ||
621 | |||
513 | poll_wait(file, &port->out_wait_q, wait); | 622 | poll_wait(file, &port->out_wait_q, wait); |
514 | poll_wait(file, &port->in_wait_q, wait); | 623 | poll_wait(file, &port->in_wait_q, wait); |
515 | /* Some room to write */ | 624 | |
516 | if (port->out_count < OUT_BUFFER_SIZE) | 625 | /* No active transfer, descriptors are available */ |
626 | if (port->output && !port->tr_running) | ||
627 | mask |= POLLOUT | POLLWRNORM; | ||
628 | |||
629 | /* Descriptor and buffer space available. */ | ||
630 | if (port->output && | ||
631 | port->active_tr_descr != port->catch_tr_descr && | ||
632 | port->out_buf_count < OUT_BUFFER_SIZE) | ||
517 | mask |= POLLOUT | POLLWRNORM; | 633 | mask |= POLLOUT | POLLWRNORM; |
634 | |||
518 | /* At least an inbufchunk of data */ | 635 | /* At least an inbufchunk of data */ |
519 | if (sync_data_avail(port) >= port->inbufchunk) | 636 | if (port->input && sync_data_avail(port) >= port->inbufchunk) |
520 | mask |= POLLIN | POLLRDNORM; | 637 | mask |= POLLIN | POLLRDNORM; |
521 | 638 | ||
522 | DEBUGPOLL(if (mask != prev_mask) | 639 | DEBUGPOLL(if (mask != prev_mask) |
@@ -531,15 +648,16 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
531 | unsigned int cmd, unsigned long arg) | 648 | unsigned int cmd, unsigned long arg) |
532 | { | 649 | { |
533 | int return_val = 0; | 650 | int return_val = 0; |
651 | int dma_w_size = regk_dma_set_w_size1; | ||
534 | int dev = iminor(file->f_path.dentry->d_inode); | 652 | int dev = iminor(file->f_path.dentry->d_inode); |
535 | sync_port* port; | 653 | sync_port *port; |
536 | reg_sser_rw_tr_cfg tr_cfg; | 654 | reg_sser_rw_tr_cfg tr_cfg; |
537 | reg_sser_rw_rec_cfg rec_cfg; | 655 | reg_sser_rw_rec_cfg rec_cfg; |
538 | reg_sser_rw_frm_cfg frm_cfg; | 656 | reg_sser_rw_frm_cfg frm_cfg; |
539 | reg_sser_rw_cfg gen_cfg; | 657 | reg_sser_rw_cfg gen_cfg; |
540 | reg_sser_rw_intr_mask intr_mask; | 658 | reg_sser_rw_intr_mask intr_mask; |
541 | 659 | ||
542 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) | 660 | if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) |
543 | { | 661 | { |
544 | DEBUG(printk("Invalid minor %d\n", dev)); | 662 | DEBUG(printk("Invalid minor %d\n", dev)); |
545 | return -1; | 663 | return -1; |
@@ -558,61 +676,81 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
558 | case SSP_SPEED: | 676 | case SSP_SPEED: |
559 | if (GET_SPEED(arg) == CODEC) | 677 | if (GET_SPEED(arg) == CODEC) |
560 | { | 678 | { |
679 | unsigned int freq; | ||
680 | |||
561 | gen_cfg.base_freq = regk_sser_f32; | 681 | gen_cfg.base_freq = regk_sser_f32; |
562 | /* FREQ = 0 => 4 MHz => clk_div = 7*/ | 682 | |
563 | gen_cfg.clk_div = 6 + (1 << GET_FREQ(arg)); | 683 | /* Clock divider will internally be |
564 | } | 684 | * gen_cfg.clk_div + 1. |
565 | else | 685 | */ |
566 | { | 686 | |
687 | freq = GET_FREQ(arg); | ||
688 | switch (freq) { | ||
689 | case FREQ_32kHz: | ||
690 | case FREQ_64kHz: | ||
691 | case FREQ_128kHz: | ||
692 | case FREQ_256kHz: | ||
693 | gen_cfg.clk_div = 125 * | ||
694 | (1 << (freq - FREQ_256kHz)) - 1; | ||
695 | break; | ||
696 | case FREQ_512kHz: | ||
697 | gen_cfg.clk_div = 62; | ||
698 | break; | ||
699 | case FREQ_1MHz: | ||
700 | case FREQ_2MHz: | ||
701 | case FREQ_4MHz: | ||
702 | gen_cfg.clk_div = 8 * (1 << freq) - 1; | ||
703 | break; | ||
704 | } | ||
705 | } else { | ||
567 | gen_cfg.base_freq = regk_sser_f29_493; | 706 | gen_cfg.base_freq = regk_sser_f29_493; |
568 | switch (GET_SPEED(arg)) | 707 | switch (GET_SPEED(arg)) { |
569 | { | 708 | case SSP150: |
570 | case SSP150: | 709 | gen_cfg.clk_div = 29493000 / (150 * 8) - 1; |
571 | gen_cfg.clk_div = 29493000 / (150 * 8) - 1; | 710 | break; |
572 | break; | 711 | case SSP300: |
573 | case SSP300: | 712 | gen_cfg.clk_div = 29493000 / (300 * 8) - 1; |
574 | gen_cfg.clk_div = 29493000 / (300 * 8) - 1; | 713 | break; |
575 | break; | 714 | case SSP600: |
576 | case SSP600: | 715 | gen_cfg.clk_div = 29493000 / (600 * 8) - 1; |
577 | gen_cfg.clk_div = 29493000 / (600 * 8) - 1; | 716 | break; |
578 | break; | 717 | case SSP1200: |
579 | case SSP1200: | 718 | gen_cfg.clk_div = 29493000 / (1200 * 8) - 1; |
580 | gen_cfg.clk_div = 29493000 / (1200 * 8) - 1; | 719 | break; |
581 | break; | 720 | case SSP2400: |
582 | case SSP2400: | 721 | gen_cfg.clk_div = 29493000 / (2400 * 8) - 1; |
583 | gen_cfg.clk_div = 29493000 / (2400 * 8) - 1; | 722 | break; |
584 | break; | 723 | case SSP4800: |
585 | case SSP4800: | 724 | gen_cfg.clk_div = 29493000 / (4800 * 8) - 1; |
586 | gen_cfg.clk_div = 29493000 / (4800 * 8) - 1; | 725 | break; |
587 | break; | 726 | case SSP9600: |
588 | case SSP9600: | 727 | gen_cfg.clk_div = 29493000 / (9600 * 8) - 1; |
589 | gen_cfg.clk_div = 29493000 / (9600 * 8) - 1; | 728 | break; |
590 | break; | 729 | case SSP19200: |
591 | case SSP19200: | 730 | gen_cfg.clk_div = 29493000 / (19200 * 8) - 1; |
592 | gen_cfg.clk_div = 29493000 / (19200 * 8) - 1; | 731 | break; |
593 | break; | 732 | case SSP28800: |
594 | case SSP28800: | 733 | gen_cfg.clk_div = 29493000 / (28800 * 8) - 1; |
595 | gen_cfg.clk_div = 29493000 / (28800 * 8) - 1; | 734 | break; |
596 | break; | 735 | case SSP57600: |
597 | case SSP57600: | 736 | gen_cfg.clk_div = 29493000 / (57600 * 8) - 1; |
598 | gen_cfg.clk_div = 29493000 / (57600 * 8) - 1; | 737 | break; |
599 | break; | 738 | case SSP115200: |
600 | case SSP115200: | 739 | gen_cfg.clk_div = 29493000 / (115200 * 8) - 1; |
601 | gen_cfg.clk_div = 29493000 / (115200 * 8) - 1; | 740 | break; |
602 | break; | 741 | case SSP230400: |
603 | case SSP230400: | 742 | gen_cfg.clk_div = 29493000 / (230400 * 8) - 1; |
604 | gen_cfg.clk_div = 29493000 / (230400 * 8) - 1; | 743 | break; |
605 | break; | 744 | case SSP460800: |
606 | case SSP460800: | 745 | gen_cfg.clk_div = 29493000 / (460800 * 8) - 1; |
607 | gen_cfg.clk_div = 29493000 / (460800 * 8) - 1; | 746 | break; |
608 | break; | 747 | case SSP921600: |
609 | case SSP921600: | 748 | gen_cfg.clk_div = 29493000 / (921600 * 8) - 1; |
610 | gen_cfg.clk_div = 29493000 / (921600 * 8) - 1; | 749 | break; |
611 | break; | 750 | case SSP3125000: |
612 | case SSP3125000: | 751 | gen_cfg.base_freq = regk_sser_f100; |
613 | gen_cfg.base_freq = regk_sser_f100; | 752 | gen_cfg.clk_div = 100000000 / (3125000 * 8) - 1; |
614 | gen_cfg.clk_div = 100000000 / (3125000 * 8) - 1; | 753 | break; |
615 | break; | ||
616 | 754 | ||
617 | } | 755 | } |
618 | } | 756 | } |
@@ -625,46 +763,60 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
625 | case MASTER_OUTPUT: | 763 | case MASTER_OUTPUT: |
626 | port->output = 1; | 764 | port->output = 1; |
627 | port->input = 0; | 765 | port->input = 0; |
766 | frm_cfg.out_on = regk_sser_tr; | ||
767 | frm_cfg.frame_pin_dir = regk_sser_out; | ||
628 | gen_cfg.clk_dir = regk_sser_out; | 768 | gen_cfg.clk_dir = regk_sser_out; |
629 | break; | 769 | break; |
630 | case SLAVE_OUTPUT: | 770 | case SLAVE_OUTPUT: |
631 | port->output = 1; | 771 | port->output = 1; |
632 | port->input = 0; | 772 | port->input = 0; |
773 | frm_cfg.frame_pin_dir = regk_sser_in; | ||
633 | gen_cfg.clk_dir = regk_sser_in; | 774 | gen_cfg.clk_dir = regk_sser_in; |
634 | break; | 775 | break; |
635 | case MASTER_INPUT: | 776 | case MASTER_INPUT: |
636 | port->output = 0; | 777 | port->output = 0; |
637 | port->input = 1; | 778 | port->input = 1; |
779 | frm_cfg.frame_pin_dir = regk_sser_out; | ||
780 | frm_cfg.out_on = regk_sser_intern_tb; | ||
638 | gen_cfg.clk_dir = regk_sser_out; | 781 | gen_cfg.clk_dir = regk_sser_out; |
639 | break; | 782 | break; |
640 | case SLAVE_INPUT: | 783 | case SLAVE_INPUT: |
641 | port->output = 0; | 784 | port->output = 0; |
642 | port->input = 1; | 785 | port->input = 1; |
786 | frm_cfg.frame_pin_dir = regk_sser_in; | ||
643 | gen_cfg.clk_dir = regk_sser_in; | 787 | gen_cfg.clk_dir = regk_sser_in; |
644 | break; | 788 | break; |
645 | case MASTER_BIDIR: | 789 | case MASTER_BIDIR: |
646 | port->output = 1; | 790 | port->output = 1; |
647 | port->input = 1; | 791 | port->input = 1; |
792 | frm_cfg.frame_pin_dir = regk_sser_out; | ||
793 | frm_cfg.out_on = regk_sser_intern_tb; | ||
648 | gen_cfg.clk_dir = regk_sser_out; | 794 | gen_cfg.clk_dir = regk_sser_out; |
649 | break; | 795 | break; |
650 | case SLAVE_BIDIR: | 796 | case SLAVE_BIDIR: |
651 | port->output = 1; | 797 | port->output = 1; |
652 | port->input = 1; | 798 | port->input = 1; |
799 | frm_cfg.frame_pin_dir = regk_sser_in; | ||
653 | gen_cfg.clk_dir = regk_sser_in; | 800 | gen_cfg.clk_dir = regk_sser_in; |
654 | break; | 801 | break; |
655 | default: | 802 | default: |
656 | spin_unlock_irq(&port->lock); | 803 | spin_unlock_irq(&port->lock); |
657 | return -EINVAL; | 804 | return -EINVAL; |
658 | |||
659 | } | 805 | } |
660 | if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)) | 806 | if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)) |
661 | intr_mask.rdav = regk_sser_yes; | 807 | intr_mask.rdav = regk_sser_yes; |
662 | break; | 808 | break; |
663 | case SSP_FRAME_SYNC: | 809 | case SSP_FRAME_SYNC: |
664 | if (arg & NORMAL_SYNC) | 810 | if (arg & NORMAL_SYNC) { |
811 | frm_cfg.rec_delay = 1; | ||
665 | frm_cfg.tr_delay = 1; | 812 | frm_cfg.tr_delay = 1; |
813 | } | ||
666 | else if (arg & EARLY_SYNC) | 814 | else if (arg & EARLY_SYNC) |
667 | frm_cfg.tr_delay = 0; | 815 | frm_cfg.rec_delay = frm_cfg.tr_delay = 0; |
816 | else if (arg & SECOND_WORD_SYNC) { | ||
817 | frm_cfg.rec_delay = 7; | ||
818 | frm_cfg.tr_delay = 1; | ||
819 | } | ||
668 | 820 | ||
669 | tr_cfg.bulk_wspace = frm_cfg.tr_delay; | 821 | tr_cfg.bulk_wspace = frm_cfg.tr_delay; |
670 | frm_cfg.early_wend = regk_sser_yes; | 822 | frm_cfg.early_wend = regk_sser_yes; |
@@ -680,9 +832,11 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
680 | else if (arg & SYNC_OFF) | 832 | else if (arg & SYNC_OFF) |
681 | frm_cfg.frame_pin_use = regk_sser_gio0; | 833 | frm_cfg.frame_pin_use = regk_sser_gio0; |
682 | 834 | ||
683 | if (arg & WORD_SIZE_8) | 835 | dma_w_size = regk_dma_set_w_size2; |
836 | if (arg & WORD_SIZE_8) { | ||
684 | rec_cfg.sample_size = tr_cfg.sample_size = 7; | 837 | rec_cfg.sample_size = tr_cfg.sample_size = 7; |
685 | else if (arg & WORD_SIZE_12) | 838 | dma_w_size = regk_dma_set_w_size1; |
839 | } else if (arg & WORD_SIZE_12) | ||
686 | rec_cfg.sample_size = tr_cfg.sample_size = 11; | 840 | rec_cfg.sample_size = tr_cfg.sample_size = 11; |
687 | else if (arg & WORD_SIZE_16) | 841 | else if (arg & WORD_SIZE_16) |
688 | rec_cfg.sample_size = tr_cfg.sample_size = 15; | 842 | rec_cfg.sample_size = tr_cfg.sample_size = 15; |
@@ -696,10 +850,13 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
696 | else if (arg & BIT_ORDER_LSB) | 850 | else if (arg & BIT_ORDER_LSB) |
697 | rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst; | 851 | rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst; |
698 | 852 | ||
699 | if (arg & FLOW_CONTROL_ENABLE) | 853 | if (arg & FLOW_CONTROL_ENABLE) { |
854 | frm_cfg.status_pin_use = regk_sser_frm; | ||
700 | rec_cfg.fifo_thr = regk_sser_thr16; | 855 | rec_cfg.fifo_thr = regk_sser_thr16; |
701 | else if (arg & FLOW_CONTROL_DISABLE) | 856 | } else if (arg & FLOW_CONTROL_DISABLE) { |
857 | frm_cfg.status_pin_use = regk_sser_gio0; | ||
702 | rec_cfg.fifo_thr = regk_sser_inf; | 858 | rec_cfg.fifo_thr = regk_sser_inf; |
859 | } | ||
703 | 860 | ||
704 | if (arg & CLOCK_NOT_GATED) | 861 | if (arg & CLOCK_NOT_GATED) |
705 | gen_cfg.gate_clk = regk_sser_no; | 862 | gen_cfg.gate_clk = regk_sser_no; |
@@ -726,9 +883,9 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
726 | break; | 883 | break; |
727 | case SSP_OPOLARITY: | 884 | case SSP_OPOLARITY: |
728 | if (arg & CLOCK_NORMAL) | 885 | if (arg & CLOCK_NORMAL) |
729 | gen_cfg.out_clk_pol = regk_sser_neg; | ||
730 | else if (arg & CLOCK_INVERT) | ||
731 | gen_cfg.out_clk_pol = regk_sser_pos; | 886 | gen_cfg.out_clk_pol = regk_sser_pos; |
887 | else if (arg & CLOCK_INVERT) | ||
888 | gen_cfg.out_clk_pol = regk_sser_neg; | ||
732 | 889 | ||
733 | if (arg & FRAME_NORMAL) | 890 | if (arg & FRAME_NORMAL) |
734 | frm_cfg.level = regk_sser_pos_hi; | 891 | frm_cfg.level = regk_sser_pos_hi; |
@@ -770,10 +927,9 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
770 | } | 927 | } |
771 | 928 | ||
772 | 929 | ||
773 | if (port->started) | 930 | if (port->started) { |
774 | { | ||
775 | tr_cfg.tr_en = port->output; | ||
776 | rec_cfg.rec_en = port->input; | 931 | rec_cfg.rec_en = port->input; |
932 | gen_cfg.en = (port->output | port->input); | ||
777 | } | 933 | } |
778 | 934 | ||
779 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); | 935 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); |
@@ -782,138 +938,145 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, | |||
782 | REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); | 938 | REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); |
783 | REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg); | 939 | REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg); |
784 | 940 | ||
941 | |||
942 | if (cmd == SSP_FRAME_SYNC && (arg & (WORD_SIZE_8 | WORD_SIZE_12 | | ||
943 | WORD_SIZE_16 | WORD_SIZE_24 | WORD_SIZE_32))) { | ||
944 | int en = gen_cfg.en; | ||
945 | gen_cfg.en = 0; | ||
946 | REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg); | ||
947 | /* ##### Should DMA be stoped before we change dma size? */ | ||
948 | DMA_WR_CMD(port->regi_dmain, dma_w_size); | ||
949 | DMA_WR_CMD(port->regi_dmaout, dma_w_size); | ||
950 | gen_cfg.en = en; | ||
951 | REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg); | ||
952 | } | ||
953 | |||
785 | spin_unlock_irq(&port->lock); | 954 | spin_unlock_irq(&port->lock); |
786 | return return_val; | 955 | return return_val; |
787 | } | 956 | } |
788 | 957 | ||
789 | static ssize_t sync_serial_write(struct file * file, const char * buf, | 958 | /* NOTE: sync_serial_write does not support concurrency */ |
790 | size_t count, loff_t *ppos) | 959 | static ssize_t sync_serial_write(struct file *file, const char *buf, |
960 | size_t count, loff_t *ppos) | ||
791 | { | 961 | { |
792 | int dev = iminor(file->f_path.dentry->d_inode); | 962 | int dev = iminor(file->f_path.dentry->d_inode); |
793 | DECLARE_WAITQUEUE(wait, current); | 963 | DECLARE_WAITQUEUE(wait, current); |
794 | sync_port *port; | 964 | struct sync_port *port; |
795 | unsigned long c, c1; | 965 | int trunc_count; |
796 | unsigned long free_outp; | ||
797 | unsigned long outp; | ||
798 | unsigned long out_buffer; | ||
799 | unsigned long flags; | 966 | unsigned long flags; |
967 | int bytes_free; | ||
968 | int out_buf_count; | ||
800 | 969 | ||
801 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) | 970 | unsigned char *rd_ptr; /* First allocated byte in the buffer */ |
802 | { | 971 | unsigned char *wr_ptr; /* First free byte in the buffer */ |
972 | unsigned char *buf_stop_ptr; /* Last byte + 1 */ | ||
973 | |||
974 | if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) { | ||
803 | DEBUG(printk("Invalid minor %d\n", dev)); | 975 | DEBUG(printk("Invalid minor %d\n", dev)); |
804 | return -ENODEV; | 976 | return -ENODEV; |
805 | } | 977 | } |
806 | port = &ports[dev]; | 978 | port = &ports[dev]; |
807 | 979 | ||
808 | DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE)); | 980 | /* |<- OUT_BUFFER_SIZE ->| |
809 | /* Space to end of buffer */ | 981 | * |<- out_buf_count ->| |
810 | /* | 982 | * |<- trunc_count ->| ...->| |
811 | * out_buffer <c1>012345<- c ->OUT_BUFFER_SIZE | 983 | * ______________________________________________________ |
812 | * outp^ +out_count | 984 | * | free | data | free | |
813 | ^free_outp | 985 | * |_________|___________________|________________________| |
814 | * out_buffer 45<- c ->0123OUT_BUFFER_SIZE | 986 | * ^ rd_ptr ^ wr_ptr |
815 | * +out_count outp^ | ||
816 | * free_outp | ||
817 | * | ||
818 | */ | 987 | */ |
988 | DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu a: %p c: %p\n", | ||
989 | port->port_nbr, count, port->active_tr_descr, | ||
990 | port->catch_tr_descr)); | ||
819 | 991 | ||
820 | /* Read variables that may be updated by interrupts */ | 992 | /* Read variables that may be updated by interrupts */ |
821 | spin_lock_irqsave(&port->lock, flags); | 993 | spin_lock_irqsave(&port->lock, flags); |
822 | count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE - port->out_count : count; | 994 | rd_ptr = port->out_rd_ptr; |
823 | outp = (unsigned long)port->outp; | 995 | out_buf_count = port->out_buf_count; |
824 | free_outp = outp + port->out_count; | ||
825 | spin_unlock_irqrestore(&port->lock, flags); | 996 | spin_unlock_irqrestore(&port->lock, flags); |
826 | out_buffer = (unsigned long)port->out_buffer; | ||
827 | 997 | ||
828 | /* Find out where and how much to write */ | 998 | /* Check if resources are available */ |
829 | if (free_outp >= out_buffer + OUT_BUFFER_SIZE) | 999 | if (port->tr_running && |
830 | free_outp -= OUT_BUFFER_SIZE; | 1000 | ((port->use_dma && port->active_tr_descr == port->catch_tr_descr) || |
831 | if (free_outp >= outp) | 1001 | out_buf_count >= OUT_BUFFER_SIZE)) { |
832 | c = out_buffer + OUT_BUFFER_SIZE - free_outp; | 1002 | DEBUGWRITE(printk(KERN_DEBUG "sser%d full\n", dev)); |
833 | else | 1003 | return -EAGAIN; |
834 | c = outp - free_outp; | 1004 | } |
835 | if (c > count) | 1005 | |
836 | c = count; | 1006 | buf_stop_ptr = port->out_buffer + OUT_BUFFER_SIZE; |
1007 | |||
1008 | /* Determine pointer to the first free byte, before copying. */ | ||
1009 | wr_ptr = rd_ptr + out_buf_count; | ||
1010 | if (wr_ptr >= buf_stop_ptr) | ||
1011 | wr_ptr -= OUT_BUFFER_SIZE; | ||
837 | 1012 | ||
838 | // DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c)); | 1013 | /* If we wrap the ring buffer, let the user space program handle it by |
839 | if (copy_from_user((void*)free_outp, buf, c)) | 1014 | * truncating the data. This could be more elegant, small buffer |
1015 | * fragments may occur. | ||
1016 | */ | ||
1017 | bytes_free = OUT_BUFFER_SIZE - out_buf_count; | ||
1018 | if (wr_ptr + bytes_free > buf_stop_ptr) | ||
1019 | bytes_free = buf_stop_ptr - wr_ptr; | ||
1020 | trunc_count = (count < bytes_free) ? count : bytes_free; | ||
1021 | |||
1022 | if (copy_from_user(wr_ptr, buf, trunc_count)) | ||
840 | return -EFAULT; | 1023 | return -EFAULT; |
841 | 1024 | ||
842 | if (c != count) { | 1025 | DEBUGOUTBUF(printk(KERN_DEBUG "%-4d + %-4d = %-4d %p %p %p\n", |
843 | buf += c; | 1026 | out_buf_count, trunc_count, |
844 | c1 = count - c; | 1027 | port->out_buf_count, port->out_buffer, |
845 | DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1)); | 1028 | wr_ptr, buf_stop_ptr)); |
846 | if (copy_from_user((void*)out_buffer, buf, c1)) | ||
847 | return -EFAULT; | ||
848 | } | ||
849 | spin_lock_irqsave(&port->lock, flags); | ||
850 | port->out_count += count; | ||
851 | spin_unlock_irqrestore(&port->lock, flags); | ||
852 | 1029 | ||
853 | /* Make sure transmitter/receiver is running */ | 1030 | /* Make sure transmitter/receiver is running */ |
854 | if (!port->started) | 1031 | if (!port->started) { |
855 | { | ||
856 | reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg); | 1032 | reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg); |
857 | reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg); | ||
858 | reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg); | 1033 | reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg); |
859 | cfg.en = regk_sser_yes; | 1034 | cfg.en = regk_sser_yes; |
860 | tr_cfg.tr_en = port->output; | ||
861 | rec_cfg.rec_en = port->input; | 1035 | rec_cfg.rec_en = port->input; |
862 | REG_WR(sser, port->regi_sser, rw_cfg, cfg); | 1036 | REG_WR(sser, port->regi_sser, rw_cfg, cfg); |
863 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); | ||
864 | REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); | 1037 | REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); |
865 | port->started = 1; | 1038 | port->started = 1; |
866 | } | 1039 | } |
867 | 1040 | ||
868 | if (file->f_flags & O_NONBLOCK) { | 1041 | /* Setup wait if blocking */ |
869 | spin_lock_irqsave(&port->lock, flags); | 1042 | if (!(file->f_flags & O_NONBLOCK)) { |
870 | if (!port->tr_running) { | 1043 | add_wait_queue(&port->out_wait_q, &wait); |
871 | if (!port->use_dma) { | 1044 | set_current_state(TASK_INTERRUPTIBLE); |
872 | reg_sser_rw_intr_mask intr_mask; | ||
873 | intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); | ||
874 | /* Start sender by writing data */ | ||
875 | send_word(port); | ||
876 | /* and enable transmitter ready IRQ */ | ||
877 | intr_mask.trdy = 1; | ||
878 | REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); | ||
879 | } else { | ||
880 | start_dma(port, (unsigned char* volatile )port->outp, c); | ||
881 | } | ||
882 | } | ||
883 | spin_unlock_irqrestore(&port->lock, flags); | ||
884 | DEBUGWRITE(printk("w d%d c %lu NB\n", | ||
885 | port->port_nbr, count)); | ||
886 | return count; | ||
887 | } | 1045 | } |
888 | 1046 | ||
889 | /* Sleep until all sent */ | ||
890 | |||
891 | add_wait_queue(&port->out_wait_q, &wait); | ||
892 | set_current_state(TASK_INTERRUPTIBLE); | ||
893 | spin_lock_irqsave(&port->lock, flags); | 1047 | spin_lock_irqsave(&port->lock, flags); |
894 | if (!port->tr_running) { | 1048 | port->out_buf_count += trunc_count; |
895 | if (!port->use_dma) { | 1049 | if (port->use_dma) { |
896 | reg_sser_rw_intr_mask intr_mask; | 1050 | start_dma_out(port, wr_ptr, trunc_count); |
897 | intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); | 1051 | } else if (!port->tr_running) { |
898 | /* Start sender by writing data */ | 1052 | reg_sser_rw_intr_mask intr_mask; |
899 | send_word(port); | 1053 | intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); |
900 | /* and enable transmitter ready IRQ */ | 1054 | /* Start sender by writing data */ |
901 | intr_mask.trdy = 1; | 1055 | send_word(port); |
902 | REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); | 1056 | /* and enable transmitter ready IRQ */ |
903 | } else { | 1057 | intr_mask.trdy = 1; |
904 | start_dma(port, port->outp, c); | 1058 | REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); |
905 | } | ||
906 | } | 1059 | } |
907 | spin_unlock_irqrestore(&port->lock, flags); | 1060 | spin_unlock_irqrestore(&port->lock, flags); |
1061 | |||
1062 | /* Exit if non blocking */ | ||
1063 | if (file->f_flags & O_NONBLOCK) { | ||
1064 | DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu %08x\n", | ||
1065 | port->port_nbr, trunc_count, | ||
1066 | REG_RD_INT(dma, port->regi_dmaout, r_intr))); | ||
1067 | return trunc_count; | ||
1068 | } | ||
1069 | |||
908 | schedule(); | 1070 | schedule(); |
909 | set_current_state(TASK_RUNNING); | 1071 | set_current_state(TASK_RUNNING); |
910 | remove_wait_queue(&port->out_wait_q, &wait); | 1072 | remove_wait_queue(&port->out_wait_q, &wait); |
1073 | |||
911 | if (signal_pending(current)) | 1074 | if (signal_pending(current)) |
912 | { | ||
913 | return -EINTR; | 1075 | return -EINTR; |
914 | } | 1076 | |
915 | DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count)); | 1077 | DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n", |
916 | return count; | 1078 | port->port_nbr, trunc_count)); |
1079 | return trunc_count; | ||
917 | } | 1080 | } |
918 | 1081 | ||
919 | static ssize_t sync_serial_read(struct file * file, char * buf, | 1082 | static ssize_t sync_serial_read(struct file * file, char * buf, |
@@ -926,7 +1089,7 @@ static ssize_t sync_serial_read(struct file * file, char * buf, | |||
926 | unsigned char* end; | 1089 | unsigned char* end; |
927 | unsigned long flags; | 1090 | unsigned long flags; |
928 | 1091 | ||
929 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) | 1092 | if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) |
930 | { | 1093 | { |
931 | DEBUG(printk("Invalid minor %d\n", dev)); | 1094 | DEBUG(printk("Invalid minor %d\n", dev)); |
932 | return -ENODEV; | 1095 | return -ENODEV; |
@@ -949,7 +1112,6 @@ static ssize_t sync_serial_read(struct file * file, char * buf, | |||
949 | port->started = 1; | 1112 | port->started = 1; |
950 | } | 1113 | } |
951 | 1114 | ||
952 | |||
953 | /* Calculate number of available bytes */ | 1115 | /* Calculate number of available bytes */ |
954 | /* Save pointers to avoid that they are modified by interrupt */ | 1116 | /* Save pointers to avoid that they are modified by interrupt */ |
955 | spin_lock_irqsave(&port->lock, flags); | 1117 | spin_lock_irqsave(&port->lock, flags); |
@@ -958,16 +1120,14 @@ static ssize_t sync_serial_read(struct file * file, char * buf, | |||
958 | spin_unlock_irqrestore(&port->lock, flags); | 1120 | spin_unlock_irqrestore(&port->lock, flags); |
959 | while ((start == end) && !port->full) /* No data */ | 1121 | while ((start == end) && !port->full) /* No data */ |
960 | { | 1122 | { |
1123 | DEBUGREAD(printk(KERN_DEBUG "&")); | ||
961 | if (file->f_flags & O_NONBLOCK) | 1124 | if (file->f_flags & O_NONBLOCK) |
962 | { | ||
963 | return -EAGAIN; | 1125 | return -EAGAIN; |
964 | } | ||
965 | 1126 | ||
966 | interruptible_sleep_on(&port->in_wait_q); | 1127 | interruptible_sleep_on(&port->in_wait_q); |
967 | if (signal_pending(current)) | 1128 | if (signal_pending(current)) |
968 | { | ||
969 | return -EINTR; | 1129 | return -EINTR; |
970 | } | 1130 | |
971 | spin_lock_irqsave(&port->lock, flags); | 1131 | spin_lock_irqsave(&port->lock, flags); |
972 | start = (unsigned char*)port->readp; /* cast away volatile */ | 1132 | start = (unsigned char*)port->readp; /* cast away volatile */ |
973 | end = (unsigned char*)port->writep; /* cast away volatile */ | 1133 | end = (unsigned char*)port->writep; /* cast away volatile */ |
@@ -1004,83 +1164,105 @@ static void send_word(sync_port* port) | |||
1004 | switch(tr_cfg.sample_size) | 1164 | switch(tr_cfg.sample_size) |
1005 | { | 1165 | { |
1006 | case 8: | 1166 | case 8: |
1007 | port->out_count--; | 1167 | port->out_buf_count--; |
1008 | tr_data.data = *port->outp++; | 1168 | tr_data.data = *port->out_rd_ptr++; |
1009 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1169 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1010 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | 1170 | if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE) |
1011 | port->outp = port->out_buffer; | 1171 | port->out_rd_ptr = port->out_buffer; |
1012 | break; | 1172 | break; |
1013 | case 12: | 1173 | case 12: |
1014 | { | 1174 | { |
1015 | int data = (*port->outp++) << 8; | 1175 | int data = (*port->out_rd_ptr++) << 8; |
1016 | data |= *port->outp++; | 1176 | data |= *port->out_rd_ptr++; |
1017 | port->out_count-=2; | 1177 | port->out_buf_count -= 2; |
1018 | tr_data.data = data; | 1178 | tr_data.data = data; |
1019 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1179 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1020 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | 1180 | if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE) |
1021 | port->outp = port->out_buffer; | 1181 | port->out_rd_ptr = port->out_buffer; |
1022 | } | 1182 | } |
1023 | break; | 1183 | break; |
1024 | case 16: | 1184 | case 16: |
1025 | port->out_count-=2; | 1185 | port->out_buf_count -= 2; |
1026 | tr_data.data = *(unsigned short *)port->outp; | 1186 | tr_data.data = *(unsigned short *)port->out_rd_ptr; |
1027 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1187 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1028 | port->outp+=2; | 1188 | port->out_rd_ptr += 2; |
1029 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | 1189 | if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE) |
1030 | port->outp = port->out_buffer; | 1190 | port->out_rd_ptr = port->out_buffer; |
1031 | break; | 1191 | break; |
1032 | case 24: | 1192 | case 24: |
1033 | port->out_count-=3; | 1193 | port->out_buf_count -= 3; |
1034 | tr_data.data = *(unsigned short *)port->outp; | 1194 | tr_data.data = *(unsigned short *)port->out_rd_ptr; |
1035 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1195 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1036 | port->outp+=2; | 1196 | port->out_rd_ptr += 2; |
1037 | tr_data.data = *port->outp++; | 1197 | tr_data.data = *port->out_rd_ptr++; |
1038 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1198 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1039 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | 1199 | if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE) |
1040 | port->outp = port->out_buffer; | 1200 | port->out_rd_ptr = port->out_buffer; |
1041 | break; | 1201 | break; |
1042 | case 32: | 1202 | case 32: |
1043 | port->out_count-=4; | 1203 | port->out_buf_count -= 4; |
1044 | tr_data.data = *(unsigned short *)port->outp; | 1204 | tr_data.data = *(unsigned short *)port->out_rd_ptr; |
1045 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1205 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1046 | port->outp+=2; | 1206 | port->out_rd_ptr += 2; |
1047 | tr_data.data = *(unsigned short *)port->outp; | 1207 | tr_data.data = *(unsigned short *)port->out_rd_ptr; |
1048 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); | 1208 | REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); |
1049 | port->outp+=2; | 1209 | port->out_rd_ptr += 2; |
1050 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | 1210 | if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE) |
1051 | port->outp = port->out_buffer; | 1211 | port->out_rd_ptr = port->out_buffer; |
1052 | break; | 1212 | break; |
1053 | } | 1213 | } |
1054 | } | 1214 | } |
1055 | 1215 | ||
1056 | 1216 | static void start_dma_out(struct sync_port *port, | |
1057 | static void start_dma(struct sync_port* port, const char* data, int count) | 1217 | const char *data, int count) |
1058 | { | 1218 | { |
1059 | port->tr_running = 1; | 1219 | port->active_tr_descr->buf = (char *) virt_to_phys((char *) data); |
1060 | port->out_descr.buf = (char*)virt_to_phys((char*)data); | 1220 | port->active_tr_descr->after = port->active_tr_descr->buf + count; |
1061 | port->out_descr.after = port->out_descr.buf + count; | 1221 | port->active_tr_descr->intr = 1; |
1062 | port->out_descr.eol = port->out_descr.intr = 1; | 1222 | |
1223 | port->active_tr_descr->eol = 1; | ||
1224 | port->prev_tr_descr->eol = 0; | ||
1225 | |||
1226 | DEBUGTRDMA(printk(KERN_DEBUG "Inserting eolr:%p eol@:%p\n", | ||
1227 | port->prev_tr_descr, port->active_tr_descr)); | ||
1228 | port->prev_tr_descr = port->active_tr_descr; | ||
1229 | port->active_tr_descr = phys_to_virt((int) port->active_tr_descr->next); | ||
1230 | |||
1231 | if (!port->tr_running) { | ||
1232 | reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, | ||
1233 | rw_tr_cfg); | ||
1063 | 1234 | ||
1064 | port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr); | 1235 | port->out_context.next = 0; |
1065 | port->out_context.saved_data_buf = port->out_descr.buf; | 1236 | port->out_context.saved_data = |
1237 | (dma_descr_data *)virt_to_phys(port->prev_tr_descr); | ||
1238 | port->out_context.saved_data_buf = port->prev_tr_descr->buf; | ||
1239 | |||
1240 | DMA_START_CONTEXT(port->regi_dmaout, | ||
1241 | virt_to_phys((char *)&port->out_context)); | ||
1242 | |||
1243 | tr_cfg.tr_en = regk_sser_yes; | ||
1244 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); | ||
1245 | DEBUGTRDMA(printk(KERN_DEBUG "dma s\n");); | ||
1246 | } else { | ||
1247 | DMA_CONTINUE_DATA(port->regi_dmaout); | ||
1248 | DEBUGTRDMA(printk(KERN_DEBUG "dma c\n");); | ||
1249 | } | ||
1066 | 1250 | ||
1067 | DMA_START_CONTEXT(port->regi_dmaout, virt_to_phys((char*)&port->out_context)); | 1251 | port->tr_running = 1; |
1068 | DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count)); | ||
1069 | } | 1252 | } |
1070 | 1253 | ||
1071 | static void start_dma_in(sync_port* port) | 1254 | static void start_dma_in(sync_port *port) |
1072 | { | 1255 | { |
1073 | int i; | 1256 | int i; |
1074 | char* buf; | 1257 | char *buf; |
1075 | port->writep = port->flip; | 1258 | port->writep = port->flip; |
1076 | 1259 | ||
1077 | if (port->writep > port->flip + port->in_buffer_size) | 1260 | if (port->writep > port->flip + port->in_buffer_size) { |
1078 | { | ||
1079 | panic("Offset too large in sync serial driver\n"); | 1261 | panic("Offset too large in sync serial driver\n"); |
1080 | return; | 1262 | return; |
1081 | } | 1263 | } |
1082 | buf = (char*)virt_to_phys(port->in_buffer); | 1264 | buf = (char*)virt_to_phys(port->in_buffer); |
1083 | for (i = 0; i < NUM_IN_DESCR; i++) { | 1265 | for (i = 0; i < NBR_IN_DESCR; i++) { |
1084 | port->in_descr[i].buf = buf; | 1266 | port->in_descr[i].buf = buf; |
1085 | port->in_descr[i].after = buf + port->inbufchunk; | 1267 | port->in_descr[i].after = buf + port->inbufchunk; |
1086 | port->in_descr[i].intr = 1; | 1268 | port->in_descr[i].intr = 1; |
@@ -1092,59 +1274,126 @@ static void start_dma_in(sync_port* port) | |||
1092 | port->in_descr[i-1].next = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); | 1274 | port->in_descr[i-1].next = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); |
1093 | port->in_descr[i-1].eol = regk_sser_yes; | 1275 | port->in_descr[i-1].eol = regk_sser_yes; |
1094 | port->next_rx_desc = &port->in_descr[0]; | 1276 | port->next_rx_desc = &port->in_descr[0]; |
1095 | port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1]; | 1277 | port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR - 1]; |
1096 | port->in_context.saved_data = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); | 1278 | port->in_context.saved_data = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); |
1097 | port->in_context.saved_data_buf = port->in_descr[0].buf; | 1279 | port->in_context.saved_data_buf = port->in_descr[0].buf; |
1098 | DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context)); | 1280 | DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context)); |
1099 | } | 1281 | } |
1100 | 1282 | ||
1101 | #ifdef SYNC_SER_DMA | 1283 | #ifdef SYNC_SER_DMA |
1102 | static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) | 1284 | static irqreturn_t tr_interrupt(int irq, void *dev_id) |
1103 | { | 1285 | { |
1104 | reg_dma_r_masked_intr masked; | 1286 | reg_dma_r_masked_intr masked; |
1105 | reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; | 1287 | reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; |
1288 | reg_dma_rw_stat stat; | ||
1106 | int i; | 1289 | int i; |
1107 | struct dma_descr_data *descr; | ||
1108 | unsigned int sentl; | ||
1109 | int found = 0; | 1290 | int found = 0; |
1291 | int stop_sser = 0; | ||
1110 | 1292 | ||
1111 | for (i = 0; i < NUMBER_OF_PORTS; i++) | 1293 | for (i = 0; i < NBR_PORTS; i++) { |
1112 | { | ||
1113 | sync_port *port = &ports[i]; | 1294 | sync_port *port = &ports[i]; |
1114 | if (!port->enabled || !port->use_dma ) | 1295 | if (!port->enabled || !port->use_dma) |
1115 | continue; | 1296 | continue; |
1116 | 1297 | ||
1298 | /* IRQ active for the port? */ | ||
1117 | masked = REG_RD(dma, port->regi_dmaout, r_masked_intr); | 1299 | masked = REG_RD(dma, port->regi_dmaout, r_masked_intr); |
1300 | if (!masked.data) | ||
1301 | continue; | ||
1118 | 1302 | ||
1119 | if (masked.data) /* IRQ active for the port? */ | 1303 | found = 1; |
1120 | { | 1304 | |
1121 | found = 1; | 1305 | /* Check if we should stop the DMA transfer */ |
1122 | /* Clear IRQ */ | 1306 | stat = REG_RD(dma, port->regi_dmaout, rw_stat); |
1123 | REG_WR(dma, port->regi_dmaout, rw_ack_intr, ack_intr); | 1307 | if (stat.list_state == regk_dma_data_at_eol) |
1124 | descr = &port->out_descr; | 1308 | stop_sser = 1; |
1125 | sentl = descr->after - descr->buf; | 1309 | |
1126 | port->out_count -= sentl; | 1310 | /* Clear IRQ */ |
1127 | port->outp += sentl; | 1311 | REG_WR(dma, port->regi_dmaout, rw_ack_intr, ack_intr); |
1128 | if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE) | 1312 | |
1129 | port->outp = port->out_buffer; | 1313 | if (!stop_sser) { |
1130 | if (port->out_count) { | 1314 | /* The DMA has completed a descriptor, EOL was not |
1131 | int c; | 1315 | * encountered, so step relevant descriptor and |
1132 | c = port->out_buffer + OUT_BUFFER_SIZE - port->outp; | 1316 | * datapointers forward. */ |
1133 | if (c > port->out_count) | 1317 | int sent; |
1134 | c = port->out_count; | 1318 | sent = port->catch_tr_descr->after - |
1135 | DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c)); | 1319 | port->catch_tr_descr->buf; |
1136 | start_dma(port, port->outp, c); | 1320 | DEBUGTXINT(printk(KERN_DEBUG "%-4d - %-4d = %-4d\t" |
1137 | } else { | 1321 | "in descr %p (ac: %p)\n", |
1138 | DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl)); | 1322 | port->out_buf_count, sent, |
1139 | port->tr_running = 0; | 1323 | port->out_buf_count - sent, |
1324 | port->catch_tr_descr, | ||
1325 | port->active_tr_descr);); | ||
1326 | port->out_buf_count -= sent; | ||
1327 | port->catch_tr_descr = | ||
1328 | phys_to_virt((int) port->catch_tr_descr->next); | ||
1329 | port->out_rd_ptr = | ||
1330 | phys_to_virt((int) port->catch_tr_descr->buf); | ||
1331 | } else { | ||
1332 | int i, sent; | ||
1333 | /* EOL handler. | ||
1334 | * Note that if an EOL was encountered during the irq | ||
1335 | * locked section of sync_ser_write the DMA will be | ||
1336 | * restarted and the eol flag will be cleared. | ||
1337 | * The remaining descriptors will be traversed by | ||
1338 | * the descriptor interrupts as usual. | ||
1339 | */ | ||
1340 | i = 0; | ||
1341 | while (!port->catch_tr_descr->eol) { | ||
1342 | sent = port->catch_tr_descr->after - | ||
1343 | port->catch_tr_descr->buf; | ||
1344 | DEBUGOUTBUF(printk(KERN_DEBUG | ||
1345 | "traversing descr %p -%d (%d)\n", | ||
1346 | port->catch_tr_descr, | ||
1347 | sent, | ||
1348 | port->out_buf_count)); | ||
1349 | port->out_buf_count -= sent; | ||
1350 | port->catch_tr_descr = phys_to_virt( | ||
1351 | (int)port->catch_tr_descr->next); | ||
1352 | i++; | ||
1353 | if (i >= NBR_OUT_DESCR) { | ||
1354 | /* TODO: Reset and recover */ | ||
1355 | panic("sync_serial: missing eol"); | ||
1356 | } | ||
1140 | } | 1357 | } |
1141 | wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */ | 1358 | sent = port->catch_tr_descr->after - |
1359 | port->catch_tr_descr->buf; | ||
1360 | DEBUGOUTBUF(printk(KERN_DEBUG | ||
1361 | "eol at descr %p -%d (%d)\n", | ||
1362 | port->catch_tr_descr, | ||
1363 | sent, | ||
1364 | port->out_buf_count)); | ||
1365 | |||
1366 | port->out_buf_count -= sent; | ||
1367 | |||
1368 | /* Update read pointer to first free byte, we | ||
1369 | * may already be writing data there. */ | ||
1370 | port->out_rd_ptr = | ||
1371 | phys_to_virt((int) port->catch_tr_descr->after); | ||
1372 | if (port->out_rd_ptr > port->out_buffer + | ||
1373 | OUT_BUFFER_SIZE) | ||
1374 | port->out_rd_ptr = port->out_buffer; | ||
1375 | |||
1376 | reg_sser_rw_tr_cfg tr_cfg = | ||
1377 | REG_RD(sser, port->regi_sser, rw_tr_cfg); | ||
1378 | DEBUGTXINT(printk(KERN_DEBUG | ||
1379 | "tr_int DMA stop %d, set catch @ %p\n", | ||
1380 | port->out_buf_count, | ||
1381 | port->active_tr_descr)); | ||
1382 | if (port->out_buf_count != 0) | ||
1383 | printk(KERN_CRIT "sync_ser: buffer not " | ||
1384 | "empty after eol.\n"); | ||
1385 | port->catch_tr_descr = port->active_tr_descr; | ||
1386 | port->tr_running = 0; | ||
1387 | tr_cfg.tr_en = regk_sser_no; | ||
1388 | REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); | ||
1142 | } | 1389 | } |
1390 | /* wake up the waiting process */ | ||
1391 | wake_up_interruptible(&port->out_wait_q); | ||
1143 | } | 1392 | } |
1144 | return IRQ_RETVAL(found); | 1393 | return IRQ_RETVAL(found); |
1145 | } /* tr_interrupt */ | 1394 | } /* tr_interrupt */ |
1146 | 1395 | ||
1147 | static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) | 1396 | static irqreturn_t rx_interrupt(int irq, void *dev_id) |
1148 | { | 1397 | { |
1149 | reg_dma_r_masked_intr masked; | 1398 | reg_dma_r_masked_intr masked; |
1150 | reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; | 1399 | reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; |
@@ -1152,7 +1401,7 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
1152 | int i; | 1401 | int i; |
1153 | int found = 0; | 1402 | int found = 0; |
1154 | 1403 | ||
1155 | for (i = 0; i < NUMBER_OF_PORTS; i++) | 1404 | for (i = 0; i < NBR_PORTS; i++) |
1156 | { | 1405 | { |
1157 | sync_port *port = &ports[i]; | 1406 | sync_port *port = &ports[i]; |
1158 | 1407 | ||
@@ -1166,7 +1415,7 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
1166 | found = 1; | 1415 | found = 1; |
1167 | while (REG_RD(dma, port->regi_dmain, rw_data) != | 1416 | while (REG_RD(dma, port->regi_dmain, rw_data) != |
1168 | virt_to_phys(port->next_rx_desc)) { | 1417 | virt_to_phys(port->next_rx_desc)) { |
1169 | 1418 | DEBUGRXINT(printk(KERN_DEBUG "!")); | |
1170 | if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) { | 1419 | if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) { |
1171 | int first_size = port->flip + port->in_buffer_size - port->writep; | 1420 | int first_size = port->flip + port->in_buffer_size - port->writep; |
1172 | memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size); | 1421 | memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size); |
@@ -1185,11 +1434,16 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
1185 | port->full = 1; | 1434 | port->full = 1; |
1186 | } | 1435 | } |
1187 | 1436 | ||
1188 | port->next_rx_desc->eol = 0; | 1437 | port->next_rx_desc->eol = 1; |
1189 | port->prev_rx_desc->eol = 1; | 1438 | port->prev_rx_desc->eol = 0; |
1190 | port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc); | 1439 | /* Cache bug workaround */ |
1440 | flush_dma_descr(port->prev_rx_desc, 0); | ||
1441 | port->prev_rx_desc = port->next_rx_desc; | ||
1191 | port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next); | 1442 | port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next); |
1192 | wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */ | 1443 | /* Cache bug workaround */ |
1444 | flush_dma_descr(port->prev_rx_desc, 1); | ||
1445 | /* wake up the waiting process */ | ||
1446 | wake_up_interruptible(&port->in_wait_q); | ||
1193 | DMA_CONTINUE(port->regi_dmain); | 1447 | DMA_CONTINUE(port->regi_dmain); |
1194 | REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr); | 1448 | REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr); |
1195 | 1449 | ||
@@ -1201,15 +1455,15 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
1201 | #endif /* SYNC_SER_DMA */ | 1455 | #endif /* SYNC_SER_DMA */ |
1202 | 1456 | ||
1203 | #ifdef SYNC_SER_MANUAL | 1457 | #ifdef SYNC_SER_MANUAL |
1204 | static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs) | 1458 | static irqreturn_t manual_interrupt(int irq, void *dev_id) |
1205 | { | 1459 | { |
1206 | int i; | 1460 | int i; |
1207 | int found = 0; | 1461 | int found = 0; |
1208 | reg_sser_r_masked_intr masked; | 1462 | reg_sser_r_masked_intr masked; |
1209 | 1463 | ||
1210 | for (i = 0; i < NUMBER_OF_PORTS; i++) | 1464 | for (i = 0; i < NBR_PORTS; i++) |
1211 | { | 1465 | { |
1212 | sync_port* port = &ports[i]; | 1466 | sync_port *port = &ports[i]; |
1213 | 1467 | ||
1214 | if (!port->enabled || port->use_dma) | 1468 | if (!port->enabled || port->use_dma) |
1215 | { | 1469 | { |
@@ -1263,7 +1517,7 @@ static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs | |||
1263 | if (masked.trdy) /* Transmitter ready? */ | 1517 | if (masked.trdy) /* Transmitter ready? */ |
1264 | { | 1518 | { |
1265 | found = 1; | 1519 | found = 1; |
1266 | if (port->out_count > 0) /* More data to send */ | 1520 | if (port->out_buf_count > 0) /* More data to send */ |
1267 | send_word(port); | 1521 | send_word(port); |
1268 | else /* transmission finished */ | 1522 | else /* transmission finished */ |
1269 | { | 1523 | { |
diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile index 5d5b613cde8c..993d987b0078 100644 --- a/arch/cris/arch-v32/kernel/Makefile +++ b/arch/cris/arch-v32/kernel/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | # $Id: Makefile,v 1.11 2004/12/17 10:16:13 starvik Exp $ | ||
2 | # | 1 | # |
3 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
4 | # | 3 | # |
@@ -6,9 +5,9 @@ | |||
6 | extra-y := head.o | 5 | extra-y := head.o |
7 | 6 | ||
8 | 7 | ||
9 | obj-y := entry.o traps.o irq.o debugport.o dma.o pinmux.o \ | 8 | obj-y := entry.o traps.o irq.o debugport.o \ |
10 | process.o ptrace.o setup.o signal.o traps.o time.o \ | 9 | process.o ptrace.o setup.o signal.o traps.o time.o \ |
11 | arbiter.o io.o | 10 | cache.o cacheflush.o |
12 | 11 | ||
13 | obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o | 12 | obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o |
14 | 13 | ||
diff --git a/arch/cris/arch-v32/kernel/arbiter.c b/arch/cris/arch-v32/kernel/arbiter.c deleted file mode 100644 index 420a5312ed03..000000000000 --- a/arch/cris/arch-v32/kernel/arbiter.c +++ /dev/null | |||
@@ -1,296 +0,0 @@ | |||
1 | /* | ||
2 | * Memory arbiter functions. Allocates bandwidth through the | ||
3 | * arbiter and sets up arbiter breakpoints. | ||
4 | * | ||
5 | * The algorithm first assigns slots to the clients that has specified | ||
6 | * bandwidth (e.g. ethernet) and then the remaining slots are divided | ||
7 | * on all the active clients. | ||
8 | * | ||
9 | * Copyright (c) 2004, 2005 Axis Communications AB. | ||
10 | */ | ||
11 | |||
12 | #include <asm/arch/hwregs/reg_map.h> | ||
13 | #include <asm/arch/hwregs/reg_rdwr.h> | ||
14 | #include <asm/arch/hwregs/marb_defs.h> | ||
15 | #include <asm/arch/arbiter.h> | ||
16 | #include <asm/arch/hwregs/intr_vect.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/signal.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <asm/io.h> | ||
22 | |||
23 | struct crisv32_watch_entry | ||
24 | { | ||
25 | unsigned long instance; | ||
26 | watch_callback* cb; | ||
27 | unsigned long start; | ||
28 | unsigned long end; | ||
29 | int used; | ||
30 | }; | ||
31 | |||
32 | #define NUMBER_OF_BP 4 | ||
33 | #define NBR_OF_CLIENTS 14 | ||
34 | #define NBR_OF_SLOTS 64 | ||
35 | #define SDRAM_BANDWIDTH 100000000 /* Some kind of expected value */ | ||
36 | #define INTMEM_BANDWIDTH 400000000 | ||
37 | #define NBR_OF_REGIONS 2 | ||
38 | |||
39 | static struct crisv32_watch_entry watches[NUMBER_OF_BP] = | ||
40 | { | ||
41 | {regi_marb_bp0}, | ||
42 | {regi_marb_bp1}, | ||
43 | {regi_marb_bp2}, | ||
44 | {regi_marb_bp3} | ||
45 | }; | ||
46 | |||
47 | static int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS]; | ||
48 | static int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS]; | ||
49 | static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH}; | ||
50 | |||
51 | DEFINE_SPINLOCK(arbiter_lock); | ||
52 | |||
53 | static irqreturn_t | ||
54 | crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs); | ||
55 | |||
56 | static void crisv32_arbiter_config(int region) | ||
57 | { | ||
58 | int slot; | ||
59 | int client; | ||
60 | int interval = 0; | ||
61 | int val[NBR_OF_SLOTS]; | ||
62 | |||
63 | for (slot = 0; slot < NBR_OF_SLOTS; slot++) | ||
64 | val[slot] = NBR_OF_CLIENTS + 1; | ||
65 | |||
66 | for (client = 0; client < NBR_OF_CLIENTS; client++) | ||
67 | { | ||
68 | int pos; | ||
69 | if (!requested_slots[region][client]) | ||
70 | continue; | ||
71 | interval = NBR_OF_SLOTS / requested_slots[region][client]; | ||
72 | pos = 0; | ||
73 | while (pos < NBR_OF_SLOTS) | ||
74 | { | ||
75 | if (val[pos] != NBR_OF_CLIENTS + 1) | ||
76 | pos++; | ||
77 | else | ||
78 | { | ||
79 | val[pos] = client; | ||
80 | pos += interval; | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | |||
85 | client = 0; | ||
86 | for (slot = 0; slot < NBR_OF_SLOTS; slot++) | ||
87 | { | ||
88 | if (val[slot] == NBR_OF_CLIENTS + 1) | ||
89 | { | ||
90 | int first = client; | ||
91 | while(!active_clients[region][client]) { | ||
92 | client = (client + 1) % NBR_OF_CLIENTS; | ||
93 | if (client == first) | ||
94 | break; | ||
95 | } | ||
96 | val[slot] = client; | ||
97 | client = (client + 1) % NBR_OF_CLIENTS; | ||
98 | } | ||
99 | if (region == EXT_REGION) | ||
100 | REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot, val[slot]); | ||
101 | else if (region == INT_REGION) | ||
102 | REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot, val[slot]); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | extern char _stext, _etext; | ||
107 | |||
108 | static void crisv32_arbiter_init(void) | ||
109 | { | ||
110 | static int initialized = 0; | ||
111 | |||
112 | if (initialized) | ||
113 | return; | ||
114 | |||
115 | initialized = 1; | ||
116 | |||
117 | /* CPU caches are active. */ | ||
118 | active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1; | ||
119 | crisv32_arbiter_config(EXT_REGION); | ||
120 | crisv32_arbiter_config(INT_REGION); | ||
121 | |||
122 | if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED, | ||
123 | "arbiter", NULL)) | ||
124 | printk(KERN_ERR "Couldn't allocate arbiter IRQ\n"); | ||
125 | |||
126 | #ifndef CONFIG_ETRAX_KGDB | ||
127 | /* Global watch for writes to kernel text segment. */ | ||
128 | crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, | ||
129 | arbiter_all_clients, arbiter_all_write, NULL); | ||
130 | #endif | ||
131 | } | ||
132 | |||
133 | |||
134 | |||
135 | int crisv32_arbiter_allocate_bandwidth(int client, int region, | ||
136 | unsigned long bandwidth) | ||
137 | { | ||
138 | int i; | ||
139 | int total_assigned = 0; | ||
140 | int total_clients = 0; | ||
141 | int req; | ||
142 | |||
143 | crisv32_arbiter_init(); | ||
144 | |||
145 | for (i = 0; i < NBR_OF_CLIENTS; i++) | ||
146 | { | ||
147 | total_assigned += requested_slots[region][i]; | ||
148 | total_clients += active_clients[region][i]; | ||
149 | } | ||
150 | req = NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth); | ||
151 | |||
152 | if (total_assigned + total_clients + req + 1 > NBR_OF_SLOTS) | ||
153 | return -ENOMEM; | ||
154 | |||
155 | active_clients[region][client] = 1; | ||
156 | requested_slots[region][client] = req; | ||
157 | crisv32_arbiter_config(region); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | int crisv32_arbiter_watch(unsigned long start, unsigned long size, | ||
163 | unsigned long clients, unsigned long accesses, | ||
164 | watch_callback* cb) | ||
165 | { | ||
166 | int i; | ||
167 | |||
168 | crisv32_arbiter_init(); | ||
169 | |||
170 | if (start > 0x80000000) { | ||
171 | printk("Arbiter: %lX doesn't look like a physical address", start); | ||
172 | return -EFAULT; | ||
173 | } | ||
174 | |||
175 | spin_lock(&arbiter_lock); | ||
176 | |||
177 | for (i = 0; i < NUMBER_OF_BP; i++) { | ||
178 | if (!watches[i].used) { | ||
179 | reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask); | ||
180 | |||
181 | watches[i].used = 1; | ||
182 | watches[i].start = start; | ||
183 | watches[i].end = start + size; | ||
184 | watches[i].cb = cb; | ||
185 | |||
186 | REG_WR_INT(marb_bp, watches[i].instance, rw_first_addr, watches[i].start); | ||
187 | REG_WR_INT(marb_bp, watches[i].instance, rw_last_addr, watches[i].end); | ||
188 | REG_WR_INT(marb_bp, watches[i].instance, rw_op, accesses); | ||
189 | REG_WR_INT(marb_bp, watches[i].instance, rw_clients, clients); | ||
190 | |||
191 | if (i == 0) | ||
192 | intr_mask.bp0 = regk_marb_yes; | ||
193 | else if (i == 1) | ||
194 | intr_mask.bp1 = regk_marb_yes; | ||
195 | else if (i == 2) | ||
196 | intr_mask.bp2 = regk_marb_yes; | ||
197 | else if (i == 3) | ||
198 | intr_mask.bp3 = regk_marb_yes; | ||
199 | |||
200 | REG_WR(marb, regi_marb, rw_intr_mask, intr_mask); | ||
201 | spin_unlock(&arbiter_lock); | ||
202 | |||
203 | return i; | ||
204 | } | ||
205 | } | ||
206 | spin_unlock(&arbiter_lock); | ||
207 | return -ENOMEM; | ||
208 | } | ||
209 | |||
210 | int crisv32_arbiter_unwatch(int id) | ||
211 | { | ||
212 | reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask); | ||
213 | |||
214 | crisv32_arbiter_init(); | ||
215 | |||
216 | spin_lock(&arbiter_lock); | ||
217 | |||
218 | if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) { | ||
219 | spin_unlock(&arbiter_lock); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | memset(&watches[id], 0, sizeof(struct crisv32_watch_entry)); | ||
224 | |||
225 | if (id == 0) | ||
226 | intr_mask.bp0 = regk_marb_no; | ||
227 | else if (id == 1) | ||
228 | intr_mask.bp2 = regk_marb_no; | ||
229 | else if (id == 2) | ||
230 | intr_mask.bp2 = regk_marb_no; | ||
231 | else if (id == 3) | ||
232 | intr_mask.bp3 = regk_marb_no; | ||
233 | |||
234 | REG_WR(marb, regi_marb, rw_intr_mask, intr_mask); | ||
235 | |||
236 | spin_unlock(&arbiter_lock); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | extern void show_registers(struct pt_regs *regs); | ||
241 | |||
242 | static irqreturn_t | ||
243 | crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs) | ||
244 | { | ||
245 | reg_marb_r_masked_intr masked_intr = REG_RD(marb, regi_marb, r_masked_intr); | ||
246 | reg_marb_bp_r_brk_clients r_clients; | ||
247 | reg_marb_bp_r_brk_addr r_addr; | ||
248 | reg_marb_bp_r_brk_op r_op; | ||
249 | reg_marb_bp_r_brk_first_client r_first; | ||
250 | reg_marb_bp_r_brk_size r_size; | ||
251 | reg_marb_bp_rw_ack ack = {0}; | ||
252 | reg_marb_rw_ack_intr ack_intr = {.bp0=1,.bp1=1,.bp2=1,.bp3=1}; | ||
253 | struct crisv32_watch_entry* watch; | ||
254 | |||
255 | if (masked_intr.bp0) { | ||
256 | watch = &watches[0]; | ||
257 | ack_intr.bp0 = regk_marb_yes; | ||
258 | } else if (masked_intr.bp1) { | ||
259 | watch = &watches[1]; | ||
260 | ack_intr.bp1 = regk_marb_yes; | ||
261 | } else if (masked_intr.bp2) { | ||
262 | watch = &watches[2]; | ||
263 | ack_intr.bp2 = regk_marb_yes; | ||
264 | } else if (masked_intr.bp3) { | ||
265 | watch = &watches[3]; | ||
266 | ack_intr.bp3 = regk_marb_yes; | ||
267 | } else { | ||
268 | return IRQ_NONE; | ||
269 | } | ||
270 | |||
271 | /* Retrieve all useful information and print it. */ | ||
272 | r_clients = REG_RD(marb_bp, watch->instance, r_brk_clients); | ||
273 | r_addr = REG_RD(marb_bp, watch->instance, r_brk_addr); | ||
274 | r_op = REG_RD(marb_bp, watch->instance, r_brk_op); | ||
275 | r_first = REG_RD(marb_bp, watch->instance, r_brk_first_client); | ||
276 | r_size = REG_RD(marb_bp, watch->instance, r_brk_size); | ||
277 | |||
278 | printk("Arbiter IRQ\n"); | ||
279 | printk("Clients %X addr %X op %X first %X size %X\n", | ||
280 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_clients, r_clients), | ||
281 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_addr, r_addr), | ||
282 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_op, r_op), | ||
283 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_first_client, r_first), | ||
284 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_size, r_size)); | ||
285 | |||
286 | REG_WR(marb_bp, watch->instance, rw_ack, ack); | ||
287 | REG_WR(marb, regi_marb, rw_ack_intr, ack_intr); | ||
288 | |||
289 | printk("IRQ occured at %lX\n", regs->erp); | ||
290 | |||
291 | if (watch->cb) | ||
292 | watch->cb(); | ||
293 | |||
294 | |||
295 | return IRQ_HANDLED; | ||
296 | } | ||
diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c index e513da711245..77d02c15a7fc 100644 --- a/arch/cris/arch-v32/kernel/crisksyms.c +++ b/arch/cris/arch-v32/kernel/crisksyms.c | |||
@@ -2,7 +2,8 @@ | |||
2 | #include <linux/irq.h> | 2 | #include <linux/irq.h> |
3 | #include <asm/arch/dma.h> | 3 | #include <asm/arch/dma.h> |
4 | #include <asm/arch/intmem.h> | 4 | #include <asm/arch/intmem.h> |
5 | #include <asm/arch/pinmux.h> | 5 | #include <asm/arch/mach/pinmux.h> |
6 | #include <asm/arch/io.h> | ||
6 | 7 | ||
7 | /* Functions for allocating DMA channels */ | 8 | /* Functions for allocating DMA channels */ |
8 | EXPORT_SYMBOL(crisv32_request_dma); | 9 | EXPORT_SYMBOL(crisv32_request_dma); |
@@ -16,7 +17,11 @@ EXPORT_SYMBOL(crisv32_intmem_virt_to_phys); | |||
16 | 17 | ||
17 | /* Functions for handling pinmux */ | 18 | /* Functions for handling pinmux */ |
18 | EXPORT_SYMBOL(crisv32_pinmux_alloc); | 19 | EXPORT_SYMBOL(crisv32_pinmux_alloc); |
20 | EXPORT_SYMBOL(crisv32_pinmux_alloc_fixed); | ||
19 | EXPORT_SYMBOL(crisv32_pinmux_dealloc); | 21 | EXPORT_SYMBOL(crisv32_pinmux_dealloc); |
22 | EXPORT_SYMBOL(crisv32_pinmux_dealloc_fixed); | ||
23 | EXPORT_SYMBOL(crisv32_io_get_name); | ||
24 | EXPORT_SYMBOL(crisv32_io_get); | ||
20 | 25 | ||
21 | /* Functions masking/unmasking interrupts */ | 26 | /* Functions masking/unmasking interrupts */ |
22 | EXPORT_SYMBOL(mask_irq); | 27 | EXPORT_SYMBOL(mask_irq); |
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c index d1272ad92153..15af4c293157 100644 --- a/arch/cris/arch-v32/kernel/debugport.c +++ b/arch/cris/arch-v32/kernel/debugport.c | |||
@@ -4,17 +4,12 @@ | |||
4 | 4 | ||
5 | #include <linux/console.h> | 5 | #include <linux/console.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/major.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/tty.h> | ||
10 | #include <asm/system.h> | 7 | #include <asm/system.h> |
11 | #include <asm/io.h> | 8 | #include <hwregs/reg_rdwr.h> |
12 | #include <asm/arch/hwregs/ser_defs.h> | 9 | #include <hwregs/reg_map.h> |
13 | #include <asm/arch/hwregs/dma_defs.h> | 10 | #include <hwregs/ser_defs.h> |
14 | #include <asm/arch/pinmux.h> | 11 | #include <hwregs/dma_defs.h> |
15 | 12 | #include <asm/arch/mach/pinmux.h> | |
16 | #include <asm/irq.h> | ||
17 | #include <asm/arch/hwregs/intr_vect_defs.h> | ||
18 | 13 | ||
19 | struct dbg_port | 14 | struct dbg_port |
20 | { | 15 | { |
@@ -59,45 +54,50 @@ struct dbg_port ports[] = | |||
59 | 115200, | 54 | 115200, |
60 | 'N', | 55 | 'N', |
61 | 8 | 56 | 8 |
62 | } | 57 | }, |
58 | #if CONFIG_ETRAX_SERIAL_PORTS == 5 | ||
59 | { | ||
60 | 4, | ||
61 | regi_ser4, | ||
62 | 0, | ||
63 | 115200, | ||
64 | 'N', | ||
65 | 8 | ||
66 | }, | ||
67 | #endif | ||
63 | }; | 68 | }; |
64 | static struct dbg_port *port = | 69 | static struct dbg_port *port = |
65 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) | 70 | #if defined(CONFIG_ETRAX_DEBUG_PORT0) |
66 | &ports[0]; | 71 | &ports[0]; |
67 | #elif defined(CONFIG_ETRAX_DEBUG_PORT1) | 72 | #elif defined(CONFIG_ETRAX_DEBUG_PORT1) |
68 | &ports[1]; | 73 | &ports[1]; |
69 | #elif defined(CONFIG_ETRAX_DEBUG_PORT2) | 74 | #elif defined(CONFIG_ETRAX_DEBUG_PORT2) |
70 | &ports[2]; | 75 | &ports[2]; |
71 | #elif defined(CONFIG_ETRAX_DEBUG_PORT3) | 76 | #elif defined(CONFIG_ETRAX_DEBUG_PORT3) |
72 | &ports[3]; | 77 | &ports[3]; |
78 | #elif defined(CONFIG_ETRAX_DEBUG_PORT4) | ||
79 | &ports[4]; | ||
73 | #else | 80 | #else |
74 | NULL; | 81 | NULL; |
75 | #endif | 82 | #endif |
76 | 83 | ||
77 | #ifdef CONFIG_ETRAX_KGDB | 84 | #ifdef CONFIG_ETRAX_KGDB |
78 | static struct dbg_port *kgdb_port = | 85 | static struct dbg_port *kgdb_port = |
79 | #if defined(CONFIG_ETRAX_KGDB_PORT0) | 86 | #if defined(CONFIG_ETRAX_KGDB_PORT0) |
80 | &ports[0]; | 87 | &ports[0]; |
81 | #elif defined(CONFIG_ETRAX_KGDB_PORT1) | 88 | #elif defined(CONFIG_ETRAX_KGDB_PORT1) |
82 | &ports[1]; | 89 | &ports[1]; |
83 | #elif defined(CONFIG_ETRAX_KGDB_PORT2) | 90 | #elif defined(CONFIG_ETRAX_KGDB_PORT2) |
84 | &ports[2]; | 91 | &ports[2]; |
85 | #elif defined(CONFIG_ETRAX_KGDB_PORT3) | 92 | #elif defined(CONFIG_ETRAX_KGDB_PORT3) |
86 | &ports[3]; | 93 | &ports[3]; |
94 | #elif defined(CONFIG_ETRAX_KGDB_PORT4) | ||
95 | &ports[4]; | ||
87 | #else | 96 | #else |
88 | NULL; | 97 | NULL; |
89 | #endif | 98 | #endif |
90 | #endif | 99 | #endif |
91 | 100 | ||
92 | #ifdef CONFIG_ETRAXFS_SIM | ||
93 | extern void print_str( const char *str ); | ||
94 | static char buffer[1024]; | ||
95 | static char msg[] = "Debug: "; | ||
96 | static int buffer_pos = sizeof(msg) - 1; | ||
97 | #endif | ||
98 | |||
99 | extern struct tty_driver *serial_driver; | ||
100 | |||
101 | static void | 101 | static void |
102 | start_port(struct dbg_port* p) | 102 | start_port(struct dbg_port* p) |
103 | { | 103 | { |
@@ -114,6 +114,10 @@ start_port(struct dbg_port* p) | |||
114 | crisv32_pinmux_alloc_fixed(pinmux_ser2); | 114 | crisv32_pinmux_alloc_fixed(pinmux_ser2); |
115 | else if (p->nbr == 3) | 115 | else if (p->nbr == 3) |
116 | crisv32_pinmux_alloc_fixed(pinmux_ser3); | 116 | crisv32_pinmux_alloc_fixed(pinmux_ser3); |
117 | #if CONFIG_ETRAX_SERIAL_PORTS == 5 | ||
118 | else if (p->nbr == 4) | ||
119 | crisv32_pinmux_alloc_fixed(pinmux_ser4); | ||
120 | #endif | ||
117 | 121 | ||
118 | /* Set up serial port registers */ | 122 | /* Set up serial port registers */ |
119 | reg_ser_rw_tr_ctrl tr_ctrl = {0}; | 123 | reg_ser_rw_tr_ctrl tr_ctrl = {0}; |
@@ -156,124 +160,21 @@ start_port(struct dbg_port* p) | |||
156 | REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl); | 160 | REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl); |
157 | } | 161 | } |
158 | 162 | ||
159 | /* No debug */ | ||
160 | #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL | ||
161 | |||
162 | static void | ||
163 | console_write(struct console *co, const char *buf, unsigned int len) | ||
164 | { | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | /* Target debug */ | ||
169 | #elif !defined(CONFIG_ETRAXFS_SIM) | ||
170 | |||
171 | static void | ||
172 | console_write_direct(struct console *co, const char *buf, unsigned int len) | ||
173 | { | ||
174 | int i; | ||
175 | reg_ser_r_stat_din stat; | ||
176 | reg_ser_rw_tr_dma_en tr_dma_en, old; | ||
177 | |||
178 | /* Switch to manual mode */ | ||
179 | tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en); | ||
180 | if (tr_dma_en.en == regk_ser_yes) { | ||
181 | tr_dma_en.en = regk_ser_no; | ||
182 | REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en); | ||
183 | } | ||
184 | |||
185 | /* Send data */ | ||
186 | for (i = 0; i < len; i++) { | ||
187 | /* LF -> CRLF */ | ||
188 | if (buf[i] == '\n') { | ||
189 | do { | ||
190 | stat = REG_RD (ser, port->instance, r_stat_din); | ||
191 | } while (!stat.tr_rdy); | ||
192 | REG_WR_INT (ser, port->instance, rw_dout, '\r'); | ||
193 | } | ||
194 | /* Wait until transmitter is ready and send.*/ | ||
195 | do { | ||
196 | stat = REG_RD (ser, port->instance, r_stat_din); | ||
197 | } while (!stat.tr_rdy); | ||
198 | REG_WR_INT (ser, port->instance, rw_dout, buf[i]); | ||
199 | } | ||
200 | |||
201 | /* Restore mode */ | ||
202 | if (tr_dma_en.en != old.en) | ||
203 | REG_WR(ser, port->instance, rw_tr_dma_en, old); | ||
204 | } | ||
205 | |||
206 | static void | ||
207 | console_write(struct console *co, const char *buf, unsigned int len) | ||
208 | { | ||
209 | if (!port) | ||
210 | return; | ||
211 | console_write_direct(co, buf, len); | ||
212 | } | ||
213 | |||
214 | |||
215 | |||
216 | #else | ||
217 | |||
218 | /* VCS debug */ | ||
219 | |||
220 | static void | ||
221 | console_write(struct console *co, const char *buf, unsigned int len) | ||
222 | { | ||
223 | char* pos; | ||
224 | pos = memchr(buf, '\n', len); | ||
225 | if (pos) { | ||
226 | int l = ++pos - buf; | ||
227 | memcpy(buffer + buffer_pos, buf, l); | ||
228 | memcpy(buffer, msg, sizeof(msg) - 1); | ||
229 | buffer[buffer_pos + l] = '\0'; | ||
230 | print_str(buffer); | ||
231 | buffer_pos = sizeof(msg) - 1; | ||
232 | if (pos - buf != len) { | ||
233 | memcpy(buffer + buffer_pos, pos, len - l); | ||
234 | buffer_pos += len - l; | ||
235 | } | ||
236 | } else { | ||
237 | memcpy(buffer + buffer_pos, buf, len); | ||
238 | buffer_pos += len; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | #endif | ||
243 | |||
244 | int raw_printk(const char *fmt, ...) | ||
245 | { | ||
246 | static char buf[1024]; | ||
247 | int printed_len; | ||
248 | va_list args; | ||
249 | va_start(args, fmt); | ||
250 | printed_len = vsnprintf(buf, sizeof(buf), fmt, args); | ||
251 | va_end(args); | ||
252 | console_write(NULL, buf, strlen(buf)); | ||
253 | return printed_len; | ||
254 | } | ||
255 | |||
256 | void | ||
257 | stupid_debug(char* buf) | ||
258 | { | ||
259 | console_write(NULL, buf, strlen(buf)); | ||
260 | } | ||
261 | |||
262 | #ifdef CONFIG_ETRAX_KGDB | 163 | #ifdef CONFIG_ETRAX_KGDB |
263 | /* Use polling to get a single character from the kernel debug port */ | 164 | /* Use polling to get a single character from the kernel debug port */ |
264 | int | 165 | int |
265 | getDebugChar(void) | 166 | getDebugChar(void) |
266 | { | 167 | { |
267 | reg_ser_rs_status_data stat; | 168 | reg_ser_rs_stat_din stat; |
268 | reg_ser_rw_ack_intr ack_intr = { 0 }; | 169 | reg_ser_rw_ack_intr ack_intr = { 0 }; |
269 | 170 | ||
270 | do { | 171 | do { |
271 | stat = REG_RD(ser, kgdb_instance, rs_status_data); | 172 | stat = REG_RD(ser, kgdb_port->instance, rs_stat_din); |
272 | } while (!stat.data_avail); | 173 | } while (!stat.dav); |
273 | 174 | ||
274 | /* Ack the data_avail interrupt. */ | 175 | /* Ack the data_avail interrupt. */ |
275 | ack_intr.data_avail = 1; | 176 | ack_intr.dav = 1; |
276 | REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr); | 177 | REG_WR(ser, kgdb_port->instance, rw_ack_intr, ack_intr); |
277 | 178 | ||
278 | return stat.data; | 179 | return stat.data; |
279 | } | 180 | } |
@@ -282,173 +183,18 @@ getDebugChar(void) | |||
282 | void | 183 | void |
283 | putDebugChar(int val) | 184 | putDebugChar(int val) |
284 | { | 185 | { |
285 | reg_ser_r_status_data stat; | 186 | reg_ser_r_stat_din stat; |
286 | do { | 187 | do { |
287 | stat = REG_RD (ser, kgdb_instance, r_status_data); | 188 | stat = REG_RD(ser, kgdb_port->instance, r_stat_din); |
288 | } while (!stat.tr_ready); | 189 | } while (!stat.tr_rdy); |
289 | REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val)); | 190 | REG_WR_INT(ser, kgdb_port->instance, rw_dout, val); |
290 | } | 191 | } |
291 | #endif /* CONFIG_ETRAX_KGDB */ | 192 | #endif /* CONFIG_ETRAX_KGDB */ |
292 | 193 | ||
293 | static int __init | ||
294 | console_setup(struct console *co, char *options) | ||
295 | { | ||
296 | char* s; | ||
297 | |||
298 | if (options) { | ||
299 | port = &ports[co->index]; | ||
300 | port->baudrate = 115200; | ||
301 | port->parity = 'N'; | ||
302 | port->bits = 8; | ||
303 | port->baudrate = simple_strtoul(options, NULL, 10); | ||
304 | s = options; | ||
305 | while(*s >= '0' && *s <= '9') | ||
306 | s++; | ||
307 | if (*s) port->parity = *s++; | ||
308 | if (*s) port->bits = *s++ - '0'; | ||
309 | port->started = 0; | ||
310 | start_port(port); | ||
311 | } | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | /* This is a dummy serial device that throws away anything written to it. | ||
316 | * This is used when no debug output is wanted. | ||
317 | */ | ||
318 | static struct tty_driver dummy_driver; | ||
319 | |||
320 | static int dummy_open(struct tty_struct *tty, struct file * filp) | ||
321 | { | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static void dummy_close(struct tty_struct *tty, struct file * filp) | ||
326 | { | ||
327 | } | ||
328 | |||
329 | static int dummy_write(struct tty_struct * tty, | ||
330 | const unsigned char *buf, int count) | ||
331 | { | ||
332 | return count; | ||
333 | } | ||
334 | |||
335 | static int | ||
336 | dummy_write_room(struct tty_struct *tty) | ||
337 | { | ||
338 | return 8192; | ||
339 | } | ||
340 | |||
341 | void __init | ||
342 | init_dummy_console(void) | ||
343 | { | ||
344 | memset(&dummy_driver, 0, sizeof(struct tty_driver)); | ||
345 | dummy_driver.driver_name = "serial"; | ||
346 | dummy_driver.name = "ttyS"; | ||
347 | dummy_driver.major = TTY_MAJOR; | ||
348 | dummy_driver.minor_start = 68; | ||
349 | dummy_driver.num = 1; /* etrax100 has 4 serial ports */ | ||
350 | dummy_driver.type = TTY_DRIVER_TYPE_SERIAL; | ||
351 | dummy_driver.subtype = SERIAL_TYPE_NORMAL; | ||
352 | dummy_driver.init_termios = tty_std_termios; | ||
353 | dummy_driver.init_termios.c_cflag = | ||
354 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ | ||
355 | dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
356 | |||
357 | dummy_driver.open = dummy_open; | ||
358 | dummy_driver.close = dummy_close; | ||
359 | dummy_driver.write = dummy_write; | ||
360 | dummy_driver.write_room = dummy_write_room; | ||
361 | if (tty_register_driver(&dummy_driver)) | ||
362 | panic("Couldn't register dummy serial driver\n"); | ||
363 | } | ||
364 | |||
365 | static struct tty_driver* | ||
366 | crisv32_console_device(struct console* co, int *index) | ||
367 | { | ||
368 | if (port) | ||
369 | *index = port->nbr; | ||
370 | return port ? serial_driver : &dummy_driver; | ||
371 | } | ||
372 | |||
373 | static struct console sercons = { | ||
374 | name : "ttyS", | ||
375 | write: console_write, | ||
376 | read : NULL, | ||
377 | device : crisv32_console_device, | ||
378 | unblank : NULL, | ||
379 | setup : console_setup, | ||
380 | flags : CON_PRINTBUFFER, | ||
381 | index : -1, | ||
382 | cflag : 0, | ||
383 | next : NULL | ||
384 | }; | ||
385 | static struct console sercons0 = { | ||
386 | name : "ttyS", | ||
387 | write: console_write, | ||
388 | read : NULL, | ||
389 | device : crisv32_console_device, | ||
390 | unblank : NULL, | ||
391 | setup : console_setup, | ||
392 | flags : CON_PRINTBUFFER, | ||
393 | index : 0, | ||
394 | cflag : 0, | ||
395 | next : NULL | ||
396 | }; | ||
397 | |||
398 | static struct console sercons1 = { | ||
399 | name : "ttyS", | ||
400 | write: console_write, | ||
401 | read : NULL, | ||
402 | device : crisv32_console_device, | ||
403 | unblank : NULL, | ||
404 | setup : console_setup, | ||
405 | flags : CON_PRINTBUFFER, | ||
406 | index : 1, | ||
407 | cflag : 0, | ||
408 | next : NULL | ||
409 | }; | ||
410 | static struct console sercons2 = { | ||
411 | name : "ttyS", | ||
412 | write: console_write, | ||
413 | read : NULL, | ||
414 | device : crisv32_console_device, | ||
415 | unblank : NULL, | ||
416 | setup : console_setup, | ||
417 | flags : CON_PRINTBUFFER, | ||
418 | index : 2, | ||
419 | cflag : 0, | ||
420 | next : NULL | ||
421 | }; | ||
422 | static struct console sercons3 = { | ||
423 | name : "ttyS", | ||
424 | write: console_write, | ||
425 | read : NULL, | ||
426 | device : crisv32_console_device, | ||
427 | unblank : NULL, | ||
428 | setup : console_setup, | ||
429 | flags : CON_PRINTBUFFER, | ||
430 | index : 3, | ||
431 | cflag : 0, | ||
432 | next : NULL | ||
433 | }; | ||
434 | |||
435 | /* Register console for printk's, etc. */ | 194 | /* Register console for printk's, etc. */ |
436 | int __init | 195 | int __init |
437 | init_etrax_debug(void) | 196 | init_etrax_debug(void) |
438 | { | 197 | { |
439 | static int first = 1; | ||
440 | |||
441 | if (!first) { | ||
442 | unregister_console(&sercons); | ||
443 | register_console(&sercons0); | ||
444 | register_console(&sercons1); | ||
445 | register_console(&sercons2); | ||
446 | register_console(&sercons3); | ||
447 | init_dummy_console(); | ||
448 | return 0; | ||
449 | } | ||
450 | first = 0; | ||
451 | register_console(&sercons); | ||
452 | start_port(port); | 198 | start_port(port); |
453 | 199 | ||
454 | #ifdef CONFIG_ETRAX_KGDB | 200 | #ifdef CONFIG_ETRAX_KGDB |
@@ -456,5 +202,3 @@ init_etrax_debug(void) | |||
456 | #endif /* CONFIG_ETRAX_KGDB */ | 202 | #endif /* CONFIG_ETRAX_KGDB */ |
457 | return 0; | 203 | return 0; |
458 | } | 204 | } |
459 | |||
460 | __initcall(init_etrax_debug); | ||
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index f9d27807b914..eebbaba45430 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S | |||
@@ -10,7 +10,7 @@ | |||
10 | * after a timer-interrupt and after each system call. | 10 | * after a timer-interrupt and after each system call. |
11 | * | 11 | * |
12 | * Stack layout in 'ret_from_system_call': | 12 | * Stack layout in 'ret_from_system_call': |
13 | * ptrace needs to have all regs on the stack. | 13 | * ptrace needs to have all regs on the stack. |
14 | * if the order here is changed, it needs to be | 14 | * if the order here is changed, it needs to be |
15 | * updated in fork.c:copy_process, signal.c:do_signal, | 15 | * updated in fork.c:copy_process, signal.c:do_signal, |
16 | * ptrace.c and ptrace.h | 16 | * ptrace.c and ptrace.h |
@@ -281,12 +281,10 @@ _work_notifysig: | |||
281 | ;; Deal with pending signals and notify-resume requests. | 281 | ;; Deal with pending signals and notify-resume requests. |
282 | 282 | ||
283 | addoq +TI_flags, $r0, $acr | 283 | addoq +TI_flags, $r0, $acr |
284 | move.d [$acr], $r13 ; The thread_info_flags parameter. | 284 | move.d [$acr], $r12 ; The thread_info_flags parameter. |
285 | move.d $r9, $r10 ; do_notify_resume syscall/irq param. | 285 | move.d $sp, $r11 ; The regs param. |
286 | moveq 0, $r11 ; oldset param - 0 in this case. | ||
287 | move.d $sp, $r12 ; The regs param. | ||
288 | jsr do_notify_resume | 286 | jsr do_notify_resume |
289 | nop | 287 | move.d $r9, $r10 ; do_notify_resume syscall/irq param. |
290 | 288 | ||
291 | ba _Rexit | 289 | ba _Rexit |
292 | nop | 290 | nop |
@@ -396,7 +394,7 @@ nmi_interrupt: | |||
396 | btstq REG_BIT(intr_vect, r_nmi, watchdog), $r0 | 394 | btstq REG_BIT(intr_vect, r_nmi, watchdog), $r0 |
397 | bpl 1f | 395 | bpl 1f |
398 | nop | 396 | nop |
399 | jsr handle_watchdog_bite ; In time.c. | 397 | jsr handle_watchdog_bite ; In time.c. |
400 | move.d $sp, $r10 ; Pointer to registers | 398 | move.d $sp, $r10 ; Pointer to registers |
401 | 1: btstq REG_BIT(intr_vect, r_nmi, ext), $r0 | 399 | 1: btstq REG_BIT(intr_vect, r_nmi, ext), $r0 |
402 | bpl 1f | 400 | bpl 1f |
@@ -515,6 +513,13 @@ _ugdb_handle_exception: | |||
515 | ba do_sigtrap ; SIGTRAP the offending process. | 513 | ba do_sigtrap ; SIGTRAP the offending process. |
516 | move.d [$sp+], $r0 ; Restore R0 in delay slot. | 514 | move.d [$sp+], $r0 ; Restore R0 in delay slot. |
517 | 515 | ||
516 | .global kernel_execve | ||
517 | kernel_execve: | ||
518 | move.d __NR_execve, $r9 | ||
519 | break 13 | ||
520 | ret | ||
521 | nop | ||
522 | |||
518 | .data | 523 | .data |
519 | 524 | ||
520 | .section .rodata,"a" | 525 | .section .rodata,"a" |
@@ -778,21 +783,21 @@ sys_call_table: | |||
778 | .long sys_epoll_ctl /* 255 */ | 783 | .long sys_epoll_ctl /* 255 */ |
779 | .long sys_epoll_wait | 784 | .long sys_epoll_wait |
780 | .long sys_remap_file_pages | 785 | .long sys_remap_file_pages |
781 | .long sys_set_tid_address | 786 | .long sys_set_tid_address |
782 | .long sys_timer_create | 787 | .long sys_timer_create |
783 | .long sys_timer_settime /* 260 */ | 788 | .long sys_timer_settime /* 260 */ |
784 | .long sys_timer_gettime | 789 | .long sys_timer_gettime |
785 | .long sys_timer_getoverrun | 790 | .long sys_timer_getoverrun |
786 | .long sys_timer_delete | 791 | .long sys_timer_delete |
787 | .long sys_clock_settime | 792 | .long sys_clock_settime |
788 | .long sys_clock_gettime /* 265 */ | 793 | .long sys_clock_gettime /* 265 */ |
789 | .long sys_clock_getres | 794 | .long sys_clock_getres |
790 | .long sys_clock_nanosleep | 795 | .long sys_clock_nanosleep |
791 | .long sys_statfs64 | 796 | .long sys_statfs64 |
792 | .long sys_fstatfs64 | 797 | .long sys_fstatfs64 |
793 | .long sys_tgkill /* 270 */ | 798 | .long sys_tgkill /* 270 */ |
794 | .long sys_utimes | 799 | .long sys_utimes |
795 | .long sys_fadvise64_64 | 800 | .long sys_fadvise64_64 |
796 | .long sys_ni_syscall /* sys_vserver */ | 801 | .long sys_ni_syscall /* sys_vserver */ |
797 | .long sys_ni_syscall /* sys_mbind */ | 802 | .long sys_ni_syscall /* sys_mbind */ |
798 | .long sys_ni_syscall /* 275 sys_get_mempolicy */ | 803 | .long sys_ni_syscall /* 275 sys_get_mempolicy */ |
@@ -805,6 +810,48 @@ sys_call_table: | |||
805 | .long sys_mq_getsetattr | 810 | .long sys_mq_getsetattr |
806 | .long sys_ni_syscall /* reserved for kexec */ | 811 | .long sys_ni_syscall /* reserved for kexec */ |
807 | .long sys_waitid | 812 | .long sys_waitid |
813 | .long sys_ni_syscall /* 285 */ /* available */ | ||
814 | .long sys_add_key | ||
815 | .long sys_request_key | ||
816 | .long sys_keyctl | ||
817 | .long sys_ioprio_set | ||
818 | .long sys_ioprio_get /* 290 */ | ||
819 | .long sys_inotify_init | ||
820 | .long sys_inotify_add_watch | ||
821 | .long sys_inotify_rm_watch | ||
822 | .long sys_migrate_pages | ||
823 | .long sys_openat /* 295 */ | ||
824 | .long sys_mkdirat | ||
825 | .long sys_mknodat | ||
826 | .long sys_fchownat | ||
827 | .long sys_futimesat | ||
828 | .long sys_fstatat64 /* 300 */ | ||
829 | .long sys_unlinkat | ||
830 | .long sys_renameat | ||
831 | .long sys_linkat | ||
832 | .long sys_symlinkat | ||
833 | .long sys_readlinkat /* 305 */ | ||
834 | .long sys_fchmodat | ||
835 | .long sys_faccessat | ||
836 | .long sys_pselect6 | ||
837 | .long sys_ppoll | ||
838 | .long sys_unshare /* 310 */ | ||
839 | .long sys_set_robust_list | ||
840 | .long sys_get_robust_list | ||
841 | .long sys_splice | ||
842 | .long sys_sync_file_range | ||
843 | .long sys_tee /* 315 */ | ||
844 | .long sys_vmsplice | ||
845 | .long sys_move_pages | ||
846 | .long sys_getcpu | ||
847 | .long sys_epoll_pwait | ||
848 | .long sys_utimensat /* 320 */ | ||
849 | .long sys_signalfd | ||
850 | .long sys_timerfd_create | ||
851 | .long sys_eventfd | ||
852 | .long sys_fallocate | ||
853 | .long sys_timerfd_settime /* 325 */ | ||
854 | .long sys_timerfd_gettime | ||
808 | 855 | ||
809 | /* | 856 | /* |
810 | * NOTE!! This doesn't have to be exact - we just have | 857 | * NOTE!! This doesn't have to be exact - we just have |
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c index b40551f9f40d..2de9d5849ef0 100644 --- a/arch/cris/arch-v32/kernel/fasttimer.c +++ b/arch/cris/arch-v32/kernel/fasttimer.c | |||
@@ -1,110 +1,9 @@ | |||
1 | /* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $ | 1 | /* |
2 | * linux/arch/cris/kernel/fasttimer.c | 2 | * linux/arch/cris/kernel/fasttimer.c |
3 | * | 3 | * |
4 | * Fast timers for ETRAX FS | 4 | * Fast timers for ETRAX FS |
5 | * This may be useful in other OS than Linux so use 2 space indentation... | ||
6 | * | ||
7 | * $Log: fasttimer.c,v $ | ||
8 | * Revision 1.11 2005/01/04 11:15:46 starvik | ||
9 | * Don't share timer IRQ. | ||
10 | * | ||
11 | * Revision 1.10 2004/12/07 09:19:38 starvik | ||
12 | * Corrected includes. | ||
13 | * Use correct interrupt macros. | ||
14 | * | ||
15 | * Revision 1.9 2004/05/14 10:18:58 starvik | ||
16 | * Export fast_timer_list | ||
17 | * | ||
18 | * Revision 1.8 2004/05/14 07:58:03 starvik | ||
19 | * Merge of changes from 2.4 | ||
20 | * | ||
21 | * Revision 1.7 2003/07/10 12:06:14 starvik | ||
22 | * Return IRQ_NONE if irq wasn't handled | ||
23 | * | ||
24 | * Revision 1.6 2003/07/04 08:27:49 starvik | ||
25 | * Merge of Linux 2.5.74 | ||
26 | * | ||
27 | * Revision 1.5 2003/06/05 10:16:22 johana | ||
28 | * New INTR_VECT macros. | ||
29 | * | ||
30 | * Revision 1.4 2003/06/03 08:49:45 johana | ||
31 | * Fixed typo. | ||
32 | * | ||
33 | * Revision 1.3 2003/06/02 12:51:27 johana | ||
34 | * Now compiles. | ||
35 | * Commented some include files that probably can be removed. | ||
36 | * | ||
37 | * Revision 1.2 2003/06/02 12:09:41 johana | ||
38 | * Ported to ETRAX FS using the trig interrupt instead of timer1. | ||
39 | * | ||
40 | * Revision 1.3 2002/12/12 08:26:32 starvik | ||
41 | * Don't use C-comments inside CVS comments | ||
42 | * | ||
43 | * Revision 1.2 2002/12/11 15:42:02 starvik | ||
44 | * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/ | ||
45 | * | ||
46 | * Revision 1.1 2002/11/18 07:58:06 starvik | ||
47 | * Fast timers (from Linux 2.4) | ||
48 | * | ||
49 | * Revision 1.5 2002/10/15 06:21:39 starvik | ||
50 | * Added call to init_waitqueue_head | ||
51 | * | 5 | * |
52 | * Revision 1.4 2002/05/28 17:47:59 johana | 6 | * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden |
53 | * Added del_fast_timer() | ||
54 | * | ||
55 | * Revision 1.3 2002/05/28 16:16:07 johana | ||
56 | * Handle empty fast_timer_list | ||
57 | * | ||
58 | * Revision 1.2 2002/05/27 15:38:42 johana | ||
59 | * Made it compile without warnings on Linux 2.4. | ||
60 | * (includes, wait_queue, PROC_FS and snprintf) | ||
61 | * | ||
62 | * Revision 1.1 2002/05/27 15:32:25 johana | ||
63 | * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree. | ||
64 | * | ||
65 | * Revision 1.8 2001/11/27 13:50:40 pkj | ||
66 | * Disable interrupts while stopping the timer and while modifying the | ||
67 | * list of active timers in timer1_handler() as it may be interrupted | ||
68 | * by other interrupts (e.g., the serial interrupt) which may add fast | ||
69 | * timers. | ||
70 | * | ||
71 | * Revision 1.7 2001/11/22 11:50:32 pkj | ||
72 | * * Only store information about the last 16 timers. | ||
73 | * * proc_fasttimer_read() now uses an allocated buffer, since it | ||
74 | * requires more space than just a page even for only writing the | ||
75 | * last 16 timers. The buffer is only allocated on request, so | ||
76 | * unless /proc/fasttimer is read, it is never allocated. | ||
77 | * * Renamed fast_timer_started to fast_timers_started to match | ||
78 | * fast_timers_added and fast_timers_expired. | ||
79 | * * Some clean-up. | ||
80 | * | ||
81 | * Revision 1.6 2000/12/13 14:02:08 johana | ||
82 | * Removed volatile for fast_timer_list | ||
83 | * | ||
84 | * Revision 1.5 2000/12/13 13:55:35 johana | ||
85 | * Added DEBUG_LOG, added som cli() and cleanup | ||
86 | * | ||
87 | * Revision 1.4 2000/12/05 13:48:50 johana | ||
88 | * Added range check when writing proc file, modified timer int handling | ||
89 | * | ||
90 | * Revision 1.3 2000/11/23 10:10:20 johana | ||
91 | * More debug/logging possibilities. | ||
92 | * Moved GET_JIFFIES_USEC() to timex.h and time.c | ||
93 | * | ||
94 | * Revision 1.2 2000/11/01 13:41:04 johana | ||
95 | * Clean up and bugfixes. | ||
96 | * Created new do_gettimeofday_fast() that gets a timeval struct | ||
97 | * with time based on jiffies and *R_TIMER0_DATA, uses a table | ||
98 | * for fast conversion of timer value to microseconds. | ||
99 | * (Much faster the standard do_gettimeofday() and we don't really | ||
100 | * want to use the true time - we want the "uptime" so timers don't screw up | ||
101 | * when we change the time. | ||
102 | * TODO: Add efficient support for continuous timers as well. | ||
103 | * | ||
104 | * Revision 1.1 2000/10/26 15:49:16 johana | ||
105 | * Added fasttimer, highresolution timers. | ||
106 | * | ||
107 | * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden | ||
108 | */ | 7 | */ |
109 | 8 | ||
110 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
@@ -122,9 +21,9 @@ | |||
122 | 21 | ||
123 | #include <linux/version.h> | 22 | #include <linux/version.h> |
124 | 23 | ||
125 | #include <asm/arch/hwregs/reg_map.h> | 24 | #include <hwregs/reg_map.h> |
126 | #include <asm/arch/hwregs/reg_rdwr.h> | 25 | #include <hwregs/reg_rdwr.h> |
127 | #include <asm/arch/hwregs/timer_defs.h> | 26 | #include <hwregs/timer_defs.h> |
128 | #include <asm/fasttimer.h> | 27 | #include <asm/fasttimer.h> |
129 | #include <linux/proc_fs.h> | 28 | #include <linux/proc_fs.h> |
130 | 29 | ||
@@ -140,30 +39,25 @@ | |||
140 | 39 | ||
141 | #define DEBUG_LOG_INCLUDED | 40 | #define DEBUG_LOG_INCLUDED |
142 | #define FAST_TIMER_LOG | 41 | #define FAST_TIMER_LOG |
143 | //#define FAST_TIMER_TEST | 42 | /* #define FAST_TIMER_TEST */ |
144 | 43 | ||
145 | #define FAST_TIMER_SANITY_CHECKS | 44 | #define FAST_TIMER_SANITY_CHECKS |
146 | 45 | ||
147 | #ifdef FAST_TIMER_SANITY_CHECKS | 46 | #ifdef FAST_TIMER_SANITY_CHECKS |
148 | #define SANITYCHECK(x) x | 47 | static int sanity_failed; |
149 | static int sanity_failed = 0; | ||
150 | #else | ||
151 | #define SANITYCHECK(x) | ||
152 | #endif | 48 | #endif |
153 | 49 | ||
154 | #define D1(x) | 50 | #define D1(x) |
155 | #define D2(x) | 51 | #define D2(x) |
156 | #define DP(x) | 52 | #define DP(x) |
157 | 53 | ||
158 | #define __INLINE__ inline | 54 | static unsigned int fast_timer_running; |
159 | 55 | static unsigned int fast_timers_added; | |
160 | static int fast_timer_running = 0; | 56 | static unsigned int fast_timers_started; |
161 | static int fast_timers_added = 0; | 57 | static unsigned int fast_timers_expired; |
162 | static int fast_timers_started = 0; | 58 | static unsigned int fast_timers_deleted; |
163 | static int fast_timers_expired = 0; | 59 | static unsigned int fast_timer_is_init; |
164 | static int fast_timers_deleted = 0; | 60 | static unsigned int fast_timer_ints; |
165 | static int fast_timer_is_init = 0; | ||
166 | static int fast_timer_ints = 0; | ||
167 | 61 | ||
168 | struct fast_timer *fast_timer_list = NULL; | 62 | struct fast_timer *fast_timer_list = NULL; |
169 | 63 | ||
@@ -171,8 +65,8 @@ struct fast_timer *fast_timer_list = NULL; | |||
171 | #define DEBUG_LOG_MAX 128 | 65 | #define DEBUG_LOG_MAX 128 |
172 | static const char * debug_log_string[DEBUG_LOG_MAX]; | 66 | static const char * debug_log_string[DEBUG_LOG_MAX]; |
173 | static unsigned long debug_log_value[DEBUG_LOG_MAX]; | 67 | static unsigned long debug_log_value[DEBUG_LOG_MAX]; |
174 | static int debug_log_cnt = 0; | 68 | static unsigned int debug_log_cnt; |
175 | static int debug_log_cnt_wrapped = 0; | 69 | static unsigned int debug_log_cnt_wrapped; |
176 | 70 | ||
177 | #define DEBUG_LOG(string, value) \ | 71 | #define DEBUG_LOG(string, value) \ |
178 | { \ | 72 | { \ |
@@ -202,103 +96,92 @@ struct fast_timer timer_expired_log[NUM_TIMER_STATS]; | |||
202 | int timer_div_settings[NUM_TIMER_STATS]; | 96 | int timer_div_settings[NUM_TIMER_STATS]; |
203 | int timer_delay_settings[NUM_TIMER_STATS]; | 97 | int timer_delay_settings[NUM_TIMER_STATS]; |
204 | 98 | ||
99 | struct work_struct fast_work; | ||
205 | 100 | ||
206 | static void | 101 | static void |
207 | timer_trig_handler(void); | 102 | timer_trig_handler(struct work_struct *work); |
208 | 103 | ||
209 | 104 | ||
210 | 105 | ||
211 | /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ | 106 | /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ |
212 | void __INLINE__ do_gettimeofday_fast(struct timeval *tv) | 107 | inline void do_gettimeofday_fast(struct fasttime_t *tv) |
213 | { | 108 | { |
214 | unsigned long sec = jiffies; | 109 | tv->tv_jiff = jiffies; |
215 | unsigned long usec = GET_JIFFIES_USEC(); | 110 | tv->tv_usec = GET_JIFFIES_USEC(); |
216 | |||
217 | usec += (sec % HZ) * (1000000 / HZ); | ||
218 | sec = sec / HZ; | ||
219 | |||
220 | if (usec > 1000000) | ||
221 | { | ||
222 | usec -= 1000000; | ||
223 | sec++; | ||
224 | } | ||
225 | tv->tv_sec = sec; | ||
226 | tv->tv_usec = usec; | ||
227 | } | 111 | } |
228 | 112 | ||
229 | int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1) | 113 | inline int fasttime_cmp(struct fasttime_t *t0, struct fasttime_t *t1) |
230 | { | 114 | { |
231 | if (t0->tv_sec < t1->tv_sec) | 115 | /* Compare jiffies. Takes care of wrapping */ |
232 | { | 116 | if (time_before(t0->tv_jiff, t1->tv_jiff)) |
233 | return -1; | 117 | return -1; |
234 | } | 118 | else if (time_after(t0->tv_jiff, t1->tv_jiff)) |
235 | else if (t0->tv_sec > t1->tv_sec) | 119 | return 1; |
236 | { | 120 | |
237 | return 1; | 121 | /* Compare us */ |
238 | } | 122 | if (t0->tv_usec < t1->tv_usec) |
239 | if (t0->tv_usec < t1->tv_usec) | 123 | return -1; |
240 | { | 124 | else if (t0->tv_usec > t1->tv_usec) |
241 | return -1; | 125 | return 1; |
242 | } | 126 | return 0; |
243 | else if (t0->tv_usec > t1->tv_usec) | ||
244 | { | ||
245 | return 1; | ||
246 | } | ||
247 | return 0; | ||
248 | } | 127 | } |
249 | 128 | ||
250 | /* Called with ints off */ | 129 | /* Called with ints off */ |
251 | void __INLINE__ start_timer_trig(unsigned long delay_us) | 130 | inline void start_timer_trig(unsigned long delay_us) |
252 | { | 131 | { |
253 | reg_timer_rw_ack_intr ack_intr = { 0 }; | 132 | reg_timer_rw_ack_intr ack_intr = { 0 }; |
254 | reg_timer_rw_intr_mask intr_mask; | 133 | reg_timer_rw_intr_mask intr_mask; |
255 | reg_timer_rw_trig trig; | 134 | reg_timer_rw_trig trig; |
256 | reg_timer_rw_trig_cfg trig_cfg = { 0 }; | 135 | reg_timer_rw_trig_cfg trig_cfg = { 0 }; |
257 | reg_timer_r_time r_time; | 136 | reg_timer_r_time r_time0; |
137 | reg_timer_r_time r_time1; | ||
138 | unsigned char trig_wrap; | ||
139 | unsigned char time_wrap; | ||
258 | 140 | ||
259 | r_time = REG_RD(timer, regi_timer, r_time); | 141 | r_time0 = REG_RD(timer, regi_timer0, r_time); |
260 | 142 | ||
261 | D1(printk("start_timer_trig : %d us freq: %i div: %i\n", | 143 | D1(printk("start_timer_trig : %d us freq: %i div: %i\n", |
262 | delay_us, freq_index, div)); | 144 | delay_us, freq_index, div)); |
263 | /* Clear trig irq */ | 145 | /* Clear trig irq */ |
264 | intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); | 146 | intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask); |
265 | intr_mask.trig = 0; | 147 | intr_mask.trig = 0; |
266 | REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); | 148 | REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask); |
267 | 149 | ||
268 | /* Set timer values */ | 150 | /* Set timer values and check if trigger wraps. */ |
269 | /* r_time is 100MHz (10 ns resolution) */ | 151 | /* r_time is 100MHz (10 ns resolution) */ |
270 | trig = r_time + delay_us*(1000/10); | 152 | trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0; |
271 | 153 | ||
272 | timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig; | 154 | timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig; |
273 | timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; | 155 | timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; |
274 | 156 | ||
275 | /* Ack interrupt */ | 157 | /* Ack interrupt */ |
276 | ack_intr.trig = 1; | 158 | ack_intr.trig = 1; |
277 | REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); | 159 | REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr); |
278 | 160 | ||
279 | /* Start timer */ | 161 | /* Start timer */ |
280 | REG_WR(timer, regi_timer, rw_trig, trig); | 162 | REG_WR(timer, regi_timer0, rw_trig, trig); |
281 | trig_cfg.tmr = regk_timer_time; | 163 | trig_cfg.tmr = regk_timer_time; |
282 | REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); | 164 | REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg); |
283 | 165 | ||
284 | /* Check if we have already passed the trig time */ | 166 | /* Check if we have already passed the trig time */ |
285 | r_time = REG_RD(timer, regi_timer, r_time); | 167 | r_time1 = REG_RD(timer, regi_timer0, r_time); |
286 | if (r_time < trig) { | 168 | time_wrap = r_time1 < r_time0; |
169 | |||
170 | if ((trig_wrap && !time_wrap) || (r_time1 < trig)) { | ||
287 | /* No, Enable trig irq */ | 171 | /* No, Enable trig irq */ |
288 | intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); | 172 | intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask); |
289 | intr_mask.trig = 1; | 173 | intr_mask.trig = 1; |
290 | REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); | 174 | REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask); |
291 | fast_timers_started++; | 175 | fast_timers_started++; |
292 | fast_timer_running = 1; | 176 | fast_timer_running = 1; |
293 | } | 177 | } else { |
294 | else | ||
295 | { | ||
296 | /* We have passed the time, disable trig point, ack intr */ | 178 | /* We have passed the time, disable trig point, ack intr */ |
297 | trig_cfg.tmr = regk_timer_off; | 179 | trig_cfg.tmr = regk_timer_off; |
298 | REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); | 180 | REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg); |
299 | REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); | 181 | REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr); |
300 | /* call the int routine directly */ | 182 | /* call the int routine */ |
301 | timer_trig_handler(); | 183 | INIT_WORK(&fast_work, timer_trig_handler); |
184 | schedule_work(&fast_work); | ||
302 | } | 185 | } |
303 | 186 | ||
304 | } | 187 | } |
@@ -320,22 +203,20 @@ void start_one_shot_timer(struct fast_timer *t, | |||
320 | do_gettimeofday_fast(&t->tv_set); | 203 | do_gettimeofday_fast(&t->tv_set); |
321 | tmp = fast_timer_list; | 204 | tmp = fast_timer_list; |
322 | 205 | ||
323 | SANITYCHECK({ /* Check so this is not in the list already... */ | 206 | #ifdef FAST_TIMER_SANITY_CHECKS |
324 | while (tmp != NULL) | 207 | /* Check so this is not in the list already... */ |
325 | { | 208 | while (tmp != NULL) { |
326 | if (tmp == t) | 209 | if (tmp == t) { |
327 | { | 210 | printk(KERN_DEBUG |
328 | printk("timer name: %s data: 0x%08lX already in list!\n", name, data); | 211 | "timer name: %s data: 0x%08lX already " |
329 | sanity_failed++; | 212 | "in list!\n", name, data); |
330 | return; | 213 | sanity_failed++; |
331 | } | 214 | goto done; |
332 | else | 215 | } else |
333 | { | 216 | tmp = tmp->next; |
334 | tmp = tmp->next; | 217 | } |
335 | } | 218 | tmp = fast_timer_list; |
336 | } | 219 | #endif |
337 | tmp = fast_timer_list; | ||
338 | }); | ||
339 | 220 | ||
340 | t->delay_us = delay_us; | 221 | t->delay_us = delay_us; |
341 | t->function = function; | 222 | t->function = function; |
@@ -343,11 +224,10 @@ void start_one_shot_timer(struct fast_timer *t, | |||
343 | t->name = name; | 224 | t->name = name; |
344 | 225 | ||
345 | t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; | 226 | t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; |
346 | t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000; | 227 | t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ; |
347 | if (t->tv_expires.tv_usec > 1000000) | 228 | if (t->tv_expires.tv_usec > 1000000) { |
348 | { | ||
349 | t->tv_expires.tv_usec -= 1000000; | 229 | t->tv_expires.tv_usec -= 1000000; |
350 | t->tv_expires.tv_sec++; | 230 | t->tv_expires.tv_jiff += HZ; |
351 | } | 231 | } |
352 | #ifdef FAST_TIMER_LOG | 232 | #ifdef FAST_TIMER_LOG |
353 | timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; | 233 | timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; |
@@ -355,15 +235,12 @@ void start_one_shot_timer(struct fast_timer *t, | |||
355 | fast_timers_added++; | 235 | fast_timers_added++; |
356 | 236 | ||
357 | /* Check if this should timeout before anything else */ | 237 | /* Check if this should timeout before anything else */ |
358 | if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0) | 238 | if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0) { |
359 | { | ||
360 | /* Put first in list and modify the timer value */ | 239 | /* Put first in list and modify the timer value */ |
361 | t->prev = NULL; | 240 | t->prev = NULL; |
362 | t->next = fast_timer_list; | 241 | t->next = fast_timer_list; |
363 | if (fast_timer_list) | 242 | if (fast_timer_list) |
364 | { | ||
365 | fast_timer_list->prev = t; | 243 | fast_timer_list->prev = t; |
366 | } | ||
367 | fast_timer_list = t; | 244 | fast_timer_list = t; |
368 | #ifdef FAST_TIMER_LOG | 245 | #ifdef FAST_TIMER_LOG |
369 | timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; | 246 | timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; |
@@ -372,10 +249,8 @@ void start_one_shot_timer(struct fast_timer *t, | |||
372 | } else { | 249 | } else { |
373 | /* Put in correct place in list */ | 250 | /* Put in correct place in list */ |
374 | while (tmp->next && | 251 | while (tmp->next && |
375 | timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) | 252 | fasttime_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) |
376 | { | ||
377 | tmp = tmp->next; | 253 | tmp = tmp->next; |
378 | } | ||
379 | /* Insert t after tmp */ | 254 | /* Insert t after tmp */ |
380 | t->prev = tmp; | 255 | t->prev = tmp; |
381 | t->next = tmp->next; | 256 | t->next = tmp->next; |
@@ -388,6 +263,7 @@ void start_one_shot_timer(struct fast_timer *t, | |||
388 | 263 | ||
389 | D2(printk("start_one_shot_timer: %d us done\n", delay_us)); | 264 | D2(printk("start_one_shot_timer: %d us done\n", delay_us)); |
390 | 265 | ||
266 | done: | ||
391 | local_irq_restore(flags); | 267 | local_irq_restore(flags); |
392 | } /* start_one_shot_timer */ | 268 | } /* start_one_shot_timer */ |
393 | 269 | ||
@@ -431,19 +307,18 @@ int del_fast_timer(struct fast_timer * t) | |||
431 | /* Timer interrupt handler for trig interrupts */ | 307 | /* Timer interrupt handler for trig interrupts */ |
432 | 308 | ||
433 | static irqreturn_t | 309 | static irqreturn_t |
434 | timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 310 | timer_trig_interrupt(int irq, void *dev_id) |
435 | { | 311 | { |
436 | reg_timer_r_masked_intr masked_intr; | 312 | reg_timer_r_masked_intr masked_intr; |
437 | |||
438 | /* Check if the timer interrupt is for us (a trig int) */ | 313 | /* Check if the timer interrupt is for us (a trig int) */ |
439 | masked_intr = REG_RD(timer, regi_timer, r_masked_intr); | 314 | masked_intr = REG_RD(timer, regi_timer0, r_masked_intr); |
440 | if (!masked_intr.trig) | 315 | if (!masked_intr.trig) |
441 | return IRQ_NONE; | 316 | return IRQ_NONE; |
442 | timer_trig_handler(); | 317 | timer_trig_handler(NULL); |
443 | return IRQ_HANDLED; | 318 | return IRQ_HANDLED; |
444 | } | 319 | } |
445 | 320 | ||
446 | static void timer_trig_handler(void) | 321 | static void timer_trig_handler(struct work_struct *work) |
447 | { | 322 | { |
448 | reg_timer_rw_ack_intr ack_intr = { 0 }; | 323 | reg_timer_rw_ack_intr ack_intr = { 0 }; |
449 | reg_timer_rw_intr_mask intr_mask; | 324 | reg_timer_rw_intr_mask intr_mask; |
@@ -451,38 +326,45 @@ static void timer_trig_handler(void) | |||
451 | struct fast_timer *t; | 326 | struct fast_timer *t; |
452 | unsigned long flags; | 327 | unsigned long flags; |
453 | 328 | ||
329 | /* We keep interrupts disabled not only when we modify the | ||
330 | * fast timer list, but any time we hold a reference to a | ||
331 | * timer in the list, since del_fast_timer may be called | ||
332 | * from (another) interrupt context. Thus, the only time | ||
333 | * when interrupts are enabled is when calling the timer | ||
334 | * callback function. | ||
335 | */ | ||
454 | local_irq_save(flags); | 336 | local_irq_save(flags); |
455 | 337 | ||
456 | /* Clear timer trig interrupt */ | 338 | /* Clear timer trig interrupt */ |
457 | intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); | 339 | intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask); |
458 | intr_mask.trig = 0; | 340 | intr_mask.trig = 0; |
459 | REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); | 341 | REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask); |
460 | 342 | ||
461 | /* First stop timer, then ack interrupt */ | 343 | /* First stop timer, then ack interrupt */ |
462 | /* Stop timer */ | 344 | /* Stop timer */ |
463 | trig_cfg.tmr = regk_timer_off; | 345 | trig_cfg.tmr = regk_timer_off; |
464 | REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); | 346 | REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg); |
465 | 347 | ||
466 | /* Ack interrupt */ | 348 | /* Ack interrupt */ |
467 | ack_intr.trig = 1; | 349 | ack_intr.trig = 1; |
468 | REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); | 350 | REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr); |
469 | 351 | ||
470 | fast_timer_running = 0; | 352 | fast_timer_running = 0; |
471 | fast_timer_ints++; | 353 | fast_timer_ints++; |
472 | 354 | ||
473 | local_irq_restore(flags); | 355 | fast_timer_function_type *f; |
356 | unsigned long d; | ||
474 | 357 | ||
475 | t = fast_timer_list; | 358 | t = fast_timer_list; |
476 | while (t) | 359 | while (t) { |
477 | { | 360 | struct fasttime_t tv; |
478 | struct timeval tv; | ||
479 | 361 | ||
480 | /* Has it really expired? */ | 362 | /* Has it really expired? */ |
481 | do_gettimeofday_fast(&tv); | 363 | do_gettimeofday_fast(&tv); |
482 | D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec)); | 364 | D1(printk(KERN_DEBUG |
365 | "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec)); | ||
483 | 366 | ||
484 | if (timeval_cmp(&t->tv_expires, &tv) <= 0) | 367 | if (fasttime_cmp(&t->tv_expires, &tv) <= 0) { |
485 | { | ||
486 | /* Yes it has expired */ | 368 | /* Yes it has expired */ |
487 | #ifdef FAST_TIMER_LOG | 369 | #ifdef FAST_TIMER_LOG |
488 | timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; | 370 | timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; |
@@ -490,84 +372,77 @@ static void timer_trig_handler(void) | |||
490 | fast_timers_expired++; | 372 | fast_timers_expired++; |
491 | 373 | ||
492 | /* Remove this timer before call, since it may reuse the timer */ | 374 | /* Remove this timer before call, since it may reuse the timer */ |
493 | local_irq_save(flags); | ||
494 | if (t->prev) | 375 | if (t->prev) |
495 | { | ||
496 | t->prev->next = t->next; | 376 | t->prev->next = t->next; |
497 | } | ||
498 | else | 377 | else |
499 | { | ||
500 | fast_timer_list = t->next; | 378 | fast_timer_list = t->next; |
501 | } | ||
502 | if (t->next) | 379 | if (t->next) |
503 | { | ||
504 | t->next->prev = t->prev; | 380 | t->next->prev = t->prev; |
505 | } | ||
506 | t->prev = NULL; | 381 | t->prev = NULL; |
507 | t->next = NULL; | 382 | t->next = NULL; |
508 | local_irq_restore(flags); | ||
509 | 383 | ||
510 | if (t->function != NULL) | 384 | /* Save function callback data before enabling |
511 | { | 385 | * interrupts, since the timer may be removed and we |
512 | t->function(t->data); | 386 | * don't know how it was allocated (e.g. ->function |
513 | } | 387 | * and ->data may become overwritten after deletion |
514 | else | 388 | * if the timer was stack-allocated). |
515 | { | 389 | */ |
390 | f = t->function; | ||
391 | d = t->data; | ||
392 | |||
393 | if (f != NULL) { | ||
394 | /* Run the callback function with interrupts | ||
395 | * enabled. */ | ||
396 | local_irq_restore(flags); | ||
397 | f(d); | ||
398 | local_irq_save(flags); | ||
399 | } else | ||
516 | DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints); | 400 | DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints); |
517 | } | 401 | } else { |
518 | } | ||
519 | else | ||
520 | { | ||
521 | /* Timer is to early, let's set it again using the normal routines */ | 402 | /* Timer is to early, let's set it again using the normal routines */ |
522 | D1(printk(".\n")); | 403 | D1(printk(".\n")); |
523 | } | 404 | } |
524 | 405 | ||
525 | local_irq_save(flags); | 406 | t = fast_timer_list; |
526 | if ((t = fast_timer_list) != NULL) | 407 | if (t != NULL) { |
527 | { | ||
528 | /* Start next timer.. */ | 408 | /* Start next timer.. */ |
529 | long us; | 409 | long us = 0; |
530 | struct timeval tv; | 410 | struct fasttime_t tv; |
531 | 411 | ||
532 | do_gettimeofday_fast(&tv); | 412 | do_gettimeofday_fast(&tv); |
533 | us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 + | 413 | |
534 | t->tv_expires.tv_usec - tv.tv_usec); | 414 | /* time_after_eq takes care of wrapping */ |
535 | if (us > 0) | 415 | if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff)) |
536 | { | 416 | us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * |
537 | if (!fast_timer_running) | 417 | 1000000 / HZ + t->tv_expires.tv_usec - |
538 | { | 418 | tv.tv_usec); |
419 | |||
420 | if (us > 0) { | ||
421 | if (!fast_timer_running) { | ||
539 | #ifdef FAST_TIMER_LOG | 422 | #ifdef FAST_TIMER_LOG |
540 | timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; | 423 | timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; |
541 | #endif | 424 | #endif |
542 | start_timer_trig(us); | 425 | start_timer_trig(us); |
543 | } | 426 | } |
544 | local_irq_restore(flags); | ||
545 | break; | 427 | break; |
546 | } | 428 | } else { |
547 | else | ||
548 | { | ||
549 | /* Timer already expired, let's handle it better late than never. | 429 | /* Timer already expired, let's handle it better late than never. |
550 | * The normal loop handles it | 430 | * The normal loop handles it |
551 | */ | 431 | */ |
552 | D1(printk("e! %d\n", us)); | 432 | D1(printk("e! %d\n", us)); |
553 | } | 433 | } |
554 | } | 434 | } |
555 | local_irq_restore(flags); | ||
556 | } | 435 | } |
557 | 436 | ||
558 | if (!t) | 437 | local_irq_restore(flags); |
559 | { | 438 | |
439 | if (!t) | ||
560 | D1(printk("ttrig stop!\n")); | 440 | D1(printk("ttrig stop!\n")); |
561 | } | ||
562 | } | 441 | } |
563 | 442 | ||
564 | static void wake_up_func(unsigned long data) | 443 | static void wake_up_func(unsigned long data) |
565 | { | 444 | { |
566 | #ifdef DECLARE_WAITQUEUE | ||
567 | wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data; | 445 | wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data; |
568 | #else | ||
569 | struct wait_queue **sleep_wait_p = (struct wait_queue **)data; | ||
570 | #endif | ||
571 | wake_up(sleep_wait_p); | 446 | wake_up(sleep_wait_p); |
572 | } | 447 | } |
573 | 448 | ||
@@ -577,28 +452,17 @@ static void wake_up_func(unsigned long data) | |||
577 | void schedule_usleep(unsigned long us) | 452 | void schedule_usleep(unsigned long us) |
578 | { | 453 | { |
579 | struct fast_timer t; | 454 | struct fast_timer t; |
580 | #ifdef DECLARE_WAITQUEUE | ||
581 | wait_queue_head_t sleep_wait; | 455 | wait_queue_head_t sleep_wait; |
582 | init_waitqueue_head(&sleep_wait); | 456 | init_waitqueue_head(&sleep_wait); |
583 | { | ||
584 | DECLARE_WAITQUEUE(wait, current); | ||
585 | #else | ||
586 | struct wait_queue *sleep_wait = NULL; | ||
587 | struct wait_queue wait = { current, NULL }; | ||
588 | #endif | ||
589 | 457 | ||
590 | D1(printk("schedule_usleep(%d)\n", us)); | 458 | D1(printk("schedule_usleep(%d)\n", us)); |
591 | add_wait_queue(&sleep_wait, &wait); | ||
592 | set_current_state(TASK_INTERRUPTIBLE); | ||
593 | start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us, | 459 | start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us, |
594 | "usleep"); | 460 | "usleep"); |
595 | schedule(); | 461 | /* Uninterruptible sleep on the fast timer. (The condition is |
596 | set_current_state(TASK_RUNNING); | 462 | * somewhat redundant since the timer is what wakes us up.) */ |
597 | remove_wait_queue(&sleep_wait, &wait); | 463 | wait_event(sleep_wait, !fast_timer_pending(&t)); |
464 | |||
598 | D1(printk("done schedule_usleep(%d)\n", us)); | 465 | D1(printk("done schedule_usleep(%d)\n", us)); |
599 | #ifdef DECLARE_WAITQUEUE | ||
600 | } | ||
601 | #endif | ||
602 | } | 466 | } |
603 | 467 | ||
604 | #ifdef CONFIG_PROC_FS | 468 | #ifdef CONFIG_PROC_FS |
@@ -618,20 +482,22 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
618 | unsigned long flags; | 482 | unsigned long flags; |
619 | int i = 0; | 483 | int i = 0; |
620 | int num_to_show; | 484 | int num_to_show; |
621 | struct timeval tv; | 485 | struct fasttime_t tv; |
622 | struct fast_timer *t, *nextt; | 486 | struct fast_timer *t, *nextt; |
623 | static char *bigbuf = NULL; | 487 | static char *bigbuf = NULL; |
624 | static unsigned long used; | 488 | static unsigned long used; |
625 | 489 | ||
626 | if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) | 490 | if (!bigbuf) { |
627 | { | 491 | bigbuf = vmalloc(BIG_BUF_SIZE); |
628 | used = 0; | 492 | if (!bigbuf) { |
629 | bigbuf[0] = '\0'; | 493 | used = 0; |
630 | return 0; | 494 | if (buf) |
631 | } | 495 | buf[0] = '\0'; |
632 | 496 | return 0; | |
633 | if (!offset || !used) | 497 | } |
634 | { | 498 | } |
499 | |||
500 | if (!offset || !used) { | ||
635 | do_gettimeofday_fast(&tv); | 501 | do_gettimeofday_fast(&tv); |
636 | 502 | ||
637 | used = 0; | 503 | used = 0; |
@@ -648,7 +514,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
648 | used += sprintf(bigbuf + used, "Fast timer running: %s\n", | 514 | used += sprintf(bigbuf + used, "Fast timer running: %s\n", |
649 | fast_timer_running ? "yes" : "no"); | 515 | fast_timer_running ? "yes" : "no"); |
650 | used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", | 516 | used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", |
651 | (unsigned long)tv.tv_sec, | 517 | (unsigned long)tv.tv_jiff, |
652 | (unsigned long)tv.tv_usec); | 518 | (unsigned long)tv.tv_usec); |
653 | #ifdef FAST_TIMER_SANITY_CHECKS | 519 | #ifdef FAST_TIMER_SANITY_CHECKS |
654 | used += sprintf(bigbuf + used, "Sanity failed: %i\n", | 520 | used += sprintf(bigbuf + used, "Sanity failed: %i\n", |
@@ -661,10 +527,8 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
661 | int end_i = debug_log_cnt; | 527 | int end_i = debug_log_cnt; |
662 | i = 0; | 528 | i = 0; |
663 | 529 | ||
664 | if (debug_log_cnt_wrapped) | 530 | if (debug_log_cnt_wrapped) |
665 | { | ||
666 | i = debug_log_cnt; | 531 | i = debug_log_cnt; |
667 | } | ||
668 | 532 | ||
669 | while ((i != end_i || (debug_log_cnt_wrapped && !used)) && | 533 | while ((i != end_i || (debug_log_cnt_wrapped && !used)) && |
670 | used+100 < BIG_BUF_SIZE) | 534 | used+100 < BIG_BUF_SIZE) |
@@ -697,9 +561,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
697 | "d: %6li us data: 0x%08lX" | 561 | "d: %6li us data: 0x%08lX" |
698 | "\n", | 562 | "\n", |
699 | t->name, | 563 | t->name, |
700 | (unsigned long)t->tv_set.tv_sec, | 564 | (unsigned long)t->tv_set.tv_jiff, |
701 | (unsigned long)t->tv_set.tv_usec, | 565 | (unsigned long)t->tv_set.tv_usec, |
702 | (unsigned long)t->tv_expires.tv_sec, | 566 | (unsigned long)t->tv_expires.tv_jiff, |
703 | (unsigned long)t->tv_expires.tv_usec, | 567 | (unsigned long)t->tv_expires.tv_usec, |
704 | t->delay_us, | 568 | t->delay_us, |
705 | t->data | 569 | t->data |
@@ -719,9 +583,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
719 | "d: %6li us data: 0x%08lX" | 583 | "d: %6li us data: 0x%08lX" |
720 | "\n", | 584 | "\n", |
721 | t->name, | 585 | t->name, |
722 | (unsigned long)t->tv_set.tv_sec, | 586 | (unsigned long)t->tv_set.tv_jiff, |
723 | (unsigned long)t->tv_set.tv_usec, | 587 | (unsigned long)t->tv_set.tv_usec, |
724 | (unsigned long)t->tv_expires.tv_sec, | 588 | (unsigned long)t->tv_expires.tv_jiff, |
725 | (unsigned long)t->tv_expires.tv_usec, | 589 | (unsigned long)t->tv_expires.tv_usec, |
726 | t->delay_us, | 590 | t->delay_us, |
727 | t->data | 591 | t->data |
@@ -739,9 +603,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
739 | "d: %6li us data: 0x%08lX" | 603 | "d: %6li us data: 0x%08lX" |
740 | "\n", | 604 | "\n", |
741 | t->name, | 605 | t->name, |
742 | (unsigned long)t->tv_set.tv_sec, | 606 | (unsigned long)t->tv_set.tv_jiff, |
743 | (unsigned long)t->tv_set.tv_usec, | 607 | (unsigned long)t->tv_set.tv_usec, |
744 | (unsigned long)t->tv_expires.tv_sec, | 608 | (unsigned long)t->tv_expires.tv_jiff, |
745 | (unsigned long)t->tv_expires.tv_usec, | 609 | (unsigned long)t->tv_expires.tv_usec, |
746 | t->delay_us, | 610 | t->delay_us, |
747 | t->data | 611 | t->data |
@@ -752,26 +616,25 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len | |||
752 | 616 | ||
753 | used += sprintf(bigbuf + used, "Active timers:\n"); | 617 | used += sprintf(bigbuf + used, "Active timers:\n"); |
754 | local_irq_save(flags); | 618 | local_irq_save(flags); |
755 | local_irq_save(flags); | ||
756 | t = fast_timer_list; | 619 | t = fast_timer_list; |
757 | while (t != NULL && (used+100 < BIG_BUF_SIZE)) | 620 | while (t != NULL && (used+100 < BIG_BUF_SIZE)) |
758 | { | 621 | { |
759 | nextt = t->next; | 622 | nextt = t->next; |
760 | local_irq_restore(flags); | 623 | local_irq_restore(flags); |
761 | used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " | 624 | used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " |
762 | "d: %6li us data: 0x%08lX" | 625 | "d: %6li us data: 0x%08lX" |
763 | /* " func: 0x%08lX" */ | 626 | /* " func: 0x%08lX" */ |
764 | "\n", | 627 | "\n", |
765 | t->name, | 628 | t->name, |
766 | (unsigned long)t->tv_set.tv_sec, | 629 | (unsigned long)t->tv_set.tv_jiff, |
767 | (unsigned long)t->tv_set.tv_usec, | 630 | (unsigned long)t->tv_set.tv_usec, |
768 | (unsigned long)t->tv_expires.tv_sec, | 631 | (unsigned long)t->tv_expires.tv_jiff, |
769 | (unsigned long)t->tv_expires.tv_usec, | 632 | (unsigned long)t->tv_expires.tv_usec, |
770 | t->delay_us, | 633 | t->delay_us, |
771 | t->data | 634 | t->data |
772 | /* , t->function */ | 635 | /* , t->function */ |
773 | ); | 636 | ); |
774 | local_irq_disable(); | 637 | local_irq_save(flags); |
775 | if (t->next != nextt) | 638 | if (t->next != nextt) |
776 | { | 639 | { |
777 | printk("timer removed!\n"); | 640 | printk("timer removed!\n"); |
@@ -800,7 +663,7 @@ static volatile int num_test_timeout = 0; | |||
800 | static struct fast_timer tr[10]; | 663 | static struct fast_timer tr[10]; |
801 | static int exp_num[10]; | 664 | static int exp_num[10]; |
802 | 665 | ||
803 | static struct timeval tv_exp[100]; | 666 | static struct fasttime_t tv_exp[100]; |
804 | 667 | ||
805 | static void test_timeout(unsigned long data) | 668 | static void test_timeout(unsigned long data) |
806 | { | 669 | { |
@@ -838,7 +701,7 @@ static void fast_timer_test(void) | |||
838 | int prev_num; | 701 | int prev_num; |
839 | int j; | 702 | int j; |
840 | 703 | ||
841 | struct timeval tv, tv0, tv1, tv2; | 704 | struct fasttime_t tv, tv0, tv1, tv2; |
842 | 705 | ||
843 | printk("fast_timer_test() start\n"); | 706 | printk("fast_timer_test() start\n"); |
844 | do_gettimeofday_fast(&tv); | 707 | do_gettimeofday_fast(&tv); |
@@ -851,21 +714,22 @@ static void fast_timer_test(void) | |||
851 | { | 714 | { |
852 | do_gettimeofday_fast(&tv_exp[j]); | 715 | do_gettimeofday_fast(&tv_exp[j]); |
853 | } | 716 | } |
854 | printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec); | 717 | printk(KERN_DEBUG "fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec); |
855 | 718 | ||
856 | for (j = 0; j < 1000; j++) | 719 | for (j = 0; j < 1000; j++) |
857 | { | 720 | { |
858 | printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]); | 721 | printk(KERN_DEBUG "%i %i %i %i %i\n", |
722 | j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]); | ||
859 | j += 4; | 723 | j += 4; |
860 | } | 724 | } |
861 | for (j = 0; j < 100; j++) | 725 | for (j = 0; j < 100; j++) |
862 | { | 726 | { |
863 | printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n", | 727 | printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n", |
864 | tv_exp[j].tv_sec,tv_exp[j].tv_usec, | 728 | tv_exp[j].tv_jiff, tv_exp[j].tv_usec, |
865 | tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec, | 729 | tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec, |
866 | tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec, | 730 | tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec, |
867 | tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec, | 731 | tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec, |
868 | tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec); | 732 | tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec); |
869 | j += 4; | 733 | j += 4; |
870 | } | 734 | } |
871 | do_gettimeofday_fast(&tv0); | 735 | do_gettimeofday_fast(&tv0); |
@@ -892,14 +756,15 @@ static void fast_timer_test(void) | |||
892 | while (num_test_timeout < i) | 756 | while (num_test_timeout < i) |
893 | { | 757 | { |
894 | if (num_test_timeout != prev_num) | 758 | if (num_test_timeout != prev_num) |
895 | { | ||
896 | prev_num = num_test_timeout; | 759 | prev_num = num_test_timeout; |
897 | } | ||
898 | } | 760 | } |
899 | do_gettimeofday_fast(&tv2); | 761 | do_gettimeofday_fast(&tv2); |
900 | printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec); | 762 | printk(KERN_INFO "Timers started %is %06i\n", |
901 | printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec); | 763 | tv0.tv_jiff, tv0.tv_usec); |
902 | printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec); | 764 | printk(KERN_INFO "Timers started at %is %06i\n", |
765 | tv1.tv_jiff, tv1.tv_usec); | ||
766 | printk(KERN_INFO "Timers done %is %06i\n", | ||
767 | tv2.tv_jiff, tv2.tv_usec); | ||
903 | DP(printk("buf0:\n"); | 768 | DP(printk("buf0:\n"); |
904 | printk(buf0); | 769 | printk(buf0); |
905 | printk("buf1:\n"); | 770 | printk("buf1:\n"); |
@@ -921,9 +786,9 @@ static void fast_timer_test(void) | |||
921 | printk("%-10s set: %6is %06ius exp: %6is %06ius " | 786 | printk("%-10s set: %6is %06ius exp: %6is %06ius " |
922 | "data: 0x%08X func: 0x%08X\n", | 787 | "data: 0x%08X func: 0x%08X\n", |
923 | t->name, | 788 | t->name, |
924 | t->tv_set.tv_sec, | 789 | t->tv_set.tv_jiff, |
925 | t->tv_set.tv_usec, | 790 | t->tv_set.tv_usec, |
926 | t->tv_expires.tv_sec, | 791 | t->tv_expires.tv_jiff, |
927 | t->tv_expires.tv_usec, | 792 | t->tv_expires.tv_usec, |
928 | t->data, | 793 | t->data, |
929 | t->function | 794 | t->function |
@@ -931,10 +796,12 @@ static void fast_timer_test(void) | |||
931 | 796 | ||
932 | printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", | 797 | printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", |
933 | t->delay_us, | 798 | t->delay_us, |
934 | tv_exp[j].tv_sec, | 799 | tv_exp[j].tv_jiff, |
935 | tv_exp[j].tv_usec, | 800 | tv_exp[j].tv_usec, |
936 | exp_num[j], | 801 | exp_num[j], |
937 | (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec); | 802 | (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) * |
803 | 1000000 + tv_exp[j].tv_usec - | ||
804 | t->tv_expires.tv_usec); | ||
938 | } | 805 | } |
939 | proc_fasttimer_read(buf5, NULL, 0, 0, 0); | 806 | proc_fasttimer_read(buf5, NULL, 0, 0, 0); |
940 | printk("buf5 after all done:\n"); | 807 | printk("buf5 after all done:\n"); |
@@ -944,7 +811,7 @@ static void fast_timer_test(void) | |||
944 | #endif | 811 | #endif |
945 | 812 | ||
946 | 813 | ||
947 | void fast_timer_init(void) | 814 | int fast_timer_init(void) |
948 | { | 815 | { |
949 | /* For some reason, request_irq() hangs when called froom time_init() */ | 816 | /* For some reason, request_irq() hangs when called froom time_init() */ |
950 | if (!fast_timer_is_init) | 817 | if (!fast_timer_is_init) |
@@ -952,18 +819,20 @@ void fast_timer_init(void) | |||
952 | printk("fast_timer_init()\n"); | 819 | printk("fast_timer_init()\n"); |
953 | 820 | ||
954 | #ifdef CONFIG_PROC_FS | 821 | #ifdef CONFIG_PROC_FS |
955 | if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) | 822 | fasttimer_proc_entry = create_proc_entry("fasttimer", 0, 0); |
956 | fasttimer_proc_entry->read_proc = proc_fasttimer_read; | 823 | if (fasttimer_proc_entry) |
824 | fasttimer_proc_entry->read_proc = proc_fasttimer_read; | ||
957 | #endif /* PROC_FS */ | 825 | #endif /* PROC_FS */ |
958 | if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED, | 826 | if (request_irq(TIMER0_INTR_VECT, timer_trig_interrupt, |
959 | "fast timer int", NULL)) | 827 | IRQF_SHARED | IRQF_DISABLED, |
960 | { | 828 | "fast timer int", &fast_timer_list)) |
961 | printk("err: timer1 irq\n"); | 829 | printk(KERN_ERR "err: fasttimer irq\n"); |
962 | } | ||
963 | fast_timer_is_init = 1; | 830 | fast_timer_is_init = 1; |
964 | #ifdef FAST_TIMER_TEST | 831 | #ifdef FAST_TIMER_TEST |
965 | printk("do test\n"); | 832 | printk("do test\n"); |
966 | fast_timer_test(); | 833 | fast_timer_test(); |
967 | #endif | 834 | #endif |
968 | } | 835 | } |
836 | return 0; | ||
969 | } | 837 | } |
838 | __initcall(fast_timer_init); | ||
diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S index 20bd80a84e48..2d66a7c320e1 100644 --- a/arch/cris/arch-v32/kernel/head.S +++ b/arch/cris/arch-v32/kernel/head.S | |||
@@ -4,22 +4,25 @@ | |||
4 | * Copyright (C) 2003, Axis Communications AB | 4 | * Copyright (C) 2003, Axis Communications AB |
5 | */ | 5 | */ |
6 | 6 | ||
7 | |||
8 | #define ASSEMBLER_MACROS_ONLY | 7 | #define ASSEMBLER_MACROS_ONLY |
9 | 8 | ||
10 | /* | 9 | /* |
11 | * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so | 10 | * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so |
12 | * -traditional must not be used when assembling this file. | 11 | * -traditional must not be used when assembling this file. |
13 | */ | 12 | */ |
14 | #include <asm/arch/hwregs/reg_rdwr.h> | 13 | #include <hwregs/reg_rdwr.h> |
15 | #include <asm/arch/hwregs/asm/mmu_defs_asm.h> | 14 | #include <asm/arch/memmap.h> |
16 | #include <asm/arch/hwregs/asm/reg_map_asm.h> | 15 | #include <hwregs/intr_vect.h> |
17 | #include <asm/arch/hwregs/asm/config_defs_asm.h> | 16 | #include <hwregs/asm/mmu_defs_asm.h> |
18 | #include <asm/arch/hwregs/asm/bif_core_defs_asm.h> | 17 | #include <hwregs/asm/reg_map_asm.h> |
18 | #include <asm/arch/mach/startup.inc> | ||
19 | 19 | ||
20 | #define CRAMFS_MAGIC 0x28cd3d45 | 20 | #define CRAMFS_MAGIC 0x28cd3d45 |
21 | #define JHEAD_MAGIC 0x1FF528A6 | ||
22 | #define JHEAD_SIZE 8 | ||
21 | #define RAM_INIT_MAGIC 0x56902387 | 23 | #define RAM_INIT_MAGIC 0x56902387 |
22 | #define COMMAND_LINE_MAGIC 0x87109563 | 24 | #define COMMAND_LINE_MAGIC 0x87109563 |
25 | #define NAND_BOOT_MAGIC 0x9a9db001 | ||
23 | 26 | ||
24 | ;; NOTE: R8 and R9 carry information from the decompressor (if the | 27 | ;; NOTE: R8 and R9 carry information from the decompressor (if the |
25 | ;; kernel was compressed). They must not be used in the code below | 28 | ;; kernel was compressed). They must not be used in the code below |
@@ -30,12 +33,11 @@ | |||
30 | .global romfs_start | 33 | .global romfs_start |
31 | .global romfs_length | 34 | .global romfs_length |
32 | .global romfs_in_flash | 35 | .global romfs_in_flash |
36 | .global nand_boot | ||
33 | .global swapper_pg_dir | 37 | .global swapper_pg_dir |
34 | .global crisv32_nand_boot | ||
35 | .global crisv32_nand_cramfs_offset | ||
36 | 38 | ||
37 | ;; Dummy section to make it bootable with current VCS simulator | 39 | ;; Dummy section to make it bootable with current VCS simulator |
38 | #ifdef CONFIG_ETRAXFS_SIM | 40 | #ifdef CONFIG_ETRAX_VCS_SIM |
39 | .section ".boot", "ax" | 41 | .section ".boot", "ax" |
40 | ba tstart | 42 | ba tstart |
41 | nop | 43 | nop |
@@ -51,33 +53,15 @@ tstart: | |||
51 | ;; | 53 | ;; |
52 | di | 54 | di |
53 | 55 | ||
54 | ;; Start clocks for used blocks. | 56 | START_CLOCKS |
55 | move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1 | 57 | |
56 | move.d [$r1], $r0 | 58 | SETUP_WAIT_STATES |
57 | or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \ | 59 | |
58 | REG_STATE(config, rw_clk_ctrl, bif, yes) | \ | 60 | GIO_INIT |
59 | REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0 | 61 | |
60 | move.d $r0, [$r1] | 62 | #ifdef CONFIG_SMP |
61 | 63 | secondary_cpu_entry: /* Entry point for secondary CPUs */ | |
62 | ;; Set up waitstates etc | 64 | di |
63 | move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r0 | ||
64 | move.d CONFIG_ETRAX_MEM_GRP1_CONFIG, $r1 | ||
65 | move.d $r1, [$r0] | ||
66 | move.d REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg), $r0 | ||
67 | move.d CONFIG_ETRAX_MEM_GRP2_CONFIG, $r1 | ||
68 | move.d $r1, [$r0] | ||
69 | move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r0 | ||
70 | move.d CONFIG_ETRAX_MEM_GRP3_CONFIG, $r1 | ||
71 | move.d $r1, [$r0] | ||
72 | move.d REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0 | ||
73 | move.d CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1 | ||
74 | move.d $r1, [$r0] | ||
75 | |||
76 | #ifdef CONFIG_ETRAXFS_SIM | ||
77 | ;; Set up minimal flash waitstates | ||
78 | move.d 0, $r10 | ||
79 | move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11 | ||
80 | move.d $r10, [$r11] | ||
81 | #endif | 65 | #endif |
82 | 66 | ||
83 | ;; Setup and enable the MMU. Use same configuration for both the data | 67 | ;; Setup and enable the MMU. Use same configuration for both the data |
@@ -85,7 +69,7 @@ tstart: | |||
85 | ;; | 69 | ;; |
86 | ;; Note; 3 cycles is needed for a bank-select to take effect. Further; | 70 | ;; Note; 3 cycles is needed for a bank-select to take effect. Further; |
87 | ;; bank 1 is the instruction MMU, bank 2 is the data MMU. | 71 | ;; bank 1 is the instruction MMU, bank 2 is the data MMU. |
88 | #ifndef CONFIG_ETRAXFS_SIM | 72 | #ifndef CONFIG_ETRAX_VCS_SIM |
89 | move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ | 73 | move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ |
90 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ | 74 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ |
91 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0 | 75 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0 |
@@ -93,7 +77,7 @@ tstart: | |||
93 | ;; Map the virtual DRAM to the RW eprom area at address 0. | 77 | ;; Map the virtual DRAM to the RW eprom area at address 0. |
94 | ;; Also map 0xa for the hook calls, | 78 | ;; Also map 0xa for the hook calls, |
95 | move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ | 79 | move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ |
96 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0) \ | 80 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ |
97 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \ | 81 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \ |
98 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0 | 82 | | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0 |
99 | #endif | 83 | #endif |
@@ -104,7 +88,7 @@ tstart: | |||
104 | 88 | ||
105 | ;; Enable certain page protections and setup linear mapping | 89 | ;; Enable certain page protections and setup linear mapping |
106 | ;; for f,e,c,b,4,0. | 90 | ;; for f,e,c,b,4,0. |
107 | #ifndef CONFIG_ETRAXFS_SIM | 91 | #ifndef CONFIG_ETRAX_VCS_SIM |
108 | move.d REG_STATE(mmu, rw_mm_cfg, we, on) \ | 92 | move.d REG_STATE(mmu, rw_mm_cfg, we, on) \ |
109 | | REG_STATE(mmu, rw_mm_cfg, acc, on) \ | 93 | | REG_STATE(mmu, rw_mm_cfg, acc, on) \ |
110 | | REG_STATE(mmu, rw_mm_cfg, ex, on) \ | 94 | | REG_STATE(mmu, rw_mm_cfg, ex, on) \ |
@@ -183,17 +167,11 @@ tstart: | |||
183 | nop | 167 | nop |
184 | nop | 168 | nop |
185 | nop | 169 | nop |
186 | move $s10, $r0 | 170 | move $s12, $r0 |
187 | cmpq 0, $r0 | 171 | cmpq 0, $r0 |
188 | beq master_cpu | 172 | beq master_cpu |
189 | nop | 173 | nop |
190 | slave_cpu: | 174 | slave_cpu: |
191 | ; A slave waits for cpu_now_booting to be equal to CPU ID. | ||
192 | move.d cpu_now_booting, $r1 | ||
193 | slave_wait: | ||
194 | cmp.d [$r1], $r0 | ||
195 | bne slave_wait | ||
196 | nop | ||
197 | ; Time to boot-up. Get stack location provided by master CPU. | 175 | ; Time to boot-up. Get stack location provided by master CPU. |
198 | move.d smp_init_current_idle_thread, $r1 | 176 | move.d smp_init_current_idle_thread, $r1 |
199 | move.d [$r1], $sp | 177 | move.d [$r1], $sp |
@@ -203,9 +181,16 @@ slave_wait: | |||
203 | jsr smp_callin | 181 | jsr smp_callin |
204 | nop | 182 | nop |
205 | master_cpu: | 183 | master_cpu: |
184 | /* Set up entry point for secondary CPUs. The boot ROM has set up | ||
185 | * EBP at start of internal memory. The CPU will get there | ||
186 | * later when we issue an IPI to them... */ | ||
187 | move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0 | ||
188 | move.d secondary_cpu_entry, $r1 | ||
189 | move.d $r1, [$r0] | ||
206 | #endif | 190 | #endif |
207 | #ifndef CONFIG_ETRAXFS_SIM | 191 | #ifndef CONFIG_ETRAX_VCS_SIM |
208 | ;; Check if starting from DRAM or flash. | 192 | ; Check if starting from DRAM (network->RAM boot or unpacked |
193 | ; compressed kernel), or directly from flash. | ||
209 | lapcq ., $r0 | 194 | lapcq ., $r0 |
210 | and.d 0x7fffffff, $r0 ; Mask off the non-cache bit. | 195 | and.d 0x7fffffff, $r0 ; Mask off the non-cache bit. |
211 | cmp.d 0x10000, $r0 ; Arbitrary, something above this code. | 196 | cmp.d 0x10000, $r0 ; Arbitrary, something above this code. |
@@ -232,12 +217,13 @@ _inflash: | |||
232 | beq _dram_initialized | 217 | beq _dram_initialized |
233 | nop | 218 | nop |
234 | 219 | ||
235 | #include "../lib/dram_init.S" | 220 | #include "../mach/dram_init.S" |
236 | 221 | ||
237 | _dram_initialized: | 222 | _dram_initialized: |
238 | ;; Copy the text and data section to DRAM. This depends on that the | 223 | ;; Copy the text and data section to DRAM. This depends on that the |
239 | ;; variables used below are correctly set up by the linker script. | 224 | ;; variables used below are correctly set up by the linker script. |
240 | ;; The calculated value stored in R4 is used below. | 225 | ;; The calculated value stored in R4 is used below. |
226 | ;; Leave the cramfs file system (piggybacked after the kernel) in flash. | ||
241 | moveq 0, $r0 ; Source. | 227 | moveq 0, $r0 ; Source. |
242 | move.d text_start, $r1 ; Destination. | 228 | move.d text_start, $r1 ; Destination. |
243 | move.d __vmlinux_end, $r2 | 229 | move.d __vmlinux_end, $r2 |
@@ -249,7 +235,7 @@ _dram_initialized: | |||
249 | blo 1b | 235 | blo 1b |
250 | nop | 236 | nop |
251 | 237 | ||
252 | ;; Keep CRAMFS in flash. | 238 | ;; Check for cramfs. |
253 | moveq 0, $r0 | 239 | moveq 0, $r0 |
254 | move.d romfs_length, $r1 | 240 | move.d romfs_length, $r1 |
255 | move.d $r0, [$r1] | 241 | move.d $r0, [$r1] |
@@ -258,6 +244,7 @@ _dram_initialized: | |||
258 | bne 1f | 244 | bne 1f |
259 | nop | 245 | nop |
260 | 246 | ||
247 | ;; Set length and start of cramfs, set romfs_in_flash flag | ||
261 | addoq +4, $r4, $acr | 248 | addoq +4, $r4, $acr |
262 | move.d [$acr], $r0 | 249 | move.d [$acr], $r0 |
263 | move.d romfs_length, $r1 | 250 | move.d romfs_length, $r1 |
@@ -273,35 +260,32 @@ _dram_initialized: | |||
273 | nop | 260 | nop |
274 | 261 | ||
275 | _inram: | 262 | _inram: |
276 | ;; Check if booting from NAND flash (in that case we just remember the offset | 263 | ;; Check if booting from NAND flash; if so, set appropriate flags |
277 | ;; into the flash where cramfs should be). | 264 | ;; and move on. |
278 | move.d REG_ADDR(config, regi_config, r_bootsel), $r0 | 265 | cmp.d NAND_BOOT_MAGIC, $r12 |
279 | move.d [$r0], $r0 | 266 | bne move_cramfs ; not nand, jump |
280 | and.d REG_MASK(config, r_bootsel, boot_mode), $r0 | ||
281 | cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0 | ||
282 | bne move_cramfs | ||
283 | moveq 1,$r0 | ||
284 | move.d crisv32_nand_boot, $r1 | ||
285 | move.d $r0, [$r1] | ||
286 | move.d crisv32_nand_cramfs_offset, $r1 | ||
287 | move.d $r9, [$r1] | ||
288 | moveq 1, $r0 | 267 | moveq 1, $r0 |
289 | move.d romfs_in_flash, $r1 | 268 | move.d nand_boot, $r1 ; tell axisflashmap we're booting from NAND |
269 | move.d $r0, [$r1] | ||
270 | moveq 0, $r0 ; tell axisflashmap romfs is not in | ||
271 | move.d romfs_in_flash, $r1 ; (directly accessed) flash | ||
290 | move.d $r0, [$r1] | 272 | move.d $r0, [$r1] |
291 | jump _start_it | 273 | jump _start_it ; continue with boot |
292 | nop | 274 | nop |
293 | 275 | ||
294 | move_cramfs: | 276 | move_cramfs: |
295 | ;; Move the cramfs after BSS. | 277 | ;; kernel is in DRAM. |
278 | ;; Must figure out if there is a piggybacked rootfs image or not. | ||
279 | ;; Set romfs_length to 0 => no rootfs image available by default. | ||
296 | moveq 0, $r0 | 280 | moveq 0, $r0 |
297 | move.d romfs_length, $r1 | 281 | move.d romfs_length, $r1 |
298 | move.d $r0, [$r1] | 282 | move.d $r0, [$r1] |
299 | 283 | ||
300 | #ifndef CONFIG_ETRAXFS_SIM | 284 | #ifndef CONFIG_ETRAX_VCS_SIM |
301 | ;; The kernel could have been unpacked to DRAM by the loader, but | 285 | ;; The kernel could have been unpacked to DRAM by the loader, but |
302 | ;; the cramfs image could still be inte the flash immediately | 286 | ;; the cramfs image could still be in the flash immediately |
303 | ;; following the compressed kernel image. The loaded passes the address | 287 | ;; following the compressed kernel image. The loader passes the address |
304 | ;; of the bute succeeding the last compressed byte in the flash in | 288 | ;; of the byte succeeding the last compressed byte in the flash in |
305 | ;; register R9 when starting the kernel. | 289 | ;; register R9 when starting the kernel. |
306 | cmp.d 0x0ffffff8, $r9 | 290 | cmp.d 0x0ffffff8, $r9 |
307 | bhs _no_romfs_in_flash ; R9 points outside the flash area. | 291 | bhs _no_romfs_in_flash ; R9 points outside the flash area. |
@@ -310,11 +294,13 @@ move_cramfs: | |||
310 | ba _no_romfs_in_flash | 294 | ba _no_romfs_in_flash |
311 | nop | 295 | nop |
312 | #endif | 296 | #endif |
297 | ;; cramfs rootfs might to be in flash. Check for it. | ||
313 | move.d [$r9], $r0 ; cramfs_super.magic | 298 | move.d [$r9], $r0 ; cramfs_super.magic |
314 | cmp.d CRAMFS_MAGIC, $r0 | 299 | cmp.d CRAMFS_MAGIC, $r0 |
315 | bne _no_romfs_in_flash | 300 | bne _no_romfs_in_flash |
316 | nop | 301 | nop |
317 | 302 | ||
303 | ;; found cramfs in flash. set address and size, and romfs_in_flash flag. | ||
318 | addoq +4, $r9, $acr | 304 | addoq +4, $r9, $acr |
319 | move.d [$acr], $r0 | 305 | move.d [$acr], $r0 |
320 | move.d romfs_length, $r1 | 306 | move.d romfs_length, $r1 |
@@ -330,27 +316,43 @@ move_cramfs: | |||
330 | nop | 316 | nop |
331 | 317 | ||
332 | _no_romfs_in_flash: | 318 | _no_romfs_in_flash: |
333 | ;; Look for cramfs. | 319 | ;; No romfs in flash, so look for cramfs, or jffs2 with jhead, |
320 | ;; after kernel in RAM, as is the case with network->RAM boot. | ||
321 | ;; For cramfs, partition starts with magic and length. | ||
322 | ;; For jffs2, a jhead is prepended which contains with magic and length. | ||
323 | ;; The jhead is not part of the jffs2 partition however. | ||
334 | #ifndef CONFIG_ETRAXFS_SIM | 324 | #ifndef CONFIG_ETRAXFS_SIM |
335 | move.d __vmlinux_end, $r0 | 325 | move.d __vmlinux_end, $r0 |
336 | #else | 326 | #else |
337 | move.d __end, $r0 | 327 | move.d __end, $r0 |
338 | #endif | 328 | #endif |
339 | move.d [$r0], $r1 | 329 | move.d [$r0], $r1 |
340 | cmp.d CRAMFS_MAGIC, $r1 | 330 | cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic? |
341 | bne 2f | 331 | beq 2f ; yes, jump |
332 | nop | ||
333 | cmp.d JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic? | ||
334 | bne 4f ; no, skip copy | ||
342 | nop | 335 | nop |
336 | addq 4, $r0 ; location of jffs2 size | ||
337 | move.d [$r0+], $r2 ; fetch jffs2 size -> r2 | ||
338 | ; r0 now points to start of jffs2 | ||
339 | ba 3f | ||
340 | nop | ||
341 | 2: | ||
342 | addoq +4, $r0, $acr ; location of cramfs size | ||
343 | move.d [$acr], $r2 ; fetch cramfs size -> r2 | ||
344 | ; r0 still points to start of cramfs | ||
345 | 3: | ||
346 | ;; Now, move the root fs to after kernel's BSS | ||
343 | 347 | ||
344 | addoq +4, $r0, $acr | 348 | move.d _end, $r1 ; start of cramfs -> r1 |
345 | move.d [$acr], $r2 | ||
346 | move.d _end, $r1 | ||
347 | move.d romfs_start, $r3 | 349 | move.d romfs_start, $r3 |
348 | move.d $r1, [$r3] | 350 | move.d $r1, [$r3] ; store at romfs_start (for axisflashmap) |
349 | move.d romfs_length, $r3 | 351 | move.d romfs_length, $r3 |
350 | move.d $r2, [$r3] | 352 | move.d $r2, [$r3] ; store size at romfs_length |
351 | 353 | ||
352 | #ifndef CONFIG_ETRAXFS_SIM | 354 | #ifndef CONFIG_ETRAX_VCS_SIM |
353 | add.d $r2, $r0 | 355 | add.d $r2, $r0 ; copy from end and downwards |
354 | add.d $r2, $r1 | 356 | add.d $r2, $r1 |
355 | 357 | ||
356 | lsrq 1, $r2 ; Size is in bytes, we copy words. | 358 | lsrq 1, $r2 ; Size is in bytes, we copy words. |
@@ -365,10 +367,17 @@ _no_romfs_in_flash: | |||
365 | nop | 367 | nop |
366 | #endif | 368 | #endif |
367 | 369 | ||
368 | 2: | 370 | 4: |
371 | ;; BSS move done. | ||
372 | ;; Clear romfs_in_flash flag, as we now know romfs is in DRAM | ||
373 | ;; Also clear nand_boot flag; if we got here, we know we've not | ||
374 | ;; booted from NAND flash. | ||
369 | moveq 0, $r0 | 375 | moveq 0, $r0 |
370 | move.d romfs_in_flash, $r1 | 376 | move.d romfs_in_flash, $r1 |
371 | move.d $r0, [$r1] | 377 | move.d $r0, [$r1] |
378 | moveq 0, $r0 | ||
379 | move.d nand_boot, $r1 | ||
380 | move.d $r0, [$r1] | ||
372 | 381 | ||
373 | jump _start_it ; Jump to cached code. | 382 | jump _start_it ; Jump to cached code. |
374 | nop | 383 | nop |
@@ -384,8 +393,8 @@ _start_it: | |||
384 | move.d cris_command_line, $r10 | 393 | move.d cris_command_line, $r10 |
385 | or.d 0x80000000, $r11 ; Make it virtual | 394 | or.d 0x80000000, $r11 ; Make it virtual |
386 | 1: | 395 | 1: |
387 | move.b [$r11+], $r12 | 396 | move.b [$r11+], $r1 |
388 | move.b $r12, [$r10+] | 397 | move.b $r1, [$r10+] |
389 | subq 1, $r13 | 398 | subq 1, $r13 |
390 | bne 1b | 399 | bne 1b |
391 | nop | 400 | nop |
@@ -401,7 +410,7 @@ no_command_line: | |||
401 | move.d etrax_irv, $r1 ; Set the exception base register and pointer. | 410 | move.d etrax_irv, $r1 ; Set the exception base register and pointer. |
402 | move.d $r0, [$r1] | 411 | move.d $r0, [$r1] |
403 | 412 | ||
404 | #ifndef CONFIG_ETRAXFS_SIM | 413 | #ifndef CONFIG_ETRAX_VCS_SIM |
405 | ;; Clear the BSS region from _bss_start to _end. | 414 | ;; Clear the BSS region from _bss_start to _end. |
406 | move.d __bss_start, $r0 | 415 | move.d __bss_start, $r0 |
407 | move.d _end, $r1 | 416 | move.d _end, $r1 |
@@ -411,7 +420,7 @@ no_command_line: | |||
411 | nop | 420 | nop |
412 | #endif | 421 | #endif |
413 | 422 | ||
414 | #ifdef CONFIG_ETRAXFS_SIM | 423 | #ifdef CONFIG_ETRAX_VCS_SIM |
415 | /* Set the watchdog timeout to something big. Will be removed when */ | 424 | /* Set the watchdog timeout to something big. Will be removed when */ |
416 | /* watchdog can be disabled with command line option */ | 425 | /* watchdog can be disabled with command line option */ |
417 | move.d 0x7fffffff, $r10 | 426 | move.d 0x7fffffff, $r10 |
@@ -423,25 +432,44 @@ no_command_line: | |||
423 | move.d __bss_start, $r0 | 432 | move.d __bss_start, $r0 |
424 | movem [$r0], $r13 | 433 | movem [$r0], $r13 |
425 | 434 | ||
435 | #ifdef CONFIG_ETRAX_L2CACHE | ||
436 | jsr l2cache_init | ||
437 | nop | ||
438 | #endif | ||
439 | |||
426 | jump start_kernel ; Jump to start_kernel() in init/main.c. | 440 | jump start_kernel ; Jump to start_kernel() in init/main.c. |
427 | nop | 441 | nop |
428 | 442 | ||
429 | .data | 443 | .data |
430 | etrax_irv: | 444 | etrax_irv: |
431 | .dword 0 | 445 | .dword 0 |
446 | |||
447 | ; Variables for communication with the Axis flash map driver (axisflashmap), | ||
448 | ; and for setting up memory in arch/cris/kernel/setup.c . | ||
449 | |||
450 | ; romfs_start is set to the start of the root file system, if it exists | ||
451 | ; in directly accessible memory (i.e. NOR Flash when booting from Flash, | ||
452 | ; or RAM when booting directly from a network-downloaded RAM image) | ||
432 | romfs_start: | 453 | romfs_start: |
433 | .dword 0 | 454 | .dword 0 |
455 | |||
456 | ; romfs_length is set to the size of the root file system image, if it exists | ||
457 | ; in directly accessible memory (see romfs_start). Otherwise it is set to 0. | ||
434 | romfs_length: | 458 | romfs_length: |
435 | .dword 0 | 459 | .dword 0 |
460 | |||
461 | ; romfs_in_flash is set to 1 if the root file system resides in directly | ||
462 | ; accessible flash memory (i.e. NOR flash). It is set to 0 for RAM boot | ||
463 | ; or NAND flash boot. | ||
436 | romfs_in_flash: | 464 | romfs_in_flash: |
437 | .dword 0 | 465 | .dword 0 |
438 | crisv32_nand_boot: | 466 | |
439 | .dword 0 | 467 | ; nand_boot is set to 1 when the kernel has been booted from NAND flash |
440 | crisv32_nand_cramfs_offset: | 468 | nand_boot: |
441 | .dword 0 | 469 | .dword 0 |
442 | 470 | ||
443 | swapper_pg_dir = 0xc0002000 | 471 | swapper_pg_dir = 0xc0002000 |
444 | 472 | ||
445 | .section ".init.data", "aw" | 473 | .section ".init.data", "aw" |
446 | 474 | ||
447 | #include "../lib/hw_settings.S" | 475 | #include "../mach/hw_settings.S" |
diff --git a/arch/cris/arch-v32/kernel/io.c b/arch/cris/arch-v32/kernel/io.c deleted file mode 100644 index a22a9e02e093..000000000000 --- a/arch/cris/arch-v32/kernel/io.c +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | /* | ||
2 | * Helper functions for I/O pins. | ||
3 | * | ||
4 | * Copyright (c) 2004 Axis Communications AB. | ||
5 | */ | ||
6 | |||
7 | #include <linux/types.h> | ||
8 | #include <linux/errno.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/ctype.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/arch/pinmux.h> | ||
16 | #include <asm/arch/hwregs/gio_defs.h> | ||
17 | |||
18 | struct crisv32_ioport crisv32_ioports[] = | ||
19 | { | ||
20 | { | ||
21 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_oe), | ||
22 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_dout), | ||
23 | (unsigned long*)REG_ADDR(gio, regi_gio, r_pa_din), | ||
24 | 8 | ||
25 | }, | ||
26 | { | ||
27 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_oe), | ||
28 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_dout), | ||
29 | (unsigned long*)REG_ADDR(gio, regi_gio, r_pb_din), | ||
30 | 18 | ||
31 | }, | ||
32 | { | ||
33 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_oe), | ||
34 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_dout), | ||
35 | (unsigned long*)REG_ADDR(gio, regi_gio, r_pc_din), | ||
36 | 18 | ||
37 | }, | ||
38 | { | ||
39 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_oe), | ||
40 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_dout), | ||
41 | (unsigned long*)REG_ADDR(gio, regi_gio, r_pd_din), | ||
42 | 18 | ||
43 | }, | ||
44 | { | ||
45 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_oe), | ||
46 | (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout), | ||
47 | (unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din), | ||
48 | 18 | ||
49 | } | ||
50 | }; | ||
51 | |||
52 | #define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports) | ||
53 | |||
54 | struct crisv32_iopin crisv32_led1_green; | ||
55 | struct crisv32_iopin crisv32_led1_red; | ||
56 | struct crisv32_iopin crisv32_led2_green; | ||
57 | struct crisv32_iopin crisv32_led2_red; | ||
58 | struct crisv32_iopin crisv32_led3_green; | ||
59 | struct crisv32_iopin crisv32_led3_red; | ||
60 | |||
61 | /* Dummy port used when green LED and red LED is on the same bit */ | ||
62 | static unsigned long io_dummy; | ||
63 | static struct crisv32_ioport dummy_port = | ||
64 | { | ||
65 | &io_dummy, | ||
66 | &io_dummy, | ||
67 | &io_dummy, | ||
68 | 18 | ||
69 | }; | ||
70 | static struct crisv32_iopin dummy_led = | ||
71 | { | ||
72 | &dummy_port, | ||
73 | 0 | ||
74 | }; | ||
75 | |||
76 | static int __init crisv32_io_init(void) | ||
77 | { | ||
78 | int ret = 0; | ||
79 | /* Initialize LEDs */ | ||
80 | ret += crisv32_io_get_name(&crisv32_led1_green, CONFIG_ETRAX_LED1G); | ||
81 | ret += crisv32_io_get_name(&crisv32_led1_red, CONFIG_ETRAX_LED1R); | ||
82 | ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_LED2G); | ||
83 | ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_LED2R); | ||
84 | ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_LED3G); | ||
85 | ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_LED3R); | ||
86 | crisv32_io_set_dir(&crisv32_led1_green, crisv32_io_dir_out); | ||
87 | crisv32_io_set_dir(&crisv32_led1_red, crisv32_io_dir_out); | ||
88 | crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out); | ||
89 | crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out); | ||
90 | crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out); | ||
91 | crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out); | ||
92 | |||
93 | if (!strcmp(CONFIG_ETRAX_LED1G, CONFIG_ETRAX_LED1R)) | ||
94 | crisv32_led1_red = dummy_led; | ||
95 | if (!strcmp(CONFIG_ETRAX_LED2G, CONFIG_ETRAX_LED2R)) | ||
96 | crisv32_led2_red = dummy_led; | ||
97 | |||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | __initcall(crisv32_io_init); | ||
102 | |||
103 | int crisv32_io_get(struct crisv32_iopin* iopin, | ||
104 | unsigned int port, unsigned int pin) | ||
105 | { | ||
106 | if (port > NBR_OF_PORTS) | ||
107 | return -EINVAL; | ||
108 | if (port > crisv32_ioports[port].pin_count) | ||
109 | return -EINVAL; | ||
110 | |||
111 | iopin->bit = 1 << pin; | ||
112 | iopin->port = &crisv32_ioports[port]; | ||
113 | |||
114 | if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) | ||
115 | return -EIO; | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | int crisv32_io_get_name(struct crisv32_iopin* iopin, | ||
121 | char* name) | ||
122 | { | ||
123 | int port; | ||
124 | int pin; | ||
125 | |||
126 | if (toupper(*name) == 'P') | ||
127 | name++; | ||
128 | |||
129 | if (toupper(*name) < 'A' || toupper(*name) > 'E') | ||
130 | return -EINVAL; | ||
131 | |||
132 | port = toupper(*name) - 'A'; | ||
133 | name++; | ||
134 | pin = simple_strtoul(name, NULL, 10); | ||
135 | |||
136 | if (pin < 0 || pin > crisv32_ioports[port].pin_count) | ||
137 | return -EINVAL; | ||
138 | |||
139 | iopin->bit = 1 << pin; | ||
140 | iopin->port = &crisv32_ioports[port]; | ||
141 | |||
142 | if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) | ||
143 | return -EIO; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #ifdef CONFIG_PCI | ||
149 | /* PCI I/O access stuff */ | ||
150 | struct cris_io_operations* cris_iops = NULL; | ||
151 | EXPORT_SYMBOL(cris_iops); | ||
152 | #endif | ||
153 | |||
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index a9acaa270243..173c141ac9ba 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c | |||
@@ -15,15 +15,21 @@ | |||
15 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/kernel_stat.h> | 17 | #include <linux/kernel_stat.h> |
18 | #include <asm/arch/hwregs/reg_map.h> | 18 | #include <hwregs/reg_map.h> |
19 | #include <asm/arch/hwregs/reg_rdwr.h> | 19 | #include <hwregs/reg_rdwr.h> |
20 | #include <asm/arch/hwregs/intr_vect.h> | 20 | #include <hwregs/intr_vect.h> |
21 | #include <asm/arch/hwregs/intr_vect_defs.h> | 21 | #include <hwregs/intr_vect_defs.h> |
22 | 22 | ||
23 | #define CPU_FIXED -1 | 23 | #define CPU_FIXED -1 |
24 | 24 | ||
25 | /* IRQ masks (refer to comment for crisv32_do_multiple) */ | 25 | /* IRQ masks (refer to comment for crisv32_do_multiple) */ |
26 | #define TIMER_MASK (1 << (TIMER_INTR_VECT - FIRST_IRQ)) | 26 | #if TIMER0_INTR_VECT - FIRST_IRQ < 32 |
27 | #define TIMER_MASK (1 << (TIMER0_INTR_VECT - FIRST_IRQ)) | ||
28 | #undef TIMER_VECT1 | ||
29 | #else | ||
30 | #define TIMER_MASK (1 << (TIMER0_INTR_VECT - FIRST_IRQ - 32)) | ||
31 | #define TIMER_VECT1 | ||
32 | #endif | ||
27 | #ifdef CONFIG_ETRAX_KGDB | 33 | #ifdef CONFIG_ETRAX_KGDB |
28 | #if defined(CONFIG_ETRAX_KGDB_PORT0) | 34 | #if defined(CONFIG_ETRAX_KGDB_PORT0) |
29 | #define IGNOREMASK (1 << (SER0_INTR_VECT - FIRST_IRQ)) | 35 | #define IGNOREMASK (1 << (SER0_INTR_VECT - FIRST_IRQ)) |
@@ -44,8 +50,8 @@ struct cris_irq_allocation | |||
44 | cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */ | 50 | cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */ |
45 | }; | 51 | }; |
46 | 52 | ||
47 | struct cris_irq_allocation irq_allocations[NR_IRQS] = | 53 | struct cris_irq_allocation irq_allocations[NR_REAL_IRQS] = |
48 | {[0 ... NR_IRQS - 1] = {0, CPU_MASK_ALL}}; | 54 | { [0 ... NR_REAL_IRQS - 1] = {0, CPU_MASK_ALL} }; |
49 | 55 | ||
50 | static unsigned long irq_regs[NR_CPUS] = | 56 | static unsigned long irq_regs[NR_CPUS] = |
51 | { | 57 | { |
@@ -55,6 +61,12 @@ static unsigned long irq_regs[NR_CPUS] = | |||
55 | #endif | 61 | #endif |
56 | }; | 62 | }; |
57 | 63 | ||
64 | #if NR_REAL_IRQS > 32 | ||
65 | #define NBR_REGS 2 | ||
66 | #else | ||
67 | #define NBR_REGS 1 | ||
68 | #endif | ||
69 | |||
58 | unsigned long cpu_irq_counters[NR_CPUS]; | 70 | unsigned long cpu_irq_counters[NR_CPUS]; |
59 | unsigned long irq_counters[NR_REAL_IRQS]; | 71 | unsigned long irq_counters[NR_REAL_IRQS]; |
60 | 72 | ||
@@ -79,45 +91,81 @@ extern void d_mmu_write(void); | |||
79 | extern void kgdb_init(void); | 91 | extern void kgdb_init(void); |
80 | extern void breakpoint(void); | 92 | extern void breakpoint(void); |
81 | 93 | ||
94 | /* From traps.c. */ | ||
95 | extern void breakh_BUG(void); | ||
96 | |||
82 | /* | 97 | /* |
83 | * Build the IRQ handler stubs using macros from irq.h. First argument is the | 98 | * Build the IRQ handler stubs using macros from irq.h. |
84 | * IRQ number, the second argument is the corresponding bit in | ||
85 | * intr_rw_vect_mask found in asm/arch/hwregs/intr_vect_defs.h. | ||
86 | */ | 99 | */ |
87 | BUILD_IRQ(0x31, (1 << 0)) /* memarb */ | 100 | BUILD_IRQ(0x31) |
88 | BUILD_IRQ(0x32, (1 << 1)) /* gen_io */ | 101 | BUILD_IRQ(0x32) |
89 | BUILD_IRQ(0x33, (1 << 2)) /* iop0 */ | 102 | BUILD_IRQ(0x33) |
90 | BUILD_IRQ(0x34, (1 << 3)) /* iop1 */ | 103 | BUILD_IRQ(0x34) |
91 | BUILD_IRQ(0x35, (1 << 4)) /* iop2 */ | 104 | BUILD_IRQ(0x35) |
92 | BUILD_IRQ(0x36, (1 << 5)) /* iop3 */ | 105 | BUILD_IRQ(0x36) |
93 | BUILD_IRQ(0x37, (1 << 6)) /* dma0 */ | 106 | BUILD_IRQ(0x37) |
94 | BUILD_IRQ(0x38, (1 << 7)) /* dma1 */ | 107 | BUILD_IRQ(0x38) |
95 | BUILD_IRQ(0x39, (1 << 8)) /* dma2 */ | 108 | BUILD_IRQ(0x39) |
96 | BUILD_IRQ(0x3a, (1 << 9)) /* dma3 */ | 109 | BUILD_IRQ(0x3a) |
97 | BUILD_IRQ(0x3b, (1 << 10)) /* dma4 */ | 110 | BUILD_IRQ(0x3b) |
98 | BUILD_IRQ(0x3c, (1 << 11)) /* dma5 */ | 111 | BUILD_IRQ(0x3c) |
99 | BUILD_IRQ(0x3d, (1 << 12)) /* dma6 */ | 112 | BUILD_IRQ(0x3d) |
100 | BUILD_IRQ(0x3e, (1 << 13)) /* dma7 */ | 113 | BUILD_IRQ(0x3e) |
101 | BUILD_IRQ(0x3f, (1 << 14)) /* dma8 */ | 114 | BUILD_IRQ(0x3f) |
102 | BUILD_IRQ(0x40, (1 << 15)) /* dma9 */ | 115 | BUILD_IRQ(0x40) |
103 | BUILD_IRQ(0x41, (1 << 16)) /* ata */ | 116 | BUILD_IRQ(0x41) |
104 | BUILD_IRQ(0x42, (1 << 17)) /* sser0 */ | 117 | BUILD_IRQ(0x42) |
105 | BUILD_IRQ(0x43, (1 << 18)) /* sser1 */ | 118 | BUILD_IRQ(0x43) |
106 | BUILD_IRQ(0x44, (1 << 19)) /* ser0 */ | 119 | BUILD_IRQ(0x44) |
107 | BUILD_IRQ(0x45, (1 << 20)) /* ser1 */ | 120 | BUILD_IRQ(0x45) |
108 | BUILD_IRQ(0x46, (1 << 21)) /* ser2 */ | 121 | BUILD_IRQ(0x46) |
109 | BUILD_IRQ(0x47, (1 << 22)) /* ser3 */ | 122 | BUILD_IRQ(0x47) |
110 | BUILD_IRQ(0x48, (1 << 23)) | 123 | BUILD_IRQ(0x48) |
111 | BUILD_IRQ(0x49, (1 << 24)) /* eth0 */ | 124 | BUILD_IRQ(0x49) |
112 | BUILD_IRQ(0x4a, (1 << 25)) /* eth1 */ | 125 | BUILD_IRQ(0x4a) |
113 | BUILD_TIMER_IRQ(0x4b, (1 << 26))/* timer */ | 126 | BUILD_IRQ(0x4b) |
114 | BUILD_IRQ(0x4c, (1 << 27)) /* bif_arb */ | 127 | BUILD_IRQ(0x4c) |
115 | BUILD_IRQ(0x4d, (1 << 28)) /* bif_dma */ | 128 | BUILD_IRQ(0x4d) |
116 | BUILD_IRQ(0x4e, (1 << 29)) /* ext */ | 129 | BUILD_IRQ(0x4e) |
117 | BUILD_IRQ(0x4f, (1 << 29)) /* ipi */ | 130 | BUILD_IRQ(0x4f) |
131 | BUILD_IRQ(0x50) | ||
132 | #if MACH_IRQS > 32 | ||
133 | BUILD_IRQ(0x51) | ||
134 | BUILD_IRQ(0x52) | ||
135 | BUILD_IRQ(0x53) | ||
136 | BUILD_IRQ(0x54) | ||
137 | BUILD_IRQ(0x55) | ||
138 | BUILD_IRQ(0x56) | ||
139 | BUILD_IRQ(0x57) | ||
140 | BUILD_IRQ(0x58) | ||
141 | BUILD_IRQ(0x59) | ||
142 | BUILD_IRQ(0x5a) | ||
143 | BUILD_IRQ(0x5b) | ||
144 | BUILD_IRQ(0x5c) | ||
145 | BUILD_IRQ(0x5d) | ||
146 | BUILD_IRQ(0x5e) | ||
147 | BUILD_IRQ(0x5f) | ||
148 | BUILD_IRQ(0x60) | ||
149 | BUILD_IRQ(0x61) | ||
150 | BUILD_IRQ(0x62) | ||
151 | BUILD_IRQ(0x63) | ||
152 | BUILD_IRQ(0x64) | ||
153 | BUILD_IRQ(0x65) | ||
154 | BUILD_IRQ(0x66) | ||
155 | BUILD_IRQ(0x67) | ||
156 | BUILD_IRQ(0x68) | ||
157 | BUILD_IRQ(0x69) | ||
158 | BUILD_IRQ(0x6a) | ||
159 | BUILD_IRQ(0x6b) | ||
160 | BUILD_IRQ(0x6c) | ||
161 | BUILD_IRQ(0x6d) | ||
162 | BUILD_IRQ(0x6e) | ||
163 | BUILD_IRQ(0x6f) | ||
164 | BUILD_IRQ(0x70) | ||
165 | #endif | ||
118 | 166 | ||
119 | /* Pointers to the low-level handlers. */ | 167 | /* Pointers to the low-level handlers. */ |
120 | static void (*interrupt[NR_IRQS])(void) = { | 168 | static void (*interrupt[MACH_IRQS])(void) = { |
121 | IRQ0x31_interrupt, IRQ0x32_interrupt, IRQ0x33_interrupt, | 169 | IRQ0x31_interrupt, IRQ0x32_interrupt, IRQ0x33_interrupt, |
122 | IRQ0x34_interrupt, IRQ0x35_interrupt, IRQ0x36_interrupt, | 170 | IRQ0x34_interrupt, IRQ0x35_interrupt, IRQ0x36_interrupt, |
123 | IRQ0x37_interrupt, IRQ0x38_interrupt, IRQ0x39_interrupt, | 171 | IRQ0x37_interrupt, IRQ0x38_interrupt, IRQ0x39_interrupt, |
@@ -128,7 +176,20 @@ static void (*interrupt[NR_IRQS])(void) = { | |||
128 | IRQ0x46_interrupt, IRQ0x47_interrupt, IRQ0x48_interrupt, | 176 | IRQ0x46_interrupt, IRQ0x47_interrupt, IRQ0x48_interrupt, |
129 | IRQ0x49_interrupt, IRQ0x4a_interrupt, IRQ0x4b_interrupt, | 177 | IRQ0x49_interrupt, IRQ0x4a_interrupt, IRQ0x4b_interrupt, |
130 | IRQ0x4c_interrupt, IRQ0x4d_interrupt, IRQ0x4e_interrupt, | 178 | IRQ0x4c_interrupt, IRQ0x4d_interrupt, IRQ0x4e_interrupt, |
131 | IRQ0x4f_interrupt | 179 | IRQ0x4f_interrupt, IRQ0x50_interrupt, |
180 | #if MACH_IRQS > 32 | ||
181 | IRQ0x51_interrupt, IRQ0x52_interrupt, IRQ0x53_interrupt, | ||
182 | IRQ0x54_interrupt, IRQ0x55_interrupt, IRQ0x56_interrupt, | ||
183 | IRQ0x57_interrupt, IRQ0x58_interrupt, IRQ0x59_interrupt, | ||
184 | IRQ0x5a_interrupt, IRQ0x5b_interrupt, IRQ0x5c_interrupt, | ||
185 | IRQ0x5d_interrupt, IRQ0x5e_interrupt, IRQ0x5f_interrupt, | ||
186 | IRQ0x60_interrupt, IRQ0x61_interrupt, IRQ0x62_interrupt, | ||
187 | IRQ0x63_interrupt, IRQ0x64_interrupt, IRQ0x65_interrupt, | ||
188 | IRQ0x66_interrupt, IRQ0x67_interrupt, IRQ0x68_interrupt, | ||
189 | IRQ0x69_interrupt, IRQ0x6a_interrupt, IRQ0x6b_interrupt, | ||
190 | IRQ0x6c_interrupt, IRQ0x6d_interrupt, IRQ0x6e_interrupt, | ||
191 | IRQ0x6f_interrupt, IRQ0x70_interrupt, | ||
192 | #endif | ||
132 | }; | 193 | }; |
133 | 194 | ||
134 | void | 195 | void |
@@ -137,13 +198,26 @@ block_irq(int irq, int cpu) | |||
137 | int intr_mask; | 198 | int intr_mask; |
138 | unsigned long flags; | 199 | unsigned long flags; |
139 | 200 | ||
140 | spin_lock_irqsave(&irq_lock, flags); | 201 | spin_lock_irqsave(&irq_lock, flags); |
141 | intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); | 202 | if (irq - FIRST_IRQ < 32) |
142 | 203 | intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], | |
143 | /* Remember; 1 let through, 0 block. */ | 204 | rw_mask, 0); |
144 | intr_mask &= ~(1 << (irq - FIRST_IRQ)); | 205 | else |
145 | 206 | intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], | |
146 | REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask); | 207 | rw_mask, 1); |
208 | |||
209 | /* Remember; 1 let thru, 0 block. */ | ||
210 | if (irq - FIRST_IRQ < 32) | ||
211 | intr_mask &= ~(1 << (irq - FIRST_IRQ)); | ||
212 | else | ||
213 | intr_mask &= ~(1 << (irq - FIRST_IRQ - 32)); | ||
214 | |||
215 | if (irq - FIRST_IRQ < 32) | ||
216 | REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, | ||
217 | 0, intr_mask); | ||
218 | else | ||
219 | REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, | ||
220 | 1, intr_mask); | ||
147 | spin_unlock_irqrestore(&irq_lock, flags); | 221 | spin_unlock_irqrestore(&irq_lock, flags); |
148 | } | 222 | } |
149 | 223 | ||
@@ -154,12 +228,26 @@ unblock_irq(int irq, int cpu) | |||
154 | unsigned long flags; | 228 | unsigned long flags; |
155 | 229 | ||
156 | spin_lock_irqsave(&irq_lock, flags); | 230 | spin_lock_irqsave(&irq_lock, flags); |
157 | intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); | 231 | if (irq - FIRST_IRQ < 32) |
158 | 232 | intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], | |
159 | /* Remember; 1 let through, 0 block. */ | 233 | rw_mask, 0); |
160 | intr_mask |= (1 << (irq - FIRST_IRQ)); | 234 | else |
235 | intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], | ||
236 | rw_mask, 1); | ||
237 | |||
238 | /* Remember; 1 let thru, 0 block. */ | ||
239 | if (irq - FIRST_IRQ < 32) | ||
240 | intr_mask |= (1 << (irq - FIRST_IRQ)); | ||
241 | else | ||
242 | intr_mask |= (1 << (irq - FIRST_IRQ - 32)); | ||
243 | |||
244 | if (irq - FIRST_IRQ < 32) | ||
245 | REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, | ||
246 | 0, intr_mask); | ||
247 | else | ||
248 | REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, | ||
249 | 1, intr_mask); | ||
161 | 250 | ||
162 | REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask); | ||
163 | spin_unlock_irqrestore(&irq_lock, flags); | 251 | spin_unlock_irqrestore(&irq_lock, flags); |
164 | } | 252 | } |
165 | 253 | ||
@@ -298,8 +386,9 @@ crisv32_do_multiple(struct pt_regs* regs) | |||
298 | { | 386 | { |
299 | int cpu; | 387 | int cpu; |
300 | int mask; | 388 | int mask; |
301 | int masked; | 389 | int masked[NBR_REGS]; |
302 | int bit; | 390 | int bit; |
391 | int i; | ||
303 | 392 | ||
304 | cpu = smp_processor_id(); | 393 | cpu = smp_processor_id(); |
305 | 394 | ||
@@ -308,42 +397,59 @@ crisv32_do_multiple(struct pt_regs* regs) | |||
308 | */ | 397 | */ |
309 | irq_enter(); | 398 | irq_enter(); |
310 | 399 | ||
311 | /* Get which IRQs that happened. */ | 400 | for (i = 0; i < NBR_REGS; i++) { |
312 | masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect); | 401 | /* Get which IRQs that happend. */ |
402 | masked[i] = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], | ||
403 | r_masked_vect, i); | ||
313 | 404 | ||
314 | /* Calculate new IRQ mask with these IRQs disabled. */ | 405 | /* Calculate new IRQ mask with these IRQs disabled. */ |
315 | mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); | 406 | mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i); |
316 | mask &= ~masked; | 407 | mask &= ~masked[i]; |
317 | 408 | ||
318 | /* Timer IRQ is never masked */ | 409 | /* Timer IRQ is never masked */ |
319 | if (masked & TIMER_MASK) | 410 | #ifdef TIMER_VECT1 |
320 | mask |= TIMER_MASK; | 411 | if ((i == 1) && (masked[0] & TIMER_MASK)) |
321 | 412 | mask |= TIMER_MASK; | |
322 | /* Block all the IRQs */ | 413 | #else |
323 | REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask); | 414 | if ((i == 0) && (masked[0] & TIMER_MASK)) |
415 | mask |= TIMER_MASK; | ||
416 | #endif | ||
417 | /* Block all the IRQs */ | ||
418 | REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i, mask); | ||
324 | 419 | ||
325 | /* Check for timer IRQ and handle it special. */ | 420 | /* Check for timer IRQ and handle it special. */ |
326 | if (masked & TIMER_MASK) { | 421 | #ifdef TIMER_VECT1 |
327 | masked &= ~TIMER_MASK; | 422 | if ((i == 1) && (masked[i] & TIMER_MASK)) { |
328 | do_IRQ(TIMER_INTR_VECT, regs); | 423 | masked[i] &= ~TIMER_MASK; |
424 | do_IRQ(TIMER0_INTR_VECT, regs); | ||
425 | } | ||
426 | #else | ||
427 | if ((i == 0) && (masked[i] & TIMER_MASK)) { | ||
428 | masked[i] &= ~TIMER_MASK; | ||
429 | do_IRQ(TIMER0_INTR_VECT, regs); | ||
430 | } | ||
329 | } | 431 | } |
432 | #endif | ||
330 | 433 | ||
331 | #ifdef IGNORE_MASK | 434 | #ifdef IGNORE_MASK |
332 | /* Remove IRQs that can't be handled as multiple. */ | 435 | /* Remove IRQs that can't be handled as multiple. */ |
333 | masked &= ~IGNORE_MASK; | 436 | masked[0] &= ~IGNORE_MASK; |
334 | #endif | 437 | #endif |
335 | 438 | ||
336 | /* Handle the rest of the IRQs. */ | 439 | /* Handle the rest of the IRQs. */ |
337 | for (bit = 0; bit < 32; bit++) | 440 | for (i = 0; i < NBR_REGS; i++) { |
338 | { | 441 | for (bit = 0; bit < 32; bit++) { |
339 | if (masked & (1 << bit)) | 442 | if (masked[i] & (1 << bit)) |
340 | do_IRQ(bit + FIRST_IRQ, regs); | 443 | do_IRQ(bit + FIRST_IRQ + i*32, regs); |
444 | } | ||
341 | } | 445 | } |
342 | 446 | ||
343 | /* Unblock all the IRQs. */ | 447 | /* Unblock all the IRQs. */ |
344 | mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask); | 448 | for (i = 0; i < NBR_REGS; i++) { |
345 | mask |= masked; | 449 | mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i); |
346 | REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask); | 450 | mask |= masked[i]; |
451 | REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, i, mask); | ||
452 | } | ||
347 | 453 | ||
348 | /* This irq_exit() will trigger the soft IRQs. */ | 454 | /* This irq_exit() will trigger the soft IRQs. */ |
349 | irq_exit(); | 455 | irq_exit(); |
@@ -361,20 +467,21 @@ init_IRQ(void) | |||
361 | reg_intr_vect_rw_mask vect_mask = {0}; | 467 | reg_intr_vect_rw_mask vect_mask = {0}; |
362 | 468 | ||
363 | /* Clear all interrupts masks. */ | 469 | /* Clear all interrupts masks. */ |
364 | REG_WR(intr_vect, regi_irq, rw_mask, vect_mask); | 470 | for (i = 0; i < NBR_REGS; i++) |
471 | REG_WR_VECT(intr_vect, regi_irq, rw_mask, i, vect_mask); | ||
365 | 472 | ||
366 | for (i = 0; i < 256; i++) | 473 | for (i = 0; i < 256; i++) |
367 | etrax_irv->v[i] = weird_irq; | 474 | etrax_irv->v[i] = weird_irq; |
368 | 475 | ||
369 | /* Point all IRQs to bad handlers. */ | 476 | /* Point all IRQ's to bad handlers. */ |
370 | for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { | 477 | for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { |
371 | irq_desc[j].chip = &crisv32_irq_type; | 478 | irq_desc[j].chip = &crisv32_irq_type; |
372 | set_exception_vector(i, interrupt[j]); | 479 | set_exception_vector(i, interrupt[j]); |
373 | } | 480 | } |
374 | 481 | ||
375 | /* Mark Timer and IPI IRQs as CPU local */ | 482 | /* Mark Timer and IPI IRQs as CPU local */ |
376 | irq_allocations[TIMER_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; | 483 | irq_allocations[TIMER0_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; |
377 | irq_desc[TIMER_INTR_VECT].status |= IRQ_PER_CPU; | 484 | irq_desc[TIMER0_INTR_VECT].status |= IRQ_PER_CPU; |
378 | irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; | 485 | irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; |
379 | irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU; | 486 | irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU; |
380 | 487 | ||
@@ -391,6 +498,11 @@ init_IRQ(void) | |||
391 | set_exception_vector(0x0a, d_mmu_access); | 498 | set_exception_vector(0x0a, d_mmu_access); |
392 | set_exception_vector(0x0b, d_mmu_write); | 499 | set_exception_vector(0x0b, d_mmu_write); |
393 | 500 | ||
501 | #ifdef CONFIG_BUG | ||
502 | /* Break 14 handler, used to implement cheap BUG(). */ | ||
503 | set_exception_vector(0x1e, breakh_BUG); | ||
504 | #endif | ||
505 | |||
394 | /* The system-call trap is reached by "break 13". */ | 506 | /* The system-call trap is reached by "break 13". */ |
395 | set_exception_vector(0x1d, system_call); | 507 | set_exception_vector(0x1d, system_call); |
396 | 508 | ||
diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c index 480e56348be2..4e2e2e271efb 100644 --- a/arch/cris/arch-v32/kernel/kgdb.c +++ b/arch/cris/arch-v32/kernel/kgdb.c | |||
@@ -381,7 +381,7 @@ static int read_register(char regno, unsigned int *valptr); | |||
381 | /* Serial port, reads one character. ETRAX 100 specific. from debugport.c */ | 381 | /* Serial port, reads one character. ETRAX 100 specific. from debugport.c */ |
382 | int getDebugChar(void); | 382 | int getDebugChar(void); |
383 | 383 | ||
384 | #ifdef CONFIG_ETRAXFS_SIM | 384 | #ifdef CONFIG_ETRAX_VCS_SIM |
385 | int getDebugChar(void) | 385 | int getDebugChar(void) |
386 | { | 386 | { |
387 | return socketread(); | 387 | return socketread(); |
@@ -391,7 +391,7 @@ int getDebugChar(void) | |||
391 | /* Serial port, writes one character. ETRAX 100 specific. from debugport.c */ | 391 | /* Serial port, writes one character. ETRAX 100 specific. from debugport.c */ |
392 | void putDebugChar(int val); | 392 | void putDebugChar(int val); |
393 | 393 | ||
394 | #ifdef CONFIG_ETRAXFS_SIM | 394 | #ifdef CONFIG_ETRAX_VCS_SIM |
395 | void putDebugChar(int val) | 395 | void putDebugChar(int val) |
396 | { | 396 | { |
397 | socketwrite((char *)&val, 1); | 397 | socketwrite((char *)&val, 1); |
@@ -1599,7 +1599,7 @@ kgdb_init(void) | |||
1599 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | 1599 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); |
1600 | 1600 | ||
1601 | ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask); | 1601 | ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask); |
1602 | ser_intr_mask.data_avail = regk_ser_yes; | 1602 | ser_intr_mask.dav = regk_ser_yes; |
1603 | REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask); | 1603 | REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask); |
1604 | #elif defined(CONFIG_ETRAX_KGDB_PORT1) | 1604 | #elif defined(CONFIG_ETRAX_KGDB_PORT1) |
1605 | /* Note: no shortcut registered (not handled by multiple_interrupt). | 1605 | /* Note: no shortcut registered (not handled by multiple_interrupt). |
@@ -1611,7 +1611,7 @@ kgdb_init(void) | |||
1611 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | 1611 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); |
1612 | 1612 | ||
1613 | ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask); | 1613 | ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask); |
1614 | ser_intr_mask.data_avail = regk_ser_yes; | 1614 | ser_intr_mask.dav = regk_ser_yes; |
1615 | REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask); | 1615 | REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask); |
1616 | #elif defined(CONFIG_ETRAX_KGDB_PORT2) | 1616 | #elif defined(CONFIG_ETRAX_KGDB_PORT2) |
1617 | /* Note: no shortcut registered (not handled by multiple_interrupt). | 1617 | /* Note: no shortcut registered (not handled by multiple_interrupt). |
@@ -1623,7 +1623,7 @@ kgdb_init(void) | |||
1623 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | 1623 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); |
1624 | 1624 | ||
1625 | ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask); | 1625 | ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask); |
1626 | ser_intr_mask.data_avail = regk_ser_yes; | 1626 | ser_intr_mask.dav = regk_ser_yes; |
1627 | REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask); | 1627 | REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask); |
1628 | #elif defined(CONFIG_ETRAX_KGDB_PORT3) | 1628 | #elif defined(CONFIG_ETRAX_KGDB_PORT3) |
1629 | /* Note: no shortcut registered (not handled by multiple_interrupt). | 1629 | /* Note: no shortcut registered (not handled by multiple_interrupt). |
@@ -1635,7 +1635,7 @@ kgdb_init(void) | |||
1635 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | 1635 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); |
1636 | 1636 | ||
1637 | ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask); | 1637 | ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask); |
1638 | ser_intr_mask.data_avail = regk_ser_yes; | 1638 | ser_intr_mask.dav = regk_ser_yes; |
1639 | REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask); | 1639 | REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask); |
1640 | #endif | 1640 | #endif |
1641 | 1641 | ||
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index b72a15580dc7..ced5b725d9bd 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c | |||
@@ -12,17 +12,13 @@ | |||
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <asm/arch/hwregs/reg_rdwr.h> | 15 | #include <hwregs/reg_rdwr.h> |
16 | #include <asm/arch/hwregs/reg_map.h> | 16 | #include <hwregs/reg_map.h> |
17 | #include <asm/arch/hwregs/timer_defs.h> | 17 | #include <hwregs/timer_defs.h> |
18 | #include <asm/arch/hwregs/intr_vect_defs.h> | 18 | #include <hwregs/intr_vect_defs.h> |
19 | 19 | ||
20 | extern void stop_watchdog(void); | 20 | extern void stop_watchdog(void); |
21 | 21 | ||
22 | #ifdef CONFIG_ETRAX_GPIO | ||
23 | extern void etrax_gpio_wake_up_check(void); /* Defined in drivers/gpio.c. */ | ||
24 | #endif | ||
25 | |||
26 | extern int cris_hlt_counter; | 22 | extern int cris_hlt_counter; |
27 | 23 | ||
28 | /* We use this if we don't have any better idle routine. */ | 24 | /* We use this if we don't have any better idle routine. */ |
@@ -82,7 +78,7 @@ hard_reset_now(void) | |||
82 | wd_ctrl.cmd = regk_timer_start; | 78 | wd_ctrl.cmd = regk_timer_start; |
83 | 79 | ||
84 | arch_enable_nmi(); | 80 | arch_enable_nmi(); |
85 | REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl); | 81 | REG_WR(timer, regi_timer0, rw_wd_ctrl, wd_ctrl); |
86 | } | 82 | } |
87 | #endif | 83 | #endif |
88 | 84 | ||
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c index 2df60529a8af..e27f4670e88e 100644 --- a/arch/cris/arch-v32/kernel/ptrace.c +++ b/arch/cris/arch-v32/kernel/ptrace.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000-2003, Axis Communications AB. | 2 | * Copyright (C) 2000-2007, Axis Communications AB. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
@@ -149,7 +149,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
149 | ret = generic_ptrace_pokedata(child, addr, data); | 149 | ret = generic_ptrace_pokedata(child, addr, data); |
150 | break; | 150 | break; |
151 | 151 | ||
152 | /* Write the word at location address in the USER area. */ | 152 | /* Write the word at location address in the USER area. */ |
153 | case PTRACE_POKEUSR: | 153 | case PTRACE_POKEUSR: |
154 | ret = -EIO; | 154 | ret = -EIO; |
155 | if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) | 155 | if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) |
@@ -201,7 +201,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
201 | 201 | ||
202 | break; | 202 | break; |
203 | 203 | ||
204 | /* Make the child exit by sending it a sigkill. */ | 204 | /* Make the child exit by sending it a sigkill. */ |
205 | case PTRACE_KILL: | 205 | case PTRACE_KILL: |
206 | ret = 0; | 206 | ret = 0; |
207 | 207 | ||
@@ -245,9 +245,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
245 | break; | 245 | break; |
246 | 246 | ||
247 | } | 247 | } |
248 | |||
248 | /* Get all GP registers from the child. */ | 249 | /* Get all GP registers from the child. */ |
249 | case PTRACE_GETREGS: { | 250 | case PTRACE_GETREGS: { |
250 | int i; | 251 | int i; |
251 | unsigned long tmp; | 252 | unsigned long tmp; |
252 | 253 | ||
253 | for (i = 0; i <= PT_MAX; i++) { | 254 | for (i = 0; i <= PT_MAX; i++) { |
@@ -294,6 +295,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
294 | break; | 295 | break; |
295 | } | 296 | } |
296 | 297 | ||
298 | out_tsk: | ||
297 | return ret; | 299 | return ret; |
298 | } | 300 | } |
299 | 301 | ||
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index 024cc6901974..58c1866804e3 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c | |||
@@ -50,7 +50,7 @@ struct rt_signal_frame { | |||
50 | unsigned char retcode[8]; /* Trampoline code. */ | 50 | unsigned char retcode[8]; /* Trampoline code. */ |
51 | }; | 51 | }; |
52 | 52 | ||
53 | int do_signal(int restart, sigset_t *oldset, struct pt_regs *regs); | 53 | void do_signal(int restart, struct pt_regs *regs); |
54 | void keep_debug_flags(unsigned long oldccs, unsigned long oldspc, | 54 | void keep_debug_flags(unsigned long oldccs, unsigned long oldspc, |
55 | struct pt_regs *regs); | 55 | struct pt_regs *regs); |
56 | /* | 56 | /* |
@@ -61,74 +61,16 @@ int | |||
61 | sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, | 61 | sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, |
62 | long srp, struct pt_regs *regs) | 62 | long srp, struct pt_regs *regs) |
63 | { | 63 | { |
64 | sigset_t saveset; | ||
65 | |||
66 | mask &= _BLOCKABLE; | 64 | mask &= _BLOCKABLE; |
67 | |||
68 | spin_lock_irq(¤t->sighand->siglock); | 65 | spin_lock_irq(¤t->sighand->siglock); |
69 | 66 | current->saved_sigmask = current->blocked; | |
70 | saveset = current->blocked; | ||
71 | |||
72 | siginitset(¤t->blocked, mask); | 67 | siginitset(¤t->blocked, mask); |
73 | |||
74 | recalc_sigpending(); | ||
75 | spin_unlock_irq(¤t->sighand->siglock); | ||
76 | |||
77 | regs->r10 = -EINTR; | ||
78 | |||
79 | while (1) { | ||
80 | current->state = TASK_INTERRUPTIBLE; | ||
81 | schedule(); | ||
82 | |||
83 | if (do_signal(0, &saveset, regs)) { | ||
84 | /* | ||
85 | * This point is reached twice: once to call | ||
86 | * the signal handler, then again to return | ||
87 | * from the sigsuspend system call. When | ||
88 | * calling the signal handler, R10 hold the | ||
89 | * signal number as set by do_signal(). The | ||
90 | * sigsuspend call will always return with | ||
91 | * the restored value above; -EINTR. | ||
92 | */ | ||
93 | return regs->r10; | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* Define some dummy arguments to be able to reach the regs argument. */ | ||
99 | int | ||
100 | sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13, | ||
101 | long mof, long srp, struct pt_regs *regs) | ||
102 | { | ||
103 | sigset_t saveset; | ||
104 | sigset_t newset; | ||
105 | |||
106 | if (sigsetsize != sizeof(sigset_t)) | ||
107 | return -EINVAL; | ||
108 | |||
109 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
110 | return -EFAULT; | ||
111 | |||
112 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
113 | spin_lock_irq(¤t->sighand->siglock); | ||
114 | |||
115 | saveset = current->blocked; | ||
116 | current->blocked = newset; | ||
117 | |||
118 | recalc_sigpending(); | 68 | recalc_sigpending(); |
119 | spin_unlock_irq(¤t->sighand->siglock); | 69 | spin_unlock_irq(¤t->sighand->siglock); |
120 | 70 | current->state = TASK_INTERRUPTIBLE; | |
121 | regs->r10 = -EINTR; | 71 | schedule(); |
122 | 72 | set_thread_flag(TIF_RESTORE_SIGMASK); | |
123 | while (1) { | 73 | return -ERESTARTNOHAND; |
124 | current->state = TASK_INTERRUPTIBLE; | ||
125 | schedule(); | ||
126 | |||
127 | if (do_signal(0, &saveset, regs)) { | ||
128 | /* See comment in function above. */ | ||
129 | return regs->r10; | ||
130 | } | ||
131 | } | ||
132 | } | 74 | } |
133 | 75 | ||
134 | int | 76 | int |
@@ -290,7 +232,7 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, | |||
290 | goto badframe; | 232 | goto badframe; |
291 | 233 | ||
292 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT) | 234 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT) |
293 | goto badframe; | 235 | goto badframe; |
294 | 236 | ||
295 | keep_debug_flags(oldccs, oldspc, regs); | 237 | keep_debug_flags(oldccs, oldspc, regs); |
296 | 238 | ||
@@ -347,11 +289,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
347 | /* Grab and setup a signal frame. | 289 | /* Grab and setup a signal frame. |
348 | * | 290 | * |
349 | * Basically a lot of state-info is stacked, and arranged for the | 291 | * Basically a lot of state-info is stacked, and arranged for the |
350 | * user-mode program to return to the kernel using either a trampoline | 292 | * user-mode program to return to the kernel using either a trampiline |
351 | * which performs the syscall sigreturn(), or a provided user-mode | 293 | * which performs the syscall sigreturn(), or a provided user-mode |
352 | * trampoline. | 294 | * trampoline. |
353 | */ | 295 | */ |
354 | static void | 296 | static int |
355 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 297 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, |
356 | struct pt_regs * regs) | 298 | struct pt_regs * regs) |
357 | { | 299 | { |
@@ -417,16 +359,17 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
417 | /* Actually move the USP to reflect the stacked frame. */ | 359 | /* Actually move the USP to reflect the stacked frame. */ |
418 | wrusp((unsigned long)frame); | 360 | wrusp((unsigned long)frame); |
419 | 361 | ||
420 | return; | 362 | return 0; |
421 | 363 | ||
422 | give_sigsegv: | 364 | give_sigsegv: |
423 | if (sig == SIGSEGV) | 365 | if (sig == SIGSEGV) |
424 | ka->sa.sa_handler = SIG_DFL; | 366 | ka->sa.sa_handler = SIG_DFL; |
425 | 367 | ||
426 | force_sig(SIGSEGV, current); | 368 | force_sig(SIGSEGV, current); |
369 | return -EFAULT; | ||
427 | } | 370 | } |
428 | 371 | ||
429 | static void | 372 | static int |
430 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 373 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
431 | sigset_t *set, struct pt_regs * regs) | 374 | sigset_t *set, struct pt_regs * regs) |
432 | { | 375 | { |
@@ -503,21 +446,24 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
503 | /* Actually move the usp to reflect the stacked frame. */ | 446 | /* Actually move the usp to reflect the stacked frame. */ |
504 | wrusp((unsigned long)frame); | 447 | wrusp((unsigned long)frame); |
505 | 448 | ||
506 | return; | 449 | return 0; |
507 | 450 | ||
508 | give_sigsegv: | 451 | give_sigsegv: |
509 | if (sig == SIGSEGV) | 452 | if (sig == SIGSEGV) |
510 | ka->sa.sa_handler = SIG_DFL; | 453 | ka->sa.sa_handler = SIG_DFL; |
511 | 454 | ||
512 | force_sig(SIGSEGV, current); | 455 | force_sig(SIGSEGV, current); |
456 | return -EFAULT; | ||
513 | } | 457 | } |
514 | 458 | ||
515 | /* Invoke a singal handler to, well, handle the signal. */ | 459 | /* Invoke a singal handler to, well, handle the signal. */ |
516 | static inline void | 460 | static inline int |
517 | handle_signal(int canrestart, unsigned long sig, | 461 | handle_signal(int canrestart, unsigned long sig, |
518 | siginfo_t *info, struct k_sigaction *ka, | 462 | siginfo_t *info, struct k_sigaction *ka, |
519 | sigset_t *oldset, struct pt_regs * regs) | 463 | sigset_t *oldset, struct pt_regs * regs) |
520 | { | 464 | { |
465 | int ret; | ||
466 | |||
521 | /* Check if this got called from a system call. */ | 467 | /* Check if this got called from a system call. */ |
522 | if (canrestart) { | 468 | if (canrestart) { |
523 | /* If so, check system call restarting. */ | 469 | /* If so, check system call restarting. */ |
@@ -561,19 +507,24 @@ handle_signal(int canrestart, unsigned long sig, | |||
561 | 507 | ||
562 | /* Set up the stack frame. */ | 508 | /* Set up the stack frame. */ |
563 | if (ka->sa.sa_flags & SA_SIGINFO) | 509 | if (ka->sa.sa_flags & SA_SIGINFO) |
564 | setup_rt_frame(sig, ka, info, oldset, regs); | 510 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
565 | else | 511 | else |
566 | setup_frame(sig, ka, oldset, regs); | 512 | ret = setup_frame(sig, ka, oldset, regs); |
567 | 513 | ||
568 | if (ka->sa.sa_flags & SA_ONESHOT) | 514 | if (ka->sa.sa_flags & SA_ONESHOT) |
569 | ka->sa.sa_handler = SIG_DFL; | 515 | ka->sa.sa_handler = SIG_DFL; |
570 | 516 | ||
571 | spin_lock_irq(¤t->sighand->siglock); | 517 | if (ret == 0) { |
572 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 518 | spin_lock_irq(¤t->sighand->siglock); |
573 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 519 | sigorsets(¤t->blocked, ¤t->blocked, |
574 | sigaddset(¤t->blocked,sig); | 520 | &ka->sa.sa_mask); |
575 | recalc_sigpending(); | 521 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
576 | spin_unlock_irq(¤t->sighand->siglock); | 522 | sigaddset(¤t->blocked, sig); |
523 | recalc_sigpending(); | ||
524 | spin_unlock_irq(¤t->sighand->siglock); | ||
525 | } | ||
526 | |||
527 | return ret; | ||
577 | } | 528 | } |
578 | 529 | ||
579 | /* | 530 | /* |
@@ -587,12 +538,13 @@ handle_signal(int canrestart, unsigned long sig, | |||
587 | * we can use user_mode(regs) to see if we came directly from kernel or user | 538 | * we can use user_mode(regs) to see if we came directly from kernel or user |
588 | * mode below. | 539 | * mode below. |
589 | */ | 540 | */ |
590 | int | 541 | void |
591 | do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) | 542 | do_signal(int canrestart, struct pt_regs *regs) |
592 | { | 543 | { |
593 | int signr; | 544 | int signr; |
594 | siginfo_t info; | 545 | siginfo_t info; |
595 | struct k_sigaction ka; | 546 | struct k_sigaction ka; |
547 | sigset_t *oldset; | ||
596 | 548 | ||
597 | /* | 549 | /* |
598 | * The common case should go fast, which is why this point is | 550 | * The common case should go fast, which is why this point is |
@@ -600,17 +552,28 @@ do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) | |||
600 | * without doing anything. | 552 | * without doing anything. |
601 | */ | 553 | */ |
602 | if (!user_mode(regs)) | 554 | if (!user_mode(regs)) |
603 | return 1; | 555 | return; |
604 | 556 | ||
605 | if (!oldset) | 557 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
558 | oldset = ¤t->saved_sigmask; | ||
559 | else | ||
606 | oldset = ¤t->blocked; | 560 | oldset = ¤t->blocked; |
607 | 561 | ||
608 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 562 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
609 | 563 | ||
610 | if (signr > 0) { | 564 | if (signr > 0) { |
611 | /* Deliver the signal. */ | 565 | /* Whee! Actually deliver the signal. */ |
612 | handle_signal(canrestart, signr, &info, &ka, oldset, regs); | 566 | if (handle_signal(canrestart, signr, &info, &ka, |
613 | return 1; | 567 | oldset, regs)) { |
568 | /* a signal was successfully delivered; the saved | ||
569 | * sigmask will have been stored in the signal frame, | ||
570 | * and will be restored by sigreturn, so we can simply | ||
571 | * clear the TIF_RESTORE_SIGMASK flag */ | ||
572 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
573 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
574 | } | ||
575 | |||
576 | return; | ||
614 | } | 577 | } |
615 | 578 | ||
616 | /* Got here from a system call? */ | 579 | /* Got here from a system call? */ |
@@ -628,7 +591,12 @@ do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) | |||
628 | } | 591 | } |
629 | } | 592 | } |
630 | 593 | ||
631 | return 0; | 594 | /* if there's no signal to deliver, we just put the saved sigmask |
595 | * back */ | ||
596 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
597 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
598 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
599 | } | ||
632 | } | 600 | } |
633 | 601 | ||
634 | asmlinkage void | 602 | asmlinkage void |
@@ -641,7 +609,7 @@ ugdb_trap_user(struct thread_info *ti, int sig) | |||
641 | user_regs(ti)->spc = 0; | 609 | user_regs(ti)->spc = 0; |
642 | } | 610 | } |
643 | /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA | 611 | /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA |
644 | not within any configured h/w breakpoint range). Synchronize with | 612 | not withing any configured h/w breakpoint range). Synchronize with |
645 | what already exists for kernel debugging. */ | 613 | what already exists for kernel debugging. */ |
646 | if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) { | 614 | if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) { |
647 | /* Break 8: subtract 2 from ERP unless in a delay slot. */ | 615 | /* Break 8: subtract 2 from ERP unless in a delay slot. */ |
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 171c96e0a5d3..a9c3334e46c9 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c | |||
@@ -1,11 +1,12 @@ | |||
1 | #include <linux/types.h> | ||
1 | #include <asm/delay.h> | 2 | #include <asm/delay.h> |
2 | #include <asm/arch/irq.h> | 3 | #include <irq.h> |
3 | #include <asm/arch/hwregs/intr_vect.h> | 4 | #include <hwregs/intr_vect.h> |
4 | #include <asm/arch/hwregs/intr_vect_defs.h> | 5 | #include <hwregs/intr_vect_defs.h> |
5 | #include <asm/tlbflush.h> | 6 | #include <asm/tlbflush.h> |
6 | #include <asm/mmu_context.h> | 7 | #include <asm/mmu_context.h> |
7 | #include <asm/arch/hwregs/mmu_defs_asm.h> | 8 | #include <hwregs/asm/mmu_defs_asm.h> |
8 | #include <asm/arch/hwregs/supp_reg.h> | 9 | #include <hwregs/supp_reg.h> |
9 | #include <asm/atomic.h> | 10 | #include <asm/atomic.h> |
10 | 11 | ||
11 | #include <linux/err.h> | 12 | #include <linux/err.h> |
@@ -20,6 +21,7 @@ | |||
20 | #define IPI_SCHEDULE 1 | 21 | #define IPI_SCHEDULE 1 |
21 | #define IPI_CALL 2 | 22 | #define IPI_CALL 2 |
22 | #define IPI_FLUSH_TLB 4 | 23 | #define IPI_FLUSH_TLB 4 |
24 | #define IPI_BOOT 8 | ||
23 | 25 | ||
24 | #define FLUSH_ALL (void*)0xffffffff | 26 | #define FLUSH_ALL (void*)0xffffffff |
25 | 27 | ||
@@ -30,6 +32,8 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED}; | |||
30 | cpumask_t cpu_online_map = CPU_MASK_NONE; | 32 | cpumask_t cpu_online_map = CPU_MASK_NONE; |
31 | EXPORT_SYMBOL(cpu_online_map); | 33 | EXPORT_SYMBOL(cpu_online_map); |
32 | cpumask_t phys_cpu_present_map = CPU_MASK_NONE; | 34 | cpumask_t phys_cpu_present_map = CPU_MASK_NONE; |
35 | cpumask_t cpu_possible_map; | ||
36 | EXPORT_SYMBOL(cpu_possible_map); | ||
33 | EXPORT_SYMBOL(phys_cpu_present_map); | 37 | EXPORT_SYMBOL(phys_cpu_present_map); |
34 | 38 | ||
35 | /* Variables used during SMP boot */ | 39 | /* Variables used during SMP boot */ |
@@ -55,13 +59,12 @@ static unsigned long flush_addr; | |||
55 | extern int setup_irq(int, struct irqaction *); | 59 | extern int setup_irq(int, struct irqaction *); |
56 | 60 | ||
57 | /* Mode registers */ | 61 | /* Mode registers */ |
58 | static unsigned long irq_regs[NR_CPUS] = | 62 | static unsigned long irq_regs[NR_CPUS] = { |
59 | { | ||
60 | regi_irq, | 63 | regi_irq, |
61 | regi_irq2 | 64 | regi_irq2 |
62 | }; | 65 | }; |
63 | 66 | ||
64 | static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 67 | static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id); |
65 | static int send_ipi(int vector, int wait, cpumask_t cpu_mask); | 68 | static int send_ipi(int vector, int wait, cpumask_t cpu_mask); |
66 | static struct irqaction irq_ipi = { | 69 | static struct irqaction irq_ipi = { |
67 | .handler = crisv32_ipi_interrupt, | 70 | .handler = crisv32_ipi_interrupt, |
@@ -101,6 +104,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
101 | 104 | ||
102 | cpu_set(0, cpu_online_map); | 105 | cpu_set(0, cpu_online_map); |
103 | cpu_set(0, phys_cpu_present_map); | 106 | cpu_set(0, phys_cpu_present_map); |
107 | cpu_set(0, cpu_possible_map); | ||
104 | } | 108 | } |
105 | 109 | ||
106 | void __init smp_cpus_done(unsigned int max_cpus) | 110 | void __init smp_cpus_done(unsigned int max_cpus) |
@@ -113,6 +117,7 @@ smp_boot_one_cpu(int cpuid) | |||
113 | { | 117 | { |
114 | unsigned timeout; | 118 | unsigned timeout; |
115 | struct task_struct *idle; | 119 | struct task_struct *idle; |
120 | cpumask_t cpu_mask = CPU_MASK_NONE; | ||
116 | 121 | ||
117 | idle = fork_idle(cpuid); | 122 | idle = fork_idle(cpuid); |
118 | if (IS_ERR(idle)) | 123 | if (IS_ERR(idle)) |
@@ -124,6 +129,12 @@ smp_boot_one_cpu(int cpuid) | |||
124 | smp_init_current_idle_thread = task_thread_info(idle); | 129 | smp_init_current_idle_thread = task_thread_info(idle); |
125 | cpu_now_booting = cpuid; | 130 | cpu_now_booting = cpuid; |
126 | 131 | ||
132 | /* Kick it */ | ||
133 | cpu_set(cpuid, cpu_online_map); | ||
134 | cpu_set(cpuid, cpu_mask); | ||
135 | send_ipi(IPI_BOOT, 0, cpu_mask); | ||
136 | cpu_clear(cpuid, cpu_online_map); | ||
137 | |||
127 | /* Wait for CPU to come online */ | 138 | /* Wait for CPU to come online */ |
128 | for (timeout = 0; timeout < 10000; timeout++) { | 139 | for (timeout = 0; timeout < 10000; timeout++) { |
129 | if(cpu_online(cpuid)) { | 140 | if(cpu_online(cpuid)) { |
@@ -165,7 +176,7 @@ void __init smp_callin(void) | |||
165 | /* Enable IRQ and idle */ | 176 | /* Enable IRQ and idle */ |
166 | REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); | 177 | REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); |
167 | unmask_irq(IPI_INTR_VECT); | 178 | unmask_irq(IPI_INTR_VECT); |
168 | unmask_irq(TIMER_INTR_VECT); | 179 | unmask_irq(TIMER0_INTR_VECT); |
169 | preempt_disable(); | 180 | preempt_disable(); |
170 | local_irq_enable(); | 181 | local_irq_enable(); |
171 | 182 | ||
@@ -328,7 +339,7 @@ int smp_call_function(void (*func)(void *info), void *info, | |||
328 | return ret; | 339 | return ret; |
329 | } | 340 | } |
330 | 341 | ||
331 | irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 342 | irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id) |
332 | { | 343 | { |
333 | void (*func) (void *info) = call_data->func; | 344 | void (*func) (void *info) = call_data->func; |
334 | void *info = call_data->info; | 345 | void *info = call_data->info; |
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index 2f7e8e200f2c..3a13dd6e0a9a 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c | |||
@@ -1,8 +1,7 @@ | |||
1 | /* $Id: time.c,v 1.19 2005/04/29 05:40:09 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/arch-v32/kernel/time.c | 2 | * linux/arch/cris/arch-v32/kernel/time.c |
4 | * | 3 | * |
5 | * Copyright (C) 2003 Axis Communications AB | 4 | * Copyright (C) 2003-2007 Axis Communications AB |
6 | * | 5 | * |
7 | */ | 6 | */ |
8 | 7 | ||
@@ -14,28 +13,34 @@ | |||
14 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
15 | #include <linux/init.h> | 14 | #include <linux/init.h> |
16 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
16 | #include <linux/cpufreq.h> | ||
17 | #include <asm/types.h> | 17 | #include <asm/types.h> |
18 | #include <asm/signal.h> | 18 | #include <asm/signal.h> |
19 | #include <asm/io.h> | 19 | #include <asm/io.h> |
20 | #include <asm/delay.h> | 20 | #include <asm/delay.h> |
21 | #include <asm/rtc.h> | 21 | #include <asm/rtc.h> |
22 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
23 | 23 | #include <asm/irq_regs.h> | |
24 | #include <asm/arch/hwregs/reg_map.h> | 24 | |
25 | #include <asm/arch/hwregs/reg_rdwr.h> | 25 | #include <hwregs/reg_map.h> |
26 | #include <asm/arch/hwregs/timer_defs.h> | 26 | #include <hwregs/reg_rdwr.h> |
27 | #include <asm/arch/hwregs/intr_vect_defs.h> | 27 | #include <hwregs/timer_defs.h> |
28 | #include <hwregs/intr_vect_defs.h> | ||
29 | #ifdef CONFIG_CRIS_MACH_ARTPEC3 | ||
30 | #include <hwregs/clkgen_defs.h> | ||
31 | #endif | ||
28 | 32 | ||
29 | /* Watchdog defines */ | 33 | /* Watchdog defines */ |
30 | #define ETRAX_WD_KEY_MASK 0x7F /* key is 7 bit */ | 34 | #define ETRAX_WD_KEY_MASK 0x7F /* key is 7 bit */ |
31 | #define ETRAX_WD_HZ 763 /* watchdog counts at 763 Hz */ | 35 | #define ETRAX_WD_HZ 763 /* watchdog counts at 763 Hz */ |
32 | #define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1) /* Number of 763 counts before watchdog bites */ | 36 | /* Number of 763 counts before watchdog bites */ |
37 | #define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1) | ||
33 | 38 | ||
34 | unsigned long timer_regs[NR_CPUS] = | 39 | unsigned long timer_regs[NR_CPUS] = |
35 | { | 40 | { |
36 | regi_timer, | 41 | regi_timer0, |
37 | #ifdef CONFIG_SMP | 42 | #ifdef CONFIG_SMP |
38 | regi_timer2 | 43 | regi_timer2 |
39 | #endif | 44 | #endif |
40 | }; | 45 | }; |
41 | 46 | ||
@@ -44,12 +49,22 @@ extern int set_rtc_mmss(unsigned long nowtime); | |||
44 | extern int setup_irq(int, struct irqaction *); | 49 | extern int setup_irq(int, struct irqaction *); |
45 | extern int have_rtc; | 50 | extern int have_rtc; |
46 | 51 | ||
52 | #ifdef CONFIG_CPU_FREQ | ||
53 | static int | ||
54 | cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, | ||
55 | void *data); | ||
56 | |||
57 | static struct notifier_block cris_time_freq_notifier_block = { | ||
58 | .notifier_call = cris_time_freq_notifier, | ||
59 | }; | ||
60 | #endif | ||
61 | |||
47 | unsigned long get_ns_in_jiffie(void) | 62 | unsigned long get_ns_in_jiffie(void) |
48 | { | 63 | { |
49 | reg_timer_r_tmr0_data data; | 64 | reg_timer_r_tmr0_data data; |
50 | unsigned long ns; | 65 | unsigned long ns; |
51 | 66 | ||
52 | data = REG_RD(timer, regi_timer, r_tmr0_data); | 67 | data = REG_RD(timer, regi_timer0, r_tmr0_data); |
53 | ns = (TIMER0_DIV - data) * 10; | 68 | ns = (TIMER0_DIV - data) * 10; |
54 | return ns; | 69 | return ns; |
55 | } | 70 | } |
@@ -59,31 +74,27 @@ unsigned long do_slow_gettimeoffset(void) | |||
59 | unsigned long count; | 74 | unsigned long count; |
60 | unsigned long usec_count = 0; | 75 | unsigned long usec_count = 0; |
61 | 76 | ||
62 | static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */ | 77 | /* For the first call after boot */ |
78 | static unsigned long count_p = TIMER0_DIV; | ||
63 | static unsigned long jiffies_p = 0; | 79 | static unsigned long jiffies_p = 0; |
64 | 80 | ||
65 | /* | 81 | /* Cache volatile jiffies temporarily; we have IRQs turned off. */ |
66 | * cache volatile jiffies temporarily; we have IRQs turned off. | ||
67 | */ | ||
68 | unsigned long jiffies_t; | 82 | unsigned long jiffies_t; |
69 | 83 | ||
70 | /* The timer interrupt comes from Etrax timer 0. In order to get | 84 | /* The timer interrupt comes from Etrax timer 0. In order to get |
71 | * better precision, we check the current value. It might have | 85 | * better precision, we check the current value. It might have |
72 | * underflowed already though. | 86 | * underflowed already though. */ |
73 | */ | 87 | count = REG_RD(timer, regi_timer0, r_tmr0_data); |
88 | jiffies_t = jiffies; | ||
74 | 89 | ||
75 | count = REG_RD(timer, regi_timer, r_tmr0_data); | 90 | /* Avoiding timer inconsistencies (they are rare, but they happen) |
76 | jiffies_t = jiffies; | 91 | * There is one problem that must be avoided here: |
77 | 92 | * 1. the timer counter underflows | |
78 | /* | ||
79 | * avoiding timer inconsistencies (they are rare, but they happen)... | ||
80 | * there are one problem that must be avoided here: | ||
81 | * 1. the timer counter underflows | ||
82 | */ | 93 | */ |
83 | if( jiffies_t == jiffies_p ) { | 94 | if( jiffies_t == jiffies_p ) { |
84 | if( count > count_p ) { | 95 | if( count > count_p ) { |
85 | /* Timer wrapped, use new count and prescale | 96 | /* Timer wrapped, use new count and prescale. |
86 | * increase the time corresponding to one jiffie | 97 | * Increase the time corresponding to one jiffy. |
87 | */ | 98 | */ |
88 | usec_count = 1000000/HZ; | 99 | usec_count = 1000000/HZ; |
89 | } | 100 | } |
@@ -106,17 +117,15 @@ unsigned long do_slow_gettimeoffset(void) | |||
106 | */ | 117 | */ |
107 | /* This gives us 1.3 ms to do something useful when the NMI comes */ | 118 | /* This gives us 1.3 ms to do something useful when the NMI comes */ |
108 | 119 | ||
109 | /* right now, starting the watchdog is the same as resetting it */ | 120 | /* Right now, starting the watchdog is the same as resetting it */ |
110 | #define start_watchdog reset_watchdog | 121 | #define start_watchdog reset_watchdog |
111 | 122 | ||
112 | #if defined(CONFIG_ETRAX_WATCHDOG) | 123 | #if defined(CONFIG_ETRAX_WATCHDOG) |
113 | static short int watchdog_key = 42; /* arbitrary 7 bit number */ | 124 | static short int watchdog_key = 42; /* arbitrary 7 bit number */ |
114 | #endif | 125 | #endif |
115 | 126 | ||
116 | /* number of pages to consider "out of memory". it is normal that the memory | 127 | /* Number of pages to consider "out of memory". It is normal that the memory |
117 | * is used though, so put this really low. | 128 | * is used though, so set this really low. */ |
118 | */ | ||
119 | |||
120 | #define WATCHDOG_MIN_FREE_PAGES 8 | 129 | #define WATCHDOG_MIN_FREE_PAGES 8 |
121 | 130 | ||
122 | void | 131 | void |
@@ -125,14 +134,15 @@ reset_watchdog(void) | |||
125 | #if defined(CONFIG_ETRAX_WATCHDOG) | 134 | #if defined(CONFIG_ETRAX_WATCHDOG) |
126 | reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; | 135 | reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; |
127 | 136 | ||
128 | /* only keep watchdog happy as long as we have memory left! */ | 137 | /* Only keep watchdog happy as long as we have memory left! */ |
129 | if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { | 138 | if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { |
130 | /* reset the watchdog with the inverse of the old key */ | 139 | /* Reset the watchdog with the inverse of the old key */ |
131 | watchdog_key ^= ETRAX_WD_KEY_MASK; /* invert key, which is 7 bits */ | 140 | /* Invert key, which is 7 bits */ |
141 | watchdog_key ^= ETRAX_WD_KEY_MASK; | ||
132 | wd_ctrl.cnt = ETRAX_WD_CNT; | 142 | wd_ctrl.cnt = ETRAX_WD_CNT; |
133 | wd_ctrl.cmd = regk_timer_start; | 143 | wd_ctrl.cmd = regk_timer_start; |
134 | wd_ctrl.key = watchdog_key; | 144 | wd_ctrl.key = watchdog_key; |
135 | REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl); | 145 | REG_WR(timer, regi_timer0, rw_wd_ctrl, wd_ctrl); |
136 | } | 146 | } |
137 | #endif | 147 | #endif |
138 | } | 148 | } |
@@ -148,7 +158,7 @@ stop_watchdog(void) | |||
148 | wd_ctrl.cnt = ETRAX_WD_CNT; | 158 | wd_ctrl.cnt = ETRAX_WD_CNT; |
149 | wd_ctrl.cmd = regk_timer_stop; | 159 | wd_ctrl.cmd = regk_timer_stop; |
150 | wd_ctrl.key = watchdog_key; | 160 | wd_ctrl.key = watchdog_key; |
151 | REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl); | 161 | REG_WR(timer, regi_timer0, rw_wd_ctrl, wd_ctrl); |
152 | #endif | 162 | #endif |
153 | } | 163 | } |
154 | 164 | ||
@@ -160,17 +170,28 @@ handle_watchdog_bite(struct pt_regs* regs) | |||
160 | #if defined(CONFIG_ETRAX_WATCHDOG) | 170 | #if defined(CONFIG_ETRAX_WATCHDOG) |
161 | extern int cause_of_death; | 171 | extern int cause_of_death; |
162 | 172 | ||
163 | raw_printk("Watchdog bite\n"); | 173 | oops_in_progress = 1; |
174 | printk(KERN_WARNING "Watchdog bite\n"); | ||
164 | 175 | ||
165 | /* Check if forced restart or unexpected watchdog */ | 176 | /* Check if forced restart or unexpected watchdog */ |
166 | if (cause_of_death == 0xbedead) { | 177 | if (cause_of_death == 0xbedead) { |
178 | #ifdef CONFIG_CRIS_MACH_ARTPEC3 | ||
179 | /* There is a bug in Artpec-3 (voodoo TR 78) that requires | ||
180 | * us to go to lower frequency for the reset to be reliable | ||
181 | */ | ||
182 | reg_clkgen_rw_clk_ctrl ctrl = | ||
183 | REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | ||
184 | ctrl.pll = 0; | ||
185 | REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, ctrl); | ||
186 | #endif | ||
167 | while(1); | 187 | while(1); |
168 | } | 188 | } |
169 | 189 | ||
170 | /* Unexpected watchdog, stop the watchdog and dump registers*/ | 190 | /* Unexpected watchdog, stop the watchdog and dump registers. */ |
171 | stop_watchdog(); | 191 | stop_watchdog(); |
172 | raw_printk("Oops: bitten by watchdog\n"); | 192 | printk(KERN_WARNING "Oops: bitten by watchdog\n"); |
173 | show_registers(regs); | 193 | show_registers(regs); |
194 | oops_in_progress = 0; | ||
174 | #ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 195 | #ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY |
175 | reset_watchdog(); | 196 | reset_watchdog(); |
176 | #endif | 197 | #endif |
@@ -178,21 +199,19 @@ handle_watchdog_bite(struct pt_regs* regs) | |||
178 | #endif | 199 | #endif |
179 | } | 200 | } |
180 | 201 | ||
181 | /* last time the cmos clock got updated */ | 202 | /* Last time the cmos clock got updated. */ |
182 | static long last_rtc_update = 0; | 203 | static long last_rtc_update = 0; |
183 | 204 | ||
184 | /* | 205 | /* |
185 | * timer_interrupt() needs to keep up the real-time clock, | 206 | * timer_interrupt() needs to keep up the real-time clock, |
186 | * as well as call the "do_timer()" routine every clocktick | 207 | * as well as call the "do_timer()" routine every clocktick. |
187 | */ | 208 | */ |
188 | |||
189 | //static unsigned short myjiff; /* used by our debug routine print_timestamp */ | ||
190 | |||
191 | extern void cris_do_profile(struct pt_regs *regs); | 209 | extern void cris_do_profile(struct pt_regs *regs); |
192 | 210 | ||
193 | static inline irqreturn_t | 211 | static inline irqreturn_t |
194 | timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 212 | timer_interrupt(int irq, void *dev_id) |
195 | { | 213 | { |
214 | struct pt_regs *regs = get_irq_regs(); | ||
196 | int cpu = smp_processor_id(); | 215 | int cpu = smp_processor_id(); |
197 | reg_timer_r_masked_intr masked_intr; | 216 | reg_timer_r_masked_intr masked_intr; |
198 | reg_timer_rw_ack_intr ack_intr = { 0 }; | 217 | reg_timer_rw_ack_intr ack_intr = { 0 }; |
@@ -202,11 +221,11 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
202 | if (!masked_intr.tmr0) | 221 | if (!masked_intr.tmr0) |
203 | return IRQ_NONE; | 222 | return IRQ_NONE; |
204 | 223 | ||
205 | /* acknowledge the timer irq */ | 224 | /* Acknowledge the timer irq. */ |
206 | ack_intr.tmr0 = 1; | 225 | ack_intr.tmr0 = 1; |
207 | REG_WR(timer, timer_regs[cpu], rw_ack_intr, ack_intr); | 226 | REG_WR(timer, timer_regs[cpu], rw_ack_intr, ack_intr); |
208 | 227 | ||
209 | /* reset watchdog otherwise it resets us! */ | 228 | /* Reset watchdog otherwise it resets us! */ |
210 | reset_watchdog(); | 229 | reset_watchdog(); |
211 | 230 | ||
212 | /* Update statistics. */ | 231 | /* Update statistics. */ |
@@ -218,7 +237,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
218 | if (cpu != 0) | 237 | if (cpu != 0) |
219 | return IRQ_HANDLED; | 238 | return IRQ_HANDLED; |
220 | 239 | ||
221 | /* call the real timer interrupt handler */ | 240 | /* Call the real timer interrupt handler */ |
222 | do_timer(1); | 241 | do_timer(1); |
223 | 242 | ||
224 | /* | 243 | /* |
@@ -236,17 +255,17 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
236 | if (set_rtc_mmss(xtime.tv_sec) == 0) | 255 | if (set_rtc_mmss(xtime.tv_sec) == 0) |
237 | last_rtc_update = xtime.tv_sec; | 256 | last_rtc_update = xtime.tv_sec; |
238 | else | 257 | else |
239 | last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ | 258 | /* Do it again in 60 s */ |
259 | last_rtc_update = xtime.tv_sec - 600; | ||
240 | } | 260 | } |
241 | return IRQ_HANDLED; | 261 | return IRQ_HANDLED; |
242 | } | 262 | } |
243 | 263 | ||
244 | /* timer is IRQF_SHARED so drivers can add stuff to the timer irq chain | 264 | /* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. |
245 | * it needs to be IRQF_DISABLED to make the jiffies update work properly | 265 | * It needs to be IRQF_DISABLED to make the jiffies update work properly. |
246 | */ | 266 | */ |
247 | 267 | static struct irqaction irq_timer = { | |
248 | static struct irqaction irq_timer = { | 268 | .handler = timer_interrupt, |
249 | .mask = timer_interrupt, | ||
250 | .flags = IRQF_SHARED | IRQF_DISABLED, | 269 | .flags = IRQF_SHARED | IRQF_DISABLED, |
251 | .mask = CPU_MASK_NONE, | 270 | .mask = CPU_MASK_NONE, |
252 | .name = "timer" | 271 | .name = "timer" |
@@ -256,27 +275,27 @@ void __init | |||
256 | cris_timer_init(void) | 275 | cris_timer_init(void) |
257 | { | 276 | { |
258 | int cpu = smp_processor_id(); | 277 | int cpu = smp_processor_id(); |
259 | reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 }; | 278 | reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 }; |
260 | reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV; | 279 | reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV; |
261 | reg_timer_rw_intr_mask timer_intr_mask; | 280 | reg_timer_rw_intr_mask timer_intr_mask; |
262 | 281 | ||
263 | /* Setup the etrax timers | 282 | /* Setup the etrax timers. |
264 | * Base frequency is 100MHz, divider 1000000 -> 100 HZ | 283 | * Base frequency is 100MHz, divider 1000000 -> 100 HZ |
265 | * We use timer0, so timer1 is free. | 284 | * We use timer0, so timer1 is free. |
266 | * The trig timer is used by the fasttimer API if enabled. | 285 | * The trig timer is used by the fasttimer API if enabled. |
267 | */ | 286 | */ |
268 | 287 | ||
269 | tmr0_ctrl.op = regk_timer_ld; | 288 | tmr0_ctrl.op = regk_timer_ld; |
270 | tmr0_ctrl.freq = regk_timer_f100; | 289 | tmr0_ctrl.freq = regk_timer_f100; |
271 | REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div); | 290 | REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div); |
272 | REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */ | 291 | REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */ |
273 | tmr0_ctrl.op = regk_timer_run; | 292 | tmr0_ctrl.op = regk_timer_run; |
274 | REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */ | 293 | REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */ |
275 | 294 | ||
276 | /* enable the timer irq */ | 295 | /* Enable the timer irq. */ |
277 | timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask); | 296 | timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask); |
278 | timer_intr_mask.tmr0 = 1; | 297 | timer_intr_mask.tmr0 = 1; |
279 | REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask); | 298 | REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask); |
280 | } | 299 | } |
281 | 300 | ||
282 | void __init | 301 | void __init |
@@ -284,7 +303,7 @@ time_init(void) | |||
284 | { | 303 | { |
285 | reg_intr_vect_rw_mask intr_mask; | 304 | reg_intr_vect_rw_mask intr_mask; |
286 | 305 | ||
287 | /* probe for the RTC and read it if it exists | 306 | /* Probe for the RTC and read it if it exists. |
288 | * Before the RTC can be probed the loops_per_usec variable needs | 307 | * Before the RTC can be probed the loops_per_usec variable needs |
289 | * to be initialized to make usleep work. A better value for | 308 | * to be initialized to make usleep work. A better value for |
290 | * loops_per_usec is calculated by the kernel later once the | 309 | * loops_per_usec is calculated by the kernel later once the |
@@ -293,52 +312,74 @@ time_init(void) | |||
293 | loops_per_usec = 50; | 312 | loops_per_usec = 50; |
294 | 313 | ||
295 | if(RTC_INIT() < 0) { | 314 | if(RTC_INIT() < 0) { |
296 | /* no RTC, start at 1980 */ | 315 | /* No RTC, start at 1980 */ |
297 | xtime.tv_sec = 0; | 316 | xtime.tv_sec = 0; |
298 | xtime.tv_nsec = 0; | 317 | xtime.tv_nsec = 0; |
299 | have_rtc = 0; | 318 | have_rtc = 0; |
300 | } else { | 319 | } else { |
301 | /* get the current time */ | 320 | /* Get the current time */ |
302 | have_rtc = 1; | 321 | have_rtc = 1; |
303 | update_xtime_from_cmos(); | 322 | update_xtime_from_cmos(); |
304 | } | 323 | } |
305 | 324 | ||
306 | /* | 325 | /* |
307 | * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the | 326 | * Initialize wall_to_monotonic such that adding it to |
308 | * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). | 327 | * xtime will yield zero, the tv_nsec field must be normalized |
328 | * (i.e., 0 <= nsec < NSEC_PER_SEC). | ||
309 | */ | 329 | */ |
310 | set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); | 330 | set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); |
311 | 331 | ||
312 | /* Start CPU local timer */ | 332 | /* Start CPU local timer. */ |
313 | cris_timer_init(); | 333 | cris_timer_init(); |
314 | 334 | ||
315 | /* enable the timer irq in global config */ | 335 | /* Enable the timer irq in global config. */ |
316 | intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); | 336 | intr_mask = REG_RD_VECT(intr_vect, regi_irq, rw_mask, 1); |
317 | intr_mask.timer = 1; | 337 | intr_mask.timer0 = 1; |
318 | REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); | 338 | REG_WR_VECT(intr_vect, regi_irq, rw_mask, 1, intr_mask); |
319 | |||
320 | /* now actually register the timer irq handler that calls timer_interrupt() */ | ||
321 | 339 | ||
322 | setup_irq(TIMER_INTR_VECT, &irq_timer); | 340 | /* Now actually register the timer irq handler that calls |
341 | * timer_interrupt(). */ | ||
342 | setup_irq(TIMER0_INTR_VECT, &irq_timer); | ||
323 | 343 | ||
324 | /* enable watchdog if we should use one */ | 344 | /* Enable watchdog if we should use one. */ |
325 | 345 | ||
326 | #if defined(CONFIG_ETRAX_WATCHDOG) | 346 | #if defined(CONFIG_ETRAX_WATCHDOG) |
327 | printk("Enabling watchdog...\n"); | 347 | printk(KERN_INFO "Enabling watchdog...\n"); |
328 | start_watchdog(); | 348 | start_watchdog(); |
329 | 349 | ||
330 | /* If we use the hardware watchdog, we want to trap it as an NMI | 350 | /* If we use the hardware watchdog, we want to trap it as an NMI |
331 | and dump registers before it resets us. For this to happen, we | 351 | * and dump registers before it resets us. For this to happen, we |
332 | must set the "m" NMI enable flag (which once set, is unset only | 352 | * must set the "m" NMI enable flag (which once set, is unset only |
333 | when an NMI is taken). | 353 | * when an NMI is taken). */ |
334 | 354 | { | |
335 | The same goes for the external NMI, but that doesn't have any | 355 | unsigned long flags; |
336 | driver or infrastructure support yet. */ | 356 | local_save_flags(flags); |
337 | { | 357 | flags |= (1<<30); /* NMI M flag is at bit 30 */ |
338 | unsigned long flags; | 358 | local_irq_restore(flags); |
339 | local_save_flags(flags); | 359 | } |
340 | flags |= (1<<30); /* NMI M flag is at bit 30 */ | 360 | #endif |
341 | local_irq_restore(flags); | 361 | |
342 | } | 362 | #ifdef CONFIG_CPU_FREQ |
363 | cpufreq_register_notifier(&cris_time_freq_notifier_block, | ||
364 | CPUFREQ_TRANSITION_NOTIFIER); | ||
343 | #endif | 365 | #endif |
344 | } | 366 | } |
367 | |||
368 | #ifdef CONFIG_CPU_FREQ | ||
369 | static int | ||
370 | cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, | ||
371 | void *data) | ||
372 | { | ||
373 | struct cpufreq_freqs *freqs = data; | ||
374 | if (val == CPUFREQ_POSTCHANGE) { | ||
375 | reg_timer_r_tmr0_data data; | ||
376 | reg_timer_rw_tmr0_div div = (freqs->new * 500) / HZ; | ||
377 | do { | ||
378 | data = REG_RD(timer, timer_regs[freqs->cpu], | ||
379 | r_tmr0_data); | ||
380 | } while (data > 20); | ||
381 | REG_WR(timer, timer_regs[freqs->cpu], rw_tmr0_div, div); | ||
382 | } | ||
383 | return 0; | ||
384 | } | ||
385 | #endif | ||
diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c index 17fd3dbd1c80..9003e382cada 100644 --- a/arch/cris/arch-v32/kernel/traps.c +++ b/arch/cris/arch-v32/kernel/traps.c | |||
@@ -1,50 +1,45 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003, Axis Communications AB. | 2 | * Copyright (C) 2003-2006, Axis Communications AB. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/ptrace.h> | 5 | #include <linux/ptrace.h> |
6 | #include <linux/module.h> | ||
6 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
7 | 8 | #include <hwregs/supp_reg.h> | |
8 | #include <asm/arch/hwregs/supp_reg.h> | 9 | #include <hwregs/intr_vect_defs.h> |
9 | 10 | #include <asm/irq.h> | |
10 | extern void reset_watchdog(void); | ||
11 | extern void stop_watchdog(void); | ||
12 | |||
13 | extern int raw_printk(const char *fmt, ...); | ||
14 | 11 | ||
15 | void | 12 | void |
16 | show_registers(struct pt_regs *regs) | 13 | show_registers(struct pt_regs *regs) |
17 | { | 14 | { |
18 | /* | 15 | /* |
19 | * It's possible to use either the USP register or current->thread.usp. | 16 | * It's possible to use either the USP register or current->thread.usp. |
20 | * USP might not correspond to the current proccess for all cases this | 17 | * USP might not correspond to the current process for all cases this |
21 | * function is called, and current->thread.usp isn't up to date for the | 18 | * function is called, and current->thread.usp isn't up to date for the |
22 | * current proccess. Experience shows that using USP is the way to go. | 19 | * current process. Experience shows that using USP is the way to go. |
23 | */ | 20 | */ |
24 | unsigned long usp; | 21 | unsigned long usp = rdusp(); |
25 | unsigned long d_mmu_cause; | 22 | unsigned long d_mmu_cause; |
26 | unsigned long i_mmu_cause; | 23 | unsigned long i_mmu_cause; |
27 | 24 | ||
28 | usp = rdusp(); | 25 | printk("CPU: %d\n", smp_processor_id()); |
29 | 26 | ||
30 | raw_printk("CPU: %d\n", smp_processor_id()); | 27 | printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n", |
28 | regs->erp, regs->srp, regs->ccs, usp, regs->mof); | ||
31 | 29 | ||
32 | raw_printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n", | 30 | printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", |
33 | regs->erp, regs->srp, regs->ccs, usp, regs->mof); | 31 | regs->r0, regs->r1, regs->r2, regs->r3); |
34 | 32 | ||
35 | raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", | 33 | printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", |
36 | regs->r0, regs->r1, regs->r2, regs->r3); | 34 | regs->r4, regs->r5, regs->r6, regs->r7); |
37 | 35 | ||
38 | raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", | 36 | printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", |
39 | regs->r4, regs->r5, regs->r6, regs->r7); | 37 | regs->r8, regs->r9, regs->r10, regs->r11); |
40 | 38 | ||
41 | raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", | 39 | printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n", |
42 | regs->r8, regs->r9, regs->r10, regs->r11); | 40 | regs->r12, regs->r13, regs->orig_r10, regs->acr); |
43 | 41 | ||
44 | raw_printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n", | 42 | printk(" sp: %08lx\n", (unsigned long)regs); |
45 | regs->r12, regs->r13, regs->orig_r10, regs->acr); | ||
46 | |||
47 | raw_printk("sp: %08lx\n", regs); | ||
48 | 43 | ||
49 | SUPP_BANK_SEL(BANK_IM); | 44 | SUPP_BANK_SEL(BANK_IM); |
50 | SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause); | 45 | SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause); |
@@ -52,18 +47,20 @@ show_registers(struct pt_regs *regs) | |||
52 | SUPP_BANK_SEL(BANK_DM); | 47 | SUPP_BANK_SEL(BANK_DM); |
53 | SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause); | 48 | SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause); |
54 | 49 | ||
55 | raw_printk(" Data MMU Cause: %08lx\n", d_mmu_cause); | 50 | printk(" Data MMU Cause: %08lx\n", d_mmu_cause); |
56 | raw_printk("Instruction MMU Cause: %08lx\n", i_mmu_cause); | 51 | printk("Instruction MMU Cause: %08lx\n", i_mmu_cause); |
57 | 52 | ||
58 | raw_printk("Process %s (pid: %d, stackpage: %08lx)\n", | 53 | printk("Process %s (pid: %d, stackpage=%08lx)\n", |
59 | current->comm, current->pid, (unsigned long) current); | 54 | current->comm, current->pid, (unsigned long)current); |
60 | 55 | ||
61 | /* Show additional info if in kernel-mode. */ | 56 | /* |
57 | * When in-kernel, we also print out the stack and code at the | ||
58 | * time of the fault.. | ||
59 | */ | ||
62 | if (!user_mode(regs)) { | 60 | if (!user_mode(regs)) { |
63 | int i; | 61 | int i; |
64 | unsigned char c; | ||
65 | 62 | ||
66 | show_stack(NULL, (unsigned long *) usp); | 63 | show_stack(NULL, (unsigned long *)usp); |
67 | 64 | ||
68 | /* | 65 | /* |
69 | * If the previous stack-dump wasn't a kernel one, dump the | 66 | * If the previous stack-dump wasn't a kernel one, dump the |
@@ -72,7 +69,7 @@ show_registers(struct pt_regs *regs) | |||
72 | if (usp != 0) | 69 | if (usp != 0) |
73 | show_stack(NULL, NULL); | 70 | show_stack(NULL, NULL); |
74 | 71 | ||
75 | raw_printk("\nCode: "); | 72 | printk("\nCode: "); |
76 | 73 | ||
77 | if (regs->erp < PAGE_OFFSET) | 74 | if (regs->erp < PAGE_OFFSET) |
78 | goto bad_value; | 75 | goto bad_value; |
@@ -84,76 +81,115 @@ show_registers(struct pt_regs *regs) | |||
84 | * instruction decoding should be in sync at the interesting | 81 | * instruction decoding should be in sync at the interesting |
85 | * point, but small enough to fit on a row. The regs->erp | 82 | * point, but small enough to fit on a row. The regs->erp |
86 | * location is pointed out in a ksymoops-friendly way by | 83 | * location is pointed out in a ksymoops-friendly way by |
87 | * wrapping the byte for that address in parenthesis. | 84 | * wrapping the byte for that address in parenthesises. |
88 | */ | 85 | */ |
89 | for (i = -12; i < 12; i++) { | 86 | for (i = -12; i < 12; i++) { |
90 | if (__get_user(c, &((unsigned char *) regs->erp)[i])) { | 87 | unsigned char c; |
88 | |||
89 | if (__get_user(c, &((unsigned char *)regs->erp)[i])) { | ||
91 | bad_value: | 90 | bad_value: |
92 | raw_printk(" Bad IP value."); | 91 | printk(" Bad IP value."); |
93 | break; | 92 | break; |
94 | } | 93 | } |
95 | 94 | ||
96 | if (i == 0) | 95 | if (i == 0) |
97 | raw_printk("(%02x) ", c); | 96 | printk("(%02x) ", c); |
98 | else | 97 | else |
99 | raw_printk("%02x ", c); | 98 | printk("%02x ", c); |
100 | } | 99 | } |
101 | 100 | printk("\n"); | |
102 | raw_printk("\n"); | ||
103 | } | 101 | } |
104 | } | 102 | } |
105 | 103 | ||
106 | /* | ||
107 | * This gets called from entry.S when the watchdog has bitten. Show something | ||
108 | * similar to an Oops dump, and if the kernel is configured to be a nice doggy; | ||
109 | * halt instead of reboot. | ||
110 | */ | ||
111 | void | 104 | void |
112 | watchdog_bite_hook(struct pt_regs *regs) | 105 | arch_enable_nmi(void) |
113 | { | 106 | { |
114 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 107 | unsigned long flags; |
115 | local_irq_disable(); | ||
116 | stop_watchdog(); | ||
117 | show_registers(regs); | ||
118 | 108 | ||
119 | while (1) | 109 | local_save_flags(flags); |
120 | ; /* Do nothing. */ | 110 | flags |= (1 << 30); /* NMI M flag is at bit 30 */ |
121 | #else | 111 | local_irq_restore(flags); |
122 | show_registers(regs); | ||
123 | #endif | ||
124 | } | 112 | } |
125 | 113 | ||
126 | /* This is normally the Oops function. */ | 114 | extern void (*nmi_handler)(struct pt_regs *); |
127 | void | 115 | void handle_nmi(struct pt_regs *regs) |
128 | die_if_kernel(const char *str, struct pt_regs *regs, long err) | ||
129 | { | 116 | { |
130 | if (user_mode(regs)) | 117 | #ifdef CONFIG_ETRAXFS |
131 | return; | 118 | reg_intr_vect_r_nmi r; |
119 | #endif | ||
132 | 120 | ||
133 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 121 | if (nmi_handler) |
134 | /* | 122 | nmi_handler(regs); |
135 | * This printout might take too long and could trigger | 123 | |
136 | * the watchdog normally. If NICE_DOGGY is set, simply | 124 | #ifdef CONFIG_ETRAXFS |
137 | * stop the watchdog during the printout. | 125 | /* Wait until nmi is no longer active. */ |
138 | */ | 126 | do { |
139 | stop_watchdog(); | 127 | r = REG_RD(intr_vect, regi_irq, r_nmi); |
128 | } while (r.ext == regk_intr_vect_on); | ||
140 | #endif | 129 | #endif |
130 | } | ||
141 | 131 | ||
142 | raw_printk("%s: %04lx\n", str, err & 0xffff); | ||
143 | 132 | ||
144 | show_registers(regs); | 133 | #ifdef CONFIG_BUG |
134 | extern void die_if_kernel(const char *str, struct pt_regs *regs, long err); | ||
145 | 135 | ||
146 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 136 | /* Copy of the regs at BUG() time. */ |
147 | reset_watchdog(); | 137 | struct pt_regs BUG_regs; |
148 | #endif | ||
149 | 138 | ||
150 | do_exit(SIGSEGV); | 139 | void do_BUG(char *file, unsigned int line) |
140 | { | ||
141 | printk("kernel BUG at %s:%d!\n", file, line); | ||
142 | die_if_kernel("Oops", &BUG_regs, 0); | ||
151 | } | 143 | } |
144 | EXPORT_SYMBOL(do_BUG); | ||
152 | 145 | ||
153 | void arch_enable_nmi(void) | 146 | void fixup_BUG(struct pt_regs *regs) |
154 | { | 147 | { |
155 | unsigned long flags; | 148 | BUG_regs = *regs; |
156 | local_save_flags(flags); | 149 | |
157 | flags |= (1<<30); /* NMI M flag is at bit 30 */ | 150 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
158 | local_irq_restore(flags); | 151 | /* |
152 | * Fixup the BUG arguments through exception handlers. | ||
153 | */ | ||
154 | { | ||
155 | const struct exception_table_entry *fixup; | ||
156 | |||
157 | /* | ||
158 | * ERP points at the "break 14" + 2, compensate for the 2 | ||
159 | * bytes. | ||
160 | */ | ||
161 | fixup = search_exception_tables(instruction_pointer(regs) - 2); | ||
162 | if (fixup) { | ||
163 | /* Adjust the instruction pointer in the stackframe. */ | ||
164 | instruction_pointer(regs) = fixup->fixup; | ||
165 | arch_fixup(regs); | ||
166 | } | ||
167 | } | ||
168 | #else | ||
169 | /* Dont try to lookup the filename + line, just dump regs. */ | ||
170 | do_BUG("unknown", 0); | ||
171 | #endif | ||
159 | } | 172 | } |
173 | |||
174 | /* | ||
175 | * Break 14 handler. Save regs and jump into the fixup_BUG. | ||
176 | */ | ||
177 | __asm__ ( ".text\n\t" | ||
178 | ".global breakh_BUG\n\t" | ||
179 | "breakh_BUG:\n\t" | ||
180 | SAVE_ALL | ||
181 | KGDB_FIXUP | ||
182 | "move.d $sp, $r10\n\t" | ||
183 | "jsr fixup_BUG\n\t" | ||
184 | "nop\n\t" | ||
185 | "jump ret_from_intr\n\t" | ||
186 | "nop\n\t"); | ||
187 | |||
188 | |||
189 | #ifdef CONFIG_DEBUG_BUGVERBOSE | ||
190 | void | ||
191 | handle_BUG(struct pt_regs *regs) | ||
192 | { | ||
193 | } | ||
194 | #endif | ||
195 | #endif | ||
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.c b/arch/cris/arch-v32/kernel/vcs_hook.c deleted file mode 100644 index 64d71c54c22c..000000000000 --- a/arch/cris/arch-v32/kernel/vcs_hook.c +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | // $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $ | ||
2 | // | ||
3 | // Call simulator hook. This is the part running in the | ||
4 | // simulated program. | ||
5 | // | ||
6 | |||
7 | #include "vcs_hook.h" | ||
8 | #include <stdarg.h> | ||
9 | #include <asm/arch-v32/hwregs/reg_map.h> | ||
10 | #include <asm/arch-v32/hwregs/intr_vect_defs.h> | ||
11 | |||
12 | #define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */ | ||
13 | #define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */ | ||
14 | |||
15 | #define HOOK_DATA(offset) ((unsigned*) HOOK_MEM_BASE_ADDR)[offset] | ||
16 | #define VHOOK_DATA(offset) ((volatile unsigned*) HOOK_MEM_BASE_ADDR)[offset] | ||
17 | #define HOOK_TRIG(funcid) do { *((unsigned *) HOOK_TRIG_ADDR) = funcid; } while(0) | ||
18 | #define HOOK_DATA_BYTE(offset) ((unsigned char*) HOOK_MEM_BASE_ADDR)[offset] | ||
19 | |||
20 | |||
21 | // ------------------------------------------------------------------ hook_call | ||
22 | int hook_call( unsigned id, unsigned pcnt, ...) { | ||
23 | va_list ap; | ||
24 | unsigned i; | ||
25 | unsigned ret; | ||
26 | #ifdef USING_SOS | ||
27 | PREEMPT_OFF_SAVE(); | ||
28 | #endif | ||
29 | |||
30 | // pass parameters | ||
31 | HOOK_DATA(0) = id; | ||
32 | |||
33 | /* Have to make hook_print_str a special case since we call with a | ||
34 | parameter of byte type. Should perhaps be a separate | ||
35 | hook_call. */ | ||
36 | |||
37 | if (id == hook_print_str) { | ||
38 | int i; | ||
39 | char *str; | ||
40 | |||
41 | HOOK_DATA(1) = pcnt; | ||
42 | |||
43 | va_start(ap, pcnt); | ||
44 | str = (char*)va_arg(ap,unsigned); | ||
45 | |||
46 | for (i=0; i!=pcnt; i++) { | ||
47 | HOOK_DATA_BYTE(8+i) = str[i]; | ||
48 | } | ||
49 | HOOK_DATA_BYTE(8+i) = 0; /* null byte */ | ||
50 | } | ||
51 | else { | ||
52 | va_start(ap, pcnt); | ||
53 | for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned); | ||
54 | va_end(ap); | ||
55 | } | ||
56 | |||
57 | // read from mem to make sure data has propagated to memory before trigging | ||
58 | *((volatile unsigned*) HOOK_MEM_BASE_ADDR); | ||
59 | |||
60 | // trigger hook | ||
61 | HOOK_TRIG(id); | ||
62 | |||
63 | // wait for call to finish | ||
64 | while( VHOOK_DATA(0) > 0 ) {} | ||
65 | |||
66 | // extract return value | ||
67 | |||
68 | ret = VHOOK_DATA(1); | ||
69 | |||
70 | #ifdef USING_SOS | ||
71 | PREEMPT_RESTORE(); | ||
72 | #endif | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | unsigned | ||
77 | hook_buf(unsigned i) | ||
78 | { | ||
79 | return (HOOK_DATA(i)); | ||
80 | } | ||
81 | |||
82 | void print_str( const char *str ) { | ||
83 | int i; | ||
84 | for (i=1; str[i]; i++); /* find null at end of string */ | ||
85 | hook_call(hook_print_str, i, str); | ||
86 | } | ||
87 | |||
88 | // --------------------------------------------------------------- CPU_KICK_DOG | ||
89 | void CPU_KICK_DOG(void) { | ||
90 | (void) hook_call( hook_kick_dog, 0 ); | ||
91 | } | ||
92 | |||
93 | // ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT | ||
94 | void CPU_WATCHDOG_TIMEOUT( unsigned t ) { | ||
95 | (void) hook_call( hook_dog_timeout, 1, t ); | ||
96 | } | ||
diff --git a/arch/cris/arch-v32/lib/Makefile b/arch/cris/arch-v32/lib/Makefile index 05b3ec6978d6..eb4aad1f1158 100644 --- a/arch/cris/arch-v32/lib/Makefile +++ b/arch/cris/arch-v32/lib/Makefile | |||
@@ -2,5 +2,6 @@ | |||
2 | # Makefile for Etrax-specific library files.. | 2 | # Makefile for Etrax-specific library files.. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o | 5 | lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o \ |
6 | csumcpfruser.o spinlock.o delay.o | ||
6 | 7 | ||
diff --git a/arch/cris/arch-v32/lib/checksum.S b/arch/cris/arch-v32/lib/checksum.S index 32e66181b826..87f3fd71ab10 100644 --- a/arch/cris/arch-v32/lib/checksum.S +++ b/arch/cris/arch-v32/lib/checksum.S | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * A fast checksum routine using movem | 2 | * A fast checksum routine using movem |
3 | * Copyright (c) 1998-2001, 2003 Axis Communications AB | 3 | * Copyright (c) 1998-2007 Axis Communications AB |
4 | * | 4 | * |
5 | * csum_partial(const unsigned char * buff, int len, unsigned int sum) | 5 | * csum_partial(const unsigned char * buff, int len, unsigned int sum) |
6 | */ | 6 | */ |
@@ -12,30 +12,23 @@ csum_partial: | |||
12 | ;; r11 - length | 12 | ;; r11 - length |
13 | ;; r12 - checksum | 13 | ;; r12 - checksum |
14 | 14 | ||
15 | ;; check for breakeven length between movem and normal word looping versions | 15 | ;; Optimized for large packets |
16 | ;; we also do _NOT_ want to compute a checksum over more than the | 16 | subq 10*4, $r11 |
17 | ;; actual length when length < 40 | 17 | blt _word_loop |
18 | 18 | move.d $r11, $acr | |
19 | cmpu.w 80,$r11 | ||
20 | blo _word_loop | ||
21 | nop | ||
22 | |||
23 | ;; need to save the registers we use below in the movem loop | ||
24 | ;; this overhead is why we have a check above for breakeven length | ||
25 | ;; only r0 - r8 have to be saved, the other ones are clobber-able | ||
26 | ;; according to the ABI | ||
27 | 19 | ||
28 | subq 9*4,$sp | 20 | subq 9*4,$sp |
29 | subq 10*4,$r11 ; update length for the first loop | 21 | clearf c |
30 | movem $r8,[$sp] | 22 | movem $r8,[$sp] |
31 | 23 | ||
32 | ;; do a movem checksum | 24 | ;; do a movem checksum |
33 | 25 | ||
34 | _mloop: movem [$r10+],$r9 ; read 10 longwords | 26 | _mloop: movem [$r10+],$r9 ; read 10 longwords |
35 | 27 | ;; Loop count without touching the c flag. | |
28 | addoq -10*4, $acr, $acr | ||
36 | ;; perform dword checksumming on the 10 longwords | 29 | ;; perform dword checksumming on the 10 longwords |
37 | 30 | ||
38 | add.d $r0,$r12 | 31 | addc $r0,$r12 |
39 | addc $r1,$r12 | 32 | addc $r1,$r12 |
40 | addc $r2,$r12 | 33 | addc $r2,$r12 |
41 | addc $r3,$r12 | 34 | addc $r3,$r12 |
@@ -46,60 +39,41 @@ _mloop: movem [$r10+],$r9 ; read 10 longwords | |||
46 | addc $r8,$r12 | 39 | addc $r8,$r12 |
47 | addc $r9,$r12 | 40 | addc $r9,$r12 |
48 | 41 | ||
49 | ;; fold the carry into the checksum, to avoid having to loop the carry | 42 | ;; test $acr without trashing carry. |
50 | ;; back into the top | 43 | move.d $acr, $acr |
51 | 44 | bpl _mloop | |
52 | addc 0,$r12 | 45 | ;; r11 <= acr is not really needed in the mloop, just using the dslot |
53 | addc 0,$r12 ; do it again, since we might have generated a carry | 46 | ;; to prepare for what is needed after mloop. |
54 | 47 | move.d $acr, $r11 | |
55 | subq 10*4,$r11 | ||
56 | bge _mloop | ||
57 | nop | ||
58 | |||
59 | addq 10*4,$r11 ; compensate for last loop underflowing length | ||
60 | 48 | ||
49 | ;; fold the last carry into r13 | ||
50 | addc 0, $r12 | ||
61 | movem [$sp+],$r8 ; restore regs | 51 | movem [$sp+],$r8 ; restore regs |
62 | 52 | ||
63 | _word_loop: | 53 | _word_loop: |
64 | ;; only fold if there is anything to fold. | 54 | addq 10*4,$r11 ; compensate for last loop underflowing length |
65 | |||
66 | cmpq 0,$r12 | ||
67 | beq _no_fold | ||
68 | |||
69 | ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below. | ||
70 | ;; r9 and r13 can be used as temporaries. | ||
71 | 55 | ||
72 | moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9 | 56 | moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9 |
73 | lsrq 16,$r9 | 57 | lsrq 16,$r9 |
74 | 58 | ||
75 | move.d $r12,$r13 | 59 | move.d $r12,$r13 |
76 | lsrq 16,$r13 ; r13 = checksum >> 16 | 60 | lsrq 16,$r13 ; r13 = checksum >> 16 |
77 | and.d $r9,$r12 ; checksum = checksum & 0xffff | 61 | and.d $r9,$r12 ; checksum = checksum & 0xffff |
78 | add.d $r13,$r12 ; checksum += r13 | ||
79 | move.d $r12,$r13 ; do the same again, maybe we got a carry last add | ||
80 | lsrq 16,$r13 | ||
81 | and.d $r9,$r12 | ||
82 | add.d $r13,$r12 | ||
83 | 62 | ||
84 | _no_fold: | 63 | _no_fold: |
85 | cmpq 2,$r11 | 64 | subq 2,$r11 |
86 | blt _no_words | 65 | blt _no_words |
87 | nop | 66 | add.d $r13,$r12 ; checksum += r13 |
88 | 67 | ||
89 | ;; checksum the rest of the words | 68 | ;; checksum the rest of the words |
90 | |||
91 | subq 2,$r11 | ||
92 | |||
93 | _wloop: subq 2,$r11 | 69 | _wloop: subq 2,$r11 |
94 | bge _wloop | 70 | bge _wloop |
95 | addu.w [$r10+],$r12 | 71 | addu.w [$r10+],$r12 |
96 | 72 | ||
97 | addq 2,$r11 | ||
98 | |||
99 | _no_words: | 73 | _no_words: |
74 | addq 2,$r11 | ||
100 | ;; see if we have one odd byte more | 75 | ;; see if we have one odd byte more |
101 | cmpq 1,$r11 | 76 | bne _do_byte |
102 | beq _do_byte | ||
103 | nop | 77 | nop |
104 | ret | 78 | ret |
105 | move.d $r12,$r10 | 79 | move.d $r12,$r10 |
diff --git a/arch/cris/arch-v32/lib/checksumcopy.S b/arch/cris/arch-v32/lib/checksumcopy.S index 9303ccbadc6d..21aabe91489b 100644 --- a/arch/cris/arch-v32/lib/checksumcopy.S +++ b/arch/cris/arch-v32/lib/checksumcopy.S | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * A fast checksum+copy routine using movem | 2 | * A fast checksum+copy routine using movem |
3 | * Copyright (c) 1998, 2001, 2003 Axis Communications AB | 3 | * Copyright (c) 1998-2007 Axis Communications AB |
4 | * | 4 | * |
5 | * Authors: Bjorn Wesen | 5 | * Authors: Bjorn Wesen |
6 | * | 6 | * |
@@ -16,32 +16,23 @@ csum_partial_copy_nocheck: | |||
16 | ;; r12 - length | 16 | ;; r12 - length |
17 | ;; r13 - checksum | 17 | ;; r13 - checksum |
18 | 18 | ||
19 | ;; check for breakeven length between movem and normal word looping versions | 19 | ;; Optimized for large packets |
20 | ;; we also do _NOT_ want to compute a checksum over more than the | 20 | subq 10*4, $r12 |
21 | ;; actual length when length < 40 | 21 | blt _word_loop |
22 | 22 | move.d $r12, $acr | |
23 | cmpu.w 80,$r12 | ||
24 | blo _word_loop | ||
25 | nop | ||
26 | |||
27 | ;; need to save the registers we use below in the movem loop | ||
28 | ;; this overhead is why we have a check above for breakeven length | ||
29 | ;; only r0 - r8 have to be saved, the other ones are clobber-able | ||
30 | ;; according to the ABI | ||
31 | 23 | ||
32 | subq 9*4,$sp | 24 | subq 9*4,$sp |
33 | subq 10*4,$r12 ; update length for the first loop | 25 | clearf c |
34 | movem $r8,[$sp] | 26 | movem $r8,[$sp] |
35 | 27 | ||
36 | ;; do a movem copy and checksum | 28 | ;; do a movem copy and checksum |
37 | |||
38 | 1: ;; A failing userspace access (the read) will have this as PC. | 29 | 1: ;; A failing userspace access (the read) will have this as PC. |
39 | _mloop: movem [$r10+],$r9 ; read 10 longwords | 30 | _mloop: movem [$r10+],$r9 ; read 10 longwords |
31 | addoq -10*4, $acr, $acr ; loop counter in latency cycle | ||
40 | movem $r9,[$r11+] ; write 10 longwords | 32 | movem $r9,[$r11+] ; write 10 longwords |
41 | 33 | ||
42 | ;; perform dword checksumming on the 10 longwords | 34 | ;; perform dword checksumming on the 10 longwords |
43 | 35 | addc $r0,$r13 | |
44 | add.d $r0,$r13 | ||
45 | addc $r1,$r13 | 36 | addc $r1,$r13 |
46 | addc $r2,$r13 | 37 | addc $r2,$r13 |
47 | addc $r3,$r13 | 38 | addc $r3,$r13 |
@@ -52,47 +43,30 @@ _mloop: movem [$r10+],$r9 ; read 10 longwords | |||
52 | addc $r8,$r13 | 43 | addc $r8,$r13 |
53 | addc $r9,$r13 | 44 | addc $r9,$r13 |
54 | 45 | ||
55 | ;; fold the carry into the checksum, to avoid having to loop the carry | 46 | ;; test $acr, without trashing carry. |
56 | ;; back into the top | 47 | move.d $acr, $acr |
57 | 48 | bpl _mloop | |
58 | addc 0,$r13 | 49 | ;; r12 <= acr is needed after mloop and in the exception handlers. |
59 | addc 0,$r13 ; do it again, since we might have generated a carry | 50 | move.d $acr, $r12 |
60 | |||
61 | subq 10*4,$r12 | ||
62 | bge _mloop | ||
63 | nop | ||
64 | |||
65 | addq 10*4,$r12 ; compensate for last loop underflowing length | ||
66 | 51 | ||
52 | ;; fold the last carry into r13 | ||
53 | addc 0, $r13 | ||
67 | movem [$sp+],$r8 ; restore regs | 54 | movem [$sp+],$r8 ; restore regs |
68 | 55 | ||
69 | _word_loop: | 56 | _word_loop: |
70 | ;; only fold if there is anything to fold. | 57 | addq 10*4,$r12 ; compensate for last loop underflowing length |
71 | |||
72 | cmpq 0,$r13 | ||
73 | beq _no_fold | ||
74 | 58 | ||
75 | ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below | 59 | ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below |
76 | ;; r9 can be used as temporary. | 60 | ;; r9 can be used as temporary. |
77 | |||
78 | move.d $r13,$r9 | 61 | move.d $r13,$r9 |
79 | lsrq 16,$r9 ; r0 = checksum >> 16 | 62 | lsrq 16,$r9 ; r0 = checksum >> 16 |
80 | and.d 0xffff,$r13 ; checksum = checksum & 0xffff | 63 | and.d 0xffff,$r13 ; checksum = checksum & 0xffff |
81 | add.d $r9,$r13 ; checksum += r0 | ||
82 | move.d $r13,$r9 ; do the same again, maybe we got a carry last add | ||
83 | lsrq 16,$r9 | ||
84 | and.d 0xffff,$r13 | ||
85 | add.d $r9,$r13 | ||
86 | 64 | ||
87 | _no_fold: | 65 | subq 2, $r12 |
88 | cmpq 2,$r12 | ||
89 | blt _no_words | 66 | blt _no_words |
90 | nop | 67 | add.d $r9,$r13 ; checksum += r0 |
91 | 68 | ||
92 | ;; copy and checksum the rest of the words | 69 | ;; copy and checksum the rest of the words |
93 | |||
94 | subq 2,$r12 | ||
95 | |||
96 | 2: ;; A failing userspace access for the read below will have this as PC. | 70 | 2: ;; A failing userspace access for the read below will have this as PC. |
97 | _wloop: move.w [$r10+],$r9 | 71 | _wloop: move.w [$r10+],$r9 |
98 | addu.w $r9,$r13 | 72 | addu.w $r9,$r13 |
@@ -100,12 +74,9 @@ _wloop: move.w [$r10+],$r9 | |||
100 | bge _wloop | 74 | bge _wloop |
101 | move.w $r9,[$r11+] | 75 | move.w $r9,[$r11+] |
102 | 76 | ||
103 | addq 2,$r12 | ||
104 | |||
105 | _no_words: | 77 | _no_words: |
106 | ;; see if we have one odd byte more | 78 | addq 2,$r12 |
107 | cmpq 1,$r12 | 79 | bne _do_byte |
108 | beq _do_byte | ||
109 | nop | 80 | nop |
110 | ret | 81 | ret |
111 | move.d $r13,$r10 | 82 | move.d $r13,$r10 |
diff --git a/arch/cris/arch-v32/lib/delay.c b/arch/cris/arch-v32/lib/delay.c new file mode 100644 index 000000000000..39f1ac9995b4 --- /dev/null +++ b/arch/cris/arch-v32/lib/delay.c | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Precise Delay Loops for ETRAX FS | ||
3 | * | ||
4 | * Copyright (C) 2006 Axis Communications AB. | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <hwregs/reg_map.h> | ||
9 | #include <hwregs/reg_rdwr.h> | ||
10 | #include <hwregs/timer_defs.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/module.h> | ||
14 | |||
15 | /* | ||
16 | * On ETRAX FS, we can check the free-running read-only 100MHz timer | ||
17 | * getting 32-bit 10ns precision, theoretically good for 42.94967295 | ||
18 | * seconds. Unsigned arithmetic and careful expression handles | ||
19 | * wrapping. | ||
20 | */ | ||
21 | |||
22 | void cris_delay10ns(u32 n10ns) | ||
23 | { | ||
24 | u32 t0 = REG_RD(timer, regi_timer0, r_time); | ||
25 | while (REG_RD(timer, regi_timer0, r_time) - t0 < n10ns) | ||
26 | ; | ||
27 | } | ||
28 | EXPORT_SYMBOL(cris_delay10ns); | ||
diff --git a/arch/cris/arch-v32/lib/spinlock.S b/arch/cris/arch-v32/lib/spinlock.S index 2437ae7f6ed2..79087ef59a1c 100644 --- a/arch/cris/arch-v32/lib/spinlock.S +++ b/arch/cris/arch-v32/lib/spinlock.S | |||
@@ -12,11 +12,11 @@ | |||
12 | 12 | ||
13 | cris_spin_lock: | 13 | cris_spin_lock: |
14 | clearf p | 14 | clearf p |
15 | 1: test.d [$r10] | 15 | 1: test.b [$r10] |
16 | beq 1b | 16 | beq 1b |
17 | clearf p | 17 | clearf p |
18 | ax | 18 | ax |
19 | clear.d [$r10] | 19 | clear.b [$r10] |
20 | bcs 1b | 20 | bcs 1b |
21 | clearf p | 21 | clearf p |
22 | ret | 22 | ret |
@@ -24,10 +24,10 @@ cris_spin_lock: | |||
24 | 24 | ||
25 | cris_spin_trylock: | 25 | cris_spin_trylock: |
26 | clearf p | 26 | clearf p |
27 | 1: move.d [$r10], $r11 | 27 | 1: move.b [$r10], $r11 |
28 | ax | 28 | ax |
29 | clear.d [$r10] | 29 | clear.b [$r10] |
30 | bcs 1b | 30 | bcs 1b |
31 | clearf p | 31 | clearf p |
32 | ret | 32 | ret |
33 | move.d $r11,$r10 | 33 | movu.b $r11,$r10 |
diff --git a/arch/cris/arch-v32/mach-a3/Kconfig b/arch/cris/arch-v32/mach-a3/Kconfig new file mode 100644 index 000000000000..a4df06d5997a --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/Kconfig | |||
@@ -0,0 +1,110 @@ | |||
1 | if CRIS_MACH_ARTPEC3 | ||
2 | |||
3 | menu "Artpec-3 options" | ||
4 | depends on CRIS_MACH_ARTPEC3 | ||
5 | |||
6 | config ETRAX_DRAM_VIRTUAL_BASE | ||
7 | hex | ||
8 | default "c0000000" | ||
9 | |||
10 | config ETRAX_L2CACHE | ||
11 | bool | ||
12 | default y | ||
13 | |||
14 | config ETRAX_SERIAL_PORTS | ||
15 | int | ||
16 | default 5 | ||
17 | |||
18 | config ETRAX_DDR | ||
19 | bool | ||
20 | default y | ||
21 | |||
22 | config ETRAX_DDR2_MRS | ||
23 | hex "DDR2 MRS" | ||
24 | default "0" | ||
25 | |||
26 | config ETRAX_DDR2_TIMING | ||
27 | hex "DDR2 SDRAM timing" | ||
28 | default "0" | ||
29 | help | ||
30 | SDRAM timing parameters. | ||
31 | |||
32 | config ETRAX_DDR2_CONFIG | ||
33 | hex "DDR2 config" | ||
34 | default "0" | ||
35 | |||
36 | config ETRAX_PIO_CE0_CFG | ||
37 | hex "PIO CE0 configuration" | ||
38 | default "0" | ||
39 | |||
40 | config ETRAX_PIO_CE1_CFG | ||
41 | hex "PIO CE1 configuration" | ||
42 | default "0" | ||
43 | |||
44 | config ETRAX_PIO_CE2_CFG | ||
45 | hex "PIO CE2 configuration" | ||
46 | default "0" | ||
47 | |||
48 | config ETRAX_DEF_GIO_PA_OE | ||
49 | hex "GIO_PA_OE" | ||
50 | default "00000000" | ||
51 | help | ||
52 | Configures the direction of general port A bits. 1 is out, 0 is in. | ||
53 | This is often totally different depending on the product used. | ||
54 | There are some guidelines though - if you know that only LED's are | ||
55 | connected to port PA, then they are usually connected to bits 2-4 | ||
56 | and you can therefore use 1c. On other boards which don't have the | ||
57 | LED's at the general ports, these bits are used for all kinds of | ||
58 | stuff. If you don't know what to use, it is always safe to put all | ||
59 | as inputs, although floating inputs isn't good. | ||
60 | |||
61 | config ETRAX_DEF_GIO_PA_OUT | ||
62 | hex "GIO_PA_OUT" | ||
63 | default "00000000" | ||
64 | help | ||
65 | Configures the initial data for the general port A bits. Most | ||
66 | products should use 00 here. | ||
67 | |||
68 | config ETRAX_DEF_GIO_PB_OE | ||
69 | hex "GIO_PB_OE" | ||
70 | default "000000000" | ||
71 | help | ||
72 | Configures the direction of general port B bits. 1 is out, 0 is in. | ||
73 | This is often totally different depending on the product used. | ||
74 | There are some guidelines though - if you know that only LED's are | ||
75 | connected to port PA, then they are usually connected to bits 2-4 | ||
76 | and you can therefore use 1c. On other boards which don't have the | ||
77 | LED's at the general ports, these bits are used for all kinds of | ||
78 | stuff. If you don't know what to use, it is always safe to put all | ||
79 | as inputs, although floating inputs isn't good. | ||
80 | |||
81 | config ETRAX_DEF_GIO_PB_OUT | ||
82 | hex "GIO_PB_OUT" | ||
83 | default "000000000" | ||
84 | help | ||
85 | Configures the initial data for the general port B bits. Most | ||
86 | products should use 00000 here. | ||
87 | |||
88 | config ETRAX_DEF_GIO_PC_OE | ||
89 | hex "GIO_PC_OE" | ||
90 | default "00000" | ||
91 | help | ||
92 | Configures the direction of general port C bits. 1 is out, 0 is in. | ||
93 | This is often totally different depending on the product used. | ||
94 | There are some guidelines though - if you know that only LED's are | ||
95 | connected to port PA, then they are usually connected to bits 2-4 | ||
96 | and you can therefore use 1c. On other boards which don't have the | ||
97 | LED's at the general ports, these bits are used for all kinds of | ||
98 | stuff. If you don't know what to use, it is always safe to put all | ||
99 | as inputs, although floating inputs isn't good. | ||
100 | |||
101 | config ETRAX_DEF_GIO_PC_OUT | ||
102 | hex "GIO_PC_OUT" | ||
103 | default "00000" | ||
104 | help | ||
105 | Configures the initial data for the general port C bits. Most | ||
106 | products should use 00000 here. | ||
107 | |||
108 | endmenu | ||
109 | |||
110 | endif | ||
diff --git a/arch/cris/arch-v32/mach-a3/Makefile b/arch/cris/arch-v32/mach-a3/Makefile new file mode 100644 index 000000000000..41fa6a6893a9 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $ | ||
2 | # | ||
3 | # Makefile for the linux kernel. | ||
4 | # | ||
5 | |||
6 | obj-y := dma.o pinmux.o io.o arbiter.o | ||
7 | obj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o | ||
8 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | ||
9 | |||
10 | clean: | ||
11 | |||
diff --git a/arch/cris/arch-v32/mach-a3/arbiter.c b/arch/cris/arch-v32/mach-a3/arbiter.c new file mode 100644 index 000000000000..8b924db71c9a --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/arbiter.c | |||
@@ -0,0 +1,634 @@ | |||
1 | /* | ||
2 | * Memory arbiter functions. Allocates bandwidth through the | ||
3 | * arbiter and sets up arbiter breakpoints. | ||
4 | * | ||
5 | * The algorithm first assigns slots to the clients that has specified | ||
6 | * bandwidth (e.g. ethernet) and then the remaining slots are divided | ||
7 | * on all the active clients. | ||
8 | * | ||
9 | * Copyright (c) 2004-2007 Axis Communications AB. | ||
10 | * | ||
11 | * The artpec-3 has two arbiters. The memory hierarchy looks like this: | ||
12 | * | ||
13 | * | ||
14 | * CPU DMAs | ||
15 | * | | | ||
16 | * | | | ||
17 | * -------------- ------------------ | ||
18 | * | foo arbiter|----| Internal memory| | ||
19 | * -------------- ------------------ | ||
20 | * | | ||
21 | * -------------- | ||
22 | * | L2 cache | | ||
23 | * -------------- | ||
24 | * | | ||
25 | * h264 etc | | ||
26 | * | | | ||
27 | * | | | ||
28 | * -------------- | ||
29 | * | bar arbiter| | ||
30 | * -------------- | ||
31 | * | | ||
32 | * --------- | ||
33 | * | SDRAM | | ||
34 | * --------- | ||
35 | * | ||
36 | */ | ||
37 | |||
38 | #include <hwregs/reg_map.h> | ||
39 | #include <hwregs/reg_rdwr.h> | ||
40 | #include <hwregs/marb_foo_defs.h> | ||
41 | #include <hwregs/marb_bar_defs.h> | ||
42 | #include <arbiter.h> | ||
43 | #include <hwregs/intr_vect.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/irq.h> | ||
46 | #include <linux/signal.h> | ||
47 | #include <linux/errno.h> | ||
48 | #include <linux/spinlock.h> | ||
49 | #include <asm/io.h> | ||
50 | #include <asm/irq_regs.h> | ||
51 | |||
52 | #define D(x) | ||
53 | |||
54 | struct crisv32_watch_entry { | ||
55 | unsigned long instance; | ||
56 | watch_callback *cb; | ||
57 | unsigned long start; | ||
58 | unsigned long end; | ||
59 | int used; | ||
60 | }; | ||
61 | |||
62 | #define NUMBER_OF_BP 4 | ||
63 | #define SDRAM_BANDWIDTH 400000000 | ||
64 | #define INTMEM_BANDWIDTH 400000000 | ||
65 | #define NBR_OF_SLOTS 64 | ||
66 | #define NBR_OF_REGIONS 2 | ||
67 | #define NBR_OF_CLIENTS 15 | ||
68 | #define ARBITERS 2 | ||
69 | #define UNASSIGNED 100 | ||
70 | |||
71 | struct arbiter { | ||
72 | unsigned long instance; | ||
73 | int nbr_regions; | ||
74 | int nbr_clients; | ||
75 | int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS]; | ||
76 | int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS]; | ||
77 | }; | ||
78 | |||
79 | static struct crisv32_watch_entry watches[ARBITERS][NUMBER_OF_BP] = | ||
80 | { | ||
81 | { | ||
82 | {regi_marb_foo_bp0}, | ||
83 | {regi_marb_foo_bp1}, | ||
84 | {regi_marb_foo_bp2}, | ||
85 | {regi_marb_foo_bp3} | ||
86 | }, | ||
87 | { | ||
88 | {regi_marb_bar_bp0}, | ||
89 | {regi_marb_bar_bp1}, | ||
90 | {regi_marb_bar_bp2}, | ||
91 | {regi_marb_bar_bp3} | ||
92 | } | ||
93 | }; | ||
94 | |||
95 | struct arbiter arbiters[ARBITERS] = | ||
96 | { | ||
97 | { /* L2 cache arbiter */ | ||
98 | .instance = regi_marb_foo, | ||
99 | .nbr_regions = 2, | ||
100 | .nbr_clients = 15 | ||
101 | }, | ||
102 | { /* DDR2 arbiter */ | ||
103 | .instance = regi_marb_bar, | ||
104 | .nbr_regions = 1, | ||
105 | .nbr_clients = 9 | ||
106 | } | ||
107 | }; | ||
108 | |||
109 | static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH}; | ||
110 | |||
111 | DEFINE_SPINLOCK(arbiter_lock); | ||
112 | |||
113 | static irqreturn_t | ||
114 | crisv32_foo_arbiter_irq(int irq, void *dev_id); | ||
115 | static irqreturn_t | ||
116 | crisv32_bar_arbiter_irq(int irq, void *dev_id); | ||
117 | |||
118 | /* | ||
119 | * "I'm the arbiter, I know the score. | ||
120 | * From square one I'll be watching all 64." | ||
121 | * (memory arbiter slots, that is) | ||
122 | * | ||
123 | * Or in other words: | ||
124 | * Program the memory arbiter slots for "region" according to what's | ||
125 | * in requested_slots[] and active_clients[], while minimizing | ||
126 | * latency. A caller may pass a non-zero positive amount for | ||
127 | * "unused_slots", which must then be the unallocated, remaining | ||
128 | * number of slots, free to hand out to any client. | ||
129 | */ | ||
130 | |||
131 | static void crisv32_arbiter_config(int arbiter, int region, int unused_slots) | ||
132 | { | ||
133 | int slot; | ||
134 | int client; | ||
135 | int interval = 0; | ||
136 | |||
137 | /* | ||
138 | * This vector corresponds to the hardware arbiter slots (see | ||
139 | * the hardware documentation for semantics). We initialize | ||
140 | * each slot with a suitable sentinel value outside the valid | ||
141 | * range {0 .. NBR_OF_CLIENTS - 1} and replace them with | ||
142 | * client indexes. Then it's fed to the hardware. | ||
143 | */ | ||
144 | s8 val[NBR_OF_SLOTS]; | ||
145 | |||
146 | for (slot = 0; slot < NBR_OF_SLOTS; slot++) | ||
147 | val[slot] = -1; | ||
148 | |||
149 | for (client = 0; client < arbiters[arbiter].nbr_clients; client++) { | ||
150 | int pos; | ||
151 | /* Allocate the requested non-zero number of slots, but | ||
152 | * also give clients with zero-requests one slot each | ||
153 | * while stocks last. We do the latter here, in client | ||
154 | * order. This makes sure zero-request clients are the | ||
155 | * first to get to any spare slots, else those slots | ||
156 | * could, when bandwidth is allocated close to the limit, | ||
157 | * all be allocated to low-index non-zero-request clients | ||
158 | * in the default-fill loop below. Another positive but | ||
159 | * secondary effect is a somewhat better spread of the | ||
160 | * zero-bandwidth clients in the vector, avoiding some of | ||
161 | * the latency that could otherwise be caused by the | ||
162 | * partitioning of non-zero-bandwidth clients at low | ||
163 | * indexes and zero-bandwidth clients at high | ||
164 | * indexes. (Note that this spreading can only affect the | ||
165 | * unallocated bandwidth.) All the above only matters for | ||
166 | * memory-intensive situations, of course. | ||
167 | */ | ||
168 | if (!arbiters[arbiter].requested_slots[region][client]) { | ||
169 | /* | ||
170 | * Skip inactive clients. Also skip zero-slot | ||
171 | * allocations in this pass when there are no known | ||
172 | * free slots. | ||
173 | */ | ||
174 | if (!arbiters[arbiter].active_clients[region][client] || | ||
175 | unused_slots <= 0) | ||
176 | continue; | ||
177 | |||
178 | unused_slots--; | ||
179 | |||
180 | /* Only allocate one slot for this client. */ | ||
181 | interval = NBR_OF_SLOTS; | ||
182 | } else | ||
183 | interval = NBR_OF_SLOTS / | ||
184 | arbiters[arbiter].requested_slots[region][client]; | ||
185 | |||
186 | pos = 0; | ||
187 | while (pos < NBR_OF_SLOTS) { | ||
188 | if (val[pos] >= 0) | ||
189 | pos++; | ||
190 | else { | ||
191 | val[pos] = client; | ||
192 | pos += interval; | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | |||
197 | client = 0; | ||
198 | for (slot = 0; slot < NBR_OF_SLOTS; slot++) { | ||
199 | /* | ||
200 | * Allocate remaining slots in round-robin | ||
201 | * client-number order for active clients. For this | ||
202 | * pass, we ignore requested bandwidth and previous | ||
203 | * allocations. | ||
204 | */ | ||
205 | if (val[slot] < 0) { | ||
206 | int first = client; | ||
207 | while (!arbiters[arbiter].active_clients[region][client]) { | ||
208 | client = (client + 1) % | ||
209 | arbiters[arbiter].nbr_clients; | ||
210 | if (client == first) | ||
211 | break; | ||
212 | } | ||
213 | val[slot] = client; | ||
214 | client = (client + 1) % arbiters[arbiter].nbr_clients; | ||
215 | } | ||
216 | if (arbiter == 0) { | ||
217 | if (region == EXT_REGION) | ||
218 | REG_WR_INT_VECT(marb_foo, regi_marb_foo, | ||
219 | rw_l2_slots, slot, val[slot]); | ||
220 | else if (region == INT_REGION) | ||
221 | REG_WR_INT_VECT(marb_foo, regi_marb_foo, | ||
222 | rw_intm_slots, slot, val[slot]); | ||
223 | } else { | ||
224 | REG_WR_INT_VECT(marb_bar, regi_marb_bar, | ||
225 | rw_ddr2_slots, slot, val[slot]); | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
230 | extern char _stext, _etext; | ||
231 | |||
232 | static void crisv32_arbiter_init(void) | ||
233 | { | ||
234 | static int initialized; | ||
235 | |||
236 | if (initialized) | ||
237 | return; | ||
238 | |||
239 | initialized = 1; | ||
240 | |||
241 | /* | ||
242 | * CPU caches are always set to active, but with zero | ||
243 | * bandwidth allocated. It should be ok to allocate zero | ||
244 | * bandwidth for the caches, because DMA for other channels | ||
245 | * will supposedly finish, once their programmed amount is | ||
246 | * done, and then the caches will get access according to the | ||
247 | * "fixed scheme" for unclaimed slots. Though, if for some | ||
248 | * use-case somewhere, there's a maximum CPU latency for | ||
249 | * e.g. some interrupt, we have to start allocating specific | ||
250 | * bandwidth for the CPU caches too. | ||
251 | */ | ||
252 | arbiters[0].active_clients[EXT_REGION][11] = 1; | ||
253 | arbiters[0].active_clients[EXT_REGION][12] = 1; | ||
254 | crisv32_arbiter_config(0, EXT_REGION, 0); | ||
255 | crisv32_arbiter_config(0, INT_REGION, 0); | ||
256 | crisv32_arbiter_config(1, EXT_REGION, 0); | ||
257 | |||
258 | if (request_irq(MEMARB_FOO_INTR_VECT, crisv32_foo_arbiter_irq, | ||
259 | IRQF_DISABLED, "arbiter", NULL)) | ||
260 | printk(KERN_ERR "Couldn't allocate arbiter IRQ\n"); | ||
261 | |||
262 | if (request_irq(MEMARB_BAR_INTR_VECT, crisv32_bar_arbiter_irq, | ||
263 | IRQF_DISABLED, "arbiter", NULL)) | ||
264 | printk(KERN_ERR "Couldn't allocate arbiter IRQ\n"); | ||
265 | |||
266 | #ifndef CONFIG_ETRAX_KGDB | ||
267 | /* Global watch for writes to kernel text segment. */ | ||
268 | crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, | ||
269 | MARB_CLIENTS(arbiter_all_clients, arbiter_bar_all_clients), | ||
270 | arbiter_all_write, NULL); | ||
271 | #endif | ||
272 | |||
273 | /* Set up max burst sizes by default */ | ||
274 | REG_WR_INT(marb_bar, regi_marb_bar, rw_h264_rd_burst, 3); | ||
275 | REG_WR_INT(marb_bar, regi_marb_bar, rw_h264_wr_burst, 3); | ||
276 | REG_WR_INT(marb_bar, regi_marb_bar, rw_ccd_burst, 3); | ||
277 | REG_WR_INT(marb_bar, regi_marb_bar, rw_vin_wr_burst, 3); | ||
278 | REG_WR_INT(marb_bar, regi_marb_bar, rw_vin_rd_burst, 3); | ||
279 | REG_WR_INT(marb_bar, regi_marb_bar, rw_sclr_rd_burst, 3); | ||
280 | REG_WR_INT(marb_bar, regi_marb_bar, rw_vout_burst, 3); | ||
281 | REG_WR_INT(marb_bar, regi_marb_bar, rw_sclr_fifo_burst, 3); | ||
282 | REG_WR_INT(marb_bar, regi_marb_bar, rw_l2cache_burst, 3); | ||
283 | } | ||
284 | |||
285 | int crisv32_arbiter_allocate_bandwidth(int client, int region, | ||
286 | unsigned long bandwidth) | ||
287 | { | ||
288 | int i; | ||
289 | int total_assigned = 0; | ||
290 | int total_clients = 0; | ||
291 | int req; | ||
292 | int arbiter = 0; | ||
293 | |||
294 | crisv32_arbiter_init(); | ||
295 | |||
296 | if (client & 0xffff0000) { | ||
297 | arbiter = 1; | ||
298 | client >>= 16; | ||
299 | } | ||
300 | |||
301 | for (i = 0; i < arbiters[arbiter].nbr_clients; i++) { | ||
302 | total_assigned += arbiters[arbiter].requested_slots[region][i]; | ||
303 | total_clients += arbiters[arbiter].active_clients[region][i]; | ||
304 | } | ||
305 | |||
306 | /* Avoid division by 0 for 0-bandwidth requests. */ | ||
307 | req = bandwidth == 0 | ||
308 | ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth); | ||
309 | |||
310 | /* | ||
311 | * We make sure that there are enough slots only for non-zero | ||
312 | * requests. Requesting 0 bandwidth *may* allocate slots, | ||
313 | * though if all bandwidth is allocated, such a client won't | ||
314 | * get any and will have to rely on getting memory access | ||
315 | * according to the fixed scheme that's the default when one | ||
316 | * of the slot-allocated clients doesn't claim their slot. | ||
317 | */ | ||
318 | if (total_assigned + req > NBR_OF_SLOTS) | ||
319 | return -ENOMEM; | ||
320 | |||
321 | arbiters[arbiter].active_clients[region][client] = 1; | ||
322 | arbiters[arbiter].requested_slots[region][client] = req; | ||
323 | crisv32_arbiter_config(arbiter, region, NBR_OF_SLOTS - total_assigned); | ||
324 | |||
325 | /* Propagate allocation from foo to bar */ | ||
326 | if (arbiter == 0) | ||
327 | crisv32_arbiter_allocate_bandwidth(8 << 16, | ||
328 | EXT_REGION, bandwidth); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * Main entry for bandwidth deallocation. | ||
334 | * | ||
335 | * Strictly speaking, for a somewhat constant set of clients where | ||
336 | * each client gets a constant bandwidth and is just enabled or | ||
337 | * disabled (somewhat dynamically), no action is necessary here to | ||
338 | * avoid starvation for non-zero-allocation clients, as the allocated | ||
339 | * slots will just be unused. However, handing out those unused slots | ||
340 | * to active clients avoids needless latency if the "fixed scheme" | ||
341 | * would give unclaimed slots to an eager low-index client. | ||
342 | */ | ||
343 | |||
344 | void crisv32_arbiter_deallocate_bandwidth(int client, int region) | ||
345 | { | ||
346 | int i; | ||
347 | int total_assigned = 0; | ||
348 | int arbiter = 0; | ||
349 | |||
350 | if (client & 0xffff0000) | ||
351 | arbiter = 1; | ||
352 | |||
353 | arbiters[arbiter].requested_slots[region][client] = 0; | ||
354 | arbiters[arbiter].active_clients[region][client] = 0; | ||
355 | |||
356 | for (i = 0; i < arbiters[arbiter].nbr_clients; i++) | ||
357 | total_assigned += arbiters[arbiter].requested_slots[region][i]; | ||
358 | |||
359 | crisv32_arbiter_config(arbiter, region, NBR_OF_SLOTS - total_assigned); | ||
360 | } | ||
361 | |||
362 | int crisv32_arbiter_watch(unsigned long start, unsigned long size, | ||
363 | unsigned long clients, unsigned long accesses, | ||
364 | watch_callback *cb) | ||
365 | { | ||
366 | int i; | ||
367 | int arbiter; | ||
368 | int used[2]; | ||
369 | int ret = 0; | ||
370 | |||
371 | crisv32_arbiter_init(); | ||
372 | |||
373 | if (start > 0x80000000) { | ||
374 | printk(KERN_ERR "Arbiter: %lX doesn't look like a " | ||
375 | "physical address", start); | ||
376 | return -EFAULT; | ||
377 | } | ||
378 | |||
379 | spin_lock(&arbiter_lock); | ||
380 | |||
381 | if (clients & 0xffff) | ||
382 | used[0] = 1; | ||
383 | if (clients & 0xffff0000) | ||
384 | used[1] = 1; | ||
385 | |||
386 | for (arbiter = 0; arbiter < ARBITERS; arbiter++) { | ||
387 | if (!used[arbiter]) | ||
388 | continue; | ||
389 | |||
390 | for (i = 0; i < NUMBER_OF_BP; i++) { | ||
391 | if (!watches[arbiter][i].used) { | ||
392 | unsigned intr_mask; | ||
393 | if (arbiter) | ||
394 | intr_mask = REG_RD_INT(marb_bar, | ||
395 | regi_marb_bar, rw_intr_mask); | ||
396 | else | ||
397 | intr_mask = REG_RD_INT(marb_foo, | ||
398 | regi_marb_foo, rw_intr_mask); | ||
399 | |||
400 | watches[arbiter][i].used = 1; | ||
401 | watches[arbiter][i].start = start; | ||
402 | watches[arbiter][i].end = start + size; | ||
403 | watches[arbiter][i].cb = cb; | ||
404 | |||
405 | ret |= (i + 1) << (arbiter + 8); | ||
406 | if (arbiter) { | ||
407 | REG_WR_INT(marb_bar_bp, | ||
408 | watches[arbiter][i].instance, | ||
409 | rw_first_addr, | ||
410 | watches[arbiter][i].start); | ||
411 | REG_WR_INT(marb_bar_bp, | ||
412 | watches[arbiter][i].instance, | ||
413 | rw_last_addr, | ||
414 | watches[arbiter][i].end); | ||
415 | REG_WR_INT(marb_bar_bp, | ||
416 | watches[arbiter][i].instance, | ||
417 | rw_op, accesses); | ||
418 | REG_WR_INT(marb_bar_bp, | ||
419 | watches[arbiter][i].instance, | ||
420 | rw_clients, | ||
421 | clients & 0xffff); | ||
422 | } else { | ||
423 | REG_WR_INT(marb_foo_bp, | ||
424 | watches[arbiter][i].instance, | ||
425 | rw_first_addr, | ||
426 | watches[arbiter][i].start); | ||
427 | REG_WR_INT(marb_foo_bp, | ||
428 | watches[arbiter][i].instance, | ||
429 | rw_last_addr, | ||
430 | watches[arbiter][i].end); | ||
431 | REG_WR_INT(marb_foo_bp, | ||
432 | watches[arbiter][i].instance, | ||
433 | rw_op, accesses); | ||
434 | REG_WR_INT(marb_foo_bp, | ||
435 | watches[arbiter][i].instance, | ||
436 | rw_clients, clients >> 16); | ||
437 | } | ||
438 | |||
439 | if (i == 0) | ||
440 | intr_mask |= 1; | ||
441 | else if (i == 1) | ||
442 | intr_mask |= 2; | ||
443 | else if (i == 2) | ||
444 | intr_mask |= 4; | ||
445 | else if (i == 3) | ||
446 | intr_mask |= 8; | ||
447 | |||
448 | if (arbiter) | ||
449 | REG_WR_INT(marb_bar, regi_marb_bar, | ||
450 | rw_intr_mask, intr_mask); | ||
451 | else | ||
452 | REG_WR_INT(marb_foo, regi_marb_foo, | ||
453 | rw_intr_mask, intr_mask); | ||
454 | |||
455 | spin_unlock(&arbiter_lock); | ||
456 | |||
457 | break; | ||
458 | } | ||
459 | } | ||
460 | } | ||
461 | spin_unlock(&arbiter_lock); | ||
462 | if (ret) | ||
463 | return ret; | ||
464 | else | ||
465 | return -ENOMEM; | ||
466 | } | ||
467 | |||
468 | int crisv32_arbiter_unwatch(int id) | ||
469 | { | ||
470 | int arbiter; | ||
471 | int intr_mask; | ||
472 | |||
473 | crisv32_arbiter_init(); | ||
474 | |||
475 | spin_lock(&arbiter_lock); | ||
476 | |||
477 | for (arbiter = 0; arbiter < ARBITERS; arbiter++) { | ||
478 | int id2; | ||
479 | |||
480 | if (arbiter) | ||
481 | intr_mask = REG_RD_INT(marb_bar, regi_marb_bar, | ||
482 | rw_intr_mask); | ||
483 | else | ||
484 | intr_mask = REG_RD_INT(marb_foo, regi_marb_foo, | ||
485 | rw_intr_mask); | ||
486 | |||
487 | id2 = (id & (0xff << (arbiter + 8))) >> (arbiter + 8); | ||
488 | if (id2 == 0) | ||
489 | continue; | ||
490 | id2--; | ||
491 | if ((id2 >= NUMBER_OF_BP) || (!watches[arbiter][id2].used)) { | ||
492 | spin_unlock(&arbiter_lock); | ||
493 | return -EINVAL; | ||
494 | } | ||
495 | |||
496 | memset(&watches[arbiter][id2], 0, | ||
497 | sizeof(struct crisv32_watch_entry)); | ||
498 | |||
499 | if (id2 == 0) | ||
500 | intr_mask &= ~1; | ||
501 | else if (id2 == 1) | ||
502 | intr_mask &= ~2; | ||
503 | else if (id2 == 2) | ||
504 | intr_mask &= ~4; | ||
505 | else if (id2 == 3) | ||
506 | intr_mask &= ~8; | ||
507 | |||
508 | if (arbiter) | ||
509 | REG_WR_INT(marb_bar, regi_marb_bar, rw_intr_mask, | ||
510 | intr_mask); | ||
511 | else | ||
512 | REG_WR_INT(marb_foo, regi_marb_foo, rw_intr_mask, | ||
513 | intr_mask); | ||
514 | } | ||
515 | |||
516 | spin_unlock(&arbiter_lock); | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | extern void show_registers(struct pt_regs *regs); | ||
521 | |||
522 | |||
523 | static irqreturn_t | ||
524 | crisv32_foo_arbiter_irq(int irq, void *dev_id) | ||
525 | { | ||
526 | reg_marb_foo_r_masked_intr masked_intr = | ||
527 | REG_RD(marb_foo, regi_marb_foo, r_masked_intr); | ||
528 | reg_marb_foo_bp_r_brk_clients r_clients; | ||
529 | reg_marb_foo_bp_r_brk_addr r_addr; | ||
530 | reg_marb_foo_bp_r_brk_op r_op; | ||
531 | reg_marb_foo_bp_r_brk_first_client r_first; | ||
532 | reg_marb_foo_bp_r_brk_size r_size; | ||
533 | reg_marb_foo_bp_rw_ack ack = {0}; | ||
534 | reg_marb_foo_rw_ack_intr ack_intr = { | ||
535 | .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1 | ||
536 | }; | ||
537 | struct crisv32_watch_entry *watch; | ||
538 | unsigned arbiter = (unsigned)dev_id; | ||
539 | |||
540 | masked_intr = REG_RD(marb_foo, regi_marb_foo, r_masked_intr); | ||
541 | |||
542 | if (masked_intr.bp0) | ||
543 | watch = &watches[arbiter][0]; | ||
544 | else if (masked_intr.bp1) | ||
545 | watch = &watches[arbiter][1]; | ||
546 | else if (masked_intr.bp2) | ||
547 | watch = &watches[arbiter][2]; | ||
548 | else if (masked_intr.bp3) | ||
549 | watch = &watches[arbiter][3]; | ||
550 | else | ||
551 | return IRQ_NONE; | ||
552 | |||
553 | /* Retrieve all useful information and print it. */ | ||
554 | r_clients = REG_RD(marb_foo_bp, watch->instance, r_brk_clients); | ||
555 | r_addr = REG_RD(marb_foo_bp, watch->instance, r_brk_addr); | ||
556 | r_op = REG_RD(marb_foo_bp, watch->instance, r_brk_op); | ||
557 | r_first = REG_RD(marb_foo_bp, watch->instance, r_brk_first_client); | ||
558 | r_size = REG_RD(marb_foo_bp, watch->instance, r_brk_size); | ||
559 | |||
560 | printk(KERN_DEBUG "Arbiter IRQ\n"); | ||
561 | printk(KERN_DEBUG "Clients %X addr %X op %X first %X size %X\n", | ||
562 | REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_clients, r_clients), | ||
563 | REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_addr, r_addr), | ||
564 | REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_op, r_op), | ||
565 | REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_first_client, r_first), | ||
566 | REG_TYPE_CONV(int, reg_marb_foo_bp_r_brk_size, r_size)); | ||
567 | |||
568 | REG_WR(marb_foo_bp, watch->instance, rw_ack, ack); | ||
569 | REG_WR(marb_foo, regi_marb_foo, rw_ack_intr, ack_intr); | ||
570 | |||
571 | printk(KERN_DEBUG "IRQ occured at %X\n", (unsigned)get_irq_regs()); | ||
572 | |||
573 | if (watch->cb) | ||
574 | watch->cb(); | ||
575 | |||
576 | return IRQ_HANDLED; | ||
577 | } | ||
578 | |||
579 | static irqreturn_t | ||
580 | crisv32_bar_arbiter_irq(int irq, void *dev_id) | ||
581 | { | ||
582 | reg_marb_bar_r_masked_intr masked_intr = | ||
583 | REG_RD(marb_bar, regi_marb_bar, r_masked_intr); | ||
584 | reg_marb_bar_bp_r_brk_clients r_clients; | ||
585 | reg_marb_bar_bp_r_brk_addr r_addr; | ||
586 | reg_marb_bar_bp_r_brk_op r_op; | ||
587 | reg_marb_bar_bp_r_brk_first_client r_first; | ||
588 | reg_marb_bar_bp_r_brk_size r_size; | ||
589 | reg_marb_bar_bp_rw_ack ack = {0}; | ||
590 | reg_marb_bar_rw_ack_intr ack_intr = { | ||
591 | .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1 | ||
592 | }; | ||
593 | struct crisv32_watch_entry *watch; | ||
594 | unsigned arbiter = (unsigned)dev_id; | ||
595 | |||
596 | masked_intr = REG_RD(marb_bar, regi_marb_bar, r_masked_intr); | ||
597 | |||
598 | if (masked_intr.bp0) | ||
599 | watch = &watches[arbiter][0]; | ||
600 | else if (masked_intr.bp1) | ||
601 | watch = &watches[arbiter][1]; | ||
602 | else if (masked_intr.bp2) | ||
603 | watch = &watches[arbiter][2]; | ||
604 | else if (masked_intr.bp3) | ||
605 | watch = &watches[arbiter][3]; | ||
606 | else | ||
607 | return IRQ_NONE; | ||
608 | |||
609 | /* Retrieve all useful information and print it. */ | ||
610 | r_clients = REG_RD(marb_bar_bp, watch->instance, r_brk_clients); | ||
611 | r_addr = REG_RD(marb_bar_bp, watch->instance, r_brk_addr); | ||
612 | r_op = REG_RD(marb_bar_bp, watch->instance, r_brk_op); | ||
613 | r_first = REG_RD(marb_bar_bp, watch->instance, r_brk_first_client); | ||
614 | r_size = REG_RD(marb_bar_bp, watch->instance, r_brk_size); | ||
615 | |||
616 | printk(KERN_DEBUG "Arbiter IRQ\n"); | ||
617 | printk(KERN_DEBUG "Clients %X addr %X op %X first %X size %X\n", | ||
618 | REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_clients, r_clients), | ||
619 | REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_addr, r_addr), | ||
620 | REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_op, r_op), | ||
621 | REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_first_client, r_first), | ||
622 | REG_TYPE_CONV(int, reg_marb_bar_bp_r_brk_size, r_size)); | ||
623 | |||
624 | REG_WR(marb_bar_bp, watch->instance, rw_ack, ack); | ||
625 | REG_WR(marb_bar, regi_marb_bar, rw_ack_intr, ack_intr); | ||
626 | |||
627 | printk(KERN_DEBUG "IRQ occured at %X\n", (unsigned)get_irq_regs()->erp); | ||
628 | |||
629 | if (watch->cb) | ||
630 | watch->cb(); | ||
631 | |||
632 | return IRQ_HANDLED; | ||
633 | } | ||
634 | |||
diff --git a/arch/cris/arch-v32/mach-a3/cpufreq.c b/arch/cris/arch-v32/mach-a3/cpufreq.c new file mode 100644 index 000000000000..8e5a3cab8ad7 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/cpufreq.c | |||
@@ -0,0 +1,153 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/cpufreq.h> | ||
4 | #include <hwregs/reg_map.h> | ||
5 | #include <hwregs/reg_rdwr.h> | ||
6 | #include <hwregs/clkgen_defs.h> | ||
7 | #include <hwregs/ddr2_defs.h> | ||
8 | |||
9 | static int | ||
10 | cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, | ||
11 | void *data); | ||
12 | |||
13 | static struct notifier_block cris_sdram_freq_notifier_block = { | ||
14 | .notifier_call = cris_sdram_freq_notifier | ||
15 | }; | ||
16 | |||
17 | static struct cpufreq_frequency_table cris_freq_table[] = { | ||
18 | {0x01, 6000}, | ||
19 | {0x02, 200000}, | ||
20 | {0, CPUFREQ_TABLE_END}, | ||
21 | }; | ||
22 | |||
23 | static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) | ||
24 | { | ||
25 | reg_clkgen_rw_clk_ctrl clk_ctrl; | ||
26 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | ||
27 | return clk_ctrl.pll ? 200000 : 6000; | ||
28 | } | ||
29 | |||
30 | static void cris_freq_set_cpu_state(unsigned int state) | ||
31 | { | ||
32 | int i = 0; | ||
33 | struct cpufreq_freqs freqs; | ||
34 | reg_clkgen_rw_clk_ctrl clk_ctrl; | ||
35 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | ||
36 | |||
37 | #ifdef CONFIG_SMP | ||
38 | for_each_present_cpu(i) | ||
39 | #endif | ||
40 | { | ||
41 | freqs.old = cris_freq_get_cpu_frequency(i); | ||
42 | freqs.new = cris_freq_table[state].frequency; | ||
43 | freqs.cpu = i; | ||
44 | } | ||
45 | |||
46 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
47 | |||
48 | local_irq_disable(); | ||
49 | |||
50 | /* Even though we may be SMP they will share the same clock | ||
51 | * so all settings are made on CPU0. */ | ||
52 | if (cris_freq_table[state].frequency == 200000) | ||
53 | clk_ctrl.pll = 1; | ||
54 | else | ||
55 | clk_ctrl.pll = 0; | ||
56 | REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); | ||
57 | |||
58 | local_irq_enable(); | ||
59 | |||
60 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
61 | }; | ||
62 | |||
63 | static int cris_freq_verify(struct cpufreq_policy *policy) | ||
64 | { | ||
65 | return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]); | ||
66 | } | ||
67 | |||
68 | static int cris_freq_target(struct cpufreq_policy *policy, | ||
69 | unsigned int target_freq, | ||
70 | unsigned int relation) | ||
71 | { | ||
72 | unsigned int newstate = 0; | ||
73 | |||
74 | if (cpufreq_frequency_table_target(policy, cris_freq_table, | ||
75 | target_freq, relation, &newstate)) | ||
76 | return -EINVAL; | ||
77 | |||
78 | cris_freq_set_cpu_state(newstate); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int cris_freq_cpu_init(struct cpufreq_policy *policy) | ||
84 | { | ||
85 | int result; | ||
86 | |||
87 | /* cpuinfo and default policy values */ | ||
88 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
89 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
90 | policy->cur = cris_freq_get_cpu_frequency(0); | ||
91 | |||
92 | result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table); | ||
93 | if (result) | ||
94 | return (result); | ||
95 | |||
96 | cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | |||
102 | static int cris_freq_cpu_exit(struct cpufreq_policy *policy) | ||
103 | { | ||
104 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | |||
109 | static struct freq_attr *cris_freq_attr[] = { | ||
110 | &cpufreq_freq_attr_scaling_available_freqs, | ||
111 | NULL, | ||
112 | }; | ||
113 | |||
114 | static struct cpufreq_driver cris_freq_driver = { | ||
115 | .get = cris_freq_get_cpu_frequency, | ||
116 | .verify = cris_freq_verify, | ||
117 | .target = cris_freq_target, | ||
118 | .init = cris_freq_cpu_init, | ||
119 | .exit = cris_freq_cpu_exit, | ||
120 | .name = "cris_freq", | ||
121 | .owner = THIS_MODULE, | ||
122 | .attr = cris_freq_attr, | ||
123 | }; | ||
124 | |||
125 | static int __init cris_freq_init(void) | ||
126 | { | ||
127 | int ret; | ||
128 | ret = cpufreq_register_driver(&cris_freq_driver); | ||
129 | cpufreq_register_notifier(&cris_sdram_freq_notifier_block, | ||
130 | CPUFREQ_TRANSITION_NOTIFIER); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static int | ||
135 | cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, | ||
136 | void *data) | ||
137 | { | ||
138 | int i; | ||
139 | struct cpufreq_freqs *freqs = data; | ||
140 | if (val == CPUFREQ_PRECHANGE) { | ||
141 | reg_ddr2_rw_cfg cfg = | ||
142 | REG_RD(ddr2, regi_ddr2_ctrl, rw_cfg); | ||
143 | cfg.ref_interval = (freqs->new == 200000 ? 1560 : 46); | ||
144 | |||
145 | if (freqs->new == 200000) | ||
146 | for (i = 0; i < 50000; i++); | ||
147 | REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing); | ||
148 | } | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | |||
153 | module_init(cris_freq_init); | ||
diff --git a/arch/cris/arch-v32/mach-a3/dma.c b/arch/cris/arch-v32/mach-a3/dma.c new file mode 100644 index 000000000000..25f236ef0b81 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/dma.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* Wrapper for DMA channel allocator that starts clocks etc */ | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/spinlock.h> | ||
5 | #include <asm/arch/mach/dma.h> | ||
6 | #include <hwregs/reg_map.h> | ||
7 | #include <hwregs/reg_rdwr.h> | ||
8 | #include <hwregs/marb_defs.h> | ||
9 | #include <hwregs/clkgen_defs.h> | ||
10 | #include <hwregs/strmux_defs.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <asm/system.h> | ||
13 | #include <arbiter.h> | ||
14 | |||
15 | static char used_dma_channels[MAX_DMA_CHANNELS]; | ||
16 | static const char *used_dma_channels_users[MAX_DMA_CHANNELS]; | ||
17 | |||
18 | static DEFINE_SPINLOCK(dma_lock); | ||
19 | |||
20 | int crisv32_request_dma(unsigned int dmanr, const char *device_id, | ||
21 | unsigned options, unsigned int bandwidth, enum dma_owner owner) | ||
22 | { | ||
23 | unsigned long flags; | ||
24 | reg_clkgen_rw_clk_ctrl clk_ctrl; | ||
25 | reg_strmux_rw_cfg strmux_cfg; | ||
26 | |||
27 | if (crisv32_arbiter_allocate_bandwidth(dmanr, | ||
28 | options & DMA_INT_MEM ? INT_REGION : EXT_REGION, | ||
29 | bandwidth)) | ||
30 | return -ENOMEM; | ||
31 | |||
32 | spin_lock_irqsave(&dma_lock, flags); | ||
33 | |||
34 | if (used_dma_channels[dmanr]) { | ||
35 | spin_unlock_irqrestore(&dma_lock, flags); | ||
36 | if (options & DMA_VERBOSE_ON_ERROR) | ||
37 | printk(KERN_ERR "Failed to request DMA %i for %s, " | ||
38 | "already allocated by %s\n", | ||
39 | dmanr, | ||
40 | device_id, | ||
41 | used_dma_channels_users[dmanr]); | ||
42 | |||
43 | if (options & DMA_PANIC_ON_ERROR) | ||
44 | panic("request_dma error!"); | ||
45 | spin_unlock_irqrestore(&dma_lock, flags); | ||
46 | return -EBUSY; | ||
47 | } | ||
48 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | ||
49 | strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); | ||
50 | |||
51 | switch (dmanr) { | ||
52 | case 0: | ||
53 | case 1: | ||
54 | clk_ctrl.dma0_1_eth = 1; | ||
55 | break; | ||
56 | case 2: | ||
57 | case 3: | ||
58 | clk_ctrl.dma2_3_strcop = 1; | ||
59 | break; | ||
60 | case 4: | ||
61 | case 5: | ||
62 | clk_ctrl.dma4_5_iop = 1; | ||
63 | break; | ||
64 | case 6: | ||
65 | case 7: | ||
66 | clk_ctrl.sser_ser_dma6_7 = 1; | ||
67 | break; | ||
68 | case 9: | ||
69 | case 11: | ||
70 | clk_ctrl.dma9_11 = 1; | ||
71 | break; | ||
72 | #if MAX_DMA_CHANNELS-1 != 11 | ||
73 | #error Check dma.c | ||
74 | #endif | ||
75 | default: | ||
76 | spin_unlock_irqrestore(&dma_lock, flags); | ||
77 | if (options & DMA_VERBOSE_ON_ERROR) | ||
78 | printk(KERN_ERR "Failed to request DMA %i for %s, " | ||
79 | "only 0-%i valid)\n", | ||
80 | dmanr, device_id, MAX_DMA_CHANNELS-1); | ||
81 | |||
82 | if (options & DMA_PANIC_ON_ERROR) | ||
83 | panic("request_dma error!"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | switch (owner) { | ||
88 | case dma_eth: | ||
89 | if (dmanr == 0) | ||
90 | strmux_cfg.dma0 = regk_strmux_eth; | ||
91 | else if (dmanr == 1) | ||
92 | strmux_cfg.dma1 = regk_strmux_eth; | ||
93 | else | ||
94 | panic("Invalid DMA channel for eth\n"); | ||
95 | break; | ||
96 | case dma_ser0: | ||
97 | if (dmanr == 0) | ||
98 | strmux_cfg.dma0 = regk_strmux_ser0; | ||
99 | else if (dmanr == 1) | ||
100 | strmux_cfg.dma1 = regk_strmux_ser0; | ||
101 | else | ||
102 | panic("Invalid DMA channel for ser0\n"); | ||
103 | break; | ||
104 | case dma_ser3: | ||
105 | if (dmanr == 2) | ||
106 | strmux_cfg.dma2 = regk_strmux_ser3; | ||
107 | else if (dmanr == 3) | ||
108 | strmux_cfg.dma3 = regk_strmux_ser3; | ||
109 | else | ||
110 | panic("Invalid DMA channel for ser3\n"); | ||
111 | break; | ||
112 | case dma_strp: | ||
113 | if (dmanr == 2) | ||
114 | strmux_cfg.dma2 = regk_strmux_strcop; | ||
115 | else if (dmanr == 3) | ||
116 | strmux_cfg.dma3 = regk_strmux_strcop; | ||
117 | else | ||
118 | panic("Invalid DMA channel for strp\n"); | ||
119 | break; | ||
120 | case dma_ser1: | ||
121 | if (dmanr == 4) | ||
122 | strmux_cfg.dma4 = regk_strmux_ser1; | ||
123 | else if (dmanr == 5) | ||
124 | strmux_cfg.dma5 = regk_strmux_ser1; | ||
125 | else | ||
126 | panic("Invalid DMA channel for ser1\n"); | ||
127 | break; | ||
128 | case dma_iop: | ||
129 | if (dmanr == 4) | ||
130 | strmux_cfg.dma4 = regk_strmux_iop; | ||
131 | else if (dmanr == 5) | ||
132 | strmux_cfg.dma5 = regk_strmux_iop; | ||
133 | else | ||
134 | panic("Invalid DMA channel for iop\n"); | ||
135 | break; | ||
136 | case dma_ser2: | ||
137 | if (dmanr == 6) | ||
138 | strmux_cfg.dma6 = regk_strmux_ser2; | ||
139 | else if (dmanr == 7) | ||
140 | strmux_cfg.dma7 = regk_strmux_ser2; | ||
141 | else | ||
142 | panic("Invalid DMA channel for ser2\n"); | ||
143 | break; | ||
144 | case dma_sser: | ||
145 | if (dmanr == 6) | ||
146 | strmux_cfg.dma6 = regk_strmux_sser; | ||
147 | else if (dmanr == 7) | ||
148 | strmux_cfg.dma7 = regk_strmux_sser; | ||
149 | else | ||
150 | panic("Invalid DMA channel for sser\n"); | ||
151 | break; | ||
152 | case dma_ser4: | ||
153 | if (dmanr == 9) | ||
154 | strmux_cfg.dma9 = regk_strmux_ser4; | ||
155 | else | ||
156 | panic("Invalid DMA channel for ser4\n"); | ||
157 | break; | ||
158 | case dma_jpeg: | ||
159 | if (dmanr == 9) | ||
160 | strmux_cfg.dma9 = regk_strmux_jpeg; | ||
161 | else | ||
162 | panic("Invalid DMA channel for JPEG\n"); | ||
163 | break; | ||
164 | case dma_h264: | ||
165 | if (dmanr == 11) | ||
166 | strmux_cfg.dma11 = regk_strmux_h264; | ||
167 | else | ||
168 | panic("Invalid DMA channel for H264\n"); | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | used_dma_channels[dmanr] = 1; | ||
173 | used_dma_channels_users[dmanr] = device_id; | ||
174 | REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); | ||
175 | REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); | ||
176 | spin_unlock_irqrestore(&dma_lock, flags); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | void crisv32_free_dma(unsigned int dmanr) | ||
181 | { | ||
182 | spin_lock(&dma_lock); | ||
183 | used_dma_channels[dmanr] = 0; | ||
184 | spin_unlock(&dma_lock); | ||
185 | } | ||
diff --git a/arch/cris/arch-v32/mach-a3/dram_init.S b/arch/cris/arch-v32/mach-a3/dram_init.S new file mode 100644 index 000000000000..94d6b41cb299 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/dram_init.S | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * DDR SDRAM initialization - alter with care | ||
3 | * This file is intended to be included from other assembler files | ||
4 | * | ||
5 | * Note: This file may not modify r8 or r9 because they are used to | ||
6 | * carry information from the decompresser to the kernel | ||
7 | * | ||
8 | * Copyright (C) 2005-2007 Axis Communications AB | ||
9 | * | ||
10 | * Authors: Mikael Starvik <starvik@axis.com> | ||
11 | */ | ||
12 | |||
13 | /* Just to be certain the config file is included, we include it here | ||
14 | * explicitely instead of depending on it being included in the file that | ||
15 | * uses this code. | ||
16 | */ | ||
17 | |||
18 | #include <hwregs/asm/reg_map_asm.h> | ||
19 | #include <hwregs/asm/ddr2_defs_asm.h> | ||
20 | |||
21 | ;; WARNING! The registers r8 and r9 are used as parameters carrying | ||
22 | ;; information from the decompressor (if the kernel was compressed). | ||
23 | ;; They should not be used in the code below. | ||
24 | |||
25 | ;; Refer to ddr2 MDS for initialization sequence | ||
26 | |||
27 | ; Start clock | ||
28 | move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_cfg), $r0 | ||
29 | move.d REG_STATE(ddr2, rw_phy_cfg, en, yes), $r1 | ||
30 | move.d $r1, [$r0] | ||
31 | |||
32 | ; Reset phy and start calibration | ||
33 | move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_ctrl), $r0 | ||
34 | move.d REG_STATE(ddr2, rw_phy_ctrl, rst, yes) | \ | ||
35 | REG_STATE(ddr2, rw_phy_ctrl, cal_rst, yes), $r1 | ||
36 | move.d $r1, [$r0] | ||
37 | move.d REG_STATE(ddr2, rw_phy_ctrl, cal_start, yes), $r1 | ||
38 | move.d $r1, [$r0] | ||
39 | |||
40 | ; 2. Wait 200us | ||
41 | move.d 10000, $r2 | ||
42 | 1: bne 1b | ||
43 | subq 1, $r2 | ||
44 | |||
45 | ; Issue commands | ||
46 | move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_ctrl), $r0 | ||
47 | move.d sdram_commands_start, $r2 | ||
48 | command_loop: | ||
49 | movu.b [$r2+], $r1 | ||
50 | movu.w [$r2+], $r3 | ||
51 | do_cmd: | ||
52 | lslq 16, $r1 | ||
53 | or.d $r3, $r1 | ||
54 | move.d $r1, [$r0] | ||
55 | cmp.d sdram_commands_end, $r2 | ||
56 | blo command_loop | ||
57 | nop | ||
58 | |||
59 | ; Set timing | ||
60 | move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_timing), $r0 | ||
61 | move.d CONFIG_ETRAX_DDR2_TIMING, $r1 | ||
62 | move.d $r1, [$r0] | ||
63 | |||
64 | ; Set latency | ||
65 | move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_latency), $r0 | ||
66 | move.d 0x13, $r1 | ||
67 | move.d $r1, [$r0] | ||
68 | |||
69 | ; Set configuration | ||
70 | move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_cfg), $r0 | ||
71 | move.d CONFIG_ETRAX_DDR2_CONFIG, $r1 | ||
72 | move.d $r1, [$r0] | ||
73 | |||
74 | ba after_sdram_commands | ||
75 | nop | ||
76 | |||
77 | sdram_commands_start: | ||
78 | .byte regk_ddr2_deselect | ||
79 | .word 0 | ||
80 | .byte regk_ddr2_pre | ||
81 | .word regk_ddr2_pre_all | ||
82 | .byte regk_ddr2_emrs2 | ||
83 | .word 0 | ||
84 | .byte regk_ddr2_emrs3 | ||
85 | .word 0 | ||
86 | .byte regk_ddr2_emrs | ||
87 | .word regk_ddr2_dll_en | ||
88 | .byte regk_ddr2_mrs | ||
89 | .word regk_ddr2_dll_rst | ||
90 | .byte regk_ddr2_pre | ||
91 | .word regk_ddr2_pre_all | ||
92 | .byte regk_ddr2_ref | ||
93 | .word 0 | ||
94 | .byte regk_ddr2_ref | ||
95 | .word 0 | ||
96 | .byte regk_ddr2_mrs | ||
97 | .word CONFIG_ETRAX_DDR2_MRS & 0xffff | ||
98 | .byte regk_ddr2_emrs | ||
99 | .word regk_ddr2_ocd_default | regk_ddr2_dll_en | ||
100 | .byte regk_ddr2_emrs | ||
101 | .word regk_ddr2_ocd_exit | regk_ddr2_dll_en | (CONFIG_ETRAX_DDR2_MRS >> 16) | ||
102 | sdram_commands_end: | ||
103 | .align 1 | ||
104 | after_sdram_commands: | ||
diff --git a/arch/cris/arch-v32/mach-a3/hw_settings.S b/arch/cris/arch-v32/mach-a3/hw_settings.S new file mode 100644 index 000000000000..258a6329cd4a --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/hw_settings.S | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * This table is used by some tools to extract hardware parameters. | ||
3 | * The table should be included in the kernel and the decompressor. | ||
4 | * Don't forget to update the tools if you change this table. | ||
5 | * | ||
6 | * Copyright (C) 2001-2007 Axis Communications AB | ||
7 | * | ||
8 | * Authors: Mikael Starvik <starvik@axis.com> | ||
9 | */ | ||
10 | |||
11 | #include <hwregs/asm/reg_map_asm.h> | ||
12 | #include <hwregs/asm/ddr2_defs_asm.h> | ||
13 | #include <hwregs/asm/gio_defs_asm.h> | ||
14 | |||
15 | .ascii "HW_PARAM_MAGIC" ; Magic number | ||
16 | .dword 0xc0004000 ; Kernel start address | ||
17 | |||
18 | ; Debug port | ||
19 | #ifdef CONFIG_ETRAX_DEBUG_PORT0 | ||
20 | .dword 0 | ||
21 | #elif defined(CONFIG_ETRAX_DEBUG_PORT1) | ||
22 | .dword 1 | ||
23 | #elif defined(CONFIG_ETRAX_DEBUG_PORT2) | ||
24 | .dword 2 | ||
25 | #elif defined(CONFIG_ETRAX_DEBUG_PORT3) | ||
26 | .dword 3 | ||
27 | #else | ||
28 | .dword 4 ; No debug | ||
29 | #endif | ||
30 | |||
31 | ; Register values | ||
32 | .dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_cfg) | ||
33 | .dword CONFIG_ETRAX_DDR2_CONFIG | ||
34 | .dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_timing) | ||
35 | .dword CONFIG_ETRAX_DDR2_TIMING | ||
36 | .dword CONFIG_ETRAX_DDR2_MRS | ||
37 | |||
38 | .dword REG_ADDR(gio, regi_gio, rw_pa_dout) | ||
39 | .dword CONFIG_ETRAX_DEF_GIO_PA_OUT | ||
40 | .dword REG_ADDR(gio, regi_gio, rw_pa_oe) | ||
41 | .dword CONFIG_ETRAX_DEF_GIO_PA_OE | ||
42 | .dword REG_ADDR(gio, regi_gio, rw_pb_dout) | ||
43 | .dword CONFIG_ETRAX_DEF_GIO_PB_OUT | ||
44 | .dword REG_ADDR(gio, regi_gio, rw_pb_oe) | ||
45 | .dword CONFIG_ETRAX_DEF_GIO_PB_OE | ||
46 | .dword REG_ADDR(gio, regi_gio, rw_pc_dout) | ||
47 | .dword CONFIG_ETRAX_DEF_GIO_PC_OUT | ||
48 | .dword REG_ADDR(gio, regi_gio, rw_pc_oe) | ||
49 | .dword CONFIG_ETRAX_DEF_GIO_PC_OE | ||
50 | |||
51 | .dword 0 ; No more register values | ||
diff --git a/arch/cris/arch-v32/mach-a3/io.c b/arch/cris/arch-v32/mach-a3/io.c new file mode 100644 index 000000000000..9eeaf3eca474 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/io.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Helper functions for I/O pins. | ||
3 | * | ||
4 | * Copyright (c) 2005-2007 Axis Communications AB. | ||
5 | */ | ||
6 | |||
7 | #include <linux/types.h> | ||
8 | #include <linux/errno.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/ctype.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/arch/mach/pinmux.h> | ||
16 | #include <hwregs/gio_defs.h> | ||
17 | |||
18 | struct crisv32_ioport crisv32_ioports[] = { | ||
19 | { | ||
20 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe), | ||
21 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout), | ||
22 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din), | ||
23 | 32 | ||
24 | }, | ||
25 | { | ||
26 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe), | ||
27 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout), | ||
28 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din), | ||
29 | 32 | ||
30 | }, | ||
31 | { | ||
32 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe), | ||
33 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout), | ||
34 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din), | ||
35 | 16 | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | #define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport) | ||
40 | |||
41 | struct crisv32_iopin crisv32_led_net0_green; | ||
42 | struct crisv32_iopin crisv32_led_net0_red; | ||
43 | struct crisv32_iopin crisv32_led2_green; | ||
44 | struct crisv32_iopin crisv32_led2_red; | ||
45 | struct crisv32_iopin crisv32_led3_green; | ||
46 | struct crisv32_iopin crisv32_led3_red; | ||
47 | |||
48 | /* Dummy port used when green LED and red LED is on the same bit */ | ||
49 | static unsigned long io_dummy; | ||
50 | static struct crisv32_ioport dummy_port = { | ||
51 | &io_dummy, | ||
52 | &io_dummy, | ||
53 | &io_dummy, | ||
54 | 32 | ||
55 | }; | ||
56 | static struct crisv32_iopin dummy_led = { | ||
57 | &dummy_port, | ||
58 | 0 | ||
59 | }; | ||
60 | |||
61 | static int __init crisv32_io_init(void) | ||
62 | { | ||
63 | int ret = 0; | ||
64 | |||
65 | u32 i; | ||
66 | |||
67 | /* Locks *should* be dynamically initialized. */ | ||
68 | for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++) | ||
69 | spin_lock_init(&crisv32_ioports[i].lock); | ||
70 | spin_lock_init(&dummy_port.lock); | ||
71 | |||
72 | /* Initialize LEDs */ | ||
73 | #if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO)) | ||
74 | ret += crisv32_io_get_name(&crisv32_led_net0_green, | ||
75 | CONFIG_ETRAX_LED_G_NET0); | ||
76 | crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out); | ||
77 | if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) { | ||
78 | ret += crisv32_io_get_name(&crisv32_led_net0_red, | ||
79 | CONFIG_ETRAX_LED_R_NET0); | ||
80 | crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out); | ||
81 | } else | ||
82 | crisv32_led_net0_red = dummy_led; | ||
83 | #endif | ||
84 | |||
85 | ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G); | ||
86 | ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R); | ||
87 | ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G); | ||
88 | ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R); | ||
89 | |||
90 | crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out); | ||
91 | crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out); | ||
92 | crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out); | ||
93 | crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out); | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | __initcall(crisv32_io_init); | ||
99 | |||
100 | int crisv32_io_get(struct crisv32_iopin *iopin, | ||
101 | unsigned int port, unsigned int pin) | ||
102 | { | ||
103 | if (port > NBR_OF_PORTS) | ||
104 | return -EINVAL; | ||
105 | if (port > crisv32_ioports[port].pin_count) | ||
106 | return -EINVAL; | ||
107 | |||
108 | iopin->bit = 1 << pin; | ||
109 | iopin->port = &crisv32_ioports[port]; | ||
110 | |||
111 | if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) | ||
112 | return -EIO; | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name) | ||
118 | { | ||
119 | int port; | ||
120 | int pin; | ||
121 | |||
122 | if (toupper(*name) == 'P') | ||
123 | name++; | ||
124 | |||
125 | if (toupper(*name) < 'A' || toupper(*name) > 'E') | ||
126 | return -EINVAL; | ||
127 | |||
128 | port = toupper(*name) - 'A'; | ||
129 | name++; | ||
130 | pin = simple_strtoul(name, NULL, 10); | ||
131 | |||
132 | if (pin < 0 || pin > crisv32_ioports[port].pin_count) | ||
133 | return -EINVAL; | ||
134 | |||
135 | iopin->bit = 1 << pin; | ||
136 | iopin->port = &crisv32_ioports[port]; | ||
137 | |||
138 | if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) | ||
139 | return -EIO; | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | #ifdef CONFIG_PCI | ||
145 | /* PCI I/O access stuff */ | ||
146 | struct cris_io_operations *cris_iops = NULL; | ||
147 | EXPORT_SYMBOL(cris_iops); | ||
148 | #endif | ||
149 | |||
diff --git a/arch/cris/arch-v32/mach-a3/pinmux.c b/arch/cris/arch-v32/mach-a3/pinmux.c new file mode 100644 index 000000000000..0a28c9bedfb7 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/pinmux.c | |||
@@ -0,0 +1,386 @@ | |||
1 | /* | ||
2 | * Allocator for I/O pins. All pins are allocated to GPIO at bootup. | ||
3 | * Unassigned pins and GPIO pins can be allocated to a fixed interface | ||
4 | * or the I/O processor instead. | ||
5 | * | ||
6 | * Copyright (c) 2005-2007 Axis Communications AB. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <hwregs/reg_map.h> | ||
15 | #include <hwregs/reg_rdwr.h> | ||
16 | #include <pinmux.h> | ||
17 | #include <hwregs/pinmux_defs.h> | ||
18 | #include <hwregs/clkgen_defs.h> | ||
19 | |||
20 | #undef DEBUG | ||
21 | |||
22 | #define PINS 80 | ||
23 | #define PORT_PINS 32 | ||
24 | #define PORTS 3 | ||
25 | |||
26 | static char pins[PINS]; | ||
27 | static DEFINE_SPINLOCK(pinmux_lock); | ||
28 | |||
29 | static void crisv32_pinmux_set(int port); | ||
30 | |||
31 | int | ||
32 | crisv32_pinmux_init(void) | ||
33 | { | ||
34 | static int initialized; | ||
35 | |||
36 | if (!initialized) { | ||
37 | initialized = 1; | ||
38 | REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0); | ||
39 | crisv32_pinmux_alloc(PORT_A, 0, 31, pinmux_gpio); | ||
40 | crisv32_pinmux_alloc(PORT_B, 0, 31, pinmux_gpio); | ||
41 | crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_gpio); | ||
42 | } | ||
43 | |||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | int | ||
48 | crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode) | ||
49 | { | ||
50 | int i; | ||
51 | unsigned long flags; | ||
52 | |||
53 | crisv32_pinmux_init(); | ||
54 | |||
55 | if (port >= PORTS) | ||
56 | return -EINVAL; | ||
57 | |||
58 | spin_lock_irqsave(&pinmux_lock, flags); | ||
59 | |||
60 | for (i = first_pin; i <= last_pin; i++) { | ||
61 | if ((pins[port * PORT_PINS + i] != pinmux_none) && | ||
62 | (pins[port * PORT_PINS + i] != pinmux_gpio) && | ||
63 | (pins[port * PORT_PINS + i] != mode)) { | ||
64 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
65 | #ifdef DEBUG | ||
66 | panic("Pinmux alloc failed!\n"); | ||
67 | #endif | ||
68 | return -EPERM; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | for (i = first_pin; i <= last_pin; i++) | ||
73 | pins[port * PORT_PINS + i] = mode; | ||
74 | |||
75 | crisv32_pinmux_set(port); | ||
76 | |||
77 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | int | ||
83 | crisv32_pinmux_alloc_fixed(enum fixed_function function) | ||
84 | { | ||
85 | int ret = -EINVAL; | ||
86 | char saved[sizeof pins]; | ||
87 | unsigned long flags; | ||
88 | |||
89 | spin_lock_irqsave(&pinmux_lock, flags); | ||
90 | |||
91 | /* Save internal data for recovery */ | ||
92 | memcpy(saved, pins, sizeof pins); | ||
93 | |||
94 | crisv32_pinmux_init(); /* must be done before we read rw_hwprot */ | ||
95 | |||
96 | reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); | ||
97 | reg_clkgen_rw_clk_ctrl clk_ctrl = REG_RD(clkgen, regi_clkgen, | ||
98 | rw_clk_ctrl); | ||
99 | |||
100 | switch (function) { | ||
101 | case pinmux_eth: | ||
102 | clk_ctrl.eth = regk_clkgen_yes; | ||
103 | clk_ctrl.dma0_1_eth = regk_clkgen_yes; | ||
104 | ret = crisv32_pinmux_alloc(PORT_B, 8, 23, pinmux_fixed); | ||
105 | ret |= crisv32_pinmux_alloc(PORT_B, 24, 25, pinmux_fixed); | ||
106 | hwprot.eth = hwprot.eth_mdio = regk_pinmux_yes; | ||
107 | break; | ||
108 | case pinmux_geth: | ||
109 | ret = crisv32_pinmux_alloc(PORT_B, 0, 7, pinmux_fixed); | ||
110 | hwprot.geth = regk_pinmux_yes; | ||
111 | break; | ||
112 | case pinmux_tg_cmos: | ||
113 | clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes; | ||
114 | ret = crisv32_pinmux_alloc(PORT_B, 27, 29, pinmux_fixed); | ||
115 | hwprot.tg_clk = regk_pinmux_yes; | ||
116 | break; | ||
117 | case pinmux_tg_ccd: | ||
118 | clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes; | ||
119 | ret = crisv32_pinmux_alloc(PORT_B, 27, 31, pinmux_fixed); | ||
120 | ret |= crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_fixed); | ||
121 | hwprot.tg = hwprot.tg_clk = regk_pinmux_yes; | ||
122 | break; | ||
123 | case pinmux_vout: | ||
124 | clk_ctrl.strdma0_2_video = regk_clkgen_yes; | ||
125 | ret = crisv32_pinmux_alloc(PORT_A, 8, 18, pinmux_fixed); | ||
126 | hwprot.vout = hwprot.vout_sync = regk_pinmux_yes; | ||
127 | break; | ||
128 | case pinmux_ser1: | ||
129 | clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; | ||
130 | ret = crisv32_pinmux_alloc(PORT_A, 24, 25, pinmux_fixed); | ||
131 | hwprot.ser1 = regk_pinmux_yes; | ||
132 | break; | ||
133 | case pinmux_ser2: | ||
134 | clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; | ||
135 | ret = crisv32_pinmux_alloc(PORT_A, 26, 27, pinmux_fixed); | ||
136 | hwprot.ser2 = regk_pinmux_yes; | ||
137 | break; | ||
138 | case pinmux_ser3: | ||
139 | clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; | ||
140 | ret = crisv32_pinmux_alloc(PORT_A, 28, 29, pinmux_fixed); | ||
141 | hwprot.ser3 = regk_pinmux_yes; | ||
142 | break; | ||
143 | case pinmux_ser4: | ||
144 | clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; | ||
145 | ret = crisv32_pinmux_alloc(PORT_A, 30, 31, pinmux_fixed); | ||
146 | hwprot.ser4 = regk_pinmux_yes; | ||
147 | break; | ||
148 | case pinmux_sser: | ||
149 | clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; | ||
150 | ret = crisv32_pinmux_alloc(PORT_A, 19, 23, pinmux_fixed); | ||
151 | hwprot.sser = regk_pinmux_yes; | ||
152 | break; | ||
153 | case pinmux_pio: | ||
154 | hwprot.pio = regk_pinmux_yes; | ||
155 | ret = 0; | ||
156 | break; | ||
157 | case pinmux_pwm0: | ||
158 | ret = crisv32_pinmux_alloc(PORT_A, 30, 30, pinmux_fixed); | ||
159 | hwprot.pwm0 = regk_pinmux_yes; | ||
160 | break; | ||
161 | case pinmux_pwm1: | ||
162 | ret = crisv32_pinmux_alloc(PORT_A, 31, 31, pinmux_fixed); | ||
163 | hwprot.pwm1 = regk_pinmux_yes; | ||
164 | break; | ||
165 | case pinmux_pwm2: | ||
166 | ret = crisv32_pinmux_alloc(PORT_B, 26, 26, pinmux_fixed); | ||
167 | hwprot.pwm2 = regk_pinmux_yes; | ||
168 | break; | ||
169 | case pinmux_i2c0: | ||
170 | ret = crisv32_pinmux_alloc(PORT_A, 0, 1, pinmux_fixed); | ||
171 | hwprot.i2c0 = regk_pinmux_yes; | ||
172 | break; | ||
173 | case pinmux_i2c1: | ||
174 | ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); | ||
175 | hwprot.i2c1 = regk_pinmux_yes; | ||
176 | break; | ||
177 | case pinmux_i2c1_3wire: | ||
178 | ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); | ||
179 | ret |= crisv32_pinmux_alloc(PORT_A, 7, 7, pinmux_fixed); | ||
180 | hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_yes; | ||
181 | break; | ||
182 | case pinmux_i2c1_sda1: | ||
183 | ret = crisv32_pinmux_alloc(PORT_A, 2, 4, pinmux_fixed); | ||
184 | hwprot.i2c1 = hwprot.i2c1_sda1 = regk_pinmux_yes; | ||
185 | break; | ||
186 | case pinmux_i2c1_sda2: | ||
187 | ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); | ||
188 | ret |= crisv32_pinmux_alloc(PORT_A, 5, 5, pinmux_fixed); | ||
189 | hwprot.i2c1 = hwprot.i2c1_sda2 = regk_pinmux_yes; | ||
190 | break; | ||
191 | case pinmux_i2c1_sda3: | ||
192 | ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); | ||
193 | ret |= crisv32_pinmux_alloc(PORT_A, 6, 6, pinmux_fixed); | ||
194 | hwprot.i2c1 = hwprot.i2c1_sda3 = regk_pinmux_yes; | ||
195 | break; | ||
196 | default: | ||
197 | ret = -EINVAL; | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | if (!ret) { | ||
202 | REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); | ||
203 | REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); | ||
204 | } else | ||
205 | memcpy(pins, saved, sizeof pins); | ||
206 | |||
207 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
208 | |||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | void | ||
213 | crisv32_pinmux_set(int port) | ||
214 | { | ||
215 | int i; | ||
216 | int gpio_val = 0; | ||
217 | int iop_val = 0; | ||
218 | int pin = port * PORT_PINS; | ||
219 | |||
220 | for (i = 0; (i < PORT_PINS) && (pin < PINS); i++, pin++) { | ||
221 | if (pins[pin] == pinmux_gpio) | ||
222 | gpio_val |= (1 << i); | ||
223 | else if (pins[pin] == pinmux_iop) | ||
224 | iop_val |= (1 << i); | ||
225 | } | ||
226 | |||
227 | REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_gio_pa + 4 * port, | ||
228 | gpio_val); | ||
229 | REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_iop_pa + 4 * port, | ||
230 | iop_val); | ||
231 | |||
232 | #ifdef DEBUG | ||
233 | crisv32_pinmux_dump(); | ||
234 | #endif | ||
235 | } | ||
236 | |||
237 | int | ||
238 | crisv32_pinmux_dealloc(int port, int first_pin, int last_pin) | ||
239 | { | ||
240 | int i; | ||
241 | unsigned long flags; | ||
242 | |||
243 | crisv32_pinmux_init(); | ||
244 | |||
245 | if (port > PORTS) | ||
246 | return -EINVAL; | ||
247 | |||
248 | spin_lock_irqsave(&pinmux_lock, flags); | ||
249 | |||
250 | for (i = first_pin; i <= last_pin; i++) | ||
251 | pins[port * PORT_PINS + i] = pinmux_none; | ||
252 | |||
253 | crisv32_pinmux_set(port); | ||
254 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | int | ||
260 | crisv32_pinmux_dealloc_fixed(enum fixed_function function) | ||
261 | { | ||
262 | int ret = -EINVAL; | ||
263 | char saved[sizeof pins]; | ||
264 | unsigned long flags; | ||
265 | |||
266 | spin_lock_irqsave(&pinmux_lock, flags); | ||
267 | |||
268 | /* Save internal data for recovery */ | ||
269 | memcpy(saved, pins, sizeof pins); | ||
270 | |||
271 | crisv32_pinmux_init(); /* must be done before we read rw_hwprot */ | ||
272 | |||
273 | reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); | ||
274 | |||
275 | switch (function) { | ||
276 | case pinmux_eth: | ||
277 | ret = crisv32_pinmux_dealloc(PORT_B, 8, 23); | ||
278 | ret |= crisv32_pinmux_dealloc(PORT_B, 24, 25); | ||
279 | ret |= crisv32_pinmux_dealloc(PORT_B, 0, 7); | ||
280 | hwprot.eth = hwprot.eth_mdio = hwprot.geth = regk_pinmux_no; | ||
281 | break; | ||
282 | case pinmux_tg_cmos: | ||
283 | ret = crisv32_pinmux_dealloc(PORT_B, 27, 29); | ||
284 | hwprot.tg_clk = regk_pinmux_no; | ||
285 | break; | ||
286 | case pinmux_tg_ccd: | ||
287 | ret = crisv32_pinmux_dealloc(PORT_B, 27, 31); | ||
288 | ret |= crisv32_pinmux_dealloc(PORT_C, 0, 15); | ||
289 | hwprot.tg = hwprot.tg_clk = regk_pinmux_no; | ||
290 | break; | ||
291 | case pinmux_vout: | ||
292 | ret = crisv32_pinmux_dealloc(PORT_A, 8, 18); | ||
293 | hwprot.vout = hwprot.vout_sync = regk_pinmux_no; | ||
294 | break; | ||
295 | case pinmux_ser1: | ||
296 | ret = crisv32_pinmux_dealloc(PORT_A, 24, 25); | ||
297 | hwprot.ser1 = regk_pinmux_no; | ||
298 | break; | ||
299 | case pinmux_ser2: | ||
300 | ret = crisv32_pinmux_dealloc(PORT_A, 26, 27); | ||
301 | hwprot.ser2 = regk_pinmux_no; | ||
302 | break; | ||
303 | case pinmux_ser3: | ||
304 | ret = crisv32_pinmux_dealloc(PORT_A, 28, 29); | ||
305 | hwprot.ser3 = regk_pinmux_no; | ||
306 | break; | ||
307 | case pinmux_ser4: | ||
308 | ret = crisv32_pinmux_dealloc(PORT_A, 30, 31); | ||
309 | hwprot.ser4 = regk_pinmux_no; | ||
310 | break; | ||
311 | case pinmux_sser: | ||
312 | ret = crisv32_pinmux_dealloc(PORT_A, 19, 23); | ||
313 | hwprot.sser = regk_pinmux_no; | ||
314 | break; | ||
315 | case pinmux_pwm0: | ||
316 | ret = crisv32_pinmux_dealloc(PORT_A, 30, 30); | ||
317 | hwprot.pwm0 = regk_pinmux_no; | ||
318 | break; | ||
319 | case pinmux_pwm1: | ||
320 | ret = crisv32_pinmux_dealloc(PORT_A, 31, 31); | ||
321 | hwprot.pwm1 = regk_pinmux_no; | ||
322 | break; | ||
323 | case pinmux_pwm2: | ||
324 | ret = crisv32_pinmux_dealloc(PORT_B, 26, 26); | ||
325 | hwprot.pwm2 = regk_pinmux_no; | ||
326 | break; | ||
327 | case pinmux_i2c0: | ||
328 | ret = crisv32_pinmux_dealloc(PORT_A, 0, 1); | ||
329 | hwprot.i2c0 = regk_pinmux_no; | ||
330 | break; | ||
331 | case pinmux_i2c1: | ||
332 | ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); | ||
333 | hwprot.i2c1 = regk_pinmux_no; | ||
334 | break; | ||
335 | case pinmux_i2c1_3wire: | ||
336 | ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); | ||
337 | ret |= crisv32_pinmux_dealloc(PORT_A, 7, 7); | ||
338 | hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_no; | ||
339 | break; | ||
340 | case pinmux_i2c1_sda1: | ||
341 | ret = crisv32_pinmux_dealloc(PORT_A, 2, 4); | ||
342 | hwprot.i2c1_sda1 = regk_pinmux_no; | ||
343 | break; | ||
344 | case pinmux_i2c1_sda2: | ||
345 | ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); | ||
346 | ret |= crisv32_pinmux_dealloc(PORT_A, 5, 5); | ||
347 | hwprot.i2c1_sda2 = regk_pinmux_no; | ||
348 | break; | ||
349 | case pinmux_i2c1_sda3: | ||
350 | ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); | ||
351 | ret |= crisv32_pinmux_dealloc(PORT_A, 6, 6); | ||
352 | hwprot.i2c1_sda3 = regk_pinmux_no; | ||
353 | break; | ||
354 | default: | ||
355 | ret = -EINVAL; | ||
356 | break; | ||
357 | } | ||
358 | |||
359 | if (!ret) | ||
360 | REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); | ||
361 | else | ||
362 | memcpy(pins, saved, sizeof pins); | ||
363 | |||
364 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
365 | |||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | void | ||
370 | crisv32_pinmux_dump(void) | ||
371 | { | ||
372 | int i, j; | ||
373 | int pin = 0; | ||
374 | |||
375 | crisv32_pinmux_init(); | ||
376 | |||
377 | for (i = 0; i < PORTS; i++) { | ||
378 | pin++; | ||
379 | printk(KERN_DEBUG "Port %c\n", 'A'+i); | ||
380 | for (j = 0; (j < PORT_PINS) && (pin < PINS); j++, pin++) | ||
381 | printk(KERN_DEBUG | ||
382 | " Pin %d = %d\n", j, pins[i * PORT_PINS + j]); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | __initcall(crisv32_pinmux_init); | ||
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.c b/arch/cris/arch-v32/mach-a3/vcs_hook.c new file mode 100644 index 000000000000..58b1a5469fd7 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/vcs_hook.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * Simulator hook mechanism | ||
3 | */ | ||
4 | |||
5 | #include "vcs_hook.h" | ||
6 | #include <asm/io.h> | ||
7 | #include <stdarg.h> | ||
8 | |||
9 | #define HOOK_TRIG_ADDR 0xb7000000 | ||
10 | #define HOOK_MEM_BASE_ADDR 0xce000000 | ||
11 | |||
12 | static volatile unsigned *hook_base; | ||
13 | |||
14 | #define HOOK_DATA(offset) hook_base[offset] | ||
15 | #define VHOOK_DATA(offset) hook_base[offset] | ||
16 | #define HOOK_TRIG(funcid) \ | ||
17 | do { \ | ||
18 | *((unsigned *) HOOK_TRIG_ADDR) = funcid; \ | ||
19 | } while (0) | ||
20 | #define HOOK_DATA_BYTE(offset) ((unsigned char *)hook_base)[offset] | ||
21 | |||
22 | static void hook_init(void) | ||
23 | { | ||
24 | static int first = 1; | ||
25 | if (first) { | ||
26 | first = 0; | ||
27 | hook_base = ioremap(HOOK_MEM_BASE_ADDR, 8192); | ||
28 | } | ||
29 | } | ||
30 | |||
31 | static unsigned hook_trig(unsigned id) | ||
32 | { | ||
33 | unsigned ret; | ||
34 | |||
35 | /* preempt_disable(); */ | ||
36 | |||
37 | /* Dummy read from mem to make sure data has propagated to memory | ||
38 | * before trigging */ | ||
39 | ret = *hook_base; | ||
40 | |||
41 | /* trigger hook */ | ||
42 | HOOK_TRIG(id); | ||
43 | |||
44 | /* wait for call to finish */ | ||
45 | while (VHOOK_DATA(0) > 0) ; | ||
46 | |||
47 | /* extract return value */ | ||
48 | |||
49 | ret = VHOOK_DATA(1); | ||
50 | |||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | int hook_call(unsigned id, unsigned pcnt, ...) | ||
55 | { | ||
56 | va_list ap; | ||
57 | int i; | ||
58 | unsigned ret; | ||
59 | |||
60 | hook_init(); | ||
61 | |||
62 | HOOK_DATA(0) = id; | ||
63 | |||
64 | va_start(ap, pcnt); | ||
65 | for (i = 1; i <= pcnt; i++) | ||
66 | HOOK_DATA(i) = va_arg(ap, unsigned); | ||
67 | va_end(ap); | ||
68 | |||
69 | ret = hook_trig(id); | ||
70 | |||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | int hook_call_str(unsigned id, unsigned size, const char *str) | ||
75 | { | ||
76 | int i; | ||
77 | unsigned ret; | ||
78 | |||
79 | hook_init(); | ||
80 | |||
81 | HOOK_DATA(0) = id; | ||
82 | HOOK_DATA(1) = size; | ||
83 | |||
84 | for (i = 0; i < size; i++) | ||
85 | HOOK_DATA_BYTE(8 + i) = str[i]; | ||
86 | HOOK_DATA_BYTE(8 + i) = 0; | ||
87 | |||
88 | ret = hook_trig(id); | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | void print_str(const char *str) | ||
94 | { | ||
95 | int i; | ||
96 | /* find null at end of string */ | ||
97 | for (i = 1; str[i]; i++) ; | ||
98 | hook_call(hook_print_str, i, str); | ||
99 | } | ||
100 | |||
101 | void CPU_WATCHDOG_TIMEOUT(unsigned t) | ||
102 | { | ||
103 | } | ||
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.h b/arch/cris/arch-v32/mach-a3/vcs_hook.h new file mode 100644 index 000000000000..8b73d0e8392d --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/vcs_hook.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Simulator hook call mechanism | ||
3 | */ | ||
4 | |||
5 | #ifndef __hook_h__ | ||
6 | #define __hook_h__ | ||
7 | |||
8 | int hook_call(unsigned id, unsigned pcnt, ...); | ||
9 | int hook_call_str(unsigned id, unsigned size, const char *str); | ||
10 | |||
11 | enum hook_ids { | ||
12 | hook_debug_on = 1, | ||
13 | hook_debug_off, | ||
14 | hook_stop_sim_ok, | ||
15 | hook_stop_sim_fail, | ||
16 | hook_alloc_shared, | ||
17 | hook_ptr_shared, | ||
18 | hook_free_shared, | ||
19 | hook_file2shared, | ||
20 | hook_cmp_shared, | ||
21 | hook_print_params, | ||
22 | hook_sim_time, | ||
23 | hook_stop_sim, | ||
24 | hook_kick_dog, | ||
25 | hook_dog_timeout, | ||
26 | hook_rand, | ||
27 | hook_srand, | ||
28 | hook_rand_range, | ||
29 | hook_print_str, | ||
30 | hook_print_hex, | ||
31 | hook_cmp_offset_shared, | ||
32 | hook_fill_random_shared, | ||
33 | hook_alloc_random_data, | ||
34 | hook_calloc_random_data, | ||
35 | hook_print_int, | ||
36 | hook_print_uint, | ||
37 | hook_fputc, | ||
38 | hook_init_fd, | ||
39 | hook_sbrk, | ||
40 | hook_print_context_descr, | ||
41 | hook_print_data_descr, | ||
42 | hook_print_group_descr, | ||
43 | hook_fill_shared, | ||
44 | hook_sl_srand, | ||
45 | hook_sl_rand_irange, | ||
46 | hook_sl_rand_urange, | ||
47 | hook_sl_sh_malloc_aligned, | ||
48 | hook_sl_sh_calloc_aligned, | ||
49 | hook_sl_sh_alloc_random_data, | ||
50 | hook_sl_sh_file2mem, | ||
51 | hook_sl_vera_mbox_handle, | ||
52 | hook_sl_vera_mbox_put, | ||
53 | hook_sl_vera_mbox_get, | ||
54 | hook_sl_system, | ||
55 | hook_sl_sh_hexdump | ||
56 | }; | ||
57 | |||
58 | #endif | ||
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig new file mode 100644 index 000000000000..f6d74475f1c6 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/Kconfig | |||
@@ -0,0 +1,216 @@ | |||
1 | if ETRAXFS | ||
2 | |||
3 | menu "ETRAX FS options" | ||
4 | depends on ETRAXFS | ||
5 | |||
6 | config ETRAX_DRAM_VIRTUAL_BASE | ||
7 | hex | ||
8 | depends on ETRAX_ARCH_V32 | ||
9 | default "c0000000" | ||
10 | |||
11 | config ETRAX_SERIAL_PORTS | ||
12 | int | ||
13 | default 4 | ||
14 | |||
15 | config ETRAX_MEM_GRP1_CONFIG | ||
16 | hex "MEM_GRP1_CONFIG" | ||
17 | depends on ETRAX_ARCH_V32 | ||
18 | default "4044a" | ||
19 | help | ||
20 | Waitstates for flash. The default value is suitable for the | ||
21 | standard flashes used in axis products (120 ns). | ||
22 | |||
23 | config ETRAX_MEM_GRP2_CONFIG | ||
24 | hex "MEM_GRP2_CONFIG" | ||
25 | depends on ETRAX_ARCH_V32 | ||
26 | default "0" | ||
27 | help | ||
28 | Waitstates for SRAM. 0 is a good choice for most Axis products. | ||
29 | |||
30 | config ETRAX_MEM_GRP3_CONFIG | ||
31 | hex "MEM_GRP3_CONFIG" | ||
32 | depends on ETRAX_ARCH_V32 | ||
33 | default "0" | ||
34 | help | ||
35 | Waitstates for CSP0-3. 0 is a good choice for most Axis products. | ||
36 | It may need to be changed if external devices such as extra | ||
37 | register-mapped LEDs are used. | ||
38 | |||
39 | config ETRAX_MEM_GRP4_CONFIG | ||
40 | hex "MEM_GRP4_CONFIG" | ||
41 | depends on ETRAX_ARCH_V32 | ||
42 | default "0" | ||
43 | help | ||
44 | Waitstates for CSP4-6. 0 is a good choice for most Axis products. | ||
45 | |||
46 | config ETRAX_SDRAM_GRP0_CONFIG | ||
47 | hex "SDRAM_GRP0_CONFIG" | ||
48 | depends on ETRAX_ARCH_V32 | ||
49 | default "336" | ||
50 | help | ||
51 | SDRAM configuration for group 0. The value depends on the | ||
52 | hardware configuration. The default value is suitable | ||
53 | for 32 MB organized as two 16 bits chips (e.g. Axis | ||
54 | part number 18550) connected as one 32 bit device (i.e. in | ||
55 | the same group). | ||
56 | |||
57 | config ETRAX_SDRAM_GRP1_CONFIG | ||
58 | hex "SDRAM_GRP1_CONFIG" | ||
59 | depends on ETRAX_ARCH_V32 | ||
60 | default "0" | ||
61 | help | ||
62 | SDRAM configuration for group 1. The defult value is 0 | ||
63 | because group 1 is not used in the default configuration, | ||
64 | described in the help for SDRAM_GRP0_CONFIG. | ||
65 | |||
66 | config ETRAX_SDRAM_TIMING | ||
67 | hex "SDRAM_TIMING" | ||
68 | depends on ETRAX_ARCH_V32 | ||
69 | default "104a" | ||
70 | help | ||
71 | SDRAM timing parameters. The default value is ok for | ||
72 | most hardwares but large SDRAMs may require a faster | ||
73 | refresh (a.k.a 8K refresh). The default value implies | ||
74 | 100MHz clock and SDR mode. | ||
75 | |||
76 | config ETRAX_SDRAM_COMMAND | ||
77 | hex "SDRAM_COMMAND" | ||
78 | depends on ETRAX_ARCH_V32 | ||
79 | default "0" | ||
80 | help | ||
81 | SDRAM command. Should be 0 unless you really know what | ||
82 | you are doing (may be != 0 for unusual address line | ||
83 | mappings such as in a MCM).. | ||
84 | |||
85 | config ETRAX_DEF_GIO_PA_OE | ||
86 | hex "GIO_PA_OE" | ||
87 | depends on ETRAX_ARCH_V32 | ||
88 | default "1c" | ||
89 | help | ||
90 | Configures the direction of general port A bits. 1 is out, 0 is in. | ||
91 | This is often totally different depending on the product used. | ||
92 | There are some guidelines though - if you know that only LED's are | ||
93 | connected to port PA, then they are usually connected to bits 2-4 | ||
94 | and you can therefore use 1c. On other boards which don't have the | ||
95 | LED's at the general ports, these bits are used for all kinds of | ||
96 | stuff. If you don't know what to use, it is always safe to put all | ||
97 | as inputs, although floating inputs isn't good. | ||
98 | |||
99 | config ETRAX_DEF_GIO_PA_OUT | ||
100 | hex "GIO_PA_OUT" | ||
101 | depends on ETRAX_ARCH_V32 | ||
102 | default "00" | ||
103 | help | ||
104 | Configures the initial data for the general port A bits. Most | ||
105 | products should use 00 here. | ||
106 | |||
107 | config ETRAX_DEF_GIO_PB_OE | ||
108 | hex "GIO_PB_OE" | ||
109 | depends on ETRAX_ARCH_V32 | ||
110 | default "00000" | ||
111 | help | ||
112 | Configures the direction of general port B bits. 1 is out, 0 is in. | ||
113 | This is often totally different depending on the product used. | ||
114 | There are some guidelines though - if you know that only LED's are | ||
115 | connected to port PA, then they are usually connected to bits 2-4 | ||
116 | and you can therefore use 1c. On other boards which don't have the | ||
117 | LED's at the general ports, these bits are used for all kinds of | ||
118 | stuff. If you don't know what to use, it is always safe to put all | ||
119 | as inputs, although floating inputs isn't good. | ||
120 | |||
121 | config ETRAX_DEF_GIO_PB_OUT | ||
122 | hex "GIO_PB_OUT" | ||
123 | depends on ETRAX_ARCH_V32 | ||
124 | default "00000" | ||
125 | help | ||
126 | Configures the initial data for the general port B bits. Most | ||
127 | products should use 00000 here. | ||
128 | |||
129 | config ETRAX_DEF_GIO_PC_OE | ||
130 | hex "GIO_PC_OE" | ||
131 | depends on ETRAX_ARCH_V32 | ||
132 | default "00000" | ||
133 | help | ||
134 | Configures the direction of general port C bits. 1 is out, 0 is in. | ||
135 | This is often totally different depending on the product used. | ||
136 | There are some guidelines though - if you know that only LED's are | ||
137 | connected to port PA, then they are usually connected to bits 2-4 | ||
138 | and you can therefore use 1c. On other boards which don't have the | ||
139 | LED's at the general ports, these bits are used for all kinds of | ||
140 | stuff. If you don't know what to use, it is always safe to put all | ||
141 | as inputs, although floating inputs isn't good. | ||
142 | |||
143 | config ETRAX_DEF_GIO_PC_OUT | ||
144 | hex "GIO_PC_OUT" | ||
145 | depends on ETRAX_ARCH_V32 | ||
146 | default "00000" | ||
147 | help | ||
148 | Configures the initial data for the general port C bits. Most | ||
149 | products should use 00000 here. | ||
150 | |||
151 | config ETRAX_DEF_GIO_PD_OE | ||
152 | hex "GIO_PD_OE" | ||
153 | depends on ETRAX_ARCH_V32 | ||
154 | default "00000" | ||
155 | help | ||
156 | Configures the direction of general port D bits. 1 is out, 0 is in. | ||
157 | This is often totally different depending on the product used. | ||
158 | There are some guidelines though - if you know that only LED's are | ||
159 | connected to port PA, then they are usually connected to bits 2-4 | ||
160 | and you can therefore use 1c. On other boards which don't have the | ||
161 | LED's at the general ports, these bits are used for all kinds of | ||
162 | stuff. If you don't know what to use, it is always safe to put all | ||
163 | as inputs, although floating inputs isn't good. | ||
164 | |||
165 | config ETRAX_DEF_GIO_PD_OUT | ||
166 | hex "GIO_PD_OUT" | ||
167 | depends on ETRAX_ARCH_V32 | ||
168 | default "00000" | ||
169 | help | ||
170 | Configures the initial data for the general port D bits. Most | ||
171 | products should use 00000 here. | ||
172 | |||
173 | config ETRAX_DEF_GIO_PE_OE | ||
174 | hex "GIO_PE_OE" | ||
175 | depends on ETRAX_ARCH_V32 | ||
176 | default "00000" | ||
177 | help | ||
178 | Configures the direction of general port E bits. 1 is out, 0 is in. | ||
179 | This is often totally different depending on the product used. | ||
180 | There are some guidelines though - if you know that only LED's are | ||
181 | connected to port PA, then they are usually connected to bits 2-4 | ||
182 | and you can therefore use 1c. On other boards which don't have the | ||
183 | LED's at the general ports, these bits are used for all kinds of | ||
184 | stuff. If you don't know what to use, it is always safe to put all | ||
185 | as inputs, although floating inputs isn't good. | ||
186 | |||
187 | config ETRAX_DEF_GIO_PE_OUT | ||
188 | hex "GIO_PE_OUT" | ||
189 | depends on ETRAX_ARCH_V32 | ||
190 | default "00000" | ||
191 | help | ||
192 | Configures the initial data for the general port E bits. Most | ||
193 | products should use 00000 here. | ||
194 | |||
195 | config ETRAX_DEF_GIO_PV_OE | ||
196 | hex "GIO_PV_OE" | ||
197 | depends on ETRAX_VIRTUAL_GPIO | ||
198 | default "0000" | ||
199 | help | ||
200 | Configures the direction of virtual general port V bits. 1 is out, | ||
201 | 0 is in. This is often totally different depending on the product | ||
202 | used. These bits are used for all kinds of stuff. If you don't know | ||
203 | what to use, it is always safe to put all as inputs, although | ||
204 | floating inputs isn't good. | ||
205 | |||
206 | config ETRAX_DEF_GIO_PV_OUT | ||
207 | hex "GIO_PV_OUT" | ||
208 | depends on ETRAX_VIRTUAL_GPIO | ||
209 | default "0000" | ||
210 | help | ||
211 | Configures the initial data for the virtual general port V bits. | ||
212 | Most products should use 0000 here. | ||
213 | |||
214 | endmenu | ||
215 | |||
216 | endif | ||
diff --git a/arch/cris/arch-v32/mach-fs/Makefile b/arch/cris/arch-v32/mach-fs/Makefile new file mode 100644 index 000000000000..4ff407a1b931 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $ | ||
2 | # | ||
3 | # Makefile for the linux kernel. | ||
4 | # | ||
5 | |||
6 | obj-y := dma.o pinmux.o io.o arbiter.o | ||
7 | bj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o | ||
8 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | ||
9 | |||
10 | clean: | ||
11 | |||
diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c new file mode 100644 index 000000000000..84d31bd7b692 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/arbiter.c | |||
@@ -0,0 +1,404 @@ | |||
1 | /* | ||
2 | * Memory arbiter functions. Allocates bandwidth through the | ||
3 | * arbiter and sets up arbiter breakpoints. | ||
4 | * | ||
5 | * The algorithm first assigns slots to the clients that has specified | ||
6 | * bandwidth (e.g. ethernet) and then the remaining slots are divided | ||
7 | * on all the active clients. | ||
8 | * | ||
9 | * Copyright (c) 2004-2007 Axis Communications AB. | ||
10 | */ | ||
11 | |||
12 | #include <hwregs/reg_map.h> | ||
13 | #include <hwregs/reg_rdwr.h> | ||
14 | #include <hwregs/marb_defs.h> | ||
15 | #include <arbiter.h> | ||
16 | #include <hwregs/intr_vect.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/signal.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/irq_regs.h> | ||
23 | |||
24 | struct crisv32_watch_entry { | ||
25 | unsigned long instance; | ||
26 | watch_callback *cb; | ||
27 | unsigned long start; | ||
28 | unsigned long end; | ||
29 | int used; | ||
30 | }; | ||
31 | |||
32 | #define NUMBER_OF_BP 4 | ||
33 | #define NBR_OF_CLIENTS 14 | ||
34 | #define NBR_OF_SLOTS 64 | ||
35 | #define SDRAM_BANDWIDTH 100000000 /* Some kind of expected value */ | ||
36 | #define INTMEM_BANDWIDTH 400000000 | ||
37 | #define NBR_OF_REGIONS 2 | ||
38 | |||
39 | static struct crisv32_watch_entry watches[NUMBER_OF_BP] = { | ||
40 | {regi_marb_bp0}, | ||
41 | {regi_marb_bp1}, | ||
42 | {regi_marb_bp2}, | ||
43 | {regi_marb_bp3} | ||
44 | }; | ||
45 | |||
46 | static u8 requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS]; | ||
47 | static u8 active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS]; | ||
48 | static int max_bandwidth[NBR_OF_REGIONS] = | ||
49 | { SDRAM_BANDWIDTH, INTMEM_BANDWIDTH }; | ||
50 | |||
51 | DEFINE_SPINLOCK(arbiter_lock); | ||
52 | |||
53 | static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id); | ||
54 | |||
55 | /* | ||
56 | * "I'm the arbiter, I know the score. | ||
57 | * From square one I'll be watching all 64." | ||
58 | * (memory arbiter slots, that is) | ||
59 | * | ||
60 | * Or in other words: | ||
61 | * Program the memory arbiter slots for "region" according to what's | ||
62 | * in requested_slots[] and active_clients[], while minimizing | ||
63 | * latency. A caller may pass a non-zero positive amount for | ||
64 | * "unused_slots", which must then be the unallocated, remaining | ||
65 | * number of slots, free to hand out to any client. | ||
66 | */ | ||
67 | |||
68 | static void crisv32_arbiter_config(int region, int unused_slots) | ||
69 | { | ||
70 | int slot; | ||
71 | int client; | ||
72 | int interval = 0; | ||
73 | |||
74 | /* | ||
75 | * This vector corresponds to the hardware arbiter slots (see | ||
76 | * the hardware documentation for semantics). We initialize | ||
77 | * each slot with a suitable sentinel value outside the valid | ||
78 | * range {0 .. NBR_OF_CLIENTS - 1} and replace them with | ||
79 | * client indexes. Then it's fed to the hardware. | ||
80 | */ | ||
81 | s8 val[NBR_OF_SLOTS]; | ||
82 | |||
83 | for (slot = 0; slot < NBR_OF_SLOTS; slot++) | ||
84 | val[slot] = -1; | ||
85 | |||
86 | for (client = 0; client < NBR_OF_CLIENTS; client++) { | ||
87 | int pos; | ||
88 | /* Allocate the requested non-zero number of slots, but | ||
89 | * also give clients with zero-requests one slot each | ||
90 | * while stocks last. We do the latter here, in client | ||
91 | * order. This makes sure zero-request clients are the | ||
92 | * first to get to any spare slots, else those slots | ||
93 | * could, when bandwidth is allocated close to the limit, | ||
94 | * all be allocated to low-index non-zero-request clients | ||
95 | * in the default-fill loop below. Another positive but | ||
96 | * secondary effect is a somewhat better spread of the | ||
97 | * zero-bandwidth clients in the vector, avoiding some of | ||
98 | * the latency that could otherwise be caused by the | ||
99 | * partitioning of non-zero-bandwidth clients at low | ||
100 | * indexes and zero-bandwidth clients at high | ||
101 | * indexes. (Note that this spreading can only affect the | ||
102 | * unallocated bandwidth.) All the above only matters for | ||
103 | * memory-intensive situations, of course. | ||
104 | */ | ||
105 | if (!requested_slots[region][client]) { | ||
106 | /* | ||
107 | * Skip inactive clients. Also skip zero-slot | ||
108 | * allocations in this pass when there are no known | ||
109 | * free slots. | ||
110 | */ | ||
111 | if (!active_clients[region][client] | ||
112 | || unused_slots <= 0) | ||
113 | continue; | ||
114 | |||
115 | unused_slots--; | ||
116 | |||
117 | /* Only allocate one slot for this client. */ | ||
118 | interval = NBR_OF_SLOTS; | ||
119 | } else | ||
120 | interval = | ||
121 | NBR_OF_SLOTS / requested_slots[region][client]; | ||
122 | |||
123 | pos = 0; | ||
124 | while (pos < NBR_OF_SLOTS) { | ||
125 | if (val[pos] >= 0) | ||
126 | pos++; | ||
127 | else { | ||
128 | val[pos] = client; | ||
129 | pos += interval; | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | client = 0; | ||
135 | for (slot = 0; slot < NBR_OF_SLOTS; slot++) { | ||
136 | /* | ||
137 | * Allocate remaining slots in round-robin | ||
138 | * client-number order for active clients. For this | ||
139 | * pass, we ignore requested bandwidth and previous | ||
140 | * allocations. | ||
141 | */ | ||
142 | if (val[slot] < 0) { | ||
143 | int first = client; | ||
144 | while (!active_clients[region][client]) { | ||
145 | client = (client + 1) % NBR_OF_CLIENTS; | ||
146 | if (client == first) | ||
147 | break; | ||
148 | } | ||
149 | val[slot] = client; | ||
150 | client = (client + 1) % NBR_OF_CLIENTS; | ||
151 | } | ||
152 | if (region == EXT_REGION) | ||
153 | REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot, | ||
154 | val[slot]); | ||
155 | else if (region == INT_REGION) | ||
156 | REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot, | ||
157 | val[slot]); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | extern char _stext, _etext; | ||
162 | |||
163 | static void crisv32_arbiter_init(void) | ||
164 | { | ||
165 | static int initialized; | ||
166 | |||
167 | if (initialized) | ||
168 | return; | ||
169 | |||
170 | initialized = 1; | ||
171 | |||
172 | /* | ||
173 | * CPU caches are always set to active, but with zero | ||
174 | * bandwidth allocated. It should be ok to allocate zero | ||
175 | * bandwidth for the caches, because DMA for other channels | ||
176 | * will supposedly finish, once their programmed amount is | ||
177 | * done, and then the caches will get access according to the | ||
178 | * "fixed scheme" for unclaimed slots. Though, if for some | ||
179 | * use-case somewhere, there's a maximum CPU latency for | ||
180 | * e.g. some interrupt, we have to start allocating specific | ||
181 | * bandwidth for the CPU caches too. | ||
182 | */ | ||
183 | active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1; | ||
184 | crisv32_arbiter_config(EXT_REGION, 0); | ||
185 | crisv32_arbiter_config(INT_REGION, 0); | ||
186 | |||
187 | if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, IRQF_DISABLED, | ||
188 | "arbiter", NULL)) | ||
189 | printk(KERN_ERR "Couldn't allocate arbiter IRQ\n"); | ||
190 | |||
191 | #ifndef CONFIG_ETRAX_KGDB | ||
192 | /* Global watch for writes to kernel text segment. */ | ||
193 | crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, | ||
194 | arbiter_all_clients, arbiter_all_write, NULL); | ||
195 | #endif | ||
196 | } | ||
197 | |||
198 | /* Main entry for bandwidth allocation. */ | ||
199 | |||
200 | int crisv32_arbiter_allocate_bandwidth(int client, int region, | ||
201 | unsigned long bandwidth) | ||
202 | { | ||
203 | int i; | ||
204 | int total_assigned = 0; | ||
205 | int total_clients = 0; | ||
206 | int req; | ||
207 | |||
208 | crisv32_arbiter_init(); | ||
209 | |||
210 | for (i = 0; i < NBR_OF_CLIENTS; i++) { | ||
211 | total_assigned += requested_slots[region][i]; | ||
212 | total_clients += active_clients[region][i]; | ||
213 | } | ||
214 | |||
215 | /* Avoid division by 0 for 0-bandwidth requests. */ | ||
216 | req = bandwidth == 0 | ||
217 | ? 0 : NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth); | ||
218 | |||
219 | /* | ||
220 | * We make sure that there are enough slots only for non-zero | ||
221 | * requests. Requesting 0 bandwidth *may* allocate slots, | ||
222 | * though if all bandwidth is allocated, such a client won't | ||
223 | * get any and will have to rely on getting memory access | ||
224 | * according to the fixed scheme that's the default when one | ||
225 | * of the slot-allocated clients doesn't claim their slot. | ||
226 | */ | ||
227 | if (total_assigned + req > NBR_OF_SLOTS) | ||
228 | return -ENOMEM; | ||
229 | |||
230 | active_clients[region][client] = 1; | ||
231 | requested_slots[region][client] = req; | ||
232 | crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | /* | ||
238 | * Main entry for bandwidth deallocation. | ||
239 | * | ||
240 | * Strictly speaking, for a somewhat constant set of clients where | ||
241 | * each client gets a constant bandwidth and is just enabled or | ||
242 | * disabled (somewhat dynamically), no action is necessary here to | ||
243 | * avoid starvation for non-zero-allocation clients, as the allocated | ||
244 | * slots will just be unused. However, handing out those unused slots | ||
245 | * to active clients avoids needless latency if the "fixed scheme" | ||
246 | * would give unclaimed slots to an eager low-index client. | ||
247 | */ | ||
248 | |||
249 | void crisv32_arbiter_deallocate_bandwidth(int client, int region) | ||
250 | { | ||
251 | int i; | ||
252 | int total_assigned = 0; | ||
253 | |||
254 | requested_slots[region][client] = 0; | ||
255 | active_clients[region][client] = 0; | ||
256 | |||
257 | for (i = 0; i < NBR_OF_CLIENTS; i++) | ||
258 | total_assigned += requested_slots[region][i]; | ||
259 | |||
260 | crisv32_arbiter_config(region, NBR_OF_SLOTS - total_assigned); | ||
261 | } | ||
262 | |||
263 | int crisv32_arbiter_watch(unsigned long start, unsigned long size, | ||
264 | unsigned long clients, unsigned long accesses, | ||
265 | watch_callback *cb) | ||
266 | { | ||
267 | int i; | ||
268 | |||
269 | crisv32_arbiter_init(); | ||
270 | |||
271 | if (start > 0x80000000) { | ||
272 | printk(KERN_ERR "Arbiter: %lX doesn't look like a " | ||
273 | "physical address", start); | ||
274 | return -EFAULT; | ||
275 | } | ||
276 | |||
277 | spin_lock(&arbiter_lock); | ||
278 | |||
279 | for (i = 0; i < NUMBER_OF_BP; i++) { | ||
280 | if (!watches[i].used) { | ||
281 | reg_marb_rw_intr_mask intr_mask = | ||
282 | REG_RD(marb, regi_marb, rw_intr_mask); | ||
283 | |||
284 | watches[i].used = 1; | ||
285 | watches[i].start = start; | ||
286 | watches[i].end = start + size; | ||
287 | watches[i].cb = cb; | ||
288 | |||
289 | REG_WR_INT(marb_bp, watches[i].instance, rw_first_addr, | ||
290 | watches[i].start); | ||
291 | REG_WR_INT(marb_bp, watches[i].instance, rw_last_addr, | ||
292 | watches[i].end); | ||
293 | REG_WR_INT(marb_bp, watches[i].instance, rw_op, | ||
294 | accesses); | ||
295 | REG_WR_INT(marb_bp, watches[i].instance, rw_clients, | ||
296 | clients); | ||
297 | |||
298 | if (i == 0) | ||
299 | intr_mask.bp0 = regk_marb_yes; | ||
300 | else if (i == 1) | ||
301 | intr_mask.bp1 = regk_marb_yes; | ||
302 | else if (i == 2) | ||
303 | intr_mask.bp2 = regk_marb_yes; | ||
304 | else if (i == 3) | ||
305 | intr_mask.bp3 = regk_marb_yes; | ||
306 | |||
307 | REG_WR(marb, regi_marb, rw_intr_mask, intr_mask); | ||
308 | spin_unlock(&arbiter_lock); | ||
309 | |||
310 | return i; | ||
311 | } | ||
312 | } | ||
313 | spin_unlock(&arbiter_lock); | ||
314 | return -ENOMEM; | ||
315 | } | ||
316 | |||
317 | int crisv32_arbiter_unwatch(int id) | ||
318 | { | ||
319 | reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask); | ||
320 | |||
321 | crisv32_arbiter_init(); | ||
322 | |||
323 | spin_lock(&arbiter_lock); | ||
324 | |||
325 | if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) { | ||
326 | spin_unlock(&arbiter_lock); | ||
327 | return -EINVAL; | ||
328 | } | ||
329 | |||
330 | memset(&watches[id], 0, sizeof(struct crisv32_watch_entry)); | ||
331 | |||
332 | if (id == 0) | ||
333 | intr_mask.bp0 = regk_marb_no; | ||
334 | else if (id == 1) | ||
335 | intr_mask.bp2 = regk_marb_no; | ||
336 | else if (id == 2) | ||
337 | intr_mask.bp2 = regk_marb_no; | ||
338 | else if (id == 3) | ||
339 | intr_mask.bp3 = regk_marb_no; | ||
340 | |||
341 | REG_WR(marb, regi_marb, rw_intr_mask, intr_mask); | ||
342 | |||
343 | spin_unlock(&arbiter_lock); | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | extern void show_registers(struct pt_regs *regs); | ||
348 | |||
349 | static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id) | ||
350 | { | ||
351 | reg_marb_r_masked_intr masked_intr = | ||
352 | REG_RD(marb, regi_marb, r_masked_intr); | ||
353 | reg_marb_bp_r_brk_clients r_clients; | ||
354 | reg_marb_bp_r_brk_addr r_addr; | ||
355 | reg_marb_bp_r_brk_op r_op; | ||
356 | reg_marb_bp_r_brk_first_client r_first; | ||
357 | reg_marb_bp_r_brk_size r_size; | ||
358 | reg_marb_bp_rw_ack ack = { 0 }; | ||
359 | reg_marb_rw_ack_intr ack_intr = { | ||
360 | .bp0 = 1, .bp1 = 1, .bp2 = 1, .bp3 = 1 | ||
361 | }; | ||
362 | struct crisv32_watch_entry *watch; | ||
363 | |||
364 | if (masked_intr.bp0) { | ||
365 | watch = &watches[0]; | ||
366 | ack_intr.bp0 = regk_marb_yes; | ||
367 | } else if (masked_intr.bp1) { | ||
368 | watch = &watches[1]; | ||
369 | ack_intr.bp1 = regk_marb_yes; | ||
370 | } else if (masked_intr.bp2) { | ||
371 | watch = &watches[2]; | ||
372 | ack_intr.bp2 = regk_marb_yes; | ||
373 | } else if (masked_intr.bp3) { | ||
374 | watch = &watches[3]; | ||
375 | ack_intr.bp3 = regk_marb_yes; | ||
376 | } else { | ||
377 | return IRQ_NONE; | ||
378 | } | ||
379 | |||
380 | /* Retrieve all useful information and print it. */ | ||
381 | r_clients = REG_RD(marb_bp, watch->instance, r_brk_clients); | ||
382 | r_addr = REG_RD(marb_bp, watch->instance, r_brk_addr); | ||
383 | r_op = REG_RD(marb_bp, watch->instance, r_brk_op); | ||
384 | r_first = REG_RD(marb_bp, watch->instance, r_brk_first_client); | ||
385 | r_size = REG_RD(marb_bp, watch->instance, r_brk_size); | ||
386 | |||
387 | printk(KERN_INFO "Arbiter IRQ\n"); | ||
388 | printk(KERN_INFO "Clients %X addr %X op %X first %X size %X\n", | ||
389 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_clients, r_clients), | ||
390 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_addr, r_addr), | ||
391 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_op, r_op), | ||
392 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_first_client, r_first), | ||
393 | REG_TYPE_CONV(int, reg_marb_bp_r_brk_size, r_size)); | ||
394 | |||
395 | REG_WR(marb_bp, watch->instance, rw_ack, ack); | ||
396 | REG_WR(marb, regi_marb, rw_ack_intr, ack_intr); | ||
397 | |||
398 | printk(KERN_INFO "IRQ occured at %lX\n", get_irq_regs()->erp); | ||
399 | |||
400 | if (watch->cb) | ||
401 | watch->cb(); | ||
402 | |||
403 | return IRQ_HANDLED; | ||
404 | } | ||
diff --git a/arch/cris/arch-v32/mach-fs/cpufreq.c b/arch/cris/arch-v32/mach-fs/cpufreq.c new file mode 100644 index 000000000000..d57631c0d8d1 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/cpufreq.c | |||
@@ -0,0 +1,146 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/cpufreq.h> | ||
4 | #include <hwregs/reg_map.h> | ||
5 | #include <asm/arch/hwregs/reg_rdwr.h> | ||
6 | #include <asm/arch/hwregs/config_defs.h> | ||
7 | #include <asm/arch/hwregs/bif_core_defs.h> | ||
8 | |||
9 | static int | ||
10 | cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, | ||
11 | void *data); | ||
12 | |||
13 | static struct notifier_block cris_sdram_freq_notifier_block = { | ||
14 | .notifier_call = cris_sdram_freq_notifier | ||
15 | }; | ||
16 | |||
17 | static struct cpufreq_frequency_table cris_freq_table[] = { | ||
18 | {0x01, 6000}, | ||
19 | {0x02, 200000}, | ||
20 | {0, CPUFREQ_TABLE_END}, | ||
21 | }; | ||
22 | |||
23 | static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) | ||
24 | { | ||
25 | reg_config_rw_clk_ctrl clk_ctrl; | ||
26 | clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); | ||
27 | return clk_ctrl.pll ? 200000 : 6000; | ||
28 | } | ||
29 | |||
30 | static void cris_freq_set_cpu_state(unsigned int state) | ||
31 | { | ||
32 | int i; | ||
33 | struct cpufreq_freqs freqs; | ||
34 | reg_config_rw_clk_ctrl clk_ctrl; | ||
35 | clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); | ||
36 | |||
37 | for_each_possible_cpu(i) { | ||
38 | freqs.old = cris_freq_get_cpu_frequency(i); | ||
39 | freqs.new = cris_freq_table[state].frequency; | ||
40 | freqs.cpu = i; | ||
41 | } | ||
42 | |||
43 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
44 | |||
45 | local_irq_disable(); | ||
46 | |||
47 | /* Even though we may be SMP they will share the same clock | ||
48 | * so all settings are made on CPU0. */ | ||
49 | if (cris_freq_table[state].frequency == 200000) | ||
50 | clk_ctrl.pll = 1; | ||
51 | else | ||
52 | clk_ctrl.pll = 0; | ||
53 | REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl); | ||
54 | |||
55 | local_irq_enable(); | ||
56 | |||
57 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
58 | }; | ||
59 | |||
60 | static int cris_freq_verify(struct cpufreq_policy *policy) | ||
61 | { | ||
62 | return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]); | ||
63 | } | ||
64 | |||
65 | static int cris_freq_target(struct cpufreq_policy *policy, | ||
66 | unsigned int target_freq, unsigned int relation) | ||
67 | { | ||
68 | unsigned int newstate = 0; | ||
69 | |||
70 | if (cpufreq_frequency_table_target | ||
71 | (policy, cris_freq_table, target_freq, relation, &newstate)) | ||
72 | return -EINVAL; | ||
73 | |||
74 | cris_freq_set_cpu_state(newstate); | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int cris_freq_cpu_init(struct cpufreq_policy *policy) | ||
80 | { | ||
81 | int result; | ||
82 | |||
83 | /* cpuinfo and default policy values */ | ||
84 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
85 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
86 | policy->cur = cris_freq_get_cpu_frequency(0); | ||
87 | |||
88 | result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table); | ||
89 | if (result) | ||
90 | return (result); | ||
91 | |||
92 | cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int cris_freq_cpu_exit(struct cpufreq_policy *policy) | ||
98 | { | ||
99 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static struct freq_attr *cris_freq_attr[] = { | ||
104 | &cpufreq_freq_attr_scaling_available_freqs, | ||
105 | NULL, | ||
106 | }; | ||
107 | |||
108 | static struct cpufreq_driver cris_freq_driver = { | ||
109 | .get = cris_freq_get_cpu_frequency, | ||
110 | .verify = cris_freq_verify, | ||
111 | .target = cris_freq_target, | ||
112 | .init = cris_freq_cpu_init, | ||
113 | .exit = cris_freq_cpu_exit, | ||
114 | .name = "cris_freq", | ||
115 | .owner = THIS_MODULE, | ||
116 | .attr = cris_freq_attr, | ||
117 | }; | ||
118 | |||
119 | static int __init cris_freq_init(void) | ||
120 | { | ||
121 | int ret; | ||
122 | ret = cpufreq_register_driver(&cris_freq_driver); | ||
123 | cpufreq_register_notifier(&cris_sdram_freq_notifier_block, | ||
124 | CPUFREQ_TRANSITION_NOTIFIER); | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | static int | ||
129 | cris_sdram_freq_notifier(struct notifier_block *nb, unsigned long val, | ||
130 | void *data) | ||
131 | { | ||
132 | int i; | ||
133 | struct cpufreq_freqs *freqs = data; | ||
134 | if (val == CPUFREQ_PRECHANGE) { | ||
135 | reg_bif_core_rw_sdram_timing timing = | ||
136 | REG_RD(bif_core, regi_bif_core, rw_sdram_timing); | ||
137 | timing.cpd = (freqs->new == 200000 ? 0 : 1); | ||
138 | |||
139 | if (freqs->new == 200000) | ||
140 | for (i = 0; i < 50000; i++) ; | ||
141 | REG_WR(bif_core, regi_bif_core, rw_sdram_timing, timing); | ||
142 | } | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | module_init(cris_freq_init); | ||
diff --git a/arch/cris/arch-v32/kernel/dma.c b/arch/cris/arch-v32/mach-fs/dma.c index 570e19128ffd..a6acf4e6345c 100644 --- a/arch/cris/arch-v32/kernel/dma.c +++ b/arch/cris/arch-v32/mach-fs/dma.c | |||
@@ -3,49 +3,54 @@ | |||
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | #include <asm/dma.h> | 5 | #include <asm/dma.h> |
6 | #include <asm/arch/hwregs/reg_map.h> | 6 | #include <hwregs/reg_map.h> |
7 | #include <asm/arch/hwregs/reg_rdwr.h> | 7 | #include <hwregs/reg_rdwr.h> |
8 | #include <asm/arch/hwregs/marb_defs.h> | 8 | #include <hwregs/marb_defs.h> |
9 | #include <asm/arch/hwregs/config_defs.h> | 9 | #include <hwregs/config_defs.h> |
10 | #include <asm/arch/hwregs/strmux_defs.h> | 10 | #include <hwregs/strmux_defs.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <asm/system.h> | 12 | #include <asm/system.h> |
13 | #include <asm/arch/arbiter.h> | 13 | #include <asm/arch/mach/arbiter.h> |
14 | 14 | ||
15 | static char used_dma_channels[MAX_DMA_CHANNELS]; | 15 | static char used_dma_channels[MAX_DMA_CHANNELS]; |
16 | static const char * used_dma_channels_users[MAX_DMA_CHANNELS]; | 16 | static const char *used_dma_channels_users[MAX_DMA_CHANNELS]; |
17 | 17 | ||
18 | static DEFINE_SPINLOCK(dma_lock); | 18 | static DEFINE_SPINLOCK(dma_lock); |
19 | 19 | ||
20 | int crisv32_request_dma(unsigned int dmanr, const char * device_id, | 20 | int crisv32_request_dma(unsigned int dmanr, const char *device_id, |
21 | unsigned options, unsigned int bandwidth, | 21 | unsigned options, unsigned int bandwidth, |
22 | enum dma_owner owner) | 22 | enum dma_owner owner) |
23 | { | 23 | { |
24 | unsigned long flags; | 24 | unsigned long flags; |
25 | reg_config_rw_clk_ctrl clk_ctrl; | 25 | reg_config_rw_clk_ctrl clk_ctrl; |
26 | reg_strmux_rw_cfg strmux_cfg; | 26 | reg_strmux_rw_cfg strmux_cfg; |
27 | 27 | ||
28 | if (crisv32_arbiter_allocate_bandwidth(dmanr, | 28 | if (crisv32_arbiter_allocate_bandwidth(dmanr, |
29 | options & DMA_INT_MEM ? INT_REGION : EXT_REGION, | 29 | options & DMA_INT_MEM ? |
30 | bandwidth)) | 30 | INT_REGION : EXT_REGION, |
31 | return -ENOMEM; | 31 | bandwidth)) |
32 | return -ENOMEM; | ||
32 | 33 | ||
33 | spin_lock_irqsave(&dma_lock, flags); | 34 | spin_lock_irqsave(&dma_lock, flags); |
34 | 35 | ||
35 | if (used_dma_channels[dmanr]) { | 36 | if (used_dma_channels[dmanr]) { |
36 | spin_unlock_irqrestore(&dma_lock, flags); | 37 | spin_unlock_irqrestore(&dma_lock, flags); |
37 | if (options & DMA_VERBOSE_ON_ERROR) { | 38 | if (options & DMA_VERBOSE_ON_ERROR) { |
38 | printk("Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]); | 39 | printk(KERN_ERR "Failed to request DMA %i for %s, " |
40 | "already allocated by %s\n", | ||
41 | dmanr, | ||
42 | device_id, | ||
43 | used_dma_channels_users[dmanr]); | ||
39 | } | 44 | } |
40 | if (options & DMA_PANIC_ON_ERROR) | 45 | if (options & DMA_PANIC_ON_ERROR) |
41 | panic("request_dma error!"); | 46 | panic("request_dma error!"); |
47 | spin_unlock_irqrestore(&dma_lock, flags); | ||
42 | return -EBUSY; | 48 | return -EBUSY; |
43 | } | 49 | } |
44 | clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); | 50 | clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); |
45 | strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); | 51 | strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); |
46 | 52 | ||
47 | switch(dmanr) | 53 | switch (dmanr) { |
48 | { | ||
49 | case 0: | 54 | case 0: |
50 | case 1: | 55 | case 1: |
51 | clk_ctrl.dma01_eth0 = 1; | 56 | clk_ctrl.dma01_eth0 = 1; |
@@ -72,7 +77,9 @@ int crisv32_request_dma(unsigned int dmanr, const char * device_id, | |||
72 | default: | 77 | default: |
73 | spin_unlock_irqrestore(&dma_lock, flags); | 78 | spin_unlock_irqrestore(&dma_lock, flags); |
74 | if (options & DMA_VERBOSE_ON_ERROR) { | 79 | if (options & DMA_VERBOSE_ON_ERROR) { |
75 | printk("Failed to request DMA %i for %s, only 0-%i valid)\n", dmanr, device_id, MAX_DMA_CHANNELS-1); | 80 | printk(KERN_ERR "Failed to request DMA %i for %s, " |
81 | "only 0-%i valid)\n", | ||
82 | dmanr, device_id, MAX_DMA_CHANNELS - 1); | ||
76 | } | 83 | } |
77 | 84 | ||
78 | if (options & DMA_PANIC_ON_ERROR) | 85 | if (options & DMA_PANIC_ON_ERROR) |
@@ -80,8 +87,7 @@ int crisv32_request_dma(unsigned int dmanr, const char * device_id, | |||
80 | return -EINVAL; | 87 | return -EINVAL; |
81 | } | 88 | } |
82 | 89 | ||
83 | switch(owner) | 90 | switch (owner) { |
84 | { | ||
85 | case dma_eth0: | 91 | case dma_eth0: |
86 | if (dmanr == 0) | 92 | if (dmanr == 0) |
87 | strmux_cfg.dma0 = regk_strmux_eth0; | 93 | strmux_cfg.dma0 = regk_strmux_eth0; |
@@ -212,7 +218,7 @@ int crisv32_request_dma(unsigned int dmanr, const char * device_id, | |||
212 | used_dma_channels_users[dmanr] = device_id; | 218 | used_dma_channels_users[dmanr] = device_id; |
213 | REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl); | 219 | REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl); |
214 | REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); | 220 | REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); |
215 | spin_unlock_irqrestore(&dma_lock,flags); | 221 | spin_unlock_irqrestore(&dma_lock, flags); |
216 | return 0; | 222 | return 0; |
217 | } | 223 | } |
218 | 224 | ||
diff --git a/arch/cris/arch-v32/lib/dram_init.S b/arch/cris/arch-v32/mach-fs/dram_init.S index 218fbe259ee5..6fbad336527b 100644 --- a/arch/cris/arch-v32/lib/dram_init.S +++ b/arch/cris/arch-v32/mach-fs/dram_init.S | |||
@@ -1,23 +1,22 @@ | |||
1 | /* $Id: dram_init.S,v 1.4 2005/04/24 18:48:32 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * DRAM/SDRAM initialization - alter with care | 2 | * DRAM/SDRAM initialization - alter with care |
4 | * This file is intended to be included from other assembler files | 3 | * This file is intended to be included from other assembler files |
5 | * | 4 | * |
6 | * Note: This file may not modify r8 or r9 because they are used to | 5 | * Note: This file may not modify r8 or r9 because they are used to |
7 | * carry information from the decompresser to the kernel | 6 | * carry information from the decompresser to the kernel |
8 | * | 7 | * |
9 | * Copyright (C) 2000-2003 Axis Communications AB | 8 | * Copyright (C) 2000-2007 Axis Communications AB |
10 | * | 9 | * |
11 | * Authors: Mikael Starvik (starvik@axis.com) | 10 | * Authors: Mikael Starvik <starvik@axis.com> |
12 | */ | 11 | */ |
13 | 12 | ||
14 | /* Just to be certain the config file is included, we include it here | 13 | /* Just to be certain the config file is included, we include it here |
15 | * explicitly instead of depending on it being included in the file that | 14 | * explicitely instead of depending on it being included in the file that |
16 | * uses this code. | 15 | * uses this code. |
17 | */ | 16 | */ |
18 | 17 | ||
19 | #include <asm/arch/hwregs/asm/reg_map_asm.h> | 18 | #include <hwregs/asm/reg_map_asm.h> |
20 | #include <asm/arch/hwregs/asm/bif_core_defs_asm.h> | 19 | #include <hwregs/asm/bif_core_defs_asm.h> |
21 | 20 | ||
22 | ;; WARNING! The registers r8 and r9 are used as parameters carrying | 21 | ;; WARNING! The registers r8 and r9 are used as parameters carrying |
23 | ;; information from the decompressor (if the kernel was compressed). | 22 | ;; information from the decompressor (if the kernel was compressed). |
@@ -46,7 +45,7 @@ | |||
46 | 45 | ||
47 | move.d 0x40, $r4 ; Assume 32 bits and CAS latency = 2 | 46 | move.d 0x40, $r4 ; Assume 32 bits and CAS latency = 2 |
48 | move.d CONFIG_ETRAX_SDRAM_TIMING, $r1 | 47 | move.d CONFIG_ETRAX_SDRAM_TIMING, $r1 |
49 | and.d 0x07, $r1 ; Get CAS latency | 48 | and.d 0x07, $r1 ; Get CAS latency |
50 | cmpq 2, $r1 ; CL = 2 ? | 49 | cmpq 2, $r1 ; CL = 2 ? |
51 | beq _bw_check | 50 | beq _bw_check |
52 | nop | 51 | nop |
@@ -80,12 +79,10 @@ _set_timing: | |||
80 | subq 1, $r2 | 79 | subq 1, $r2 |
81 | 80 | ||
82 | ; Issue initialization command sequence | 81 | ; Issue initialization command sequence |
83 | move.d _sdram_commands_start, $r2 | 82 | lapc _sdram_commands_start, $r2 |
84 | and.d 0x000fffff, $r2 ; Make sure commands are read from flash | 83 | lapc _sdram_commands_end, $r3 |
85 | move.d _sdram_commands_end, $r3 | ||
86 | and.d 0x000fffff, $r3 | ||
87 | 1: clear.d $r6 | 84 | 1: clear.d $r6 |
88 | move.b [$r2+], $r6 ; Load command | 85 | move.b [$r2+], $r6 ; Load command |
89 | or.d $r4, $r6 ; Add calculated mrs | 86 | or.d $r4, $r6 ; Add calculated mrs |
90 | move.d $r6, [$r5] ; Write rw_sdram_cmd | 87 | move.d $r6, [$r5] ; Write rw_sdram_cmd |
91 | ; Wait 80 ns between each command | 88 | ; Wait 80 ns between each command |
diff --git a/arch/cris/arch-v32/lib/hw_settings.S b/arch/cris/arch-v32/mach-fs/hw_settings.S index fff9443513d1..8bde93c36214 100644 --- a/arch/cris/arch-v32/lib/hw_settings.S +++ b/arch/cris/arch-v32/mach-fs/hw_settings.S | |||
@@ -1,18 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: hw_settings.S,v 1.3 2005/04/24 18:36:57 starvik Exp $ | ||
3 | * | ||
4 | * This table is used by some tools to extract hardware parameters. | 2 | * This table is used by some tools to extract hardware parameters. |
5 | * The table should be included in the kernel and the decompressor. | 3 | * The table should be included in the kernel and the decompressor. |
6 | * Don't forget to update the tools if you change this table. | 4 | * Don't forget to update the tools if you change this table. |
7 | * | 5 | * |
8 | * Copyright (C) 2001 Axis Communications AB | 6 | * Copyright (C) 2001-2007 Axis Communications AB |
9 | * | 7 | * |
10 | * Authors: Mikael Starvik (starvik@axis.com) | 8 | * Authors: Mikael Starvik <starvik@axis.com> |
11 | */ | 9 | */ |
12 | 10 | ||
13 | #include <asm/arch/hwregs/asm/reg_map_asm.h> | 11 | #include <hwregs/asm/reg_map_asm.h> |
14 | #include <asm/arch/hwregs/asm/bif_core_defs_asm.h> | 12 | #include <hwregs/asm/bif_core_defs_asm.h> |
15 | #include <asm/arch/hwregs/asm/gio_defs_asm.h> | 13 | #include <hwregs/asm/gio_defs_asm.h> |
16 | 14 | ||
17 | .ascii "HW_PARAM_MAGIC" ; Magic number | 15 | .ascii "HW_PARAM_MAGIC" ; Magic number |
18 | .dword 0xc0004000 ; Kernel start address | 16 | .dword 0xc0004000 ; Kernel start address |
diff --git a/arch/cris/arch-v32/mach-fs/io.c b/arch/cris/arch-v32/mach-fs/io.c new file mode 100644 index 000000000000..a03a3ad3a188 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/io.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * Helper functions for I/O pins. | ||
3 | * | ||
4 | * Copyright (c) 2004-2007 Axis Communications AB. | ||
5 | */ | ||
6 | |||
7 | #include <linux/types.h> | ||
8 | #include <linux/errno.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/ctype.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/arch/pinmux.h> | ||
16 | #include <asm/arch/hwregs/gio_defs.h> | ||
17 | |||
18 | #ifndef DEBUG | ||
19 | #define DEBUG(x) | ||
20 | #endif | ||
21 | |||
22 | struct crisv32_ioport crisv32_ioports[] = { | ||
23 | { | ||
24 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe), | ||
25 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout), | ||
26 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din), | ||
27 | 8 | ||
28 | }, | ||
29 | { | ||
30 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe), | ||
31 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout), | ||
32 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din), | ||
33 | 18 | ||
34 | }, | ||
35 | { | ||
36 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe), | ||
37 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout), | ||
38 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din), | ||
39 | 18 | ||
40 | }, | ||
41 | { | ||
42 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_oe), | ||
43 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pd_dout), | ||
44 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pd_din), | ||
45 | 18 | ||
46 | }, | ||
47 | { | ||
48 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_oe), | ||
49 | (unsigned long *)REG_ADDR(gio, regi_gio, rw_pe_dout), | ||
50 | (unsigned long *)REG_ADDR(gio, regi_gio, r_pe_din), | ||
51 | 18 | ||
52 | } | ||
53 | }; | ||
54 | |||
55 | #define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport) | ||
56 | |||
57 | struct crisv32_iopin crisv32_led_net0_green; | ||
58 | struct crisv32_iopin crisv32_led_net0_red; | ||
59 | struct crisv32_iopin crisv32_led_net1_green; | ||
60 | struct crisv32_iopin crisv32_led_net1_red; | ||
61 | struct crisv32_iopin crisv32_led2_green; | ||
62 | struct crisv32_iopin crisv32_led2_red; | ||
63 | struct crisv32_iopin crisv32_led3_green; | ||
64 | struct crisv32_iopin crisv32_led3_red; | ||
65 | |||
66 | /* Dummy port used when green LED and red LED is on the same bit */ | ||
67 | static unsigned long io_dummy; | ||
68 | static struct crisv32_ioport dummy_port = { | ||
69 | &io_dummy, | ||
70 | &io_dummy, | ||
71 | &io_dummy, | ||
72 | 18 | ||
73 | }; | ||
74 | static struct crisv32_iopin dummy_led = { | ||
75 | &dummy_port, | ||
76 | 0 | ||
77 | }; | ||
78 | |||
79 | static int __init crisv32_io_init(void) | ||
80 | { | ||
81 | int ret = 0; | ||
82 | |||
83 | u32 i; | ||
84 | |||
85 | /* Locks *should* be dynamically initialized. */ | ||
86 | for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++) | ||
87 | spin_lock_init(&crisv32_ioports[i].lock); | ||
88 | spin_lock_init(&dummy_port.lock); | ||
89 | |||
90 | /* Initialize LEDs */ | ||
91 | #if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO)) | ||
92 | ret += | ||
93 | crisv32_io_get_name(&crisv32_led_net0_green, | ||
94 | CONFIG_ETRAX_LED_G_NET0); | ||
95 | crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out); | ||
96 | if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) { | ||
97 | ret += | ||
98 | crisv32_io_get_name(&crisv32_led_net0_red, | ||
99 | CONFIG_ETRAX_LED_R_NET0); | ||
100 | crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out); | ||
101 | } else | ||
102 | crisv32_led_net0_red = dummy_led; | ||
103 | #endif | ||
104 | |||
105 | #ifdef CONFIG_ETRAX_NBR_LED_GRP_TWO | ||
106 | ret += | ||
107 | crisv32_io_get_name(&crisv32_led_net1_green, | ||
108 | CONFIG_ETRAX_LED_G_NET1); | ||
109 | crisv32_io_set_dir(&crisv32_led_net1_green, crisv32_io_dir_out); | ||
110 | if (strcmp(CONFIG_ETRAX_LED_G_NET1, CONFIG_ETRAX_LED_R_NET1)) { | ||
111 | crisv32_io_get_name(&crisv32_led_net1_red, | ||
112 | CONFIG_ETRAX_LED_R_NET1); | ||
113 | crisv32_io_set_dir(&crisv32_led_net1_red, crisv32_io_dir_out); | ||
114 | } else | ||
115 | crisv32_led_net1_red = dummy_led; | ||
116 | #endif | ||
117 | |||
118 | ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G); | ||
119 | ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R); | ||
120 | ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G); | ||
121 | ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R); | ||
122 | |||
123 | crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out); | ||
124 | crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out); | ||
125 | crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out); | ||
126 | crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out); | ||
127 | |||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | __initcall(crisv32_io_init); | ||
132 | |||
133 | int crisv32_io_get(struct crisv32_iopin *iopin, | ||
134 | unsigned int port, unsigned int pin) | ||
135 | { | ||
136 | if (port > NBR_OF_PORTS) | ||
137 | return -EINVAL; | ||
138 | if (port > crisv32_ioports[port].pin_count) | ||
139 | return -EINVAL; | ||
140 | |||
141 | iopin->bit = 1 << pin; | ||
142 | iopin->port = &crisv32_ioports[port]; | ||
143 | |||
144 | /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */ | ||
145 | /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */ | ||
146 | if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio)) | ||
147 | return -EIO; | ||
148 | DEBUG(printk(KERN_DEBUG "crisv32_io_get: Allocated pin %d on port %d\n", | ||
149 | pin, port)); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name) | ||
155 | { | ||
156 | int port; | ||
157 | int pin; | ||
158 | |||
159 | if (toupper(*name) == 'P') | ||
160 | name++; | ||
161 | |||
162 | if (toupper(*name) < 'A' || toupper(*name) > 'E') | ||
163 | return -EINVAL; | ||
164 | |||
165 | port = toupper(*name) - 'A'; | ||
166 | name++; | ||
167 | pin = simple_strtoul(name, NULL, 10); | ||
168 | |||
169 | if (pin < 0 || pin > crisv32_ioports[port].pin_count) | ||
170 | return -EINVAL; | ||
171 | |||
172 | iopin->bit = 1 << pin; | ||
173 | iopin->port = &crisv32_ioports[port]; | ||
174 | |||
175 | /* Only allocate pinmux gpiopins if port != PORT_A (port 0) */ | ||
176 | /* NOTE! crisv32_pinmux_alloc thinks PORT_B is port 0 */ | ||
177 | if (port != 0 && crisv32_pinmux_alloc(port - 1, pin, pin, pinmux_gpio)) | ||
178 | return -EIO; | ||
179 | |||
180 | DEBUG(printk(KERN_DEBUG | ||
181 | "crisv32_io_get_name: Allocated pin %d on port %d\n", | ||
182 | pin, port)); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | #ifdef CONFIG_PCI | ||
188 | /* PCI I/O access stuff */ | ||
189 | struct cris_io_operations *cris_iops = NULL; | ||
190 | EXPORT_SYMBOL(cris_iops); | ||
191 | #endif | ||
diff --git a/arch/cris/arch-v32/mach-fs/pinmux.c b/arch/cris/arch-v32/mach-fs/pinmux.c new file mode 100644 index 000000000000..d722ad9ae626 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/pinmux.c | |||
@@ -0,0 +1,309 @@ | |||
1 | /* | ||
2 | * Allocator for I/O pins. All pins are allocated to GPIO at bootup. | ||
3 | * Unassigned pins and GPIO pins can be allocated to a fixed interface | ||
4 | * or the I/O processor instead. | ||
5 | * | ||
6 | * Copyright (c) 2004-2007 Axis Communications AB. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <hwregs/reg_map.h> | ||
15 | #include <hwregs/reg_rdwr.h> | ||
16 | #include <pinmux.h> | ||
17 | #include <hwregs/pinmux_defs.h> | ||
18 | |||
19 | #undef DEBUG | ||
20 | |||
21 | #define PORT_PINS 18 | ||
22 | #define PORTS 4 | ||
23 | |||
24 | static char pins[PORTS][PORT_PINS]; | ||
25 | static DEFINE_SPINLOCK(pinmux_lock); | ||
26 | |||
27 | static void crisv32_pinmux_set(int port); | ||
28 | |||
29 | int crisv32_pinmux_init(void) | ||
30 | { | ||
31 | static int initialized; | ||
32 | |||
33 | if (!initialized) { | ||
34 | reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa); | ||
35 | initialized = 1; | ||
36 | REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0); | ||
37 | pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 = | ||
38 | pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes; | ||
39 | REG_WR(pinmux, regi_pinmux, rw_pa, pa); | ||
40 | crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio); | ||
41 | crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio); | ||
42 | crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio); | ||
43 | crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio); | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | int | ||
50 | crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode) | ||
51 | { | ||
52 | int i; | ||
53 | unsigned long flags; | ||
54 | |||
55 | crisv32_pinmux_init(); | ||
56 | |||
57 | if (port > PORTS) | ||
58 | return -EINVAL; | ||
59 | |||
60 | spin_lock_irqsave(&pinmux_lock, flags); | ||
61 | |||
62 | for (i = first_pin; i <= last_pin; i++) { | ||
63 | if ((pins[port][i] != pinmux_none) | ||
64 | && (pins[port][i] != pinmux_gpio) | ||
65 | && (pins[port][i] != mode)) { | ||
66 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
67 | #ifdef DEBUG | ||
68 | panic("Pinmux alloc failed!\n"); | ||
69 | #endif | ||
70 | return -EPERM; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | for (i = first_pin; i <= last_pin; i++) | ||
75 | pins[port][i] = mode; | ||
76 | |||
77 | crisv32_pinmux_set(port); | ||
78 | |||
79 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | int crisv32_pinmux_alloc_fixed(enum fixed_function function) | ||
85 | { | ||
86 | int ret = -EINVAL; | ||
87 | char saved[sizeof pins]; | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&pinmux_lock, flags); | ||
91 | |||
92 | /* Save internal data for recovery */ | ||
93 | memcpy(saved, pins, sizeof pins); | ||
94 | |||
95 | crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */ | ||
96 | |||
97 | reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); | ||
98 | |||
99 | switch (function) { | ||
100 | case pinmux_ser1: | ||
101 | ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed); | ||
102 | hwprot.ser1 = regk_pinmux_yes; | ||
103 | break; | ||
104 | case pinmux_ser2: | ||
105 | ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed); | ||
106 | hwprot.ser2 = regk_pinmux_yes; | ||
107 | break; | ||
108 | case pinmux_ser3: | ||
109 | ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed); | ||
110 | hwprot.ser3 = regk_pinmux_yes; | ||
111 | break; | ||
112 | case pinmux_sser0: | ||
113 | ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed); | ||
114 | ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed); | ||
115 | hwprot.sser0 = regk_pinmux_yes; | ||
116 | break; | ||
117 | case pinmux_sser1: | ||
118 | ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed); | ||
119 | hwprot.sser1 = regk_pinmux_yes; | ||
120 | break; | ||
121 | case pinmux_ata0: | ||
122 | ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed); | ||
123 | ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed); | ||
124 | hwprot.ata0 = regk_pinmux_yes; | ||
125 | break; | ||
126 | case pinmux_ata1: | ||
127 | ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed); | ||
128 | ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed); | ||
129 | hwprot.ata1 = regk_pinmux_yes; | ||
130 | break; | ||
131 | case pinmux_ata2: | ||
132 | ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed); | ||
133 | ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed); | ||
134 | hwprot.ata2 = regk_pinmux_yes; | ||
135 | break; | ||
136 | case pinmux_ata3: | ||
137 | ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed); | ||
138 | ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed); | ||
139 | hwprot.ata2 = regk_pinmux_yes; | ||
140 | break; | ||
141 | case pinmux_ata: | ||
142 | ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed); | ||
143 | ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed); | ||
144 | hwprot.ata = regk_pinmux_yes; | ||
145 | break; | ||
146 | case pinmux_eth1: | ||
147 | ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed); | ||
148 | hwprot.eth1 = regk_pinmux_yes; | ||
149 | hwprot.eth1_mgm = regk_pinmux_yes; | ||
150 | break; | ||
151 | case pinmux_timer: | ||
152 | ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed); | ||
153 | hwprot.timer = regk_pinmux_yes; | ||
154 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | if (!ret) | ||
159 | REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); | ||
160 | else | ||
161 | memcpy(pins, saved, sizeof pins); | ||
162 | |||
163 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
164 | |||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | void crisv32_pinmux_set(int port) | ||
169 | { | ||
170 | int i; | ||
171 | int gpio_val = 0; | ||
172 | int iop_val = 0; | ||
173 | |||
174 | for (i = 0; i < PORT_PINS; i++) { | ||
175 | if (pins[port][i] == pinmux_gpio) | ||
176 | gpio_val |= (1 << i); | ||
177 | else if (pins[port][i] == pinmux_iop) | ||
178 | iop_val |= (1 << i); | ||
179 | } | ||
180 | |||
181 | REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8 * port, | ||
182 | gpio_val); | ||
183 | REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8 * port, | ||
184 | iop_val); | ||
185 | |||
186 | #ifdef DEBUG | ||
187 | crisv32_pinmux_dump(); | ||
188 | #endif | ||
189 | } | ||
190 | |||
191 | int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin) | ||
192 | { | ||
193 | int i; | ||
194 | unsigned long flags; | ||
195 | |||
196 | crisv32_pinmux_init(); | ||
197 | |||
198 | if (port > PORTS) | ||
199 | return -EINVAL; | ||
200 | |||
201 | spin_lock_irqsave(&pinmux_lock, flags); | ||
202 | |||
203 | for (i = first_pin; i <= last_pin; i++) | ||
204 | pins[port][i] = pinmux_none; | ||
205 | |||
206 | crisv32_pinmux_set(port); | ||
207 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | int crisv32_pinmux_dealloc_fixed(enum fixed_function function) | ||
213 | { | ||
214 | int ret = -EINVAL; | ||
215 | char saved[sizeof pins]; | ||
216 | unsigned long flags; | ||
217 | |||
218 | spin_lock_irqsave(&pinmux_lock, flags); | ||
219 | |||
220 | /* Save internal data for recovery */ | ||
221 | memcpy(saved, pins, sizeof pins); | ||
222 | |||
223 | crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */ | ||
224 | |||
225 | reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); | ||
226 | |||
227 | switch (function) { | ||
228 | case pinmux_ser1: | ||
229 | ret = crisv32_pinmux_dealloc(PORT_C, 4, 7); | ||
230 | hwprot.ser1 = regk_pinmux_no; | ||
231 | break; | ||
232 | case pinmux_ser2: | ||
233 | ret = crisv32_pinmux_dealloc(PORT_C, 8, 11); | ||
234 | hwprot.ser2 = regk_pinmux_no; | ||
235 | break; | ||
236 | case pinmux_ser3: | ||
237 | ret = crisv32_pinmux_dealloc(PORT_C, 12, 15); | ||
238 | hwprot.ser3 = regk_pinmux_no; | ||
239 | break; | ||
240 | case pinmux_sser0: | ||
241 | ret = crisv32_pinmux_dealloc(PORT_C, 0, 3); | ||
242 | ret |= crisv32_pinmux_dealloc(PORT_C, 16, 16); | ||
243 | hwprot.sser0 = regk_pinmux_no; | ||
244 | break; | ||
245 | case pinmux_sser1: | ||
246 | ret = crisv32_pinmux_dealloc(PORT_D, 0, 4); | ||
247 | hwprot.sser1 = regk_pinmux_no; | ||
248 | break; | ||
249 | case pinmux_ata0: | ||
250 | ret = crisv32_pinmux_dealloc(PORT_D, 5, 7); | ||
251 | ret |= crisv32_pinmux_dealloc(PORT_D, 15, 17); | ||
252 | hwprot.ata0 = regk_pinmux_no; | ||
253 | break; | ||
254 | case pinmux_ata1: | ||
255 | ret = crisv32_pinmux_dealloc(PORT_D, 0, 4); | ||
256 | ret |= crisv32_pinmux_dealloc(PORT_E, 17, 17); | ||
257 | hwprot.ata1 = regk_pinmux_no; | ||
258 | break; | ||
259 | case pinmux_ata2: | ||
260 | ret = crisv32_pinmux_dealloc(PORT_C, 11, 15); | ||
261 | ret |= crisv32_pinmux_dealloc(PORT_E, 3, 3); | ||
262 | hwprot.ata2 = regk_pinmux_no; | ||
263 | break; | ||
264 | case pinmux_ata3: | ||
265 | ret = crisv32_pinmux_dealloc(PORT_C, 8, 10); | ||
266 | ret |= crisv32_pinmux_dealloc(PORT_C, 0, 2); | ||
267 | hwprot.ata2 = regk_pinmux_no; | ||
268 | break; | ||
269 | case pinmux_ata: | ||
270 | ret = crisv32_pinmux_dealloc(PORT_B, 0, 15); | ||
271 | ret |= crisv32_pinmux_dealloc(PORT_D, 8, 15); | ||
272 | hwprot.ata = regk_pinmux_no; | ||
273 | break; | ||
274 | case pinmux_eth1: | ||
275 | ret = crisv32_pinmux_dealloc(PORT_E, 0, 17); | ||
276 | hwprot.eth1 = regk_pinmux_no; | ||
277 | hwprot.eth1_mgm = regk_pinmux_no; | ||
278 | break; | ||
279 | case pinmux_timer: | ||
280 | ret = crisv32_pinmux_dealloc(PORT_C, 16, 16); | ||
281 | hwprot.timer = regk_pinmux_no; | ||
282 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | if (!ret) | ||
287 | REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); | ||
288 | else | ||
289 | memcpy(pins, saved, sizeof pins); | ||
290 | |||
291 | spin_unlock_irqrestore(&pinmux_lock, flags); | ||
292 | |||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | void crisv32_pinmux_dump(void) | ||
297 | { | ||
298 | int i, j; | ||
299 | |||
300 | crisv32_pinmux_init(); | ||
301 | |||
302 | for (i = 0; i < PORTS; i++) { | ||
303 | printk(KERN_DEBUG "Port %c\n", 'B' + i); | ||
304 | for (j = 0; j < PORT_PINS; j++) | ||
305 | printk(KERN_DEBUG " Pin %d = %d\n", j, pins[i][j]); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | __initcall(crisv32_pinmux_init); | ||
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.c b/arch/cris/arch-v32/mach-fs/vcs_hook.c new file mode 100644 index 000000000000..593b10f07ef1 --- /dev/null +++ b/arch/cris/arch-v32/mach-fs/vcs_hook.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Call simulator hook. This is the part running in the | ||
3 | * simulated program. | ||
4 | */ | ||
5 | |||
6 | #include "vcs_hook.h" | ||
7 | #include <stdarg.h> | ||
8 | #include <asm/arch-v32/hwregs/reg_map.h> | ||
9 | #include <asm/arch-v32/hwregs/intr_vect_defs.h> | ||
10 | |||
11 | #define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */ | ||
12 | #define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */ | ||
13 | |||
14 | #define HOOK_DATA(offset) ((unsigned *)HOOK_MEM_BASE_ADDR)[offset] | ||
15 | #define VHOOK_DATA(offset) ((volatile unsigned *)HOOK_MEM_BASE_ADDR)[offset] | ||
16 | #define HOOK_TRIG(funcid) \ | ||
17 | do { \ | ||
18 | *((unsigned *) HOOK_TRIG_ADDR) = funcid; \ | ||
19 | } while (0) | ||
20 | #define HOOK_DATA_BYTE(offset) ((unsigned char *)HOOK_MEM_BASE_ADDR)[offset] | ||
21 | |||
22 | int hook_call(unsigned id, unsigned pcnt, ...) | ||
23 | { | ||
24 | va_list ap; | ||
25 | unsigned i; | ||
26 | unsigned ret; | ||
27 | #ifdef USING_SOS | ||
28 | PREEMPT_OFF_SAVE(); | ||
29 | #endif | ||
30 | |||
31 | /* pass parameters */ | ||
32 | HOOK_DATA(0) = id; | ||
33 | |||
34 | /* Have to make hook_print_str a special case since we call with a | ||
35 | * parameter of byte type. Should perhaps be a separate | ||
36 | * hook_call. */ | ||
37 | |||
38 | if (id == hook_print_str) { | ||
39 | int i; | ||
40 | char *str; | ||
41 | |||
42 | HOOK_DATA(1) = pcnt; | ||
43 | |||
44 | va_start(ap, pcnt); | ||
45 | str = (char *)va_arg(ap, unsigned); | ||
46 | |||
47 | for (i = 0; i != pcnt; i++) | ||
48 | HOOK_DATA_BYTE(8 + i) = str[i]; | ||
49 | |||
50 | HOOK_DATA_BYTE(8 + i) = 0; /* null byte */ | ||
51 | } else { | ||
52 | va_start(ap, pcnt); | ||
53 | for (i = 1; i <= pcnt; i++) | ||
54 | HOOK_DATA(i) = va_arg(ap, unsigned); | ||
55 | va_end(ap); | ||
56 | } | ||
57 | |||
58 | /* read from mem to make sure data has propagated to memory before | ||
59 | * trigging */ | ||
60 | ret = *((volatile unsigned *)HOOK_MEM_BASE_ADDR); | ||
61 | |||
62 | /* trigger hook */ | ||
63 | HOOK_TRIG(id); | ||
64 | |||
65 | /* wait for call to finish */ | ||
66 | while (VHOOK_DATA(0) > 0) ; | ||
67 | |||
68 | /* extract return value */ | ||
69 | |||
70 | ret = VHOOK_DATA(1); | ||
71 | |||
72 | #ifdef USING_SOS | ||
73 | PREEMPT_RESTORE(); | ||
74 | #endif | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | unsigned hook_buf(unsigned i) | ||
79 | { | ||
80 | return (HOOK_DATA(i)); | ||
81 | } | ||
82 | |||
83 | void print_str(const char *str) | ||
84 | { | ||
85 | int i; | ||
86 | /* find null at end of string */ | ||
87 | for (i = 1; str[i]; i++) ; | ||
88 | hook_call(hook_print_str, i, str); | ||
89 | } | ||
90 | |||
91 | void CPU_KICK_DOG(void) | ||
92 | { | ||
93 | (void)hook_call(hook_kick_dog, 0); | ||
94 | } | ||
95 | |||
96 | void CPU_WATCHDOG_TIMEOUT(unsigned t) | ||
97 | { | ||
98 | (void)hook_call(hook_dog_timeout, 1, t); | ||
99 | } | ||
100 | |||
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.h b/arch/cris/arch-v32/mach-fs/vcs_hook.h index 7d73709e3cc6..c000b9fece41 100644 --- a/arch/cris/arch-v32/kernel/vcs_hook.h +++ b/arch/cris/arch-v32/mach-fs/vcs_hook.h | |||
@@ -1,11 +1,11 @@ | |||
1 | // $Id: vcs_hook.h,v 1.1 2003/08/12 12:01:06 starvik Exp $ | 1 | /* |
2 | // | 2 | * Call simulator hook functions |
3 | // Call simulator hook functions | 3 | */ |
4 | 4 | ||
5 | #ifndef HOOK_H | 5 | #ifndef HOOK_H |
6 | #define HOOK_H | 6 | #define HOOK_H |
7 | 7 | ||
8 | int hook_call( unsigned id, unsigned pcnt, ...); | 8 | int hook_call(unsigned id, unsigned pcnt, ...); |
9 | 9 | ||
10 | enum hook_ids { | 10 | enum hook_ids { |
11 | hook_debug_on = 1, | 11 | hook_debug_on = 1, |
diff --git a/arch/cris/arch-v32/mm/Makefile b/arch/cris/arch-v32/mm/Makefile index 9146f88484b1..0b801f2964ac 100644 --- a/arch/cris/arch-v32/mm/Makefile +++ b/arch/cris/arch-v32/mm/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | # Makefile for the Linux/cris parts of the memory manager. | 1 | # Makefile for the Linux/cris parts of the memory manager. |
2 | 2 | ||
3 | obj-y := mmu.o init.o tlb.o intmem.o | 3 | obj-y += mmu.o init.o tlb.o intmem.o |
4 | obj-$(CONFIG_ETRAX_L2CACHE) += l2cache.o | ||
diff --git a/arch/cris/arch-v32/mm/init.c b/arch/cris/arch-v32/mm/init.c index a84ba7ff22d2..5a9ac5834647 100644 --- a/arch/cris/arch-v32/mm/init.c +++ b/arch/cris/arch-v32/mm/init.c | |||
@@ -65,7 +65,7 @@ cris_mmu_init(void) | |||
65 | REG_STATE(mmu, rw_mm_cfg, seg_d, page) | | 65 | REG_STATE(mmu, rw_mm_cfg, seg_d, page) | |
66 | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) | | 66 | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) | |
67 | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) | | 67 | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) | |
68 | #ifndef CONFIG_ETRAXFS_SIM | 68 | #ifndef CONFIG_ETRAX_VCS_SIM |
69 | REG_STATE(mmu, rw_mm_cfg, seg_a, page) | | 69 | REG_STATE(mmu, rw_mm_cfg, seg_a, page) | |
70 | #else | 70 | #else |
71 | REG_STATE(mmu, rw_mm_cfg, seg_a, linear) | | 71 | REG_STATE(mmu, rw_mm_cfg, seg_a, linear) | |
@@ -84,13 +84,9 @@ cris_mmu_init(void) | |||
84 | mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) | | 84 | mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) | |
85 | REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) | | 85 | REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) | |
86 | REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) | | 86 | REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) | |
87 | #ifndef CONFIG_ETRAXFS_SIM | ||
88 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) | | 87 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) | |
89 | #else | ||
90 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x0) | | ||
91 | #endif | ||
92 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) | | 88 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) | |
93 | #ifndef CONFIG_ETRAXFS_SIM | 89 | #ifndef CONFIG_ETRAX_VCS_SIM |
94 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) | | 90 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) | |
95 | #else | 91 | #else |
96 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa) | | 92 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa) | |
diff --git a/arch/cris/arch-v32/mm/intmem.c b/arch/cris/arch-v32/mm/intmem.c index 41ee7f7997fd..9e8b69cdf19e 100644 --- a/arch/cris/arch-v32/mm/intmem.c +++ b/arch/cris/arch-v32/mm/intmem.c | |||
@@ -7,11 +7,17 @@ | |||
7 | #include <linux/list.h> | 7 | #include <linux/list.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <asm/io.h> | 9 | #include <asm/io.h> |
10 | #include <asm/arch/memmap.h> | 10 | #include <memmap.h> |
11 | 11 | ||
12 | #define STATUS_FREE 0 | 12 | #define STATUS_FREE 0 |
13 | #define STATUS_ALLOCATED 1 | 13 | #define STATUS_ALLOCATED 1 |
14 | 14 | ||
15 | #ifdef CONFIG_ETRAX_L2CACHE | ||
16 | #define RESERVED_SIZE 66*1024 | ||
17 | #else | ||
18 | #define RESERVED_SIZE 0 | ||
19 | #endif | ||
20 | |||
15 | struct intmem_allocation { | 21 | struct intmem_allocation { |
16 | struct list_head entry; | 22 | struct list_head entry; |
17 | unsigned int size; | 23 | unsigned int size; |
@@ -30,9 +36,10 @@ static void crisv32_intmem_init(void) | |||
30 | struct intmem_allocation* alloc = | 36 | struct intmem_allocation* alloc = |
31 | (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL); | 37 | (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL); |
32 | INIT_LIST_HEAD(&intmem_allocations); | 38 | INIT_LIST_HEAD(&intmem_allocations); |
33 | intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE); | 39 | intmem_virtual = ioremap(MEM_INTMEM_START + RESERVED_SIZE, |
40 | MEM_INTMEM_SIZE - RESERVED_SIZE); | ||
34 | initiated = 1; | 41 | initiated = 1; |
35 | alloc->size = MEM_INTMEM_SIZE; | 42 | alloc->size = MEM_INTMEM_SIZE - RESERVED_SIZE; |
36 | alloc->offset = 0; | 43 | alloc->offset = 0; |
37 | alloc->status = STATUS_FREE; | 44 | alloc->status = STATUS_FREE; |
38 | list_add_tail(&alloc->entry, &intmem_allocations); | 45 | list_add_tail(&alloc->entry, &intmem_allocations); |
@@ -59,19 +66,23 @@ void* crisv32_intmem_alloc(unsigned size, unsigned align) | |||
59 | (struct intmem_allocation*) | 66 | (struct intmem_allocation*) |
60 | kmalloc(sizeof *alloc, GFP_ATOMIC); | 67 | kmalloc(sizeof *alloc, GFP_ATOMIC); |
61 | alloc->status = STATUS_FREE; | 68 | alloc->status = STATUS_FREE; |
62 | alloc->size = allocation->size - size - alignment; | 69 | alloc->size = allocation->size - size - |
63 | alloc->offset = allocation->offset + size; | 70 | alignment; |
71 | alloc->offset = allocation->offset + size + | ||
72 | alignment; | ||
64 | list_add(&alloc->entry, &allocation->entry); | 73 | list_add(&alloc->entry, &allocation->entry); |
65 | 74 | ||
66 | if (alignment) { | 75 | if (alignment) { |
67 | struct intmem_allocation* tmp; | 76 | struct intmem_allocation *tmp; |
68 | tmp = (struct intmem_allocation*) | 77 | tmp = (struct intmem_allocation *) |
69 | kmalloc(sizeof *tmp, GFP_ATOMIC); | 78 | kmalloc(sizeof *tmp, |
79 | GFP_ATOMIC); | ||
70 | tmp->offset = allocation->offset; | 80 | tmp->offset = allocation->offset; |
71 | tmp->size = alignment; | 81 | tmp->size = alignment; |
72 | tmp->status = STATUS_FREE; | 82 | tmp->status = STATUS_FREE; |
73 | allocation->offset += alignment; | 83 | allocation->offset += alignment; |
74 | list_add_tail(&tmp->entry, &allocation->entry); | 84 | list_add_tail(&tmp->entry, |
85 | &allocation->entry); | ||
75 | } | 86 | } |
76 | } | 87 | } |
77 | allocation->status = STATUS_ALLOCATED; | 88 | allocation->status = STATUS_ALLOCATED; |
@@ -96,22 +107,24 @@ void crisv32_intmem_free(void* addr) | |||
96 | 107 | ||
97 | list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) { | 108 | list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) { |
98 | if (allocation->offset == (int)(addr - intmem_virtual)) { | 109 | if (allocation->offset == (int)(addr - intmem_virtual)) { |
99 | struct intmem_allocation* prev = | 110 | struct intmem_allocation *prev = |
100 | list_entry(allocation->entry.prev, | 111 | list_entry(allocation->entry.prev, |
101 | struct intmem_allocation, entry); | 112 | struct intmem_allocation, entry); |
102 | struct intmem_allocation* next = | 113 | struct intmem_allocation *next = |
103 | list_entry(allocation->entry.next, | 114 | list_entry(allocation->entry.next, |
104 | struct intmem_allocation, entry); | 115 | struct intmem_allocation, entry); |
105 | 116 | ||
106 | allocation->status = STATUS_FREE; | 117 | allocation->status = STATUS_FREE; |
107 | /* Join with prev and/or next if also free */ | 118 | /* Join with prev and/or next if also free */ |
108 | if (prev->status == STATUS_FREE) { | 119 | if ((prev != &intmem_allocations) && |
120 | (prev->status == STATUS_FREE)) { | ||
109 | prev->size += allocation->size; | 121 | prev->size += allocation->size; |
110 | list_del(&allocation->entry); | 122 | list_del(&allocation->entry); |
111 | kfree(allocation); | 123 | kfree(allocation); |
112 | allocation = prev; | 124 | allocation = prev; |
113 | } | 125 | } |
114 | if (next->status == STATUS_FREE) { | 126 | if ((next != &intmem_allocations) && |
127 | (next->status == STATUS_FREE)) { | ||
115 | allocation->size += next->size; | 128 | allocation->size += next->size; |
116 | list_del(&next->entry); | 129 | list_del(&next->entry); |
117 | kfree(next); | 130 | kfree(next); |
@@ -125,15 +138,16 @@ void crisv32_intmem_free(void* addr) | |||
125 | 138 | ||
126 | void* crisv32_intmem_phys_to_virt(unsigned long addr) | 139 | void* crisv32_intmem_phys_to_virt(unsigned long addr) |
127 | { | 140 | { |
128 | return (void*)(addr - MEM_INTMEM_START+ | 141 | return (void *)(addr - (MEM_INTMEM_START + RESERVED_SIZE) + |
129 | (unsigned long)intmem_virtual); | 142 | (unsigned long)intmem_virtual); |
130 | } | 143 | } |
131 | 144 | ||
132 | unsigned long crisv32_intmem_virt_to_phys(void* addr) | 145 | unsigned long crisv32_intmem_virt_to_phys(void* addr) |
133 | { | 146 | { |
134 | return (unsigned long)((unsigned long )addr - | 147 | return (unsigned long)((unsigned long )addr - |
135 | (unsigned long)intmem_virtual + MEM_INTMEM_START); | 148 | (unsigned long)intmem_virtual + MEM_INTMEM_START + |
149 | RESERVED_SIZE); | ||
136 | } | 150 | } |
137 | 151 | ||
138 | 152 | module_init(crisv32_intmem_init); | |
139 | 153 | ||
diff --git a/arch/cris/arch-v32/mm/l2cache.c b/arch/cris/arch-v32/mm/l2cache.c new file mode 100644 index 000000000000..332ff10dcc6b --- /dev/null +++ b/arch/cris/arch-v32/mm/l2cache.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <memmap.h> | ||
5 | #include <hwregs/reg_map.h> | ||
6 | #include <hwregs/reg_rdwr.h> | ||
7 | #include <hwregs/l2cache_defs.h> | ||
8 | #include <asm/io.h> | ||
9 | |||
10 | #define L2CACHE_SIZE 64 | ||
11 | |||
12 | int __init l2cache_init(void) | ||
13 | { | ||
14 | reg_l2cache_rw_ctrl ctrl = {0}; | ||
15 | reg_l2cache_rw_cfg cfg = {.en = regk_l2cache_yes}; | ||
16 | |||
17 | ctrl.csize = L2CACHE_SIZE; | ||
18 | ctrl.cbase = L2CACHE_SIZE / 4 + (L2CACHE_SIZE % 4 ? 1 : 0); | ||
19 | REG_WR(l2cache, regi_l2cache, rw_ctrl, ctrl); | ||
20 | |||
21 | /* Flush the tag memory */ | ||
22 | memset((void *)(MEM_INTMEM_START | MEM_NON_CACHEABLE), 0, 2*1024); | ||
23 | |||
24 | /* Enable the cache */ | ||
25 | REG_WR(l2cache, regi_l2cache, rw_cfg, cfg); | ||
26 | |||
27 | return 0; | ||
28 | } | ||
29 | |||
diff --git a/arch/cris/arch-v32/mm/mmu.S b/arch/cris/arch-v32/mm/mmu.S index 27b70e5006af..2238d154bde3 100644 --- a/arch/cris/arch-v32/mm/mmu.S +++ b/arch/cris/arch-v32/mm/mmu.S | |||
@@ -1,3 +1,5 @@ | |||
1 | ; WARNING : The refill handler has been modified, see below !!! | ||
2 | |||
1 | /* | 3 | /* |
2 | * Copyright (C) 2003 Axis Communications AB | 4 | * Copyright (C) 2003 Axis Communications AB |
3 | * | 5 | * |
@@ -61,6 +63,14 @@ | |||
61 | ; Note that the code is optimized to minimize stalls (makes the code harder | 63 | ; Note that the code is optimized to minimize stalls (makes the code harder |
62 | ; to read). | 64 | ; to read). |
63 | ; | 65 | ; |
66 | ; WARNING !!! | ||
67 | ; Modified by Mikael Asker 060725: added a workaround for strange TLB | ||
68 | ; behavior. If the same PTE is present in more than one set, the TLB | ||
69 | ; doesn't recognize it and we get stuck in a loop of refill exceptions. | ||
70 | ; The workaround detects such loops and exits them by flushing | ||
71 | ; the TLB contents. The problem and workaround were verified | ||
72 | ; in VCS by Mikael Starvik. | ||
73 | ; | ||
64 | ; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each | 74 | ; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each |
65 | ; PMD holds 16 MB of virtual memory. | 75 | ; PMD holds 16 MB of virtual memory. |
66 | ; Bits 0-12 : Offset within a page | 76 | ; Bits 0-12 : Offset within a page |
@@ -68,6 +78,11 @@ | |||
68 | ; Bits 24-31 : PMD offset within the PGD | 78 | ; Bits 24-31 : PMD offset within the PGD |
69 | 79 | ||
70 | .macro MMU_REFILL_HANDLER handler, mmu | 80 | .macro MMU_REFILL_HANDLER handler, mmu |
81 | .data | ||
82 | 1: .dword 0 ; refill_count | ||
83 | ; == 0 <=> last_refill_cause is invalid | ||
84 | 2: .dword 0 ; last_refill_cause | ||
85 | .text | ||
71 | .globl \handler | 86 | .globl \handler |
72 | \handler: | 87 | \handler: |
73 | subq 4, $sp | 88 | subq 4, $sp |
@@ -76,42 +91,96 @@ | |||
76 | subq 4, $sp | 91 | subq 4, $sp |
77 | move \mmu, $srs ; Select MMU support register bank | 92 | move \mmu, $srs ; Select MMU support register bank |
78 | move.d $acr, [$sp] | 93 | move.d $acr, [$sp] |
79 | subq 4, $sp | 94 | subq 12, $sp |
80 | move.d $r0, [$sp] | 95 | move.d 1b, $acr ; Point to refill_count |
96 | movem $r2, [$sp] | ||
97 | |||
98 | test.d [$acr] ; refill_count == 0 ? | ||
99 | beq 5f ; yes, last_refill_cause is invalid | ||
100 | move.d $acr, $r1 | ||
101 | |||
102 | ; last_refill_cause is valid, investigate cause | ||
103 | addq 4, $r1 ; Point to last_refill_cause | ||
104 | move $s3, $r0 ; Get rw_mm_cause | ||
105 | move.d [$r1], $r2 ; Get last_refill_cause | ||
106 | cmp.d $r0, $r2 ; rw_mm_cause == last_refill_cause ? | ||
107 | beq 6f ; yes, increment count | ||
108 | moveq 1, $r2 | ||
109 | |||
110 | ; rw_mm_cause != last_refill_cause | ||
111 | move.d $r2, [$acr] ; refill_count = 1 | ||
112 | move.d $r0, [$r1] ; last_refill_cause = rw_mm_cause | ||
113 | |||
114 | 3: ; Probably not in a loop, continue normal processing | ||
81 | #ifdef CONFIG_SMP | 115 | #ifdef CONFIG_SMP |
82 | move $s7, $acr ; PGD | 116 | move $s7, $acr ; PGD |
83 | #else | 117 | #else |
84 | move.d per_cpu__current_pgd, $acr ; PGD | 118 | move.d per_cpu__current_pgd, $acr ; PGD |
85 | #endif | 119 | #endif |
86 | ; Look up PMD in PGD | 120 | ; Look up PMD in PGD |
87 | move $s3, $r0 ; rw_mm_cause | ||
88 | lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31) | 121 | lsrq 24, $r0 ; Get PMD index into PGD (bit 24-31) |
89 | move.d [$acr], $acr ; PGD for the current process | 122 | move.d [$acr], $acr ; PGD for the current process |
90 | addi $r0.d, $acr, $acr | 123 | addi $r0.d, $acr, $acr |
91 | move $s3, $r0 ; rw_mm_cause | 124 | move $s3, $r0 ; rw_mm_cause |
92 | move.d [$acr], $acr ; Get PMD | 125 | move.d [$acr], $acr ; Get PMD |
93 | beq 1f | 126 | beq 8f |
94 | ; Look up PTE in PMD | 127 | ; Look up PTE in PMD |
95 | lsrq PAGE_SHIFT, $r0 | 128 | lsrq PAGE_SHIFT, $r0 |
96 | and.w PAGE_MASK, $acr ; Remove PMD flags | 129 | and.w PAGE_MASK, $acr ; Remove PMD flags |
97 | and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23) | 130 | and.d 0x7ff, $r0 ; Get PTE index into PMD (bit 13-23) |
98 | addi $r0.d, $acr, $acr | 131 | addi $r0.d, $acr, $acr |
99 | move.d [$acr], $acr ; Get PTE | 132 | move.d [$acr], $acr ; Get PTE |
100 | beq 2f | 133 | beq 9f |
101 | move.d [$sp+], $r0 ; Pop r0 in delayslot | 134 | movem [$sp], $r2 ; Restore r0-r2 in delay slot |
135 | addq 12, $sp | ||
102 | ; Store in TLB | 136 | ; Store in TLB |
103 | move $acr, $s5 | 137 | move $acr, $s5 |
104 | ; Return | 138 | 4: ; Return |
105 | move.d [$sp+], $acr | 139 | move.d [$sp+], $acr |
106 | move [$sp], $srs | 140 | move [$sp], $srs |
107 | addq 4, $sp | 141 | addq 4, $sp |
108 | rete | 142 | rete |
109 | rfe | 143 | rfe |
110 | 1: ; PMD missing, let the mm subsystem fix it up. | 144 | |
111 | move.d [$sp+], $r0 ; Pop r0 | 145 | 5: ; last_refill_cause is invalid |
112 | 2: ; PTE missing, let the mm subsystem fix it up. | 146 | moveq 1, $r2 |
147 | addq 4, $r1 ; Point to last_refill_cause | ||
148 | move.d $r2, [$acr] ; refill_count = 1 | ||
149 | move $s3, $r0 ; Get rw_mm_cause | ||
150 | ba 3b ; Continue normal processing | ||
151 | move.d $r0,[$r1] ; last_refill_cause = rw_mm_cause | ||
152 | |||
153 | 6: ; rw_mm_cause == last_refill_cause | ||
154 | move.d [$acr], $r2 ; Get refill_count | ||
155 | cmpq 4, $r2 ; refill_count > 4 ? | ||
156 | bhi 7f ; yes | ||
157 | addq 1, $r2 ; refill_count++ | ||
158 | ba 3b ; Continue normal processing | ||
159 | move.d $r2, [$acr] | ||
160 | |||
161 | 7: ; refill_count > 4, error | ||
162 | move.d $acr, $r0 ; Save pointer to refill_count | ||
163 | clear.d [$r0] ; refill_count = 0 | ||
164 | |||
165 | ;; rewind the short stack | ||
166 | movem [$sp], $r2 ; Restore r0-r2 | ||
167 | addq 12, $sp | ||
168 | move.d [$sp+], $acr | ||
169 | move [$sp], $srs | ||
170 | addq 4, $sp | ||
171 | ;; Keep it simple (slow), save all the regs. | ||
172 | SAVE_ALL | ||
173 | jsr __flush_tlb_all | ||
174 | nop | ||
175 | ba ret_from_intr ; Return | ||
176 | nop | ||
177 | |||
178 | 8: ; PMD missing, let the mm subsystem fix it up. | ||
179 | movem [$sp], $r2 ; Restore r0-r2 | ||
180 | 9: ; PTE missing, let the mm subsystem fix it up. | ||
181 | addq 12, $sp | ||
113 | move.d [$sp+], $acr | 182 | move.d [$sp+], $acr |
114 | move [$sp], $srs | 183 | move [$sp], $srs |
115 | addq 4, $sp | 184 | addq 4, $sp |
116 | SAVE_ALL | 185 | SAVE_ALL |
117 | move \mmu, $srs | 186 | move \mmu, $srs |
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c index a076ef6e9389..eda5ebcaea54 100644 --- a/arch/cris/arch-v32/mm/tlb.c +++ b/arch/cris/arch-v32/mm/tlb.c | |||
@@ -13,8 +13,8 @@ | |||
13 | #include <asm/arch/hwregs/supp_reg.h> | 13 | #include <asm/arch/hwregs/supp_reg.h> |
14 | 14 | ||
15 | #define UPDATE_TLB_SEL_IDX(val) \ | 15 | #define UPDATE_TLB_SEL_IDX(val) \ |
16 | do { \ | 16 | do { \ |
17 | unsigned long tlb_sel; \ | 17 | unsigned long tlb_sel; \ |
18 | \ | 18 | \ |
19 | tlb_sel = REG_FIELD(mmu, rw_mm_tlb_sel, idx, val); \ | 19 | tlb_sel = REG_FIELD(mmu, rw_mm_tlb_sel, idx, val); \ |
20 | SUPP_REG_WR(RW_MM_TLB_SEL, tlb_sel); \ | 20 | SUPP_REG_WR(RW_MM_TLB_SEL, tlb_sel); \ |
@@ -30,8 +30,8 @@ do { \ | |||
30 | * The TLB can host up to 256 different mm contexts at the same time. The running | 30 | * The TLB can host up to 256 different mm contexts at the same time. The running |
31 | * context is found in the PID register. Each TLB entry contains a page_id that | 31 | * context is found in the PID register. Each TLB entry contains a page_id that |
32 | * has to match the PID register to give a hit. page_id_map keeps track of which | 32 | * has to match the PID register to give a hit. page_id_map keeps track of which |
33 | * mm is assigned to which page_id, making sure it's known when to invalidate TLB | 33 | * mm's is assigned to which page_id's, making sure it's known when to |
34 | * entries. | 34 | * invalidate TLB entries. |
35 | * | 35 | * |
36 | * The last page_id is never running, it is used as an invalid page_id so that | 36 | * The last page_id is never running, it is used as an invalid page_id so that |
37 | * it's possible to make TLB entries that will nerver match. | 37 | * it's possible to make TLB entries that will nerver match. |
@@ -179,29 +179,29 @@ void | |||
179 | switch_mm(struct mm_struct *prev, struct mm_struct *next, | 179 | switch_mm(struct mm_struct *prev, struct mm_struct *next, |
180 | struct task_struct *tsk) | 180 | struct task_struct *tsk) |
181 | { | 181 | { |
182 | int cpu = smp_processor_id(); | 182 | if (prev != next) { |
183 | 183 | int cpu = smp_processor_id(); | |
184 | /* Make sure there is a MMU context. */ | 184 | |
185 | spin_lock(&mmu_context_lock); | 185 | /* Make sure there is a MMU context. */ |
186 | get_mmu_context(next); | 186 | spin_lock(&mmu_context_lock); |
187 | cpu_set(cpu, next->cpu_vm_mask); | 187 | get_mmu_context(next); |
188 | spin_unlock(&mmu_context_lock); | 188 | cpu_set(cpu, next->cpu_vm_mask); |
189 | 189 | spin_unlock(&mmu_context_lock); | |
190 | /* | 190 | |
191 | * Remember the pgd for the fault handlers. Keep a separate copy of it | 191 | /* |
192 | * because current and active_mm might be invalid at points where | 192 | * Remember the pgd for the fault handlers. Keep a seperate |
193 | * there's still a need to derefer the pgd. | 193 | * copy of it because current and active_mm might be invalid |
194 | */ | 194 | * at points where * there's still a need to derefer the pgd. |
195 | per_cpu(current_pgd, cpu) = next->pgd; | 195 | */ |
196 | 196 | per_cpu(current_pgd, cpu) = next->pgd; | |
197 | /* Switch context in the MMU. */ | 197 | |
198 | if (tsk && task_thread_info(tsk)) | 198 | /* Switch context in the MMU. */ |
199 | { | 199 | if (tsk && task_thread_info(tsk)) { |
200 | SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | task_thread_info(tsk)->tls); | 200 | SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | |
201 | } | 201 | task_thread_info(tsk)->tls); |
202 | else | 202 | } else { |
203 | { | 203 | SPEC_REG_WR(SPEC_REG_PID, next->context.page_id); |
204 | SPEC_REG_WR(SPEC_REG_PID, next->context.page_id); | 204 | } |
205 | } | 205 | } |
206 | } | 206 | } |
207 | 207 | ||
diff --git a/arch/cris/arch-v32/vmlinux.lds.S b/arch/cris/arch-v32/vmlinux.lds.S index fead8c59ea63..d5f28e40717c 100644 --- a/arch/cris/arch-v32/vmlinux.lds.S +++ b/arch/cris/arch-v32/vmlinux.lds.S | |||
@@ -9,6 +9,13 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <asm-generic/vmlinux.lds.h> | 11 | #include <asm-generic/vmlinux.lds.h> |
12 | #include <asm/page.h> | ||
13 | |||
14 | #ifdef CONFIG_ETRAX_VMEM_SIZE | ||
15 | #define __CONFIG_ETRAX_VMEM_SIZE CONFIG_ETRAX_VMEM_SIZE | ||
16 | #else | ||
17 | #define __CONFIG_ETRAX_VMEM_SIZE 0 | ||
18 | #endif | ||
12 | 19 | ||
13 | jiffies = jiffies_64; | 20 | jiffies = jiffies_64; |
14 | SECTIONS | 21 | SECTIONS |
@@ -17,18 +24,19 @@ SECTIONS | |||
17 | dram_start = .; | 24 | dram_start = .; |
18 | ebp_start = .; | 25 | ebp_start = .; |
19 | 26 | ||
20 | /* The boot section is only necessary until the VCS top level testbench */ | 27 | /* The boot section is only necessary until the VCS top */ |
21 | /* includes both flash and DRAM. */ | 28 | /* level testbench includes both flash and DRAM. */ |
22 | .boot : { *(.boot) } | 29 | .boot : { *(.boot) } |
23 | 30 | ||
24 | . = DRAM_VIRTUAL_BASE + 0x4000; /* See head.S and pages reserved at the start. */ | 31 | /* See head.S and pages reserved at the start. */ |
32 | . = DRAM_VIRTUAL_BASE + 0x4000; | ||
25 | 33 | ||
26 | _text = .; /* Text and read-only data. */ | 34 | _text = .; /* Text and read-only data. */ |
27 | text_start = .; /* Lots of aliases. */ | 35 | text_start = .; /* Lots of aliases. */ |
28 | _stext = .; | 36 | _stext = .; |
29 | __stext = .; | 37 | __stext = .; |
30 | .text : { | 38 | .text : { |
31 | *(.text) | 39 | TEXT_TEXT |
32 | SCHED_TEXT | 40 | SCHED_TEXT |
33 | LOCK_TEXT | 41 | LOCK_TEXT |
34 | *(.fixup) | 42 | *(.fixup) |
@@ -39,9 +47,9 @@ SECTIONS | |||
39 | __etext = .; | 47 | __etext = .; |
40 | 48 | ||
41 | . = ALIGN(4); /* Exception table. */ | 49 | . = ALIGN(4); /* Exception table. */ |
42 | __start___ex_table = .; | 50 | __start___ex_table = .; |
43 | __ex_table : { *(__ex_table) } | 51 | __ex_table : { *(__ex_table) } |
44 | __stop___ex_table = .; | 52 | __stop___ex_table = .; |
45 | 53 | ||
46 | RODATA | 54 | RODATA |
47 | 55 | ||
@@ -54,33 +62,27 @@ SECTIONS | |||
54 | __edata = . ; /* End of data section. */ | 62 | __edata = . ; /* End of data section. */ |
55 | _edata = . ; | 63 | _edata = . ; |
56 | 64 | ||
57 | . = ALIGN(8192); /* init_task and stack, must be aligned. */ | 65 | . = ALIGN(PAGE_SIZE); /* init_task and stack, must be aligned. */ |
58 | .data.init_task : { *(.data.init_task) } | 66 | .data.init_task : { *(.data.init_task) } |
59 | 67 | ||
60 | . = ALIGN(8192); /* Init code and data. */ | 68 | . = ALIGN(PAGE_SIZE); /* Init code and data. */ |
61 | __init_begin = .; | 69 | __init_begin = .; |
62 | .init.text : { | 70 | .init.text : { |
63 | _sinittext = .; | 71 | _sinittext = .; |
64 | INIT_TEXT | 72 | INIT_TEXT |
65 | _einittext = .; | 73 | _einittext = .; |
66 | } | 74 | } |
67 | .init.data : { INIT_DATA } | 75 | .init.data : { INIT_DATA } |
68 | . = ALIGN(16); | 76 | . = ALIGN(16); |
69 | __setup_start = .; | 77 | __setup_start = .; |
70 | .init.setup : { *(.init.setup) } | 78 | .init.setup : { *(.init.setup) } |
71 | __setup_end = .; | 79 | __setup_end = .; |
72 | __start___param = .; | 80 | __start___param = .; |
73 | __param : { *(__param) } | 81 | __param : { *(__param) } |
74 | __stop___param = .; | 82 | __stop___param = .; |
75 | .initcall.init : { | 83 | .initcall.init : { |
76 | __initcall_start = .; | 84 | __initcall_start = .; |
77 | *(.initcall1.init); | 85 | INITCALLS |
78 | *(.initcall2.init); | ||
79 | *(.initcall3.init); | ||
80 | *(.initcall4.init); | ||
81 | *(.initcall5.init); | ||
82 | *(.initcall6.init); | ||
83 | *(.initcall7.init); | ||
84 | __initcall_end = .; | 86 | __initcall_end = .; |
85 | } | 87 | } |
86 | 88 | ||
@@ -91,25 +93,23 @@ SECTIONS | |||
91 | } | 93 | } |
92 | SECURITY_INIT | 94 | SECURITY_INIT |
93 | 95 | ||
94 | PERCPU(8192) | 96 | __vmlinux_end = .; /* Last address of the physical file. */ |
97 | PERCPU(PAGE_SIZE) | ||
95 | 98 | ||
96 | #ifdef CONFIG_BLK_DEV_INITRD | ||
97 | .init.ramfs : { | 99 | .init.ramfs : { |
98 | __initramfs_start = .; | 100 | __initramfs_start = .; |
99 | *(.init.ramfs) | 101 | *(.init.ramfs) |
100 | __initramfs_end = .; | 102 | __initramfs_end = .; |
101 | /* | ||
102 | * We fill to the next page, so we can discard all init | ||
103 | * pages without needing to consider what payload might be | ||
104 | * appended to the kernel image. | ||
105 | */ | ||
106 | FILL (0); | ||
107 | . = ALIGN (8192); | ||
108 | } | 103 | } |
109 | #endif | ||
110 | 104 | ||
111 | __vmlinux_end = .; /* Last address of the physical file. */ | 105 | /* |
112 | __init_end = .; | 106 | * We fill to the next page, so we can discard all init |
107 | * pages without needing to consider what payload might be | ||
108 | * appended to the kernel image. | ||
109 | */ | ||
110 | . = ALIGN (PAGE_SIZE); | ||
111 | |||
112 | __init_end = .; | ||
113 | 113 | ||
114 | __data_end = . ; /* Move to _edata? */ | 114 | __data_end = . ; /* Move to _edata? */ |
115 | __bss_start = .; /* BSS. */ | 115 | __bss_start = .; /* BSS. */ |
@@ -123,11 +123,11 @@ SECTIONS | |||
123 | __end = .; | 123 | __end = .; |
124 | 124 | ||
125 | /* Sections to be discarded */ | 125 | /* Sections to be discarded */ |
126 | /DISCARD/ : { | 126 | /DISCARD/ : { |
127 | EXIT_TEXT | 127 | EXIT_TEXT |
128 | EXIT_DATA | 128 | EXIT_DATA |
129 | *(.exitcall.exit) | 129 | *(.exitcall.exit) |
130 | } | 130 | } |
131 | 131 | ||
132 | dram_end = dram_start + CONFIG_ETRAX_DRAM_SIZE*1024*1024; | 132 | dram_end = dram_start + (CONFIG_ETRAX_DRAM_SIZE - __CONFIG_ETRAX_VMEM_SIZE)*1024*1024; |
133 | } | 133 | } |
diff --git a/arch/cris/artpec_3_defconfig b/arch/cris/artpec_3_defconfig new file mode 100644 index 000000000000..41fe67409aab --- /dev/null +++ b/arch/cris/artpec_3_defconfig | |||
@@ -0,0 +1,582 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.24-rc3 | ||
4 | # Mon Dec 3 11:18:54 2007 | ||
5 | # | ||
6 | CONFIG_MMU=y | ||
7 | CONFIG_ZONE_DMA=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_IOMAP=y | ||
10 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
11 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
12 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
13 | CONFIG_GENERIC_HWEIGHT=y | ||
14 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
15 | CONFIG_NO_IOPORT=y | ||
16 | CONFIG_FORCE_MAX_ZONEORDER=6 | ||
17 | CONFIG_CRIS=y | ||
18 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_EXPERIMENTAL=y | ||
24 | CONFIG_BROKEN_ON_SMP=y | ||
25 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
26 | CONFIG_LOCALVERSION="" | ||
27 | CONFIG_LOCALVERSION_AUTO=y | ||
28 | # CONFIG_SWAP is not set | ||
29 | # CONFIG_SYSVIPC is not set | ||
30 | # CONFIG_POSIX_MQUEUE is not set | ||
31 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
32 | # CONFIG_TASKSTATS is not set | ||
33 | # CONFIG_USER_NS is not set | ||
34 | # CONFIG_PID_NS is not set | ||
35 | # CONFIG_AUDIT is not set | ||
36 | # CONFIG_IKCONFIG is not set | ||
37 | CONFIG_LOG_BUF_SHIFT=14 | ||
38 | # CONFIG_CGROUPS is not set | ||
39 | CONFIG_FAIR_GROUP_SCHED=y | ||
40 | CONFIG_FAIR_USER_SCHED=y | ||
41 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
42 | CONFIG_SYSFS_DEPRECATED=y | ||
43 | # CONFIG_RELAY is not set | ||
44 | # CONFIG_BLK_DEV_INITRD is not set | ||
45 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
46 | CONFIG_SYSCTL=y | ||
47 | CONFIG_EMBEDDED=y | ||
48 | CONFIG_UID16=y | ||
49 | CONFIG_SYSCTL_SYSCALL=y | ||
50 | # CONFIG_KALLSYMS is not set | ||
51 | # CONFIG_HOTPLUG is not set | ||
52 | CONFIG_PRINTK=y | ||
53 | CONFIG_BUG=y | ||
54 | CONFIG_ELF_CORE=y | ||
55 | CONFIG_BASE_FULL=y | ||
56 | CONFIG_FUTEX=y | ||
57 | CONFIG_ANON_INODES=y | ||
58 | CONFIG_EPOLL=y | ||
59 | CONFIG_SIGNALFD=y | ||
60 | CONFIG_EVENTFD=y | ||
61 | CONFIG_SHMEM=y | ||
62 | CONFIG_VM_EVENT_COUNTERS=y | ||
63 | CONFIG_SLUB_DEBUG=y | ||
64 | # CONFIG_SLAB is not set | ||
65 | CONFIG_SLUB=y | ||
66 | # CONFIG_SLOB is not set | ||
67 | CONFIG_RT_MUTEXES=y | ||
68 | # CONFIG_TINY_SHMEM is not set | ||
69 | CONFIG_BASE_SMALL=0 | ||
70 | # CONFIG_MODULES is not set | ||
71 | CONFIG_BLOCK=y | ||
72 | # CONFIG_LBD is not set | ||
73 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
74 | # CONFIG_LSF is not set | ||
75 | # CONFIG_BLK_DEV_BSG is not set | ||
76 | |||
77 | # | ||
78 | # IO Schedulers | ||
79 | # | ||
80 | CONFIG_IOSCHED_NOOP=y | ||
81 | # CONFIG_IOSCHED_AS is not set | ||
82 | # CONFIG_IOSCHED_DEADLINE is not set | ||
83 | CONFIG_IOSCHED_CFQ=y | ||
84 | # CONFIG_DEFAULT_AS is not set | ||
85 | # CONFIG_DEFAULT_DEADLINE is not set | ||
86 | CONFIG_DEFAULT_CFQ=y | ||
87 | # CONFIG_DEFAULT_NOOP is not set | ||
88 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
89 | |||
90 | # | ||
91 | # General setup | ||
92 | # | ||
93 | CONFIG_BINFMT_ELF=y | ||
94 | # CONFIG_BINFMT_MISC is not set | ||
95 | CONFIG_GENERIC_HARDIRQS=y | ||
96 | CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock3 init=/linuxrc" | ||
97 | # CONFIG_ETRAX_WATCHDOG is not set | ||
98 | CONFIG_ETRAX_FAST_TIMER=y | ||
99 | # CONFIG_ETRAX_KMALLOCED_MODULES is not set | ||
100 | # CONFIG_OOM_REBOOT is not set | ||
101 | CONFIG_PREEMPT_NONE=y | ||
102 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
103 | # CONFIG_PREEMPT is not set | ||
104 | CONFIG_SELECT_MEMORY_MODEL=y | ||
105 | CONFIG_FLATMEM_MANUAL=y | ||
106 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
107 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
108 | CONFIG_FLATMEM=y | ||
109 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
110 | # CONFIG_SPARSEMEM_STATIC is not set | ||
111 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
112 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
113 | # CONFIG_RESOURCES_64BIT is not set | ||
114 | CONFIG_ZONE_DMA_FLAG=1 | ||
115 | CONFIG_BOUNCE=y | ||
116 | CONFIG_VIRT_TO_BUS=y | ||
117 | |||
118 | # | ||
119 | # Hardware setup | ||
120 | # | ||
121 | # CONFIG_ETRAX100LX is not set | ||
122 | # CONFIG_ETRAX100LX_V2 is not set | ||
123 | # CONFIG_SVINTO_SIM is not set | ||
124 | # CONFIG_ETRAXFS is not set | ||
125 | CONFIG_CRIS_MACH_ARTPEC3=y | ||
126 | # CONFIG_ETRAX_VCS_SIM is not set | ||
127 | # CONFIG_ETRAX_ARCH_V10 is not set | ||
128 | CONFIG_ETRAX_ARCH_V32=y | ||
129 | CONFIG_ETRAX_DRAM_SIZE=32 | ||
130 | CONFIG_ETRAX_VMEM_SIZE=8 | ||
131 | CONFIG_ETRAX_FLASH_BUSWIDTH=2 | ||
132 | CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1 | ||
133 | CONFIG_ETRAX_FLASH1_SIZE=4 | ||
134 | CONFIG_ETRAX_DEBUG_PORT0=y | ||
135 | # CONFIG_ETRAX_DEBUG_PORT1 is not set | ||
136 | # CONFIG_ETRAX_DEBUG_PORT2 is not set | ||
137 | # CONFIG_ETRAX_DEBUG_PORT3 is not set | ||
138 | # CONFIG_ETRAX_DEBUG_PORT_NULL is not set | ||
139 | CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000 | ||
140 | CONFIG_ETRAX_SERIAL_PORTS=5 | ||
141 | CONFIG_ETRAX_DEF_GIO_PA_OE=1c | ||
142 | CONFIG_ETRAX_DEF_GIO_PA_OUT=00 | ||
143 | CONFIG_ETRAX_DEF_GIO_PB_OE=00000 | ||
144 | CONFIG_ETRAX_DEF_GIO_PB_OUT=00000 | ||
145 | CONFIG_ETRAX_DEF_GIO_PC_OE=00000 | ||
146 | CONFIG_ETRAX_DEF_GIO_PC_OUT=00000 | ||
147 | |||
148 | # | ||
149 | # Artpec-3 options | ||
150 | # | ||
151 | CONFIG_ETRAX_L2CACHE=y | ||
152 | CONFIG_ETRAX_DDR=y | ||
153 | CONFIG_ETRAX_DDR2_MRS=0 | ||
154 | CONFIG_ETRAX_DDR2_TIMING=0 | ||
155 | CONFIG_ETRAX_DDR2_CONFIG=0 | ||
156 | CONFIG_ETRAX_PIO_CE0_CFG=0 | ||
157 | CONFIG_ETRAX_PIO_CE1_CFG=0 | ||
158 | CONFIG_ETRAX_PIO_CE2_CFG=0 | ||
159 | # CONFIG_CPU_FREQ is not set | ||
160 | # CONFIG_ETRAX_NBR_LED_GRP_ZERO is not set | ||
161 | CONFIG_ETRAX_NBR_LED_GRP_ONE=y | ||
162 | # CONFIG_ETRAX_NBR_LED_GRP_TWO is not set | ||
163 | CONFIG_ETRAX_LED_G_NET0="PA3" | ||
164 | CONFIG_ETRAX_LED_R_NET0="PA4" | ||
165 | CONFIG_ETRAX_V32_LED2G="PA5" | ||
166 | CONFIG_ETRAX_V32_LED2R="PA6" | ||
167 | CONFIG_ETRAX_V32_LED3G="PA7" | ||
168 | CONFIG_ETRAX_V32_LED3R="PA7" | ||
169 | |||
170 | # | ||
171 | # Networking | ||
172 | # | ||
173 | CONFIG_NET=y | ||
174 | |||
175 | # | ||
176 | # Networking options | ||
177 | # | ||
178 | CONFIG_PACKET=y | ||
179 | # CONFIG_PACKET_MMAP is not set | ||
180 | CONFIG_UNIX=y | ||
181 | CONFIG_XFRM=y | ||
182 | # CONFIG_XFRM_USER is not set | ||
183 | # CONFIG_XFRM_SUB_POLICY is not set | ||
184 | # CONFIG_XFRM_MIGRATE is not set | ||
185 | # CONFIG_NET_KEY is not set | ||
186 | CONFIG_INET=y | ||
187 | # CONFIG_IP_MULTICAST is not set | ||
188 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
189 | CONFIG_IP_FIB_HASH=y | ||
190 | # CONFIG_IP_PNP is not set | ||
191 | # CONFIG_NET_IPIP is not set | ||
192 | # CONFIG_NET_IPGRE is not set | ||
193 | # CONFIG_ARPD is not set | ||
194 | # CONFIG_SYN_COOKIES is not set | ||
195 | # CONFIG_INET_AH is not set | ||
196 | # CONFIG_INET_ESP is not set | ||
197 | # CONFIG_INET_IPCOMP is not set | ||
198 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
199 | # CONFIG_INET_TUNNEL is not set | ||
200 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
201 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
202 | CONFIG_INET_XFRM_MODE_BEET=y | ||
203 | # CONFIG_INET_LRO is not set | ||
204 | CONFIG_INET_DIAG=y | ||
205 | CONFIG_INET_TCP_DIAG=y | ||
206 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
207 | CONFIG_TCP_CONG_CUBIC=y | ||
208 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
209 | # CONFIG_TCP_MD5SIG is not set | ||
210 | # CONFIG_IP_VS is not set | ||
211 | # CONFIG_IPV6 is not set | ||
212 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
213 | # CONFIG_INET6_TUNNEL is not set | ||
214 | # CONFIG_NETWORK_SECMARK is not set | ||
215 | CONFIG_NETFILTER=y | ||
216 | # CONFIG_NETFILTER_DEBUG is not set | ||
217 | |||
218 | # | ||
219 | # Core Netfilter Configuration | ||
220 | # | ||
221 | # CONFIG_NETFILTER_NETLINK is not set | ||
222 | # CONFIG_NF_CONNTRACK_ENABLED is not set | ||
223 | # CONFIG_NF_CONNTRACK is not set | ||
224 | # CONFIG_NETFILTER_XTABLES is not set | ||
225 | |||
226 | # | ||
227 | # IP: Netfilter Configuration | ||
228 | # | ||
229 | # CONFIG_IP_NF_QUEUE is not set | ||
230 | # CONFIG_IP_NF_IPTABLES is not set | ||
231 | # CONFIG_IP_NF_ARPTABLES is not set | ||
232 | # CONFIG_IP_DCCP is not set | ||
233 | # CONFIG_IP_SCTP is not set | ||
234 | # CONFIG_TIPC is not set | ||
235 | # CONFIG_ATM is not set | ||
236 | # CONFIG_BRIDGE is not set | ||
237 | # CONFIG_VLAN_8021Q is not set | ||
238 | # CONFIG_DECNET is not set | ||
239 | # CONFIG_LLC2 is not set | ||
240 | # CONFIG_IPX is not set | ||
241 | # CONFIG_ATALK is not set | ||
242 | # CONFIG_X25 is not set | ||
243 | # CONFIG_LAPB is not set | ||
244 | # CONFIG_ECONET is not set | ||
245 | # CONFIG_WAN_ROUTER is not set | ||
246 | # CONFIG_NET_SCHED is not set | ||
247 | |||
248 | # | ||
249 | # Network testing | ||
250 | # | ||
251 | # CONFIG_NET_PKTGEN is not set | ||
252 | # CONFIG_HAMRADIO is not set | ||
253 | # CONFIG_IRDA is not set | ||
254 | # CONFIG_BT is not set | ||
255 | # CONFIG_AF_RXRPC is not set | ||
256 | |||
257 | # | ||
258 | # Wireless | ||
259 | # | ||
260 | # CONFIG_CFG80211 is not set | ||
261 | # CONFIG_WIRELESS_EXT is not set | ||
262 | # CONFIG_MAC80211 is not set | ||
263 | # CONFIG_IEEE80211 is not set | ||
264 | # CONFIG_RFKILL is not set | ||
265 | # CONFIG_NET_9P is not set | ||
266 | |||
267 | # | ||
268 | # Drivers for built-in interfaces | ||
269 | # | ||
270 | CONFIG_ETRAX_ETHERNET=y | ||
271 | # CONFIG_ETRAX_IDE is not set | ||
272 | CONFIG_ETRAX_AXISFLASHMAP=y | ||
273 | CONFIG_ETRAX_PTABLE_SECTOR=65536 | ||
274 | # CONFIG_ETRAX_I2C is not set | ||
275 | # CONFIG_ETRAX_GPIO is not set | ||
276 | # CONFIG_ETRAX_NO_PHY is not set | ||
277 | # CONFIG_ETRAX_ETHERNET_IFACE0 is not set | ||
278 | # CONFIG_ETRAX_ETHERNET_GBIT is not set | ||
279 | # CONFIG_ETRAXFS_SERIAL is not set | ||
280 | # CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set | ||
281 | # CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE is not set | ||
282 | # CONFIG_ETRAX_NANDFLASH is not set | ||
283 | # CONFIG_ETRAX_CARDBUS is not set | ||
284 | # CONFIG_ETRAX_IOP_FW_LOAD is not set | ||
285 | # CONFIG_ETRAX_STREAMCOPROC is not set | ||
286 | # CONFIG_ETRAX_SPI_MMC is not set | ||
287 | # CONFIG_ETRAX_SPI_MMC_BOARD is not set | ||
288 | # CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set | ||
289 | CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y | ||
290 | |||
291 | # | ||
292 | # Generic Driver Options | ||
293 | # | ||
294 | CONFIG_STANDALONE=y | ||
295 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
296 | # CONFIG_SYS_HYPERVISOR is not set | ||
297 | CONFIG_MTD=y | ||
298 | # CONFIG_MTD_DEBUG is not set | ||
299 | CONFIG_MTD_CONCAT=y | ||
300 | CONFIG_MTD_PARTITIONS=y | ||
301 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
302 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
303 | |||
304 | # | ||
305 | # User Modules And Translation Layers | ||
306 | # | ||
307 | CONFIG_MTD_CHAR=y | ||
308 | CONFIG_MTD_BLKDEVS=y | ||
309 | CONFIG_MTD_BLOCK=y | ||
310 | # CONFIG_FTL is not set | ||
311 | # CONFIG_NFTL is not set | ||
312 | # CONFIG_INFTL is not set | ||
313 | # CONFIG_RFD_FTL is not set | ||
314 | # CONFIG_SSFDC is not set | ||
315 | # CONFIG_MTD_OOPS is not set | ||
316 | |||
317 | # | ||
318 | # RAM/ROM/Flash chip drivers | ||
319 | # | ||
320 | CONFIG_MTD_CFI=y | ||
321 | CONFIG_MTD_JEDECPROBE=y | ||
322 | CONFIG_MTD_GEN_PROBE=y | ||
323 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
324 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
325 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
326 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
327 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
328 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
329 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
330 | CONFIG_MTD_CFI_I1=y | ||
331 | CONFIG_MTD_CFI_I2=y | ||
332 | # CONFIG_MTD_CFI_I4 is not set | ||
333 | # CONFIG_MTD_CFI_I8 is not set | ||
334 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
335 | CONFIG_MTD_CFI_AMDSTD=y | ||
336 | # CONFIG_MTD_CFI_STAA is not set | ||
337 | CONFIG_MTD_CFI_UTIL=y | ||
338 | CONFIG_MTD_RAM=y | ||
339 | # CONFIG_MTD_ROM is not set | ||
340 | # CONFIG_MTD_ABSENT is not set | ||
341 | |||
342 | # | ||
343 | # Mapping drivers for chip access | ||
344 | # | ||
345 | CONFIG_MTD_COMPLEX_MAPPINGS=y | ||
346 | # CONFIG_MTD_PHYSMAP is not set | ||
347 | # CONFIG_MTD_PLATRAM is not set | ||
348 | |||
349 | # | ||
350 | # Self-contained MTD device drivers | ||
351 | # | ||
352 | # CONFIG_MTD_SLRAM is not set | ||
353 | # CONFIG_MTD_PHRAM is not set | ||
354 | CONFIG_MTD_MTDRAM=y | ||
355 | CONFIG_MTDRAM_TOTAL_SIZE=0 | ||
356 | CONFIG_MTDRAM_ERASE_SIZE=64 | ||
357 | CONFIG_MTDRAM_ABS_POS=0x0 | ||
358 | # CONFIG_MTD_BLOCK2MTD is not set | ||
359 | |||
360 | # | ||
361 | # Disk-On-Chip Device Drivers | ||
362 | # | ||
363 | # CONFIG_MTD_DOC2000 is not set | ||
364 | # CONFIG_MTD_DOC2001 is not set | ||
365 | # CONFIG_MTD_DOC2001PLUS is not set | ||
366 | # CONFIG_MTD_NAND is not set | ||
367 | # CONFIG_MTD_ONENAND is not set | ||
368 | |||
369 | # | ||
370 | # UBI - Unsorted block images | ||
371 | # | ||
372 | # CONFIG_MTD_UBI is not set | ||
373 | CONFIG_BLK_DEV=y | ||
374 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
375 | # CONFIG_BLK_DEV_LOOP is not set | ||
376 | # CONFIG_BLK_DEV_NBD is not set | ||
377 | CONFIG_BLK_DEV_RAM=y | ||
378 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
379 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
380 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | ||
381 | # CONFIG_CDROM_PKTCDVD is not set | ||
382 | # CONFIG_ATA_OVER_ETH is not set | ||
383 | CONFIG_NETDEVICES=y | ||
384 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
385 | # CONFIG_DUMMY is not set | ||
386 | # CONFIG_BONDING is not set | ||
387 | # CONFIG_MACVLAN is not set | ||
388 | # CONFIG_EQUALIZER is not set | ||
389 | # CONFIG_TUN is not set | ||
390 | # CONFIG_VETH is not set | ||
391 | # CONFIG_PHYLIB is not set | ||
392 | CONFIG_NET_ETHERNET=y | ||
393 | CONFIG_MII=y | ||
394 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
395 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
396 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
397 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
398 | CONFIG_NETDEV_1000=y | ||
399 | CONFIG_NETDEV_10000=y | ||
400 | |||
401 | # | ||
402 | # Wireless LAN | ||
403 | # | ||
404 | # CONFIG_WLAN_PRE80211 is not set | ||
405 | # CONFIG_WLAN_80211 is not set | ||
406 | # CONFIG_WAN is not set | ||
407 | # CONFIG_PPP is not set | ||
408 | # CONFIG_SLIP is not set | ||
409 | # CONFIG_SHAPER is not set | ||
410 | # CONFIG_NETCONSOLE is not set | ||
411 | # CONFIG_NETPOLL is not set | ||
412 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
413 | # CONFIG_RTC_CLASS is not set | ||
414 | |||
415 | # | ||
416 | # Input device support | ||
417 | # | ||
418 | # CONFIG_INPUT is not set | ||
419 | |||
420 | # | ||
421 | # Hardware I/O ports | ||
422 | # | ||
423 | CONFIG_SERIO=y | ||
424 | # CONFIG_SERIO_I8042 is not set | ||
425 | # CONFIG_SERIO_SERPORT is not set | ||
426 | # CONFIG_SERIO_LIBPS2 is not set | ||
427 | # CONFIG_SERIO_RAW is not set | ||
428 | # CONFIG_GAMEPORT is not set | ||
429 | |||
430 | # | ||
431 | # Character devices | ||
432 | # | ||
433 | # CONFIG_VT is not set | ||
434 | CONFIG_UNIX98_PTYS=y | ||
435 | CONFIG_LEGACY_PTYS=y | ||
436 | CONFIG_LEGACY_PTY_COUNT=256 | ||
437 | CONFIG_HW_RANDOM=y | ||
438 | # CONFIG_RTC is not set | ||
439 | # CONFIG_GEN_RTC is not set | ||
440 | # CONFIG_R3964 is not set | ||
441 | # CONFIG_RAW_DRIVER is not set | ||
442 | |||
443 | # | ||
444 | # File systems | ||
445 | # | ||
446 | # CONFIG_EXT2_FS is not set | ||
447 | # CONFIG_EXT3_FS is not set | ||
448 | # CONFIG_EXT4DEV_FS is not set | ||
449 | # CONFIG_REISERFS_FS is not set | ||
450 | # CONFIG_JFS_FS is not set | ||
451 | # CONFIG_FS_POSIX_ACL is not set | ||
452 | # CONFIG_XFS_FS is not set | ||
453 | # CONFIG_GFS2_FS is not set | ||
454 | # CONFIG_OCFS2_FS is not set | ||
455 | # CONFIG_MINIX_FS is not set | ||
456 | # CONFIG_ROMFS_FS is not set | ||
457 | CONFIG_INOTIFY=y | ||
458 | CONFIG_INOTIFY_USER=y | ||
459 | # CONFIG_QUOTA is not set | ||
460 | CONFIG_DNOTIFY=y | ||
461 | # CONFIG_AUTOFS_FS is not set | ||
462 | # CONFIG_AUTOFS4_FS is not set | ||
463 | # CONFIG_FUSE_FS is not set | ||
464 | |||
465 | # | ||
466 | # CD-ROM/DVD Filesystems | ||
467 | # | ||
468 | # CONFIG_ISO9660_FS is not set | ||
469 | # CONFIG_UDF_FS is not set | ||
470 | |||
471 | # | ||
472 | # DOS/FAT/NT Filesystems | ||
473 | # | ||
474 | # CONFIG_MSDOS_FS is not set | ||
475 | # CONFIG_VFAT_FS is not set | ||
476 | # CONFIG_NTFS_FS is not set | ||
477 | |||
478 | # | ||
479 | # Pseudo filesystems | ||
480 | # | ||
481 | CONFIG_PROC_FS=y | ||
482 | CONFIG_PROC_KCORE=y | ||
483 | CONFIG_PROC_SYSCTL=y | ||
484 | CONFIG_SYSFS=y | ||
485 | CONFIG_TMPFS=y | ||
486 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
487 | # CONFIG_HUGETLB_PAGE is not set | ||
488 | # CONFIG_CONFIGFS_FS is not set | ||
489 | |||
490 | # | ||
491 | # Miscellaneous filesystems | ||
492 | # | ||
493 | # CONFIG_ADFS_FS is not set | ||
494 | # CONFIG_AFFS_FS is not set | ||
495 | # CONFIG_HFS_FS is not set | ||
496 | # CONFIG_HFSPLUS_FS is not set | ||
497 | # CONFIG_BEFS_FS is not set | ||
498 | # CONFIG_BFS_FS is not set | ||
499 | # CONFIG_EFS_FS is not set | ||
500 | CONFIG_JFFS2_FS=y | ||
501 | CONFIG_JFFS2_FS_DEBUG=0 | ||
502 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
503 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
504 | # CONFIG_JFFS2_SUMMARY is not set | ||
505 | # CONFIG_JFFS2_FS_XATTR is not set | ||
506 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
507 | CONFIG_JFFS2_ZLIB=y | ||
508 | # CONFIG_JFFS2_LZO is not set | ||
509 | CONFIG_JFFS2_RTIME=y | ||
510 | # CONFIG_JFFS2_RUBIN is not set | ||
511 | CONFIG_CRAMFS=y | ||
512 | # CONFIG_VXFS_FS is not set | ||
513 | # CONFIG_HPFS_FS is not set | ||
514 | # CONFIG_QNX4FS_FS is not set | ||
515 | # CONFIG_SYSV_FS is not set | ||
516 | # CONFIG_UFS_FS is not set | ||
517 | CONFIG_NETWORK_FILESYSTEMS=y | ||
518 | CONFIG_NFS_FS=y | ||
519 | CONFIG_NFS_V3=y | ||
520 | # CONFIG_NFS_V3_ACL is not set | ||
521 | # CONFIG_NFS_V4 is not set | ||
522 | # CONFIG_NFS_DIRECTIO is not set | ||
523 | # CONFIG_NFSD is not set | ||
524 | CONFIG_LOCKD=y | ||
525 | CONFIG_LOCKD_V4=y | ||
526 | CONFIG_NFS_COMMON=y | ||
527 | CONFIG_SUNRPC=y | ||
528 | # CONFIG_SUNRPC_BIND34 is not set | ||
529 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
530 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
531 | # CONFIG_SMB_FS is not set | ||
532 | # CONFIG_CIFS is not set | ||
533 | # CONFIG_NCP_FS is not set | ||
534 | # CONFIG_CODA_FS is not set | ||
535 | # CONFIG_AFS_FS is not set | ||
536 | |||
537 | # | ||
538 | # Partition Types | ||
539 | # | ||
540 | # CONFIG_PARTITION_ADVANCED is not set | ||
541 | CONFIG_MSDOS_PARTITION=y | ||
542 | # CONFIG_NLS is not set | ||
543 | # CONFIG_DLM is not set | ||
544 | |||
545 | # | ||
546 | # Kernel hacking | ||
547 | # | ||
548 | # CONFIG_PROFILING is not set | ||
549 | # CONFIG_SYSTEM_PROFILER is not set | ||
550 | # CONFIG_PRINTK_TIME is not set | ||
551 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
552 | CONFIG_ENABLE_MUST_CHECK=y | ||
553 | # CONFIG_MAGIC_SYSRQ is not set | ||
554 | # CONFIG_UNUSED_SYMBOLS is not set | ||
555 | # CONFIG_DEBUG_FS is not set | ||
556 | # CONFIG_HEADERS_CHECK is not set | ||
557 | # CONFIG_DEBUG_KERNEL is not set | ||
558 | # CONFIG_SLUB_DEBUG_ON is not set | ||
559 | # CONFIG_SAMPLES is not set | ||
560 | |||
561 | # | ||
562 | # Security options | ||
563 | # | ||
564 | # CONFIG_KEYS is not set | ||
565 | # CONFIG_SECURITY is not set | ||
566 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
567 | # CONFIG_CRYPTO is not set | ||
568 | |||
569 | # | ||
570 | # Library routines | ||
571 | # | ||
572 | CONFIG_BITREVERSE=y | ||
573 | # CONFIG_CRC_CCITT is not set | ||
574 | # CONFIG_CRC16 is not set | ||
575 | # CONFIG_CRC_ITU_T is not set | ||
576 | CONFIG_CRC32=y | ||
577 | # CONFIG_CRC7 is not set | ||
578 | # CONFIG_LIBCRC32C is not set | ||
579 | CONFIG_ZLIB_INFLATE=y | ||
580 | CONFIG_ZLIB_DEFLATE=y | ||
581 | CONFIG_PLIST=y | ||
582 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/cris/defconfig b/arch/cris/defconfig index 9c33ae659934..59f36a58f842 100644 --- a/arch/cris/defconfig +++ b/arch/cris/defconfig | |||
@@ -1,52 +1,91 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11 | 3 | # Linux kernel version: 2.6.24-rc3 |
4 | # Mon Jun 20 13:42:02 2005 | 4 | # Mon Dec 3 11:34:27 2007 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_UID16=y | 7 | CONFIG_ZONE_DMA=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_IOMAP=y | 9 | CONFIG_GENERIC_IOMAP=y |
10 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
11 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
12 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
13 | CONFIG_GENERIC_HWEIGHT=y | ||
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 14 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
15 | CONFIG_NO_IOPORT=y | ||
16 | CONFIG_FORCE_MAX_ZONEORDER=6 | ||
11 | CONFIG_CRIS=y | 17 | CONFIG_CRIS=y |
18 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
12 | 19 | ||
13 | # | 20 | # |
14 | # Code maturity level options | 21 | # General setup |
15 | # | 22 | # |
16 | CONFIG_EXPERIMENTAL=y | 23 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | 24 | CONFIG_BROKEN_ON_SMP=y |
19 | 25 | CONFIG_INIT_ENV_ARG_LIMIT=32 | |
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | 26 | CONFIG_LOCALVERSION="" |
27 | CONFIG_LOCALVERSION_AUTO=y | ||
24 | # CONFIG_SWAP is not set | 28 | # CONFIG_SWAP is not set |
25 | # CONFIG_SYSVIPC is not set | 29 | # CONFIG_SYSVIPC is not set |
26 | # CONFIG_POSIX_MQUEUE is not set | 30 | # CONFIG_POSIX_MQUEUE is not set |
27 | # CONFIG_BSD_PROCESS_ACCT is not set | 31 | # CONFIG_BSD_PROCESS_ACCT is not set |
28 | CONFIG_SYSCTL=y | 32 | # CONFIG_TASKSTATS is not set |
33 | # CONFIG_USER_NS is not set | ||
34 | # CONFIG_PID_NS is not set | ||
29 | # CONFIG_AUDIT is not set | 35 | # CONFIG_AUDIT is not set |
30 | CONFIG_LOG_BUF_SHIFT=14 | ||
31 | # CONFIG_HOTPLUG is not set | ||
32 | CONFIG_KOBJECT_UEVENT=y | ||
33 | # CONFIG_IKCONFIG is not set | 36 | # CONFIG_IKCONFIG is not set |
37 | CONFIG_LOG_BUF_SHIFT=14 | ||
38 | # CONFIG_CGROUPS is not set | ||
39 | CONFIG_FAIR_GROUP_SCHED=y | ||
40 | CONFIG_FAIR_USER_SCHED=y | ||
41 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
42 | CONFIG_SYSFS_DEPRECATED=y | ||
43 | # CONFIG_RELAY is not set | ||
44 | # CONFIG_BLK_DEV_INITRD is not set | ||
45 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
46 | CONFIG_SYSCTL=y | ||
34 | CONFIG_EMBEDDED=y | 47 | CONFIG_EMBEDDED=y |
48 | CONFIG_UID16=y | ||
49 | CONFIG_SYSCTL_SYSCALL=y | ||
35 | # CONFIG_KALLSYMS is not set | 50 | # CONFIG_KALLSYMS is not set |
51 | # CONFIG_HOTPLUG is not set | ||
52 | CONFIG_PRINTK=y | ||
53 | CONFIG_BUG=y | ||
54 | CONFIG_ELF_CORE=y | ||
55 | CONFIG_BASE_FULL=y | ||
36 | CONFIG_FUTEX=y | 56 | CONFIG_FUTEX=y |
57 | CONFIG_ANON_INODES=y | ||
37 | CONFIG_EPOLL=y | 58 | CONFIG_EPOLL=y |
38 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 59 | CONFIG_SIGNALFD=y |
60 | CONFIG_EVENTFD=y | ||
39 | CONFIG_SHMEM=y | 61 | CONFIG_SHMEM=y |
40 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 62 | CONFIG_VM_EVENT_COUNTERS=y |
41 | CONFIG_CC_ALIGN_LABELS=0 | 63 | CONFIG_SLUB_DEBUG=y |
42 | CONFIG_CC_ALIGN_LOOPS=0 | 64 | # CONFIG_SLAB is not set |
43 | CONFIG_CC_ALIGN_JUMPS=0 | 65 | CONFIG_SLUB=y |
66 | # CONFIG_SLOB is not set | ||
67 | CONFIG_RT_MUTEXES=y | ||
44 | # CONFIG_TINY_SHMEM is not set | 68 | # CONFIG_TINY_SHMEM is not set |
69 | CONFIG_BASE_SMALL=0 | ||
70 | # CONFIG_MODULES is not set | ||
71 | CONFIG_BLOCK=y | ||
72 | # CONFIG_LBD is not set | ||
73 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
74 | # CONFIG_LSF is not set | ||
75 | # CONFIG_BLK_DEV_BSG is not set | ||
45 | 76 | ||
46 | # | 77 | # |
47 | # Loadable module support | 78 | # IO Schedulers |
48 | # | 79 | # |
49 | # CONFIG_MODULES is not set | 80 | CONFIG_IOSCHED_NOOP=y |
81 | # CONFIG_IOSCHED_AS is not set | ||
82 | # CONFIG_IOSCHED_DEADLINE is not set | ||
83 | CONFIG_IOSCHED_CFQ=y | ||
84 | # CONFIG_DEFAULT_AS is not set | ||
85 | # CONFIG_DEFAULT_DEADLINE is not set | ||
86 | CONFIG_DEFAULT_CFQ=y | ||
87 | # CONFIG_DEFAULT_NOOP is not set | ||
88 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
50 | 89 | ||
51 | # | 90 | # |
52 | # General setup | 91 | # General setup |
@@ -54,12 +93,27 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
54 | CONFIG_BINFMT_ELF=y | 93 | CONFIG_BINFMT_ELF=y |
55 | # CONFIG_BINFMT_MISC is not set | 94 | # CONFIG_BINFMT_MISC is not set |
56 | CONFIG_GENERIC_HARDIRQS=y | 95 | CONFIG_GENERIC_HARDIRQS=y |
57 | # CONFIG_SMP is not set | ||
58 | CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock3 init=/linuxrc" | 96 | CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock3 init=/linuxrc" |
59 | # CONFIG_ETRAX_WATCHDOG is not set | 97 | # CONFIG_ETRAX_WATCHDOG is not set |
60 | CONFIG_ETRAX_FAST_TIMER=y | 98 | CONFIG_ETRAX_FAST_TIMER=y |
61 | # CONFIG_PREEMPT is not set | 99 | # CONFIG_ETRAX_KMALLOCED_MODULES is not set |
62 | # CONFIG_OOM_REBOOT is not set | 100 | # CONFIG_OOM_REBOOT is not set |
101 | CONFIG_PREEMPT_NONE=y | ||
102 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
103 | # CONFIG_PREEMPT is not set | ||
104 | CONFIG_SELECT_MEMORY_MODEL=y | ||
105 | CONFIG_FLATMEM_MANUAL=y | ||
106 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
107 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
108 | CONFIG_FLATMEM=y | ||
109 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
110 | # CONFIG_SPARSEMEM_STATIC is not set | ||
111 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
112 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
113 | # CONFIG_RESOURCES_64BIT is not set | ||
114 | CONFIG_ZONE_DMA_FLAG=1 | ||
115 | CONFIG_BOUNCE=y | ||
116 | CONFIG_VIRT_TO_BUS=y | ||
63 | 117 | ||
64 | # | 118 | # |
65 | # Hardware setup | 119 | # Hardware setup |
@@ -68,127 +122,180 @@ CONFIG_ETRAX_FAST_TIMER=y | |||
68 | CONFIG_ETRAX100LX_V2=y | 122 | CONFIG_ETRAX100LX_V2=y |
69 | # CONFIG_SVINTO_SIM is not set | 123 | # CONFIG_SVINTO_SIM is not set |
70 | # CONFIG_ETRAXFS is not set | 124 | # CONFIG_ETRAXFS is not set |
71 | # CONFIG_ETRAXFS_SIM is not set | 125 | # CONFIG_CRIS_MACH_ARTPEC3 is not set |
126 | # CONFIG_ETRAX_VCS_SIM is not set | ||
72 | CONFIG_ETRAX_ARCH_V10=y | 127 | CONFIG_ETRAX_ARCH_V10=y |
73 | # CONFIG_ETRAX_ARCH_V32 is not set | 128 | # CONFIG_ETRAX_ARCH_V32 is not set |
74 | CONFIG_ETRAX_DRAM_SIZE=32 | 129 | CONFIG_ETRAX_DRAM_SIZE=32 |
75 | CONFIG_ETRAX_FLASH_BUSWIDTH=2 | 130 | CONFIG_ETRAX_FLASH_BUSWIDTH=2 |
131 | CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1 | ||
76 | CONFIG_ETRAX_FLASH1_SIZE=4 | 132 | CONFIG_ETRAX_FLASH1_SIZE=4 |
133 | # CONFIG_ETRAX_DEBUG_PORT0 is not set | ||
134 | # CONFIG_ETRAX_DEBUG_PORT1 is not set | ||
135 | # CONFIG_ETRAX_DEBUG_PORT2 is not set | ||
136 | # CONFIG_ETRAX_DEBUG_PORT3 is not set | ||
137 | CONFIG_ETRAX_DEBUG_PORT_NULL=y | ||
138 | |||
139 | # | ||
140 | # CRIS v10 options | ||
141 | # | ||
77 | CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000 | 142 | CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000 |
78 | CONFIG_ETRAX_PA_LEDS=y | 143 | CONFIG_ETRAX_PA_LEDS=y |
79 | # CONFIG_ETRAX_PB_LEDS is not set | 144 | # CONFIG_ETRAX_PB_LEDS is not set |
80 | # CONFIG_ETRAX_CSP0_LEDS is not set | 145 | # CONFIG_ETRAX_CSP0_LEDS is not set |
81 | # CONFIG_ETRAX_NO_LEDS is not set | 146 | # CONFIG_ETRAX_NO_LEDS is not set |
82 | CONFIG_ETRAX_LED1G=2 | 147 | CONFIG_ETRAX_LED1G=2 |
83 | CONFIG_ETRAX_LED1R=2 | 148 | CONFIG_ETRAX_LED1R=3 |
84 | CONFIG_ETRAX_LED2G=3 | 149 | CONFIG_ETRAX_LED2G=4 |
85 | CONFIG_ETRAX_LED2R=3 | 150 | CONFIG_ETRAX_LED2R=5 |
86 | CONFIG_ETRAX_LED3G=2 | 151 | CONFIG_ETRAX_LED3G=2 |
87 | CONFIG_ETRAX_LED3R=2 | 152 | CONFIG_ETRAX_LED3R=2 |
88 | CONFIG_ETRAX_DEBUG_PORT0=y | ||
89 | # CONFIG_ETRAX_DEBUG_PORT1 is not set | ||
90 | # CONFIG_ETRAX_DEBUG_PORT2 is not set | ||
91 | # CONFIG_ETRAX_DEBUG_PORT3 is not set | ||
92 | # CONFIG_ETRAX_DEBUG_PORT_NULL is not set | ||
93 | CONFIG_ETRAX_RESCUE_SER0=y | 153 | CONFIG_ETRAX_RESCUE_SER0=y |
94 | # CONFIG_ETRAX_RESCUE_SER1 is not set | 154 | # CONFIG_ETRAX_RESCUE_SER1 is not set |
95 | # CONFIG_ETRAX_RESCUE_SER2 is not set | 155 | # CONFIG_ETRAX_RESCUE_SER2 is not set |
96 | # CONFIG_ETRAX_RESCUE_SER3 is not set | 156 | # CONFIG_ETRAX_RESCUE_SER3 is not set |
97 | CONFIG_ETRAX_DEF_R_WAITSTATES=0x95a6 | 157 | CONFIG_ETRAX_DEF_R_WAITSTATES=95a6 |
98 | CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x4 | 158 | CONFIG_ETRAX_DEF_R_BUS_CONFIG=104 |
99 | CONFIG_ETRAX_SDRAM=y | 159 | # CONFIG_ETRAX_SDRAM is not set |
100 | CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x09e05757 | 160 | CONFIG_ETRAX_DEF_R_DRAM_CONFIG=1a200040 |
101 | CONFIG_ETRAX_DEF_R_SDRAM_TIMING=0x80008002 | 161 | CONFIG_ETRAX_DEF_R_DRAM_TIMING=5611 |
102 | CONFIG_ETRAX_DEF_R_PORT_PA_DIR=0x1d | 162 | CONFIG_ETRAX_DEF_R_PORT_PA_DIR=1c |
103 | CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0x00 | 163 | CONFIG_ETRAX_DEF_R_PORT_PA_DATA=00 |
104 | CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=0x00 | 164 | CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=00 |
105 | CONFIG_ETRAX_DEF_R_PORT_PB_DIR=0x1e | 165 | CONFIG_ETRAX_DEF_R_PORT_PB_DIR=00 |
106 | CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0xf3 | 166 | CONFIG_ETRAX_DEF_R_PORT_PB_DATA=ff |
107 | # CONFIG_ETRAX_SOFT_SHUTDOWN is not set | 167 | # CONFIG_ETRAX_SOFT_SHUTDOWN is not set |
108 | 168 | ||
109 | # | 169 | # |
170 | # Networking | ||
171 | # | ||
172 | CONFIG_NET=y | ||
173 | |||
174 | # | ||
175 | # Networking options | ||
176 | # | ||
177 | CONFIG_PACKET=y | ||
178 | # CONFIG_PACKET_MMAP is not set | ||
179 | CONFIG_UNIX=y | ||
180 | CONFIG_XFRM=y | ||
181 | # CONFIG_XFRM_USER is not set | ||
182 | # CONFIG_XFRM_SUB_POLICY is not set | ||
183 | # CONFIG_XFRM_MIGRATE is not set | ||
184 | # CONFIG_NET_KEY is not set | ||
185 | CONFIG_INET=y | ||
186 | # CONFIG_IP_MULTICAST is not set | ||
187 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
188 | CONFIG_IP_FIB_HASH=y | ||
189 | # CONFIG_IP_PNP is not set | ||
190 | # CONFIG_NET_IPIP is not set | ||
191 | # CONFIG_NET_IPGRE is not set | ||
192 | # CONFIG_ARPD is not set | ||
193 | # CONFIG_SYN_COOKIES is not set | ||
194 | # CONFIG_INET_AH is not set | ||
195 | # CONFIG_INET_ESP is not set | ||
196 | # CONFIG_INET_IPCOMP is not set | ||
197 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
198 | # CONFIG_INET_TUNNEL is not set | ||
199 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
200 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
201 | CONFIG_INET_XFRM_MODE_BEET=y | ||
202 | # CONFIG_INET_LRO is not set | ||
203 | CONFIG_INET_DIAG=y | ||
204 | CONFIG_INET_TCP_DIAG=y | ||
205 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
206 | CONFIG_TCP_CONG_CUBIC=y | ||
207 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
208 | # CONFIG_TCP_MD5SIG is not set | ||
209 | # CONFIG_IP_VS is not set | ||
210 | # CONFIG_IPV6 is not set | ||
211 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
212 | # CONFIG_INET6_TUNNEL is not set | ||
213 | # CONFIG_NETWORK_SECMARK is not set | ||
214 | CONFIG_NETFILTER=y | ||
215 | # CONFIG_NETFILTER_DEBUG is not set | ||
216 | |||
217 | # | ||
218 | # Core Netfilter Configuration | ||
219 | # | ||
220 | # CONFIG_NETFILTER_NETLINK is not set | ||
221 | # CONFIG_NF_CONNTRACK_ENABLED is not set | ||
222 | # CONFIG_NF_CONNTRACK is not set | ||
223 | # CONFIG_NETFILTER_XTABLES is not set | ||
224 | |||
225 | # | ||
226 | # IP: Netfilter Configuration | ||
227 | # | ||
228 | # CONFIG_IP_NF_QUEUE is not set | ||
229 | # CONFIG_IP_NF_IPTABLES is not set | ||
230 | # CONFIG_IP_NF_ARPTABLES is not set | ||
231 | # CONFIG_IP_DCCP is not set | ||
232 | # CONFIG_IP_SCTP is not set | ||
233 | # CONFIG_TIPC is not set | ||
234 | # CONFIG_ATM is not set | ||
235 | # CONFIG_BRIDGE is not set | ||
236 | # CONFIG_VLAN_8021Q is not set | ||
237 | # CONFIG_DECNET is not set | ||
238 | # CONFIG_LLC2 is not set | ||
239 | # CONFIG_IPX is not set | ||
240 | # CONFIG_ATALK is not set | ||
241 | # CONFIG_X25 is not set | ||
242 | # CONFIG_LAPB is not set | ||
243 | # CONFIG_ECONET is not set | ||
244 | # CONFIG_WAN_ROUTER is not set | ||
245 | # CONFIG_NET_SCHED is not set | ||
246 | |||
247 | # | ||
248 | # Network testing | ||
249 | # | ||
250 | # CONFIG_NET_PKTGEN is not set | ||
251 | # CONFIG_HAMRADIO is not set | ||
252 | # CONFIG_IRDA is not set | ||
253 | # CONFIG_BT is not set | ||
254 | # CONFIG_AF_RXRPC is not set | ||
255 | |||
256 | # | ||
257 | # Wireless | ||
258 | # | ||
259 | # CONFIG_CFG80211 is not set | ||
260 | # CONFIG_WIRELESS_EXT is not set | ||
261 | # CONFIG_MAC80211 is not set | ||
262 | # CONFIG_IEEE80211 is not set | ||
263 | # CONFIG_RFKILL is not set | ||
264 | # CONFIG_NET_9P is not set | ||
265 | |||
266 | # | ||
110 | # Drivers for built-in interfaces | 267 | # Drivers for built-in interfaces |
111 | # | 268 | # |
112 | CONFIG_ETRAX_ETHERNET=y | 269 | CONFIG_ETRAX_ETHERNET=y |
113 | # CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set | ||
114 | CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y | ||
115 | CONFIG_ETRAX_SERIAL=y | 270 | CONFIG_ETRAX_SERIAL=y |
116 | # CONFIG_ETRAX_SERIAL_FAST_TIMER is not set | 271 | # CONFIG_ETRAX_SERIAL_FAST_TIMER is not set |
117 | # CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is not set | 272 | # CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is not set |
118 | CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS=5 | 273 | CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS=5 |
119 | CONFIG_ETRAX_SERIAL_PORT0=y | 274 | # CONFIG_ETRAX_SERIAL_PORT0 is not set |
120 | # CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT is not set | ||
121 | CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT=y | ||
122 | # CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN is not set | ||
123 | CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN=y | ||
124 | CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE=y | ||
125 | # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA is not set | ||
126 | # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set | ||
127 | # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED is not set | ||
128 | CONFIG_ETRAX_SER0_DTR_ON_PA_BIT=-1 | ||
129 | CONFIG_ETRAX_SER0_RI_ON_PA_BIT=-1 | ||
130 | CONFIG_ETRAX_SER0_DSR_ON_PA_BIT=-1 | ||
131 | CONFIG_ETRAX_SER0_CD_ON_PA_BIT=-1 | ||
132 | CONFIG_ETRAX_SER0_DTR_ON_PB_BIT=-1 | ||
133 | CONFIG_ETRAX_SER0_RI_ON_PB_BIT=-1 | ||
134 | CONFIG_ETRAX_SER0_DSR_ON_PB_BIT=-1 | ||
135 | CONFIG_ETRAX_SER0_CD_ON_PB_BIT=-1 | ||
136 | # CONFIG_ETRAX_SERIAL_PORT1 is not set | 275 | # CONFIG_ETRAX_SERIAL_PORT1 is not set |
137 | CONFIG_ETRAX_SERIAL_PORT2=y | 276 | # CONFIG_ETRAX_SERIAL_PORT2 is not set |
138 | # CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set | ||
139 | CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y | ||
140 | # CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set | ||
141 | CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y | ||
142 | CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE=y | ||
143 | # CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA is not set | ||
144 | # CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PB is not set | ||
145 | # CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED is not set | ||
146 | CONFIG_ETRAX_SER2_DTR_ON_PA_BIT=-1 | ||
147 | CONFIG_ETRAX_SER2_RI_ON_PA_BIT=-1 | ||
148 | CONFIG_ETRAX_SER2_DSR_ON_PA_BIT=-1 | ||
149 | CONFIG_ETRAX_SER2_CD_ON_PA_BIT=-1 | ||
150 | CONFIG_ETRAX_SER2_DTR_ON_PB_BIT=-1 | ||
151 | CONFIG_ETRAX_SER2_RI_ON_PB_BIT=-1 | ||
152 | CONFIG_ETRAX_SER2_DSR_ON_PB_BIT=-1 | ||
153 | CONFIG_ETRAX_SER2_CD_ON_PB_BIT=-1 | ||
154 | # CONFIG_ETRAX_SERIAL_PORT3 is not set | 277 | # CONFIG_ETRAX_SERIAL_PORT3 is not set |
155 | CONFIG_ETRAX_RS485=y | 278 | # CONFIG_ETRAX_RS485 is not set |
156 | # CONFIG_ETRAX_RS485_ON_PA is not set | 279 | # CONFIG_ETRAX_IDE is not set |
157 | # CONFIG_ETRAX_RS485_DISABLE_RECEIVER is not set | 280 | # CONFIG_ETRAX_USB_HOST is not set |
158 | CONFIG_ETRAX_IDE=y | ||
159 | CONFIG_ETRAX_IDE_DELAY=15 | ||
160 | CONFIG_ETRAX_IDE_PB7_RESET=y | ||
161 | # CONFIG_ETRAX_IDE_G27_RESET is not set | ||
162 | CONFIG_ETRAX_USB_HOST=y | ||
163 | CONFIG_ETRAX_USB_HOST_PORT1=y | ||
164 | CONFIG_ETRAX_USB_HOST_PORT2=y | ||
165 | CONFIG_ETRAX_AXISFLASHMAP=y | 281 | CONFIG_ETRAX_AXISFLASHMAP=y |
166 | CONFIG_ETRAX_PTABLE_SECTOR=65536 | 282 | CONFIG_ETRAX_PTABLE_SECTOR=65536 |
167 | # CONFIG_ETRAX_I2C is not set | 283 | # CONFIG_ETRAX_I2C is not set |
168 | # CONFIG_ETRAX_GPIO is not set | 284 | # CONFIG_ETRAX_GPIO is not set |
169 | CONFIG_ETRAX_RTC=y | 285 | # CONFIG_ETRAX_RTC is not set |
170 | CONFIG_ETRAX_DS1302=y | 286 | # CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set |
171 | # CONFIG_ETRAX_PCF8563 is not set | 287 | CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y |
172 | CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT=y | ||
173 | CONFIG_ETRAX_DS1302_RSTBIT=0 | ||
174 | CONFIG_ETRAX_DS1302_SCLBIT=1 | ||
175 | CONFIG_ETRAX_DS1302_SDABIT=0 | ||
176 | CONFIG_ETRAX_DS1302_TRICKLE_CHARGE=0 | ||
177 | 288 | ||
178 | # | 289 | # |
179 | # Generic Driver Options | 290 | # Generic Driver Options |
180 | # | 291 | # |
181 | CONFIG_STANDALONE=y | 292 | CONFIG_STANDALONE=y |
182 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 293 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
183 | # CONFIG_FW_LOADER is not set | 294 | # CONFIG_SYS_HYPERVISOR is not set |
184 | |||
185 | # | ||
186 | # Memory Technology Devices (MTD) | ||
187 | # | ||
188 | CONFIG_MTD=y | 295 | CONFIG_MTD=y |
189 | # CONFIG_MTD_DEBUG is not set | 296 | # CONFIG_MTD_DEBUG is not set |
190 | CONFIG_MTD_PARTITIONS=y | ||
191 | CONFIG_MTD_CONCAT=y | 297 | CONFIG_MTD_CONCAT=y |
298 | CONFIG_MTD_PARTITIONS=y | ||
192 | # CONFIG_MTD_REDBOOT_PARTS is not set | 299 | # CONFIG_MTD_REDBOOT_PARTS is not set |
193 | # CONFIG_MTD_CMDLINE_PARTS is not set | 300 | # CONFIG_MTD_CMDLINE_PARTS is not set |
194 | 301 | ||
@@ -196,16 +303,20 @@ CONFIG_MTD_CONCAT=y | |||
196 | # User Modules And Translation Layers | 303 | # User Modules And Translation Layers |
197 | # | 304 | # |
198 | CONFIG_MTD_CHAR=y | 305 | CONFIG_MTD_CHAR=y |
306 | CONFIG_MTD_BLKDEVS=y | ||
199 | CONFIG_MTD_BLOCK=y | 307 | CONFIG_MTD_BLOCK=y |
200 | # CONFIG_FTL is not set | 308 | # CONFIG_FTL is not set |
201 | # CONFIG_NFTL is not set | 309 | # CONFIG_NFTL is not set |
202 | # CONFIG_INFTL is not set | 310 | # CONFIG_INFTL is not set |
311 | # CONFIG_RFD_FTL is not set | ||
312 | # CONFIG_SSFDC is not set | ||
313 | # CONFIG_MTD_OOPS is not set | ||
203 | 314 | ||
204 | # | 315 | # |
205 | # RAM/ROM/Flash chip drivers | 316 | # RAM/ROM/Flash chip drivers |
206 | # | 317 | # |
207 | CONFIG_MTD_CFI=y | 318 | CONFIG_MTD_CFI=y |
208 | # CONFIG_MTD_JEDECPROBE is not set | 319 | CONFIG_MTD_JEDECPROBE=y |
209 | CONFIG_MTD_GEN_PROBE=y | 320 | CONFIG_MTD_GEN_PROBE=y |
210 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | 321 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set |
211 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | 322 | CONFIG_MTD_MAP_BANK_WIDTH_1=y |
@@ -220,20 +331,18 @@ CONFIG_MTD_CFI_I2=y | |||
220 | # CONFIG_MTD_CFI_I8 is not set | 331 | # CONFIG_MTD_CFI_I8 is not set |
221 | # CONFIG_MTD_CFI_INTELEXT is not set | 332 | # CONFIG_MTD_CFI_INTELEXT is not set |
222 | CONFIG_MTD_CFI_AMDSTD=y | 333 | CONFIG_MTD_CFI_AMDSTD=y |
223 | CONFIG_MTD_CFI_AMDSTD_RETRY=0 | ||
224 | # CONFIG_MTD_CFI_STAA is not set | 334 | # CONFIG_MTD_CFI_STAA is not set |
225 | CONFIG_MTD_CFI_UTIL=y | 335 | CONFIG_MTD_CFI_UTIL=y |
226 | CONFIG_MTD_RAM=y | 336 | CONFIG_MTD_RAM=y |
227 | # CONFIG_MTD_ROM is not set | 337 | # CONFIG_MTD_ROM is not set |
228 | # CONFIG_MTD_ABSENT is not set | 338 | # CONFIG_MTD_ABSENT is not set |
229 | # CONFIG_MTD_SHARP is not set | ||
230 | # CONFIG_MTD_JEDEC is not set | ||
231 | 339 | ||
232 | # | 340 | # |
233 | # Mapping drivers for chip access | 341 | # Mapping drivers for chip access |
234 | # | 342 | # |
235 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 343 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
236 | # CONFIG_MTD_PHYSMAP is not set | 344 | # CONFIG_MTD_PHYSMAP is not set |
345 | # CONFIG_MTD_PLATRAM is not set | ||
237 | 346 | ||
238 | # | 347 | # |
239 | # Self-contained MTD device drivers | 348 | # Self-contained MTD device drivers |
@@ -244,7 +353,6 @@ CONFIG_MTD_MTDRAM=y | |||
244 | CONFIG_MTDRAM_TOTAL_SIZE=0 | 353 | CONFIG_MTDRAM_TOTAL_SIZE=0 |
245 | CONFIG_MTDRAM_ERASE_SIZE=64 | 354 | CONFIG_MTDRAM_ERASE_SIZE=64 |
246 | CONFIG_MTDRAM_ABS_POS=0x0 | 355 | CONFIG_MTDRAM_ABS_POS=0x0 |
247 | # CONFIG_MTD_BLKMTD is not set | ||
248 | # CONFIG_MTD_BLOCK2MTD is not set | 356 | # CONFIG_MTD_BLOCK2MTD is not set |
249 | 357 | ||
250 | # | 358 | # |
@@ -253,216 +361,54 @@ CONFIG_MTDRAM_ABS_POS=0x0 | |||
253 | # CONFIG_MTD_DOC2000 is not set | 361 | # CONFIG_MTD_DOC2000 is not set |
254 | # CONFIG_MTD_DOC2001 is not set | 362 | # CONFIG_MTD_DOC2001 is not set |
255 | # CONFIG_MTD_DOC2001PLUS is not set | 363 | # CONFIG_MTD_DOC2001PLUS is not set |
256 | |||
257 | # | ||
258 | # NAND Flash Device Drivers | ||
259 | # | ||
260 | # CONFIG_MTD_NAND is not set | 364 | # CONFIG_MTD_NAND is not set |
365 | # CONFIG_MTD_ONENAND is not set | ||
261 | 366 | ||
262 | # | 367 | # |
263 | # Parallel port support | 368 | # UBI - Unsorted block images |
264 | # | ||
265 | # CONFIG_PARPORT is not set | ||
266 | |||
267 | # | ||
268 | # Plug and Play support | ||
269 | # | 369 | # |
270 | 370 | # CONFIG_MTD_UBI is not set | |
271 | # | 371 | CONFIG_BLK_DEV=y |
272 | # Block devices | ||
273 | # | ||
274 | # CONFIG_BLK_DEV_FD is not set | ||
275 | # CONFIG_BLK_DEV_COW_COMMON is not set | 372 | # CONFIG_BLK_DEV_COW_COMMON is not set |
276 | # CONFIG_BLK_DEV_LOOP is not set | 373 | # CONFIG_BLK_DEV_LOOP is not set |
277 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
278 | # CONFIG_BLK_DEV_NBD is not set | 374 | # CONFIG_BLK_DEV_NBD is not set |
279 | # CONFIG_BLK_DEV_UB is not set | ||
280 | CONFIG_BLK_DEV_RAM=y | 375 | CONFIG_BLK_DEV_RAM=y |
281 | CONFIG_BLK_DEV_RAM_COUNT=16 | 376 | CONFIG_BLK_DEV_RAM_COUNT=16 |
282 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 377 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
283 | # CONFIG_BLK_DEV_INITRD is not set | 378 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 |
284 | CONFIG_INITRAMFS_SOURCE="" | ||
285 | # CONFIG_CDROM_PKTCDVD is not set | 379 | # CONFIG_CDROM_PKTCDVD is not set |
286 | |||
287 | # | ||
288 | # IO Schedulers | ||
289 | # | ||
290 | CONFIG_IOSCHED_NOOP=y | ||
291 | # CONFIG_IOSCHED_AS is not set | ||
292 | # CONFIG_IOSCHED_DEADLINE is not set | ||
293 | CONFIG_IOSCHED_CFQ=y | ||
294 | # CONFIG_ATA_OVER_ETH is not set | 380 | # CONFIG_ATA_OVER_ETH is not set |
295 | |||
296 | # | ||
297 | # Multi-device support (RAID and LVM) | ||
298 | # | ||
299 | # CONFIG_MD is not set | ||
300 | |||
301 | # | ||
302 | # ATA/ATAPI/MFM/RLL support | ||
303 | # | ||
304 | # CONFIG_IDE is not set | ||
305 | # CONFIG_PARIDE is not set | ||
306 | |||
307 | # | ||
308 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
309 | # | ||
310 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
311 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
312 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
313 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
314 | # CONFIG_IDE_TASK_IOCTL is not set | ||
315 | |||
316 | # | ||
317 | # IDE chipset support/bugfixes | ||
318 | # | ||
319 | # CONFIG_IDE_GENERIC is not set | ||
320 | # CONFIG_IDE_ARM is not set | ||
321 | # CONFIG_IDEDMA_AUTO is not set | ||
322 | # CONFIG_BLK_DEV_HD is not set | ||
323 | |||
324 | # | ||
325 | # SCSI device support | ||
326 | # | ||
327 | # CONFIG_SCSI is not set | ||
328 | # CONFIG_ISCSI_TCP is not set | ||
329 | |||
330 | # | ||
331 | # IEEE 1394 (FireWire) support | ||
332 | # | ||
333 | |||
334 | # | ||
335 | # I2O device support | ||
336 | # | ||
337 | |||
338 | # | ||
339 | # Networking support | ||
340 | # | ||
341 | CONFIG_NET=y | ||
342 | |||
343 | # | ||
344 | # Networking options | ||
345 | # | ||
346 | CONFIG_PACKET=y | ||
347 | # CONFIG_PACKET_MMAP is not set | ||
348 | # CONFIG_NETLINK_DEV is not set | ||
349 | CONFIG_UNIX=y | ||
350 | # CONFIG_NET_KEY is not set | ||
351 | CONFIG_INET=y | ||
352 | # CONFIG_IP_MULTICAST is not set | ||
353 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
354 | # CONFIG_IP_PNP is not set | ||
355 | # CONFIG_NET_IPIP is not set | ||
356 | # CONFIG_NET_IPGRE is not set | ||
357 | # CONFIG_ARPD is not set | ||
358 | # CONFIG_SYN_COOKIES is not set | ||
359 | # CONFIG_INET_AH is not set | ||
360 | # CONFIG_INET_ESP is not set | ||
361 | # CONFIG_INET_IPCOMP is not set | ||
362 | # CONFIG_INET_TUNNEL is not set | ||
363 | CONFIG_IP_TCPDIAG=y | ||
364 | # CONFIG_IP_TCPDIAG_IPV6 is not set | ||
365 | |||
366 | # | ||
367 | # IP: Virtual Server Configuration | ||
368 | # | ||
369 | # CONFIG_IP_VS is not set | ||
370 | # CONFIG_IPV6 is not set | ||
371 | CONFIG_NETFILTER=y | ||
372 | # CONFIG_NETFILTER_DEBUG is not set | ||
373 | |||
374 | # | ||
375 | # IP: Netfilter Configuration | ||
376 | # | ||
377 | # CONFIG_IP_NF_CONNTRACK is not set | ||
378 | # CONFIG_IP_NF_CONNTRACK_MARK is not set | ||
379 | # CONFIG_IP_NF_QUEUE is not set | ||
380 | # CONFIG_IP_NF_IPTABLES is not set | ||
381 | # CONFIG_IP_NF_ARPTABLES is not set | ||
382 | |||
383 | # | ||
384 | # SCTP Configuration (EXPERIMENTAL) | ||
385 | # | ||
386 | # CONFIG_IP_SCTP is not set | ||
387 | # CONFIG_ATM is not set | ||
388 | # CONFIG_BRIDGE is not set | ||
389 | # CONFIG_VLAN_8021Q is not set | ||
390 | # CONFIG_DECNET is not set | ||
391 | # CONFIG_LLC2 is not set | ||
392 | # CONFIG_IPX is not set | ||
393 | # CONFIG_ATALK is not set | ||
394 | # CONFIG_X25 is not set | ||
395 | # CONFIG_LAPB is not set | ||
396 | # CONFIG_NET_DIVERT is not set | ||
397 | # CONFIG_ECONET is not set | ||
398 | # CONFIG_WAN_ROUTER is not set | ||
399 | |||
400 | # | ||
401 | # QoS and/or fair queueing | ||
402 | # | ||
403 | # CONFIG_NET_SCHED is not set | ||
404 | # CONFIG_NET_CLS_ROUTE is not set | ||
405 | |||
406 | # | ||
407 | # Network testing | ||
408 | # | ||
409 | # CONFIG_NET_PKTGEN is not set | ||
410 | # CONFIG_NETPOLL is not set | ||
411 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
412 | # CONFIG_HAMRADIO is not set | ||
413 | # CONFIG_IRDA is not set | ||
414 | # CONFIG_AF_RXRPC is not set | ||
415 | # CONFIG_AF_RXRPC_DEBUG is not set | ||
416 | # CONFIG_BT is not set | ||
417 | # CONFIG_I2C is not set | ||
418 | |||
419 | CONFIG_NETDEVICES=y | 381 | CONFIG_NETDEVICES=y |
382 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
420 | # CONFIG_DUMMY is not set | 383 | # CONFIG_DUMMY is not set |
421 | # CONFIG_BONDING is not set | 384 | # CONFIG_BONDING is not set |
385 | # CONFIG_MACVLAN is not set | ||
422 | # CONFIG_EQUALIZER is not set | 386 | # CONFIG_EQUALIZER is not set |
423 | # CONFIG_TUN is not set | 387 | # CONFIG_TUN is not set |
424 | 388 | # CONFIG_VETH is not set | |
425 | # | 389 | # CONFIG_PHYLIB is not set |
426 | # Ethernet (10 or 100Mbit) | ||
427 | # | ||
428 | CONFIG_NET_ETHERNET=y | 390 | CONFIG_NET_ETHERNET=y |
429 | # CONFIG_MII is not set | 391 | CONFIG_MII=y |
392 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
393 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
394 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
395 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
396 | CONFIG_NETDEV_1000=y | ||
397 | CONFIG_NETDEV_10000=y | ||
430 | 398 | ||
431 | # | 399 | # |
432 | # Ethernet (1000 Mbit) | 400 | # Wireless LAN |
433 | # | ||
434 | |||
435 | # | ||
436 | # Ethernet (10000 Mbit) | ||
437 | # | ||
438 | |||
439 | # | ||
440 | # Token Ring devices | ||
441 | # | ||
442 | |||
443 | # | ||
444 | # Wireless LAN (non-hamradio) | ||
445 | # | ||
446 | # CONFIG_NET_RADIO is not set | ||
447 | |||
448 | # | ||
449 | # Wan interfaces | ||
450 | # | 401 | # |
402 | # CONFIG_WLAN_PRE80211 is not set | ||
403 | # CONFIG_WLAN_80211 is not set | ||
451 | # CONFIG_WAN is not set | 404 | # CONFIG_WAN is not set |
452 | # CONFIG_PPP is not set | 405 | # CONFIG_PPP is not set |
453 | # CONFIG_SLIP is not set | 406 | # CONFIG_SLIP is not set |
454 | # CONFIG_SHAPER is not set | 407 | # CONFIG_SHAPER is not set |
455 | # CONFIG_NETCONSOLE is not set | 408 | # CONFIG_NETCONSOLE is not set |
456 | 409 | # CONFIG_NETPOLL is not set | |
457 | # | 410 | # CONFIG_NET_POLL_CONTROLLER is not set |
458 | # ISDN subsystem | 411 | # CONFIG_RTC_CLASS is not set |
459 | # | ||
460 | # CONFIG_ISDN is not set | ||
461 | |||
462 | # | ||
463 | # Telephony Support | ||
464 | # | ||
465 | # CONFIG_PHONE is not set | ||
466 | 412 | ||
467 | # | 413 | # |
468 | # Input device support | 414 | # Input device support |
@@ -470,7 +416,7 @@ CONFIG_NET_ETHERNET=y | |||
470 | # CONFIG_INPUT is not set | 416 | # CONFIG_INPUT is not set |
471 | 417 | ||
472 | # | 418 | # |
473 | # Input I/O drivers | 419 | # Hardware I/O ports |
474 | # | 420 | # |
475 | CONFIG_SERIO=y | 421 | CONFIG_SERIO=y |
476 | # CONFIG_SERIO_I8042 is not set | 422 | # CONFIG_SERIO_I8042 is not set |
@@ -480,94 +426,39 @@ CONFIG_SERIO=y | |||
480 | # CONFIG_GAMEPORT is not set | 426 | # CONFIG_GAMEPORT is not set |
481 | 427 | ||
482 | # | 428 | # |
483 | # Input Device Drivers | ||
484 | # | ||
485 | CONFIG_INPUT_KEYBOARD=y | ||
486 | CONFIG_KEYBOARD_ATKBD=y | ||
487 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
488 | # CONFIG_KEYBOARD_LKKBD is not set | ||
489 | # CONFIG_KEYBOARD_XTKBD is not set | ||
490 | # CONFIG_KEYBOARD_NEWTON is not set | ||
491 | CONFIG_INPUT_MOUSE=y | ||
492 | CONFIG_MOUSE_PS2=y | ||
493 | # CONFIG_MOUSE_SERIAL is not set | ||
494 | # CONFIG_MOUSE_VSXXXAA is not set | ||
495 | # CONFIG_INPUT_JOYSTICK is not set | ||
496 | # CONFIG_INPUT_TABLET is not set | ||
497 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
498 | # CONFIG_INPUT_MISC is not set | ||
499 | |||
500 | # | ||
501 | # Character devices | 429 | # Character devices |
502 | # | 430 | # |
503 | # CONFIG_VT is not set | 431 | # CONFIG_VT is not set |
504 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
505 | |||
506 | # | ||
507 | # Serial drivers | ||
508 | # | ||
509 | # CONFIG_SERIAL_8250 is not set | ||
510 | |||
511 | # | ||
512 | # Non-8250 serial port support | ||
513 | # | ||
514 | CONFIG_SERIAL_CORE=y | ||
515 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
516 | CONFIG_UNIX98_PTYS=y | 432 | CONFIG_UNIX98_PTYS=y |
517 | CONFIG_LEGACY_PTYS=y | 433 | CONFIG_LEGACY_PTYS=y |
518 | CONFIG_LEGACY_PTY_COUNT=256 | 434 | CONFIG_LEGACY_PTY_COUNT=256 |
519 | 435 | CONFIG_HW_RANDOM=y | |
520 | # | ||
521 | # IPMI | ||
522 | # | ||
523 | # CONFIG_IPMI_HANDLER is not set | ||
524 | |||
525 | # | ||
526 | # Watchdog Cards | ||
527 | # | ||
528 | # CONFIG_WATCHDOG is not set | ||
529 | # CONFIG_RTC is not set | 436 | # CONFIG_RTC is not set |
530 | # CONFIG_GEN_RTC is not set | 437 | # CONFIG_GEN_RTC is not set |
531 | # CONFIG_DTLK is not set | ||
532 | # CONFIG_R3964 is not set | 438 | # CONFIG_R3964 is not set |
533 | # CONFIG_RTC_LIB is not set | ||
534 | # CONFIG_RTC_CLASS is not set | ||
535 | |||
536 | # | ||
537 | # Ftape, the floppy tape device driver | ||
538 | # | ||
539 | # CONFIG_DRM is not set | ||
540 | # CONFIG_RAW_DRIVER is not set | 439 | # CONFIG_RAW_DRIVER is not set |
541 | 440 | ||
542 | # | 441 | # |
543 | # Multimedia devices | ||
544 | # | ||
545 | # CONFIG_VIDEO_DEV is not set | ||
546 | |||
547 | # | ||
548 | # Digital Video Broadcasting Devices | ||
549 | # | ||
550 | # CONFIG_DVB is not set | ||
551 | |||
552 | # | ||
553 | # File systems | 442 | # File systems |
554 | # | 443 | # |
555 | # CONFIG_EXT2_FS is not set | 444 | # CONFIG_EXT2_FS is not set |
556 | # CONFIG_EXT3_FS is not set | 445 | # CONFIG_EXT3_FS is not set |
557 | # CONFIG_JBD is not set | 446 | # CONFIG_EXT4DEV_FS is not set |
558 | # CONFIG_REISERFS_FS is not set | 447 | # CONFIG_REISERFS_FS is not set |
559 | # CONFIG_JFS_FS is not set | 448 | # CONFIG_JFS_FS is not set |
560 | 449 | # CONFIG_FS_POSIX_ACL is not set | |
561 | # | ||
562 | # XFS support | ||
563 | # | ||
564 | # CONFIG_XFS_FS is not set | 450 | # CONFIG_XFS_FS is not set |
451 | # CONFIG_GFS2_FS is not set | ||
452 | # CONFIG_OCFS2_FS is not set | ||
565 | # CONFIG_MINIX_FS is not set | 453 | # CONFIG_MINIX_FS is not set |
566 | # CONFIG_ROMFS_FS is not set | 454 | # CONFIG_ROMFS_FS is not set |
455 | CONFIG_INOTIFY=y | ||
456 | CONFIG_INOTIFY_USER=y | ||
567 | # CONFIG_QUOTA is not set | 457 | # CONFIG_QUOTA is not set |
568 | CONFIG_DNOTIFY=y | 458 | CONFIG_DNOTIFY=y |
569 | # CONFIG_AUTOFS_FS is not set | 459 | # CONFIG_AUTOFS_FS is not set |
570 | # CONFIG_AUTOFS4_FS is not set | 460 | # CONFIG_AUTOFS4_FS is not set |
461 | # CONFIG_FUSE_FS is not set | ||
571 | 462 | ||
572 | # | 463 | # |
573 | # CD-ROM/DVD Filesystems | 464 | # CD-ROM/DVD Filesystems |
@@ -587,13 +478,12 @@ CONFIG_DNOTIFY=y | |||
587 | # | 478 | # |
588 | CONFIG_PROC_FS=y | 479 | CONFIG_PROC_FS=y |
589 | CONFIG_PROC_KCORE=y | 480 | CONFIG_PROC_KCORE=y |
481 | CONFIG_PROC_SYSCTL=y | ||
590 | CONFIG_SYSFS=y | 482 | CONFIG_SYSFS=y |
591 | # CONFIG_DEVFS_FS is not set | ||
592 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
593 | CONFIG_TMPFS=y | 483 | CONFIG_TMPFS=y |
594 | # CONFIG_TMPFS_XATTR is not set | 484 | # CONFIG_TMPFS_POSIX_ACL is not set |
595 | # CONFIG_HUGETLB_PAGE is not set | 485 | # CONFIG_HUGETLB_PAGE is not set |
596 | CONFIG_RAMFS=y | 486 | # CONFIG_CONFIGFS_FS is not set |
597 | 487 | ||
598 | # | 488 | # |
599 | # Miscellaneous filesystems | 489 | # Miscellaneous filesystems |
@@ -605,15 +495,15 @@ CONFIG_RAMFS=y | |||
605 | # CONFIG_BEFS_FS is not set | 495 | # CONFIG_BEFS_FS is not set |
606 | # CONFIG_BFS_FS is not set | 496 | # CONFIG_BFS_FS is not set |
607 | # CONFIG_EFS_FS is not set | 497 | # CONFIG_EFS_FS is not set |
608 | CONFIG_JFFS_FS=y | ||
609 | CONFIG_JFFS_FS_VERBOSE=0 | ||
610 | # CONFIG_JFFS_PROC_FS is not set | ||
611 | CONFIG_JFFS2_FS=y | 498 | CONFIG_JFFS2_FS=y |
612 | CONFIG_JFFS2_FS_DEBUG=0 | 499 | CONFIG_JFFS2_FS_DEBUG=0 |
613 | # CONFIG_JFFS2_FS_NAND is not set | 500 | CONFIG_JFFS2_FS_WRITEBUFFER=y |
614 | # CONFIG_JFFS2_FS_NOR_ECC is not set | 501 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set |
502 | # CONFIG_JFFS2_SUMMARY is not set | ||
503 | # CONFIG_JFFS2_FS_XATTR is not set | ||
615 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | 504 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set |
616 | CONFIG_JFFS2_ZLIB=y | 505 | CONFIG_JFFS2_ZLIB=y |
506 | # CONFIG_JFFS2_LZO is not set | ||
617 | CONFIG_JFFS2_RTIME=y | 507 | CONFIG_JFFS2_RTIME=y |
618 | # CONFIG_JFFS2_RUBIN is not set | 508 | # CONFIG_JFFS2_RUBIN is not set |
619 | CONFIG_CRAMFS=y | 509 | CONFIG_CRAMFS=y |
@@ -622,12 +512,10 @@ CONFIG_CRAMFS=y | |||
622 | # CONFIG_QNX4FS_FS is not set | 512 | # CONFIG_QNX4FS_FS is not set |
623 | # CONFIG_SYSV_FS is not set | 513 | # CONFIG_SYSV_FS is not set |
624 | # CONFIG_UFS_FS is not set | 514 | # CONFIG_UFS_FS is not set |
625 | 515 | CONFIG_NETWORK_FILESYSTEMS=y | |
626 | # | ||
627 | # Network File Systems | ||
628 | # | ||
629 | CONFIG_NFS_FS=y | 516 | CONFIG_NFS_FS=y |
630 | CONFIG_NFS_V3=y | 517 | CONFIG_NFS_V3=y |
518 | # CONFIG_NFS_V3_ACL is not set | ||
631 | # CONFIG_NFS_V4 is not set | 519 | # CONFIG_NFS_V4 is not set |
632 | # CONFIG_NFS_DIRECTIO is not set | 520 | # CONFIG_NFS_DIRECTIO is not set |
633 | # CONFIG_NFSD is not set | 521 | # CONFIG_NFSD is not set |
@@ -649,181 +537,44 @@ CONFIG_SUNRPC=y | |||
649 | # | 537 | # |
650 | # CONFIG_PARTITION_ADVANCED is not set | 538 | # CONFIG_PARTITION_ADVANCED is not set |
651 | CONFIG_MSDOS_PARTITION=y | 539 | CONFIG_MSDOS_PARTITION=y |
652 | |||
653 | # | ||
654 | # Native Language Support | ||
655 | # | ||
656 | # CONFIG_NLS is not set | 540 | # CONFIG_NLS is not set |
657 | 541 | # CONFIG_DLM is not set | |
658 | # | ||
659 | # Sound | ||
660 | # | ||
661 | # CONFIG_SOUND is not set | ||
662 | |||
663 | # | ||
664 | # Generic devices | ||
665 | # | ||
666 | # CONFIG_SND_MPU401_UART is not set | ||
667 | # CONFIG_SND_DUMMY is not set | ||
668 | # CONFIG_SND_VIRMIDI is not set | ||
669 | # CONFIG_SND_MTPAV is not set | ||
670 | # CONFIG_SND_SERIAL_U16550 is not set | ||
671 | # CONFIG_SND_MPU401 is not set | ||
672 | |||
673 | # | ||
674 | # PCCARD (PCMCIA/CardBus) support | ||
675 | # | ||
676 | # CONFIG_PCCARD is not set | ||
677 | # CONFIG_PARPORT_PC_PCMCIA is not set | ||
678 | # CONFIG_NET_PCMCIA is not set | ||
679 | |||
680 | # | ||
681 | # PC-card bridges | ||
682 | # | ||
683 | |||
684 | # | ||
685 | # USB support | ||
686 | # | ||
687 | CONFIG_USB=y | ||
688 | # CONFIG_USB_DEBUG is not set | ||
689 | |||
690 | # | ||
691 | # Miscellaneous USB options | ||
692 | # | ||
693 | CONFIG_USB_DEVICEFS=y | ||
694 | # CONFIG_USB_BANDWIDTH is not set | ||
695 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
696 | # CONFIG_USB_OTG is not set | ||
697 | # CONFIG_USB_ARCH_HAS_HCD is not set | ||
698 | # CONFIG_USB_ARCH_HAS_OHCI is not set | ||
699 | |||
700 | # | ||
701 | # USB Host Controller Drivers | ||
702 | # | ||
703 | # CONFIG_USB_SL811_HCD is not set | ||
704 | |||
705 | # | ||
706 | # USB Device Class drivers | ||
707 | # | ||
708 | |||
709 | # | ||
710 | # USB Bluetooth TTY can only be used with disabled Bluetooth subsystem | ||
711 | # | ||
712 | # CONFIG_USB_ACM is not set | ||
713 | # CONFIG_USB_PRINTER is not set | ||
714 | |||
715 | # | ||
716 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
717 | # | ||
718 | # CONFIG_USB_STORAGE is not set | ||
719 | |||
720 | # | ||
721 | # USB Input Devices | ||
722 | # | ||
723 | # CONFIG_USB_HID is not set | ||
724 | # HID_SUPPORT is not set | ||
725 | |||
726 | # | ||
727 | # USB HID Boot Protocol drivers | ||
728 | # | ||
729 | # CONFIG_USB_KBD is not set | ||
730 | # CONFIG_USB_MOUSE is not set | ||
731 | # CONFIG_USB_AIPTEK is not set | ||
732 | # CONFIG_USB_WACOM is not set | ||
733 | # CONFIG_USB_KBTAB is not set | ||
734 | # CONFIG_USB_POWERMATE is not set | ||
735 | # CONFIG_USB_MTOUCH is not set | ||
736 | # CONFIG_USB_EGALAX is not set | ||
737 | # CONFIG_USB_XPAD is not set | ||
738 | # CONFIG_USB_ATI_REMOTE is not set | ||
739 | |||
740 | # | ||
741 | # USB Imaging devices | ||
742 | # | ||
743 | # CONFIG_USB_MDC800 is not set | ||
744 | |||
745 | # | ||
746 | # USB Multimedia devices | ||
747 | # | ||
748 | # CONFIG_USB_DABUSB is not set | ||
749 | |||
750 | # | ||
751 | # Video4Linux support is needed for USB Multimedia device support | ||
752 | # | ||
753 | |||
754 | # | ||
755 | # USB Network Adapters | ||
756 | # | ||
757 | # CONFIG_USB_CATC is not set | ||
758 | # CONFIG_USB_KAWETH is not set | ||
759 | # CONFIG_USB_PEGASUS is not set | ||
760 | CONFIG_USB_RTL8150=y | ||
761 | # CONFIG_USB_USBNET is not set | ||
762 | |||
763 | # | ||
764 | # USB port drivers | ||
765 | # | ||
766 | |||
767 | # | ||
768 | # USB Serial Converter support | ||
769 | # | ||
770 | # CONFIG_USB_SERIAL is not set | ||
771 | |||
772 | # | ||
773 | # USB Miscellaneous drivers | ||
774 | # | ||
775 | # CONFIG_USB_EMI62 is not set | ||
776 | # CONFIG_USB_EMI26 is not set | ||
777 | # CONFIG_USB_AUERSWALD is not set | ||
778 | # CONFIG_USB_RIO500 is not set | ||
779 | # CONFIG_USB_LEGOTOWER is not set | ||
780 | # CONFIG_USB_LCD is not set | ||
781 | # CONFIG_USB_LED is not set | ||
782 | # CONFIG_USB_CYTHERM is not set | ||
783 | # CONFIG_USB_PHIDGETKIT is not set | ||
784 | # CONFIG_USB_PHIDGETSERVO is not set | ||
785 | # CONFIG_USB_IDMOUSE is not set | ||
786 | # CONFIG_USB_TEST is not set | ||
787 | |||
788 | # | ||
789 | # USB ATM/DSL drivers | ||
790 | # | ||
791 | |||
792 | # | ||
793 | # USB Gadget Support | ||
794 | # | ||
795 | # CONFIG_USB_GADGET is not set | ||
796 | 542 | ||
797 | # | 543 | # |
798 | # Kernel hacking | 544 | # Kernel hacking |
799 | # | 545 | # |
800 | # CONFIG_PROFILING is not set | 546 | # CONFIG_PROFILING is not set |
801 | # CONFIG_SYSTEM_PROFILER is not set | 547 | # CONFIG_SYSTEM_PROFILER is not set |
802 | # CONFIG_ETRAX_KGDB is not set | 548 | # CONFIG_PRINTK_TIME is not set |
803 | # CONFIG_DEBUG_INFO is not set | 549 | CONFIG_ENABLE_WARN_DEPRECATED=y |
804 | # CONFIG_FRAME_POINTER is not set | 550 | CONFIG_ENABLE_MUST_CHECK=y |
805 | # CONFIG_DEBUG_NMI_OOPS is not set | 551 | # CONFIG_MAGIC_SYSRQ is not set |
552 | # CONFIG_UNUSED_SYMBOLS is not set | ||
553 | # CONFIG_DEBUG_FS is not set | ||
554 | # CONFIG_HEADERS_CHECK is not set | ||
555 | # CONFIG_DEBUG_KERNEL is not set | ||
556 | # CONFIG_SLUB_DEBUG_ON is not set | ||
557 | # CONFIG_SAMPLES is not set | ||
806 | 558 | ||
807 | # | 559 | # |
808 | # Security options | 560 | # Security options |
809 | # | 561 | # |
810 | # CONFIG_KEYS is not set | 562 | # CONFIG_KEYS is not set |
811 | # CONFIG_SECURITY is not set | 563 | # CONFIG_SECURITY is not set |
812 | 564 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | |
813 | # | ||
814 | # Cryptographic options | ||
815 | # | ||
816 | # CONFIG_CRYPTO is not set | 565 | # CONFIG_CRYPTO is not set |
817 | 566 | ||
818 | # | 567 | # |
819 | # Hardware crypto devices | ||
820 | # CONFIG_CRYPTO_HW is not set | ||
821 | |||
822 | # | ||
823 | # Library routines | 568 | # Library routines |
824 | # | 569 | # |
570 | CONFIG_BITREVERSE=y | ||
825 | # CONFIG_CRC_CCITT is not set | 571 | # CONFIG_CRC_CCITT is not set |
572 | # CONFIG_CRC16 is not set | ||
573 | # CONFIG_CRC_ITU_T is not set | ||
826 | CONFIG_CRC32=y | 574 | CONFIG_CRC32=y |
575 | # CONFIG_CRC7 is not set | ||
827 | # CONFIG_LIBCRC32C is not set | 576 | # CONFIG_LIBCRC32C is not set |
828 | CONFIG_ZLIB_INFLATE=y | 577 | CONFIG_ZLIB_INFLATE=y |
829 | CONFIG_ZLIB_DEFLATE=y | 578 | CONFIG_ZLIB_DEFLATE=y |
579 | CONFIG_PLIST=y | ||
580 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/cris/etraxfs_defconfig b/arch/cris/etraxfs_defconfig new file mode 100644 index 000000000000..73c646a37255 --- /dev/null +++ b/arch/cris/etraxfs_defconfig | |||
@@ -0,0 +1,585 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.24-rc3 | ||
4 | # Fri Nov 30 14:24:26 2007 | ||
5 | # | ||
6 | CONFIG_MMU=y | ||
7 | CONFIG_ZONE_DMA=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_IOMAP=y | ||
10 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
11 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
12 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
13 | CONFIG_GENERIC_HWEIGHT=y | ||
14 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
15 | CONFIG_NO_IOPORT=y | ||
16 | CONFIG_FORCE_MAX_ZONEORDER=6 | ||
17 | CONFIG_CRIS=y | ||
18 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_EXPERIMENTAL=y | ||
24 | CONFIG_BROKEN_ON_SMP=y | ||
25 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
26 | CONFIG_LOCALVERSION="" | ||
27 | CONFIG_LOCALVERSION_AUTO=y | ||
28 | # CONFIG_SWAP is not set | ||
29 | # CONFIG_SYSVIPC is not set | ||
30 | # CONFIG_POSIX_MQUEUE is not set | ||
31 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
32 | # CONFIG_TASKSTATS is not set | ||
33 | # CONFIG_USER_NS is not set | ||
34 | # CONFIG_PID_NS is not set | ||
35 | # CONFIG_AUDIT is not set | ||
36 | # CONFIG_IKCONFIG is not set | ||
37 | CONFIG_LOG_BUF_SHIFT=14 | ||
38 | # CONFIG_CGROUPS is not set | ||
39 | CONFIG_FAIR_GROUP_SCHED=y | ||
40 | CONFIG_FAIR_USER_SCHED=y | ||
41 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
42 | CONFIG_SYSFS_DEPRECATED=y | ||
43 | # CONFIG_RELAY is not set | ||
44 | # CONFIG_BLK_DEV_INITRD is not set | ||
45 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
46 | CONFIG_SYSCTL=y | ||
47 | CONFIG_EMBEDDED=y | ||
48 | CONFIG_UID16=y | ||
49 | CONFIG_SYSCTL_SYSCALL=y | ||
50 | # CONFIG_KALLSYMS is not set | ||
51 | # CONFIG_HOTPLUG is not set | ||
52 | CONFIG_PRINTK=y | ||
53 | CONFIG_BUG=y | ||
54 | CONFIG_ELF_CORE=y | ||
55 | CONFIG_BASE_FULL=y | ||
56 | CONFIG_FUTEX=y | ||
57 | CONFIG_ANON_INODES=y | ||
58 | CONFIG_EPOLL=y | ||
59 | CONFIG_SIGNALFD=y | ||
60 | CONFIG_EVENTFD=y | ||
61 | CONFIG_SHMEM=y | ||
62 | CONFIG_VM_EVENT_COUNTERS=y | ||
63 | CONFIG_SLUB_DEBUG=y | ||
64 | # CONFIG_SLAB is not set | ||
65 | CONFIG_SLUB=y | ||
66 | # CONFIG_SLOB is not set | ||
67 | CONFIG_RT_MUTEXES=y | ||
68 | # CONFIG_TINY_SHMEM is not set | ||
69 | CONFIG_BASE_SMALL=0 | ||
70 | # CONFIG_MODULES is not set | ||
71 | CONFIG_BLOCK=y | ||
72 | # CONFIG_LBD is not set | ||
73 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
74 | # CONFIG_LSF is not set | ||
75 | # CONFIG_BLK_DEV_BSG is not set | ||
76 | |||
77 | # | ||
78 | # IO Schedulers | ||
79 | # | ||
80 | CONFIG_IOSCHED_NOOP=y | ||
81 | # CONFIG_IOSCHED_AS is not set | ||
82 | # CONFIG_IOSCHED_DEADLINE is not set | ||
83 | CONFIG_IOSCHED_CFQ=y | ||
84 | # CONFIG_DEFAULT_AS is not set | ||
85 | # CONFIG_DEFAULT_DEADLINE is not set | ||
86 | CONFIG_DEFAULT_CFQ=y | ||
87 | # CONFIG_DEFAULT_NOOP is not set | ||
88 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
89 | |||
90 | # | ||
91 | # General setup | ||
92 | # | ||
93 | CONFIG_BINFMT_ELF=y | ||
94 | # CONFIG_BINFMT_MISC is not set | ||
95 | CONFIG_GENERIC_HARDIRQS=y | ||
96 | CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock3 init=/linuxrc" | ||
97 | # CONFIG_ETRAX_WATCHDOG is not set | ||
98 | CONFIG_ETRAX_FAST_TIMER=y | ||
99 | # CONFIG_ETRAX_KMALLOCED_MODULES is not set | ||
100 | # CONFIG_OOM_REBOOT is not set | ||
101 | CONFIG_PREEMPT_NONE=y | ||
102 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
103 | # CONFIG_PREEMPT is not set | ||
104 | CONFIG_SELECT_MEMORY_MODEL=y | ||
105 | CONFIG_FLATMEM_MANUAL=y | ||
106 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
107 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
108 | CONFIG_FLATMEM=y | ||
109 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
110 | # CONFIG_SPARSEMEM_STATIC is not set | ||
111 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
112 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
113 | # CONFIG_RESOURCES_64BIT is not set | ||
114 | CONFIG_ZONE_DMA_FLAG=1 | ||
115 | CONFIG_BOUNCE=y | ||
116 | CONFIG_VIRT_TO_BUS=y | ||
117 | |||
118 | # | ||
119 | # Hardware setup | ||
120 | # | ||
121 | # CONFIG_ETRAX100LX is not set | ||
122 | # CONFIG_ETRAX100LX_V2 is not set | ||
123 | # CONFIG_SVINTO_SIM is not set | ||
124 | CONFIG_ETRAXFS=y | ||
125 | # CONFIG_CRIS_MACH_ARTPEC3 is not set | ||
126 | # CONFIG_ETRAX_VCS_SIM is not set | ||
127 | # CONFIG_ETRAX_ARCH_V10 is not set | ||
128 | CONFIG_ETRAX_ARCH_V32=y | ||
129 | CONFIG_ETRAX_DRAM_SIZE=32 | ||
130 | CONFIG_ETRAX_FLASH_BUSWIDTH=2 | ||
131 | CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1 | ||
132 | CONFIG_ETRAX_FLASH1_SIZE=4 | ||
133 | CONFIG_ETRAX_DEBUG_PORT0=y | ||
134 | # CONFIG_ETRAX_DEBUG_PORT1 is not set | ||
135 | # CONFIG_ETRAX_DEBUG_PORT2 is not set | ||
136 | # CONFIG_ETRAX_DEBUG_PORT3 is not set | ||
137 | # CONFIG_ETRAX_DEBUG_PORT_NULL is not set | ||
138 | CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000 | ||
139 | |||
140 | # | ||
141 | # ETRAX FS options | ||
142 | # | ||
143 | CONFIG_ETRAX_SERIAL_PORTS=4 | ||
144 | CONFIG_ETRAX_MEM_GRP1_CONFIG=4044a | ||
145 | CONFIG_ETRAX_MEM_GRP2_CONFIG=0 | ||
146 | CONFIG_ETRAX_MEM_GRP3_CONFIG=0 | ||
147 | CONFIG_ETRAX_MEM_GRP4_CONFIG=0 | ||
148 | CONFIG_ETRAX_SDRAM_GRP0_CONFIG=336 | ||
149 | CONFIG_ETRAX_SDRAM_GRP1_CONFIG=0 | ||
150 | CONFIG_ETRAX_SDRAM_TIMING=104a | ||
151 | CONFIG_ETRAX_SDRAM_COMMAND=0 | ||
152 | CONFIG_ETRAX_DEF_GIO_PA_OE=1c | ||
153 | CONFIG_ETRAX_DEF_GIO_PA_OUT=00 | ||
154 | CONFIG_ETRAX_DEF_GIO_PB_OE=00000 | ||
155 | CONFIG_ETRAX_DEF_GIO_PB_OUT=00000 | ||
156 | CONFIG_ETRAX_DEF_GIO_PC_OE=00000 | ||
157 | CONFIG_ETRAX_DEF_GIO_PC_OUT=00000 | ||
158 | CONFIG_ETRAX_DEF_GIO_PD_OE=00000 | ||
159 | CONFIG_ETRAX_DEF_GIO_PD_OUT=00000 | ||
160 | CONFIG_ETRAX_DEF_GIO_PE_OE=00000 | ||
161 | CONFIG_ETRAX_DEF_GIO_PE_OUT=00000 | ||
162 | # CONFIG_CPU_FREQ is not set | ||
163 | # CONFIG_ETRAX_NBR_LED_GRP_ZERO is not set | ||
164 | CONFIG_ETRAX_NBR_LED_GRP_ONE=y | ||
165 | # CONFIG_ETRAX_NBR_LED_GRP_TWO is not set | ||
166 | CONFIG_ETRAX_LED_G_NET0="PA3" | ||
167 | CONFIG_ETRAX_LED_R_NET0="PA4" | ||
168 | CONFIG_ETRAX_V32_LED2G="PA5" | ||
169 | CONFIG_ETRAX_V32_LED2R="PA6" | ||
170 | CONFIG_ETRAX_V32_LED3G="PA7" | ||
171 | CONFIG_ETRAX_V32_LED3R="PA7" | ||
172 | |||
173 | # | ||
174 | # Networking | ||
175 | # | ||
176 | CONFIG_NET=y | ||
177 | |||
178 | # | ||
179 | # Networking options | ||
180 | # | ||
181 | CONFIG_PACKET=y | ||
182 | # CONFIG_PACKET_MMAP is not set | ||
183 | CONFIG_UNIX=y | ||
184 | CONFIG_XFRM=y | ||
185 | # CONFIG_XFRM_USER is not set | ||
186 | # CONFIG_XFRM_SUB_POLICY is not set | ||
187 | # CONFIG_XFRM_MIGRATE is not set | ||
188 | # CONFIG_NET_KEY is not set | ||
189 | CONFIG_INET=y | ||
190 | # CONFIG_IP_MULTICAST is not set | ||
191 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
192 | CONFIG_IP_FIB_HASH=y | ||
193 | # CONFIG_IP_PNP is not set | ||
194 | # CONFIG_NET_IPIP is not set | ||
195 | # CONFIG_NET_IPGRE is not set | ||
196 | # CONFIG_ARPD is not set | ||
197 | # CONFIG_SYN_COOKIES is not set | ||
198 | # CONFIG_INET_AH is not set | ||
199 | # CONFIG_INET_ESP is not set | ||
200 | # CONFIG_INET_IPCOMP is not set | ||
201 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
202 | # CONFIG_INET_TUNNEL is not set | ||
203 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
204 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
205 | CONFIG_INET_XFRM_MODE_BEET=y | ||
206 | # CONFIG_INET_LRO is not set | ||
207 | CONFIG_INET_DIAG=y | ||
208 | CONFIG_INET_TCP_DIAG=y | ||
209 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
210 | CONFIG_TCP_CONG_CUBIC=y | ||
211 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
212 | # CONFIG_TCP_MD5SIG is not set | ||
213 | # CONFIG_IP_VS is not set | ||
214 | # CONFIG_IPV6 is not set | ||
215 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
216 | # CONFIG_INET6_TUNNEL is not set | ||
217 | # CONFIG_NETWORK_SECMARK is not set | ||
218 | CONFIG_NETFILTER=y | ||
219 | # CONFIG_NETFILTER_DEBUG is not set | ||
220 | |||
221 | # | ||
222 | # Core Netfilter Configuration | ||
223 | # | ||
224 | # CONFIG_NETFILTER_NETLINK is not set | ||
225 | # CONFIG_NF_CONNTRACK_ENABLED is not set | ||
226 | # CONFIG_NF_CONNTRACK is not set | ||
227 | # CONFIG_NETFILTER_XTABLES is not set | ||
228 | |||
229 | # | ||
230 | # IP: Netfilter Configuration | ||
231 | # | ||
232 | # CONFIG_IP_NF_QUEUE is not set | ||
233 | # CONFIG_IP_NF_IPTABLES is not set | ||
234 | # CONFIG_IP_NF_ARPTABLES is not set | ||
235 | # CONFIG_IP_DCCP is not set | ||
236 | # CONFIG_IP_SCTP is not set | ||
237 | # CONFIG_TIPC is not set | ||
238 | # CONFIG_ATM is not set | ||
239 | # CONFIG_BRIDGE is not set | ||
240 | # CONFIG_VLAN_8021Q is not set | ||
241 | # CONFIG_DECNET is not set | ||
242 | # CONFIG_LLC2 is not set | ||
243 | # CONFIG_IPX is not set | ||
244 | # CONFIG_ATALK is not set | ||
245 | # CONFIG_X25 is not set | ||
246 | # CONFIG_LAPB is not set | ||
247 | # CONFIG_ECONET is not set | ||
248 | # CONFIG_WAN_ROUTER is not set | ||
249 | # CONFIG_NET_SCHED is not set | ||
250 | |||
251 | # | ||
252 | # Network testing | ||
253 | # | ||
254 | # CONFIG_NET_PKTGEN is not set | ||
255 | # CONFIG_HAMRADIO is not set | ||
256 | # CONFIG_IRDA is not set | ||
257 | # CONFIG_BT is not set | ||
258 | # CONFIG_AF_RXRPC is not set | ||
259 | |||
260 | # | ||
261 | # Wireless | ||
262 | # | ||
263 | # CONFIG_CFG80211 is not set | ||
264 | # CONFIG_WIRELESS_EXT is not set | ||
265 | # CONFIG_MAC80211 is not set | ||
266 | # CONFIG_IEEE80211 is not set | ||
267 | # CONFIG_RFKILL is not set | ||
268 | # CONFIG_NET_9P is not set | ||
269 | |||
270 | # | ||
271 | # Drivers for built-in interfaces | ||
272 | # | ||
273 | CONFIG_ETRAX_ETHERNET=y | ||
274 | # CONFIG_ETRAX_IDE is not set | ||
275 | CONFIG_ETRAX_AXISFLASHMAP=y | ||
276 | CONFIG_ETRAX_PTABLE_SECTOR=65536 | ||
277 | # CONFIG_ETRAX_I2C is not set | ||
278 | # CONFIG_ETRAX_GPIO is not set | ||
279 | # CONFIG_ETRAX_NO_PHY is not set | ||
280 | # CONFIG_ETRAX_ETHERNET_IFACE0 is not set | ||
281 | # CONFIG_ETRAX_ETHERNET_IFACE1 is not set | ||
282 | # CONFIG_ETRAXFS_SERIAL is not set | ||
283 | # CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set | ||
284 | # CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE is not set | ||
285 | # CONFIG_ETRAX_NANDFLASH is not set | ||
286 | # CONFIG_ETRAX_CARDBUS is not set | ||
287 | # CONFIG_ETRAX_IOP_FW_LOAD is not set | ||
288 | # CONFIG_ETRAX_STREAMCOPROC is not set | ||
289 | # CONFIG_ETRAX_SPI_MMC is not set | ||
290 | # CONFIG_ETRAX_SPI_MMC_BOARD is not set | ||
291 | # CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set | ||
292 | CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y | ||
293 | |||
294 | # | ||
295 | # Generic Driver Options | ||
296 | # | ||
297 | CONFIG_STANDALONE=y | ||
298 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
299 | # CONFIG_SYS_HYPERVISOR is not set | ||
300 | CONFIG_MTD=y | ||
301 | # CONFIG_MTD_DEBUG is not set | ||
302 | CONFIG_MTD_CONCAT=y | ||
303 | CONFIG_MTD_PARTITIONS=y | ||
304 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
305 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
306 | |||
307 | # | ||
308 | # User Modules And Translation Layers | ||
309 | # | ||
310 | CONFIG_MTD_CHAR=y | ||
311 | CONFIG_MTD_BLKDEVS=y | ||
312 | CONFIG_MTD_BLOCK=y | ||
313 | # CONFIG_FTL is not set | ||
314 | # CONFIG_NFTL is not set | ||
315 | # CONFIG_INFTL is not set | ||
316 | # CONFIG_RFD_FTL is not set | ||
317 | # CONFIG_SSFDC is not set | ||
318 | # CONFIG_MTD_OOPS is not set | ||
319 | |||
320 | # | ||
321 | # RAM/ROM/Flash chip drivers | ||
322 | # | ||
323 | CONFIG_MTD_CFI=y | ||
324 | CONFIG_MTD_JEDECPROBE=y | ||
325 | CONFIG_MTD_GEN_PROBE=y | ||
326 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
327 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
328 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
329 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
330 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
331 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
332 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
333 | CONFIG_MTD_CFI_I1=y | ||
334 | CONFIG_MTD_CFI_I2=y | ||
335 | # CONFIG_MTD_CFI_I4 is not set | ||
336 | # CONFIG_MTD_CFI_I8 is not set | ||
337 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
338 | CONFIG_MTD_CFI_AMDSTD=y | ||
339 | # CONFIG_MTD_CFI_STAA is not set | ||
340 | CONFIG_MTD_CFI_UTIL=y | ||
341 | CONFIG_MTD_RAM=y | ||
342 | # CONFIG_MTD_ROM is not set | ||
343 | # CONFIG_MTD_ABSENT is not set | ||
344 | |||
345 | # | ||
346 | # Mapping drivers for chip access | ||
347 | # | ||
348 | CONFIG_MTD_COMPLEX_MAPPINGS=y | ||
349 | # CONFIG_MTD_PHYSMAP is not set | ||
350 | # CONFIG_MTD_PLATRAM is not set | ||
351 | |||
352 | # | ||
353 | # Self-contained MTD device drivers | ||
354 | # | ||
355 | # CONFIG_MTD_SLRAM is not set | ||
356 | # CONFIG_MTD_PHRAM is not set | ||
357 | CONFIG_MTD_MTDRAM=y | ||
358 | CONFIG_MTDRAM_TOTAL_SIZE=0 | ||
359 | CONFIG_MTDRAM_ERASE_SIZE=64 | ||
360 | CONFIG_MTDRAM_ABS_POS=0x0 | ||
361 | # CONFIG_MTD_BLOCK2MTD is not set | ||
362 | |||
363 | # | ||
364 | # Disk-On-Chip Device Drivers | ||
365 | # | ||
366 | # CONFIG_MTD_DOC2000 is not set | ||
367 | # CONFIG_MTD_DOC2001 is not set | ||
368 | # CONFIG_MTD_DOC2001PLUS is not set | ||
369 | # CONFIG_MTD_NAND is not set | ||
370 | # CONFIG_MTD_ONENAND is not set | ||
371 | |||
372 | # | ||
373 | # UBI - Unsorted block images | ||
374 | # | ||
375 | # CONFIG_MTD_UBI is not set | ||
376 | CONFIG_BLK_DEV=y | ||
377 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
378 | # CONFIG_BLK_DEV_LOOP is not set | ||
379 | # CONFIG_BLK_DEV_NBD is not set | ||
380 | CONFIG_BLK_DEV_RAM=y | ||
381 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
382 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
383 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | ||
384 | # CONFIG_CDROM_PKTCDVD is not set | ||
385 | # CONFIG_ATA_OVER_ETH is not set | ||
386 | CONFIG_NETDEVICES=y | ||
387 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
388 | # CONFIG_DUMMY is not set | ||
389 | # CONFIG_BONDING is not set | ||
390 | # CONFIG_MACVLAN is not set | ||
391 | # CONFIG_EQUALIZER is not set | ||
392 | # CONFIG_TUN is not set | ||
393 | # CONFIG_VETH is not set | ||
394 | # CONFIG_PHYLIB is not set | ||
395 | CONFIG_NET_ETHERNET=y | ||
396 | CONFIG_MII=y | ||
397 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
398 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
399 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
400 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
401 | CONFIG_NETDEV_1000=y | ||
402 | CONFIG_NETDEV_10000=y | ||
403 | |||
404 | # | ||
405 | # Wireless LAN | ||
406 | # | ||
407 | # CONFIG_WLAN_PRE80211 is not set | ||
408 | # CONFIG_WLAN_80211 is not set | ||
409 | # CONFIG_WAN is not set | ||
410 | # CONFIG_PPP is not set | ||
411 | # CONFIG_SLIP is not set | ||
412 | # CONFIG_SHAPER is not set | ||
413 | # CONFIG_NETCONSOLE is not set | ||
414 | # CONFIG_NETPOLL is not set | ||
415 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
416 | # CONFIG_RTC_CLASS is not set | ||
417 | |||
418 | # | ||
419 | # Input device support | ||
420 | # | ||
421 | # CONFIG_INPUT is not set | ||
422 | |||
423 | # | ||
424 | # Hardware I/O ports | ||
425 | # | ||
426 | CONFIG_SERIO=y | ||
427 | # CONFIG_SERIO_I8042 is not set | ||
428 | # CONFIG_SERIO_SERPORT is not set | ||
429 | # CONFIG_SERIO_LIBPS2 is not set | ||
430 | # CONFIG_SERIO_RAW is not set | ||
431 | # CONFIG_GAMEPORT is not set | ||
432 | |||
433 | # | ||
434 | # Character devices | ||
435 | # | ||
436 | # CONFIG_VT is not set | ||
437 | CONFIG_UNIX98_PTYS=y | ||
438 | CONFIG_LEGACY_PTYS=y | ||
439 | CONFIG_LEGACY_PTY_COUNT=256 | ||
440 | CONFIG_HW_RANDOM=y | ||
441 | # CONFIG_RTC is not set | ||
442 | # CONFIG_GEN_RTC is not set | ||
443 | # CONFIG_R3964 is not set | ||
444 | # CONFIG_RAW_DRIVER is not set | ||
445 | |||
446 | # | ||
447 | # File systems | ||
448 | # | ||
449 | # CONFIG_EXT2_FS is not set | ||
450 | # CONFIG_EXT3_FS is not set | ||
451 | # CONFIG_EXT4DEV_FS is not set | ||
452 | # CONFIG_REISERFS_FS is not set | ||
453 | # CONFIG_JFS_FS is not set | ||
454 | # CONFIG_FS_POSIX_ACL is not set | ||
455 | # CONFIG_XFS_FS is not set | ||
456 | # CONFIG_GFS2_FS is not set | ||
457 | # CONFIG_OCFS2_FS is not set | ||
458 | # CONFIG_MINIX_FS is not set | ||
459 | # CONFIG_ROMFS_FS is not set | ||
460 | CONFIG_INOTIFY=y | ||
461 | CONFIG_INOTIFY_USER=y | ||
462 | # CONFIG_QUOTA is not set | ||
463 | CONFIG_DNOTIFY=y | ||
464 | # CONFIG_AUTOFS_FS is not set | ||
465 | # CONFIG_AUTOFS4_FS is not set | ||
466 | # CONFIG_FUSE_FS is not set | ||
467 | |||
468 | # | ||
469 | # CD-ROM/DVD Filesystems | ||
470 | # | ||
471 | # CONFIG_ISO9660_FS is not set | ||
472 | # CONFIG_UDF_FS is not set | ||
473 | |||
474 | # | ||
475 | # DOS/FAT/NT Filesystems | ||
476 | # | ||
477 | # CONFIG_MSDOS_FS is not set | ||
478 | # CONFIG_VFAT_FS is not set | ||
479 | # CONFIG_NTFS_FS is not set | ||
480 | |||
481 | # | ||
482 | # Pseudo filesystems | ||
483 | # | ||
484 | CONFIG_PROC_FS=y | ||
485 | CONFIG_PROC_KCORE=y | ||
486 | CONFIG_PROC_SYSCTL=y | ||
487 | CONFIG_SYSFS=y | ||
488 | CONFIG_TMPFS=y | ||
489 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
490 | # CONFIG_HUGETLB_PAGE is not set | ||
491 | # CONFIG_CONFIGFS_FS is not set | ||
492 | |||
493 | # | ||
494 | # Miscellaneous filesystems | ||
495 | # | ||
496 | # CONFIG_ADFS_FS is not set | ||
497 | # CONFIG_AFFS_FS is not set | ||
498 | # CONFIG_HFS_FS is not set | ||
499 | # CONFIG_HFSPLUS_FS is not set | ||
500 | # CONFIG_BEFS_FS is not set | ||
501 | # CONFIG_BFS_FS is not set | ||
502 | # CONFIG_EFS_FS is not set | ||
503 | CONFIG_JFFS2_FS=y | ||
504 | CONFIG_JFFS2_FS_DEBUG=0 | ||
505 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
506 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
507 | # CONFIG_JFFS2_SUMMARY is not set | ||
508 | # CONFIG_JFFS2_FS_XATTR is not set | ||
509 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
510 | CONFIG_JFFS2_ZLIB=y | ||
511 | # CONFIG_JFFS2_LZO is not set | ||
512 | CONFIG_JFFS2_RTIME=y | ||
513 | # CONFIG_JFFS2_RUBIN is not set | ||
514 | CONFIG_CRAMFS=y | ||
515 | # CONFIG_VXFS_FS is not set | ||
516 | # CONFIG_HPFS_FS is not set | ||
517 | # CONFIG_QNX4FS_FS is not set | ||
518 | # CONFIG_SYSV_FS is not set | ||
519 | # CONFIG_UFS_FS is not set | ||
520 | CONFIG_NETWORK_FILESYSTEMS=y | ||
521 | CONFIG_NFS_FS=y | ||
522 | CONFIG_NFS_V3=y | ||
523 | # CONFIG_NFS_V3_ACL is not set | ||
524 | # CONFIG_NFS_V4 is not set | ||
525 | # CONFIG_NFS_DIRECTIO is not set | ||
526 | # CONFIG_NFSD is not set | ||
527 | CONFIG_LOCKD=y | ||
528 | CONFIG_LOCKD_V4=y | ||
529 | CONFIG_NFS_COMMON=y | ||
530 | CONFIG_SUNRPC=y | ||
531 | # CONFIG_SUNRPC_BIND34 is not set | ||
532 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
533 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
534 | # CONFIG_SMB_FS is not set | ||
535 | # CONFIG_CIFS is not set | ||
536 | # CONFIG_NCP_FS is not set | ||
537 | # CONFIG_CODA_FS is not set | ||
538 | # CONFIG_AFS_FS is not set | ||
539 | |||
540 | # | ||
541 | # Partition Types | ||
542 | # | ||
543 | # CONFIG_PARTITION_ADVANCED is not set | ||
544 | CONFIG_MSDOS_PARTITION=y | ||
545 | # CONFIG_NLS is not set | ||
546 | # CONFIG_DLM is not set | ||
547 | |||
548 | # | ||
549 | # Kernel hacking | ||
550 | # | ||
551 | # CONFIG_PROFILING is not set | ||
552 | # CONFIG_SYSTEM_PROFILER is not set | ||
553 | # CONFIG_PRINTK_TIME is not set | ||
554 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
555 | CONFIG_ENABLE_MUST_CHECK=y | ||
556 | # CONFIG_MAGIC_SYSRQ is not set | ||
557 | # CONFIG_UNUSED_SYMBOLS is not set | ||
558 | # CONFIG_DEBUG_FS is not set | ||
559 | # CONFIG_HEADERS_CHECK is not set | ||
560 | # CONFIG_DEBUG_KERNEL is not set | ||
561 | # CONFIG_SLUB_DEBUG_ON is not set | ||
562 | # CONFIG_SAMPLES is not set | ||
563 | |||
564 | # | ||
565 | # Security options | ||
566 | # | ||
567 | # CONFIG_KEYS is not set | ||
568 | # CONFIG_SECURITY is not set | ||
569 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
570 | # CONFIG_CRYPTO is not set | ||
571 | |||
572 | # | ||
573 | # Library routines | ||
574 | # | ||
575 | CONFIG_BITREVERSE=y | ||
576 | # CONFIG_CRC_CCITT is not set | ||
577 | # CONFIG_CRC16 is not set | ||
578 | # CONFIG_CRC_ITU_T is not set | ||
579 | CONFIG_CRC32=y | ||
580 | # CONFIG_CRC7 is not set | ||
581 | # CONFIG_LIBCRC32C is not set | ||
582 | CONFIG_ZLIB_INFLATE=y | ||
583 | CONFIG_ZLIB_DEFLATE=y | ||
584 | CONFIG_PLIST=y | ||
585 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c index 11b867df8617..a187833febc8 100644 --- a/arch/cris/kernel/module.c +++ b/arch/cris/kernel/module.c | |||
@@ -28,20 +28,28 @@ | |||
28 | #define DEBUGP(fmt , ...) | 28 | #define DEBUGP(fmt , ...) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #ifdef CONFIG_ETRAX_KMALLOCED_MODULES | ||
32 | #define MALLOC_MODULE(size) kmalloc(size, GFP_KERNEL) | ||
33 | #define FREE_MODULE(region) kfree(region) | ||
34 | #else | ||
35 | #define MALLOC_MODULE(size) vmalloc_exec(size) | ||
36 | #define FREE_MODULE(region) vfree(region) | ||
37 | #endif | ||
38 | |||
31 | void *module_alloc(unsigned long size) | 39 | void *module_alloc(unsigned long size) |
32 | { | 40 | { |
33 | if (size == 0) | 41 | if (size == 0) |
34 | return NULL; | 42 | return NULL; |
35 | return vmalloc_exec(size); | 43 | return MALLOC_MODULE(size); |
36 | } | 44 | } |
37 | 45 | ||
38 | 46 | ||
39 | /* Free memory returned from module_alloc */ | 47 | /* Free memory returned from module_alloc */ |
40 | void module_free(struct module *mod, void *module_region) | 48 | void module_free(struct module *mod, void *module_region) |
41 | { | 49 | { |
42 | vfree(module_region); | 50 | FREE_MODULE(module_region); |
43 | /* FIXME: If module_region == mod->init_region, trim exception | 51 | /* FIXME: If module_region == mod->init_region, trim exception |
44 | table entries. */ | 52 | table entries. */ |
45 | } | 53 | } |
46 | 54 | ||
47 | /* We don't need anything special. */ | 55 | /* We don't need anything special. */ |
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 9ca558fc5bc8..ef2db8fd102a 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: process.c,v 1.21 2005/03/04 08:16:17 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/kernel/process.c | 2 | * linux/arch/cris/kernel/process.c |
4 | * | 3 | * |
5 | * Copyright (C) 1995 Linus Torvalds | 4 | * Copyright (C) 1995 Linus Torvalds |
@@ -7,105 +6,6 @@ | |||
7 | * | 6 | * |
8 | * Authors: Bjorn Wesen (bjornw@axis.com) | 7 | * Authors: Bjorn Wesen (bjornw@axis.com) |
9 | * | 8 | * |
10 | * $Log: process.c,v $ | ||
11 | * Revision 1.21 2005/03/04 08:16:17 starvik | ||
12 | * Merge of Linux 2.6.11. | ||
13 | * | ||
14 | * Revision 1.20 2005/01/18 05:57:22 starvik | ||
15 | * Renamed hlt_counter to cris_hlt_counter and made it global. | ||
16 | * | ||
17 | * Revision 1.19 2004/10/19 13:07:43 starvik | ||
18 | * Merge of Linux 2.6.9 | ||
19 | * | ||
20 | * Revision 1.18 2004/08/16 12:37:23 starvik | ||
21 | * Merge of Linux 2.6.8 | ||
22 | * | ||
23 | * Revision 1.17 2004/04/05 13:53:48 starvik | ||
24 | * Merge of Linux 2.6.5 | ||
25 | * | ||
26 | * Revision 1.16 2003/10/27 08:04:33 starvik | ||
27 | * Merge of Linux 2.6.0-test9 | ||
28 | * | ||
29 | * Revision 1.15 2003/09/11 07:29:52 starvik | ||
30 | * Merge of Linux 2.6.0-test5 | ||
31 | * | ||
32 | * Revision 1.14 2003/06/10 10:21:12 johana | ||
33 | * Moved thread_saved_pc() from arch/cris/kernel/process.c to | ||
34 | * subarch specific process.c. arch-v32 has an erp, no irp. | ||
35 | * | ||
36 | * Revision 1.13 2003/04/09 05:20:47 starvik | ||
37 | * Merge of Linux 2.5.67 | ||
38 | * | ||
39 | * Revision 1.12 2002/12/11 15:41:11 starvik | ||
40 | * Extracted v10 (ETRAX 100LX) specific stuff to arch/cris/arch-v10/kernel | ||
41 | * | ||
42 | * Revision 1.11 2002/12/10 09:00:10 starvik | ||
43 | * Merge of Linux 2.5.51 | ||
44 | * | ||
45 | * Revision 1.10 2002/11/27 08:42:34 starvik | ||
46 | * Argument to user_regs() is thread_info* | ||
47 | * | ||
48 | * Revision 1.9 2002/11/26 09:44:21 starvik | ||
49 | * New threads exits through ret_from_fork (necessary for preemptive scheduling) | ||
50 | * | ||
51 | * Revision 1.8 2002/11/19 14:35:24 starvik | ||
52 | * Changes from linux 2.4 | ||
53 | * Changed struct initializer syntax to the currently prefered notation | ||
54 | * | ||
55 | * Revision 1.7 2002/11/18 07:39:42 starvik | ||
56 | * thread_saved_pc moved here from processor.h | ||
57 | * | ||
58 | * Revision 1.6 2002/11/14 06:51:27 starvik | ||
59 | * Made cpu_idle more similar with other archs | ||
60 | * init_task_union -> init_thread_union | ||
61 | * Updated for new interrupt macros | ||
62 | * sys_clone and do_fork have a new argument, user_tid | ||
63 | * | ||
64 | * Revision 1.5 2002/11/05 06:45:11 starvik | ||
65 | * Merge of Linux 2.5.45 | ||
66 | * | ||
67 | * Revision 1.4 2002/02/05 15:37:44 bjornw | ||
68 | * Need init_task.h | ||
69 | * | ||
70 | * Revision 1.3 2002/01/21 15:22:49 bjornw | ||
71 | * current->counter is gone | ||
72 | * | ||
73 | * Revision 1.22 2001/11/13 09:40:43 orjanf | ||
74 | * Added dump_fpu (needed for core dumps). | ||
75 | * | ||
76 | * Revision 1.21 2001/11/12 18:26:21 pkj | ||
77 | * Fixed compiler warnings. | ||
78 | * | ||
79 | * Revision 1.20 2001/10/03 08:21:39 jonashg | ||
80 | * cause_of_death does not exist if CONFIG_SVINTO_SIM is defined. | ||
81 | * | ||
82 | * Revision 1.19 2001/09/26 11:52:54 bjornw | ||
83 | * INIT_MMAP is gone in 2.4.10 | ||
84 | * | ||
85 | * Revision 1.18 2001/08/21 21:43:51 hp | ||
86 | * Move last watchdog fix inside #ifdef CONFIG_ETRAX_WATCHDOG | ||
87 | * | ||
88 | * Revision 1.17 2001/08/21 13:48:01 jonashg | ||
89 | * Added fix by HP to avoid oops when doing a hard_reset_now. | ||
90 | * | ||
91 | * Revision 1.16 2001/06/21 02:00:40 hp | ||
92 | * * entry.S: Include asm/unistd.h. | ||
93 | * (_sys_call_table): Use section .rodata, not .data. | ||
94 | * (_kernel_thread): Move from... | ||
95 | * * process.c: ... here. | ||
96 | * * entryoffsets.c (VAL): Break out from... | ||
97 | * (OF): Use VAL. | ||
98 | * (LCLONE_VM): New asmified value from CLONE_VM. | ||
99 | * | ||
100 | * Revision 1.15 2001/06/20 16:31:57 hp | ||
101 | * Add comments to describe empty functions according to review. | ||
102 | * | ||
103 | * Revision 1.14 2001/05/29 11:27:59 markusl | ||
104 | * Fixed so that hard_reset_now will do reset even if watchdog wasn't enabled | ||
105 | * | ||
106 | * Revision 1.13 2001/03/20 19:44:06 bjornw | ||
107 | * Use the 7th syscall argument for regs instead of current_regs | ||
108 | * | ||
109 | */ | 9 | */ |
110 | 10 | ||
111 | /* | 11 | /* |
@@ -206,6 +106,7 @@ EXPORT_SYMBOL(pm_power_off); | |||
206 | * low exit latency (ie sit in a loop waiting for | 106 | * low exit latency (ie sit in a loop waiting for |
207 | * somebody to say that they'd like to reschedule) | 107 | * somebody to say that they'd like to reschedule) |
208 | */ | 108 | */ |
109 | |||
209 | void cpu_idle (void) | 110 | void cpu_idle (void) |
210 | { | 111 | { |
211 | /* endless idle loop with no priority at all */ | 112 | /* endless idle loop with no priority at all */ |
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c index 3ccd20e85dce..b326023baab2 100644 --- a/arch/cris/kernel/ptrace.c +++ b/arch/cris/kernel/ptrace.c | |||
@@ -2,65 +2,11 @@ | |||
2 | * linux/arch/cris/kernel/ptrace.c | 2 | * linux/arch/cris/kernel/ptrace.c |
3 | * | 3 | * |
4 | * Parts taken from the m68k port. | 4 | * Parts taken from the m68k port. |
5 | * | 5 | * |
6 | * Copyright (c) 2000, 2001, 2002 Axis Communications AB | 6 | * Copyright (c) 2000, 2001, 2002 Axis Communications AB |
7 | * | 7 | * |
8 | * Authors: Bjorn Wesen | 8 | * Authors: Bjorn Wesen |
9 | * | 9 | * |
10 | * $Log: ptrace.c,v $ | ||
11 | * Revision 1.10 2004/09/22 11:50:01 orjanf | ||
12 | * * Moved get_reg/put_reg to arch-specific files. | ||
13 | * * Added functions to access debug registers (CRISv32). | ||
14 | * * Added support for PTRACE_SINGLESTEP (CRISv32). | ||
15 | * * Added S flag to CCS_MASK (CRISv32). | ||
16 | * | ||
17 | * Revision 1.9 2003/07/04 12:56:11 tobiasa | ||
18 | * Moved arch-specific code to arch-specific files. | ||
19 | * | ||
20 | * Revision 1.8 2003/04/09 05:20:47 starvik | ||
21 | * Merge of Linux 2.5.67 | ||
22 | * | ||
23 | * Revision 1.7 2002/11/27 08:42:34 starvik | ||
24 | * Argument to user_regs() is thread_info* | ||
25 | * | ||
26 | * Revision 1.6 2002/11/20 11:56:11 starvik | ||
27 | * Merge of Linux 2.5.48 | ||
28 | * | ||
29 | * Revision 1.5 2002/11/18 07:41:19 starvik | ||
30 | * Removed warning | ||
31 | * | ||
32 | * Revision 1.4 2002/11/11 12:47:28 starvik | ||
33 | * SYSCALL_TRACE has been moved to thread flags | ||
34 | * | ||
35 | * Revision 1.3 2002/02/05 15:37:18 bjornw | ||
36 | * * Add do_notify_resume (replaces do_signal in the callchain) | ||
37 | * * syscall_trace is now do_syscall_trace | ||
38 | * * current->ptrace flag PT_TRACESYS -> PT_SYSCALLTRACE | ||
39 | * * Keep track of the current->work.syscall_trace counter | ||
40 | * | ||
41 | * Revision 1.2 2001/12/18 13:35:20 bjornw | ||
42 | * Applied the 2.4.13->2.4.16 CRIS patch to 2.5.1 (is a copy of 2.4.15). | ||
43 | * | ||
44 | * Revision 1.8 2001/11/12 18:26:21 pkj | ||
45 | * Fixed compiler warnings. | ||
46 | * | ||
47 | * Revision 1.7 2001/09/26 11:53:49 bjornw | ||
48 | * PTRACE_DETACH works more simple in 2.4.10 | ||
49 | * | ||
50 | * Revision 1.6 2001/07/25 16:08:47 bjornw | ||
51 | * PTRACE_ATTACH bulk moved into arch-independent code in 2.4.7 | ||
52 | * | ||
53 | * Revision 1.5 2001/03/26 14:24:28 orjanf | ||
54 | * * Changed loop condition. | ||
55 | * * Added comment documenting non-standard ptrace behaviour. | ||
56 | * | ||
57 | * Revision 1.4 2001/03/20 19:44:41 bjornw | ||
58 | * Use the user_regs macro instead of thread.esp0 | ||
59 | * | ||
60 | * Revision 1.3 2000/12/18 23:45:25 bjornw | ||
61 | * Linux/CRIS first version | ||
62 | * | ||
63 | * | ||
64 | */ | 10 | */ |
65 | 11 | ||
66 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -85,7 +31,7 @@ extern int do_signal(int canrestart, struct pt_regs *regs); | |||
85 | 31 | ||
86 | 32 | ||
87 | void do_notify_resume(int canrestart, struct pt_regs *regs, | 33 | void do_notify_resume(int canrestart, struct pt_regs *regs, |
88 | __u32 thread_info_flags ) | 34 | __u32 thread_info_flags) |
89 | { | 35 | { |
90 | /* deal with pending signal delivery */ | 36 | /* deal with pending signal delivery */ |
91 | if (thread_info_flags & _TIF_SIGPENDING) | 37 | if (thread_info_flags & _TIF_SIGPENDING) |
diff --git a/arch/cris/kernel/semaphore.c b/arch/cris/kernel/semaphore.c index b884263d3cd4..f137a439041f 100644 --- a/arch/cris/kernel/semaphore.c +++ b/arch/cris/kernel/semaphore.c | |||
@@ -4,7 +4,6 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/init.h> | ||
8 | #include <asm/semaphore-helper.h> | 7 | #include <asm/semaphore-helper.h> |
9 | 8 | ||
10 | /* | 9 | /* |
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index c34fb235b09f..04d48dd91ddf 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/screen_info.h> | 18 | #include <linux/screen_info.h> |
19 | #include <linux/utsname.h> | 19 | #include <linux/utsname.h> |
20 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
21 | 21 | #include <linux/cpu.h> | |
22 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
23 | 23 | ||
24 | /* | 24 | /* |
@@ -36,6 +36,8 @@ extern unsigned long dram_start, dram_end; | |||
36 | 36 | ||
37 | extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */ | 37 | extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */ |
38 | 38 | ||
39 | static struct cpu cpu_devices[NR_CPUS]; | ||
40 | |||
39 | extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ | 41 | extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ |
40 | 42 | ||
41 | /* This mainly sets up the memory area, and can be really confusing. | 43 | /* This mainly sets up the memory area, and can be really confusing. |
@@ -45,24 +47,23 @@ extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ | |||
45 | * given by the macro __pa(). | 47 | * given by the macro __pa(). |
46 | * | 48 | * |
47 | * In this DRAM, the kernel code and data is loaded, in the beginning. | 49 | * In this DRAM, the kernel code and data is loaded, in the beginning. |
48 | * It really starts at c0004000 to make room for some special pages - | 50 | * It really starts at c0004000 to make room for some special pages - |
49 | * the start address is text_start. The kernel data ends at _end. After | 51 | * the start address is text_start. The kernel data ends at _end. After |
50 | * this the ROM filesystem is appended (if there is any). | 52 | * this the ROM filesystem is appended (if there is any). |
51 | * | 53 | * |
52 | * Between this address and dram_end, we have RAM pages usable to the | 54 | * Between this address and dram_end, we have RAM pages usable to the |
53 | * boot code and the system. | 55 | * boot code and the system. |
54 | * | 56 | * |
55 | */ | 57 | */ |
56 | 58 | ||
57 | void __init | 59 | void __init setup_arch(char **cmdline_p) |
58 | setup_arch(char **cmdline_p) | ||
59 | { | 60 | { |
60 | extern void init_etrax_debug(void); | 61 | extern void init_etrax_debug(void); |
61 | unsigned long bootmap_size; | 62 | unsigned long bootmap_size; |
62 | unsigned long start_pfn, max_pfn; | 63 | unsigned long start_pfn, max_pfn; |
63 | unsigned long memory_start; | 64 | unsigned long memory_start; |
64 | 65 | ||
65 | /* register an initial console printing routine for printk's */ | 66 | /* register an initial console printing routine for printk's */ |
66 | 67 | ||
67 | init_etrax_debug(); | 68 | init_etrax_debug(); |
68 | 69 | ||
@@ -121,7 +122,7 @@ setup_arch(char **cmdline_p) | |||
121 | min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT; | 122 | min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT; |
122 | 123 | ||
123 | bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, | 124 | bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, |
124 | min_low_pfn, | 125 | min_low_pfn, |
125 | max_low_pfn); | 126 | max_low_pfn); |
126 | 127 | ||
127 | /* And free all memory not belonging to the kernel (addr, size) */ | 128 | /* And free all memory not belonging to the kernel (addr, size) */ |
@@ -187,4 +188,16 @@ const struct seq_operations cpuinfo_op = { | |||
187 | .show = show_cpuinfo, | 188 | .show = show_cpuinfo, |
188 | }; | 189 | }; |
189 | 190 | ||
191 | static int __init topology_init(void) | ||
192 | { | ||
193 | int i; | ||
194 | |||
195 | for_each_possible_cpu(i) { | ||
196 | return register_cpu(&cpu_devices[i], i); | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | subsys_initcall(topology_init); | ||
190 | 203 | ||
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index 7a2cc7efbcf8..ff4c6aa75def 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* $Id: time.c,v 1.18 2005/03/04 08:16:17 starvik Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/kernel/time.c | 2 | * linux/arch/cris/kernel/time.c |
4 | * | 3 | * |
5 | * Copyright (C) 1991, 1992, 1995 Linus Torvalds | 4 | * Copyright (C) 1991, 1992, 1995 Linus Torvalds |
@@ -18,7 +17,7 @@ | |||
18 | * Linux/CRIS specific code: | 17 | * Linux/CRIS specific code: |
19 | * | 18 | * |
20 | * Authors: Bjorn Wesen | 19 | * Authors: Bjorn Wesen |
21 | * Johan Adolfsson | 20 | * Johan Adolfsson |
22 | * | 21 | * |
23 | */ | 22 | */ |
24 | 23 | ||
@@ -208,10 +207,16 @@ cris_do_profile(struct pt_regs* regs) | |||
208 | #endif | 207 | #endif |
209 | 208 | ||
210 | #ifdef CONFIG_PROFILING | 209 | #ifdef CONFIG_PROFILING |
211 | profile_tick(CPU_PROFILING); | 210 | profile_tick(CPU_PROFILING); |
212 | #endif | 211 | #endif |
213 | } | 212 | } |
214 | 213 | ||
214 | unsigned long long sched_clock(void) | ||
215 | { | ||
216 | return (unsigned long long)jiffies * (1000000000 / HZ) + | ||
217 | get_ns_in_jiffie(); | ||
218 | } | ||
219 | |||
215 | static int | 220 | static int |
216 | __init init_udelay(void) | 221 | __init init_udelay(void) |
217 | { | 222 | { |
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index 520d92205fed..541efbf09371 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c | |||
@@ -1,66 +1,78 @@ | |||
1 | /* $Id: traps.c,v 1.11 2005/01/24 16:03:19 orjanf Exp $ | 1 | /* |
2 | * | ||
3 | * linux/arch/cris/traps.c | 2 | * linux/arch/cris/traps.c |
4 | * | 3 | * |
5 | * Here we handle the break vectors not used by the system call | 4 | * Here we handle the break vectors not used by the system call |
6 | * mechanism, as well as some general stack/register dumping | 5 | * mechanism, as well as some general stack/register dumping |
7 | * things. | 6 | * things. |
8 | * | 7 | * |
9 | * Copyright (C) 2000-2002 Axis Communications AB | 8 | * Copyright (C) 2000-2007 Axis Communications AB |
10 | * | 9 | * |
11 | * Authors: Bjorn Wesen | 10 | * Authors: Bjorn Wesen |
12 | * Hans-Peter Nilsson | 11 | * Hans-Peter Nilsson |
13 | * | 12 | * |
14 | */ | 13 | */ |
15 | 14 | ||
16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | |||
18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
20 | 20 | ||
21 | extern void arch_enable_nmi(void); | ||
22 | extern void stop_watchdog(void); | ||
23 | extern void reset_watchdog(void); | ||
24 | extern void show_registers(struct pt_regs *regs); | ||
25 | |||
26 | #ifdef CONFIG_DEBUG_BUGVERBOSE | ||
27 | extern void handle_BUG(struct pt_regs *regs); | ||
28 | #else | ||
29 | #define handle_BUG(regs) | ||
30 | #endif | ||
31 | |||
21 | static int kstack_depth_to_print = 24; | 32 | static int kstack_depth_to_print = 24; |
22 | 33 | ||
23 | extern int raw_printk(const char *fmt, ...); | 34 | void (*nmi_handler)(struct pt_regs *); |
24 | 35 | ||
25 | void show_trace(unsigned long * stack) | 36 | void |
37 | show_trace(unsigned long *stack) | ||
26 | { | 38 | { |
27 | unsigned long addr, module_start, module_end; | 39 | unsigned long addr, module_start, module_end; |
28 | extern char _stext, _etext; | 40 | extern char _stext, _etext; |
29 | int i; | 41 | int i; |
30 | 42 | ||
31 | raw_printk("\nCall Trace: "); | 43 | printk("\nCall Trace: "); |
32 | 44 | ||
33 | i = 1; | 45 | i = 1; |
34 | module_start = VMALLOC_START; | 46 | module_start = VMALLOC_START; |
35 | module_end = VMALLOC_END; | 47 | module_end = VMALLOC_END; |
36 | 48 | ||
37 | while (((long) stack & (THREAD_SIZE-1)) != 0) { | 49 | while (((long)stack & (THREAD_SIZE-1)) != 0) { |
38 | if (__get_user (addr, stack)) { | 50 | if (__get_user(addr, stack)) { |
39 | /* This message matches "failing address" marked | 51 | /* This message matches "failing address" marked |
40 | s390 in ksymoops, so lines containing it will | 52 | s390 in ksymoops, so lines containing it will |
41 | not be filtered out by ksymoops. */ | 53 | not be filtered out by ksymoops. */ |
42 | raw_printk ("Failing address 0x%lx\n", (unsigned long)stack); | 54 | printk("Failing address 0x%lx\n", (unsigned long)stack); |
43 | break; | 55 | break; |
44 | } | 56 | } |
45 | stack++; | 57 | stack++; |
46 | 58 | ||
47 | /* | 59 | /* |
48 | * If the address is either in the text segment of the | 60 | * If the address is either in the text segment of the |
49 | * kernel, or in the region which contains vmalloc'ed | 61 | * kernel, or in the region which contains vmalloc'ed |
50 | * memory, it *may* be the address of a calling | 62 | * memory, it *may* be the address of a calling |
51 | * routine; if so, print it so that someone tracing | 63 | * routine; if so, print it so that someone tracing |
52 | * down the cause of the crash will be able to figure | 64 | * down the cause of the crash will be able to figure |
53 | * out the call path that was taken. | 65 | * out the call path that was taken. |
54 | */ | 66 | */ |
55 | if (((addr >= (unsigned long) &_stext) && | 67 | if (((addr >= (unsigned long)&_stext) && |
56 | (addr <= (unsigned long) &_etext)) || | 68 | (addr <= (unsigned long)&_etext)) || |
57 | ((addr >= module_start) && (addr <= module_end))) { | 69 | ((addr >= module_start) && (addr <= module_end))) { |
58 | if (i && ((i % 8) == 0)) | 70 | if (i && ((i % 8) == 0)) |
59 | raw_printk("\n "); | 71 | printk("\n "); |
60 | raw_printk("[<%08lx>] ", addr); | 72 | printk("[<%08lx>] ", addr); |
61 | i++; | 73 | i++; |
62 | } | 74 | } |
63 | } | 75 | } |
64 | } | 76 | } |
65 | 77 | ||
66 | /* | 78 | /* |
@@ -78,109 +90,149 @@ void show_trace(unsigned long * stack) | |||
78 | * with the ksymoops maintainer. | 90 | * with the ksymoops maintainer. |
79 | */ | 91 | */ |
80 | 92 | ||
81 | void | 93 | void |
82 | show_stack(struct task_struct *task, unsigned long *sp) | 94 | show_stack(struct task_struct *task, unsigned long *sp) |
83 | { | 95 | { |
84 | unsigned long *stack, addr; | 96 | unsigned long *stack, addr; |
85 | int i; | 97 | int i; |
86 | 98 | ||
87 | /* | 99 | /* |
88 | * debugging aid: "show_stack(NULL);" prints a | 100 | * debugging aid: "show_stack(NULL);" prints a |
89 | * back trace. | 101 | * back trace. |
90 | */ | 102 | */ |
91 | 103 | ||
92 | if(sp == NULL) { | 104 | if (sp == NULL) { |
93 | if (task) | 105 | if (task) |
94 | sp = (unsigned long*)task->thread.ksp; | 106 | sp = (unsigned long*)task->thread.ksp; |
95 | else | 107 | else |
96 | sp = (unsigned long*)rdsp(); | 108 | sp = (unsigned long*)rdsp(); |
97 | } | 109 | } |
98 | 110 | ||
99 | stack = sp; | 111 | stack = sp; |
100 | 112 | ||
101 | raw_printk("\nStack from %08lx:\n ", (unsigned long)stack); | 113 | printk("\nStack from %08lx:\n ", (unsigned long)stack); |
102 | for(i = 0; i < kstack_depth_to_print; i++) { | 114 | for (i = 0; i < kstack_depth_to_print; i++) { |
103 | if (((long) stack & (THREAD_SIZE-1)) == 0) | 115 | if (((long)stack & (THREAD_SIZE-1)) == 0) |
104 | break; | 116 | break; |
105 | if (i && ((i % 8) == 0)) | 117 | if (i && ((i % 8) == 0)) |
106 | raw_printk("\n "); | 118 | printk("\n "); |
107 | if (__get_user (addr, stack)) { | 119 | if (__get_user(addr, stack)) { |
108 | /* This message matches "failing address" marked | 120 | /* This message matches "failing address" marked |
109 | s390 in ksymoops, so lines containing it will | 121 | s390 in ksymoops, so lines containing it will |
110 | not be filtered out by ksymoops. */ | 122 | not be filtered out by ksymoops. */ |
111 | raw_printk ("Failing address 0x%lx\n", (unsigned long)stack); | 123 | printk("Failing address 0x%lx\n", (unsigned long)stack); |
112 | break; | 124 | break; |
113 | } | 125 | } |
114 | stack++; | 126 | stack++; |
115 | raw_printk("%08lx ", addr); | 127 | printk("%08lx ", addr); |
116 | } | 128 | } |
117 | show_trace(sp); | 129 | show_trace(sp); |
118 | } | 130 | } |
119 | 131 | ||
120 | static void (*nmi_handler)(struct pt_regs*); | 132 | #if 0 |
121 | extern void arch_enable_nmi(void); | 133 | /* displays a short stack trace */ |
122 | 134 | ||
123 | void set_nmi_handler(void (*handler)(struct pt_regs*)) | 135 | int |
136 | show_stack(void) | ||
124 | { | 137 | { |
125 | nmi_handler = handler; | 138 | unsigned long *sp = (unsigned long *)rdusp(); |
126 | arch_enable_nmi(); | 139 | int i; |
140 | |||
141 | printk("Stack dump [0x%08lx]:\n", (unsigned long)sp); | ||
142 | for (i = 0; i < 16; i++) | ||
143 | printk("sp + %d: 0x%08lx\n", i*4, sp[i]); | ||
144 | return 0; | ||
127 | } | 145 | } |
146 | #endif | ||
128 | 147 | ||
129 | void handle_nmi(struct pt_regs* regs) | 148 | void |
149 | dump_stack(void) | ||
130 | { | 150 | { |
131 | if (nmi_handler) | 151 | show_stack(NULL, NULL); |
132 | nmi_handler(regs); | 152 | } |
153 | EXPORT_SYMBOL(dump_stack); | ||
154 | |||
155 | void | ||
156 | set_nmi_handler(void (*handler)(struct pt_regs *)) | ||
157 | { | ||
158 | nmi_handler = handler; | ||
159 | arch_enable_nmi(); | ||
133 | } | 160 | } |
134 | 161 | ||
135 | #ifdef CONFIG_DEBUG_NMI_OOPS | 162 | #ifdef CONFIG_DEBUG_NMI_OOPS |
136 | void oops_nmi_handler(struct pt_regs* regs) | 163 | void |
164 | oops_nmi_handler(struct pt_regs *regs) | ||
137 | { | 165 | { |
138 | stop_watchdog(); | 166 | stop_watchdog(); |
139 | raw_printk("NMI!\n"); | 167 | oops_in_progress = 1; |
140 | show_registers(regs); | 168 | printk("NMI!\n"); |
169 | show_registers(regs); | ||
170 | oops_in_progress = 0; | ||
141 | } | 171 | } |
142 | 172 | ||
143 | static int | 173 | static int __init |
144 | __init oops_nmi_register(void) | 174 | oops_nmi_register(void) |
145 | { | 175 | { |
146 | set_nmi_handler(oops_nmi_handler); | 176 | set_nmi_handler(oops_nmi_handler); |
147 | return 0; | 177 | return 0; |
148 | } | 178 | } |
149 | 179 | ||
150 | __initcall(oops_nmi_register); | 180 | __initcall(oops_nmi_register); |
151 | 181 | ||
152 | #endif | 182 | #endif |
153 | 183 | ||
154 | #if 0 | 184 | /* |
155 | /* displays a short stack trace */ | 185 | * This gets called from entry.S when the watchdog has bitten. Show something |
156 | 186 | * similiar to an Oops dump, and if the kernel is configured to be a nice | |
157 | int | 187 | * doggy, then halt instead of reboot. |
158 | show_stack() | 188 | */ |
189 | void | ||
190 | watchdog_bite_hook(struct pt_regs *regs) | ||
159 | { | 191 | { |
160 | unsigned long *sp = (unsigned long *)rdusp(); | 192 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY |
161 | int i; | 193 | local_irq_disable(); |
162 | raw_printk("Stack dump [0x%08lx]:\n", (unsigned long)sp); | 194 | stop_watchdog(); |
163 | for(i = 0; i < 16; i++) | 195 | show_registers(regs); |
164 | raw_printk("sp + %d: 0x%08lx\n", i*4, sp[i]); | 196 | |
165 | return 0; | 197 | while (1) |
166 | } | 198 | ; /* Do nothing. */ |
199 | #else | ||
200 | show_registers(regs); | ||
167 | #endif | 201 | #endif |
202 | } | ||
168 | 203 | ||
169 | void dump_stack(void) | 204 | /* This is normally the Oops function. */ |
205 | void | ||
206 | die_if_kernel(const char *str, struct pt_regs *regs, long err) | ||
170 | { | 207 | { |
171 | show_stack(NULL, NULL); | 208 | if (user_mode(regs)) |
172 | } | 209 | return; |
173 | 210 | ||
174 | EXPORT_SYMBOL(dump_stack); | 211 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY |
212 | /* | ||
213 | * This printout might take too long and could trigger | ||
214 | * the watchdog normally. If NICE_DOGGY is set, simply | ||
215 | * stop the watchdog during the printout. | ||
216 | */ | ||
217 | stop_watchdog(); | ||
218 | #endif | ||
175 | 219 | ||
176 | void __init | 220 | handle_BUG(regs); |
177 | trap_init(void) | 221 | |
178 | { | 222 | printk("%s: %04lx\n", str, err & 0xffff); |
179 | /* Nothing needs to be done */ | 223 | |
224 | show_registers(regs); | ||
225 | |||
226 | oops_in_progress = 0; | ||
227 | |||
228 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | ||
229 | reset_watchdog(); | ||
230 | #endif | ||
231 | do_exit(SIGSEGV); | ||
180 | } | 232 | } |
181 | 233 | ||
182 | void spinning_cpu(void* addr) | 234 | void __init |
235 | trap_init(void) | ||
183 | { | 236 | { |
184 | raw_printk("CPU %d spinning on %X\n", smp_processor_id(), addr); | 237 | /* Nothing needs to be done */ |
185 | dump_stack(); | ||
186 | } | 238 | } |
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 3034f3ff950c..c4c76db90f9c 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c | |||
@@ -1,130 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/cris/mm/fault.c | 2 | * linux/arch/cris/mm/fault.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000, 2001 Axis Communications AB | 4 | * Copyright (C) 2000-2006 Axis Communications AB |
5 | * | ||
6 | * Authors: Bjorn Wesen | ||
7 | * | ||
8 | * $Log: fault.c,v $ | ||
9 | * Revision 1.20 2005/03/04 08:16:18 starvik | ||
10 | * Merge of Linux 2.6.11. | ||
11 | * | ||
12 | * Revision 1.19 2005/01/14 10:07:59 starvik | ||
13 | * Fixed warning. | ||
14 | * | ||
15 | * Revision 1.18 2005/01/12 08:10:14 starvik | ||
16 | * Re-added the change of frametype when handling kernel page fault fixup | ||
17 | * for v10. This is necessary to avoid that the CPU remakes the faulting | ||
18 | * access. | ||
19 | * | ||
20 | * Revision 1.17 2005/01/11 13:53:05 starvik | ||
21 | * Use raw_printk. | ||
22 | * | ||
23 | * Revision 1.16 2004/12/17 11:39:41 starvik | ||
24 | * SMP support. | ||
25 | * | ||
26 | * Revision 1.15 2004/11/23 18:36:18 starvik | ||
27 | * Stack is now non-executable. | ||
28 | * Signal handler trampolines are placed in a reserved page mapped into all | ||
29 | * processes. | ||
30 | * | ||
31 | * Revision 1.14 2004/11/23 07:10:21 starvik | ||
32 | * Moved find_fixup_code to generic code. | ||
33 | * | ||
34 | * Revision 1.13 2004/11/23 07:00:54 starvik | ||
35 | * Actually use the execute permission bit in the MMU. This makes it possible | ||
36 | * to prevent e.g. attacks where executable code is put on the stack. | ||
37 | * | ||
38 | * Revision 1.12 2004/09/29 06:16:04 starvik | ||
39 | * Use instruction_pointer | ||
40 | * | ||
41 | * Revision 1.11 2004/05/14 07:58:05 starvik | ||
42 | * Merge of changes from 2.4 | ||
43 | * | ||
44 | * Revision 1.10 2003/10/27 14:51:24 starvik | ||
45 | * Removed debugcode | ||
46 | * | ||
47 | * Revision 1.9 2003/10/27 14:50:42 starvik | ||
48 | * Changed do_page_fault signature | ||
49 | * | ||
50 | * Revision 1.8 2003/07/04 13:02:48 tobiasa | ||
51 | * Moved code snippet from arch/cris/mm/fault.c that searches for fixup code | ||
52 | * to separate function in arch-specific files. | ||
53 | * | ||
54 | * Revision 1.7 2003/01/22 06:48:38 starvik | ||
55 | * Fixed warnings issued by GCC 3.2.1 | ||
56 | * | ||
57 | * Revision 1.6 2003/01/09 14:42:52 starvik | ||
58 | * Merge of Linux 2.5.55 | ||
59 | * | ||
60 | * Revision 1.5 2002/12/11 14:44:48 starvik | ||
61 | * Extracted v10 (ETRAX 100LX) specific stuff to arch/cris/arch-v10/mm | ||
62 | * | ||
63 | * Revision 1.4 2002/11/13 15:10:28 starvik | ||
64 | * pte_offset has been renamed to pte_offset_kernel | ||
65 | * | ||
66 | * Revision 1.3 2002/11/05 06:45:13 starvik | ||
67 | * Merge of Linux 2.5.45 | ||
68 | * | ||
69 | * Revision 1.2 2001/12/18 13:35:22 bjornw | ||
70 | * Applied the 2.4.13->2.4.16 CRIS patch to 2.5.1 (is a copy of 2.4.15). | ||
71 | * | ||
72 | * Revision 1.20 2001/11/22 13:34:06 bjornw | ||
73 | * * Bug workaround (LX TR89): force a rerun of the whole of an interrupted | ||
74 | * unaligned write, because the second half of the write will be corrupted | ||
75 | * otherwise. Affected unaligned writes spanning not-yet mapped pages. | ||
76 | * * Optimization: use the wr_rd bit in R_MMU_CAUSE to know whether a miss | ||
77 | * was due to a read or a write (before we didn't know this until the next | ||
78 | * restart of the interrupted instruction, thus wasting one fault-irq) | ||
79 | * | ||
80 | * Revision 1.19 2001/11/12 19:02:10 pkj | ||
81 | * Fixed compiler warnings. | ||
82 | * | ||
83 | * Revision 1.18 2001/07/18 22:14:32 bjornw | ||
84 | * Enable interrupts in the bulk of do_page_fault | ||
85 | * | ||
86 | * Revision 1.17 2001/07/18 13:07:23 bjornw | ||
87 | * * Detect non-existant PTE's in vmalloc pmd synchronization | ||
88 | * * Remove comment about fast-paths for VMALLOC_START etc, because all that | ||
89 | * was totally bogus anyway it turned out :) | ||
90 | * * Fix detection of vmalloc-area synchronization | ||
91 | * * Add some comments | ||
92 | * | ||
93 | * Revision 1.16 2001/06/13 00:06:08 bjornw | ||
94 | * current_pgd should be volatile | ||
95 | * | ||
96 | * Revision 1.15 2001/06/13 00:02:23 bjornw | ||
97 | * Use a separate variable to store the current pgd to avoid races in schedule | ||
98 | * | ||
99 | * Revision 1.14 2001/05/16 17:41:07 hp | ||
100 | * Last comment tweak further tweaked. | ||
101 | * | ||
102 | * Revision 1.13 2001/05/15 00:58:44 hp | ||
103 | * Expand a bit on the comment why we compare address >= TASK_SIZE rather | ||
104 | * than >= VMALLOC_START. | ||
105 | * | ||
106 | * Revision 1.12 2001/04/04 10:51:14 bjornw | ||
107 | * mmap_sem is grabbed for reading | ||
108 | * | ||
109 | * Revision 1.11 2001/03/23 07:36:07 starvik | ||
110 | * Corrected according to review remarks | ||
111 | * | ||
112 | * Revision 1.10 2001/03/21 16:10:11 bjornw | ||
113 | * CRIS_FRAME_FIXUP not needed anymore, use FRAME_NORMAL | ||
114 | * | ||
115 | * Revision 1.9 2001/03/05 13:22:20 bjornw | ||
116 | * Spell-fix and fix in vmalloc_fault handling | ||
117 | * | ||
118 | * Revision 1.8 2000/11/22 14:45:31 bjornw | ||
119 | * * 2.4.0-test10 removed the set_pgdir instantaneous kernel global mapping | ||
120 | * into all processes. Instead we fill in the missing PTE entries on demand. | ||
121 | * | ||
122 | * Revision 1.7 2000/11/21 16:39:09 bjornw | ||
123 | * fixup switches frametype | ||
124 | * | ||
125 | * Revision 1.6 2000/11/17 16:54:08 bjornw | ||
126 | * More detailed siginfo reporting | ||
127 | * | 5 | * |
6 | * Authors: Bjorn Wesen | ||
128 | * | 7 | * |
129 | */ | 8 | */ |
130 | 9 | ||
@@ -135,7 +14,6 @@ | |||
135 | 14 | ||
136 | extern int find_fixup_code(struct pt_regs *); | 15 | extern int find_fixup_code(struct pt_regs *); |
137 | extern void die_if_kernel(const char *, struct pt_regs *, long); | 16 | extern void die_if_kernel(const char *, struct pt_regs *, long); |
138 | extern int raw_printk(const char *fmt, ...); | ||
139 | 17 | ||
140 | /* debug of low-level TLB reload */ | 18 | /* debug of low-level TLB reload */ |
141 | #undef DEBUG | 19 | #undef DEBUG |
@@ -164,8 +42,8 @@ unsigned long cris_signal_return_page; | |||
164 | * address. | 42 | * address. |
165 | * | 43 | * |
166 | * error_code: | 44 | * error_code: |
167 | * bit 0 == 0 means no page found, 1 means protection fault | 45 | * bit 0 == 0 means no page found, 1 means protection fault |
168 | * bit 1 == 0 means read, 1 means write | 46 | * bit 1 == 0 means read, 1 means write |
169 | * | 47 | * |
170 | * If this routine detects a bad access, it returns 1, otherwise it | 48 | * If this routine detects a bad access, it returns 1, otherwise it |
171 | * returns 0. | 49 | * returns 0. |
@@ -181,9 +59,10 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
181 | siginfo_t info; | 59 | siginfo_t info; |
182 | int fault; | 60 | int fault; |
183 | 61 | ||
184 | D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n", | 62 | D(printk(KERN_DEBUG |
185 | address, smp_processor_id(), instruction_pointer(regs), | 63 | "Page fault for %lX on %X at %lX, prot %d write %d\n", |
186 | protection, writeaccess)); | 64 | address, smp_processor_id(), instruction_pointer(regs), |
65 | protection, writeaccess)); | ||
187 | 66 | ||
188 | tsk = current; | 67 | tsk = current; |
189 | 68 | ||
@@ -233,7 +112,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
233 | * context, we must not take the fault.. | 112 | * context, we must not take the fault.. |
234 | */ | 113 | */ |
235 | 114 | ||
236 | if (in_atomic() || !mm) | 115 | if (in_interrupt() || !mm) |
237 | goto no_context; | 116 | goto no_context; |
238 | 117 | ||
239 | down_read(&mm->mmap_sem); | 118 | down_read(&mm->mmap_sem); |
@@ -319,6 +198,9 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
319 | /* info.si_code has been set above */ | 198 | /* info.si_code has been set above */ |
320 | info.si_addr = (void *)address; | 199 | info.si_addr = (void *)address; |
321 | force_sig_info(SIGSEGV, &info, tsk); | 200 | force_sig_info(SIGSEGV, &info, tsk); |
201 | printk(KERN_NOTICE "%s (pid %d) segfaults for page " | ||
202 | "address %08lx at pc %08lx\n", | ||
203 | tsk->comm, tsk->pid, address, instruction_pointer(regs)); | ||
322 | return; | 204 | return; |
323 | } | 205 | } |
324 | 206 | ||
@@ -326,7 +208,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
326 | 208 | ||
327 | /* Are we prepared to handle this kernel fault? | 209 | /* Are we prepared to handle this kernel fault? |
328 | * | 210 | * |
329 | * (The kernel has valid exception-points in the source | 211 | * (The kernel has valid exception-points in the source |
330 | * when it acesses user-memory. When it fails in one | 212 | * when it acesses user-memory. When it fails in one |
331 | * of those points, we find it in a table and do a jump | 213 | * of those points, we find it in a table and do a jump |
332 | * to some fixup code that loads an appropriate error | 214 | * to some fixup code that loads an appropriate error |
@@ -341,13 +223,18 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
341 | * terminate things with extreme prejudice. | 223 | * terminate things with extreme prejudice. |
342 | */ | 224 | */ |
343 | 225 | ||
344 | if ((unsigned long) (address) < PAGE_SIZE) | 226 | if (!oops_in_progress) { |
345 | raw_printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); | 227 | oops_in_progress = 1; |
346 | else | 228 | if ((unsigned long) (address) < PAGE_SIZE) |
347 | raw_printk(KERN_ALERT "Unable to handle kernel access"); | 229 | printk(KERN_ALERT "Unable to handle kernel NULL " |
348 | raw_printk(" at virtual address %08lx\n",address); | 230 | "pointer dereference"); |
349 | 231 | else | |
350 | die_if_kernel("Oops", regs, (writeaccess << 1) | protection); | 232 | printk(KERN_ALERT "Unable to handle kernel access" |
233 | " at virtual address %08lx\n", address); | ||
234 | |||
235 | die_if_kernel("Oops", regs, (writeaccess << 1) | protection); | ||
236 | oops_in_progress = 0; | ||
237 | } | ||
351 | 238 | ||
352 | do_exit(SIGKILL); | 239 | do_exit(SIGKILL); |
353 | 240 | ||
@@ -360,7 +247,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
360 | up_read(&mm->mmap_sem); | 247 | up_read(&mm->mmap_sem); |
361 | printk("VM: killing process %s\n", tsk->comm); | 248 | printk("VM: killing process %s\n", tsk->comm); |
362 | if (user_mode(regs)) | 249 | if (user_mode(regs)) |
363 | do_group_exit(SIGKILL); | 250 | do_exit(SIGKILL); |
364 | goto no_context; | 251 | goto no_context; |
365 | 252 | ||
366 | do_sigbus: | 253 | do_sigbus: |
@@ -406,8 +293,8 @@ vmalloc_fault: | |||
406 | /* Since we're two-level, we don't need to do both | 293 | /* Since we're two-level, we don't need to do both |
407 | * set_pgd and set_pmd (they do the same thing). If | 294 | * set_pgd and set_pmd (they do the same thing). If |
408 | * we go three-level at some point, do the right thing | 295 | * we go three-level at some point, do the right thing |
409 | * with pgd_present and set_pgd here. | 296 | * with pgd_present and set_pgd here. |
410 | * | 297 | * |
411 | * Also, since the vmalloc area is global, we don't | 298 | * Also, since the vmalloc area is global, we don't |
412 | * need to copy individual PTE's, it is enough to | 299 | * need to copy individual PTE's, it is enough to |
413 | * copy the pgd pointer into the pte page of the | 300 | * copy the pgd pointer into the pte page of the |
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index 0c833d176226..4207a2b52750 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c | |||
@@ -6,117 +6,6 @@ | |||
6 | * | 6 | * |
7 | * Authors: Bjorn Wesen (bjornw@axis.com) | 7 | * Authors: Bjorn Wesen (bjornw@axis.com) |
8 | * | 8 | * |
9 | * $Log: init.c,v $ | ||
10 | * Revision 1.11 2004/05/28 09:28:56 starvik | ||
11 | * Calculation of loops_per_usec moved because initialization order has changed | ||
12 | * in Linux 2.6. | ||
13 | * | ||
14 | * Revision 1.10 2004/05/14 07:58:05 starvik | ||
15 | * Merge of changes from 2.4 | ||
16 | * | ||
17 | * Revision 1.9 2003/07/04 08:27:54 starvik | ||
18 | * Merge of Linux 2.5.74 | ||
19 | * | ||
20 | * Revision 1.8 2003/04/09 05:20:48 starvik | ||
21 | * Merge of Linux 2.5.67 | ||
22 | * | ||
23 | * Revision 1.7 2003/01/22 06:48:38 starvik | ||
24 | * Fixed warnings issued by GCC 3.2.1 | ||
25 | * | ||
26 | * Revision 1.6 2002/12/11 14:44:48 starvik | ||
27 | * Extracted v10 (ETRAX 100LX) specific stuff to arch/cris/arch-v10/mm | ||
28 | * | ||
29 | * Revision 1.5 2002/11/18 07:37:37 starvik | ||
30 | * Added cache bug workaround (from Linux 2.4) | ||
31 | * | ||
32 | * Revision 1.4 2002/11/13 15:40:24 starvik | ||
33 | * Removed the page table cache stuff (as done in other archs) | ||
34 | * | ||
35 | * Revision 1.3 2002/11/05 06:45:13 starvik | ||
36 | * Merge of Linux 2.5.45 | ||
37 | * | ||
38 | * Revision 1.2 2001/12/18 13:35:22 bjornw | ||
39 | * Applied the 2.4.13->2.4.16 CRIS patch to 2.5.1 (is a copy of 2.4.15). | ||
40 | * | ||
41 | * Revision 1.31 2001/11/13 16:22:00 bjornw | ||
42 | * Skip calculating totalram and sharedram in si_meminfo | ||
43 | * | ||
44 | * Revision 1.30 2001/11/12 19:02:10 pkj | ||
45 | * Fixed compiler warnings. | ||
46 | * | ||
47 | * Revision 1.29 2001/07/25 16:09:50 bjornw | ||
48 | * val->sharedram will stay 0 | ||
49 | * | ||
50 | * Revision 1.28 2001/06/28 16:30:17 bjornw | ||
51 | * Oops. This needs to wait until 2.4.6 is merged | ||
52 | * | ||
53 | * Revision 1.27 2001/06/28 14:04:07 bjornw | ||
54 | * Fill in sharedram | ||
55 | * | ||
56 | * Revision 1.26 2001/06/18 06:36:02 hp | ||
57 | * Enable free_initmem of __init-type pages | ||
58 | * | ||
59 | * Revision 1.25 2001/06/13 00:02:23 bjornw | ||
60 | * Use a separate variable to store the current pgd to avoid races in schedule | ||
61 | * | ||
62 | * Revision 1.24 2001/05/15 00:52:20 hp | ||
63 | * Only map segment 0xa as seg if CONFIG_JULIETTE | ||
64 | * | ||
65 | * Revision 1.23 2001/04/04 14:35:40 bjornw | ||
66 | * * Removed get_pte_slow and friends (2.4.3 change) | ||
67 | * * Removed bad_pmd handling (2.4.3 change) | ||
68 | * | ||
69 | * Revision 1.22 2001/04/04 13:38:04 matsfg | ||
70 | * Moved ioremap to a separate function instead | ||
71 | * | ||
72 | * Revision 1.21 2001/03/27 09:28:33 bjornw | ||
73 | * ioremap used too early - lets try it in mem_init instead | ||
74 | * | ||
75 | * Revision 1.20 2001/03/23 07:39:21 starvik | ||
76 | * Corrected according to review remarks | ||
77 | * | ||
78 | * Revision 1.19 2001/03/15 14:25:17 bjornw | ||
79 | * More general shadow registers and ioremaped addresses for external I/O | ||
80 | * | ||
81 | * Revision 1.18 2001/02/23 12:46:44 bjornw | ||
82 | * * 0xc was not CSE1; 0x8 is, same as uncached flash, so we move the uncached | ||
83 | * flash during CRIS_LOW_MAP from 0xe to 0x8 so both the flash and the I/O | ||
84 | * is mapped straight over (for !CRIS_LOW_MAP the uncached flash is still 0xe) | ||
85 | * | ||
86 | * Revision 1.17 2001/02/22 15:05:21 bjornw | ||
87 | * Map 0x9 straight over during LOW_MAP to allow for memory mapped LEDs | ||
88 | * | ||
89 | * Revision 1.16 2001/02/22 15:02:35 bjornw | ||
90 | * Map 0xc straight over during LOW_MAP to allow for memory mapped I/O | ||
91 | * | ||
92 | * Revision 1.15 2001/01/10 21:12:10 bjornw | ||
93 | * loops_per_sec -> loops_per_jiffy | ||
94 | * | ||
95 | * Revision 1.14 2000/11/22 16:23:20 bjornw | ||
96 | * Initialize totalhigh counters to 0 to make /proc/meminfo look nice. | ||
97 | * | ||
98 | * Revision 1.13 2000/11/21 16:37:51 bjornw | ||
99 | * Temporarily disable initmem freeing | ||
100 | * | ||
101 | * Revision 1.12 2000/11/21 13:55:07 bjornw | ||
102 | * Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type | ||
103 | * | ||
104 | * Revision 1.11 2000/10/06 12:38:22 bjornw | ||
105 | * Cast empty_bad_page correctly (should really be of * type from the start.. | ||
106 | * | ||
107 | * Revision 1.10 2000/10/04 16:53:57 bjornw | ||
108 | * Fix memory-map due to LX features | ||
109 | * | ||
110 | * Revision 1.9 2000/09/13 15:47:49 bjornw | ||
111 | * Wrong count in reserved-pages loop | ||
112 | * | ||
113 | * Revision 1.8 2000/09/13 14:35:10 bjornw | ||
114 | * 2.4.0-test8 added a new arg to free_area_init_node | ||
115 | * | ||
116 | * Revision 1.7 2000/08/17 15:35:55 bjornw | ||
117 | * 2.4.0-test6 removed MAP_NR and inserted virt_to_page | ||
118 | * | ||
119 | * | ||
120 | */ | 9 | */ |
121 | 10 | ||
122 | #include <linux/init.h> | 11 | #include <linux/init.h> |